+static
+ULONG
+GetRegistryPropertyType(
+ _In_ ULONG ulProperty)
+{
+ switch (ulProperty)
+ {
+ case CM_DRP_DEVICEDESC:
+ case CM_DRP_SERVICE:
+ case CM_DRP_CLASS:
+ case CM_DRP_CLASSGUID:
+ case CM_DRP_DRIVER:
+ case CM_DRP_MFG:
+ case CM_DRP_FRIENDLYNAME:
+ case CM_DRP_LOCATION_INFORMATION:
+ case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME:
+ case CM_DRP_ENUMERATOR_NAME:
+ case CM_DRP_SECURITY_SDS:
+ case CM_DRP_UI_NUMBER_DESC_FORMAT:
+ return REG_SZ;
+
+ case CM_DRP_HARDWAREID:
+ case CM_DRP_COMPATIBLEIDS:
+ case CM_DRP_UPPERFILTERS:
+ case CM_DRP_LOWERFILTERS:
+ return REG_MULTI_SZ;
+
+ case CM_DRP_CONFIGFLAGS:
+ case CM_DRP_CAPABILITIES:
+ case CM_DRP_UI_NUMBER:
+ case CM_DRP_LEGACYBUSTYPE:
+ case CM_DRP_BUSNUMBER:
+ case CM_DRP_DEVTYPE:
+ case CM_DRP_EXCLUSIVE:
+ case CM_DRP_CHARACTERISTICS:
+ case CM_DRP_ADDRESS:
+ case CM_DRP_REMOVAL_POLICY:
+ case CM_DRP_REMOVAL_POLICY_HW_DEFAULT:
+ case CM_DRP_REMOVAL_POLICY_OVERRIDE:
+ case CM_DRP_INSTALL_STATE:
+ return REG_DWORD;
+
+ case CM_DRP_BUSTYPEGUID:
+ case CM_DRP_SECURITY:
+ case CM_DRP_DEVICE_POWER_DATA:
+ default:
+ return REG_BINARY;
+ }
+
+ return REG_NONE;
+}
+
+
+static
+VOID
+SplitDeviceInstanceId(
+ _In_ PWSTR pszDeviceInstanceId,
+ _Out_ PWSTR pszDeviceId,
+ _Out_ PWSTR pszInstanceId)
+{
+ PWCHAR ptr;
+
+ wcscpy(pszDeviceId, pszDeviceInstanceId);
+
+ ptr = wcschr(pszDeviceId, L'\\');
+ if (ptr != NULL)
+ {
+ *ptr = UNICODE_NULL;
+ ptr++;
+
+ wcscpy(pszInstanceId, ptr);
+ }
+ else
+ {
+ *pszInstanceId = UNICODE_NULL;
+ }
+}
+
+
+static
+CONFIGRET
+GetDeviceInstanceKeyPath(
+ _In_ RPC_BINDING_HANDLE BindingHandle,
+ _In_ PWSTR pszDeviceInst,
+ _Out_ PWSTR pszKeyPath,
+ _Out_ PWSTR pszInstancePath,
+ _In_ ULONG ulHardwareProfile,
+ _In_ ULONG ulFlags)
+{
+ PWSTR pszBuffer = NULL;
+ ULONG ulType = 0;
+ ULONG ulTransferLength, ulLength;
+ CONFIGRET ret = CR_SUCCESS;
+
+ TRACE("GetDeviceInstanceKeyPath()\n");
+
+ /* Allocate a buffer for the device id */
+ pszBuffer = MyMalloc(300 * sizeof(WCHAR));
+ if (pszBuffer == NULL)
+ {
+ ERR("MyMalloc() failed\n");
+ return CR_OUT_OF_MEMORY;
+ }
+
+ if (ulFlags & CM_REGISTRY_SOFTWARE)
+ {
+ /* Software Key Path */
+
+ if (ulFlags & CM_REGISTRY_CONFIG)
+ {
+ SplitDeviceInstanceId(pszDeviceInst,
+ pszBuffer,
+ pszInstancePath);
+
+ if (ulHardwareProfile == 0)
+ {
+ wsprintfW(pszKeyPath,
+ L"%s\\%s\\%s\\%s",
+ L"System\\CurrentControlSet\\Hardware Profiles",
+ L"Current",
+ L"System\\CurrentControlSet\\Enum",
+ pszBuffer);
+ }
+ else
+ {
+ wsprintfW(pszKeyPath,
+ L"%s\\%04lu\\%s\\%s",
+ L"System\\CurrentControlSet\\Hardware Profiles",
+ ulHardwareProfile,
+ L"System\\CurrentControlSet\\Enum",
+ pszBuffer);
+ }
+ }
+ else if (ulFlags & CM_REGISTRY_USER)
+ {
+ wsprintfW(pszKeyPath,
+ L"%s\\%s",
+ L"System\\CurrentControlSet\\Enum",
+ pszDeviceInst);
+
+ wcscpy(pszInstancePath,
+ L"Device Parameters");
+ }
+ else
+ {
+ SplitDeviceInstanceId(pszDeviceInst,
+ pszBuffer,
+ pszInstancePath);
+
+ wsprintfW(pszKeyPath,
+ L"%s\\%s",
+ L"System\\CurrentControlSet\\Enum",
+ pszBuffer);
+ }
+ }
+ else
+ {
+ /* Hardware Key Path */
+
+ ulTransferLength = 300 * sizeof(WCHAR);
+ ulLength = 300 * sizeof(WCHAR);
+ ret = PNP_GetDeviceRegProp(BindingHandle,
+ pszDeviceInst,
+ CM_DRP_DRIVER,
+ &ulType,
+ (PVOID)pszBuffer,
+ &ulTransferLength,
+ &ulLength,
+ 0);
+ if (ret != CR_SUCCESS)
+ {
+ ERR("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret);
+ goto done;
+ }
+
+ TRACE("szBuffer: %S\n", pszBuffer);
+
+ SplitDeviceInstanceId(pszBuffer,
+ pszBuffer,
+ pszInstancePath);
+
+ TRACE("szBuffer: %S\n", pszBuffer);
+
+ if (ulFlags & CM_REGISTRY_CONFIG)
+ {
+ if (ulHardwareProfile == 0)
+ {
+ wsprintfW(pszKeyPath,
+ L"%s\\%s\\%s\\%s",
+ L"System\\CurrentControlSet\\Hardware Profiles",
+ L"Current",
+ L"System\\CurrentControlSet\\Control\\Class",
+ pszBuffer);
+ }
+ else
+ {
+ wsprintfW(pszKeyPath,
+ L"%s\\%04lu\\%s\\%s",
+ L"System\\CurrentControlSet\\Hardware Profiles",
+ ulHardwareProfile,
+ L"System\\CurrentControlSet\\Control\\Class",
+ pszBuffer);
+ }
+ }
+ else
+ {
+ wsprintfW(pszKeyPath,
+ L"%s\\%s",
+ L"System\\CurrentControlSet\\Control\\Class",
+ pszBuffer);
+ }
+ }
+
+done:
+ if (pszBuffer != NULL)
+ MyFree(pszBuffer);
+
+ return ret;
+}
+
+
+BOOL
+IsValidRangeList(
+ _In_ PINTERNAL_RANGE_LIST pRangeList)
+{
+ BOOL bValid = TRUE;
+
+ if (pRangeList == NULL)
+ return FALSE;
+
+ _SEH2_TRY
+ {
+ if (pRangeList->ulMagic != RANGE_LIST_MAGIC)
+ bValid = FALSE;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ bValid = FALSE;
+ }
+ _SEH2_END;
+
+ return bValid;
+}
+
+
+/***********************************************************************
+ * CMP_GetBlockedDriverInfo [SETUPAPI.@]
+ */
+CONFIGRET
+WINAPI
+CMP_GetBlockedDriverInfo(
+ _Out_opt_ LPWSTR pszNames,
+ _Inout_ PULONG pulLength,
+ _In_ ULONG ulFlags,
+ _In_opt_ HMACHINE hMachine)
+{
+ RPC_BINDING_HANDLE BindingHandle = NULL;
+ ULONG ulTransferLength;
+ CONFIGRET ret;
+
+ TRACE("CMP_GetBlockedDriverInfo(%p %p %lx %p)\n",
+ pszNames, pulLength, ulFlags, hMachine);
+
+ if (hMachine != NULL)
+ {
+ BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
+ if (BindingHandle == NULL)
+ return CR_FAILURE;
+ }
+ else
+ {
+ if (!PnpGetLocalHandles(&BindingHandle, NULL))
+ return CR_FAILURE;
+ }
+
+ ulTransferLength = *pulLength;
+
+ RpcTryExcept
+ {
+ ret = PNP_GetBlockedDriverInfo(BindingHandle,
+ (PBYTE)pszNames,
+ &ulTransferLength,
+ pulLength,
+ ulFlags);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ret = RpcStatusToCmStatus(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return ret;
+}
+
+
+/***********************************************************************
+ * CMP_GetServerSideDeviceInstallFlags [SETUPAPI.@]
+ */
+CONFIGRET
+WINAPI
+CMP_GetServerSideDeviceInstallFlags(
+ _Out_ PULONG pulSSDIFlags,
+ _In_ ULONG ulFlags,
+ _In_opt_ HMACHINE hMachine)
+{
+ RPC_BINDING_HANDLE BindingHandle = NULL;
+ CONFIGRET ret;
+
+ TRACE("CMP_GetServerSideDeviceInstallFlags(%p %lx %p)\n",
+ pulSSDIFlags, ulFlags, hMachine);
+
+ if (pulSSDIFlags == NULL)
+ return CR_INVALID_POINTER;
+
+ if (ulFlags != 0)
+ return CR_INVALID_FLAG;
+
+ if (hMachine != NULL)
+ {
+ BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
+ if (BindingHandle == NULL)
+ return CR_FAILURE;
+ }
+ else
+ {
+ if (!PnpGetLocalHandles(&BindingHandle, NULL))
+ return CR_FAILURE;
+ }
+
+ RpcTryExcept
+ {
+ ret = PNP_GetServerSideDeviceInstallFlags(BindingHandle,
+ pulSSDIFlags,
+ ulFlags);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ret = RpcStatusToCmStatus(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return ret;
+}
+
+