Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenscm.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS system libraries 00004 * FILE: lib/advapi32/service/scm.c 00005 * PURPOSE: Service control manager functions 00006 * PROGRAMMER: Emanuele Aliberti 00007 * Eric Kohl 00008 * UPDATE HISTORY: 00009 * 19990413 EA created 00010 * 19990515 EA 00011 */ 00012 00013 /* INCLUDES ******************************************************************/ 00014 00015 #include <advapi32.h> 00016 WINE_DEFAULT_DEBUG_CHANNEL(advapi); 00017 00018 00019 /* FUNCTIONS *****************************************************************/ 00020 00021 handle_t __RPC_USER 00022 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName) 00023 { 00024 handle_t hBinding = NULL; 00025 UCHAR *pszStringBinding; 00026 RPC_STATUS status; 00027 00028 TRACE("SVCCTL_HANDLEA_bind() called\n"); 00029 00030 status = RpcStringBindingComposeA(NULL, 00031 (UCHAR *)"ncacn_np", 00032 (UCHAR *)szMachineName, 00033 (UCHAR *)"\\pipe\\ntsvcs", 00034 NULL, 00035 (UCHAR **)&pszStringBinding); 00036 if (status != RPC_S_OK) 00037 { 00038 ERR("RpcStringBindingCompose returned 0x%x\n", status); 00039 return NULL; 00040 } 00041 00042 /* Set the binding handle that will be used to bind to the server. */ 00043 status = RpcBindingFromStringBindingA(pszStringBinding, 00044 &hBinding); 00045 if (status != RPC_S_OK) 00046 { 00047 ERR("RpcBindingFromStringBinding returned 0x%x\n", status); 00048 } 00049 00050 status = RpcStringFreeA(&pszStringBinding); 00051 if (status != RPC_S_OK) 00052 { 00053 ERR("RpcStringFree returned 0x%x\n", status); 00054 } 00055 00056 return hBinding; 00057 } 00058 00059 00060 void __RPC_USER 00061 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName, 00062 handle_t hBinding) 00063 { 00064 RPC_STATUS status; 00065 00066 TRACE("SVCCTL_HANDLEA_unbind() called\n"); 00067 00068 status = RpcBindingFree(&hBinding); 00069 if (status != RPC_S_OK) 00070 { 00071 ERR("RpcBindingFree returned 0x%x\n", status); 00072 } 00073 } 00074 00075 00076 handle_t __RPC_USER 00077 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName) 00078 { 00079 handle_t hBinding = NULL; 00080 LPWSTR pszStringBinding; 00081 RPC_STATUS status; 00082 00083 TRACE("SVCCTL_HANDLEW_bind() called\n"); 00084 00085 status = RpcStringBindingComposeW(NULL, 00086 L"ncacn_np", 00087 szMachineName, 00088 L"\\pipe\\ntsvcs", 00089 NULL, 00090 &pszStringBinding); 00091 if (status != RPC_S_OK) 00092 { 00093 ERR("RpcStringBindingCompose returned 0x%x\n", status); 00094 return NULL; 00095 } 00096 00097 /* Set the binding handle that will be used to bind to the server. */ 00098 status = RpcBindingFromStringBindingW(pszStringBinding, 00099 &hBinding); 00100 if (status != RPC_S_OK) 00101 { 00102 ERR("RpcBindingFromStringBinding returned 0x%x\n", status); 00103 } 00104 00105 status = RpcStringFreeW(&pszStringBinding); 00106 if (status != RPC_S_OK) 00107 { 00108 ERR("RpcStringFree returned 0x%x\n", status); 00109 } 00110 00111 return hBinding; 00112 } 00113 00114 00115 void __RPC_USER 00116 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName, 00117 handle_t hBinding) 00118 { 00119 RPC_STATUS status; 00120 00121 TRACE("SVCCTL_HANDLEW_unbind() called\n"); 00122 00123 status = RpcBindingFree(&hBinding); 00124 if (status != RPC_S_OK) 00125 { 00126 ERR("RpcBindingFree returned 0x%x\n", status); 00127 } 00128 } 00129 00130 00131 DWORD 00132 ScmRpcStatusToWinError(RPC_STATUS Status) 00133 { 00134 switch (Status) 00135 { 00136 case RPC_S_INVALID_BINDING: 00137 case RPC_X_SS_IN_NULL_CONTEXT: 00138 return ERROR_INVALID_HANDLE; 00139 00140 case RPC_X_ENUM_VALUE_OUT_OF_RANGE: 00141 case RPC_X_BYTE_COUNT_TOO_SMALL: 00142 return ERROR_INVALID_PARAMETER; 00143 00144 case RPC_X_NULL_REF_POINTER: 00145 return ERROR_INVALID_ADDRESS; 00146 00147 default: 00148 return (DWORD)Status; 00149 } 00150 } 00151 00152 00153 /********************************************************************** 00154 * ChangeServiceConfig2A 00155 * 00156 * @implemented 00157 */ 00158 BOOL WINAPI 00159 ChangeServiceConfig2A(SC_HANDLE hService, 00160 DWORD dwInfoLevel, 00161 LPVOID lpInfo) 00162 { 00163 SC_RPC_CONFIG_INFOA Info; 00164 DWORD dwError; 00165 00166 TRACE("ChangeServiceConfig2A() called\n"); 00167 00168 /* Fill relevent field of the Info structure */ 00169 Info.dwInfoLevel = dwInfoLevel; 00170 switch (dwInfoLevel) 00171 { 00172 case SERVICE_CONFIG_DESCRIPTION: 00173 Info.psd = (LPSERVICE_DESCRIPTIONA)&lpInfo; 00174 Info.lpDescription = ((LPSERVICE_DESCRIPTIONA)lpInfo)->lpDescription; //HACK 00175 break; 00176 00177 case SERVICE_CONFIG_FAILURE_ACTIONS: 00178 Info.psfa = (LPSERVICE_FAILURE_ACTIONSA)lpInfo; 00179 break; 00180 00181 default: 00182 WARN("Unknown info level 0x%lx\n", dwInfoLevel); 00183 SetLastError(ERROR_INVALID_PARAMETER); 00184 return FALSE; 00185 } 00186 00187 if (lpInfo == NULL) 00188 return TRUE; 00189 00190 RpcTryExcept 00191 { 00192 dwError = RChangeServiceConfig2A((SC_RPC_HANDLE)hService, 00193 Info); 00194 } 00195 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00196 { 00197 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00198 } 00199 RpcEndExcept; 00200 00201 if (dwError != ERROR_SUCCESS) 00202 { 00203 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError); 00204 SetLastError(dwError); 00205 return FALSE; 00206 } 00207 00208 return TRUE; 00209 } 00210 00211 00212 /********************************************************************** 00213 * ChangeServiceConfig2W 00214 * 00215 * @implemented 00216 */ 00217 BOOL WINAPI 00218 ChangeServiceConfig2W(SC_HANDLE hService, 00219 DWORD dwInfoLevel, 00220 LPVOID lpInfo) 00221 { 00222 SC_RPC_CONFIG_INFOW Info; 00223 DWORD dwError; 00224 00225 TRACE("ChangeServiceConfig2W() called\n"); 00226 00227 /* Fill relevent field of the Info structure */ 00228 Info.dwInfoLevel = dwInfoLevel; 00229 switch (dwInfoLevel) 00230 { 00231 case SERVICE_CONFIG_DESCRIPTION: 00232 Info.psd = (LPSERVICE_DESCRIPTIONW)lpInfo; 00233 break; 00234 00235 case SERVICE_CONFIG_FAILURE_ACTIONS: 00236 Info.psfa = (LPSERVICE_FAILURE_ACTIONSW)&lpInfo; 00237 break; 00238 00239 default: 00240 WARN("Unknown info level 0x%lx\n", dwInfoLevel); 00241 SetLastError(ERROR_INVALID_PARAMETER); 00242 return FALSE; 00243 } 00244 00245 if (lpInfo == NULL) 00246 return TRUE; 00247 00248 RpcTryExcept 00249 { 00250 dwError = RChangeServiceConfig2W((SC_RPC_HANDLE)hService, 00251 Info); 00252 } 00253 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00254 { 00255 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00256 } 00257 RpcEndExcept; 00258 00259 if (dwError != ERROR_SUCCESS) 00260 { 00261 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError); 00262 SetLastError(dwError); 00263 return FALSE; 00264 } 00265 00266 return TRUE; 00267 } 00268 00269 00270 /********************************************************************** 00271 * ChangeServiceConfigA 00272 * 00273 * @implemented 00274 */ 00275 BOOL WINAPI 00276 ChangeServiceConfigA(SC_HANDLE hService, 00277 DWORD dwServiceType, 00278 DWORD dwStartType, 00279 DWORD dwErrorControl, 00280 LPCSTR lpBinaryPathName, 00281 LPCSTR lpLoadOrderGroup, 00282 LPDWORD lpdwTagId, 00283 LPCSTR lpDependencies, 00284 LPCSTR lpServiceStartName, 00285 LPCSTR lpPassword, 00286 LPCSTR lpDisplayName) 00287 { 00288 DWORD dwError; 00289 DWORD dwDependenciesLength = 0; 00290 DWORD dwLength; 00291 LPCSTR lpStr; 00292 00293 TRACE("ChangeServiceConfigA() called\n"); 00294 00295 /* Calculate the Dependencies length*/ 00296 if (lpDependencies != NULL) 00297 { 00298 lpStr = lpDependencies; 00299 while (*lpStr) 00300 { 00301 dwLength = strlen(lpStr) + 1; 00302 dwDependenciesLength += dwLength; 00303 lpStr = lpStr + dwLength; 00304 } 00305 dwDependenciesLength++; 00306 } 00307 00308 /* FIXME: Encrypt the password */ 00309 00310 RpcTryExcept 00311 { 00312 /* Call to services.exe using RPC */ 00313 dwError = RChangeServiceConfigA((SC_RPC_HANDLE)hService, 00314 dwServiceType, 00315 dwStartType, 00316 dwErrorControl, 00317 (LPSTR)lpBinaryPathName, 00318 (LPSTR)lpLoadOrderGroup, 00319 lpdwTagId, 00320 (LPSTR)lpDependencies, 00321 dwDependenciesLength, 00322 (LPSTR)lpServiceStartName, 00323 NULL, /* FIXME: lpPassword */ 00324 0, /* FIXME: dwPasswordLength */ 00325 (LPSTR)lpDisplayName); 00326 } 00327 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00328 { 00329 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00330 } 00331 RpcEndExcept; 00332 00333 if (dwError != ERROR_SUCCESS) 00334 { 00335 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError); 00336 SetLastError(dwError); 00337 return FALSE; 00338 } 00339 00340 return TRUE; 00341 } 00342 00343 00344 /********************************************************************** 00345 * ChangeServiceConfigW 00346 * 00347 * @implemented 00348 */ 00349 BOOL WINAPI 00350 ChangeServiceConfigW(SC_HANDLE hService, 00351 DWORD dwServiceType, 00352 DWORD dwStartType, 00353 DWORD dwErrorControl, 00354 LPCWSTR lpBinaryPathName, 00355 LPCWSTR lpLoadOrderGroup, 00356 LPDWORD lpdwTagId, 00357 LPCWSTR lpDependencies, 00358 LPCWSTR lpServiceStartName, 00359 LPCWSTR lpPassword, 00360 LPCWSTR lpDisplayName) 00361 { 00362 DWORD dwError; 00363 DWORD dwDependenciesLength = 0; 00364 DWORD dwLength; 00365 LPCWSTR lpStr; 00366 00367 TRACE("ChangeServiceConfigW() called\n"); 00368 00369 /* Calculate the Dependencies length*/ 00370 if (lpDependencies != NULL) 00371 { 00372 lpStr = lpDependencies; 00373 while (*lpStr) 00374 { 00375 dwLength = wcslen(lpStr) + 1; 00376 dwDependenciesLength += dwLength; 00377 lpStr = lpStr + dwLength; 00378 } 00379 dwDependenciesLength++; 00380 } 00381 00382 /* FIXME: Encrypt the password */ 00383 00384 RpcTryExcept 00385 { 00386 /* Call to services.exe using RPC */ 00387 dwError = RChangeServiceConfigW((SC_RPC_HANDLE)hService, 00388 dwServiceType, 00389 dwStartType, 00390 dwErrorControl, 00391 (LPWSTR)lpBinaryPathName, 00392 (LPWSTR)lpLoadOrderGroup, 00393 lpdwTagId, 00394 (LPBYTE)lpDependencies, 00395 dwDependenciesLength, 00396 (LPWSTR)lpServiceStartName, 00397 NULL, /* FIXME: lpPassword */ 00398 0, /* FIXME: dwPasswordLength */ 00399 (LPWSTR)lpDisplayName); 00400 } 00401 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00402 { 00403 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00404 } 00405 RpcEndExcept; 00406 00407 if (dwError != ERROR_SUCCESS) 00408 { 00409 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError); 00410 SetLastError(dwError); 00411 return FALSE; 00412 } 00413 00414 return TRUE; 00415 } 00416 00417 00418 /********************************************************************** 00419 * CloseServiceHandle 00420 * 00421 * @implemented 00422 */ 00423 BOOL WINAPI 00424 CloseServiceHandle(SC_HANDLE hSCObject) 00425 { 00426 DWORD dwError; 00427 00428 TRACE("CloseServiceHandle() called\n"); 00429 00430 if (!hSCObject) 00431 { 00432 SetLastError(ERROR_INVALID_HANDLE); 00433 return FALSE; 00434 } 00435 00436 RpcTryExcept 00437 { 00438 /* Call to services.exe using RPC */ 00439 dwError = RCloseServiceHandle((LPSC_RPC_HANDLE)&hSCObject); 00440 } 00441 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00442 { 00443 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00444 } 00445 RpcEndExcept; 00446 00447 if (dwError) 00448 { 00449 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError); 00450 SetLastError(dwError); 00451 return FALSE; 00452 } 00453 00454 TRACE("CloseServiceHandle() done\n"); 00455 00456 return TRUE; 00457 } 00458 00459 00460 /********************************************************************** 00461 * ControlService 00462 * 00463 * @implemented 00464 */ 00465 BOOL WINAPI 00466 ControlService(SC_HANDLE hService, 00467 DWORD dwControl, 00468 LPSERVICE_STATUS lpServiceStatus) 00469 { 00470 DWORD dwError; 00471 00472 TRACE("ControlService(%x, %x, %p)\n", 00473 hService, dwControl, lpServiceStatus); 00474 00475 RpcTryExcept 00476 { 00477 /* Call to services.exe using RPC */ 00478 dwError = RControlService((SC_RPC_HANDLE)hService, 00479 dwControl, 00480 lpServiceStatus); 00481 } 00482 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00483 { 00484 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00485 } 00486 RpcEndExcept; 00487 00488 if (dwError != ERROR_SUCCESS) 00489 { 00490 TRACE("RControlService() failed (Error %lu)\n", dwError); 00491 SetLastError(dwError); 00492 return FALSE; 00493 } 00494 00495 TRACE("ControlService() done\n"); 00496 00497 return TRUE; 00498 } 00499 00500 00501 /********************************************************************** 00502 * ControlServiceEx 00503 * 00504 * @unimplemented 00505 */ 00506 BOOL WINAPI 00507 ControlServiceEx(IN SC_HANDLE hService, 00508 IN DWORD dwControl, 00509 IN DWORD dwInfoLevel, 00510 IN OUT PVOID pControlParams) 00511 { 00512 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n", 00513 hService, dwControl, dwInfoLevel, pControlParams); 00514 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 00515 return FALSE; 00516 } 00517 00518 00519 /********************************************************************** 00520 * CreateServiceA 00521 * 00522 * @implemented 00523 */ 00524 SC_HANDLE WINAPI 00525 CreateServiceA(SC_HANDLE hSCManager, 00526 LPCSTR lpServiceName, 00527 LPCSTR lpDisplayName, 00528 DWORD dwDesiredAccess, 00529 DWORD dwServiceType, 00530 DWORD dwStartType, 00531 DWORD dwErrorControl, 00532 LPCSTR lpBinaryPathName, 00533 LPCSTR lpLoadOrderGroup, 00534 LPDWORD lpdwTagId, 00535 LPCSTR lpDependencies, 00536 LPCSTR lpServiceStartName, 00537 LPCSTR lpPassword) 00538 { 00539 SC_HANDLE hService = NULL; 00540 DWORD dwDependenciesLength = 0; 00541 DWORD dwError; 00542 DWORD dwLength; 00543 LPCSTR lpStr; 00544 00545 TRACE("CreateServiceA() called\n"); 00546 TRACE("%p %s %s\n", hSCManager, 00547 lpServiceName, lpDisplayName); 00548 00549 if (!hSCManager) 00550 { 00551 SetLastError(ERROR_INVALID_HANDLE); 00552 return NULL; 00553 } 00554 00555 /* Calculate the Dependencies length */ 00556 if (lpDependencies != NULL) 00557 { 00558 lpStr = lpDependencies; 00559 while (*lpStr) 00560 { 00561 dwLength = strlen(lpStr) + 1; 00562 dwDependenciesLength += dwLength; 00563 lpStr = lpStr + dwLength; 00564 } 00565 dwDependenciesLength++; 00566 } 00567 00568 /* FIXME: Encrypt the password */ 00569 00570 RpcTryExcept 00571 { 00572 /* Call to services.exe using RPC */ 00573 dwError = RCreateServiceA((SC_RPC_HANDLE)hSCManager, 00574 (LPSTR)lpServiceName, 00575 (LPSTR)lpDisplayName, 00576 dwDesiredAccess, 00577 dwServiceType, 00578 dwStartType, 00579 dwErrorControl, 00580 (LPSTR)lpBinaryPathName, 00581 (LPSTR)lpLoadOrderGroup, 00582 lpdwTagId, 00583 (LPBYTE)lpDependencies, 00584 dwDependenciesLength, 00585 (LPSTR)lpServiceStartName, 00586 NULL, /* FIXME: lpPassword */ 00587 0, /* FIXME: dwPasswordLength */ 00588 (SC_RPC_HANDLE *)&hService); 00589 } 00590 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00591 { 00592 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00593 } 00594 RpcEndExcept; 00595 00596 if (dwError != ERROR_SUCCESS) 00597 { 00598 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError); 00599 SetLastError(dwError); 00600 return NULL; 00601 } 00602 00603 return hService; 00604 } 00605 00606 00607 /********************************************************************** 00608 * CreateServiceW 00609 * 00610 * @implemented 00611 */ 00612 SC_HANDLE WINAPI 00613 CreateServiceW(SC_HANDLE hSCManager, 00614 LPCWSTR lpServiceName, 00615 LPCWSTR lpDisplayName, 00616 DWORD dwDesiredAccess, 00617 DWORD dwServiceType, 00618 DWORD dwStartType, 00619 DWORD dwErrorControl, 00620 LPCWSTR lpBinaryPathName, 00621 LPCWSTR lpLoadOrderGroup, 00622 LPDWORD lpdwTagId, 00623 LPCWSTR lpDependencies, 00624 LPCWSTR lpServiceStartName, 00625 LPCWSTR lpPassword) 00626 { 00627 SC_HANDLE hService = NULL; 00628 DWORD dwDependenciesLength = 0; 00629 DWORD dwError; 00630 DWORD dwLength; 00631 LPCWSTR lpStr; 00632 00633 TRACE("CreateServiceW() called\n"); 00634 TRACE("%p %S %S\n", hSCManager, 00635 lpServiceName, lpDisplayName); 00636 00637 if (!hSCManager) 00638 { 00639 SetLastError(ERROR_INVALID_HANDLE); 00640 return NULL; 00641 } 00642 00643 /* Calculate the Dependencies length */ 00644 if (lpDependencies != NULL) 00645 { 00646 lpStr = lpDependencies; 00647 while (*lpStr) 00648 { 00649 dwLength = wcslen(lpStr) + 1; 00650 dwDependenciesLength += dwLength; 00651 lpStr = lpStr + dwLength; 00652 } 00653 dwDependenciesLength++; 00654 00655 dwDependenciesLength *= sizeof(WCHAR); 00656 } 00657 00658 /* FIXME: Encrypt the password */ 00659 00660 RpcTryExcept 00661 { 00662 /* Call to services.exe using RPC */ 00663 dwError = RCreateServiceW((SC_RPC_HANDLE)hSCManager, 00664 lpServiceName, 00665 lpDisplayName, 00666 dwDesiredAccess, 00667 dwServiceType, 00668 dwStartType, 00669 dwErrorControl, 00670 lpBinaryPathName, 00671 lpLoadOrderGroup, 00672 lpdwTagId, 00673 (LPBYTE)lpDependencies, 00674 dwDependenciesLength, 00675 lpServiceStartName, 00676 NULL, /* FIXME: lpPassword */ 00677 0, /* FIXME: dwPasswordLength */ 00678 (SC_RPC_HANDLE *)&hService); 00679 } 00680 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00681 { 00682 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00683 } 00684 RpcEndExcept; 00685 00686 if (dwError != ERROR_SUCCESS) 00687 { 00688 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError); 00689 SetLastError(dwError); 00690 return NULL; 00691 } 00692 00693 return hService; 00694 } 00695 00696 00697 /********************************************************************** 00698 * DeleteService 00699 * 00700 * @implemented 00701 */ 00702 BOOL WINAPI 00703 DeleteService(SC_HANDLE hService) 00704 { 00705 DWORD dwError; 00706 00707 TRACE("DeleteService(%x)\n", hService); 00708 00709 RpcTryExcept 00710 { 00711 /* Call to services.exe using RPC */ 00712 dwError = RDeleteService((SC_RPC_HANDLE)hService); 00713 } 00714 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00715 { 00716 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00717 } 00718 RpcEndExcept; 00719 00720 if (dwError != ERROR_SUCCESS) 00721 { 00722 TRACE("RDeleteService() failed (Error %lu)\n", dwError); 00723 SetLastError(dwError); 00724 return FALSE; 00725 } 00726 00727 return TRUE; 00728 } 00729 00730 00731 /********************************************************************** 00732 * EnumDependentServicesA 00733 * 00734 * @implemented 00735 */ 00736 BOOL WINAPI 00737 EnumDependentServicesA(SC_HANDLE hService, 00738 DWORD dwServiceState, 00739 LPENUM_SERVICE_STATUSA lpServices, 00740 DWORD cbBufSize, 00741 LPDWORD pcbBytesNeeded, 00742 LPDWORD lpServicesReturned) 00743 { 00744 ENUM_SERVICE_STATUSA ServiceStatus; 00745 LPENUM_SERVICE_STATUSA lpStatusPtr; 00746 DWORD dwBufferSize; 00747 DWORD dwError; 00748 DWORD dwCount; 00749 00750 TRACE("EnumDependentServicesA() called\n"); 00751 00752 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSA)) 00753 { 00754 lpStatusPtr = &ServiceStatus; 00755 dwBufferSize = sizeof(ENUM_SERVICE_STATUSA); 00756 } 00757 else 00758 { 00759 lpStatusPtr = lpServices; 00760 dwBufferSize = cbBufSize; 00761 } 00762 00763 RpcTryExcept 00764 { 00765 dwError = REnumDependentServicesA((SC_RPC_HANDLE)hService, 00766 dwServiceState, 00767 (LPBYTE)lpStatusPtr, 00768 dwBufferSize, 00769 pcbBytesNeeded, 00770 lpServicesReturned); 00771 } 00772 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00773 { 00774 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00775 } 00776 RpcEndExcept; 00777 00778 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 00779 { 00780 if (*lpServicesReturned > 0) 00781 { 00782 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 00783 { 00784 if (lpStatusPtr->lpServiceName) 00785 lpStatusPtr->lpServiceName = 00786 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 00787 00788 if (lpStatusPtr->lpDisplayName) 00789 lpStatusPtr->lpDisplayName = 00790 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 00791 00792 lpStatusPtr++; 00793 } 00794 } 00795 } 00796 00797 if (dwError != ERROR_SUCCESS) 00798 { 00799 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError); 00800 SetLastError(dwError); 00801 return FALSE; 00802 } 00803 00804 TRACE("EnumDependentServicesA() done\n"); 00805 00806 return TRUE; 00807 } 00808 00809 00810 /********************************************************************** 00811 * EnumDependentServicesW 00812 * 00813 * @implemented 00814 */ 00815 BOOL WINAPI 00816 EnumDependentServicesW(SC_HANDLE hService, 00817 DWORD dwServiceState, 00818 LPENUM_SERVICE_STATUSW lpServices, 00819 DWORD cbBufSize, 00820 LPDWORD pcbBytesNeeded, 00821 LPDWORD lpServicesReturned) 00822 { 00823 ENUM_SERVICE_STATUSW ServiceStatus; 00824 LPENUM_SERVICE_STATUSW lpStatusPtr; 00825 DWORD dwBufferSize; 00826 DWORD dwError; 00827 DWORD dwCount; 00828 00829 TRACE("EnumDependentServicesW() called\n"); 00830 00831 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) 00832 { 00833 lpStatusPtr = &ServiceStatus; 00834 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); 00835 } 00836 else 00837 { 00838 lpStatusPtr = lpServices; 00839 dwBufferSize = cbBufSize; 00840 } 00841 00842 RpcTryExcept 00843 { 00844 dwError = REnumDependentServicesW((SC_RPC_HANDLE)hService, 00845 dwServiceState, 00846 (LPBYTE)lpStatusPtr, 00847 dwBufferSize, 00848 pcbBytesNeeded, 00849 lpServicesReturned); 00850 } 00851 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00852 { 00853 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00854 } 00855 RpcEndExcept; 00856 00857 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 00858 { 00859 if (*lpServicesReturned > 0) 00860 { 00861 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 00862 { 00863 if (lpStatusPtr->lpServiceName) 00864 lpStatusPtr->lpServiceName = 00865 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 00866 00867 if (lpStatusPtr->lpDisplayName) 00868 lpStatusPtr->lpDisplayName = 00869 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 00870 00871 lpStatusPtr++; 00872 } 00873 } 00874 } 00875 00876 if (dwError != ERROR_SUCCESS) 00877 { 00878 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError); 00879 SetLastError(dwError); 00880 return FALSE; 00881 } 00882 00883 TRACE("EnumDependentServicesW() done\n"); 00884 00885 return TRUE; 00886 } 00887 00888 00889 /********************************************************************** 00890 * EnumServiceGroupW 00891 * 00892 * @implemented 00893 */ 00894 BOOL WINAPI 00895 EnumServiceGroupW(SC_HANDLE hSCManager, 00896 DWORD dwServiceType, 00897 DWORD dwServiceState, 00898 LPENUM_SERVICE_STATUSW lpServices, 00899 DWORD cbBufSize, 00900 LPDWORD pcbBytesNeeded, 00901 LPDWORD lpServicesReturned, 00902 LPDWORD lpResumeHandle, 00903 LPCWSTR lpGroup) 00904 { 00905 ENUM_SERVICE_STATUSW ServiceStatus; 00906 LPENUM_SERVICE_STATUSW lpStatusPtr; 00907 DWORD dwBufferSize; 00908 DWORD dwError; 00909 DWORD dwCount; 00910 00911 TRACE("EnumServiceGroupW() called\n"); 00912 00913 if (!hSCManager) 00914 { 00915 SetLastError(ERROR_INVALID_HANDLE); 00916 return FALSE; 00917 } 00918 00919 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) 00920 { 00921 lpStatusPtr = &ServiceStatus; 00922 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); 00923 } 00924 else 00925 { 00926 lpStatusPtr = lpServices; 00927 dwBufferSize = cbBufSize; 00928 } 00929 00930 RpcTryExcept 00931 { 00932 if (lpGroup == NULL) 00933 { 00934 dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager, 00935 dwServiceType, 00936 dwServiceState, 00937 (LPBYTE)lpStatusPtr, 00938 dwBufferSize, 00939 pcbBytesNeeded, 00940 lpServicesReturned, 00941 lpResumeHandle); 00942 } 00943 else 00944 { 00945 dwError = REnumServiceGroupW((SC_RPC_HANDLE)hSCManager, 00946 dwServiceType, 00947 dwServiceState, 00948 (LPBYTE)lpStatusPtr, 00949 dwBufferSize, 00950 pcbBytesNeeded, 00951 lpServicesReturned, 00952 lpResumeHandle, 00953 lpGroup); 00954 } 00955 } 00956 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00957 { 00958 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00959 } 00960 RpcEndExcept; 00961 00962 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 00963 { 00964 if (*lpServicesReturned > 0) 00965 { 00966 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 00967 { 00968 if (lpStatusPtr->lpServiceName) 00969 lpStatusPtr->lpServiceName = 00970 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 00971 00972 if (lpStatusPtr->lpDisplayName) 00973 lpStatusPtr->lpDisplayName = 00974 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 00975 00976 lpStatusPtr++; 00977 } 00978 } 00979 } 00980 00981 if (dwError != ERROR_SUCCESS) 00982 { 00983 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError); 00984 SetLastError(dwError); 00985 return FALSE; 00986 } 00987 00988 TRACE("EnumServiceGroupW() done\n"); 00989 00990 return TRUE; 00991 } 00992 00993 00994 /********************************************************************** 00995 * EnumServicesStatusA 00996 * 00997 * @implemented 00998 */ 00999 BOOL WINAPI 01000 EnumServicesStatusA(SC_HANDLE hSCManager, 01001 DWORD dwServiceType, 01002 DWORD dwServiceState, 01003 LPENUM_SERVICE_STATUSA lpServices, 01004 DWORD cbBufSize, 01005 LPDWORD pcbBytesNeeded, 01006 LPDWORD lpServicesReturned, 01007 LPDWORD lpResumeHandle) 01008 { 01009 ENUM_SERVICE_STATUSA ServiceStatus; 01010 LPENUM_SERVICE_STATUSA lpStatusPtr; 01011 DWORD dwBufferSize; 01012 DWORD dwError; 01013 DWORD dwCount; 01014 01015 TRACE("EnumServicesStatusA() called\n"); 01016 01017 if (!hSCManager) 01018 { 01019 SetLastError(ERROR_INVALID_HANDLE); 01020 return FALSE; 01021 } 01022 01023 if (dwServiceType != SERVICE_DRIVER && dwServiceType != SERVICE_WIN32) 01024 { 01025 if (pcbBytesNeeded && lpServicesReturned) 01026 { 01027 *pcbBytesNeeded = 0; 01028 *lpServicesReturned = 0; 01029 } 01030 01031 SetLastError(ERROR_INVALID_PARAMETER); 01032 return FALSE; 01033 } 01034 01035 if (dwServiceState != SERVICE_ACTIVE && dwServiceState != SERVICE_INACTIVE && dwServiceState != SERVICE_STATE_ALL) 01036 { 01037 if (pcbBytesNeeded) 01038 *pcbBytesNeeded = 0; 01039 01040 if (lpServicesReturned) 01041 *lpServicesReturned = 0; 01042 01043 SetLastError(ERROR_INVALID_PARAMETER); 01044 return FALSE; 01045 } 01046 01047 if (!pcbBytesNeeded || !lpServicesReturned) 01048 { 01049 SetLastError(ERROR_INVALID_ADDRESS); 01050 return FALSE; 01051 } 01052 01053 if (!lpServices && cbBufSize != 0) 01054 { 01055 SetLastError(ERROR_INVALID_ADDRESS); 01056 return FALSE; 01057 } 01058 01059 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) 01060 { 01061 lpStatusPtr = &ServiceStatus; 01062 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); 01063 } 01064 else 01065 { 01066 lpStatusPtr = lpServices; 01067 dwBufferSize = cbBufSize; 01068 } 01069 01070 RpcTryExcept 01071 { 01072 dwError = REnumServicesStatusA((SC_RPC_HANDLE)hSCManager, 01073 dwServiceType, 01074 dwServiceState, 01075 (LPBYTE)lpStatusPtr, 01076 dwBufferSize, 01077 pcbBytesNeeded, 01078 lpServicesReturned, 01079 lpResumeHandle); 01080 } 01081 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01082 { 01083 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01084 } 01085 RpcEndExcept; 01086 01087 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 01088 { 01089 if (*lpServicesReturned > 0) 01090 { 01091 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 01092 { 01093 if (lpStatusPtr->lpServiceName) 01094 lpStatusPtr->lpServiceName = 01095 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 01096 01097 if (lpStatusPtr->lpDisplayName) 01098 lpStatusPtr->lpDisplayName = 01099 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 01100 01101 lpStatusPtr++; 01102 } 01103 } 01104 } 01105 01106 if (dwError != ERROR_SUCCESS) 01107 { 01108 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError); 01109 SetLastError(dwError); 01110 return FALSE; 01111 } 01112 01113 TRACE("EnumServicesStatusA() done\n"); 01114 01115 return TRUE; 01116 } 01117 01118 01119 /********************************************************************** 01120 * EnumServicesStatusW 01121 * 01122 * @implemented 01123 */ 01124 BOOL WINAPI 01125 EnumServicesStatusW(SC_HANDLE hSCManager, 01126 DWORD dwServiceType, 01127 DWORD dwServiceState, 01128 LPENUM_SERVICE_STATUSW lpServices, 01129 DWORD cbBufSize, 01130 LPDWORD pcbBytesNeeded, 01131 LPDWORD lpServicesReturned, 01132 LPDWORD lpResumeHandle) 01133 { 01134 ENUM_SERVICE_STATUSW ServiceStatus; 01135 LPENUM_SERVICE_STATUSW lpStatusPtr; 01136 DWORD dwBufferSize; 01137 DWORD dwError; 01138 DWORD dwCount; 01139 01140 TRACE("EnumServicesStatusW() called\n"); 01141 01142 if (!hSCManager) 01143 { 01144 SetLastError(ERROR_INVALID_HANDLE); 01145 return FALSE; 01146 } 01147 01148 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW)) 01149 { 01150 lpStatusPtr = &ServiceStatus; 01151 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW); 01152 } 01153 else 01154 { 01155 lpStatusPtr = lpServices; 01156 dwBufferSize = cbBufSize; 01157 } 01158 01159 RpcTryExcept 01160 { 01161 dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager, 01162 dwServiceType, 01163 dwServiceState, 01164 (LPBYTE)lpStatusPtr, 01165 dwBufferSize, 01166 pcbBytesNeeded, 01167 lpServicesReturned, 01168 lpResumeHandle); 01169 } 01170 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01171 { 01172 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01173 } 01174 RpcEndExcept; 01175 01176 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 01177 { 01178 if (*lpServicesReturned > 0) 01179 { 01180 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 01181 { 01182 if (lpStatusPtr->lpServiceName) 01183 lpStatusPtr->lpServiceName = 01184 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 01185 01186 if (lpStatusPtr->lpDisplayName) 01187 lpStatusPtr->lpDisplayName = 01188 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 01189 01190 lpStatusPtr++; 01191 } 01192 } 01193 } 01194 01195 if (dwError != ERROR_SUCCESS) 01196 { 01197 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError); 01198 SetLastError(dwError); 01199 return FALSE; 01200 } 01201 01202 TRACE("EnumServicesStatusW() done\n"); 01203 01204 return TRUE; 01205 } 01206 01207 01208 /********************************************************************** 01209 * EnumServicesStatusExA 01210 * 01211 * @implemented 01212 */ 01213 BOOL WINAPI 01214 EnumServicesStatusExA(SC_HANDLE hSCManager, 01215 SC_ENUM_TYPE InfoLevel, 01216 DWORD dwServiceType, 01217 DWORD dwServiceState, 01218 LPBYTE lpServices, 01219 DWORD cbBufSize, 01220 LPDWORD pcbBytesNeeded, 01221 LPDWORD lpServicesReturned, 01222 LPDWORD lpResumeHandle, 01223 LPCSTR pszGroupName) 01224 { 01225 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus; 01226 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr; 01227 DWORD dwBufferSize; 01228 DWORD dwError; 01229 DWORD dwCount; 01230 01231 TRACE("EnumServicesStatusExA() called\n"); 01232 01233 if (InfoLevel != SC_ENUM_PROCESS_INFO) 01234 { 01235 SetLastError(ERROR_INVALID_LEVEL); 01236 return FALSE; 01237 } 01238 01239 if (!hSCManager) 01240 { 01241 SetLastError(ERROR_INVALID_HANDLE); 01242 return FALSE; 01243 } 01244 01245 if (lpServices == NULL || 01246 cbBufSize < sizeof(ENUM_SERVICE_STATUS_PROCESSA)) 01247 { 01248 lpStatusPtr = &ServiceStatus; 01249 dwBufferSize = sizeof(ENUM_SERVICE_STATUS_PROCESSA); 01250 } 01251 else 01252 { 01253 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices; 01254 dwBufferSize = cbBufSize; 01255 } 01256 01257 RpcTryExcept 01258 { 01259 dwError = REnumServicesStatusExA((SC_RPC_HANDLE)hSCManager, 01260 InfoLevel, 01261 dwServiceType, 01262 dwServiceState, 01263 (LPBYTE)lpStatusPtr, 01264 dwBufferSize, 01265 pcbBytesNeeded, 01266 lpServicesReturned, 01267 lpResumeHandle, 01268 (LPSTR)pszGroupName); 01269 } 01270 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01271 { 01272 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01273 } 01274 RpcEndExcept; 01275 01276 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 01277 { 01278 if (InfoLevel == SC_ENUM_PROCESS_INFO) 01279 { 01280 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 01281 { 01282 if (lpStatusPtr->lpServiceName) 01283 lpStatusPtr->lpServiceName = 01284 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 01285 01286 if (lpStatusPtr->lpDisplayName) 01287 lpStatusPtr->lpDisplayName = 01288 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 01289 01290 lpStatusPtr++; 01291 } 01292 } 01293 } 01294 01295 if (dwError != ERROR_SUCCESS) 01296 { 01297 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError); 01298 SetLastError(dwError); 01299 return FALSE; 01300 } 01301 01302 TRACE("EnumServicesStatusExA() done\n"); 01303 01304 return TRUE; 01305 } 01306 01307 01308 /********************************************************************** 01309 * EnumServicesStatusExW 01310 * 01311 * @implemented 01312 */ 01313 BOOL WINAPI 01314 EnumServicesStatusExW(SC_HANDLE hSCManager, 01315 SC_ENUM_TYPE InfoLevel, 01316 DWORD dwServiceType, 01317 DWORD dwServiceState, 01318 LPBYTE lpServices, 01319 DWORD cbBufSize, 01320 LPDWORD pcbBytesNeeded, 01321 LPDWORD lpServicesReturned, 01322 LPDWORD lpResumeHandle, 01323 LPCWSTR pszGroupName) 01324 { 01325 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus; 01326 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr; 01327 DWORD dwBufferSize; 01328 DWORD dwError; 01329 DWORD dwCount; 01330 01331 TRACE("EnumServicesStatusExW() called\n"); 01332 01333 if (InfoLevel != SC_ENUM_PROCESS_INFO) 01334 { 01335 SetLastError(ERROR_INVALID_LEVEL); 01336 return FALSE; 01337 } 01338 01339 if (lpServices == NULL || 01340 cbBufSize < sizeof(ENUM_SERVICE_STATUS_PROCESSW)) 01341 { 01342 lpStatusPtr = &ServiceStatus; 01343 dwBufferSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW); 01344 } 01345 else 01346 { 01347 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices; 01348 dwBufferSize = cbBufSize; 01349 } 01350 01351 RpcTryExcept 01352 { 01353 dwError = REnumServicesStatusExW((SC_RPC_HANDLE)hSCManager, 01354 InfoLevel, 01355 dwServiceType, 01356 dwServiceState, 01357 (LPBYTE)lpStatusPtr, 01358 dwBufferSize, 01359 pcbBytesNeeded, 01360 lpServicesReturned, 01361 lpResumeHandle, 01362 (LPWSTR)pszGroupName); 01363 } 01364 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01365 { 01366 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01367 } 01368 RpcEndExcept; 01369 01370 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA) 01371 { 01372 if (InfoLevel == SC_ENUM_PROCESS_INFO) 01373 { 01374 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) 01375 { 01376 if (lpStatusPtr->lpServiceName) 01377 lpStatusPtr->lpServiceName = 01378 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); 01379 01380 if (lpStatusPtr->lpDisplayName) 01381 lpStatusPtr->lpDisplayName = 01382 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); 01383 01384 lpStatusPtr++; 01385 } 01386 } 01387 } 01388 01389 if (dwError != ERROR_SUCCESS) 01390 { 01391 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError); 01392 SetLastError(dwError); 01393 return FALSE; 01394 } 01395 01396 TRACE("EnumServicesStatusExW() done\n"); 01397 01398 return TRUE; 01399 } 01400 01401 01402 /********************************************************************** 01403 * GetServiceDisplayNameA 01404 * 01405 * @implemented 01406 */ 01407 BOOL WINAPI 01408 GetServiceDisplayNameA(SC_HANDLE hSCManager, 01409 LPCSTR lpServiceName, 01410 LPSTR lpDisplayName, 01411 LPDWORD lpcchBuffer) 01412 { 01413 DWORD dwError; 01414 LPSTR lpNameBuffer; 01415 CHAR szEmptyName[] = ""; 01416 01417 TRACE("GetServiceDisplayNameA() called\n"); 01418 TRACE("%p %s %p %p\n", hSCManager, 01419 debugstr_a(lpServiceName), lpDisplayName, lpcchBuffer); 01420 01421 if (!hSCManager) 01422 { 01423 SetLastError(ERROR_INVALID_HANDLE); 01424 return FALSE; 01425 } 01426 01427 if (!lpDisplayName || *lpcchBuffer < sizeof(CHAR)) 01428 { 01429 lpNameBuffer = szEmptyName; 01430 *lpcchBuffer = sizeof(CHAR); 01431 } 01432 else 01433 { 01434 lpNameBuffer = lpDisplayName; 01435 } 01436 01437 RpcTryExcept 01438 { 01439 dwError = RGetServiceDisplayNameA((SC_RPC_HANDLE)hSCManager, 01440 lpServiceName, 01441 lpNameBuffer, 01442 lpcchBuffer); 01443 } 01444 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01445 { 01446 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */ 01447 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01448 } 01449 RpcEndExcept; 01450 01451 if (dwError != ERROR_SUCCESS) 01452 { 01453 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError); 01454 SetLastError(dwError); 01455 return FALSE; 01456 } 01457 01458 return TRUE; 01459 } 01460 01461 01462 /********************************************************************** 01463 * GetServiceDisplayNameW 01464 * 01465 * @implemented 01466 */ 01467 BOOL WINAPI 01468 GetServiceDisplayNameW(SC_HANDLE hSCManager, 01469 LPCWSTR lpServiceName, 01470 LPWSTR lpDisplayName, 01471 LPDWORD lpcchBuffer) 01472 { 01473 DWORD dwError; 01474 LPWSTR lpNameBuffer; 01475 WCHAR szEmptyName[] = L""; 01476 01477 TRACE("GetServiceDisplayNameW() called\n"); 01478 01479 if (!hSCManager) 01480 { 01481 SetLastError(ERROR_INVALID_HANDLE); 01482 return FALSE; 01483 } 01484 01485 if (!lpDisplayName || *lpcchBuffer < sizeof(WCHAR)) 01486 { 01487 lpNameBuffer = szEmptyName; 01488 *lpcchBuffer = sizeof(WCHAR); 01489 } 01490 else 01491 { 01492 lpNameBuffer = lpDisplayName; 01493 } 01494 01495 RpcTryExcept 01496 { 01497 dwError = RGetServiceDisplayNameW((SC_RPC_HANDLE)hSCManager, 01498 lpServiceName, 01499 lpNameBuffer, 01500 lpcchBuffer); 01501 } 01502 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01503 { 01504 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01505 } 01506 RpcEndExcept; 01507 01508 if (dwError != ERROR_SUCCESS) 01509 { 01510 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError); 01511 SetLastError(dwError); 01512 return FALSE; 01513 } 01514 01515 return TRUE; 01516 } 01517 01518 01519 /********************************************************************** 01520 * GetServiceKeyNameA 01521 * 01522 * @implemented 01523 */ 01524 BOOL WINAPI 01525 GetServiceKeyNameA(SC_HANDLE hSCManager, 01526 LPCSTR lpDisplayName, 01527 LPSTR lpServiceName, 01528 LPDWORD lpcchBuffer) 01529 { 01530 DWORD dwError; 01531 LPSTR lpNameBuffer; 01532 CHAR szEmptyName[] = ""; 01533 01534 TRACE("GetServiceKeyNameA() called\n"); 01535 01536 if (!hSCManager) 01537 { 01538 SetLastError(ERROR_INVALID_HANDLE); 01539 return FALSE; 01540 } 01541 01542 if (!lpServiceName || *lpcchBuffer < sizeof(CHAR)) 01543 { 01544 lpNameBuffer = szEmptyName; 01545 *lpcchBuffer = sizeof(CHAR); 01546 } 01547 else 01548 { 01549 lpNameBuffer = lpServiceName; 01550 } 01551 01552 RpcTryExcept 01553 { 01554 dwError = RGetServiceKeyNameA((SC_RPC_HANDLE)hSCManager, 01555 lpDisplayName, 01556 lpNameBuffer, 01557 lpcchBuffer); 01558 } 01559 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01560 { 01561 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01562 } 01563 RpcEndExcept; 01564 01565 if (dwError != ERROR_SUCCESS) 01566 { 01567 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError); 01568 SetLastError(dwError); 01569 return FALSE; 01570 } 01571 01572 return TRUE; 01573 } 01574 01575 01576 /********************************************************************** 01577 * GetServiceKeyNameW 01578 * 01579 * @implemented 01580 */ 01581 BOOL WINAPI 01582 GetServiceKeyNameW(SC_HANDLE hSCManager, 01583 LPCWSTR lpDisplayName, 01584 LPWSTR lpServiceName, 01585 LPDWORD lpcchBuffer) 01586 { 01587 DWORD dwError; 01588 LPWSTR lpNameBuffer; 01589 WCHAR szEmptyName[] = L""; 01590 01591 TRACE("GetServiceKeyNameW() called\n"); 01592 01593 if (!hSCManager) 01594 { 01595 SetLastError(ERROR_INVALID_HANDLE); 01596 return FALSE; 01597 } 01598 01599 if (!lpServiceName || *lpcchBuffer < sizeof(WCHAR)) 01600 { 01601 lpNameBuffer = szEmptyName; 01602 *lpcchBuffer = sizeof(WCHAR); 01603 } 01604 else 01605 { 01606 lpNameBuffer = lpServiceName; 01607 } 01608 01609 RpcTryExcept 01610 { 01611 dwError = RGetServiceKeyNameW((SC_RPC_HANDLE)hSCManager, 01612 lpDisplayName, 01613 lpNameBuffer, 01614 lpcchBuffer); 01615 } 01616 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01617 { 01618 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01619 } 01620 RpcEndExcept; 01621 01622 if (dwError != ERROR_SUCCESS) 01623 { 01624 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError); 01625 SetLastError(dwError); 01626 return FALSE; 01627 } 01628 01629 return TRUE; 01630 } 01631 01632 01633 /********************************************************************** 01634 * LockServiceDatabase 01635 * 01636 * @implemented 01637 */ 01638 SC_LOCK WINAPI 01639 LockServiceDatabase(SC_HANDLE hSCManager) 01640 { 01641 SC_LOCK hLock; 01642 DWORD dwError; 01643 01644 TRACE("LockServiceDatabase(%x)\n", hSCManager); 01645 01646 RpcTryExcept 01647 { 01648 /* Call to services.exe using RPC */ 01649 dwError = RLockServiceDatabase((SC_RPC_HANDLE)hSCManager, 01650 (SC_RPC_LOCK *)&hLock); 01651 } 01652 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01653 { 01654 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01655 } 01656 RpcEndExcept; 01657 01658 if (dwError != ERROR_SUCCESS) 01659 { 01660 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError); 01661 SetLastError(dwError); 01662 return NULL; 01663 } 01664 01665 TRACE("hLock = %p\n", hLock); 01666 01667 return hLock; 01668 } 01669 01670 01671 static VOID 01672 WaitForSCManager(VOID) 01673 { 01674 HANDLE hEvent; 01675 01676 TRACE("WaitForSCManager() called\n"); 01677 01678 /* Try to open the existing event */ 01679 hEvent = OpenEventW(SYNCHRONIZE, 01680 FALSE, 01681 L"SvcctrlStartEvent_A3752DX"); 01682 if (hEvent == NULL) 01683 { 01684 if (GetLastError() != ERROR_FILE_NOT_FOUND) 01685 return; 01686 01687 /* Try to create a new event */ 01688 hEvent = CreateEventW(NULL, 01689 TRUE, 01690 FALSE, 01691 L"SvcctrlStartEvent_A3752DX"); 01692 if (hEvent == NULL) 01693 { 01694 /* Try to open the existing event again */ 01695 hEvent = OpenEventW(SYNCHRONIZE, 01696 FALSE, 01697 L"SvcctrlStartEvent_A3752DX"); 01698 if (hEvent == NULL) 01699 return; 01700 } 01701 } 01702 01703 /* Wait for 3 minutes */ 01704 WaitForSingleObject(hEvent, 180000); 01705 CloseHandle(hEvent); 01706 01707 TRACE("ScmWaitForSCManager() done\n"); 01708 } 01709 01710 01711 /********************************************************************** 01712 * OpenSCManagerA 01713 * 01714 * @implemented 01715 */ 01716 SC_HANDLE WINAPI 01717 OpenSCManagerA(LPCSTR lpMachineName, 01718 LPCSTR lpDatabaseName, 01719 DWORD dwDesiredAccess) 01720 { 01721 SC_HANDLE hScm = NULL; 01722 DWORD dwError; 01723 01724 TRACE("OpenSCManagerA(%s, %s, %lx)\n", 01725 lpMachineName, lpDatabaseName, dwDesiredAccess); 01726 01727 WaitForSCManager(); 01728 01729 RpcTryExcept 01730 { 01731 /* Call to services.exe using RPC */ 01732 dwError = ROpenSCManagerA((LPSTR)lpMachineName, 01733 (LPSTR)lpDatabaseName, 01734 dwDesiredAccess, 01735 (SC_RPC_HANDLE *)&hScm); 01736 } 01737 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01738 { 01739 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01740 } 01741 RpcEndExcept; 01742 01743 if (dwError != ERROR_SUCCESS) 01744 { 01745 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError); 01746 SetLastError(dwError); 01747 return NULL; 01748 } 01749 01750 TRACE("hScm = %p\n", hScm); 01751 01752 return hScm; 01753 } 01754 01755 01756 /********************************************************************** 01757 * OpenSCManagerW 01758 * 01759 * @implemented 01760 */ 01761 SC_HANDLE WINAPI 01762 OpenSCManagerW(LPCWSTR lpMachineName, 01763 LPCWSTR lpDatabaseName, 01764 DWORD dwDesiredAccess) 01765 { 01766 SC_HANDLE hScm = NULL; 01767 DWORD dwError; 01768 01769 TRACE("OpenSCManagerW(%S, %S, %lx)\n", 01770 lpMachineName, lpDatabaseName, dwDesiredAccess); 01771 01772 WaitForSCManager(); 01773 01774 RpcTryExcept 01775 { 01776 /* Call to services.exe using RPC */ 01777 dwError = ROpenSCManagerW((LPWSTR)lpMachineName, 01778 (LPWSTR)lpDatabaseName, 01779 dwDesiredAccess, 01780 (SC_RPC_HANDLE *)&hScm); 01781 } 01782 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01783 { 01784 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01785 } 01786 RpcEndExcept; 01787 01788 if (dwError != ERROR_SUCCESS) 01789 { 01790 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError); 01791 SetLastError(dwError); 01792 return NULL; 01793 } 01794 01795 TRACE("hScm = %p\n", hScm); 01796 01797 return hScm; 01798 } 01799 01800 01801 /********************************************************************** 01802 * OpenServiceA 01803 * 01804 * @implemented 01805 */ 01806 SC_HANDLE WINAPI 01807 OpenServiceA(SC_HANDLE hSCManager, 01808 LPCSTR lpServiceName, 01809 DWORD dwDesiredAccess) 01810 { 01811 SC_HANDLE hService = NULL; 01812 DWORD dwError; 01813 01814 TRACE("OpenServiceA(%p, %s, %lx)\n", 01815 hSCManager, lpServiceName, dwDesiredAccess); 01816 01817 if (!hSCManager) 01818 { 01819 SetLastError(ERROR_INVALID_HANDLE); 01820 return NULL; 01821 } 01822 01823 RpcTryExcept 01824 { 01825 /* Call to services.exe using RPC */ 01826 dwError = ROpenServiceA((SC_RPC_HANDLE)hSCManager, 01827 (LPSTR)lpServiceName, 01828 dwDesiredAccess, 01829 (SC_RPC_HANDLE *)&hService); 01830 } 01831 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01832 { 01833 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01834 } 01835 RpcEndExcept; 01836 01837 if (dwError != ERROR_SUCCESS) 01838 { 01839 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError); 01840 SetLastError(dwError); 01841 return NULL; 01842 } 01843 01844 TRACE("hService = %p\n", hService); 01845 01846 return hService; 01847 } 01848 01849 01850 /********************************************************************** 01851 * OpenServiceW 01852 * 01853 * @implemented 01854 */ 01855 SC_HANDLE WINAPI 01856 OpenServiceW(SC_HANDLE hSCManager, 01857 LPCWSTR lpServiceName, 01858 DWORD dwDesiredAccess) 01859 { 01860 SC_HANDLE hService = NULL; 01861 DWORD dwError; 01862 01863 TRACE("OpenServiceW(%p, %S, %lx)\n", 01864 hSCManager, lpServiceName, dwDesiredAccess); 01865 01866 if (!hSCManager) 01867 { 01868 SetLastError(ERROR_INVALID_HANDLE); 01869 return NULL; 01870 } 01871 01872 RpcTryExcept 01873 { 01874 /* Call to services.exe using RPC */ 01875 dwError = ROpenServiceW((SC_RPC_HANDLE)hSCManager, 01876 (LPWSTR)lpServiceName, 01877 dwDesiredAccess, 01878 (SC_RPC_HANDLE *)&hService); 01879 } 01880 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01881 { 01882 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01883 } 01884 RpcEndExcept; 01885 01886 if (dwError != ERROR_SUCCESS) 01887 { 01888 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError); 01889 SetLastError(dwError); 01890 return NULL; 01891 } 01892 01893 TRACE("hService = %p\n", hService); 01894 01895 return hService; 01896 } 01897 01898 01899 /********************************************************************** 01900 * QueryServiceConfigA 01901 * 01902 * @implemented 01903 */ 01904 BOOL WINAPI 01905 QueryServiceConfigA(SC_HANDLE hService, 01906 LPQUERY_SERVICE_CONFIGA lpServiceConfig, 01907 DWORD cbBufSize, 01908 LPDWORD pcbBytesNeeded) 01909 { 01910 QUERY_SERVICE_CONFIGA ServiceConfig; 01911 LPQUERY_SERVICE_CONFIGA lpConfigPtr; 01912 DWORD dwBufferSize; 01913 DWORD dwError; 01914 01915 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n", 01916 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded); 01917 01918 if (lpServiceConfig == NULL || 01919 cbBufSize < sizeof(QUERY_SERVICE_CONFIGA)) 01920 { 01921 lpConfigPtr = &ServiceConfig; 01922 dwBufferSize = sizeof(QUERY_SERVICE_CONFIGA); 01923 } 01924 else 01925 { 01926 lpConfigPtr = lpServiceConfig; 01927 dwBufferSize = cbBufSize; 01928 } 01929 01930 RpcTryExcept 01931 { 01932 /* Call to services.exe using RPC */ 01933 dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService, 01934 (LPBYTE)lpConfigPtr, 01935 dwBufferSize, 01936 pcbBytesNeeded); 01937 } 01938 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 01939 { 01940 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 01941 } 01942 RpcEndExcept; 01943 01944 if (dwError != ERROR_SUCCESS) 01945 { 01946 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError); 01947 SetLastError(dwError); 01948 return FALSE; 01949 } 01950 01951 /* Adjust the pointers */ 01952 if (lpConfigPtr->lpBinaryPathName) 01953 lpConfigPtr->lpBinaryPathName = 01954 (LPSTR)((ULONG_PTR)lpConfigPtr + 01955 (ULONG_PTR)lpConfigPtr->lpBinaryPathName); 01956 01957 if (lpConfigPtr->lpLoadOrderGroup) 01958 lpConfigPtr->lpLoadOrderGroup = 01959 (LPSTR)((ULONG_PTR)lpConfigPtr + 01960 (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup); 01961 01962 if (lpConfigPtr->lpDependencies) 01963 lpConfigPtr->lpDependencies = 01964 (LPSTR)((ULONG_PTR)lpConfigPtr + 01965 (ULONG_PTR)lpConfigPtr->lpDependencies); 01966 01967 if (lpConfigPtr->lpServiceStartName) 01968 lpConfigPtr->lpServiceStartName = 01969 (LPSTR)((ULONG_PTR)lpConfigPtr + 01970 (ULONG_PTR)lpConfigPtr->lpServiceStartName); 01971 01972 if (lpConfigPtr->lpDisplayName) 01973 lpConfigPtr->lpDisplayName = 01974 (LPSTR)((ULONG_PTR)lpConfigPtr + 01975 (ULONG_PTR)lpConfigPtr->lpDisplayName); 01976 01977 TRACE("QueryServiceConfigA() done\n"); 01978 01979 return TRUE; 01980 } 01981 01982 01983 /********************************************************************** 01984 * QueryServiceConfigW 01985 * 01986 * @implemented 01987 */ 01988 BOOL WINAPI 01989 QueryServiceConfigW(SC_HANDLE hService, 01990 LPQUERY_SERVICE_CONFIGW lpServiceConfig, 01991 DWORD cbBufSize, 01992 LPDWORD pcbBytesNeeded) 01993 { 01994 QUERY_SERVICE_CONFIGW ServiceConfig; 01995 LPQUERY_SERVICE_CONFIGW lpConfigPtr; 01996 DWORD dwBufferSize; 01997 DWORD dwError; 01998 01999 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n", 02000 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded); 02001 02002 if (lpServiceConfig == NULL || 02003 cbBufSize < sizeof(QUERY_SERVICE_CONFIGW)) 02004 { 02005 lpConfigPtr = &ServiceConfig; 02006 dwBufferSize = sizeof(QUERY_SERVICE_CONFIGW); 02007 } 02008 else 02009 { 02010 lpConfigPtr = lpServiceConfig; 02011 dwBufferSize = cbBufSize; 02012 } 02013 02014 RpcTryExcept 02015 { 02016 /* Call to services.exe using RPC */ 02017 dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService, 02018 (LPBYTE)lpConfigPtr, 02019 dwBufferSize, 02020 pcbBytesNeeded); 02021 } 02022 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02023 { 02024 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02025 } 02026 RpcEndExcept; 02027 02028 if (dwError != ERROR_SUCCESS) 02029 { 02030 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError); 02031 SetLastError(dwError); 02032 return FALSE; 02033 } 02034 02035 /* Adjust the pointers */ 02036 if (lpConfigPtr->lpBinaryPathName) 02037 lpConfigPtr->lpBinaryPathName = 02038 (LPWSTR)((ULONG_PTR)lpConfigPtr + 02039 (ULONG_PTR)lpConfigPtr->lpBinaryPathName); 02040 02041 if (lpConfigPtr->lpLoadOrderGroup) 02042 lpConfigPtr->lpLoadOrderGroup = 02043 (LPWSTR)((ULONG_PTR)lpConfigPtr + 02044 (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup); 02045 02046 if (lpConfigPtr->lpDependencies) 02047 lpConfigPtr->lpDependencies = 02048 (LPWSTR)((ULONG_PTR)lpConfigPtr + 02049 (ULONG_PTR)lpConfigPtr->lpDependencies); 02050 02051 if (lpConfigPtr->lpServiceStartName) 02052 lpConfigPtr->lpServiceStartName = 02053 (LPWSTR)((ULONG_PTR)lpConfigPtr + 02054 (ULONG_PTR)lpConfigPtr->lpServiceStartName); 02055 02056 if (lpConfigPtr->lpDisplayName) 02057 lpConfigPtr->lpDisplayName = 02058 (LPWSTR)((ULONG_PTR)lpConfigPtr + 02059 (ULONG_PTR)lpConfigPtr->lpDisplayName); 02060 02061 TRACE("QueryServiceConfigW() done\n"); 02062 02063 return TRUE; 02064 } 02065 02066 02067 /********************************************************************** 02068 * QueryServiceConfig2A 02069 * 02070 * @implemented 02071 */ 02072 BOOL WINAPI 02073 QueryServiceConfig2A(SC_HANDLE hService, 02074 DWORD dwInfoLevel, 02075 LPBYTE lpBuffer, 02076 DWORD cbBufSize, 02077 LPDWORD pcbBytesNeeded) 02078 { 02079 SERVICE_DESCRIPTIONA ServiceDescription; 02080 SERVICE_FAILURE_ACTIONSA ServiceFailureActions; 02081 LPBYTE lpTempBuffer; 02082 BOOL bUseTempBuffer = FALSE; 02083 DWORD dwBufferSize; 02084 DWORD dwError; 02085 02086 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n", 02087 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); 02088 02089 lpTempBuffer = lpBuffer; 02090 dwBufferSize = cbBufSize; 02091 02092 switch (dwInfoLevel) 02093 { 02094 case SERVICE_CONFIG_DESCRIPTION: 02095 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_DESCRIPTIONA))) 02096 { 02097 lpTempBuffer = (LPBYTE)&ServiceDescription; 02098 dwBufferSize = sizeof(SERVICE_DESCRIPTIONA); 02099 bUseTempBuffer = TRUE; 02100 } 02101 break; 02102 02103 case SERVICE_CONFIG_FAILURE_ACTIONS: 02104 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_FAILURE_ACTIONSA))) 02105 { 02106 lpTempBuffer = (LPBYTE)&ServiceFailureActions; 02107 dwBufferSize = sizeof(SERVICE_FAILURE_ACTIONSA); 02108 bUseTempBuffer = TRUE; 02109 } 02110 break; 02111 02112 default: 02113 WARN("Unknown info level 0x%lx\n", dwInfoLevel); 02114 SetLastError(ERROR_INVALID_LEVEL); 02115 return FALSE; 02116 } 02117 02118 RpcTryExcept 02119 { 02120 /* Call to services.exe using RPC */ 02121 dwError = RQueryServiceConfig2A((SC_RPC_HANDLE)hService, 02122 dwInfoLevel, 02123 lpTempBuffer, 02124 dwBufferSize, 02125 pcbBytesNeeded); 02126 } 02127 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02128 { 02129 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02130 } 02131 RpcEndExcept; 02132 02133 if (dwError != ERROR_SUCCESS) 02134 { 02135 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError); 02136 SetLastError(dwError); 02137 return FALSE; 02138 } 02139 02140 if (bUseTempBuffer == TRUE) 02141 { 02142 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n"); 02143 SetLastError(ERROR_INSUFFICIENT_BUFFER); 02144 return FALSE; 02145 } 02146 02147 switch (dwInfoLevel) 02148 { 02149 case SERVICE_CONFIG_DESCRIPTION: 02150 { 02151 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpTempBuffer; 02152 02153 if (lpPtr->lpDescription != NULL) 02154 lpPtr->lpDescription = 02155 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription); 02156 } 02157 break; 02158 02159 case SERVICE_CONFIG_FAILURE_ACTIONS: 02160 { 02161 LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpTempBuffer; 02162 02163 if (lpPtr->lpRebootMsg != NULL) 02164 lpPtr->lpRebootMsg = 02165 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg); 02166 02167 if (lpPtr->lpCommand != NULL) 02168 lpPtr->lpCommand = 02169 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand); 02170 02171 if (lpPtr->lpsaActions != NULL) 02172 lpPtr->lpsaActions = 02173 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions); 02174 } 02175 break; 02176 } 02177 02178 TRACE("QueryServiceConfig2A() done\n"); 02179 02180 return TRUE; 02181 } 02182 02183 02184 /********************************************************************** 02185 * QueryServiceConfig2W 02186 * 02187 * @implemented 02188 */ 02189 BOOL WINAPI 02190 QueryServiceConfig2W(SC_HANDLE hService, 02191 DWORD dwInfoLevel, 02192 LPBYTE lpBuffer, 02193 DWORD cbBufSize, 02194 LPDWORD pcbBytesNeeded) 02195 { 02196 SERVICE_DESCRIPTIONW ServiceDescription; 02197 SERVICE_FAILURE_ACTIONSW ServiceFailureActions; 02198 LPBYTE lpTempBuffer; 02199 BOOL bUseTempBuffer = FALSE; 02200 DWORD dwBufferSize; 02201 DWORD dwError; 02202 02203 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n", 02204 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); 02205 02206 lpTempBuffer = lpBuffer; 02207 dwBufferSize = cbBufSize; 02208 02209 switch (dwInfoLevel) 02210 { 02211 case SERVICE_CONFIG_DESCRIPTION: 02212 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_DESCRIPTIONW))) 02213 { 02214 lpTempBuffer = (LPBYTE)&ServiceDescription; 02215 dwBufferSize = sizeof(SERVICE_DESCRIPTIONW); 02216 bUseTempBuffer = TRUE; 02217 } 02218 break; 02219 02220 case SERVICE_CONFIG_FAILURE_ACTIONS: 02221 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_FAILURE_ACTIONSW))) 02222 { 02223 lpTempBuffer = (LPBYTE)&ServiceFailureActions; 02224 dwBufferSize = sizeof(SERVICE_FAILURE_ACTIONSW); 02225 bUseTempBuffer = TRUE; 02226 } 02227 break; 02228 02229 default: 02230 WARN("Unknown info level 0x%lx\n", dwInfoLevel); 02231 SetLastError(ERROR_INVALID_LEVEL); 02232 return FALSE; 02233 } 02234 02235 RpcTryExcept 02236 { 02237 /* Call to services.exe using RPC */ 02238 dwError = RQueryServiceConfig2W((SC_RPC_HANDLE)hService, 02239 dwInfoLevel, 02240 lpTempBuffer, 02241 dwBufferSize, 02242 pcbBytesNeeded); 02243 } 02244 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02245 { 02246 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02247 } 02248 RpcEndExcept; 02249 02250 if (dwError != ERROR_SUCCESS) 02251 { 02252 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError); 02253 SetLastError(dwError); 02254 return FALSE; 02255 } 02256 02257 if (bUseTempBuffer == TRUE) 02258 { 02259 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n"); 02260 SetLastError(ERROR_INSUFFICIENT_BUFFER); 02261 return FALSE; 02262 } 02263 02264 switch (dwInfoLevel) 02265 { 02266 case SERVICE_CONFIG_DESCRIPTION: 02267 { 02268 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpTempBuffer; 02269 02270 if (lpPtr->lpDescription != NULL) 02271 lpPtr->lpDescription = 02272 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription); 02273 } 02274 break; 02275 02276 case SERVICE_CONFIG_FAILURE_ACTIONS: 02277 { 02278 LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpTempBuffer; 02279 02280 if (lpPtr->lpRebootMsg != NULL) 02281 lpPtr->lpRebootMsg = 02282 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg); 02283 02284 if (lpPtr->lpCommand != NULL) 02285 lpPtr->lpCommand = 02286 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand); 02287 02288 if (lpPtr->lpsaActions != NULL) 02289 lpPtr->lpsaActions = 02290 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions); 02291 } 02292 break; 02293 } 02294 02295 TRACE("QueryServiceConfig2W() done\n"); 02296 02297 return TRUE; 02298 } 02299 02300 02301 /********************************************************************** 02302 * QueryServiceLockStatusA 02303 * 02304 * @implemented 02305 */ 02306 BOOL WINAPI 02307 QueryServiceLockStatusA(SC_HANDLE hSCManager, 02308 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, 02309 DWORD cbBufSize, 02310 LPDWORD pcbBytesNeeded) 02311 { 02312 QUERY_SERVICE_LOCK_STATUSA LockStatus; 02313 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr; 02314 DWORD dwBufferSize; 02315 DWORD dwError; 02316 02317 TRACE("QueryServiceLockStatusA() called\n"); 02318 02319 if (lpLockStatus == NULL || cbBufSize < sizeof(QUERY_SERVICE_LOCK_STATUSA)) 02320 { 02321 lpStatusPtr = &LockStatus; 02322 dwBufferSize = sizeof(QUERY_SERVICE_LOCK_STATUSA); 02323 } 02324 else 02325 { 02326 lpStatusPtr = lpLockStatus; 02327 dwBufferSize = cbBufSize; 02328 } 02329 02330 RpcTryExcept 02331 { 02332 /* Call to services.exe using RPC */ 02333 dwError = RQueryServiceLockStatusA((SC_RPC_HANDLE)hSCManager, 02334 lpStatusPtr, 02335 dwBufferSize, 02336 pcbBytesNeeded); 02337 } 02338 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02339 { 02340 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02341 } 02342 RpcEndExcept; 02343 02344 if (dwError != ERROR_SUCCESS) 02345 { 02346 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError); 02347 SetLastError(dwError); 02348 return FALSE; 02349 } 02350 02351 if (lpStatusPtr->lpLockOwner != NULL) 02352 { 02353 lpStatusPtr->lpLockOwner = 02354 (LPSTR)((UINT_PTR)lpStatusPtr + (UINT_PTR)lpStatusPtr->lpLockOwner); 02355 } 02356 02357 TRACE("QueryServiceLockStatusA() done\n"); 02358 02359 return TRUE; 02360 } 02361 02362 02363 /********************************************************************** 02364 * QueryServiceLockStatusW 02365 * 02366 * @implemented 02367 */ 02368 BOOL WINAPI 02369 QueryServiceLockStatusW(SC_HANDLE hSCManager, 02370 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, 02371 DWORD cbBufSize, 02372 LPDWORD pcbBytesNeeded) 02373 { 02374 QUERY_SERVICE_LOCK_STATUSW LockStatus; 02375 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr; 02376 DWORD dwBufferSize; 02377 DWORD dwError; 02378 02379 TRACE("QueryServiceLockStatusW() called\n"); 02380 02381 if (lpLockStatus == NULL || cbBufSize < sizeof(QUERY_SERVICE_LOCK_STATUSW)) 02382 { 02383 lpStatusPtr = &LockStatus; 02384 dwBufferSize = sizeof(QUERY_SERVICE_LOCK_STATUSW); 02385 } 02386 else 02387 { 02388 lpStatusPtr = lpLockStatus; 02389 dwBufferSize = cbBufSize; 02390 } 02391 02392 RpcTryExcept 02393 { 02394 /* Call to services.exe using RPC */ 02395 dwError = RQueryServiceLockStatusW((SC_RPC_HANDLE)hSCManager, 02396 lpStatusPtr, 02397 dwBufferSize, 02398 pcbBytesNeeded); 02399 } 02400 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02401 { 02402 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02403 } 02404 RpcEndExcept; 02405 02406 if (dwError != ERROR_SUCCESS) 02407 { 02408 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError); 02409 SetLastError(dwError); 02410 return FALSE; 02411 } 02412 02413 if (lpStatusPtr->lpLockOwner != NULL) 02414 { 02415 lpStatusPtr->lpLockOwner = 02416 (LPWSTR)((UINT_PTR)lpStatusPtr + (UINT_PTR)lpStatusPtr->lpLockOwner); 02417 } 02418 02419 TRACE("QueryServiceLockStatusW() done\n"); 02420 02421 return TRUE; 02422 } 02423 02424 02425 /********************************************************************** 02426 * QueryServiceObjectSecurity 02427 * 02428 * @implemented 02429 */ 02430 BOOL WINAPI 02431 QueryServiceObjectSecurity(SC_HANDLE hService, 02432 SECURITY_INFORMATION dwSecurityInformation, 02433 PSECURITY_DESCRIPTOR lpSecurityDescriptor, 02434 DWORD cbBufSize, 02435 LPDWORD pcbBytesNeeded) 02436 { 02437 DWORD dwError; 02438 02439 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n", 02440 hService, dwSecurityInformation, lpSecurityDescriptor); 02441 02442 RpcTryExcept 02443 { 02444 /* Call to services.exe using RPC */ 02445 dwError = RQueryServiceObjectSecurity((SC_RPC_HANDLE)hService, 02446 dwSecurityInformation, 02447 (LPBYTE)lpSecurityDescriptor, 02448 cbBufSize, 02449 pcbBytesNeeded); 02450 } 02451 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02452 { 02453 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02454 } 02455 RpcEndExcept; 02456 02457 if (dwError != ERROR_SUCCESS) 02458 { 02459 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError); 02460 SetLastError(dwError); 02461 return FALSE; 02462 } 02463 02464 return TRUE; 02465 } 02466 02467 /********************************************************************** 02468 * SetServiceObjectSecurity 02469 * 02470 * @implemented 02471 */ 02472 BOOL WINAPI 02473 SetServiceObjectSecurity(SC_HANDLE hService, 02474 SECURITY_INFORMATION dwSecurityInformation, 02475 PSECURITY_DESCRIPTOR lpSecurityDescriptor) 02476 { 02477 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL; 02478 ULONG Length; 02479 NTSTATUS Status; 02480 DWORD dwError; 02481 02482 Length = 0; 02483 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor, 02484 SelfRelativeSD, 02485 &Length); 02486 if (Status != STATUS_BUFFER_TOO_SMALL) 02487 { 02488 SetLastError(ERROR_INVALID_PARAMETER); 02489 return FALSE; 02490 } 02491 02492 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length); 02493 if (SelfRelativeSD == NULL) 02494 { 02495 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 02496 return FALSE; 02497 } 02498 02499 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor, 02500 SelfRelativeSD, 02501 &Length); 02502 if (!NT_SUCCESS(Status)) 02503 { 02504 HeapFree(GetProcessHeap(), 0, SelfRelativeSD); 02505 SetLastError(RtlNtStatusToDosError(Status)); 02506 return FALSE; 02507 } 02508 02509 RpcTryExcept 02510 { 02511 /* Call to services.exe using RPC */ 02512 dwError = RSetServiceObjectSecurity((SC_RPC_HANDLE)hService, 02513 dwSecurityInformation, 02514 (LPBYTE)SelfRelativeSD, 02515 Length); 02516 } 02517 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02518 { 02519 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02520 } 02521 RpcEndExcept; 02522 02523 HeapFree(GetProcessHeap(), 0, SelfRelativeSD); 02524 02525 if (dwError != ERROR_SUCCESS) 02526 { 02527 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError); 02528 SetLastError(dwError); 02529 return FALSE; 02530 } 02531 02532 return TRUE; 02533 } 02534 02535 02536 /********************************************************************** 02537 * QueryServiceStatus 02538 * 02539 * @implemented 02540 */ 02541 BOOL WINAPI 02542 QueryServiceStatus(SC_HANDLE hService, 02543 LPSERVICE_STATUS lpServiceStatus) 02544 { 02545 DWORD dwError; 02546 02547 TRACE("QueryServiceStatus(%p, %p)\n", 02548 hService, lpServiceStatus); 02549 02550 if (!hService) 02551 { 02552 SetLastError(ERROR_INVALID_HANDLE); 02553 return FALSE; 02554 } 02555 02556 RpcTryExcept 02557 { 02558 /* Call to services.exe using RPC */ 02559 dwError = RQueryServiceStatus((SC_RPC_HANDLE)hService, 02560 lpServiceStatus); 02561 } 02562 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02563 { 02564 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02565 } 02566 RpcEndExcept; 02567 02568 if (dwError != ERROR_SUCCESS) 02569 { 02570 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError); 02571 SetLastError(dwError); 02572 return FALSE; 02573 } 02574 02575 return TRUE; 02576 } 02577 02578 02579 /********************************************************************** 02580 * QueryServiceStatusEx 02581 * 02582 * @implemented 02583 */ 02584 BOOL WINAPI 02585 QueryServiceStatusEx(SC_HANDLE hService, 02586 SC_STATUS_TYPE InfoLevel, 02587 LPBYTE lpBuffer, 02588 DWORD cbBufSize, 02589 LPDWORD pcbBytesNeeded) 02590 { 02591 DWORD dwError; 02592 02593 TRACE("QueryServiceStatusEx() called\n"); 02594 02595 if (InfoLevel != SC_STATUS_PROCESS_INFO) 02596 { 02597 SetLastError(ERROR_INVALID_LEVEL); 02598 return FALSE; 02599 } 02600 02601 if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS)) 02602 { 02603 *pcbBytesNeeded = sizeof(SERVICE_STATUS_PROCESS); 02604 SetLastError(ERROR_INSUFFICIENT_BUFFER); 02605 return FALSE; 02606 } 02607 02608 RpcTryExcept 02609 { 02610 /* Call to services.exe using RPC */ 02611 dwError = RQueryServiceStatusEx((SC_RPC_HANDLE)hService, 02612 InfoLevel, 02613 lpBuffer, 02614 cbBufSize, 02615 pcbBytesNeeded); 02616 } 02617 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02618 { 02619 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02620 } 02621 RpcEndExcept; 02622 02623 if (dwError != ERROR_SUCCESS) 02624 { 02625 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError); 02626 SetLastError(dwError); 02627 return FALSE; 02628 } 02629 02630 return TRUE; 02631 } 02632 02633 02634 /********************************************************************** 02635 * StartServiceA 02636 * 02637 * @implemented 02638 */ 02639 BOOL WINAPI 02640 StartServiceA(SC_HANDLE hService, 02641 DWORD dwNumServiceArgs, 02642 LPCSTR *lpServiceArgVectors) 02643 { 02644 DWORD dwError; 02645 02646 RpcTryExcept 02647 { 02648 dwError = RStartServiceA((SC_RPC_HANDLE)hService, 02649 dwNumServiceArgs, 02650 (LPSTRING_PTRSA)lpServiceArgVectors); 02651 } 02652 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02653 { 02654 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02655 } 02656 RpcEndExcept; 02657 02658 if (dwError != ERROR_SUCCESS) 02659 { 02660 ERR("RStartServiceA() failed (Error %lu)\n", dwError); 02661 SetLastError(dwError); 02662 return FALSE; 02663 } 02664 02665 return TRUE; 02666 } 02667 02668 02669 /********************************************************************** 02670 * StartServiceW 02671 * 02672 * @implemented 02673 */ 02674 BOOL WINAPI 02675 StartServiceW(SC_HANDLE hService, 02676 DWORD dwNumServiceArgs, 02677 LPCWSTR *lpServiceArgVectors) 02678 { 02679 DWORD dwError; 02680 02681 RpcTryExcept 02682 { 02683 dwError = RStartServiceW((SC_RPC_HANDLE)hService, 02684 dwNumServiceArgs, 02685 (LPSTRING_PTRSW)lpServiceArgVectors); 02686 } 02687 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02688 { 02689 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02690 } 02691 RpcEndExcept; 02692 02693 if (dwError != ERROR_SUCCESS) 02694 { 02695 ERR("RStartServiceW() failed (Error %lu)\n", dwError); 02696 SetLastError(dwError); 02697 return FALSE; 02698 } 02699 02700 return TRUE; 02701 } 02702 02703 02704 /********************************************************************** 02705 * UnlockServiceDatabase 02706 * 02707 * @implemented 02708 */ 02709 BOOL WINAPI 02710 UnlockServiceDatabase(SC_LOCK ScLock) 02711 { 02712 DWORD dwError; 02713 02714 TRACE("UnlockServiceDatabase(%x)\n", ScLock); 02715 02716 RpcTryExcept 02717 { 02718 /* Call to services.exe using RPC */ 02719 dwError = RUnlockServiceDatabase((LPSC_RPC_LOCK)&ScLock); 02720 } 02721 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02722 { 02723 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02724 } 02725 RpcEndExcept; 02726 02727 if (dwError != ERROR_SUCCESS) 02728 { 02729 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError); 02730 SetLastError(dwError); 02731 return FALSE; 02732 } 02733 02734 return TRUE; 02735 } 02736 02737 02738 /********************************************************************** 02739 * NotifyBootConfigStatus 02740 * 02741 * @implemented 02742 */ 02743 BOOL WINAPI 02744 NotifyBootConfigStatus(BOOL BootAcceptable) 02745 { 02746 DWORD dwError; 02747 02748 TRACE("NotifyBootConfigStatus()\n"); 02749 02750 RpcTryExcept 02751 { 02752 /* Call to services.exe using RPC */ 02753 dwError = RNotifyBootConfigStatus(NULL, 02754 BootAcceptable); 02755 } 02756 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 02757 { 02758 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 02759 } 02760 RpcEndExcept; 02761 02762 if (dwError != ERROR_SUCCESS) 02763 { 02764 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError); 02765 SetLastError(dwError); 02766 return FALSE; 02767 } 02768 02769 return TRUE; 02770 } 02771 02772 /* EOF */ Generated on Mon May 28 2012 04:22:17 for ReactOS by
1.7.6.1
|