+++ /dev/null
-/*
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: services/umpnpmgr/umpnpmgr.c
- * PURPOSE: User-mode Plug and Play manager
- * PROGRAMMER: Eric Kohl
- * Hervé Poussineau (hpoussin@reactos.org)
- */
-
-/* INCLUDES *****************************************************************/
-#define WIN32_NO_STATUS
-#include <windows.h>
-#include <cmtypes.h>
-#include <cmfuncs.h>
-#include <rtlfuncs.h>
-#include <umpnpmgr/sysguid.h>
-#include <wdmguid.h>
-#include <cfgmgr32.h>
-
-#include <rpc.h>
-#include <rpcdce.h>
-
-#include "pnp_c.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* GLOBALS ******************************************************************/
-
-static VOID CALLBACK
-ServiceMain(DWORD argc, LPTSTR *argv);
-
-static SERVICE_TABLE_ENTRY ServiceTable[2] =
-{
- {TEXT("PlugPlay"), ServiceMain},
- {NULL, NULL}
-};
-
-static WCHAR szRootDeviceId[] = L"HTREE\\ROOT\\0";
-
-static HKEY hEnumKey = NULL;
-static HKEY hClassKey = NULL;
-
-static HANDLE hUserToken = NULL;
-static HANDLE hInstallEvent = NULL;
-
-
-/* FUNCTIONS *****************************************************************/
-
-static DWORD WINAPI
-RpcServerThread(LPVOID lpParameter)
-{
- RPC_STATUS Status;
-
- DPRINT("RpcServerThread() called\n");
-
- Status = RpcServerUseProtseqEpW(L"ncacn_np",
- 20,
- L"\\pipe\\umpnpmgr",
- NULL); // Security descriptor
- if (Status != RPC_S_OK)
- {
- DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
- 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;
- }
-
- 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_NO_SUCH_DEVICE:
- return CR_NO_SUCH_DEVINST;
-
- default:
- /* FIXME: add more mappings */
- DPRINT1("Unable to map status 0x%08lx\n", Status);
- return CR_FAILURE;
- }
-}
-
-
-/* Function 2 */
-CONFIGRET
-PNP_GetVersion(handle_t BindingHandle,
- unsigned short *Version)
-{
- *Version = 0x0400;
- return CR_SUCCESS;
-}
-
-
-/* Function 3 */
-CONFIGRET
-PNP_GetGlobalState(handle_t BindingHandle,
- unsigned long *State,
- unsigned long Flags)
-{
- *State = CM_GLOBAL_STATE_CAN_DO_UI | CM_GLOBAL_STATE_SERVICES_AVAILABLE;
- return CR_SUCCESS;
-}
-
-
-/* Function 4 */
-CONFIGRET
-PNP_InitDetection(handle_t BindingHandle)
-{
- DPRINT("PNP_InitDetection() called\n");
- return CR_SUCCESS;
-}
-
-
-/* Function 5 */
-CONFIGRET
-PNP_ReportLogOn(handle_t BindingHandle,
- unsigned long Admin,
- unsigned long ProcessId)
-{
- HANDLE hProcess;
-
- DPRINT1("PNP_ReportLogOn(%lu, %lu) called\n", Admin, ProcessId);
-
- /* Get the users token */
- hProcess = OpenProcess(PROCESS_ALL_ACCESS,
- TRUE,
- ProcessId);
- if (hProcess != NULL)
- {
- if (hUserToken != NULL)
- {
- CloseHandle(hUserToken);
- hUserToken = NULL;
- }
-
- OpenProcessToken(hProcess,
- TOKEN_ALL_ACCESS,
- &hUserToken);
- CloseHandle(hProcess);
- }
-
- /* Trigger the installer thread */
- if (hInstallEvent != NULL)
- SetEvent(hInstallEvent);
-
- return CR_SUCCESS;
-}
-
-
-/* Function 6 */
-CONFIGRET
-PNP_ValidateDeviceInstance(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
- HKEY hEnumKey = NULL;
- HKEY hDeviceKey = NULL;
-
- DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
- DeviceInstance, Flags);
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"System\\CurrentControlSet\\Enum",
- 0,
- KEY_ALL_ACCESS,
- &hEnumKey))
- {
- DPRINT("Could not open the Enum Key!\n");
- ret = CR_FAILURE;
- goto Done;
- }
-
- if (RegOpenKeyExW(hEnumKey,
- DeviceInstance,
- 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);
-
- if (hEnumKey != NULL)
- RegCloseKey(hEnumKey);
-
- DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 7 */
-CONFIGRET
-PNP_GetRootDeviceInstance(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long Length)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_GetRootDeviceInstance() called\n");
-
- if (Length < lstrlenW(szRootDeviceId) + 1)
- {
- ret = CR_BUFFER_SMALL;
- goto Done;
- }
-
- lstrcpyW(DeviceInstance,
- szRootDeviceId);
-
-Done:
- DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 8 */
-CONFIGRET
-PNP_GetRelatedDeviceInstance(handle_t BindingHandle,
- unsigned long Relationship,
- wchar_t *DeviceId,
- wchar_t *RelatedDeviceId,
- unsigned long Length,
- unsigned long Flags)
-{
- PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData;
- CONFIGRET ret = CR_SUCCESS;
- NTSTATUS Status;
-
- DPRINT("PNP_GetRelatedDeviceInstance() called\n");
- DPRINT(" Relationship %ld\n", Relationship);
- DPRINT(" DeviceId %S\n", DeviceId);
-
- RtlInitUnicodeString(&PlugPlayData.TargetDeviceInstance,
- DeviceId);
-
- PlugPlayData.Relation = Relationship;
-
- PlugPlayData.RelatedDeviceInstance.Length = 0;
- PlugPlayData.RelatedDeviceInstance.MaximumLength = Length;
- PlugPlayData.RelatedDeviceInstance.Buffer = RelatedDeviceId;
-
- 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 */
-CONFIGRET
-PNP_EnumerateSubKeys(handle_t BindingHandle,
- unsigned long Branch,
- unsigned long Index,
- wchar_t *Buffer,
- unsigned long Length,
- unsigned long *RequiredLength,
- DWORD Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
- HKEY hKey;
- DWORD dwError;
-
- DPRINT("PNP_EnumerateSubKeys() called\n");
-
- switch (Branch)
- {
- case PNP_BRANCH_ENUM:
- hKey = hEnumKey;
- break;
-
- case PNP_BRANCH_CLASS:
- hKey = hClassKey;
- break;
-
- default:
- return CR_FAILURE;
- }
-
- *RequiredLength = Length;
- dwError = RegEnumKeyExW(hKey,
- Index,
- Buffer,
- RequiredLength,
- NULL,
- NULL,
- NULL,
- NULL);
- if (dwError != ERROR_SUCCESS)
- {
- ret = (dwError == ERROR_NO_MORE_ITEMS) ? CR_NO_SUCH_VALUE : CR_FAILURE;
- }
- else
- {
- (*RequiredLength)++;
- }
-
- DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 11 */
-CONFIGRET
-PNP_GetDeviceListSize(handle_t BindingHandle,
- wchar_t *Filter,
- unsigned long *Length,
- DWORD Flags)
-{
- DPRINT("PNP_GetDeviceListSize() called\n");
-
- /* FIXME */
- *Length = 2;
-
- return CR_SUCCESS;
-}
-
-
-/* Function 12 */
-CONFIGRET
-PNP_GetDepth(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long *Depth,
- DWORD Flags)
-{
- PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData;
- CONFIGRET ret = CR_SUCCESS;
- NTSTATUS Status;
-
- DPRINT("PNP_GetDepth() called\n");
-
- RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
- DeviceInstance);
-
- Status = NtPlugPlayControl(PlugPlayControlGetDeviceDepth,
- (PVOID)&PlugPlayData,
- sizeof(PLUGPLAY_CONTROL_DEPTH_DATA));
- if (NT_SUCCESS(Status))
- {
- *Depth = PlugPlayData.Depth;
- }
- else
- {
- ret = NtStatusToCrError(Status);
- }
-
- DPRINT("PNP_GetDepth() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 13 */
-CONFIGRET
-PNP_GetDeviceRegProp(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long Property,
- unsigned long *DataType,
- char *Buffer,
- unsigned long *TransferLen,
- unsigned long *Length,
- DWORD Flags)
-{
- PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData;
- CONFIGRET ret = CR_SUCCESS;
- LPWSTR lpValueName = NULL;
- HKEY hKey = 0;
- NTSTATUS Status;
-
- DPRINT("PNP_GetDeviceRegProp() called\n");
-
- switch (Property)
- {
- case CM_DRP_DEVICEDESC:
- lpValueName = L"DeviceDesc";
- break;
-
- case CM_DRP_HARDWAREID:
- lpValueName = L"HardwareID";
- break;
-
- case CM_DRP_COMPATIBLEIDS:
- lpValueName = L"CompatibleIDs";
- break;
-
- case CM_DRP_SERVICE:
- lpValueName = L"Service";
- break;
-
- case CM_DRP_CLASS:
- lpValueName = L"Class";
- break;
-
- case CM_DRP_CLASSGUID:
- lpValueName = L"ClassGUID";
- break;
-
- case CM_DRP_DRIVER:
- lpValueName = L"Driver";
- break;
-
- case CM_DRP_CONFIGFLAGS:
- lpValueName = L"ConfigFlags";
- break;
-
- case CM_DRP_MFG:
- lpValueName = L"Mfg";
- break;
-
- case CM_DRP_FRIENDLYNAME:
- lpValueName = L"FriendlyName";
- break;
-
- case CM_DRP_LOCATION_INFORMATION:
- lpValueName = L"LocationInformation";
- break;
-
- case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME:
- lpValueName = NULL;
- break;
-
- case CM_DRP_CAPABILITIES:
- lpValueName = L"Capabilities";
- break;
-
- case CM_DRP_UI_NUMBER:
- lpValueName = NULL;
- break;
-
- case CM_DRP_UPPERFILTERS:
- lpValueName = L"UpperFilters";
- break;
-
- case CM_DRP_LOWERFILTERS:
- lpValueName = L"LowerFilters";
- break;
-
- case CM_DRP_BUSTYPEGUID:
- lpValueName = NULL;
- break;
-
- case CM_DRP_LEGACYBUSTYPE:
- lpValueName = NULL;
- break;
-
- case CM_DRP_BUSNUMBER:
- lpValueName = NULL;
- break;
-
- case CM_DRP_ENUMERATOR_NAME:
- lpValueName = NULL;
- break;
-
- default:
- return CR_INVALID_PROPERTY;
- }
-
- DPRINT("Value name: %S\n", lpValueName);
-
- if (lpValueName)
- {
- /* Retrieve information from the Registry */
- if (RegOpenKeyExW(hEnumKey,
- DeviceInstance,
- 0,
- KEY_ALL_ACCESS,
- &hKey))
- return CR_INVALID_DEVNODE;
-
- if (RegQueryValueExW(hKey,
- lpValueName,
- NULL,
- DataType,
- (LPBYTE)Buffer,
- Length))
- ret = CR_REGISTRY_ERROR;
-
- /* FIXME: Check buffer size */
-
- RegCloseKey(hKey);
- }
- else
- {
- /* Retrieve information from the Device Node */
- RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
- DeviceInstance);
- PlugPlayData.Buffer = Buffer;
- PlugPlayData.BufferSize = *TransferLen;
-
- switch (Property)
- {
-#if 0
- case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME:
- PlugPlayData.Property = DevicePropertyPhysicalDeviceObjectName;
- break;
-
- case CM_DRP_UI_NUMBER:
- PlugPlayData.Property = DevicePropertyUINumber;
- break;
-
- case CM_DRP_BUSTYPEGUID:
- PlugPlayData.Property = DevicePropertyBusTypeGuid;
- break;
-
- case CM_DRP_LEGACYBUSTYPE:
- PlugPlayData.Property = DevicePropertyLegacyBusType;
- break;
-
- case CM_DRP_BUSNUMBER:
- PlugPlayData.Property = DevicePropertyBusNumber;
- break;
-
- case CM_DRP_ENUMERATOR_NAME:
- PlugPlayData.Property = DevicePropertyEnumeratorName;
- break;
-#endif
-
- default:
- return CR_INVALID_PROPERTY;
- }
-
- Status = NtPlugPlayControl(PlugPlayControlProperty,
- (PVOID)&PlugPlayData,
- sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA));
- if (NT_SUCCESS(Status))
- {
- *Length = PlugPlayData.BufferSize;
- }
- else
- {
- ret = NtStatusToCrError(Status);
- }
- }
-
- DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 14 */
-CONFIGRET
-PNP_SetDeviceRegProp(handle_t BindingHandle,
- wchar_t *DeviceId,
- unsigned long Property,
- unsigned long DataType,
- char *Buffer,
- unsigned long Length,
- unsigned long Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
- LPWSTR lpValueName = NULL;
- HKEY hKey = 0;
-
- DPRINT("PNP_SetDeviceRegProp() called\n");
-
- DPRINT("DeviceId: %S\n", DeviceId);
- DPRINT("Property: %lu\n", Property);
- DPRINT("DataType: %lu\n", DataType);
- DPRINT("Length: %lu\n", Length);
-
- switch (Property)
- {
- case CM_DRP_DEVICEDESC:
- lpValueName = L"DeviceDesc";
- break;
-
- case CM_DRP_HARDWAREID:
- lpValueName = L"HardwareID";
- break;
-
- case CM_DRP_COMPATIBLEIDS:
- lpValueName = L"CompatibleIDs";
- break;
-
- case CM_DRP_SERVICE:
- lpValueName = L"Service";
- break;
-
- case CM_DRP_CLASS:
- lpValueName = L"Class";
- break;
-
- case CM_DRP_CLASSGUID:
- lpValueName = L"ClassGUID";
- break;
-
- case CM_DRP_DRIVER:
- lpValueName = L"Driver";
- break;
-
- case CM_DRP_CONFIGFLAGS:
- lpValueName = L"ConfigFlags";
- break;
-
- case CM_DRP_MFG:
- lpValueName = L"Mfg";
- break;
-
- case CM_DRP_FRIENDLYNAME:
- lpValueName = L"FriendlyName";
- break;
-
- case CM_DRP_LOCATION_INFORMATION:
- lpValueName = L"LocationInformation";
- break;
-
- case CM_DRP_UPPERFILTERS:
- lpValueName = L"UpperFilters";
- break;
-
- case CM_DRP_LOWERFILTERS:
- lpValueName = L"LowerFilters";
- break;
-
- default:
- return CR_INVALID_PROPERTY;
- }
-
- DPRINT("Value name: %S\n", lpValueName);
-
- if (RegOpenKeyExW(hEnumKey,
- DeviceId,
- 0,
- KEY_ALL_ACCESS,
- &hKey))
- return CR_INVALID_DEVNODE;
-
- if (Length == 0)
- {
- if (RegDeleteValueW(hKey,
- lpValueName))
- ret = CR_REGISTRY_ERROR;
- }
- else
- {
- if (RegSetValueExW(hKey,
- lpValueName,
- 0,
- DataType,
- (const BYTE*)Buffer,
- Length))
- ret = CR_REGISTRY_ERROR;
- }
-
- RegCloseKey(hKey);
-
- DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 15 */
-CONFIGRET
-PNP_GetClassInstance(handle_t BindingHandle,
- wchar_t *DeviceId, /* in */
- wchar_t *Buffer, /* out */
- unsigned long Length)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_Get_Class_Instance() called\n");
-
- DPRINT("PNP_Get_Class_Instance() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 16 */
-CONFIGRET
-PNP_CreateKey(handle_t BindingHandle,
- wchar_t *SubKey,
- unsigned long samDesired,
- unsigned long Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_CreateKey() called\n");
-
- DPRINT("PNP_CreateKey() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 17 */
-CONFIGRET
-PNP_DeleteRegistryKey(handle_t BindingHandle,
- wchar_t *DeviceId,
- wchar_t *ParentKey,
- wchar_t *ChildKey,
- unsigned long Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_DeleteRegistryKey() called\n");
-
- DPRINT("PNP_DeleteRegistryKey() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 18 */
-#if 0
-CONFIGRET
-PNP_GetClassCount(handle_t BindingHandle,
- unsigned long *ClassCount,
- unsigned long Flags)
-{
- HANDLE hKey = NULL;
- DWORD dwError;
-
- dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- pszRegPathClass,
- 0,
- KEY_QUERY_VALUE,
- &hKey);
- if (dwError != ERROR_SUCCESS)
- return CR_INVALID_DATA;
-
- dwError = RegQueryInfoKeyW(hKey,
- NULL,
- NULL,
- NULL,
- &ClassCount,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
- RegCloseKey(hKey);
- if (dwError != ERROR_SUCCESS)
- return CR_INVALID_DATA;
-
- return CR_SUCCESS;
-}
-#endif
-
-
-/* Function 19 */
-CONFIGRET
-PNP_GetClassName(handle_t BindingHandle,
- wchar_t *ClassGuid,
- wchar_t *Buffer,
- unsigned long *Length,
- unsigned long Flags)
-{
- WCHAR szKeyName[MAX_PATH];
- CONFIGRET ret = CR_SUCCESS;
- HKEY hKey = NULL;
- ULONG ulSize;
-
- DPRINT("PNP_GetClassName() called\n");
-
- lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class");
- lstrcatW(szKeyName, L"\\");
- lstrcatW(szKeyName, ClassGuid);
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- szKeyName,
- 0,
- KEY_QUERY_VALUE,
- &hKey))
- return CR_REGISTRY_ERROR;
-
- ulSize = *Length * sizeof(WCHAR);
- if (RegQueryValueExW(hKey,
- L"Class",
- NULL,
- NULL,
- (LPBYTE)Buffer,
- &ulSize))
- {
- *Length = 0;
- ret = CR_REGISTRY_ERROR;
- }
- else
- {
- *Length = ulSize / sizeof(WCHAR);
- }
-
- RegCloseKey(hKey);
-
- DPRINT("PNP_GetClassName() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 20 */
-CONFIGRET
-PNP_DeleteClassKey(handle_t BindingHandle,
- wchar_t *ClassGuid,
- unsigned long Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid, Flags);
-
- if (Flags & CM_DELETE_CLASS_SUBKEYS)
- {
- if (RegDeleteTreeW(hClassKey, ClassGuid) != ERROR_SUCCESS)
- ret = CR_REGISTRY_ERROR;
- }
- else
- {
- if (RegDeleteKeyW(hClassKey, ClassGuid) != ERROR_SUCCESS)
- ret = CR_REGISTRY_ERROR;
- }
-
- DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 28 */
-CONFIGRET
-PNP_CreateDevInst(handle_t BindingHandle,
- wchar_t *DeviceId, /* [in, out, string, size_is(Length)] */
- wchar_t *ParentDeviceId, /* [in, string] */
- unsigned long Length, /* [in] */
- unsigned long Flags) /* [in] */
-{
- CONFIGRET ret = CR_CALL_NOT_IMPLEMENTED;
-
- DPRINT1("PNP_CreateDevInst() called\n");
-
- DPRINT1("PNP_CreateDevInst() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 29 */
-CONFIGRET
-PNP_DeviceInstanceAction(handle_t BindingHandle,
- unsigned long MajorAction,
- unsigned long MinorAction,
- wchar_t *DeviceInstance1,
- wchar_t *DeviceInstance2)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_DeviceInstanceAction() called\n");
-
- switch (MajorAction)
- {
- case 2:
- DPRINT("Move device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
- break;
-
- case 3:
- DPRINT("Setup device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
- break;
-
- case 4:
- DPRINT("Enable device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
- break;
-
- case 5:
- DPRINT("Disable device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
- break;
-
- case 7:
- DPRINT("Reenumerate device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
- break;
-
- default:
- DPRINT1("Unknown function %lu\n", MajorAction);
- ret = CR_CALL_NOT_IMPLEMENTED;
- }
-
- DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 30 */
-CONFIGRET
-PNP_GetDeviceStatus(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long *pStatus,
- unsigned long *pProblem,
- DWORD Flags)
-{
- PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
- CONFIGRET ret = CR_SUCCESS;
- NTSTATUS Status;
-
- DPRINT("PNP_GetDeviceStatus() called\n");
-
- RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
- DeviceInstance);
- PlugPlayData.Operation = 0; /* Get status */
-
- Status = NtPlugPlayControl(PlugPlayControlDeviceStatus,
- (PVOID)&PlugPlayData,
- sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
- if (NT_SUCCESS(Status))
- {
- *pStatus = PlugPlayData.DeviceStatus;
- *pProblem = PlugPlayData.DeviceProblem;
- }
- else
- {
- ret = NtStatusToCrError(Status);
- }
-
- DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 31 */
-CONFIGRET
-PNP_SetDeviceProblem(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long Problem,
- DWORD Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT1("PNP_SetDeviceProblem() called\n");
-
- /* FIXME */
-
- DPRINT1("PNP_SetDeviceProblem() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 33 */
-CONFIGRET
-PNP_UninstallDevInst(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- DWORD Flags)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT1("PNP_UninstallDevInst() called\n");
-
- /* FIXME */
-
- DPRINT1("PNP_UninstallDevInst() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 38 */
-CONFIGRET
-PNP_IsDockStationPresent(handle_t BindingHandle,
- unsigned long *Present)
-{
- HKEY hKey;
- DWORD dwType;
- DWORD dwValue;
- DWORD dwSize;
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT1("PNP_IsDockStationPresent() called\n");
-
- *Present = FALSE;
-
- if (RegOpenKeyExW(HKEY_CURRENT_CONFIG,
- L"CurrentDockInfo",
- 0,
- KEY_READ,
- &hKey) != ERROR_SUCCESS)
- return CR_REGISTRY_ERROR;
-
- dwSize = sizeof(DWORD);
- if (RegQueryValueExW(hKey,
- L"DockingState",
- NULL,
- &dwType,
- (LPBYTE)&dwValue,
- &dwSize) != ERROR_SUCCESS)
- ret = CR_REGISTRY_ERROR;
-
- RegCloseKey(hKey);
-
- if (ret == CR_SUCCESS)
- {
- if (dwType != REG_DWORD || dwSize != sizeof(DWORD))
- {
- ret = CR_REGISTRY_ERROR;
- }
- else if (dwValue != 0)
- {
- *Present = TRUE;
- }
- }
-
- DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 39 */
-CONFIGRET
-PNP_RequestEjectPC(handle_t BindingHandle)
-{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT1("PNP_RequestEjectPC() called\n");
-
- ret = CR_FAILURE; /* FIXME */
-
- DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret);
-
- return ret;
-}
-
-
-/* Function 58 */
-CONFIGRET
-PNP_RunDetection(handle_t BindingHandle,
- unsigned long Flags)
-{
- DPRINT("PNP_RunDetection() called\n");
- return CR_CALL_NOT_IMPLEMENTED;
-}
-
-
-typedef BOOL (WINAPI *PDEV_INSTALL_W)(HWND, HINSTANCE, LPCWSTR, INT);
-
-static BOOL
-InstallDevice(PCWSTR DeviceInstance, BOOL SetupIsActive)
-{
- PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
- HMODULE hNewDev = NULL;
- PDEV_INSTALL_W DevInstallW;
- NTSTATUS Status;
- BOOL DeviceInstalled = FALSE;
-
- RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
- DeviceInstance);
- PlugPlayData.Operation = 0; /* Get status */
-
- /* Get device status */
- Status = NtPlugPlayControl(PlugPlayControlDeviceStatus,
- (PVOID)&PlugPlayData,
- sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
- if (!NT_SUCCESS(Status))
- return FALSE;
-
- if (PlugPlayData.DeviceStatus & DNF_STARTED || PlugPlayData.DeviceStatus & DNF_START_FAILED)
- /* Device is already started, or disabled due to some problem. Don't install it */
- return TRUE;
-
- /* Install device */
- SetEnvironmentVariable(L"USERPROFILE", L"."); /* FIXME: why is it needed? */
-
- hNewDev = LoadLibraryW(L"newdev.dll");
- if (!hNewDev)
- goto cleanup;
-
- DevInstallW = (PDEV_INSTALL_W)GetProcAddress(hNewDev, (LPCSTR)"DevInstallW");
- if (!DevInstallW)
- goto cleanup;
-
- if (!DevInstallW(NULL, NULL, DeviceInstance, SetupIsActive ? SW_HIDE : SW_SHOWNOACTIVATE))
- goto cleanup;
-
- DeviceInstalled = TRUE;
-
-cleanup:
- if (hNewDev != NULL)
- FreeLibrary(hNewDev);
-
- return DeviceInstalled;
-}
-
-
-static BOOL
-SetupIsActive(VOID)
-{
- HKEY hKey = INVALID_HANDLE_VALUE;
- DWORD regType, active, size;
- LONG rc;
- BOOL ret = FALSE;
-
- rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_QUERY_VALUE, &hKey);
- if (rc != ERROR_SUCCESS)
- goto cleanup;
-
- size = sizeof(DWORD);
- rc = RegQueryValueExW(hKey, L"SystemSetupInProgress", NULL, ®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 != INVALID_HANDLE_VALUE)
- RegCloseKey(hKey);
-
- DPRINT("System setup in progress? %S\n", ret ? L"YES" : L"NO");
-
- return ret;
-}
-
-
-static DWORD WINAPI
-PnpEventThread(LPVOID lpParameter)
-{
- PPLUGPLAY_EVENT_BLOCK PnpEvent;
- ULONG PnpEventSize;
- NTSTATUS Status;
- RPC_STATUS RpcStatus;
- BOOL setupActive;
-
- PnpEventSize = 0x1000;
- PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
- if (PnpEvent == NULL)
- return ERROR_OUTOFMEMORY;
-
- setupActive = SetupIsActive();
-
- for (;;)
- {
- DPRINT("Calling NtGetPlugPlayEvent()\n");
-
- /* 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;
- PnpEvent = HeapReAlloc(GetProcessHeap(), 0, PnpEvent, PnpEventSize);
- if (PnpEvent == NULL)
- return ERROR_OUTOFMEMORY;
- continue;
- }
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status);
- break;
- }
-
- DPRINT("Received PnP Event\n");
- if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
- {
- DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
- InstallDevice(PnpEvent->TargetDevice.DeviceIds, setupActive);
- }
- else
- {
- DPRINT1("Unknown event\n");
- }
-
- /* FIXME: Process the pnp event */
-
- /* Dequeue the current pnp event and signal the next one */
- NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
- }
-
- HeapFree(GetProcessHeap(), 0, PnpEvent);
-
- return ERROR_SUCCESS;
-}
-
-
-static VOID CALLBACK
-ServiceMain(DWORD argc, LPTSTR *argv)
-{
- HANDLE hThread;
- DWORD dwThreadId;
-
- DPRINT("ServiceMain() called\n");
-
- 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);
-
- DPRINT("ServiceMain() done\n");
-}
-
-
-int
-main(int argc, char *argv[])
-{
- DWORD dwError;
-
- DPRINT("Umpnpmgr: main() started\n");
-
- hInstallEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (hInstallEvent == NULL)
- {
- dwError = GetLastError();
- DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError);
- return dwError;
- }
-
- dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"System\\CurrentControlSet\\Enum",
- 0,
- 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;
- }
-
- StartServiceCtrlDispatcher(ServiceTable);
-
- DPRINT("Umpnpmgr: main() done\n");
-
- ExitThread(0);
-
- return 0;
-}
-
-/* EOF */