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