mirror of
https://github.com/reactos/reactos.git
synced 2024-11-18 13:01:40 +00:00
[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). svn path=/branches/ntvdm/; revision=61370
This commit is contained in:
parent
5005df3ef3
commit
f29962099c
1 changed files with 112 additions and 13 deletions
|
@ -16,6 +16,8 @@
|
||||||
#include "bop.h"
|
#include "bop.h"
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
|
|
||||||
|
#include <isvbop.h>
|
||||||
|
|
||||||
typedef VOID (WINAPI *VDD_PROC)(VOID);
|
typedef VOID (WINAPI *VDD_PROC)(VOID);
|
||||||
|
|
||||||
typedef struct _VDD_MODULE
|
typedef struct _VDD_MODULE
|
||||||
|
@ -24,13 +26,10 @@ typedef struct _VDD_MODULE
|
||||||
VDD_PROC DispatchRoutine;
|
VDD_PROC DispatchRoutine;
|
||||||
} VDD_MODULE, *PVDD_MODULE;
|
} VDD_MODULE, *PVDD_MODULE;
|
||||||
|
|
||||||
/* BOP Identifiers */
|
|
||||||
#define BOP_3RDPARTY 0x58 // 3rd-party VDD BOP
|
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
// TODO: Maybe use a linked list.
|
// 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
|
#define MAX_VDD_MODULES 0xFF + 1
|
||||||
VDD_MODULE VDDList[MAX_VDD_MODULES] = {{NULL}};
|
VDD_MODULE VDDList[MAX_VDD_MODULES] = {{NULL}};
|
||||||
|
|
||||||
|
@ -77,11 +76,21 @@ VOID WINAPI ThirdPartyVDDBop(LPWORD Stack)
|
||||||
/* Clear the Carry Flag (no error happened so far) */
|
/* Clear the Carry Flag (no error happened so far) */
|
||||||
setCF(0);
|
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 */
|
/* Retrieve the VDD name in DS:SI */
|
||||||
DllName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI());
|
DllName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI());
|
||||||
|
|
||||||
/* Retrieve the initialization routine API name in ES:DI (optional --> ES=DI=0) */
|
/* 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());
|
InitRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getES(), getDI());
|
||||||
|
|
||||||
/* Retrieve the dispatch routine API name in DS:BX */
|
/* Retrieve the dispatch routine API name in DS:BX */
|
||||||
|
@ -139,14 +148,6 @@ VOID WINAPI ThirdPartyVDDBop(LPWORD Stack)
|
||||||
/* If we arrived there, that means everything is OK */
|
/* If we arrived there, that means everything is OK */
|
||||||
|
|
||||||
/* Register the VDD DLL */
|
/* 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].hDll = hDll;
|
||||||
VDDList[Entry].DispatchRoutine = DispatchRoutine;
|
VDDList[Entry].DispatchRoutine = DispatchRoutine;
|
||||||
|
|
||||||
|
@ -232,12 +233,110 @@ Quit:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
VOID VDDSupInitialize(VOID)
|
VOID VDDSupInitialize(VOID)
|
||||||
{
|
{
|
||||||
/* Register the 3rd-party VDD BOP Handler */
|
/* Register the 3rd-party VDD BOP Handler */
|
||||||
RegisterBop(BOP_3RDPARTY, ThirdPartyVDDBop);
|
RegisterBop(BOP_3RDPARTY, ThirdPartyVDDBop);
|
||||||
|
|
||||||
|
/* Load the installable VDDs from the registry */
|
||||||
|
LoadInstallableVDD();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue