/* $Id: VBoxICD.c $ */ /** @file * VirtualBox Windows Guest Mesa3D - OpenGL driver loader. */ /* * Copyright (C) 2018-2023 Oracle and/or its affiliates. * * This file is part of VirtualBox base platform packages, as * available from https://www.virtualbox.org. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, in version 3 of the * License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * SPDX-License-Identifier: GPL-3.0-only */ #include #include static const char *g_pszGalliumDll = #ifdef VBOX_WOW64 "VBoxGL-x86.dll" #else "VBoxGL.dll" #endif ; static const char *g_pszChromiumDll = #ifdef VBOX_WOW64 "VBoxOGL-x86.dll" #else "VBoxOGL.dll" #endif ; extern struct VBOXWDDMDLLPROC aIcdProcs[]; HMODULE volatile g_hmodICD = NULL; static NTSTATUS vboxDdiQueryAdapterInfo(D3DKMT_HANDLE hAdapter, VBOXWDDM_QAI *pAdapterInfo, uint32_t cbAdapterInfo) { NTSTATUS Status; D3DKMTFUNCTIONS const *d3dkmt = D3DKMTFunctions(); if (d3dkmt->pfnD3DKMTQueryAdapterInfo) { D3DKMT_QUERYADAPTERINFO QAI; memset(&QAI, 0, sizeof(QAI)); QAI.hAdapter = hAdapter; QAI.Type = KMTQAITYPE_UMDRIVERPRIVATE; QAI.pPrivateDriverData = pAdapterInfo; QAI.PrivateDriverDataSize = cbAdapterInfo; Status = d3dkmt->pfnD3DKMTQueryAdapterInfo(&QAI); } else { Status = STATUS_NOT_SUPPORTED; } return Status; } void VBoxLoadICD(void) { NTSTATUS Status; D3DKMT_HANDLE hAdapter = 0; D3DKMTLoad(); Status = vboxDispKmtOpenAdapter(&hAdapter); if (Status == STATUS_SUCCESS) { VBOXWDDM_QAI adapterInfo; Status = vboxDdiQueryAdapterInfo(hAdapter, &adapterInfo, sizeof(adapterInfo)); if (Status == STATUS_SUCCESS) { const char *pszDll = NULL; switch (adapterInfo.enmHwType) { case VBOXVIDEO_HWTYPE_VBOX: pszDll = g_pszChromiumDll; break; default: case VBOXVIDEO_HWTYPE_VMSVGA: pszDll = g_pszGalliumDll; break; } if (pszDll) { g_hmodICD = VBoxWddmLoadSystemDll(pszDll); if (g_hmodICD) { VBoxWddmLoadAdresses(g_hmodICD, aIcdProcs); } } } vboxDispKmtCloseAdapter(hAdapter); } } /* * MSDN says: * "You should never perform the following tasks from within DllMain: * Call LoadLibrary or LoadLibraryEx (either directly or indirectly)." * * However it turned out that loading the real ICD from DLL_PROCESS_ATTACH works, * and loading it in a lazy way fails for unknown reason on 64 bit Windows. * * So just call VBoxLoadICD from DLL_PROCESS_ATTACH. */ BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved) { RT_NOREF(hDLLInst); switch (fdwReason) { case DLL_PROCESS_ATTACH: VBoxLoadICD(); break; case DLL_PROCESS_DETACH: if (lpvReserved == NULL) { /* "The DLL is being unloaded because of a call to FreeLibrary." */ if (g_hmodICD) { FreeLibrary(g_hmodICD); g_hmodICD = NULL; } } else { /* "The DLL is being unloaded due to process termination." */ /* Do not bother. */ } break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; default: break; } return TRUE; }