diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index b64578d0016..f17e6878d8d 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -30,7 +30,7 @@ type win32 0026 stub CreateProcessAsUserA 0027 stub CreateProcessAsUserW 0028 stdcall CreateServiceA(long ptr ptr long long long long ptr ptr ptr ptr ptr ptr) CreateServiceA -0029 stdcall CreateServiceW (long ptr ptr long long long long ptr ptr ptr ptr ptr ptr) CreateServiceA +0029 stdcall CreateServiceW (long ptr ptr long long long long ptr ptr ptr ptr ptr ptr) CreateServiceW 0030 stdcall CryptAcquireContextA(ptr str str long long) CryptAcquireContextA 0031 stub CryptAcquireContextW 0032 stub CryptContextAddRef diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 96355d0439b..7ce141a3b6d 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -15,8 +15,11 @@ DEFAULT_DEBUG_CHANNEL(advapi) +static DWORD start_dwNumServiceArgs; +static LPWSTR *start_lpServiceArgVectors; + /****************************************************************************** - * EnumServicesStatus32A [ADVAPI32.38] + * EnumServicesStatusA [ADVAPI32.38] */ BOOL WINAPI EnumServicesStatusA( SC_HANDLE hSCManager, DWORD dwServiceType, @@ -31,25 +34,66 @@ EnumServicesStatusA( SC_HANDLE hSCManager, DWORD dwServiceType, } /****************************************************************************** - * StartServiceCtrlDispatcher32A [ADVAPI32.196] + * StartServiceCtrlDispatcherA [ADVAPI32.196] */ BOOL WINAPI StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent ) { - LPSERVICE_TABLE_ENTRYA ptr = servent; - LPSERVICE_MAIN_FUNCTIONA fpMain; + LPSERVICE_MAIN_FUNCTIONA fpMain; + HANDLE wait; + DWORD dwNumServiceArgs ; + LPWSTR *lpArgVecW; + LPSTR *lpArgVecA; + int i; + + TRACE("(%p)\n", servent); + wait = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, "ADVAPI32_ServiceStartData"); + if(wait == 0) + { + ERR("Couldn't find wait semaphore\n"); + ERR("perhaps you need to start services using StartService\n"); + return FALSE; + } - while (ptr->lpServiceName) { - FIXME("%s at %p\n", ptr->lpServiceName, ptr); - fpMain = ptr->lpServiceProc; - fpMain(0,NULL); /* try to start the service */ - ptr++; - } - return TRUE; + dwNumServiceArgs = start_dwNumServiceArgs; + lpArgVecW = start_lpServiceArgVectors; + + ReleaseSemaphore(wait, 1, NULL); + + /* Convert the Unicode arg vectors back to ASCII */ + if(dwNumServiceArgs) + lpArgVecA = (LPSTR*) HeapAlloc( GetProcessHeap(), 0, + dwNumServiceArgs*sizeof(LPSTR) ); + else + lpArgVecA = NULL; + + for(i=0; ilpServiceName) { + TRACE("%s at %p)\n", debugstr_a(servent->lpServiceName),servent); + fpMain = servent->lpServiceProc; + + /* try to start the service */ + fpMain( dwNumServiceArgs, lpArgVecA); + + servent++; + } + + if(dwNumServiceArgs) + { + /* free arg strings */ + for(i=0; ilpServiceName) { - FIXME("%s at %p): STUB.\n", - debugstr_w(ptr->lpServiceName),ptr); - fpMain = ptr->lpServiceProc; - fpMain(0,NULL); /* try to start the service */ - ptr++; - } - return TRUE; + TRACE("(%p)\n", servent); + wait = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, "ADVAPI32_ServiceStartData"); + if(wait == 0) + { + ERR("Couldn't find wait semaphore\n"); + ERR("perhaps you need to start services using StartService\n"); + return FALSE; + } + + dwNumServiceArgs = start_dwNumServiceArgs; + lpServiceArgVectors = start_lpServiceArgVectors; + + ReleaseSemaphore(wait, 1, NULL); + + /* FIXME: should we blindly start all services? */ + while (servent->lpServiceName) { + TRACE("%s at %p)\n", debugstr_w(servent->lpServiceName),servent); + fpMain = servent->lpServiceProc; + + /* try to start the service */ + fpMain( dwNumServiceArgs, lpServiceArgVectors); + + servent++; + } + + return TRUE; } /****************************************************************************** @@ -115,7 +179,7 @@ SetServiceStatus( SERVICE_STATUS_HANDLE hService, LPSERVICE_STATUS lpStatus ) } /****************************************************************************** - * OpenSCManager32A [ADVAPI32.110] + * OpenSCManagerA [ADVAPI32.110] */ SC_HANDLE WINAPI OpenSCManagerA( LPCSTR lpMachineName, LPCSTR lpDatabaseName, @@ -131,7 +195,7 @@ OpenSCManagerA( LPCSTR lpMachineName, LPCSTR lpDatabaseName, } /****************************************************************************** - * OpenSCManager32W [ADVAPI32.111] + * OpenSCManagerW [ADVAPI32.111] * Establishes a connection to the service control manager and opens database * * NOTES @@ -228,7 +292,7 @@ CloseServiceHandle( SC_HANDLE hSCObject ) /****************************************************************************** - * OpenService32A [ADVAPI32.112] + * OpenServiceA [ADVAPI32.112] */ SC_HANDLE WINAPI OpenServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName, @@ -248,7 +312,7 @@ OpenServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName, /****************************************************************************** - * OpenService32W [ADVAPI32.113] + * OpenServiceW [ADVAPI32.113] * Opens a handle to an existing service * * PARAMS @@ -287,9 +351,25 @@ OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, return hKey; } +/****************************************************************************** + * CreateServiceW [ADVAPI32.29] + */ +SC_HANDLE WINAPI +CreateServiceW( DWORD hSCManager, LPCWSTR lpServiceName, + LPCWSTR lpDisplayName, DWORD dwDesiredAccess, + DWORD dwServiceType, DWORD dwStartType, + DWORD dwErrorControl, LPCWSTR lpBinaryPathName, + LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, + LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, + LPCWSTR lpPassword ) +{ + FIXME("(%ld,%s,%s,...)\n", hSCManager, debugstr_w(lpServiceName), debugstr_w(lpDisplayName)); + return FALSE; +} + /****************************************************************************** - * CreateService32A [ADVAPI32.29] + * CreateServiceA [ADVAPI32.28] */ SC_HANDLE WINAPI CreateServiceA( DWORD hSCManager, LPCSTR lpServiceName, @@ -300,9 +380,87 @@ CreateServiceA( DWORD hSCManager, LPCSTR lpServiceName, LPCSTR lpDependencies, LPCSTR lpServiceStartName, LPCSTR lpPassword ) { - FIXME("(%ld,%s,%s,...): stub\n", - hSCManager, debugstr_a(lpServiceName), debugstr_a(lpDisplayName)); - return 1; + HKEY hKey; + LONG r; + DWORD dp; + + TRACE("(%ld,%s,%s,...)\n", hSCManager, debugstr_a(lpServiceName), debugstr_a(lpDisplayName)); + + r = RegCreateKeyExA(hSCManager, lpServiceName, 0, NULL, + REG_OPTION_NON_VOLATILE, dwDesiredAccess, NULL, &hKey, &dp); + if (r!=ERROR_SUCCESS) + return 0; + if (dp != REG_CREATED_NEW_KEY) + return 0; + + if(lpDisplayName) + { + r = RegSetValueExA(hKey, "DisplayName", 0, REG_SZ, lpDisplayName, lstrlenA(lpDisplayName) ); + if (r!=ERROR_SUCCESS) + return 0; + } + + r = RegSetValueExA(hKey, "Type", 0, REG_DWORD, (LPVOID)&dwServiceType, sizeof (DWORD) ); + if (r!=ERROR_SUCCESS) + return 0; + + r = RegSetValueExA(hKey, "Start", 0, REG_DWORD, (LPVOID)&dwStartType, sizeof (DWORD) ); + if (r!=ERROR_SUCCESS) + return 0; + + r = RegSetValueExA(hKey, "ErrorControl", 0, REG_DWORD, + (LPVOID)&dwErrorControl, sizeof (DWORD) ); + if (r!=ERROR_SUCCESS) + return 0; + + if(lpBinaryPathName) + { + r = RegSetValueExA(hKey, "ImagePath", 0, REG_SZ, + lpBinaryPathName,lstrlenA(lpBinaryPathName)+1 ); + if (r!=ERROR_SUCCESS) + return 0; + } + + if(lpLoadOrderGroup) + { + r = RegSetValueExA(hKey, "Group", 0, REG_SZ, + lpLoadOrderGroup, lstrlenA(lpLoadOrderGroup)+1 ); + if (r!=ERROR_SUCCESS) + return 0; + } + + r = RegSetValueExA(hKey, "ErrorControl", 0, REG_DWORD, + (LPVOID)&dwErrorControl, sizeof (DWORD) ); + if (r!=ERROR_SUCCESS) + return 0; + + if(lpDependencies) + { + DWORD len = 0; + + /* determine the length of a double null terminated multi string */ + do { + len += (lstrlenA(&lpDependencies[len])+1); + } while (lpDependencies[len++]); + + /* fixme: this should be unicode */ + r = RegSetValueExA(hKey, "Dependencies", 0, REG_MULTI_SZ, + lpDependencies, len ); + if (r!=ERROR_SUCCESS) + return 0; + } + + if(lpPassword) + { + FIXME("Don't know how to add a Password for a service.\n"); + } + + if(lpServiceStartName) + { + FIXME("Don't know how to add a ServiceStartName for a service.\n"); + } + + return hKey; } @@ -324,22 +482,42 @@ DeleteService( SC_HANDLE hService ) /****************************************************************************** - * StartService32A [ADVAPI32.195] + * StartServiceA [ADVAPI32.195] * - * NOTES - * How do we convert lpServiceArgVectors to use the 32W version? */ BOOL WINAPI StartServiceA( SC_HANDLE hService, DWORD dwNumServiceArgs, LPCSTR *lpServiceArgVectors ) { - FIXME("(%d,%ld,%p): stub\n",hService,dwNumServiceArgs,lpServiceArgVectors); + LPWSTR *lpwstr=NULL; + int i; + + TRACE("(%d,%ld,%p)\n",hService,dwNumServiceArgs,lpServiceArgVectors); + + if(dwNumServiceArgs) + lpwstr = (LPWSTR*) HeapAlloc( GetProcessHeap(), 0, + dwNumServiceArgs*sizeof(LPWSTR) ); + else + lpwstr = NULL; + + for(i=0; idwServiceType = val; - /* FIXME: how are these determined or read from the registry? */ - lpservicestatus->dwCurrentState = 0 /*SERVICE_STOPPED*/; + /* SERVICE: unavailable=0, stopped=1, starting=2, running=3? */; + lpservicestatus->dwCurrentState = 1; lpservicestatus->dwControlsAccepted = 0; lpservicestatus->dwWin32ExitCode = NO_ERROR; lpservicestatus->dwServiceSpecificExitCode = 0; diff --git a/include/winsvc.h b/include/winsvc.h index 38bbda36ccd..604890804f9 100644 --- a/include/winsvc.h +++ b/include/winsvc.h @@ -27,8 +27,8 @@ typedef struct _SERVICE_STATUS { /* Service main function prototype */ -typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTIONA)(DWORD,LPSTR); -typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR); +typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTIONA)(DWORD,LPSTR*); +typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR*); DECL_WINELIB_TYPE_AW(LPSERVICE_MAIN_FUNCTION) /* Service start table */