diff --git a/base/services/umpnpmgr/rpcserver.c b/base/services/umpnpmgr/rpcserver.c index 4f4131c1b78..190e5d502b2 100644 --- a/base/services/umpnpmgr/rpcserver.c +++ b/base/services/umpnpmgr/rpcserver.c @@ -191,10 +191,40 @@ SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID, } +static +CONFIGRET +ClearDeviceStatus( + _In_ LPWSTR pszDeviceID, + _In_ DWORD ulStatus, + _In_ DWORD ulProblem) +{ + PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData; + CONFIGRET ret = CR_SUCCESS; + NTSTATUS Status; + + DPRINT1("ClearDeviceStatus(%S 0x%lx 0x%lx)\n", + pszDeviceID, ulStatus, ulProblem); + + RtlInitUnicodeString(&PlugPlayData.DeviceInstance, + pszDeviceID); + PlugPlayData.Operation = PNP_CLEAR_DEVICE_STATUS; + PlugPlayData.DeviceStatus = ulStatus; + PlugPlayData.DeviceProblem = ulProblem; + + Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, + (PVOID)&PlugPlayData, + sizeof(PLUGPLAY_CONTROL_STATUS_DATA)); + if (!NT_SUCCESS(Status)) + ret = NtStatusToCrError(Status); + + return ret; +} + + static CONFIGRET GetDeviceStatus( - _In_ LPWSTR pDeviceID, + _In_ LPWSTR pszDeviceID, _Out_ DWORD *pulStatus, _Out_ DWORD *pulProblem) { @@ -203,10 +233,10 @@ GetDeviceStatus( NTSTATUS Status; DPRINT("GetDeviceStatus(%S %p %p)\n", - pDeviceID, pulStatus, pulProblem); + pszDeviceID, pulStatus, pulProblem); RtlInitUnicodeString(&PlugPlayData.DeviceInstance, - pDeviceID); + pszDeviceID); PlugPlayData.Operation = PNP_GET_DEVICE_STATUS; Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, @@ -229,7 +259,7 @@ GetDeviceStatus( static CONFIGRET SetDeviceStatus( - _In_ LPWSTR pDeviceID, + _In_ LPWSTR pszDeviceID, _In_ DWORD ulStatus, _In_ DWORD ulProblem) { @@ -238,10 +268,10 @@ SetDeviceStatus( NTSTATUS Status; DPRINT1("SetDeviceStatus(%S 0x%lx 0x%lx)\n", - pDeviceID, ulStatus, ulProblem); + pszDeviceID, ulStatus, ulProblem); RtlInitUnicodeString(&PlugPlayData.DeviceInstance, - pDeviceID); + pszDeviceID); PlugPlayData.Operation = PNP_SET_DEVICE_STATUS; PlugPlayData.DeviceStatus = ulStatus; PlugPlayData.DeviceProblem = ulProblem; @@ -2781,27 +2811,83 @@ PNP_CreateDevInst( static CONFIGRET -MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination, - LPWSTR pszDeviceInstanceSource) +SetupDeviceInstance( + _In_ LPWSTR pszDeviceInstance, + _In_ DWORD ulMinorAction) { - DPRINT("MoveDeviceInstance: not implemented\n"); - /* FIXME */ - return CR_CALL_NOT_IMPLEMENTED; + HKEY hDeviceKey = NULL; + DWORD dwDisableCount, dwSize; + DWORD ulStatus, ulProblem; + DWORD dwError; + CONFIGRET ret = CR_SUCCESS; + + DPRINT1("SetupDeviceInstance(%S 0x%08lx)\n", + pszDeviceInstance, ulMinorAction); + + if (IsRootDeviceInstanceID(pszDeviceInstance)) + return CR_INVALID_DEVINST; + + if (ulMinorAction & ~CM_SETUP_BITS) + return CR_INVALID_FLAG; + + if ((ulMinorAction == CM_SETUP_DOWNLOAD) || + (ulMinorAction == CM_SETUP_WRITE_LOG_CONFS)) + return CR_SUCCESS; + + dwError = RegOpenKeyExW(hEnumKey, + pszDeviceInstance, + 0, + KEY_READ, + &hDeviceKey); + if (dwError != ERROR_SUCCESS) + return CR_INVALID_DEVNODE; + + dwSize = sizeof(dwDisableCount); + dwError = RegQueryValueExW(hDeviceKey, + L"DisableCount", + NULL, + NULL, + (LPBYTE)&dwDisableCount, + &dwSize); + if ((dwError == ERROR_SUCCESS) && + (dwDisableCount > 0)) + { + goto done; + } + + GetDeviceStatus(pszDeviceInstance, + &ulStatus, + &ulProblem); + + if (ulStatus & DN_STARTED) + { + goto done; + } + + if (ulStatus & DN_HAS_PROBLEM) + { + ret = ClearDeviceStatus(pszDeviceInstance, + DN_HAS_PROBLEM, + ulProblem); + } + + if (ret != CR_SUCCESS) + goto done; + + + /* FIXME: Start the device */ + +done: + if (hDeviceKey != NULL) + RegCloseKey(hDeviceKey); + + return ret; } static CONFIGRET -SetupDeviceInstance(LPWSTR pszDeviceInstance, - DWORD ulFlags) -{ - DPRINT("SetupDeviceInstance: not implemented\n"); - /* FIXME */ - return CR_CALL_NOT_IMPLEMENTED; -} - - -static CONFIGRET -EnableDeviceInstance(LPWSTR pszDeviceInstance) +EnableDeviceInstance( + _In_ LPWSTR pszDeviceInstance) { PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData; CONFIGRET ret = CR_SUCCESS; @@ -2809,8 +2895,11 @@ EnableDeviceInstance(LPWSTR pszDeviceInstance) DPRINT("Enable device instance %S\n", pszDeviceInstance); - RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, pszDeviceInstance); - Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA)); + RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, + pszDeviceInstance); + Status = NtPlugPlayControl(PlugPlayControlResetDevice, + &ResetDeviceData, + sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status); @@ -2818,31 +2907,22 @@ EnableDeviceInstance(LPWSTR pszDeviceInstance) } -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) + _In_ ULONG ulMinorAction) { PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status; DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n", - pszDeviceInstance, ulFlags); + pszDeviceInstance, ulMinorAction); - if (ulFlags & ~CM_REENUMERATE_BITS) + if (ulMinorAction & ~CM_REENUMERATE_BITS) return CR_INVALID_FLAG; - if (ulFlags & CM_REENUMERATE_RETRY_INSTALLATION) + if (ulMinorAction & CM_REENUMERATE_RETRY_INSTALLATION) { DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n"); } @@ -2866,8 +2946,8 @@ DWORD WINAPI PNP_DeviceInstanceAction( handle_t hBinding, - DWORD ulAction, - DWORD ulFlags, + DWORD ulMajorAction, + DWORD ulMinorAction, LPWSTR pszDeviceInstance1, LPWSTR pszDeviceInstance2) { @@ -2875,35 +2955,28 @@ PNP_DeviceInstanceAction( UNREFERENCED_PARAMETER(hBinding); - DPRINT("PNP_DeviceInstanceAction() called\n"); + DPRINT("PNP_DeviceInstanceAction(%p %lu 0x%08lx %S %S)\n", + hBinding, ulMajorAction, ulMinorAction, + pszDeviceInstance1, pszDeviceInstance2); - switch (ulAction) + switch (ulMajorAction) { - case PNP_DEVINST_MOVE: - ret = MoveDeviceInstance(pszDeviceInstance1, - pszDeviceInstance2); - break; - case PNP_DEVINST_SETUP: ret = SetupDeviceInstance(pszDeviceInstance1, - ulFlags); + ulMinorAction); 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); + ulMinorAction); break; default: - DPRINT1("Unknown device action %lu: not implemented\n", ulAction); + DPRINT1("Unknown device action %lu: not implemented\n", ulMajorAction); ret = CR_CALL_NOT_IMPLEMENTED; } diff --git a/sdk/include/reactos/idl/pnp.idl b/sdk/include/reactos/idl/pnp.idl index 6856c4e5ac0..d1aa03e678d 100644 --- a/sdk/include/reactos/idl/pnp.idl +++ b/sdk/include/reactos/idl/pnp.idl @@ -551,8 +551,8 @@ interface pnp __stdcall PNP_DeviceInstanceAction( [in] handle_t hBinding, - [in] DWORD ulAction, - [in] DWORD ulFlags, + [in] DWORD ulMajorAction, + [in] DWORD ulMinorAction, [in, string, unique] LPWSTR pszDeviceInstance1, [in, string, unique] LPWSTR pszDeviceInstance2);