[UMPNPMGR][USETUP] Use PlugPlayControlStartDevice in usetup and umpnpmgr
[reactos.git] / base / services / umpnpmgr / rpcserver.c
index 313ca1c..cf49713 100644 (file)
@@ -410,6 +410,131 @@ IsRootDeviceInstanceID(
 }
 
 
+static
+CONFIGRET
+OpenConfigurationKey(
+    _In_ LPCWSTR pszDeviceID,
+    _Out_ PHKEY phKey)
+{
+    WCHAR szKeyName[MAX_PATH];
+    HKEY hInstanceKey;
+    DWORD dwError;
+
+    /* Build the full device instance key name */
+    wcscpy(szKeyName, L"System\\CurrentControlSet\\Enum\\");
+    wcscat(szKeyName, pszDeviceID);
+
+    /* Open the device instance key */
+    dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                            szKeyName,
+                            0,
+                            KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY,
+                            &hInstanceKey);
+    if (dwError != ERROR_SUCCESS)
+        return CR_INVALID_DEVINST;
+
+    /* Create or open the LogConf key */
+    dwError = RegCreateKeyExW(hInstanceKey,
+                              L"LogConf",
+                              0,
+                              NULL,
+                              REG_OPTION_NON_VOLATILE,
+                              KEY_ALL_ACCESS,
+                              NULL,
+                              phKey,
+                              NULL);
+
+    /* Close the device instance key */
+    RegCloseKey(hInstanceKey);
+
+    if (dwError != ERROR_SUCCESS)
+        return CR_REGISTRY_ERROR;
+
+    return CR_SUCCESS;
+}
+
+
+static
+CONFIGRET
+GetConfigurationData(
+    _In_ HKEY hKey,
+    _In_ ULONG ulLogConfType,
+    _Out_ PULONG pulRegDataType,
+    _Out_ PULONG pulDataSize,
+    _Out_ LPBYTE *ppBuffer)
+{
+    LPCWSTR pszValueName;
+
+    switch (ulLogConfType)
+    {
+        case BOOT_LOG_CONF:
+            pszValueName = L"BootConfig";
+            *pulRegDataType = REG_RESOURCE_LIST;
+            break;
+
+        case ALLOC_LOG_CONF:
+            pszValueName = L"AllocConfig";
+            *pulRegDataType = REG_RESOURCE_LIST;
+            break;
+
+        case FORCED_LOG_CONF:
+            pszValueName = L"ForcedConfig";
+            *pulRegDataType = REG_RESOURCE_LIST;
+            break;
+
+        case FILTERED_LOG_CONF:
+            pszValueName = L"FilteredConfigVector";
+            *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
+            break;
+
+        case BASIC_LOG_CONF:
+            pszValueName = L"BasicConfigVector";
+            *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
+            break;
+
+        case OVERRIDE_LOG_CONF:
+            pszValueName = L"OverrideConfigVector";
+            *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
+            break;
+
+        default:
+            DPRINT1("Unsupported configuration type!\n");
+            return CR_FAILURE;
+    }
+
+    /* Get the configuration data size */
+    if (RegQueryValueExW(hKey,
+                         pszValueName,
+                         NULL,
+                         NULL,
+                         NULL,
+                         pulDataSize) != ERROR_SUCCESS)
+    {
+        return CR_INVALID_LOG_CONF;
+    }
+
+    /* Allocate the buffer */
+    *ppBuffer = HeapAlloc(GetProcessHeap(), 0, *pulDataSize);
+    if (*ppBuffer == NULL)
+    {
+        return CR_OUT_OF_MEMORY;
+    }
+
+    /* Retrieve the configuration data */
+    if (RegQueryValueExW(hKey,
+                         pszValueName,
+                         NULL,
+                         NULL,
+                         (LPBYTE)*ppBuffer,
+                         pulDataSize) != ERROR_SUCCESS)
+    {
+        return CR_INVALID_LOG_CONF;
+    }
+
+    return CR_SUCCESS;
+}
+
+
 /* PUBLIC FUNCTIONS **********************************************************/
 
 /* Function 0 */
