ReactOS  0.4.15-dev-5500-g82cf6c2
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 
42 
43 /* FUNCTIONS *****************************************************************/
44 
46 RpcServerThread(LPVOID lpParameter)
47 {
49  BOOLEAN RegisteredProtSeq = FALSE;
50 
51  UNREFERENCED_PARAMETER(lpParameter);
52 
53  DPRINT("RpcServerThread() called\n");
54 
56 
57 #if 0
58  /* 2k/XP/2k3-compatible protocol sequence/endpoint */
59  Status = RpcServerUseProtseqEpW(L"ncacn_np",
60  20,
61  L"\\pipe\\ntsvcs",
62  NULL); // Security descriptor
63  if (Status == RPC_S_OK)
64  RegisteredProtSeq = TRUE;
65  else
66  DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
67 #endif
68 
69  /* Vista/7-compatible protocol sequence/endpoint */
70  Status = RpcServerUseProtseqEpW(L"ncacn_np",
71  20,
72  L"\\pipe\\plugplay",
73  NULL); // Security descriptor
74  if (Status == RPC_S_OK)
75  RegisteredProtSeq = TRUE;
76  else
77  DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
78 
79  /* Make sure there's a usable endpoint */
80  if (RegisteredProtSeq == FALSE)
81  return 0;
82 
83  Status = RpcServerRegisterIf(pnp_v1_0_s_ifspec,
84  NULL,
85  NULL);
86  if (Status != RPC_S_OK)
87  {
88  DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
89  return 0;
90  }
91 
93  20,
94  FALSE);
95  if (Status != RPC_S_OK)
96  {
97  DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
98  return 0;
99  }
100 
101  /* ROS HACK (this should never happen...) */
102  DPRINT1("*** Other devices won't be installed correctly. If something\n");
103  DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
104 
105  DPRINT("RpcServerThread() done\n");
106 
107  return 0;
108 }
109 
110 
112 {
114 }
115 
116 
118 {
119  HeapFree(GetProcessHeap(), 0, ptr);
120 }
121 
122 
123 static CONFIGRET WINAPI
125 {
126  switch (Status)
127  {
130 
132  return CR_INVALID_DATA;
133 
135  return CR_NO_SUCH_DEVINST;
136 
138  return CR_ACCESS_DENIED;
139 
141  return CR_BUFFER_SMALL;
142 
144  return CR_NO_SUCH_VALUE;
145 
146  default:
147  return CR_FAILURE;
148  }
149 }
150 
151 
152 static VOID
153 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID,
154  OUT LPWSTR pszEnumerator,
155  OUT LPWSTR pszDevice,
156  OUT LPWSTR pszInstance)
157 {
158  WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN];
159  LPWSTR lpEnumerator = NULL;
160  LPWSTR lpDevice = NULL;
161  LPWSTR lpInstance = NULL;
162  LPWSTR ptr;
163 
164  wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID);
165 
166  *pszEnumerator = 0;
167  *pszDevice = 0;
168  *pszInstance = 0;
169 
170  lpEnumerator = szLocalDeviceInstanceID;
171 
172  ptr = wcschr(lpEnumerator, L'\\');
173  if (ptr != NULL)
174  {
175  *ptr = 0;
176  lpDevice = ++ptr;
177 
178  ptr = wcschr(lpDevice, L'\\');
179  if (ptr != NULL)
180  {
181  *ptr = 0;
182  lpInstance = ++ptr;
183  }
184  }
185 
186  if (lpEnumerator != NULL)
187  wcscpy(pszEnumerator, lpEnumerator);
188 
189  if (lpDevice != NULL)
190  wcscpy(pszDevice, lpDevice);
191 
192  if (lpInstance != NULL)
193  wcscpy(pszInstance, lpInstance);
194 }
195 
196 
197 static
198 CONFIGRET
200  _In_ LPWSTR pszDeviceID,
201  _In_ DWORD ulStatus,
202  _In_ DWORD ulProblem)
203 {
204  PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
207 
208  DPRINT1("ClearDeviceStatus(%S 0x%lx 0x%lx)\n",
209  pszDeviceID, ulStatus, ulProblem);
210 
211  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
212  pszDeviceID);
213  PlugPlayData.Operation = PNP_CLEAR_DEVICE_STATUS;
214  PlugPlayData.DeviceStatus = ulStatus;
215  PlugPlayData.DeviceProblem = ulProblem;
216 
218  (PVOID)&PlugPlayData,
220  if (!NT_SUCCESS(Status))
222 
223  return ret;
224 }
225 
226 
227 static
228 CONFIGRET
230  _In_ LPWSTR pszDeviceID,
231  _Out_ DWORD *pulStatus,
232  _Out_ DWORD *pulProblem)
233 {
234  PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
237 
238  DPRINT("GetDeviceStatus(%S %p %p)\n",
239  pszDeviceID, pulStatus, pulProblem);
240 
241  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
242  pszDeviceID);
243  PlugPlayData.Operation = PNP_GET_DEVICE_STATUS;
244 
246  (PVOID)&PlugPlayData,
248  if (NT_SUCCESS(Status))
249  {
250  *pulStatus = PlugPlayData.DeviceStatus;
251  *pulProblem = PlugPlayData.DeviceProblem;
252  }
253  else
254  {
256  }
257 
258  return ret;
259 }
260 
261 
262 static
263 CONFIGRET
265  _In_ LPWSTR pszDeviceID,
266  _In_ DWORD ulStatus,
267  _In_ DWORD ulProblem)
268 {
269  PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
272 
273  DPRINT1("SetDeviceStatus(%S 0x%lx 0x%lx)\n",
274  pszDeviceID, ulStatus, ulProblem);
275 
276  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
277  pszDeviceID);
278  PlugPlayData.Operation = PNP_SET_DEVICE_STATUS;
279  PlugPlayData.DeviceStatus = ulStatus;
280  PlugPlayData.DeviceProblem = ulProblem;
281 
283  (PVOID)&PlugPlayData,
285  if (!NT_SUCCESS(Status))
287 
288  return ret;
289 }
290 
291 
292 static
293 CONFIGRET
295  _In_ LPWSTR pszDeviceInstance,
296  _Inout_opt_ PPNP_VETO_TYPE pVetoType,
297  _Inout_opt_ LPWSTR pszVetoName,
298  _In_ DWORD ulNameLength)
299 {
300  PLUGPLAY_CONTROL_QUERY_REMOVE_DATA QueryRemoveData;
303 
304  DPRINT1("DisableDeviceInstance(%S %p %p %lu)\n",
305  pszDeviceInstance, pVetoType, pszVetoName, ulNameLength);
306 
307  RtlInitUnicodeString(&QueryRemoveData.DeviceInstance,
308  pszDeviceInstance);
309 
310  QueryRemoveData.Flags = 0;
311  QueryRemoveData.VetoType = 0;
312  QueryRemoveData.VetoName = pszVetoName;
313  QueryRemoveData.NameLength = ulNameLength;
314 
316  &QueryRemoveData,
319  {
321  }
323  {
324  if (pVetoType != NULL)
325  *pVetoType = QueryRemoveData.VetoType;
326 
328  }
329  else if (!NT_SUCCESS(Status))
330  {
332  }
333 
334  return ret;
335 }
336 
337 
338 static
339 BOOL
341  _In_ PWSTR pszDeviceInstanceID)
342 {
343  INT nPartLength[3] = {0, 0, 0};
344  INT nLength = 0, nParts = 0;
345  PWCHAR p;
346 
347  DPRINT("IsValidDeviceInstanceID(%S)\n",
348  pszDeviceInstanceID);
349 
350  if (pszDeviceInstanceID == NULL)
351  {
352  DPRINT("Device instance ID is NULL!\n");
353  return FALSE;
354  }
355 
356  p = pszDeviceInstanceID;
357  while (*p != UNICODE_NULL)
358  {
359  if (*p == L'\\')
360  {
361  nParts++;
362  if (nParts >= 3)
363  {
364  DPRINT("Too many separators: %d\n", nParts);
365  return FALSE;
366  }
367  }
368  else
369  {
370  nPartLength[nParts]++;
371  }
372 
373  nLength++;
374  if (nLength >= MAX_DEVICE_ID_LEN)
375  {
376  DPRINT("Too long: %d\n", nLength);
377  return FALSE;
378  }
379 
380  p++;
381  }
382 
383  if (nParts != 2)
384  {
385  DPRINT("Invalid number of separtors: %d\n", nParts);
386  return FALSE;
387  }
388 
389  if ((nPartLength[0] == 0) ||
390  (nPartLength[1] == 0) ||
391  (nPartLength[2] == 0))
392  {
393  DPRINT("Invalid part lengths: %d %d %d\n",
394  nPartLength[0], nPartLength[1], nPartLength[2]);
395  return FALSE;
396  }
397 
398  DPRINT("Valid device instance ID!\n");
399 
400  return TRUE;
401 }
402 
403 
404 static
405 BOOL
407  _In_ PWSTR pszDeviceInstanceID)
408 {
409  if (_wcsicmp(pszDeviceInstanceID, szRootDeviceInstanceID) == 0)
410  return TRUE;
411 
412  return FALSE;
413 }
414 
415 
416 static
417 BOOL
419  _In_ LPWSTR pszDeviceInstanceID)
420 {
421  DWORD ulStatus, ulProblem;
422 
423  return (GetDeviceStatus(pszDeviceInstanceID, &ulStatus, &ulProblem) == CR_SUCCESS);
424 }
425 
426 
427 static
428 CONFIGRET
430  _In_ LPCWSTR pszDeviceID,
431  _Out_ PHKEY phKey)
432 {
433  WCHAR szKeyName[MAX_PATH];
434  HKEY hInstanceKey;
435  DWORD dwError;
436 
437  /* Build the full device instance key name */
438  wcscpy(szKeyName, L"System\\CurrentControlSet\\Enum\\");
439  wcscat(szKeyName, pszDeviceID);
440 
441  /* Open the device instance key */
443  szKeyName,
444  0,
446  &hInstanceKey);
447  if (dwError != ERROR_SUCCESS)
448  return CR_INVALID_DEVINST;
449 
450  /* Create or open the LogConf key */
451  dwError = RegCreateKeyExW(hInstanceKey,
452  L"LogConf",
453  0,
454  NULL,
457  NULL,
458  phKey,
459  NULL);
460 
461  /* Close the device instance key */
462  RegCloseKey(hInstanceKey);
463 
464  if (dwError != ERROR_SUCCESS)
465  return CR_REGISTRY_ERROR;
466 
467  return CR_SUCCESS;
468 }
469 
470 
471 static
472 CONFIGRET
474  _In_ HKEY hKey,
475  _In_ ULONG ulLogConfType,
476  _Out_ PULONG pulRegDataType,
477  _Out_ PULONG pulDataSize,
478  _Out_ LPBYTE *ppBuffer)
479 {
480  LPCWSTR pszValueName;
481 
482  switch (ulLogConfType)
483  {
484  case BOOT_LOG_CONF:
485  pszValueName = L"BootConfig";
486  *pulRegDataType = REG_RESOURCE_LIST;
487  break;
488 
489  case ALLOC_LOG_CONF:
490  pszValueName = L"AllocConfig";
491  *pulRegDataType = REG_RESOURCE_LIST;
492  break;
493 
494  case FORCED_LOG_CONF:
495  pszValueName = L"ForcedConfig";
496  *pulRegDataType = REG_RESOURCE_LIST;
497  break;
498 
499  case FILTERED_LOG_CONF:
500  pszValueName = L"FilteredConfigVector";
501  *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
502  break;
503 
504  case BASIC_LOG_CONF:
505  pszValueName = L"BasicConfigVector";
506  *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
507  break;
508 
509  case OVERRIDE_LOG_CONF:
510  pszValueName = L"OverrideConfigVector";
511  *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
512  break;
513 
514  default:
515  DPRINT1("Unsupported configuration type!\n");
516  return CR_FAILURE;
517  }
518 
519  /* Get the configuration data size */
521  pszValueName,
522  NULL,
523  NULL,
524  NULL,
525  pulDataSize) != ERROR_SUCCESS)
526  {
527  return CR_INVALID_LOG_CONF;
528  }
529 
530  /* Allocate the buffer */
531  *ppBuffer = HeapAlloc(GetProcessHeap(), 0, *pulDataSize);
532  if (*ppBuffer == NULL)
533  {
534  return CR_OUT_OF_MEMORY;
535  }
536 
537  /* Retrieve the configuration data */
539  pszValueName,
540  NULL,
541  NULL,
542  (LPBYTE)*ppBuffer,
543  pulDataSize) != ERROR_SUCCESS)
544  {
545  return CR_INVALID_LOG_CONF;
546  }
547 
548  return CR_SUCCESS;
549 }
550 
551 
552 VOID
555  PNP_NOTIFY_HANDLE pHandle)
556 {
557  DPRINT1("PNP_NOTIFY_HANDLE_rundown(%p)\n", pHandle);
558 }
559 
560 
561 /* PUBLIC FUNCTIONS **********************************************************/
562 
563 /* Function 0 */
564 DWORD
565 WINAPI
568 {
570  return CR_SUCCESS;
571 }
572 
573 
574 /* Function 1 */
575 DWORD
576 WINAPI
579 {
581  return CR_SUCCESS;
582 }
583 
584 
585 /* Function 2 */
586 DWORD
587 WINAPI
590  WORD *pVersion)
591 {
593 
594  DPRINT("PNP_GetVersion(%p %p)\n",
595  hBinding, pVersion);
596 
597  *pVersion = 0x0400;
598 
599  return CR_SUCCESS;
600 }
601 
602 
603 /* Function 3 */
604 DWORD
605 WINAPI
608  DWORD *pulState,
609  DWORD ulFlags)
610 {
612  UNREFERENCED_PARAMETER(ulFlags);
613 
614  DPRINT("PNP_GetGlobalState(%p %p 0x%08lx)\n",
615  hBinding, pulState, ulFlags);
616 
618 
619  return CR_SUCCESS;
620 }
621 
622 
623 /* Function 4 */
624 DWORD
625 WINAPI
628 {
630 
631  DPRINT("PNP_InitDetection(%p)\n",
632  hBinding);
633 
634  return CR_SUCCESS;
635 }
636 
637 
638 /* Function 5 */
639 DWORD
640 WINAPI
643  BOOL Admin,
645 {
648 
650  UNREFERENCED_PARAMETER(Admin);
651 
652  DPRINT("PNP_ReportLogOn(%p %u, %u)\n",
653  hBinding, Admin, ProcessId);
654 
655  /* Get the users token */
657 
658  if (!hProcess)
659  {
660  DPRINT1("OpenProcess failed with error %u\n", GetLastError());
661  goto cleanup;
662  }
663 
664  if (hUserToken)
665  {
667  hUserToken = NULL;
668  }
669 
671  {
672  DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
673  goto cleanup;
674  }
675 
676  /* Trigger the installer thread */
677  if (hInstallEvent)
679 
681 
682 cleanup:
683  if (hProcess)
685 
686  return ReturnValue;
687 }
688 
689 
690 /* Function 6 */
691 DWORD
692 WINAPI
695  LPWSTR pDeviceID,
696  DWORD ulFlags)
697 {
699  HKEY hDeviceKey = NULL;
700 
702  UNREFERENCED_PARAMETER(ulFlags);
703 
704  DPRINT("PNP_ValidateDeviceInstance(%p %S 0x%08lx)\n",
705  hBinding, pDeviceID, ulFlags);
706 
707  if (!IsValidDeviceInstanceID(pDeviceID))
708  return CR_INVALID_DEVINST;
709 
711  pDeviceID,
712  0,
713  KEY_READ,
714  &hDeviceKey))
715  {
716  DPRINT("Could not open the Device Key!\n");
718  goto Done;
719  }
720 
721  /* FIXME: add more tests */
722 
723 Done:
724  if (hDeviceKey != NULL)
725  RegCloseKey(hDeviceKey);
726 
727  DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret);
728 
729  return ret;
730 }
731 
732 
733 /* Function 7 */
734 DWORD
735 WINAPI
738  LPWSTR pDeviceID,
739  PNP_RPC_STRING_LEN ulLength)
740 {
742 
744 
745  DPRINT("PNP_GetRootDeviceInstance(%p %S %lu)\n",
746  hBinding, pDeviceID, ulLength);
747 
748  if (!pDeviceID)
749  {
751  goto Done;
752  }
753 
754  if (ulLength < lstrlenW(szRootDeviceInstanceID) + 1)
755  {
757  goto Done;
758  }
759 
760  lstrcpyW(pDeviceID,
762 
763 Done:
764  DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret);
765 
766  return ret;
767 }
768 
769 
770 /* Function 8 */
771 DWORD
772 WINAPI
775  DWORD ulRelationship,
776  LPWSTR pDeviceID,
777  LPWSTR pRelatedDeviceId,
778  PNP_RPC_STRING_LEN *pulLength,
779  DWORD ulFlags)
780 {
784 
786  UNREFERENCED_PARAMETER(ulFlags);
787 
788  DPRINT("PNP_GetRelatedDeviceInstance(%p %lu %S %p %p 0x%lx)\n",
789  hBinding, ulRelationship, pDeviceID, pRelatedDeviceId,
790  pulLength, ulFlags);
791 
792  if (!IsValidDeviceInstanceID(pDeviceID))
793  return CR_INVALID_DEVINST;
794 
795  if (ulRelationship == PNP_GET_PARENT_DEVICE_INSTANCE)
796  {
797  /* The root device does not have a parent */
798  if (IsRootDeviceInstanceID(pDeviceID))
799  return CR_NO_SUCH_DEVINST;
800 
801  /* Return the root device for non existing devices */
802  if (!IsPresentDeviceInstanceID(pDeviceID))
803  {
804  if ((wcslen(szRootDeviceInstanceID) + 1) > *pulLength)
805  {
806  *pulLength = wcslen(szRootDeviceInstanceID) + 1;
807  return CR_BUFFER_SMALL;
808  }
809 
810  wcscpy(pRelatedDeviceId, szRootDeviceInstanceID);
811  *pulLength = wcslen(szRootDeviceInstanceID) + 1;
812  return CR_SUCCESS;
813  }
814  }
815  else if (ulRelationship == PNP_GET_SIBLING_DEVICE_INSTANCE)
816  {
817  /* The root device does not have siblings */
818  if (IsRootDeviceInstanceID(pDeviceID))
819  return CR_NO_SUCH_DEVINST;
820  }
821 
823  pDeviceID);
824 
825  PlugPlayData.Relation = ulRelationship;
826 
827  PlugPlayData.RelatedDeviceInstanceLength = *pulLength;
828  PlugPlayData.RelatedDeviceInstance = pRelatedDeviceId;
829 
831  (PVOID)&PlugPlayData,
833  if (!NT_SUCCESS(Status))
834  {
836  }
837 
838  DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret);
839  if (ret == CR_SUCCESS)
840  {
841  DPRINT("RelatedDevice: %wZ\n", &PlugPlayData.RelatedDeviceInstance);
842  }
843 
844  return ret;
845 }
846 
847 
848 /* Function 9 */
849 DWORD
850 WINAPI
853  DWORD ulBranch,
854  DWORD ulIndex,
855  LPWSTR Buffer,
856  PNP_RPC_STRING_LEN ulLength,
857  PNP_RPC_STRING_LEN *pulRequiredLen,
858  DWORD ulFlags)
859 {
861  HKEY hKey;
862  DWORD dwError;
863 
865  UNREFERENCED_PARAMETER(ulFlags);
866 
867  DPRINT("PNP_EnumerateSubKeys(%p %lu %lu %p %lu %p 0x%08lx)\n",
868  hBinding, ulBranch, ulIndex, Buffer, ulLength,
869  pulRequiredLen, ulFlags);
870 
871  switch (ulBranch)
872  {
873  case PNP_ENUMERATOR_SUBKEYS:
874  hKey = hEnumKey;
875  break;
876 
877  case PNP_CLASS_SUBKEYS:
878  hKey = hClassKey;
879  break;
880 
881  default:
882  return CR_FAILURE;
883  }
884 
885  *pulRequiredLen = ulLength;
886  dwError = RegEnumKeyExW(hKey,
887  ulIndex,
888  Buffer,
889  pulRequiredLen,
890  NULL,
891  NULL,
892  NULL,
893  NULL);
894  if (dwError != ERROR_SUCCESS)
895  {
897  }
898  else
899  {
900  (*pulRequiredLen)++;
901  }
902 
903  DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
904 
905  return ret;
906 }
907 
908 
909 static
910 CONFIGRET
912  _In_ PWSTR pszDevice,
913  _In_ DWORD ulFlags,
914  _Inout_ PWSTR pszBuffer,
915  _Inout_ PDWORD pulLength)
916 {
920 
921  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
922  pszDevice);
923 
924  if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS)
925  {
926  PlugPlayData.Relations = 3;
927  }
928  else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS)
929  {
930  PlugPlayData.Relations = 2;
931  }
932  else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS)
933  {
934  PlugPlayData.Relations = 1;
935  }
936  else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS)
937  {
938  PlugPlayData.Relations = 0;
939  }
940 
941  PlugPlayData.BufferSize = *pulLength * sizeof(WCHAR);
942  PlugPlayData.Buffer = pszBuffer;
943 
945  (PVOID)&PlugPlayData,
947  if (NT_SUCCESS(Status))
948  {
949  *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR);
950  }
951  else
952  {
954  }
955 
956  return ret;
957 }
958 
959 
960 static
961 CONFIGRET
963  _In_ PWSTR pszService,
964  _Inout_ PWSTR pszBuffer,
965  _Inout_ PDWORD pulLength)
966 {
967  WCHAR szPathBuffer[512];
968  WCHAR szName[16];
969  HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL;
970  DWORD dwValues, dwSize, dwIndex, dwUsedLength, dwPathLength;
971  DWORD dwError;
972  PWSTR pPtr;
974 
975  /* Open the device key */
977  L"System\\CurrentControlSet\\Services",
978  0,
979  KEY_READ,
980  &hServicesKey);
981  if (dwError != ERROR_SUCCESS)
982  {
983  DPRINT("Failed to open the services key (Error %lu)\n", dwError);
984  return CR_REGISTRY_ERROR;
985  }
986 
987  dwError = RegOpenKeyExW(hServicesKey,
988  pszService,
989  0,
990  KEY_READ,
991  &hServiceKey);
992  if (dwError != ERROR_SUCCESS)
993  {
994  DPRINT("Failed to open the service key (Error %lu)\n", dwError);
996  goto Done;
997  }
998 
999  dwError = RegOpenKeyExW(hServiceKey,
1000  L"Enum",
1001  0,
1002  KEY_READ,
1003  &hEnumKey);
1004  if (dwError != ERROR_SUCCESS)
1005  {
1006  DPRINT("Failed to open the service enum key (Error %lu)\n", dwError);
1008  goto Done;
1009  }
1010 
1011  /* Retrieve the number of device instances */
1012  dwSize = sizeof(DWORD);
1013  dwError = RegQueryValueExW(hEnumKey,
1014  L"Count",
1015  NULL,
1016  NULL,
1017  (LPBYTE)&dwValues,
1018  &dwSize);
1019  if (dwError != ERROR_SUCCESS)
1020  {
1021  DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError);
1022  dwValues = 1;
1023  }
1024 
1025  DPRINT("dwValues %lu\n", dwValues);
1026 
1027  dwUsedLength = 0;
1028  pPtr = pszBuffer;
1029 
1030  for (dwIndex = 0; dwIndex < dwValues; dwIndex++)
1031  {
1032  wsprintf(szName, L"%lu", dwIndex);
1033 
1034  dwSize = sizeof(szPathBuffer);
1035  dwError = RegQueryValueExW(hEnumKey,
1036  szName,
1037  NULL,
1038  NULL,
1039  (LPBYTE)szPathBuffer,
1040  &dwSize);
1041  if (dwError != ERROR_SUCCESS)
1042  break;
1043 
1044  DPRINT("Path: %S\n", szPathBuffer);
1045 
1046  dwPathLength = wcslen(szPathBuffer) + 1;
1047  if (dwUsedLength + dwPathLength + 1 > *pulLength)
1048  {
1049  ret = CR_BUFFER_SMALL;
1050  break;
1051  }
1052 
1053  wcscpy(pPtr, szPathBuffer);
1054  dwUsedLength += dwPathLength;
1055  pPtr += dwPathLength;
1056 
1057  *pPtr = UNICODE_NULL;
1058  }
1059 
1060 Done:
1061  if (hEnumKey != NULL)
1063 
1064  if (hServiceKey != NULL)
1065  RegCloseKey(hServiceKey);
1066 
1067  if (hServicesKey != NULL)
1069 
1070  if (ret == CR_SUCCESS)
1071  *pulLength = dwUsedLength + 1;
1072  else
1073  *pulLength = 0;
1074 
1075  return ret;
1076 }
1077 
1078 
1079 static
1080 CONFIGRET
1082  _In_ PWSTR pszDevice,
1083  _Inout_ PWSTR pszBuffer,
1084  _Inout_ PDWORD pulLength)
1085 {
1086  WCHAR szInstanceBuffer[MAX_DEVICE_ID_LEN];
1087  WCHAR szPathBuffer[512];
1088  HKEY hDeviceKey;
1089  DWORD dwInstanceLength, dwPathLength, dwUsedLength;
1090  DWORD dwIndex, dwError;
1091  PWSTR pPtr;
1093 
1094  /* Open the device key */
1095  dwError = RegOpenKeyExW(hEnumKey,
1096  pszDevice,
1097  0,
1099  &hDeviceKey);
1100  if (dwError != ERROR_SUCCESS)
1101  {
1102  DPRINT("Failed to open the device key (Error %lu)\n", dwError);
1103  return CR_REGISTRY_ERROR;
1104  }
1105 
1106  dwUsedLength = 0;
1107  pPtr = pszBuffer;
1108 
1109  for (dwIndex = 0; ; dwIndex++)
1110  {
1111  dwInstanceLength = MAX_DEVICE_ID_LEN;
1112  dwError = RegEnumKeyExW(hDeviceKey,
1113  dwIndex,
1114  szInstanceBuffer,
1115  &dwInstanceLength,
1116  NULL,
1117  NULL,
1118  NULL,
1119  NULL);
1120  if (dwError != ERROR_SUCCESS)
1121  break;
1122 
1123  wsprintf(szPathBuffer, L"%s\\%s", pszDevice, szInstanceBuffer);
1124  DPRINT("Path: %S\n", szPathBuffer);
1125 
1126  dwPathLength = wcslen(szPathBuffer) + 1;
1127  if (dwUsedLength + dwPathLength + 1 > *pulLength)
1128  {
1129  ret = CR_BUFFER_SMALL;
1130  break;
1131  }
1132 
1133  wcscpy(pPtr, szPathBuffer);
1134  dwUsedLength += dwPathLength;
1135  pPtr += dwPathLength;
1136 
1137  *pPtr = UNICODE_NULL;
1138  }
1139 
1140  RegCloseKey(hDeviceKey);
1141 
1142  if (ret == CR_SUCCESS)
1143  *pulLength = dwUsedLength + 1;
1144  else
1145  *pulLength = 0;
1146 
1147  return ret;
1148 }
1149 
1150 
1151 CONFIGRET
1153  _In_ PWSTR pszEnumerator,
1154  _Inout_ PWSTR pszBuffer,
1155  _Inout_ PDWORD pulLength)
1156 {
1157  WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN];
1158  WCHAR szPathBuffer[512];
1159  HKEY hEnumeratorKey;
1160  PWSTR pPtr;
1161  DWORD dwIndex, dwDeviceLength, dwUsedLength, dwRemainingLength, dwPathLength;
1162  DWORD dwError;
1164 
1165  /* Open the enumerator key */
1166  dwError = RegOpenKeyExW(hEnumKey,
1167  pszEnumerator,
1168  0,
1170  &hEnumeratorKey);
1171  if (dwError != ERROR_SUCCESS)
1172  {
1173  DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError);
1174  return CR_REGISTRY_ERROR;
1175  }
1176 
1177  dwUsedLength = 0;
1178  dwRemainingLength = *pulLength;
1179  pPtr = pszBuffer;
1180 
1181  for (dwIndex = 0; ; dwIndex++)
1182  {
1183  dwDeviceLength = MAX_DEVICE_ID_LEN;
1184  dwError = RegEnumKeyExW(hEnumeratorKey,
1185  dwIndex,
1186  szDeviceBuffer,
1187  &dwDeviceLength,
1188  NULL,
1189  NULL,
1190  NULL,
1191  NULL);
1192  if (dwError != ERROR_SUCCESS)
1193  break;
1194 
1195  wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer);
1196  DPRINT("Path: %S\n", szPathBuffer);
1197 
1198  dwPathLength = dwRemainingLength;
1199  ret = GetDeviceInstanceList(szPathBuffer,
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  RegCloseKey(hEnumeratorKey);
1211 
1212  if (ret == CR_SUCCESS)
1213  *pulLength = dwUsedLength + 1;
1214  else
1215  *pulLength = 0;
1216 
1217  return ret;
1218 }
1219 
1220 
1221 static
1222 CONFIGRET
1224  _Inout_ PWSTR pszBuffer,
1225  _Inout_ PDWORD pulLength)
1226 {
1227  WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN];
1228  PWSTR pPtr;
1229  DWORD dwIndex, dwEnumeratorLength, dwUsedLength, dwRemainingLength, dwPathLength;
1230  DWORD dwError;
1232 
1233  dwUsedLength = 0;
1234  dwRemainingLength = *pulLength;
1235  pPtr = pszBuffer;
1236 
1237  for (dwIndex = 0; ; dwIndex++)
1238  {
1239  dwEnumeratorLength = MAX_DEVICE_ID_LEN;
1240  dwError = RegEnumKeyExW(hEnumKey,
1241  dwIndex,
1242  szEnumeratorBuffer,
1243  &dwEnumeratorLength,
1244  NULL, NULL, NULL, NULL);
1245  if (dwError != ERROR_SUCCESS)
1246  break;
1247 
1248  dwPathLength = dwRemainingLength;
1249  ret = GetEnumeratorInstanceList(szEnumeratorBuffer,
1250  pPtr,
1251  &dwPathLength);
1252  if (ret != CR_SUCCESS)
1253  break;
1254 
1255  dwUsedLength += dwPathLength - 1;
1256  dwRemainingLength -= dwPathLength - 1;
1257  pPtr += dwPathLength - 1;
1258  }
1259 
1260  if (ret == CR_SUCCESS)
1261  *pulLength = dwUsedLength + 1;
1262  else
1263  *pulLength = 0;
1264 
1265  return ret;
1266 }
1267 
1268 
1269 /* Function 10 */
1270 DWORD
1271 WINAPI
1274  LPWSTR pszFilter,
1275  LPWSTR Buffer,
1276  PNP_RPC_STRING_LEN *pulLength,
1277  DWORD ulFlags)
1278 {
1279  WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
1280  WCHAR szDevice[MAX_DEVICE_ID_LEN];
1281  WCHAR szInstance[MAX_DEVICE_ID_LEN];
1283 
1284  DPRINT("PNP_GetDeviceList(%p %S %p %p 0x%08lx)\n",
1285  hBinding, pszFilter, Buffer, pulLength, ulFlags);
1286 
1287  if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
1288  return CR_INVALID_FLAG;
1289 
1290  if (pulLength == NULL)
1291  return CR_INVALID_POINTER;
1292 
1293  if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
1294  (pszFilter == NULL))
1295  return CR_INVALID_POINTER;
1296 
1297  if (ulFlags &
1302  {
1303  ret = GetRelationsInstanceList(pszFilter,
1304  ulFlags,
1305  Buffer,
1306  pulLength);
1307  }
1308  else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
1309  {
1310  ret = GetServiceInstanceList(pszFilter,
1311  Buffer,
1312  pulLength);
1313  }
1314  else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
1315  {
1316  SplitDeviceInstanceID(pszFilter,
1317  szEnumerator,
1318  szDevice,
1319  szInstance);
1320 
1321  if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
1322  {
1323  ret = GetDeviceInstanceList(pszFilter,
1324  Buffer,
1325  pulLength);
1326  }
1327  else
1328  {
1329  ret = GetEnumeratorInstanceList(pszFilter,
1330  Buffer,
1331  pulLength);
1332  }
1333  }
1334  else /* CM_GETIDLIST_FILTER_NONE */
1335  {
1337  pulLength);
1338  }
1339 
1340  return ret;
1341 }
1342 
1343 
1344 static
1345 CONFIGRET
1347  _In_ PWSTR pszDevice,
1348  _In_ DWORD ulFlags,
1349  _Inout_ PDWORD pulLength)
1350 {
1352  NTSTATUS Status;
1354 
1355  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
1356  pszDevice);
1357 
1358  if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS)
1359  {
1360  PlugPlayData.Relations = 3;
1361  }
1362  else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS)
1363  {
1364  PlugPlayData.Relations = 2;
1365  }
1366  else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS)
1367  {
1368  PlugPlayData.Relations = 1;
1369  }
1370  else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS)
1371  {
1372  PlugPlayData.Relations = 0;
1373  }
1374 
1375  PlugPlayData.BufferSize = 0;
1376  PlugPlayData.Buffer = NULL;
1377 
1379  (PVOID)&PlugPlayData,
1381  if (NT_SUCCESS(Status))
1382  {
1383  *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR);
1384  }
1385  else
1386  {
1388  }
1389 
1390  return ret;
1391 }
1392 
1393 
1394 static
1395 CONFIGRET
1397  _In_ PWSTR pszService,
1398  _Out_ PDWORD pulLength)
1399 {
1400  HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL;
1401  DWORD dwValues, dwMaxValueLength, dwSize;
1402  DWORD dwError;
1404 
1405  /* Open the device key */
1407  L"System\\CurrentControlSet\\Services",
1408  0,
1409  KEY_READ,
1410  &hServicesKey);
1411  if (dwError != ERROR_SUCCESS)
1412  {
1413  DPRINT("Failed to open the services key (Error %lu)\n", dwError);
1414  return CR_REGISTRY_ERROR;
1415  }
1416 
1417  dwError = RegOpenKeyExW(hServicesKey,
1418  pszService,
1419  0,
1420  KEY_READ,
1421  &hServiceKey);
1422  if (dwError != ERROR_SUCCESS)
1423  {
1424  DPRINT("Failed to open the service key (Error %lu)\n", dwError);
1426  goto Done;
1427  }
1428 
1429  dwError = RegOpenKeyExW(hServiceKey,
1430  L"Enum",
1431  0,
1432  KEY_READ,
1433  &hEnumKey);
1434  if (dwError != ERROR_SUCCESS)
1435  {
1436  DPRINT("Failed to open the service enum key (Error %lu)\n", dwError);
1438  goto Done;
1439  }
1440 
1441  /* Retrieve the number of device instances */
1442  dwSize = sizeof(DWORD);
1443  dwError = RegQueryValueExW(hEnumKey,
1444  L"Count",
1445  NULL,
1446  NULL,
1447  (LPBYTE)&dwValues,
1448  &dwSize);
1449  if (dwError != ERROR_SUCCESS)
1450  {
1451  DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError);
1452  dwValues = 1;
1453  }
1454 
1455  /* Retrieve the maximum instance name length */
1456  dwError = RegQueryInfoKeyW(hEnumKey,
1457  NULL,
1458  NULL,
1459  NULL,
1460  NULL,
1461  NULL,
1462  NULL,
1463  NULL,
1464  NULL,
1465  &dwMaxValueLength,
1466  NULL,
1467  NULL);
1468  if (dwError != ERROR_SUCCESS)
1469  {
1470  DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
1471  dwMaxValueLength = MAX_DEVICE_ID_LEN;
1472  }
1473 
1474  DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues, dwMaxValueLength / sizeof(WCHAR));
1475 
1476  /* Return the largest possible buffer size */
1477  *pulLength = dwValues * dwMaxValueLength / sizeof(WCHAR) + 2;
1478 
1479 Done:
1480  if (hEnumKey != NULL)
1482 
1483  if (hServiceKey != NULL)
1484  RegCloseKey(hServiceKey);
1485 
1486  if (hServicesKey != NULL)
1488 
1489  return ret;
1490 }
1491 
1492 
1493 static
1494 CONFIGRET
1496  _In_ LPCWSTR pszDevice,
1497  _Out_ PULONG pulLength)
1498 {
1499  HKEY hDeviceKey;
1500  DWORD dwSubKeys, dwMaxSubKeyLength;
1501  DWORD dwError;
1502 
1503  /* Open the device key */
1504  dwError = RegOpenKeyExW(hEnumKey,
1505  pszDevice,
1506  0,
1507  KEY_READ,
1508  &hDeviceKey);
1509  if (dwError != ERROR_SUCCESS)
1510  {
1511  DPRINT("Failed to open the device key (Error %lu)\n", dwError);
1512  return CR_REGISTRY_ERROR;
1513  }
1514 
1515  /* Retrieve the number of device instances and the maximum name length */
1516  dwError = RegQueryInfoKeyW(hDeviceKey,
1517  NULL,
1518  NULL,
1519  NULL,
1520  &dwSubKeys,
1521  &dwMaxSubKeyLength,
1522  NULL,
1523  NULL,
1524  NULL,
1525  NULL,
1526  NULL,
1527  NULL);
1528  if (dwError != ERROR_SUCCESS)
1529  {
1530  DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
1531  dwSubKeys = 0;
1532  dwMaxSubKeyLength = 0;
1533  }
1534 
1535  /* Close the device key */
1536  RegCloseKey(hDeviceKey);
1537 
1538  /* Return the largest possible buffer size */
1539  *pulLength = dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1);
1540 
1541  return CR_SUCCESS;
1542 }
1543 
1544 
1545 static
1546 CONFIGRET
1548  _In_ LPCWSTR pszEnumerator,
1549  _Out_ PULONG pulLength)
1550 {
1551  WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN];
1552  WCHAR szPathBuffer[512];
1553  HKEY hEnumeratorKey;
1554  DWORD dwIndex, dwDeviceLength, dwBufferLength;
1555  DWORD dwError;
1557 
1558  *pulLength = 0;
1559 
1560  /* Open the enumerator key */
1561  dwError = RegOpenKeyExW(hEnumKey,
1562  pszEnumerator,
1563  0,
1565  &hEnumeratorKey);
1566  if (dwError != ERROR_SUCCESS)
1567  {
1568  DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError);
1569  return CR_REGISTRY_ERROR;
1570  }
1571 
1572  for (dwIndex = 0; ; dwIndex++)
1573  {
1574  dwDeviceLength = MAX_DEVICE_ID_LEN;
1575  dwError = RegEnumKeyExW(hEnumeratorKey,
1576  dwIndex,
1577  szDeviceBuffer,
1578  &dwDeviceLength,
1579  NULL,
1580  NULL,
1581  NULL,
1582  NULL);
1583  if (dwError != ERROR_SUCCESS)
1584  break;
1585 
1586  wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer);
1587  DPRINT("Path: %S\n", szPathBuffer);
1588 
1589  ret = GetDeviceInstanceListSize(szPathBuffer, &dwBufferLength);
1590  if (ret != CR_SUCCESS)
1591  {
1592  *pulLength = 0;
1593  break;
1594  }
1595 
1596  *pulLength += dwBufferLength;
1597  }
1598 
1599  /* Close the enumerator key */
1600  RegCloseKey(hEnumeratorKey);
1601 
1602  return ret;
1603 }
1604 
1605 
1606 static
1607 CONFIGRET
1609  _Out_ PULONG pulLength)
1610 {
1611  WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN];
1612  DWORD dwIndex, dwEnumeratorLength, dwBufferLength;
1613  DWORD dwError;
1615 
1616  for (dwIndex = 0; ; dwIndex++)
1617  {
1618  dwEnumeratorLength = MAX_DEVICE_ID_LEN;
1619  dwError = RegEnumKeyExW(hEnumKey,
1620  dwIndex,
1621  szEnumeratorBuffer,
1622  &dwEnumeratorLength,
1623  NULL, NULL, NULL, NULL);
1624  if (dwError != ERROR_SUCCESS)
1625  break;
1626 
1627  /* Get the size of all device instances for the enumerator */
1628  ret = GetEnumeratorInstanceListSize(szEnumeratorBuffer,
1629  &dwBufferLength);
1630  if (ret != CR_SUCCESS)
1631  break;
1632 
1633  *pulLength += dwBufferLength;
1634  }
1635 
1636  return ret;
1637 }
1638 
1639 
1640 /* Function 11 */
1641 DWORD
1642 WINAPI
1645  LPWSTR pszFilter,
1646  PNP_RPC_BUFFER_SIZE *pulLength,
1647  DWORD ulFlags)
1648 {
1649  WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
1650  WCHAR szDevice[MAX_DEVICE_ID_LEN];
1651  WCHAR szInstance[MAX_DEVICE_ID_LEN];
1653 
1654  DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%08lx)\n",
1655  hBinding, pszFilter, pulLength, ulFlags);
1656 
1657  if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
1658  return CR_INVALID_FLAG;
1659 
1660  if (pulLength == NULL)
1661  return CR_INVALID_POINTER;
1662 
1663  if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
1664  (pszFilter == NULL))
1665  return CR_INVALID_POINTER;
1666 
1667  *pulLength = 0;
1668 
1669  if (ulFlags &
1674  {
1675  ret = GetRelationsInstanceListSize(pszFilter,
1676  ulFlags,
1677  pulLength);
1678  }
1679  else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
1680  {
1681  ret = GetServiceInstanceListSize(pszFilter,
1682  pulLength);
1683  }
1684  else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
1685  {
1686  SplitDeviceInstanceID(pszFilter,
1687  szEnumerator,
1688  szDevice,
1689  szInstance);
1690 
1691  if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
1692  {
1693  ret = GetDeviceInstanceListSize(pszFilter,
1694  pulLength);
1695  }
1696  else
1697  {
1698  ret = GetEnumeratorInstanceListSize(pszFilter,
1699  pulLength);
1700  }
1701  }
1702  else /* CM_GETIDLIST_FILTER_NONE */
1703  {
1704  ret = GetAllInstanceListSize(pulLength);
1705  }
1706 
1707  /* Add one character for the terminating double UNICODE_NULL */
1708  if (ret == CR_SUCCESS)
1709  (*pulLength) += 1;
1710 
1711  return ret;
1712 }
1713 
1714 
1715 /* Function 12 */
1716 DWORD
1717 WINAPI
1720  LPWSTR pszDeviceID,
1721  DWORD *pulDepth,
1722  DWORD ulFlags)
1723 {
1724  PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData;
1726  NTSTATUS Status;
1727 
1729  UNREFERENCED_PARAMETER(ulFlags);
1730 
1731  DPRINT("PNP_GetDepth(%p %S %p 0x%08lx)\n",
1732  hBinding, pszDeviceID, pulDepth, ulFlags);
1733 
1734  if (!IsValidDeviceInstanceID(pszDeviceID))
1735  return CR_INVALID_DEVINST;
1736 
1737  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
1738  pszDeviceID);
1739 
1741  (PVOID)&PlugPlayData,
1742  sizeof(PLUGPLAY_CONTROL_DEPTH_DATA));
1743  if (NT_SUCCESS(Status))
1744  {
1745  *pulDepth = PlugPlayData.Depth;
1746  }
1747  else
1748  {
1750  }
1751 
1752  DPRINT("PNP_GetDepth() done (returns %lx)\n", ret);
1753 
1754  return ret;
1755 }
1756 
1757 
1758 /* Function 13 */
1759 DWORD
1760 WINAPI
1763  LPWSTR pDeviceID,
1764  DWORD ulProperty,
1765  DWORD *pulRegDataType,
1766  BYTE *Buffer,
1767  PNP_PROP_SIZE *pulTransferLen,
1768  PNP_PROP_SIZE *pulLength,
1769  DWORD ulFlags)
1770 {
1771  PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData;
1773  LPWSTR lpValueName = NULL;
1774  HKEY hKey = NULL;
1775  LONG lError;
1776  NTSTATUS Status;
1777 
1779 
1780  DPRINT("PNP_GetDeviceRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
1781  hBinding, pDeviceID, ulProperty, pulRegDataType, Buffer,
1782  pulTransferLen, pulLength, ulFlags);
1783 
1784  if (pulTransferLen == NULL || pulLength == NULL)
1785  {
1787  goto done;
1788  }
1789 
1790  if (ulFlags != 0)
1791  {
1792  ret = CR_INVALID_FLAG;
1793  goto done;
1794  }
1795 
1796  /* Check pDeviceID */
1797  if (!IsValidDeviceInstanceID(pDeviceID))
1798  {
1800  goto done;
1801  }
1802 
1803  if (*pulLength < *pulTransferLen)
1804  *pulLength = *pulTransferLen;
1805 
1806  *pulTransferLen = 0;
1807 
1808  switch (ulProperty)
1809  {
1810  case CM_DRP_DEVICEDESC:
1811  lpValueName = L"DeviceDesc";
1812  break;
1813 
1814  case CM_DRP_HARDWAREID:
1815  lpValueName = L"HardwareID";
1816  break;
1817 
1818  case CM_DRP_COMPATIBLEIDS:
1819  lpValueName = L"CompatibleIDs";
1820  break;
1821 
1822  case CM_DRP_SERVICE:
1823  lpValueName = L"Service";
1824  break;
1825 
1826  case CM_DRP_CLASS:
1827  lpValueName = L"Class";
1828  break;
1829 
1830  case CM_DRP_CLASSGUID:
1831  lpValueName = L"ClassGUID";
1832  break;
1833 
1834  case CM_DRP_DRIVER:
1835  lpValueName = L"Driver";
1836  break;
1837 
1838  case CM_DRP_CONFIGFLAGS:
1839  lpValueName = L"ConfigFlags";
1840  break;
1841 
1842  case CM_DRP_MFG:
1843  lpValueName = L"Mfg";
1844  break;
1845 
1846  case CM_DRP_FRIENDLYNAME:
1847  lpValueName = L"FriendlyName";
1848  break;
1849 
1851  lpValueName = L"LocationInformation";
1852  break;
1853 
1856  *pulRegDataType = REG_SZ;
1857  break;
1858 
1859  case CM_DRP_CAPABILITIES:
1860  lpValueName = L"Capabilities";
1861  break;
1862 
1863  case CM_DRP_UI_NUMBER:
1864  PlugPlayData.Property = PNP_PROPERTY_UI_NUMBER;
1865  break;
1866 
1867  case CM_DRP_UPPERFILTERS:
1868  lpValueName = L"UpperFilters";
1869  break;
1870 
1871  case CM_DRP_LOWERFILTERS:
1872  lpValueName = L"LowerFilters";
1873  break;
1874 
1875  case CM_DRP_BUSTYPEGUID:
1876  PlugPlayData.Property = PNP_PROPERTY_BUSTYPEGUID;
1877  *pulRegDataType = REG_BINARY;
1878  break;
1879 
1880  case CM_DRP_LEGACYBUSTYPE:
1881  PlugPlayData.Property = PNP_PROPERTY_LEGACYBUSTYPE;
1882  *pulRegDataType = REG_DWORD;
1883  break;
1884 
1885  case CM_DRP_BUSNUMBER:
1886  PlugPlayData.Property = PNP_PROPERTY_BUSNUMBER;
1887  *pulRegDataType = REG_DWORD;
1888  break;
1889 
1891  PlugPlayData.Property = PNP_PROPERTY_ENUMERATOR_NAME;
1892  *pulRegDataType = REG_SZ;
1893  break;
1894 
1895  case CM_DRP_SECURITY:
1896  lpValueName = L"Security";
1897  break;
1898 
1899  case CM_DRP_DEVTYPE:
1900  lpValueName = L"DeviceType";
1901  break;
1902 
1903  case CM_DRP_EXCLUSIVE:
1904  lpValueName = L"Exclusive";
1905  break;
1906 
1908  lpValueName = L"DeviceCharacteristics";
1909  break;
1910 
1911  case CM_DRP_ADDRESS:
1912  PlugPlayData.Property = PNP_PROPERTY_ADDRESS;
1913  *pulRegDataType = REG_DWORD;
1914  break;
1915 
1917  lpValueName = L"UINumberDescFormat";
1918  break;
1919 
1921  PlugPlayData.Property = PNP_PROPERTY_POWER_DATA;
1922  *pulRegDataType = REG_BINARY;
1923  break;
1924 
1925  case CM_DRP_REMOVAL_POLICY:
1926  PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY;
1927  *pulRegDataType = REG_DWORD;
1928  break;
1929 
1932  *pulRegDataType = REG_DWORD;
1933  break;
1934 
1936  lpValueName = L"RemovalPolicy";
1937  *pulRegDataType = REG_DWORD;
1938  break;
1939 
1940  case CM_DRP_INSTALL_STATE:
1941  PlugPlayData.Property = PNP_PROPERTY_INSTALL_STATE;
1942  *pulRegDataType = REG_DWORD;
1943  break;
1944 
1945 #if (WINVER >= _WIN32_WINNT_WS03)
1946  case CM_DRP_LOCATION_PATHS:
1947  PlugPlayData.Property = PNP_PROPERTY_LOCATION_PATHS;
1948  *pulRegDataType = REG_MULTI_SZ;
1949  break;
1950 #endif
1951 
1952 #if (WINVER >= _WIN32_WINNT_WIN7)
1954  PlugPlayData.Property = PNP_PROPERTY_CONTAINERID;
1955  *pulRegDataType = REG_SZ;
1956  break;
1957 #endif
1958 
1959  default:
1961  goto done;
1962  }
1963 
1964  DPRINT("Value name: %S\n", lpValueName);
1965 
1966  if (lpValueName)
1967  {
1968  /* Retrieve information from the Registry */
1969  lError = RegOpenKeyExW(hEnumKey,
1970  pDeviceID,
1971  0,
1973  &hKey);
1974  if (lError != ERROR_SUCCESS)
1975  {
1976  hKey = NULL;
1977  *pulLength = 0;
1979  goto done;
1980  }
1981 
1982  lError = RegQueryValueExW(hKey,
1983  lpValueName,
1984  NULL,
1985  pulRegDataType,
1986  Buffer,
1987  pulLength);
1988  if (lError != ERROR_SUCCESS)
1989  {
1990  if (lError == ERROR_MORE_DATA)
1991  {
1992  ret = CR_BUFFER_SMALL;
1993  }
1994  else
1995  {
1996  *pulLength = 0;
1998  }
1999  }
2000  }
2001  else
2002  {
2003  /* Retrieve information from the Device Node */
2004  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
2005  pDeviceID);
2006  PlugPlayData.Buffer = Buffer;
2007  PlugPlayData.BufferSize = *pulLength;
2008 
2010  (PVOID)&PlugPlayData,
2012  if (NT_SUCCESS(Status))
2013  {
2014  *pulLength = PlugPlayData.BufferSize;
2015  }
2016  else
2017  {
2019  }
2020  }
2021 
2022 done:
2023  if (pulTransferLen)
2024  *pulTransferLen = (ret == CR_SUCCESS) ? *pulLength : 0;
2025 
2026  if (hKey != NULL)
2027  RegCloseKey(hKey);
2028 
2029  DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret);
2030 
2031  return ret;
2032 }
2033 
2034 
2035 /* Function 14 */
2036 DWORD
2037 WINAPI
2040  LPWSTR pDeviceId,
2041  DWORD ulProperty,
2042  DWORD ulDataType,
2043  BYTE *Buffer,
2044  PNP_PROP_SIZE ulLength,
2045  DWORD ulFlags)
2046 {
2048  LPWSTR lpValueName = NULL;
2049  HKEY hKey = 0;
2050 
2052  UNREFERENCED_PARAMETER(ulFlags);
2053 
2054  DPRINT("PNP_SetDeviceRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
2055  hBinding, pDeviceId, ulProperty, ulDataType, Buffer,
2056  ulLength, ulFlags);
2057 
2058  if (!IsValidDeviceInstanceID(pDeviceId))
2059  return CR_INVALID_DEVINST;
2060 
2061  switch (ulProperty)
2062  {
2063  case CM_DRP_DEVICEDESC:
2064  lpValueName = L"DeviceDesc";
2065  break;
2066 
2067  case CM_DRP_HARDWAREID:
2068  lpValueName = L"HardwareID";
2069  break;
2070 
2071  case CM_DRP_COMPATIBLEIDS:
2072  lpValueName = L"CompatibleIDs";
2073  break;
2074 
2075  case CM_DRP_SERVICE:
2076  lpValueName = L"Service";
2077  break;
2078 
2079  case CM_DRP_CLASS:
2080  lpValueName = L"Class";
2081  break;
2082 
2083  case CM_DRP_CLASSGUID:
2084  lpValueName = L"ClassGUID";
2085  break;
2086 
2087  case CM_DRP_DRIVER:
2088  lpValueName = L"Driver";
2089  break;
2090 
2091  case CM_DRP_CONFIGFLAGS:
2092  lpValueName = L"ConfigFlags";
2093  break;
2094 
2095  case CM_DRP_MFG:
2096  lpValueName = L"Mfg";
2097  break;
2098 
2099  case CM_DRP_FRIENDLYNAME:
2100  lpValueName = L"FriendlyName";
2101  break;
2102 
2104  lpValueName = L"LocationInformation";
2105  break;
2106 
2107  case CM_DRP_UPPERFILTERS:
2108  lpValueName = L"UpperFilters";
2109  break;
2110 
2111  case CM_DRP_LOWERFILTERS:
2112  lpValueName = L"LowerFilters";
2113  break;
2114 
2115  case CM_DRP_SECURITY:
2116  lpValueName = L"Security";
2117  break;
2118 
2119  case CM_DRP_DEVTYPE:
2120  lpValueName = L"DeviceType";
2121  break;
2122 
2123  case CM_DRP_EXCLUSIVE:
2124  lpValueName = L"Exclusive";
2125  break;
2126 
2128  lpValueName = L"DeviceCharacteristics";
2129  break;
2130 
2132  lpValueName = L"UINumberDescFormat";
2133  break;
2134 
2136  lpValueName = L"RemovalPolicy";
2137  break;
2138 
2139  default:
2140  return CR_INVALID_PROPERTY;
2141  }
2142 
2143  DPRINT("Value name: %S\n", lpValueName);
2144 
2145  if (RegOpenKeyExW(hEnumKey,
2146  pDeviceId,
2147  0,
2148  KEY_SET_VALUE,
2149  &hKey))
2150  return CR_INVALID_DEVNODE;
2151 
2152  if (ulLength == 0)
2153  {
2154  if (RegDeleteValueW(hKey,
2155  lpValueName))
2157  }
2158  else
2159  {
2160  if (RegSetValueExW(hKey,
2161  lpValueName,
2162  0,
2163  ulDataType,
2164  Buffer,
2165  ulLength))
2167  }
2168 
2169  RegCloseKey(hKey);
2170 
2171  DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret);
2172 
2173  return ret;
2174 }
2175 
2176 
2177 /* Function 15 */
2178 DWORD
2179 WINAPI
2182  LPWSTR pDeviceId,
2183  LPWSTR pszClassInstance,
2184  PNP_RPC_STRING_LEN ulLength)
2185 {
2186  WCHAR szClassGuid[40];
2187  WCHAR szClassInstance[5];
2188  HKEY hDeviceClassKey = NULL;
2189  HKEY hClassInstanceKey;
2190  ULONG ulTransferLength, ulDataLength;
2191  DWORD dwDataType, dwDisposition, i;
2192  DWORD dwError;
2194 
2195  DPRINT("PNP_GetClassInstance(%p %S %p %lu)\n",
2196  hBinding, pDeviceId, pszClassInstance, ulLength);
2197 
2198  if (!IsValidDeviceInstanceID(pDeviceId))
2199  return CR_INVALID_DEVINST;
2200 
2201  ulTransferLength = ulLength;
2203  pDeviceId,
2204  CM_DRP_DRIVER,
2205  &dwDataType,
2206  (BYTE *)pszClassInstance,
2207  &ulTransferLength,
2208  &ulLength,
2209  0);
2210  if (ret == CR_SUCCESS)
2211  return ret;
2212 
2213  ulTransferLength = sizeof(szClassGuid);
2214  ulDataLength = sizeof(szClassGuid);
2216  pDeviceId,
2218  &dwDataType,
2219  (BYTE *)szClassGuid,
2220  &ulTransferLength,
2221  &ulDataLength,
2222  0);
2223  if (ret != CR_SUCCESS)
2224  {
2225  DPRINT1("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret);
2226  goto done;
2227  }
2228 
2229  dwError = RegOpenKeyExW(hClassKey,
2230  szClassGuid,
2231  0,
2232  KEY_READ,
2233  &hDeviceClassKey);
2234  if (dwError != ERROR_SUCCESS)
2235  {
2236  DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError);
2237  ret = CR_FAILURE;
2238  goto done;
2239  }
2240 
2241  for (i = 0; i < 10000; i++)
2242  {
2243  wsprintf(szClassInstance, L"%04lu", i);
2244 
2245  dwError = RegCreateKeyExW(hDeviceClassKey,
2246  szClassInstance,
2247  0,
2248  NULL,
2251  NULL,
2252  &hClassInstanceKey,
2253  &dwDisposition);
2254  if (dwError == ERROR_SUCCESS)
2255  {
2256  RegCloseKey(hClassInstanceKey);
2257 
2258  if (dwDisposition == REG_CREATED_NEW_KEY)
2259  {
2260  wsprintf(pszClassInstance,
2261  L"%s\\%s",
2262  szClassGuid,
2263  szClassInstance);
2264 
2265  ulDataLength = (wcslen(pszClassInstance) + 1) * sizeof(WCHAR);
2267  pDeviceId,
2268  CM_DRP_DRIVER,
2269  REG_SZ,
2270  (BYTE *)pszClassInstance,
2271  ulDataLength,
2272  0);
2273  if (ret != CR_SUCCESS)
2274  {
2275  DPRINT1("PNP_SetDeviceRegProp() failed (Error %lu)\n", ret);
2276  RegDeleteKeyW(hDeviceClassKey,
2277  szClassInstance);
2278  }
2279 
2280  break;
2281  }
2282  }
2283  }
2284 
2285 done:
2286  if (hDeviceClassKey != NULL)
2287  RegCloseKey(hDeviceClassKey);
2288 
2289  return ret;
2290 }
2291 
2292 
2293 /* Function 16 */
2294 DWORD
2295 WINAPI
2298  LPWSTR pszSubKey,
2299  DWORD samDesired,
2300  DWORD ulFlags)
2301 {
2302  HKEY hDeviceKey = NULL, hParametersKey = NULL;
2303  DWORD dwError;
2305 
2307  UNREFERENCED_PARAMETER(samDesired);
2308 
2309  DPRINT("PNP_CreateKey(%p %S 0x%lx 0x%08lx)\n",
2310  hBinding, pszSubKey, samDesired, ulFlags);
2311 
2312  if (ulFlags != 0)
2313  return CR_INVALID_FLAG;
2314 
2315  if (!IsValidDeviceInstanceID(pszSubKey))
2316  return CR_INVALID_DEVINST;
2317 
2318  dwError = RegOpenKeyExW(hEnumKey,
2319  pszSubKey,
2320  0,
2321  KEY_WRITE,
2322  &hDeviceKey);
2323  if (dwError != ERROR_SUCCESS)
2324  {
2326  goto done;
2327  }
2328 
2329  dwError = RegCreateKeyExW(hDeviceKey,
2330  L"Device Parameters",
2331  0,
2332  NULL,
2335  NULL,
2336  &hParametersKey,
2337  NULL);
2338  if (dwError != ERROR_SUCCESS)
2339  {
2341  goto done;
2342  }
2343 
2344  /* FIXME: Set key security */
2345 
2346 done:
2347  if (hParametersKey != NULL)
2348  RegCloseKey(hParametersKey);
2349 
2350  if (hDeviceKey != NULL)
2351  RegCloseKey(hDeviceKey);
2352 
2353  return ret;
2354 }
2355 
2356 
2357 /* Function 17 */
2358 DWORD
2359 WINAPI
2362  LPWSTR pszDeviceID,
2363  LPWSTR pszParentKey,
2364  LPWSTR pszChildKey,
2365  DWORD ulFlags)
2366 {
2367  UNIMPLEMENTED;
2368  return CR_CALL_NOT_IMPLEMENTED;
2369 }
2370 
2371 
2372 /* Function 18 */
2373 DWORD
2374 WINAPI
2377  DWORD *pulClassCount,
2378  DWORD ulFlags)
2379 {
2380  HKEY hKey;
2381  DWORD dwError;
2382 
2384  UNREFERENCED_PARAMETER(ulFlags);
2385 
2386  DPRINT("PNP_GetClassCount(%p %p 0x%08lx)\n",
2387  hBinding, pulClassCount, ulFlags);
2388 
2391  0,
2393  &hKey);
2394  if (dwError != ERROR_SUCCESS)
2395  return CR_INVALID_DATA;
2396 
2397  dwError = RegQueryInfoKeyW(hKey,
2398  NULL,
2399  NULL,
2400  NULL,
2401  pulClassCount,
2402  NULL,
2403  NULL,
2404  NULL,
2405  NULL,
2406  NULL,
2407  NULL,
2408  NULL);
2409  RegCloseKey(hKey);
2410  if (dwError != ERROR_SUCCESS)
2411  return CR_INVALID_DATA;
2412 
2413  return CR_SUCCESS;
2414 }
2415 
2416 
2417 /* Function 19 */
2418 DWORD
2419 WINAPI
2422  LPWSTR pszClassGuid,
2423  LPWSTR Buffer,
2424  PNP_RPC_STRING_LEN *pulLength,
2425  DWORD ulFlags)
2426 {
2427  WCHAR szKeyName[MAX_PATH];
2429  HKEY hKey;
2430  DWORD dwSize;
2431 
2433  UNREFERENCED_PARAMETER(ulFlags);
2434 
2435  DPRINT("PNP_GetClassName(%p %S %p %p 0x%08lx)\n",
2436  hBinding, pszClassGuid, Buffer, pulLength, ulFlags);
2437 
2438  lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class\\");
2439  if (lstrlenW(pszClassGuid) + 1 < sizeof(szKeyName)/sizeof(WCHAR)-(lstrlenW(szKeyName) * sizeof(WCHAR)))
2440  lstrcatW(szKeyName, pszClassGuid);
2441  else
2442  return CR_INVALID_DATA;
2443 
2445  szKeyName,
2446  0,
2448  &hKey))
2449  return CR_REGISTRY_ERROR;
2450 
2451  dwSize = *pulLength * sizeof(WCHAR);
2452  if (RegQueryValueExW(hKey,
2453  L"Class",
2454  NULL,
2455  NULL,
2456  (LPBYTE)Buffer,
2457  &dwSize))
2458  {
2459  *pulLength = 0;
2461  }
2462  else
2463  {
2464  *pulLength = dwSize / sizeof(WCHAR);
2465  }
2466 
2467  RegCloseKey(hKey);
2468 
2469  DPRINT("PNP_GetClassName() done (returns %lx)\n", ret);
2470 
2471  return ret;
2472 }
2473 
2474 
2475 /* Function 20 */
2476 DWORD
2477 WINAPI
2480  LPWSTR pszClassGuid,
2481  DWORD ulFlags)
2482 {
2484 
2486 
2487  DPRINT("PNP_DeleteClassKey(%p %S 0x%08lx)\n",
2488  hBinding, pszClassGuid, ulFlags);
2489 
2490  if (ulFlags & CM_DELETE_CLASS_SUBKEYS)
2491  {
2492  if (SHDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
2494  }
2495  else
2496  {
2497  if (RegDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
2499  }
2500 
2501  DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret);
2502 
2503  return ret;
2504 }
2505 
2506 
2507 /* Function 21 */
2508 DWORD
2509 WINAPI
2512  LPWSTR pszInterfaceDevice,
2513  GUID *AliasInterfaceGuid,
2514  LPWSTR pszAliasInterfaceDevice,
2515  PNP_RPC_STRING_LEN *pulLength,
2516  PNP_RPC_STRING_LEN *pulTransferLen,
2517  DWORD ulFlags)
2518 {
2519  UNIMPLEMENTED;
2520  return CR_CALL_NOT_IMPLEMENTED;
2521 }
2522 
2523 
2524 /* Function 22 */
2525 DWORD
2526 WINAPI
2530  LPWSTR pszDeviceID,
2531  BYTE *Buffer,
2532  PNP_RPC_BUFFER_SIZE *pulLength,
2533  DWORD ulFlags)
2534 {
2535  NTSTATUS Status;
2537  DWORD ret = CR_SUCCESS;
2538 
2540 
2541  DPRINT("PNP_GetInterfaceDeviceList(%p %p %S %p %p 0x%08lx)\n",
2542  hBinding, InterfaceGuid, pszDeviceID, Buffer, pulLength, ulFlags);
2543 
2544  if (!IsValidDeviceInstanceID(pszDeviceID))
2545  return CR_INVALID_DEVINST;
2546 
2547  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
2548  pszDeviceID);
2549 
2550  PlugPlayData.Flags = ulFlags;
2551  PlugPlayData.FilterGuid = InterfaceGuid;
2552  PlugPlayData.Buffer = Buffer;
2553  PlugPlayData.BufferSize = *pulLength;
2554 
2556  (PVOID)&PlugPlayData,
2558  if (NT_SUCCESS(Status))
2559  {
2560  *pulLength = PlugPlayData.BufferSize;
2561  }
2562  else
2563  {
2565  }
2566 
2567  DPRINT("PNP_GetInterfaceDeviceList() done (returns %lx)\n", ret);
2568  return ret;
2569 }
2570 
2571 
2572 /* Function 23 */
2573 DWORD
2574 WINAPI
2577  PNP_RPC_BUFFER_SIZE *pulLen,
2579  LPWSTR pszDeviceID,
2580  DWORD ulFlags)
2581 {
2582  NTSTATUS Status;
2584  DWORD ret = CR_SUCCESS;
2585 
2587 
2588  DPRINT("PNP_GetInterfaceDeviceListSize(%p %p %p %S 0x%08lx)\n",
2589  hBinding, pulLen, InterfaceGuid, pszDeviceID, ulFlags);
2590 
2591  if (!IsValidDeviceInstanceID(pszDeviceID))
2592  return CR_INVALID_DEVINST;
2593 
2594  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
2595  pszDeviceID);
2596 
2597  PlugPlayData.FilterGuid = InterfaceGuid;
2598  PlugPlayData.Buffer = NULL;
2599  PlugPlayData.BufferSize = 0;
2600  PlugPlayData.Flags = ulFlags;
2601 
2603  (PVOID)&PlugPlayData,
2605  if (NT_SUCCESS(Status))
2606  {
2607  *pulLen = PlugPlayData.BufferSize;
2608  }
2609  else
2610  {
2612  }
2613 
2614  DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret);
2615  return ret;
2616 }
2617 
2618 
2619 /* Function 24 */
2620 DWORD
2621 WINAPI
2624  LPWSTR pszDeviceID,
2626  LPWSTR pszReference,
2627  LPWSTR pszSymLink,
2628  PNP_RPC_STRING_LEN *pulLength,
2629  PNP_RPC_STRING_LEN *pulTransferLen,
2630  DWORD ulFlags)
2631 {
2632  UNIMPLEMENTED;
2633  return CR_CALL_NOT_IMPLEMENTED;
2634 }
2635 
2636 
2637 /* Function 25 */
2638 DWORD
2639 WINAPI
2642  LPWSTR pszInterfaceDevice,
2643  DWORD ulFlags)
2644 {
2645  UNIMPLEMENTED;
2646  return CR_CALL_NOT_IMPLEMENTED;
2647 }
2648 
2649 
2650 /* Function 26 */
2651 DWORD
2652 WINAPI
2655  LPWSTR pszClassGuid,
2656  DWORD ulProperty,
2657  DWORD *pulRegDataType,
2658  BYTE *Buffer,
2659  PNP_RPC_STRING_LEN *pulTransferLen,
2660  PNP_RPC_STRING_LEN *pulLength,
2661  DWORD ulFlags)
2662 {
2664  LPWSTR lpValueName = NULL;
2665  HKEY hInstKey = NULL;
2666  HKEY hPropKey = NULL;
2667  LONG lError;
2668 
2670 
2671  DPRINT("PNP_GetClassRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
2672  hBinding, pszClassGuid, ulProperty, pulRegDataType,
2673  Buffer, pulTransferLen, pulLength, ulFlags);
2674 
2675  if (pulTransferLen == NULL || pulLength == NULL)
2676  {
2678  goto done;
2679  }
2680 
2681  if (ulFlags != 0)
2682  {
2683  ret = CR_INVALID_FLAG;
2684  goto done;
2685  }
2686 
2687  if (*pulLength < *pulTransferLen)
2688  *pulLength = *pulTransferLen;
2689 
2690  *pulTransferLen = 0;
2691 
2692  switch (ulProperty)
2693  {
2694  case CM_CRP_SECURITY:
2695  lpValueName = L"Security";
2696  break;
2697 
2698  case CM_CRP_DEVTYPE:
2699  lpValueName = L"DeviceType";
2700  break;
2701 
2702  case CM_CRP_EXCLUSIVE:
2703  lpValueName = L"Exclusive";
2704  break;
2705 
2707  lpValueName = L"DeviceCharacteristics";
2708  break;
2709 
2710  default:
2712  goto done;
2713  }
2714 
2715  DPRINT("Value name: %S\n", lpValueName);
2716 
2717  lError = RegOpenKeyExW(hClassKey,
2718  pszClassGuid,
2719  0,
2720  KEY_READ,
2721  &hInstKey);
2722  if (lError != ERROR_SUCCESS)
2723  {
2724  *pulLength = 0;
2726  goto done;
2727  }
2728 
2729  lError = RegOpenKeyExW(hInstKey,
2730  L"Properties",
2731  0,
2732  KEY_READ,
2733  &hPropKey);
2734  if (lError != ERROR_SUCCESS)
2735  {
2736  *pulLength = 0;
2738  goto done;
2739  }
2740 
2741  lError = RegQueryValueExW(hPropKey,
2742  lpValueName,
2743  NULL,
2744  pulRegDataType,
2745  Buffer,
2746  pulLength);
2747  if (lError != ERROR_SUCCESS)
2748  {
2749  if (lError == ERROR_MORE_DATA)
2750  {
2751  ret = CR_BUFFER_SMALL;
2752  }
2753  else
2754  {
2755  *pulLength = 0;
2757  }
2758  }
2759 
2760 done:
2761  if (ret == CR_SUCCESS)
2762  *pulTransferLen = *pulLength;
2763 
2764  if (hPropKey != NULL)
2765  RegCloseKey(hPropKey);
2766 
2767  if (hInstKey != NULL)
2768  RegCloseKey(hInstKey);
2769 
2770  DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret);
2771 
2772  return ret;
2773 }
2774 
2775 
2776 /* Function 27 */
2777 DWORD
2778 WINAPI
2781  LPWSTR pszClassGuid,
2782  DWORD ulProperty,
2783  DWORD ulDataType,
2784  BYTE *Buffer,
2785  PNP_PROP_SIZE ulLength,
2786  DWORD ulFlags)
2787 {
2789  LPWSTR lpValueName = NULL;
2790  HKEY hInstKey = 0;
2791  HKEY hPropKey = 0;
2792  LONG lError;
2793 
2795 
2796  DPRINT("PNP_SetClassRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
2797  hBinding, pszClassGuid, ulProperty, ulDataType,
2798  Buffer, ulLength, ulFlags);
2799 
2800  if (ulFlags != 0)
2801  return CR_INVALID_FLAG;
2802 
2803  switch (ulProperty)
2804  {
2805  case CM_CRP_SECURITY:
2806  lpValueName = L"Security";
2807  break;
2808 
2809  case CM_CRP_DEVTYPE:
2810  lpValueName = L"DeviceType";
2811  break;
2812 
2813  case CM_CRP_EXCLUSIVE:
2814  lpValueName = L"Exclusive";
2815  break;
2816 
2818  lpValueName = L"DeviceCharacteristics";
2819  break;
2820 
2821  default:
2822  return CR_INVALID_PROPERTY;
2823  }
2824 
2825  lError = RegOpenKeyExW(hClassKey,
2826  pszClassGuid,
2827  0,
2828  KEY_WRITE,
2829  &hInstKey);
2830  if (lError != ERROR_SUCCESS)
2831  {
2833  goto done;
2834  }
2835 
2836  /* FIXME: Set security descriptor */
2837  lError = RegCreateKeyExW(hInstKey,
2838  L"Properties",
2839  0,
2840  NULL,
2843  NULL,
2844  &hPropKey,
2845  NULL);
2846  if (lError != ERROR_SUCCESS)
2847  {
2849  goto done;
2850  }
2851 
2852  if (ulLength == 0)
2853  {
2854  if (RegDeleteValueW(hPropKey,
2855  lpValueName))
2857  }
2858  else
2859  {
2860  if (RegSetValueExW(hPropKey,
2861  lpValueName,
2862  0,
2863  ulDataType,
2864  Buffer,
2865  ulLength))
2867  }
2868 
2869 done:
2870  if (hPropKey != NULL)
2871  RegCloseKey(hPropKey);
2872 
2873  if (hInstKey != NULL)
2874  RegCloseKey(hInstKey);
2875 
2876  return ret;
2877 }
2878 
2879 
2880 static
2881 CONFIGRET
2883  _In_ LPWSTR pszDeviceID,
2884  _In_ BOOL bPhantomDevice)
2885 {
2886  WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
2887  WCHAR szDevice[MAX_DEVICE_ID_LEN];
2888  WCHAR szInstance[MAX_DEVICE_ID_LEN];
2889  HKEY hKeyEnumerator;
2890  HKEY hKeyDevice;
2891  HKEY hKeyInstance;
2892  HKEY hKeyControl;
2893  LONG lError;
2894 
2895  /* Split the instance ID */
2896  SplitDeviceInstanceID(pszDeviceID,
2897  szEnumerator,
2898  szDevice,
2899  szInstance);
2900 
2901  /* Open or create the enumerator key */
2902  lError = RegCreateKeyExW(hEnumKey,
2903  szEnumerator,
2904  0,
2905  NULL,
2908  NULL,
2909  &hKeyEnumerator,
2910  NULL);
2911  if (lError != ERROR_SUCCESS)
2912  {
2913  return CR_REGISTRY_ERROR;
2914  }
2915 
2916  /* Open or create the device key */
2917  lError = RegCreateKeyExW(hKeyEnumerator,
2918  szDevice,
2919  0,
2920  NULL,
2923  NULL,
2924  &hKeyDevice,
2925  NULL);
2926 
2927  /* Close the enumerator key */
2928  RegCloseKey(hKeyEnumerator);
2929 
2930  if (lError != ERROR_SUCCESS)
2931  {
2932  return CR_REGISTRY_ERROR;
2933  }
2934 
2935  /* Try to open the instance key and fail if it exists */
2936  lError = RegOpenKeyExW(hKeyDevice,
2937  szInstance,
2938  0,
2939  KEY_SET_VALUE,
2940  &hKeyInstance);
2941  if (lError == ERROR_SUCCESS)
2942  {
2943  DPRINT1("Instance %S already exists!\n", szInstance);
2944  RegCloseKey(hKeyInstance);
2945  RegCloseKey(hKeyDevice);
2946  return CR_ALREADY_SUCH_DEVINST;
2947  }
2948 
2949  /* Create a new instance key */
2950  lError = RegCreateKeyExW(hKeyDevice,
2951  szInstance,
2952  0,
2953  NULL,
2956  NULL,
2957  &hKeyInstance,
2958  NULL);
2959 
2960  /* Close the device key */
2961  RegCloseKey(hKeyDevice);
2962 
2963  if (lError != ERROR_SUCCESS)
2964  {
2965  return CR_REGISTRY_ERROR;
2966  }
2967 
2968  if (bPhantomDevice)
2969  {
2970  DWORD dwPhantomValue = 1;
2971  RegSetValueExW(hKeyInstance,
2972  L"Phantom",
2973  0,
2974  REG_DWORD,
2975  (PBYTE)&dwPhantomValue,
2976  sizeof(dwPhantomValue));
2977  }
2978 
2979  /* Create the 'Control' sub key */
2980  lError = RegCreateKeyExW(hKeyInstance,
2981  L"Control",
2982  0,
2983  NULL,
2986  NULL,
2987  &hKeyControl,
2988  NULL);
2989  if (lError == ERROR_SUCCESS)
2990  {
2991  RegCloseKey(hKeyControl);
2992  }
2993 
2994  RegCloseKey(hKeyInstance);
2995 
2996  return (lError == ERROR_SUCCESS) ? CR_SUCCESS : CR_REGISTRY_ERROR;
2997 }
2998 
2999 
3000 static
3001 CONFIGRET
3003  _Inout_ LPWSTR pszDeviceID,
3004  _In_ PNP_RPC_STRING_LEN ulLength)
3005 {
3006  WCHAR szGeneratedInstance[MAX_DEVICE_ID_LEN];
3007  HKEY hKey;
3008  DWORD dwInstanceNumber;
3009  DWORD dwError = ERROR_SUCCESS;
3011 
3012  /* Fail, if the device name contains backslashes */
3013  if (wcschr(pszDeviceID, L'\\') != NULL)
3014  return CR_INVALID_DEVICE_ID;
3015 
3016  /* Generated ID is: Root<Device ID><Instance number> */
3017  dwInstanceNumber = 0;
3018  while (dwError == ERROR_SUCCESS)
3019  {
3020  if (dwInstanceNumber >= 10000)
3021  return CR_FAILURE;
3022 
3023  swprintf(szGeneratedInstance, L"Root\\%ls\\%04lu",
3024  pszDeviceID, dwInstanceNumber);
3025 
3026  /* Try to open the enum key of the device instance */
3027  dwError = RegOpenKeyEx(hEnumKey, szGeneratedInstance, 0, KEY_QUERY_VALUE, &hKey);
3028  if (dwError == ERROR_SUCCESS)
3029  {
3030  RegCloseKey(hKey);
3031  dwInstanceNumber++;
3032  }
3033  }
3034 
3035  /* pszDeviceID is an out parameter too for generated IDs */
3036  if (wcslen(szGeneratedInstance) > ulLength)
3037  {
3038  ret = CR_BUFFER_SMALL;
3039  }
3040  else
3041  {
3042  wcscpy(pszDeviceID, szGeneratedInstance);
3043  }
3044 
3045  return ret;
3046 }
3047 
3048 
3049 /* Function 28 */
3050 DWORD
3051 WINAPI
3054  LPWSTR pszDeviceID,
3055  LPWSTR pszParentDeviceID,
3056  PNP_RPC_STRING_LEN ulLength,
3057  DWORD ulFlags)
3058 {
3060  HKEY hKey = NULL;
3061  DWORD dwSize, dwPhantom;
3062  NTSTATUS Status;
3064 
3065  DPRINT("PNP_CreateDevInst(%p %S %S %lu 0x%08lx)\n",
3066  hBinding, pszParentDeviceID, pszDeviceID, ulLength, ulFlags);
3067 
3068  if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
3069  return CR_INVALID_FLAG;
3070 
3071  if (pszDeviceID == NULL || pszParentDeviceID == NULL)
3072  return CR_INVALID_POINTER;
3073 
3074  /* Fail, if the parent device is not the root device */
3075  if (!IsRootDeviceInstanceID(pszParentDeviceID))
3076  return CR_INVALID_DEVINST;
3077 
3078  if (ulFlags & CM_CREATE_DEVNODE_GENERATE_ID)
3079  {
3080  ret = GenerateDeviceID(pszDeviceID,
3081  ulLength);
3082  if (ret != CR_SUCCESS)
3083  return ret;
3084  }
3085 
3086  /* Try to open the device instance key */
3087  RegOpenKeyEx(hEnumKey, pszDeviceID, 0, KEY_READ | KEY_WRITE, &hKey);
3088 
3089  if (ulFlags & CM_CREATE_DEVNODE_PHANTOM)
3090  {
3091  /* Fail, if the device already exists */
3092  if (hKey != NULL)
3093  {
3095  goto done;
3096  }
3097 
3098  /* Create the phantom device instance */
3099  ret = CreateDeviceInstance(pszDeviceID, TRUE);
3100  }
3101  else
3102  {
3103  /* Fail, if the device exists and is present */
3104  if ((hKey != NULL) && (IsPresentDeviceInstanceID(pszDeviceID)))
3105  {
3107  goto done;
3108  }
3109 
3110  /* If it does not already exist ... */
3111  if (hKey == NULL)
3112  {
3113  /* Create the device instance */
3114  ret = CreateDeviceInstance(pszDeviceID, FALSE);
3115 
3116  /* Open the device instance key */
3117  RegOpenKeyEx(hEnumKey, pszDeviceID, 0, KEY_READ | KEY_WRITE, &hKey);
3118  }
3119 
3120  /* Create a device node for the device */
3121  RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceID);
3123  &ControlData,
3124  sizeof(ControlData));
3125  if (!NT_SUCCESS(Status))
3126  {
3127  ret = CR_FAILURE;
3128  goto done;
3129  }
3130 
3131  /* If the device is a phantom device, turn it into a normal device */
3132  if (hKey != NULL)
3133  {
3134  dwPhantom = 0;
3135  dwSize = sizeof(DWORD);
3136  RegQueryValueEx(hKey, L"Phantom", NULL, NULL, (PBYTE)&dwPhantom, &dwSize);
3137 
3138  if (dwPhantom != 0)
3139  RegDeleteValue(hKey, L"Phantom");
3140  }
3141  }
3142 
3143 done:
3144  if (hKey)
3145  RegCloseKey(hKey);
3146 
3147  DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret);
3148 
3149  return ret;
3150 }
3151 
3152 
3153 static CONFIGRET
3155  _In_ LPWSTR pszDeviceInstance,
3156  _In_ DWORD ulMinorAction)
3157 {
3159  HKEY hDeviceKey = NULL;
3160  DWORD dwDisableCount, dwSize;
3161  DWORD ulStatus, ulProblem;
3162  DWORD dwError;
3164  NTSTATUS Status;
3165 
3166  DPRINT1("SetupDeviceInstance(%S 0x%08lx)\n",
3167  pszDeviceInstance, ulMinorAction);
3168 
3169  if (IsRootDeviceInstanceID(pszDeviceInstance))
3170  return CR_INVALID_DEVINST;
3171 
3172  if (ulMinorAction & ~CM_SETUP_BITS)
3173  return CR_INVALID_FLAG;
3174 
3175  if ((ulMinorAction == CM_SETUP_DOWNLOAD) ||
3176  (ulMinorAction == CM_SETUP_WRITE_LOG_CONFS))
3177  return CR_SUCCESS;
3178 
3179  dwError = RegOpenKeyExW(hEnumKey,
3180  pszDeviceInstance,
3181  0,
3182  KEY_READ,
3183  &hDeviceKey);
3184  if (dwError != ERROR_SUCCESS)
3185  return CR_INVALID_DEVNODE;
3186 
3187  dwSize = sizeof(dwDisableCount);
3188  dwError = RegQueryValueExW(hDeviceKey,
3189  L"DisableCount",
3190  NULL,
3191  NULL,
3192  (LPBYTE)&dwDisableCount,
3193  &dwSize);
3194  if ((dwError == ERROR_SUCCESS) &&
3195  (dwDisableCount > 0))
3196  {
3197  goto done;
3198  }
3199 
3200  GetDeviceStatus(pszDeviceInstance,
3201  &ulStatus,
3202  &ulProblem);
3203 
3204  if (ulStatus & DN_STARTED)
3205  {
3206  goto done;
3207  }
3208 
3209  if (ulStatus & DN_HAS_PROBLEM)
3210  {
3211  ret = ClearDeviceStatus(pszDeviceInstance,
3213  ulProblem);
3214  }
3215 
3216  if (ret != CR_SUCCESS)
3217  goto done;
3218 
3219  /* Start the device */
3220  RtlInitUnicodeString(&ControlData.DeviceInstance,
3221  pszDeviceInstance);
3223  &ControlData,
3225  if (!NT_SUCCESS(Status))
3227 
3228 done:
3229  if (hDeviceKey != NULL)
3230  RegCloseKey(hDeviceKey);
3231 
3232  return ret;
3233 }
3234 
3235 
3236 static CONFIGRET
3238  _In_ LPWSTR pszDeviceInstance)
3239 {
3242  NTSTATUS Status;
3243 
3244  DPRINT("Enable device instance %S\n", pszDeviceInstance);
3245 
3246  RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceInstance);
3247  Status = NtPlugPlayControl(PlugPlayControlStartDevice, &ControlData, sizeof(ControlData));
3248  if (!NT_SUCCESS(Status))
3250 
3251  return ret;
3252 }
3253 
3254 
3255 static CONFIGRET
3257  _In_ LPWSTR pszDeviceInstance,
3258  _In_ ULONG ulMinorAction)
3259 {
3260  PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData;
3262  NTSTATUS Status;
3263 
3264  DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
3265  pszDeviceInstance, ulMinorAction);
3266 
3267  if (ulMinorAction & ~CM_REENUMERATE_BITS)
3268  return CR_INVALID_FLAG;
3269 
3270  if (ulMinorAction & CM_REENUMERATE_RETRY_INSTALLATION)
3271  {
3272  DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
3273  }
3274 
3275  RtlInitUnicodeString(&EnumerateDeviceData.DeviceInstance,
3276  pszDeviceInstance);
3277  EnumerateDeviceData.Flags = 0;
3278 
3280  &EnumerateDeviceData,
3282  if (!NT_SUCCESS(Status))
3284 
3285  return ret;
3286 }
3287 
3288 
3289 /* Function 29 */
3290 DWORD
3291 WINAPI
3294  DWORD ulMajorAction,
3295  DWORD ulMinorAction,
3296  LPWSTR pszDeviceInstance1,
3297  LPWSTR pszDeviceInstance2)
3298 {
3300 
3302 
3303  DPRINT("PNP_DeviceInstanceAction(%p %lu 0x%08lx %S %S)\n",
3304  hBinding, ulMajorAction, ulMinorAction,
3305  pszDeviceInstance1, pszDeviceInstance2);
3306 
3307  switch (ulMajorAction)
3308  {
3309  case PNP_DEVINST_SETUP:
3310  ret = SetupDeviceInstance(pszDeviceInstance1,
3311  ulMinorAction);
3312  break;
3313 
3314  case PNP_DEVINST_ENABLE:
3315  ret = EnableDeviceInstance(pszDeviceInstance1);
3316  break;
3317 
3318  case PNP_DEVINST_REENUMERATE:
3319  ret = ReenumerateDeviceInstance(pszDeviceInstance1,
3320  ulMinorAction);
3321  break;
3322 
3323  default:
3324  DPRINT1("Unknown device action %lu: not implemented\n", ulMajorAction);
3326  }
3327 
3328  DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret);
3329 
3330  return ret;
3331 }
3332 
3333 
3334 /* Function 30 */
3335 DWORD
3336 WINAPI
3339  LPWSTR pDeviceID,
3340  DWORD *pulStatus,
3341  DWORD *pulProblem,
3342  DWORD ulFlags)
3343 {
3344  DWORD ulDataType, ulTransferLength, ulLength;
3345  DWORD ulCapabilities, ulConfigFlags;
3346  CONFIGRET ret;
3347 
3349  UNREFERENCED_PARAMETER(ulFlags);
3350 
3351  DPRINT("PNP_GetDeviceStatus(%p %S %p %p 0x%08lx)\n",
3352  hBinding, pDeviceID, pulStatus, pulProblem, ulFlags);
3353 
3354  if (ulFlags != 0)
3355  return CR_INVALID_FLAG;
3356 
3357  if ((pulStatus == NULL) || (pulProblem == NULL))
3358  return CR_INVALID_POINTER;
3359 
3360  if (!IsValidDeviceInstanceID(pDeviceID))
3361  return CR_INVALID_DEVINST;
3362 
3363  ret = GetDeviceStatus(pDeviceID, pulStatus, pulProblem);
3364  if (ret != CR_SUCCESS)
3365  return ret;
3366 
3367  /* Check for DN_REMOVABLE */
3368  ulTransferLength = sizeof(ulCapabilities);
3369  ulLength = sizeof(ulCapabilities);
3371  pDeviceID,
3373  &ulDataType,
3374  (PBYTE)&ulCapabilities,
3375  &ulTransferLength,
3376  &ulLength,
3377  0);
3378  if (ret != CR_SUCCESS)
3379  ulCapabilities = 0;
3380 
3381  if (ulCapabilities & CM_DEVCAP_REMOVABLE)
3382  *pulStatus |= DN_REMOVABLE;
3383 
3384  /* Check for DN_MANUAL */
3385  ulTransferLength = sizeof(ulConfigFlags);
3386  ulLength = sizeof(ulConfigFlags);
3388  pDeviceID,
3390  &ulDataType,
3391  (PBYTE)&ulConfigFlags,
3392  &ulTransferLength,
3393  &ulLength,
3394  0);
3395  if (ret != CR_SUCCESS)
3396  ulConfigFlags = 0;
3397 
3398  if (ulConfigFlags & CONFIGFLAG_MANUAL_INSTALL)
3399  *pulStatus |= DN_MANUAL;
3400 
3401  /* Check for failed install */
3402  if (((*pulStatus & DN_HAS_PROBLEM) == 0) && (ulConfigFlags & CONFIGFLAG_FAILEDINSTALL))
3403  {
3404  *pulStatus |= DN_HAS_PROBLEM;
3405  *pulProblem = CM_PROB_FAILED_INSTALL;
3406  }
3407 
3408  return CR_SUCCESS;
3409 }
3410 
3411 
3412 /* Function 31 */
3413 DWORD
3414 WINAPI
3417  LPWSTR pDeviceID,
3418  DWORD ulProblem,
3419  DWORD ulFlags)
3420 {
3421  ULONG ulOldStatus, ulOldProblem;
3423 
3425 
3426  DPRINT1("PNP_SetDeviceProblem(%p %S %lu 0x%08lx)\n",
3427  hBinding, pDeviceID, ulProblem, ulFlags);
3428 
3429  if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
3430  return CR_INVALID_FLAG;
3431 
3432  if (!IsValidDeviceInstanceID(pDeviceID))
3433  return CR_INVALID_DEVINST;
3434 
3435  ret = GetDeviceStatus(pDeviceID,
3436  &ulOldStatus,
3437  &ulOldProblem);
3438  if (ret != CR_SUCCESS)
3439  return ret;
3440 
3441  if (((ulFlags & CM_SET_DEVNODE_PROBLEM_OVERRIDE) == 0) &&
3442  (ulOldProblem != 0) &&
3443  (ulOldProblem != ulProblem))
3444  {
3445  return CR_FAILURE;
3446  }
3447 
3448  if (ulProblem == 0)
3449  {
3450  ret = ClearDeviceStatus(pDeviceID,
3452  ulOldProblem);
3453  }
3454  else
3455  {
3456  ret = SetDeviceStatus(pDeviceID,
3458  ulProblem);
3459  }
3460 
3461  return ret;
3462 }
3463 
3464 
3465 /* Function 32 */
3466 DWORD
3467 WINAPI
3470  LPWSTR pDeviceID,
3471  PPNP_VETO_TYPE pVetoType,
3472  LPWSTR pszVetoName,
3473  DWORD ulNameLength,
3474  DWORD ulFlags)
3475 {
3477 
3478  DPRINT1("PNP_DisableDevInst(%p %S %p %p %lu 0x%08lx)\n",
3479  hBinding, pDeviceID, pVetoType, pszVetoName, ulNameLength, ulFlags);
3480 
3481  if (ulFlags & ~CM_DISABLE_BITS)
3482  return CR_INVALID_FLAG;
3483 
3484  if (!IsValidDeviceInstanceID(pDeviceID) ||
3485  IsRootDeviceInstanceID(pDeviceID))
3486  return CR_INVALID_DEVINST;
3487 
3488  return DisableDeviceInstance(pDeviceID,
3489  pVetoType,
3490  pszVetoName,
3491  ulNameLength);
3492 }
3493 
3494 
3495 /* Function 33 */
3496 DWORD
3497 WINAPI
3500  LPWSTR pDeviceID,
3501  DWORD ulFlags)
3502 {
3503  UNIMPLEMENTED;
3504  return CR_CALL_NOT_IMPLEMENTED;
3505 }
3506 
3507 
3508 static BOOL
3509 CheckForDeviceId(LPWSTR lpDeviceIdList,
3510  LPWSTR lpDeviceId)
3511 {
3512  LPWSTR lpPtr;
3513  DWORD dwLength;
3514 
3515  lpPtr = lpDeviceIdList;
3516  while (*lpPtr != 0)
3517  {
3518  dwLength = wcslen(lpPtr);
3519  if (0 == _wcsicmp(lpPtr, lpDeviceId))
3520  return TRUE;
3521 
3522  lpPtr += (dwLength + 1);
3523  }
3524 
3525  return FALSE;
3526 }
3527 
3528 
3529 static VOID
3530 AppendDeviceId(LPWSTR lpDeviceIdList,
3531  LPDWORD lpDeviceIdListSize,
3532  LPWSTR lpDeviceId)
3533 {
3534  DWORD dwLen;
3535  DWORD dwPos;
3536 
3537  dwLen = wcslen(lpDeviceId);
3538  dwPos = (*lpDeviceIdListSize / sizeof(WCHAR)) - 1;
3539 
3540  wcscpy(&lpDeviceIdList[dwPos], lpDeviceId);
3541 
3542  dwPos += (dwLen + 1);
3543 
3544  lpDeviceIdList[dwPos] = 0;
3545 
3546  *lpDeviceIdListSize = dwPos * sizeof(WCHAR);
3547 }
3548 
3549 
3550 /* Function 34 */
3551 DWORD
3552 WINAPI
3555  LPWSTR pszDeviceID,
3556  LPWSTR pszID,
3557  DWORD ulFlags)
3558 {
3560  HKEY hDeviceKey;
3561  LPWSTR pszSubKey;
3562  DWORD dwDeviceIdListSize;
3563  DWORD dwNewDeviceIdSize;
3564  WCHAR * pszDeviceIdList = NULL;
3565 
3567 
3568  DPRINT("PNP_AddID(%p %S %S 0x%08lx)\n",
3569  hBinding, pszDeviceID, pszID, ulFlags);
3570 
3571  if (RegOpenKeyExW(hEnumKey,
3572  pszDeviceID,
3573  0,
3575  &hDeviceKey) != ERROR_SUCCESS)
3576  {
3577  DPRINT("Failed to open the device key!\n");
3578  return CR_INVALID_DEVNODE;
3579  }
3580 
3581  pszSubKey = (ulFlags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID";
3582 
3583  if (RegQueryValueExW(hDeviceKey,
3584  pszSubKey,
3585  NULL,
3586  NULL,
3587  NULL,
3588  &dwDeviceIdListSize) != ERROR_SUCCESS)
3589  {
3590  DPRINT("Failed to query the desired ID string!\n");
3592  goto Done;
3593  }
3594 
3595  dwNewDeviceIdSize = lstrlenW(pszDeviceID);
3596  if (!dwNewDeviceIdSize)
3597  {
3599  goto Done;
3600  }
3601 
3602  dwDeviceIdListSize += (dwNewDeviceIdSize + 2) * sizeof(WCHAR);
3603 
3604  pszDeviceIdList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeviceIdListSize);
3605  if (!pszDeviceIdList)
3606  {
3607  DPRINT("Failed to allocate memory for the desired ID string!\n");
3609  goto Done;
3610  }
3611 
3612  if (RegQueryValueExW(hDeviceKey,
3613  pszSubKey,
3614  NULL,
3615  NULL,
3616  (LPBYTE)pszDeviceIdList,
3617  &dwDeviceIdListSize) != ERROR_SUCCESS)
3618  {
3619  DPRINT("Failed to query the desired ID string!\n");
3621  goto Done;
3622  }
3623 
3624  /* Check whether the device ID is already in use */
3625  if (CheckForDeviceId(pszDeviceIdList, pszDeviceID))
3626  {
3627  DPRINT("Device ID was found in the ID string!\n");
3628  ret = CR_SUCCESS;
3629  goto Done;
3630  }
3631 
3632  /* Append the Device ID */
3633  AppendDeviceId(pszDeviceIdList, &dwDeviceIdListSize, pszID);
3634 
3635  if (RegSetValueExW(hDeviceKey,
3636  pszSubKey,
3637  0,
3638  REG_MULTI_SZ,
3639  (LPBYTE)pszDeviceIdList,
3640  dwDeviceIdListSize) != ERROR_SUCCESS)
3641  {
3642  DPRINT("Failed to set the desired ID string!\n");
3644  }
3645 
3646 Done:
3647  RegCloseKey(hDeviceKey);
3648  if (pszDeviceIdList)
3649  HeapFree(GetProcessHeap(), 0, pszDeviceIdList);
3650 
3651  DPRINT("PNP_AddID() done (returns %lx)\n", ret);
3652 
3653  return ret;
3654 }
3655 
3656 
3657 /* Function 35 */
3658 DWORD
3659 WINAPI
3662  LPWSTR pszDeviceID,
3663  DWORD ulFlags)
3664 {
3665  DPRINT("PNP_RegisterDriver(%p %S 0x%lx)\n",
3666  hBinding, pszDeviceID, ulFlags);
3667 
3668  if (ulFlags & ~CM_REGISTER_DEVICE_DRIVER_BITS)
3669  return CR_INVALID_FLAG;
3670 
3671  if (!IsValidDeviceInstanceID(pszDeviceID))
3672  return CR_INVALID_DEVINST;
3673 
3674  SetDeviceStatus(pszDeviceID, 0, 0);
3675 
3676  return CR_SUCCESS;
3677 }
3678 
3679 
3680 /* Function 36 */
3681 DWORD
3682 WINAPI
3685  LPWSTR pszDeviceID,
3686  PPNP_VETO_TYPE pVetoType,
3687  LPWSTR pszVetoName,
3688  DWORD ulNameLength,
3689  DWORD ulFlags)
3690 {
3692  NTSTATUS Status;
3693  DWORD ret = CR_SUCCESS;
3694 
3695  DPRINT1("PNP_QueryRemove(%p %S %p %p %lu 0x%lx)\n",
3696  hBinding, pszDeviceID, pVetoType, pszVetoName,
3697  ulNameLength, ulFlags);
3698 
3699  if (ulFlags & ~CM_REMOVE_BITS)
3700  return CR_INVALID_FLAG;
3701 
3702  if (!IsValidDeviceInstanceID(pszDeviceID) ||
3703  IsRootDeviceInstanceID(pszDeviceID))
3704  return CR_INVALID_DEVINST;
3705 
3706  if (pVetoType != NULL)
3707  *pVetoType = PNP_VetoTypeUnknown;
3708 
3709  if (pszVetoName != NULL && ulNameLength > 0)
3710  *pszVetoName = UNICODE_NULL;
3711 
3712  RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData));
3713  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
3714  pszDeviceID);
3715  PlugPlayData.VetoName = pszVetoName;
3716  PlugPlayData.NameLength = ulNameLength;
3717 // PlugPlayData.Flags =
3718 
3720  &PlugPlayData,
3721  sizeof(PlugPlayData));
3722  if (!NT_SUCCESS(Status))
3724 
3725  return ret;
3726 }
3727 
3728 
3729 /* Function 37 */
3730 DWORD
3731 WINAPI
3734  LPWSTR pszDeviceID,
3735  PPNP_VETO_TYPE pVetoType,
3736  LPWSTR pszVetoName,
3737  DWORD ulNameLength,
3738  DWORD ulFlags)
3739 {
3741  NTSTATUS Status;
3742  DWORD ret = CR_SUCCESS;
3743 
3744  DPRINT1("PNP_RequestDeviceEject(%p %S %p %p %lu 0x%lx)\n",
3745  hBinding, pszDeviceID, pVetoType, pszVetoName,
3746  ulNameLength, ulFlags);
3747 
3748  if (ulFlags != 0)
3749  return CR_INVALID_FLAG;
3750 
3751  if (!IsValidDeviceInstanceID(pszDeviceID))
3752  return CR_INVALID_DEVINST;
3753 
3754  if (pVetoType != NULL)
3755  *pVetoType = PNP_VetoTypeUnknown;
3756 
3757  if (pszVetoName != NULL && ulNameLength > 0)
3758  *pszVetoName = UNICODE_NULL;
3759 
3760  RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData));
3761  RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
3762  pszDeviceID);
3763  PlugPlayData.VetoName = pszVetoName;
3764  PlugPlayData.NameLength = ulNameLength;
3765 // PlugPlayData.Flags =
3766 
3768  &PlugPlayData,
3769  sizeof(PlugPlayData));
3770  if (!NT_SUCCESS(Status))
3772 
3773  return ret;
3774 }
3775 
3776 
3777 /* Function 38 */
3778 CONFIGRET
3779 WINAPI
3782  BOOL *Present)
3783 {
3784  HKEY hKey;
3785  DWORD dwType;
3786  DWORD dwValue;
3787  DWORD dwSize;
3789 
3791 
3792  DPRINT1("PNP_IsDockStationPresent(%p %p)\n",
3793  hBinding, Present);
3794 
3795  *Present = FALSE;
3796 
3798  L"CurrentDockInfo",
3799  0,
3800  KEY_READ,
3801  &hKey) != ERROR_SUCCESS)
3802  return CR_REGISTRY_ERROR;
3803 
3804  dwSize = sizeof(DWORD);
3805  if (RegQueryValueExW(hKey,
3806  L"DockingState",
3807  NULL,
3808  &dwType,
3809  (LPBYTE)&dwValue,
3810  &dwSize) != ERROR_SUCCESS)
3812 
3813  RegCloseKey(hKey);
3814 
3815  if (ret == CR_SUCCESS)
3816  {
3817  if (dwType != REG_DWORD || dwSize != sizeof(DWORD))
3818  {
3820  }
3821  else if (dwValue != 0)
3822  {
3823  *Present = TRUE;
3824  }
3825  }
3826 
3827  DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret);
3828 
3829  return ret;
3830 }
3831 
3832 
3833 /* Function 39 */
3834 DWORD
3835 WINAPI
3838 {
3839  WCHAR szDockDeviceInstance[MAX_DEVICE_ID_LEN];
3841  NTSTATUS Status;
3842 
3843  DPRINT("PNP_RequestEjectPC(%p)\n", hBinding);
3844 
3845  /* Retrieve the dock device */
3846  DockData.DeviceInstanceLength = ARRAYSIZE(szDockDeviceInstance);
3847  DockData.DeviceInstance = szDockDeviceInstance;
3848 
3850  &DockData,
3851  sizeof(DockData));
3852  if (!NT_SUCCESS(Status))
3853  return NtStatusToCrError(Status);
3854 
3855  /* Eject the dock device */
3857  szDockDeviceInstance,
3858  NULL,
3859  NULL,
3860  0,
3861  0);
3862 }
3863 
3864 
3865 /* Function 40 */
3866 DWORD
3867 WINAPI
3870  DWORD ulAction,
3871  LPWSTR pDeviceID,
3872  DWORD ulConfig,
3873  DWORD *pulValue,
3874  PPNP_VETO_TYPE pVetoType,
3875  LPWSTR pszVetoName,
3876  DWORD ulNameLength,
3877  DWORD ulFlags)
3878 {
3880  WCHAR szKeyName[MAX_PATH];
3881  HKEY hKey;
3882  HKEY hDeviceKey;
3883  DWORD dwSize;
3884 
3886 
3887  DPRINT("PNP_HwProfFlags() called\n");
3888 
3889  if (!IsValidDeviceInstanceID(pDeviceID))
3890  return CR_INVALID_DEVINST;
3891 
3892  if (ulConfig == 0)
3893  {
3894  wcscpy(szKeyName,
3895  L"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
3896  }
3897  else
3898  {
3899  swprintf(szKeyName,
3900  L"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
3901  ulConfig);
3902  }
3903 
3905  szKeyName,
3906  0,
3908  &hKey) != ERROR_SUCCESS)
3909  return CR_REGISTRY_ERROR;
3910 
3911  if (ulAction == PNP_GET_HWPROFFLAGS)
3912  {
3913  if (RegOpenKeyExW(hKey,
3914  pDeviceID,
3915  0,
3917  &hDeviceKey) != ERROR_SUCCESS)
3918  {
3919  *pulValue = 0;
3920  }
3921  else
3922  {
3923  dwSize = sizeof(DWORD);
3924  if (RegQueryValueExW(hDeviceKey,
3925  L"CSConfigFlags",
3926  NULL,
3927  NULL,
3928  (LPBYTE)pulValue,
3929  &dwSize) != ERROR_SUCCESS)
3930  {
3931  *pulValue = 0;
3932  }
3933 
3934  RegCloseKey(hDeviceKey);
3935  }
3936  }
3937  else if (ulAction == PNP_SET_HWPROFFLAGS)
3938  {
3939  /* FIXME: not implemented yet */
3941  }
3942 
3943  RegCloseKey(hKey);
3944 
3945  return ret;
3946 }
3947 
3948 
3949 /* Function 41 */
3950 DWORD
3951 WINAPI
3954  DWORD ulIndex,
3955  HWPROFILEINFO *pHWProfileInfo,
3956  DWORD ulProfileInfoSize,
3957  DWORD ulFlags)
3958 {
3959  WCHAR szProfileName[5];
3960  HKEY hKeyConfig = NULL;
3961  HKEY hKeyProfiles = NULL;
3962  HKEY hKeyProfile = NULL;
3963  DWORD dwDisposition;
3964  DWORD dwSize;
3965  LONG lError;
3967 
3969 
3970  DPRINT("PNP_GetHwProfInfo() called\n");
3971 
3972  if (ulProfileInfoSize == 0)
3973  {
3974  ret = CR_INVALID_DATA;
3975  goto done;
3976  }
3977 
3978  if (ulFlags != 0)
3979  {
3980  ret = CR_INVALID_FLAG;
3981  goto done;
3982  }
3983 
3984  /* Initialize the profile information */
3985  pHWProfileInfo->HWPI_ulHWProfile = 0;
3986  pHWProfileInfo->HWPI_szFriendlyName[0] = 0;
3987  pHWProfileInfo->HWPI_dwFlags = 0;
3988 
3989  /* Open the 'IDConfigDB' key */
3991  L"System\\CurrentControlSet\\Control\\IDConfigDB",
3992  0,
3993  NULL,
3996  NULL,
3997  &hKeyConfig,
3998  &dwDisposition);
3999  if (lError != ERROR_SUCCESS)
4000  {
4002  goto done;
4003  }
4004 
4005  /* Open the 'Hardware Profiles' subkey */
4006  lError = RegCreateKeyExW(hKeyConfig,
4007  L"Hardware Profiles",
4008  0,
4009  NULL,
4012  NULL,
4013  &hKeyProfiles,
4014  &dwDisposition);
4015  if (lError != ERROR_SUCCESS)
4016  {
4018  goto done;
4019  }
4020 
4021  if (ulIndex == (ULONG)-1)
4022  {
4023  dwSize = sizeof(ULONG);
4024  lError = RegQueryValueExW(hKeyConfig,
4025  L"CurrentConfig",
4026  NULL,
4027  NULL,
4028  (LPBYTE)&pHWProfileInfo->HWPI_ulHWProfile,
4029  &dwSize);
4030  if (lError != ERROR_SUCCESS)
4031  {
4032  pHWProfileInfo->HWPI_ulHWProfile = 0;
4034  goto done;
4035  }
4036  }
4037  else
4038  {
4039  /* FIXME: not implemented yet */
4041  goto done;
4042  }
4043 
4044  swprintf(szProfileName, L"%04lu", pHWProfileInfo->HWPI_ulHWProfile);
4045 
4046  lError = RegOpenKeyExW(hKeyProfiles,
4047  szProfileName,
4048  0,
4050  &hKeyProfile);
4051  if (lError != ERROR_SUCCESS)
4052  {
4054  goto done;
4055  }
4056 
4057  dwSize = sizeof(pHWProfileInfo->HWPI_szFriendlyName);
4058  lError = RegQueryValueExW(hKeyProfile,
4059  L"FriendlyName",
4060  NULL,
4061  NULL,
4062  (LPBYTE)&pHWProfileInfo->HWPI_szFriendlyName,
4063  &dwSize);
4064  if (lError != ERROR_SUCCESS)
4065  {
4067  goto done;
4068  }
4069 
4070 done:
4071  if (hKeyProfile != NULL)
4072  RegCloseKey(hKeyProfile);
4073 
4074  if (hKeyProfiles != NULL)
4075  RegCloseKey(hKeyProfiles);
4076 
4077  if (hKeyConfig != NULL)
4078  RegCloseKey(hKeyConfig);
4079 
4080  return ret;
4081 }
4082 
4083 
4084 /* Function 42 */
4085 DWORD
4086 WINAPI
4089  LPWSTR pDeviceID,
4090  DWORD ulPriority,
4091  DWORD *pulLogConfTag,
4092  DWORD ulFlags)
4093 {
4094  UNIMPLEMENTED;
4095  return CR_CALL_NOT_IMPLEMENTED;
4096 }
4097 
4098 
4099 /* Function 43 */
4100 DWORD
4101 WINAPI
4104  LPWSTR pDeviceID,
4105  DWORD ulLogConfType,
4106  DWORD ulLogConfTag,
4107  DWORD ulFlags)
4108 {
4109  UNIMPLEMENTED;
4110  return CR_CALL_NOT_IMPLEMENTED;
4111 }
4112 
4113 
4114 /* Function 44 */
4115 DWORD
4116 WINAPI
4119  LPWSTR pDeviceID,
4120  DWORD ulLogConfType,
4121  DWORD *pulLogConfTag,
4122  DWORD ulFlags)
4123 {
4124  HKEY hConfigKey = NULL;
4125  DWORD RegDataType = 0;
4126  ULONG ulDataSize = 0;
4127  LPBYTE lpData = NULL;
4129 
4130  DPRINT("PNP_GetFirstLogConf(%p %S %lu %p 0x%08lx)\n",
4131  hBinding, pDeviceID, ulLogConfType, pulLogConfTag, ulFlags);
4132 
4133  if (pulLogConfTag == NULL)
4134  return CR_INVALID_POINTER;
4135 
4136  *pulLogConfTag = (DWORD)0;
4137 
4138  if (ulFlags & ~LOG_CONF_BITS)
4139  return CR_INVALID_FLAG;
4140 
4141  if (!IsValidDeviceInstanceID(pDeviceID))
4142  return CR_INVALID_DEVINST;
4143 
4144  ret = OpenConfigurationKey(pDeviceID,
4145  &hConfigKey);
4146  if (ret != CR_SUCCESS)
4147  {
4148  DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
4150  goto done;
4151  }
4152 
4153  ret = GetConfigurationData(hConfigKey,
4154  ulLogConfType,
4155  &RegDataType,
4156  &ulDataSize,
4157  &lpData);
4158  if (ret != CR_SUCCESS)
4159  {
4160  DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
4162  goto done;
4163  }
4164 
4165  DPRINT("Data size %lu\n", ulDataSize);
4166  if (ulDataSize == 0 || lpData == NULL)
4167  {
4168  DPRINT1("No config data available!\n");
4170  goto done;
4171  }
4172 
4173  /* Get the first tag */
4174  if (RegDataType == REG_RESOURCE_LIST)
4175  {
4176  DPRINT("REG_RESOURCE_LIST\n");
4177 
4178  DPRINT("ResourceList->Count %lu\n", ((PCM_RESOURCE_LIST)lpData)->Count);
4179  if (((PCM_RESOURCE_LIST)lpData)->Count == 0)
4180  {
4181  DPRINT1("No resource descriptors!\n");
4183  goto done;
4184  }
4185 
4186  DPRINT("lpData %p\n", lpData);
4187  DPRINT("&List[0] %p\n", &(((PCM_RESOURCE_LIST)lpData)->List[0]));
4188 
4189  *pulLogConfTag = (DWORD)((DWORD_PTR)&(((PCM_RESOURCE_LIST)lpData)->List[0]) - (DWORD_PTR)lpData);
4190  DPRINT("Offset (Tag): 0x%08lx\n", *pulLogConfTag);
4191  }
4192  else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
4193  {
4194  DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
4195  /* FIXME */
4197  goto done;
4198  }
4199 
4200 done:
4201  if (lpData != NULL)
4202  HeapFree(GetProcessHeap(), 0, lpData);
4203 
4204  if (hConfigKey != NULL)
4205  RegCloseKey(hConfigKey);
4206 
4207  DPRINT("PNP_GetFirstLogConf() returns %lu\n", ret);
4208 
4209  return ret;
4210 }
4211 
4212 
4213 /* Function 45 */
4214 DWORD
4215 WINAPI
4218  LPWSTR pDeviceID,
4219  DWORD ulLogConfType,
4220  DWORD ulCurrentTag,
4221  DWORD *pulNextTag,
4222  DWORD ulFlags)
4223 {
4224  HKEY hConfigKey = NULL;
4225  DWORD RegDataType = 0;
4226  ULONG ulDataSize = 0;
4227  LPBYTE lpData = NULL;
4229 
4230  DPRINT("PNP_GetNextLogConf(%p %S %lu %ul %p 0x%08lx)\n",
4231  hBinding, pDeviceID, ulLogConfType, ulCurrentTag, pulNextTag, ulFlags);
4232 
4233  if (pulNextTag == NULL)
4234  return CR_INVALID_POINTER;
4235 
4236  *pulNextTag = (DWORD)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  DPRINT("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  /* FIXME: Get the next tag */
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  DPRINT("PNP_GetNextLogConf() returns %lu\n", ret);
4298 
4299  return ret;
4300 }
4301 
4302 
4303 /* Function 46 */
4304 DWORD
4305 WINAPI
4308  LPWSTR pDeviceID,
4309  DWORD ulType,
4310  DWORD ulTag,
4311  DWORD *pPriority,
4312  DWORD ulFlags)
4313 {
4314  UNIMPLEMENTED;
4315  return CR_CALL_NOT_IMPLEMENTED;
4316 }
4317 
4318 
4319 /* Function 47 */
4320 DWORD
4321 WINAPI
4324  LPWSTR pDeviceID,
4325  DWORD ulLogConfTag,
4326  DWORD ulLogConfType,
4327  RESOURCEID ResourceID,
4328  DWORD *pulResourceTag,
4329  BYTE *ResourceData,
4330  PNP_RPC_BUFFER_SIZE ResourceLen,
4331  DWORD ulFlags)
4332 {
4333  UNIMPLEMENTED;
4334  return CR_CALL_NOT_IMPLEMENTED;
4335 }
4336 
4337 
4338 /* Function 48 */
4339 DWORD
4340 WINAPI
4343  LPWSTR pDeviceID,
4344  DWORD ulLogConfTag,
4345  DWORD ulLogConfType,
4346  RESOURCEID ResourceID,
4347  DWORD ulResourceTag,
4348  DWORD *pulPreviousResType,
4349  DWORD *pulPreviousResTag,
4350  DWORD ulFlags)
4351 {
4352  UNIMPLEMENTED;
4353  return CR_CALL_NOT_IMPLEMENTED;
4354 }
4355 
4356 
4357 /* Function 49 */
4358 DWORD
4359 WINAPI
4362  LPWSTR pDeviceID,
4363  DWORD ulLogConfTag,
4364  DWORD ulLogConfType,
4365  RESOURCEID ResourceID,
4366  DWORD ulResourceTag,
4367  DWORD *pulNextResType,
4368  DWORD *pulNextResTag,
4369  DWORD ulFlags)
4370 {
4371  HKEY hConfigKey = NULL;
4372  DWORD RegDataType = 0;
4373  ULONG ulDataSize = 0;
4374  LPBYTE lpData = NULL;
4376 
4377  DPRINT1("PNP_GetNextResDes(%p %S 0x%lx %lu %lu %ul %p %p 0x%08lx)\n",
4378  hBinding, pDeviceID, ulLogConfTag, ulLogConfType, ResourceID,
4379  ulResourceTag, pulNextResType, pulNextResTag, ulFlags);
4380 
4381  if (pulNextResType == NULL)
4382  return CR_INVALID_POINTER;
4383 
4384  *pulNextResType = 0;
4385 
4386  if (ulFlags != 0)
4387  return CR_INVALID_FLAG;
4388 
4389  if (!IsValidDeviceInstanceID(pDeviceID))
4390  return CR_INVALID_DEVINST;
4391 
4392  ret = OpenConfigurationKey(pDeviceID,
4393  &hConfigKey);
4394  if (ret != CR_SUCCESS)
4395  {
4396  DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
4398  goto done;
4399  }
4400 
4401  ret = GetConfigurationData(hConfigKey,
4402  ulLogConfType,
4403  &RegDataType,
4404  &ulDataSize,
4405  &lpData);
4406  if (ret != CR_SUCCESS)
4407  {
4408  DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
4410  goto done;
4411  }
4412 
4413  DPRINT1("Data size %lu\n", ulDataSize);
4414 
4415  if (ulDataSize == 0 || lpData == NULL)
4416  {
4417  DPRINT1("No config data available!\n");
4419  goto done;
4420  }
4421 
4422  /* Get the next resource descriptor */
4423  if (RegDataType == REG_RESOURCE_LIST)
4424  {
4425  DPRINT1("FIXME: REG_RESOURCE_LIST\n");
4426  /* FIXME */
4428  goto done;
4429  }
4430  else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
4431  {
4432  DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
4433  /* FIXME */
4435  goto done;
4436  }
4437 
4438 done:
4439  if (lpData != NULL)
4440  HeapFree(GetProcessHeap(), 0, lpData);
4441 
4442  if (hConfigKey != NULL)
4443  RegCloseKey(hConfigKey);
4444 
4445  DPRINT1("PNP_GetNextResDes() returns %lu\n", ret);
4446 
4447  return ret;
4448 }
4449 
4450 
4451 /* Function 50 */
4452 DWORD
4453 WINAPI
4456  LPWSTR pDeviceID,
4457  DWORD ulLogConfTag,
4458  DWORD ulLogConfType,
4459  RESOURCEID ResourceID,
4460  DWORD ulResourceTag,
4461  BYTE *Buffer,
4462  PNP_RPC_BUFFER_SIZE BufferLen,
4463  DWORD ulFlags)
4464 {
4465  UNIMPLEMENTED;
4466  return CR_CALL_NOT_IMPLEMENTED;
4467 }
4468 
4469 
4470 /* Function 51 */
4471 DWORD
4472 WINAPI
4475  LPWSTR pDeviceID,
4476  DWORD ulLogConfTag,
4477  DWORD ulLogConfType,
4478  RESOURCEID ResourceID,
4479  DWORD ulResourceTag,
4480  DWORD *pulSize,
4481  DWORD ulFlags)
4482 {
4483  UNIMPLEMENTED;
4484  return CR_CALL_NOT_IMPLEMENTED;
4485 }
4486 
4487 
4488 /* Function 52 */
4489 DWORD
4490 WINAPI
4493  LPWSTR pDeviceID,
4494  DWORD ulLogConfTag,
4495  DWORD ulLogConfType,
4496  RESOURCEID CurrentResourceID,
4497  RESOURCEID NewResourceID,
4498  DWORD ulResourceTag,
4499  BYTE *ResourceData,
4500  PNP_RPC_BUFFER_SIZE ResourceLen,
4501  DWORD ulFlags)
4502 {
4503  UNIMPLEMENTED;
4504  return CR_CALL_NOT_IMPLEMENTED;
4505 }
4506 
4507 
4508 /* Function 53 */
4509 DWORD
4510 WINAPI
4513  LPWSTR pDeviceID,
4514  RESOURCEID ResourceID,
4515  BYTE *ResourceData,
4516  PNP_RPC_BUFFER_SIZE ResourceLen,
4517  BOOL *pbConflictDetected,
4518  DWORD ulFlags)
4519 {
4520  DPRINT("PNP_DetectResourceConflict()\n");
4521 
4522  if (pbConflictDetected != NULL)
4523  *pbConflictDetected = FALSE;
4524 
4525  return CR_CALL_NOT_IMPLEMENTED;
4526 }
4527 
4528 
4529 /* Function 54 */
4530 DWORD
4531 WINAPI
4534  LPWSTR pDeviceID,
4535  RESOURCEID ResourceID,
4536  BYTE *ResourceData,
4537  PNP_RPC_BUFFER_SIZE ResourceLen,
4538  BYTE *Buffer,
4539  PNP_RPC_BUFFER_SIZE BufferLen,
4540  DWORD ulFlags)
4541 {
4542  UNIMPLEMENTED;
4543  return CR_CALL_NOT_IMPLEMENTED;
4544 }
4545 
4546 
4547 /* Function 55 */
4548 DWORD
4549 WINAPI
4552  DWORD ulHardwareProfile,
4553  DWORD ulFlags)
4554 {
4555  return CR_CALL_NOT_IMPLEMENTED;
4556 }
4557 
4558 
4559 /* Function 56 */
4560 DWORD
4561 WINAPI
4564  BYTE *pData,
4565  DWORD DataLen,
4566  LPWSTR pDeviceID,
4567  RESOURCEID ResourceID,
4568  DWORD ulFlags)
4569 {
4570  return CR_CALL_NOT_IMPLEMENTED;
4571 }
4572 
4573 
4574 /* Function 57 */
4575 DWORD
4576 WINAPI
4579  DWORD *pulSize,
4580  LPWSTR pDeviceID,
4581  RESOURCEID ResourceID,
4582  DWORD ulFlags)
4583 {
4584  if (pulSize != NULL)
4585  *pulSize = 0;
4586 
4587  return CR_CALL_NOT_IMPLEMENTED;
4588 }
4589 
4590 
4591 /* Function 58 */
4592 CONFIGRET
4593 WINAPI
4596  DWORD ulFlags)
4597 {
4598  return CR_CALL_NOT_IMPLEMENTED;
4599 }
4600 
4601 
4602 /* Function 59 */
4603 DWORD
4604 WINAPI
4607  DWORD ulUnknown2,
4608  LPWSTR pszName,
4609  BYTE *pNotificationFilter,
4610  DWORD ulNotificationFilterSize,
4611  DWORD ulFlags,
4612  PNP_NOTIFY_HANDLE *pNotifyHandle,
4613  DWORD ulUnknown8,
4614  DWORD *pulUnknown9)
4615 {
4616  PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface;
4617  PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle;
4618  PNOTIFY_ENTRY pNotifyData = NULL;
4619 
4620  DPRINT1("PNP_RegisterNotification(%p %lx '%S' %p %lu 0x%lx %p %lx %p)\n",
4621  hBinding, ulUnknown2, pszName, pNotificationFilter,
4622  ulNotificationFilterSize, ulFlags, pNotifyHandle, ulUnknown8, pulUnknown9);
4623 
4624  if (pNotifyHandle == NULL)
4625  return CR_INVALID_POINTER;
4626 
4627  *pNotifyHandle = NULL;
4628 
4629  if (pNotificationFilter == NULL ||
4630  pulUnknown9 == NULL)
4631  return CR_INVALID_POINTER;
4632 
4633  if (ulFlags & ~0x7)
4634  return CR_INVALID_FLAG;
4635 
4636  if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HDR)) ||
4637  (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR)))
4638  return CR_INVALID_DATA;
4639 
4640  if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
4641  {
4642  DPRINT1("DBT_DEVTYP_DEVICEINTERFACE\n");
4643  pBroadcastDeviceInterface = (PDEV_BROADCAST_DEVICEINTERFACE_W)pNotificationFilter;
4644 
4645  if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)) ||
4646  (pBroadcastDeviceInterface->dbcc_size < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)))
4647  return CR_INVALID_DATA;
4648 
4649  pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_ENTRY));
4650  if (pNotifyData == NULL)
4651  return CR_OUT_OF_MEMORY;
4652 
4653  if (pszName != NULL)
4654  {
4655  pNotifyData->pszName = RtlAllocateHeap(GetProcessHeap(),
4657  (wcslen(pszName) + 1) * sizeof(WCHAR));
4658  if (pNotifyData->pszName == NULL)
4659  {
4660  RtlFreeHeap(GetProcessHeap(), 0, pNotifyData);
4661  return CR_OUT_OF_MEMORY;
4662  }
4663  }
4664 
4665  /* Add the entry to the notification list */
4667 
4668  DPRINT("pNotifyData: %p\n", pNotifyData);
4669  *pNotifyHandle = (PNP_NOTIFY_HANDLE)pNotifyData;
4670  }
4671  else if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_HANDLE)
4672  {
4673  DPRINT1("DBT_DEVTYP_HANDLE\n");
4674  pBroadcastDeviceHandle = (PDEV_BROADCAST_HANDLE)pNotificationFilter;
4675 
4676  if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HANDLE)) ||
4677  (pBroadcastDeviceHandle->dbch_size < sizeof(DEV_BROADCAST_HANDLE)))
4678  return CR_INVALID_DATA;
4679 
4680  if (ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)
4681  return CR_INVALID_FLAG;
4682  }
4683  else
4684  {
4685  DPRINT1("Invalid device type %lu\n", ((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype);
4686  return CR_INVALID_DATA;
4687  }
4688 
4689  return CR_SUCCESS;
4690 }
4691 
4692 
4693 /* Function 60 */
4694 DWORD
4695 WINAPI
4698  PNP_NOTIFY_HANDLE *pNotifyHandle)
4699 {
4701 
4702  DPRINT1("PNP_UnregisterNotification(%p %p)\n",
4703  hBinding, pNotifyHandle);
4704 
4705  pEntry = (PNOTIFY_ENTRY)*pNotifyHandle;
4706  if (pEntry == NULL)
4707  return CR_INVALID_DATA;
4708 
4709  RemoveEntryList(&pEntry->ListEntry);
4710  if (pEntry->pszName)
4711  RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry->pszName);
4712  RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry);
4713  *pNotifyHandle = NULL;
4714 
4715  return CR_SUCCESS;
4716 }
4717 
4718 
4719 /* Function 61 */
4720 DWORD
4721 WINAPI
4724  LPWSTR pDeviceID,
4725  LPWSTR CustomPropName,
4726  DWORD *pulRegDataType,
4727  BYTE *Buffer,
4728  PNP_RPC_STRING_LEN *pulTransferLen,
4729  PNP_RPC_STRING_LEN *pulLength,
4730  DWORD ulFlags)
4731 {
4732  HKEY hDeviceKey = NULL;
4733  HKEY hParamKey = NULL;
4734  LONG lError;
4736 
4738 
4739  DPRINT("PNP_GetCustomDevProp() called\n");
4740 
4741  if (pulTransferLen == NULL || pulLength == NULL)
4742  {
4744  goto done;
4745  }
4746 
4747  if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
4748  {
4749  ret = CR_INVALID_FLAG;
4750  goto done;
4751  }
4752 
4753  if (!IsValidDeviceInstanceID(pDeviceID))
4754  return CR_INVALID_DEVINST;
4755 
4756  if (*pulLength < *pulTransferLen)
4757  *pulLength = *pulTransferLen;
4758 
4759  *pulTransferLen = 0;
4760 
4761  lError = RegOpenKeyExW(hEnumKey,
4762  pDeviceID,
4763  0,
4764  KEY_READ,
4765  &hDeviceKey);
4766  if (lError != ERROR_SUCCESS)
4767  {
4769  goto done;
4770  }
4771 
4772  lError = RegOpenKeyExW(hDeviceKey,
4773  L"Device Parameters",
4774  0,
4775  KEY_READ,
4776  &hParamKey);
4777  if (lError != ERROR_SUCCESS)
4778  {
4780  goto done;
4781  }
4782 
4783  lError = RegQueryValueExW(hParamKey,
4784  CustomPropName,
4785  NULL,
4786  pulRegDataType,
4787  Buffer,
4788  pulLength);
4789  if (lError != ERROR_SUCCESS)
4790  {
4791  if (lError == ERROR_MORE_DATA)
4792  {
4793  ret = CR_BUFFER_SMALL;
4794  }
4795  else
4796  {
4797  *pulLength = 0;
4799  }
4800  }
4801 
4802 done:
4803  if (ret == CR_SUCCESS)
4804  *pulTransferLen = *pulLength;
4805 
4806  if (hParamKey != NULL)
4807  RegCloseKey(hParamKey);
4808 
4809  if (hDeviceKey != NULL)
4810  RegCloseKey(hDeviceKey);
4811 
4812  DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret);
4813 
4814  return ret;
4815 }
4816 
4817 
4818 /* Function 62 */
4819 DWORD
4820 WINAPI
4823  WORD *pwVersion)
4824 {
4826 
4827  *pwVersion = 0x501;
4828  return CR_SUCCESS;
4829 }
4830 
4831 
4832 /* Function 63 */
4833 DWORD
4834 WINAPI
4837  BYTE *Buffer,
4838  PNP_RPC_BUFFER_SIZE *pulTransferLen,
4839  PNP_RPC_BUFFER_SIZE *pulLength,
4840  DWORD ulFlags)
4841 {
4842  UNIMPLEMENTED;
4843  return CR_CALL_NOT_IMPLEMENTED;
4844 }
4845 
4846 
4847 /* Function 64 */
4848 DWORD
4849 WINAPI
4852  DWORD *pulSSDIFlags,
4853  DWORD ulFlags)
4854 {
4856 
4857  DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
4858  hBinding, pulSSDIFlags, ulFlags);
4859 
4860  if (pulSSDIFlags == NULL)
4861  return CR_INVALID_POINTER;
4862 
4863  if (ulFlags != 0)
4864  return CR_INVALID_FLAG;
4865 
4866  /* FIXME */
4867  *pulSSDIFlags = 0;
4868 
4869  return CR_SUCCESS;
4870 }
4871 
4872 
4873 /* Function 65 */
4874 DWORD
4875 WINAPI
4879  DWORD ObjectType,
4880  LPWSTR PropertyCultureName,
4881  PNP_PROP_COUNT *PropertyCount,
4882  PNP_PROP_COUNT *TransferLen,
4883  DEVPROPKEY *PropertyKeys,
4884  DWORD Flags)
4885 {
4886  UNIMPLEMENTED;
4887  return CR_CALL_NOT_IMPLEMENTED;
4888 }
4889 
4890 
4891 /* Function 66 */
4892 DWORD
4893 WINAPI
4897  DWORD ObjectType,
4898  LPWSTR PropertyCultureName,
4899  const DEVPROPKEY *PropertyKey,
4901  PNP_PROP_SIZE *PropertySize,
4902  PNP_PROP_SIZE *TransferLen,
4904  DWORD Flags)
4905 {
4906  UNIMPLEMENTED;
4907  return CR_CALL_NOT_IMPLEMENTED;
4908 }
4909 
4910 
4911 /* Function 67 */
4912 DWORD
4913 WINAPI
4917  DWORD ObjectType,
4918  LPWSTR PropertyCultureName,
4919  const DEVPROPKEY *PropertyKey,
4921  PNP_PROP_SIZE PropertySize,
4923  DWORD Flags)
4924 {
4925  UNIMPLEMENTED;
4926  return CR_CALL_NOT_IMPLEMENTED;
4927 }
4928 
4929 
4930 /* Function 68 */
4931 DWORD
4932 WINAPI
4935 {
4936  UNIMPLEMENTED;
4937  return CR_CALL_NOT_IMPLEMENTED;
4938 }
4939 
4940 
4941 /* Function 69 */
4942 DWORD
4943 WINAPI
4946 {
4947  UNIMPLEMENTED;
4948  return CR_CALL_NOT_IMPLEMENTED;
4949 }
4950 
4951 
4952 /* Function 70 */
4953 DWORD
4954 WINAPI
4957 {
4958  UNIMPLEMENTED;
4959  return CR_CALL_NOT_IMPLEMENTED;
4960 }
4961 
4962 
4963 /* Function 71 */
4964 DWORD
4965 WINAPI
4968 {
4969  UNIMPLEMENTED;
4970  return CR_CALL_NOT_IMPLEMENTED;
4971 }
4972 
4973 
4974 /* Function 72 */
4975 DWORD
4976 WINAPI
4979 {
4980  UNIMPLEMENTED;
4981  return CR_CALL_NOT_IMPLEMENTED;
4982 }
4983 
4984 
4985 /* Function 73 */
4986 DWORD
4987 WINAPI
4990  LPWSTR pszFilter,
4991  DWORD ulFlags)
4992 {
4993  UNIMPLEMENTED;
4994  return CR_CALL_NOT_IMPLEMENTED;
4995 }
4996 
4997 
4998 /* Function 74 */
4999 DWORD
5000 WINAPI
5003 {
5004  UNIMPLEMENTED;
5005  return CR_CALL_NOT_IMPLEMENTED;
5006 }
#define RegQueryValueEx
Definition: winreg.h:524
#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:2527
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
static const WCHAR szName[]
Definition: powrprof.c:45
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:1718
#define CloseHandle
Definition: compat.h:739
#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:2360
#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:34
#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:4117
#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:4473
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:153
#define CM_DRP_REMOVAL_POLICY_HW_DEFAULT
Definition: cfgmgr32.h:720
#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:4216
#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
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
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:4532
#define CM_GETIDLIST_FILTER_NONE
Definition: cfgmgr32.h:654
static CONFIGRET SetupDeviceInstance(_In_ LPWSTR pszDeviceInstance, _In_ DWORD ulMinorAction)
Definition: rpcserver.c:3154
static CONFIGRET GetServiceInstanceListSize(_In_ PWSTR pszService, _Out_ PDWORD pulLength)
Definition: rpcserver.c:1396
_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:340
static CONFIGRET WINAPI NtStatusToCrError(NTSTATUS Status)
Definition: rpcserver.c:124
static CONFIGRET GetAllInstanceList(_Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength)
Definition: rpcserver.c:1223
#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:3052
_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:1608
#define TOKEN_ASSIGN_PRIMARY
Definition: setypes.h:921
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
DWORD WINAPI PNP_ReportLogOn(handle_t hBinding, BOOL Admin, DWORD ProcessId)
Definition: rpcserver.c:641
#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:4360
#define CR_ALREADY_SUCH_DEVINST
Definition: cfgmgr32.h:862
PWSTR pszName
Definition: precomp.h:45
#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:4966
UNICODE_STRING DeviceInstance
Definition: cmtypes.h:525
CONFIGRET GetEnumeratorInstanceList(_In_ PWSTR pszEnumerator, _Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength)
Definition: rpcserver.c:1152
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
#define InsertTailList(ListHead, Entry)
DWORD WINAPI PNP_RequestEjectPC(handle_t hBinding)
Definition: rpcserver.c:3836
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:1495
#define CR_ACCESS_DENIED
Definition: cfgmgr32.h:897
#define CM_GETIDLIST_FILTER_BUSRELATIONS
Definition: cfgmgr32.h:660
#define lstrlenW
Definition: compat.h:750
#define CM_DRP_REMOVAL_POLICY
Definition: cfgmgr32.h:719
DWORD WINAPI PNP_DeleteServiceDevices(handle_t hBinding)
Definition: rpcserver.c:5001
DWORD WINAPI PNP_GetServerSideDeviceInstallFlags(handle_t hBinding, DWORD *pulSSDIFlags, DWORD ulFlags)
Definition: rpcserver.c:4850
#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:2640
#define CM_SETUP_WRITE_LOG_CONFS
Definition: cfgmgr32.h:822
#define REG_RESOURCE_REQUIREMENTS_LIST
Definition: nt_native.h:1504
void * PNP_NOTIFY_HANDLE
Definition: pnp.idl:7
#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 CR_INVALID_DEVICE_ID
Definition: cfgmgr32.h:876
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#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:3337
#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:1761
#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:2375
#define CM_SETUP_DOWNLOAD
Definition: cfgmgr32.h:821
static CONFIGRET GetDeviceStatus(_In_ LPWSTR pszDeviceID, _Out_ DWORD *pulStatus, _Out_ DWORD *pulProblem)
Definition: rpcserver.c:229
#define L(x)
Definition: ntvdm.h:50
#define CM_REENUMERATE_BITS
Definition: cfgmgr32.h:793
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:429
DWORD WINAPI PNP_FreeLogConf(handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfType, DWORD ulLogConfTag, DWORD ulFlags)
Definition: rpcserver.c:4102
#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:4722
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:4341
static VOID AppendDeviceId(LPWSTR lpDeviceIdList, LPDWORD lpDeviceIdListSize, LPWSTR lpDeviceId)
Definition: rpcserver.c:3530
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:588
#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:3683
DWORD WINAPI PNP_InstallDevInst(handle_t hBinding)
Definition: rpcserver.c:4933
#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:3780
DWORD WINAPI PNP_CreateKey(handle_t hBinding, LPWSTR pszSubKey, DWORD samDesired, DWORD ulFlags)
Definition: rpcserver.c:2296
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:4322
static CONFIGRET GetRelationsInstanceListSize(_In_ PWSTR pszDevice, _In_ DWORD ulFlags, _Inout_ PDWORD pulLength)
Definition: rpcserver.c:1346
unsigned char BOOLEAN
static BOOL IsPresentDeviceInstanceID(_In_ LPWSTR pszDeviceInstanceID)
Definition: rpcserver.c:418
DWORD WINAPI PNP_SetActiveService(handle_t hBinding, LPWSTR pszFilter, DWORD ulFlags)
Definition: rpcserver.c:4988
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:4511
#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:851
DWORD WINAPI PNP_QueryArbitratorFreeData(handle_