Author: hbelusca Date: Tue Dec 24 13:33:51 2013 New Revision: 61370
URL: http://svn.reactos.org/svn/reactos?rev=61370&view=rev Log: [NTVDM] Load VDDs registered in HKLM\SYSTEM\CurrentControlSet\Control\VirtualDeviceDrivers key, value "VDD" (of type REG_MULTI_SZ). I still don't call FreeLibrary to unload them at the end of NTVDM's lifetime (otherwise we would have to store their handles in an array).
Modified: branches/ntvdm/subsystems/ntvdm/vddsup.c
Modified: branches/ntvdm/subsystems/ntvdm/vddsup.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/vddsup.c?... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/vddsup.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/vddsup.c [iso-8859-1] Tue Dec 24 13:33:51 2013 @@ -16,6 +16,8 @@ #include "bop.h" #include "registers.h"
+#include <isvbop.h> + typedef VOID (WINAPI *VDD_PROC)(VOID);
typedef struct _VDD_MODULE @@ -24,13 +26,10 @@ VDD_PROC DispatchRoutine; } VDD_MODULE, *PVDD_MODULE;
-/* BOP Identifiers */ -#define BOP_3RDPARTY 0x58 // 3rd-party VDD BOP - /* PRIVATE VARIABLES **********************************************************/
// TODO: Maybe use a linked list. -// But the number of elements must be <= MAXUSHORT +// But the number of elements must be <= MAXUSHORT (MAXWORD) #define MAX_VDD_MODULES 0xFF + 1 VDD_MODULE VDDList[MAX_VDD_MODULES] = {{NULL}};
@@ -77,11 +76,21 @@ /* Clear the Carry Flag (no error happened so far) */ setCF(0);
+ /* Retrieve the next free entry in the table (used later on) */ + Entry = GetNextFreeVDDEntry(); + if (Entry >= MAX_VDD_MODULES) + { + DPRINT1("Failed to create a new VDD module entry\n"); + Success = FALSE; + RetVal = 4; + goto Quit; + } + /* Retrieve the VDD name in DS:SI */ DllName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI());
/* Retrieve the initialization routine API name in ES:DI (optional --> ES=DI=0) */ - if (getES() != 0 || getDI() != 0) + if (TO_LINEAR(getES(), getDI()) != 0) InitRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getES(), getDI());
/* Retrieve the dispatch routine API name in DS:BX */ @@ -139,14 +148,6 @@ /* If we arrived there, that means everything is OK */
/* Register the VDD DLL */ - Entry = GetNextFreeVDDEntry(); - if (Entry == MAX_VDD_MODULES) - { - DPRINT1("Failed to create a new VDD module entry\n"); - Success = FALSE; - RetVal = 4; - goto Quit; - } VDDList[Entry].hDll = hDll; VDDList[Entry].DispatchRoutine = DispatchRoutine;
@@ -232,12 +233,110 @@ } }
+BOOL LoadInstallableVDD(VOID) +{ +#define ERROR_MEMORYVDD L"Insufficient memory to load installable Virtual Device Drivers." +#define ERROR_REGVDD L"Virtual Device Driver format in the registry is invalid." +#define ERROR_LOADVDD L"An installable Virtual Device Driver failed Dll initialization." + + BOOL Success = TRUE; + LONG Error = 0; + DWORD Type = 0; + DWORD BufSize = 0; + + HKEY hVDDKey; + LPCWSTR VDDKeyName = L"SYSTEM\CurrentControlSet\Control\VirtualDeviceDrivers"; + LPWSTR VDDValueName = L"VDD"; + LPWSTR VDDList = NULL; + + HANDLE hVDD; + + /* Open the VDD registry key */ + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, + VDDKeyName, + 0, + KEY_QUERY_VALUE, + &hVDDKey) != ERROR_SUCCESS) + { + DisplayMessage(ERROR_REGVDD); + return FALSE; + } + + /* + * Retrieve the size of the VDD registry value + * and check that it's of REG_MULTI_SZ type. + */ + Error = RegQueryValueExW(hVDDKey, + VDDValueName, + NULL, + &Type, + NULL, + &BufSize); + if (Error != ERROR_SUCCESS || Type != REG_MULTI_SZ) + { + DisplayMessage(ERROR_REGVDD); + Success = FALSE; + goto Quit; + } + + /* Allocate the buffer */ + BufSize = (BufSize < 2*sizeof(WCHAR) ? 2*sizeof(WCHAR) : BufSize); + VDDList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BufSize); + if (VDDList == NULL) + { + DisplayMessage(ERROR_MEMORYVDD); + Success = FALSE; + goto Quit; + } + + /* Retrieve the list of VDDs to load */ + if (RegQueryValueExW(hVDDKey, + VDDValueName, + NULL, + NULL, + (LPBYTE)VDDList, + &BufSize) != ERROR_SUCCESS) + { + DisplayMessage(ERROR_REGVDD); + Success = FALSE; + goto Quit; + } + + /* Load the VDDs */ + VDDValueName = VDDList; + while (*VDDList) + { + DPRINT1("Loading VDD '%S'...", VDDList); + hVDD = LoadLibraryW(VDDList); + if (hVDD == NULL) + { + DbgPrint("Failed\n"); + DisplayMessage(ERROR_LOADVDD); + } + else + { + DbgPrint("Succeeded\n"); + } + /* Go to next string */ + VDDList += wcslen(VDDList) + 1; + } + VDDList = VDDValueName; + +Quit: + if (VDDList) HeapFree(GetProcessHeap(), 0, VDDList); + RegCloseKey(hVDDKey); + return Success; +} + /* PUBLIC FUNCTIONS ***********************************************************/
VOID VDDSupInitialize(VOID) { /* Register the 3rd-party VDD BOP Handler */ RegisterBop(BOP_3RDPARTY, ThirdPartyVDDBop); + + /* Load the installable VDDs from the registry */ + LoadInstallableVDD(); }
/* EOF */