ReactOS  0.4.15-dev-3324-gda4e15f
rpcserver.c
Go to the documentation of this file.
1 /*
2  * ReactOS kernel
3  * Copyright (C) 2005 ReactOS Team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT: See COPYING in the top level directory
21  * PROJECT: ReactOS kernel
22  * FILE: base/services/umpnpmgr/rpcserver.c
23  * PURPOSE: RPC server
24  * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org)
25  * HervĂ© Poussineau (hpoussin@reactos.org)
26  * Colin Finck (colin@reactos.org)
27  */
28 
29 /* INCLUDES *****************************************************************/
30 
31 #include "precomp.h"
32 
33 #define NDEBUG
34 #include <debug.h>
35 
36 
37 /* GLOBALS ******************************************************************/
38 
39 static WCHAR szRootDeviceInstanceID[] = L"HTREE\\ROOT\\0";
40 
41 
42 /* FUNCTIONS *****************************************************************/
43 
46 {
48  BOOLEAN RegisteredProtSeq = FALSE;
49 
51 
52  DPRINT("RpcServerThread() called\n");
53 
54 #if 0
55  /* 2k/XP/2k3-compatible protocol sequence/endpoint */
56  Status = RpcServerUseProtseqEpW(L"ncacn_np",
57  20,
58  L"\\pipe\\ntsvcs",
59  NULL); // Security descriptor
60  if (Status == RPC_S_OK)
61  RegisteredProtSeq = TRUE;
62  else
63  DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
64 #endif
65 
66  /* Vista/7-compatible protocol sequence/endpoint */
67  Status = RpcServerUseProtseqEpW(L"ncacn_np",
68  20,
69  L"\\pipe\\plugplay",
70  NULL); // Security descriptor
71  if (Status == RPC_S_OK)
72  RegisteredProtSeq = TRUE;
73  else
74  DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
75 
76  /* Make sure there's a usable endpoint */
77  if (RegisteredProtSeq == FALSE)
78  return 0;
79 
80  Status = RpcServerRegisterIf(pnp_v1_0_s_ifspec,
81  NULL,
82  NULL);
83  if (Status != RPC_S_OK)
84  {
85  DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
86  return 0;
87  }
88 
90  20,
91  FALSE);
92  if (Status != RPC_S_OK)
93  {
94  DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
95  return 0;
96  }
97 
98  /* ROS HACK (this should never happen...) */
99  DPRINT1("*** Other devices won't be installed correctly. If something\n");
100  DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
101 
102  DPRINT("RpcServerThread() done\n");
103 
104  return 0;
105 }
106 
107 
109 {
111 }
112 
113 
115 {
116  HeapFree(GetProcessHeap(), 0, ptr);
117 }
118 
119 
120 static CONFIGRET WINAPI
122 {
123  switch (Status)
124  {
127 
129  return CR_INVALID_DATA;
130 
132  return CR_NO_SUCH_DEVINST;
133 
135  return CR_ACCESS_DENIED;
136 
138  return CR_BUFFER_SMALL;
139 
141  return CR_NO_SUCH_VALUE;
142 
143  default:
144  return CR_FAILURE;
145  }
146 }
147 
148 
149 static VOID
150 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID,
151  OUT LPWSTR pszEnumerator,
152  OUT LPWSTR pszDevice,
153  OUT LPWSTR pszInstance)
154 {
155  WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN];
156  LPWSTR lpEnumerator = NULL;
157  LPWSTR lpDevice = NULL;
158  LPWSTR lpInstance = NULL;
159  LPWSTR ptr;
160 
161  wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID);
162 
163  *pszEnumerator = 0;
164  *pszDevice = 0;
165  *pszInstance = 0;
166 
167  lpEnumerator = szLocalDeviceInstanceID;
168 
169  ptr = wcschr(lpEnumerator, L'\\');
170  if (ptr != NULL)
171  {
172  *ptr = 0;
173  lpDevice = ++ptr;
174 
175  ptr = wcschr(lpDevice, L'\\');
176  if (ptr != NULL)
177  {
178  *ptr = 0;
179  lpInstance = ++ptr;
180  }
181  }
182 
183  if (lpEnumerator != NULL)
184  wcscpy(pszEnumerator, lpEnumerator);
185 
186  if (lpDevice != NULL)
187  wcscpy(pszDevice, lpDevice);
188 
189  if (lpInstance != NULL)
190  wcscpy(pszInstance, lpInstance);
191 }
192 
193 
194 static
195 CONFIGRET
197  _In_ LPWSTR pszDeviceID,
198  _In_ DWORD ulStatus,
199  _In_ DWORD ulProblem)
200 {
201  PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
204 
205  DPRINT1("ClearDeviceStatus(%S 0x%lx 0x%lx)\n",
206  pszDeviceID, ulStatus, ulProblem);
207 
208  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
209  pszDeviceID);
210  PlugPlayData.Operation = PNP_CLEAR_DEVICE_STATUS;
211  PlugPlayData.DeviceStatus = ulStatus;
212  PlugPlayData.DeviceProblem = ulProblem;
213 
215  (PVOID)&PlugPlayData,
217  if (!NT_SUCCESS(Status))
219 
220  return ret;
221 }
222 
223 
224 static
225 CONFIGRET
227  _In_ LPWSTR pszDeviceID,
228  _Out_ DWORD *pulStatus,
229  _Out_ DWORD *pulProblem)
230 {
231  PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
234 
235  DPRINT("GetDeviceStatus(%S %p %p)\n",
236  pszDeviceID, pulStatus, pulProblem);
237 
238  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
239  pszDeviceID);
240  PlugPlayData.Operation = PNP_GET_DEVICE_STATUS;
241 
243  (PVOID)&PlugPlayData,
245  if (NT_SUCCESS(Status))
246  {
247  *pulStatus = PlugPlayData.DeviceStatus;
248  *pulProblem = PlugPlayData.DeviceProblem;
249  }
250  else
251  {
253  }
254 
255  return ret;
256 }
257 
258 
259 static
260 CONFIGRET
262  _In_ LPWSTR pszDeviceID,
263  _In_ DWORD ulStatus,
264  _In_ DWORD ulProblem)
265 {
266  PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
269 
270  DPRINT1("SetDeviceStatus(%S 0x%lx 0x%lx)\n",
271  pszDeviceID, ulStatus, ulProblem);
272 
273  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
274  pszDeviceID);
275  PlugPlayData.Operation = PNP_SET_DEVICE_STATUS;
276  PlugPlayData.DeviceStatus = ulStatus;
277  PlugPlayData.DeviceProblem = ulProblem;
278 
280  (PVOID)&PlugPlayData,
282  if (!NT_SUCCESS(Status))
284 
285  return ret;
286 }
287 
288 
289 static
290 CONFIGRET
292  _In_ LPWSTR pszDeviceInstance,
293  _Inout_opt_ PPNP_VETO_TYPE pVetoType,
294  _Inout_opt_ LPWSTR pszVetoName,
295  _In_ DWORD ulNameLength)
296 {
297  PLUGPLAY_CONTROL_QUERY_REMOVE_DATA QueryRemoveData;
300 
301  DPRINT1("DisableDeviceInstance(%S %p %p %lu)\n",
302  pszDeviceInstance, pVetoType, pszVetoName, ulNameLength);
303 
304  RtlInitUnicodeString(&QueryRemoveData.DeviceInstance,
305  pszDeviceInstance);
306 
307  QueryRemoveData.Flags = 0;
308  QueryRemoveData.VetoType = 0;
309  QueryRemoveData.VetoName = pszVetoName;
310  QueryRemoveData.NameLength = ulNameLength;
311 
313  &QueryRemoveData,
316  {
318  }
320  {
321  if (pVetoType != NULL)
322  *pVetoType = QueryRemoveData.VetoType;
323 
325  }
326  else if (!NT_SUCCESS(Status))
327  {
329  }
330 
331  return ret;
332 }
333 
334 
335 static
336 BOOL
338  _In_ PWSTR pszDeviceInstanceID)
339 {
340  INT nPartLength[3] = {0, 0, 0};
341  INT nLength = 0, nParts = 0;
342  PWCHAR p;
343 
344  DPRINT("IsValidDeviceInstanceID(%S)\n",
345  pszDeviceInstanceID);
346 
347  if (pszDeviceInstanceID == NULL)
348  {
349  DPRINT("Device instance ID is NULL!\n");
350  return FALSE;
351  }
352 
353  p = pszDeviceInstanceID;
354  while (*p != UNICODE_NULL)
355  {
356  if (*p == L'\\')
357  {
358  nParts++;
359  if (nParts >= 3)
360  {
361  DPRINT("Too many separators: %d\n", nParts);
362  return FALSE;
363  }
364  }
365  else
366  {
367  nPartLength[nParts]++;
368  }
369 
370  nLength++;
371  if (nLength >= MAX_DEVICE_ID_LEN)
372  {
373  DPRINT("Too long: %d\n", nLength);
374  return FALSE;
375  }
376 
377  p++;
378  }
379 
380  if (nParts != 2)
381  {
382  DPRINT("Invalid number of separtors: %d\n", nParts);
383  return FALSE;
384  }
385 
386  if ((nPartLength[0] == 0) ||
387  (nPartLength[1] == 0) ||
388  (nPartLength[2] == 0))
389  {
390  DPRINT("Invalid part lengths: %d %d %d\n",
391  nPartLength[0], nPartLength[1], nPartLength[2]);
392  return FALSE;
393  }
394 
395  DPRINT("Valid device instance ID!\n");
396 
397  return TRUE;
398 }
399 
400 
401 static
402 BOOL
404  _In_ PWSTR pszDeviceInstanceID)
405 {
406  if (_wcsicmp(pszDeviceInstanceID, szRootDeviceInstanceID) == 0)
407  return TRUE;
408 
409  return FALSE;
410 }
411 
412 
413 static
414 CONFIGRET
416  _In_ LPCWSTR pszDeviceID,
417  _Out_ PHKEY phKey)
418 {
419  WCHAR szKeyName[MAX_PATH];
420  HKEY hInstanceKey;
421  DWORD dwError;
422 
423  /* Build the full device instance key name */
424  wcscpy(szKeyName, L"System\\CurrentControlSet\\Enum\\");
425  wcscat(szKeyName, pszDeviceID);
426 
427  /* Open the device instance key */
429  szKeyName,
430  0,
432  &hInstanceKey);
433  if (dwError != ERROR_SUCCESS)
434  return CR_INVALID_DEVINST;
435 
436  /* Create or open the LogConf key */
437  dwError = RegCreateKeyExW(hInstanceKey,
438  L"LogConf",
439  0,
440  NULL,
443  NULL,
444  phKey,
445  NULL);
446 
447  /* Close the device instance key */
448  RegCloseKey(hInstanceKey);
449 
450  if (dwError != ERROR_SUCCESS)
451  return CR_REGISTRY_ERROR;
452 
453  return CR_SUCCESS;
454 }
455 
456 
457 static
458 CONFIGRET
460  _In_ HKEY hKey,
461  _In_ ULONG ulLogConfType,
462  _Out_ PULONG pulRegDataType,
463  _Out_ PULONG pulDataSize,
464  _Out_ LPBYTE *ppBuffer)
465 {
466  LPCWSTR pszValueName;
467 
468  switch (ulLogConfType)
469  {
470  case BOOT_LOG_CONF:
471  pszValueName = L"BootConfig";
472  *pulRegDataType = REG_RESOURCE_LIST;
473  break;
474 
475  case ALLOC_LOG_CONF:
476  pszValueName = L"AllocConfig";
477  *pulRegDataType = REG_RESOURCE_LIST;
478  break;
479 
480  case FORCED_LOG_CONF:
481  pszValueName = L"ForcedConfig";
482  *pulRegDataType = REG_RESOURCE_LIST;
483  break;
484 
485  case FILTERED_LOG_CONF:
486  pszValueName = L"FilteredConfigVector";
487  *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
488  break;
489 
490  case BASIC_LOG_CONF:
491  pszValueName = L"BasicConfigVector";
492  *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
493  break;
494 
495  case OVERRIDE_LOG_CONF:
496  pszValueName = L"OverrideConfigVector";
497  *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
498  break;
499 
500  default:
501  DPRINT1("Unsupported configuration type!\n");
502  return CR_FAILURE;
503  }
504 
505  /* Get the configuration data size */
507  pszValueName,
508  NULL,
509  NULL,
510  NULL,
511  pulDataSize) != ERROR_SUCCESS)
512  {
513  return CR_INVALID_LOG_CONF;
514  }
515 
516  /* Allocate the buffer */
517  *ppBuffer = HeapAlloc(GetProcessHeap(), 0, *pulDataSize);
518  if (*ppBuffer == NULL)
519  {
520  return CR_OUT_OF_MEMORY;
521  }
522 
523  /* Retrieve the configuration data */
525  pszValueName,
526  NULL,
527  NULL,
528  (LPBYTE)*ppBuffer,
529  pulDataSize) != ERROR_SUCCESS)
530  {
531  return CR_INVALID_LOG_CONF;
532  }
533 
534  return CR_SUCCESS;
535 }
536 
537 
538 /* PUBLIC FUNCTIONS **********************************************************/
539 
540 /* Function 0 */
541 DWORD
542 WINAPI
545 {
547  return CR_SUCCESS;
548 }
549 
550 
551 /* Function 1 */
552 DWORD
553 WINAPI
556 {
558  return CR_SUCCESS;
559 }
560 
561 
562 /* Function 2 */
563 DWORD
564 WINAPI
567  WORD *pVersion)
568 {
570 
571  DPRINT("PNP_GetVersion(%p %p)\n",
572  hBinding, pVersion);
573 
574  *pVersion = 0x0400;
575 
576  return CR_SUCCESS;
577 }
578 
579 
580 /* Function 3 */
581 DWORD
582 WINAPI
585  DWORD *pulState,
586  DWORD ulFlags)
587 {
589  UNREFERENCED_PARAMETER(ulFlags);
590 
591  DPRINT("PNP_GetGlobalState(%p %p 0x%08lx)\n",
592  hBinding, pulState, ulFlags);
593 
595 
596  return CR_SUCCESS;
597 }
598 
599 
600 /* Function 4 */
601 DWORD
602 WINAPI
605 {
607 
608  DPRINT("PNP_InitDetection(%p)\n",
609  hBinding);
610 
611  return CR_SUCCESS;
612 }
613 
614 
615 /* Function 5 */
616 DWORD
617 WINAPI
620  BOOL Admin,
622 {
625 
627  UNREFERENCED_PARAMETER(Admin);
628 
629  DPRINT("PNP_ReportLogOn(%p %u, %u)\n",
630  hBinding, Admin, ProcessId);
631 
632  /* Get the users token */
634 
635  if (!hProcess)
636  {
637  DPRINT1("OpenProcess failed with error %u\n", GetLastError());
638  goto cleanup;
639  }
640 
641  if (hUserToken)
642  {
644  hUserToken = NULL;
645  }
646 
648  {
649  DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
650  goto cleanup;
651  }
652 
653  /* Trigger the installer thread */
654  if (hInstallEvent)
656 
658 
659 cleanup:
660  if (hProcess)
662 
663  return ReturnValue;
664 }
665 
666 
667 /* Function 6 */
668 DWORD
669 WINAPI
672  LPWSTR pDeviceID,
673  DWORD ulFlags)
674 {
676  HKEY hDeviceKey = NULL;
677 
679  UNREFERENCED_PARAMETER(ulFlags);
680 
681  DPRINT("PNP_ValidateDeviceInstance(%p %S 0x%08lx)\n",
682  hBinding, pDeviceID, ulFlags);
683 
684  if (!IsValidDeviceInstanceID(pDeviceID))
685  return CR_INVALID_DEVINST;
686 
688  pDeviceID,
689  0,
690  KEY_READ,
691  &hDeviceKey))
692  {
693  DPRINT("Could not open the Device Key!\n");
695  goto Done;
696  }
697 
698  /* FIXME: add more tests */
699 
700 Done:
701  if (hDeviceKey != NULL)
702  RegCloseKey(hDeviceKey);
703 
704  DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret);
705 
706  return ret;
707 }
708 
709 
710 /* Function 7 */
711 DWORD
712 WINAPI
715  LPWSTR pDeviceID,
716  PNP_RPC_STRING_LEN ulLength)
717 {
719 
721 
722  DPRINT("PNP_GetRootDeviceInstance(%p %S %lu)\n",
723  hBinding, pDeviceID, ulLength);
724 
725  if (!pDeviceID)
726  {
728  goto Done;
729  }
730 
731  if (ulLength < lstrlenW(szRootDeviceInstanceID) + 1)
732  {
734  goto Done;
735  }
736 
737  lstrcpyW(pDeviceID,
739 
740 Done:
741  DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret);
742 
743  return ret;
744 }
745 
746 
747 /* Function 8 */
748 DWORD
749 WINAPI
752  DWORD ulRelationship,
753  LPWSTR pDeviceID,
754  LPWSTR pRelatedDeviceId,
755  PNP_RPC_STRING_LEN *pulLength,
756  DWORD ulFlags)
757 {
761 
763  UNREFERENCED_PARAMETER(ulFlags);
764 
765  DPRINT("PNP_GetRelatedDeviceInstance(%p %lu %S %p %p 0x%lx)\n",
766  hBinding, ulRelationship, pDeviceID, pRelatedDeviceId,
767  pulLength, ulFlags);
768 
769  if (!IsValidDeviceInstanceID(pDeviceID))
770  return CR_INVALID_DEVINST;
771 
773  pDeviceID);
774 
775  PlugPlayData.Relation = ulRelationship;
776 
777  PlugPlayData.RelatedDeviceInstanceLength = *pulLength;
778  PlugPlayData.RelatedDeviceInstance = pRelatedDeviceId;
779 
781  (PVOID)&PlugPlayData,
783  if (!NT_SUCCESS(Status))
784  {
786  }
787 
788  DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret);
789  if (ret == CR_SUCCESS)
790  {
791  DPRINT("RelatedDevice: %wZ\n", &PlugPlayData.RelatedDeviceInstance);
792  }
793 
794  return ret;
795 }
796 
797 
798 /* Function 9 */
799 DWORD
800 WINAPI
803  DWORD ulBranch,
804  DWORD ulIndex,
805  LPWSTR Buffer,
806  PNP_RPC_STRING_LEN ulLength,
807  PNP_RPC_STRING_LEN *pulRequiredLen,
808  DWORD ulFlags)
809 {
811  HKEY hKey;
812  DWORD dwError;
813 
815  UNREFERENCED_PARAMETER(ulFlags);
816 
817  DPRINT("PNP_EnumerateSubKeys(%p %lu %lu %p %lu %p 0x%08lx)\n",
818  hBinding, ulBranch, ulIndex, Buffer, ulLength,
819  pulRequiredLen, ulFlags);
820 
821  switch (ulBranch)
822  {
823  case PNP_ENUMERATOR_SUBKEYS:
824  hKey = hEnumKey;
825  break;
826 
827  case PNP_CLASS_SUBKEYS:
828  hKey = hClassKey;
829  break;
830 
831  default:
832  return CR_FAILURE;
833  }
834 
835  *pulRequiredLen = ulLength;
836  dwError = RegEnumKeyExW(hKey,
837  ulIndex,
838  Buffer,
839  pulRequiredLen,
840  NULL,
841  NULL,
842  NULL,
843  NULL);
844  if (dwError != ERROR_SUCCESS)
845  {
847  }
848  else
849  {
850  (*pulRequiredLen)++;
851  }
852 
853  DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
854 
855  return ret;
856 }
857 
858 
859 static
860 CONFIGRET
862  _In_ PWSTR pszDevice,
863  _In_ DWORD ulFlags,
864  _Inout_ PWSTR pszBuffer,
865  _Inout_ PDWORD pulLength)
866 {
870 
871  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
872  pszDevice);
873 
874  if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS)
875  {
876  PlugPlayData.Relations = 3;
877  }
878  else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS)
879  {
880  PlugPlayData.Relations = 2;
881  }
882  else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS)
883  {
884  PlugPlayData.Relations = 1;
885  }
886  else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS)
887  {
888  PlugPlayData.Relations = 0;
889  }
890 
891  PlugPlayData.BufferSize = *pulLength * sizeof(WCHAR);
892  PlugPlayData.Buffer = pszBuffer;
893 
895  (PVOID)&PlugPlayData,
897  if (NT_SUCCESS(Status))
898  {
899  *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR);
900  }
901  else
902  {
904  }
905 
906  return ret;
907 }
908 
909 
910 static
911 CONFIGRET
913  _In_ PWSTR pszService,
914  _Inout_ PWSTR pszBuffer,
915  _Inout_ PDWORD pulLength)
916 {
917  WCHAR szPathBuffer[512];
918  WCHAR szName[16];
919  HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL;
920  DWORD dwValues, dwSize, dwIndex, dwUsedLength, dwPathLength;
921  DWORD dwError;
922  PWSTR pPtr;
924 
925  /* Open the device key */
927  L"System\\CurrentControlSet\\Services",
928  0,
929  KEY_READ,
930  &hServicesKey);
931  if (dwError != ERROR_SUCCESS)
932  {
933  DPRINT("Failed to open the services key (Error %lu)\n", dwError);
934  return CR_REGISTRY_ERROR;
935  }
936 
937  dwError = RegOpenKeyExW(hServicesKey,
938  pszService,
939  0,
940  KEY_READ,
941  &hServiceKey);
942  if (dwError != ERROR_SUCCESS)
943  {
944  DPRINT("Failed to open the service key (Error %lu)\n", dwError);
946  goto Done;
947  }
948 
949  dwError = RegOpenKeyExW(hServiceKey,
950  L"Enum",
951  0,
952  KEY_READ,
953  &hEnumKey);
954  if (dwError != ERROR_SUCCESS)
955  {
956  DPRINT("Failed to open the service enum key (Error %lu)\n", dwError);
958  goto Done;
959  }
960 
961  /* Retrieve the number of device instances */
962  dwSize = sizeof(DWORD);
963  dwError = RegQueryValueExW(hEnumKey,
964  L"Count",
965  NULL,
966  NULL,
967  (LPBYTE)&dwValues,
968  &dwSize);
969  if (dwError != ERROR_SUCCESS)
970  {
971  DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError);
972  dwValues = 1;
973  }
974 
975  DPRINT("dwValues %lu\n", dwValues);
976 
977  dwUsedLength = 0;
978  pPtr = pszBuffer;
979 
980  for (dwIndex = 0; dwIndex < dwValues; dwIndex++)
981  {
982  wsprintf(szName, L"%lu", dwIndex);
983 
984  dwSize = sizeof(szPathBuffer);
985  dwError = RegQueryValueExW(hEnumKey,
986  szName,
987  NULL,
988  NULL,
989  (LPBYTE)szPathBuffer,
990  &dwSize);
991  if (dwError != ERROR_SUCCESS)
992  break;
993 
994  DPRINT("Path: %S\n", szPathBuffer);
995 
996  dwPathLength = wcslen(szPathBuffer) + 1;
997  if (dwUsedLength + dwPathLength + 1 > *pulLength)
998  {
1000  break;
1001  }
1002 
1003  wcscpy(pPtr, szPathBuffer);
1004  dwUsedLength += dwPathLength;
1005  pPtr += dwPathLength;
1006 
1007  *pPtr = UNICODE_NULL;
1008  }
1009 
1010 Done:
1011  if (hEnumKey != NULL)
1013 
1014  if (hServiceKey != NULL)
1015  RegCloseKey(hServiceKey);
1016 
1017  if (hServicesKey != NULL)
1019 
1020  if (ret == CR_SUCCESS)
1021  *pulLength = dwUsedLength + 1;
1022  else
1023  *pulLength = 0;
1024 
1025  return ret;
1026 }
1027 
1028 
1029 static
1030 CONFIGRET
1032  _In_ PWSTR pszDevice,
1033  _Inout_ PWSTR pszBuffer,
1034  _Inout_ PDWORD pulLength)
1035 {
1036  WCHAR szInstanceBuffer[MAX_DEVICE_ID_LEN];
1037  WCHAR szPathBuffer[512];
1038  HKEY hDeviceKey;
1039  DWORD dwInstanceLength, dwPathLength, dwUsedLength;
1040  DWORD dwIndex, dwError;
1041  PWSTR pPtr;
1043 
1044  /* Open the device key */
1045  dwError = RegOpenKeyExW(hEnumKey,
1046  pszDevice,
1047  0,
1049  &hDeviceKey);
1050  if (dwError != ERROR_SUCCESS)
1051  {
1052  DPRINT("Failed to open the device key (Error %lu)\n", dwError);
1053  return CR_REGISTRY_ERROR;
1054  }
1055 
1056  dwUsedLength = 0;
1057  pPtr = pszBuffer;
1058 
1059  for (dwIndex = 0; ; dwIndex++)
1060  {
1061  dwInstanceLength = MAX_DEVICE_ID_LEN;
1062  dwError = RegEnumKeyExW(hDeviceKey,
1063  dwIndex,
1064  szInstanceBuffer,
1065  &dwInstanceLength,
1066  NULL,
1067  NULL,
1068  NULL,
1069  NULL);
1070  if (dwError != ERROR_SUCCESS)
1071  break;
1072 
1073  wsprintf(szPathBuffer, L"%s\\%s", pszDevice, szInstanceBuffer);
1074  DPRINT("Path: %S\n", szPathBuffer);
1075 
1076  dwPathLength = wcslen(szPathBuffer) + 1;
1077  if (dwUsedLength + dwPathLength + 1 > *pulLength)
1078  {
1079  ret = CR_BUFFER_SMALL;
1080  break;
1081  }
1082 
1083  wcscpy(pPtr, szPathBuffer);
1084  dwUsedLength += dwPathLength;
1085  pPtr += dwPathLength;
1086 
1087  *pPtr = UNICODE_NULL;
1088  }
1089 
1090  RegCloseKey(hDeviceKey);
1091 
1092  if (ret == CR_SUCCESS)
1093  *pulLength = dwUsedLength + 1;
1094  else
1095  *pulLength = 0;
1096 
1097  return ret;
1098 }
1099 
1100 
1101 CONFIGRET
1103  _In_ PWSTR pszEnumerator,
1104  _Inout_ PWSTR pszBuffer,
1105  _Inout_ PDWORD pulLength)
1106 {
1107  WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN];
1108  WCHAR szPathBuffer[512];
1109  HKEY hEnumeratorKey;
1110  PWSTR pPtr;
1111  DWORD dwIndex, dwDeviceLength, dwUsedLength, dwRemainingLength, dwPathLength;
1112  DWORD dwError;
1114 
1115  /* Open the enumerator key */
1116  dwError = RegOpenKeyExW(hEnumKey,
1117  pszEnumerator,
1118  0,
1120  &hEnumeratorKey);
1121  if (dwError != ERROR_SUCCESS)
1122  {
1123  DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError);
1124  return CR_REGISTRY_ERROR;
1125  }
1126 
1127  dwUsedLength = 0;
1128  dwRemainingLength = *pulLength;
1129  pPtr = pszBuffer;
1130 
1131  for (dwIndex = 0; ; dwIndex++)
1132  {
1133  dwDeviceLength = MAX_DEVICE_ID_LEN;
1134  dwError = RegEnumKeyExW(hEnumeratorKey,
1135  dwIndex,
1136  szDeviceBuffer,
1137  &dwDeviceLength,
1138  NULL,
1139  NULL,
1140  NULL,
1141  NULL);
1142  if (dwError != ERROR_SUCCESS)
1143  break;
1144 
1145  wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer);
1146  DPRINT("Path: %S\n", szPathBuffer);
1147 
1148  dwPathLength = dwRemainingLength;
1149  ret = GetDeviceInstanceList(szPathBuffer,
1150  pPtr,
1151  &dwPathLength);
1152  if (ret != CR_SUCCESS)
1153  break;
1154 
1155  dwUsedLength += dwPathLength - 1;
1156  dwRemainingLength -= dwPathLength - 1;
1157  pPtr += dwPathLength - 1;
1158  }
1159 
1160  RegCloseKey(hEnumeratorKey);
1161 
1162  if (ret == CR_SUCCESS)
1163  *pulLength = dwUsedLength + 1;
1164  else
1165  *pulLength = 0;
1166 
1167  return ret;
1168 }
1169 
1170 
1171 static
1172 CONFIGRET
1174  _Inout_ PWSTR pszBuffer,
1175  _Inout_ PDWORD pulLength)
1176 {
1177  WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN];
1178  PWSTR pPtr;
1179  DWORD dwIndex, dwEnumeratorLength, dwUsedLength, dwRemainingLength, dwPathLength;
1180  DWORD dwError;
1182 
1183  dwUsedLength = 0;
1184  dwRemainingLength = *pulLength;
1185  pPtr = pszBuffer;
1186 
1187  for (dwIndex = 0; ; dwIndex++)
1188  {
1189  dwEnumeratorLength = MAX_DEVICE_ID_LEN;
1190  dwError = RegEnumKeyExW(hEnumKey,
1191  dwIndex,
1192  szEnumeratorBuffer,
1193  &dwEnumeratorLength,
1194  NULL, NULL, NULL, NULL);
1195  if (dwError != ERROR_SUCCESS)
1196  break;
1197 
1198  dwPathLength = dwRemainingLength;
1199  ret = GetEnumeratorInstanceList(szEnumeratorBuffer,
1200  pPtr,
1201  &dwPathLength);
1202  if (ret != CR_SUCCESS)
1203  break;
1204 
1205  dwUsedLength += dwPathLength - 1;
1206  dwRemainingLength -= dwPathLength - 1;
1207  pPtr += dwPathLength - 1;
1208  }
1209 
1210  if (ret == CR_SUCCESS)
1211  *pulLength = dwUsedLength + 1;
1212  else
1213  *pulLength = 0;
1214 
1215  return ret;
1216 }
1217 
1218 
1219 /* Function 10 */
1220 DWORD
1221 WINAPI
1224  LPWSTR pszFilter,
1225  LPWSTR Buffer,
1226  PNP_RPC_STRING_LEN *pulLength,
1227  DWORD ulFlags)
1228 {
1229  WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
1230  WCHAR szDevice[MAX_DEVICE_ID_LEN];
1231  WCHAR szInstance[MAX_DEVICE_ID_LEN];
1233 
1234  DPRINT("PNP_GetDeviceList(%p %S %p %p 0x%08lx)\n",
1235  hBinding, pszFilter, Buffer, pulLength, ulFlags);
1236 
1237  if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
1238  return CR_INVALID_FLAG;
1239 
1240  if (pulLength == NULL)
1241  return CR_INVALID_POINTER;
1242 
1243  if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
1244  (pszFilter == NULL))
1245  return CR_INVALID_POINTER;
1246 
1247  if (ulFlags &
1252  {
1253  ret = GetRelationsInstanceList(pszFilter,
1254  ulFlags,
1255  Buffer,
1256  pulLength);
1257  }
1258  else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
1259  {
1260  ret = GetServiceInstanceList(pszFilter,
1261  Buffer,
1262  pulLength);
1263  }
1264  else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
1265  {
1266  SplitDeviceInstanceID(pszFilter,
1267  szEnumerator,
1268  szDevice,
1269  szInstance);
1270 
1271  if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
1272  {
1273  ret = GetDeviceInstanceList(pszFilter,
1274  Buffer,
1275  pulLength);
1276  }
1277  else
1278  {
1279  ret = GetEnumeratorInstanceList(pszFilter,
1280  Buffer,
1281  pulLength);
1282  }
1283  }
1284  else /* CM_GETIDLIST_FILTER_NONE */
1285  {
1287  pulLength);
1288  }
1289 
1290  return ret;
1291 }
1292 
1293 
1294 static
1295 CONFIGRET
1297  _In_ PWSTR pszDevice,
1298  _In_ DWORD ulFlags,
1299  _Inout_ PDWORD pulLength)
1300 {
1302  NTSTATUS Status;
1304 
1305  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
1306  pszDevice);
1307 
1308  if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS)
1309  {
1310  PlugPlayData.Relations = 3;
1311  }
1312  else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS)
1313  {
1314  PlugPlayData.Relations = 2;
1315  }
1316  else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS)
1317  {
1318  PlugPlayData.Relations = 1;
1319  }
1320  else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS)
1321  {
1322  PlugPlayData.Relations = 0;
1323  }
1324 
1325  PlugPlayData.BufferSize = 0;
1326  PlugPlayData.Buffer = NULL;
1327 
1329  (PVOID)&PlugPlayData,
1331  if (NT_SUCCESS(Status))
1332  {
1333  *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR);
1334  }
1335  else
1336  {
1338  }
1339 
1340  return ret;
1341 }
1342 
1343 
1344 static
1345 CONFIGRET
1347  _In_ PWSTR pszService,
1348  _Out_ PDWORD pulLength)
1349 {
1350  HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL;
1351  DWORD dwValues, dwMaxValueLength, dwSize;
1352  DWORD dwError;
1354 
1355  /* Open the device key */
1357  L"System\\CurrentControlSet\\Services",
1358  0,
1359  KEY_READ,
1360  &hServicesKey);
1361  if (dwError != ERROR_SUCCESS)
1362  {
1363  DPRINT("Failed to open the services key (Error %lu)\n", dwError);
1364  return CR_REGISTRY_ERROR;
1365  }
1366 
1367  dwError = RegOpenKeyExW(hServicesKey,
1368  pszService,
1369  0,
1370  KEY_READ,
1371  &hServiceKey);
1372  if (dwError != ERROR_SUCCESS)
1373  {
1374  DPRINT("Failed to open the service key (Error %lu)\n", dwError);
1376  goto Done;
1377  }
1378 
1379  dwError = RegOpenKeyExW(hServiceKey,
1380  L"Enum",
1381  0,
1382  KEY_READ,
1383  &hEnumKey);
1384  if (dwError != ERROR_SUCCESS)
1385  {
1386  DPRINT("Failed to open the service enum key (Error %lu)\n", dwError);
1388  goto Done;
1389  }
1390 
1391  /* Retrieve the number of device instances */
1392  dwSize = sizeof(DWORD);
1393  dwError = RegQueryValueExW(hEnumKey,
1394  L"Count",
1395  NULL,
1396  NULL,
1397  (LPBYTE)&dwValues,
1398  &dwSize);
1399  if (dwError != ERROR_SUCCESS)
1400  {
1401  DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError);
1402  dwValues = 1;
1403  }
1404 
1405  /* Retrieve the maximum instance name length */
1406  dwError = RegQueryInfoKeyW(hEnumKey,
1407  NULL,
1408  NULL,
1409  NULL,
1410  NULL,
1411  NULL,
1412  NULL,
1413  NULL,
1414  NULL,
1415  &dwMaxValueLength,
1416  NULL,
1417  NULL);
1418  if (dwError != ERROR_SUCCESS)
1419  {
1420  DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
1421  dwMaxValueLength = MAX_DEVICE_ID_LEN;
1422  }
1423 
1424  DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues, dwMaxValueLength / sizeof(WCHAR));
1425 
1426  /* Return the largest possible buffer size */
1427  *pulLength = dwValues * dwMaxValueLength / sizeof(WCHAR) + 2;
1428 
1429 Done:
1430  if (hEnumKey != NULL)
1432 
1433  if (hServiceKey != NULL)
1434  RegCloseKey(hServiceKey);
1435 
1436  if (hServicesKey != NULL)
1438 
1439  return ret;
1440 }
1441 
1442 
1443 static
1444 CONFIGRET
1446  _In_ LPCWSTR pszDevice,
1447  _Out_ PULONG pulLength)
1448 {
1449  HKEY hDeviceKey;
1450  DWORD dwSubKeys, dwMaxSubKeyLength;
1451  DWORD dwError;
1452 
1453  /* Open the device key */
1454  dwError = RegOpenKeyExW(hEnumKey,
1455  pszDevice,
1456  0,
1457  KEY_READ,
1458  &hDeviceKey);
1459  if (dwError != ERROR_SUCCESS)
1460  {
1461  DPRINT("Failed to open the device key (Error %lu)\n", dwError);
1462  return CR_REGISTRY_ERROR;
1463  }
1464 
1465  /* Retrieve the number of device instances and the maximum name length */
1466  dwError = RegQueryInfoKeyW(hDeviceKey,
1467  NULL,
1468  NULL,
1469  NULL,
1470  &dwSubKeys,
1471  &dwMaxSubKeyLength,
1472  NULL,
1473  NULL,
1474  NULL,
1475  NULL,
1476  NULL,
1477  NULL);
1478  if (dwError != ERROR_SUCCESS)
1479  {
1480  DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
1481  dwSubKeys = 0;
1482  dwMaxSubKeyLength = 0;
1483  }
1484 
1485  /* Close the device key */
1486  RegCloseKey(hDeviceKey);
1487 
1488  /* Return the largest possible buffer size */
1489  *pulLength = dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1);
1490 
1491  return CR_SUCCESS;
1492 }
1493 
1494 
1495 static
1496 CONFIGRET
1498  _In_ LPCWSTR pszEnumerator,
1499  _Out_ PULONG pulLength)
1500 {
1501  WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN];
1502  WCHAR szPathBuffer[512];
1503  HKEY hEnumeratorKey;
1504  DWORD dwIndex, dwDeviceLength, dwBufferLength;
1505  DWORD dwError;
1507 
1508  *pulLength = 0;
1509 
1510  /* Open the enumerator key */
1511  dwError = RegOpenKeyExW(hEnumKey,
1512  pszEnumerator,
1513  0,
1515  &hEnumeratorKey);
1516  if (dwError != ERROR_SUCCESS)
1517  {
1518  DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError);
1519  return CR_REGISTRY_ERROR;
1520  }
1521 
1522  for (dwIndex = 0; ; dwIndex++)
1523  {
1524  dwDeviceLength = MAX_DEVICE_ID_LEN;
1525  dwError = RegEnumKeyExW(hEnumeratorKey,
1526  dwIndex,
1527  szDeviceBuffer,
1528  &dwDeviceLength,
1529  NULL,
1530  NULL,
1531  NULL,
1532  NULL);
1533  if (dwError != ERROR_SUCCESS)
1534  break;
1535 
1536  wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer);
1537  DPRINT("Path: %S\n", szPathBuffer);
1538 
1539  ret = GetDeviceInstanceListSize(szPathBuffer, &dwBufferLength);
1540  if (ret != CR_SUCCESS)
1541  {
1542  *pulLength = 0;
1543  break;
1544  }
1545 
1546  *pulLength += dwBufferLength;
1547  }
1548 
1549  /* Close the enumerator key */
1550  RegCloseKey(hEnumeratorKey);
1551 
1552  return ret;
1553 }
1554 
1555 
1556 static
1557 CONFIGRET
1559  _Out_ PULONG pulLength)
1560 {
1561  WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN];
1562  DWORD dwIndex, dwEnumeratorLength, dwBufferLength;
1563  DWORD dwError;
1565 
1566  for (dwIndex = 0; ; dwIndex++)
1567  {
1568  dwEnumeratorLength = MAX_DEVICE_ID_LEN;
1569  dwError = RegEnumKeyExW(hEnumKey,
1570  dwIndex,
1571  szEnumeratorBuffer,
1572  &dwEnumeratorLength,
1573  NULL, NULL, NULL, NULL);
1574  if (dwError != ERROR_SUCCESS)
1575  break;
1576 
1577  /* Get the size of all device instances for the enumerator */
1578  ret = GetEnumeratorInstanceListSize(szEnumeratorBuffer,
1579  &dwBufferLength);
1580  if (ret != CR_SUCCESS)
1581  break;
1582 
1583  *pulLength += dwBufferLength;
1584  }
1585 
1586  return ret;
1587 }
1588 
1589 
1590 /* Function 11 */
1591 DWORD
1592 WINAPI
1595  LPWSTR pszFilter,
1596  PNP_RPC_BUFFER_SIZE *pulLength,
1597  DWORD ulFlags)
1598 {
1599  WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
1600  WCHAR szDevice[MAX_DEVICE_ID_LEN];
1601  WCHAR szInstance[MAX_DEVICE_ID_LEN];
1603 
1604  DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%08lx)\n",
1605  hBinding, pszFilter, pulLength, ulFlags);
1606 
1607  if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
1608  return CR_INVALID_FLAG;
1609 
1610  if (pulLength == NULL)
1611  return CR_INVALID_POINTER;
1612 
1613  if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
1614  (pszFilter == NULL))
1615  return CR_INVALID_POINTER;
1616 
1617  *pulLength = 0;
1618 
1619  if (ulFlags &
1624  {
1625  ret = GetRelationsInstanceListSize(pszFilter,
1626  ulFlags,
1627  pulLength);
1628  }
1629  else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
1630  {
1631  ret = GetServiceInstanceListSize(pszFilter,
1632  pulLength);
1633  }
1634  else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
1635  {
1636  SplitDeviceInstanceID(pszFilter,
1637  szEnumerator,
1638  szDevice,
1639  szInstance);
1640 
1641  if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
1642  {
1643  ret = GetDeviceInstanceListSize(pszFilter,
1644  pulLength);
1645  }
1646  else
1647  {
1648  ret = GetEnumeratorInstanceListSize(pszFilter,
1649  pulLength);
1650  }
1651  }
1652  else /* CM_GETIDLIST_FILTER_NONE */
1653  {
1654  ret = GetAllInstanceListSize(pulLength);
1655  }
1656 
1657  /* Add one character for the terminating double UNICODE_NULL */
1658  if (ret == CR_SUCCESS)
1659  (*pulLength) += 1;
1660 
1661  return ret;
1662 }
1663 
1664 
1665 /* Function 12 */
1666 DWORD
1667 WINAPI
1670  LPWSTR pszDeviceID,
1671  DWORD *pulDepth,
1672  DWORD ulFlags)
1673 {
1674  PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData;
1676  NTSTATUS Status;
1677 
1679  UNREFERENCED_PARAMETER(ulFlags);
1680 
1681  DPRINT("PNP_GetDepth(%p %S %p 0x%08lx)\n",
1682  hBinding, pszDeviceID, pulDepth, ulFlags);
1683 
1684  if (!IsValidDeviceInstanceID(pszDeviceID))
1685  return CR_INVALID_DEVINST;
1686 
1687  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
1688  pszDeviceID);
1689 
1691  (PVOID)&PlugPlayData,
1692  sizeof(PLUGPLAY_CONTROL_DEPTH_DATA));
1693  if (NT_SUCCESS(Status))
1694  {
1695  *pulDepth = PlugPlayData.Depth;
1696  }
1697  else
1698  {
1700  }
1701 
1702  DPRINT("PNP_GetDepth() done (returns %lx)\n", ret);
1703 
1704  return ret;
1705 }
1706 
1707 
1708 /* Function 13 */
1709 DWORD
1710 WINAPI
1713  LPWSTR pDeviceID,
1714  DWORD ulProperty,
1715  DWORD *pulRegDataType,
1716  BYTE *Buffer,
1717  PNP_PROP_SIZE *pulTransferLen,
1718  PNP_PROP_SIZE *pulLength,
1719  DWORD ulFlags)
1720 {
1721  PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData;
1723  LPWSTR lpValueName = NULL;
1724  HKEY hKey = NULL;
1725  LONG lError;
1726  NTSTATUS Status;
1727 
1729 
1730  DPRINT("PNP_GetDeviceRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
1731  hBinding, pDeviceID, ulProperty, pulRegDataType, Buffer,
1732  pulTransferLen, pulLength, ulFlags);
1733 
1734  if (pulTransferLen == NULL || pulLength == NULL)
1735  {
1737  goto done;
1738  }
1739 
1740  if (ulFlags != 0)
1741  {
1742  ret = CR_INVALID_FLAG;
1743  goto done;
1744  }
1745 
1746  /* Check pDeviceID */
1747  if (!IsValidDeviceInstanceID(pDeviceID))
1748  {
1750  goto done;
1751  }
1752 
1753  if (*pulLength < *pulTransferLen)
1754  *pulLength = *pulTransferLen;
1755 
1756  *pulTransferLen = 0;
1757 
1758  switch (ulProperty)
1759  {
1760  case CM_DRP_DEVICEDESC:
1761  lpValueName = L"DeviceDesc";
1762  break;
1763 
1764  case CM_DRP_HARDWAREID:
1765  lpValueName = L"HardwareID";
1766  break;
1767 
1768  case CM_DRP_COMPATIBLEIDS:
1769  lpValueName = L"CompatibleIDs";
1770  break;
1771 
1772  case CM_DRP_SERVICE:
1773  lpValueName = L"Service";
1774  break;
1775 
1776  case CM_DRP_CLASS:
1777  lpValueName = L"Class";
1778  break;
1779 
1780  case CM_DRP_CLASSGUID:
1781  lpValueName = L"ClassGUID";
1782  break;
1783 
1784  case CM_DRP_DRIVER:
1785  lpValueName = L"Driver";
1786  break;
1787 
1788  case CM_DRP_CONFIGFLAGS:
1789  lpValueName = L"ConfigFlags";
1790  break;
1791 
1792  case CM_DRP_MFG:
1793  lpValueName = L"Mfg";
1794  break;
1795 
1796  case CM_DRP_FRIENDLYNAME:
1797  lpValueName = L"FriendlyName";
1798  break;
1799 
1801  lpValueName = L"LocationInformation";
1802  break;
1803 
1806  *pulRegDataType = REG_SZ;
1807  break;
1808 
1809  case CM_DRP_CAPABILITIES:
1810  lpValueName = L"Capabilities";
1811  break;
1812 
1813  case CM_DRP_UI_NUMBER:
1814  PlugPlayData.Property = PNP_PROPERTY_UI_NUMBER;
1815  break;
1816 
1817  case CM_DRP_UPPERFILTERS:
1818  lpValueName = L"UpperFilters";
1819  break;
1820 
1821  case CM_DRP_LOWERFILTERS:
1822  lpValueName = L"LowerFilters";
1823  break;
1824 
1825  case CM_DRP_BUSTYPEGUID:
1826  PlugPlayData.Property = PNP_PROPERTY_BUSTYPEGUID;
1827  *pulRegDataType = REG_BINARY;
1828  break;
1829 
1830  case CM_DRP_LEGACYBUSTYPE:
1831  PlugPlayData.Property = PNP_PROPERTY_LEGACYBUSTYPE;
1832  *pulRegDataType = REG_DWORD;
1833  break;
1834 
1835  case CM_DRP_BUSNUMBER:
1836  PlugPlayData.Property = PNP_PROPERTY_BUSNUMBER;
1837  *pulRegDataType = REG_DWORD;
1838  break;
1839 
1841  PlugPlayData.Property = PNP_PROPERTY_ENUMERATOR_NAME;
1842  *pulRegDataType = REG_SZ;
1843  break;
1844 
1845  case CM_DRP_SECURITY:
1846  lpValueName = L"Security";
1847  break;
1848 
1849  case CM_DRP_DEVTYPE:
1850  lpValueName = L"DeviceType";
1851  break;
1852 
1853  case CM_DRP_EXCLUSIVE:
1854  lpValueName = L"Exclusive";
1855  break;
1856 
1858  lpValueName = L"DeviceCharacteristics";
1859  break;
1860 
1861  case CM_DRP_ADDRESS:
1862  PlugPlayData.Property = PNP_PROPERTY_ADDRESS;
1863  *pulRegDataType = REG_DWORD;
1864  break;
1865 
1867  lpValueName = L"UINumberDescFormat";
1868  break;
1869 
1871  PlugPlayData.Property = PNP_PROPERTY_POWER_DATA;
1872  *pulRegDataType = REG_BINARY;
1873  break;
1874 
1875  case CM_DRP_REMOVAL_POLICY:
1876  PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY;
1877  *pulRegDataType = REG_DWORD;
1878  break;
1879 
1882  *pulRegDataType = REG_DWORD;
1883  break;
1884 
1886  lpValueName = L"RemovalPolicy";
1887  *pulRegDataType = REG_DWORD;
1888  break;
1889 
1890  case CM_DRP_INSTALL_STATE:
1891  PlugPlayData.Property = PNP_PROPERTY_INSTALL_STATE;
1892  *pulRegDataType = REG_DWORD;
1893  break;
1894 
1895 #if (WINVER >= _WIN32_WINNT_WS03)
1896  case CM_DRP_LOCATION_PATHS:
1897  PlugPlayData.Property = PNP_PROPERTY_LOCATION_PATHS;
1898  *pulRegDataType = REG_MULTI_SZ;
1899  break;
1900 #endif
1901 
1902 #if (WINVER >= _WIN32_WINNT_WIN7)
1904  PlugPlayData.Property = PNP_PROPERTY_CONTAINERID;
1905  *pulRegDataType = REG_SZ;
1906  break;
1907 #endif
1908 
1909  default:
1911  goto done;
1912  }
1913 
1914  DPRINT("Value name: %S\n", lpValueName);
1915 
1916  if (lpValueName)
1917  {
1918  /* Retrieve information from the Registry */
1919  lError = RegOpenKeyExW(hEnumKey,
1920  pDeviceID,
1921  0,
1923  &hKey);
1924  if (lError != ERROR_SUCCESS)
1925  {
1926  hKey = NULL;
1927  *pulLength = 0;
1929  goto done;
1930  }
1931 
1932  lError = RegQueryValueExW(hKey,
1933  lpValueName,
1934  NULL,
1935  pulRegDataType,
1936  Buffer,
1937  pulLength);
1938  if (lError != ERROR_SUCCESS)
1939  {
1940  if (lError == ERROR_MORE_DATA)
1941  {
1942  ret = CR_BUFFER_SMALL;
1943  }
1944  else
1945  {
1946  *pulLength = 0;
1948  }
1949  }
1950  }
1951  else
1952  {
1953  /* Retrieve information from the Device Node */
1954  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
1955  pDeviceID);
1956  PlugPlayData.Buffer = Buffer;
1957  PlugPlayData.BufferSize = *pulLength;
1958 
1960  (PVOID)&PlugPlayData,
1962  if (NT_SUCCESS(Status))
1963  {
1964  *pulLength = PlugPlayData.BufferSize;
1965  }
1966  else
1967  {
1969  }
1970  }
1971 
1972 done:
1973  if (pulTransferLen)
1974  *pulTransferLen = (ret == CR_SUCCESS) ? *pulLength : 0;
1975 
1976  if (hKey != NULL)
1977  RegCloseKey(hKey);
1978 
1979  DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret);
1980 
1981  return ret;
1982 }
1983 
1984 
1985 /* Function 14 */
1986 DWORD
1987 WINAPI
1990  LPWSTR pDeviceId,
1991  DWORD ulProperty,
1992  DWORD ulDataType,
1993  BYTE *Buffer,
1994  PNP_PROP_SIZE ulLength,
1995  DWORD ulFlags)
1996 {
1998  LPWSTR lpValueName = NULL;
1999  HKEY hKey = 0;
2000 
2002  UNREFERENCED_PARAMETER(ulFlags);
2003 
2004  DPRINT("PNP_SetDeviceRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
2005  hBinding, pDeviceId, ulProperty, ulDataType, Buffer,
2006  ulLength, ulFlags);
2007 
2008  if (!IsValidDeviceInstanceID(pDeviceId))
2009  return CR_INVALID_DEVINST;
2010 
2011  switch (ulProperty)
2012  {
2013  case CM_DRP_DEVICEDESC:
2014  lpValueName = L"DeviceDesc";
2015  break;
2016 
2017  case CM_DRP_HARDWAREID:
2018  lpValueName = L"HardwareID";
2019  break;
2020 
2021  case CM_DRP_COMPATIBLEIDS:
2022  lpValueName = L"CompatibleIDs";
2023  break;
2024 
2025  case CM_DRP_SERVICE:
2026  lpValueName = L"Service";
2027  break;
2028 
2029  case CM_DRP_CLASS:
2030  lpValueName = L"Class";
2031  break;
2032 
2033  case CM_DRP_CLASSGUID:
2034  lpValueName = L"ClassGUID";
2035  break;
2036 
2037  case CM_DRP_DRIVER:
2038  lpValueName = L"Driver";
2039  break;
2040 
2041  case CM_DRP_CONFIGFLAGS:
2042  lpValueName = L"ConfigFlags";
2043  break;
2044 
2045  case CM_DRP_MFG:
2046  lpValueName = L"Mfg";
2047  break;
2048 
2049  case CM_DRP_FRIENDLYNAME:
2050  lpValueName = L"FriendlyName";
2051  break;
2052 
2054  lpValueName = L"LocationInformation";
2055  break;
2056 
2057  case CM_DRP_UPPERFILTERS:
2058  lpValueName = L"UpperFilters";
2059  break;
2060 
2061  case CM_DRP_LOWERFILTERS:
2062  lpValueName = L"LowerFilters";
2063  break;
2064 
2065  case CM_DRP_SECURITY:
2066  lpValueName = L"Security";
2067  break;
2068 
2069  case CM_DRP_DEVTYPE:
2070  lpValueName = L"DeviceType";
2071  break;
2072 
2073  case CM_DRP_EXCLUSIVE:
2074  lpValueName = L"Exclusive";
2075  break;
2076 
2078  lpValueName = L"DeviceCharacteristics";
2079  break;
2080 
2082  lpValueName = L"UINumberDescFormat";
2083  break;
2084 
2086  lpValueName = L"RemovalPolicy";
2087  break;
2088 
2089  default:
2090  return CR_INVALID_PROPERTY;
2091  }
2092 
2093  DPRINT("Value name: %S\n", lpValueName);
2094 
2095  if (RegOpenKeyExW(hEnumKey,
2096  pDeviceId,
2097  0,
2098  KEY_SET_VALUE,
2099  &hKey))
2100  return CR_INVALID_DEVNODE;
2101 
2102  if (ulLength == 0)
2103  {
2104  if (RegDeleteValueW(hKey,
2105  lpValueName))
2107  }
2108  else
2109  {
2110  if (RegSetValueExW(hKey,
2111  lpValueName,
2112  0,
2113  ulDataType,
2114  Buffer,
2115  ulLength))
2117  }
2118 
2119  RegCloseKey(hKey);
2120 
2121  DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret);
2122 
2123  return ret;
2124 }
2125 
2126 
2127 /* Function 15 */
2128 DWORD
2129 WINAPI
2132  LPWSTR pDeviceId,
2133  LPWSTR pszClassInstance,
2134  PNP_RPC_STRING_LEN ulLength)
2135 {
2136  WCHAR szClassGuid[40];
2137  WCHAR szClassInstance[5];
2138  HKEY hDeviceClassKey = NULL;
2139  HKEY hClassInstanceKey;
2140  ULONG ulTransferLength, ulDataLength;
2141  DWORD dwDataType, dwDisposition, i;
2142  DWORD dwError;
2144 
2145  DPRINT("PNP_GetClassInstance(%p %S %p %lu)\n",
2146  hBinding, pDeviceId, pszClassInstance, ulLength);
2147 
2148  if (!IsValidDeviceInstanceID(pDeviceId))
2149  return CR_INVALID_DEVINST;
2150 
2151  ulTransferLength = ulLength;
2153  pDeviceId,
2154  CM_DRP_DRIVER,
2155  &dwDataType,
2156  (BYTE *)pszClassInstance,
2157  &ulTransferLength,
2158  &ulLength,
2159  0);
2160  if (ret == CR_SUCCESS)
2161  return ret;
2162 
2163  ulTransferLength = sizeof(szClassGuid);
2164  ulDataLength = sizeof(szClassGuid);
2166  pDeviceId,
2168  &dwDataType,
2169  (BYTE *)szClassGuid,
2170  &ulTransferLength,
2171  &ulDataLength,
2172  0);
2173  if (ret != CR_SUCCESS)
2174  {
2175  DPRINT1("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret);
2176  goto done;
2177  }
2178 
2179  dwError = RegOpenKeyExW(hClassKey,
2180  szClassGuid,
2181  0,
2182  KEY_READ,
2183  &hDeviceClassKey);
2184  if (dwError != ERROR_SUCCESS)
2185  {
2186  DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError);
2187  ret = CR_FAILURE;
2188  goto done;
2189  }
2190 
2191  for (i = 0; i < 10000; i++)
2192  {
2193  wsprintf(szClassInstance, L"%04lu", i);
2194 
2195  dwError = RegCreateKeyExW(hDeviceClassKey,
2196  szClassInstance,
2197  0,
2198  NULL,
2201  NULL,
2202  &hClassInstanceKey,
2203  &dwDisposition);
2204  if (dwError == ERROR_SUCCESS)
2205  {
2206  RegCloseKey(hClassInstanceKey);
2207 
2208  if (dwDisposition == REG_CREATED_NEW_KEY)
2209  {
2210  wsprintf(pszClassInstance,
2211  L"%s\\%s",
2212  szClassGuid,
2213  szClassInstance);
2214 
2215  ulDataLength = (wcslen(pszClassInstance) + 1) * sizeof(WCHAR);
2217  pDeviceId,
2218  CM_DRP_DRIVER,
2219  REG_SZ,
2220  (BYTE *)pszClassInstance,
2221  ulDataLength,
2222  0);
2223  if (ret != CR_SUCCESS)
2224  {
2225  DPRINT1("PNP_SetDeviceRegProp() failed (Error %lu)\n", ret);
2226  RegDeleteKeyW(hDeviceClassKey,
2227  szClassInstance);
2228  }
2229 
2230  break;
2231  }
2232  }
2233  }
2234 
2235 done:
2236  if (hDeviceClassKey != NULL)
2237  RegCloseKey(hDeviceClassKey);
2238 
2239  return ret;
2240 }
2241 
2242 
2243 /* Function 16 */
2244 DWORD
2245 WINAPI
2248  LPWSTR pszSubKey,
2249  DWORD samDesired,
2250  DWORD ulFlags)
2251 {
2252  HKEY hDeviceKey = NULL, hParametersKey = NULL;
2253  DWORD dwError;
2255 
2257  UNREFERENCED_PARAMETER(samDesired);
2258 
2259  DPRINT("PNP_CreateKey(%p %S 0x%lx 0x%08lx)\n",
2260  hBinding, pszSubKey, samDesired, ulFlags);
2261 
2262  if (ulFlags != 0)
2263  return CR_INVALID_FLAG;
2264 
2265  if (!IsValidDeviceInstanceID(pszSubKey))
2266  return CR_INVALID_DEVINST;
2267 
2268  dwError = RegOpenKeyExW(hEnumKey,
2269  pszSubKey,
2270  0,
2271  KEY_WRITE,
2272  &hDeviceKey);
2273  if (dwError != ERROR_SUCCESS)
2274  {
2276  goto done;
2277  }
2278 
2279  dwError = RegCreateKeyExW(hDeviceKey,
2280  L"Device Parameters",
2281  0,
2282  NULL,
2285  NULL,
2286  &hParametersKey,
2287  NULL);
2288  if (dwError != ERROR_SUCCESS)
2289  {
2291  goto done;
2292  }
2293 
2294  /* FIXME: Set key security */
2295 
2296 done:
2297  if (hParametersKey != NULL)
2298  RegCloseKey(hParametersKey);
2299 
2300  if (hDeviceKey != NULL)
2301  RegCloseKey(hDeviceKey);
2302 
2303  return ret;
2304 }
2305 
2306 
2307 /* Function 17 */
2308 DWORD
2309 WINAPI
2312  LPWSTR pszDeviceID,
2313  LPWSTR pszParentKey,
2314  LPWSTR pszChildKey,
2315  DWORD ulFlags)
2316 {
2317  UNIMPLEMENTED;
2318  return CR_CALL_NOT_IMPLEMENTED;
2319 }
2320 
2321 
2322 /* Function 18 */
2323 DWORD
2324 WINAPI
2327  DWORD *pulClassCount,
2328  DWORD ulFlags)
2329 {
2330  HKEY hKey;
2331  DWORD dwError;
2332 
2334  UNREFERENCED_PARAMETER(ulFlags);
2335 
2336  DPRINT("PNP_GetClassCount(%p %p 0x%08lx)\n",
2337  hBinding, pulClassCount, ulFlags);
2338 
2341  0,
2343  &hKey);
2344  if (dwError != ERROR_SUCCESS)
2345  return CR_INVALID_DATA;
2346 
2347  dwError = RegQueryInfoKeyW(hKey,
2348  NULL,
2349  NULL,
2350  NULL,
2351  pulClassCount,
2352  NULL,
2353  NULL,
2354  NULL,
2355  NULL,
2356  NULL,
2357  NULL,
2358  NULL);
2359  RegCloseKey(hKey);
2360  if (dwError != ERROR_SUCCESS)
2361  return CR_INVALID_DATA;
2362 
2363  return CR_SUCCESS;
2364 }
2365 
2366 
2367 /* Function 19 */
2368 DWORD
2369 WINAPI
2372  LPWSTR pszClassGuid,
2373  LPWSTR Buffer,
2374  PNP_RPC_STRING_LEN *pulLength,
2375  DWORD ulFlags)
2376 {
2377  WCHAR szKeyName[MAX_PATH];
2379  HKEY hKey;
2380  DWORD dwSize;
2381 
2383  UNREFERENCED_PARAMETER(ulFlags);
2384 
2385  DPRINT("PNP_GetClassName(%p %S %p %p 0x%08lx)\n",
2386  hBinding, pszClassGuid, Buffer, pulLength, ulFlags);
2387 
2388  lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class\\");
2389  if (lstrlenW(pszClassGuid) + 1 < sizeof(szKeyName)/sizeof(WCHAR)-(lstrlenW(szKeyName) * sizeof(WCHAR)))
2390  lstrcatW(szKeyName, pszClassGuid);
2391  else
2392  return CR_INVALID_DATA;
2393 
2395  szKeyName,
2396  0,
2398  &hKey))
2399  return CR_REGISTRY_ERROR;
2400 
2401  dwSize = *pulLength * sizeof(WCHAR);
2402  if (RegQueryValueExW(hKey,
2403  L"Class",
2404  NULL,
2405  NULL,
2406  (LPBYTE)Buffer,
2407  &dwSize))
2408  {
2409  *pulLength = 0;
2411  }
2412  else
2413  {
2414  *pulLength = dwSize / sizeof(WCHAR);
2415  }
2416 
2417  RegCloseKey(hKey);
2418 
2419  DPRINT("PNP_GetClassName() done (returns %lx)\n", ret);
2420 
2421  return ret;
2422 }
2423 
2424 
2425 /* Function 20 */
2426 DWORD
2427 WINAPI
2430  LPWSTR pszClassGuid,
2431  DWORD ulFlags)
2432 {
2434 
2436 
2437  DPRINT("PNP_DeleteClassKey(%p %S 0x%08lx)\n",
2438  hBinding, pszClassGuid, ulFlags);
2439 
2440  if (ulFlags & CM_DELETE_CLASS_SUBKEYS)
2441  {
2442  if (SHDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
2444  }
2445  else
2446  {
2447  if (RegDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
2449  }
2450 
2451  DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret);
2452 
2453  return ret;
2454 }
2455 
2456 
2457 /* Function 21 */
2458 DWORD
2459 WINAPI
2462  LPWSTR pszInterfaceDevice,
2463  GUID *AliasInterfaceGuid,
2464  LPWSTR pszAliasInterfaceDevice,
2465  PNP_RPC_STRING_LEN *pulLength,
2466  PNP_RPC_STRING_LEN *pulTransferLen,
2467  DWORD ulFlags)
2468 {
2469  UNIMPLEMENTED;
2470  return CR_CALL_NOT_IMPLEMENTED;
2471 }
2472 
2473 
2474 /* Function 22 */
2475 DWORD
2476 WINAPI
2480  LPWSTR pszDeviceID,
2481  BYTE *Buffer,
2482  PNP_RPC_BUFFER_SIZE *pulLength,
2483  DWORD ulFlags)
2484 {
2485  NTSTATUS Status;
2487  DWORD ret = CR_SUCCESS;
2488 
2490 
2491  DPRINT("PNP_GetInterfaceDeviceList(%p %p %S %p %p 0x%08lx)\n",
2492  hBinding, InterfaceGuid, pszDeviceID, Buffer, pulLength, ulFlags);
2493 
2494  if (!IsValidDeviceInstanceID(pszDeviceID))
2495  return CR_INVALID_DEVINST;
2496 
2497  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
2498  pszDeviceID);
2499 
2500  PlugPlayData.Flags = ulFlags;
2501  PlugPlayData.FilterGuid = InterfaceGuid;
2502  PlugPlayData.Buffer = Buffer;
2503  PlugPlayData.BufferSize = *pulLength;
2504 
2506  (PVOID)&PlugPlayData,
2508  if (NT_SUCCESS(Status))
2509  {
2510  *pulLength = PlugPlayData.BufferSize;
2511  }
2512  else
2513  {
2515  }
2516 
2517  DPRINT("PNP_GetInterfaceDeviceList() done (returns %lx)\n", ret);
2518  return ret;
2519 }
2520 
2521 
2522 /* Function 23 */
2523 DWORD
2524 WINAPI
2527  PNP_RPC_BUFFER_SIZE *pulLen,
2529  LPWSTR pszDeviceID,
2530  DWORD ulFlags)
2531 {
2532  NTSTATUS Status;
2534  DWORD ret = CR_SUCCESS;
2535 
2537 
2538  DPRINT("PNP_GetInterfaceDeviceListSize(%p %p %p %S 0x%08lx)\n",
2539  hBinding, pulLen, InterfaceGuid, pszDeviceID, ulFlags);
2540 
2541  if (!IsValidDeviceInstanceID(pszDeviceID))
2542  return CR_INVALID_DEVINST;
2543 
2544  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
2545  pszDeviceID);
2546 
2547  PlugPlayData.FilterGuid = InterfaceGuid;
2548  PlugPlayData.Buffer = NULL;
2549  PlugPlayData.BufferSize = 0;
2550  PlugPlayData.Flags = ulFlags;
2551 
2553  (PVOID)&PlugPlayData,
2555  if (NT_SUCCESS(Status))
2556  {
2557  *pulLen = PlugPlayData.BufferSize;
2558  }
2559  else
2560  {
2562  }
2563 
2564  DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret);
2565  return ret;
2566 }
2567 
2568 
2569 /* Function 24 */
2570 DWORD
2571 WINAPI
2574  LPWSTR pszDeviceID,
2576  LPWSTR pszReference,
2577  LPWSTR pszSymLink,
2578  PNP_RPC_STRING_LEN *pulLength,
2579  PNP_RPC_STRING_LEN *pulTransferLen,
2580  DWORD ulFlags)
2581 {
2582  UNIMPLEMENTED;
2583  return CR_CALL_NOT_IMPLEMENTED;
2584 }
2585 
2586 
2587 /* Function 25 */
2588 DWORD
2589 WINAPI
2592  LPWSTR pszInterfaceDevice,
2593  DWORD ulFlags)
2594 {
2595  UNIMPLEMENTED;
2596  return CR_CALL_NOT_IMPLEMENTED;
2597 }
2598 
2599 
2600 /* Function 26 */
2601 DWORD
2602 WINAPI
2605  LPWSTR pszClassGuid,
2606  DWORD ulProperty,
2607  DWORD *pulRegDataType,
2608  BYTE *Buffer,
2609  PNP_RPC_STRING_LEN *pulTransferLen,
2610  PNP_RPC_STRING_LEN *pulLength,
2611  DWORD ulFlags)
2612 {
2614  LPWSTR lpValueName = NULL;
2615  HKEY hInstKey = NULL;
2616  HKEY hPropKey = NULL;
2617  LONG lError;
2618 
2620 
2621  DPRINT("PNP_GetClassRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
2622  hBinding, pszClassGuid, ulProperty, pulRegDataType,
2623  Buffer, pulTransferLen, pulLength, ulFlags);
2624 
2625  if (pulTransferLen == NULL || pulLength == NULL)
2626  {
2628  goto done;
2629  }
2630 
2631  if (ulFlags != 0)
2632  {
2633  ret = CR_INVALID_FLAG;
2634  goto done;
2635  }
2636 
2637  if (*pulLength < *pulTransferLen)
2638  *pulLength = *pulTransferLen;
2639 
2640  *pulTransferLen = 0;
2641 
2642  switch (ulProperty)
2643  {
2644  case CM_CRP_SECURITY:
2645  lpValueName = L"Security";
2646  break;
2647 
2648  case CM_CRP_DEVTYPE:
2649  lpValueName = L"DeviceType";
2650  break;
2651 
2652  case CM_CRP_EXCLUSIVE:
2653  lpValueName = L"Exclusive";
2654  break;
2655 
2657  lpValueName = L"DeviceCharacteristics";
2658  break;
2659 
2660  default:
2662  goto done;
2663  }
2664 
2665  DPRINT("Value name: %S\n", lpValueName);
2666 
2667  lError = RegOpenKeyExW(hClassKey,
2668  pszClassGuid,
2669  0,
2670  KEY_READ,
2671  &hInstKey);
2672  if (lError != ERROR_SUCCESS)
2673  {
2674  *pulLength = 0;
2676  goto done;
2677  }
2678 
2679  lError = RegOpenKeyExW(hInstKey,
2680  L"Properties",
2681  0,
2682  KEY_READ,
2683  &hPropKey);
2684  if (lError != ERROR_SUCCESS)
2685  {
2686  *pulLength = 0;
2688  goto done;
2689  }
2690 
2691  lError = RegQueryValueExW(hPropKey,
2692  lpValueName,
2693  NULL,
2694  pulRegDataType,
2695  Buffer,
2696  pulLength);
2697  if (lError != ERROR_SUCCESS)
2698  {
2699  if (lError == ERROR_MORE_DATA)
2700  {
2701  ret = CR_BUFFER_SMALL;
2702  }
2703  else
2704  {
2705  *pulLength = 0;
2707  }
2708  }
2709 
2710 done:
2711  if (ret == CR_SUCCESS)
2712  *pulTransferLen = *pulLength;
2713 
2714  if (hPropKey != NULL)
2715  RegCloseKey(hPropKey);
2716 
2717  if (hInstKey != NULL)
2718  RegCloseKey(hInstKey);
2719 
2720  DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret);
2721 
2722  return ret;
2723 }
2724 
2725 
2726 /* Function 27 */
2727 DWORD
2728 WINAPI
2731  LPWSTR pszClassGuid,
2732  DWORD ulProperty,
2733  DWORD ulDataType,
2734  BYTE *Buffer,
2735  PNP_PROP_SIZE ulLength,
2736  DWORD ulFlags)
2737 {
2739  LPWSTR lpValueName = NULL;
2740  HKEY hInstKey = 0;
2741  HKEY hPropKey = 0;
2742  LONG lError;
2743 
2745 
2746  DPRINT("PNP_SetClassRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
2747  hBinding, pszClassGuid, ulProperty, ulDataType,
2748  Buffer, ulLength, ulFlags);
2749 
2750  if (ulFlags != 0)
2751  return CR_INVALID_FLAG;
2752 
2753  switch (ulProperty)
2754  {
2755  case CM_CRP_SECURITY:
2756  lpValueName = L"Security";
2757  break;
2758 
2759  case CM_CRP_DEVTYPE:
2760  lpValueName = L"DeviceType";
2761  break;
2762 
2763  case CM_CRP_EXCLUSIVE:
2764  lpValueName = L"Exclusive";
2765  break;
2766 
2768  lpValueName = L"DeviceCharacteristics";
2769  break;
2770 
2771  default:
2772  return CR_INVALID_PROPERTY;
2773  }
2774 
2775  lError = RegOpenKeyExW(hClassKey,
2776  pszClassGuid,
2777  0,
2778  KEY_WRITE,
2779  &hInstKey);
2780  if (lError != ERROR_SUCCESS)
2781  {
2783  goto done;
2784  }
2785 
2786  /* FIXME: Set security descriptor */
2787  lError = RegCreateKeyExW(hInstKey,
2788  L"Properties",
2789  0,
2790  NULL,
2793  NULL,
2794  &hPropKey,
2795  NULL);
2796  if (lError != ERROR_SUCCESS)
2797  {
2799  goto done;
2800  }
2801 
2802  if (ulLength == 0)
2803  {
2804  if (RegDeleteValueW(hPropKey,
2805  lpValueName))
2807  }
2808  else
2809  {
2810  if (RegSetValueExW(hPropKey,
2811  lpValueName,
2812  0,
2813  ulDataType,
2814  Buffer,
2815  ulLength))
2817  }
2818 
2819 done:
2820  if (hPropKey != NULL)
2821  RegCloseKey(hPropKey);
2822 
2823  if (hInstKey != NULL)
2824  RegCloseKey(hInstKey);
2825 
2826  return ret;
2827 }
2828 
2829 
2830 static CONFIGRET
2832 {
2833  WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
2834  WCHAR szDevice[MAX_DEVICE_ID_LEN];
2835  WCHAR szInstance[MAX_DEVICE_ID_LEN];
2836  HKEY hKeyEnumerator;
2837  HKEY hKeyDevice;
2838  HKEY hKeyInstance;
2839  HKEY hKeyControl;
2840  LONG lError;
2841 
2842  /* Split the instance ID */
2843  SplitDeviceInstanceID(pszDeviceID,
2844  szEnumerator,
2845  szDevice,
2846  szInstance);
2847 
2848  /* Open or create the enumerator key */
2849  lError = RegCreateKeyExW(hEnumKey,
2850  szEnumerator,
2851  0,
2852  NULL,
2855  NULL,
2856  &hKeyEnumerator,
2857  NULL);
2858  if (lError != ERROR_SUCCESS)
2859  {
2860  return CR_REGISTRY_ERROR;
2861  }
2862 
2863  /* Open or create the device key */
2864  lError = RegCreateKeyExW(hKeyEnumerator,
2865  szDevice,
2866  0,
2867  NULL,
2870  NULL,
2871  &hKeyDevice,
2872  NULL);
2873 
2874  /* Close the enumerator key */
2875  RegCloseKey(hKeyEnumerator);
2876 
2877  if (lError != ERROR_SUCCESS)
2878  {
2879  return CR_REGISTRY_ERROR;
2880  }
2881 
2882  /* Try to open the instance key and fail if it exists */
2883  lError = RegOpenKeyExW(hKeyDevice,
2884  szInstance,
2885  0,
2886  KEY_SET_VALUE,
2887  &hKeyInstance);
2888  if (lError == ERROR_SUCCESS)
2889  {
2890  DPRINT1("Instance %S already exists!\n", szInstance);
2891  RegCloseKey(hKeyInstance);
2892  RegCloseKey(hKeyDevice);
2893  return CR_ALREADY_SUCH_DEVINST;
2894  }
2895 
2896  /* Create a new instance key */
2897  lError = RegCreateKeyExW(hKeyDevice,
2898  szInstance,
2899  0,
2900  NULL,
2903  NULL,
2904  &hKeyInstance,
2905  NULL);
2906 
2907  /* Close the device key */
2908  RegCloseKey(hKeyDevice);
2909 
2910  if (lError != ERROR_SUCCESS)
2911  {
2912  return CR_REGISTRY_ERROR;
2913  }
2914 
2915  /* Create the 'Control' sub key */
2916  lError = RegCreateKeyExW(hKeyInstance,
2917  L"Control",
2918  0,
2919  NULL,
2922  NULL,
2923  &hKeyControl,
2924  NULL);
2925  if (lError == ERROR_SUCCESS)
2926  {
2927  RegCloseKey(hKeyControl);
2928  }
2929 
2930  RegCloseKey(hKeyInstance);
2931 
2932  return (lError == ERROR_SUCCESS) ? CR_SUCCESS : CR_REGISTRY_ERROR;
2933 }
2934 
2935 
2936 /* Function 28 */
2937 DWORD
2938 WINAPI
2941  LPWSTR pszDeviceID,
2942  LPWSTR pszParentDeviceID,
2943  PNP_RPC_STRING_LEN ulLength,
2944  DWORD ulFlags)
2945 {
2947 
2948  DPRINT("PNP_CreateDevInst(%p %S %S %lu 0x%08lx)\n",
2949  hBinding, pszParentDeviceID, pszDeviceID, ulLength, ulFlags);
2950 
2951  if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
2952  return CR_INVALID_FLAG;
2953 
2954  if (pszDeviceID == NULL || pszParentDeviceID == NULL)
2955  return CR_INVALID_POINTER;
2956 
2957  /* Fail, if the parent device is not the root device */
2958  if (!IsRootDeviceInstanceID(pszParentDeviceID))
2959  return CR_INVALID_DEVINST;
2960 
2961  if (ulFlags & CM_CREATE_DEVNODE_GENERATE_ID)
2962  {
2963  WCHAR szGeneratedInstance[MAX_DEVICE_ID_LEN];
2964  DWORD dwInstanceNumber;
2965 
2966  /* Generated ID is: Root<Device ID><Instance number> */
2967  dwInstanceNumber = 0;
2968  do
2969  {
2970  swprintf(szGeneratedInstance, L"Root\\%ls\\%04lu",
2971  pszDeviceID, dwInstanceNumber);
2972 
2973  /* Try to create a device instance with this ID */
2974  ret = CreateDeviceInstance(szGeneratedInstance);
2975 
2976  dwInstanceNumber++;
2977  }
2978  while (ret == CR_ALREADY_SUCH_DEVINST);
2979 
2980  if (ret == CR_SUCCESS)
2981  {
2982  /* pszDeviceID is an out parameter too for generated IDs */
2983  if (wcslen(szGeneratedInstance) > ulLength)
2984  {
2985  ret = CR_BUFFER_SMALL;
2986  }
2987  else
2988  {
2989  wcscpy(pszDeviceID, szGeneratedInstance);
2990  }
2991  }
2992  }
2993  else
2994  {
2995  /* Create the device instance */
2996  ret = CreateDeviceInstance(pszDeviceID);
2997  }
2998 
2999  DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret);
3000 
3001  return ret;
3002 }
3003 
3004 
3005 static CONFIGRET
3007  _In_ LPWSTR pszDeviceInstance,
3008  _In_ DWORD ulMinorAction)
3009 {
3011  HKEY hDeviceKey = NULL;
3012  DWORD dwDisableCount, dwSize;
3013  DWORD ulStatus, ulProblem;
3014  DWORD dwError;
3016  NTSTATUS Status;
3017 
3018  DPRINT1("SetupDeviceInstance(%S 0x%08lx)\n",
3019  pszDeviceInstance, ulMinorAction);
3020 
3021  if (IsRootDeviceInstanceID(pszDeviceInstance))
3022  return CR_INVALID_DEVINST;
3023 
3024  if (ulMinorAction & ~CM_SETUP_BITS)
3025  return CR_INVALID_FLAG;
3026 
3027  if ((ulMinorAction == CM_SETUP_DOWNLOAD) ||
3028  (ulMinorAction == CM_SETUP_WRITE_LOG_CONFS))
3029  return CR_SUCCESS;
3030 
3031  dwError = RegOpenKeyExW(hEnumKey,
3032  pszDeviceInstance,
3033  0,
3034  KEY_READ,
3035  &hDeviceKey);
3036  if (dwError != ERROR_SUCCESS)
3037  return CR_INVALID_DEVNODE;
3038 
3039  dwSize = sizeof(dwDisableCount);
3040  dwError = RegQueryValueExW(hDeviceKey,
3041  L"DisableCount",
3042  NULL,
3043  NULL,
3044  (LPBYTE)&dwDisableCount,
3045  &dwSize);
3046  if ((dwError == ERROR_SUCCESS) &&
3047  (dwDisableCount > 0))
3048  {
3049  goto done;
3050  }
3051 
3052  GetDeviceStatus(pszDeviceInstance,
3053  &ulStatus,
3054  &ulProblem);
3055 
3056  if (ulStatus & DN_STARTED)
3057  {
3058  goto done;
3059  }
3060 
3061  if (ulStatus & DN_HAS_PROBLEM)
3062  {
3063  ret = ClearDeviceStatus(pszDeviceInstance,
3065  ulProblem);
3066  }
3067 
3068  if (ret != CR_SUCCESS)
3069  goto done;
3070 
3071  /* Start the device */
3072  RtlInitUnicodeString(&ControlData.DeviceInstance,
3073  pszDeviceInstance);
3075  &ControlData,
3077  if (!NT_SUCCESS(Status))
3079 
3080 done:
3081  if (hDeviceKey != NULL)
3082  RegCloseKey(hDeviceKey);
3083 
3084  return ret;
3085 }
3086 
3087 
3088 static CONFIGRET
3090  _In_ LPWSTR pszDeviceInstance)
3091 {
3094  NTSTATUS Status;
3095 
3096  DPRINT("Enable device instance %S\n", pszDeviceInstance);
3097 
3098  RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceInstance);
3099  Status = NtPlugPlayControl(PlugPlayControlStartDevice, &ControlData, sizeof(ControlData));
3100  if (!NT_SUCCESS(Status))
3102 
3103  return ret;
3104 }
3105 
3106 
3107 static CONFIGRET
3109  _In_ LPWSTR pszDeviceInstance,
3110  _In_ ULONG ulMinorAction)
3111 {
3112  PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData;
3114  NTSTATUS Status;
3115 
3116  DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
3117  pszDeviceInstance, ulMinorAction);
3118 
3119  if (ulMinorAction & ~CM_REENUMERATE_BITS)
3120  return CR_INVALID_FLAG;
3121 
3122  if (ulMinorAction & CM_REENUMERATE_RETRY_INSTALLATION)
3123  {
3124  DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
3125  }
3126 
3127  RtlInitUnicodeString(&EnumerateDeviceData.DeviceInstance,
3128  pszDeviceInstance);
3129  EnumerateDeviceData.Flags = 0;
3130 
3132  &EnumerateDeviceData,
3134  if (!NT_SUCCESS(Status))
3136 
3137  return ret;
3138 }
3139 
3140 
3141 /* Function 29 */
3142 DWORD
3143 WINAPI
3146  DWORD ulMajorAction,
3147  DWORD ulMinorAction,
3148  LPWSTR pszDeviceInstance1,
3149  LPWSTR pszDeviceInstance2)
3150 {
3152 
3154 
3155  DPRINT("PNP_DeviceInstanceAction(%p %lu 0x%08lx %S %S)\n",
3156  hBinding, ulMajorAction, ulMinorAction,
3157  pszDeviceInstance1, pszDeviceInstance2);
3158 
3159  switch (ulMajorAction)
3160  {
3161  case PNP_DEVINST_SETUP:
3162  ret = SetupDeviceInstance(pszDeviceInstance1,
3163  ulMinorAction);
3164  break;
3165 
3166  case PNP_DEVINST_ENABLE:
3167  ret = EnableDeviceInstance(pszDeviceInstance1);
3168  break;
3169 
3170  case PNP_DEVINST_REENUMERATE:
3171  ret = ReenumerateDeviceInstance(pszDeviceInstance1,
3172  ulMinorAction);
3173  break;
3174 
3175  default:
3176  DPRINT1("Unknown device action %lu: not implemented\n", ulMajorAction);
3178  }
3179 
3180  DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret);
3181 
3182  return ret;
3183 }
3184 
3185 
3186 /* Function 30 */
3187 DWORD
3188 WINAPI
3191  LPWSTR pDeviceID,
3192  DWORD *pulStatus,
3193  DWORD *pulProblem,
3194  DWORD ulFlags)
3195 {
3196  DWORD ulDataType, ulTransferLength, ulLength;
3197  DWORD ulCapabilities, ulConfigFlags;
3198  CONFIGRET ret;
3199 
3201  UNREFERENCED_PARAMETER(ulFlags);
3202 
3203  DPRINT("PNP_GetDeviceStatus(%p %S %p %p 0x%08lx)\n",
3204  hBinding, pDeviceID, pulStatus, pulProblem, ulFlags);
3205 
3206  if (ulFlags != 0)
3207  return CR_INVALID_FLAG;
3208 
3209  if ((pulStatus == NULL) || (pulProblem == NULL))
3210  return CR_INVALID_POINTER;
3211 
3212  if (!IsValidDeviceInstanceID(pDeviceID))
3213  return CR_INVALID_DEVINST;
3214 
3215  ret = GetDeviceStatus(pDeviceID, pulStatus, pulProblem);
3216  if (ret != CR_SUCCESS)
3217  return ret;
3218 
3219  /* Check for DN_REMOVABLE */
3220  ulTransferLength = sizeof(ulCapabilities);
3221  ulLength = sizeof(ulCapabilities);
3223  pDeviceID,
3225  &ulDataType,
3226  (PBYTE)&ulCapabilities,
3227  &ulTransferLength,
3228  &ulLength,
3229  0);
3230  if (ret != CR_SUCCESS)
3231  ulCapabilities = 0;
3232 
3233  if (ulCapabilities & CM_DEVCAP_REMOVABLE)
3234  *pulStatus |= DN_REMOVABLE;
3235 
3236  /* Check for DN_MANUAL */
3237  ulTransferLength = sizeof(ulConfigFlags);
3238  ulLength = sizeof(ulConfigFlags);
3240  pDeviceID,
3242  &ulDataType,
3243  (PBYTE)&ulConfigFlags,
3244  &ulTransferLength,
3245  &ulLength,
3246  0);
3247  if (ret != CR_SUCCESS)
3248  ulConfigFlags = 0;
3249 
3250  if (ulConfigFlags & CONFIGFLAG_MANUAL_INSTALL)
3251  *pulStatus |= DN_MANUAL;
3252 
3253  /* Check for failed install */
3254  if (((*pulStatus & DN_HAS_PROBLEM) == 0) && (ulConfigFlags & CONFIGFLAG_FAILEDINSTALL))
3255  {
3256  *pulStatus |= DN_HAS_PROBLEM;
3257  *pulProblem = CM_PROB_FAILED_INSTALL;
3258  }
3259 
3260  return CR_SUCCESS;
3261 }
3262 
3263 
3264 /* Function 31 */
3265 DWORD
3266 WINAPI
3269  LPWSTR pDeviceID,
3270  DWORD ulProblem,
3271  DWORD ulFlags)
3272 {
3273  ULONG ulOldStatus, ulOldProblem;
3275 
3277 
3278  DPRINT1("PNP_SetDeviceProblem(%p %S %lu 0x%08lx)\n",
3279  hBinding, pDeviceID, ulProblem, ulFlags);
3280 
3281  if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
3282  return CR_INVALID_FLAG;
3283 
3284  if (!IsValidDeviceInstanceID(pDeviceID))
3285  return CR_INVALID_DEVINST;
3286 
3287  ret = GetDeviceStatus(pDeviceID,
3288  &ulOldStatus,
3289  &ulOldProblem);
3290  if (ret != CR_SUCCESS)
3291  return ret;
3292 
3293  if (((ulFlags & CM_SET_DEVNODE_PROBLEM_OVERRIDE) == 0) &&
3294  (ulOldProblem != 0) &&
3295  (ulOldProblem != ulProblem))
3296  {
3297  return CR_FAILURE;
3298  }
3299 
3300  if (ulProblem == 0)
3301  {
3302  ret = ClearDeviceStatus(pDeviceID,
3304  ulOldProblem);
3305  }
3306  else
3307  {
3308  ret = SetDeviceStatus(pDeviceID,
3310  ulProblem);
3311  }
3312 
3313  return ret;
3314 }
3315 
3316 
3317 /* Function 32 */
3318 DWORD
3319 WINAPI
3322  LPWSTR pDeviceID,
3323  PPNP_VETO_TYPE pVetoType,
3324  LPWSTR pszVetoName,
3325  DWORD ulNameLength,
3326  DWORD ulFlags)
3327 {
3329 
3330  DPRINT1("PNP_DisableDevInst(%p %S %p %p %lu 0x%08lx)\n",
3331  hBinding, pDeviceID, pVetoType, pszVetoName, ulNameLength, ulFlags);
3332 
3333  if (ulFlags & ~CM_DISABLE_BITS)
3334  return CR_INVALID_FLAG;
3335 
3336  if (!IsValidDeviceInstanceID(pDeviceID) ||
3337  IsRootDeviceInstanceID(pDeviceID))
3338  return CR_INVALID_DEVINST;
3339 
3340  return DisableDeviceInstance(pDeviceID,
3341  pVetoType,
3342  pszVetoName,
3343  ulNameLength);
3344 }
3345 
3346 
3347 /* Function 33 */
3348 DWORD
3349 WINAPI
3352  LPWSTR pDeviceID,
3353  DWORD ulFlags)
3354 {
3355  UNIMPLEMENTED;
3356  return CR_CALL_NOT_IMPLEMENTED;
3357 }
3358 
3359 
3360 static BOOL
3361 CheckForDeviceId(LPWSTR lpDeviceIdList,
3362  LPWSTR lpDeviceId)
3363 {
3364  LPWSTR lpPtr;
3365  DWORD dwLength;
3366 
3367  lpPtr = lpDeviceIdList;
3368  while (*lpPtr != 0)
3369  {
3370  dwLength = wcslen(lpPtr);
3371  if (0 == _wcsicmp(lpPtr, lpDeviceId))
3372  return TRUE;
3373 
3374  lpPtr += (dwLength + 1);
3375  }
3376 
3377  return FALSE;
3378 }
3379 
3380 
3381 static VOID
3382 AppendDeviceId(LPWSTR lpDeviceIdList,
3383  LPDWORD lpDeviceIdListSize,
3384  LPWSTR lpDeviceId)
3385 {
3386  DWORD dwLen;
3387  DWORD dwPos;
3388 
3389  dwLen = wcslen(lpDeviceId);
3390  dwPos = (*lpDeviceIdListSize / sizeof(WCHAR)) - 1;
3391 
3392  wcscpy(&lpDeviceIdList[dwPos], lpDeviceId);
3393 
3394  dwPos += (dwLen + 1);
3395 
3396  lpDeviceIdList[dwPos] = 0;
3397 
3398  *lpDeviceIdListSize = dwPos * sizeof(WCHAR);
3399 }
3400 
3401 
3402 /* Function 34 */
3403 DWORD
3404 WINAPI
3407  LPWSTR pszDeviceID,
3408  LPWSTR pszID,
3409  DWORD ulFlags)
3410 {
3412  HKEY hDeviceKey;
3413  LPWSTR pszSubKey;
3414  DWORD dwDeviceIdListSize;
3415  DWORD dwNewDeviceIdSize;
3416  WCHAR * pszDeviceIdList = NULL;
3417 
3419 
3420  DPRINT("PNP_AddID(%p %S %S 0x%08lx)\n",
3421  hBinding, pszDeviceID, pszID, ulFlags);
3422 
3423  if (RegOpenKeyExW(hEnumKey,
3424  pszDeviceID,
3425  0,
3427  &hDeviceKey) != ERROR_SUCCESS)
3428  {
3429  DPRINT("Failed to open the device key!\n");
3430  return CR_INVALID_DEVNODE;
3431  }
3432 
3433  pszSubKey = (ulFlags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID";
3434 
3435  if (RegQueryValueExW(hDeviceKey,
3436  pszSubKey,
3437  NULL,
3438  NULL,
3439  NULL,
3440  &dwDeviceIdListSize) != ERROR_SUCCESS)
3441  {
3442  DPRINT("Failed to query the desired ID string!\n");
3444  goto Done;
3445  }
3446 
3447  dwNewDeviceIdSize = lstrlenW(pszDeviceID);
3448  if (!dwNewDeviceIdSize)
3449  {
3451  goto Done;
3452  }
3453 
3454  dwDeviceIdListSize += (dwNewDeviceIdSize + 2) * sizeof(WCHAR);
3455 
3456  pszDeviceIdList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeviceIdListSize);
3457  if (!pszDeviceIdList)
3458  {
3459  DPRINT("Failed to allocate memory for the desired ID string!\n");
3461  goto Done;
3462  }
3463 
3464  if (RegQueryValueExW(hDeviceKey,
3465  pszSubKey,
3466  NULL,
3467  NULL,
3468  (LPBYTE)pszDeviceIdList,
3469  &dwDeviceIdListSize) != ERROR_SUCCESS)
3470  {
3471  DPRINT("Failed to query the desired ID string!\n");
3473  goto Done;
3474  }
3475 
3476  /* Check whether the device ID is already in use */
3477  if (CheckForDeviceId(pszDeviceIdList, pszDeviceID))
3478  {
3479  DPRINT("Device ID was found in the ID string!\n");
3480  ret = CR_SUCCESS;
3481  goto Done;
3482  }
3483 
3484  /* Append the Device ID */
3485  AppendDeviceId(pszDeviceIdList, &dwDeviceIdListSize, pszID);
3486 
3487  if (RegSetValueExW(hDeviceKey,
3488  pszSubKey,
3489  0,
3490  REG_MULTI_SZ,
3491  (LPBYTE)pszDeviceIdList,
3492  dwDeviceIdListSize) != ERROR_SUCCESS)
3493  {
3494  DPRINT("Failed to set the desired ID string!\n");
3496  }
3497 
3498 Done:
3499  RegCloseKey(hDeviceKey);
3500  if (pszDeviceIdList)
3501  HeapFree(GetProcessHeap(), 0, pszDeviceIdList);
3502 
3503  DPRINT("PNP_AddID() done (returns %lx)\n", ret);
3504 
3505  return ret;
3506 }
3507 
3508 
3509 /* Function 35 */
3510 DWORD
3511 WINAPI
3514  LPWSTR pszDeviceID,
3515  DWORD ulFlags)
3516 {
3517  DPRINT("PNP_RegisterDriver(%p %S 0x%lx)\n",
3518  hBinding, pszDeviceID, ulFlags);
3519 
3520  if (ulFlags & ~CM_REGISTER_DEVICE_DRIVER_BITS)
3521  return CR_INVALID_FLAG;
3522 
3523  if (!IsValidDeviceInstanceID(pszDeviceID))
3524  return CR_INVALID_DEVINST;
3525 
3526  SetDeviceStatus(pszDeviceID, 0, 0);
3527 
3528  return CR_SUCCESS;
3529 }
3530 
3531 
3532 /* Function 36 */
3533 DWORD
3534 WINAPI
3537  LPWSTR pszDeviceID,
3538  PPNP_VETO_TYPE pVetoType,
3539  LPWSTR pszVetoName,
3540  DWORD ulNameLength,
3541  DWORD ulFlags)
3542 {
3544  NTSTATUS Status;
3545  DWORD ret = CR_SUCCESS;
3546 
3547  DPRINT1("PNP_QueryRemove(%p %S %p %p %lu 0x%lx)\n",
3548  hBinding, pszDeviceID, pVetoType, pszVetoName,
3549  ulNameLength, ulFlags);
3550 
3551  if (ulFlags & ~CM_REMOVE_BITS)
3552  return CR_INVALID_FLAG;
3553 
3554  if (!IsValidDeviceInstanceID(pszDeviceID) ||
3555  IsRootDeviceInstanceID(pszDeviceID))
3556  return CR_INVALID_DEVINST;
3557 
3558  if (pVetoType != NULL)
3559  *pVetoType = PNP_VetoTypeUnknown;
3560 
3561  if (pszVetoName != NULL && ulNameLength > 0)
3562  *pszVetoName = UNICODE_NULL;
3563 
3564  RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData));
3565  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
3566  pszDeviceID);
3567  PlugPlayData.VetoName = pszVetoName;
3568  PlugPlayData.NameLength = ulNameLength;
3569 // PlugPlayData.Flags =
3570 
3572  &PlugPlayData,
3573  sizeof(PlugPlayData));
3574  if (!NT_SUCCESS(Status))
3576 
3577  return ret;
3578 }
3579 
3580 
3581 /* Function 37 */
3582 DWORD
3583 WINAPI
3586  LPWSTR pszDeviceID,
3587  PPNP_VETO_TYPE pVetoType,
3588  LPWSTR pszVetoName,
3589  DWORD ulNameLength,
3590  DWORD ulFlags)
3591 {
3593  NTSTATUS Status;
3594  DWORD ret = CR_SUCCESS;
3595 
3596  DPRINT1("PNP_RequestDeviceEject(%p %S %p %p %lu 0x%lx)\n",
3597  hBinding, pszDeviceID, pVetoType, pszVetoName,
3598  ulNameLength, ulFlags);
3599 
3600  if (ulFlags != 0)
3601  return CR_INVALID_FLAG;
3602 
3603  if (!IsValidDeviceInstanceID(pszDeviceID))
3604  return CR_INVALID_DEVINST;
3605 
3606  if (pVetoType != NULL)
3607  *pVetoType = PNP_VetoTypeUnknown;
3608 
3609  if (pszVetoName != NULL && ulNameLength > 0)
3610  *pszVetoName = UNICODE_NULL;
3611 
3612  RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData));
3613  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
3614  pszDeviceID);
3615  PlugPlayData.VetoName = pszVetoName;
3616  PlugPlayData.NameLength = ulNameLength;
3617 // PlugPlayData.Flags =
3618 
3620  &PlugPlayData,
3621  sizeof(PlugPlayData));
3622  if (!NT_SUCCESS(Status))
3624 
3625  return ret;
3626 }
3627 
3628 
3629 /* Function 38 */
3630 CONFIGRET
3631 WINAPI
3634  BOOL *Present)
3635 {
3636  HKEY hKey;
3637  DWORD dwType;
3638  DWORD dwValue;
3639  DWORD dwSize;
3641 
3643 
3644  DPRINT1("PNP_IsDockStationPresent(%p %p)\n",
3645  hBinding, Present);
3646 
3647  *Present = FALSE;
3648 
3650  L"CurrentDockInfo",
3651  0,
3652  KEY_READ,
3653  &hKey) != ERROR_SUCCESS)
3654  return CR_REGISTRY_ERROR;
3655 
3656  dwSize = sizeof(DWORD);
3657  if (RegQueryValueExW(hKey,
3658  L"DockingState",
3659  NULL,
3660  &dwType,
3661  (LPBYTE)&dwValue,
3662  &dwSize) != ERROR_SUCCESS)
3664 
3665  RegCloseKey(hKey);
3666 
3667  if (ret == CR_SUCCESS)
3668  {
3669  if (dwType != REG_DWORD || dwSize != sizeof(DWORD))
3670  {
3672  }
3673  else if (dwValue != 0)
3674  {
3675  *Present = TRUE;
3676  }
3677  }
3678 
3679  DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret);
3680 
3681  return ret;
3682 }
3683 
3684 
3685 /* Function 39 */
3686 DWORD
3687 WINAPI
3690 {
3691  WCHAR szDockDeviceInstance[MAX_DEVICE_ID_LEN];
3693  NTSTATUS Status;
3694 
3695  DPRINT("PNP_RequestEjectPC(%p)\n", hBinding);
3696 
3697  /* Retrieve the dock device */
3698  DockData.DeviceInstanceLength = ARRAYSIZE(szDockDeviceInstance);
3699  DockData.DeviceInstance = szDockDeviceInstance;
3700 
3702  &DockData,
3703  sizeof(DockData));
3704  if (!NT_SUCCESS(Status))
3705  return NtStatusToCrError(Status);
3706 
3707  /* Eject the dock device */
3709  szDockDeviceInstance,
3710  NULL,
3711  NULL,
3712  0,
3713  0);
3714 }
3715 
3716 
3717 /* Function 40 */
3718 DWORD
3719 WINAPI
3722  DWORD ulAction,
3723  LPWSTR pDeviceID,
3724  DWORD ulConfig,
3725  DWORD *pulValue,
3726  PPNP_VETO_TYPE pVetoType,
3727  LPWSTR pszVetoName,
3728  DWORD ulNameLength,
3729  DWORD ulFlags)
3730 {
3732  WCHAR szKeyName[MAX_PATH];
3733  HKEY hKey;
3734  HKEY hDeviceKey;
3735  DWORD dwSize;
3736 
3738 
3739  DPRINT("PNP_HwProfFlags() called\n");
3740 
3741  if (!IsValidDeviceInstanceID(pDeviceID))
3742  return CR_INVALID_DEVINST;
3743 
3744  if (ulConfig == 0)
3745  {
3746  wcscpy(szKeyName,
3747  L"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
3748  }
3749  else
3750  {
3751  swprintf(szKeyName,
3752  L"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
3753  ulConfig);
3754  }
3755 
3757  szKeyName,
3758  0,
3760  &hKey) != ERROR_SUCCESS)
3761  return CR_REGISTRY_ERROR;
3762 
3763  if (ulAction == PNP_GET_HWPROFFLAGS)
3764  {
3765  if (RegOpenKeyExW(hKey,
3766  pDeviceID,
3767  0,
3769  &hDeviceKey) != ERROR_SUCCESS)
3770  {
3771  *pulValue = 0;
3772  }
3773  else
3774  {
3775  dwSize = sizeof(DWORD);
3776  if (RegQueryValueExW(hDeviceKey,
3777  L"CSConfigFlags",
3778  NULL,
3779  NULL,
3780  (LPBYTE)pulValue,
3781  &dwSize) != ERROR_SUCCESS)
3782  {
3783  *pulValue = 0;
3784  }
3785 
3786  RegCloseKey(hDeviceKey);
3787  }
3788  }
3789  else if (ulAction == PNP_SET_HWPROFFLAGS)
3790  {
3791  /* FIXME: not implemented yet */
3793  }
3794 
3795  RegCloseKey(hKey);
3796 
3797  return ret;
3798 }
3799 
3800 
3801 /* Function 41 */
3802 DWORD
3803 WINAPI
3806  DWORD ulIndex,
3807  HWPROFILEINFO *pHWProfileInfo,
3808  DWORD ulProfileInfoSize,
3809  DWORD ulFlags)
3810 {
3811  WCHAR szProfileName[5];
3812  HKEY hKeyConfig = NULL;
3813  HKEY hKeyProfiles = NULL;
3814  HKEY hKeyProfile = NULL;
3815  DWORD dwDisposition;
3816  DWORD dwSize;
3817  LONG lError;
3819 
3821 
3822  DPRINT("PNP_GetHwProfInfo() called\n");
3823 
3824  if (ulProfileInfoSize == 0)
3825  {
3826  ret = CR_INVALID_DATA;
3827  goto done;
3828  }
3829 
3830  if (ulFlags != 0)
3831  {
3832  ret = CR_INVALID_FLAG;
3833  goto done;
3834  }
3835 
3836  /* Initialize the profile information */
3837  pHWProfileInfo->HWPI_ulHWProfile = 0;
3838  pHWProfileInfo->HWPI_szFriendlyName[0] = 0;
3839  pHWProfileInfo->HWPI_dwFlags = 0;
3840 
3841  /* Open the 'IDConfigDB' key */
3843  L"System\\CurrentControlSet\\Control\\IDConfigDB",
3844  0,
3845  NULL,
3848  NULL,
3849  &hKeyConfig,
3850  &dwDisposition);
3851  if (lError != ERROR_SUCCESS)
3852  {
3854  goto done;
3855  }
3856 
3857  /* Open the 'Hardware Profiles' subkey */
3858  lError = RegCreateKeyExW(hKeyConfig,
3859  L"Hardware Profiles",
3860  0,
3861  NULL,
3864  NULL,
3865  &hKeyProfiles,
3866  &dwDisposition);
3867  if (lError != ERROR_SUCCESS)
3868  {
3870  goto done;
3871  }
3872 
3873  if (ulIndex == (ULONG)-1)
3874  {
3875  dwSize = sizeof(ULONG);
3876  lError = RegQueryValueExW(hKeyConfig,
3877  L"CurrentConfig",
3878  NULL,
3879  NULL,
3880  (LPBYTE)&pHWProfileInfo->HWPI_ulHWProfile,
3881  &dwSize);
3882  if (lError != ERROR_SUCCESS)
3883  {
3884  pHWProfileInfo->HWPI_ulHWProfile = 0;
3886  goto done;
3887  }
3888  }
3889  else
3890  {
3891  /* FIXME: not implemented yet */
3893  goto done;
3894  }
3895 
3896  swprintf(szProfileName, L"%04lu", pHWProfileInfo->HWPI_ulHWProfile);
3897 
3898  lError = RegOpenKeyExW(hKeyProfiles,
3899  szProfileName,
3900  0,
3902  &hKeyProfile);
3903  if (lError != ERROR_SUCCESS)
3904  {
3906  goto done;
3907  }
3908 
3909  dwSize = sizeof(pHWProfileInfo->HWPI_szFriendlyName);
3910  lError = RegQueryValueExW(hKeyProfile,
3911  L"FriendlyName",
3912  NULL,
3913  NULL,
3914  (LPBYTE)&pHWProfileInfo->HWPI_szFriendlyName,
3915  &dwSize);
3916  if (lError != ERROR_SUCCESS)
3917  {
3919  goto done;
3920  }
3921 
3922 done:
3923  if (hKeyProfile != NULL)
3924  RegCloseKey(hKeyProfile);
3925 
3926  if (hKeyProfiles != NULL)
3927  RegCloseKey(hKeyProfiles);
3928 
3929  if (hKeyConfig != NULL)
3930  RegCloseKey(hKeyConfig);
3931 
3932  return ret;
3933 }
3934 
3935 
3936 /* Function 42 */
3937 DWORD
3938 WINAPI
3941  LPWSTR pDeviceID,
3942  DWORD ulPriority,
3943  DWORD *pulLogConfTag,
3944  DWORD ulFlags)
3945 {
3946  UNIMPLEMENTED;
3947  return CR_CALL_NOT_IMPLEMENTED;
3948 }
3949 
3950 
3951 /* Function 43 */
3952 DWORD
3953 WINAPI
3956  LPWSTR pDeviceID,
3957  DWORD ulLogConfType,
3958  DWORD ulLogConfTag,
3959  DWORD ulFlags)
3960 {
3961  UNIMPLEMENTED;
3962  return CR_CALL_NOT_IMPLEMENTED;
3963 }
3964 
3965 
3966 /* Function 44 */
3967 DWORD
3968 WINAPI
3971  LPWSTR pDeviceID,
3972  DWORD ulLogConfType,
3973  DWORD *pulLogConfTag,
3974  DWORD ulFlags)
3975 {
3976  HKEY hConfigKey = NULL;
3977  DWORD RegDataType = 0;
3978  ULONG ulDataSize = 0;
3979  LPBYTE lpData = NULL;
3981 
3982  DPRINT("PNP_GetFirstLogConf(%p %S %lu %p 0x%08lx)\n",
3983  hBinding, pDeviceID, ulLogConfType, pulLogConfTag, ulFlags);
3984 
3985  if (pulLogConfTag == NULL)
3986  return CR_INVALID_POINTER;
3987 
3988  *pulLogConfTag = (DWORD)0;
3989 
3990  if (ulFlags & ~LOG_CONF_BITS)
3991  return CR_INVALID_FLAG;
3992 
3993  if (!IsValidDeviceInstanceID(pDeviceID))
3994  return CR_INVALID_DEVINST;
3995 
3996  ret = OpenConfigurationKey(pDeviceID,
3997  &hConfigKey);
3998  if (ret != CR_SUCCESS)
3999  {
4000  DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
4002  goto done;
4003  }
4004 
4005  ret = GetConfigurationData(hConfigKey,
4006  ulLogConfType,
4007  &RegDataType,
4008  &ulDataSize,
4009  &lpData);
4010  if (ret != CR_SUCCESS)
4011  {
4012  DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
4014  goto done;
4015  }
4016 
4017  DPRINT("Data size %lu\n", ulDataSize);
4018  if (ulDataSize == 0 || lpData == NULL)
4019  {
4020  DPRINT1("No config data available!\n");
4022  goto done;
4023  }
4024 
4025  /* Get the first tag */
4026  if (RegDataType == REG_RESOURCE_LIST)
4027  {
4028  DPRINT("REG_RESOURCE_LIST\n");
4029 
4030  DPRINT("ResourceList->Count %lu\n", ((PCM_RESOURCE_LIST)lpData)->Count);
4031  if (((PCM_RESOURCE_LIST)lpData)->Count == 0)
4032  {
4033  DPRINT1("No resource descriptors!\n");
4035  goto done;
4036  }
4037 
4038  DPRINT("lpData %p\n", lpData);
4039  DPRINT("&List[0] %p\n", &(((PCM_RESOURCE_LIST)lpData)->List[0]));
4040 
4041  *pulLogConfTag = (DWORD)((DWORD_PTR)&(((PCM_RESOURCE_LIST)lpData)->List[0]) - (DWORD_PTR)lpData);
4042  DPRINT("Offset (Tag): 0x%08lx\n", *pulLogConfTag);
4043  }
4044  else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
4045  {
4046  DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
4047  /* FIXME */
4049  goto done;
4050  }
4051 
4052 done:
4053  if (lpData != NULL)
4054  HeapFree(GetProcessHeap(), 0, lpData);
4055 
4056  if (hConfigKey != NULL)
4057  RegCloseKey(hConfigKey);
4058 
4059  DPRINT("PNP_GetFirstLogConf() returns %lu\n", ret);
4060 
4061  return ret;
4062 }
4063 
4064 
4065 /* Function 45 */
4066 DWORD
4067 WINAPI
4070  LPWSTR pDeviceID,
4071  DWORD ulLogConfType,
4072  DWORD ulCurrentTag,
4073  DWORD *pulNextTag,
4074  DWORD ulFlags)
4075 {
4076  HKEY hConfigKey = NULL;
4077  DWORD RegDataType = 0;
4078  ULONG ulDataSize = 0;
4079  LPBYTE lpData = NULL;
4081 
4082  DPRINT("PNP_GetNextLogConf(%p %S %lu %ul %p 0x%08lx)\n",
4083  hBinding, pDeviceID, ulLogConfType, ulCurrentTag, pulNextTag, ulFlags);
4084 
4085  if (pulNextTag == NULL)
4086  return CR_INVALID_POINTER;
4087 
4088  *pulNextTag = (DWORD)0;
4089 
4090  if (ulFlags != 0)
4091  return CR_INVALID_FLAG;
4092 
4093  if (!IsValidDeviceInstanceID(pDeviceID))
4094  return CR_INVALID_DEVINST;
4095 
4096  ret = OpenConfigurationKey(pDeviceID,
4097  &hConfigKey);
4098  if (ret != CR_SUCCESS)
4099  {
4100  DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
4102  goto done;
4103  }
4104 
4105  ret = GetConfigurationData(hConfigKey,
4106  ulLogConfType,
4107  &RegDataType,
4108  &ulDataSize,
4109  &lpData);
4110  if (ret != CR_SUCCESS)
4111  {
4112  DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
4114  goto done;
4115  }
4116 
4117  DPRINT("Data size %lu\n", ulDataSize);
4118 
4119  if (ulDataSize == 0 || lpData == NULL)
4120  {
4121  DPRINT1("No config data available!\n");
4123  goto done;
4124  }
4125 
4126  /* FIXME: Get the next tag */
4127  if (RegDataType == REG_RESOURCE_LIST)
4128  {
4129  DPRINT1("FIXME: REG_RESOURCE_LIST\n");
4130  /* FIXME */
4132  goto done;
4133  }
4134  else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
4135  {
4136  DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
4137  /* FIXME */
4139  goto done;
4140  }
4141 
4142 done:
4143  if (lpData != NULL)
4144  HeapFree(GetProcessHeap(), 0, lpData);
4145 
4146  if (hConfigKey != NULL)
4147  RegCloseKey(hConfigKey);
4148 
4149  DPRINT("PNP_GetNextLogConf() returns %lu\n", ret);
4150 
4151  return ret;
4152 }
4153 
4154 
4155 /* Function 46 */
4156 DWORD
4157 WINAPI
4160  LPWSTR pDeviceID,
4161  DWORD ulType,
4162  DWORD ulTag,
4163  DWORD *pPriority,
4164  DWORD ulFlags)
4165 {
4166  UNIMPLEMENTED;
4167  return CR_CALL_NOT_IMPLEMENTED;
4168 }
4169 
4170 
4171 /* Function 47 */
4172 DWORD
4173 WINAPI
4176  LPWSTR pDeviceID,
4177  DWORD ulLogConfTag,
4178  DWORD ulLogConfType,
4179  RESOURCEID ResourceID,
4180  DWORD *pulResourceTag,
4181  BYTE *ResourceData,
4182  PNP_RPC_BUFFER_SIZE ResourceLen,
4183  DWORD ulFlags)
4184 {
4185  UNIMPLEMENTED;
4186  return CR_CALL_NOT_IMPLEMENTED;
4187 }
4188 
4189 
4190 /* Function 48 */
4191 DWORD
4192 WINAPI
4195  LPWSTR pDeviceID,
4196  DWORD ulLogConfTag,
4197  DWORD ulLogConfType,
4198  RESOURCEID ResourceID,
4199  DWORD ulResourceTag,
4200  DWORD *pulPreviousResType,
4201  DWORD *pulPreviousResTag,
4202  DWORD ulFlags)
4203 {
4204  UNIMPLEMENTED;
4205  return CR_CALL_NOT_IMPLEMENTED;
4206 }
4207 
4208 
4209 /* Function 49 */
4210 DWORD
4211 WINAPI
4214  LPWSTR pDeviceID,
4215  DWORD ulLogConfTag,
4216  DWORD ulLogConfType,
4217  RESOURCEID ResourceID,
4218  DWORD ulResourceTag,
4219  DWORD *pulNextResType,
4220  DWORD *pulNextResTag,
4221  DWORD ulFlags)
4222 {
4223  HKEY hConfigKey = NULL;
4224  DWORD RegDataType = 0;
4225  ULONG ulDataSize = 0;
4226  LPBYTE lpData = NULL;
4228 
4229  DPRINT1("PNP_GetNextResDes(%p %S 0x%lx %lu %lu %ul %p %p 0x%08lx)\n",
4230  hBinding, pDeviceID, ulLogConfTag, ulLogConfType, ResourceID,
4231  ulResourceTag, pulNextResType, pulNextResTag, ulFlags);
4232 
4233  if (pulNextResType == NULL)
4234  return CR_INVALID_POINTER;
4235 
4236  *pulNextResType = 0;
4237 
4238  if (ulFlags != 0)
4239  return CR_INVALID_FLAG;
4240 
4241  if (!IsValidDeviceInstanceID(pDeviceID))
4242  return CR_INVALID_DEVINST;
4243 
4244  ret = OpenConfigurationKey(pDeviceID,
4245  &hConfigKey);
4246  if (ret != CR_SUCCESS)
4247  {
4248  DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
4250  goto done;
4251  }
4252 
4253  ret = GetConfigurationData(hConfigKey,
4254  ulLogConfType,
4255  &RegDataType,
4256  &ulDataSize,
4257  &lpData);
4258  if (ret != CR_SUCCESS)
4259  {
4260  DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
4262  goto done;
4263  }
4264 
4265  DPRINT1("Data size %lu\n", ulDataSize);
4266 
4267  if (ulDataSize == 0 || lpData == NULL)
4268  {
4269  DPRINT1("No config data available!\n");
4271  goto done;
4272  }
4273 
4274  /* Get the next resource descriptor */
4275  if (RegDataType == REG_RESOURCE_LIST)
4276  {
4277  DPRINT1("FIXME: REG_RESOURCE_LIST\n");
4278  /* FIXME */
4280  goto done;
4281  }
4282  else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
4283  {
4284  DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
4285  /* FIXME */
4287  goto done;
4288  }
4289 
4290 done:
4291  if (lpData != NULL)
4292  HeapFree(GetProcessHeap(), 0, lpData);
4293 
4294  if (hConfigKey != NULL)
4295  RegCloseKey(hConfigKey);
4296 
4297  DPRINT1("PNP_GetNextResDes() returns %lu\n", ret);
4298 
4299  return ret;
4300 }
4301 
4302 
4303 /* Function 50 */
4304 DWORD
4305 WINAPI
4308  LPWSTR pDeviceID,
4309  DWORD ulLogConfTag,
4310  DWORD ulLogConfType,
4311  RESOURCEID ResourceID,
4312  DWORD ulResourceTag,
4313  BYTE *Buffer,
4314  PNP_RPC_BUFFER_SIZE BufferLen,
4315  DWORD ulFlags)
4316 {
4317  UNIMPLEMENTED;
4318  return CR_CALL_NOT_IMPLEMENTED;
4319 }
4320 
4321 
4322 /* Function 51 */
4323 DWORD
4324 WINAPI
4327  LPWSTR pDeviceID,
4328  DWORD ulLogConfTag,
4329  DWORD ulLogConfType,
4330  RESOURCEID ResourceID,
4331  DWORD ulResourceTag,
4332  DWORD *pulSize,
4333  DWORD ulFlags)
4334 {
4335  UNIMPLEMENTED;
4336  return CR_CALL_NOT_IMPLEMENTED;
4337 }
4338 
4339 
4340 /* Function 52 */
4341 DWORD
4342 WINAPI
4345  LPWSTR pDeviceID,
4346  DWORD ulLogConfTag,
4347  DWORD ulLogConfType,
4348  RESOURCEID CurrentResourceID,
4349  RESOURCEID NewResourceID,
4350  DWORD ulResourceTag,
4351  BYTE *ResourceData,
4352  PNP_RPC_BUFFER_SIZE ResourceLen,
4353  DWORD ulFlags)
4354 {
4355  UNIMPLEMENTED;
4356  return CR_CALL_NOT_IMPLEMENTED;
4357 }
4358 
4359 
4360 /* Function 53 */
4361 DWORD
4362 WINAPI
4365  LPWSTR pDeviceID,
4366  RESOURCEID ResourceID,
4367  BYTE *ResourceData,
4368  PNP_RPC_BUFFER_SIZE ResourceLen,
4369  BOOL *pbConflictDetected,
4370  DWORD ulFlags)
4371 {
4372  DPRINT("PNP_DetectResourceConflict()\n");
4373 
4374  if (pbConflictDetected != NULL)
4375  *pbConflictDetected = FALSE;
4376 
4377  return CR_CALL_NOT_IMPLEMENTED;
4378 }
4379 
4380 
4381 /* Function 54 */
4382 DWORD
4383 WINAPI
4386  LPWSTR pDeviceID,
4387  RESOURCEID ResourceID,
4388  BYTE *ResourceData,
4389  PNP_RPC_BUFFER_SIZE ResourceLen,
4390  BYTE *Buffer,
4391  PNP_RPC_BUFFER_SIZE BufferLen,
4392  DWORD ulFlags)
4393 {
4394  UNIMPLEMENTED;
4395  return CR_CALL_NOT_IMPLEMENTED;
4396 }
4397 
4398 
4399 /* Function 55 */
4400 DWORD
4401 WINAPI
4404  DWORD ulHardwareProfile,
4405  DWORD ulFlags)
4406 {
4407  return CR_CALL_NOT_IMPLEMENTED;
4408 }
4409 
4410 
4411 /* Function 56 */
4412 DWORD
4413 WINAPI
4416  BYTE *pData,
4417  DWORD DataLen,
4418  LPWSTR pDeviceID,
4419  RESOURCEID ResourceID,
4420  DWORD ulFlags)
4421 {
4422  return CR_CALL_NOT_IMPLEMENTED;
4423 }
4424 
4425 
4426 /* Function 57 */
4427 DWORD
4428 WINAPI
4431  DWORD *pulSize,
4432  LPWSTR pDeviceID,
4433  RESOURCEID ResourceID,
4434  DWORD ulFlags)
4435 {
4436  if (pulSize != NULL)
4437  *pulSize = 0;
4438 
4439  return CR_CALL_NOT_IMPLEMENTED;
4440 }
4441 
4442 
4443 /* Function 58 */
4444 CONFIGRET
4445 WINAPI
4448  DWORD ulFlags)
4449 {
4450  return CR_CALL_NOT_IMPLEMENTED;
4451 }
4452 
4453 
4454 /* Function 59 */
4455 DWORD
4456 WINAPI
4459  DWORD ulUnknown2,
4460  LPWSTR pszName,
4461  BYTE *pNotificationFilter,
4462  DWORD ulNotificationFilterSize,
4463  DWORD ulFlags,
4464  DWORD *pulNotify,
4465  DWORD ulUnknown8,
4466  DWORD *pulUnknown9)
4467 {
4468  PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface;
4469  PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle;
4470 #if 0
4471  PNOTIFY_DATA pNotifyData;
4472 #endif
4473 
4474  DPRINT1("PNP_RegisterNotification(%p %lx '%S' %p %lu 0x%lx %p %lx %p)\n",
4475  hBinding, ulUnknown2, pszName, pNotificationFilter,
4476  ulNotificationFilterSize, ulFlags, pulNotify, ulUnknown8, pulUnknown9);
4477 
4478  if (pNotificationFilter == NULL ||
4479  pulNotify == NULL ||
4480  pulUnknown9 == NULL)
4481  return CR_INVALID_POINTER;
4482 
4483  if (ulFlags & ~0x7)
4484  return CR_INVALID_FLAG;
4485 
4486  if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HDR)) ||
4487  (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR)))
4488  return CR_INVALID_DATA;
4489 
4490  if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
4491  {
4492  DPRINT1("DBT_DEVTYP_DEVICEINTERFACE\n");
4493  pBroadcastDeviceInterface = (PDEV_BROADCAST_DEVICEINTERFACE_W)pNotificationFilter;
4494 
4495  if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)) ||
4496  (pBroadcastDeviceInterface->dbcc_size < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)))
4497  return CR_INVALID_DATA;
4498  }
4499  else if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_HANDLE)
4500  {
4501  DPRINT1("DBT_DEVTYP_HANDLE\n");
4502  pBroadcastDeviceHandle = (PDEV_BROADCAST_HANDLE)pNotificationFilter;
4503 
4504  if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HANDLE)) ||
4505  (pBroadcastDeviceHandle->dbch_size < sizeof(DEV_BROADCAST_HANDLE)))
4506  return CR_INVALID_DATA;
4507 
4508  if (ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)
4509  return CR_INVALID_FLAG;
4510  }
4511  else
4512  {
4513  DPRINT1("Invalid device type %lu\n", ((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype);
4514  return CR_INVALID_DATA;
4515  }
4516 
4517 
4518 #if 0
4519  pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_DATA));
4520  if (pNotifyData == NULL)
4521  return CR_OUT_OF_MEMORY;
4522 
4523  *pulNotify = (DWORD)pNotifyData;
4524 #endif
4525 
4526  *pulNotify = 1;
4527 
4528  return CR_SUCCESS;
4529 }
4530 
4531 
4532 /* Function 60 */
4533 DWORD
4534 WINAPI
4537  DWORD ulNotify)
4538 {
4539  DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
4540  hBinding, ulNotify);
4541 
4542 #if 0
4543  UNIMPLEMENTED;
4544  return CR_CALL_NOT_IMPLEMENTED;
4545 #endif
4546 
4547  return CR_SUCCESS;
4548 }
4549 
4550 
4551 /* Function 61 */
4552 DWORD
4553 WINAPI
4556  LPWSTR pDeviceID,
4557  LPWSTR CustomPropName,
4558  DWORD *pulRegDataType,
4559  BYTE *Buffer,
4560  PNP_RPC_STRING_LEN *pulTransferLen,
4561  PNP_RPC_STRING_LEN *pulLength,
4562  DWORD ulFlags)
4563 {
4564  HKEY hDeviceKey = NULL;
4565  HKEY hParamKey = NULL;
4566  LONG lError;
4568 
4570 
4571  DPRINT("PNP_GetCustomDevProp() called\n");
4572 
4573  if (pulTransferLen == NULL || pulLength == NULL)
4574  {
4576  goto done;
4577  }
4578 
4579  if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
4580  {
4581  ret = CR_INVALID_FLAG;
4582  goto done;
4583  }
4584 
4585  if (!IsValidDeviceInstanceID(pDeviceID))
4586  return CR_INVALID_DEVINST;
4587 
4588  if (*pulLength < *pulTransferLen)
4589  *pulLength = *pulTransferLen;
4590 
4591  *pulTransferLen = 0;
4592 
4593  lError = RegOpenKeyExW(hEnumKey,
4594  pDeviceID,
4595  0,
4596  KEY_READ,
4597  &hDeviceKey);
4598  if (lError != ERROR_SUCCESS)
4599  {
4601  goto done;
4602  }
4603 
4604  lError = RegOpenKeyExW(hDeviceKey,
4605  L"Device Parameters",
4606  0,
4607  KEY_READ,
4608  &hParamKey);
4609  if (lError != ERROR_SUCCESS)
4610  {
4612  goto done;
4613  }
4614 
4615  lError = RegQueryValueExW(hParamKey,
4616  CustomPropName,
4617  NULL,
4618  pulRegDataType,
4619  Buffer,
4620  pulLength);
4621  if (lError != ERROR_SUCCESS)
4622  {
4623  if (lError == ERROR_MORE_DATA)
4624  {
4625  ret = CR_BUFFER_SMALL;
4626  }
4627  else
4628  {
4629  *pulLength = 0;
4631  }
4632  }
4633 
4634 done:
4635  if (ret == CR_SUCCESS)
4636  *pulTransferLen = *pulLength;
4637 
4638  if (hParamKey != NULL)
4639  RegCloseKey(hParamKey);
4640 
4641  if (hDeviceKey != NULL)
4642  RegCloseKey(hDeviceKey);
4643 
4644  DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret);
4645 
4646  return ret;
4647 }
4648 
4649 
4650 /* Function 62 */
4651 DWORD
4652 WINAPI
4655  WORD *pwVersion)
4656 {
4658 
4659  *pwVersion = 0x501;
4660  return CR_SUCCESS;
4661 }
4662 
4663 
4664 /* Function 63 */
4665 DWORD
4666 WINAPI
4669  BYTE *Buffer,
4670  PNP_RPC_BUFFER_SIZE *pulTransferLen,
4671  PNP_RPC_BUFFER_SIZE *pulLength,
4672  DWORD ulFlags)
4673 {
4674  UNIMPLEMENTED;
4675  return CR_CALL_NOT_IMPLEMENTED;
4676 }
4677 
4678 
4679 /* Function 64 */
4680 DWORD
4681 WINAPI
4684  DWORD *pulSSDIFlags,
4685  DWORD ulFlags)
4686 {
4688 
4689  DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
4690  hBinding, pulSSDIFlags, ulFlags);
4691 
4692  if (pulSSDIFlags == NULL)
4693  return CR_INVALID_POINTER;
4694 
4695  if (ulFlags != 0)
4696  return CR_INVALID_FLAG;
4697 
4698  /* FIXME */
4699  *pulSSDIFlags = 0;
4700 
4701  return CR_SUCCESS;
4702 }
4703 
4704 
4705 /* Function 65 */
4706 DWORD
4707 WINAPI
4711  DWORD ObjectType,
4712  LPWSTR PropertyCultureName,
4713  PNP_PROP_COUNT *PropertyCount,
4714  PNP_PROP_COUNT *TransferLen,
4715  DEVPROPKEY *PropertyKeys,
4716  DWORD Flags)
4717 {
4718  UNIMPLEMENTED;
4719  return CR_CALL_NOT_IMPLEMENTED;
4720 }
4721 
4722 
4723 /* Function 66 */
4724 DWORD
4725 WINAPI
4729  DWORD ObjectType,
4730  LPWSTR PropertyCultureName,
4731  const DEVPROPKEY *PropertyKey,
4733  PNP_PROP_SIZE *PropertySize,
4734  PNP_PROP_SIZE *TransferLen,
4736  DWORD Flags)
4737 {
4738  UNIMPLEMENTED;
4739  return CR_CALL_NOT_IMPLEMENTED;
4740 }
4741 
4742 
4743 /* Function 67 */
4744 DWORD
4745 WINAPI
4749  DWORD ObjectType,
4750  LPWSTR PropertyCultureName,
4751  const DEVPROPKEY *PropertyKey,
4753  PNP_PROP_SIZE PropertySize,
4755  DWORD Flags)
4756 {
4757  UNIMPLEMENTED;
4758  return CR_CALL_NOT_IMPLEMENTED;
4759 }
4760 
4761 
4762 /* Function 68 */
4763 DWORD
4764 WINAPI
4767 {
4768  UNIMPLEMENTED;
4769  return CR_CALL_NOT_IMPLEMENTED;
4770 }
4771 
4772 
4773 /* Function 69 */
4774 DWORD
4775 WINAPI
4778 {
4779  UNIMPLEMENTED;
4780  return CR_CALL_NOT_IMPLEMENTED;
4781 }
4782 
4783 
4784 /* Function 70 */
4785 DWORD
4786 WINAPI
4789 {
4790  UNIMPLEMENTED;
4791  return CR_CALL_NOT_IMPLEMENTED;
4792 }
4793 
4794 
4795 /* Function 71 */
4796 DWORD
4797 WINAPI
4800 {
4801  UNIMPLEMENTED;
4802  return CR_CALL_NOT_IMPLEMENTED;
4803 }
4804 
4805 
4806 /* Function 72 */
4807 DWORD
4808 WINAPI
4811 {
4812  UNIMPLEMENTED;
4813  return CR_CALL_NOT_IMPLEMENTED;
4814 }
4815 
4816 
4817 /* Function 73 */
4818 DWORD
4819 WINAPI
4822  LPWSTR pszFilter,
4823  DWORD ulFlags)
4824 {
4825  UNIMPLEMENTED;
4826  return CR_CALL_NOT_IMPLEMENTED;
4827 }
4828 
4829 
4830 /* Function 74 */
4831 DWORD
4832 WINAPI
4835 {
4836  UNIMPLEMENTED;
4837  return CR_CALL_NOT_IMPLEMENTED;
4838 }
#define CR_NO_SUCH_REGISTRY_KEY
Definition: cfgmgr32.h:892
DWORD WINAPI PNP_GetInterfaceDeviceList(handle_t hBinding, GUID *InterfaceGuid, LPWSTR pszDeviceID, BYTE *Buffer, PNP_RPC_BUFFER_SIZE *pulLength, DWORD ulFlags)
Definition: rpcserver.c:2477
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
ObjectType
Definition: metafile.c:80
#define PNP_PROPERTY_POWER_DATA
Definition: cmtypes.h:39
#define IN
Definition: typedefs.h:39
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2709
#define CR_INVALID_DEVINST
Definition: cfgmgr32.h:848
DWORD WINAPI PNP_GetDepth(handle_t hBinding, LPWSTR pszDeviceID, DWORD *pulDepth, DWORD ulFlags)
Definition: rpcserver.c:1668
#define CloseHandle
Definition: compat.h:598
#define CM_DEVCAP_REMOVABLE
Definition: cfgmgr32.h:737
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
#define _Inout_
Definition: ms_sal.h:378
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD WINAPI PNP_DeleteRegistryKey(handle_t hBinding, LPWSTR pszDeviceID, LPWSTR pszParentKey, LPWSTR pszChildKey, DWORD ulFlags)
Definition: rpcserver.c:2310
#define CM_REGISTER_DEVICE_DRIVER_BITS
Definition: cfgmgr32.h:798
#define KEY_SET_VALUE
Definition: nt_native.h:1017
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned long PNP_RPC_BUFFER_SIZE
Definition: pnp.idl:31
#define CR_INVALID_FLAG
Definition: cfgmgr32.h:846
DWORD WINAPI PNP_GetFirstLogConf(handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfType, DWORD *pulLogConfTag, DWORD ulFlags)
Definition: rpcserver.c:3969
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
handle_t hBinding
Definition: ctx_c.c:54
DWORD WINAPI PNP_GetResDesDataSize(handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID ResourceID, DWORD ulResourceTag, DWORD *pulSize, DWORD ulFlags)
Definition: rpcserver.c:4325
DWORD HWPI_dwFlags
Definition: cfgmgr32.h:556
#define _Out_
Definition: ms_sal.h:345
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define CM_CREATE_DEVNODE_GENERATE_ID
Definition: cfgmgr32.h:622
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
HANDLE hInstallEvent
Definition: install.c:40
#define DBT_DEVTYP_DEVICEINTERFACE
Definition: dbt.h:24
static VOID SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID, OUT LPWSTR pszEnumerator, OUT LPWSTR pszDevice, OUT LPWSTR pszInstance)
Definition: rpcserver.c:150
#define CM_DRP_REMOVAL_POLICY_HW_DEFAULT
Definition: cfgmgr32.h:720
DWORD WINAPI PNP_UnregisterNotification(handle_t hBinding, DWORD ulNotify)
Definition: rpcserver.c:4535
#define CM_DELETE_CLASS_SUBKEYS
Definition: cfgmgr32.h:635
#define CM_DRP_FRIENDLYNAME
Definition: cfgmgr32.h:688
DWORD WINAPI PNP_GetNextLogConf(handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfType, DWORD ulCurrentTag, DWORD *pulNextTag, DWORD ulFlags)
Definition: rpcserver.c:4068
#define CM_DRP_EXCLUSIVE
Definition: cfgmgr32.h:711
#define FORCED_LOG_CONF
Definition: cfgmgr32.h:600
#define CM_DRP_LEGACYBUSTYPE
Definition: cfgmgr32.h:702
LONG NTSTATUS
Definition: precomp.h:26
#define CM_SETUP_BITS
Definition: cfgmgr32.h:828
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)
Definition: rpcserver.c:4384
#define CM_GETIDLIST_FILTER_NONE
Definition: cfgmgr32.h:654
static CONFIGRET SetupDeviceInstance(_In_ LPWSTR pszDeviceInstance, _In_ DWORD ulMinorAction)
Definition: rpcserver.c:3006
static CONFIGRET GetServiceInstanceListSize(_In_ PWSTR pszService, _Out_ PDWORD pulLength)
Definition: rpcserver.c:1346
_In_ DWORD nLength
Definition: wincon.h:473
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
static BOOL IsValidDeviceInstanceID(_In_ PWSTR pszDeviceInstanceID)
Definition: rpcserver.c:337
DWORD WINAPI PNP_RegisterNotification(handle_t hBinding, DWORD ulUnknown2, LPWSTR pszName, BYTE *pNotificationFilter, DWORD ulNotificationFilterSize, DWORD ulFlags, DWORD *pulNotify, DWORD ulUnknown8, DWORD *pulUnknown9)
Definition: rpcserver.c:4457
static CONFIGRET WINAPI NtStatusToCrError(NTSTATUS Status)
Definition: rpcserver.c:121
static CONFIGRET GetAllInstanceList(_Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength)
Definition: rpcserver.c:1173
#define CM_GETIDLIST_FILTER_SERVICE
Definition: cfgmgr32.h:656
DWORD WINAPI PNP_CreateDevInst(handle_t hBinding, LPWSTR pszDeviceID, LPWSTR pszParentDeviceID, PNP_RPC_STRING_LEN ulLength, DWORD ulFlags)
Definition: rpcserver.c:2939
_Check_return_ _Out_ PULONG pulSize
Definition: winddi.h:2120
#define CM_CRP_DEVTYPE
Definition: cfgmgr32.h:710
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
static CONFIGRET GetAllInstanceListSize(_Out_ PULONG pulLength)
Definition: rpcserver.c:1558
#define TOKEN_ASSIGN_PRIMARY
Definition: setypes.h:890
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
DWORD WINAPI PNP_ReportLogOn(handle_t hBinding, BOOL Admin, DWORD ProcessId)
Definition: rpcserver.c:618
#define PNP_SET_DEVICE_STATUS
Definition: cmtypes.h:60
#define CM_DRP_BUSTYPEGUID
Definition: cfgmgr32.h:701
#define CR_NO_SUCH_VALUE
Definition: cfgmgr32.h:883
DWORD WINAPI PNP_GetNextResDes(handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID ResourceID, DWORD ulResourceTag, DWORD *pulNextResType, DWORD *pulNextResTag, DWORD ulFlags)
Definition: rpcserver.c:4212
#define CR_ALREADY_SUCH_DEVINST
Definition: cfgmgr32.h:862
#define CM_DRP_SERVICE
Definition: cfgmgr32.h:680
#define CM_DRP_COMPATIBLEIDS
Definition: cfgmgr32.h:678
uint16_t * PWCHAR
Definition: typedefs.h:56
DWORD WINAPI PNP_DriverStoreDeleteDriverPackage(handle_t hBinding)
Definition: rpcserver.c:4798
#define swprintf
Definition: precomp.h:40
UNICODE_STRING DeviceInstance
Definition: cmtypes.h:525
CONFIGRET GetEnumeratorInstanceList(_In_ PWSTR pszEnumerator, _Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength)
Definition: rpcserver.c:1102
struct _DEV_BROADCAST_DEVICEINTERFACE_W DEV_BROADCAST_DEVICEINTERFACE_W
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
#define CR_REMOVE_VETOED
Definition: cfgmgr32.h:869
DWORD WINAPI PNP_RequestEjectPC(handle_t hBinding)
Definition: rpcserver.c:3688
ULONG DEVPROPTYPE
Definition: devpropdef.h:24
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
static CONFIGRET GetDeviceInstanceListSize(_In_ LPCWSTR pszDevice, _Out_ PULONG pulLength)
Definition: rpcserver.c:1445
#define CR_ACCESS_DENIED
Definition: cfgmgr32.h:897
#define CM_GETIDLIST_FILTER_BUSRELATIONS
Definition: cfgmgr32.h:660
#define lstrlenW
Definition: compat.h:609
#define CM_DRP_REMOVAL_POLICY
Definition: cfgmgr32.h:719
DWORD WINAPI PNP_DeleteServiceDevices(handle_t hBinding)
Definition: rpcserver.c:4833
DWORD WINAPI PNP_GetServerSideDeviceInstallFlags(handle_t hBinding, DWORD *pulSSDIFlags, DWORD ulFlags)
Definition: rpcserver.c:4682
#define CM_DRP_SECURITY
Definition: cfgmgr32.h:705
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI PNP_UnregisterDeviceClassAssociation(handle_t hBinding, LPWSTR pszInterfaceDevice, DWORD ulFlags)
Definition: rpcserver.c:2590
#define CM_SETUP_WRITE_LOG_CONFS
Definition: cfgmgr32.h:822
#define REG_RESOURCE_REQUIREMENTS_LIST
Definition: nt_native.h:1504
#define CM_GETIDLIST_FILTER_EJECTRELATIONS
Definition: cfgmgr32.h:657
#define CM_SET_DEVNODE_PROBLEM_BITS
Definition: cfgmgr32.h:808
#define CM_ADD_ID_COMPATIBLE
Definition: cfgmgr32.h:615
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
#define CM_CRP_CHARACTERISTICS
Definition: cfgmgr32.h:714
struct _DEV_BROADCAST_DEVICEINTERFACE_W * PDEV_BROADCAST_DEVICEINTERFACE_W
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define CM_SET_DEVNODE_PROBLEM_OVERRIDE
Definition: cfgmgr32.h:807
DWORD WINAPI PNP_GetDeviceStatus(handle_t hBinding, LPWSTR pDeviceID, DWORD *pulStatus, DWORD *pulProblem, DWORD ulFlags)
Definition: rpcserver.c:3189
#define STATUS_PLUGPLAY_QUERY_VETOED
Definition: ntstatus.h:219
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)
Definition: rpcserver.c:1711
#define CM_DRP_UPPERFILTERS
Definition: cfgmgr32.h:693
return STATUS_NOT_IMPLEMENTED
long RPC_STATUS
Definition: rpc.h:52
DWORD WINAPI PNP_GetClassCount(handle_t hBinding, DWORD *pulClassCount, DWORD ulFlags)
Definition: rpcserver.c:2325
#define CM_SETUP_DOWNLOAD
Definition: cfgmgr32.h:821
static CONFIGRET GetDeviceStatus(_In_ LPWSTR pszDeviceID, _Out_ DWORD *pulStatus, _Out_ DWORD *pulProblem)
Definition: rpcserver.c:226
#define CM_REENUMERATE_BITS
Definition: cfgmgr32.h:793
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
UINT32 void void ** ReturnValue
Definition: acevents.h:214
static CONFIGRET OpenConfigurationKey(_In_ LPCWSTR pszDeviceID, _Out_ PHKEY phKey)
Definition: rpcserver.c:415
DWORD WINAPI PNP_FreeLogConf(handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfType, DWORD ulLogConfTag, DWORD ulFlags)
Definition: rpcserver.c:3954
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define CM_DRP_LOWERFILTERS
Definition: cfgmgr32.h:697
unsigned int BOOL
Definition: ntddk_ex.h:94
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)
Definition: rpcserver.c:4554
long LONG
Definition: pedump.c:60
#define CM_CRP_EXCLUSIVE
Definition: cfgmgr32.h:712
#define CR_NO_MORE_LOG_CONF
Definition: cfgmgr32.h:859
void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
Definition: rpcserver.c:55
#define REG_MULTI_SZ
Definition: nt_native.h:1501
DWORD WINAPI PNP_FreeResDes(handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID ResourceID, DWORD ulResourceTag, DWORD *pulPreviousResType, DWORD *pulPreviousResTag, DWORD ulFlags)
Definition: rpcserver.c:4193
static VOID AppendDeviceId(LPWSTR lpDeviceIdList, LPDWORD lpDeviceIdListSize, LPWSTR lpDeviceId)
Definition: rpcserver.c:3382
RPC_STATUS WINAPI RpcServerListen(UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait)
Definition: rpc_server.c:1520
DWORD WINAPI PNP_GetVersion(handle_t hBinding, WORD *pVersion)
Definition: rpcserver.c:565
#define FILTERED_LOG_CONF
Definition: cfgmgr32.h:597
static PVOID ptr
Definition: dispmode.c:27
DWORD WINAPI PNP_QueryRemove(handle_t hBinding, LPWSTR pszDeviceID, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, DWORD ulNameLength, DWORD ulFlags)
Definition: rpcserver.c:3535
DWORD WINAPI PNP_InstallDevInst(handle_t hBinding)
Definition: rpcserver.c:4765
#define CR_SUCCESS
Definition: cfgmgr32.h:842
#define CM_DRP_ENUMERATOR_NAME
Definition: cfgmgr32.h:704
CONFIGRET WINAPI PNP_IsDockStationPresent(handle_t hBinding, BOOL *Present)
Definition: rpcserver.c:3632
DWORD WINAPI PNP_CreateKey(handle_t hBinding, LPWSTR pszSubKey, DWORD samDesired, DWORD ulFlags)
Definition: rpcserver.c:2246
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)
Definition: rpcserver.c:4174
static CONFIGRET GetRelationsInstanceListSize(_In_ PWSTR pszDevice, _In_ DWORD ulFlags, _Inout_ PDWORD pulLength)
Definition: rpcserver.c:1296
unsigned char BOOLEAN
DWORD WINAPI PNP_SetActiveService(handle_t hBinding, LPWSTR pszFilter, DWORD ulFlags)
Definition: rpcserver.c:4820
DWORD WINAPI PNP_DetectResourceConflict(handle_t hBinding, LPWSTR pDeviceID, RESOURCEID ResourceID, BYTE *ResourceData, PNP_RPC_BUFFER_SIZE ResourceLen, BOOL *pbConflictDetected, DWORD ulFlags)
Definition: rpcserver.c:4363
#define _In_
Definition: ms_sal.h:308
#define CM_DRP_CLASSGUID
Definition: cfgmgr32.h:684
#define PNP_PROPERTY_BUSTYPEGUID
Definition: cmtypes.h:36
#define BASIC_LOG_CONF
Definition: cfgmgr32.h:596
#define CR_INVALID_PROPERTY
Definition: cfgmgr32.h:899
#define PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT
Definition: cmtypes.h:44
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)
Definition: rpcserver.c:801
DWORD WINAPI PNP_QueryArbitratorFreeData(handle_t hBinding, BYTE *pData, DWORD DataLen, LPWSTR pDeviceID, RESOURCEID ResourceID, DWORD ulFlags)
Definition: rpcserver.c:4414
unsigned long PNP_PROP_COUNT
Definition: pnp.idl:29
CONFIGRET WINAPI PNP_RunDetection(handle_t hBinding, DWORD ulFlags)
Definition: rpcserver.c:4446
HKEY hClassKey
Definition: umpnpmgr.c:45
#define CR_OUT_OF_MEMORY
Definition: cfgmgr32.h:844
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)
Definition: rpcserver.c:4708
Definition: bufpool.h:45
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
#define CM_CREATE_DEVNODE_BITS
Definition: cfgmgr32.h:624
#define __RPC_FAR
Definition: rpc.h:56
static CONFIGRET ClearDeviceStatus(_In_ LPWSTR pszDeviceID, _In_ DWORD ulStatus, _In_ DWORD ulProblem)
Definition: rpcserver.c:196
#define CM_CRP_SECURITY
Definition: cfgmgr32.h:706
DWORD WINAPI PNP_ApplyPowerSettings(handle_t hBinding)
Definition: rpcserver.c:4776
DWORD WINAPI PNP_SetClassRegProp(handle_t hBinding, LPWSTR pszClassGuid, DWORD ulProperty, DWORD ulDataType, BYTE *Buffer, PNP_PROP_SIZE ulLength, DWORD ulFlags)
Definition: rpcserver.c:2729
#define __RPC_USER
Definition: rpc.h:65
#define CM_DISABLE_BITS
Definition: cfgmgr32.h:652
#define CM_DRP_DEVTYPE
Definition: cfgmgr32.h:709
#define CM_REMOVE_BITS
Definition: cfgmgr32.h:780
#define ALLOC_LOG_CONF
Definition: cfgmgr32.h:598
#define CM_GLOBAL_STATE_SERVICES_AVAILABLE
Definition: cfgmgr32.h:910
#define PNP_PROPERTY_ADDRESS
Definition: cmtypes.h:42
#define CM_GETIDLIST_FILTER_REMOVALRELATIONS
Definition: cfgmgr32.h:658
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
static CONFIGRET EnableDeviceInstance(_In_ LPWSTR pszDeviceInstance)
Definition: rpcserver.c:3089
DWORD WINAPI PNP_ValidateDeviceInstance(handle_t hBinding, LPWSTR pDeviceID, DWORD ulFlags)
Definition: rpcserver.c:670
UNICODE_STRING DeviceInstance
Definition: cmtypes.h:507
struct _DEV_BROADCAST_HANDLE DEV_BROADCAST_HANDLE
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
HANDLE hUserToken
Definition: install.c:39
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)
Definition: rpcserver.c:4726
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4899
static HANDLE hServicesKey
Definition: devinst.c:21
static CONFIGRET SetDeviceStatus(_In_ LPWSTR pszDeviceID, _In_ DWORD ulStatus, _In_ DWORD ulProblem)
Definition: rpcserver.c:261
#define PNP_PROPERTY_LOCATION_PATHS
Definition: cmtypes.h:46
int Count
Definition: noreturn.cpp:7
_In_ WDFDEVICE _In_ PWDF_DEVICE_INTERFACE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG _Out_ PDEVPROPTYPE PropertyType
static CONFIGRET GetConfigurationData(_In_ HKEY hKey, _In_ ULONG ulLogConfType, _Out_ PULONG pulRegDataType, _Out_ PULONG pulDataSize, _Out_ LPBYTE *ppBuffer)
Definition: rpcserver.c:459
#define PNP_PROPERTY_ENUMERATOR_NAME
Definition: cmtypes.h:43
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define TOKEN_QUERY
Definition: setypes.h:893
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD DWORD * dwLength
Definition: fusion.c:85
DWORD WINAPI PNP_GetClassInstance(handle_t hBinding, LPWSTR pDeviceId, LPWSTR pszClassInstance, PNP_RPC_STRING_LEN ulLength)
Definition: rpcserver.c:2130
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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)
Definition: rpcserver.c:4343
#define CM_GLOBAL_STATE_CAN_DO_UI
Definition: cfgmgr32.h:908
#define PNP_GET_DEVICE_STATUS
Definition: cmtypes.h:59
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define DN_REMOVABLE
Definition: cfg.h:132
#define PNP_PROPERTY_REMOVAL_POLICY
Definition: cmtypes.h:40
DWORD WINAPI PNP_QueryArbitratorFreeSize(handle_t hBinding, DWORD *pulSize, LPWSTR pDeviceID, RESOURCEID ResourceID, DWORD ulFlags)
Definition: rpcserver.c:4429
#define CR_BUFFER_SMALL
Definition: cfgmgr32.h:872
#define CM_DRP_HARDWAREID
Definition: cfgmgr32.h:677
ULONG RESOURCEID
Definition: cfgmgr32.h:96
#define CM_DRP_REMOVAL_POLICY_OVERRIDE
Definition: cfgmgr32.h:721
static CONFIGRET GetDeviceInstanceList(_In_ PWSTR pszDevice, _Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength)
Definition: rpcserver.c:1031
#define CR_INVALID_LOG_CONF
Definition: cfgmgr32.h:850
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
#define DN_HAS_PROBLEM
Definition: cfg.h:128
struct _DEV_BROADCAST_HANDLE * PDEV_BROADCAST_HANDLE
DWORD WINAPI PNP_SetHwProf(handle_t hBinding, DWORD ulHardwareProfile, DWORD ulFlags)
Definition: rpcserver.c:4402
unsigned short WORD
Definition: ntddk_ex.h:93
DWORD WINAPI PNP_InitDetection(handle_t hBinding)
Definition: rpcserver.c:603
#define CR_FAILURE
Definition: cfgmgr32.h:865
unsigned long DWORD
Definition: ntddk_ex.h:95
#define CM_DRP_LOCATION_INFORMATION
Definition: cfgmgr32.h:689
RPC_STATUS WINAPI RpcServerRegisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv)
Definition: rpc_server.c:1116
DWORD WINAPI PNP_RegisterServiceNotification(handle_t hBinding)
Definition: rpcserver.c:4809
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
DWORD WINAPI PNP_DeviceInstanceAction(handle_t hBinding, DWORD ulMajorAction, DWORD ulMinorAction, LPWSTR pszDeviceInstance1, LPWSTR pszDeviceInstance2)
Definition: rpcserver.c:3144
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)
Definition: rpcserver.c:3720
DWORD WINAPI PNP_AddEmptyLogConf(handle_t hBinding, LPWSTR pDeviceID, DWORD ulPriority, DWORD *pulLogConfTag, DWORD ulFlags)
Definition: rpcserver.c:3939