[NTOSKRNL][USETUP][UMPNPMGR] Pass user response data to NtPlugPlayControl(PlugPlayCon...
[reactos.git] / base / services / umpnpmgr / umpnpmgr.c
index 3c96571..7aa6481 100644 (file)
 
 /* INCLUDES *****************************************************************/
 
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#include <winreg.h>
-#include <winsvc.h>
-#include <winuser.h>
-#include <dbt.h>
-#include <stdio.h>
-#include <cmfuncs.h>
-#include <rtlfuncs.h>
-#include <setypes.h>
-#include <umpnpmgr/sysguid.h>
-#include <cfgmgr32.h>
-#include <regstr.h>
-#include <userenv.h>
-#include <shlwapi.h>
-#include <pnp_s.h>
+#include "precomp.h"
 
 #define NDEBUG
 #include <debug.h>
 
-/* GLOBALS ******************************************************************/
-
-static WCHAR ServiceName[] = L"PlugPlay";
-
-static SERVICE_STATUS_HANDLE ServiceStatusHandle;
-static SERVICE_STATUS ServiceStatus;
-
-static WCHAR szRootDeviceId[] = L"HTREE\\ROOT\\0";
-
-static HKEY hEnumKey = NULL;
-static HKEY hClassKey = NULL;
-
-static HANDLE hUserToken = NULL;
-static HANDLE hInstallEvent = NULL;
-static HANDLE hNoPendingInstalls = NULL;
-
-static SLIST_HEADER DeviceInstallListHead;
-static HANDLE hDeviceInstallListNotEmpty;
-
-typedef struct
-{
-    SLIST_ENTRY ListEntry;
-    WCHAR DeviceIds[1];
-} DeviceInstallParams;
-
-/* FUNCTIONS *****************************************************************/
-
-static DWORD WINAPI
-RpcServerThread(LPVOID lpParameter)
-{
-    RPC_STATUS Status;
-    BOOLEAN RegisteredProtSeq = FALSE;
-
-    UNREFERENCED_PARAMETER(lpParameter);
-
-    DPRINT("RpcServerThread() called\n");
-
-#if 0
-    /* 2k/XP/2k3-compatible protocol sequence/endpoint */
-    Status = RpcServerUseProtseqEpW(L"ncacn_np",
-                                    20,
-                                    L"\\pipe\\ntsvcs",
-                                    NULL);  // Security descriptor
-    if (Status == RPC_S_OK)
-        RegisteredProtSeq = TRUE;
-    else
-        DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
-#endif
-
-    /* Vista/7-compatible protocol sequence/endpoint */
-    Status = RpcServerUseProtseqEpW(L"ncacn_np",
-                                    20,
-                                    L"\\pipe\\plugplay",
-                                    NULL);  // Security descriptor
-    if (Status == RPC_S_OK)
-        RegisteredProtSeq = TRUE;
-    else
-        DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
-
-    /* Make sure there's a usable endpoint */
-    if (RegisteredProtSeq == FALSE)
-        return 0;
-
-    Status = RpcServerRegisterIf(pnp_v1_0_s_ifspec,
-                                 NULL,
-                                 NULL);
-    if (Status != RPC_S_OK)
-    {
-        DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
-        return 0;
-    }
-
-    Status = RpcServerListen(1,
-                             20,
-                             FALSE);
-    if (Status != RPC_S_OK)
-    {
-        DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
-        return 0;
-    }
-
-    /* ROS HACK (this should never happen...) */
-    DPRINT1("*** Other devices won't be installed correctly. If something\n");
-    DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
-
-    DPRINT("RpcServerThread() done\n");
-
-    return 0;
-}
-
-
-void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
-{
-    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
-}
-
-
-void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
-{
-    HeapFree(GetProcessHeap(), 0, ptr);
-}
-
-
-static CONFIGRET WINAPI
-NtStatusToCrError(NTSTATUS Status)
-{
-    switch (Status)
-    {
-        case STATUS_NOT_IMPLEMENTED:
-            return CR_CALL_NOT_IMPLEMENTED;
-
-        case STATUS_INVALID_PARAMETER:
-            return CR_INVALID_DATA;
-
-        case STATUS_NO_SUCH_DEVICE:
-            return CR_NO_SUCH_DEVINST;
-
-        case STATUS_ACCESS_DENIED:
-            return CR_ACCESS_DENIED;
-
-        case STATUS_BUFFER_TOO_SMALL:
-            return CR_BUFFER_SMALL;
-
-        case STATUS_OBJECT_NAME_NOT_FOUND:
-            return CR_NO_SUCH_VALUE;
-
-        default:
-            return CR_FAILURE;
-    }
-}
-
-
-static VOID
-SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID,
-                      OUT LPWSTR pszEnumerator,
-                      OUT LPWSTR pszDevice,
-                      OUT LPWSTR pszInstance)
-{
-    WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN];
-    LPWSTR lpEnumerator = NULL;
-    LPWSTR lpDevice = NULL;
-    LPWSTR lpInstance = NULL;
-    LPWSTR ptr;
-
-    wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID);
-
-    *pszEnumerator = 0;
-    *pszDevice = 0;
-    *pszInstance = 0;
-
-    lpEnumerator = szLocalDeviceInstanceID;
-
-    ptr = wcschr(lpEnumerator, L'\\');
-    if (ptr != NULL)
-    {
-        *ptr = 0;
-        lpDevice = ++ptr;
-
-        ptr = wcschr(lpDevice, L'\\');
-        if (ptr != NULL)
-        {
-            *ptr = 0;
-            lpInstance = ++ptr;
-        }
-    }
-
-    if (lpEnumerator != NULL)
-        wcscpy(pszEnumerator, lpEnumerator);
-
-    if (lpDevice != NULL)
-        wcscpy(pszDevice, lpDevice);
-
-    if (lpInstance != NULL)
-        wcscpy(pszInstance, lpInstance);
-}
-
-
-/* PUBLIC FUNCTIONS **********************************************************/
-
-/* Function 0 */
-DWORD
-WINAPI
-PNP_Disconnect(
-    handle_t hBinding)
-{
-    UNREFERENCED_PARAMETER(hBinding);
-    return CR_SUCCESS;
-}
-
-
-/* Function 1 */
-DWORD
-WINAPI
-PNP_Connect(
-    handle_t hBinding)
-{
-    UNREFERENCED_PARAMETER(hBinding);
-    return CR_SUCCESS;
-}
-
-
-/* Function 2 */
-DWORD
-WINAPI
-PNP_GetVersion(
-    handle_t hBinding,
-    WORD *pVersion)
-{
-    UNREFERENCED_PARAMETER(hBinding);
-
-    *pVersion = 0x0400;
-    return CR_SUCCESS;
-}
-
-
-/* Function 3 */
-DWORD
-WINAPI
-PNP_GetGlobalState(
-    handle_t hBinding,
-    DWORD *pulState,
-    DWORD ulFlags)
-{
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    *pulState = CM_GLOBAL_STATE_CAN_DO_UI | CM_GLOBAL_STATE_SERVICES_AVAILABLE;
-    return CR_SUCCESS;
-}
-
-
-/* Function 4 */
-DWORD
-WINAPI
-PNP_InitDetection(
-    handle_t hBinding)
-{
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_InitDetection() called\n");
-    return CR_SUCCESS;
-}
-
-
-/* Function 5 */
-DWORD
-WINAPI
-PNP_ReportLogOn(
-    handle_t hBinding,
-    BOOL Admin,
-    DWORD ProcessId)
-{
-    DWORD ReturnValue = CR_FAILURE;
-    HANDLE hProcess;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(Admin);
-
-    DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin, ProcessId);
-
-    /* Get the users token */
-    hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcessId);
-
-    if (!hProcess)
-    {
-        DPRINT1("OpenProcess failed with error %u\n", GetLastError());
-        goto cleanup;
-    }
-
-    if (hUserToken)
-    {
-        CloseHandle(hUserToken);
-        hUserToken = NULL;
-    }
-
-    if (!OpenProcessToken(hProcess, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY, &hUserToken))
-    {
-        DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
-        goto cleanup;
-    }
-
-    /* Trigger the installer thread */
-    if (hInstallEvent)
-        SetEvent(hInstallEvent);
-
-    ReturnValue = CR_SUCCESS;
-
-cleanup:
-    if (hProcess)
-        CloseHandle(hProcess);
-
-    return ReturnValue;
-}
-
-
-/* Function 6 */
-DWORD
-WINAPI
-PNP_ValidateDeviceInstance(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-    HKEY hDeviceKey = NULL;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
-           pDeviceID, ulFlags);
-
-    if (RegOpenKeyExW(hEnumKey,
-                      pDeviceID,
-                      0,
-                      KEY_READ,
-                      &hDeviceKey))
-    {
-        DPRINT("Could not open the Device Key!\n");
-        ret = CR_NO_SUCH_DEVNODE;
-        goto Done;
-    }
-
-    /* FIXME: add more tests */
-
-Done:
-    if (hDeviceKey != NULL)
-        RegCloseKey(hDeviceKey);
-
-    DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 7 */
-DWORD
-WINAPI
-PNP_GetRootDeviceInstance(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    PNP_RPC_STRING_LEN ulLength)
-{
-    CONFIGRET ret = CR_SUCCESS;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_GetRootDeviceInstance() called\n");
-
-    if (!pDeviceID)
-    {
-        ret = CR_INVALID_POINTER;
-        goto Done;
-    }
-    if (ulLength < lstrlenW(szRootDeviceId) + 1)
-    {
-        ret = CR_BUFFER_SMALL;
-        goto Done;
-    }
-
-    lstrcpyW(pDeviceID,
-             szRootDeviceId);
-
-Done:
-    DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 8 */
-DWORD
-WINAPI
-PNP_GetRelatedDeviceInstance(
-    handle_t hBinding,
-    DWORD ulRelationship,
-    LPWSTR pDeviceID,
-    LPWSTR pRelatedDeviceId,
-    PNP_RPC_STRING_LEN *pulLength,
-    DWORD ulFlags)
-{
-    PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData;
-    CONFIGRET ret = CR_SUCCESS;
-    NTSTATUS Status;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    DPRINT("PNP_GetRelatedDeviceInstance() called\n");
-    DPRINT("  Relationship %ld\n", ulRelationship);
-    DPRINT("  DeviceId %S\n", pDeviceID);
-
-    RtlInitUnicodeString(&PlugPlayData.TargetDeviceInstance,
-                         pDeviceID);
-
-    PlugPlayData.Relation = ulRelationship;
-
-    PlugPlayData.RelatedDeviceInstanceLength = *pulLength;
-    PlugPlayData.RelatedDeviceInstance = pRelatedDeviceId;
-
-    Status = NtPlugPlayControl(PlugPlayControlGetRelatedDevice,
-                               (PVOID)&PlugPlayData,
-                               sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA));
-    if (!NT_SUCCESS(Status))
-    {
-        ret = NtStatusToCrError(Status);
-    }
-
-    DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret);
-    if (ret == CR_SUCCESS)
-    {
-        DPRINT("RelatedDevice: %wZ\n", &PlugPlayData.RelatedDeviceInstance);
-    }
-
-    return ret;
-}
-
-
-/* Function 9 */
-DWORD
-WINAPI
-PNP_EnumerateSubKeys(
-    handle_t hBinding,
-    DWORD ulBranch,
-    DWORD ulIndex,
-    LPWSTR Buffer,
-    PNP_RPC_STRING_LEN ulLength,
-    PNP_RPC_STRING_LEN *pulRequiredLen,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-    HKEY hKey;
-    DWORD dwError;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    DPRINT("PNP_EnumerateSubKeys() called\n");
-
-    switch (ulBranch)
-    {
-        case PNP_ENUMERATOR_SUBKEYS:
-            hKey = hEnumKey;
-            break;
-
-        case PNP_CLASS_SUBKEYS:
-            hKey = hClassKey;
-            break;
-
-        default:
-            return CR_FAILURE;
-    }
-
-    *pulRequiredLen = ulLength;
-    dwError = RegEnumKeyExW(hKey,
-                            ulIndex,
-                            Buffer,
-                            pulRequiredLen,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL);
-    if (dwError != ERROR_SUCCESS)
-    {
-        ret = (dwError == ERROR_NO_MORE_ITEMS) ? CR_NO_SUCH_VALUE : CR_FAILURE;
-    }
-    else
-    {
-        (*pulRequiredLen)++;
-    }
-
-    DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-static
-CONFIGRET
-GetDeviceInstanceList(
-    _In_ PWSTR pszDevice,
-    _Inout_ PWSTR pszBuffer,
-    _Inout_ PDWORD pulLength)
-{
-    WCHAR szInstanceBuffer[MAX_DEVICE_ID_LEN];
-    WCHAR szPathBuffer[512];
-    HKEY hDeviceKey;
-    DWORD dwInstanceLength, dwPathLength, dwUsedLength;
-    DWORD dwIndex, dwError;
-    PWSTR pPtr;
-    CONFIGRET ret = CR_SUCCESS;
-
-    dwError = RegOpenKeyExW(hEnumKey,
-                            pszDevice,
-                            0,
-                            KEY_ENUMERATE_SUB_KEYS,
-                            &hDeviceKey);
-    if (dwError != ERROR_SUCCESS)
-    {
-        DPRINT("Failed to open the device key (Error %lu)\n", dwError);
-        return CR_REGISTRY_ERROR;
-    }
-
-    dwUsedLength = 0;
-    pPtr = pszBuffer;
-
-    for (dwIndex = 0; ; dwIndex++)
-    {
-        dwInstanceLength = MAX_DEVICE_ID_LEN;
-        dwError = RegEnumKeyExW(hDeviceKey,
-                                dwIndex,
-                                szInstanceBuffer,
-                                &dwInstanceLength,
-                                NULL,
-                                NULL,
-                                NULL,
-                                NULL);
-        if (dwError != ERROR_SUCCESS)
-            break;
-
-        wsprintf(szPathBuffer, L"%s\\%s", pszDevice, szInstanceBuffer);
-        DPRINT("Path: %S\n", szPathBuffer);
-
-        dwPathLength = wcslen(szPathBuffer) + 1;
-        if (dwUsedLength + dwPathLength + 1 > *pulLength)
-        {
-            ret = CR_BUFFER_SMALL;
-            break;
-        }
-
-        wcscpy(pPtr, szPathBuffer);
-        dwUsedLength += dwPathLength;
-        pPtr += dwPathLength;
-
-        *pPtr = UNICODE_NULL;
-    }
-
-    RegCloseKey(hDeviceKey);
-
-    if (ret == CR_SUCCESS)
-        *pulLength = dwUsedLength + 1;
-    else
-        *pulLength = 0;
-
-    return ret;
-}
-
-
-/* Function 10 */
-DWORD
-WINAPI
-PNP_GetDeviceList(
-    handle_t hBinding,
-    LPWSTR pszFilter,
-    LPWSTR Buffer,
-    PNP_RPC_STRING_LEN *pulLength,
-    DWORD ulFlags)
-{
-    PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData;
-    WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
-    WCHAR szDevice[MAX_DEVICE_ID_LEN];
-    WCHAR szInstance[MAX_DEVICE_ID_LEN];
-    CONFIGRET ret = CR_SUCCESS;
-    NTSTATUS Status;
-
-    DPRINT("PNP_GetDeviceList() called\n");
-
-    if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
-        return CR_INVALID_FLAG;
-
-    if (pulLength == NULL)
-        return CR_INVALID_POINTER;
-
-    if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
-        (pszFilter == NULL))
-        return CR_INVALID_POINTER;
-
-    if (ulFlags &
-        (CM_GETIDLIST_FILTER_BUSRELATIONS |
-         CM_GETIDLIST_FILTER_POWERRELATIONS |
-         CM_GETIDLIST_FILTER_REMOVALRELATIONS |
-         CM_GETIDLIST_FILTER_EJECTRELATIONS))
-    {
-        RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
-                             pszFilter);
-        if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS)
-        {
-            PlugPlayData.Relations = 3;
-        }
-        else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS)
-        {
-            PlugPlayData.Relations = 2;
-        }
-        else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS)
-        {
-            PlugPlayData.Relations = 1;
-        }
-        else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS)
-        {
-            PlugPlayData.Relations = 0;
-        }
-
-        PlugPlayData.BufferSize = *pulLength * sizeof(WCHAR);
-        PlugPlayData.Buffer = Buffer;
-
-        Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations,
-                                   (PVOID)&PlugPlayData,
-                                   sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA));
-        if (NT_SUCCESS(Status))
-        {
-            *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR);
-        }
-        else
-        {
-            ret = NtStatusToCrError(Status);
-        }
-    }
-    else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
-    {
-        ret = CR_CALL_NOT_IMPLEMENTED;
-    }
-    else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
-    {
-        SplitDeviceInstanceID(pszFilter,
-                              szEnumerator,
-                              szDevice,
-                              szInstance);
-
-        if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
-        {
-            ret = GetDeviceInstanceList(pszFilter,
-                                        Buffer,
-                                        pulLength);
-        }
-        else
-        {
-            ret = CR_CALL_NOT_IMPLEMENTED;
-        }
-    }
-    else /* CM_GETIDLIST_FILTER_NONE */
-    {
-        ret = CR_CALL_NOT_IMPLEMENTED;
-    }
-
-    return ret;
-}
-
-
-static
-CONFIGRET
-GetDeviceInstanceListSize(
-    _In_ LPCWSTR pszDevice,
-    _Out_ PULONG pulLength)
-{
-    HKEY hDeviceKey;
-    DWORD dwSubKeys, dwMaxSubKeyLength;
-    DWORD dwError;
-
-    /* Open the device key */
-    dwError = RegOpenKeyExW(hEnumKey,
-                            pszDevice,
-                            0,
-                            KEY_READ,
-                            &hDeviceKey);
-    if (dwError != ERROR_SUCCESS)
-    {
-        DPRINT("Failed to open the device key (Error %lu)\n", dwError);
-        return CR_REGISTRY_ERROR;
-    }
-
-    /* Retrieve the number of device instances and the maximum name length */
-    dwError = RegQueryInfoKeyW(hDeviceKey,
-                               NULL,
-                               NULL,
-                               NULL,
-                               &dwSubKeys,
-                               &dwMaxSubKeyLength,
-                               NULL,
-                               NULL,
-                               NULL,
-                               NULL,
-                               NULL,
-                               NULL);
-    if (dwError != ERROR_SUCCESS)
-    {
-        DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
-        dwSubKeys = 0;
-        dwMaxSubKeyLength = 0;
-    }
-
-    /* Close the device key */
-    RegCloseKey(hDeviceKey);
-
-    /* Return the largest possible buffer size */
-    *pulLength = (dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1)) + 1;
-
-    return CR_SUCCESS;
-}
-
-
-/* Function 11 */
-DWORD
-WINAPI
-PNP_GetDeviceListSize(
-    handle_t hBinding,
-    LPWSTR pszFilter,
-    PNP_RPC_BUFFER_SIZE *pulLength,
-    DWORD ulFlags)
-{
-    PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData;
-    WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
-    WCHAR szDevice[MAX_DEVICE_ID_LEN];
-    WCHAR szInstance[MAX_DEVICE_ID_LEN];
-    CONFIGRET ret = CR_SUCCESS;
-    NTSTATUS Status;
-
-    DPRINT("PNP_GetDeviceListSize() called\n");
-
-    if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
-        return CR_INVALID_FLAG;
-
-    if (pulLength == NULL)
-        return CR_INVALID_POINTER;
-
-    if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
-        (pszFilter == NULL))
-        return CR_INVALID_POINTER;
-
-    *pulLength = 0;
-
-    if (ulFlags &
-        (CM_GETIDLIST_FILTER_BUSRELATIONS |
-         CM_GETIDLIST_FILTER_POWERRELATIONS |
-         CM_GETIDLIST_FILTER_REMOVALRELATIONS |
-         CM_GETIDLIST_FILTER_EJECTRELATIONS))
-    {
-        RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
-                             pszFilter);
-        if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS)
-        {
-            PlugPlayData.Relations = 3;
-        }
-        else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS)
-        {
-            PlugPlayData.Relations = 2;
-        }
-        else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS)
-        {
-            PlugPlayData.Relations = 1;
-        }
-        else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS)
-        {
-            PlugPlayData.Relations = 0;
-        }
-
-        PlugPlayData.BufferSize = 0;
-        PlugPlayData.Buffer = NULL;
-
-        Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations,
-                                   (PVOID)&PlugPlayData,
-                                   sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA));
-        if (NT_SUCCESS(Status))
-        {
-            *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR);
-        }
-        else
-        {
-            ret = NtStatusToCrError(Status);
-        }
-    }
-    else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
-    {
-        ret = CR_CALL_NOT_IMPLEMENTED;
-    }
-    else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
-    {
-        SplitDeviceInstanceID(pszFilter,
-                              szEnumerator,
-                              szDevice,
-                              szInstance);
-
-        if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
-        {
-            ret = GetDeviceInstanceListSize(pszFilter,
-                                            pulLength);
-        }
-        else
-        {
-            ret = CR_CALL_NOT_IMPLEMENTED;
-        }
-    }
-    else /* CM_GETIDLIST_FILTER_NONE */
-    {
-        ret = CR_CALL_NOT_IMPLEMENTED;
-    }
-
-    return ret;
-}
-
-
-/* Function 12 */
-DWORD
-WINAPI
-PNP_GetDepth(
-    handle_t hBinding,
-    LPWSTR pszDeviceID,
-    DWORD *pulDepth,
-    DWORD ulFlags)
-{
-    PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData;
-    CONFIGRET ret = CR_SUCCESS;
-    NTSTATUS Status;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    DPRINT("PNP_GetDepth() called\n");
-
-    RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
-                         pszDeviceID);
-
-    Status = NtPlugPlayControl(PlugPlayControlGetDeviceDepth,
-                               (PVOID)&PlugPlayData,
-                               sizeof(PLUGPLAY_CONTROL_DEPTH_DATA));
-    if (NT_SUCCESS(Status))
-    {
-        *pulDepth = PlugPlayData.Depth;
-    }
-    else
-    {
-        ret = NtStatusToCrError(Status);
-    }
-
-    DPRINT("PNP_GetDepth() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 13 */
-DWORD
-WINAPI
-PNP_GetDeviceRegProp(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulProperty,
-    DWORD *pulRegDataType,
-    BYTE *Buffer,
-    PNP_PROP_SIZE *pulTransferLen,
-    PNP_PROP_SIZE *pulLength,
-    DWORD ulFlags)
-{
-    PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData;
-    CONFIGRET ret = CR_SUCCESS;
-    LPWSTR lpValueName = NULL;
-    HKEY hKey = NULL;
-    LONG lError;
-    NTSTATUS Status;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_GetDeviceRegProp() called\n");
-
-    if (pulTransferLen == NULL || pulLength == NULL)
-    {
-        ret = CR_INVALID_POINTER;
-        goto done;
-    }
-
-    if (ulFlags != 0)
-    {
-        ret = CR_INVALID_FLAG;
-        goto done;
-    }
-
-    /* FIXME: Check pDeviceID */
-
-    if (*pulLength < *pulTransferLen)
-        *pulLength = *pulTransferLen;
-
-    *pulTransferLen = 0;
-
-    switch (ulProperty)
-    {
-        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_PHYSICAL_DEVICE_OBJECT_NAME:
-            PlugPlayData.Property = PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME;
-            break;
-
-        case CM_DRP_CAPABILITIES:
-            lpValueName = L"Capabilities";
-            break;
-
-        case CM_DRP_UI_NUMBER:
-            PlugPlayData.Property = PNP_PROPERTY_UI_NUMBER;
-            break;
-
-        case CM_DRP_UPPERFILTERS:
-            lpValueName = L"UpperFilters";
-            break;
-
-        case CM_DRP_LOWERFILTERS:
-            lpValueName = L"LowerFilters";
-            break;
-
-        case CM_DRP_BUSTYPEGUID:
-            PlugPlayData.Property = PNP_PROPERTY_BUSTYPEGUID;
-            break;
-
-        case CM_DRP_LEGACYBUSTYPE:
-            PlugPlayData.Property = PNP_PROPERTY_LEGACYBUSTYPE;
-            break;
-
-        case CM_DRP_BUSNUMBER:
-            PlugPlayData.Property = PNP_PROPERTY_BUSNUMBER;
-            break;
-
-        case CM_DRP_ENUMERATOR_NAME:
-            PlugPlayData.Property = PNP_PROPERTY_ENUMERATOR_NAME;
-            break;
-
-        case CM_DRP_SECURITY:
-            lpValueName = L"Security";
-            break;
-
-        case CM_DRP_DEVTYPE:
-            lpValueName = L"DeviceType";
-            break;
-
-        case CM_DRP_EXCLUSIVE:
-            lpValueName = L"Exclusive";
-            break;
-
-        case CM_DRP_CHARACTERISTICS:
-            lpValueName = L"DeviceCharacteristics";
-            break;
-
-        case CM_DRP_ADDRESS:
-            PlugPlayData.Property = PNP_PROPERTY_ADDRESS;
-            break;
-
-        case CM_DRP_UI_NUMBER_DESC_FORMAT:
-            lpValueName = L"UINumberDescFormat";
-            break;
-
-        case CM_DRP_DEVICE_POWER_DATA:
-            PlugPlayData.Property = PNP_PROPERTY_POWER_DATA;
-            break;
-
-        case CM_DRP_REMOVAL_POLICY:
-            PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY;
-            break;
-
-        case CM_DRP_REMOVAL_POLICY_HW_DEFAULT:
-            PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT;
-            break;
-
-        case CM_DRP_REMOVAL_POLICY_OVERRIDE:
-            lpValueName = L"RemovalPolicy";
-            break;
-
-        case CM_DRP_INSTALL_STATE:
-            PlugPlayData.Property = PNP_PROPERTY_INSTALL_STATE;
-            break;
-
-#if (WINVER >= _WIN32_WINNT_WS03)
-        case CM_DRP_LOCATION_PATHS:
-            PlugPlayData.Property = PNP_PROPERTY_LOCATION_PATHS;
-            break;
-#endif
-
-#if (WINVER >= _WIN32_WINNT_WIN7)
-        case CM_DRP_BASE_CONTAINERID:
-            PlugPlayData.Property = PNP_PROPERTY_CONTAINERID;
-            break;
-#endif
-
-        default:
-            ret = CR_INVALID_PROPERTY;
-            goto done;
-    }
-
-    DPRINT("Value name: %S\n", lpValueName);
-
-    if (lpValueName)
-    {
-        /* Retrieve information from the Registry */
-        lError = RegOpenKeyExW(hEnumKey,
-                               pDeviceID,
-                               0,
-                               KEY_QUERY_VALUE,
-                               &hKey);
-        if (lError != ERROR_SUCCESS)
-        {
-            hKey = NULL;
-            *pulLength = 0;
-            ret = CR_INVALID_DEVNODE;
-            goto done;
-        }
-
-        lError = RegQueryValueExW(hKey,
-                                  lpValueName,
-                                  NULL,
-                                  pulRegDataType,
-                                  Buffer,
-                                  pulLength);
-        if (lError != ERROR_SUCCESS)
-        {
-            if (lError == ERROR_MORE_DATA)
-            {
-                ret = CR_BUFFER_SMALL;
-            }
-            else
-            {
-                *pulLength = 0;
-                ret = CR_NO_SUCH_VALUE;
-            }
-        }
-    }
-    else
-    {
-        /* Retrieve information from the Device Node */
-        RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
-                             pDeviceID);
-        PlugPlayData.Buffer = Buffer;
-        PlugPlayData.BufferSize = *pulLength;
-
-        Status = NtPlugPlayControl(PlugPlayControlProperty,
-                                   (PVOID)&PlugPlayData,
-                                   sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA));
-        if (NT_SUCCESS(Status))
-        {
-            *pulLength = PlugPlayData.BufferSize;
-        }
-        else
-        {
-            ret = NtStatusToCrError(Status);
-        }
-    }
-
-done:
-    if (pulTransferLen)
-        *pulTransferLen = (ret == CR_SUCCESS) ? *pulLength : 0;
-
-    if (hKey != NULL)
-        RegCloseKey(hKey);
-
-    DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 14 */
-DWORD
-WINAPI
-PNP_SetDeviceRegProp(
-    handle_t hBinding,
-    LPWSTR pDeviceId,
-    DWORD ulProperty,
-    DWORD ulDataType,
-    BYTE *Buffer,
-    PNP_PROP_SIZE ulLength,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-    LPWSTR lpValueName = NULL;
-    HKEY hKey = 0;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    DPRINT("PNP_SetDeviceRegProp() called\n");
-
-    DPRINT("DeviceId: %S\n", pDeviceId);
-    DPRINT("Property: %lu\n", ulProperty);
-    DPRINT("DataType: %lu\n", ulDataType);
-    DPRINT("Length: %lu\n", ulLength);
-
-    switch (ulProperty)
-    {
-        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;
-
-        case CM_DRP_SECURITY:
-            lpValueName = L"Security";
-            break;
-
-        case CM_DRP_DEVTYPE:
-            lpValueName = L"DeviceType";
-            break;
-
-        case CM_DRP_EXCLUSIVE:
-            lpValueName = L"Exclusive";
-            break;
-
-        case CM_DRP_CHARACTERISTICS:
-            lpValueName = L"DeviceCharacteristics";
-            break;
-
-        case CM_DRP_UI_NUMBER_DESC_FORMAT:
-            lpValueName = L"UINumberDescFormat";
-            break;
-
-        case CM_DRP_REMOVAL_POLICY_OVERRIDE:
-            lpValueName = L"RemovalPolicy";
-            break;
-
-        default:
-            return CR_INVALID_PROPERTY;
-    }
-
-    DPRINT("Value name: %S\n", lpValueName);
-
-    if (RegOpenKeyExW(hEnumKey,
-                      pDeviceId,
-                      0,
-                      KEY_SET_VALUE,
-                      &hKey))
-        return CR_INVALID_DEVNODE;
-
-    if (ulLength == 0)
-    {
-        if (RegDeleteValueW(hKey,
-                            lpValueName))
-            ret = CR_REGISTRY_ERROR;
-    }
-    else
-    {
-        if (RegSetValueExW(hKey,
-                           lpValueName,
-                           0,
-                           ulDataType,
-                           Buffer,
-                           ulLength))
-            ret = CR_REGISTRY_ERROR;
-    }
-
-    RegCloseKey(hKey);
-
-    DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 15 */
-DWORD
-WINAPI
-PNP_GetClassInstance(
-    handle_t hBinding,
-    LPWSTR pDeviceId,
-    LPWSTR pszClassInstance,
-    PNP_RPC_STRING_LEN ulLength)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 16 */
-DWORD
-WINAPI
-PNP_CreateKey(
-    handle_t hBinding,
-    LPWSTR pszSubKey,
-    DWORD samDesired,
-    DWORD ulFlags)
-{
-    HKEY hKey = 0;
-
-    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
-                        pszSubKey,
-                        0,
-                        NULL,
-                        0,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hKey,
-                        NULL))
-        return CR_REGISTRY_ERROR;
-
-    /* FIXME: Set security key */
-
-    RegCloseKey(hKey);
-
-    return CR_SUCCESS;
-}
-
-
-/* Function 17 */
-DWORD
-WINAPI
-PNP_DeleteRegistryKey(
-    handle_t hBinding,
-    LPWSTR pszDeviceID,
-    LPWSTR pszParentKey,
-    LPWSTR pszChildKey,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 18 */
-DWORD
-WINAPI
-PNP_GetClassCount(
-    handle_t hBinding,
-    DWORD *pulClassCount,
-    DWORD ulFlags)
-{
-    HKEY hKey;
-    DWORD dwError;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                            REGSTR_PATH_CLASS,
-                            0,
-                            KEY_QUERY_VALUE,
-                            &hKey);
-    if (dwError != ERROR_SUCCESS)
-        return CR_INVALID_DATA;
-
-    dwError = RegQueryInfoKeyW(hKey,
-                               NULL,
-                               NULL,
-                               NULL,
-                               pulClassCount,
-                               NULL,
-                               NULL,
-                               NULL,
-                               NULL,
-                               NULL,
-                               NULL,
-                               NULL);
-    RegCloseKey(hKey);
-    if (dwError != ERROR_SUCCESS)
-        return CR_INVALID_DATA;
-
-    return CR_SUCCESS;
-}
-
-
-/* Function 19 */
-DWORD
-WINAPI
-PNP_GetClassName(
-    handle_t hBinding,
-    LPWSTR pszClassGuid,
-    LPWSTR Buffer,
-    PNP_RPC_STRING_LEN *pulLength,
-    DWORD ulFlags)
-{
-    WCHAR szKeyName[MAX_PATH];
-    CONFIGRET ret = CR_SUCCESS;
-    HKEY hKey;
-    DWORD dwSize;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    DPRINT("PNP_GetClassName() called\n");
-
-    lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class\\");
-    if (lstrlenW(pszClassGuid) + 1 < sizeof(szKeyName)/sizeof(WCHAR)-(lstrlenW(szKeyName) * sizeof(WCHAR)))
-        lstrcatW(szKeyName, pszClassGuid);
-    else
-        return CR_INVALID_DATA;
-
-    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                      szKeyName,
-                      0,
-                      KEY_QUERY_VALUE,
-                      &hKey))
-        return CR_REGISTRY_ERROR;
-
-    dwSize = *pulLength * sizeof(WCHAR);
-    if (RegQueryValueExW(hKey,
-                         L"Class",
-                         NULL,
-                         NULL,
-                         (LPBYTE)Buffer,
-                         &dwSize))
-    {
-        *pulLength = 0;
-        ret = CR_REGISTRY_ERROR;
-    }
-    else
-    {
-        *pulLength = dwSize / sizeof(WCHAR);
-    }
-
-    RegCloseKey(hKey);
-
-    DPRINT("PNP_GetClassName() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 20 */
-DWORD
-WINAPI
-PNP_DeleteClassKey(
-    handle_t hBinding,
-    LPWSTR pszClassGuid,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid, ulFlags);
-
-    if (ulFlags & CM_DELETE_CLASS_SUBKEYS)
-    {
-        if (SHDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
-            ret = CR_REGISTRY_ERROR;
-    }
-    else
-    {
-        if (RegDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
-            ret = CR_REGISTRY_ERROR;
-    }
-
-    DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 21 */
-DWORD
-WINAPI
-PNP_GetInterfaceDeviceAlias(
-    handle_t hBinding,
-    LPWSTR pszInterfaceDevice,
-    GUID *AliasInterfaceGuid,
-    LPWSTR pszAliasInterfaceDevice,
-    PNP_RPC_STRING_LEN *pulLength,
-    PNP_RPC_STRING_LEN *pulTransferLen,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 22 */
-DWORD
-WINAPI
-PNP_GetInterfaceDeviceList(
-    handle_t hBinding,
-    GUID *InterfaceGuid,
-    LPWSTR pszDeviceID,
-    BYTE *Buffer,
-    PNP_RPC_BUFFER_SIZE *pulLength,
-    DWORD ulFlags)
-{
-    NTSTATUS Status;
-    PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData;
-    DWORD ret = CR_SUCCESS;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
-                         pszDeviceID);
-
-    PlugPlayData.Flags = ulFlags;
-    PlugPlayData.FilterGuid = InterfaceGuid;
-    PlugPlayData.Buffer = Buffer;
-    PlugPlayData.BufferSize = *pulLength;
-
-    Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList,
-                               (PVOID)&PlugPlayData,
-                               sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA));
-    if (NT_SUCCESS(Status))
-    {
-        *pulLength = PlugPlayData.BufferSize;
-    }
-    else
-    {
-        ret = NtStatusToCrError(Status);
-    }
-
-    DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret);
-    return ret;
-}
-
-
-/* Function 23 */
-DWORD
-WINAPI
-PNP_GetInterfaceDeviceListSize(
-    handle_t hBinding,
-    PNP_RPC_BUFFER_SIZE *pulLen,
-    GUID *InterfaceGuid,
-    LPWSTR pszDeviceID,
-    DWORD ulFlags)
-{
-    NTSTATUS Status;
-    PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData;
-    DWORD ret = CR_SUCCESS;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
-
-    RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
-                         pszDeviceID);
-
-    PlugPlayData.FilterGuid = InterfaceGuid;
-    PlugPlayData.Buffer = NULL;
-    PlugPlayData.BufferSize = 0;
-    PlugPlayData.Flags = ulFlags;
-
-    Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList,
-                               (PVOID)&PlugPlayData,
-                               sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA));
-    if (NT_SUCCESS(Status))
-    {
-        *pulLen = PlugPlayData.BufferSize;
-    }
-    else
-    {
-        ret = NtStatusToCrError(Status);
-    }
-
-    DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret);
-    return ret;
-}
-
-
-/* Function 24 */
-DWORD
-WINAPI
-PNP_RegisterDeviceClassAssociation(
-    handle_t hBinding,
-    LPWSTR pszDeviceID,
-    GUID *InterfaceGuid,
-    LPWSTR pszReference,
-    LPWSTR pszSymLink,
-    PNP_RPC_STRING_LEN *pulLength,
-    PNP_RPC_STRING_LEN *pulTransferLen,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 25 */
-DWORD
-WINAPI
-PNP_UnregisterDeviceClassAssociation(
-    handle_t hBinding,
-    LPWSTR pszInterfaceDevice,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 26 */
-DWORD
-WINAPI
-PNP_GetClassRegProp(
-    handle_t hBinding,
-    LPWSTR pszClassGuid,
-    DWORD ulProperty,
-    DWORD *pulRegDataType,
-    BYTE *Buffer,
-    PNP_RPC_STRING_LEN *pulTransferLen,
-    PNP_RPC_STRING_LEN *pulLength,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-    LPWSTR lpValueName = NULL;
-    HKEY hInstKey = NULL;
-    HKEY hPropKey = NULL;
-    LONG lError;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_GetClassRegProp() called\n");
-
-    if (pulTransferLen == NULL || pulLength == NULL)
-    {
-        ret = CR_INVALID_POINTER;
-        goto done;
-    }
-
-    if (ulFlags != 0)
-    {
-        ret = CR_INVALID_FLAG;
-        goto done;
-    }
-
-    if (*pulLength < *pulTransferLen)
-        *pulLength = *pulTransferLen;
-
-    *pulTransferLen = 0;
-
-    switch (ulProperty)
-    {
-        case CM_CRP_SECURITY:
-            lpValueName = L"Security";
-            break;
-
-        case CM_CRP_DEVTYPE:
-            lpValueName = L"DeviceType";
-            break;
-
-        case CM_CRP_EXCLUSIVE:
-            lpValueName = L"Exclusive";
-            break;
-
-        case CM_CRP_CHARACTERISTICS:
-            lpValueName = L"DeviceCharacteristics";
-            break;
-
-        default:
-            ret = CR_INVALID_PROPERTY;
-            goto done;
-    }
-
-    DPRINT("Value name: %S\n", lpValueName);
-
-    lError = RegOpenKeyExW(hClassKey,
-                           pszClassGuid,
-                           0,
-                           KEY_READ,
-                           &hInstKey);
-    if (lError != ERROR_SUCCESS)
-    {
-        *pulLength = 0;
-        ret = CR_NO_SUCH_REGISTRY_KEY;
-        goto done;
-    }
-
-    lError = RegOpenKeyExW(hInstKey,
-                           L"Properties",
-                           0,
-                           KEY_READ,
-                           &hPropKey);
-    if (lError != ERROR_SUCCESS)
-    {
-        *pulLength = 0;
-        ret = CR_NO_SUCH_REGISTRY_KEY;
-        goto done;
-    }
-
-    lError = RegQueryValueExW(hPropKey,
-                              lpValueName,
-                              NULL,
-                              pulRegDataType,
-                              Buffer,
-                              pulLength);
-    if (lError != ERROR_SUCCESS)
-    {
-        if (lError == ERROR_MORE_DATA)
-        {
-            ret = CR_BUFFER_SMALL;
-        }
-        else
-        {
-            *pulLength = 0;
-            ret = CR_NO_SUCH_VALUE;
-        }
-    }
-
-done:
-    if (ret == CR_SUCCESS)
-        *pulTransferLen = *pulLength;
-
-    if (hPropKey != NULL)
-        RegCloseKey(hPropKey);
-
-    if (hInstKey != NULL)
-        RegCloseKey(hInstKey);
-
-    DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 27 */
-DWORD
-WINAPI
-PNP_SetClassRegProp(
-    handle_t hBinding,
-    LPWSTR pszClassGuid,
-    DWORD ulProperty,
-    DWORD ulDataType,
-    BYTE *Buffer,
-    PNP_PROP_SIZE ulLength,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-    LPWSTR lpValueName = NULL;
-    HKEY hInstKey = 0;
-    HKEY hPropKey = 0;
-    LONG lError;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_SetClassRegProp() called\n");
-
-    if (ulFlags != 0)
-        return CR_INVALID_FLAG;
-
-    switch (ulProperty)
-    {
-        case CM_CRP_SECURITY:
-            lpValueName = L"Security";
-            break;
-
-        case CM_CRP_DEVTYPE:
-            lpValueName = L"DeviceType";
-            break;
-
-        case CM_CRP_EXCLUSIVE:
-            lpValueName = L"Exclusive";
-            break;
-
-        case CM_CRP_CHARACTERISTICS:
-            lpValueName = L"DeviceCharacteristics";
-            break;
-
-        default:
-            return CR_INVALID_PROPERTY;
-    }
-
-    lError = RegOpenKeyExW(hClassKey,
-                           pszClassGuid,
-                           0,
-                           KEY_WRITE,
-                           &hInstKey);
-    if (lError != ERROR_SUCCESS)
-    {
-        ret = CR_NO_SUCH_REGISTRY_KEY;
-        goto done;
-    }
-
-    /* FIXME: Set security descriptor */
-    lError = RegCreateKeyExW(hInstKey,
-                             L"Properties",
-                             0,
-                             NULL,
-                             REG_OPTION_NON_VOLATILE,
-                             KEY_ALL_ACCESS,
-                             NULL,
-                             &hPropKey,
-                             NULL);
-    if (lError != ERROR_SUCCESS)
-    {
-        ret = CR_REGISTRY_ERROR;
-        goto done;
-    }
-
-    if (ulLength == 0)
-    {
-        if (RegDeleteValueW(hPropKey,
-                            lpValueName))
-            ret = CR_REGISTRY_ERROR;
-    }
-    else
-    {
-        if (RegSetValueExW(hPropKey,
-                           lpValueName,
-                           0,
-                           ulDataType,
-                           Buffer,
-                           ulLength))
-            ret = CR_REGISTRY_ERROR;
-    }
-
-done:
-    if (hPropKey != NULL)
-        RegCloseKey(hPropKey);
-
-    if (hInstKey != NULL)
-        RegCloseKey(hInstKey);
-
-    return ret;
-}
-
-
-static CONFIGRET
-CreateDeviceInstance(LPWSTR pszDeviceID)
-{
-    WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
-    WCHAR szDevice[MAX_DEVICE_ID_LEN];
-    WCHAR szInstance[MAX_DEVICE_ID_LEN];
-    HKEY hKeyEnumerator;
-    HKEY hKeyDevice;
-    HKEY hKeyInstance;
-    HKEY hKeyControl;
-    LONG lError;
-
-    /* Split the instance ID */
-    SplitDeviceInstanceID(pszDeviceID,
-                          szEnumerator,
-                          szDevice,
-                          szInstance);
-
-    /* Open or create the enumerator key */
-    lError = RegCreateKeyExW(hEnumKey,
-                             szEnumerator,
-                             0,
-                             NULL,
-                             REG_OPTION_NON_VOLATILE,
-                             KEY_ALL_ACCESS,
-                             NULL,
-                             &hKeyEnumerator,
-                             NULL);
-    if (lError != ERROR_SUCCESS)
-    {
-        return CR_REGISTRY_ERROR;
-    }
-
-    /* Open or create the device key */
-    lError = RegCreateKeyExW(hKeyEnumerator,
-                             szDevice,
-                             0,
-                             NULL,
-                             REG_OPTION_NON_VOLATILE,
-                             KEY_ALL_ACCESS,
-                             NULL,
-                             &hKeyDevice,
-                             NULL);
-
-    /* Close the enumerator key */
-    RegCloseKey(hKeyEnumerator);
-
-    if (lError != ERROR_SUCCESS)
-    {
-        return CR_REGISTRY_ERROR;
-    }
-
-    /* Try to open the instance key and fail if it exists */
-    lError = RegOpenKeyExW(hKeyDevice,
-                           szInstance,
-                           0,
-                           KEY_SET_VALUE,
-                           &hKeyInstance);
-    if (lError == ERROR_SUCCESS)
-    {
-        DPRINT1("Instance %S already exists!\n", szInstance);
-        RegCloseKey(hKeyInstance);
-        RegCloseKey(hKeyDevice);
-        return CR_ALREADY_SUCH_DEVINST;
-    }
-
-    /* Create a new instance key */
-    lError = RegCreateKeyExW(hKeyDevice,
-                             szInstance,
-                             0,
-                             NULL,
-                             REG_OPTION_NON_VOLATILE,
-                             KEY_ALL_ACCESS,
-                             NULL,
-                             &hKeyInstance,
-                             NULL);
-
-    /* Close the device key */
-    RegCloseKey(hKeyDevice);
-
-    if (lError != ERROR_SUCCESS)
-    {
-        return CR_REGISTRY_ERROR;
-    }
-
-    /* Create the 'Control' sub key */
-    lError = RegCreateKeyExW(hKeyInstance,
-                             L"Control",
-                             0,
-                             NULL,
-                             REG_OPTION_NON_VOLATILE,
-                             KEY_ALL_ACCESS,
-                             NULL,
-                             &hKeyControl,
-                             NULL);
-    if (lError == ERROR_SUCCESS)
-    {
-        RegCloseKey(hKeyControl);
-    }
-
-    RegCloseKey(hKeyInstance);
-
-    return (lError == ERROR_SUCCESS) ? CR_SUCCESS : CR_REGISTRY_ERROR;
-}
-
-
-/* Function 28 */
-DWORD
-WINAPI
-PNP_CreateDevInst(
-    handle_t hBinding,
-    LPWSTR pszDeviceID,
-    LPWSTR pszParentDeviceID,
-    PNP_RPC_STRING_LEN ulLength,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-
-    DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID);
-
-    if (ulFlags & CM_CREATE_DEVNODE_GENERATE_ID)
-    {
-        WCHAR szGeneratedInstance[MAX_DEVICE_ID_LEN];
-        DWORD dwInstanceNumber;
-
-        /* Generated ID is: Root\<Device ID>\<Instance number> */
-        dwInstanceNumber = 0;
-        do
-        {
-            swprintf(szGeneratedInstance, L"Root\\%ls\\%04lu",
-                     pszDeviceID, dwInstanceNumber);
-
-            /* Try to create a device instance with this ID */
-            ret = CreateDeviceInstance(szGeneratedInstance);
-
-            dwInstanceNumber++;
-        }
-        while (ret == CR_ALREADY_SUCH_DEVINST);
-
-        if (ret == CR_SUCCESS)
-        {
-            /* pszDeviceID is an out parameter too for generated IDs */
-            if (wcslen(szGeneratedInstance) > ulLength)
-            {
-                ret = CR_BUFFER_SMALL;
-            }
-            else
-            {
-                wcscpy(pszDeviceID, szGeneratedInstance);
-            }
-        }
-    }
-    else
-    {
-        /* Create the device instance */
-        ret = CreateDeviceInstance(pszDeviceID);
-    }
-
-    DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-static CONFIGRET
-MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination,
-                   LPWSTR pszDeviceInstanceSource)
-{
-    DPRINT("MoveDeviceInstance: not implemented\n");
-    /* FIXME */
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-static CONFIGRET
-SetupDeviceInstance(LPWSTR pszDeviceInstance,
-                    DWORD ulFlags)
-{
-    DPRINT("SetupDeviceInstance: not implemented\n");
-    /* FIXME */
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-static CONFIGRET
-EnableDeviceInstance(LPWSTR pszDeviceInstance)
-{
-    PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
-    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));
-    if (!NT_SUCCESS(Status))
-        ret = NtStatusToCrError(Status);
-
-    return ret;
-}
-
-
-static CONFIGRET
-DisableDeviceInstance(LPWSTR pszDeviceInstance)
-{
-    DPRINT("DisableDeviceInstance: not implemented\n");
-    /* FIXME */
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-static CONFIGRET
-ReenumerateDeviceInstance(
-    _In_ LPWSTR pszDeviceInstance,
-    _In_ ULONG ulFlags)
-{
-    PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData;
-    CONFIGRET ret = CR_SUCCESS;
-    NTSTATUS Status;
-
-    DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
-           pszDeviceInstance, ulFlags);
-
-    if (ulFlags & ~CM_REENUMERATE_BITS)
-        return CR_INVALID_FLAG;
-
-    if (ulFlags & CM_REENUMERATE_RETRY_INSTALLATION)
-    {
-        DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
-    }
-
-    RtlInitUnicodeString(&EnumerateDeviceData.DeviceInstance,
-                         pszDeviceInstance);
-    EnumerateDeviceData.Flags = 0;
-
-    Status = NtPlugPlayControl(PlugPlayControlEnumerateDevice,
-                               &EnumerateDeviceData,
-                               sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA));
-    if (!NT_SUCCESS(Status))
-        ret = NtStatusToCrError(Status);
-
-    return ret;
-}
-
-
-/* Function 29 */
-DWORD
-WINAPI
-PNP_DeviceInstanceAction(
-    handle_t hBinding,
-    DWORD ulAction,
-    DWORD ulFlags,
-    LPWSTR pszDeviceInstance1,
-    LPWSTR pszDeviceInstance2)
-{
-    CONFIGRET ret = CR_SUCCESS;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_DeviceInstanceAction() called\n");
-
-    switch (ulAction)
-    {
-        case PNP_DEVINST_MOVE:
-            ret = MoveDeviceInstance(pszDeviceInstance1,
-                                     pszDeviceInstance2);
-            break;
-
-        case PNP_DEVINST_SETUP:
-            ret = SetupDeviceInstance(pszDeviceInstance1,
-                                      ulFlags);
-            break;
-
-        case PNP_DEVINST_ENABLE:
-            ret = EnableDeviceInstance(pszDeviceInstance1);
-            break;
-
-        case PNP_DEVINST_DISABLE:
-            ret = DisableDeviceInstance(pszDeviceInstance1);
-            break;
-
-        case PNP_DEVINST_REENUMERATE:
-            ret = ReenumerateDeviceInstance(pszDeviceInstance1,
-                                            ulFlags);
-            break;
-
-        default:
-            DPRINT1("Unknown device action %lu: not implemented\n", ulAction);
-            ret = CR_CALL_NOT_IMPLEMENTED;
-    }
-
-    DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 30 */
-DWORD
-WINAPI
-PNP_GetDeviceStatus(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD *pulStatus,
-    DWORD *pulProblem,
-    DWORD ulFlags)
-{
-    PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
-    CONFIGRET ret = CR_SUCCESS;
-    NTSTATUS Status;
-
-    UNREFERENCED_PARAMETER(hBinding);
-    UNREFERENCED_PARAMETER(ulFlags);
-
-    DPRINT("PNP_GetDeviceStatus() called\n");
-
-    RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
-                         pDeviceID);
-    PlugPlayData.Operation = 0; /* Get status */
-
-    Status = NtPlugPlayControl(PlugPlayControlDeviceStatus,
-                               (PVOID)&PlugPlayData,
-                               sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
-    if (NT_SUCCESS(Status))
-    {
-        *pulStatus = PlugPlayData.DeviceStatus;
-        *pulProblem = PlugPlayData.DeviceProblem;
-    }
-    else
-    {
-        ret = NtStatusToCrError(Status);
-    }
-
-    DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 31 */
-DWORD
-WINAPI
-PNP_SetDeviceProblem(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulProblem,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 32 */
-DWORD
-WINAPI
-PNP_DisableDevInst(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    PPNP_VETO_TYPE pVetoType,
-    LPWSTR pszVetoName,
-    DWORD ulNameLength,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-/* Function 33 */
-DWORD
-WINAPI
-PNP_UninstallDevInst(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-static BOOL
-CheckForDeviceId(LPWSTR lpDeviceIdList,
-                 LPWSTR lpDeviceId)
-{
-    LPWSTR lpPtr;
-    DWORD dwLength;
-
-    lpPtr = lpDeviceIdList;
-    while (*lpPtr != 0)
-    {
-        dwLength = wcslen(lpPtr);
-        if (0 == _wcsicmp(lpPtr, lpDeviceId))
-            return TRUE;
-
-        lpPtr += (dwLength + 1);
-    }
-
-    return FALSE;
-}
-
-
-static VOID
-AppendDeviceId(LPWSTR lpDeviceIdList,
-               LPDWORD lpDeviceIdListSize,
-               LPWSTR lpDeviceId)
-{
-    DWORD dwLen;
-    DWORD dwPos;
-
-    dwLen = wcslen(lpDeviceId);
-    dwPos = (*lpDeviceIdListSize / sizeof(WCHAR)) - 1;
-
-    wcscpy(&lpDeviceIdList[dwPos], lpDeviceId);
-
-    dwPos += (dwLen + 1);
-
-    lpDeviceIdList[dwPos] = 0;
-
-    *lpDeviceIdListSize = dwPos * sizeof(WCHAR);
-}
-
-
-/* Function 34 */
-DWORD
-WINAPI
-PNP_AddID(
-    handle_t hBinding,
-    LPWSTR pszDeviceID,
-    LPWSTR pszID,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-    HKEY hDeviceKey;
-    LPWSTR pszSubKey;
-    DWORD dwDeviceIdListSize;
-    DWORD dwNewDeviceIdSize;
-    WCHAR * pszDeviceIdList = NULL;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_AddID() called\n");
-    DPRINT("  DeviceInstance: %S\n", pszDeviceID);
-    DPRINT("  DeviceId: %S\n", pszID);
-    DPRINT("  Flags: %lx\n", ulFlags);
-
-    if (RegOpenKeyExW(hEnumKey,
-                      pszDeviceID,
-                      0,
-                      KEY_QUERY_VALUE | KEY_SET_VALUE,
-                      &hDeviceKey) != ERROR_SUCCESS)
-    {
-        DPRINT("Failed to open the device key!\n");
-        return CR_INVALID_DEVNODE;
-    }
-
-    pszSubKey = (ulFlags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID";
-
-    if (RegQueryValueExW(hDeviceKey,
-                         pszSubKey,
-                         NULL,
-                         NULL,
-                         NULL,
-                         &dwDeviceIdListSize) != ERROR_SUCCESS)
-    {
-        DPRINT("Failed to query the desired ID string!\n");
-        ret = CR_REGISTRY_ERROR;
-        goto Done;
-    }
-
-    dwNewDeviceIdSize = lstrlenW(pszDeviceID);
-    if (!dwNewDeviceIdSize)
-    {
-        ret = CR_INVALID_POINTER;
-        goto Done;
-    }
-
-    dwDeviceIdListSize += (dwNewDeviceIdSize + 2) * sizeof(WCHAR);
-
-    pszDeviceIdList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeviceIdListSize);
-    if (!pszDeviceIdList)
-    {
-        DPRINT("Failed to allocate memory for the desired ID string!\n");
-        ret = CR_OUT_OF_MEMORY;
-        goto Done;
-    }
-
-    if (RegQueryValueExW(hDeviceKey,
-                         pszSubKey,
-                         NULL,
-                         NULL,
-                         (LPBYTE)pszDeviceIdList,
-                         &dwDeviceIdListSize) != ERROR_SUCCESS)
-    {
-        DPRINT("Failed to query the desired ID string!\n");
-        ret = CR_REGISTRY_ERROR;
-        goto Done;
-    }
-
-    /* Check whether the device ID is already in use */
-    if (CheckForDeviceId(pszDeviceIdList, pszDeviceID))
-    {
-        DPRINT("Device ID was found in the ID string!\n");
-        ret = CR_SUCCESS;
-        goto Done;
-    }
-
-    /* Append the Device ID */
-    AppendDeviceId(pszDeviceIdList, &dwDeviceIdListSize, pszID);
-
-    if (RegSetValueExW(hDeviceKey,
-                       pszSubKey,
-                       0,
-                       REG_MULTI_SZ,
-                       (LPBYTE)pszDeviceIdList,
-                       dwDeviceIdListSize) != ERROR_SUCCESS)
-    {
-        DPRINT("Failed to set the desired ID string!\n");
-        ret = CR_REGISTRY_ERROR;
-    }
-
-Done:
-    RegCloseKey(hDeviceKey);
-    if (pszDeviceIdList)
-        HeapFree(GetProcessHeap(), 0, pszDeviceIdList);
-
-    DPRINT("PNP_AddID() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 35 */
-DWORD
-WINAPI
-PNP_RegisterDriver(
-    handle_t hBinding,
-    LPWSTR pszDeviceID,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 36 */
-DWORD
-WINAPI
-PNP_QueryRemove(
-    handle_t hBinding,
-    LPWSTR pszDeviceID,
-    PPNP_VETO_TYPE pVetoType,
-    LPWSTR pszVetoName,
-    DWORD ulNameLength,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 37 */
-DWORD
-WINAPI
-PNP_RequestDeviceEject(
-    handle_t hBinding,
-    LPWSTR pszDeviceID,
-    PPNP_VETO_TYPE pVetoType,
-    LPWSTR pszVetoName,
-    DWORD ulNameLength,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 38 */
-CONFIGRET
-WINAPI
-PNP_IsDockStationPresent(
-    handle_t hBinding,
-    BOOL *Present)
-{
-    HKEY hKey;
-    DWORD dwType;
-    DWORD dwValue;
-    DWORD dwSize;
-    CONFIGRET ret = CR_SUCCESS;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    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 */
-DWORD
-WINAPI
-PNP_RequestEjectPC(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 40 */
-DWORD
-WINAPI
-PNP_HwProfFlags(
-    handle_t hBinding,
-    DWORD ulAction,
-    LPWSTR pDeviceID,
-    DWORD ulConfig,
-    DWORD *pulValue,
-    PPNP_VETO_TYPE pVetoType,
-    LPWSTR pszVetoName,
-    DWORD ulNameLength,
-    DWORD ulFlags)
-{
-    CONFIGRET ret = CR_SUCCESS;
-    WCHAR szKeyName[MAX_PATH];
-    HKEY hKey;
-    HKEY hDeviceKey;
-    DWORD dwSize;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_HwProfFlags() called\n");
-
-    if (ulConfig == 0)
-    {
-        wcscpy(szKeyName,
-               L"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
-    }
-    else
-    {
-        swprintf(szKeyName,
-                 L"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
-                 ulConfig);
-    }
-
-    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                      szKeyName,
-                      0,
-                      KEY_QUERY_VALUE,
-                      &hKey) != ERROR_SUCCESS)
-        return CR_REGISTRY_ERROR;
-
-    if (ulAction == PNP_GET_HWPROFFLAGS)
-    {
-         if (RegOpenKeyExW(hKey,
-                           pDeviceID,
-                           0,
-                           KEY_QUERY_VALUE,
-                           &hDeviceKey) != ERROR_SUCCESS)
-         {
-            *pulValue = 0;
-         }
-         else
-         {
-             dwSize = sizeof(DWORD);
-             if (RegQueryValueExW(hDeviceKey,
-                                  L"CSConfigFlags",
-                                  NULL,
-                                  NULL,
-                                  (LPBYTE)pulValue,
-                                  &dwSize) != ERROR_SUCCESS)
-             {
-                 *pulValue = 0;
-             }
-
-             RegCloseKey(hDeviceKey);
-         }
-    }
-    else if (ulAction == PNP_SET_HWPROFFLAGS)
-    {
-        /* FIXME: not implemented yet */
-        ret = CR_CALL_NOT_IMPLEMENTED;
-    }
-
-    RegCloseKey(hKey);
-
-    return ret;
-}
-
-
-/* Function 41 */
-DWORD
-WINAPI
-PNP_GetHwProfInfo(
-    handle_t hBinding,
-    DWORD ulIndex,
-    HWPROFILEINFO *pHWProfileInfo,
-    DWORD ulProfileInfoSize,
-    DWORD ulFlags)
-{
-    WCHAR szProfileName[5];
-    HKEY hKeyConfig = NULL;
-    HKEY hKeyProfiles = NULL;
-    HKEY hKeyProfile = NULL;
-    DWORD dwDisposition;
-    DWORD dwSize;
-    LONG lError;
-    CONFIGRET ret = CR_SUCCESS;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_GetHwProfInfo() called\n");
-
-    if (ulProfileInfoSize == 0)
-    {
-        ret = CR_INVALID_DATA;
-        goto done;
-    }
-
-    if (ulFlags != 0)
-    {
-        ret = CR_INVALID_FLAG;
-        goto done;
-    }
-
-    /* Initialize the profile information */
-    pHWProfileInfo->HWPI_ulHWProfile = 0;
-    pHWProfileInfo->HWPI_szFriendlyName[0] = 0;
-    pHWProfileInfo->HWPI_dwFlags = 0;
-
-    /* Open the 'IDConfigDB' key */
-    lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
-                             L"System\\CurrentControlSet\\Control\\IDConfigDB",
-                             0,
-                             NULL,
-                             REG_OPTION_NON_VOLATILE,
-                             KEY_QUERY_VALUE,
-                             NULL,
-                             &hKeyConfig,
-                             &dwDisposition);
-    if (lError != ERROR_SUCCESS)
-    {
-        ret = CR_REGISTRY_ERROR;
-        goto done;
-    }
-
-    /* Open the 'Hardware Profiles' subkey */
-    lError = RegCreateKeyExW(hKeyConfig,
-                             L"Hardware Profiles",
-                             0,
-                             NULL,
-                             REG_OPTION_NON_VOLATILE,
-                             KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
-                             NULL,
-                             &hKeyProfiles,
-                             &dwDisposition);
-    if (lError != ERROR_SUCCESS)
-    {
-        ret = CR_REGISTRY_ERROR;
-        goto done;
-    }
-
-    if (ulIndex == (ULONG)-1)
-    {
-        dwSize = sizeof(ULONG);
-        lError = RegQueryValueExW(hKeyConfig,
-                                  L"CurrentConfig",
-                                  NULL,
-                                  NULL,
-                                  (LPBYTE)&pHWProfileInfo->HWPI_ulHWProfile,
-                                  &dwSize);
-        if (lError != ERROR_SUCCESS)
-        {
-            pHWProfileInfo->HWPI_ulHWProfile = 0;
-            ret = CR_REGISTRY_ERROR;
-            goto done;
-        }
-    }
-    else
-    {
-        /* FIXME: not implemented yet */
-        ret = CR_CALL_NOT_IMPLEMENTED;
-        goto done;
-    }
-
-    swprintf(szProfileName, L"%04lu", pHWProfileInfo->HWPI_ulHWProfile);
-
-    lError = RegOpenKeyExW(hKeyProfiles,
-                           szProfileName,
-                           0,
-                           KEY_QUERY_VALUE,
-                           &hKeyProfile);
-    if (lError != ERROR_SUCCESS)
-    {
-        ret = CR_REGISTRY_ERROR;
-        goto done;
-    }
-
-    dwSize = sizeof(pHWProfileInfo->HWPI_szFriendlyName);
-    lError = RegQueryValueExW(hKeyProfile,
-                              L"FriendlyName",
-                              NULL,
-                              NULL,
-                              (LPBYTE)&pHWProfileInfo->HWPI_szFriendlyName,
-                              &dwSize);
-    if (lError != ERROR_SUCCESS)
-    {
-        ret = CR_REGISTRY_ERROR;
-        goto done;
-    }
-
-done:
-    if (hKeyProfile != NULL)
-        RegCloseKey(hKeyProfile);
-
-    if (hKeyProfiles != NULL)
-        RegCloseKey(hKeyProfiles);
-
-    if (hKeyConfig != NULL)
-        RegCloseKey(hKeyConfig);
-
-    return ret;
-}
-
-
-/* Function 42 */
-DWORD
-WINAPI
-PNP_AddEmptyLogConf(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulPriority,
-    DWORD *pulLogConfTag,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 43 */
-DWORD
-WINAPI
-PNP_FreeLogConf(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfType,
-    DWORD ulLogConfTag,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 44 */
-DWORD
-WINAPI
-PNP_GetFirstLogConf(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfType,
-    DWORD *pulLogConfTag,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 45 */
-DWORD
-WINAPI
-PNP_GetNextLogConf(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfType,
-    DWORD ulCurrentTag,
-    DWORD *pulNextTag,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 46 */
-DWORD
-WINAPI
-PNP_GetLogConfPriority(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulType,
-    DWORD ulTag,
-    DWORD *pPriority,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 47 */
-DWORD
-WINAPI
-PNP_AddResDes(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfTag,
-    DWORD ulLogConfType,
-    RESOURCEID ResourceID,
-    DWORD *pulResourceTag,
-    BYTE *ResourceData,
-    PNP_RPC_BUFFER_SIZE ResourceLen,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 48 */
-DWORD
-WINAPI
-PNP_FreeResDes(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfTag,
-    DWORD ulLogConfType,
-    RESOURCEID ResourceID,
-    DWORD ulResourceTag,
-    DWORD *pulPreviousResType,
-    DWORD *pulPreviousResTag,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
 
+/* GLOBALS ******************************************************************/
 
-/* Function 49 */
-DWORD
-WINAPI
-PNP_GetNextResDes(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfTag,
-    DWORD ulLogConfType,
-    RESOURCEID ResourceID,
-    DWORD ulResourceTag,
-    DWORD *pulNextResType,
-    DWORD *pulNextResTag,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 50 */
-DWORD
-WINAPI
-PNP_GetResDesData(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfTag,
-    DWORD ulLogConfType,
-    RESOURCEID ResourceID,
-    DWORD ulResourceTag,
-    BYTE *Buffer,
-    PNP_RPC_BUFFER_SIZE BufferLen,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 51 */
-DWORD
-WINAPI
-PNP_GetResDesDataSize(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfTag,
-    DWORD ulLogConfType,
-    RESOURCEID ResourceID,
-    DWORD ulResourceTag,
-    DWORD *pulSize,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 52 */
-DWORD
-WINAPI
-PNP_ModifyResDes(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    DWORD ulLogConfTag,
-    DWORD ulLogConfType,
-    RESOURCEID CurrentResourceID,
-    RESOURCEID NewResourceID,
-    DWORD ulResourceTag,
-    BYTE *ResourceData,
-    PNP_RPC_BUFFER_SIZE ResourceLen,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 53 */
-DWORD
-WINAPI
-PNP_DetectResourceConflict(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    RESOURCEID ResourceID,
-    BYTE *ResourceData,
-    PNP_RPC_BUFFER_SIZE ResourceLen,
-    BOOL *pbConflictDetected,
-    DWORD ulFlags)
-{
-    DPRINT("PNP_DetectResourceConflict()\n");
-
-    if (pbConflictDetected != NULL)
-        *pbConflictDetected = FALSE;
-
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 54 */
-DWORD
-WINAPI
-PNP_QueryResConfList(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    RESOURCEID ResourceID,
-    BYTE *ResourceData,
-    PNP_RPC_BUFFER_SIZE ResourceLen,
-    BYTE *Buffer,
-    PNP_RPC_BUFFER_SIZE BufferLen,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 55 */
-DWORD
-WINAPI
-PNP_SetHwProf(
-    handle_t hBinding,
-    DWORD ulHardwareProfile,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 56 */
-DWORD
-WINAPI
-PNP_QueryArbitratorFreeData(
-    handle_t hBinding,
-    BYTE *pData,
-    DWORD DataLen,
-    LPWSTR pDeviceID,
-    RESOURCEID ResourceID,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 57 */
-DWORD
-WINAPI
-PNP_QueryArbitratorFreeSize(
-    handle_t hBinding,
-    DWORD *pulSize,
-    LPWSTR pDeviceID,
-    RESOURCEID ResourceID,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 58 */
-CONFIGRET
-WINAPI
-PNP_RunDetection(
-    handle_t hBinding,
-    DWORD ulFlags)
-{
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 59 */
-DWORD
-WINAPI
-PNP_RegisterNotification(
-    handle_t hBinding,
-    DWORD ulFlags,
-    DWORD *pulNotify)
-{
-#if 0
-    PNOTIFY_DATA pNotifyData;
-#endif
-
-    DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
-           hBinding, ulFlags, pulNotify);
-
-#if 0
-    pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_DATA));
-    if (pNotifyData == NULL)
-        return CR_OUT_OF_MEMORY;
-
-    *pulNotify = (DWORD)pNotifyData;
-#endif
-
-    *pulNotify = 1;
-
-    return CR_SUCCESS;
-}
-
-
-/* Function 60 */
-DWORD
-WINAPI
-PNP_UnregisterNotification(
-    handle_t hBinding,
-    DWORD ulNotify)
-{
-    DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
-           hBinding, ulNotify);
-
-#if 0
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-#endif
-
-    return CR_SUCCESS;
-}
-
-
-/* Function 61 */
-DWORD
-WINAPI
-PNP_GetCustomDevProp(
-    handle_t hBinding,
-    LPWSTR pDeviceID,
-    LPWSTR CustomPropName,
-    DWORD *pulRegDataType,
-    BYTE *Buffer,
-    PNP_RPC_STRING_LEN *pulTransferLen,
-    PNP_RPC_STRING_LEN *pulLength,
-    DWORD ulFlags)
-{
-    HKEY hDeviceKey = NULL;
-    HKEY hParamKey = NULL;
-    LONG lError;
-    CONFIGRET ret = CR_SUCCESS;
-
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT("PNP_GetCustomDevProp() called\n");
-
-    if (pulTransferLen == NULL || pulLength == NULL)
-    {
-        ret = CR_INVALID_POINTER;
-        goto done;
-    }
-
-    if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
-    {
-        ret = CR_INVALID_FLAG;
-        goto done;
-    }
-
-    if (*pulLength < *pulTransferLen)
-        *pulLength = *pulTransferLen;
-
-    *pulTransferLen = 0;
-
-    lError = RegOpenKeyExW(hEnumKey,
-                           pDeviceID,
-                           0,
-                           KEY_READ,
-                           &hDeviceKey);
-    if (lError != ERROR_SUCCESS)
-    {
-        ret = CR_REGISTRY_ERROR;
-        goto done;
-    }
-
-    lError = RegOpenKeyExW(hDeviceKey,
-                           L"Device Parameters",
-                           0,
-                           KEY_READ,
-                           &hParamKey);
-    if (lError != ERROR_SUCCESS)
-    {
-        ret = CR_REGISTRY_ERROR;
-        goto done;
-    }
-
-    lError = RegQueryValueExW(hParamKey,
-                              CustomPropName,
-                              NULL,
-                              pulRegDataType,
-                              Buffer,
-                              pulLength);
-    if (lError != ERROR_SUCCESS)
-    {
-        if (lError == ERROR_MORE_DATA)
-        {
-            ret = CR_BUFFER_SMALL;
-        }
-        else
-        {
-            *pulLength = 0;
-            ret = CR_NO_SUCH_VALUE;
-        }
-    }
-
-done:
-    if (ret == CR_SUCCESS)
-        *pulTransferLen = *pulLength;
-
-    if (hParamKey != NULL)
-        RegCloseKey(hParamKey);
-
-    if (hDeviceKey != NULL)
-        RegCloseKey(hDeviceKey);
-
-    DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret);
-
-    return ret;
-}
-
-
-/* Function 62 */
-DWORD
-WINAPI
-PNP_GetVersionInternal(
-    handle_t hBinding,
-    WORD *pwVersion)
-{
-    UNREFERENCED_PARAMETER(hBinding);
-
-    *pwVersion = 0x501;
-    return CR_SUCCESS;
-}
-
-
-/* Function 63 */
-DWORD
-WINAPI
-PNP_GetBlockedDriverInfo(
-    handle_t hBinding,
-    BYTE *Buffer,
-    PNP_RPC_BUFFER_SIZE *pulTransferLen,
-    PNP_RPC_BUFFER_SIZE *pulLength,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 64 */
-DWORD
-WINAPI
-PNP_GetServerSideDeviceInstallFlags(
-    handle_t hBinding,
-    DWORD *pulSSDIFlags,
-    DWORD ulFlags)
-{
-    UNREFERENCED_PARAMETER(hBinding);
-
-    DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
-            hBinding, pulSSDIFlags, ulFlags);
-
-    if (pulSSDIFlags == NULL)
-        return CR_INVALID_POINTER;
-
-    if (ulFlags != 0)
-        return CR_INVALID_FLAG;
-
-    /* FIXME */
-    *pulSSDIFlags = 0;
-
-    return CR_SUCCESS;
-}
-
-
-/* Function 65 */
-DWORD
-WINAPI
-PNP_GetObjectPropKeys(
-    handle_t hBinding,
-    LPWSTR ObjectName,
-    DWORD ObjectType,
-    LPWSTR PropertyCultureName,
-    PNP_PROP_COUNT *PropertyCount,
-    PNP_PROP_COUNT *TransferLen,
-    DEVPROPKEY *PropertyKeys,
-    DWORD Flags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 66 */
-DWORD
-WINAPI
-PNP_GetObjectProp(
-    handle_t hBinding,
-    LPWSTR ObjectName,
-    DWORD ObjectType,
-    LPWSTR PropertyCultureName,
-    const DEVPROPKEY *PropertyKey,
-    DEVPROPTYPE *PropertyType,
-    PNP_PROP_SIZE *PropertySize,
-    PNP_PROP_SIZE *TransferLen,
-    BYTE *PropertyBuffer,
-    DWORD Flags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 67 */
-DWORD
-WINAPI
-PNP_SetObjectProp(
-    handle_t hBinding,
-    LPWSTR ObjectName,
-    DWORD ObjectType,
-    LPWSTR PropertyCultureName,
-    const DEVPROPKEY *PropertyKey,
-    DEVPROPTYPE PropertyType,
-    PNP_PROP_SIZE PropertySize,
-    BYTE *PropertyBuffer,
-    DWORD Flags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 68 */
-DWORD
-WINAPI
-PNP_InstallDevInst(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 69 */
-DWORD
-WINAPI
-PNP_ApplyPowerSettings(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 70 */
-DWORD
-WINAPI
-PNP_DriverStoreAddDriverPackage(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 71 */
-DWORD
-WINAPI
-PNP_DriverStoreDeleteDriverPackage(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 72 */
-DWORD
-WINAPI
-PNP_RegisterServiceNotification(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 73 */
-DWORD
-WINAPI
-PNP_SetActiveService(
-    handle_t hBinding,
-    LPWSTR pszFilter,
-    DWORD ulFlags)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/* Function 74 */
-DWORD
-WINAPI
-PNP_DeleteServiceDevices(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-static BOOL
-InstallDevice(PCWSTR DeviceInstance, BOOL ShowWizard)
-{
-    BOOL DeviceInstalled = FALSE;
-    DWORD BytesWritten;
-    DWORD Value;
-    HANDLE hInstallEvent;
-    HANDLE hPipe = INVALID_HANDLE_VALUE;
-    LPVOID Environment = NULL;
-    PROCESS_INFORMATION ProcessInfo;
-    STARTUPINFOW StartupInfo;
-    UUID RandomUuid;
-    HKEY DeviceKey;
-
-    /* The following lengths are constant (see below), they cannot overflow */
-    WCHAR CommandLine[116];
-    WCHAR InstallEventName[73];
-    WCHAR PipeName[74];
-    WCHAR UuidString[39];
-
-    DPRINT("InstallDevice(%S, %d)\n", DeviceInstance, ShowWizard);
-
-    ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
-
-    if (RegOpenKeyExW(hEnumKey,
-                      DeviceInstance,
-                      0,
-                      KEY_QUERY_VALUE,
-                      &DeviceKey) == ERROR_SUCCESS)
-    {
-        if (RegQueryValueExW(DeviceKey,
-                             L"Class",
-                             NULL,
-                             NULL,
-                             NULL,
-                             NULL) == ERROR_SUCCESS)
-        {
-            DPRINT("No need to install: %S\n", DeviceInstance);
-            RegCloseKey(DeviceKey);
-            return TRUE;
-        }
-
-        BytesWritten = sizeof(DWORD);
-        if (RegQueryValueExW(DeviceKey,
-                             L"ConfigFlags",
-                             NULL,
-                             NULL,
-                             (PBYTE)&Value,
-                             &BytesWritten) == ERROR_SUCCESS)
-        {
-            if (Value & CONFIGFLAG_FAILEDINSTALL)
-            {
-                DPRINT("No need to install: %S\n", DeviceInstance);
-                RegCloseKey(DeviceKey);
-                return TRUE;
-            }
-        }
-
-        RegCloseKey(DeviceKey);
-    }
-
-    DPRINT1("Installing: %S\n", DeviceInstance);
-
-    /* Create a random UUID for the named pipe & event*/
-    UuidCreate(&RandomUuid);
-    swprintf(UuidString, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
-        RandomUuid.Data1, RandomUuid.Data2, RandomUuid.Data3,
-        RandomUuid.Data4[0], RandomUuid.Data4[1], RandomUuid.Data4[2],
-        RandomUuid.Data4[3], RandomUuid.Data4[4], RandomUuid.Data4[5],
-        RandomUuid.Data4[6], RandomUuid.Data4[7]);
-
-    /* Create the event */
-    wcscpy(InstallEventName, L"Global\\PNP_Device_Install_Event_0.");
-    wcscat(InstallEventName, UuidString);
-    hInstallEvent = CreateEventW(NULL, TRUE, FALSE, InstallEventName);
-    if (!hInstallEvent)
-    {
-        DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName, GetLastError());
-        goto cleanup;
-    }
-
-    /* Create the named pipe */
-    wcscpy(PipeName, L"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
-    wcscat(PipeName, UuidString);
-    hPipe = CreateNamedPipeW(PipeName, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 512, 512, 0, NULL);
-    if (hPipe == INVALID_HANDLE_VALUE)
-    {
-        DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
-        goto cleanup;
-    }
-
-    /* Launch rundll32 to call ClientSideInstallW */
-    wcscpy(CommandLine, L"rundll32.exe newdev.dll,ClientSideInstall ");
-    wcscat(CommandLine, PipeName);
-
-    ZeroMemory(&StartupInfo, sizeof(StartupInfo));
-    StartupInfo.cb = sizeof(StartupInfo);
-
-    if (hUserToken)
-    {
-        /* newdev has to run under the environment of the current user */
-        if (!CreateEnvironmentBlock(&Environment, hUserToken, FALSE))
-        {
-            DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
-            goto cleanup;
-        }
-
-        if (!CreateProcessAsUserW(hUserToken, NULL, CommandLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, Environment, NULL, &StartupInfo, &ProcessInfo))
-        {
-            DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
-            goto cleanup;
-        }
-    }
-    else
-    {
-        /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
-
-           Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
-           (ShowWizard is only set to FALSE for these two modes) */
-        ASSERT(!ShowWizard);
-
-        if (!CreateProcessW(NULL, CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
-        {
-            DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
-            goto cleanup;
-        }
-    }
-
-    /* Wait for the function to connect to our pipe */
-    if (!ConnectNamedPipe(hPipe, NULL))
-    {
-        if (GetLastError() != ERROR_PIPE_CONNECTED)
-        {
-            DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
-            goto cleanup;
-        }
-    }
-
-    /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
-    Value = sizeof(InstallEventName);
-    WriteFile(hPipe, &Value, sizeof(Value), &BytesWritten, NULL);
-    WriteFile(hPipe, InstallEventName, Value, &BytesWritten, NULL);
-
-    /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
-       Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
-    WriteFile(hPipe, &ShowWizard, sizeof(ShowWizard), &BytesWritten, NULL);
-
-    Value = (wcslen(DeviceInstance) + 1) * sizeof(WCHAR);
-    WriteFile(hPipe, &Value, sizeof(Value), &BytesWritten, NULL);
-    WriteFile(hPipe, DeviceInstance, Value, &BytesWritten, NULL);
-
-    /* Wait for newdev.dll to finish processing */
-    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
-
-    /* If the event got signalled, this is success */
-    DeviceInstalled = WaitForSingleObject(hInstallEvent, 0) == WAIT_OBJECT_0;
-
-cleanup:
-    if (hInstallEvent)
-        CloseHandle(hInstallEvent);
-
-    if (hPipe != INVALID_HANDLE_VALUE)
-        CloseHandle(hPipe);
-
-    if (Environment)
-        DestroyEnvironmentBlock(Environment);
-
-    if (ProcessInfo.hProcess)
-        CloseHandle(ProcessInfo.hProcess);
-
-    if (ProcessInfo.hThread)
-        CloseHandle(ProcessInfo.hThread);
-
-    if (!DeviceInstalled)
-    {
-        DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance);
-    }
-
-    return DeviceInstalled;
-}
-
-
-static LONG
-ReadRegSzKey(
-    IN HKEY hKey,
-    IN LPCWSTR pszKey,
-    OUT LPWSTR* pValue)
-{
-    LONG rc;
-    DWORD dwType;
-    DWORD cbData = 0;
-    LPWSTR Value;
-
-    if (!pValue)
-        return ERROR_INVALID_PARAMETER;
-
-    *pValue = NULL;
-    rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData);
-    if (rc != ERROR_SUCCESS)
-        return rc;
-    if (dwType != REG_SZ)
-        return ERROR_FILE_NOT_FOUND;
-    Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
-    if (!Value)
-        return ERROR_NOT_ENOUGH_MEMORY;
-    rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
-    if (rc != ERROR_SUCCESS)
-    {
-        HeapFree(GetProcessHeap(), 0, Value);
-        return rc;
-    }
-    /* NULL-terminate the string */
-    Value[cbData / sizeof(WCHAR)] = '\0';
-
-    *pValue = Value;
-    return ERROR_SUCCESS;
-}
-
-
-static BOOL
-SetupIsActive(VOID)
-{
-    HKEY hKey = NULL;
-    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 != NULL)
-        RegCloseKey(hKey);
-
-    DPRINT("System setup in progress? %S\n", ret ? L"YES" : L"NO");
-
-    return ret;
-}
-
-
-static BOOL
-IsConsoleBoot(VOID)
-{
-    HKEY ControlKey = NULL;
-    LPWSTR SystemStartOptions = NULL;
-    LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
-    BOOL ConsoleBoot = FALSE;
-    LONG rc;
-
-    rc = RegOpenKeyExW(
-        HKEY_LOCAL_MACHINE,
-        L"SYSTEM\\CurrentControlSet\\Control",
-        0,
-        KEY_QUERY_VALUE,
-        &ControlKey);
-
-    rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
-    if (rc != ERROR_SUCCESS)
-        goto cleanup;
-
-    /* Check for CONSOLE switch in SystemStartOptions */
-    CurrentOption = SystemStartOptions;
-    while (CurrentOption)
-    {
-        NextOption = wcschr(CurrentOption, L' ');
-        if (NextOption)
-            *NextOption = L'\0';
-        if (_wcsicmp(CurrentOption, L"CONSOLE") == 0)
-        {
-            DPRINT("Found %S. Switching to console boot\n", CurrentOption);
-            ConsoleBoot = TRUE;
-            goto cleanup;
-        }
-        CurrentOption = NextOption ? NextOption + 1 : NULL;
-    }
-
-cleanup:
-    if (ControlKey != NULL)
-        RegCloseKey(ControlKey);
-    HeapFree(GetProcessHeap(), 0, SystemStartOptions);
-    return ConsoleBoot;
-}
-
-
-/* Loop to install all queued devices installations */
-static DWORD WINAPI
-DeviceInstallThread(LPVOID lpParameter)
-{
-    PSLIST_ENTRY ListEntry;
-    DeviceInstallParams* Params;
-    BOOL showWizard;
-
-    UNREFERENCED_PARAMETER(lpParameter);
-
-    WaitForSingleObject(hInstallEvent, INFINITE);
-
-    showWizard = !SetupIsActive() && !IsConsoleBoot();
+static WCHAR ServiceName[] = L"PlugPlay";
 
-    while (TRUE)
-    {
-        ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead);
+static SERVICE_STATUS_HANDLE ServiceStatusHandle;
+static SERVICE_STATUS ServiceStatus;
 
-        if (ListEntry == NULL)
-        {
-            SetEvent(hNoPendingInstalls);
-            WaitForSingleObject(hDeviceInstallListNotEmpty, INFINITE);
-        }
-        else
-        {
-            ResetEvent(hNoPendingInstalls);
-            Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry);
-            InstallDevice(Params->DeviceIds, showWizard);
-            HeapFree(GetProcessHeap(), 0, Params);
-        }
-    }
+HKEY hEnumKey = NULL;
+HKEY hClassKey = NULL;
 
-    return 0;
-}
 
+/* FUNCTIONS *****************************************************************/
 
 static DWORD WINAPI
 PnpEventThread(LPVOID lpParameter)
 {
+    PLUGPLAY_CONTROL_USER_RESPONSE_DATA ResponseData = {0, 0, 0, 0};
     DWORD dwRet = ERROR_SUCCESS;
     NTSTATUS Status;
     RPC_STATUS RpcStatus;
@@ -3782,7 +183,14 @@ PnpEventThread(LPVOID lpParameter)
         }
 
         /* Dequeue the current PnP event and signal the next one */
-        NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
+        Status = NtPlugPlayControl(PlugPlayControlUserResponse,
+                                   &ResponseData,
+                                   sizeof(ResponseData));
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("NtPlugPlayControl(PlugPlayControlUserResponse) failed (Status 0x%08lx)\n", Status);
+            break;
+        }
     }
 
     HeapFree(GetProcessHeap(), 0, PnpEvent);