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 PlugPlayData.Property = PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME; 786 break; 787 788 case CM_DRP_CAPABILITIES: 789 lpValueName = L"Capabilities"; 790 break; 791 792 case CM_DRP_UI_NUMBER: 793 PlugPlayData.Property = PNP_PROPERTY_UI_NUMBER; 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 PlugPlayData.Property = PNP_PROPERTY_BUSTYPEGUID; 806 break; 807 808 case CM_DRP_LEGACYBUSTYPE: 809 PlugPlayData.Property = PNP_PROPERTY_LEGACYBUSTYPE; 810 break; 811 812 case CM_DRP_BUSNUMBER: 813 PlugPlayData.Property = PNP_PROPERTY_BUSNUMBER; 814 break; 815 816 case CM_DRP_ENUMERATOR_NAME: 817 PlugPlayData.Property = PNP_PROPERTY_ENUMERATOR_NAME; 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 PlugPlayData.Property = PNP_PROPERTY_ADDRESS; 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 PlugPlayData.Property = PNP_PROPERTY_POWER_DATA; 846 break; 847 848 case CM_DRP_REMOVAL_POLICY: 849 PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY; 850 break; 851 852 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT: 853 PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT; 854 break; 855 856 case CM_DRP_REMOVAL_POLICY_OVERRIDE: 857 lpValueName = L"RemovalPolicy"; 858 break; 859 860 case CM_DRP_INSTALL_STATE: 861 PlugPlayData.Property = PNP_PROPERTY_INSTALL_STATE; 862 break; 863 864 #if (WINVER >= _WIN32_WINNT_WS03) 865 case CM_DRP_LOCATION_PATHS: 866 PlugPlayData.Property = PNP_PROPERTY_LOCATION_PATHS; 867 break; 868 #endif 869 870 #if (WINVER >= _WIN32_WINNT_WIN7) 871 case CM_DRP_BASE_CONTAINERID: 872 PlugPlayData.Property = PNP_PROPERTY_CONTAINERID; 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 Status = NtPlugPlayControl(PlugPlayControlProperty, 927 (PVOID)&PlugPlayData, 928 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA)); 929 if (NT_SUCCESS(Status)) 930 { 931 *pulLength = PlugPlayData.BufferSize; 932 } 933 else 934 { 935 ret = NtStatusToCrError(Status); 936 } 937 } 938 939 done: 940 if (pulTransferLen) 941 *pulTransferLen = (ret == CR_SUCCESS) ? *pulLength : 0; 942 943 if (hKey != NULL) 944 RegCloseKey(hKey); 945 946 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret); 947 948 return ret; 949 } 950 951 952 /* Function 14 */ 953 DWORD 954 WINAPI 955 PNP_SetDeviceRegProp( 956 handle_t hBinding, 957 LPWSTR pDeviceId, 958 DWORD ulProperty, 959 DWORD ulDataType, 960 BYTE *Buffer, 961 PNP_PROP_SIZE ulLength, 962 DWORD ulFlags) 963 { 964 CONFIGRET ret = CR_SUCCESS; 965 LPWSTR lpValueName = NULL; 966 HKEY hKey = 0; 967 968 UNREFERENCED_PARAMETER(hBinding); 969 UNREFERENCED_PARAMETER(ulFlags); 970 971 DPRINT("PNP_SetDeviceRegProp() called\n"); 972 973 DPRINT("DeviceId: %S\n", pDeviceId); 974 DPRINT("Property: %lu\n", ulProperty); 975 DPRINT("DataType: %lu\n", ulDataType); 976 DPRINT("Length: %lu\n", ulLength); 977 978 switch (ulProperty) 979 { 980 case CM_DRP_DEVICEDESC: 981 lpValueName = L"DeviceDesc"; 982 break; 983 984 case CM_DRP_HARDWAREID: 985 lpValueName = L"HardwareID"; 986 break; 987 988 case CM_DRP_COMPATIBLEIDS: 989 lpValueName = L"CompatibleIDs"; 990 break; 991 992 case CM_DRP_SERVICE: 993 lpValueName = L"Service"; 994 break; 995 996 case CM_DRP_CLASS: 997 lpValueName = L"Class"; 998 break; 999 1000 case CM_DRP_CLASSGUID: 1001 lpValueName = L"ClassGUID"; 1002 break; 1003 1004 case CM_DRP_DRIVER: 1005 lpValueName = L"Driver"; 1006 break; 1007 1008 case CM_DRP_CONFIGFLAGS: 1009 lpValueName = L"ConfigFlags"; 1010 break; 1011 1012 case CM_DRP_MFG: 1013 lpValueName = L"Mfg"; 1014 break; 1015 1016 case CM_DRP_FRIENDLYNAME: 1017 lpValueName = L"FriendlyName"; 1018 break; 1019 1020 case CM_DRP_LOCATION_INFORMATION: 1021 lpValueName = L"LocationInformation"; 1022 break; 1023 1024 case CM_DRP_UPPERFILTERS: 1025 lpValueName = L"UpperFilters"; 1026 break; 1027 1028 case CM_DRP_LOWERFILTERS: 1029 lpValueName = L"LowerFilters"; 1030 break; 1031 1032 case CM_DRP_SECURITY: 1033 lpValueName = L"Security"; 1034 break; 1035 1036 case CM_DRP_DEVTYPE: 1037 lpValueName = L"DeviceType"; 1038 break; 1039 1040 case CM_DRP_EXCLUSIVE: 1041 lpValueName = L"Exclusive"; 1042 break; 1043 1044 case CM_DRP_CHARACTERISTICS: 1045 lpValueName = L"DeviceCharacteristics"; 1046 break; 1047 1048 case CM_DRP_UI_NUMBER_DESC_FORMAT: 1049 lpValueName = L"UINumberDescFormat"; 1050 break; 1051 1052 case CM_DRP_REMOVAL_POLICY_OVERRIDE: 1053 lpValueName = L"RemovalPolicy"; 1054 break; 1055 1056 default: 1057 return CR_INVALID_PROPERTY; 1058 } 1059 1060 DPRINT("Value name: %S\n", lpValueName); 1061 1062 if (RegOpenKeyExW(hEnumKey, 1063 pDeviceId, 1064 0, 1065 KEY_SET_VALUE, 1066 &hKey)) 1067 return CR_INVALID_DEVNODE; 1068 1069 if (ulLength == 0) 1070 { 1071 if (RegDeleteValueW(hKey, 1072 lpValueName)) 1073 ret = CR_REGISTRY_ERROR; 1074 } 1075 else 1076 { 1077 if (RegSetValueExW(hKey, 1078 lpValueName, 1079 0, 1080 ulDataType, 1081 Buffer, 1082 ulLength)) 1083 ret = CR_REGISTRY_ERROR; 1084 } 1085 1086 RegCloseKey(hKey); 1087 1088 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret); 1089 1090 return ret; 1091 } 1092 1093 1094 /* Function 15 */ 1095 DWORD 1096 WINAPI 1097 PNP_GetClassInstance( 1098 handle_t hBinding, 1099 LPWSTR pDeviceId, 1100 LPWSTR pszClassInstance, 1101 PNP_RPC_STRING_LEN ulLength) 1102 { 1103 UNIMPLEMENTED; 1104 return CR_CALL_NOT_IMPLEMENTED; 1105 } 1106 1107 1108 /* Function 16 */ 1109 DWORD 1110 WINAPI 1111 PNP_CreateKey( 1112 handle_t hBinding, 1113 LPWSTR pszSubKey, 1114 DWORD samDesired, 1115 DWORD ulFlags) 1116 { 1117 HKEY hKey = 0; 1118 1119 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, 1120 pszSubKey, 1121 0, 1122 NULL, 1123 0, 1124 KEY_ALL_ACCESS, 1125 NULL, 1126 &hKey, 1127 NULL)) 1128 return CR_REGISTRY_ERROR; 1129 1130 /* FIXME: Set security key */ 1131 1132 RegCloseKey(hKey); 1133 1134 return CR_SUCCESS; 1135 } 1136 1137 1138 /* Function 17 */ 1139 DWORD 1140 WINAPI 1141 PNP_DeleteRegistryKey( 1142 handle_t hBinding, 1143 LPWSTR pszDeviceID, 1144 LPWSTR pszParentKey, 1145 LPWSTR pszChildKey, 1146 DWORD ulFlags) 1147 { 1148 UNIMPLEMENTED; 1149 return CR_CALL_NOT_IMPLEMENTED; 1150 } 1151 1152 1153 /* Function 18 */ 1154 DWORD 1155 WINAPI 1156 PNP_GetClassCount( 1157 handle_t hBinding, 1158 DWORD *pulClassCount, 1159 DWORD ulFlags) 1160 { 1161 HKEY hKey; 1162 DWORD dwError; 1163 1164 UNREFERENCED_PARAMETER(hBinding); 1165 UNREFERENCED_PARAMETER(ulFlags); 1166 1167 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1168 REGSTR_PATH_CLASS, 1169 0, 1170 KEY_QUERY_VALUE, 1171 &hKey); 1172 if (dwError != ERROR_SUCCESS) 1173 return CR_INVALID_DATA; 1174 1175 dwError = RegQueryInfoKeyW(hKey, 1176 NULL, 1177 NULL, 1178 NULL, 1179 pulClassCount, 1180 NULL, 1181 NULL, 1182 NULL, 1183 NULL, 1184 NULL, 1185 NULL, 1186 NULL); 1187 RegCloseKey(hKey); 1188 if (dwError != ERROR_SUCCESS) 1189 return CR_INVALID_DATA; 1190 1191 return CR_SUCCESS; 1192 } 1193 1194 1195 /* Function 19 */ 1196 DWORD 1197 WINAPI 1198 PNP_GetClassName( 1199 handle_t hBinding, 1200 LPWSTR pszClassGuid, 1201 LPWSTR Buffer, 1202 PNP_RPC_STRING_LEN *pulLength, 1203 DWORD ulFlags) 1204 { 1205 WCHAR szKeyName[MAX_PATH]; 1206 CONFIGRET ret = CR_SUCCESS; 1207 HKEY hKey; 1208 DWORD dwSize; 1209 1210 UNREFERENCED_PARAMETER(hBinding); 1211 UNREFERENCED_PARAMETER(ulFlags); 1212 1213 DPRINT("PNP_GetClassName() called\n"); 1214 1215 lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class\\"); 1216 if (lstrlenW(pszClassGuid) + 1 < sizeof(szKeyName)/sizeof(WCHAR)-(lstrlenW(szKeyName) * sizeof(WCHAR))) 1217 lstrcatW(szKeyName, pszClassGuid); 1218 else 1219 return CR_INVALID_DATA; 1220 1221 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1222 szKeyName, 1223 0, 1224 KEY_QUERY_VALUE, 1225 &hKey)) 1226 return CR_REGISTRY_ERROR; 1227 1228 dwSize = *pulLength * sizeof(WCHAR); 1229 if (RegQueryValueExW(hKey, 1230 L"Class", 1231 NULL, 1232 NULL, 1233 (LPBYTE)Buffer, 1234 &dwSize)) 1235 { 1236 *pulLength = 0; 1237 ret = CR_REGISTRY_ERROR; 1238 } 1239 else 1240 { 1241 *pulLength = dwSize / sizeof(WCHAR); 1242 } 1243 1244 RegCloseKey(hKey); 1245 1246 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret); 1247 1248 return ret; 1249 } 1250 1251 1252 /* Function 20 */ 1253 DWORD 1254 WINAPI 1255 PNP_DeleteClassKey( 1256 handle_t hBinding, 1257 LPWSTR pszClassGuid, 1258 DWORD ulFlags) 1259 { 1260 CONFIGRET ret = CR_SUCCESS; 1261 1262 UNREFERENCED_PARAMETER(hBinding); 1263 1264 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid, ulFlags); 1265 1266 if (ulFlags & CM_DELETE_CLASS_SUBKEYS) 1267 { 1268 if (SHDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS) 1269 ret = CR_REGISTRY_ERROR; 1270 } 1271 else 1272 { 1273 if (RegDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS) 1274 ret = CR_REGISTRY_ERROR; 1275 } 1276 1277 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret); 1278 1279 return ret; 1280 } 1281 1282 1283 /* Function 21 */ 1284 DWORD 1285 WINAPI 1286 PNP_GetInterfaceDeviceAlias( 1287 handle_t hBinding, 1288 LPWSTR pszInterfaceDevice, 1289 GUID *AliasInterfaceGuid, 1290 LPWSTR pszAliasInterfaceDevice, 1291 PNP_RPC_STRING_LEN *pulLength, 1292 PNP_RPC_STRING_LEN *pulTransferLen, 1293 DWORD ulFlags) 1294 { 1295 UNIMPLEMENTED; 1296 return CR_CALL_NOT_IMPLEMENTED; 1297 } 1298 1299 1300 /* Function 22 */ 1301 DWORD 1302 WINAPI 1303 PNP_GetInterfaceDeviceList( 1304 handle_t hBinding, 1305 GUID *InterfaceGuid, 1306 LPWSTR pszDeviceID, 1307 BYTE *Buffer, 1308 PNP_RPC_BUFFER_SIZE *pulLength, 1309 DWORD ulFlags) 1310 { 1311 NTSTATUS Status; 1312 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData; 1313 DWORD ret = CR_SUCCESS; 1314 1315 UNREFERENCED_PARAMETER(hBinding); 1316 1317 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 1318 pszDeviceID); 1319 1320 PlugPlayData.Flags = ulFlags; 1321 PlugPlayData.FilterGuid = InterfaceGuid; 1322 PlugPlayData.Buffer = Buffer; 1323 PlugPlayData.BufferSize = *pulLength; 1324 1325 Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList, 1326 (PVOID)&PlugPlayData, 1327 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA)); 1328 if (NT_SUCCESS(Status)) 1329 { 1330 *pulLength = PlugPlayData.BufferSize; 1331 } 1332 else 1333 { 1334 ret = NtStatusToCrError(Status); 1335 } 1336 1337 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret); 1338 return ret; 1339 } 1340 1341 1342 /* Function 23 */ 1343 DWORD 1344 WINAPI 1345 PNP_GetInterfaceDeviceListSize( 1346 handle_t hBinding, 1347 PNP_RPC_BUFFER_SIZE *pulLen, 1348 GUID *InterfaceGuid, 1349 LPWSTR pszDeviceID, 1350 DWORD ulFlags) 1351 { 1352 NTSTATUS Status; 1353 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData; 1354 DWORD ret = CR_SUCCESS; 1355 1356 UNREFERENCED_PARAMETER(hBinding); 1357 1358 DPRINT("PNP_GetInterfaceDeviceListSize() called\n"); 1359 1360 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 1361 pszDeviceID); 1362 1363 PlugPlayData.FilterGuid = InterfaceGuid; 1364 PlugPlayData.Buffer = NULL; 1365 PlugPlayData.BufferSize = 0; 1366 PlugPlayData.Flags = ulFlags; 1367 1368 Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList, 1369 (PVOID)&PlugPlayData, 1370 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA)); 1371 if (NT_SUCCESS(Status)) 1372 { 1373 *pulLen = PlugPlayData.BufferSize; 1374 } 1375 else 1376 { 1377 ret = NtStatusToCrError(Status); 1378 } 1379 1380 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret); 1381 return ret; 1382 } 1383 1384 1385 /* Function 24 */ 1386 DWORD 1387 WINAPI 1388 PNP_RegisterDeviceClassAssociation( 1389 handle_t hBinding, 1390 LPWSTR pszDeviceID, 1391 GUID *InterfaceGuid, 1392 LPWSTR pszReference, 1393 LPWSTR pszSymLink, 1394 PNP_RPC_STRING_LEN *pulLength, 1395 PNP_RPC_STRING_LEN *pulTransferLen, 1396 DWORD ulFlags) 1397 { 1398 UNIMPLEMENTED; 1399 return CR_CALL_NOT_IMPLEMENTED; 1400 } 1401 1402 1403 /* Function 25 */ 1404 DWORD 1405 WINAPI 1406 PNP_UnregisterDeviceClassAssociation( 1407 handle_t hBinding, 1408 LPWSTR pszInterfaceDevice, 1409 DWORD ulFlags) 1410 { 1411 UNIMPLEMENTED; 1412 return CR_CALL_NOT_IMPLEMENTED; 1413 } 1414 1415 1416 /* Function 26 */ 1417 DWORD 1418 WINAPI 1419 PNP_GetClassRegProp( 1420 handle_t hBinding, 1421 LPWSTR pszClassGuid, 1422 DWORD ulProperty, 1423 DWORD *pulRegDataType, 1424 BYTE *Buffer, 1425 PNP_RPC_STRING_LEN *pulTransferLen, 1426 PNP_RPC_STRING_LEN *pulLength, 1427 DWORD ulFlags) 1428 { 1429 CONFIGRET ret = CR_SUCCESS; 1430 LPWSTR lpValueName = NULL; 1431 HKEY hInstKey = NULL; 1432 HKEY hPropKey = NULL; 1433 LONG lError; 1434 1435 UNREFERENCED_PARAMETER(hBinding); 1436 1437 DPRINT("PNP_GetClassRegProp() called\n"); 1438 1439 if (pulTransferLen == NULL || pulLength == NULL) 1440 { 1441 ret = CR_INVALID_POINTER; 1442 goto done; 1443 } 1444 1445 if (ulFlags != 0) 1446 { 1447 ret = CR_INVALID_FLAG; 1448 goto done; 1449 } 1450 1451 if (*pulLength < *pulTransferLen) 1452 *pulLength = *pulTransferLen; 1453 1454 *pulTransferLen = 0; 1455 1456 switch (ulProperty) 1457 { 1458 case CM_CRP_SECURITY: 1459 lpValueName = L"Security"; 1460 break; 1461 1462 case CM_CRP_DEVTYPE: 1463 lpValueName = L"DeviceType"; 1464 break; 1465 1466 case CM_CRP_EXCLUSIVE: 1467 lpValueName = L"Exclusive"; 1468 break; 1469 1470 case CM_CRP_CHARACTERISTICS: 1471 lpValueName = L"DeviceCharacteristics"; 1472 break; 1473 1474 default: 1475 ret = CR_INVALID_PROPERTY; 1476 goto done; 1477 } 1478 1479 DPRINT("Value name: %S\n", lpValueName); 1480 1481 lError = RegOpenKeyExW(hClassKey, 1482 pszClassGuid, 1483 0, 1484 KEY_READ, 1485 &hInstKey); 1486 if (lError != ERROR_SUCCESS) 1487 { 1488 *pulLength = 0; 1489 ret = CR_NO_SUCH_REGISTRY_KEY; 1490 goto done; 1491 } 1492 1493 lError = RegOpenKeyExW(hInstKey, 1494 L"Properties", 1495 0, 1496 KEY_READ, 1497 &hPropKey); 1498 if (lError != ERROR_SUCCESS) 1499 { 1500 *pulLength = 0; 1501 ret = CR_NO_SUCH_REGISTRY_KEY; 1502 goto done; 1503 } 1504 1505 lError = RegQueryValueExW(hPropKey, 1506 lpValueName, 1507 NULL, 1508 pulRegDataType, 1509 Buffer, 1510 pulLength); 1511 if (lError != ERROR_SUCCESS) 1512 { 1513 if (lError == ERROR_MORE_DATA) 1514 { 1515 ret = CR_BUFFER_SMALL; 1516 } 1517 else 1518 { 1519 *pulLength = 0; 1520 ret = CR_NO_SUCH_VALUE; 1521 } 1522 } 1523 1524 done: 1525 if (ret == CR_SUCCESS) 1526 *pulTransferLen = *pulLength; 1527 1528 if (hPropKey != NULL) 1529 RegCloseKey(hPropKey); 1530 1531 if (hInstKey != NULL) 1532 RegCloseKey(hInstKey); 1533 1534 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret); 1535 1536 return ret; 1537 } 1538 1539 1540 /* Function 27 */ 1541 DWORD 1542 WINAPI 1543 PNP_SetClassRegProp( 1544 handle_t hBinding, 1545 LPWSTR pszClassGuid, 1546 DWORD ulProperty, 1547 DWORD ulDataType, 1548 BYTE *Buffer, 1549 PNP_PROP_SIZE ulLength, 1550 DWORD ulFlags) 1551 { 1552 CONFIGRET ret = CR_SUCCESS; 1553 LPWSTR lpValueName = NULL; 1554 HKEY hInstKey = 0; 1555 HKEY hPropKey = 0; 1556 LONG lError; 1557 1558 UNREFERENCED_PARAMETER(hBinding); 1559 1560 DPRINT("PNP_SetClassRegProp() called\n"); 1561 1562 if (ulFlags != 0) 1563 return CR_INVALID_FLAG; 1564 1565 switch (ulProperty) 1566 { 1567 case CM_CRP_SECURITY: 1568 lpValueName = L"Security"; 1569 break; 1570 1571 case CM_CRP_DEVTYPE: 1572 lpValueName = L"DeviceType"; 1573 break; 1574 1575 case CM_CRP_EXCLUSIVE: 1576 lpValueName = L"Exclusive"; 1577 break; 1578 1579 case CM_CRP_CHARACTERISTICS: 1580 lpValueName = L"DeviceCharacteristics"; 1581 break; 1582 1583 default: 1584 return CR_INVALID_PROPERTY; 1585 } 1586 1587 lError = RegOpenKeyExW(hClassKey, 1588 pszClassGuid, 1589 0, 1590 KEY_WRITE, 1591 &hInstKey); 1592 if (lError != ERROR_SUCCESS) 1593 { 1594 ret = CR_NO_SUCH_REGISTRY_KEY; 1595 goto done; 1596 } 1597 1598 /* FIXME: Set security descriptor */ 1599 lError = RegCreateKeyExW(hInstKey, 1600 L"Properties", 1601 0, 1602 NULL, 1603 REG_OPTION_NON_VOLATILE, 1604 KEY_ALL_ACCESS, 1605 NULL, 1606 &hPropKey, 1607 NULL); 1608 if (lError != ERROR_SUCCESS) 1609 { 1610 ret = CR_REGISTRY_ERROR; 1611 goto done; 1612 } 1613 1614 if (ulLength == 0) 1615 { 1616 if (RegDeleteValueW(hPropKey, 1617 lpValueName)) 1618 ret = CR_REGISTRY_ERROR; 1619 } 1620 else 1621 { 1622 if (RegSetValueExW(hPropKey, 1623 lpValueName, 1624 0, 1625 ulDataType, 1626 Buffer, 1627 ulLength)) 1628 ret = CR_REGISTRY_ERROR; 1629 } 1630 1631 done: 1632 if (hPropKey != NULL) 1633 RegCloseKey(hPropKey); 1634 1635 if (hInstKey != NULL) 1636 RegCloseKey(hInstKey); 1637 1638 return ret; 1639 } 1640 1641 1642 static VOID 1643 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID, 1644 OUT LPWSTR pszEnumerator, 1645 OUT LPWSTR pszDevice, 1646 OUT LPWSTR pszInstance) 1647 { 1648 WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN]; 1649 LPWSTR lpEnumerator = NULL; 1650 LPWSTR lpDevice = NULL; 1651 LPWSTR lpInstance = NULL; 1652 LPWSTR ptr; 1653 1654 wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID); 1655 1656 *pszEnumerator = 0; 1657 *pszDevice = 0; 1658 *pszInstance = 0; 1659 1660 lpEnumerator = szLocalDeviceInstanceID; 1661 1662 ptr = wcschr(lpEnumerator, L'\\'); 1663 if (ptr != NULL) 1664 { 1665 *ptr = 0; 1666 lpDevice = ++ptr; 1667 1668 ptr = wcschr(lpDevice, L'\\'); 1669 if (ptr != NULL) 1670 { 1671 *ptr = 0; 1672 lpInstance = ++ptr; 1673 } 1674 } 1675 1676 if (lpEnumerator != NULL) 1677 wcscpy(pszEnumerator, lpEnumerator); 1678 1679 if (lpDevice != NULL) 1680 wcscpy(pszDevice, lpDevice); 1681 1682 if (lpInstance != NULL) 1683 wcscpy(pszInstance, lpInstance); 1684 } 1685 1686 1687 static CONFIGRET 1688 CreateDeviceInstance(LPWSTR pszDeviceID) 1689 { 1690 WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; 1691 WCHAR szDevice[MAX_DEVICE_ID_LEN]; 1692 WCHAR szInstance[MAX_DEVICE_ID_LEN]; 1693 HKEY hKeyEnumerator; 1694 HKEY hKeyDevice; 1695 HKEY hKeyInstance; 1696 HKEY hKeyControl; 1697 LONG lError; 1698 1699 /* Split the instance ID */ 1700 SplitDeviceInstanceID(pszDeviceID, 1701 szEnumerator, 1702 szDevice, 1703 szInstance); 1704 1705 /* Open or create the enumerator key */ 1706 lError = RegCreateKeyExW(hEnumKey, 1707 szEnumerator, 1708 0, 1709 NULL, 1710 REG_OPTION_NON_VOLATILE, 1711 KEY_ALL_ACCESS, 1712 NULL, 1713 &hKeyEnumerator, 1714 NULL); 1715 if (lError != ERROR_SUCCESS) 1716 { 1717 return CR_REGISTRY_ERROR; 1718 } 1719 1720 /* Open or create the device key */ 1721 lError = RegCreateKeyExW(hKeyEnumerator, 1722 szDevice, 1723 0, 1724 NULL, 1725 REG_OPTION_NON_VOLATILE, 1726 KEY_ALL_ACCESS, 1727 NULL, 1728 &hKeyDevice, 1729 NULL); 1730 1731 /* Close the enumerator key */ 1732 RegCloseKey(hKeyEnumerator); 1733 1734 if (lError != ERROR_SUCCESS) 1735 { 1736 return CR_REGISTRY_ERROR; 1737 } 1738 1739 /* Try to open the instance key and fail if it exists */ 1740 lError = RegOpenKeyExW(hKeyDevice, 1741 szInstance, 1742 0, 1743 KEY_SET_VALUE, 1744 &hKeyInstance); 1745 if (lError == ERROR_SUCCESS) 1746 { 1747 DPRINT1("Instance %S already exists!\n", szInstance); 1748 RegCloseKey(hKeyInstance); 1749 RegCloseKey(hKeyDevice); 1750 return CR_ALREADY_SUCH_DEVINST; 1751 } 1752 1753 /* Create a new instance key */ 1754 lError = RegCreateKeyExW(hKeyDevice, 1755 szInstance, 1756 0, 1757 NULL, 1758 REG_OPTION_NON_VOLATILE, 1759 KEY_ALL_ACCESS, 1760 NULL, 1761 &hKeyInstance, 1762 NULL); 1763 1764 /* Close the device key */ 1765 RegCloseKey(hKeyDevice); 1766 1767 if (lError != ERROR_SUCCESS) 1768 { 1769 return CR_REGISTRY_ERROR; 1770 } 1771 1772 /* Create the 'Control' sub key */ 1773 lError = RegCreateKeyExW(hKeyInstance, 1774 L"Control", 1775 0, 1776 NULL, 1777 REG_OPTION_NON_VOLATILE, 1778 KEY_ALL_ACCESS, 1779 NULL, 1780 &hKeyControl, 1781 NULL); 1782 if (lError == ERROR_SUCCESS) 1783 { 1784 RegCloseKey(hKeyControl); 1785 } 1786 1787 RegCloseKey(hKeyInstance); 1788 1789 return (lError == ERROR_SUCCESS) ? CR_SUCCESS : CR_REGISTRY_ERROR; 1790 } 1791 1792 1793 /* Function 28 */ 1794 DWORD 1795 WINAPI 1796 PNP_CreateDevInst( 1797 handle_t hBinding, 1798 LPWSTR pszDeviceID, 1799 LPWSTR pszParentDeviceID, 1800 PNP_RPC_STRING_LEN ulLength, 1801 DWORD ulFlags) 1802 { 1803 CONFIGRET ret = CR_SUCCESS; 1804 1805 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID); 1806 1807 if (ulFlags & CM_CREATE_DEVNODE_GENERATE_ID) 1808 { 1809 WCHAR szGeneratedInstance[MAX_DEVICE_ID_LEN]; 1810 DWORD dwInstanceNumber; 1811 1812 /* Generated ID is: Root\<Device ID>\<Instance number> */ 1813 dwInstanceNumber = 0; 1814 do 1815 { 1816 swprintf(szGeneratedInstance, L"Root\\%ls\\%04lu", 1817 pszDeviceID, dwInstanceNumber); 1818 1819 /* Try to create a device instance with this ID */ 1820 ret = CreateDeviceInstance(szGeneratedInstance); 1821 1822 dwInstanceNumber++; 1823 } 1824 while (ret == CR_ALREADY_SUCH_DEVINST); 1825 1826 if (ret == CR_SUCCESS) 1827 { 1828 /* pszDeviceID is an out parameter too for generated IDs */ 1829 if (wcslen(szGeneratedInstance) > ulLength) 1830 { 1831 ret = CR_BUFFER_SMALL; 1832 } 1833 else 1834 { 1835 wcscpy(pszDeviceID, szGeneratedInstance); 1836 } 1837 } 1838 } 1839 else 1840 { 1841 /* Create the device instance */ 1842 ret = CreateDeviceInstance(pszDeviceID); 1843 } 1844 1845 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret); 1846 1847 return ret; 1848 } 1849 1850 1851 static CONFIGRET 1852 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination, 1853 LPWSTR pszDeviceInstanceSource) 1854 { 1855 DPRINT("MoveDeviceInstance: not implemented\n"); 1856 /* FIXME */ 1857 return CR_CALL_NOT_IMPLEMENTED; 1858 } 1859 1860 1861 static CONFIGRET 1862 SetupDeviceInstance(LPWSTR pszDeviceInstance, 1863 DWORD ulFlags) 1864 { 1865 DPRINT("SetupDeviceInstance: not implemented\n"); 1866 /* FIXME */ 1867 return CR_CALL_NOT_IMPLEMENTED; 1868 } 1869 1870 1871 static CONFIGRET 1872 EnableDeviceInstance(LPWSTR pszDeviceInstance) 1873 { 1874 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData; 1875 CONFIGRET ret = CR_SUCCESS; 1876 NTSTATUS Status; 1877 1878 DPRINT("Enable device instance %S\n", pszDeviceInstance); 1879 1880 RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, pszDeviceInstance); 1881 Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA)); 1882 if (!NT_SUCCESS(Status)) 1883 ret = NtStatusToCrError(Status); 1884 1885 return ret; 1886 } 1887 1888 1889 static CONFIGRET 1890 DisableDeviceInstance(LPWSTR pszDeviceInstance) 1891 { 1892 DPRINT("DisableDeviceInstance: not implemented\n"); 1893 /* FIXME */ 1894 return CR_CALL_NOT_IMPLEMENTED; 1895 } 1896 1897 1898 static CONFIGRET 1899 ReenumerateDeviceInstance( 1900 _In_ LPWSTR pszDeviceInstance, 1901 _In_ ULONG ulFlags) 1902 { 1903 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData; 1904 CONFIGRET ret = CR_SUCCESS; 1905 NTSTATUS Status; 1906 1907 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n", 1908 pszDeviceInstance, ulFlags); 1909 1910 if (ulFlags & ~CM_REENUMERATE_BITS) 1911 return CR_INVALID_FLAG; 1912 1913 if (ulFlags & CM_REENUMERATE_RETRY_INSTALLATION) 1914 { 1915 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n"); 1916 } 1917 1918 RtlInitUnicodeString(&EnumerateDeviceData.DeviceInstance, 1919 pszDeviceInstance); 1920 EnumerateDeviceData.Flags = 0; 1921 1922 Status = NtPlugPlayControl(PlugPlayControlEnumerateDevice, 1923 &EnumerateDeviceData, 1924 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA)); 1925 if (!NT_SUCCESS(Status)) 1926 ret = NtStatusToCrError(Status); 1927 1928 return ret; 1929 } 1930 1931 1932 /* Function 29 */ 1933 DWORD 1934 WINAPI 1935 PNP_DeviceInstanceAction( 1936 handle_t hBinding, 1937 DWORD ulAction, 1938 DWORD ulFlags, 1939 LPWSTR pszDeviceInstance1, 1940 LPWSTR pszDeviceInstance2) 1941 { 1942 CONFIGRET ret = CR_SUCCESS; 1943 1944 UNREFERENCED_PARAMETER(hBinding); 1945 1946 DPRINT("PNP_DeviceInstanceAction() called\n"); 1947 1948 switch (ulAction) 1949 { 1950 case PNP_DEVINST_MOVE: 1951 ret = MoveDeviceInstance(pszDeviceInstance1, 1952 pszDeviceInstance2); 1953 break; 1954 1955 case PNP_DEVINST_SETUP: 1956 ret = SetupDeviceInstance(pszDeviceInstance1, 1957 ulFlags); 1958 break; 1959 1960 case PNP_DEVINST_ENABLE: 1961 ret = EnableDeviceInstance(pszDeviceInstance1); 1962 break; 1963 1964 case PNP_DEVINST_DISABLE: 1965 ret = DisableDeviceInstance(pszDeviceInstance1); 1966 break; 1967 1968 case PNP_DEVINST_REENUMERATE: 1969 ret = ReenumerateDeviceInstance(pszDeviceInstance1, 1970 ulFlags); 1971 break; 1972 1973 default: 1974 DPRINT1("Unknown device action %lu: not implemented\n", ulAction); 1975 ret = CR_CALL_NOT_IMPLEMENTED; 1976 } 1977 1978 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret); 1979 1980 return ret; 1981 } 1982 1983 1984 /* Function 30 */ 1985 DWORD 1986 WINAPI 1987 PNP_GetDeviceStatus( 1988 handle_t hBinding, 1989 LPWSTR pDeviceID, 1990 DWORD *pulStatus, 1991 DWORD *pulProblem, 1992 DWORD ulFlags) 1993 { 1994 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData; 1995 CONFIGRET ret = CR_SUCCESS; 1996 NTSTATUS Status; 1997 1998 UNREFERENCED_PARAMETER(hBinding); 1999 UNREFERENCED_PARAMETER(ulFlags); 2000 2001 DPRINT("PNP_GetDeviceStatus() called\n"); 2002 2003 RtlInitUnicodeString(&PlugPlayData.DeviceInstance, 2004 pDeviceID); 2005 PlugPlayData.Operation = 0; /* Get status */ 2006 2007 Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, 2008 (PVOID)&PlugPlayData, 2009 sizeof(PLUGPLAY_CONTROL_STATUS_DATA)); 2010 if (NT_SUCCESS(Status)) 2011 { 2012 *pulStatus = PlugPlayData.DeviceStatus; 2013 *pulProblem = PlugPlayData.DeviceProblem; 2014 } 2015 else 2016 { 2017 ret = NtStatusToCrError(Status); 2018 } 2019 2020 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret); 2021 2022 return ret; 2023 } 2024 2025 2026 /* Function 31 */ 2027 DWORD 2028 WINAPI 2029 PNP_SetDeviceProblem( 2030 handle_t hBinding, 2031 LPWSTR pDeviceID, 2032 DWORD ulProblem, 2033 DWORD ulFlags) 2034 { 2035 UNIMPLEMENTED; 2036 return CR_CALL_NOT_IMPLEMENTED; 2037 } 2038 2039 2040 /* Function 32 */ 2041 DWORD 2042 WINAPI 2043 PNP_DisableDevInst( 2044 handle_t hBinding, 2045 LPWSTR pDeviceID, 2046 PPNP_VETO_TYPE pVetoType, 2047 LPWSTR pszVetoName, 2048 DWORD ulNameLength, 2049 DWORD ulFlags) 2050 { 2051 UNIMPLEMENTED; 2052 return CR_CALL_NOT_IMPLEMENTED; 2053 } 2054 2055 /* Function 33 */ 2056 DWORD 2057 WINAPI 2058 PNP_UninstallDevInst( 2059 handle_t hBinding, 2060 LPWSTR pDeviceID, 2061 DWORD ulFlags) 2062 { 2063 UNIMPLEMENTED; 2064 return CR_CALL_NOT_IMPLEMENTED; 2065 } 2066 2067 2068 static BOOL 2069 CheckForDeviceId(LPWSTR lpDeviceIdList, 2070 LPWSTR lpDeviceId) 2071 { 2072 LPWSTR lpPtr; 2073 DWORD dwLength; 2074 2075 lpPtr = lpDeviceIdList; 2076 while (*lpPtr != 0) 2077 { 2078 dwLength = wcslen(lpPtr); 2079 if (0 == _wcsicmp(lpPtr, lpDeviceId)) 2080 return TRUE; 2081 2082 lpPtr += (dwLength + 1); 2083 } 2084 2085 return FALSE; 2086 } 2087 2088 2089 static VOID 2090 AppendDeviceId(LPWSTR lpDeviceIdList, 2091 LPDWORD lpDeviceIdListSize, 2092 LPWSTR lpDeviceId) 2093 { 2094 DWORD dwLen; 2095 DWORD dwPos; 2096 2097 dwLen = wcslen(lpDeviceId); 2098 dwPos = (*lpDeviceIdListSize / sizeof(WCHAR)) - 1; 2099 2100 wcscpy(&lpDeviceIdList[dwPos], lpDeviceId); 2101 2102 dwPos += (dwLen + 1); 2103 2104 lpDeviceIdList[dwPos] = 0; 2105 2106 *lpDeviceIdListSize = dwPos * sizeof(WCHAR); 2107 } 2108 2109 2110 /* Function 34 */ 2111 DWORD 2112 WINAPI 2113 PNP_AddID( 2114 handle_t hBinding, 2115 LPWSTR pszDeviceID, 2116 LPWSTR pszID, 2117 DWORD ulFlags) 2118 { 2119 CONFIGRET ret = CR_SUCCESS; 2120 HKEY hDeviceKey; 2121 LPWSTR pszSubKey; 2122 DWORD dwDeviceIdListSize; 2123 DWORD dwNewDeviceIdSize; 2124 WCHAR * pszDeviceIdList = NULL; 2125 2126 UNREFERENCED_PARAMETER(hBinding); 2127 2128 DPRINT("PNP_AddID() called\n"); 2129 DPRINT(" DeviceInstance: %S\n", pszDeviceID); 2130 DPRINT(" DeviceId: %S\n", pszID); 2131 DPRINT(" Flags: %lx\n", ulFlags); 2132 2133 if (RegOpenKeyExW(hEnumKey, 2134 pszDeviceID, 2135 0, 2136 KEY_QUERY_VALUE | KEY_SET_VALUE, 2137 &hDeviceKey) != ERROR_SUCCESS) 2138 { 2139 DPRINT("Failed to open the device key!\n"); 2140 return CR_INVALID_DEVNODE; 2141 } 2142 2143 pszSubKey = (ulFlags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID"; 2144 2145 if (RegQueryValueExW(hDeviceKey, 2146 pszSubKey, 2147 NULL, 2148 NULL, 2149 NULL, 2150 &dwDeviceIdListSize) != ERROR_SUCCESS) 2151 { 2152 DPRINT("Failed to query the desired ID string!\n"); 2153 ret = CR_REGISTRY_ERROR; 2154 goto Done; 2155 } 2156 2157 dwNewDeviceIdSize = lstrlenW(pszDeviceID); 2158 if (!dwNewDeviceIdSize) 2159 { 2160 ret = CR_INVALID_POINTER; 2161 goto Done; 2162 } 2163 2164 dwDeviceIdListSize += (dwNewDeviceIdSize + 2) * sizeof(WCHAR); 2165 2166 pszDeviceIdList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeviceIdListSize); 2167 if (!pszDeviceIdList) 2168 { 2169 DPRINT("Failed to allocate memory for the desired ID string!\n"); 2170 ret = CR_OUT_OF_MEMORY; 2171 goto Done; 2172 } 2173 2174 if (RegQueryValueExW(hDeviceKey, 2175 pszSubKey, 2176 NULL, 2177 NULL, 2178 (LPBYTE)pszDeviceIdList, 2179 &dwDeviceIdListSize) != ERROR_SUCCESS) 2180 { 2181 DPRINT("Failed to query the desired ID string!\n"); 2182 ret = CR_REGISTRY_ERROR; 2183 goto Done; 2184 } 2185 2186 /* Check whether the device ID is already in use */ 2187 if (CheckForDeviceId(pszDeviceIdList, pszDeviceID)) 2188 { 2189 DPRINT("Device ID was found in the ID string!\n"); 2190 ret = CR_SUCCESS; 2191 goto Done; 2192 } 2193 2194 /* Append the Device ID */ 2195 AppendDeviceId(pszDeviceIdList, &dwDeviceIdListSize, pszID); 2196 2197 if (RegSetValueExW(hDeviceKey, 2198 pszSubKey, 2199 0, 2200 REG_MULTI_SZ, 2201 (LPBYTE)pszDeviceIdList, 2202 dwDeviceIdListSize) != ERROR_SUCCESS) 2203 { 2204 DPRINT("Failed to set the desired ID string!\n"); 2205 ret = CR_REGISTRY_ERROR; 2206 } 2207 2208 Done: 2209 RegCloseKey(hDeviceKey); 2210 if (pszDeviceIdList) 2211 HeapFree(GetProcessHeap(), 0, pszDeviceIdList); 2212 2213 DPRINT("PNP_AddID() done (returns %lx)\n", ret); 2214 2215 return ret; 2216 } 2217 2218 2219 /* Function 35 */ 2220 DWORD 2221 WINAPI 2222 PNP_RegisterDriver( 2223 handle_t hBinding, 2224 LPWSTR pszDeviceID, 2225 DWORD ulFlags) 2226 { 2227 UNIMPLEMENTED; 2228 return CR_CALL_NOT_IMPLEMENTED; 2229 } 2230 2231 2232 /* Function 36 */ 2233 DWORD 2234 WINAPI 2235 PNP_QueryRemove( 2236 handle_t hBinding, 2237 LPWSTR pszDeviceID, 2238 PPNP_VETO_TYPE pVetoType, 2239 LPWSTR pszVetoName, 2240 DWORD ulNameLength, 2241 DWORD ulFlags) 2242 { 2243 UNIMPLEMENTED; 2244 return CR_CALL_NOT_IMPLEMENTED; 2245 } 2246 2247 2248 /* Function 37 */ 2249 DWORD 2250 WINAPI 2251 PNP_RequestDeviceEject( 2252 handle_t hBinding, 2253 LPWSTR pszDeviceID, 2254 PPNP_VETO_TYPE pVetoType, 2255 LPWSTR pszVetoName, 2256 DWORD ulNameLength, 2257 DWORD ulFlags) 2258 { 2259 UNIMPLEMENTED; 2260 return CR_CALL_NOT_IMPLEMENTED; 2261 } 2262 2263 2264 /* Function 38 */ 2265 CONFIGRET 2266 WINAPI 2267 PNP_IsDockStationPresent( 2268 handle_t hBinding, 2269 BOOL *Present) 2270 { 2271 HKEY hKey; 2272 DWORD dwType; 2273 DWORD dwValue; 2274 DWORD dwSize; 2275 CONFIGRET ret = CR_SUCCESS; 2276 2277 UNREFERENCED_PARAMETER(hBinding); 2278 2279 DPRINT1("PNP_IsDockStationPresent() called\n"); 2280 2281 *Present = FALSE; 2282 2283 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG, 2284 L"CurrentDockInfo", 2285 0, 2286 KEY_READ, 2287 &hKey) != ERROR_SUCCESS) 2288 return CR_REGISTRY_ERROR; 2289 2290 dwSize = sizeof(DWORD); 2291 if (RegQueryValueExW(hKey, 2292 L"DockingState", 2293 NULL, 2294 &dwType, 2295 (LPBYTE)&dwValue, 2296 &dwSize) != ERROR_SUCCESS) 2297 ret = CR_REGISTRY_ERROR; 2298 2299 RegCloseKey(hKey); 2300 2301 if (ret == CR_SUCCESS) 2302 { 2303 if (dwType != REG_DWORD || dwSize != sizeof(DWORD)) 2304 { 2305 ret = CR_REGISTRY_ERROR; 2306 } 2307 else if (dwValue != 0) 2308 { 2309 *Present = TRUE; 2310 } 2311 } 2312 2313 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret); 2314 2315 return ret; 2316 } 2317 2318 2319 /* Function 39 */ 2320 DWORD 2321 WINAPI 2322 PNP_RequestEjectPC( 2323 handle_t hBinding) 2324 { 2325 UNIMPLEMENTED; 2326 return CR_CALL_NOT_IMPLEMENTED; 2327 } 2328 2329 2330 /* Function 40 */ 2331 DWORD 2332 WINAPI 2333 PNP_HwProfFlags( 2334 handle_t hBinding, 2335 DWORD ulAction, 2336 LPWSTR pDeviceID, 2337 DWORD ulConfig, 2338 DWORD *pulValue, 2339 PPNP_VETO_TYPE pVetoType, 2340 LPWSTR pszVetoName, 2341 DWORD ulNameLength, 2342 DWORD ulFlags) 2343 { 2344 CONFIGRET ret = CR_SUCCESS; 2345 WCHAR szKeyName[MAX_PATH]; 2346 HKEY hKey; 2347 HKEY hDeviceKey; 2348 DWORD dwSize; 2349 2350 UNREFERENCED_PARAMETER(hBinding); 2351 2352 DPRINT("PNP_HwProfFlags() called\n"); 2353 2354 if (ulConfig == 0) 2355 { 2356 wcscpy(szKeyName, 2357 L"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum"); 2358 } 2359 else 2360 { 2361 swprintf(szKeyName, 2362 L"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum", 2363 ulConfig); 2364 } 2365 2366 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 2367 szKeyName, 2368 0, 2369 KEY_QUERY_VALUE, 2370 &hKey) != ERROR_SUCCESS) 2371 return CR_REGISTRY_ERROR; 2372 2373 if (ulAction == PNP_GET_HWPROFFLAGS) 2374 { 2375 if (RegOpenKeyExW(hKey, 2376 pDeviceID, 2377 0, 2378 KEY_QUERY_VALUE, 2379 &hDeviceKey) != ERROR_SUCCESS) 2380 { 2381 *pulValue = 0; 2382 } 2383 else 2384 { 2385 dwSize = sizeof(DWORD); 2386 if (RegQueryValueExW(hDeviceKey, 2387 L"CSConfigFlags", 2388 NULL, 2389 NULL, 2390 (LPBYTE)pulValue, 2391 &dwSize) != ERROR_SUCCESS) 2392 { 2393 *pulValue = 0; 2394 } 2395 2396 RegCloseKey(hDeviceKey); 2397 } 2398 } 2399 else if (ulAction == PNP_SET_HWPROFFLAGS) 2400 { 2401 /* FIXME: not implemented yet */ 2402 ret = CR_CALL_NOT_IMPLEMENTED; 2403 } 2404 2405 RegCloseKey(hKey); 2406 2407 return ret; 2408 } 2409 2410 2411 /* Function 41 */ 2412 DWORD 2413 WINAPI 2414 PNP_GetHwProfInfo( 2415 handle_t hBinding, 2416 DWORD ulIndex, 2417 HWPROFILEINFO *pHWProfileInfo, 2418 DWORD ulProfileInfoSize, 2419 DWORD ulFlags) 2420 { 2421 WCHAR szProfileName[5]; 2422 HKEY hKeyConfig = NULL; 2423 HKEY hKeyProfiles = NULL; 2424 HKEY hKeyProfile = NULL; 2425 DWORD dwDisposition; 2426 DWORD dwSize; 2427 LONG lError; 2428 CONFIGRET ret = CR_SUCCESS; 2429 2430 UNREFERENCED_PARAMETER(hBinding); 2431 2432 DPRINT("PNP_GetHwProfInfo() called\n"); 2433 2434 if (ulProfileInfoSize == 0) 2435 { 2436 ret = CR_INVALID_DATA; 2437 goto done; 2438 } 2439 2440 if (ulFlags != 0) 2441 { 2442 ret = CR_INVALID_FLAG; 2443 goto done; 2444 } 2445 2446 /* Initialize the profile information */ 2447 pHWProfileInfo->HWPI_ulHWProfile = 0; 2448 pHWProfileInfo->HWPI_szFriendlyName[0] = 0; 2449 pHWProfileInfo->HWPI_dwFlags = 0; 2450 2451 /* Open the 'IDConfigDB' key */ 2452 lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE, 2453 L"System\\CurrentControlSet\\Control\\IDConfigDB", 2454 0, 2455 NULL, 2456 REG_OPTION_NON_VOLATILE, 2457 KEY_QUERY_VALUE, 2458 NULL, 2459 &hKeyConfig, 2460 &dwDisposition); 2461 if (lError != ERROR_SUCCESS) 2462 { 2463 ret = CR_REGISTRY_ERROR; 2464 goto done; 2465 } 2466 2467 /* Open the 'Hardware Profiles' subkey */ 2468 lError = RegCreateKeyExW(hKeyConfig, 2469 L"Hardware Profiles", 2470 0, 2471 NULL, 2472 REG_OPTION_NON_VOLATILE, 2473 KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, 2474 NULL, 2475 &hKeyProfiles, 2476 &dwDisposition); 2477 if (lError != ERROR_SUCCESS) 2478 { 2479 ret = CR_REGISTRY_ERROR; 2480 goto done; 2481 } 2482 2483 if (ulIndex == (ULONG)-1) 2484 { 2485 dwSize = sizeof(ULONG); 2486 lError = RegQueryValueExW(hKeyConfig, 2487 L"CurrentConfig", 2488 NULL, 2489 NULL, 2490 (LPBYTE)&pHWProfileInfo->HWPI_ulHWProfile, 2491 &dwSize); 2492 if (lError != ERROR_SUCCESS) 2493 { 2494 pHWProfileInfo->HWPI_ulHWProfile = 0; 2495 ret = CR_REGISTRY_ERROR; 2496 goto done; 2497 } 2498 } 2499 else 2500 { 2501 /* FIXME: not implemented yet */ 2502 ret = CR_CALL_NOT_IMPLEMENTED; 2503 goto done; 2504 } 2505 2506 swprintf(szProfileName, L"%04lu", pHWProfileInfo->HWPI_ulHWProfile); 2507 2508 lError = RegOpenKeyExW(hKeyProfiles, 2509 szProfileName, 2510 0, 2511 KEY_QUERY_VALUE, 2512 &hKeyProfile); 2513 if (lError != ERROR_SUCCESS) 2514 { 2515 ret = CR_REGISTRY_ERROR; 2516 goto done; 2517 } 2518 2519 dwSize = sizeof(pHWProfileInfo->HWPI_szFriendlyName); 2520 lError = RegQueryValueExW(hKeyProfile, 2521 L"FriendlyName", 2522 NULL, 2523 NULL, 2524 (LPBYTE)&pHWProfileInfo->HWPI_szFriendlyName, 2525 &dwSize); 2526 if (lError != ERROR_SUCCESS) 2527 { 2528 ret = CR_REGISTRY_ERROR; 2529 goto done; 2530 } 2531 2532 done: 2533 if (hKeyProfile != NULL) 2534 RegCloseKey(hKeyProfile); 2535 2536 if (hKeyProfiles != NULL) 2537 RegCloseKey(hKeyProfiles); 2538 2539 if (hKeyConfig != NULL) 2540 RegCloseKey(hKeyConfig); 2541 2542 return ret; 2543 } 2544 2545 2546 /* Function 42 */ 2547 DWORD 2548 WINAPI 2549 PNP_AddEmptyLogConf( 2550 handle_t hBinding, 2551 LPWSTR pDeviceID, 2552 DWORD ulPriority, 2553 DWORD *pulLogConfTag, 2554 DWORD ulFlags) 2555 { 2556 UNIMPLEMENTED; 2557 return CR_CALL_NOT_IMPLEMENTED; 2558 } 2559 2560 2561 /* Function 43 */ 2562 DWORD 2563 WINAPI 2564 PNP_FreeLogConf( 2565 handle_t hBinding, 2566 LPWSTR pDeviceID, 2567 DWORD ulLogConfType, 2568 DWORD ulLogConfTag, 2569 DWORD ulFlags) 2570 { 2571 UNIMPLEMENTED; 2572 return CR_CALL_NOT_IMPLEMENTED; 2573 } 2574 2575 2576 /* Function 44 */ 2577 DWORD 2578 WINAPI 2579 PNP_GetFirstLogConf( 2580 handle_t hBinding, 2581 LPWSTR pDeviceID, 2582 DWORD ulLogConfType, 2583 DWORD *pulLogConfTag, 2584 DWORD ulFlags) 2585 { 2586 UNIMPLEMENTED; 2587 return CR_CALL_NOT_IMPLEMENTED; 2588 } 2589 2590 2591 /* Function 45 */ 2592 DWORD 2593 WINAPI 2594 PNP_GetNextLogConf( 2595 handle_t hBinding, 2596 LPWSTR pDeviceID, 2597 DWORD ulLogConfType, 2598 DWORD ulCurrentTag, 2599 DWORD *pulNextTag, 2600 DWORD ulFlags) 2601 { 2602 UNIMPLEMENTED; 2603 return CR_CALL_NOT_IMPLEMENTED; 2604 } 2605 2606 2607 /* Function 46 */ 2608 DWORD 2609 WINAPI 2610 PNP_GetLogConfPriority( 2611 handle_t hBinding, 2612 LPWSTR pDeviceID, 2613 DWORD ulType, 2614 DWORD ulTag, 2615 DWORD *pPriority, 2616 DWORD ulFlags) 2617 { 2618 UNIMPLEMENTED; 2619 return CR_CALL_NOT_IMPLEMENTED; 2620 } 2621 2622 2623 /* Function 47 */ 2624 DWORD 2625 WINAPI 2626 PNP_AddResDes( 2627 handle_t hBinding, 2628 LPWSTR pDeviceID, 2629 DWORD ulLogConfTag, 2630 DWORD ulLogConfType, 2631 RESOURCEID ResourceID, 2632 DWORD *pulResourceTag, 2633 BYTE *ResourceData, 2634 PNP_RPC_BUFFER_SIZE ResourceLen, 2635 DWORD ulFlags) 2636 { 2637 UNIMPLEMENTED; 2638 return CR_CALL_NOT_IMPLEMENTED; 2639 } 2640 2641 2642 /* Function 48 */ 2643 DWORD 2644 WINAPI 2645 PNP_FreeResDes( 2646 handle_t hBinding, 2647 LPWSTR pDeviceID, 2648 DWORD ulLogConfTag, 2649 DWORD ulLogConfType, 2650 RESOURCEID ResourceID, 2651 DWORD ulResourceTag, 2652 DWORD *pulPreviousResType, 2653 DWORD *pulPreviousResTag, 2654 DWORD ulFlags) 2655 { 2656 UNIMPLEMENTED; 2657 return CR_CALL_NOT_IMPLEMENTED; 2658 } 2659 2660 2661 /* Function 49 */ 2662 DWORD 2663 WINAPI 2664 PNP_GetNextResDes( 2665 handle_t hBinding, 2666 LPWSTR pDeviceID, 2667 DWORD ulLogConfTag, 2668 DWORD ulLogConfType, 2669 RESOURCEID ResourceID, 2670 DWORD ulResourceTag, 2671 DWORD *pulNextResType, 2672 DWORD *pulNextResTag, 2673 DWORD ulFlags) 2674 { 2675 UNIMPLEMENTED; 2676 return CR_CALL_NOT_IMPLEMENTED; 2677 } 2678 2679 2680 /* Function 50 */ 2681 DWORD 2682 WINAPI 2683 PNP_GetResDesData( 2684 handle_t hBinding, 2685 LPWSTR pDeviceID, 2686 DWORD ulLogConfTag, 2687 DWORD ulLogConfType, 2688 RESOURCEID ResourceID, 2689 DWORD ulResourceTag, 2690 BYTE *Buffer, 2691 PNP_RPC_BUFFER_SIZE BufferLen, 2692 DWORD ulFlags) 2693 { 2694 UNIMPLEMENTED; 2695 return CR_CALL_NOT_IMPLEMENTED; 2696 } 2697 2698 2699 /* Function 51 */ 2700 DWORD 2701 WINAPI 2702 PNP_GetResDesDataSize( 2703 handle_t hBinding, 2704 LPWSTR pDeviceID, 2705 DWORD ulLogConfTag, 2706 DWORD ulLogConfType, 2707 RESOURCEID ResourceID, 2708 DWORD ulResourceTag, 2709 DWORD *pulSize, 2710 DWORD ulFlags) 2711 { 2712 UNIMPLEMENTED; 2713 return CR_CALL_NOT_IMPLEMENTED; 2714 } 2715 2716 2717 /* Function 52 */ 2718 DWORD 2719 WINAPI 2720 PNP_ModifyResDes( 2721 handle_t hBinding, 2722 LPWSTR pDeviceID, 2723 DWORD ulLogConfTag, 2724 DWORD ulLogConfType, 2725 RESOURCEID CurrentResourceID, 2726 RESOURCEID NewResourceID, 2727 DWORD ulResourceTag, 2728 BYTE *ResourceData, 2729 PNP_RPC_BUFFER_SIZE ResourceLen, 2730 DWORD ulFlags) 2731 { 2732 UNIMPLEMENTED; 2733 return CR_CALL_NOT_IMPLEMENTED; 2734 } 2735 2736 2737 /* Function 53 */ 2738 DWORD 2739 WINAPI 2740 PNP_DetectResourceConflict( 2741 handle_t hBinding, 2742 LPWSTR pDeviceID, 2743 RESOURCEID ResourceID, 2744 BYTE *ResourceData, 2745 PNP_RPC_BUFFER_SIZE ResourceLen, 2746 BOOL *pbConflictDetected, 2747 DWORD ulFlags) 2748 { 2749 DPRINT("PNP_DetectResourceConflict()\n"); 2750 2751 if (pbConflictDetected != NULL) 2752 *pbConflictDetected = FALSE; 2753 2754 return CR_CALL_NOT_IMPLEMENTED; 2755 } 2756 2757 2758 /* Function 54 */ 2759 DWORD 2760 WINAPI 2761 PNP_QueryResConfList( 2762 handle_t hBinding, 2763 LPWSTR pDeviceID, 2764 RESOURCEID ResourceID, 2765 BYTE *ResourceData, 2766 PNP_RPC_BUFFER_SIZE ResourceLen, 2767 BYTE *Buffer, 2768 PNP_RPC_BUFFER_SIZE BufferLen, 2769 DWORD ulFlags) 2770 { 2771 UNIMPLEMENTED; 2772 return CR_CALL_NOT_IMPLEMENTED; 2773 } 2774 2775 2776 /* Function 55 */ 2777 DWORD 2778 WINAPI 2779 PNP_SetHwProf( 2780 handle_t hBinding, 2781 DWORD ulHardwareProfile, 2782 DWORD ulFlags) 2783 { 2784 UNIMPLEMENTED; 2785 return CR_CALL_NOT_IMPLEMENTED; 2786 } 2787 2788 2789 /* Function 56 */ 2790 DWORD 2791 WINAPI 2792 PNP_QueryArbitratorFreeData( 2793 handle_t hBinding, 2794 BYTE *pData, 2795 DWORD DataLen, 2796 LPWSTR pDeviceID, 2797 RESOURCEID ResourceID, 2798 DWORD ulFlags) 2799 { 2800 UNIMPLEMENTED; 2801 return CR_CALL_NOT_IMPLEMENTED; 2802 } 2803 2804 2805 /* Function 57 */ 2806 DWORD 2807 WINAPI 2808 PNP_QueryArbitratorFreeSize( 2809 handle_t hBinding, 2810 DWORD *pulSize, 2811 LPWSTR pDeviceID, 2812 RESOURCEID ResourceID, 2813 DWORD ulFlags) 2814 { 2815 UNIMPLEMENTED; 2816 return CR_CALL_NOT_IMPLEMENTED; 2817 } 2818 2819 2820 /* Function 58 */ 2821 CONFIGRET 2822 WINAPI 2823 PNP_RunDetection( 2824 handle_t hBinding, 2825 DWORD ulFlags) 2826 { 2827 return CR_CALL_NOT_IMPLEMENTED; 2828 } 2829 2830 2831 /* Function 59 */ 2832 DWORD 2833 WINAPI 2834 PNP_RegisterNotification( 2835 handle_t hBinding, 2836 DWORD ulFlags, 2837 DWORD *pulNotify) 2838 { 2839 #if 0 2840 PNOTIFY_DATA pNotifyData; 2841 #endif 2842 2843 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n", 2844 hBinding, ulFlags, pulNotify); 2845 2846 #if 0 2847 pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_DATA)); 2848 if (pNotifyData == NULL) 2849 return CR_OUT_OF_MEMORY; 2850 2851 *pulNotify = (DWORD)pNotifyData; 2852 #endif 2853 2854 *pulNotify = 1; 2855 2856 return CR_SUCCESS; 2857 } 2858 2859 2860 /* Function 60 */ 2861 DWORD 2862 WINAPI 2863 PNP_UnregisterNotification( 2864 handle_t hBinding, 2865 DWORD ulNotify) 2866 { 2867 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n", 2868 hBinding, ulNotify); 2869 2870 #if 0 2871 UNIMPLEMENTED; 2872 return CR_CALL_NOT_IMPLEMENTED; 2873 #endif 2874 2875 return CR_SUCCESS; 2876 } 2877 2878 2879 /* Function 61 */ 2880 DWORD 2881 WINAPI 2882 PNP_GetCustomDevProp( 2883 handle_t hBinding, 2884 LPWSTR pDeviceID, 2885 LPWSTR CustomPropName, 2886 DWORD *pulRegDataType, 2887 BYTE *Buffer, 2888 PNP_RPC_STRING_LEN *pulTransferLen, 2889 PNP_RPC_STRING_LEN *pulLength, 2890 DWORD ulFlags) 2891 { 2892 HKEY hDeviceKey = NULL; 2893 HKEY hParamKey = NULL; 2894 LONG lError; 2895 CONFIGRET ret = CR_SUCCESS; 2896 2897 UNREFERENCED_PARAMETER(hBinding); 2898 2899 DPRINT("PNP_GetCustomDevProp() called\n"); 2900 2901 if (pulTransferLen == NULL || pulLength == NULL) 2902 { 2903 ret = CR_INVALID_POINTER; 2904 goto done; 2905 } 2906 2907 if (ulFlags & ~CM_CUSTOMDEVPROP_BITS) 2908 { 2909 ret = CR_INVALID_FLAG; 2910 goto done; 2911 } 2912 2913 if (*pulLength < *pulTransferLen) 2914 *pulLength = *pulTransferLen; 2915 2916 *pulTransferLen = 0; 2917 2918 lError = RegOpenKeyExW(hEnumKey, 2919 pDeviceID, 2920 0, 2921 KEY_READ, 2922 &hDeviceKey); 2923 if (lError != ERROR_SUCCESS) 2924 { 2925 ret = CR_REGISTRY_ERROR; 2926 goto done; 2927 } 2928 2929 lError = RegOpenKeyExW(hDeviceKey, 2930 L"Device Parameters", 2931 0, 2932 KEY_READ, 2933 &hParamKey); 2934 if (lError != ERROR_SUCCESS) 2935 { 2936 ret = CR_REGISTRY_ERROR; 2937 goto done; 2938 } 2939 2940 lError = RegQueryValueExW(hParamKey, 2941 CustomPropName, 2942 NULL, 2943 pulRegDataType, 2944 Buffer, 2945 pulLength); 2946 if (lError != ERROR_SUCCESS) 2947 { 2948 if (lError == ERROR_MORE_DATA) 2949 { 2950 ret = CR_BUFFER_SMALL; 2951 } 2952 else 2953 { 2954 *pulLength = 0; 2955 ret = CR_NO_SUCH_VALUE; 2956 } 2957 } 2958 2959 done: 2960 if (ret == CR_SUCCESS) 2961 *pulTransferLen = *pulLength; 2962 2963 if (hParamKey != NULL) 2964 RegCloseKey(hParamKey); 2965 2966 if (hDeviceKey != NULL) 2967 RegCloseKey(hDeviceKey); 2968 2969 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret); 2970 2971 return ret; 2972 } 2973 2974 2975 /* Function 62 */ 2976 DWORD 2977 WINAPI 2978 PNP_GetVersionInternal( 2979 handle_t hBinding, 2980 WORD *pwVersion) 2981 { 2982 UNREFERENCED_PARAMETER(hBinding); 2983 2984 *pwVersion = 0x501; 2985 return CR_SUCCESS; 2986 } 2987 2988 2989 /* Function 63 */ 2990 DWORD 2991 WINAPI 2992 PNP_GetBlockedDriverInfo( 2993 handle_t hBinding, 2994 BYTE *Buffer, 2995 PNP_RPC_BUFFER_SIZE *pulTransferLen, 2996 PNP_RPC_BUFFER_SIZE *pulLength, 2997 DWORD ulFlags) 2998 { 2999 UNIMPLEMENTED; 3000 return CR_CALL_NOT_IMPLEMENTED; 3001 } 3002 3003 3004 /* Function 64 */ 3005 DWORD 3006 WINAPI 3007 PNP_GetServerSideDeviceInstallFlags( 3008 handle_t hBinding, 3009 DWORD *pulSSDIFlags, 3010 DWORD ulFlags) 3011 { 3012 UNREFERENCED_PARAMETER(hBinding); 3013 3014 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n", 3015 hBinding, pulSSDIFlags, ulFlags); 3016 3017 if (pulSSDIFlags == NULL) 3018 return CR_INVALID_POINTER; 3019 3020 if (ulFlags != 0) 3021 return CR_INVALID_FLAG; 3022 3023 /* FIXME */ 3024 *pulSSDIFlags = 0; 3025 3026 return CR_SUCCESS; 3027 } 3028 3029 3030 /* Function 65 */ 3031 DWORD 3032 WINAPI 3033 PNP_GetObjectPropKeys( 3034 handle_t hBinding, 3035 LPWSTR ObjectName, 3036 DWORD ObjectType, 3037 LPWSTR PropertyCultureName, 3038 PNP_PROP_COUNT *PropertyCount, 3039 PNP_PROP_COUNT *TransferLen, 3040 DEVPROPKEY *PropertyKeys, 3041 DWORD Flags) 3042 { 3043 UNIMPLEMENTED; 3044 return CR_CALL_NOT_IMPLEMENTED; 3045 } 3046 3047 3048 /* Function 66 */ 3049 DWORD 3050 WINAPI 3051 PNP_GetObjectProp( 3052 handle_t hBinding, 3053 LPWSTR ObjectName, 3054 DWORD ObjectType, 3055 LPWSTR PropertyCultureName, 3056 const DEVPROPKEY *PropertyKey, 3057 DEVPROPTYPE *PropertyType, 3058 PNP_PROP_SIZE *PropertySize, 3059 PNP_PROP_SIZE *TransferLen, 3060 BYTE *PropertyBuffer, 3061 DWORD Flags) 3062 { 3063 UNIMPLEMENTED; 3064 return CR_CALL_NOT_IMPLEMENTED; 3065 } 3066 3067 3068 /* Function 67 */ 3069 DWORD 3070 WINAPI 3071 PNP_SetObjectProp( 3072 handle_t hBinding, 3073 LPWSTR ObjectName, 3074 DWORD ObjectType, 3075 LPWSTR PropertyCultureName, 3076 const DEVPROPKEY *PropertyKey, 3077 DEVPROPTYPE PropertyType, 3078 PNP_PROP_SIZE PropertySize, 3079 BYTE *PropertyBuffer, 3080 DWORD Flags) 3081 { 3082 UNIMPLEMENTED; 3083 return CR_CALL_NOT_IMPLEMENTED; 3084 } 3085 3086 3087 /* Function 68 */ 3088 DWORD 3089 WINAPI 3090 PNP_InstallDevInst( 3091 handle_t hBinding) 3092 { 3093 UNIMPLEMENTED; 3094 return CR_CALL_NOT_IMPLEMENTED; 3095 } 3096 3097 3098 /* Function 69 */ 3099 DWORD 3100 WINAPI 3101 PNP_ApplyPowerSettings( 3102 handle_t hBinding) 3103 { 3104 UNIMPLEMENTED; 3105 return CR_CALL_NOT_IMPLEMENTED; 3106 } 3107 3108 3109 /* Function 70 */ 3110 DWORD 3111 WINAPI 3112 PNP_DriverStoreAddDriverPackage( 3113 handle_t hBinding) 3114 { 3115 UNIMPLEMENTED; 3116 return CR_CALL_NOT_IMPLEMENTED; 3117 } 3118 3119 3120 /* Function 71 */ 3121 DWORD 3122 WINAPI 3123 PNP_DriverStoreDeleteDriverPackage( 3124 handle_t hBinding) 3125 { 3126 UNIMPLEMENTED; 3127 return CR_CALL_NOT_IMPLEMENTED; 3128 } 3129 3130 3131 /* Function 72 */ 3132 DWORD 3133 WINAPI 3134 PNP_RegisterServiceNotification( 3135 handle_t hBinding) 3136 { 3137 UNIMPLEMENTED; 3138 return CR_CALL_NOT_IMPLEMENTED; 3139 } 3140 3141 3142 /* Function 73 */ 3143 DWORD 3144 WINAPI 3145 PNP_SetActiveService( 3146 handle_t hBinding, 3147 LPWSTR pszFilter, 3148 DWORD ulFlags) 3149 { 3150 UNIMPLEMENTED; 3151 return CR_CALL_NOT_IMPLEMENTED; 3152 } 3153 3154 3155 /* Function 74 */ 3156 DWORD 3157 WINAPI 3158 PNP_DeleteServiceDevices( 3159 handle_t hBinding) 3160 { 3161 UNIMPLEMENTED; 3162 return CR_CALL_NOT_IMPLEMENTED; 3163 } 3164 3165 3166 static BOOL 3167 InstallDevice(PCWSTR DeviceInstance, BOOL ShowWizard) 3168 { 3169 BOOL DeviceInstalled = FALSE; 3170 DWORD BytesWritten; 3171 DWORD Value; 3172 HANDLE hInstallEvent; 3173 HANDLE hPipe = INVALID_HANDLE_VALUE; 3174 LPVOID Environment = NULL; 3175 PROCESS_INFORMATION ProcessInfo; 3176 STARTUPINFOW StartupInfo; 3177 UUID RandomUuid; 3178 HKEY DeviceKey; 3179 3180 /* The following lengths are constant (see below), they cannot overflow */ 3181 WCHAR CommandLine[116]; 3182 WCHAR InstallEventName[73]; 3183 WCHAR PipeName[74]; 3184 WCHAR UuidString[39]; 3185 3186 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance, ShowWizard); 3187 3188 ZeroMemory(&ProcessInfo, sizeof(ProcessInfo)); 3189 3190 if (RegOpenKeyExW(hEnumKey, 3191 DeviceInstance, 3192 0, 3193 KEY_QUERY_VALUE, 3194 &DeviceKey) == ERROR_SUCCESS) 3195 { 3196 if (RegQueryValueExW(DeviceKey, 3197 L"Class", 3198 NULL, 3199 NULL, 3200 NULL, 3201 NULL) == ERROR_SUCCESS) 3202 { 3203 DPRINT("No need to install: %S\n", DeviceInstance); 3204 RegCloseKey(DeviceKey); 3205 return TRUE; 3206 } 3207 3208 BytesWritten = sizeof(DWORD); 3209 if (RegQueryValueExW(DeviceKey, 3210 L"ConfigFlags", 3211 NULL, 3212 NULL, 3213 (PBYTE)&Value, 3214 &BytesWritten) == ERROR_SUCCESS) 3215 { 3216 if (Value & CONFIGFLAG_FAILEDINSTALL) 3217 { 3218 DPRINT("No need to install: %S\n", DeviceInstance); 3219 RegCloseKey(DeviceKey); 3220 return TRUE; 3221 } 3222 } 3223 3224 RegCloseKey(DeviceKey); 3225 } 3226 3227 DPRINT1("Installing: %S\n", DeviceInstance); 3228 3229 /* Create a random UUID for the named pipe & event*/ 3230 UuidCreate(&RandomUuid); 3231 swprintf(UuidString, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", 3232 RandomUuid.Data1, RandomUuid.Data2, RandomUuid.Data3, 3233 RandomUuid.Data4[0], RandomUuid.Data4[1], RandomUuid.Data4[2], 3234 RandomUuid.Data4[3], RandomUuid.Data4[4], RandomUuid.Data4[5], 3235 RandomUuid.Data4[6], RandomUuid.Data4[7]); 3236 3237 /* Create the event */ 3238 wcscpy(InstallEventName, L"Global\\PNP_Device_Install_Event_0."); 3239 wcscat(InstallEventName, UuidString); 3240 hInstallEvent = CreateEventW(NULL, TRUE, FALSE, InstallEventName); 3241 if (!hInstallEvent) 3242 { 3243 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName, GetLastError()); 3244 goto cleanup; 3245 } 3246 3247 /* Create the named pipe */ 3248 wcscpy(PipeName, L"\\\\.\\pipe\\PNP_Device_Install_Pipe_0."); 3249 wcscat(PipeName, UuidString); 3250 hPipe = CreateNamedPipeW(PipeName, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 512, 512, 0, NULL); 3251 if (hPipe == INVALID_HANDLE_VALUE) 3252 { 3253 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError()); 3254 goto cleanup; 3255 } 3256 3257 /* Launch rundll32 to call ClientSideInstallW */ 3258 wcscpy(CommandLine, L"rundll32.exe newdev.dll,ClientSideInstall "); 3259 wcscat(CommandLine, PipeName); 3260 3261 ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 3262 StartupInfo.cb = sizeof(StartupInfo); 3263 3264 if (hUserToken) 3265 { 3266 /* newdev has to run under the environment of the current user */ 3267 if (!CreateEnvironmentBlock(&Environment, hUserToken, FALSE)) 3268 { 3269 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError()); 3270 goto cleanup; 3271 } 3272 3273 if (!CreateProcessAsUserW(hUserToken, NULL, CommandLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, Environment, NULL, &StartupInfo, &ProcessInfo)) 3274 { 3275 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError()); 3276 goto cleanup; 3277 } 3278 } 3279 else 3280 { 3281 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges. 3282 3283 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here. 3284 (ShowWizard is only set to FALSE for these two modes) */ 3285 ASSERT(!ShowWizard); 3286 3287 if (!CreateProcessW(NULL, CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)) 3288 { 3289 DPRINT1("CreateProcessW failed with error %u\n", GetLastError()); 3290 goto cleanup; 3291 } 3292 } 3293 3294 /* Wait for the function to connect to our pipe */ 3295 if (!ConnectNamedPipe(hPipe, NULL)) 3296 { 3297 if (GetLastError() != ERROR_PIPE_CONNECTED) 3298 { 3299 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError()); 3300 goto cleanup; 3301 } 3302 } 3303 3304 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */ 3305 Value = sizeof(InstallEventName); 3306 WriteFile(hPipe, &Value, sizeof(Value), &BytesWritten, NULL); 3307 WriteFile(hPipe, InstallEventName, Value, &BytesWritten, NULL); 3308 3309 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once. 3310 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */ 3311 WriteFile(hPipe, &ShowWizard, sizeof(ShowWizard), &BytesWritten, NULL); 3312 3313 Value = (wcslen(DeviceInstance) + 1) * sizeof(WCHAR); 3314 WriteFile(hPipe, &Value, sizeof(Value), &BytesWritten, NULL); 3315 WriteFile(hPipe, DeviceInstance, Value, &BytesWritten, NULL); 3316 3317 /* Wait for newdev.dll to finish processing */ 3318 WaitForSingleObject(ProcessInfo.hProcess, INFINITE); 3319 3320 /* If the event got signalled, this is success */ 3321 DeviceInstalled = WaitForSingleObject(hInstallEvent, 0) == WAIT_OBJECT_0; 3322 3323 cleanup: 3324 if (hInstallEvent) 3325 CloseHandle(hInstallEvent); 3326 3327 if (hPipe != INVALID_HANDLE_VALUE) 3328 CloseHandle(hPipe); 3329 3330 if (Environment) 3331 DestroyEnvironmentBlock(Environment); 3332 3333 if (ProcessInfo.hProcess) 3334 CloseHandle(ProcessInfo.hProcess); 3335 3336 if (ProcessInfo.hThread) 3337 CloseHandle(ProcessInfo.hThread); 3338 3339 if (!DeviceInstalled) 3340 { 3341 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance); 3342 } 3343 3344 return DeviceInstalled; 3345 } 3346 3347 3348 static LONG 3349 ReadRegSzKey( 3350 IN HKEY hKey, 3351 IN LPCWSTR pszKey, 3352 OUT LPWSTR* pValue) 3353 { 3354 LONG rc; 3355 DWORD dwType; 3356 DWORD cbData = 0; 3357 LPWSTR Value; 3358 3359 if (!pValue) 3360 return ERROR_INVALID_PARAMETER; 3361 3362 *pValue = NULL; 3363 rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); 3364 if (rc != ERROR_SUCCESS) 3365 return rc; 3366 if (dwType != REG_SZ) 3367 return ERROR_FILE_NOT_FOUND; 3368 Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); 3369 if (!Value) 3370 return ERROR_NOT_ENOUGH_MEMORY; 3371 rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData); 3372 if (rc != ERROR_SUCCESS) 3373 { 3374 HeapFree(GetProcessHeap(), 0, Value); 3375 return rc; 3376 } 3377 /* NULL-terminate the string */ 3378 Value[cbData / sizeof(WCHAR)] = '\0'; 3379 3380 *pValue = Value; 3381 return ERROR_SUCCESS; 3382 } 3383 3384 3385 static BOOL 3386 SetupIsActive(VOID) 3387 { 3388 HKEY hKey = NULL; 3389 DWORD regType, active, size; 3390 LONG rc; 3391 BOOL ret = FALSE; 3392 3393 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_QUERY_VALUE, &hKey); 3394 if (rc != ERROR_SUCCESS) 3395 goto cleanup; 3396 3397 size = sizeof(DWORD); 3398 rc = RegQueryValueExW(hKey, L"SystemSetupInProgress", NULL, ®Type, (LPBYTE)&active, &size); 3399 if (rc != ERROR_SUCCESS) 3400 goto cleanup; 3401 if (regType != REG_DWORD || size != sizeof(DWORD)) 3402 goto cleanup; 3403 3404 ret = (active != 0); 3405 3406 cleanup: 3407 if (hKey != NULL) 3408 RegCloseKey(hKey); 3409 3410 DPRINT("System setup in progress? %S\n", ret ? L"YES" : L"NO"); 3411 3412 return ret; 3413 } 3414 3415 3416 static BOOL 3417 IsConsoleBoot(VOID) 3418 { 3419 HKEY ControlKey = NULL; 3420 LPWSTR SystemStartOptions = NULL; 3421 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */ 3422 BOOL ConsoleBoot = FALSE; 3423 LONG rc; 3424 3425 rc = RegOpenKeyExW( 3426 HKEY_LOCAL_MACHINE, 3427 L"SYSTEM\\CurrentControlSet\\Control", 3428 0, 3429 KEY_QUERY_VALUE, 3430 &ControlKey); 3431 3432 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions); 3433 if (rc != ERROR_SUCCESS) 3434 goto cleanup; 3435 3436 /* Check for CONSOLE switch in SystemStartOptions */ 3437 CurrentOption = SystemStartOptions; 3438 while (CurrentOption) 3439 { 3440 NextOption = wcschr(CurrentOption, L' '); 3441 if (NextOption) 3442 *NextOption = L'\0'; 3443 if (_wcsicmp(CurrentOption, L"CONSOLE") == 0) 3444 { 3445 DPRINT("Found %S. Switching to console boot\n", CurrentOption); 3446 ConsoleBoot = TRUE; 3447 goto cleanup; 3448 } 3449 CurrentOption = NextOption ? NextOption + 1 : NULL; 3450 } 3451 3452 cleanup: 3453 if (ControlKey != NULL) 3454 RegCloseKey(ControlKey); 3455 HeapFree(GetProcessHeap(), 0, SystemStartOptions); 3456 return ConsoleBoot; 3457 } 3458 3459 3460 /* Loop to install all queued devices installations */ 3461 static DWORD WINAPI 3462 DeviceInstallThread(LPVOID lpParameter) 3463 { 3464 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED 3465 PSLIST_ENTRY ListEntry; 3466 #else 3467 PLIST_ENTRY ListEntry; 3468 #endif 3469 DeviceInstallParams* Params; 3470 BOOL showWizard; 3471 3472 UNREFERENCED_PARAMETER(lpParameter); 3473 3474 WaitForSingleObject(hInstallEvent, INFINITE); 3475 3476 showWizard = !SetupIsActive() && !IsConsoleBoot(); 3477 3478 while (TRUE) 3479 { 3480 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED 3481 ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead); 3482 #else 3483 if ((BOOL)IsListEmpty(&DeviceInstallListHead)) 3484 ListEntry = NULL; 3485 else 3486 ListEntry = RemoveHeadList(&DeviceInstallListHead); 3487 #endif 3488 if (ListEntry == NULL) 3489 { 3490 SetEvent(hNoPendingInstalls); 3491 WaitForSingleObject(hDeviceInstallListNotEmpty, INFINITE); 3492 } 3493 else 3494 { 3495 ResetEvent(hNoPendingInstalls); 3496 Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry); 3497 InstallDevice(Params->DeviceIds, showWizard); 3498 } 3499 } 3500 3501 return 0; 3502 } 3503 3504 3505 static DWORD WINAPI 3506 PnpEventThread(LPVOID lpParameter) 3507 { 3508 PPLUGPLAY_EVENT_BLOCK PnpEvent; 3509 ULONG PnpEventSize; 3510 NTSTATUS Status; 3511 RPC_STATUS RpcStatus; 3512 3513 UNREFERENCED_PARAMETER(lpParameter); 3514 3515 PnpEventSize = 0x1000; 3516 PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize); 3517 if (PnpEvent == NULL) 3518 return ERROR_OUTOFMEMORY; 3519 3520 for (;;) 3521 { 3522 DPRINT("Calling NtGetPlugPlayEvent()\n"); 3523 3524 /* Wait for the next pnp event */ 3525 Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize); 3526 3527 /* Resize the buffer for the PnP event if it's too small. */ 3528 if (Status == STATUS_BUFFER_TOO_SMALL) 3529 { 3530 PnpEventSize += 0x400; 3531 HeapFree(GetProcessHeap(), 0, PnpEvent); 3532 PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize); 3533 if (PnpEvent == NULL) 3534 return ERROR_OUTOFMEMORY; 3535 continue; 3536 } 3537 3538 if (!NT_SUCCESS(Status)) 3539 { 3540 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status); 3541 break; 3542 } 3543 3544 /* Process the pnp event */ 3545 DPRINT("Received PnP Event\n"); 3546 if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ENUMERATED, &RpcStatus)) 3547 { 3548 DeviceInstallParams* Params; 3549 DWORD len; 3550 DWORD DeviceIdLength; 3551 3552 DPRINT("Device enumerated: %S\n", PnpEvent->TargetDevice.DeviceIds); 3553 3554 DeviceIdLength = lstrlenW(PnpEvent->TargetDevice.DeviceIds); 3555 if (DeviceIdLength) 3556 { 3557 /* Queue device install (will be dequeued by DeviceInstallThread */ 3558 len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR); 3559 Params = HeapAlloc(GetProcessHeap(), 0, len); 3560 if (Params) 3561 { 3562 wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds); 3563 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED 3564 InterlockedPushEntrySList(&DeviceInstallListHead, &Params->ListEntry); 3565 #else 3566 InsertTailList(&DeviceInstallListHead, &Params->ListEntry); 3567 #endif 3568 SetEvent(hDeviceInstallListNotEmpty); 3569 } 3570 } 3571 } 3572 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus)) 3573 { 3574 // DWORD dwRecipient; 3575 3576 DPRINT("Device arrival: %S\n", PnpEvent->TargetDevice.DeviceIds); 3577 3578 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS; 3579 // BroadcastSystemMessageW(BSF_POSTMESSAGE, 3580 // &dwRecipient, 3581 // WM_DEVICECHANGE, 3582 // DBT_DEVNODES_CHANGED, 3583 // 0); 3584 SendMessageW(HWND_BROADCAST, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, 0); 3585 } 3586 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_EJECT_VETOED, &RpcStatus)) 3587 { 3588 DPRINT1("Eject vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds); 3589 } 3590 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_KERNEL_INITIATED_EJECT, &RpcStatus)) 3591 { 3592 DPRINT1("Kernel initiated eject: %S\n", PnpEvent->TargetDevice.DeviceIds); 3593 } 3594 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SAFE_REMOVAL, &RpcStatus)) 3595 { 3596 // DWORD dwRecipient; 3597 3598 DPRINT1("Safe removal: %S\n", PnpEvent->TargetDevice.DeviceIds); 3599 3600 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS; 3601 // BroadcastSystemMessageW(BSF_POSTMESSAGE, 3602 // &dwRecipient, 3603 // WM_DEVICECHANGE, 3604 // DBT_DEVNODES_CHANGED, 3605 // 0); 3606 SendMessageW(HWND_BROADCAST, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, 0); 3607 } 3608 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SURPRISE_REMOVAL, &RpcStatus)) 3609 { 3610 // DWORD dwRecipient; 3611 3612 DPRINT1("Surprise removal: %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_REMOVAL_VETOED, &RpcStatus)) 3623 { 3624 DPRINT1("Removal vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds); 3625 } 3626 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVE_PENDING, &RpcStatus)) 3627 { 3628 DPRINT1("Removal pending: %S\n", PnpEvent->TargetDevice.DeviceIds); 3629 } 3630 else 3631 { 3632 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n", 3633 PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3, 3634 PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2], 3635 PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5], 3636 PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]); 3637 } 3638 3639 /* Dequeue the current pnp event and signal the next one */ 3640 NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0); 3641 } 3642 3643 HeapFree(GetProcessHeap(), 0, PnpEvent); 3644 3645 return ERROR_SUCCESS; 3646 } 3647 3648 3649 static VOID 3650 UpdateServiceStatus(DWORD dwState) 3651 { 3652 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 3653 ServiceStatus.dwCurrentState = dwState; 3654 ServiceStatus.dwControlsAccepted = 0; 3655 ServiceStatus.dwWin32ExitCode = 0; 3656 ServiceStatus.dwServiceSpecificExitCode = 0; 3657 ServiceStatus.dwCheckPoint = 0; 3658 3659 if (dwState == SERVICE_START_PENDING || 3660 dwState == SERVICE_STOP_PENDING || 3661 dwState == SERVICE_PAUSE_PENDING || 3662 dwState == SERVICE_CONTINUE_PENDING) 3663 ServiceStatus.dwWaitHint = 10000; 3664 else 3665 ServiceStatus.dwWaitHint = 0; 3666 3667 SetServiceStatus(ServiceStatusHandle, 3668 &ServiceStatus); 3669 } 3670 3671 3672 static DWORD WINAPI 3673 ServiceControlHandler(DWORD dwControl, 3674 DWORD dwEventType, 3675 LPVOID lpEventData, 3676 LPVOID lpContext) 3677 { 3678 DPRINT1("ServiceControlHandler() called\n"); 3679 3680 switch (dwControl) 3681 { 3682 case SERVICE_CONTROL_STOP: 3683 DPRINT1(" SERVICE_CONTROL_STOP received\n"); 3684 /* Stop listening to RPC Messages */ 3685 RpcMgmtStopServerListening(NULL); 3686 UpdateServiceStatus(SERVICE_STOPPED); 3687 return ERROR_SUCCESS; 3688 3689 case SERVICE_CONTROL_PAUSE: 3690 DPRINT1(" SERVICE_CONTROL_PAUSE received\n"); 3691 UpdateServiceStatus(SERVICE_PAUSED); 3692 return ERROR_SUCCESS; 3693 3694 case SERVICE_CONTROL_CONTINUE: 3695 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n"); 3696 UpdateServiceStatus(SERVICE_RUNNING); 3697 return ERROR_SUCCESS; 3698 3699 case SERVICE_CONTROL_INTERROGATE: 3700 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n"); 3701 SetServiceStatus(ServiceStatusHandle, 3702 &ServiceStatus); 3703 return ERROR_SUCCESS; 3704 3705 case SERVICE_CONTROL_SHUTDOWN: 3706 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n"); 3707 /* Stop listening to RPC Messages */ 3708 RpcMgmtStopServerListening(NULL); 3709 UpdateServiceStatus(SERVICE_STOPPED); 3710 return ERROR_SUCCESS; 3711 3712 default : 3713 DPRINT1(" Control %lu received\n", dwControl); 3714 return ERROR_CALL_NOT_IMPLEMENTED; 3715 } 3716 } 3717 3718 3719 VOID WINAPI 3720 ServiceMain(DWORD argc, LPTSTR *argv) 3721 { 3722 HANDLE hThread; 3723 DWORD dwThreadId; 3724 3725 UNREFERENCED_PARAMETER(argc); 3726 UNREFERENCED_PARAMETER(argv); 3727 3728 DPRINT("ServiceMain() called\n"); 3729 3730 ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, 3731 ServiceControlHandler, 3732 NULL); 3733 if (!ServiceStatusHandle) 3734 { 3735 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError()); 3736 return; 3737 } 3738 3739 UpdateServiceStatus(SERVICE_START_PENDING); 3740 3741 hThread = CreateThread(NULL, 3742 0, 3743 PnpEventThread, 3744 NULL, 3745 0, 3746 &dwThreadId); 3747 if (hThread != NULL) 3748 CloseHandle(hThread); 3749 3750 hThread = CreateThread(NULL, 3751 0, 3752 RpcServerThread, 3753 NULL, 3754 0, 3755 &dwThreadId); 3756 if (hThread != NULL) 3757 CloseHandle(hThread); 3758 3759 hThread = CreateThread(NULL, 3760 0, 3761 DeviceInstallThread, 3762 NULL, 3763 0, 3764 &dwThreadId); 3765 if (hThread != NULL) 3766 CloseHandle(hThread); 3767 3768 UpdateServiceStatus(SERVICE_RUNNING); 3769 3770 DPRINT("ServiceMain() done\n"); 3771 } 3772 3773 static DWORD 3774 InitializePnPManager(VOID) 3775 { 3776 BOOLEAN OldValue; 3777 DWORD dwError; 3778 3779 DPRINT("UMPNPMGR: InitializePnPManager() started\n"); 3780 3781 /* We need this privilege for using CreateProcessAsUserW */ 3782 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &OldValue); 3783 3784 hInstallEvent = CreateEventW(NULL, TRUE, SetupIsActive()/*FALSE*/, NULL); 3785 if (hInstallEvent == NULL) 3786 { 3787 dwError = GetLastError(); 3788 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError); 3789 return dwError; 3790 } 3791 3792 hDeviceInstallListNotEmpty = CreateEventW(NULL, FALSE, FALSE, NULL); 3793 if (hDeviceInstallListNotEmpty == NULL) 3794 { 3795 dwError = GetLastError(); 3796 DPRINT1("Could not create the Event! (Error %lu)\n", dwError); 3797 return dwError; 3798 } 3799 3800 hNoPendingInstalls = CreateEventW(NULL, 3801 TRUE, 3802 FALSE, 3803 L"Global\\PnP_No_Pending_Install_Events"); 3804 if (hNoPendingInstalls == NULL) 3805 { 3806 dwError = GetLastError(); 3807 DPRINT1("Could not create the Event! (Error %lu)\n", dwError); 3808 return dwError; 3809 } 3810 3811 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED 3812 InitializeSListHead(&DeviceInstallListHead); 3813 #else 3814 InitializeListHead(&DeviceInstallListHead); 3815 #endif 3816 3817 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 3818 L"System\\CurrentControlSet\\Enum", 3819 0, 3820 KEY_ALL_ACCESS, 3821 &hEnumKey); 3822 if (dwError != ERROR_SUCCESS) 3823 { 3824 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError); 3825 return dwError; 3826 } 3827 3828 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 3829 L"System\\CurrentControlSet\\Control\\Class", 3830 0, 3831 KEY_ALL_ACCESS, 3832 &hClassKey); 3833 if (dwError != ERROR_SUCCESS) 3834 { 3835 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError); 3836 return dwError; 3837 } 3838 3839 DPRINT("UMPNPMGR: InitializePnPManager() done\n"); 3840 3841 return 0; 3842 } 3843 3844 BOOL WINAPI 3845 DllMain(HINSTANCE hinstDLL, 3846 DWORD fdwReason, 3847 LPVOID lpvReserved) 3848 { 3849 switch (fdwReason) 3850 { 3851 case DLL_PROCESS_ATTACH: 3852 DisableThreadLibraryCalls(hinstDLL); 3853 InitializePnPManager(); 3854 break; 3855 3856 case DLL_PROCESS_DETACH: 3857 break; 3858 } 3859 3860 return TRUE; 3861 } 3862 3863 /* EOF */ 3864