Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensctrl.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS advapi32 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: dll/win32/advapi32/service/sctrl.c 00005 * PURPOSE: Service control manager functions 00006 * COPYRIGHT: Copyright 1999 Emanuele Aliberti 00007 * Copyright 2007 Ged Murphy <gedmurphy@reactos.org> 00008 * Gregor Brunmar <gregor.brunmar@home.se> 00009 * 00010 */ 00011 00012 00013 /* INCLUDES ******************************************************************/ 00014 00015 #include <advapi32.h> 00016 WINE_DEFAULT_DEBUG_CHANNEL(advapi); 00017 00018 00019 /* TYPES *********************************************************************/ 00020 00021 typedef struct _SERVICE_THREAD_PARAMSA 00022 { 00023 LPSERVICE_MAIN_FUNCTIONA lpServiceMain; 00024 DWORD dwArgCount; 00025 LPSTR *lpArgVector; 00026 } SERVICE_THREAD_PARAMSA, *PSERVICE_THREAD_PARAMSA; 00027 00028 00029 typedef struct _SERVICE_THREAD_PARAMSW 00030 { 00031 LPSERVICE_MAIN_FUNCTIONW lpServiceMain; 00032 DWORD dwArgCount; 00033 LPWSTR *lpArgVector; 00034 } SERVICE_THREAD_PARAMSW, *PSERVICE_THREAD_PARAMSW; 00035 00036 00037 typedef struct _ACTIVE_SERVICE 00038 { 00039 SERVICE_STATUS_HANDLE hServiceStatus; 00040 UNICODE_STRING ServiceName; 00041 union 00042 { 00043 SERVICE_THREAD_PARAMSA A; 00044 SERVICE_THREAD_PARAMSW W; 00045 } ThreadParams; 00046 LPHANDLER_FUNCTION HandlerFunction; 00047 LPHANDLER_FUNCTION_EX HandlerFunctionEx; 00048 LPVOID HandlerContext; 00049 BOOL bUnicode; 00050 } ACTIVE_SERVICE, *PACTIVE_SERVICE; 00051 00052 00053 /* GLOBALS *******************************************************************/ 00054 00055 static DWORD dwActiveServiceCount = 0; 00056 static PACTIVE_SERVICE lpActiveServices = NULL; 00057 static handle_t hStatusBinding = NULL; 00058 00059 00060 /* FUNCTIONS *****************************************************************/ 00061 00062 handle_t __RPC_USER 00063 RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus) 00064 { 00065 return hStatusBinding; 00066 } 00067 00068 00069 void __RPC_USER 00070 RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus, 00071 handle_t hBinding) 00072 { 00073 } 00074 00075 00076 static RPC_STATUS 00077 ScCreateStatusBinding(VOID) 00078 { 00079 LPWSTR pszStringBinding; 00080 RPC_STATUS status; 00081 00082 TRACE("ScCreateStatusBinding() called\n"); 00083 00084 status = RpcStringBindingComposeW(NULL, 00085 L"ncacn_np", 00086 NULL, 00087 L"\\pipe\\ntsvcs", 00088 NULL, 00089 &pszStringBinding); 00090 if (status != RPC_S_OK) 00091 { 00092 ERR("RpcStringBindingCompose returned 0x%x\n", status); 00093 return status; 00094 } 00095 00096 /* Set the binding handle that will be used to bind to the server. */ 00097 status = RpcBindingFromStringBindingW(pszStringBinding, 00098 &hStatusBinding); 00099 if (status != RPC_S_OK) 00100 { 00101 ERR("RpcBindingFromStringBinding returned 0x%x\n", status); 00102 } 00103 00104 status = RpcStringFreeW(&pszStringBinding); 00105 if (status != RPC_S_OK) 00106 { 00107 ERR("RpcStringFree returned 0x%x\n", status); 00108 } 00109 00110 return status; 00111 } 00112 00113 00114 static RPC_STATUS 00115 ScDestroyStatusBinding(VOID) 00116 { 00117 RPC_STATUS status; 00118 00119 TRACE("ScDestroyStatusBinding() called\n"); 00120 00121 if (hStatusBinding == NULL) 00122 return RPC_S_OK; 00123 00124 status = RpcBindingFree(&hStatusBinding); 00125 if (status != RPC_S_OK) 00126 { 00127 ERR("RpcBindingFree returned 0x%x\n", status); 00128 } 00129 else 00130 { 00131 hStatusBinding = NULL; 00132 } 00133 00134 return status; 00135 } 00136 00137 00138 static PACTIVE_SERVICE 00139 ScLookupServiceByServiceName(LPCWSTR lpServiceName) 00140 { 00141 DWORD i; 00142 00143 TRACE("ScLookupServiceByServiceName(%S) called\n", lpServiceName); 00144 00145 for (i = 0; i < dwActiveServiceCount; i++) 00146 { 00147 TRACE("Checking %S\n", lpActiveServices[i].ServiceName.Buffer); 00148 if (_wcsicmp(lpActiveServices[i].ServiceName.Buffer, lpServiceName) == 0) 00149 { 00150 TRACE("Found!\n"); 00151 return &lpActiveServices[i]; 00152 } 00153 } 00154 00155 TRACE("No service found!\n"); 00156 00157 SetLastError(ERROR_SERVICE_DOES_NOT_EXIST); 00158 00159 return NULL; 00160 } 00161 00162 00163 static DWORD WINAPI 00164 ScServiceMainStub(LPVOID Context) 00165 { 00166 PACTIVE_SERVICE lpService = (PACTIVE_SERVICE)Context; 00167 00168 TRACE("ScServiceMainStub() called\n"); 00169 00170 /* Call the main service routine and free the arguments vector */ 00171 if (lpService->bUnicode) 00172 { 00173 (lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount, 00174 lpService->ThreadParams.W.lpArgVector); 00175 00176 if (lpService->ThreadParams.A.lpArgVector != NULL) 00177 { 00178 HeapFree(GetProcessHeap(), 00179 0, 00180 lpService->ThreadParams.W.lpArgVector); 00181 00182 lpService->ThreadParams.W.lpArgVector = NULL; 00183 lpService->ThreadParams.W.dwArgCount = 0; 00184 } 00185 } 00186 else 00187 { 00188 (lpService->ThreadParams.A.lpServiceMain)(lpService->ThreadParams.A.dwArgCount, 00189 lpService->ThreadParams.A.lpArgVector); 00190 00191 if (lpService->ThreadParams.A.lpArgVector != NULL) 00192 { 00193 HeapFree(GetProcessHeap(), 00194 0, 00195 lpService->ThreadParams.A.lpArgVector); 00196 00197 lpService->ThreadParams.A.lpArgVector = NULL; 00198 lpService->ThreadParams.A.dwArgCount = 0; 00199 } 00200 } 00201 00202 return ERROR_SUCCESS; 00203 } 00204 00205 00206 static DWORD 00207 ScConnectControlPipe(HANDLE *hPipe) 00208 { 00209 DWORD dwBytesWritten; 00210 DWORD dwState; 00211 DWORD dwServiceCurrent = 0; 00212 NTSTATUS Status; 00213 WCHAR NtControlPipeName[MAX_PATH + 1]; 00214 RTL_QUERY_REGISTRY_TABLE QueryTable[2]; 00215 DWORD dwProcessId; 00216 00217 /* Get the service number and create the named pipe */ 00218 RtlZeroMemory(&QueryTable, 00219 sizeof(QueryTable)); 00220 00221 QueryTable[0].Name = L""; 00222 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; 00223 QueryTable[0].EntryContext = &dwServiceCurrent; 00224 00225 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, 00226 L"ServiceCurrent", 00227 QueryTable, 00228 NULL, 00229 NULL); 00230 00231 if (!NT_SUCCESS(Status)) 00232 { 00233 ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status); 00234 return RtlNtStatusToDosError(Status); 00235 } 00236 00237 swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", dwServiceCurrent); 00238 00239 if (!WaitNamedPipeW(NtControlPipeName, 15000)) 00240 { 00241 ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, GetLastError()); 00242 return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT; 00243 } 00244 00245 *hPipe = CreateFileW(NtControlPipeName, 00246 GENERIC_READ | GENERIC_WRITE, 00247 0, 00248 NULL, 00249 OPEN_EXISTING, 00250 FILE_ATTRIBUTE_NORMAL, 00251 NULL); 00252 if (*hPipe == INVALID_HANDLE_VALUE) 00253 { 00254 ERR("CreateFileW() failed for pipe %S (Error %lu)\n", NtControlPipeName, GetLastError()); 00255 return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT; 00256 } 00257 00258 dwState = PIPE_READMODE_MESSAGE; 00259 if (!SetNamedPipeHandleState(*hPipe, &dwState, NULL, NULL)) 00260 { 00261 CloseHandle(*hPipe); 00262 *hPipe = INVALID_HANDLE_VALUE; 00263 return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT; 00264 } 00265 00266 /* Pass the ProcessId to the SCM */ 00267 dwProcessId = GetCurrentProcessId(); 00268 WriteFile(*hPipe, 00269 &dwProcessId, 00270 sizeof(DWORD), 00271 &dwBytesWritten, 00272 NULL); 00273 00274 TRACE("Sent Process ID %lu\n", dwProcessId); 00275 00276 return ERROR_SUCCESS; 00277 } 00278 00279 00280 static DWORD 00281 ScBuildUnicodeArgsVector(PSCM_CONTROL_PACKET ControlPacket, 00282 LPDWORD lpArgCount, 00283 LPWSTR **lpArgVector) 00284 { 00285 LPWSTR *lpVector; 00286 LPWSTR *lpArg; 00287 DWORD i; 00288 00289 *lpArgCount = 0; 00290 *lpArgVector = NULL; 00291 00292 if (ControlPacket->dwArgumentsCount > 0) 00293 { 00294 lpVector = HeapAlloc(GetProcessHeap(), 00295 HEAP_ZERO_MEMORY, 00296 ControlPacket->dwSize - ControlPacket->dwArgumentsOffset); 00297 if (lpVector == NULL) 00298 return ERROR_OUTOFMEMORY; 00299 00300 memcpy(lpVector, 00301 ((PBYTE)ControlPacket + ControlPacket->dwArgumentsOffset), 00302 ControlPacket->dwSize - ControlPacket->dwArgumentsOffset); 00303 00304 lpArg = lpVector; 00305 for (i = 0; i < ControlPacket->dwArgumentsCount; i++) 00306 { 00307 *lpArg = (LPWSTR)((ULONG_PTR)lpArg + (ULONG_PTR)*lpArg); 00308 lpArg++; 00309 } 00310 00311 *lpArgCount = ControlPacket->dwArgumentsCount; 00312 *lpArgVector = lpVector; 00313 } 00314 00315 return ERROR_SUCCESS; 00316 } 00317 00318 00319 static DWORD 00320 ScBuildAnsiArgsVector(PSCM_CONTROL_PACKET ControlPacket, 00321 LPDWORD lpArgCount, 00322 LPSTR **lpArgVector) 00323 { 00324 LPSTR *lpVector; 00325 LPSTR *lpPtr; 00326 LPWSTR lpUnicodeString; 00327 LPSTR lpAnsiString; 00328 DWORD dwVectorSize; 00329 DWORD dwUnicodeSize; 00330 DWORD dwAnsiSize; 00331 DWORD i; 00332 00333 *lpArgCount = 0; 00334 *lpArgVector = NULL; 00335 00336 if (ControlPacket->dwArgumentsCount > 0) 00337 { 00338 dwVectorSize = ControlPacket->dwArgumentsCount * sizeof(LPWSTR); 00339 00340 lpUnicodeString = (LPWSTR)((PBYTE)ControlPacket + 00341 ControlPacket->dwArgumentsOffset + 00342 dwVectorSize); 00343 dwUnicodeSize = (ControlPacket->dwSize - 00344 ControlPacket->dwArgumentsOffset - 00345 dwVectorSize) / sizeof(WCHAR); 00346 00347 dwAnsiSize = WideCharToMultiByte(CP_ACP, 00348 0, 00349 lpUnicodeString, 00350 dwUnicodeSize, 00351 NULL, 00352 0, 00353 NULL, 00354 NULL); 00355 00356 lpVector = HeapAlloc(GetProcessHeap(), 00357 HEAP_ZERO_MEMORY, 00358 dwVectorSize + dwAnsiSize); 00359 if (lpVector == NULL) 00360 return ERROR_OUTOFMEMORY; 00361 00362 lpPtr = (LPSTR*)lpVector; 00363 lpAnsiString = (LPSTR)((ULONG_PTR)lpVector + dwVectorSize); 00364 00365 WideCharToMultiByte(CP_ACP, 00366 0, 00367 lpUnicodeString, 00368 dwUnicodeSize, 00369 lpAnsiString, 00370 dwAnsiSize, 00371 NULL, 00372 NULL); 00373 00374 for (i = 0; i < ControlPacket->dwArgumentsCount; i++) 00375 { 00376 *lpPtr = lpAnsiString; 00377 00378 lpPtr++; 00379 lpAnsiString += (strlen(lpAnsiString) + 1); 00380 } 00381 00382 *lpArgCount = ControlPacket->dwArgumentsCount; 00383 *lpArgVector = lpVector; 00384 } 00385 00386 return ERROR_SUCCESS; 00387 } 00388 00389 00390 static DWORD 00391 ScStartService(PACTIVE_SERVICE lpService, 00392 PSCM_CONTROL_PACKET ControlPacket) 00393 { 00394 HANDLE ThreadHandle; 00395 DWORD ThreadId; 00396 DWORD dwError; 00397 00398 TRACE("ScStartService() called\n"); 00399 TRACE("Size: %lu\n", ControlPacket->dwSize); 00400 TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset)); 00401 00402 /* Set the service status handle */ 00403 lpService->hServiceStatus = ControlPacket->hServiceStatus; 00404 00405 /* Build the arguments vector */ 00406 if (lpService->bUnicode == TRUE) 00407 { 00408 dwError = ScBuildUnicodeArgsVector(ControlPacket, 00409 &lpService->ThreadParams.W.dwArgCount, 00410 &lpService->ThreadParams.W.lpArgVector); 00411 } 00412 else 00413 { 00414 dwError = ScBuildAnsiArgsVector(ControlPacket, 00415 &lpService->ThreadParams.A.dwArgCount, 00416 &lpService->ThreadParams.A.lpArgVector); 00417 } 00418 00419 if (dwError != ERROR_SUCCESS) 00420 return dwError; 00421 00422 /* Invoke the services entry point and implement the command loop */ 00423 ThreadHandle = CreateThread(NULL, 00424 0, 00425 ScServiceMainStub, 00426 lpService, 00427 CREATE_SUSPENDED, 00428 &ThreadId); 00429 if (ThreadHandle == NULL) 00430 { 00431 /* Free the arguments vector */ 00432 if (lpService->bUnicode) 00433 { 00434 if (lpService->ThreadParams.W.lpArgVector != NULL) 00435 { 00436 HeapFree(GetProcessHeap(), 00437 0, 00438 lpService->ThreadParams.W.lpArgVector); 00439 lpService->ThreadParams.W.lpArgVector = NULL; 00440 lpService->ThreadParams.W.dwArgCount = 0; 00441 } 00442 } 00443 else 00444 { 00445 if (lpService->ThreadParams.A.lpArgVector != NULL) 00446 { 00447 HeapFree(GetProcessHeap(), 00448 0, 00449 lpService->ThreadParams.A.lpArgVector); 00450 lpService->ThreadParams.A.lpArgVector = NULL; 00451 lpService->ThreadParams.A.dwArgCount = 0; 00452 } 00453 } 00454 00455 return ERROR_SERVICE_NO_THREAD; 00456 } 00457 00458 ResumeThread(ThreadHandle); 00459 CloseHandle(ThreadHandle); 00460 00461 return ERROR_SUCCESS; 00462 } 00463 00464 00465 static DWORD 00466 ScControlService(PACTIVE_SERVICE lpService, 00467 PSCM_CONTROL_PACKET ControlPacket) 00468 { 00469 TRACE("ScControlService() called\n"); 00470 TRACE("Size: %lu\n", ControlPacket->dwSize); 00471 TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset)); 00472 00473 if (lpService->HandlerFunction) 00474 { 00475 (lpService->HandlerFunction)(ControlPacket->dwControl); 00476 } 00477 else if (lpService->HandlerFunctionEx) 00478 { 00479 /* FIXME: send correct params */ 00480 (lpService->HandlerFunctionEx)(ControlPacket->dwControl, 0, NULL, NULL); 00481 } 00482 00483 TRACE("ScControlService() done\n"); 00484 00485 return ERROR_SUCCESS; 00486 } 00487 00488 00489 static BOOL 00490 ScServiceDispatcher(HANDLE hPipe, 00491 PUCHAR lpBuffer, 00492 DWORD dwBufferSize) 00493 { 00494 PSCM_CONTROL_PACKET ControlPacket; 00495 DWORD Count; 00496 BOOL bResult; 00497 DWORD dwRunningServices = 0; 00498 LPWSTR lpServiceName; 00499 PACTIVE_SERVICE lpService; 00500 SCM_REPLY_PACKET ReplyPacket; 00501 DWORD dwError; 00502 00503 TRACE("ScDispatcherLoop() called\n"); 00504 00505 ControlPacket = HeapAlloc(GetProcessHeap(), 00506 HEAP_ZERO_MEMORY, 00507 1024); 00508 if (ControlPacket == NULL) 00509 return FALSE; 00510 00511 while (TRUE) 00512 { 00513 /* Read command from the control pipe */ 00514 bResult = ReadFile(hPipe, 00515 ControlPacket, 00516 1024, 00517 &Count, 00518 NULL); 00519 if (bResult == FALSE) 00520 { 00521 ERR("Pipe read failed (Error: %lu)\n", GetLastError()); 00522 return FALSE; 00523 } 00524 00525 lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset); 00526 TRACE("Service: %S\n", lpServiceName); 00527 00528 lpService = ScLookupServiceByServiceName(lpServiceName); 00529 if (lpService != NULL) 00530 { 00531 /* Execute command */ 00532 switch (ControlPacket->dwControl) 00533 { 00534 case SERVICE_CONTROL_START: 00535 TRACE("Start command - recieved SERVICE_CONTROL_START\n"); 00536 dwError = ScStartService(lpService, ControlPacket); 00537 if (dwError == ERROR_SUCCESS) 00538 dwRunningServices++; 00539 break; 00540 00541 case SERVICE_CONTROL_STOP: 00542 TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n"); 00543 dwError = ScControlService(lpService, ControlPacket); 00544 if (dwError == ERROR_SUCCESS) 00545 dwRunningServices--; 00546 break; 00547 00548 default: 00549 TRACE("Command %lu received", ControlPacket->dwControl); 00550 dwError = ScControlService(lpService, ControlPacket); 00551 break; 00552 } 00553 } 00554 else 00555 { 00556 dwError = ERROR_SERVICE_DOES_NOT_EXIST; 00557 } 00558 00559 ReplyPacket.dwError = dwError; 00560 00561 /* Send the reply packet */ 00562 bResult = WriteFile(hPipe, 00563 &ReplyPacket, 00564 sizeof(ReplyPacket), 00565 &Count, 00566 NULL); 00567 if (bResult == FALSE) 00568 { 00569 ERR("Pipe write failed (Error: %lu)\n", GetLastError()); 00570 return FALSE; 00571 } 00572 00573 if (dwRunningServices == 0) 00574 break; 00575 } 00576 00577 HeapFree(GetProcessHeap(), 00578 0, 00579 ControlPacket); 00580 00581 return TRUE; 00582 } 00583 00584 00585 /********************************************************************** 00586 * RegisterServiceCtrlHandlerA 00587 * 00588 * @implemented 00589 */ 00590 SERVICE_STATUS_HANDLE WINAPI 00591 RegisterServiceCtrlHandlerA(LPCSTR lpServiceName, 00592 LPHANDLER_FUNCTION lpHandlerProc) 00593 { 00594 ANSI_STRING ServiceNameA; 00595 UNICODE_STRING ServiceNameU; 00596 SERVICE_STATUS_HANDLE SHandle; 00597 00598 RtlInitAnsiString(&ServiceNameA, (LPSTR)lpServiceName); 00599 if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE))) 00600 { 00601 SetLastError(ERROR_OUTOFMEMORY); 00602 return (SERVICE_STATUS_HANDLE)0; 00603 } 00604 00605 SHandle = RegisterServiceCtrlHandlerW(ServiceNameU.Buffer, 00606 lpHandlerProc); 00607 00608 RtlFreeUnicodeString(&ServiceNameU); 00609 00610 return SHandle; 00611 } 00612 00613 00614 /********************************************************************** 00615 * RegisterServiceCtrlHandlerW 00616 * 00617 * @implemented 00618 */ 00619 SERVICE_STATUS_HANDLE WINAPI 00620 RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName, 00621 LPHANDLER_FUNCTION lpHandlerProc) 00622 { 00623 PACTIVE_SERVICE Service; 00624 00625 Service = ScLookupServiceByServiceName((LPWSTR)lpServiceName); 00626 if (Service == NULL) 00627 { 00628 return (SERVICE_STATUS_HANDLE)NULL; 00629 } 00630 00631 Service->HandlerFunction = lpHandlerProc; 00632 Service->HandlerFunctionEx = NULL; 00633 00634 TRACE("RegisterServiceCtrlHandler returning %lu\n", Service->hServiceStatus); 00635 00636 return Service->hServiceStatus; 00637 } 00638 00639 00640 /********************************************************************** 00641 * RegisterServiceCtrlHandlerExA 00642 * 00643 * @implemented 00644 */ 00645 SERVICE_STATUS_HANDLE WINAPI 00646 RegisterServiceCtrlHandlerExA(LPCSTR lpServiceName, 00647 LPHANDLER_FUNCTION_EX lpHandlerProc, 00648 LPVOID lpContext) 00649 { 00650 ANSI_STRING ServiceNameA; 00651 UNICODE_STRING ServiceNameU; 00652 SERVICE_STATUS_HANDLE SHandle; 00653 00654 RtlInitAnsiString(&ServiceNameA, (LPSTR)lpServiceName); 00655 if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE))) 00656 { 00657 SetLastError(ERROR_OUTOFMEMORY); 00658 return (SERVICE_STATUS_HANDLE)0; 00659 } 00660 00661 SHandle = RegisterServiceCtrlHandlerExW(ServiceNameU.Buffer, 00662 lpHandlerProc, 00663 lpContext); 00664 00665 RtlFreeUnicodeString(&ServiceNameU); 00666 00667 return SHandle; 00668 } 00669 00670 00671 /********************************************************************** 00672 * RegisterServiceCtrlHandlerExW 00673 * 00674 * @implemented 00675 */ 00676 SERVICE_STATUS_HANDLE WINAPI 00677 RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName, 00678 LPHANDLER_FUNCTION_EX lpHandlerProc, 00679 LPVOID lpContext) 00680 { 00681 PACTIVE_SERVICE Service; 00682 00683 Service = ScLookupServiceByServiceName(lpServiceName); 00684 if (Service == NULL) 00685 { 00686 return (SERVICE_STATUS_HANDLE)NULL; 00687 } 00688 00689 Service->HandlerFunction = NULL; 00690 Service->HandlerFunctionEx = lpHandlerProc; 00691 Service->HandlerContext = lpContext; 00692 00693 TRACE("RegisterServiceCtrlHandlerEx returning %lu\n", Service->hServiceStatus); 00694 00695 return Service->hServiceStatus; 00696 } 00697 00698 00699 /********************************************************************** 00700 * I_ScSetServiceBitsA 00701 * 00702 * Undocumented 00703 * 00704 * @implemented 00705 */ 00706 BOOL WINAPI 00707 I_ScSetServiceBitsA(SERVICE_STATUS_HANDLE hServiceStatus, 00708 DWORD dwServiceBits, 00709 BOOL bSetBitsOn, 00710 BOOL bUpdateImmediately, 00711 LPSTR lpString) 00712 { 00713 BOOL bResult; 00714 00715 RpcTryExcept 00716 { 00717 /* Call to services.exe using RPC */ 00718 bResult = RI_ScSetServiceBitsA((RPC_SERVICE_STATUS_HANDLE)hServiceStatus, 00719 dwServiceBits, 00720 bSetBitsOn, 00721 bUpdateImmediately, 00722 lpString); 00723 } 00724 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00725 { 00726 SetLastError(ScmRpcStatusToWinError(RpcExceptionCode())); 00727 bResult = FALSE; 00728 } 00729 RpcEndExcept; 00730 00731 return bResult; 00732 } 00733 00734 00735 /********************************************************************** 00736 * I_ScSetServiceBitsW 00737 * 00738 * Undocumented 00739 * 00740 * @implemented 00741 */ 00742 BOOL WINAPI 00743 I_ScSetServiceBitsW(SERVICE_STATUS_HANDLE hServiceStatus, 00744 DWORD dwServiceBits, 00745 BOOL bSetBitsOn, 00746 BOOL bUpdateImmediately, 00747 LPWSTR lpString) 00748 { 00749 BOOL bResult; 00750 00751 RpcTryExcept 00752 { 00753 /* Call to services.exe using RPC */ 00754 bResult = RI_ScSetServiceBitsW((RPC_SERVICE_STATUS_HANDLE)hServiceStatus, 00755 dwServiceBits, 00756 bSetBitsOn, 00757 bUpdateImmediately, 00758 lpString); 00759 } 00760 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00761 { 00762 SetLastError(ScmRpcStatusToWinError(RpcExceptionCode())); 00763 bResult = FALSE; 00764 } 00765 RpcEndExcept; 00766 00767 return bResult; 00768 } 00769 00770 00771 /********************************************************************** 00772 * SetServiceBits 00773 * 00774 * @implemented 00775 */ 00776 BOOL WINAPI 00777 SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus, 00778 DWORD dwServiceBits, 00779 BOOL bSetBitsOn, 00780 BOOL bUpdateImmediately) 00781 { 00782 return I_ScSetServiceBitsW(hServiceStatus, 00783 dwServiceBits, 00784 bSetBitsOn, 00785 bUpdateImmediately, 00786 NULL); 00787 } 00788 00789 00790 /********************************************************************** 00791 * SetServiceStatus 00792 * 00793 * @implemented 00794 */ 00795 BOOL WINAPI 00796 SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, 00797 LPSERVICE_STATUS lpServiceStatus) 00798 { 00799 DWORD dwError; 00800 00801 TRACE("SetServiceStatus() called\n"); 00802 TRACE("hServiceStatus %lu\n", hServiceStatus); 00803 00804 RpcTryExcept 00805 { 00806 /* Call to services.exe using RPC */ 00807 dwError = RSetServiceStatus((RPC_SERVICE_STATUS_HANDLE)hServiceStatus, 00808 lpServiceStatus); 00809 } 00810 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 00811 { 00812 dwError = ScmRpcStatusToWinError(RpcExceptionCode()); 00813 } 00814 RpcEndExcept; 00815 00816 if (dwError != ERROR_SUCCESS) 00817 { 00818 ERR("ScmrSetServiceStatus() failed (Error %lu)\n", dwError); 00819 SetLastError(dwError); 00820 return FALSE; 00821 } 00822 00823 TRACE("SetServiceStatus() done (ret %lu)\n", dwError); 00824 00825 return TRUE; 00826 } 00827 00828 00829 /********************************************************************** 00830 * StartServiceCtrlDispatcherA 00831 * 00832 * @implemented 00833 */ 00834 BOOL WINAPI 00835 StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable) 00836 { 00837 ULONG i; 00838 HANDLE hPipe; 00839 DWORD dwError; 00840 PUCHAR lpMessageBuffer; 00841 00842 TRACE("StartServiceCtrlDispatcherA() called\n"); 00843 00844 i = 0; 00845 while (lpServiceStartTable[i].lpServiceProc != NULL) 00846 { 00847 i++; 00848 } 00849 00850 dwActiveServiceCount = i; 00851 lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(), 00852 HEAP_ZERO_MEMORY, 00853 dwActiveServiceCount * sizeof(ACTIVE_SERVICE)); 00854 if (lpActiveServices == NULL) 00855 { 00856 return FALSE; 00857 } 00858 00859 /* Copy service names and start procedure */ 00860 for (i = 0; i < dwActiveServiceCount; i++) 00861 { 00862 RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName, 00863 lpServiceStartTable[i].lpServiceName); 00864 lpActiveServices[i].ThreadParams.A.lpServiceMain = lpServiceStartTable[i].lpServiceProc; 00865 lpActiveServices[i].hServiceStatus = 0; 00866 lpActiveServices[i].bUnicode = FALSE; 00867 } 00868 00869 dwError = ScConnectControlPipe(&hPipe); 00870 if (dwError != ERROR_SUCCESS) 00871 { 00872 /* Free the service table */ 00873 for (i = 0; i < dwActiveServiceCount; i++) 00874 { 00875 RtlFreeUnicodeString(&lpActiveServices[i].ServiceName); 00876 } 00877 RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); 00878 lpActiveServices = NULL; 00879 dwActiveServiceCount = 0; 00880 return FALSE; 00881 } 00882 00883 lpMessageBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 00884 HEAP_ZERO_MEMORY, 00885 256); 00886 if (lpMessageBuffer == NULL) 00887 { 00888 /* Free the service table */ 00889 for (i = 0; i < dwActiveServiceCount; i++) 00890 { 00891 RtlFreeUnicodeString(&lpActiveServices[i].ServiceName); 00892 } 00893 RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); 00894 lpActiveServices = NULL; 00895 dwActiveServiceCount = 0; 00896 CloseHandle(hPipe); 00897 return FALSE; 00898 } 00899 00900 ScCreateStatusBinding(); 00901 00902 ScServiceDispatcher(hPipe, lpMessageBuffer, 256); 00903 00904 ScDestroyStatusBinding(); 00905 00906 CloseHandle(hPipe); 00907 00908 /* Free the message buffer */ 00909 RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer); 00910 00911 /* Free the service table */ 00912 for (i = 0; i < dwActiveServiceCount; i++) 00913 { 00914 RtlFreeUnicodeString(&lpActiveServices[i].ServiceName); 00915 } 00916 RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); 00917 lpActiveServices = NULL; 00918 dwActiveServiceCount = 0; 00919 00920 return TRUE; 00921 } 00922 00923 00924 /********************************************************************** 00925 * StartServiceCtrlDispatcherW 00926 * 00927 * @implemented 00928 */ 00929 BOOL WINAPI 00930 StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable) 00931 { 00932 ULONG i; 00933 HANDLE hPipe; 00934 DWORD dwError; 00935 PUCHAR lpMessageBuffer; 00936 00937 TRACE("StartServiceCtrlDispatcherW() called\n"); 00938 00939 i = 0; 00940 while (lpServiceStartTable[i].lpServiceProc != NULL) 00941 { 00942 i++; 00943 } 00944 00945 dwActiveServiceCount = i; 00946 lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(), 00947 HEAP_ZERO_MEMORY, 00948 dwActiveServiceCount * sizeof(ACTIVE_SERVICE)); 00949 if (lpActiveServices == NULL) 00950 { 00951 return FALSE; 00952 } 00953 00954 /* Copy service names and start procedure */ 00955 for (i = 0; i < dwActiveServiceCount; i++) 00956 { 00957 RtlCreateUnicodeString(&lpActiveServices[i].ServiceName, 00958 lpServiceStartTable[i].lpServiceName); 00959 lpActiveServices[i].ThreadParams.W.lpServiceMain = lpServiceStartTable[i].lpServiceProc; 00960 lpActiveServices[i].hServiceStatus = 0; 00961 lpActiveServices[i].bUnicode = TRUE; 00962 } 00963 00964 dwError = ScConnectControlPipe(&hPipe); 00965 if (dwError != ERROR_SUCCESS) 00966 { 00967 /* Free the service table */ 00968 for (i = 0; i < dwActiveServiceCount; i++) 00969 { 00970 RtlFreeUnicodeString(&lpActiveServices[i].ServiceName); 00971 } 00972 RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); 00973 lpActiveServices = NULL; 00974 dwActiveServiceCount = 0; 00975 return FALSE; 00976 } 00977 00978 lpMessageBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 00979 HEAP_ZERO_MEMORY, 00980 256); 00981 if (lpMessageBuffer == NULL) 00982 { 00983 /* Free the service table */ 00984 for (i = 0; i < dwActiveServiceCount; i++) 00985 { 00986 RtlFreeUnicodeString(&lpActiveServices[i].ServiceName); 00987 } 00988 RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); 00989 lpActiveServices = NULL; 00990 dwActiveServiceCount = 0; 00991 CloseHandle(hPipe); 00992 return FALSE; 00993 } 00994 00995 ScCreateStatusBinding(); 00996 00997 ScServiceDispatcher(hPipe, lpMessageBuffer, 256); 00998 00999 ScDestroyStatusBinding(); 01000 01001 CloseHandle(hPipe); 01002 01003 /* Free the message buffer */ 01004 RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer); 01005 01006 /* Free the service table */ 01007 for (i = 0; i < dwActiveServiceCount; i++) 01008 { 01009 RtlFreeUnicodeString(&lpActiveServices[i].ServiceName); 01010 } 01011 RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); 01012 lpActiveServices = NULL; 01013 dwActiveServiceCount = 0; 01014 01015 return TRUE; 01016 } 01017 01018 /* EOF */ Generated on Sun May 27 2012 04:22:45 for ReactOS by
1.7.6.1
|