1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: lib/advapi32/service/scm.c 5 * PURPOSE: Service control manager functions 6 * PROGRAMMER: Emanuele Aliberti 7 * Eric Kohl 8 */ 9 10 /* INCLUDES ******************************************************************/ 11 12 #include <advapi32.h> 13 WINE_DEFAULT_DEBUG_CHANNEL(advapi); 14 15 16 /* FUNCTIONS *****************************************************************/ 17 18 handle_t __RPC_USER 19 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName) 20 { 21 handle_t hBinding = NULL; 22 RPC_CSTR pszStringBinding; 23 RPC_STATUS status; 24 25 TRACE("SVCCTL_HANDLEA_bind(%s)\n", 26 debugstr_a(szMachineName)); 27 28 status = RpcStringBindingComposeA(NULL, 29 (RPC_CSTR)"ncacn_np", 30 (RPC_CSTR)szMachineName, 31 (RPC_CSTR)"\\pipe\\ntsvcs", 32 NULL, 33 &pszStringBinding); 34 if (status != RPC_S_OK) 35 { 36 ERR("RpcStringBindingCompose returned 0x%x\n", status); 37 return NULL; 38 } 39 40 /* Set the binding handle that will be used to bind to the server. */ 41 status = RpcBindingFromStringBindingA(pszStringBinding, 42 &hBinding); 43 if (status != RPC_S_OK) 44 { 45 ERR("RpcBindingFromStringBinding returned 0x%x\n", status); 46 } 47 48 status = RpcStringFreeA(&pszStringBinding); 49 if (status != RPC_S_OK) 50 { 51 ERR("RpcStringFree returned 0x%x\n", status); 52 } 53 54 return hBinding; 55 } 56 57 58 void __RPC_USER 59 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName, 60 handle_t hBinding) 61 { 62 RPC_STATUS status; 63 64 TRACE("SVCCTL_HANDLEA_unbind(%s %p)\n", 65 debugstr_a(szMachineName), hBinding); 66 67 status = RpcBindingFree(&hBinding); 68 if (status != RPC_S_OK) 69 { 70 ERR("RpcBindingFree returned 0x%x\n", status); 71 } 72 } 73 74 75 handle_t __RPC_USER 76 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName) 77 { 78 handle_t hBinding = NULL; 79 RPC_WSTR pszStringBinding; 80 RPC_STATUS status; 81 82 TRACE("SVCCTL_HANDLEW_bind(%s)\n", 83 debugstr_w(szMachineName)); 84 85 status = RpcStringBindingComposeW(NULL, 86 L"ncacn_np", 87 szMachineName, 88 L"\\pipe\\ntsvcs", 89 NULL, 90 &pszStringBinding); 91 if (status != RPC_S_OK) 92 { 93 ERR("RpcStringBindingCompose returned 0x%x\n", status); 94 return NULL; 95 } 96 97 /* Set the binding handle that will be used to bind to the server. */ 98 status = RpcBindingFromStringBindingW(pszStringBinding, 99 &hBinding); 100 if (status != RPC_S_OK) 101 { 102 ERR("RpcBindingFromStringBinding returned 0x%x\n", status); 103 } 104 105 status = RpcStringFreeW(&pszStringBinding); 106 if (status != RPC_S_OK) 107 { 108 ERR("RpcStringFree returned 0x%x\n", status); 109 } 110 111 return hBinding; 112 } 113 114 115 void __RPC_USER 116 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName, 117 handle_t hBinding) 118 { 119 RPC_STATUS status; 120 121 TRACE("SVCCTL_HANDLEW_unbind(%s %p)\n", 122 debugstr_w(szMachineName), hBinding); 123 124 status = RpcBindingFree(&hBinding); 125 if (status != RPC_S_OK) 126 { 127 ERR("RpcBindingFree returned 0x%x\n", status); 128 } 129 } 130 131 132 DWORD 133 ScmRpcStatusToWinError(RPC_STATUS Status) 134 { 135 TRACE("ScmRpcStatusToWinError(%lx)\n", 136 Status); 137 138 switch (Status) 139 { 140 case STATUS_ACCESS_VIOLATION: 141 case RPC_S_INVALID_BINDING: 142 case RPC_X_SS_IN_NULL_CONTEXT: 143 return ERROR_INVALID_HANDLE; 144 145 case RPC_X_ENUM_VALUE_OUT_OF_RANGE: 146 case RPC_X_BYTE_COUNT_TOO_SMALL: 147 return ERROR_INVALID_PARAMETER; 148 149 case RPC_X_NULL_REF_POINTER: 150 return ERROR_INVALID_ADDRESS; 151 152 default: 153 return (DWORD)Status; 154 } 155 } 156 157 158 /********************************************************************** 159 * ChangeServiceConfig2A 160 * 161 * @implemented 162 */ 163 BOOL WINAPI 164 ChangeServiceConfig2A(SC_HANDLE hService, 165 DWORD dwInfoLevel, 166 LPVOID lpInfo) 167 { 168 SC_RPC_CONFIG_INFOA Info; 169 DWORD dwError; 170 171 TRACE("ChangeServiceConfig2A(%p %lu %p)\n", 172 hService, dwInfoLevel, lpInfo); 173 174 if (lpInfo == NULL) return TRUE; 175 176 /* Fill relevant field of the Info structure */ 177 Info.dwInfoLevel = dwInfoLevel; 178 switch (dwInfoLevel) 179 { 180 case SERVICE_CONFIG_DESCRIPTION: 181 Info.psd = lpInfo; 182 break; 183 184 case SERVICE_CONFIG_FAILURE_ACTIONS: 185 Info.psfa = lpInfo; 186 break; 187 188 default: 189 WARN("Unknown info level 0x%lx\n", dwInfoLevel); 190 SetLastError(ERROR_INVALID_PARAMETER); 191 return FALSE; 192 } 193 194 RpcTryExcept 195 { 196 dwError = RChangeServiceConfig2A((SC_RPC_HANDLE)hService, 197 Info); 198 } 199 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 200 { 201 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 202 } 203 RpcEndExcept; 204 205 if (dwError != ERROR_SUCCESS) 206 { 207 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError); 208 SetLastError(dwError); 209 return FALSE; 210 } 211 212 return TRUE; 213 } 214 215 216 /********************************************************************** 217 * ChangeServiceConfig2W 218 * 219 * @implemented 220 */ 221 BOOL WINAPI 222 ChangeServiceConfig2W(SC_HANDLE hService, 223 DWORD dwInfoLevel, 224 LPVOID lpInfo) 225 { 226 SC_RPC_CONFIG_INFOW Info; 227 DWORD dwError; 228 229 TRACE("ChangeServiceConfig2W(%p %lu %p)\n", 230 hService, dwInfoLevel, lpInfo); 231 232 if (lpInfo == NULL) return TRUE; 233 234 /* Fill relevant field of the Info structure */ 235 Info.dwInfoLevel = dwInfoLevel; 236 switch (dwInfoLevel) 237 { 238 case SERVICE_CONFIG_DESCRIPTION: 239 Info.psd = lpInfo; 240 break; 241 242 case SERVICE_CONFIG_FAILURE_ACTIONS: 243 Info.psfa = lpInfo; 244 break; 245 246 default: 247 WARN("Unknown info level 0x%lx\n", dwInfoLevel); 248 SetLastError(ERROR_INVALID_PARAMETER); 249 return FALSE; 250 } 251 252 RpcTryExcept 253 { 254 dwError = RChangeServiceConfig2W((SC_RPC_HANDLE)hService, 255 Info); 256 } 257 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 258 { 259 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 260 } 261 RpcEndExcept; 262 263 if (dwError != ERROR_SUCCESS) 264 { 265 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError); 266 SetLastError(dwError); 267 return FALSE; 268 } 269 270 return TRUE; 271 } 272 273 274 /********************************************************************** 275 * ChangeServiceConfigA 276 * 277 * @implemented 278 */ 279 BOOL WINAPI 280 ChangeServiceConfigA(SC_HANDLE hService, 281 DWORD dwServiceType, 282 DWORD dwStartType, 283 DWORD dwErrorControl, 284 LPCSTR lpBinaryPathName, 285 LPCSTR lpLoadOrderGroup, 286 LPDWORD lpdwTagId, 287 LPCSTR lpDependencies, 288 LPCSTR lpServiceStartName, 289 LPCSTR lpPassword, 290 LPCSTR lpDisplayName) 291 { 292 DWORD dwError; 293 DWORD dwDependenciesLength = 0; 294 SIZE_T cchLength; 295 LPCSTR lpStr; 296 DWORD dwPasswordLength = 0; 297 LPWSTR lpPasswordW = NULL; 298 LPBYTE lpEncryptedPassword = NULL; 299 300 TRACE("ChangeServiceConfigA(%p %lu %lu %lu %s %s %p %s %s %s %s)\n", 301 dwServiceType, dwStartType, dwErrorControl, debugstr_a(lpBinaryPathName), 302 debugstr_a(lpLoadOrderGroup), lpdwTagId, debugstr_a(lpDependencies), 303 debugstr_a(lpServiceStartName), debugstr_a(lpPassword), debugstr_a(lpDisplayName)); 304 305 /* Calculate the Dependencies length*/ 306 if (lpDependencies != NULL) 307 { 308 lpStr = lpDependencies; 309 while (*lpStr) 310 { 311 cchLength = strlen(lpStr) + 1; 312 dwDependenciesLength += (DWORD)cchLength; 313 lpStr = lpStr + cchLength; 314 } 315 dwDependenciesLength++; 316 } 317 318 if (lpPassword != NULL) 319 { 320 /* Convert the password to unicode */ 321 lpPasswordW = HeapAlloc(GetProcessHeap(), 322 HEAP_ZERO_MEMORY, 323 (strlen(lpPassword) + 1) * sizeof(WCHAR)); 324 if (lpPasswordW == NULL) 325 { 326 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 327 return FALSE; 328 } 329 330 MultiByteToWideChar(CP_ACP, 331 0, 332 lpPassword, 333 -1, 334 lpPasswordW, 335 (int)(strlen(lpPassword) + 1)); 336 337 /* FIXME: Encrypt the password */ 338 lpEncryptedPassword = (LPBYTE)lpPasswordW; 339 dwPasswordLength = (wcslen(lpPasswordW) + 1) * sizeof(WCHAR); 340 } 341 342 RpcTryExcept 343 { 344 dwError = RChangeServiceConfigA((SC_RPC_HANDLE)hService, 345 dwServiceType, 346 dwStartType, 347 dwErrorControl, 348 (LPSTR)lpBinaryPathName, 349 (LPSTR)lpLoadOrderGroup, 350 lpdwTagId, 351 (LPBYTE)lpDependencies, 352 dwDependenciesLength, 353 (LPSTR)lpServiceStartName, 354 lpEncryptedPassword, 355 dwPasswordLength, 356 (LPSTR)lpDisplayName); 357 } 358 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 359 { 360 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 361 } 362 RpcEndExcept; 363 364 if (lpPasswordW != NULL) 365 HeapFree(GetProcessHeap(), 0, lpPasswordW); 366 367 if (dwError != ERROR_SUCCESS) 368 { 369 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError); 370 SetLastError(dwError); 371 return FALSE; 372 } 373 374 return TRUE; 375 } 376 377 378 /********************************************************************** 379 * ChangeServiceConfigW 380 * 381 * @implemented 382 */ 383 BOOL WINAPI 384 ChangeServiceConfigW(SC_HANDLE hService, 385 DWORD dwServiceType, 386 DWORD dwStartType, 387 DWORD dwErrorControl, 388 LPCWSTR lpBinaryPathName, 389 LPCWSTR lpLoadOrderGroup, 390 LPDWORD lpdwTagId, 391 LPCWSTR lpDependencies, 392 LPCWSTR lpServiceStartName, 393 LPCWSTR lpPassword, 394 LPCWSTR lpDisplayName) 395 { 396 DWORD dwError; 397 DWORD dwDependenciesLength = 0; 398 SIZE_T cchLength; 399 LPCWSTR lpStr; 400 DWORD dwPasswordLength = 0; 401 LPBYTE lpEncryptedPassword = NULL; 402 403 TRACE("ChangeServiceConfigW(%p %lu %lu %lu %s %s %p %s %s %s %s)\n", 404 dwServiceType, dwStartType, dwErrorControl, debugstr_w(lpBinaryPathName), 405 debugstr_w(lpLoadOrderGroup), lpdwTagId, debugstr_w(lpDependencies), 406 debugstr_w(lpServiceStartName), debugstr_w(lpPassword), debugstr_w(lpDisplayName)); 407 408 /* Calculate the Dependencies length*/ 409 if (lpDependencies != NULL) 410 { 411 lpStr = lpDependencies; 412 while (*lpStr) 413 { 414 cchLength = wcslen(lpStr) + 1; 415 dwDependenciesLength += (DWORD)cchLength; 416 lpStr = lpStr + cchLength; 417 } 418 dwDependenciesLength++; 419 dwDependenciesLength *= sizeof(WCHAR); 420 } 421 422 if (lpPassword != NULL) 423 { 424 /* FIXME: Encrypt the password */ 425 lpEncryptedPassword = (LPBYTE)lpPassword; 426 dwPasswordLength = (wcslen(lpPassword) + 1) * sizeof(WCHAR); 427 } 428 429 RpcTryExcept 430 { 431 dwError = RChangeServiceConfigW((SC_RPC_HANDLE)hService, 432 dwServiceType, 433 dwStartType, 434 dwErrorControl, 435 (LPWSTR)lpBinaryPathName, 436 (LPWSTR)lpLoadOrderGroup, 437 lpdwTagId, 438 (LPBYTE)lpDependencies, 439 dwDependenciesLength, 440 (LPWSTR)lpServiceStartName, 441 lpEncryptedPassword, 442 dwPasswordLength, 443 (LPWSTR)lpDisplayName); 444 } 445 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 446 { 447 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 448 } 449 RpcEndExcept; 450 451 if (dwError != ERROR_SUCCESS) 452 { 453 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError); 454 SetLastError(dwError); 455 return FALSE; 456 } 457 458 return TRUE; 459 } 460 461 462 /********************************************************************** 463 * CloseServiceHandle 464 * 465 * @implemented 466 */ 467 BOOL WINAPI 468 CloseServiceHandle(SC_HANDLE hSCObject) 469 { 470 DWORD dwError; 471 472 TRACE("CloseServiceHandle(%p)\n", 473 hSCObject); 474 475 if (!hSCObject) 476 { 477 SetLastError(ERROR_INVALID_HANDLE); 478 return FALSE; 479 } 480 481 RpcTryExcept 482 { 483 dwError = RCloseServiceHandle((LPSC_RPC_HANDLE)&hSCObject); 484 } 485 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 486 { 487 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 488 } 489 RpcEndExcept; 490 491 if (dwError) 492 { 493 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError); 494 SetLastError(dwError); 495 return FALSE; 496 } 497 498 TRACE("CloseServiceHandle() done\n"); 499 500 return TRUE; 501 } 502 503 504 /********************************************************************** 505 * ControlService 506 * 507 * @implemented 508 */ 509 BOOL WINAPI 510 ControlService(SC_HANDLE hService, 511 DWORD dwControl, 512 LPSERVICE_STATUS lpServiceStatus) 513 { 514 DWORD dwError; 515 516 TRACE("ControlService(%p %lu %p)\n", 517 hService, dwControl, lpServiceStatus); 518 519 RpcTryExcept 520 { 521 dwError = RControlService((SC_RPC_HANDLE)hService, 522 dwControl, 523 lpServiceStatus); 524 } 525 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 526 { 527 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 528 } 529 RpcEndExcept; 530 531 if (dwError != ERROR_SUCCESS) 532 { 533 TRACE("RControlService() failed (Error %lu)\n", dwError); 534 SetLastError(dwError); 535 return FALSE; 536 } 537 538 TRACE("ControlService() done\n"); 539 540 return TRUE; 541 } 542 543 544 /********************************************************************** 545 * ControlServiceEx 546 * 547 * @unimplemented 548 */ 549 BOOL WINAPI 550 ControlServiceEx(IN SC_HANDLE hService, 551 IN DWORD dwControl, 552 IN DWORD dwInfoLevel, 553 IN OUT PVOID pControlParams) 554 { 555 FIXME("ControlServiceEx(%p %lu %lu %p)\n", 556 hService, dwControl, dwInfoLevel, pControlParams); 557 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 558 return FALSE; 559 } 560 561 562 /********************************************************************** 563 * CreateServiceA 564 * 565 * @implemented 566 */ 567 SC_HANDLE WINAPI 568 CreateServiceA(SC_HANDLE hSCManager, 569 LPCSTR lpServiceName, 570 LPCSTR lpDisplayName, 571 DWORD dwDesiredAccess, 572 DWORD dwServiceType, 573 DWORD dwStartType, 574 DWORD dwErrorControl, 575 LPCSTR lpBinaryPathName, 576 LPCSTR lpLoadOrderGroup, 577 LPDWORD lpdwTagId, 578 LPCSTR lpDependencies, 579 LPCSTR lpServiceStartName, 580 LPCSTR lpPassword) 581 { 582 SC_HANDLE hService = NULL; 583 DWORD dwDependenciesLength = 0; 584 DWORD dwError; 585 SIZE_T cchLength; 586 LPCSTR lpStr; 587 DWORD dwPasswordLength = 0; 588 LPWSTR lpPasswordW = NULL; 589 LPBYTE lpEncryptedPassword = NULL; 590 591 TRACE("CreateServiceA(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n", 592 hSCManager, debugstr_a(lpServiceName), debugstr_a(lpDisplayName), 593 dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, 594 debugstr_a(lpBinaryPathName), debugstr_a(lpLoadOrderGroup), lpdwTagId, 595 debugstr_a(lpDependencies), debugstr_a(lpServiceStartName), debugstr_a(lpPassword)); 596 597 if (!hSCManager) 598 { 599 SetLastError(ERROR_INVALID_HANDLE); 600 return NULL; 601 } 602 603 /* Calculate the Dependencies length */ 604 if (lpDependencies != NULL) 605 { 606 lpStr = lpDependencies; 607 while (*lpStr) 608 { 609 cchLength = strlen(lpStr) + 1; 610 dwDependenciesLength += (DWORD)cchLength; 611 lpStr = lpStr + cchLength; 612 } 613 dwDependenciesLength++; 614 } 615 616 if (lpPassword != NULL) 617 { 618 /* Convert the password to unicode */ 619 lpPasswordW = HeapAlloc(GetProcessHeap(), 620 HEAP_ZERO_MEMORY, 621 (strlen(lpPassword) + 1) * sizeof(WCHAR)); 622 if (lpPasswordW == NULL) 623 { 624 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 625 return FALSE; 626 } 627 628 MultiByteToWideChar(CP_ACP, 629 0, 630 lpPassword, 631 -1, 632 lpPasswordW, 633 (int)(strlen(lpPassword) + 1)); 634 635 /* FIXME: Encrypt the password */ 636 lpEncryptedPassword = (LPBYTE)lpPasswordW; 637 dwPasswordLength = (wcslen(lpPasswordW) + 1) * sizeof(WCHAR); 638 } 639 640 RpcTryExcept 641 { 642 dwError = RCreateServiceA((SC_RPC_HANDLE)hSCManager, 643 (LPSTR)lpServiceName, 644 (LPSTR)lpDisplayName, 645 dwDesiredAccess, 646 dwServiceType, 647 dwStartType, 648 dwErrorControl, 649 (LPSTR)lpBinaryPathName, 650 (LPSTR)lpLoadOrderGroup, 651 lpdwTagId, 652 (LPBYTE)lpDependencies, 653 dwDependenciesLength, 654 (LPSTR)lpServiceStartName, 655 lpEncryptedPassword, 656 dwPasswordLength, 657 (SC_RPC_HANDLE *)&hService); 658 } 659 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 660 { 661 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 662 } 663 RpcEndExcept; 664 665 if (lpPasswordW != NULL) 666 HeapFree(GetProcessHeap(), 0, lpPasswordW); 667 668 SetLastError(dwError); 669 if (dwError != ERROR_SUCCESS) 670 { 671 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError); 672 return NULL; 673 } 674 675 return hService; 676 } 677 678 679 /********************************************************************** 680 * CreateServiceW 681 * 682 * @implemented 683 */ 684 SC_HANDLE WINAPI 685 CreateServiceW(SC_HANDLE hSCManager, 686 LPCWSTR lpServiceName, 687 LPCWSTR lpDisplayName, 688 DWORD dwDesiredAccess, 689 DWORD dwServiceType, 690 DWORD dwStartType, 691 DWORD dwErrorControl, 692 LPCWSTR lpBinaryPathName, 693 LPCWSTR lpLoadOrderGroup, 694 LPDWORD lpdwTagId, 695 LPCWSTR lpDependencies, 696 LPCWSTR lpServiceStartName, 697 LPCWSTR lpPassword) 698 { 699 SC_HANDLE hService = NULL; 700 DWORD dwDependenciesLength = 0; 701 DWORD dwError; 702 SIZE_T cchLength; 703 LPCWSTR lpStr; 704 DWORD dwPasswordLength = 0; 705 LPBYTE lpEncryptedPassword = NULL; 706 707 TRACE("CreateServiceW(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n", 708 hSCManager, debugstr_w(lpServiceName), debugstr_w(lpDisplayName), 709 dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, 710 debugstr_w(lpBinaryPathName), debugstr_w(lpLoadOrderGroup), lpdwTagId, 711 debugstr_w(lpDependencies), debugstr_w(lpServiceStartName), debugstr_w(lpPassword)); 712 713 if (!hSCManager) 714 { 715 SetLastError(ERROR_INVALID_HANDLE); 716 return NULL; 717 } 718 719 /* Calculate the Dependencies length */ 720 if (lpDependencies != NULL) 721 { 722 lpStr = lpDependencies; 723 while (*lpStr) 724 { 725 cchLength = wcslen(lpStr) + 1; 726 dwDependenciesLength += (DWORD)cchLength; 727 lpStr = lpStr + cchLength; 728 } 729 dwDependenciesLength++; 730 dwDependenciesLength *= sizeof(WCHAR); 731 } 732 733 if (lpPassword != NULL) 734 { 735 /* FIXME: Encrypt the password */ 736 lpEncryptedPassword = (LPBYTE)lpPassword; 737 dwPasswordLength = (wcslen(lpPassword) + 1) * sizeof(WCHAR); 738 } 739 740 RpcTryExcept 741 { 742 dwError = RCreateServiceW((SC_RPC_HANDLE)hSCManager, 743 lpServiceName, 744 lpDisplayName, 745 dwDesiredAccess, 746 dwServiceType, 747 dwStartType, 748 dwErrorControl, 749 lpBinaryPathName, 750 lpLoadOrderGroup, 751 lpdwTagId, 752 (LPBYTE)lpDependencies, 753 dwDependenciesLength, 754 lpServiceStartName, 755 lpEncryptedPassword, 756 dwPasswordLength, 757 (SC_RPC_HANDLE *)&hService); 758 } 759 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 760 { 761 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 762 } 763 RpcEndExcept; 764 765 SetLastError(dwError); 766 if (dwError != ERROR_SUCCESS) 767 { 768 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError); 769 return NULL; 770 } 771 772 return hService; 773 } 774 775 776 /********************************************************************** 777 * DeleteService 778 * 779 * @implemented 780 */ 781 BOOL WINAPI 782 DeleteService(SC_HANDLE hService) 783 { 784 DWORD dwError; 785 786 TRACE("DeleteService(%p)\n", 787 hService); 788 789 RpcTryExcept 790 { 791 dwError = RDeleteService((SC_RPC_HANDLE)hService); 792 } 793 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 794 { 795 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 796 } 797 RpcEndExcept; 798 799 if (dwError != ERROR_SUCCESS) 800 { 801 TRACE("RDeleteService() failed (Error %lu)\n", dwError); 802 SetLastError(dwError); 803 return FALSE; 804 } 805 806 return TRUE; 807 } 808 809 810 /********************************************************************** 811 * EnumDependentServicesA 812 * 813 * @implemented 814 */ 815 BOOL WINAPI 816 EnumDependentServicesA(SC_HANDLE hService, 817 DWORD dwServiceState, 818 LPENUM_SERVICE_STATUSA lpServices, 819 DWORD cbBufSize, 820 LPDWORD pcbBytesNeeded, 821 LPDWORD lpServicesReturned) 822 { 823 ENUM_SERVICE_STATUSA ServiceStatus; 824 LPENUM_SERVICE_STATUSA lpStatusPtr; 825 DWORD dwBufferSize; 826 DWORD dwError; 827 DWORD dwCount; 828 829 TRACE("EnumDependentServicesA(%p %lu %p %lu %p %p)\n", 830 hService, dwServiceState, lpServices, cbBufSize, 831 pcbBytesNeeded, lpServicesReturned); 832 833 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSA)) 834 { 835 lpStatusPtr = &ServiceStatus; 836 dwBufferSize = sizeof(ENUM_SERVICE_STATUSA); 837 } 838 else 839 { 840 lpStatusPtr = lpServices; 841 dwBufferSize = cbBufSize; 842 } 843 844 RpcTryExcept 845 { 846 dwError = REnumDependentServicesA((SC_RPC_HANDLE)hService, 847 dwServiceState, 848 (LPBYTE)lpStatusPtr, 849 dwBufferSize, 850 pcbBytesNeeded, 851 lpServicesReturned); 852 } 853 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 854 { 855 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 856 } 857 RpcEndExcept; 858 859 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 860 { 861 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 862 { 863 if (lpStatusPtr->lpServiceName) 864 lpStatusPtr->lpServiceName = 865 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 866 867 if (lpStatusPtr->lpDisplayName) 868 lpStatusPtr->lpDisplayName = 869 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 870 871 lpStatusPtr++; 872 } 873 } 874 875 if (dwError != ERROR_SUCCESS) 876 { 877 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError); 878 SetLastError(dwError); 879 return FALSE; 880 } 881 882 TRACE("EnumDependentServicesA() done\n"); 883 884 return TRUE; 885 } 886 887 888 /********************************************************************** 889 * EnumDependentServicesW 890 * 891 * @implemented 892 */ 893 BOOL WINAPI 894 EnumDependentServicesW(SC_HANDLE hService, 895 DWORD dwServiceState, 896 LPENUM_SERVICE_STATUSW lpServices, 897 DWORD cbBufSize, 898 LPDWORD pcbBytesNeeded, 899 LPDWORD lpServicesReturned) 900 { 901 ENUM_SERVICE_STATUSW ServiceStatus; 902 LPENUM_SERVICE_STATUSW lpStatusPtr; 903 DWORD dwBufferSize; 904 DWORD dwError; 905 DWORD dwCount; 906 907 TRACE("EnumDependentServicesW(%p %lu %p %lu %p %p)\n", 908 hService, dwServiceState, lpServices, cbBufSize, 909 pcbBytesNeeded, lpServicesReturned); 910 911 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) 912 { 913 lpStatusPtr = &ServiceStatus; 914 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); 915 } 916 else 917 { 918 lpStatusPtr = lpServices; 919 dwBufferSize = cbBufSize; 920 } 921 922 RpcTryExcept 923 { 924 dwError = REnumDependentServicesW((SC_RPC_HANDLE)hService, 925 dwServiceState, 926 (LPBYTE)lpStatusPtr, 927 dwBufferSize, 928 pcbBytesNeeded, 929 lpServicesReturned); 930 } 931 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 932 { 933 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 934 } 935 RpcEndExcept; 936 937 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 938 { 939 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 940 { 941 if (lpStatusPtr->lpServiceName) 942 lpStatusPtr->lpServiceName = 943 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 944 945 if (lpStatusPtr->lpDisplayName) 946 lpStatusPtr->lpDisplayName = 947 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 948 949 lpStatusPtr++; 950 } 951 } 952 953 if (dwError != ERROR_SUCCESS) 954 { 955 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError); 956 SetLastError(dwError); 957 return FALSE; 958 } 959 960 TRACE("EnumDependentServicesW() done\n"); 961 962 return TRUE; 963 } 964 965 966 /********************************************************************** 967 * EnumServiceGroupW 968 * 969 * @implemented 970 */ 971 BOOL WINAPI 972 EnumServiceGroupW(SC_HANDLE hSCManager, 973 DWORD dwServiceType, 974 DWORD dwServiceState, 975 LPENUM_SERVICE_STATUSW lpServices, 976 DWORD cbBufSize, 977 LPDWORD pcbBytesNeeded, 978 LPDWORD lpServicesReturned, 979 LPDWORD lpResumeHandle, 980 LPCWSTR lpGroup) 981 { 982 ENUM_SERVICE_STATUSW ServiceStatus; 983 LPENUM_SERVICE_STATUSW lpStatusPtr; 984 DWORD dwBufferSize; 985 DWORD dwError; 986 DWORD dwCount; 987 988 TRACE("EnumServiceGroupW(%p %lu %lu %p %lu %p %p %p %s)\n", 989 hSCManager, dwServiceType, dwServiceState, lpServices, 990 cbBufSize, pcbBytesNeeded, lpServicesReturned, 991 lpResumeHandle, debugstr_w(lpGroup)); 992 993 if (!hSCManager) 994 { 995 SetLastError(ERROR_INVALID_HANDLE); 996 return FALSE; 997 } 998 999 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL) 1000 { 1001 SetLastError(ERROR_INVALID_ADDRESS); 1002 return FALSE; 1003 } 1004 1005 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) 1006 { 1007 lpStatusPtr = &ServiceStatus; 1008 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); 1009 } 1010 else 1011 { 1012 lpStatusPtr = lpServices; 1013 dwBufferSize = cbBufSize; 1014 } 1015 1016 RpcTryExcept 1017 { 1018 if (lpGroup == NULL) 1019 { 1020 dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager, 1021 dwServiceType, 1022 dwServiceState, 1023 (LPBYTE)lpStatusPtr, 1024 dwBufferSize, 1025 pcbBytesNeeded, 1026 lpServicesReturned, 1027 lpResumeHandle); 1028 } 1029 else 1030 { 1031 dwError = REnumServiceGroupW((SC_RPC_HANDLE)hSCManager, 1032 dwServiceType, 1033 dwServiceState, 1034 (LPBYTE)lpStatusPtr, 1035 dwBufferSize, 1036 pcbBytesNeeded, 1037 lpServicesReturned, 1038 lpResumeHandle, 1039 lpGroup); 1040 } 1041 } 1042 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1043 { 1044 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1045 } 1046 RpcEndExcept; 1047 1048 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 1049 { 1050 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 1051 { 1052 if (lpStatusPtr->lpServiceName) 1053 lpStatusPtr->lpServiceName = 1054 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 1055 1056 if (lpStatusPtr->lpDisplayName) 1057 lpStatusPtr->lpDisplayName = 1058 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 1059 1060 lpStatusPtr++; 1061 } 1062 } 1063 1064 if (dwError != ERROR_SUCCESS) 1065 { 1066 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError); 1067 SetLastError(dwError); 1068 return FALSE; 1069 } 1070 1071 TRACE("EnumServiceGroupW() done\n"); 1072 1073 return TRUE; 1074 } 1075 1076 1077 /********************************************************************** 1078 * EnumServicesStatusA 1079 * 1080 * @implemented 1081 */ 1082 BOOL WINAPI 1083 EnumServicesStatusA(SC_HANDLE hSCManager, 1084 DWORD dwServiceType, 1085 DWORD dwServiceState, 1086 LPENUM_SERVICE_STATUSA lpServices, 1087 DWORD cbBufSize, 1088 LPDWORD pcbBytesNeeded, 1089 LPDWORD lpServicesReturned, 1090 LPDWORD lpResumeHandle) 1091 { 1092 ENUM_SERVICE_STATUSA ServiceStatus; 1093 LPENUM_SERVICE_STATUSA lpStatusPtr; 1094 DWORD dwBufferSize; 1095 DWORD dwError; 1096 DWORD dwCount; 1097 1098 TRACE("EnumServicesStatusA(%p %lu %lu %p %lu %p %p %p)\n", 1099 hSCManager, dwServiceType, dwServiceState, lpServices, 1100 cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle); 1101 1102 if (!hSCManager) 1103 { 1104 SetLastError(ERROR_INVALID_HANDLE); 1105 return FALSE; 1106 } 1107 1108 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL) 1109 { 1110 SetLastError(ERROR_INVALID_ADDRESS); 1111 return FALSE; 1112 } 1113 1114 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSA)) 1115 { 1116 lpStatusPtr = &ServiceStatus; 1117 dwBufferSize = sizeof(ENUM_SERVICE_STATUSA); 1118 } 1119 else 1120 { 1121 lpStatusPtr = lpServices; 1122 dwBufferSize = cbBufSize; 1123 } 1124 1125 RpcTryExcept 1126 { 1127 dwError = REnumServicesStatusA((SC_RPC_HANDLE)hSCManager, 1128 dwServiceType, 1129 dwServiceState, 1130 (LPBYTE)lpStatusPtr, 1131 dwBufferSize, 1132 pcbBytesNeeded, 1133 lpServicesReturned, 1134 lpResumeHandle); 1135 } 1136 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1137 { 1138 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1139 } 1140 RpcEndExcept; 1141 1142 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 1143 { 1144 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 1145 { 1146 if (lpStatusPtr->lpServiceName) 1147 lpStatusPtr->lpServiceName = 1148 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 1149 1150 if (lpStatusPtr->lpDisplayName) 1151 lpStatusPtr->lpDisplayName = 1152 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 1153 1154 lpStatusPtr++; 1155 } 1156 } 1157 1158 if (dwError != ERROR_SUCCESS) 1159 { 1160 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError); 1161 SetLastError(dwError); 1162 return FALSE; 1163 } 1164 1165 TRACE("EnumServicesStatusA() done\n"); 1166 1167 return TRUE; 1168 } 1169 1170 1171 /********************************************************************** 1172 * EnumServicesStatusW 1173 * 1174 * @implemented 1175 */ 1176 BOOL WINAPI 1177 EnumServicesStatusW(SC_HANDLE hSCManager, 1178 DWORD dwServiceType, 1179 DWORD dwServiceState, 1180 LPENUM_SERVICE_STATUSW lpServices, 1181 DWORD cbBufSize, 1182 LPDWORD pcbBytesNeeded, 1183 LPDWORD lpServicesReturned, 1184 LPDWORD lpResumeHandle) 1185 { 1186 ENUM_SERVICE_STATUSW ServiceStatus; 1187 LPENUM_SERVICE_STATUSW lpStatusPtr; 1188 DWORD dwBufferSize; 1189 DWORD dwError; 1190 DWORD dwCount; 1191 1192 TRACE("EnumServicesStatusW(%p %lu %lu %p %lu %p %p %p)\n", 1193 hSCManager, dwServiceType, dwServiceState, lpServices, 1194 cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle); 1195 1196 if (!hSCManager) 1197 { 1198 SetLastError(ERROR_INVALID_HANDLE); 1199 return FALSE; 1200 } 1201 1202 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL) 1203 { 1204 SetLastError(ERROR_INVALID_ADDRESS); 1205 return FALSE; 1206 } 1207 1208 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) 1209 { 1210 lpStatusPtr = &ServiceStatus; 1211 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); 1212 } 1213 else 1214 { 1215 lpStatusPtr = lpServices; 1216 dwBufferSize = cbBufSize; 1217 } 1218 1219 RpcTryExcept 1220 { 1221 dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager, 1222 dwServiceType, 1223 dwServiceState, 1224 (LPBYTE)lpStatusPtr, 1225 dwBufferSize, 1226 pcbBytesNeeded, 1227 lpServicesReturned, 1228 lpResumeHandle); 1229 } 1230 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1231 { 1232 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1233 } 1234 RpcEndExcept; 1235 1236 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 1237 { 1238 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 1239 { 1240 if (lpStatusPtr->lpServiceName) 1241 lpStatusPtr->lpServiceName = 1242 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 1243 1244 if (lpStatusPtr->lpDisplayName) 1245 lpStatusPtr->lpDisplayName = 1246 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 1247 1248 lpStatusPtr++; 1249 } 1250 } 1251 1252 if (dwError != ERROR_SUCCESS) 1253 { 1254 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError); 1255 SetLastError(dwError); 1256 return FALSE; 1257 } 1258 1259 TRACE("EnumServicesStatusW() done\n"); 1260 1261 return TRUE; 1262 } 1263 1264 1265 /********************************************************************** 1266 * EnumServicesStatusExA 1267 * 1268 * @implemented 1269 */ 1270 BOOL WINAPI 1271 EnumServicesStatusExA(SC_HANDLE hSCManager, 1272 SC_ENUM_TYPE InfoLevel, 1273 DWORD dwServiceType, 1274 DWORD dwServiceState, 1275 LPBYTE lpServices, 1276 DWORD cbBufSize, 1277 LPDWORD pcbBytesNeeded, 1278 LPDWORD lpServicesReturned, 1279 LPDWORD lpResumeHandle, 1280 LPCSTR pszGroupName) 1281 { 1282 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus; 1283 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr; 1284 DWORD dwBufferSize; 1285 DWORD dwError; 1286 DWORD dwCount; 1287 1288 TRACE("EnumServicesStatusExA(%p %lu %lu %p %lu %p %p %p %s)\n", 1289 hSCManager, dwServiceType, dwServiceState, lpServices, 1290 cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, 1291 debugstr_a(pszGroupName)); 1292 1293 if (InfoLevel != SC_ENUM_PROCESS_INFO) 1294 { 1295 SetLastError(ERROR_INVALID_LEVEL); 1296 return FALSE; 1297 } 1298 1299 if (!hSCManager) 1300 { 1301 SetLastError(ERROR_INVALID_HANDLE); 1302 return FALSE; 1303 } 1304 1305 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL) 1306 { 1307 SetLastError(ERROR_INVALID_ADDRESS); 1308 return FALSE; 1309 } 1310 1311 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUS_PROCESSA)) 1312 { 1313 lpStatusPtr = &ServiceStatus; 1314 dwBufferSize = sizeof(ENUM_SERVICE_STATUS_PROCESSA); 1315 } 1316 else 1317 { 1318 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices; 1319 dwBufferSize = cbBufSize; 1320 } 1321 1322 RpcTryExcept 1323 { 1324 dwError = REnumServicesStatusExA((SC_RPC_HANDLE)hSCManager, 1325 InfoLevel, 1326 dwServiceType, 1327 dwServiceState, 1328 (LPBYTE)lpStatusPtr, 1329 dwBufferSize, 1330 pcbBytesNeeded, 1331 lpServicesReturned, 1332 lpResumeHandle, 1333 (LPSTR)pszGroupName); 1334 } 1335 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1336 { 1337 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1338 } 1339 RpcEndExcept; 1340 1341 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 1342 { 1343 if (InfoLevel == SC_ENUM_PROCESS_INFO) 1344 { 1345 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 1346 { 1347 if (lpStatusPtr->lpServiceName) 1348 lpStatusPtr->lpServiceName = 1349 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 1350 1351 if (lpStatusPtr->lpDisplayName) 1352 lpStatusPtr->lpDisplayName = 1353 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 1354 1355 lpStatusPtr++; 1356 } 1357 } 1358 } 1359 1360 if (dwError != ERROR_SUCCESS) 1361 { 1362 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError); 1363 SetLastError(dwError); 1364 return FALSE; 1365 } 1366 1367 TRACE("EnumServicesStatusExA() done\n"); 1368 1369 return TRUE; 1370 } 1371 1372 1373 /********************************************************************** 1374 * EnumServicesStatusExW 1375 * 1376 * @implemented 1377 */ 1378 BOOL WINAPI 1379 EnumServicesStatusExW(SC_HANDLE hSCManager, 1380 SC_ENUM_TYPE InfoLevel, 1381 DWORD dwServiceType, 1382 DWORD dwServiceState, 1383 LPBYTE lpServices, 1384 DWORD cbBufSize, 1385 LPDWORD pcbBytesNeeded, 1386 LPDWORD lpServicesReturned, 1387 LPDWORD lpResumeHandle, 1388 LPCWSTR pszGroupName) 1389 { 1390 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus; 1391 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr; 1392 DWORD dwBufferSize; 1393 DWORD dwError; 1394 DWORD dwCount; 1395 1396 TRACE("EnumServicesStatusExW(%p %lu %lu %p %lu %p %p %p %s)\n", 1397 hSCManager, dwServiceType, dwServiceState, lpServices, 1398 cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle, 1399 debugstr_w(pszGroupName)); 1400 1401 if (InfoLevel != SC_ENUM_PROCESS_INFO) 1402 { 1403 SetLastError(ERROR_INVALID_LEVEL); 1404 return FALSE; 1405 } 1406 1407 if (!hSCManager) 1408 { 1409 SetLastError(ERROR_INVALID_HANDLE); 1410 return FALSE; 1411 } 1412 1413 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL) 1414 { 1415 SetLastError(ERROR_INVALID_ADDRESS); 1416 return FALSE; 1417 } 1418 1419 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUS_PROCESSW)) 1420 { 1421 lpStatusPtr = &ServiceStatus; 1422 dwBufferSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW); 1423 } 1424 else 1425 { 1426 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices; 1427 dwBufferSize = cbBufSize; 1428 } 1429 1430 RpcTryExcept 1431 { 1432 dwError = REnumServicesStatusExW((SC_RPC_HANDLE)hSCManager, 1433 InfoLevel, 1434 dwServiceType, 1435 dwServiceState, 1436 (LPBYTE)lpStatusPtr, 1437 dwBufferSize, 1438 pcbBytesNeeded, 1439 lpServicesReturned, 1440 lpResumeHandle, 1441 (LPWSTR)pszGroupName); 1442 } 1443 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1444 { 1445 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1446 } 1447 RpcEndExcept; 1448 1449 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 1450 { 1451 if (InfoLevel == SC_ENUM_PROCESS_INFO) 1452 { 1453 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 1454 { 1455 if (lpStatusPtr->lpServiceName) 1456 lpStatusPtr->lpServiceName = 1457 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 1458 1459 if (lpStatusPtr->lpDisplayName) 1460 lpStatusPtr->lpDisplayName = 1461 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 1462 1463 lpStatusPtr++; 1464 } 1465 } 1466 } 1467 1468 if (dwError != ERROR_SUCCESS) 1469 { 1470 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError); 1471 SetLastError(dwError); 1472 return FALSE; 1473 } 1474 1475 TRACE("EnumServicesStatusExW() done\n"); 1476 1477 return TRUE; 1478 } 1479 1480 1481 /********************************************************************** 1482 * GetServiceDisplayNameA 1483 * 1484 * @implemented 1485 */ 1486 BOOL WINAPI 1487 GetServiceDisplayNameA(SC_HANDLE hSCManager, 1488 LPCSTR lpServiceName, 1489 LPSTR lpDisplayName, 1490 LPDWORD lpcchBuffer) 1491 { 1492 DWORD dwError; 1493 LPSTR lpNameBuffer; 1494 CHAR szEmptyName[] = ""; 1495 1496 TRACE("GetServiceDisplayNameA(%p %s %p %p)\n", 1497 hSCManager, debugstr_a(lpServiceName), lpDisplayName, lpcchBuffer); 1498 1499 if (!hSCManager) 1500 { 1501 SetLastError(ERROR_INVALID_HANDLE); 1502 return FALSE; 1503 } 1504 1505 if (!lpDisplayName || *lpcchBuffer < sizeof(CHAR)) 1506 { 1507 lpNameBuffer = szEmptyName; 1508 *lpcchBuffer = sizeof(CHAR); 1509 } 1510 else 1511 { 1512 lpNameBuffer = lpDisplayName; 1513 } 1514 1515 RpcTryExcept 1516 { 1517 dwError = RGetServiceDisplayNameA((SC_RPC_HANDLE)hSCManager, 1518 lpServiceName, 1519 lpNameBuffer, 1520 lpcchBuffer); 1521 } 1522 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1523 { 1524 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1525 } 1526 RpcEndExcept; 1527 1528 if (dwError != ERROR_SUCCESS) 1529 { 1530 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError); 1531 SetLastError(dwError); 1532 return FALSE; 1533 } 1534 1535 return TRUE; 1536 } 1537 1538 1539 /********************************************************************** 1540 * GetServiceDisplayNameW 1541 * 1542 * @implemented 1543 */ 1544 BOOL WINAPI 1545 GetServiceDisplayNameW(SC_HANDLE hSCManager, 1546 LPCWSTR lpServiceName, 1547 LPWSTR lpDisplayName, 1548 LPDWORD lpcchBuffer) 1549 { 1550 DWORD dwError; 1551 LPWSTR lpNameBuffer; 1552 WCHAR szEmptyName[] = L""; 1553 1554 TRACE("GetServiceDisplayNameW(%p %s %p %p)\n", 1555 hSCManager, debugstr_w(lpServiceName), lpDisplayName, lpcchBuffer); 1556 1557 if (!hSCManager) 1558 { 1559 SetLastError(ERROR_INVALID_HANDLE); 1560 return FALSE; 1561 } 1562 1563 if (!lpDisplayName || *lpcchBuffer < sizeof(WCHAR)) 1564 { 1565 lpNameBuffer = szEmptyName; 1566 *lpcchBuffer = sizeof(WCHAR); 1567 } 1568 else 1569 { 1570 lpNameBuffer = lpDisplayName; 1571 } 1572 1573 RpcTryExcept 1574 { 1575 dwError = RGetServiceDisplayNameW((SC_RPC_HANDLE)hSCManager, 1576 lpServiceName, 1577 lpNameBuffer, 1578 lpcchBuffer); 1579 } 1580 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1581 { 1582 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1583 } 1584 RpcEndExcept; 1585 1586 if (dwError != ERROR_SUCCESS) 1587 { 1588 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError); 1589 SetLastError(dwError); 1590 return FALSE; 1591 } 1592 1593 return TRUE; 1594 } 1595 1596 1597 /********************************************************************** 1598 * GetServiceKeyNameA 1599 * 1600 * @implemented 1601 */ 1602 BOOL WINAPI 1603 GetServiceKeyNameA(SC_HANDLE hSCManager, 1604 LPCSTR lpDisplayName, 1605 LPSTR lpServiceName, 1606 LPDWORD lpcchBuffer) 1607 { 1608 DWORD dwError; 1609 LPSTR lpNameBuffer; 1610 CHAR szEmptyName[] = ""; 1611 1612 TRACE("GetServiceKeyNameA(%p %s %p %p)\n", 1613 hSCManager, debugstr_a(lpDisplayName), lpServiceName, lpcchBuffer); 1614 1615 if (!hSCManager) 1616 { 1617 SetLastError(ERROR_INVALID_HANDLE); 1618 return FALSE; 1619 } 1620 1621 if (!lpServiceName || *lpcchBuffer < sizeof(CHAR)) 1622 { 1623 lpNameBuffer = szEmptyName; 1624 *lpcchBuffer = sizeof(CHAR); 1625 } 1626 else 1627 { 1628 lpNameBuffer = lpServiceName; 1629 } 1630 1631 RpcTryExcept 1632 { 1633 dwError = RGetServiceKeyNameA((SC_RPC_HANDLE)hSCManager, 1634 lpDisplayName, 1635 lpNameBuffer, 1636 lpcchBuffer); 1637 } 1638 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1639 { 1640 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */ 1641 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1642 } 1643 RpcEndExcept; 1644 1645 if (dwError != ERROR_SUCCESS) 1646 { 1647 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError); 1648 SetLastError(dwError); 1649 return FALSE; 1650 } 1651 1652 return TRUE; 1653 } 1654 1655 1656 /********************************************************************** 1657 * GetServiceKeyNameW 1658 * 1659 * @implemented 1660 */ 1661 BOOL WINAPI 1662 GetServiceKeyNameW(SC_HANDLE hSCManager, 1663 LPCWSTR lpDisplayName, 1664 LPWSTR lpServiceName, 1665 LPDWORD lpcchBuffer) 1666 { 1667 DWORD dwError; 1668 LPWSTR lpNameBuffer; 1669 WCHAR szEmptyName[] = L""; 1670 1671 TRACE("GetServiceKeyNameW(%p %s %p %p)\n", 1672 hSCManager, debugstr_w(lpDisplayName), lpServiceName, lpcchBuffer); 1673 1674 if (!hSCManager) 1675 { 1676 SetLastError(ERROR_INVALID_HANDLE); 1677 return FALSE; 1678 } 1679 1680 if (!lpServiceName || *lpcchBuffer < sizeof(WCHAR)) 1681 { 1682 lpNameBuffer = szEmptyName; 1683 *lpcchBuffer = sizeof(WCHAR); 1684 } 1685 else 1686 { 1687 lpNameBuffer = lpServiceName; 1688 } 1689 1690 RpcTryExcept 1691 { 1692 dwError = RGetServiceKeyNameW((SC_RPC_HANDLE)hSCManager, 1693 lpDisplayName, 1694 lpNameBuffer, 1695 lpcchBuffer); 1696 } 1697 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1698 { 1699 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1700 } 1701 RpcEndExcept; 1702 1703 if (dwError != ERROR_SUCCESS) 1704 { 1705 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError); 1706 SetLastError(dwError); 1707 return FALSE; 1708 } 1709 1710 return TRUE; 1711 } 1712 1713 1714 /********************************************************************** 1715 * I_ScGetCurrentGroupStateW 1716 * 1717 * @implemented 1718 */ 1719 DWORD WINAPI 1720 I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager, 1721 LPWSTR pszGroupName, 1722 LPDWORD pdwGroupState) 1723 { 1724 DWORD dwError; 1725 1726 TRACE("I_ScGetCurrentGroupStateW(%p %s %p)\n", 1727 hSCManager, debugstr_w(pszGroupName), pdwGroupState); 1728 1729 RpcTryExcept 1730 { 1731 dwError = RI_ScGetCurrentGroupStateW((SC_RPC_HANDLE)hSCManager, 1732 pszGroupName, 1733 pdwGroupState); 1734 } 1735 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1736 { 1737 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1738 } 1739 RpcEndExcept 1740 1741 if (dwError != ERROR_SUCCESS) 1742 { 1743 TRACE("RI_ScGetCurrentGroupStateW() failed (Error %lu)\n", dwError); 1744 SetLastError(dwError); 1745 } 1746 1747 return dwError; 1748 } 1749 1750 1751 /********************************************************************** 1752 * LockServiceDatabase 1753 * 1754 * @implemented 1755 */ 1756 SC_LOCK WINAPI 1757 LockServiceDatabase(SC_HANDLE hSCManager) 1758 { 1759 SC_LOCK hLock; 1760 DWORD dwError; 1761 1762 TRACE("LockServiceDatabase(%p)\n", 1763 hSCManager); 1764 1765 RpcTryExcept 1766 { 1767 dwError = RLockServiceDatabase((SC_RPC_HANDLE)hSCManager, 1768 (SC_RPC_LOCK *)&hLock); 1769 } 1770 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1771 { 1772 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1773 } 1774 RpcEndExcept; 1775 1776 if (dwError != ERROR_SUCCESS) 1777 { 1778 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError); 1779 SetLastError(dwError); 1780 return NULL; 1781 } 1782 1783 TRACE("hLock = %p\n", hLock); 1784 1785 return hLock; 1786 } 1787 1788 1789 static VOID 1790 WaitForSCManager(VOID) 1791 { 1792 HANDLE hEvent; 1793 1794 TRACE("WaitForSCManager()\n"); 1795 1796 /* Try to open the existing event */ 1797 hEvent = OpenEventW(SYNCHRONIZE, FALSE, SCM_START_EVENT); 1798 if (hEvent == NULL) 1799 { 1800 if (GetLastError() != ERROR_FILE_NOT_FOUND) 1801 return; 1802 1803 /* Try to create a new event */ 1804 hEvent = CreateEventW(NULL, TRUE, FALSE, SCM_START_EVENT); 1805 if (hEvent == NULL) 1806 return; 1807 } 1808 1809 /* Wait for 3 minutes */ 1810 WaitForSingleObject(hEvent, 180000); 1811 CloseHandle(hEvent); 1812 1813 TRACE("ScmWaitForSCManager() done\n"); 1814 } 1815 1816 1817 /********************************************************************** 1818 * OpenSCManagerA 1819 * 1820 * @implemented 1821 */ 1822 SC_HANDLE WINAPI 1823 OpenSCManagerA(LPCSTR lpMachineName, 1824 LPCSTR lpDatabaseName, 1825 DWORD dwDesiredAccess) 1826 { 1827 SC_HANDLE hScm = NULL; 1828 DWORD dwError; 1829 1830 TRACE("OpenSCManagerA(%s %s %lx)\n", 1831 debugstr_a(lpMachineName), debugstr_a(lpDatabaseName), dwDesiredAccess); 1832 1833 WaitForSCManager(); 1834 1835 RpcTryExcept 1836 { 1837 dwError = ROpenSCManagerA((LPSTR)lpMachineName, 1838 (LPSTR)lpDatabaseName, 1839 dwDesiredAccess, 1840 (SC_RPC_HANDLE *)&hScm); 1841 } 1842 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1843 { 1844 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1845 } 1846 RpcEndExcept; 1847 1848 if (dwError != ERROR_SUCCESS) 1849 { 1850 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError); 1851 SetLastError(dwError); 1852 return NULL; 1853 } 1854 1855 TRACE("hScm = %p\n", hScm); 1856 1857 return hScm; 1858 } 1859 1860 1861 /********************************************************************** 1862 * OpenSCManagerW 1863 * 1864 * @implemented 1865 */ 1866 SC_HANDLE WINAPI 1867 OpenSCManagerW(LPCWSTR lpMachineName, 1868 LPCWSTR lpDatabaseName, 1869 DWORD dwDesiredAccess) 1870 { 1871 SC_HANDLE hScm = NULL; 1872 DWORD dwError; 1873 1874 TRACE("OpenSCManagerW(%s %s %lx)\n", 1875 debugstr_w(lpMachineName), debugstr_w(lpDatabaseName), dwDesiredAccess); 1876 1877 WaitForSCManager(); 1878 1879 RpcTryExcept 1880 { 1881 dwError = ROpenSCManagerW((LPWSTR)lpMachineName, 1882 (LPWSTR)lpDatabaseName, 1883 dwDesiredAccess, 1884 (SC_RPC_HANDLE *)&hScm); 1885 } 1886 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1887 { 1888 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1889 } 1890 RpcEndExcept; 1891 1892 if (dwError != ERROR_SUCCESS) 1893 { 1894 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError); 1895 SetLastError(dwError); 1896 return NULL; 1897 } 1898 1899 TRACE("hScm = %p\n", hScm); 1900 1901 return hScm; 1902 } 1903 1904 1905 /********************************************************************** 1906 * OpenServiceA 1907 * 1908 * @implemented 1909 */ 1910 SC_HANDLE WINAPI 1911 OpenServiceA(SC_HANDLE hSCManager, 1912 LPCSTR lpServiceName, 1913 DWORD dwDesiredAccess) 1914 { 1915 SC_HANDLE hService = NULL; 1916 DWORD dwError; 1917 1918 TRACE("OpenServiceA(%p %s %lx)\n", 1919 hSCManager, debugstr_a(lpServiceName), dwDesiredAccess); 1920 1921 if (!hSCManager) 1922 { 1923 SetLastError(ERROR_INVALID_HANDLE); 1924 return NULL; 1925 } 1926 1927 RpcTryExcept 1928 { 1929 dwError = ROpenServiceA((SC_RPC_HANDLE)hSCManager, 1930 (LPSTR)lpServiceName, 1931 dwDesiredAccess, 1932 (SC_RPC_HANDLE *)&hService); 1933 } 1934 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1935 { 1936 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1937 } 1938 RpcEndExcept; 1939 1940 SetLastError(dwError); 1941 if (dwError != ERROR_SUCCESS) 1942 { 1943 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError); 1944 return NULL; 1945 } 1946 1947 TRACE("hService = %p\n", hService); 1948 1949 return hService; 1950 } 1951 1952 1953 /********************************************************************** 1954 * OpenServiceW 1955 * 1956 * @implemented 1957 */ 1958 SC_HANDLE WINAPI 1959 OpenServiceW(SC_HANDLE hSCManager, 1960 LPCWSTR lpServiceName, 1961 DWORD dwDesiredAccess) 1962 { 1963 SC_HANDLE hService = NULL; 1964 DWORD dwError; 1965 1966 TRACE("OpenServiceW(%p %s %lx)\n", 1967 hSCManager, debugstr_w(lpServiceName), dwDesiredAccess); 1968 1969 if (!hSCManager) 1970 { 1971 SetLastError(ERROR_INVALID_HANDLE); 1972 return NULL; 1973 } 1974 1975 RpcTryExcept 1976 { 1977 dwError = ROpenServiceW((SC_RPC_HANDLE)hSCManager, 1978 (LPWSTR)lpServiceName, 1979 dwDesiredAccess, 1980 (SC_RPC_HANDLE *)&hService); 1981 } 1982 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1983 { 1984 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 1985 } 1986 RpcEndExcept; 1987 1988 SetLastError(dwError); 1989 if (dwError != ERROR_SUCCESS) 1990 { 1991 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError); 1992 return NULL; 1993 } 1994 1995 TRACE("hService = %p\n", hService); 1996 1997 return hService; 1998 } 1999 2000 2001 /********************************************************************** 2002 * QueryServiceConfigA 2003 * 2004 * @implemented 2005 */ 2006 BOOL WINAPI 2007 QueryServiceConfigA(SC_HANDLE hService, 2008 LPQUERY_SERVICE_CONFIGA lpServiceConfig, 2009 DWORD cbBufSize, 2010 LPDWORD pcbBytesNeeded) 2011 { 2012 QUERY_SERVICE_CONFIGA ServiceConfig; 2013 LPQUERY_SERVICE_CONFIGA lpConfigPtr; 2014 DWORD dwBufferSize; 2015 DWORD dwError; 2016 2017 TRACE("QueryServiceConfigA(%p %p %lu %p)\n", 2018 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded); 2019 2020 if (lpServiceConfig == NULL || 2021 cbBufSize < sizeof(QUERY_SERVICE_CONFIGA)) 2022 { 2023 lpConfigPtr = &ServiceConfig; 2024 dwBufferSize = sizeof(QUERY_SERVICE_CONFIGA); 2025 } 2026 else 2027 { 2028 lpConfigPtr = lpServiceConfig; 2029 dwBufferSize = cbBufSize; 2030 } 2031 2032 RpcTryExcept 2033 { 2034 dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService, 2035 (LPBYTE)lpConfigPtr, 2036 dwBufferSize, 2037 pcbBytesNeeded); 2038 } 2039 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2040 { 2041 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2042 } 2043 RpcEndExcept; 2044 2045 if (dwError != ERROR_SUCCESS) 2046 { 2047 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError); 2048 SetLastError(dwError); 2049 return FALSE; 2050 } 2051 2052 /* Adjust the pointers */ 2053 if (lpConfigPtr->lpBinaryPathName) 2054 lpConfigPtr->lpBinaryPathName = 2055 (LPSTR)((ULONG_PTR)lpConfigPtr + 2056 (ULONG_PTR)lpConfigPtr->lpBinaryPathName); 2057 2058 if (lpConfigPtr->lpLoadOrderGroup) 2059 lpConfigPtr->lpLoadOrderGroup = 2060 (LPSTR)((ULONG_PTR)lpConfigPtr + 2061 (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup); 2062 2063 if (lpConfigPtr->lpDependencies) 2064 lpConfigPtr->lpDependencies = 2065 (LPSTR)((ULONG_PTR)lpConfigPtr + 2066 (ULONG_PTR)lpConfigPtr->lpDependencies); 2067 2068 if (lpConfigPtr->lpServiceStartName) 2069 lpConfigPtr->lpServiceStartName = 2070 (LPSTR)((ULONG_PTR)lpConfigPtr + 2071 (ULONG_PTR)lpConfigPtr->lpServiceStartName); 2072 2073 if (lpConfigPtr->lpDisplayName) 2074 lpConfigPtr->lpDisplayName = 2075 (LPSTR)((ULONG_PTR)lpConfigPtr + 2076 (ULONG_PTR)lpConfigPtr->lpDisplayName); 2077 2078 TRACE("QueryServiceConfigA() done\n"); 2079 2080 return TRUE; 2081 } 2082 2083 2084 /********************************************************************** 2085 * QueryServiceConfigW 2086 * 2087 * @implemented 2088 */ 2089 BOOL WINAPI 2090 QueryServiceConfigW(SC_HANDLE hService, 2091 LPQUERY_SERVICE_CONFIGW lpServiceConfig, 2092 DWORD cbBufSize, 2093 LPDWORD pcbBytesNeeded) 2094 { 2095 QUERY_SERVICE_CONFIGW ServiceConfig; 2096 LPQUERY_SERVICE_CONFIGW lpConfigPtr; 2097 DWORD dwBufferSize; 2098 DWORD dwError; 2099 2100 TRACE("QueryServiceConfigW(%p %p %lu %p)\n", 2101 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded); 2102 2103 if (lpServiceConfig == NULL || 2104 cbBufSize < sizeof(QUERY_SERVICE_CONFIGW)) 2105 { 2106 lpConfigPtr = &ServiceConfig; 2107 dwBufferSize = sizeof(QUERY_SERVICE_CONFIGW); 2108 } 2109 else 2110 { 2111 lpConfigPtr = lpServiceConfig; 2112 dwBufferSize = cbBufSize; 2113 } 2114 2115 RpcTryExcept 2116 { 2117 dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService, 2118 (LPBYTE)lpConfigPtr, 2119 dwBufferSize, 2120 pcbBytesNeeded); 2121 } 2122 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2123 { 2124 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2125 } 2126 RpcEndExcept; 2127 2128 if (dwError != ERROR_SUCCESS) 2129 { 2130 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError); 2131 SetLastError(dwError); 2132 return FALSE; 2133 } 2134 2135 /* Adjust the pointers */ 2136 if (lpConfigPtr->lpBinaryPathName) 2137 lpConfigPtr->lpBinaryPathName = 2138 (LPWSTR)((ULONG_PTR)lpConfigPtr + 2139 (ULONG_PTR)lpConfigPtr->lpBinaryPathName); 2140 2141 if (lpConfigPtr->lpLoadOrderGroup) 2142 lpConfigPtr->lpLoadOrderGroup = 2143 (LPWSTR)((ULONG_PTR)lpConfigPtr + 2144 (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup); 2145 2146 if (lpConfigPtr->lpDependencies) 2147 lpConfigPtr->lpDependencies = 2148 (LPWSTR)((ULONG_PTR)lpConfigPtr + 2149 (ULONG_PTR)lpConfigPtr->lpDependencies); 2150 2151 if (lpConfigPtr->lpServiceStartName) 2152 lpConfigPtr->lpServiceStartName = 2153 (LPWSTR)((ULONG_PTR)lpConfigPtr + 2154 (ULONG_PTR)lpConfigPtr->lpServiceStartName); 2155 2156 if (lpConfigPtr->lpDisplayName) 2157 lpConfigPtr->lpDisplayName = 2158 (LPWSTR)((ULONG_PTR)lpConfigPtr + 2159 (ULONG_PTR)lpConfigPtr->lpDisplayName); 2160 2161 TRACE("QueryServiceConfigW() done\n"); 2162 2163 return TRUE; 2164 } 2165 2166 2167 /********************************************************************** 2168 * QueryServiceConfig2A 2169 * 2170 * @implemented 2171 */ 2172 BOOL WINAPI 2173 QueryServiceConfig2A(SC_HANDLE hService, 2174 DWORD dwInfoLevel, 2175 LPBYTE lpBuffer, 2176 DWORD cbBufSize, 2177 LPDWORD pcbBytesNeeded) 2178 { 2179 SERVICE_DESCRIPTIONA ServiceDescription; 2180 SERVICE_FAILURE_ACTIONSA ServiceFailureActions; 2181 LPBYTE lpTempBuffer; 2182 BOOL bUseTempBuffer = FALSE; 2183 DWORD dwBufferSize; 2184 DWORD dwError; 2185 2186 TRACE("QueryServiceConfig2A(%p %lu %p %lu %p)\n", 2187 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); 2188 2189 lpTempBuffer = lpBuffer; 2190 dwBufferSize = cbBufSize; 2191 2192 switch (dwInfoLevel) 2193 { 2194 case SERVICE_CONFIG_DESCRIPTION: 2195 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_DESCRIPTIONA))) 2196 { 2197 lpTempBuffer = (LPBYTE)&ServiceDescription; 2198 dwBufferSize = sizeof(SERVICE_DESCRIPTIONA); 2199 bUseTempBuffer = TRUE; 2200 } 2201 break; 2202 2203 case SERVICE_CONFIG_FAILURE_ACTIONS: 2204 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_FAILURE_ACTIONSA))) 2205 { 2206 lpTempBuffer = (LPBYTE)&ServiceFailureActions; 2207 dwBufferSize = sizeof(SERVICE_FAILURE_ACTIONSA); 2208 bUseTempBuffer = TRUE; 2209 } 2210 break; 2211 2212 default: 2213 WARN("Unknown info level 0x%lx\n", dwInfoLevel); 2214 SetLastError(ERROR_INVALID_LEVEL); 2215 return FALSE; 2216 } 2217 2218 RpcTryExcept 2219 { 2220 dwError = RQueryServiceConfig2A((SC_RPC_HANDLE)hService, 2221 dwInfoLevel, 2222 lpTempBuffer, 2223 dwBufferSize, 2224 pcbBytesNeeded); 2225 } 2226 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2227 { 2228 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2229 } 2230 RpcEndExcept; 2231 2232 if (dwError != ERROR_SUCCESS) 2233 { 2234 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError); 2235 SetLastError(dwError); 2236 return FALSE; 2237 } 2238 2239 if (bUseTempBuffer != FALSE) 2240 { 2241 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n"); 2242 *pcbBytesNeeded = dwBufferSize; 2243 SetLastError(ERROR_INSUFFICIENT_BUFFER); 2244 return FALSE; 2245 } 2246 2247 switch (dwInfoLevel) 2248 { 2249 case SERVICE_CONFIG_DESCRIPTION: 2250 { 2251 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpTempBuffer; 2252 2253 if (lpPtr->lpDescription != NULL) 2254 lpPtr->lpDescription = 2255 (LPSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpDescription); 2256 } 2257 break; 2258 2259 case SERVICE_CONFIG_FAILURE_ACTIONS: 2260 { 2261 LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpTempBuffer; 2262 2263 if (lpPtr->lpRebootMsg != NULL) 2264 lpPtr->lpRebootMsg = 2265 (LPSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpRebootMsg); 2266 2267 if (lpPtr->lpCommand != NULL) 2268 lpPtr->lpCommand = 2269 (LPSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpCommand); 2270 2271 if (lpPtr->lpsaActions != NULL) 2272 lpPtr->lpsaActions = 2273 (LPSC_ACTION)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpsaActions); 2274 } 2275 break; 2276 } 2277 2278 TRACE("QueryServiceConfig2A() done\n"); 2279 2280 return TRUE; 2281 } 2282 2283 2284 /********************************************************************** 2285 * QueryServiceConfig2W 2286 * 2287 * @implemented 2288 */ 2289 BOOL WINAPI 2290 QueryServiceConfig2W(SC_HANDLE hService, 2291 DWORD dwInfoLevel, 2292 LPBYTE lpBuffer, 2293 DWORD cbBufSize, 2294 LPDWORD pcbBytesNeeded) 2295 { 2296 SERVICE_DESCRIPTIONW ServiceDescription; 2297 SERVICE_FAILURE_ACTIONSW ServiceFailureActions; 2298 LPBYTE lpTempBuffer; 2299 BOOL bUseTempBuffer = FALSE; 2300 DWORD dwBufferSize; 2301 DWORD dwError; 2302 2303 TRACE("QueryServiceConfig2W(%p %lu %p %lu %p)\n", 2304 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); 2305 2306 lpTempBuffer = lpBuffer; 2307 dwBufferSize = cbBufSize; 2308 2309 switch (dwInfoLevel) 2310 { 2311 case SERVICE_CONFIG_DESCRIPTION: 2312 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_DESCRIPTIONW))) 2313 { 2314 lpTempBuffer = (LPBYTE)&ServiceDescription; 2315 dwBufferSize = sizeof(SERVICE_DESCRIPTIONW); 2316 bUseTempBuffer = TRUE; 2317 } 2318 break; 2319 2320 case SERVICE_CONFIG_FAILURE_ACTIONS: 2321 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_FAILURE_ACTIONSW))) 2322 { 2323 lpTempBuffer = (LPBYTE)&ServiceFailureActions; 2324 dwBufferSize = sizeof(SERVICE_FAILURE_ACTIONSW); 2325 bUseTempBuffer = TRUE; 2326 } 2327 break; 2328 2329 default: 2330 WARN("Unknown info level 0x%lx\n", dwInfoLevel); 2331 SetLastError(ERROR_INVALID_LEVEL); 2332 return FALSE; 2333 } 2334 2335 RpcTryExcept 2336 { 2337 dwError = RQueryServiceConfig2W((SC_RPC_HANDLE)hService, 2338 dwInfoLevel, 2339 lpTempBuffer, 2340 dwBufferSize, 2341 pcbBytesNeeded); 2342 } 2343 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2344 { 2345 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2346 } 2347 RpcEndExcept; 2348 2349 if (dwError != ERROR_SUCCESS) 2350 { 2351 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError); 2352 SetLastError(dwError); 2353 return FALSE; 2354 } 2355 2356 if (bUseTempBuffer != FALSE) 2357 { 2358 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n"); 2359 *pcbBytesNeeded = dwBufferSize; 2360 SetLastError(ERROR_INSUFFICIENT_BUFFER); 2361 return FALSE; 2362 } 2363 2364 switch (dwInfoLevel) 2365 { 2366 case SERVICE_CONFIG_DESCRIPTION: 2367 { 2368 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpTempBuffer; 2369 2370 if (lpPtr->lpDescription != NULL) 2371 lpPtr->lpDescription = 2372 (LPWSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpDescription); 2373 } 2374 break; 2375 2376 case SERVICE_CONFIG_FAILURE_ACTIONS: 2377 { 2378 LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpTempBuffer; 2379 2380 if (lpPtr->lpRebootMsg != NULL) 2381 lpPtr->lpRebootMsg = 2382 (LPWSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpRebootMsg); 2383 2384 if (lpPtr->lpCommand != NULL) 2385 lpPtr->lpCommand = 2386 (LPWSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpCommand); 2387 2388 if (lpPtr->lpsaActions != NULL) 2389 lpPtr->lpsaActions = 2390 (LPSC_ACTION)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpsaActions); 2391 } 2392 break; 2393 } 2394 2395 TRACE("QueryServiceConfig2W() done\n"); 2396 2397 return TRUE; 2398 } 2399 2400 2401 /********************************************************************** 2402 * QueryServiceLockStatusA 2403 * 2404 * @implemented 2405 */ 2406 BOOL WINAPI 2407 QueryServiceLockStatusA(SC_HANDLE hSCManager, 2408 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, 2409 DWORD cbBufSize, 2410 LPDWORD pcbBytesNeeded) 2411 { 2412 QUERY_SERVICE_LOCK_STATUSA LockStatus; 2413 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr; 2414 DWORD dwBufferSize; 2415 DWORD dwError; 2416 2417 TRACE("QueryServiceLockStatusA(%p %p %lu %p)\n", 2418 hSCManager, lpLockStatus, cbBufSize, pcbBytesNeeded); 2419 2420 if (lpLockStatus == NULL || cbBufSize < sizeof(QUERY_SERVICE_LOCK_STATUSA)) 2421 { 2422 lpStatusPtr = &LockStatus; 2423 dwBufferSize = sizeof(QUERY_SERVICE_LOCK_STATUSA); 2424 } 2425 else 2426 { 2427 lpStatusPtr = lpLockStatus; 2428 dwBufferSize = cbBufSize; 2429 } 2430 2431 RpcTryExcept 2432 { 2433 dwError = RQueryServiceLockStatusA((SC_RPC_HANDLE)hSCManager, 2434 (LPBYTE)lpStatusPtr, 2435 dwBufferSize, 2436 pcbBytesNeeded); 2437 } 2438 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2439 { 2440 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2441 } 2442 RpcEndExcept; 2443 2444 if (dwError != ERROR_SUCCESS) 2445 { 2446 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError); 2447 SetLastError(dwError); 2448 return FALSE; 2449 } 2450 2451 if (lpStatusPtr->lpLockOwner != NULL) 2452 { 2453 lpStatusPtr->lpLockOwner = 2454 (LPSTR)((ULONG_PTR)lpStatusPtr + (ULONG_PTR)lpStatusPtr->lpLockOwner); 2455 } 2456 2457 TRACE("QueryServiceLockStatusA() done\n"); 2458 2459 return TRUE; 2460 } 2461 2462 2463 /********************************************************************** 2464 * QueryServiceLockStatusW 2465 * 2466 * @implemented 2467 */ 2468 BOOL WINAPI 2469 QueryServiceLockStatusW(SC_HANDLE hSCManager, 2470 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, 2471 DWORD cbBufSize, 2472 LPDWORD pcbBytesNeeded) 2473 { 2474 QUERY_SERVICE_LOCK_STATUSW LockStatus; 2475 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr; 2476 DWORD dwBufferSize; 2477 DWORD dwError; 2478 2479 TRACE("QueryServiceLockStatusW(%p %p %lu %p)\n", 2480 hSCManager, lpLockStatus, cbBufSize, pcbBytesNeeded); 2481 2482 if (lpLockStatus == NULL || cbBufSize < sizeof(QUERY_SERVICE_LOCK_STATUSW)) 2483 { 2484 lpStatusPtr = &LockStatus; 2485 dwBufferSize = sizeof(QUERY_SERVICE_LOCK_STATUSW); 2486 } 2487 else 2488 { 2489 lpStatusPtr = lpLockStatus; 2490 dwBufferSize = cbBufSize; 2491 } 2492 2493 RpcTryExcept 2494 { 2495 dwError = RQueryServiceLockStatusW((SC_RPC_HANDLE)hSCManager, 2496 (LPBYTE)lpStatusPtr, 2497 dwBufferSize, 2498 pcbBytesNeeded); 2499 } 2500 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2501 { 2502 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2503 } 2504 RpcEndExcept; 2505 2506 if (dwError != ERROR_SUCCESS) 2507 { 2508 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError); 2509 SetLastError(dwError); 2510 return FALSE; 2511 } 2512 2513 if (lpStatusPtr->lpLockOwner != NULL) 2514 { 2515 lpStatusPtr->lpLockOwner = 2516 (LPWSTR)((ULONG_PTR)lpStatusPtr + (ULONG_PTR)lpStatusPtr->lpLockOwner); 2517 } 2518 2519 TRACE("QueryServiceLockStatusW() done\n"); 2520 2521 return TRUE; 2522 } 2523 2524 2525 /********************************************************************** 2526 * QueryServiceObjectSecurity 2527 * 2528 * @implemented 2529 */ 2530 BOOL WINAPI 2531 QueryServiceObjectSecurity(SC_HANDLE hService, 2532 SECURITY_INFORMATION dwSecurityInformation, 2533 PSECURITY_DESCRIPTOR lpSecurityDescriptor, 2534 DWORD cbBufSize, 2535 LPDWORD pcbBytesNeeded) 2536 { 2537 DWORD dwError; 2538 2539 TRACE("QueryServiceObjectSecurity(%p %lu %p)\n", 2540 hService, dwSecurityInformation, lpSecurityDescriptor); 2541 2542 RpcTryExcept 2543 { 2544 dwError = RQueryServiceObjectSecurity((SC_RPC_HANDLE)hService, 2545 dwSecurityInformation, 2546 (LPBYTE)lpSecurityDescriptor, 2547 cbBufSize, 2548 pcbBytesNeeded); 2549 } 2550 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2551 { 2552 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2553 } 2554 RpcEndExcept; 2555 2556 if (dwError != ERROR_SUCCESS) 2557 { 2558 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError); 2559 SetLastError(dwError); 2560 return FALSE; 2561 } 2562 2563 return TRUE; 2564 } 2565 2566 2567 /********************************************************************** 2568 * SetServiceObjectSecurity 2569 * 2570 * @implemented 2571 */ 2572 BOOL WINAPI 2573 SetServiceObjectSecurity(SC_HANDLE hService, 2574 SECURITY_INFORMATION dwSecurityInformation, 2575 PSECURITY_DESCRIPTOR lpSecurityDescriptor) 2576 { 2577 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL; 2578 ULONG Length; 2579 NTSTATUS Status; 2580 DWORD dwError; 2581 2582 TRACE("SetServiceObjectSecurity(%p %lu %p)\n", 2583 hService, dwSecurityInformation, lpSecurityDescriptor); 2584 2585 Length = 0; 2586 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor, 2587 SelfRelativeSD, 2588 &Length); 2589 if (Status != STATUS_BUFFER_TOO_SMALL) 2590 { 2591 SetLastError(ERROR_INVALID_PARAMETER); 2592 return FALSE; 2593 } 2594 2595 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length); 2596 if (SelfRelativeSD == NULL) 2597 { 2598 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2599 return FALSE; 2600 } 2601 2602 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor, 2603 SelfRelativeSD, 2604 &Length); 2605 if (!NT_SUCCESS(Status)) 2606 { 2607 HeapFree(GetProcessHeap(), 0, SelfRelativeSD); 2608 SetLastError(RtlNtStatusToDosError(Status)); 2609 return FALSE; 2610 } 2611 2612 RpcTryExcept 2613 { 2614 dwError = RSetServiceObjectSecurity((SC_RPC_HANDLE)hService, 2615 dwSecurityInformation, 2616 (LPBYTE)SelfRelativeSD, 2617 Length); 2618 } 2619 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2620 { 2621 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2622 } 2623 RpcEndExcept; 2624 2625 HeapFree(GetProcessHeap(), 0, SelfRelativeSD); 2626 2627 if (dwError != ERROR_SUCCESS) 2628 { 2629 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError); 2630 SetLastError(dwError); 2631 return FALSE; 2632 } 2633 2634 return TRUE; 2635 } 2636 2637 2638 /********************************************************************** 2639 * QueryServiceStatus 2640 * 2641 * @implemented 2642 */ 2643 BOOL WINAPI 2644 QueryServiceStatus(SC_HANDLE hService, 2645 LPSERVICE_STATUS lpServiceStatus) 2646 { 2647 DWORD dwError; 2648 2649 TRACE("QueryServiceStatus(%p %p)\n", 2650 hService, lpServiceStatus); 2651 2652 if (!hService) 2653 { 2654 SetLastError(ERROR_INVALID_HANDLE); 2655 return FALSE; 2656 } 2657 2658 RpcTryExcept 2659 { 2660 dwError = RQueryServiceStatus((SC_RPC_HANDLE)hService, 2661 lpServiceStatus); 2662 } 2663 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2664 { 2665 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2666 } 2667 RpcEndExcept; 2668 2669 if (dwError != ERROR_SUCCESS) 2670 { 2671 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError); 2672 SetLastError(dwError); 2673 return FALSE; 2674 } 2675 2676 return TRUE; 2677 } 2678 2679 2680 /********************************************************************** 2681 * QueryServiceStatusEx 2682 * 2683 * @implemented 2684 */ 2685 BOOL WINAPI 2686 QueryServiceStatusEx(SC_HANDLE hService, 2687 SC_STATUS_TYPE InfoLevel, 2688 LPBYTE lpBuffer, 2689 DWORD cbBufSize, 2690 LPDWORD pcbBytesNeeded) 2691 { 2692 DWORD dwError; 2693 2694 TRACE("QueryServiceStatusEx(%p %lu %p %lu %p)\n", 2695 hService, InfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); 2696 2697 if (InfoLevel != SC_STATUS_PROCESS_INFO) 2698 { 2699 SetLastError(ERROR_INVALID_LEVEL); 2700 return FALSE; 2701 } 2702 2703 if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS)) 2704 { 2705 *pcbBytesNeeded = sizeof(SERVICE_STATUS_PROCESS); 2706 SetLastError(ERROR_INSUFFICIENT_BUFFER); 2707 return FALSE; 2708 } 2709 2710 RpcTryExcept 2711 { 2712 dwError = RQueryServiceStatusEx((SC_RPC_HANDLE)hService, 2713 InfoLevel, 2714 lpBuffer, 2715 cbBufSize, 2716 pcbBytesNeeded); 2717 } 2718 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2719 { 2720 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2721 } 2722 RpcEndExcept; 2723 2724 if (dwError != ERROR_SUCCESS) 2725 { 2726 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError); 2727 SetLastError(dwError); 2728 return FALSE; 2729 } 2730 2731 return TRUE; 2732 } 2733 2734 2735 /********************************************************************** 2736 * StartServiceA 2737 * 2738 * @implemented 2739 */ 2740 BOOL WINAPI 2741 StartServiceA(SC_HANDLE hService, 2742 DWORD dwNumServiceArgs, 2743 LPCSTR *lpServiceArgVectors) 2744 { 2745 DWORD dwError; 2746 2747 TRACE("StartServiceA(%p %lu %p)\n", 2748 hService, dwNumServiceArgs, lpServiceArgVectors); 2749 2750 RpcTryExcept 2751 { 2752 dwError = RStartServiceA((SC_RPC_HANDLE)hService, 2753 dwNumServiceArgs, 2754 (LPSTRING_PTRSA)lpServiceArgVectors); 2755 } 2756 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2757 { 2758 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2759 } 2760 RpcEndExcept; 2761 2762 if (dwError != ERROR_SUCCESS) 2763 { 2764 ERR("RStartServiceA() failed (Error %lu)\n", dwError); 2765 SetLastError(dwError); 2766 return FALSE; 2767 } 2768 2769 return TRUE; 2770 } 2771 2772 2773 /********************************************************************** 2774 * StartServiceW 2775 * 2776 * @implemented 2777 */ 2778 BOOL WINAPI 2779 StartServiceW(SC_HANDLE hService, 2780 DWORD dwNumServiceArgs, 2781 LPCWSTR *lpServiceArgVectors) 2782 { 2783 DWORD dwError; 2784 2785 TRACE("StartServiceW(%p %lu %p)\n", 2786 hService, dwNumServiceArgs, lpServiceArgVectors); 2787 2788 RpcTryExcept 2789 { 2790 dwError = RStartServiceW((SC_RPC_HANDLE)hService, 2791 dwNumServiceArgs, 2792 (LPSTRING_PTRSW)lpServiceArgVectors); 2793 } 2794 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2795 { 2796 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2797 } 2798 RpcEndExcept; 2799 2800 if (dwError != ERROR_SUCCESS) 2801 { 2802 ERR("RStartServiceW() failed (Error %lu)\n", dwError); 2803 SetLastError(dwError); 2804 return FALSE; 2805 } 2806 2807 return TRUE; 2808 } 2809 2810 2811 /********************************************************************** 2812 * UnlockServiceDatabase 2813 * 2814 * @implemented 2815 */ 2816 BOOL WINAPI 2817 UnlockServiceDatabase(SC_LOCK ScLock) 2818 { 2819 DWORD dwError; 2820 2821 TRACE("UnlockServiceDatabase(%x)\n", 2822 ScLock); 2823 2824 RpcTryExcept 2825 { 2826 dwError = RUnlockServiceDatabase((LPSC_RPC_LOCK)&ScLock); 2827 } 2828 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2829 { 2830 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2831 } 2832 RpcEndExcept; 2833 2834 if (dwError == ERROR_INVALID_HANDLE) 2835 dwError = ERROR_INVALID_SERVICE_LOCK; 2836 2837 if (dwError != ERROR_SUCCESS) 2838 { 2839 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError); 2840 SetLastError(dwError); 2841 return FALSE; 2842 } 2843 2844 return TRUE; 2845 } 2846 2847 2848 /********************************************************************** 2849 * NotifyBootConfigStatus 2850 * 2851 * @implemented 2852 */ 2853 BOOL WINAPI 2854 NotifyBootConfigStatus(BOOL BootAcceptable) 2855 { 2856 DWORD dwError; 2857 2858 TRACE("NotifyBootConfigStatus(%u)\n", 2859 BootAcceptable); 2860 2861 RpcTryExcept 2862 { 2863 dwError = RNotifyBootConfigStatus(NULL, 2864 BootAcceptable); 2865 } 2866 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2867 { 2868 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 2869 } 2870 RpcEndExcept; 2871 2872 if (dwError != ERROR_SUCCESS) 2873 { 2874 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError); 2875 SetLastError(dwError); 2876 return FALSE; 2877 } 2878 2879 return TRUE; 2880 } 2881 2882 /* EOF */ 2883