@@ -1678,6 +1803,7 @@ PNP_GetDeviceRegProp(
 
         case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME:
             PlugPlayData.Property = PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME;
+            *pulRegDataType = REG_SZ;
             break;
 
         case CM_DRP_CAPABILITIES:
@@ -1698,18 +1824,22 @@ PNP_GetDeviceRegProp(
 
         case CM_DRP_BUSTYPEGUID:
             PlugPlayData.Property = PNP_PROPERTY_BUSTYPEGUID;
+            *pulRegDataType = REG_BINARY;
             break;
 
         case CM_DRP_LEGACYBUSTYPE:
             PlugPlayData.Property = PNP_PROPERTY_LEGACYBUSTYPE;
+            *pulRegDataType = REG_DWORD;
             break;
 
         case CM_DRP_BUSNUMBER:
             PlugPlayData.Property = PNP_PROPERTY_BUSNUMBER;
+            *pulRegDataType = REG_DWORD;
             break;
 
         case CM_DRP_ENUMERATOR_NAME:
             PlugPlayData.Property = PNP_PROPERTY_ENUMERATOR_NAME;
+            *pulRegDataType = REG_SZ;
             break;
 
         case CM_DRP_SECURITY:
@@ -1730,6 +1860,7 @@ PNP_GetDeviceRegProp(
 
         case CM_DRP_ADDRESS:
             PlugPlayData.Property = PNP_PROPERTY_ADDRESS;
+            *pulRegDataType = REG_DWORD;
             break;
 
         case CM_DRP_UI_NUMBER_DESC_FORMAT:
@@ -1738,33 +1869,40 @@ PNP_GetDeviceRegProp(
 
         case CM_DRP_DEVICE_POWER_DATA:
             PlugPlayData.Property = PNP_PROPERTY_POWER_DATA;
+            *pulRegDataType = REG_BINARY;
             break;
 
         case CM_DRP_REMOVAL_POLICY:
             PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY;
+            *pulRegDataType = REG_DWORD;
             break;
 
         case CM_DRP_REMOVAL_POLICY_HW_DEFAULT:
             PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT;
+            *pulRegDataType = REG_DWORD;
             break;
 
         case CM_DRP_REMOVAL_POLICY_OVERRIDE:
             lpValueName = L"RemovalPolicy";
+            *pulRegDataType = REG_DWORD;
             break;
 
         case CM_DRP_INSTALL_STATE:
             PlugPlayData.Property = PNP_PROPERTY_INSTALL_STATE;
+            *pulRegDataType = REG_DWORD;
             break;
 
 #if (WINVER >= _WIN32_WINNT_WS03)
         case CM_DRP_LOCATION_PATHS:
             PlugPlayData.Property = PNP_PROPERTY_LOCATION_PATHS;
+            *pulRegDataType = REG_MULTI_SZ;
             break;
 #endif
 
 #if (WINVER >= _WIN32_WINNT_WIN7)
         case CM_DRP_BASE_CONTAINERID:
             PlugPlayData.Property = PNP_PROPERTY_CONTAINERID;
+            *pulRegDataType = REG_SZ;
             break;
 #endif
 
@@ -2480,7 +2618,9 @@ PNP_GetClassRegProp(
 
     UNREFERENCED_PARAMETER(hBinding);
 
-    DPRINT("PNP_GetClassRegProp() called\n");
+    DPRINT("PNP_GetClassRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
+           hBinding, pszClassGuid, ulProperty, pulRegDataType,
+           Buffer, pulTransferLen, pulLength, ulFlags);
 
     if (pulTransferLen == NULL || pulLength == NULL)
     {
@@ -2603,7 +2743,9 @@ PNP_SetClassRegProp(
 
     UNREFERENCED_PARAMETER(hBinding);
 
-    DPRINT("PNP_SetClassRegProp() called\n");
+    DPRINT("PNP_SetClassRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
+           hBinding, pszClassGuid, ulProperty, ulDataType,
+           Buffer, ulLength, ulFlags);
 
     if (ulFlags != 0)
         return CR_INVALID_FLAG;
@@ -2939,17 +3081,14 @@ static CONFIGRET
 EnableDeviceInstance(
     _In_ LPWSTR pszDeviceInstance)
 {
-    PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
+    PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData;
     CONFIGRET ret = CR_SUCCESS;
     NTSTATUS Status;
 
     DPRINT("Enable device instance %S\n", pszDeviceInstance);
 
-    RtlInitUnicodeString(&ResetDeviceData.DeviceInstance,
-                         pszDeviceInstance);
-    Status = NtPlugPlayControl(PlugPlayControlResetDevice,
-                               &ResetDeviceData,
-                               sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA));
+    RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceInstance);
+    Status = NtPlugPlayControl(PlugPlayControlStartDevice, &ControlData, sizeof(ControlData));
     if (!NT_SUCCESS(Status))
         ret = NtStatusToCrError(Status);
 
@@ -3325,7 +3464,7 @@ PNP_QueryRemove(
                          pszDeviceID);
     PlugPlayData.VetoName = pszVetoName;
     PlugPlayData.NameLength = ulNameLength;
-//    PlugPlayData.Flags = 
+//    PlugPlayData.Flags =
 
     Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice,
                                &PlugPlayData,
@@ -3373,7 +3512,7 @@ PNP_RequestDeviceEject(
                          pszDeviceID);
     PlugPlayData.VetoName = pszVetoName;
     PlugPlayData.NameLength = ulNameLength;
-//    PlugPlayData.Flags = 
+//    PlugPlayData.Flags =
 
     Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice,
                                &PlugPlayData,
@@ -3732,8 +3871,92 @@ PNP_GetFirstLogConf(
     DWORD *pulLogConfTag,
     DWORD ulFlags)
 {
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
+    HKEY hConfigKey = NULL;
+    DWORD RegDataType = 0;
+    ULONG ulDataSize = 0;
+    LPBYTE lpData = NULL;
+    CONFIGRET ret = CR_SUCCESS;
+
+    DPRINT("PNP_GetFirstLogConf(%p %S %lu %p 0x%08lx)\n",
+           hBinding, pDeviceID, ulLogConfType, pulLogConfTag, ulFlags);
+
+    if (pulLogConfTag == NULL)
+        return CR_INVALID_POINTER;
+
+    *pulLogConfTag = (DWORD)0;
+
+    if (ulFlags & ~LOG_CONF_BITS)
+        return CR_INVALID_FLAG;
+
+    if (!IsValidDeviceInstanceID(pDeviceID))
+        return CR_INVALID_DEVINST;
+
+    ret = OpenConfigurationKey(pDeviceID,
+                               &hConfigKey);
+    if (ret != CR_SUCCESS)
+    {
+        DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    ret = GetConfigurationData(hConfigKey,
+                               ulLogConfType,
+                               &RegDataType,
+                               &ulDataSize,
+                               &lpData);
+    if (ret != CR_SUCCESS)
+    {
+        DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    DPRINT("Data size %lu\n", ulDataSize);
+    if (ulDataSize == 0 || lpData == NULL)
+    {
+        DPRINT1("No config data available!\n");
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    /* Get the first tag */
+    if (RegDataType == REG_RESOURCE_LIST)
+    {
+        DPRINT("REG_RESOURCE_LIST\n");
+
+        DPRINT("ResourceList->Count %lu\n", ((PCM_RESOURCE_LIST)lpData)->Count);
+        if (((PCM_RESOURCE_LIST)lpData)->Count == 0)
+        {
+            DPRINT1("No resource descriptors!\n");
+            ret = CR_NO_MORE_LOG_CONF;
+            goto done;
+        }
+
+        DPRINT("lpData %p\n", lpData);
+        DPRINT("&List[0] %p\n", &(((PCM_RESOURCE_LIST)lpData)->List[0]));
+
+        *pulLogConfTag = (DWORD)((DWORD_PTR)&(((PCM_RESOURCE_LIST)lpData)->List[0]) - (DWORD_PTR)lpData);
+        DPRINT("Offset (Tag): 0x%08lx\n", *pulLogConfTag);
+    }
+    else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
+    {
+        DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
+        /* FIXME */
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+done:
+    if (lpData != NULL)
+        HeapFree(GetProcessHeap(), 0, lpData);
+
+    if (hConfigKey != NULL)
+        RegCloseKey(hConfigKey);
+
+    DPRINT("PNP_GetFirstLogConf() returns %lu\n", ret);
+
+    return ret;
 }
 
 
@@ -3748,8 +3971,82 @@ PNP_GetNextLogConf(
     DWORD *pulNextTag,
     DWORD ulFlags)
 {
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
+    HKEY hConfigKey = NULL;
+    DWORD RegDataType = 0;
+    ULONG ulDataSize = 0;
+    LPBYTE lpData = NULL;
+    CONFIGRET ret = CR_SUCCESS;
+
+    DPRINT("PNP_GetNextLogConf(%p %S %lu %ul %p 0x%08lx)\n",
+           hBinding, pDeviceID, ulLogConfType, ulCurrentTag, pulNextTag, ulFlags);
+
+    if (pulNextTag == NULL)
+        return CR_INVALID_POINTER;
+
+    *pulNextTag = (DWORD)0;
+
+    if (ulFlags != 0)
+        return CR_INVALID_FLAG;
+
+    if (!IsValidDeviceInstanceID(pDeviceID))
+        return CR_INVALID_DEVINST;
+
+    ret = OpenConfigurationKey(pDeviceID,
+                               &hConfigKey);
+    if (ret != CR_SUCCESS)
+    {
+        DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    ret = GetConfigurationData(hConfigKey,
+                               ulLogConfType,
+                               &RegDataType,
+                               &ulDataSize,
+                               &lpData);
+    if (ret != CR_SUCCESS)
+    {
+        DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    DPRINT("Data size %lu\n", ulDataSize);
+
+    if (ulDataSize == 0 || lpData == NULL)
+    {
+        DPRINT1("No config data available!\n");
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    /* FIXME: Get the next tag */
+    if (RegDataType == REG_RESOURCE_LIST)
+    {
+        DPRINT1("FIXME: REG_RESOURCE_LIST\n");
+        /* FIXME */
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+    else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
+    {
+        DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
+        /* FIXME */
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+done:
+    if (lpData != NULL)
+        HeapFree(GetProcessHeap(), 0, lpData);
+
+    if (hConfigKey != NULL)
+        RegCloseKey(hConfigKey);
+
+    DPRINT("PNP_GetNextLogConf() returns %lu\n", ret);
+
+    return ret;
 }
 
 
@@ -3821,8 +4118,83 @@ PNP_GetNextResDes(
     DWORD *pulNextResTag,
     DWORD ulFlags)
 {
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
+    HKEY hConfigKey = NULL;
+    DWORD RegDataType = 0;
+    ULONG ulDataSize = 0;
+    LPBYTE lpData = NULL;
+    CONFIGRET ret = CR_SUCCESS;
+
+    DPRINT1("PNP_GetNextResDes(%p %S 0x%lx %lu %lu %ul %p %p 0x%08lx)\n",
+           hBinding, pDeviceID, ulLogConfTag, ulLogConfType, ResourceID,
+           ulResourceTag, pulNextResType, pulNextResTag, ulFlags);
+
+    if (pulNextResType == NULL)
+        return CR_INVALID_POINTER;
+
+    *pulNextResType = 0;
+
+    if (ulFlags != 0)
+        return CR_INVALID_FLAG;
+
+    if (!IsValidDeviceInstanceID(pDeviceID))
+        return CR_INVALID_DEVINST;
+
+    ret = OpenConfigurationKey(pDeviceID,
+                               &hConfigKey);
+    if (ret != CR_SUCCESS)
+    {
+        DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    ret = GetConfigurationData(hConfigKey,
+                               ulLogConfType,
+                               &RegDataType,
+                               &ulDataSize,
+                               &lpData);
+    if (ret != CR_SUCCESS)
+    {
+        DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    DPRINT1("Data size %lu\n", ulDataSize);
+
+    if (ulDataSize == 0 || lpData == NULL)
+    {
+        DPRINT1("No config data available!\n");
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+    /* Get the next resource descriptor */
+    if (RegDataType == REG_RESOURCE_LIST)
+    {
+        DPRINT1("FIXME: REG_RESOURCE_LIST\n");
+        /* FIXME */
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+    else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
+    {
+        DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
+        /* FIXME */
+        ret = CR_NO_MORE_LOG_CONF;
+        goto done;
+    }
+
+done:
+    if (lpData != NULL)
+        HeapFree(GetProcessHeap(), 0, lpData);
+
+    if (hConfigKey != NULL)
+        RegCloseKey(hConfigKey);
+
+    DPRINT1("PNP_GetNextResDes() returns %lu\n", ret);
+
+    return ret;
 }