1 /* 2 * ReactOS kernel 3 * Copyright (C) 2005 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* 20 * COPYRIGHT: See COPYING in the top level directory 21 * PROJECT: ReactOS kernel 22 * FILE: base/services/umpnpmgr/rpcserver.c 23 * PURPOSE: RPC server 24 * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org) 25 * Herv� Poussineau (hpoussin@reactos.org) 26 * Colin Finck (colin@reactos.org) 27 */ 28 29 /* INCLUDES *****************************************************************/ 30 31 #include "precomp.h" 32 33 #define NDEBUG 34 #include <debug.h> 35 36 37 /* GLOBALS ******************************************************************/ 38 39 static WCHAR szRootDeviceInstanceID[] = L"HTREE\\ROOT\\0"; 40 41 42 /* FUNCTIONS *****************************************************************/ 43 44 DWORD WINAPI 45 RpcServerThread(LPVOID lpParameter) 46 { 47 RPC_STATUS Status; 48 BOOLEAN RegisteredProtSeq = FALSE; 49 50 UNREFERENCED_PARAMETER(lpParameter); 51 52 DPRINT("RpcServerThread() called\n"); 53 54 #if 0 55 /* 2k/XP/2k3-compatible protocol sequence/endpoint */ 56 Status = RpcServerUseProtseqEpW(L"ncacn_np", 57 20, 58 L"\\pipe\\ntsvcs", 59 NULL); // Security descriptor 60 if (Status == RPC_S_OK) 61 RegisteredProtSeq = TRUE; 62 else 63 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status); 64 #endif 65 66 /* Vista/7-compatible protocol sequence/endpoint */ 67 Status = RpcServerUseProtseqEpW(L"ncacn_np", 68 20, 69 L"\\pipe\\plugplay", 70 NULL); // Security descriptor 71 if (Status == RPC_S_OK) 72 RegisteredProtSeq = TRUE; 73 else 74 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status); 75 76 /* Make sure there's a usable endpoint */ 77 if (RegisteredProtSeq == FALSE) 78 return 0; 79 80 Status = RpcServerRegisterIf(pnp_v1_0_s_ifspec, 81 NULL, 82 NULL); 83 if (Status != RPC_S_OK) 84 { 85 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status); 86 return 0; 87 } 88 89 Status = RpcServerListen(1, 90 20, 91 FALSE); 92 if (Status != RPC_S_OK) 93 { 94 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status); 95 return 0; 96 } 97 98 /* ROS HACK (this should never happen...) */ 99 DPRINT1("*** Other devices won't be installed correctly. If something\n"); 100 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n"); 101 102 DPRINT("RpcServerThread() done\n"); 103 104 return 0; 105 } 106 107 108 void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len) 109 { 110 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); 111 } 112 113 114 void __RPC_USER midl_user_free(void __RPC_FAR * ptr) 115 { 116 HeapFree(GetProcessHeap(), 0, ptr); 117 } 118 119 120 static CONFIGRET WINAPI 121 NtStatusToCrError(NTSTATUS Status) 122 { 123 switch (Status) 124 { 125 case STATUS_NOT_IMPLEMENTED: 126 return CR_CALL_NOT_IMPLEMENTED; 127 128 case STATUS_INVALID_PARAMETER: 129 return CR_INVALID_DATA; 130 131 case STATUS_NO_SUCH_DEVICE: 132 return CR_NO_SUCH_DEVINST; 133 134 case STATUS_ACCESS_DENIED: 135 return CR_ACCESS_DENIED; 136 137 case STATUS_BUFFER_TOO_SMALL: 138 return CR_BUFFER_SMALL; 139 140 case STATUS_OBJECT_NAME_NOT_FOUND: 141 return CR_NO_SUCH_VALUE; 142 143 default: 144 return CR_FAILURE; 145 } 146 } 147 148 149 static VOID 150 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID, 151 OUT LPWSTR pszEnumerator, 152 OUT LPWSTR pszDevice, 153 OUT LPWSTR pszInstance) 154 { 155 WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN]; 156 LPWSTR lpEnumerator = NULL; 157 LPWSTR lpDevice = NULL; 158 LPWSTR lpInstance = NULL; 159 LPWSTR ptr; 160 161 wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID); 162 163 *pszEnumerator = 0; 164 *pszDevice = 0; 165 *pszInstance = 0; 166 167 lpEnumerator = szLocalDeviceInstanceID; 168 169 ptr = wcschr(lpEnumerator, L'\\'); 170 if (ptr != NULL) 171 { 172 *ptr = 0; 173 lpDevice = ++ptr; 174 175 ptr = wcschr(lpDevice, L'\\'); 176 if (ptr != NULL) 177 { 178 *ptr = 0; 179 lpInstance = ++ptr; 180 } 181 } 182 183 if (lpEnumerator != NULL) 184 wcscpy(pszEnumerator, lpEnumerator); 185 186 if (lpDevice != NULL) 187 wcscpy(pszDevice, lpDevice); 188 189 if (lpInstance != NULL) 190 wcscpy(pszInstance, lpInstance); 191 } 192 193 194 static 195 CONFIGRET 196 GetDeviceStatus( 197 _In_ LPWSTR pDeviceID, 198 _Out_ DWORD *pulStatus, 199 _Out_ DWORD *pulProblem) 200 { 201 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData; 202 CONFIGRET ret = CR_SUCCESS; 203 NTSTATUS Status; 204 205 DPRINT("GetDeviceStatus(%S %p %p)\n", 206 pDeviceID, pulStatus, pulProblem); 207 208 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 209 pDeviceID); 210 PlugPlayData.Operation = 0; /* Get status */ 211 212 Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, 213 (PVOID)&PlugPlayData, 214 sizeof(PLUGPLAY_CONTROL_STATUS_DATA)); 215 if (NT_SUCCESS(Status)) 216 { 217 *pulStatus = PlugPlayData.DeviceStatus; 218 *pulProblem = PlugPlayData.DeviceProblem; 219 } 220 else 221 { 222 ret = NtStatusToCrError(Status); 223 } 224 225 return ret; 226 } 227 228 229 static 230 BOOL 231 IsValidDeviceInstanceID( 232 _In_ PWSTR pszDeviceInstanceID) 233 { 234 INT nPartLength[3] = {0, 0, 0}; 235 INT nLength = 0, nParts = 0; 236 PWCHAR p; 237 238 DPRINT("IsValidDeviceInstanceID(%S)\n", 239 pszDeviceInstanceID); 240 241 if (pszDeviceInstanceID == NULL) 242 { 243 DPRINT("Device instance ID is NULL!\n"); 244 return FALSE; 245 } 246 247 p = pszDeviceInstanceID; 248 while (*p != UNICODE_NULL) 249 { 250 if (*p == L'\\') 251 { 252 nParts++; 253 if (nParts >= 3) 254 { 255 DPRINT("Too many separators: %d\n", nParts); 256 return FALSE; 257 } 258 } 259 else 260 { 261 nPartLength[nParts]++; 262 } 263 264 nLength++; 265 if (nLength >= MAX_DEVICE_ID_LEN) 266 { 267 DPRINT("Too long: %d\n", nLength); 268 return FALSE; 269 } 270 271 p++; 272 } 273 274 if (nParts != 2) 275 { 276 DPRINT("Invalid number of separtors: %d\n", nParts); 277 return FALSE; 278 } 279 280 if ((nPartLength[0] == 0) || 281 (nPartLength[1] == 0) || 282 (nPartLength[2] == 0)) 283 { 284 DPRINT("Invalid part lengths: %d %d %d\n", 285 nPartLength[0], nPartLength[1], nPartLength[2]); 286 return FALSE; 287 } 288 289 DPRINT("Valid device instance ID!\n"); 290 291 return TRUE; 292 } 293 294 295 static 296 BOOL 297 IsRootDeviceInstanceID( 298 _In_ PWSTR pszDeviceInstanceID) 299 { 300 if (_wcsicmp(pszDeviceInstanceID, szRootDeviceInstanceID) == 0) 301 return TRUE; 302 303 return FALSE; 304 } 305 306 307 /* PUBLIC FUNCTIONS **********************************************************/ 308 309 /* Function 0 */ 310 DWORD 311 WINAPI 312 PNP_Disconnect( 313 handle_t hBinding) 314 { 315 UNREFERENCED_PARAMETER(hBinding); 316 return CR_SUCCESS; 317 } 318 319 320 /* Function 1 */ 321 DWORD 322 WINAPI 323 PNP_Connect( 324 handle_t hBinding) 325 { 326 UNREFERENCED_PARAMETER(hBinding); 327 return CR_SUCCESS; 328 } 329 330 331 /* Function 2 */ 332 DWORD 333 WINAPI 334 PNP_GetVersion( 335 handle_t hBinding, 336 WORD *pVersion) 337 { 338 UNREFERENCED_PARAMETER(hBinding); 339 340 *pVersion = 0x0400; 341 return CR_SUCCESS; 342 } 343 344 345 /* Function 3 */ 346 DWORD 347 WINAPI 348 PNP_GetGlobalState( 349 handle_t hBinding, 350 DWORD *pulState, 351 DWORD ulFlags) 352 { 353 UNREFERENCED_PARAMETER(hBinding); 354 UNREFERENCED_PARAMETER(ulFlags); 355 356 *pulState = CM_GLOBAL_STATE_CAN_DO_UI | CM_GLOBAL_STATE_SERVICES_AVAILABLE; 357 return CR_SUCCESS; 358 } 359 360 361 /* Function 4 */ 362 DWORD 363 WINAPI 364 PNP_InitDetection( 365 handle_t hBinding) 366 { 367 UNREFERENCED_PARAMETER(hBinding); 368 369 DPRINT("PNP_InitDetection() called\n"); 370 return CR_SUCCESS; 371 } 372 373 374 /* Function 5 */ 375 DWORD 376 WINAPI 377 PNP_ReportLogOn( 378 handle_t hBinding, 379 BOOL Admin, 380 DWORD ProcessId) 381 { 382 DWORD ReturnValue = CR_FAILURE; 383 HANDLE hProcess; 384 385 UNREFERENCED_PARAMETER(hBinding); 386 UNREFERENCED_PARAMETER(Admin); 387 388 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin, ProcessId); 389 390 /* Get the users token */ 391 hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcessId); 392 393 if (!hProcess) 394 { 395 DPRINT1("OpenProcess failed with error %u\n", GetLastError()); 396 goto cleanup; 397 } 398 399 if (hUserToken) 400 { 401 CloseHandle(hUserToken); 402 hUserToken = NULL; 403 } 404 405 if (!OpenProcessToken(hProcess, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY, &hUserToken)) 406 { 407 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError()); 408 goto cleanup; 409 } 410 411 /* Trigger the installer thread */ 412 if (hInstallEvent) 413 SetEvent(hInstallEvent); 414 415 ReturnValue = CR_SUCCESS; 416 417 cleanup: 418 if (hProcess) 419 CloseHandle(hProcess); 420 421 return ReturnValue; 422 } 423 424 425 /* Function 6 */ 426 DWORD 427 WINAPI 428 PNP_ValidateDeviceInstance( 429 handle_t hBinding, 430 LPWSTR pDeviceID, 431 DWORD ulFlags) 432 { 433 CONFIGRET ret = CR_SUCCESS; 434 HKEY hDeviceKey = NULL; 435 436 UNREFERENCED_PARAMETER(hBinding); 437 UNREFERENCED_PARAMETER(ulFlags); 438 439 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n", 440 pDeviceID, ulFlags); 441 442 if (!IsValidDeviceInstanceID(pDeviceID)) 443 return CR_INVALID_DEVINST; 444 445 if (RegOpenKeyExW(hEnumKey, 446 pDeviceID, 447 0, 448 KEY_READ, 449 &hDeviceKey)) 450 { 451 DPRINT("Could not open the Device Key!\n"); 452 ret = CR_NO_SUCH_DEVNODE; 453 goto Done; 454 } 455 456 /* FIXME: add more tests */ 457 458 Done: 459 if (hDeviceKey != NULL) 460 RegCloseKey(hDeviceKey); 461 462 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret); 463 464 return ret; 465 } 466 467 468 /* Function 7 */ 469 DWORD 470 WINAPI 471 PNP_GetRootDeviceInstance( 472 handle_t hBinding, 473 LPWSTR pDeviceID, 474 PNP_RPC_STRING_LEN ulLength) 475 { 476 CONFIGRET ret = CR_SUCCESS; 477 478 UNREFERENCED_PARAMETER(hBinding); 479 480 DPRINT("PNP_GetRootDeviceInstance() called\n"); 481 482 if (!pDeviceID) 483 { 484 ret = CR_INVALID_POINTER; 485 goto Done; 486 } 487 if (ulLength < lstrlenW(szRootDeviceInstanceID) + 1) 488 { 489 ret = CR_BUFFER_SMALL; 490 goto Done; 491 } 492 493 lstrcpyW(pDeviceID, 494 szRootDeviceInstanceID); 495 496 Done: 497 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret); 498 499 return ret; 500 } 501 502 503 /* Function 8 */ 504 DWORD 505 WINAPI 506 PNP_GetRelatedDeviceInstance( 507 handle_t hBinding, 508 DWORD ulRelationship, 509 LPWSTR pDeviceID, 510 LPWSTR pRelatedDeviceId, 511 PNP_RPC_STRING_LEN *pulLength, 512 DWORD ulFlags) 513 { 514 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData; 515 CONFIGRET ret = CR_SUCCESS; 516 NTSTATUS Status; 517 518 UNREFERENCED_PARAMETER(hBinding); 519 UNREFERENCED_PARAMETER(ulFlags); 520 521 DPRINT("PNP_GetRelatedDeviceInstance() called\n"); 522 DPRINT(" Relationship %ld\n", ulRelationship); 523 DPRINT(" DeviceId %S\n", pDeviceID); 524 525 if (!IsValidDeviceInstanceID(pDeviceID)) 526 return CR_INVALID_DEVINST; 527 528 RtlInitUnicodeString(&PlugPlayData.TargetDeviceInstance, 529 pDeviceID); 530 531 PlugPlayData.Relation = ulRelationship; 532 533 PlugPlayData.RelatedDeviceInstanceLength = *pulLength; 534 PlugPlayData.RelatedDeviceInstance = pRelatedDeviceId; 535 536 Status = NtPlugPlayControl(PlugPlayControlGetRelatedDevice, 537 (PVOID)&PlugPlayData, 538 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA)); 539 if (!NT_SUCCESS(Status)) 540 { 541 ret = NtStatusToCrError(Status); 542 } 543 544 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret); 545 if (ret == CR_SUCCESS) 546 { 547 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData.RelatedDeviceInstance); 548 } 549 550 return ret; 551 } 552 553 554 /* Function 9 */ 555 DWORD 556 WINAPI 557 PNP_EnumerateSubKeys( 558 handle_t hBinding, 559 DWORD ulBranch, 560 DWORD ulIndex, 561 LPWSTR Buffer, 562 PNP_RPC_STRING_LEN ulLength, 563 PNP_RPC_STRING_LEN *pulRequiredLen, 564 DWORD ulFlags) 565 { 566 CONFIGRET ret = CR_SUCCESS; 567 HKEY hKey; 568 DWORD dwError; 569 570 UNREFERENCED_PARAMETER(hBinding); 571 UNREFERENCED_PARAMETER(ulFlags); 572 573 DPRINT("PNP_EnumerateSubKeys() called\n"); 574 575 switch (ulBranch) 576 { 577 case PNP_ENUMERATOR_SUBKEYS: 578 hKey = hEnumKey; 579 break; 580 581 case PNP_CLASS_SUBKEYS: 582 hKey = hClassKey; 583 break; 584 585 default: 586 return CR_FAILURE; 587 } 588 589 *pulRequiredLen = ulLength; 590 dwError = RegEnumKeyExW(hKey, 591 ulIndex, 592 Buffer, 593 pulRequiredLen, 594 NULL, 595 NULL, 596 NULL, 597 NULL); 598 if (dwError != ERROR_SUCCESS) 599 { 600 ret = (dwError == ERROR_NO_MORE_ITEMS) ? CR_NO_SUCH_VALUE : CR_FAILURE; 601 } 602 else 603 { 604 (*pulRequiredLen)++; 605 } 606 607 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret); 608 609 return ret; 610 } 611 612 613 static 614 CONFIGRET 615 GetRelationsInstanceList( 616 _In_ PWSTR pszDevice, 617 _In_ DWORD ulFlags, 618 _Inout_ PWSTR pszBuffer, 619 _Inout_ PDWORD pulLength) 620 { 621 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData; 622 NTSTATUS Status; 623 CONFIGRET ret = CR_SUCCESS; 624 625 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 626 pszDevice); 627 628 if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS) 629 { 630 PlugPlayData.Relations = 3; 631 } 632 else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS) 633 { 634 PlugPlayData.Relations = 2; 635 } 636 else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS) 637 { 638 PlugPlayData.Relations = 1; 639 } 640 else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS) 641 { 642 PlugPlayData.Relations = 0; 643 } 644 645 PlugPlayData.BufferSize = *pulLength * sizeof(WCHAR); 646 PlugPlayData.Buffer = pszBuffer; 647 648 Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations, 649 (PVOID)&PlugPlayData, 650 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA)); 651 if (NT_SUCCESS(Status)) 652 { 653 *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR); 654 } 655 else 656 { 657 ret = NtStatusToCrError(Status); 658 } 659 660 return ret; 661 } 662 663 664 static 665 CONFIGRET 666 GetServiceInstanceList( 667 _In_ PWSTR pszService, 668 _Inout_ PWSTR pszBuffer, 669 _Inout_ PDWORD pulLength) 670 { 671 WCHAR szPathBuffer[512]; 672 WCHAR szName[16]; 673 HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL; 674 DWORD dwValues, dwSize, dwIndex, dwUsedLength, dwPathLength; 675 DWORD dwError; 676 PWSTR pPtr; 677 CONFIGRET ret = CR_SUCCESS; 678 679 /* Open the device key */ 680 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 681 L"System\\CurrentControlSet\\Services", 682 0, 683 KEY_READ, 684 &hServicesKey); 685 if (dwError != ERROR_SUCCESS) 686 { 687 DPRINT("Failed to open the services key (Error %lu)\n", dwError); 688 return CR_REGISTRY_ERROR; 689 } 690 691 dwError = RegOpenKeyExW(hServicesKey, 692 pszService, 693 0, 694 KEY_READ, 695 &hServiceKey); 696 if (dwError != ERROR_SUCCESS) 697 { 698 DPRINT("Failed to open the service key (Error %lu)\n", dwError); 699 ret = CR_REGISTRY_ERROR; 700 goto Done; 701 } 702 703 dwError = RegOpenKeyExW(hServiceKey, 704 L"Enum", 705 0, 706 KEY_READ, 707 &hEnumKey); 708 if (dwError != ERROR_SUCCESS) 709 { 710 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError); 711 ret = CR_REGISTRY_ERROR; 712 goto Done; 713 } 714 715 /* Retrieve the number of device instances */ 716 dwSize = sizeof(DWORD); 717 dwError = RegQueryValueExW(hEnumKey, 718 L"Count", 719 NULL, 720 NULL, 721 (LPBYTE)&dwValues, 722 &dwSize); 723 if (dwError != ERROR_SUCCESS) 724 { 725 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError); 726 dwValues = 1; 727 } 728 729 DPRINT("dwValues %lu\n", dwValues); 730 731 dwUsedLength = 0; 732 pPtr = pszBuffer; 733 734 for (dwIndex = 0; dwIndex < dwValues; dwIndex++) 735 { 736 wsprintf(szName, L"%lu", dwIndex); 737 738 dwSize = sizeof(szPathBuffer); 739 dwError = RegQueryValueExW(hEnumKey, 740 szName, 741 NULL, 742 NULL, 743 (LPBYTE)szPathBuffer, 744 &dwSize); 745 if (dwError != ERROR_SUCCESS) 746 break; 747 748 DPRINT("Path: %S\n", szPathBuffer); 749 750 dwPathLength = wcslen(szPathBuffer) + 1; 751 if (dwUsedLength + dwPathLength + 1 > *pulLength) 752 { 753 ret = CR_BUFFER_SMALL; 754 break; 755 } 756 757 wcscpy(pPtr, szPathBuffer); 758 dwUsedLength += dwPathLength; 759 pPtr += dwPathLength; 760 761 *pPtr = UNICODE_NULL; 762 } 763 764 Done: 765 if (hEnumKey != NULL) 766 RegCloseKey(hEnumKey); 767 768 if (hServiceKey != NULL) 769 RegCloseKey(hServiceKey); 770 771 if (hServicesKey != NULL) 772 RegCloseKey(hServicesKey); 773 774 if (ret == CR_SUCCESS) 775 *pulLength = dwUsedLength + 1; 776 else 777 *pulLength = 0; 778 779 return ret; 780 } 781 782 783 static 784 CONFIGRET 785 GetDeviceInstanceList( 786 _In_ PWSTR pszDevice, 787 _Inout_ PWSTR pszBuffer, 788 _Inout_ PDWORD pulLength) 789 { 790 WCHAR szInstanceBuffer[MAX_DEVICE_ID_LEN]; 791 WCHAR szPathBuffer[512]; 792 HKEY hDeviceKey; 793 DWORD dwInstanceLength, dwPathLength, dwUsedLength; 794 DWORD dwIndex, dwError; 795 PWSTR pPtr; 796 CONFIGRET ret = CR_SUCCESS; 797 798 /* Open the device key */ 799 dwError = RegOpenKeyExW(hEnumKey, 800 pszDevice, 801 0, 802 KEY_ENUMERATE_SUB_KEYS, 803 &hDeviceKey); 804 if (dwError != ERROR_SUCCESS) 805 { 806 DPRINT("Failed to open the device key (Error %lu)\n", dwError); 807 return CR_REGISTRY_ERROR; 808 } 809 810 dwUsedLength = 0; 811 pPtr = pszBuffer; 812 813 for (dwIndex = 0; ; dwIndex++) 814 { 815 dwInstanceLength = MAX_DEVICE_ID_LEN; 816 dwError = RegEnumKeyExW(hDeviceKey, 817 dwIndex, 818 szInstanceBuffer, 819 &dwInstanceLength, 820 NULL, 821 NULL, 822 NULL, 823 NULL); 824 if (dwError != ERROR_SUCCESS) 825 break; 826 827 wsprintf(szPathBuffer, L"%s\\%s", pszDevice, szInstanceBuffer); 828 DPRINT("Path: %S\n", szPathBuffer); 829 830 dwPathLength = wcslen(szPathBuffer) + 1; 831 if (dwUsedLength + dwPathLength + 1 > *pulLength) 832 { 833 ret = CR_BUFFER_SMALL; 834 break; 835 } 836 837 wcscpy(pPtr, szPathBuffer); 838 dwUsedLength += dwPathLength; 839 pPtr += dwPathLength; 840 841 *pPtr = UNICODE_NULL; 842 } 843 844 RegCloseKey(hDeviceKey); 845 846 if (ret == CR_SUCCESS) 847 *pulLength = dwUsedLength + 1; 848 else 849 *pulLength = 0; 850 851 return ret; 852 } 853 854 855 CONFIGRET 856 GetEnumeratorInstanceList( 857 _In_ PWSTR pszEnumerator, 858 _Inout_ PWSTR pszBuffer, 859 _Inout_ PDWORD pulLength) 860 { 861 WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN]; 862 WCHAR szPathBuffer[512]; 863 HKEY hEnumeratorKey; 864 PWSTR pPtr; 865 DWORD dwIndex, dwDeviceLength, dwUsedLength, dwRemainingLength, dwPathLength; 866 DWORD dwError; 867 CONFIGRET ret = CR_SUCCESS; 868 869 /* Open the enumerator key */ 870 dwError = RegOpenKeyExW(hEnumKey, 871 pszEnumerator, 872 0, 873 KEY_ENUMERATE_SUB_KEYS, 874 &hEnumeratorKey); 875 if (dwError != ERROR_SUCCESS) 876 { 877 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError); 878 return CR_REGISTRY_ERROR; 879 } 880 881 dwUsedLength = 0; 882 dwRemainingLength = *pulLength; 883 pPtr = pszBuffer; 884 885 for (dwIndex = 0; ; dwIndex++) 886 { 887 dwDeviceLength = MAX_DEVICE_ID_LEN; 888 dwError = RegEnumKeyExW(hEnumeratorKey, 889 dwIndex, 890 szDeviceBuffer, 891 &dwDeviceLength, 892 NULL, 893 NULL, 894 NULL, 895 NULL); 896 if (dwError != ERROR_SUCCESS) 897 break; 898 899 wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer); 900 DPRINT("Path: %S\n", szPathBuffer); 901 902 dwPathLength = dwRemainingLength; 903 ret = GetDeviceInstanceList(szPathBuffer, 904 pPtr, 905 &dwPathLength); 906 if (ret != CR_SUCCESS) 907 break; 908 909 dwUsedLength += dwPathLength - 1; 910 dwRemainingLength += dwPathLength - 1; 911 pPtr += dwPathLength - 1; 912 } 913 914 RegCloseKey(hEnumeratorKey); 915 916 if (ret == CR_SUCCESS) 917 *pulLength = dwUsedLength + 1; 918 else 919 *pulLength = 0; 920 921 return ret; 922 } 923 924 925 static 926 CONFIGRET 927 GetAllInstanceList( 928 _Inout_ PWSTR pszBuffer, 929 _Inout_ PDWORD pulLength) 930 { 931 WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN]; 932 PWSTR pPtr; 933 DWORD dwIndex, dwEnumeratorLength, dwUsedLength, dwRemainingLength, dwPathLength; 934 DWORD dwError; 935 CONFIGRET ret = CR_SUCCESS; 936 937 dwUsedLength = 0; 938 dwRemainingLength = *pulLength; 939 pPtr = pszBuffer; 940 941 for (dwIndex = 0; ; dwIndex++) 942 { 943 dwEnumeratorLength = MAX_DEVICE_ID_LEN; 944 dwError = RegEnumKeyExW(hEnumKey, 945 dwIndex, 946 szEnumeratorBuffer, 947 &dwEnumeratorLength, 948 NULL, NULL, NULL, NULL); 949 if (dwError != ERROR_SUCCESS) 950 break; 951 952 dwPathLength = dwRemainingLength; 953 ret = GetEnumeratorInstanceList(szEnumeratorBuffer, 954 pPtr, 955 &dwPathLength); 956 if (ret != CR_SUCCESS) 957 break; 958 959 dwUsedLength += dwPathLength - 1; 960 dwRemainingLength += dwPathLength - 1; 961 pPtr += dwPathLength - 1; 962 } 963 964 if (ret == CR_SUCCESS) 965 *pulLength = dwUsedLength + 1; 966 else 967 *pulLength = 0; 968 969 return ret; 970 } 971 972 973 /* Function 10 */ 974 DWORD 975 WINAPI 976 PNP_GetDeviceList( 977 handle_t hBinding, 978 LPWSTR pszFilter, 979 LPWSTR Buffer, 980 PNP_RPC_STRING_LEN *pulLength, 981 DWORD ulFlags) 982 { 983 WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; 984 WCHAR szDevice[MAX_DEVICE_ID_LEN]; 985 WCHAR szInstance[MAX_DEVICE_ID_LEN]; 986 CONFIGRET ret = CR_SUCCESS; 987 988 DPRINT("PNP_GetDeviceList() called\n"); 989 990 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS) 991 return CR_INVALID_FLAG; 992 993 if (pulLength == NULL) 994 return CR_INVALID_POINTER; 995 996 if ((ulFlags != CM_GETIDLIST_FILTER_NONE) && 997 (pszFilter == NULL)) 998 return CR_INVALID_POINTER; 999 1000 if (ulFlags & 1001 (CM_GETIDLIST_FILTER_BUSRELATIONS | 1002 CM_GETIDLIST_FILTER_POWERRELATIONS | 1003 CM_GETIDLIST_FILTER_REMOVALRELATIONS | 1004 CM_GETIDLIST_FILTER_EJECTRELATIONS)) 1005 { 1006 ret = GetRelationsInstanceList(pszFilter, 1007 ulFlags, 1008 Buffer, 1009 pulLength); 1010 } 1011 else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE) 1012 { 1013 ret = GetServiceInstanceList(pszFilter, 1014 Buffer, 1015 pulLength); 1016 } 1017 else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR) 1018 { 1019 SplitDeviceInstanceID(pszFilter, 1020 szEnumerator, 1021 szDevice, 1022 szInstance); 1023 1024 if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL) 1025 { 1026 ret = GetDeviceInstanceList(pszFilter, 1027 Buffer, 1028 pulLength); 1029 } 1030 else 1031 { 1032 ret = GetEnumeratorInstanceList(pszFilter, 1033 Buffer, 1034 pulLength); 1035 } 1036 } 1037 else /* CM_GETIDLIST_FILTER_NONE */ 1038 { 1039 ret = GetAllInstanceList(Buffer, 1040 pulLength); 1041 } 1042 1043 return ret; 1044 } 1045 1046 1047 static 1048 CONFIGRET 1049 GetRelationsInstanceListSize( 1050 _In_ PWSTR pszDevice, 1051 _In_ DWORD ulFlags, 1052 _Inout_ PDWORD pulLength) 1053 { 1054 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData; 1055 NTSTATUS Status; 1056 CONFIGRET ret = CR_SUCCESS; 1057 1058 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 1059 pszDevice); 1060 1061 if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS) 1062 { 1063 PlugPlayData.Relations = 3; 1064 } 1065 else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS) 1066 { 1067 PlugPlayData.Relations = 2; 1068 } 1069 else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS) 1070 { 1071 PlugPlayData.Relations = 1; 1072 } 1073 else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS) 1074 { 1075 PlugPlayData.Relations = 0; 1076 } 1077 1078 PlugPlayData.BufferSize = 0; 1079 PlugPlayData.Buffer = NULL; 1080 1081 Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations, 1082 (PVOID)&PlugPlayData, 1083 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA)); 1084 if (NT_SUCCESS(Status)) 1085 { 1086 *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR); 1087 } 1088 else 1089 { 1090 ret = NtStatusToCrError(Status); 1091 } 1092 1093 return ret; 1094 } 1095 1096 1097 static 1098 CONFIGRET 1099 GetServiceInstanceListSize( 1100 _In_ PWSTR pszService, 1101 _Out_ PDWORD pulLength) 1102 { 1103 HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL; 1104 DWORD dwValues, dwMaxValueLength, dwSize; 1105 DWORD dwError; 1106 CONFIGRET ret = CR_SUCCESS; 1107 1108 /* Open the device key */ 1109 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1110 L"System\\CurrentControlSet\\Services", 1111 0, 1112 KEY_READ, 1113 &hServicesKey); 1114 if (dwError != ERROR_SUCCESS) 1115 { 1116 DPRINT("Failed to open the services key (Error %lu)\n", dwError); 1117 return CR_REGISTRY_ERROR; 1118 } 1119 1120 dwError = RegOpenKeyExW(hServicesKey, 1121 pszService, 1122 0, 1123 KEY_READ, 1124 &hServiceKey); 1125 if (dwError != ERROR_SUCCESS) 1126 { 1127 DPRINT("Failed to open the service key (Error %lu)\n", dwError); 1128 ret = CR_REGISTRY_ERROR; 1129 goto Done; 1130 } 1131 1132 dwError = RegOpenKeyExW(hServiceKey, 1133 L"Enum", 1134 0, 1135 KEY_READ, 1136 &hEnumKey); 1137 if (dwError != ERROR_SUCCESS) 1138 { 1139 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError); 1140 ret = CR_REGISTRY_ERROR; 1141 goto Done; 1142 } 1143 1144 /* Retrieve the number of device instances */ 1145 dwSize = sizeof(DWORD); 1146 dwError = RegQueryValueExW(hEnumKey, 1147 L"Count", 1148 NULL, 1149 NULL, 1150 (LPBYTE)&dwValues, 1151 &dwSize); 1152 if (dwError != ERROR_SUCCESS) 1153 { 1154 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError); 1155 dwValues = 1; 1156 } 1157 1158 /* Retrieve the maximum instance name length */ 1159 dwError = RegQueryInfoKeyW(hEnumKey, 1160 NULL, 1161 NULL, 1162 NULL, 1163 NULL, 1164 NULL, 1165 NULL, 1166 NULL, 1167 NULL, 1168 &dwMaxValueLength, 1169 NULL, 1170 NULL); 1171 if (dwError != ERROR_SUCCESS) 1172 { 1173 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError); 1174 dwMaxValueLength = MAX_DEVICE_ID_LEN; 1175 } 1176 1177 DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues, dwMaxValueLength / sizeof(WCHAR)); 1178 1179 /* Return the largest possible buffer size */ 1180 *pulLength = dwValues * dwMaxValueLength / sizeof(WCHAR) + 2; 1181 1182 Done: 1183 if (hEnumKey != NULL) 1184 RegCloseKey(hEnumKey); 1185 1186 if (hServiceKey != NULL) 1187 RegCloseKey(hServiceKey); 1188 1189 if (hServicesKey != NULL) 1190 RegCloseKey(hServicesKey); 1191 1192 return ret; 1193 } 1194 1195 1196 static 1197 CONFIGRET 1198 GetDeviceInstanceListSize( 1199 _In_ LPCWSTR pszDevice, 1200 _Out_ PULONG pulLength) 1201 { 1202 HKEY hDeviceKey; 1203 DWORD dwSubKeys, dwMaxSubKeyLength; 1204 DWORD dwError; 1205 1206 /* Open the device key */ 1207 dwError = RegOpenKeyExW(hEnumKey, 1208 pszDevice, 1209 0, 1210 KEY_READ, 1211 &hDeviceKey); 1212 if (dwError != ERROR_SUCCESS) 1213 { 1214 DPRINT("Failed to open the device key (Error %lu)\n", dwError); 1215 return CR_REGISTRY_ERROR; 1216 } 1217 1218 /* Retrieve the number of device instances and the maximum name length */ 1219 dwError = RegQueryInfoKeyW(hDeviceKey, 1220 NULL, 1221 NULL, 1222 NULL, 1223 &dwSubKeys, 1224 &dwMaxSubKeyLength, 1225 NULL, 1226 NULL, 1227 NULL, 1228 NULL, 1229 NULL, 1230 NULL); 1231 if (dwError != ERROR_SUCCESS) 1232 { 1233 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError); 1234 dwSubKeys = 0; 1235 dwMaxSubKeyLength = 0; 1236 } 1237 1238 /* Close the device key */ 1239 RegCloseKey(hDeviceKey); 1240 1241 /* Return the largest possible buffer size */ 1242 *pulLength = dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1); 1243 1244 return CR_SUCCESS; 1245 } 1246 1247 1248 static 1249 CONFIGRET 1250 GetEnumeratorInstanceListSize( 1251 _In_ LPCWSTR pszEnumerator, 1252 _Out_ PULONG pulLength) 1253 { 1254 WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN]; 1255 WCHAR szPathBuffer[512]; 1256 HKEY hEnumeratorKey; 1257 DWORD dwIndex, dwDeviceLength, dwBufferLength; 1258 DWORD dwError; 1259 CONFIGRET ret = CR_SUCCESS; 1260 1261 *pulLength = 0; 1262 1263 /* Open the enumerator key */ 1264 dwError = RegOpenKeyExW(hEnumKey, 1265 pszEnumerator, 1266 0, 1267 KEY_ENUMERATE_SUB_KEYS, 1268 &hEnumeratorKey); 1269 if (dwError != ERROR_SUCCESS) 1270 { 1271 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError); 1272 return CR_REGISTRY_ERROR; 1273 } 1274 1275 for (dwIndex = 0; ; dwIndex++) 1276 { 1277 dwDeviceLength = MAX_DEVICE_ID_LEN; 1278 dwError = RegEnumKeyExW(hEnumeratorKey, 1279 dwIndex, 1280 szDeviceBuffer, 1281 &dwDeviceLength, 1282 NULL, 1283 NULL, 1284 NULL, 1285 NULL); 1286 if (dwError != ERROR_SUCCESS) 1287 break; 1288 1289 wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer); 1290 DPRINT("Path: %S\n", szPathBuffer); 1291 1292 ret = GetDeviceInstanceListSize(szPathBuffer, &dwBufferLength); 1293 if (ret != CR_SUCCESS) 1294 { 1295 *pulLength = 0; 1296 break; 1297 } 1298 1299 *pulLength += dwBufferLength; 1300 } 1301 1302 /* Close the enumerator key */ 1303 RegCloseKey(hEnumeratorKey); 1304 1305 return ret; 1306 } 1307 1308 1309 static 1310 CONFIGRET 1311 GetAllInstanceListSize( 1312 _Out_ PULONG pulLength) 1313 { 1314 WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN]; 1315 DWORD dwIndex, dwEnumeratorLength, dwBufferLength; 1316 DWORD dwError; 1317 CONFIGRET ret = CR_SUCCESS; 1318 1319 for (dwIndex = 0; ; dwIndex++) 1320 { 1321 dwEnumeratorLength = MAX_DEVICE_ID_LEN; 1322 dwError = RegEnumKeyExW(hEnumKey, 1323 dwIndex, 1324 szEnumeratorBuffer, 1325 &dwEnumeratorLength, 1326 NULL, NULL, NULL, NULL); 1327 if (dwError != ERROR_SUCCESS) 1328 break; 1329 1330 /* Get the size of all device instances for the enumerator */ 1331 ret = GetEnumeratorInstanceListSize(szEnumeratorBuffer, 1332 &dwBufferLength); 1333 if (ret != CR_SUCCESS) 1334 break; 1335 1336 *pulLength += dwBufferLength; 1337 } 1338 1339 return ret; 1340 } 1341 1342 1343 /* Function 11 */ 1344 DWORD 1345 WINAPI 1346 PNP_GetDeviceListSize( 1347 handle_t hBinding, 1348 LPWSTR pszFilter, 1349 PNP_RPC_BUFFER_SIZE *pulLength, 1350 DWORD ulFlags) 1351 { 1352 WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; 1353 WCHAR szDevice[MAX_DEVICE_ID_LEN]; 1354 WCHAR szInstance[MAX_DEVICE_ID_LEN]; 1355 CONFIGRET ret = CR_SUCCESS; 1356 1357 DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%lx)\n", 1358 hBinding, pszFilter, pulLength, ulFlags); 1359 1360 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS) 1361 return CR_INVALID_FLAG; 1362 1363 if (pulLength == NULL) 1364 return CR_INVALID_POINTER; 1365 1366 if ((ulFlags != CM_GETIDLIST_FILTER_NONE) && 1367 (pszFilter == NULL)) 1368 return CR_INVALID_POINTER; 1369 1370 *pulLength = 0; 1371 1372 if (ulFlags & 1373 (CM_GETIDLIST_FILTER_BUSRELATIONS | 1374 CM_GETIDLIST_FILTER_POWERRELATIONS | 1375 CM_GETIDLIST_FILTER_REMOVALRELATIONS | 1376 CM_GETIDLIST_FILTER_EJECTRELATIONS)) 1377 { 1378 ret = GetRelationsInstanceListSize(pszFilter, 1379 ulFlags, 1380 pulLength); 1381 } 1382 else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE) 1383 { 1384 ret = GetServiceInstanceListSize(pszFilter, 1385 pulLength); 1386 } 1387 else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR) 1388 { 1389 SplitDeviceInstanceID(pszFilter, 1390 szEnumerator, 1391 szDevice, 1392 szInstance); 1393 1394 if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL) 1395 { 1396 ret = GetDeviceInstanceListSize(pszFilter, 1397 pulLength); 1398 } 1399 else 1400 { 1401 ret = GetEnumeratorInstanceListSize(pszFilter, 1402 pulLength); 1403 } 1404 } 1405 else /* CM_GETIDLIST_FILTER_NONE */ 1406 { 1407 ret = GetAllInstanceListSize(pulLength); 1408 } 1409 1410 /* Add one character for the terminating double UNICODE_NULL */ 1411 if (ret == CR_SUCCESS) 1412 (*pulLength) += 1; 1413 1414 return ret; 1415 } 1416 1417 1418 /* Function 12 */ 1419 DWORD 1420 WINAPI 1421 PNP_GetDepth( 1422 handle_t hBinding, 1423 LPWSTR pszDeviceID, 1424 DWORD *pulDepth, 1425 DWORD ulFlags) 1426 { 1427 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData; 1428 CONFIGRET ret = CR_SUCCESS; 1429 NTSTATUS Status; 1430 1431 UNREFERENCED_PARAMETER(hBinding); 1432 UNREFERENCED_PARAMETER(ulFlags); 1433 1434 DPRINT("PNP_GetDepth() called\n"); 1435 1436 if (!IsValidDeviceInstanceID(pszDeviceID)) 1437 return CR_INVALID_DEVINST; 1438 1439 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 1440 pszDeviceID); 1441 1442 Status = NtPlugPlayControl(PlugPlayControlGetDeviceDepth, 1443 (PVOID)&PlugPlayData, 1444 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA)); 1445 if (NT_SUCCESS(Status)) 1446 { 1447 *pulDepth = PlugPlayData.Depth; 1448 } 1449 else 1450 { 1451 ret = NtStatusToCrError(Status); 1452 } 1453 1454 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret); 1455 1456 return ret; 1457 } 1458 1459 1460 /* Function 13 */ 1461 DWORD 1462 WINAPI 1463 PNP_GetDeviceRegProp( 1464 handle_t hBinding, 1465 LPWSTR pDeviceID, 1466 DWORD ulProperty, 1467 DWORD *pulRegDataType, 1468 BYTE *Buffer, 1469 PNP_PROP_SIZE *pulTransferLen, 1470 PNP_PROP_SIZE *pulLength, 1471 DWORD ulFlags) 1472 { 1473 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData; 1474 CONFIGRET ret = CR_SUCCESS; 1475 LPWSTR lpValueName = NULL; 1476 HKEY hKey = NULL; 1477 LONG lError; 1478 NTSTATUS Status; 1479 1480 UNREFERENCED_PARAMETER(hBinding); 1481 1482 DPRINT("PNP_GetDeviceRegProp() called\n"); 1483 1484 if (pulTransferLen == NULL || pulLength == NULL) 1485 { 1486 ret = CR_INVALID_POINTER; 1487 goto done; 1488 } 1489 1490 if (ulFlags != 0) 1491 { 1492 ret = CR_INVALID_FLAG; 1493 goto done; 1494 } 1495 1496 /* Check pDeviceID */ 1497 if (!IsValidDeviceInstanceID(pDeviceID)) 1498 { 1499 ret = CR_INVALID_DEVINST; 1500 goto done; 1501 } 1502 1503 if (*pulLength < *pulTransferLen) 1504 *pulLength = *pulTransferLen; 1505 1506 *pulTransferLen = 0; 1507 1508 switch (ulProperty) 1509 { 1510 case CM_DRP_DEVICEDESC: 1511 lpValueName = L"DeviceDesc"; 1512 break; 1513 1514 case CM_DRP_HARDWAREID: 1515 lpValueName = L"HardwareID"; 1516 break; 1517 1518 case CM_DRP_COMPATIBLEIDS: 1519 lpValueName = L"CompatibleIDs"; 1520 break; 1521 1522 case CM_DRP_SERVICE: 1523 lpValueName = L"Service"; 1524 break; 1525 1526 case CM_DRP_CLASS: 1527 lpValueName = L"Class"; 1528 break; 1529 1530 case CM_DRP_CLASSGUID: 1531 lpValueName = L"ClassGUID"; 1532 break; 1533 1534 case CM_DRP_DRIVER: 1535 lpValueName = L"Driver"; 1536 break; 1537 1538 case CM_DRP_CONFIGFLAGS: 1539 lpValueName = L"ConfigFlags"; 1540 break; 1541 1542 case CM_DRP_MFG: 1543 lpValueName = L"Mfg"; 1544 break; 1545 1546 case CM_DRP_FRIENDLYNAME: 1547 lpValueName = L"FriendlyName"; 1548 break; 1549 1550 case CM_DRP_LOCATION_INFORMATION: 1551 lpValueName = L"LocationInformation"; 1552 break; 1553 1554 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME: 1555 PlugPlayData.Property = PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME; 1556 break; 1557 1558 case CM_DRP_CAPABILITIES: 1559 lpValueName = L"Capabilities"; 1560 break; 1561 1562 case CM_DRP_UI_NUMBER: 1563 PlugPlayData.Property = PNP_PROPERTY_UI_NUMBER; 1564 break; 1565 1566 case CM_DRP_UPPERFILTERS: 1567 lpValueName = L"UpperFilters"; 1568 break; 1569 1570 case CM_DRP_LOWERFILTERS: 1571 lpValueName = L"LowerFilters"; 1572 break; 1573 1574 case CM_DRP_BUSTYPEGUID: 1575 PlugPlayData.Property = PNP_PROPERTY_BUSTYPEGUID; 1576 break; 1577 1578 case CM_DRP_LEGACYBUSTYPE: 1579 PlugPlayData.Property = PNP_PROPERTY_LEGACYBUSTYPE; 1580 break; 1581 1582 case CM_DRP_BUSNUMBER: 1583 PlugPlayData.Property = PNP_PROPERTY_BUSNUMBER; 1584 break; 1585 1586 case CM_DRP_ENUMERATOR_NAME: 1587 PlugPlayData.Property = PNP_PROPERTY_ENUMERATOR_NAME; 1588 break; 1589 1590 case CM_DRP_SECURITY: 1591 lpValueName = L"Security"; 1592 break; 1593 1594 case CM_DRP_DEVTYPE: 1595 lpValueName = L"DeviceType"; 1596 break; 1597 1598 case CM_DRP_EXCLUSIVE: 1599 lpValueName = L"Exclusive"; 1600 break; 1601 1602 case CM_DRP_CHARACTERISTICS: 1603 lpValueName = L"DeviceCharacteristics"; 1604 break; 1605 1606 case CM_DRP_ADDRESS: 1607 PlugPlayData.Property = PNP_PROPERTY_ADDRESS; 1608 break; 1609 1610 case CM_DRP_UI_NUMBER_DESC_FORMAT: 1611 lpValueName = L"UINumberDescFormat"; 1612 break; 1613 1614 case CM_DRP_DEVICE_POWER_DATA: 1615 PlugPlayData.Property = PNP_PROPERTY_POWER_DATA; 1616 break; 1617 1618 case CM_DRP_REMOVAL_POLICY: 1619 PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY; 1620 break; 1621 1622 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT: 1623 PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT; 1624 break; 1625 1626 case CM_DRP_REMOVAL_POLICY_OVERRIDE: 1627 lpValueName = L"RemovalPolicy"; 1628 break; 1629 1630 case CM_DRP_INSTALL_STATE: 1631 PlugPlayData.Property = PNP_PROPERTY_INSTALL_STATE; 1632 break; 1633 1634 #if (WINVER >= _WIN32_WINNT_WS03) 1635 case CM_DRP_LOCATION_PATHS: 1636 PlugPlayData.Property = PNP_PROPERTY_LOCATION_PATHS; 1637 break; 1638 #endif 1639 1640 #if (WINVER >= _WIN32_WINNT_WIN7) 1641 case CM_DRP_BASE_CONTAINERID: 1642 PlugPlayData.Property = PNP_PROPERTY_CONTAINERID; 1643 break; 1644 #endif 1645 1646 default: 1647 ret = CR_INVALID_PROPERTY; 1648 goto done; 1649 } 1650 1651 DPRINT("Value name: %S\n", lpValueName); 1652 1653 if (lpValueName) 1654 { 1655 /* Retrieve information from the Registry */ 1656 lError = RegOpenKeyExW(hEnumKey, 1657 pDeviceID, 1658 0, 1659 KEY_QUERY_VALUE, 1660 &hKey); 1661 if (lError != ERROR_SUCCESS) 1662 { 1663 hKey = NULL; 1664 *pulLength = 0; 1665 ret = CR_INVALID_DEVNODE; 1666 goto done; 1667 } 1668 1669 lError = RegQueryValueExW(hKey, 1670 lpValueName, 1671 NULL, 1672 pulRegDataType, 1673 Buffer, 1674 pulLength); 1675 if (lError != ERROR_SUCCESS) 1676 { 1677 if (lError == ERROR_MORE_DATA) 1678 { 1679 ret = CR_BUFFER_SMALL; 1680 } 1681 else 1682 { 1683 *pulLength = 0; 1684 ret = CR_NO_SUCH_VALUE; 1685 } 1686 } 1687 } 1688 else 1689 { 1690 /* Retrieve information from the Device Node */ 1691 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 1692 pDeviceID); 1693 PlugPlayData.Buffer = Buffer; 1694 PlugPlayData.BufferSize = *pulLength; 1695 1696 Status = NtPlugPlayControl(PlugPlayControlProperty, 1697 (PVOID)&PlugPlayData, 1698 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA)); 1699 if (NT_SUCCESS(Status)) 1700 { 1701 *pulLength = PlugPlayData.BufferSize; 1702 } 1703 else 1704 { 1705 ret = NtStatusToCrError(Status); 1706 } 1707 } 1708 1709 done: 1710 if (pulTransferLen) 1711 *pulTransferLen = (ret == CR_SUCCESS) ? *pulLength : 0; 1712 1713 if (hKey != NULL) 1714 RegCloseKey(hKey); 1715 1716 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret); 1717 1718 return ret; 1719 } 1720 1721 1722 /* Function 14 */ 1723 DWORD 1724 WINAPI 1725 PNP_SetDeviceRegProp( 1726 handle_t hBinding, 1727 LPWSTR pDeviceId, 1728 DWORD ulProperty, 1729 DWORD ulDataType, 1730 BYTE *Buffer, 1731 PNP_PROP_SIZE ulLength, 1732 DWORD ulFlags) 1733 { 1734 CONFIGRET ret = CR_SUCCESS; 1735 LPWSTR lpValueName = NULL; 1736 HKEY hKey = 0; 1737 1738 UNREFERENCED_PARAMETER(hBinding); 1739 UNREFERENCED_PARAMETER(ulFlags); 1740 1741 DPRINT("PNP_SetDeviceRegProp() called\n"); 1742 1743 DPRINT("DeviceId: %S\n", pDeviceId); 1744 DPRINT("Property: %lu\n", ulProperty); 1745 DPRINT("DataType: %lu\n", ulDataType); 1746 DPRINT("Length: %lu\n", ulLength); 1747 1748 if (!IsValidDeviceInstanceID(pDeviceId)) 1749 return CR_INVALID_DEVINST; 1750 1751 switch (ulProperty) 1752 { 1753 case CM_DRP_DEVICEDESC: 1754 lpValueName = L"DeviceDesc"; 1755 break; 1756 1757 case CM_DRP_HARDWAREID: 1758 lpValueName = L"HardwareID"; 1759 break; 1760 1761 case CM_DRP_COMPATIBLEIDS: 1762 lpValueName = L"CompatibleIDs"; 1763 break; 1764 1765 case CM_DRP_SERVICE: 1766 lpValueName = L"Service"; 1767 break; 1768 1769 case CM_DRP_CLASS: 1770 lpValueName = L"Class"; 1771 break; 1772 1773 case CM_DRP_CLASSGUID: 1774 lpValueName = L"ClassGUID"; 1775 break; 1776 1777 case CM_DRP_DRIVER: 1778 lpValueName = L"Driver"; 1779 break; 1780 1781 case CM_DRP_CONFIGFLAGS: 1782 lpValueName = L"ConfigFlags"; 1783 break; 1784 1785 case CM_DRP_MFG: 1786 lpValueName = L"Mfg"; 1787 break; 1788 1789 case CM_DRP_FRIENDLYNAME: 1790 lpValueName = L"FriendlyName"; 1791 break; 1792 1793 case CM_DRP_LOCATION_INFORMATION: 1794 lpValueName = L"LocationInformation"; 1795 break; 1796 1797 case CM_DRP_UPPERFILTERS: 1798 lpValueName = L"UpperFilters"; 1799 break; 1800 1801 case CM_DRP_LOWERFILTERS: 1802 lpValueName = L"LowerFilters"; 1803 break; 1804 1805 case CM_DRP_SECURITY: 1806 lpValueName = L"Security"; 1807 break; 1808 1809 case CM_DRP_DEVTYPE: 1810 lpValueName = L"DeviceType"; 1811 break; 1812 1813 case CM_DRP_EXCLUSIVE: 1814 lpValueName = L"Exclusive"; 1815 break; 1816 1817 case CM_DRP_CHARACTERISTICS: 1818 lpValueName = L"DeviceCharacteristics"; 1819 break; 1820 1821 case CM_DRP_UI_NUMBER_DESC_FORMAT: 1822 lpValueName = L"UINumberDescFormat"; 1823 break; 1824 1825 case CM_DRP_REMOVAL_POLICY_OVERRIDE: 1826 lpValueName = L"RemovalPolicy"; 1827 break; 1828 1829 default: 1830 return CR_INVALID_PROPERTY; 1831 } 1832 1833 DPRINT("Value name: %S\n", lpValueName); 1834 1835 if (RegOpenKeyExW(hEnumKey, 1836 pDeviceId, 1837 0, 1838 KEY_SET_VALUE, 1839 &hKey)) 1840 return CR_INVALID_DEVNODE; 1841 1842 if (ulLength == 0) 1843 { 1844 if (RegDeleteValueW(hKey, 1845 lpValueName)) 1846 ret = CR_REGISTRY_ERROR; 1847 } 1848 else 1849 { 1850 if (RegSetValueExW(hKey, 1851 lpValueName, 1852 0, 1853 ulDataType, 1854 Buffer, 1855 ulLength)) 1856 ret = CR_REGISTRY_ERROR; 1857 } 1858 1859 RegCloseKey(hKey); 1860 1861 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret); 1862 1863 return ret; 1864 } 1865 1866 1867 /* Function 15 */ 1868 DWORD 1869 WINAPI 1870 PNP_GetClassInstance( 1871 handle_t hBinding, 1872 LPWSTR pDeviceId, 1873 LPWSTR pszClassInstance, 1874 PNP_RPC_STRING_LEN ulLength) 1875 { 1876 WCHAR szClassGuid[40]; 1877 WCHAR szClassInstance[5]; 1878 HKEY hDeviceClassKey = NULL; 1879 HKEY hClassInstanceKey; 1880 ULONG ulTransferLength, ulDataLength; 1881 DWORD dwDataType, dwDisposition, i; 1882 DWORD dwError; 1883 CONFIGRET ret = CR_SUCCESS; 1884 1885 DPRINT("PNP_GetClassInstance(%p %S %p %lu)\n", 1886 hBinding, pDeviceId, pszClassInstance, ulLength); 1887 1888 if (!IsValidDeviceInstanceID(pDeviceId)) 1889 return CR_INVALID_DEVINST; 1890 1891 ulTransferLength = ulLength; 1892 ret = PNP_GetDeviceRegProp(hBinding, 1893 pDeviceId, 1894 CM_DRP_DRIVER, 1895 &dwDataType, 1896 (BYTE *)pszClassInstance, 1897 &ulTransferLength, 1898 &ulLength, 1899 0); 1900 if (ret == CR_SUCCESS) 1901 return ret; 1902 1903 ulTransferLength = sizeof(szClassGuid); 1904 ulDataLength = sizeof(szClassGuid); 1905 ret = PNP_GetDeviceRegProp(hBinding, 1906 pDeviceId, 1907 CM_DRP_CLASSGUID, 1908 &dwDataType, 1909 (BYTE *)szClassGuid, 1910 &ulTransferLength, 1911 &ulDataLength, 1912 0); 1913 if (ret != CR_SUCCESS) 1914 { 1915 DPRINT1("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret); 1916 goto done; 1917 } 1918 1919 dwError = RegOpenKeyExW(hClassKey, 1920 szClassGuid, 1921 0, 1922 KEY_READ, 1923 &hDeviceClassKey); 1924 if (dwError != ERROR_SUCCESS) 1925 { 1926 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError); 1927 ret = CR_FAILURE; 1928 goto done; 1929 } 1930 1931 for (i = 0; i < 10000; i++) 1932 { 1933 wsprintf(szClassInstance, L"%04lu", i); 1934 1935 dwError = RegCreateKeyExW(hDeviceClassKey, 1936 szClassInstance, 1937 0, 1938 NULL, 1939 REG_OPTION_NON_VOLATILE, 1940 KEY_ALL_ACCESS, 1941 NULL, 1942 &hClassInstanceKey, 1943 &dwDisposition); 1944 if (dwError == ERROR_SUCCESS) 1945 { 1946 RegCloseKey(hClassInstanceKey); 1947 1948 if (dwDisposition == REG_CREATED_NEW_KEY) 1949 { 1950 wsprintf(pszClassInstance, 1951 L"%s\\%s", 1952 szClassGuid, 1953 szClassInstance); 1954 1955 ulDataLength = (wcslen(pszClassInstance) + 1) * sizeof(WCHAR); 1956 ret = PNP_SetDeviceRegProp(hBinding, 1957 pDeviceId, 1958 CM_DRP_DRIVER, 1959 REG_SZ, 1960 (BYTE *)pszClassInstance, 1961 ulDataLength, 1962 0); 1963 if (ret != CR_SUCCESS) 1964 { 1965 DPRINT1("PNP_SetDeviceRegProp() failed (Error %lu)\n", ret); 1966 RegDeleteKeyW(hDeviceClassKey, 1967 szClassInstance); 1968 } 1969 1970 break; 1971 } 1972 } 1973 } 1974 1975 done: 1976 if (hDeviceClassKey != NULL) 1977 RegCloseKey(hDeviceClassKey); 1978 1979 return ret; 1980 } 1981 1982 1983 /* Function 16 */ 1984 DWORD 1985 WINAPI 1986 PNP_CreateKey( 1987 handle_t hBinding, 1988 LPWSTR pszSubKey, 1989 DWORD samDesired, 1990 DWORD ulFlags) 1991 { 1992 HKEY hKey = 0; 1993 1994 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, 1995 pszSubKey, 1996 0, 1997 NULL, 1998 0, 1999 KEY_ALL_ACCESS, 2000 NULL, 2001 &hKey, 2002 NULL)) 2003 return CR_REGISTRY_ERROR; 2004 2005 /* FIXME: Set security key */ 2006 2007 RegCloseKey(hKey); 2008 2009 return CR_SUCCESS; 2010 } 2011 2012 2013 /* Function 17 */ 2014 DWORD 2015 WINAPI 2016 PNP_DeleteRegistryKey( 2017 handle_t hBinding, 2018 LPWSTR pszDeviceID, 2019 LPWSTR pszParentKey, 2020 LPWSTR pszChildKey, 2021 DWORD ulFlags) 2022 { 2023 UNIMPLEMENTED; 2024 return CR_CALL_NOT_IMPLEMENTED; 2025 } 2026 2027 2028 /* Function 18 */ 2029 DWORD 2030 WINAPI 2031 PNP_GetClassCount( 2032 handle_t hBinding, 2033 DWORD *pulClassCount, 2034 DWORD ulFlags) 2035 { 2036 HKEY hKey; 2037 DWORD dwError; 2038 2039 UNREFERENCED_PARAMETER(hBinding); 2040 UNREFERENCED_PARAMETER(ulFlags); 2041 2042 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 2043 REGSTR_PATH_CLASS, 2044 0, 2045 KEY_QUERY_VALUE, 2046 &hKey); 2047 if (dwError != ERROR_SUCCESS) 2048 return CR_INVALID_DATA; 2049 2050 dwError = RegQueryInfoKeyW(hKey, 2051 NULL, 2052 NULL, 2053 NULL, 2054 pulClassCount, 2055 NULL, 2056 NULL, 2057 NULL, 2058 NULL, 2059 NULL, 2060 NULL, 2061 NULL); 2062 RegCloseKey(hKey); 2063 if (dwError != ERROR_SUCCESS) 2064 return CR_INVALID_DATA; 2065 2066 return CR_SUCCESS; 2067 } 2068 2069 2070 /* Function 19 */ 2071 DWORD 2072 WINAPI 2073 PNP_GetClassName( 2074 handle_t hBinding, 2075 LPWSTR pszClassGuid, 2076 LPWSTR Buffer, 2077 PNP_RPC_STRING_LEN *pulLength, 2078 DWORD ulFlags) 2079 { 2080 WCHAR szKeyName[MAX_PATH]; 2081 CONFIGRET ret = CR_SUCCESS; 2082 HKEY hKey; 2083 DWORD dwSize; 2084 2085 UNREFERENCED_PARAMETER(hBinding); 2086 UNREFERENCED_PARAMETER(ulFlags); 2087 2088 DPRINT("PNP_GetClassName() called\n"); 2089 2090 lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class\\"); 2091 if (lstrlenW(pszClassGuid) + 1 < sizeof(szKeyName)/sizeof(WCHAR)-(lstrlenW(szKeyName) * sizeof(WCHAR))) 2092 lstrcatW(szKeyName, pszClassGuid); 2093 else 2094 return CR_INVALID_DATA; 2095 2096 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 2097 szKeyName, 2098 0, 2099 KEY_QUERY_VALUE, 2100 &hKey)) 2101 return CR_REGISTRY_ERROR; 2102 2103 dwSize = *pulLength * sizeof(WCHAR); 2104 if (RegQueryValueExW(hKey, 2105 L"Class", 2106 NULL, 2107 NULL, 2108 (LPBYTE)Buffer, 2109 &dwSize)) 2110 { 2111 *pulLength = 0; 2112 ret = CR_REGISTRY_ERROR; 2113 } 2114 else 2115 { 2116 *pulLength = dwSize / sizeof(WCHAR); 2117 } 2118 2119 RegCloseKey(hKey); 2120 2121 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret); 2122 2123 return ret; 2124 } 2125 2126 2127 /* Function 20 */ 2128 DWORD 2129 WINAPI 2130 PNP_DeleteClassKey( 2131 handle_t hBinding, 2132 LPWSTR pszClassGuid, 2133 DWORD ulFlags) 2134 { 2135 CONFIGRET ret = CR_SUCCESS; 2136 2137 UNREFERENCED_PARAMETER(hBinding); 2138 2139 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid, ulFlags); 2140 2141 if (ulFlags & CM_DELETE_CLASS_SUBKEYS) 2142 { 2143 if (SHDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS) 2144 ret = CR_REGISTRY_ERROR; 2145 } 2146 else 2147 { 2148 if (RegDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS) 2149 ret = CR_REGISTRY_ERROR; 2150 } 2151 2152 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret); 2153 2154 return ret; 2155 } 2156 2157 2158 /* Function 21 */ 2159 DWORD 2160 WINAPI 2161 PNP_GetInterfaceDeviceAlias( 2162 handle_t hBinding, 2163 LPWSTR pszInterfaceDevice, 2164 GUID *AliasInterfaceGuid, 2165 LPWSTR pszAliasInterfaceDevice, 2166 PNP_RPC_STRING_LEN *pulLength, 2167 PNP_RPC_STRING_LEN *pulTransferLen, 2168 DWORD ulFlags) 2169 { 2170 UNIMPLEMENTED; 2171 return CR_CALL_NOT_IMPLEMENTED; 2172 } 2173 2174 2175 /* Function 22 */ 2176 DWORD 2177 WINAPI 2178 PNP_GetInterfaceDeviceList( 2179 handle_t hBinding, 2180 GUID *InterfaceGuid, 2181 LPWSTR pszDeviceID, 2182 BYTE *Buffer, 2183 PNP_RPC_BUFFER_SIZE *pulLength, 2184 DWORD ulFlags) 2185 { 2186 NTSTATUS Status; 2187 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData; 2188 DWORD ret = CR_SUCCESS; 2189 2190 UNREFERENCED_PARAMETER(hBinding); 2191 2192 if (!IsValidDeviceInstanceID(pszDeviceID)) 2193 return CR_INVALID_DEVINST; 2194 2195 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 2196 pszDeviceID); 2197 2198 PlugPlayData.Flags = ulFlags; 2199 PlugPlayData.FilterGuid = InterfaceGuid; 2200 PlugPlayData.Buffer = Buffer; 2201 PlugPlayData.BufferSize = *pulLength; 2202 2203 Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList, 2204 (PVOID)&PlugPlayData, 2205 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA)); 2206 if (NT_SUCCESS(Status)) 2207 { 2208 *pulLength = PlugPlayData.BufferSize; 2209 } 2210 else 2211 { 2212 ret = NtStatusToCrError(Status); 2213 } 2214 2215 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret); 2216 return ret; 2217 } 2218 2219 2220 /* Function 23 */ 2221 DWORD 2222 WINAPI 2223 PNP_GetInterfaceDeviceListSize( 2224 handle_t hBinding, 2225 PNP_RPC_BUFFER_SIZE *pulLen, 2226 GUID *InterfaceGuid, 2227 LPWSTR pszDeviceID, 2228 DWORD ulFlags) 2229 { 2230 NTSTATUS Status; 2231 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData; 2232 DWORD ret = CR_SUCCESS; 2233 2234 UNREFERENCED_PARAMETER(hBinding); 2235 2236 DPRINT("PNP_GetInterfaceDeviceListSize() called\n"); 2237 2238 if (!IsValidDeviceInstanceID(pszDeviceID)) 2239 return CR_INVALID_DEVINST; 2240 2241 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 2242 pszDeviceID); 2243 2244 PlugPlayData.FilterGuid = InterfaceGuid; 2245 PlugPlayData.Buffer = NULL; 2246 PlugPlayData.BufferSize = 0; 2247 PlugPlayData.Flags = ulFlags; 2248 2249 Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList, 2250 (PVOID)&PlugPlayData, 2251 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA)); 2252 if (NT_SUCCESS(Status)) 2253 { 2254 *pulLen = PlugPlayData.BufferSize; 2255 } 2256 else 2257 { 2258 ret = NtStatusToCrError(Status); 2259 } 2260 2261 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret); 2262 return ret; 2263 } 2264 2265 2266 /* Function 24 */ 2267 DWORD 2268 WINAPI 2269 PNP_RegisterDeviceClassAssociation( 2270 handle_t hBinding, 2271 LPWSTR pszDeviceID, 2272 GUID *InterfaceGuid, 2273 LPWSTR pszReference, 2274 LPWSTR pszSymLink, 2275 PNP_RPC_STRING_LEN *pulLength, 2276 PNP_RPC_STRING_LEN *pulTransferLen, 2277 DWORD ulFlags) 2278 { 2279 UNIMPLEMENTED; 2280 return CR_CALL_NOT_IMPLEMENTED; 2281 } 2282 2283 2284 /* Function 25 */ 2285 DWORD 2286 WINAPI 2287 PNP_UnregisterDeviceClassAssociation( 2288 handle_t hBinding, 2289 LPWSTR pszInterfaceDevice, 2290 DWORD ulFlags) 2291 { 2292 UNIMPLEMENTED; 2293 return CR_CALL_NOT_IMPLEMENTED; 2294 } 2295 2296 2297 /* Function 26 */ 2298 DWORD 2299 WINAPI 2300 PNP_GetClassRegProp( 2301 handle_t hBinding, 2302 LPWSTR pszClassGuid, 2303 DWORD ulProperty, 2304 DWORD *pulRegDataType, 2305 BYTE *Buffer, 2306 PNP_RPC_STRING_LEN *pulTransferLen, 2307 PNP_RPC_STRING_LEN *pulLength, 2308 DWORD ulFlags) 2309 { 2310 CONFIGRET ret = CR_SUCCESS; 2311 LPWSTR lpValueName = NULL; 2312 HKEY hInstKey = NULL; 2313 HKEY hPropKey = NULL; 2314 LONG lError; 2315 2316 UNREFERENCED_PARAMETER(hBinding); 2317 2318 DPRINT("PNP_GetClassRegProp() called\n"); 2319 2320 if (pulTransferLen == NULL || pulLength == NULL) 2321 { 2322 ret = CR_INVALID_POINTER; 2323 goto done; 2324 } 2325 2326 if (ulFlags != 0) 2327 { 2328 ret = CR_INVALID_FLAG; 2329 goto done; 2330 } 2331 2332 if (*pulLength < *pulTransferLen) 2333 *pulLength = *pulTransferLen; 2334 2335 *pulTransferLen = 0; 2336 2337 switch (ulProperty) 2338 { 2339 case CM_CRP_SECURITY: 2340 lpValueName = L"Security"; 2341 break; 2342 2343 case CM_CRP_DEVTYPE: 2344 lpValueName = L"DeviceType"; 2345 break; 2346 2347 case CM_CRP_EXCLUSIVE: 2348 lpValueName = L"Exclusive"; 2349 break; 2350 2351 case CM_CRP_CHARACTERISTICS: 2352 lpValueName = L"DeviceCharacteristics"; 2353 break; 2354 2355 default: 2356 ret = CR_INVALID_PROPERTY; 2357 goto done; 2358 } 2359 2360 DPRINT("Value name: %S\n", lpValueName); 2361 2362 lError = RegOpenKeyExW(hClassKey, 2363 pszClassGuid, 2364 0, 2365 KEY_READ, 2366 &hInstKey); 2367 if (lError != ERROR_SUCCESS) 2368 { 2369 *pulLength = 0; 2370 ret = CR_NO_SUCH_REGISTRY_KEY; 2371 goto done; 2372 } 2373 2374 lError = RegOpenKeyExW(hInstKey, 2375 L"Properties", 2376 0, 2377 KEY_READ, 2378 &hPropKey); 2379 if (lError != ERROR_SUCCESS) 2380 { 2381 *pulLength = 0; 2382 ret = CR_NO_SUCH_REGISTRY_KEY; 2383 goto done; 2384 } 2385 2386 lError = RegQueryValueExW(hPropKey, 2387 lpValueName, 2388 NULL, 2389 pulRegDataType, 2390 Buffer, 2391 pulLength); 2392 if (lError != ERROR_SUCCESS) 2393 { 2394 if (lError == ERROR_MORE_DATA) 2395 { 2396 ret = CR_BUFFER_SMALL; 2397 } 2398 else 2399 { 2400 *pulLength = 0; 2401 ret = CR_NO_SUCH_VALUE; 2402 } 2403 } 2404 2405 done: 2406 if (ret == CR_SUCCESS) 2407 *pulTransferLen = *pulLength; 2408 2409 if (hPropKey != NULL) 2410 RegCloseKey(hPropKey); 2411 2412 if (hInstKey != NULL) 2413 RegCloseKey(hInstKey); 2414 2415 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret); 2416 2417 return ret; 2418 } 2419 2420 2421 /* Function 27 */ 2422 DWORD 2423 WINAPI 2424 PNP_SetClassRegProp( 2425 handle_t hBinding, 2426 LPWSTR pszClassGuid, 2427 DWORD ulProperty, 2428 DWORD ulDataType, 2429 BYTE *Buffer, 2430 PNP_PROP_SIZE ulLength, 2431 DWORD ulFlags) 2432 { 2433 CONFIGRET ret = CR_SUCCESS; 2434 LPWSTR lpValueName = NULL; 2435 HKEY hInstKey = 0; 2436 HKEY hPropKey = 0; 2437 LONG lError; 2438 2439 UNREFERENCED_PARAMETER(hBinding); 2440 2441 DPRINT("PNP_SetClassRegProp() called\n"); 2442 2443 if (ulFlags != 0) 2444 return CR_INVALID_FLAG; 2445 2446 switch (ulProperty) 2447 { 2448 case CM_CRP_SECURITY: 2449 lpValueName = L"Security"; 2450 break; 2451 2452 case CM_CRP_DEVTYPE: 2453 lpValueName = L"DeviceType"; 2454 break; 2455 2456 case CM_CRP_EXCLUSIVE: 2457 lpValueName = L"Exclusive"; 2458 break; 2459 2460 case CM_CRP_CHARACTERISTICS: 2461 lpValueName = L"DeviceCharacteristics"; 2462 break; 2463 2464 default: 2465 return CR_INVALID_PROPERTY; 2466 } 2467 2468 lError = RegOpenKeyExW(hClassKey, 2469 pszClassGuid, 2470 0, 2471 KEY_WRITE, 2472 &hInstKey); 2473 if (lError != ERROR_SUCCESS) 2474 { 2475 ret = CR_NO_SUCH_REGISTRY_KEY; 2476 goto done; 2477 } 2478 2479 /* FIXME: Set security descriptor */ 2480 lError = RegCreateKeyExW(hInstKey, 2481 L"Properties", 2482 0, 2483 NULL, 2484 REG_OPTION_NON_VOLATILE, 2485 KEY_ALL_ACCESS, 2486 NULL, 2487 &hPropKey, 2488 NULL); 2489 if (lError != ERROR_SUCCESS) 2490 { 2491 ret = CR_REGISTRY_ERROR; 2492 goto done; 2493 } 2494 2495 if (ulLength == 0) 2496 { 2497 if (RegDeleteValueW(hPropKey, 2498 lpValueName)) 2499 ret = CR_REGISTRY_ERROR; 2500 } 2501 else 2502 { 2503 if (RegSetValueExW(hPropKey, 2504 lpValueName, 2505 0, 2506 ulDataType, 2507 Buffer, 2508 ulLength)) 2509 ret = CR_REGISTRY_ERROR; 2510 } 2511 2512 done: 2513 if (hPropKey != NULL) 2514 RegCloseKey(hPropKey); 2515 2516 if (hInstKey != NULL) 2517 RegCloseKey(hInstKey); 2518 2519 return ret; 2520 } 2521 2522 2523 static CONFIGRET 2524 CreateDeviceInstance(LPWSTR pszDeviceID) 2525 { 2526 WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; 2527 WCHAR szDevice[MAX_DEVICE_ID_LEN]; 2528 WCHAR szInstance[MAX_DEVICE_ID_LEN]; 2529 HKEY hKeyEnumerator; 2530 HKEY hKeyDevice; 2531 HKEY hKeyInstance; 2532 HKEY hKeyControl; 2533 LONG lError; 2534 2535 /* Split the instance ID */ 2536 SplitDeviceInstanceID(pszDeviceID, 2537 szEnumerator, 2538 szDevice, 2539 szInstance); 2540 2541 /* Open or create the enumerator key */ 2542 lError = RegCreateKeyExW(hEnumKey, 2543 szEnumerator, 2544 0, 2545 NULL, 2546 REG_OPTION_NON_VOLATILE, 2547 KEY_ALL_ACCESS, 2548 NULL, 2549 &hKeyEnumerator, 2550 NULL); 2551 if (lError != ERROR_SUCCESS) 2552 { 2553 return CR_REGISTRY_ERROR; 2554 } 2555 2556 /* Open or create the device key */ 2557 lError = RegCreateKeyExW(hKeyEnumerator, 2558 szDevice, 2559 0, 2560 NULL, 2561 REG_OPTION_NON_VOLATILE, 2562 KEY_ALL_ACCESS, 2563 NULL, 2564 &hKeyDevice, 2565 NULL); 2566 2567 /* Close the enumerator key */ 2568 RegCloseKey(hKeyEnumerator); 2569 2570 if (lError != ERROR_SUCCESS) 2571 { 2572 return CR_REGISTRY_ERROR; 2573 } 2574 2575 /* Try to open the instance key and fail if it exists */ 2576 lError = RegOpenKeyExW(hKeyDevice, 2577 szInstance, 2578 0, 2579 KEY_SET_VALUE, 2580 &hKeyInstance); 2581 if (lError == ERROR_SUCCESS) 2582 { 2583 DPRINT1("Instance %S already exists!\n", szInstance); 2584 RegCloseKey(hKeyInstance); 2585 RegCloseKey(hKeyDevice); 2586 return CR_ALREADY_SUCH_DEVINST; 2587 } 2588 2589 /* Create a new instance key */ 2590 lError = RegCreateKeyExW(hKeyDevice, 2591 szInstance, 2592 0, 2593 NULL, 2594 REG_OPTION_NON_VOLATILE, 2595 KEY_ALL_ACCESS, 2596 NULL, 2597 &hKeyInstance, 2598 NULL); 2599 2600 /* Close the device key */ 2601 RegCloseKey(hKeyDevice); 2602 2603 if (lError != ERROR_SUCCESS) 2604 { 2605 return CR_REGISTRY_ERROR; 2606 } 2607 2608 /* Create the 'Control' sub key */ 2609 lError = RegCreateKeyExW(hKeyInstance, 2610 L"Control", 2611 0, 2612 NULL, 2613 REG_OPTION_NON_VOLATILE, 2614 KEY_ALL_ACCESS, 2615 NULL, 2616 &hKeyControl, 2617 NULL); 2618 if (lError == ERROR_SUCCESS) 2619 { 2620 RegCloseKey(hKeyControl); 2621 } 2622 2623 RegCloseKey(hKeyInstance); 2624 2625 return (lError == ERROR_SUCCESS) ? CR_SUCCESS : CR_REGISTRY_ERROR; 2626 } 2627 2628 2629 /* Function 28 */ 2630 DWORD 2631 WINAPI 2632 PNP_CreateDevInst( 2633 handle_t hBinding, 2634 LPWSTR pszDeviceID, 2635 LPWSTR pszParentDeviceID, 2636 PNP_RPC_STRING_LEN ulLength, 2637 DWORD ulFlags) 2638 { 2639 CONFIGRET ret = CR_SUCCESS; 2640 2641 DPRINT("PNP_CreateDevInst(%p %S %S %lu 0x%08lx)\n", 2642 hBinding, pszParentDeviceID, pszDeviceID, ulLength, ulFlags); 2643 2644 if (ulFlags & ~CM_CREATE_DEVNODE_BITS) 2645 return CR_INVALID_FLAG; 2646 2647 if (pszDeviceID == NULL || pszParentDeviceID == NULL) 2648 return CR_INVALID_POINTER; 2649 2650 /* Fail, if the parent device is not the root device */ 2651 if (!IsRootDeviceInstanceID(pszParentDeviceID)) 2652 return CR_INVALID_DEVINST; 2653 2654 if (ulFlags & CM_CREATE_DEVNODE_GENERATE_ID) 2655 { 2656 WCHAR szGeneratedInstance[MAX_DEVICE_ID_LEN]; 2657 DWORD dwInstanceNumber; 2658 2659 /* Generated ID is: Root\<Device ID>\<Instance number> */ 2660 dwInstanceNumber = 0; 2661 do 2662 { 2663 swprintf(szGeneratedInstance, L"Root\\%ls\\%04lu", 2664 pszDeviceID, dwInstanceNumber); 2665 2666 /* Try to create a device instance with this ID */ 2667 ret = CreateDeviceInstance(szGeneratedInstance); 2668 2669 dwInstanceNumber++; 2670 } 2671 while (ret == CR_ALREADY_SUCH_DEVINST); 2672 2673 if (ret == CR_SUCCESS) 2674 { 2675 /* pszDeviceID is an out parameter too for generated IDs */ 2676 if (wcslen(szGeneratedInstance) > ulLength) 2677 { 2678 ret = CR_BUFFER_SMALL; 2679 } 2680 else 2681 { 2682 wcscpy(pszDeviceID, szGeneratedInstance); 2683 } 2684 } 2685 } 2686 else 2687 { 2688 /* Create the device instance */ 2689 ret = CreateDeviceInstance(pszDeviceID); 2690 } 2691 2692 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret); 2693 2694 return ret; 2695 } 2696 2697 2698 static CONFIGRET 2699 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination, 2700 LPWSTR pszDeviceInstanceSource) 2701 { 2702 DPRINT("MoveDeviceInstance: not implemented\n"); 2703 /* FIXME */ 2704 return CR_CALL_NOT_IMPLEMENTED; 2705 } 2706 2707 2708 static CONFIGRET 2709 SetupDeviceInstance(LPWSTR pszDeviceInstance, 2710 DWORD ulFlags) 2711 { 2712 DPRINT("SetupDeviceInstance: not implemented\n"); 2713 /* FIXME */ 2714 return CR_CALL_NOT_IMPLEMENTED; 2715 } 2716 2717 2718 static CONFIGRET 2719 EnableDeviceInstance(LPWSTR pszDeviceInstance) 2720 { 2721 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData; 2722 CONFIGRET ret = CR_SUCCESS; 2723 NTSTATUS Status; 2724 2725 DPRINT("Enable device instance %S\n", pszDeviceInstance); 2726 2727 RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, pszDeviceInstance); 2728 Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA)); 2729 if (!NT_SUCCESS(Status)) 2730 ret = NtStatusToCrError(Status); 2731 2732 return ret; 2733 } 2734 2735 2736 static CONFIGRET 2737 DisableDeviceInstance(LPWSTR pszDeviceInstance) 2738 { 2739 DPRINT("DisableDeviceInstance: not implemented\n"); 2740 /* FIXME */ 2741 return CR_CALL_NOT_IMPLEMENTED; 2742 } 2743 2744 2745 static CONFIGRET 2746 ReenumerateDeviceInstance( 2747 _In_ LPWSTR pszDeviceInstance, 2748 _In_ ULONG ulFlags) 2749 { 2750 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData; 2751 CONFIGRET ret = CR_SUCCESS; 2752 NTSTATUS Status; 2753 2754 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n", 2755 pszDeviceInstance, ulFlags); 2756 2757 if (ulFlags & ~CM_REENUMERATE_BITS) 2758 return CR_INVALID_FLAG; 2759 2760 if (ulFlags & CM_REENUMERATE_RETRY_INSTALLATION) 2761 { 2762 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n"); 2763 } 2764 2765 RtlInitUnicodeString(&EnumerateDeviceData.DeviceInstance, 2766 pszDeviceInstance); 2767 EnumerateDeviceData.Flags = 0; 2768 2769 Status = NtPlugPlayControl(PlugPlayControlEnumerateDevice, 2770 &EnumerateDeviceData, 2771 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA)); 2772 if (!NT_SUCCESS(Status)) 2773 ret = NtStatusToCrError(Status); 2774 2775 return ret; 2776 } 2777 2778 2779 /* Function 29 */ 2780 DWORD 2781 WINAPI 2782 PNP_DeviceInstanceAction( 2783 handle_t hBinding, 2784 DWORD ulAction, 2785 DWORD ulFlags, 2786 LPWSTR pszDeviceInstance1, 2787 LPWSTR pszDeviceInstance2) 2788 { 2789 CONFIGRET ret = CR_SUCCESS; 2790 2791 UNREFERENCED_PARAMETER(hBinding); 2792 2793 DPRINT("PNP_DeviceInstanceAction() called\n"); 2794 2795 switch (ulAction) 2796 { 2797 case PNP_DEVINST_MOVE: 2798 ret = MoveDeviceInstance(pszDeviceInstance1, 2799 pszDeviceInstance2); 2800 break; 2801 2802 case PNP_DEVINST_SETUP: 2803 ret = SetupDeviceInstance(pszDeviceInstance1, 2804 ulFlags); 2805 break; 2806 2807 case PNP_DEVINST_ENABLE: 2808 ret = EnableDeviceInstance(pszDeviceInstance1); 2809 break; 2810 2811 case PNP_DEVINST_DISABLE: 2812 ret = DisableDeviceInstance(pszDeviceInstance1); 2813 break; 2814 2815 case PNP_DEVINST_REENUMERATE: 2816 ret = ReenumerateDeviceInstance(pszDeviceInstance1, 2817 ulFlags); 2818 break; 2819 2820 default: 2821 DPRINT1("Unknown device action %lu: not implemented\n", ulAction); 2822 ret = CR_CALL_NOT_IMPLEMENTED; 2823 } 2824 2825 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret); 2826 2827 return ret; 2828 } 2829 2830 2831 /* Function 30 */ 2832 DWORD 2833 WINAPI 2834 PNP_GetDeviceStatus( 2835 handle_t hBinding, 2836 LPWSTR pDeviceID, 2837 DWORD *pulStatus, 2838 DWORD *pulProblem, 2839 DWORD ulFlags) 2840 { 2841 UNREFERENCED_PARAMETER(hBinding); 2842 UNREFERENCED_PARAMETER(ulFlags); 2843 2844 DPRINT("PNP_GetDeviceStatus(%p %S %p %p)\n", 2845 hBinding, pDeviceID, pulStatus, pulProblem, ulFlags); 2846 2847 if (!IsValidDeviceInstanceID(pDeviceID)) 2848 return CR_INVALID_DEVINST; 2849 2850 return GetDeviceStatus(pDeviceID, pulStatus, pulProblem); 2851 } 2852 2853 2854 /* Function 31 */ 2855 DWORD 2856 WINAPI 2857 PNP_SetDeviceProblem( 2858 handle_t hBinding, 2859 LPWSTR pDeviceID, 2860 DWORD ulProblem, 2861 DWORD ulFlags) 2862 { 2863 UNIMPLEMENTED; 2864 return CR_CALL_NOT_IMPLEMENTED; 2865 } 2866 2867 2868 /* Function 32 */ 2869 DWORD 2870 WINAPI 2871 PNP_DisableDevInst( 2872 handle_t hBinding, 2873 LPWSTR pDeviceID, 2874 PPNP_VETO_TYPE pVetoType, 2875 LPWSTR pszVetoName, 2876 DWORD ulNameLength, 2877 DWORD ulFlags) 2878 { 2879 UNIMPLEMENTED; 2880 return CR_CALL_NOT_IMPLEMENTED; 2881 } 2882 2883 /* Function 33 */ 2884 DWORD 2885 WINAPI 2886 PNP_UninstallDevInst( 2887 handle_t hBinding, 2888 LPWSTR pDeviceID, 2889 DWORD ulFlags) 2890 { 2891 UNIMPLEMENTED; 2892 return CR_CALL_NOT_IMPLEMENTED; 2893 } 2894 2895 2896 static BOOL 2897 CheckForDeviceId(LPWSTR lpDeviceIdList, 2898 LPWSTR lpDeviceId) 2899 { 2900 LPWSTR lpPtr; 2901 DWORD dwLength; 2902 2903 lpPtr = lpDeviceIdList; 2904 while (*lpPtr != 0) 2905 { 2906 dwLength = wcslen(lpPtr); 2907 if (0 == _wcsicmp(lpPtr, lpDeviceId)) 2908 return TRUE; 2909 2910 lpPtr += (dwLength + 1); 2911 } 2912 2913 return FALSE; 2914 } 2915 2916 2917 static VOID 2918 AppendDeviceId(LPWSTR lpDeviceIdList, 2919 LPDWORD lpDeviceIdListSize, 2920 LPWSTR lpDeviceId) 2921 { 2922 DWORD dwLen; 2923 DWORD dwPos; 2924 2925 dwLen = wcslen(lpDeviceId); 2926 dwPos = (*lpDeviceIdListSize / sizeof(WCHAR)) - 1; 2927 2928 wcscpy(&lpDeviceIdList[dwPos], lpDeviceId); 2929 2930 dwPos += (dwLen + 1); 2931 2932 lpDeviceIdList[dwPos] = 0; 2933 2934 *lpDeviceIdListSize = dwPos * sizeof(WCHAR); 2935 } 2936 2937 2938 /* Function 34 */ 2939 DWORD 2940 WINAPI 2941 PNP_AddID( 2942 handle_t hBinding, 2943 LPWSTR pszDeviceID, 2944 LPWSTR pszID, 2945 DWORD ulFlags) 2946 { 2947 CONFIGRET ret = CR_SUCCESS; 2948 HKEY hDeviceKey; 2949 LPWSTR pszSubKey; 2950 DWORD dwDeviceIdListSize; 2951 DWORD dwNewDeviceIdSize; 2952 WCHAR * pszDeviceIdList = NULL; 2953 2954 UNREFERENCED_PARAMETER(hBinding); 2955 2956 DPRINT("PNP_AddID() called\n"); 2957 DPRINT(" DeviceInstance: %S\n", pszDeviceID); 2958 DPRINT(" DeviceId: %S\n", pszID); 2959 DPRINT(" Flags: %lx\n", ulFlags); 2960 2961 if (RegOpenKeyExW(hEnumKey, 2962 pszDeviceID, 2963 0, 2964 KEY_QUERY_VALUE | KEY_SET_VALUE, 2965 &hDeviceKey) != ERROR_SUCCESS) 2966 { 2967 DPRINT("Failed to open the device key!\n"); 2968 return CR_INVALID_DEVNODE; 2969 } 2970 2971 pszSubKey = (ulFlags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID"; 2972 2973 if (RegQueryValueExW(hDeviceKey, 2974 pszSubKey, 2975 NULL, 2976 NULL, 2977 NULL, 2978 &dwDeviceIdListSize) != ERROR_SUCCESS) 2979 { 2980 DPRINT("Failed to query the desired ID string!\n"); 2981 ret = CR_REGISTRY_ERROR; 2982 goto Done; 2983 } 2984 2985 dwNewDeviceIdSize = lstrlenW(pszDeviceID); 2986 if (!dwNewDeviceIdSize) 2987 { 2988 ret = CR_INVALID_POINTER; 2989 goto Done; 2990 } 2991 2992 dwDeviceIdListSize += (dwNewDeviceIdSize + 2) * sizeof(WCHAR); 2993 2994 pszDeviceIdList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeviceIdListSize); 2995 if (!pszDeviceIdList) 2996 { 2997 DPRINT("Failed to allocate memory for the desired ID string!\n"); 2998 ret = CR_OUT_OF_MEMORY; 2999 goto Done; 3000 } 3001 3002 if (RegQueryValueExW(hDeviceKey, 3003 pszSubKey, 3004 NULL, 3005 NULL, 3006 (LPBYTE)pszDeviceIdList, 3007 &dwDeviceIdListSize) != ERROR_SUCCESS) 3008 { 3009 DPRINT("Failed to query the desired ID string!\n"); 3010 ret = CR_REGISTRY_ERROR; 3011 goto Done; 3012 } 3013 3014 /* Check whether the device ID is already in use */ 3015 if (CheckForDeviceId(pszDeviceIdList, pszDeviceID)) 3016 { 3017 DPRINT("Device ID was found in the ID string!\n"); 3018 ret = CR_SUCCESS; 3019 goto Done; 3020 } 3021 3022 /* Append the Device ID */ 3023 AppendDeviceId(pszDeviceIdList, &dwDeviceIdListSize, pszID); 3024 3025 if (RegSetValueExW(hDeviceKey, 3026 pszSubKey, 3027 0, 3028 REG_MULTI_SZ, 3029 (LPBYTE)pszDeviceIdList, 3030 dwDeviceIdListSize) != ERROR_SUCCESS) 3031 { 3032 DPRINT("Failed to set the desired ID string!\n"); 3033 ret = CR_REGISTRY_ERROR; 3034 } 3035 3036 Done: 3037 RegCloseKey(hDeviceKey); 3038 if (pszDeviceIdList) 3039 HeapFree(GetProcessHeap(), 0, pszDeviceIdList); 3040 3041 DPRINT("PNP_AddID() done (returns %lx)\n", ret); 3042 3043 return ret; 3044 } 3045 3046 3047 /* Function 35 */ 3048 DWORD 3049 WINAPI 3050 PNP_RegisterDriver( 3051 handle_t hBinding, 3052 LPWSTR pszDeviceID, 3053 DWORD ulFlags) 3054 { 3055 UNIMPLEMENTED; 3056 return CR_CALL_NOT_IMPLEMENTED; 3057 } 3058 3059 3060 /* Function 36 */ 3061 DWORD 3062 WINAPI 3063 PNP_QueryRemove( 3064 handle_t hBinding, 3065 LPWSTR pszDeviceID, 3066 PPNP_VETO_TYPE pVetoType, 3067 LPWSTR pszVetoName, 3068 DWORD ulNameLength, 3069 DWORD ulFlags) 3070 { 3071 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData; 3072 NTSTATUS Status; 3073 DWORD ret = CR_SUCCESS; 3074 3075 DPRINT1("PNP_QueryRemove(%p %S %p %p %lu 0x%lx)\n", 3076 hBinding, pszDeviceID, pVetoType, pszVetoName, 3077 ulNameLength, ulFlags); 3078 3079 if (ulFlags & ~CM_REMOVE_BITS) 3080 return CR_INVALID_FLAG; 3081 3082 if (!IsValidDeviceInstanceID(pszDeviceID) || 3083 IsRootDeviceInstanceID(pszDeviceID)) 3084 return CR_INVALID_DEVINST; 3085 3086 if (pVetoType != NULL) 3087 *pVetoType = PNP_VetoTypeUnknown; 3088 3089 if (pszVetoName != NULL && ulNameLength > 0) 3090 *pszVetoName = UNICODE_NULL; 3091 3092 RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData)); 3093 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 3094 pszDeviceID); 3095 PlugPlayData.VetoName = pszVetoName; 3096 PlugPlayData.NameLength = ulNameLength; 3097 // PlugPlayData.Flags = 3098 3099 Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice, 3100 &PlugPlayData, 3101 sizeof(PlugPlayData)); 3102 if (!NT_SUCCESS(Status)) 3103 ret = NtStatusToCrError(Status); 3104 3105 return ret; 3106 } 3107 3108 3109 /* Function 37 */ 3110 DWORD 3111 WINAPI 3112 PNP_RequestDeviceEject( 3113 handle_t hBinding, 3114 LPWSTR pszDeviceID, 3115 PPNP_VETO_TYPE pVetoType, 3116 LPWSTR pszVetoName, 3117 DWORD ulNameLength, 3118 DWORD ulFlags) 3119 { 3120 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData; 3121 NTSTATUS Status; 3122 DWORD ret = CR_SUCCESS; 3123 3124 DPRINT1("PNP_RequestDeviceEject(%p %S %p %p %lu 0x%lx)\n", 3125 hBinding, pszDeviceID, pVetoType, pszVetoName, 3126 ulNameLength, ulFlags); 3127 3128 if (ulFlags != 0) 3129 return CR_INVALID_FLAG; 3130 3131 if (!IsValidDeviceInstanceID(pszDeviceID)) 3132 return CR_INVALID_DEVINST; 3133 3134 if (pVetoType != NULL) 3135 *pVetoType = PNP_VetoTypeUnknown; 3136 3137 if (pszVetoName != NULL && ulNameLength > 0) 3138 *pszVetoName = UNICODE_NULL; 3139 3140 RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData)); 3141 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 3142 pszDeviceID); 3143 PlugPlayData.VetoName = pszVetoName; 3144 PlugPlayData.NameLength = ulNameLength; 3145 // PlugPlayData.Flags = 3146 3147 Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice, 3148 &PlugPlayData, 3149 sizeof(PlugPlayData)); 3150 if (!NT_SUCCESS(Status)) 3151 ret = NtStatusToCrError(Status); 3152 3153 return ret; 3154 } 3155 3156 3157 /* Function 38 */ 3158 CONFIGRET 3159 WINAPI 3160 PNP_IsDockStationPresent( 3161 handle_t hBinding, 3162 BOOL *Present) 3163 { 3164 HKEY hKey; 3165 DWORD dwType; 3166 DWORD dwValue; 3167 DWORD dwSize; 3168 CONFIGRET ret = CR_SUCCESS; 3169 3170 UNREFERENCED_PARAMETER(hBinding); 3171 3172 DPRINT1("PNP_IsDockStationPresent() called\n"); 3173 3174 *Present = FALSE; 3175 3176 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG, 3177 L"CurrentDockInfo", 3178 0, 3179 KEY_READ, 3180 &hKey) != ERROR_SUCCESS) 3181 return CR_REGISTRY_ERROR; 3182 3183 dwSize = sizeof(DWORD); 3184 if (RegQueryValueExW(hKey, 3185 L"DockingState", 3186 NULL, 3187 &dwType, 3188 (LPBYTE)&dwValue, 3189 &dwSize) != ERROR_SUCCESS) 3190 ret = CR_REGISTRY_ERROR; 3191 3192 RegCloseKey(hKey); 3193 3194 if (ret == CR_SUCCESS) 3195 { 3196 if (dwType != REG_DWORD || dwSize != sizeof(DWORD)) 3197 { 3198 ret = CR_REGISTRY_ERROR; 3199 } 3200 else if (dwValue != 0) 3201 { 3202 *Present = TRUE; 3203 } 3204 } 3205 3206 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret); 3207 3208 return ret; 3209 } 3210 3211 3212 /* Function 39 */ 3213 DWORD 3214 WINAPI 3215 PNP_RequestEjectPC( 3216 handle_t hBinding) 3217 { 3218 WCHAR szDockDeviceInstance[MAX_DEVICE_ID_LEN]; 3219 PLUGPLAY_CONTROL_RETRIEVE_DOCK_DATA DockData; 3220 NTSTATUS Status; 3221 3222 DPRINT("PNP_RequestEjectPC(%p)\n", hBinding); 3223 3224 /* Retrieve the dock device */ 3225 DockData.DeviceInstanceLength = ARRAYSIZE(szDockDeviceInstance); 3226 DockData.DeviceInstance = szDockDeviceInstance; 3227 3228 Status = NtPlugPlayControl(PlugPlayControlRetrieveDock, 3229 &DockData, 3230 sizeof(DockData)); 3231 if (!NT_SUCCESS(Status)) 3232 return NtStatusToCrError(Status); 3233 3234 /* Eject the dock device */ 3235 return PNP_RequestDeviceEject(hBinding, 3236 szDockDeviceInstance, 3237 NULL, 3238 NULL, 3239 0, 3240 0); 3241 } 3242 3243 3244 /* Function 40 */ 3245 DWORD 3246 WINAPI 3247 PNP_HwProfFlags( 3248 handle_t hBinding, 3249 DWORD ulAction, 3250 LPWSTR pDeviceID, 3251 DWORD ulConfig, 3252 DWORD *pulValue, 3253 PPNP_VETO_TYPE pVetoType, 3254 LPWSTR pszVetoName, 3255 DWORD ulNameLength, 3256 DWORD ulFlags) 3257 { 3258 CONFIGRET ret = CR_SUCCESS; 3259 WCHAR szKeyName[MAX_PATH]; 3260 HKEY hKey; 3261 HKEY hDeviceKey; 3262 DWORD dwSize; 3263 3264 UNREFERENCED_PARAMETER(hBinding); 3265 3266 DPRINT("PNP_HwProfFlags() called\n"); 3267 3268 if (!IsValidDeviceInstanceID(pDeviceID)) 3269 return CR_INVALID_DEVINST; 3270 3271 if (ulConfig == 0) 3272 { 3273 wcscpy(szKeyName, 3274 L"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum"); 3275 } 3276 else 3277 { 3278 swprintf(szKeyName, 3279 L"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum", 3280 ulConfig); 3281 } 3282 3283 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 3284 szKeyName, 3285 0, 3286 KEY_QUERY_VALUE, 3287 &hKey) != ERROR_SUCCESS) 3288 return CR_REGISTRY_ERROR; 3289 3290 if (ulAction == PNP_GET_HWPROFFLAGS) 3291 { 3292 if (RegOpenKeyExW(hKey, 3293 pDeviceID, 3294 0, 3295 KEY_QUERY_VALUE, 3296 &hDeviceKey) != ERROR_SUCCESS) 3297 { 3298 *pulValue = 0; 3299 } 3300 else 3301 { 3302 dwSize = sizeof(DWORD); 3303 if (RegQueryValueExW(hDeviceKey, 3304 L"CSConfigFlags", 3305 NULL, 3306 NULL, 3307 (LPBYTE)pulValue, 3308 &dwSize) != ERROR_SUCCESS) 3309 { 3310 *pulValue = 0; 3311 } 3312 3313 RegCloseKey(hDeviceKey); 3314 } 3315 } 3316 else if (ulAction == PNP_SET_HWPROFFLAGS) 3317 { 3318 /* FIXME: not implemented yet */ 3319 ret = CR_CALL_NOT_IMPLEMENTED; 3320 } 3321 3322 RegCloseKey(hKey); 3323 3324 return ret; 3325 } 3326 3327 3328 /* Function 41 */ 3329 DWORD 3330 WINAPI 3331 PNP_GetHwProfInfo( 3332 handle_t hBinding, 3333 DWORD ulIndex, 3334 HWPROFILEINFO *pHWProfileInfo, 3335 DWORD ulProfileInfoSize, 3336 DWORD ulFlags) 3337 { 3338 WCHAR szProfileName[5]; 3339 HKEY hKeyConfig = NULL; 3340 HKEY hKeyProfiles = NULL; 3341 HKEY hKeyProfile = NULL; 3342 DWORD dwDisposition; 3343 DWORD dwSize; 3344 LONG lError; 3345 CONFIGRET ret = CR_SUCCESS; 3346 3347 UNREFERENCED_PARAMETER(hBinding); 3348 3349 DPRINT("PNP_GetHwProfInfo() called\n"); 3350 3351 if (ulProfileInfoSize == 0) 3352 { 3353 ret = CR_INVALID_DATA; 3354 goto done; 3355 } 3356 3357 if (ulFlags != 0) 3358 { 3359 ret = CR_INVALID_FLAG; 3360 goto done; 3361 } 3362 3363 /* Initialize the profile information */ 3364 pHWProfileInfo->HWPI_ulHWProfile = 0; 3365 pHWProfileInfo->HWPI_szFriendlyName[0] = 0; 3366 pHWProfileInfo->HWPI_dwFlags = 0; 3367 3368 /* Open the 'IDConfigDB' key */ 3369 lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE, 3370 L"System\\CurrentControlSet\\Control\\IDConfigDB", 3371 0, 3372 NULL, 3373 REG_OPTION_NON_VOLATILE, 3374 KEY_QUERY_VALUE, 3375 NULL, 3376 &hKeyConfig, 3377 &dwDisposition); 3378 if (lError != ERROR_SUCCESS) 3379 { 3380 ret = CR_REGISTRY_ERROR; 3381 goto done; 3382 } 3383 3384 /* Open the 'Hardware Profiles' subkey */ 3385 lError = RegCreateKeyExW(hKeyConfig, 3386 L"Hardware Profiles", 3387 0, 3388 NULL, 3389 REG_OPTION_NON_VOLATILE, 3390 KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, 3391 NULL, 3392 &hKeyProfiles, 3393 &dwDisposition); 3394 if (lError != ERROR_SUCCESS) 3395 { 3396 ret = CR_REGISTRY_ERROR; 3397 goto done; 3398 } 3399 3400 if (ulIndex == (ULONG)-1) 3401 { 3402 dwSize = sizeof(ULONG); 3403 lError = RegQueryValueExW(hKeyConfig, 3404 L"CurrentConfig", 3405 NULL, 3406 NULL, 3407 (LPBYTE)&pHWProfileInfo->HWPI_ulHWProfile, 3408 &dwSize); 3409 if (lError != ERROR_SUCCESS) 3410 { 3411 pHWProfileInfo->HWPI_ulHWProfile = 0; 3412 ret = CR_REGISTRY_ERROR; 3413 goto done; 3414 } 3415 } 3416 else 3417 { 3418 /* FIXME: not implemented yet */ 3419 ret = CR_CALL_NOT_IMPLEMENTED; 3420 goto done; 3421 } 3422 3423 swprintf(szProfileName, L"%04lu", pHWProfileInfo->HWPI_ulHWProfile); 3424 3425 lError = RegOpenKeyExW(hKeyProfiles, 3426 szProfileName, 3427 0, 3428 KEY_QUERY_VALUE, 3429 &hKeyProfile); 3430 if (lError != ERROR_SUCCESS) 3431 { 3432 ret = CR_REGISTRY_ERROR; 3433 goto done; 3434 } 3435 3436 dwSize = sizeof(pHWProfileInfo->HWPI_szFriendlyName); 3437 lError = RegQueryValueExW(hKeyProfile, 3438 L"FriendlyName", 3439 NULL, 3440 NULL, 3441 (LPBYTE)&pHWProfileInfo->HWPI_szFriendlyName, 3442 &dwSize); 3443 if (lError != ERROR_SUCCESS) 3444 { 3445 ret = CR_REGISTRY_ERROR; 3446 goto done; 3447 } 3448 3449 done: 3450 if (hKeyProfile != NULL) 3451 RegCloseKey(hKeyProfile); 3452 3453 if (hKeyProfiles != NULL) 3454 RegCloseKey(hKeyProfiles); 3455 3456 if (hKeyConfig != NULL) 3457 RegCloseKey(hKeyConfig); 3458 3459 return ret; 3460 } 3461 3462 3463 /* Function 42 */ 3464 DWORD 3465 WINAPI 3466 PNP_AddEmptyLogConf( 3467 handle_t hBinding, 3468 LPWSTR pDeviceID, 3469 DWORD ulPriority, 3470 DWORD *pulLogConfTag, 3471 DWORD ulFlags) 3472 { 3473 UNIMPLEMENTED; 3474 return CR_CALL_NOT_IMPLEMENTED; 3475 } 3476 3477 3478 /* Function 43 */ 3479 DWORD 3480 WINAPI 3481 PNP_FreeLogConf( 3482 handle_t hBinding, 3483 LPWSTR pDeviceID, 3484 DWORD ulLogConfType, 3485 DWORD ulLogConfTag, 3486 DWORD ulFlags) 3487 { 3488 UNIMPLEMENTED; 3489 return CR_CALL_NOT_IMPLEMENTED; 3490 } 3491 3492 3493 /* Function 44 */ 3494 DWORD 3495 WINAPI 3496 PNP_GetFirstLogConf( 3497 handle_t hBinding, 3498 LPWSTR pDeviceID, 3499 DWORD ulLogConfType, 3500 DWORD *pulLogConfTag, 3501 DWORD ulFlags) 3502 { 3503 UNIMPLEMENTED; 3504 return CR_CALL_NOT_IMPLEMENTED; 3505 } 3506 3507 3508 /* Function 45 */ 3509 DWORD 3510 WINAPI 3511 PNP_GetNextLogConf( 3512 handle_t hBinding, 3513 LPWSTR pDeviceID, 3514 DWORD ulLogConfType, 3515 DWORD ulCurrentTag, 3516 DWORD *pulNextTag, 3517 DWORD ulFlags) 3518 { 3519 UNIMPLEMENTED; 3520 return CR_CALL_NOT_IMPLEMENTED; 3521 } 3522 3523 3524 /* Function 46 */ 3525 DWORD 3526 WINAPI 3527 PNP_GetLogConfPriority( 3528 handle_t hBinding, 3529 LPWSTR pDeviceID, 3530 DWORD ulType, 3531 DWORD ulTag, 3532 DWORD *pPriority, 3533 DWORD ulFlags) 3534 { 3535 UNIMPLEMENTED; 3536 return CR_CALL_NOT_IMPLEMENTED; 3537 } 3538 3539 3540 /* Function 47 */ 3541 DWORD 3542 WINAPI 3543 PNP_AddResDes( 3544 handle_t hBinding, 3545 LPWSTR pDeviceID, 3546 DWORD ulLogConfTag, 3547 DWORD ulLogConfType, 3548 RESOURCEID ResourceID, 3549 DWORD *pulResourceTag, 3550 BYTE *ResourceData, 3551 PNP_RPC_BUFFER_SIZE ResourceLen, 3552 DWORD ulFlags) 3553 { 3554 UNIMPLEMENTED; 3555 return CR_CALL_NOT_IMPLEMENTED; 3556 } 3557 3558 3559 /* Function 48 */ 3560 DWORD 3561 WINAPI 3562 PNP_FreeResDes( 3563 handle_t hBinding, 3564 LPWSTR pDeviceID, 3565 DWORD ulLogConfTag, 3566 DWORD ulLogConfType, 3567 RESOURCEID ResourceID, 3568 DWORD ulResourceTag, 3569 DWORD *pulPreviousResType, 3570 DWORD *pulPreviousResTag, 3571 DWORD ulFlags) 3572 { 3573 UNIMPLEMENTED; 3574 return CR_CALL_NOT_IMPLEMENTED; 3575 } 3576 3577 3578 /* Function 49 */ 3579 DWORD 3580 WINAPI 3581 PNP_GetNextResDes( 3582 handle_t hBinding, 3583 LPWSTR pDeviceID, 3584 DWORD ulLogConfTag, 3585 DWORD ulLogConfType, 3586 RESOURCEID ResourceID, 3587 DWORD ulResourceTag, 3588 DWORD *pulNextResType, 3589 DWORD *pulNextResTag, 3590 DWORD ulFlags) 3591 { 3592 UNIMPLEMENTED; 3593 return CR_CALL_NOT_IMPLEMENTED; 3594 } 3595 3596 3597 /* Function 50 */ 3598 DWORD 3599 WINAPI 3600 PNP_GetResDesData( 3601 handle_t hBinding, 3602 LPWSTR pDeviceID, 3603 DWORD ulLogConfTag, 3604 DWORD ulLogConfType, 3605 RESOURCEID ResourceID, 3606 DWORD ulResourceTag, 3607 BYTE *Buffer, 3608 PNP_RPC_BUFFER_SIZE BufferLen, 3609 DWORD ulFlags) 3610 { 3611 UNIMPLEMENTED; 3612 return CR_CALL_NOT_IMPLEMENTED; 3613 } 3614 3615 3616 /* Function 51 */ 3617 DWORD 3618 WINAPI 3619 PNP_GetResDesDataSize( 3620 handle_t hBinding, 3621 LPWSTR pDeviceID, 3622 DWORD ulLogConfTag, 3623 DWORD ulLogConfType, 3624 RESOURCEID ResourceID, 3625 DWORD ulResourceTag, 3626 DWORD *pulSize, 3627 DWORD ulFlags) 3628 { 3629 UNIMPLEMENTED; 3630 return CR_CALL_NOT_IMPLEMENTED; 3631 } 3632 3633 3634 /* Function 52 */ 3635 DWORD 3636 WINAPI 3637 PNP_ModifyResDes( 3638 handle_t hBinding, 3639 LPWSTR pDeviceID, 3640 DWORD ulLogConfTag, 3641 DWORD ulLogConfType, 3642 RESOURCEID CurrentResourceID, 3643 RESOURCEID NewResourceID, 3644 DWORD ulResourceTag, 3645 BYTE *ResourceData, 3646 PNP_RPC_BUFFER_SIZE ResourceLen, 3647 DWORD ulFlags) 3648 { 3649 UNIMPLEMENTED; 3650 return CR_CALL_NOT_IMPLEMENTED; 3651 } 3652 3653 3654 /* Function 53 */ 3655 DWORD 3656 WINAPI 3657 PNP_DetectResourceConflict( 3658 handle_t hBinding, 3659 LPWSTR pDeviceID, 3660 RESOURCEID ResourceID, 3661 BYTE *ResourceData, 3662 PNP_RPC_BUFFER_SIZE ResourceLen, 3663 BOOL *pbConflictDetected, 3664 DWORD ulFlags) 3665 { 3666 DPRINT("PNP_DetectResourceConflict()\n"); 3667 3668 if (pbConflictDetected != NULL) 3669 *pbConflictDetected = FALSE; 3670 3671 return CR_CALL_NOT_IMPLEMENTED; 3672 } 3673 3674 3675 /* Function 54 */ 3676 DWORD 3677 WINAPI 3678 PNP_QueryResConfList( 3679 handle_t hBinding, 3680 LPWSTR pDeviceID, 3681 RESOURCEID ResourceID, 3682 BYTE *ResourceData, 3683 PNP_RPC_BUFFER_SIZE ResourceLen, 3684 BYTE *Buffer, 3685 PNP_RPC_BUFFER_SIZE BufferLen, 3686 DWORD ulFlags) 3687 { 3688 UNIMPLEMENTED; 3689 return CR_CALL_NOT_IMPLEMENTED; 3690 } 3691 3692 3693 /* Function 55 */ 3694 DWORD 3695 WINAPI 3696 PNP_SetHwProf( 3697 handle_t hBinding, 3698 DWORD ulHardwareProfile, 3699 DWORD ulFlags) 3700 { 3701 return CR_CALL_NOT_IMPLEMENTED; 3702 } 3703 3704 3705 /* Function 56 */ 3706 DWORD 3707 WINAPI 3708 PNP_QueryArbitratorFreeData( 3709 handle_t hBinding, 3710 BYTE *pData, 3711 DWORD DataLen, 3712 LPWSTR pDeviceID, 3713 RESOURCEID ResourceID, 3714 DWORD ulFlags) 3715 { 3716 return CR_CALL_NOT_IMPLEMENTED; 3717 } 3718 3719 3720 /* Function 57 */ 3721 DWORD 3722 WINAPI 3723 PNP_QueryArbitratorFreeSize( 3724 handle_t hBinding, 3725 DWORD *pulSize, 3726 LPWSTR pDeviceID, 3727 RESOURCEID ResourceID, 3728 DWORD ulFlags) 3729 { 3730 if (pulSize != NULL) 3731 *pulSize = 0; 3732 3733 return CR_CALL_NOT_IMPLEMENTED; 3734 } 3735 3736 3737 /* Function 58 */ 3738 CONFIGRET 3739 WINAPI 3740 PNP_RunDetection( 3741 handle_t hBinding, 3742 DWORD ulFlags) 3743 { 3744 return CR_CALL_NOT_IMPLEMENTED; 3745 } 3746 3747 3748 /* Function 59 */ 3749 DWORD 3750 WINAPI 3751 PNP_RegisterNotification( 3752 handle_t hBinding, 3753 DWORD ulUnknown2, 3754 LPWSTR pszName, 3755 BYTE *pNotificationFilter, 3756 DWORD ulNotificationFilterSize, 3757 DWORD ulFlags, 3758 DWORD *pulNotify, 3759 DWORD ulUnknown8, 3760 DWORD *pulUnknown9) 3761 { 3762 PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface; 3763 PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle; 3764 #if 0 3765 PNOTIFY_DATA pNotifyData; 3766 #endif 3767 3768 DPRINT1("PNP_RegisterNotification(%p %lx '%S' %p %lu 0x%lx %p %lx %p)\n", 3769 hBinding, ulUnknown2, pszName, pNotificationFilter, 3770 ulNotificationFilterSize, ulFlags, pulNotify, ulUnknown8, pulUnknown9); 3771 3772 if (pNotificationFilter == NULL || 3773 pulNotify == NULL || 3774 pulUnknown9 == NULL) 3775 return CR_INVALID_POINTER; 3776 3777 if (ulFlags & ~0x7) 3778 return CR_INVALID_FLAG; 3779 3780 if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HDR)) || 3781 (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR))) 3782 return CR_INVALID_DATA; 3783 3784 if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) 3785 { 3786 DPRINT1("DBT_DEVTYP_DEVICEINTERFACE\n"); 3787 pBroadcastDeviceInterface = (PDEV_BROADCAST_DEVICEINTERFACE_W)pNotificationFilter; 3788 3789 if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)) || 3790 (pBroadcastDeviceInterface->dbcc_size < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W))) 3791 return CR_INVALID_DATA; 3792 } 3793 else if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_HANDLE) 3794 { 3795 DPRINT1("DBT_DEVTYP_HANDLE\n"); 3796 pBroadcastDeviceHandle = (PDEV_BROADCAST_HANDLE)pNotificationFilter; 3797 3798 if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HANDLE)) || 3799 (pBroadcastDeviceHandle->dbch_size < sizeof(DEV_BROADCAST_HANDLE))) 3800 return CR_INVALID_DATA; 3801 3802 if (ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) 3803 return CR_INVALID_FLAG; 3804 } 3805 else 3806 { 3807 DPRINT1("Invalid device type %lu\n", ((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype); 3808 return CR_INVALID_DATA; 3809 } 3810 3811 3812 #if 0 3813 pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_DATA)); 3814 if (pNotifyData == NULL) 3815 return CR_OUT_OF_MEMORY; 3816 3817 *pulNotify = (DWORD)pNotifyData; 3818 #endif 3819 3820 *pulNotify = 1; 3821 3822 return CR_SUCCESS; 3823 } 3824 3825 3826 /* Function 60 */ 3827 DWORD 3828 WINAPI 3829 PNP_UnregisterNotification( 3830 handle_t hBinding, 3831 DWORD ulNotify) 3832 { 3833 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n", 3834 hBinding, ulNotify); 3835 3836 #if 0 3837 UNIMPLEMENTED; 3838 return CR_CALL_NOT_IMPLEMENTED; 3839 #endif 3840 3841 return CR_SUCCESS; 3842 } 3843 3844 3845 /* Function 61 */ 3846 DWORD 3847 WINAPI 3848 PNP_GetCustomDevProp( 3849 handle_t hBinding, 3850 LPWSTR pDeviceID, 3851 LPWSTR CustomPropName, 3852 DWORD *pulRegDataType, 3853 BYTE *Buffer, 3854 PNP_RPC_STRING_LEN *pulTransferLen, 3855 PNP_RPC_STRING_LEN *pulLength, 3856 DWORD ulFlags) 3857 { 3858 HKEY hDeviceKey = NULL; 3859 HKEY hParamKey = NULL; 3860 LONG lError; 3861 CONFIGRET ret = CR_SUCCESS; 3862 3863 UNREFERENCED_PARAMETER(hBinding); 3864 3865 DPRINT("PNP_GetCustomDevProp() called\n"); 3866 3867 if (pulTransferLen == NULL || pulLength == NULL) 3868 { 3869 ret = CR_INVALID_POINTER; 3870 goto done; 3871 } 3872 3873 if (ulFlags & ~CM_CUSTOMDEVPROP_BITS) 3874 { 3875 ret = CR_INVALID_FLAG; 3876 goto done; 3877 } 3878 3879 if (!IsValidDeviceInstanceID(pDeviceID)) 3880 return CR_INVALID_DEVINST; 3881 3882 if (*pulLength < *pulTransferLen) 3883 *pulLength = *pulTransferLen; 3884 3885 *pulTransferLen = 0; 3886 3887 lError = RegOpenKeyExW(hEnumKey, 3888 pDeviceID, 3889 0, 3890 KEY_READ, 3891 &hDeviceKey); 3892 if (lError != ERROR_SUCCESS) 3893 { 3894 ret = CR_REGISTRY_ERROR; 3895 goto done; 3896 } 3897 3898 lError = RegOpenKeyExW(hDeviceKey, 3899 L"Device Parameters", 3900 0, 3901 KEY_READ, 3902 &hParamKey); 3903 if (lError != ERROR_SUCCESS) 3904 { 3905 ret = CR_REGISTRY_ERROR; 3906 goto done; 3907 } 3908 3909 lError = RegQueryValueExW(hParamKey, 3910 CustomPropName, 3911 NULL, 3912 pulRegDataType, 3913 Buffer, 3914 pulLength); 3915 if (lError != ERROR_SUCCESS) 3916 { 3917 if (lError == ERROR_MORE_DATA) 3918 { 3919 ret = CR_BUFFER_SMALL; 3920 } 3921 else 3922 { 3923 *pulLength = 0; 3924 ret = CR_NO_SUCH_VALUE; 3925 } 3926 } 3927 3928 done: 3929 if (ret == CR_SUCCESS) 3930 *pulTransferLen = *pulLength; 3931 3932 if (hParamKey != NULL) 3933 RegCloseKey(hParamKey); 3934 3935 if (hDeviceKey != NULL) 3936 RegCloseKey(hDeviceKey); 3937 3938 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret); 3939 3940 return ret; 3941 } 3942 3943 3944 /* Function 62 */ 3945 DWORD 3946 WINAPI 3947 PNP_GetVersionInternal( 3948 handle_t hBinding, 3949 WORD *pwVersion) 3950 { 3951 UNREFERENCED_PARAMETER(hBinding); 3952 3953 *pwVersion = 0x501; 3954 return CR_SUCCESS; 3955 } 3956 3957 3958 /* Function 63 */ 3959 DWORD 3960 WINAPI 3961 PNP_GetBlockedDriverInfo( 3962 handle_t hBinding, 3963 BYTE *Buffer, 3964 PNP_RPC_BUFFER_SIZE *pulTransferLen, 3965 PNP_RPC_BUFFER_SIZE *pulLength, 3966 DWORD ulFlags) 3967 { 3968 UNIMPLEMENTED; 3969 return CR_CALL_NOT_IMPLEMENTED; 3970 } 3971 3972 3973 /* Function 64 */ 3974 DWORD 3975 WINAPI 3976 PNP_GetServerSideDeviceInstallFlags( 3977 handle_t hBinding, 3978 DWORD *pulSSDIFlags, 3979 DWORD ulFlags) 3980 { 3981 UNREFERENCED_PARAMETER(hBinding); 3982 3983 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n", 3984 hBinding, pulSSDIFlags, ulFlags); 3985 3986 if (pulSSDIFlags == NULL) 3987 return CR_INVALID_POINTER; 3988 3989 if (ulFlags != 0) 3990 return CR_INVALID_FLAG; 3991 3992 /* FIXME */ 3993 *pulSSDIFlags = 0; 3994 3995 return CR_SUCCESS; 3996 } 3997 3998 3999 /* Function 65 */ 4000 DWORD 4001 WINAPI 4002 PNP_GetObjectPropKeys( 4003 handle_t hBinding, 4004 LPWSTR ObjectName, 4005 DWORD ObjectType, 4006 LPWSTR PropertyCultureName, 4007 PNP_PROP_COUNT *PropertyCount, 4008 PNP_PROP_COUNT *TransferLen, 4009 DEVPROPKEY *PropertyKeys, 4010 DWORD Flags) 4011 { 4012 UNIMPLEMENTED; 4013 return CR_CALL_NOT_IMPLEMENTED; 4014 } 4015 4016 4017 /* Function 66 */ 4018 DWORD 4019 WINAPI 4020 PNP_GetObjectProp( 4021 handle_t hBinding, 4022 LPWSTR ObjectName, 4023 DWORD ObjectType, 4024 LPWSTR PropertyCultureName, 4025 const DEVPROPKEY *PropertyKey, 4026 DEVPROPTYPE *PropertyType, 4027 PNP_PROP_SIZE *PropertySize, 4028 PNP_PROP_SIZE *TransferLen, 4029 BYTE *PropertyBuffer, 4030 DWORD Flags) 4031 { 4032 UNIMPLEMENTED; 4033 return CR_CALL_NOT_IMPLEMENTED; 4034 } 4035 4036 4037 /* Function 67 */ 4038 DWORD 4039 WINAPI 4040 PNP_SetObjectProp( 4041 handle_t hBinding, 4042 LPWSTR ObjectName, 4043 DWORD ObjectType, 4044 LPWSTR PropertyCultureName, 4045 const DEVPROPKEY *PropertyKey, 4046 DEVPROPTYPE PropertyType, 4047 PNP_PROP_SIZE PropertySize, 4048 BYTE *PropertyBuffer, 4049 DWORD Flags) 4050 { 4051 UNIMPLEMENTED; 4052 return CR_CALL_NOT_IMPLEMENTED; 4053 } 4054 4055 4056 /* Function 68 */ 4057 DWORD 4058 WINAPI 4059 PNP_InstallDevInst( 4060 handle_t hBinding) 4061 { 4062 UNIMPLEMENTED; 4063 return CR_CALL_NOT_IMPLEMENTED; 4064 } 4065 4066 4067 /* Function 69 */ 4068 DWORD 4069 WINAPI 4070 PNP_ApplyPowerSettings( 4071 handle_t hBinding) 4072 { 4073 UNIMPLEMENTED; 4074 return CR_CALL_NOT_IMPLEMENTED; 4075 } 4076 4077 4078 /* Function 70 */ 4079 DWORD 4080 WINAPI 4081 PNP_DriverStoreAddDriverPackage( 4082 handle_t hBinding) 4083 { 4084 UNIMPLEMENTED; 4085 return CR_CALL_NOT_IMPLEMENTED; 4086 } 4087 4088 4089 /* Function 71 */ 4090 DWORD 4091 WINAPI 4092 PNP_DriverStoreDeleteDriverPackage( 4093 handle_t hBinding) 4094 { 4095 UNIMPLEMENTED; 4096 return CR_CALL_NOT_IMPLEMENTED; 4097 } 4098 4099 4100 /* Function 72 */ 4101 DWORD 4102 WINAPI 4103 PNP_RegisterServiceNotification( 4104 handle_t hBinding) 4105 { 4106 UNIMPLEMENTED; 4107 return CR_CALL_NOT_IMPLEMENTED; 4108 } 4109 4110 4111 /* Function 73 */ 4112 DWORD 4113 WINAPI 4114 PNP_SetActiveService( 4115 handle_t hBinding, 4116 LPWSTR pszFilter, 4117 DWORD ulFlags) 4118 { 4119 UNIMPLEMENTED; 4120 return CR_CALL_NOT_IMPLEMENTED; 4121 } 4122 4123 4124 /* Function 74 */ 4125 DWORD 4126 WINAPI 4127 PNP_DeleteServiceDevices( 4128 handle_t hBinding) 4129 { 4130 UNIMPLEMENTED; 4131 return CR_CALL_NOT_IMPLEMENTED; 4132 } 4133