Fix umpnpmgr build
[reactos.git] / reactos / services / umpnpmgr / umpnpmgr.c
index cdeb7a7..9da7d80 100644 (file)
  * 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 <cmtypes.h>
+#include <cmfuncs.h>
+#include <rtlfuncs.h>
+#include <umpnpmgr/sysguid.h>
+#include <wdmguid.h>
+#include <cfgmgr32.h>
 
 #include <rpc.h>
 #include <rpcdce.h>
@@ -57,6 +59,10 @@ static WCHAR szRootDeviceId[] = L"HTREE\\ROOT\\0";
 static HKEY hEnumKey = NULL;
 static HKEY hClassKey = NULL;
 
+static HANDLE hUserToken = NULL;
+static HANDLE hInstallEvent = NULL;
+
+
 /* FUNCTIONS *****************************************************************/
 
 static DWORD WINAPI
@@ -112,6 +118,23 @@ void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
 }
 
 
+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)
@@ -121,6 +144,7 @@ PNP_GetVersion(handle_t BindingHandle,
 }
 
 
+/* Function 3 */
 CONFIGRET
 PNP_GetGlobalState(handle_t BindingHandle,
                    unsigned long *State,
@@ -131,6 +155,52 @@ PNP_GetGlobalState(handle_t BindingHandle,
 }
 
 
+/* 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,
@@ -180,6 +250,7 @@ Done:
 }
 
 
+/* Function 7 */
 CONFIGRET
 PNP_GetRootDeviceInstance(handle_t BindingHandle,
                           wchar_t *DeviceInstance,
@@ -205,6 +276,7 @@ Done:
 }
 
 
+/* Function 8 */
 CONFIGRET
 PNP_GetRelatedDeviceInstance(handle_t BindingHandle,
                              unsigned long Relationship,
@@ -235,8 +307,7 @@ PNP_GetRelatedDeviceInstance(handle_t BindingHandle,
                                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);
@@ -249,6 +320,7 @@ PNP_GetRelatedDeviceInstance(handle_t BindingHandle,
 }
 
 
+/* Function 9 */
 CONFIGRET
 PNP_EnumerateSubKeys(handle_t BindingHandle,
                      unsigned long Branch,
@@ -302,6 +374,23 @@ PNP_EnumerateSubKeys(handle_t BindingHandle,
 }
 
 
+/* 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,
@@ -326,7 +415,7 @@ PNP_GetDepth(handle_t BindingHandle,
     }
     else
     {
-        ret = CR_FAILURE; /* FIXME */
+        ret = NtStatusToCrError(Status);
     }
 
     DPRINT("PNP_GetDepth() done (returns %lx)\n", ret);
@@ -335,118 +424,7 @@ PNP_GetDepth(handle_t BindingHandle,
 }
 
 
-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,
@@ -624,7 +602,7 @@ PNP_GetDeviceRegProp(handle_t BindingHandle,
         }
         else
         {
-            ret = CR_FAILURE; /* FIXME */
+            ret = NtStatusToCrError(Status);
         }
     }
 
@@ -634,6 +612,211 @@ PNP_GetDeviceRegProp(handle_t BindingHandle,
 }
 
 
+/* 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,
@@ -683,6 +866,7 @@ PNP_GetClassName(handle_t BindingHandle,
 }
 
 
+/* Function 20 */
 CONFIGRET
 PNP_DeleteClassKey(handle_t BindingHandle,
                    wchar_t *ClassGuid,
@@ -709,6 +893,62 @@ PNP_DeleteClassKey(handle_t BindingHandle,
 }
 
 
+/* 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,
@@ -736,7 +976,7 @@ PNP_GetDeviceStatus(handle_t BindingHandle,
     }
     else
     {
-        ret = CR_FAILURE; /* FIXME */
+        ret = NtStatusToCrError(Status);
     }
 
     DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret);
@@ -745,6 +985,7 @@ PNP_GetDeviceStatus(handle_t BindingHandle,
 }
 
 
+/* Function 31 */
 CONFIGRET
 PNP_SetDeviceProblem(handle_t BindingHandle,
                      wchar_t *DeviceInstance,
@@ -763,6 +1004,182 @@ PNP_SetDeviceProblem(handle_t BindingHandle,
 }
 
 
+/* 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, &regType, (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)
 {
@@ -770,12 +1187,15 @@ 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");
@@ -803,6 +1223,7 @@ PnpEventThread(LPVOID lpParameter)
         if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
         {
             DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
+            InstallDevice(PnpEvent->TargetDevice.DeviceIds, setupActive);
         }
         else
         {
@@ -858,6 +1279,14 @@ main(int argc, char *argv[])
 
     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,