https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fe3ae243695b3d2d9a6417...
commit fe3ae243695b3d2d9a641789a959c33d596573b0 Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Thu May 30 11:48:29 2019 +0200 Commit: Eric Kohl eric.kohl@reactos.org CommitDate: Thu May 30 11:48:29 2019 +0200
[UMPNPMGR] Split the monolithic monster: service, rpc and installer. --- base/services/umpnpmgr/CMakeLists.txt | 2 + base/services/umpnpmgr/install.c | 377 ++ base/services/umpnpmgr/precomp.h | 75 + base/services/umpnpmgr/{umpnpmgr.c => rpcserver.c} | 735 +--- base/services/umpnpmgr/umpnpmgr.c | 4091 +------------------- 5 files changed, 463 insertions(+), 4817 deletions(-)
diff --git a/base/services/umpnpmgr/CMakeLists.txt b/base/services/umpnpmgr/CMakeLists.txt index 4248d0e9d8..7c344f9914 100644 --- a/base/services/umpnpmgr/CMakeLists.txt +++ b/base/services/umpnpmgr/CMakeLists.txt @@ -4,6 +4,8 @@ add_rpc_files(server ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/pnp.idl) spec2def(umpnpmgr.dll umpnpmgr.spec ADD_IMPORTLIB)
add_library(umpnpmgr MODULE + install.c + rpcserver.c umpnpmgr.c umpnpmgr.rc ${CMAKE_CURRENT_BINARY_DIR}/pnp_s.c diff --git a/base/services/umpnpmgr/install.c b/base/services/umpnpmgr/install.c new file mode 100644 index 0000000000..2f3bdfd105 --- /dev/null +++ b/base/services/umpnpmgr/install.c @@ -0,0 +1,377 @@ +/* + * ReactOS kernel + * Copyright (C) 2005 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: base/services/umpnpmgr/install.c + * PURPOSE: Device installer + * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org) + * Herv� Poussineau (hpoussin@reactos.org) + * Colin Finck (colin@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include "precomp.h" + +#define NDEBUG +#include <debug.h> + + +/* GLOBALS ******************************************************************/ + +HANDLE hUserToken = NULL; +HANDLE hInstallEvent = NULL; +HANDLE hNoPendingInstalls = NULL; + +SLIST_HEADER DeviceInstallListHead; +HANDLE hDeviceInstallListNotEmpty; + + +/* FUNCTIONS *****************************************************************/ + +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; +} + + +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, ®Type, (LPBYTE)&active, &size); + if (rc != ERROR_SUCCESS) + goto cleanup; + if (regType != REG_DWORD || size != sizeof(DWORD)) + goto cleanup; + + ret = (active != 0); + +cleanup: + if (hKey != 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 */ +DWORD +WINAPI +DeviceInstallThread(LPVOID lpParameter) +{ + PSLIST_ENTRY ListEntry; + DeviceInstallParams* Params; + BOOL showWizard; + + UNREFERENCED_PARAMETER(lpParameter); + + WaitForSingleObject(hInstallEvent, INFINITE); + + showWizard = !SetupIsActive() && !IsConsoleBoot(); + + while (TRUE) + { + ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead); + + 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); + } + } + + return 0; +} diff --git a/base/services/umpnpmgr/precomp.h b/base/services/umpnpmgr/precomp.h new file mode 100644 index 0000000000..3c51aa47b2 --- /dev/null +++ b/base/services/umpnpmgr/precomp.h @@ -0,0 +1,75 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: base/services/umpnpmgr/install.c + * PURPOSE: Device installer + * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org) + * Herv� Poussineau (hpoussin@reactos.org) + * Colin Finck (colin@reactos.org) + */ + +#ifndef _UMPNPMGR_PCH_ +#define _UMPNPMGR_PCH_ + +#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> + + +typedef struct +{ + SLIST_ENTRY ListEntry; + WCHAR DeviceIds[1]; +} DeviceInstallParams; + + +/* install.c */ + +extern HANDLE hUserToken; +extern HANDLE hInstallEvent; +extern HANDLE hNoPendingInstalls; + +extern SLIST_HEADER DeviceInstallListHead; +extern HANDLE hDeviceInstallListNotEmpty; + +BOOL +SetupIsActive(VOID); + +DWORD +WINAPI +DeviceInstallThread( + LPVOID lpParameter); + + +/* rpcserver.c */ + +DWORD +WINAPI +RpcServerThread( + LPVOID lpParameter); + + +/* umpnpmgr.c */ + +extern HKEY hEnumKey; +extern HKEY hClassKey; + + +#endif /* _UMPNPMGR_PCH_ */ \ No newline at end of file diff --git a/base/services/umpnpmgr/umpnpmgr.c b/base/services/umpnpmgr/rpcserver.c similarity index 79% copy from base/services/umpnpmgr/umpnpmgr.c copy to base/services/umpnpmgr/rpcserver.c index 4248879a50..2d0c02da95 100644 --- a/base/services/umpnpmgr/umpnpmgr.c +++ b/base/services/umpnpmgr/rpcserver.c @@ -19,8 +19,8 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: base/services/umpnpmgr/umpnpmgr.c - * PURPOSE: User-mode Plug and Play manager + * FILE: base/services/umpnpmgr/rpcserver.c + * PURPOSE: RPC server * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org) * Herv� Poussineau (hpoussin@reactos.org) * Colin Finck (colin@reactos.org) @@ -28,58 +28,20 @@
/* 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; +/* GLOBALS ******************************************************************/
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 +DWORD WINAPI RpcServerThread(LPVOID lpParameter) { RPC_STATUS Status; @@ -3798,690 +3760,3 @@ PNP_DeleteServiceDevices( 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, ®Type, (LPBYTE)&active, &size); - if (rc != ERROR_SUCCESS) - goto cleanup; - if (regType != REG_DWORD || size != sizeof(DWORD)) - goto cleanup; - - ret = (active != 0); - -cleanup: - if (hKey != 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(); - - while (TRUE) - { - ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead); - - 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); - } - } - - return 0; -} - - -static DWORD WINAPI -PnpEventThread(LPVOID lpParameter) -{ - DWORD dwRet = ERROR_SUCCESS; - NTSTATUS Status; - RPC_STATUS RpcStatus; - PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent; - ULONG PnpEventSize; - - UNREFERENCED_PARAMETER(lpParameter); - - PnpEventSize = 0x1000; - PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize); - if (PnpEvent == NULL) - return ERROR_OUTOFMEMORY; - - for (;;) - { - DPRINT("Calling NtGetPlugPlayEvent()\n"); - - /* Wait for the next PnP event */ - Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize); - - /* Resize the buffer for the PnP event if it's too small */ - if (Status == STATUS_BUFFER_TOO_SMALL) - { - PnpEventSize += 0x400; - NewPnpEvent = HeapReAlloc(GetProcessHeap(), 0, PnpEvent, PnpEventSize); - if (NewPnpEvent == NULL) - { - dwRet = ERROR_OUTOFMEMORY; - break; - } - PnpEvent = NewPnpEvent; - continue; - } - - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status); - break; - } - - /* Process the PnP event */ - DPRINT("Received PnP Event\n"); - if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ENUMERATED, &RpcStatus)) - { - DeviceInstallParams* Params; - DWORD len; - DWORD DeviceIdLength; - - DPRINT("Device enumerated: %S\n", PnpEvent->TargetDevice.DeviceIds); - - DeviceIdLength = lstrlenW(PnpEvent->TargetDevice.DeviceIds); - if (DeviceIdLength) - { - /* Queue device install (will be dequeued by DeviceInstallThread) */ - len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR); - Params = HeapAlloc(GetProcessHeap(), 0, len); - if (Params) - { - wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds); - InterlockedPushEntrySList(&DeviceInstallListHead, &Params->ListEntry); - SetEvent(hDeviceInstallListNotEmpty); - } - } - } - else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus)) - { -// DWORD dwRecipient; - - DPRINT("Device arrival: %S\n", PnpEvent->TargetDevice.DeviceIds); - -// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS; -// BroadcastSystemMessageW(BSF_POSTMESSAGE, -// &dwRecipient, -// WM_DEVICECHANGE, -// DBT_DEVNODES_CHANGED, -// 0); - SendMessageW(HWND_BROADCAST, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, 0); - } - else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_EJECT_VETOED, &RpcStatus)) - { - DPRINT1("Eject vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds); - } - else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_KERNEL_INITIATED_EJECT, &RpcStatus)) - { - DPRINT1("Kernel initiated eject: %S\n", PnpEvent->TargetDevice.DeviceIds); - } - else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SAFE_REMOVAL, &RpcStatus)) - { -// DWORD dwRecipient; - - DPRINT1("Safe removal: %S\n", PnpEvent->TargetDevice.DeviceIds); - -// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS; -// BroadcastSystemMessageW(BSF_POSTMESSAGE, -// &dwRecipient, -// WM_DEVICECHANGE, -// DBT_DEVNODES_CHANGED, -// 0); - SendMessageW(HWND_BROADCAST, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, 0); - } - else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SURPRISE_REMOVAL, &RpcStatus)) - { -// DWORD dwRecipient; - - DPRINT1("Surprise removal: %S\n", PnpEvent->TargetDevice.DeviceIds); - -// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS; -// BroadcastSystemMessageW(BSF_POSTMESSAGE, -// &dwRecipient, -// WM_DEVICECHANGE, -// DBT_DEVNODES_CHANGED, -// 0); - SendMessageW(HWND_BROADCAST, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, 0); - } - else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVAL_VETOED, &RpcStatus)) - { - DPRINT1("Removal vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds); - } - else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVE_PENDING, &RpcStatus)) - { - DPRINT1("Removal pending: %S\n", PnpEvent->TargetDevice.DeviceIds); - } - else - { - DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n", - PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3, - PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2], - PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5], - PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]); - } - - /* Dequeue the current PnP event and signal the next one */ - NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0); - } - - HeapFree(GetProcessHeap(), 0, PnpEvent); - - return dwRet; -} - - -static VOID -UpdateServiceStatus(DWORD dwState) -{ - ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - ServiceStatus.dwCurrentState = dwState; - ServiceStatus.dwControlsAccepted = 0; - ServiceStatus.dwWin32ExitCode = 0; - ServiceStatus.dwServiceSpecificExitCode = 0; - ServiceStatus.dwCheckPoint = 0; - - if (dwState == SERVICE_START_PENDING || - dwState == SERVICE_STOP_PENDING || - dwState == SERVICE_PAUSE_PENDING || - dwState == SERVICE_CONTINUE_PENDING) - ServiceStatus.dwWaitHint = 10000; - else - ServiceStatus.dwWaitHint = 0; - - SetServiceStatus(ServiceStatusHandle, - &ServiceStatus); -} - - -static DWORD WINAPI -ServiceControlHandler(DWORD dwControl, - DWORD dwEventType, - LPVOID lpEventData, - LPVOID lpContext) -{ - DPRINT1("ServiceControlHandler() called\n"); - - switch (dwControl) - { - case SERVICE_CONTROL_STOP: - DPRINT1(" SERVICE_CONTROL_STOP received\n"); - /* Stop listening to RPC Messages */ - RpcMgmtStopServerListening(NULL); - UpdateServiceStatus(SERVICE_STOPPED); - return ERROR_SUCCESS; - - case SERVICE_CONTROL_PAUSE: - DPRINT1(" SERVICE_CONTROL_PAUSE received\n"); - UpdateServiceStatus(SERVICE_PAUSED); - return ERROR_SUCCESS; - - case SERVICE_CONTROL_CONTINUE: - DPRINT1(" SERVICE_CONTROL_CONTINUE received\n"); - UpdateServiceStatus(SERVICE_RUNNING); - return ERROR_SUCCESS; - - case SERVICE_CONTROL_INTERROGATE: - DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n"); - SetServiceStatus(ServiceStatusHandle, - &ServiceStatus); - return ERROR_SUCCESS; - - case SERVICE_CONTROL_SHUTDOWN: - DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n"); - /* Stop listening to RPC Messages */ - RpcMgmtStopServerListening(NULL); - UpdateServiceStatus(SERVICE_STOPPED); - return ERROR_SUCCESS; - - default : - DPRINT1(" Control %lu received\n", dwControl); - return ERROR_CALL_NOT_IMPLEMENTED; - } -} - - -VOID WINAPI -ServiceMain(DWORD argc, LPTSTR *argv) -{ - HANDLE hThread; - DWORD dwThreadId; - - UNREFERENCED_PARAMETER(argc); - UNREFERENCED_PARAMETER(argv); - - DPRINT("ServiceMain() called\n"); - - ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, - ServiceControlHandler, - NULL); - if (!ServiceStatusHandle) - { - DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError()); - return; - } - - UpdateServiceStatus(SERVICE_START_PENDING); - - hThread = CreateThread(NULL, - 0, - PnpEventThread, - NULL, - 0, - &dwThreadId); - if (hThread != NULL) - CloseHandle(hThread); - - hThread = CreateThread(NULL, - 0, - RpcServerThread, - NULL, - 0, - &dwThreadId); - if (hThread != NULL) - CloseHandle(hThread); - - hThread = CreateThread(NULL, - 0, - DeviceInstallThread, - NULL, - 0, - &dwThreadId); - if (hThread != NULL) - CloseHandle(hThread); - - UpdateServiceStatus(SERVICE_RUNNING); - - DPRINT("ServiceMain() done\n"); -} - -static DWORD -InitializePnPManager(VOID) -{ - BOOLEAN OldValue; - DWORD dwError; - - DPRINT("UMPNPMGR: InitializePnPManager() started\n"); - - /* We need this privilege for using CreateProcessAsUserW */ - RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &OldValue); - - hInstallEvent = CreateEventW(NULL, TRUE, SetupIsActive()/*FALSE*/, NULL); - if (hInstallEvent == NULL) - { - dwError = GetLastError(); - DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError); - return dwError; - } - - hDeviceInstallListNotEmpty = CreateEventW(NULL, FALSE, FALSE, NULL); - if (hDeviceInstallListNotEmpty == NULL) - { - dwError = GetLastError(); - DPRINT1("Could not create the Event! (Error %lu)\n", dwError); - return dwError; - } - - hNoPendingInstalls = CreateEventW(NULL, - TRUE, - FALSE, - L"Global\PnP_No_Pending_Install_Events"); - if (hNoPendingInstalls == NULL) - { - dwError = GetLastError(); - DPRINT1("Could not create the Event! (Error %lu)\n", dwError); - return dwError; - } - - InitializeSListHead(&DeviceInstallListHead); - - dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"System\CurrentControlSet\Enum", - 0, - KEY_ALL_ACCESS, - &hEnumKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError); - return dwError; - } - - dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"System\CurrentControlSet\Control\Class", - 0, - KEY_ALL_ACCESS, - &hClassKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError); - return dwError; - } - - DPRINT("UMPNPMGR: InitializePnPManager() done\n"); - - return 0; -} - -BOOL WINAPI -DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - InitializePnPManager(); - break; - - case DLL_PROCESS_DETACH: - break; - } - - return TRUE; -} - -/* EOF */ diff --git a/base/services/umpnpmgr/umpnpmgr.c b/base/services/umpnpmgr/umpnpmgr.c index 4248879a50..e26fa2f64d 100644 --- a/base/services/umpnpmgr/umpnpmgr.c +++ b/base/services/umpnpmgr/umpnpmgr.c @@ -28,30 +28,12 @@
/* 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"; @@ -59,4077 +41,12 @@ 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; +HKEY hEnumKey = NULL; +HKEY hClassKey = NULL;
-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 -GetRelationsInstanceList( - _In_ PWSTR pszDevice, - _In_ DWORD ulFlags, - _Inout_ PWSTR pszBuffer, - _Inout_ PDWORD pulLength) -{ - PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData; - NTSTATUS Status; - CONFIGRET ret = CR_SUCCESS; - - RtlInitUnicodeString(&PlugPlayData.DeviceInstance, - pszDevice); - - 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 = pszBuffer; - - Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations, - (PVOID)&PlugPlayData, - sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA)); - if (NT_SUCCESS(Status)) - { - *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR); - } - else - { - ret = NtStatusToCrError(Status); - } - - return ret; -} - - -static -CONFIGRET -GetServiceInstanceList( - _In_ PWSTR pszService, - _Inout_ PWSTR pszBuffer, - _Inout_ PDWORD pulLength) -{ - WCHAR szPathBuffer[512]; - WCHAR szName[16]; - HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL; - DWORD dwValues, dwSize, dwIndex, dwUsedLength, dwPathLength; - DWORD dwError; - PWSTR pPtr; - CONFIGRET ret = CR_SUCCESS; - - /* Open the device key */ - dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"System\CurrentControlSet\Services", - 0, - KEY_READ, - &hServicesKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT("Failed to open the services key (Error %lu)\n", dwError); - return CR_REGISTRY_ERROR; - } - - dwError = RegOpenKeyExW(hServicesKey, - pszService, - 0, - KEY_READ, - &hServiceKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT("Failed to open the service key (Error %lu)\n", dwError); - ret = CR_REGISTRY_ERROR; - goto Done; - } - - dwError = RegOpenKeyExW(hServiceKey, - L"Enum", - 0, - KEY_READ, - &hEnumKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT("Failed to open the service enum key (Error %lu)\n", dwError); - ret = CR_REGISTRY_ERROR; - goto Done; - } - - /* Retrieve the number of device instances */ - dwSize = sizeof(DWORD); - dwError = RegQueryValueExW(hEnumKey, - L"Count", - NULL, - NULL, - (LPBYTE)&dwValues, - &dwSize); - if (dwError != ERROR_SUCCESS) - { - DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError); - dwValues = 1; - } - - DPRINT("dwValues %lu\n", dwValues); - - dwUsedLength = 0; - pPtr = pszBuffer; - - for (dwIndex = 0; dwIndex < dwValues; dwIndex++) - { - wsprintf(szName, L"%lu", dwIndex); - - dwSize = sizeof(szPathBuffer); - dwError = RegQueryValueExW(hEnumKey, - szName, - NULL, - NULL, - (LPBYTE)szPathBuffer, - &dwSize); - if (dwError != ERROR_SUCCESS) - break; - - 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; - } - -Done: - if (hEnumKey != NULL) - RegCloseKey(hEnumKey); - - if (hServiceKey != NULL) - RegCloseKey(hServiceKey); - - if (hServicesKey != NULL) - RegCloseKey(hServicesKey); - - if (ret == CR_SUCCESS) - *pulLength = dwUsedLength + 1; - else - *pulLength = 0; - - 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; - - /* Open the device key */ - 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; -} - - -CONFIGRET -GetEnumeratorInstanceList( - _In_ PWSTR pszEnumerator, - _Inout_ PWSTR pszBuffer, - _Inout_ PDWORD pulLength) -{ - WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN]; - WCHAR szPathBuffer[512]; - HKEY hEnumeratorKey; - PWSTR pPtr; - DWORD dwIndex, dwDeviceLength, dwUsedLength, dwRemainingLength, dwPathLength; - DWORD dwError; - CONFIGRET ret = CR_SUCCESS; - - /* Open the enumerator key */ - dwError = RegOpenKeyExW(hEnumKey, - pszEnumerator, - 0, - KEY_ENUMERATE_SUB_KEYS, - &hEnumeratorKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError); - return CR_REGISTRY_ERROR; - } - - dwUsedLength = 0; - dwRemainingLength = *pulLength; - pPtr = pszBuffer; - - for (dwIndex = 0; ; dwIndex++) - { - dwDeviceLength = MAX_DEVICE_ID_LEN; - dwError = RegEnumKeyExW(hEnumeratorKey, - dwIndex, - szDeviceBuffer, - &dwDeviceLength, - NULL, - NULL, - NULL, - NULL); - if (dwError != ERROR_SUCCESS) - break; - - wsprintf(szPathBuffer, L"%s\%s", pszEnumerator, szDeviceBuffer); - DPRINT("Path: %S\n", szPathBuffer); - - dwPathLength = dwRemainingLength; - ret = GetDeviceInstanceList(szPathBuffer, - pPtr, - &dwPathLength); - if (ret != CR_SUCCESS) - break; - - dwUsedLength += dwPathLength - 1; - dwRemainingLength += dwPathLength - 1; - pPtr += dwPathLength - 1; - } - - RegCloseKey(hEnumeratorKey); - - if (ret == CR_SUCCESS) - *pulLength = dwUsedLength + 1; - else - *pulLength = 0; - - return ret; -} - - -static -CONFIGRET -GetAllInstanceList( - _Inout_ PWSTR pszBuffer, - _Inout_ PDWORD pulLength) -{ - WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN]; - PWSTR pPtr; - DWORD dwIndex, dwEnumeratorLength, dwUsedLength, dwRemainingLength, dwPathLength; - DWORD dwError; - CONFIGRET ret = CR_SUCCESS; - - dwUsedLength = 0; - dwRemainingLength = *pulLength; - pPtr = pszBuffer; - - for (dwIndex = 0; ; dwIndex++) - { - dwEnumeratorLength = MAX_DEVICE_ID_LEN; - dwError = RegEnumKeyExW(hEnumKey, - dwIndex, - szEnumeratorBuffer, - &dwEnumeratorLength, - NULL, NULL, NULL, NULL); - if (dwError != ERROR_SUCCESS) - break; - - dwPathLength = dwRemainingLength; - ret = GetEnumeratorInstanceList(szEnumeratorBuffer, - pPtr, - &dwPathLength); - if (ret != CR_SUCCESS) - break; - - dwUsedLength += dwPathLength - 1; - dwRemainingLength += dwPathLength - 1; - pPtr += dwPathLength - 1; - } - - 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) -{ - WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; - WCHAR szDevice[MAX_DEVICE_ID_LEN]; - WCHAR szInstance[MAX_DEVICE_ID_LEN]; - CONFIGRET ret = CR_SUCCESS; - - 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)) - { - ret = GetRelationsInstanceList(pszFilter, - ulFlags, - Buffer, - pulLength); - } - else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE) - { - ret = GetServiceInstanceList(pszFilter, - Buffer, - pulLength); - } - 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 = GetEnumeratorInstanceList(pszFilter, - Buffer, - pulLength); - } - } - else /* CM_GETIDLIST_FILTER_NONE */ - { - ret = GetAllInstanceList(Buffer, - pulLength); - } - - return ret; -} - - -static -CONFIGRET -GetRelationsInstanceListSize( - _In_ PWSTR pszDevice, - _In_ DWORD ulFlags, - _Inout_ PDWORD pulLength) -{ - PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData; - NTSTATUS Status; - CONFIGRET ret = CR_SUCCESS; - - RtlInitUnicodeString(&PlugPlayData.DeviceInstance, - pszDevice); - - 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); - } - - return ret; -} - - -static -CONFIGRET -GetServiceInstanceListSize( - _In_ PWSTR pszService, - _Out_ PDWORD pulLength) -{ - HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL; - DWORD dwValues, dwMaxValueLength, dwSize; - DWORD dwError; - CONFIGRET ret = CR_SUCCESS; - - /* Open the device key */ - dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"System\CurrentControlSet\Services", - 0, - KEY_READ, - &hServicesKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT("Failed to open the services key (Error %lu)\n", dwError); - return CR_REGISTRY_ERROR; - } - - dwError = RegOpenKeyExW(hServicesKey, - pszService, - 0, - KEY_READ, - &hServiceKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT("Failed to open the service key (Error %lu)\n", dwError); - ret = CR_REGISTRY_ERROR; - goto Done; - } - - dwError = RegOpenKeyExW(hServiceKey, - L"Enum", - 0, - KEY_READ, - &hEnumKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT("Failed to open the service enum key (Error %lu)\n", dwError); - ret = CR_REGISTRY_ERROR; - goto Done; - } - - /* Retrieve the number of device instances */ - dwSize = sizeof(DWORD); - dwError = RegQueryValueExW(hEnumKey, - L"Count", - NULL, - NULL, - (LPBYTE)&dwValues, - &dwSize); - if (dwError != ERROR_SUCCESS) - { - DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError); - dwValues = 1; - } - - /* Retrieve the maximum instance name length */ - dwError = RegQueryInfoKeyW(hEnumKey, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - &dwMaxValueLength, - NULL, - NULL); - if (dwError != ERROR_SUCCESS) - { - DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError); - dwMaxValueLength = MAX_DEVICE_ID_LEN; - } - - DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues, dwMaxValueLength / sizeof(WCHAR)); - - /* Return the largest possible buffer size */ - *pulLength = dwValues * dwMaxValueLength / sizeof(WCHAR) + 2; - -Done: - if (hEnumKey != NULL) - RegCloseKey(hEnumKey); - - if (hServiceKey != NULL) - RegCloseKey(hServiceKey); - - if (hServicesKey != NULL) - RegCloseKey(hServicesKey); - - 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); - - return CR_SUCCESS; -} - - -static -CONFIGRET -GetEnumeratorInstanceListSize( - _In_ LPCWSTR pszEnumerator, - _Out_ PULONG pulLength) -{ - WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN]; - WCHAR szPathBuffer[512]; - HKEY hEnumeratorKey; - DWORD dwIndex, dwDeviceLength, dwBufferLength; - DWORD dwError; - CONFIGRET ret = CR_SUCCESS; - - *pulLength = 0; - - /* Open the enumerator key */ - dwError = RegOpenKeyExW(hEnumKey, - pszEnumerator, - 0, - KEY_ENUMERATE_SUB_KEYS, - &hEnumeratorKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError); - return CR_REGISTRY_ERROR; - } - - for (dwIndex = 0; ; dwIndex++) - { - dwDeviceLength = MAX_DEVICE_ID_LEN; - dwError = RegEnumKeyExW(hEnumeratorKey, - dwIndex, - szDeviceBuffer, - &dwDeviceLength, - NULL, - NULL, - NULL, - NULL); - if (dwError != ERROR_SUCCESS) - break; - - wsprintf(szPathBuffer, L"%s\%s", pszEnumerator, szDeviceBuffer); - DPRINT("Path: %S\n", szPathBuffer); - - ret = GetDeviceInstanceListSize(szPathBuffer, &dwBufferLength); - if (ret != CR_SUCCESS) - { - *pulLength = 0; - break; - } - - *pulLength += dwBufferLength; - } - - /* Close the enumerator key */ - RegCloseKey(hEnumeratorKey); - - return ret; -} - - -static -CONFIGRET -GetAllInstanceListSize( - _Out_ PULONG pulLength) -{ - WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN]; - DWORD dwIndex, dwEnumeratorLength, dwBufferLength; - DWORD dwError; - CONFIGRET ret = CR_SUCCESS; - - for (dwIndex = 0; ; dwIndex++) - { - dwEnumeratorLength = MAX_DEVICE_ID_LEN; - dwError = RegEnumKeyExW(hEnumKey, - dwIndex, - szEnumeratorBuffer, - &dwEnumeratorLength, - NULL, NULL, NULL, NULL); - if (dwError != ERROR_SUCCESS) - break; - - /* Get the size of all device instances for the enumerator */ - ret = GetEnumeratorInstanceListSize(szEnumeratorBuffer, - &dwBufferLength); - if (ret != CR_SUCCESS) - break; - - *pulLength += dwBufferLength; - } - - return ret; -} - - -/* Function 11 */ -DWORD -WINAPI -PNP_GetDeviceListSize( - handle_t hBinding, - LPWSTR pszFilter, - PNP_RPC_BUFFER_SIZE *pulLength, - DWORD ulFlags) -{ - WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; - WCHAR szDevice[MAX_DEVICE_ID_LEN]; - WCHAR szInstance[MAX_DEVICE_ID_LEN]; - CONFIGRET ret = CR_SUCCESS; - - DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%lx)\n", - hBinding, pszFilter, pulLength, ulFlags); - - 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)) - { - ret = GetRelationsInstanceListSize(pszFilter, - ulFlags, - pulLength); - } - else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE) - { - ret = GetServiceInstanceListSize(pszFilter, - pulLength); - } - 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 = GetEnumeratorInstanceListSize(pszFilter, - pulLength); - } - } - else /* CM_GETIDLIST_FILTER_NONE */ - { - ret = GetAllInstanceListSize(pulLength); - } - - /* Add one character for the terminating double UNICODE_NULL */ - if (ret == CR_SUCCESS) - (*pulLength) += 1; - - 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; -} - - -/* 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) -{ - return CR_CALL_NOT_IMPLEMENTED; -} - - -/* Function 57 */ -DWORD -WINAPI -PNP_QueryArbitratorFreeSize( - handle_t hBinding, - DWORD *pulSize, - LPWSTR pDeviceID, - RESOURCEID ResourceID, - DWORD ulFlags) -{ - if (pulSize != NULL) - *pulSize = 0; - - 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; -} ... 381 lines suppressed ...