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