/* GLOBALS ******************************************************************/
-static VOID CALLBACK
-ServiceMain(DWORD argc, LPTSTR *argv);
-
-static SERVICE_TABLE_ENTRY ServiceTable[2] =
+static VOID CALLBACK ServiceMain(DWORD argc, LPWSTR *argv);
+static WCHAR ServiceName[] = L"PlugPlay";
+static SERVICE_TABLE_ENTRYW ServiceTable[] =
{
- {TEXT("PlugPlay"), ServiceMain},
+ {ServiceName, ServiceMain},
{NULL, NULL}
};
+static SERVICE_STATUS_HANDLE ServiceStatusHandle;
+static SERVICE_STATUS ServiceStatus;
+
static WCHAR szRootDeviceId[] = L"HTREE\\ROOT\\0";
static HKEY hEnumKey = NULL;
RpcServerThread(LPVOID lpParameter)
{
RPC_STATUS Status;
+ BOOLEAN RegisteredProtSeq = FALSE;
UNREFERENCED_PARAMETER(lpParameter);
DPRINT("RpcServerThread() called\n");
+#if 0
+ /* XP-compatible protocol sequence/endpoint */
Status = RpcServerUseProtseqEpW(L"ncacn_np",
20,
- L"\\pipe\\umpnpmgr",
+ L"\\pipe\\ntsvcs",
NULL); // Security descriptor
- if (Status != RPC_S_OK)
- {
+ if (Status == RPC_S_OK)
+ RegisteredProtSeq = TRUE;
+ else
+ DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
+#endif
+
+ /* Vista-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,
case CM_DRP_BUSNUMBER:
PlugPlayData.Property = DevicePropertyBusNumber;
break;
+#endif
case CM_DRP_ENUMERATOR_NAME:
- PlugPlayData.Property = DevicePropertyEnumeratorName;
+ PlugPlayData.Property = 15; //DevicePropertyEnumeratorName;
break;
-#endif
default:
return CR_INVALID_PROPERTY;
DWORD samDesired,
DWORD ulFlags)
{
- UNIMPLEMENTED;
- return CR_CALL_NOT_IMPLEMENTED;
+ 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;
}
}
+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\n");
+
+ 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(LPWSTR pszDeviceInstance)
+{
+ DPRINT("ReenumerateDeviceInstance: not implemented\n");
+ /* FIXME */
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
/* Function 29 */
DWORD PNP_DeviceInstanceAction(
handle_t hBinding,
- DWORD ulMajorAction,
- DWORD ulMinorAction,
+ DWORD ulAction,
+ DWORD ulFlags,
LPWSTR pszDeviceInstance1,
LPWSTR pszDeviceInstance2)
{
CONFIGRET ret = CR_SUCCESS;
- NTSTATUS Status;
UNREFERENCED_PARAMETER(hBinding);
- UNREFERENCED_PARAMETER(ulMinorAction);
- UNREFERENCED_PARAMETER(pszDeviceInstance2);
DPRINT("PNP_DeviceInstanceAction() called\n");
- switch (ulMajorAction)
+ switch (ulAction)
{
+ case PNP_DEVINST_MOVE:
+ ret = MoveDeviceInstance(pszDeviceInstance1,
+ pszDeviceInstance2);
+ break;
+
case PNP_DEVINST_SETUP:
- DPRINT("Setup device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
+ ret = SetupDeviceInstance(pszDeviceInstance1,
+ ulFlags);
break;
case PNP_DEVINST_ENABLE:
- {
- PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
- DPRINT("Enable device instance\n");
- RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, pszDeviceInstance1);
- Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA));
- if (!NT_SUCCESS(Status))
- ret = NtStatusToCrError(Status);
+ ret = EnableDeviceInstance(pszDeviceInstance1);
+ break;
+
+ case PNP_DEVINST_DISABLE:
+ ret = DisableDeviceInstance(pszDeviceInstance1);
break;
- }
case PNP_DEVINST_REENUMERATE:
- DPRINT("Reenumerate device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
+ ret = ReenumerateDeviceInstance(pszDeviceInstance1);
break;
default:
- DPRINT1("Unknown function %lu\n", ulMajorAction);
+ DPRINT1("Unknown device action %lu: not implemented\n", ulAction);
ret = CR_CALL_NOT_IMPLEMENTED;
}
DWORD ulNameLength,
DWORD ulFlags)
{
- UNIMPLEMENTED;
- return CR_CALL_NOT_IMPLEMENTED;
+ 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\\%04u\\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 55 */
DWORD PNP_SetHwProf(
- handle_t hBinding)
+ handle_t hBinding,
+ DWORD ulHardwareProfile,
+ DWORD ulFlags)
{
UNIMPLEMENTED;
return CR_CALL_NOT_IMPLEMENTED;
/* Function 56 */
DWORD PNP_QueryArbitratorFreeData(
- handle_t hBinding)
+ handle_t hBinding,
+ BYTE *pData,
+ DWORD DataLen,
+ LPWSTR pDeviceID,
+ RESOURCEID ResourceID,
+ DWORD ulFlags)
{
UNIMPLEMENTED;
return CR_CALL_NOT_IMPLEMENTED;
/* Function 57 */
DWORD PNP_QueryArbitratorFreeSize(
- handle_t hBinding)
+ handle_t hBinding,
+ DWORD *pulSize,
+ LPWSTR pDeviceID,
+ RESOURCEID ResourceID,
+ DWORD ulFlags)
{
UNIMPLEMENTED;
return CR_CALL_NOT_IMPLEMENTED;
DWORD len;
DWORD DeviceIdLength;
- DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
+ DPRINT("Device enumerated: %S\n", PnpEvent->TargetDevice.DeviceIds);
DeviceIdLength = lstrlenW(PnpEvent->TargetDevice.DeviceIds);
if (DeviceIdLength)
}
}
}
+ else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
+ {
+ DPRINT("Device arrival: %S\n", PnpEvent->TargetDevice.DeviceIds);
+ /* FIXME: ? */
+ }
else
{
DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
}
+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");
+ 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");
+ UpdateServiceStatus(SERVICE_STOPPED);
+ return ERROR_SUCCESS;
+
+ default :
+ DPRINT1(" Control %lu received\n");
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+}
+
+
static VOID CALLBACK
ServiceMain(DWORD argc, LPTSTR *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,
if (hThread != NULL)
CloseHandle(hThread);
+ UpdateServiceStatus(SERVICE_RUNNING);
+
DPRINT("ServiceMain() done\n");
}