* FILE: services/umpnpmgr/umpnpmgr.c
* PURPOSE: User-mode Plug and Play manager
* PROGRAMMER: Eric Kohl
+ * Hervé Poussineau (hpoussin@reactos.org)
*/
/* INCLUDES *****************************************************************/
-
+#define WIN32_NO_STATUS
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
-#include <ndk/sysguid.h>
-#include <ddk/wdmguid.h>
-#include <ddk/cfgmgr32.h>
+#include <umpnpmgr/sysguid.h>
+#include <wdmguid.h>
+#include <cfgmgr32.h>
#include <rpc.h>
#include <rpcdce.h>
static HKEY hEnumKey = NULL;
static HKEY hClassKey = NULL;
+static HANDLE hUserToken = NULL;
+static HANDLE hInstallEvent = NULL;
+
+
/* FUNCTIONS *****************************************************************/
static DWORD WINAPI
}
+static CONFIGRET WINAPI
+NtStatusToCrError(NTSTATUS Status)
+{
+ switch (Status)
+ {
+ case STATUS_NO_SUCH_DEVICE:
+ return CR_NO_SUCH_DEVINST;
+
+ default:
+ /* FIXME: add more mappings */
+ DPRINT1("Unable to map status 0x%08lx\n", Status);
+ return CR_FAILURE;
+ }
+}
+
+
+/* Function 2 */
CONFIGRET
PNP_GetVersion(handle_t BindingHandle,
unsigned short *Version)
}
+/* Function 3 */
CONFIGRET
PNP_GetGlobalState(handle_t BindingHandle,
unsigned long *State,
}
+/* Function 4 */
+CONFIGRET
+PNP_InitDetection(handle_t BindingHandle)
+{
+ DPRINT("PNP_InitDetection() called\n");
+ return CR_SUCCESS;
+}
+
+
+/* Function 5 */
+CONFIGRET
+PNP_ReportLogOn(handle_t BindingHandle,
+ unsigned long Admin,
+ unsigned long ProcessId)
+{
+ HANDLE hProcess;
+
+ DPRINT1("PNP_ReportLogOn(%lu, %lu) called\n", Admin, ProcessId);
+
+ /* Get the users token */
+ hProcess = OpenProcess(PROCESS_ALL_ACCESS,
+ TRUE,
+ ProcessId);
+ if (hProcess != NULL)
+ {
+ if (hUserToken != NULL)
+ {
+ CloseHandle(hUserToken);
+ hUserToken = NULL;
+ }
+
+ OpenProcessToken(hProcess,
+ TOKEN_ALL_ACCESS,
+ &hUserToken);
+ CloseHandle(hProcess);
+ }
+
+ /* Trigger the installer thread */
+ if (hInstallEvent != NULL)
+ SetEvent(hInstallEvent);
+
+ return CR_SUCCESS;
+}
+
+
+/* Function 6 */
CONFIGRET
PNP_ValidateDeviceInstance(handle_t BindingHandle,
wchar_t *DeviceInstance,
}
+/* Function 7 */
CONFIGRET
PNP_GetRootDeviceInstance(handle_t BindingHandle,
wchar_t *DeviceInstance,
}
+/* Function 8 */
CONFIGRET
PNP_GetRelatedDeviceInstance(handle_t BindingHandle,
unsigned long Relationship,
sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA));
if (!NT_SUCCESS(Status))
{
- /* FIXME: Map Status to ret */
- ret = CR_FAILURE;
+ ret = NtStatusToCrError(Status);
}
DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret);
}
+/* Function 9 */
CONFIGRET
PNP_EnumerateSubKeys(handle_t BindingHandle,
unsigned long Branch,
HKEY hKey;
DWORD dwError;
- DPRINT1("PNP_EnumerateSubKeys() called\n");
+ DPRINT("PNP_EnumerateSubKeys() called\n");
switch (Branch)
{
- case 1:
+ case PNP_BRANCH_ENUM:
hKey = hEnumKey;
break;
- case 2:
+ case PNP_BRANCH_CLASS:
hKey = hClassKey;
break;
NULL);
if (dwError != ERROR_SUCCESS)
{
- ret = CR_FAILURE;
+ ret = (dwError == ERROR_NO_MORE_ITEMS) ? CR_NO_SUCH_VALUE : CR_FAILURE;
}
-
- DPRINT1("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
- if (ret == CR_SUCCESS)
+ else
{
- DPRINT1("Sub key: %S\n", Buffer);
+ (*RequiredLength)++;
}
+ DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
+
return ret;
}
+/* Function 11 */
+CONFIGRET
+PNP_GetDeviceListSize(handle_t BindingHandle,
+ wchar_t *Filter,
+ unsigned long *Length,
+ DWORD Flags)
+{
+ DPRINT("PNP_GetDeviceListSize() called\n");
+
+ /* FIXME */
+ *Length = 2;
+
+ return CR_SUCCESS;
+}
+
+
+/* Function 12 */
CONFIGRET
PNP_GetDepth(handle_t BindingHandle,
wchar_t *DeviceInstance,
}
else
{
- ret = CR_FAILURE; /* FIXME */
+ ret = NtStatusToCrError(Status);
}
DPRINT("PNP_GetDepth() done (returns %lx)\n", ret);
}
-CONFIGRET
-PNP_SetDeviceRegProp(handle_t BindingHandle,
- wchar_t *DeviceId,
- unsigned long Property,
- unsigned long DataType,
- char *Buffer,
- unsigned long Length,
- unsigned long Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
- LPWSTR lpValueName = NULL;
- HKEY hKey = 0;
-
- DPRINT("PNP_SetDeviceRegProp() called\n");
-
- DPRINT("DeviceId: %S\n", DeviceId);
- DPRINT("Property: %lu\n", Property);
- DPRINT("DataType: %lu\n", DataType);
- DPRINT("Length: %lu\n", Length);
-
- switch (Property)
- {
- case CM_DRP_DEVICEDESC:
- lpValueName = L"DeviceDesc";
- break;
-
- case CM_DRP_HARDWAREID:
- lpValueName = L"HardwareID";
- break;
-
- case CM_DRP_COMPATIBLEIDS:
- lpValueName = L"CompatibleIDs";
- break;
-
- case CM_DRP_SERVICE:
- lpValueName = L"Service";
- break;
-
- case CM_DRP_CLASS:
- lpValueName = L"Class";
- break;
-
- case CM_DRP_CLASSGUID:
- lpValueName = L"ClassGUID";
- break;
-
- case CM_DRP_DRIVER:
- lpValueName = L"Driver";
- break;
-
- case CM_DRP_CONFIGFLAGS:
- lpValueName = L"ConfigFlags";
- break;
-
- case CM_DRP_MFG:
- lpValueName = L"Mfg";
- break;
-
- case CM_DRP_FRIENDLYNAME:
- lpValueName = L"FriendlyName";
- break;
-
- case CM_DRP_LOCATION_INFORMATION:
- lpValueName = L"LocationInformation";
- break;
-
- case CM_DRP_UPPERFILTERS:
- lpValueName = L"UpperFilters";
- break;
-
- case CM_DRP_LOWERFILTERS:
- lpValueName = L"LowerFilters";
- break;
-
- default:
- return CR_INVALID_PROPERTY;
- }
-
- DPRINT("Value name: %S\n", lpValueName);
-
- if (RegOpenKeyExW(hEnumKey,
- DeviceId,
- 0,
- KEY_ALL_ACCESS,
- &hKey))
- return CR_INVALID_DEVNODE;
-
- if (Length == 0)
- {
- if (RegDeleteValueW(hKey,
- lpValueName))
- ret = CR_REGISTRY_ERROR;
- }
- else
- {
- if (RegSetValueExW(hKey,
- lpValueName,
- 0,
- DataType,
- (const BYTE*)Buffer,
- Length))
- ret = CR_REGISTRY_ERROR;
- }
-
- RegCloseKey(hKey);
-
- DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
+/* Function 13 */
CONFIGRET
PNP_GetDeviceRegProp(handle_t BindingHandle,
wchar_t *DeviceInstance,
}
else
{
- ret = CR_FAILURE; /* FIXME */
+ ret = NtStatusToCrError(Status);
}
}
}
+/* Function 14 */
+CONFIGRET
+PNP_SetDeviceRegProp(handle_t BindingHandle,
+ wchar_t *DeviceId,
+ unsigned long Property,
+ unsigned long DataType,
+ char *Buffer,
+ unsigned long Length,
+ unsigned long Flags)
+{
+ CONFIGRET ret = CR_SUCCESS;
+ LPWSTR lpValueName = NULL;
+ HKEY hKey = 0;
+
+ DPRINT("PNP_SetDeviceRegProp() called\n");
+
+ DPRINT("DeviceId: %S\n", DeviceId);
+ DPRINT("Property: %lu\n", Property);
+ DPRINT("DataType: %lu\n", DataType);
+ DPRINT("Length: %lu\n", Length);
+
+ switch (Property)
+ {
+ case CM_DRP_DEVICEDESC:
+ lpValueName = L"DeviceDesc";
+ break;
+
+ case CM_DRP_HARDWAREID:
+ lpValueName = L"HardwareID";
+ break;
+
+ case CM_DRP_COMPATIBLEIDS:
+ lpValueName = L"CompatibleIDs";
+ break;
+
+ case CM_DRP_SERVICE:
+ lpValueName = L"Service";
+ break;
+
+ case CM_DRP_CLASS:
+ lpValueName = L"Class";
+ break;
+
+ case CM_DRP_CLASSGUID:
+ lpValueName = L"ClassGUID";
+ break;
+
+ case CM_DRP_DRIVER:
+ lpValueName = L"Driver";
+ break;
+
+ case CM_DRP_CONFIGFLAGS:
+ lpValueName = L"ConfigFlags";
+ break;
+
+ case CM_DRP_MFG:
+ lpValueName = L"Mfg";
+ break;
+
+ case CM_DRP_FRIENDLYNAME:
+ lpValueName = L"FriendlyName";
+ break;
+
+ case CM_DRP_LOCATION_INFORMATION:
+ lpValueName = L"LocationInformation";
+ break;
+
+ case CM_DRP_UPPERFILTERS:
+ lpValueName = L"UpperFilters";
+ break;
+
+ case CM_DRP_LOWERFILTERS:
+ lpValueName = L"LowerFilters";
+ break;
+
+ default:
+ return CR_INVALID_PROPERTY;
+ }
+
+ DPRINT("Value name: %S\n", lpValueName);
+
+ if (RegOpenKeyExW(hEnumKey,
+ DeviceId,
+ 0,
+ KEY_ALL_ACCESS,
+ &hKey))
+ return CR_INVALID_DEVNODE;
+
+ if (Length == 0)
+ {
+ if (RegDeleteValueW(hKey,
+ lpValueName))
+ ret = CR_REGISTRY_ERROR;
+ }
+ else
+ {
+ if (RegSetValueExW(hKey,
+ lpValueName,
+ 0,
+ DataType,
+ (const BYTE*)Buffer,
+ Length))
+ ret = CR_REGISTRY_ERROR;
+ }
+
+ RegCloseKey(hKey);
+
+ DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 15 */
+CONFIGRET
+PNP_GetClassInstance(handle_t BindingHandle,
+ wchar_t *DeviceId, /* in */
+ wchar_t *Buffer, /* out */
+ unsigned long Length)
+{
+ CONFIGRET ret = CR_SUCCESS;
+
+ DPRINT("PNP_Get_Class_Instance() called\n");
+
+ DPRINT("PNP_Get_Class_Instance() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 16 */
+CONFIGRET
+PNP_CreateKey(handle_t BindingHandle,
+ wchar_t *SubKey,
+ unsigned long samDesired,
+ unsigned long Flags)
+{
+ CONFIGRET ret = CR_SUCCESS;
+
+ DPRINT("PNP_CreateKey() called\n");
+
+ DPRINT("PNP_CreateKey() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 17 */
+CONFIGRET
+PNP_DeleteRegistryKey(handle_t BindingHandle,
+ wchar_t *DeviceId,
+ wchar_t *ParentKey,
+ wchar_t *ChildKey,
+ unsigned long Flags)
+{
+ CONFIGRET ret = CR_SUCCESS;
+
+ DPRINT("PNP_DeleteRegistryKey() called\n");
+
+ DPRINT("PNP_DeleteRegistryKey() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 18 */
+#if 0
+CONFIGRET
+PNP_GetClassCount(handle_t BindingHandle,
+ unsigned long *ClassCount,
+ unsigned long Flags)
+{
+ HANDLE hKey = NULL;
+ DWORD dwError;
+
+ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ pszRegPathClass,
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey);
+ if (dwError != ERROR_SUCCESS)
+ return CR_INVALID_DATA;
+
+ dwError = RegQueryInfoKeyW(hKey,
+ NULL,
+ NULL,
+ NULL,
+ &ClassCount,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ RegCloseKey(hKey);
+ if (dwError != ERROR_SUCCESS)
+ return CR_INVALID_DATA;
+
+ return CR_SUCCESS;
+}
+#endif
+
+
+/* Function 19 */
CONFIGRET
PNP_GetClassName(handle_t BindingHandle,
- wchar_t *ClassGuid, /* in */
- wchar_t *Buffer, /* out */
- unsigned long *Length, /* in out */
+ wchar_t *ClassGuid,
+ wchar_t *Buffer,
+ unsigned long *Length,
unsigned long Flags)
{
WCHAR szKeyName[MAX_PATH];
HKEY hKey = NULL;
ULONG ulSize;
- DPRINT1("PNP_GetClassName() called\n");
+ DPRINT("PNP_GetClassName() called\n");
lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class");
lstrcatW(szKeyName, L"\\");
RegCloseKey(hKey);
- DPRINT1("PNP_GetClassName() done (returns %lx)\n", ret);
+ DPRINT("PNP_GetClassName() done (returns %lx)\n", ret);
return ret;
}
+/* Function 20 */
+CONFIGRET
+PNP_DeleteClassKey(handle_t BindingHandle,
+ wchar_t *ClassGuid,
+ unsigned long Flags)
+{
+ CONFIGRET ret = CR_SUCCESS;
+
+ DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid, Flags);
+
+ if (Flags & CM_DELETE_CLASS_SUBKEYS)
+ {
+ if (RegDeleteTreeW(hClassKey, ClassGuid) != ERROR_SUCCESS)
+ ret = CR_REGISTRY_ERROR;
+ }
+ else
+ {
+ if (RegDeleteKeyW(hClassKey, ClassGuid) != ERROR_SUCCESS)
+ ret = CR_REGISTRY_ERROR;
+ }
+
+ DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 29 */
+CONFIGRET
+PNP_DeviceInstanceAction(handle_t BindingHandle,
+ unsigned long MajorAction,
+ unsigned long MinorAction,
+ wchar_t *DeviceInstance1,
+ wchar_t *DeviceInstance2)
+{
+ CONFIGRET ret = CR_SUCCESS;
+
+ DPRINT("PNP_DeviceInstanceAction() called\n");
+
+ switch (MajorAction)
+ {
+ case 2:
+ DPRINT("Move device instance\n");
+ /* FIXME */
+ ret = CR_CALL_NOT_IMPLEMENTED;
+ break;
+
+ case 3:
+ DPRINT("Setup device instance\n");
+ /* FIXME */
+ ret = CR_CALL_NOT_IMPLEMENTED;
+ break;
+
+ case 4:
+ DPRINT("Enable device instance\n");
+ /* FIXME */
+ ret = CR_CALL_NOT_IMPLEMENTED;
+ break;
+
+ case 5:
+ DPRINT("Disable device instance\n");
+ /* FIXME */
+ ret = CR_CALL_NOT_IMPLEMENTED;
+ break;
+
+ case 7:
+ DPRINT("Reenumerate device instance\n");
+ /* FIXME */
+ ret = CR_CALL_NOT_IMPLEMENTED;
+ break;
+
+ default:
+ DPRINT1("Unknown function %lu\n", MajorAction);
+ ret = CR_CALL_NOT_IMPLEMENTED;
+ }
+
+ DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 30 */
CONFIGRET
PNP_GetDeviceStatus(handle_t BindingHandle,
wchar_t *DeviceInstance,
}
else
{
- ret = CR_FAILURE; /* FIXME */
+ ret = NtStatusToCrError(Status);
}
DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret);
}
+/* Function 31 */
CONFIGRET
PNP_SetDeviceProblem(handle_t BindingHandle,
wchar_t *DeviceInstance,
}
+/* Function 33 */
+CONFIGRET
+PNP_UninstallDevInst(handle_t BindingHandle,
+ wchar_t *DeviceInstance,
+ DWORD Flags)
+{
+ CONFIGRET ret = CR_SUCCESS;
+
+ DPRINT1("PNP_UninstallDevInst() called\n");
+
+ /* FIXME */
+
+ DPRINT1("PNP_UninstallDevInst() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 38 */
+CONFIGRET
+PNP_IsDockStationPresent(handle_t BindingHandle,
+ unsigned long *Present)
+{
+ HKEY hKey;
+ DWORD dwType;
+ DWORD dwValue;
+ DWORD dwSize;
+ CONFIGRET ret = CR_SUCCESS;
+
+ DPRINT1("PNP_IsDockStationPresent() called\n");
+
+ *Present = FALSE;
+
+ if (RegOpenKeyExW(HKEY_CURRENT_CONFIG,
+ L"CurrentDockInfo",
+ 0,
+ KEY_READ,
+ &hKey) != ERROR_SUCCESS)
+ return CR_REGISTRY_ERROR;
+
+ dwSize = sizeof(DWORD);
+ if (RegQueryValueExW(hKey,
+ L"DockingState",
+ NULL,
+ &dwType,
+ (LPBYTE)&dwValue,
+ &dwSize) != ERROR_SUCCESS)
+ ret = CR_REGISTRY_ERROR;
+
+ RegCloseKey(hKey);
+
+ if (ret == CR_SUCCESS)
+ {
+ if (dwType != REG_DWORD || dwSize != sizeof(DWORD))
+ {
+ ret = CR_REGISTRY_ERROR;
+ }
+ else if (dwValue != 0)
+ {
+ *Present = TRUE;
+ }
+ }
+
+ DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 39 */
+CONFIGRET
+PNP_RequestEjectPC(handle_t BindingHandle)
+{
+ CONFIGRET ret = CR_SUCCESS;
+
+ DPRINT1("PNP_RequestEjectPC() called\n");
+
+ ret = CR_FAILURE; /* FIXME */
+
+ DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret);
+
+ return ret;
+}
+
+
+/* Function 58 */
+CONFIGRET
+PNP_RunDetection(handle_t BindingHandle,
+ unsigned long Flags)
+{
+ DPRINT("PNP_RunDetection() called\n");
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+typedef BOOL (WINAPI *PDEV_INSTALL_W)(HWND, HINSTANCE, LPCWSTR, INT);
+
+static BOOL
+InstallDevice(PCWSTR DeviceInstance, BOOL SetupIsActive)
+{
+ PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
+ HMODULE hNewDev = NULL;
+ PDEV_INSTALL_W DevInstallW;
+ NTSTATUS Status;
+ BOOL DeviceInstalled = FALSE;
+
+ RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
+ DeviceInstance);
+ PlugPlayData.Operation = 0; /* Get status */
+
+ /* Get device status */
+ Status = NtPlugPlayControl(PlugPlayControlDeviceStatus,
+ (PVOID)&PlugPlayData,
+ sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
+ if (!NT_SUCCESS(Status))
+ return FALSE;
+
+ if (PlugPlayData.DeviceStatus & DNF_STARTED || PlugPlayData.DeviceStatus & DNF_START_FAILED)
+ /* Device is already started, or disabled due to some problem. Don't install it */
+ return TRUE;
+
+ /* Install device */
+ SetEnvironmentVariable(L"USERPROFILE", L"."); /* FIXME: why is it needed? */
+
+ hNewDev = LoadLibraryW(L"newdev.dll");
+ if (!hNewDev)
+ goto cleanup;
+
+ DevInstallW = (PDEV_INSTALL_W)GetProcAddress(hNewDev, (LPCSTR)"DevInstallW");
+ if (!DevInstallW)
+ goto cleanup;
+
+ if (!DevInstallW(NULL, NULL, DeviceInstance, SetupIsActive ? SW_HIDE : SW_SHOWNOACTIVATE))
+ goto cleanup;
+
+ DeviceInstalled = TRUE;
+
+cleanup:
+ if (hNewDev != NULL)
+ FreeLibrary(hNewDev);
+
+ return DeviceInstalled;
+}
+
+
+static BOOL
+SetupIsActive(VOID)
+{
+ HKEY hKey = INVALID_HANDLE_VALUE;
+ DWORD regType, active, size;
+ LONG rc;
+ BOOL ret = FALSE;
+
+ rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_QUERY_VALUE, &hKey);
+ if (rc != ERROR_SUCCESS)
+ goto cleanup;
+
+ size = sizeof(DWORD);
+ rc = RegQueryValueExW(hKey, L"SystemSetupInProgress", NULL, ®Type, (LPBYTE)&active, &size);
+ if (rc != ERROR_SUCCESS)
+ goto cleanup;
+ if (regType != REG_DWORD || size != sizeof(DWORD))
+ goto cleanup;
+
+ ret = (active != 0);
+
+cleanup:
+ if (hKey != INVALID_HANDLE_VALUE)
+ RegCloseKey(hKey);
+
+ DPRINT("System setup in progress? %S\n", ret ? L"YES" : L"NO");
+
+ return ret;
+}
+
+
static DWORD WINAPI
PnpEventThread(LPVOID lpParameter)
{
ULONG PnpEventSize;
NTSTATUS Status;
RPC_STATUS RpcStatus;
+ BOOL setupActive;
PnpEventSize = 0x1000;
PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
if (PnpEvent == NULL)
return ERROR_OUTOFMEMORY;
+ setupActive = SetupIsActive();
+
for (;;)
{
DPRINT("Calling NtGetPlugPlayEvent()\n");
if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
{
DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
+ InstallDevice(PnpEvent->TargetDevice.DeviceIds, setupActive);
}
else
{
DPRINT("Umpnpmgr: main() started\n");
+ hInstallEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (hInstallEvent == NULL)
+ {
+ dwError = GetLastError();
+ DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError);
+ return dwError;
+ }
+
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Enum",
0,