ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

scm.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.