Added code to some service functions (some untested), fixed
declaration of service main function.
This commit is contained in:
parent
2bab80dea4
commit
0c0f7d3560
|
@ -30,7 +30,7 @@ type win32
|
||||||
0026 stub CreateProcessAsUserA
|
0026 stub CreateProcessAsUserA
|
||||||
0027 stub CreateProcessAsUserW
|
0027 stub CreateProcessAsUserW
|
||||||
0028 stdcall CreateServiceA(long ptr ptr long long long long ptr ptr ptr ptr ptr ptr) CreateServiceA
|
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
|
0030 stdcall CryptAcquireContextA(ptr str str long long) CryptAcquireContextA
|
||||||
0031 stub CryptAcquireContextW
|
0031 stub CryptAcquireContextW
|
||||||
0032 stub CryptContextAddRef
|
0032 stub CryptContextAddRef
|
||||||
|
|
|
@ -15,8 +15,11 @@
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(advapi)
|
DEFAULT_DEBUG_CHANNEL(advapi)
|
||||||
|
|
||||||
|
static DWORD start_dwNumServiceArgs;
|
||||||
|
static LPWSTR *start_lpServiceArgVectors;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* EnumServicesStatus32A [ADVAPI32.38]
|
* EnumServicesStatusA [ADVAPI32.38]
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
EnumServicesStatusA( SC_HANDLE hSCManager, DWORD dwServiceType,
|
EnumServicesStatusA( SC_HANDLE hSCManager, DWORD dwServiceType,
|
||||||
|
@ -31,25 +34,66 @@ EnumServicesStatusA( SC_HANDLE hSCManager, DWORD dwServiceType,
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* StartServiceCtrlDispatcher32A [ADVAPI32.196]
|
* StartServiceCtrlDispatcherA [ADVAPI32.196]
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
|
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;
|
||||||
|
|
||||||
while (ptr->lpServiceName) {
|
TRACE("(%p)\n", servent);
|
||||||
FIXME("%s at %p\n", ptr->lpServiceName, ptr);
|
wait = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, "ADVAPI32_ServiceStartData");
|
||||||
fpMain = ptr->lpServiceProc;
|
if(wait == 0)
|
||||||
fpMain(0,NULL); /* try to start the service */
|
{
|
||||||
ptr++;
|
ERR("Couldn't find wait semaphore\n");
|
||||||
|
ERR("perhaps you need to start services using StartService\n");
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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; i<dwNumServiceArgs; i++)
|
||||||
|
lpArgVecA[i]=HEAP_strdupWtoA(GetProcessHeap(), 0, lpArgVecW[i]);
|
||||||
|
|
||||||
|
/* FIXME: should we blindly start all services? */
|
||||||
|
while (servent->lpServiceName) {
|
||||||
|
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; i<dwNumServiceArgs; i++)
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpArgVecA[i]);
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpArgVecA);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* StartServiceCtrlDispatcher32W [ADVAPI32.197]
|
* StartServiceCtrlDispatcherW [ADVAPI32.197]
|
||||||
*
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
* servent []
|
* servent []
|
||||||
|
@ -57,16 +101,36 @@ StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent )
|
StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent )
|
||||||
{
|
{
|
||||||
LPSERVICE_TABLE_ENTRYW ptr = servent;
|
|
||||||
LPSERVICE_MAIN_FUNCTIONW fpMain;
|
LPSERVICE_MAIN_FUNCTIONW fpMain;
|
||||||
|
HANDLE wait;
|
||||||
|
DWORD dwNumServiceArgs ;
|
||||||
|
LPWSTR *lpServiceArgVectors ;
|
||||||
|
|
||||||
while (ptr->lpServiceName) {
|
TRACE("(%p)\n", servent);
|
||||||
FIXME("%s at %p): STUB.\n",
|
wait = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, "ADVAPI32_ServiceStartData");
|
||||||
debugstr_w(ptr->lpServiceName),ptr);
|
if(wait == 0)
|
||||||
fpMain = ptr->lpServiceProc;
|
{
|
||||||
fpMain(0,NULL); /* try to start the service */
|
ERR("Couldn't find wait semaphore\n");
|
||||||
ptr++;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +179,7 @@ SetServiceStatus( SERVICE_STATUS_HANDLE hService, LPSERVICE_STATUS lpStatus )
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* OpenSCManager32A [ADVAPI32.110]
|
* OpenSCManagerA [ADVAPI32.110]
|
||||||
*/
|
*/
|
||||||
SC_HANDLE WINAPI
|
SC_HANDLE WINAPI
|
||||||
OpenSCManagerA( LPCSTR lpMachineName, LPCSTR lpDatabaseName,
|
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
|
* Establishes a connection to the service control manager and opens database
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
|
@ -228,7 +292,7 @@ CloseServiceHandle( SC_HANDLE hSCObject )
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* OpenService32A [ADVAPI32.112]
|
* OpenServiceA [ADVAPI32.112]
|
||||||
*/
|
*/
|
||||||
SC_HANDLE WINAPI
|
SC_HANDLE WINAPI
|
||||||
OpenServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
|
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
|
* Opens a handle to an existing service
|
||||||
*
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
|
@ -287,9 +351,25 @@ OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName,
|
||||||
return hKey;
|
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
|
SC_HANDLE WINAPI
|
||||||
CreateServiceA( DWORD hSCManager, LPCSTR lpServiceName,
|
CreateServiceA( DWORD hSCManager, LPCSTR lpServiceName,
|
||||||
|
@ -300,9 +380,87 @@ CreateServiceA( DWORD hSCManager, LPCSTR lpServiceName,
|
||||||
LPCSTR lpDependencies, LPCSTR lpServiceStartName,
|
LPCSTR lpDependencies, LPCSTR lpServiceStartName,
|
||||||
LPCSTR lpPassword )
|
LPCSTR lpPassword )
|
||||||
{
|
{
|
||||||
FIXME("(%ld,%s,%s,...): stub\n",
|
HKEY hKey;
|
||||||
hSCManager, debugstr_a(lpServiceName), debugstr_a(lpDisplayName));
|
LONG r;
|
||||||
return 1;
|
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
|
BOOL WINAPI
|
||||||
StartServiceA( SC_HANDLE hService, DWORD dwNumServiceArgs,
|
StartServiceA( SC_HANDLE hService, DWORD dwNumServiceArgs,
|
||||||
LPCSTR *lpServiceArgVectors )
|
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; i<dwNumServiceArgs; i++)
|
||||||
|
lpwstr[i]=HEAP_strdupAtoW(GetProcessHeap(), 0, lpServiceArgVectors[i]);
|
||||||
|
|
||||||
|
StartServiceW(hService, dwNumServiceArgs, lpwstr);
|
||||||
|
|
||||||
|
if(dwNumServiceArgs)
|
||||||
|
{
|
||||||
|
for(i=0; i<dwNumServiceArgs; i++)
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpwstr[i]);
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpwstr);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* StartService32W [ADVAPI32.198]
|
* StartServiceW [ADVAPI32.198]
|
||||||
* Starts a service
|
* Starts a service
|
||||||
*
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
|
@ -347,6 +525,20 @@ StartServiceA( SC_HANDLE hService, DWORD dwNumServiceArgs,
|
||||||
* dwNumServiceArgs [I] Number of arguments
|
* dwNumServiceArgs [I] Number of arguments
|
||||||
* lpServiceArgVectors [I] Address of array of argument string pointers
|
* lpServiceArgVectors [I] Address of array of argument string pointers
|
||||||
*
|
*
|
||||||
|
* NOTES
|
||||||
|
*
|
||||||
|
* NT implements this function using an obscure RPC call...
|
||||||
|
*
|
||||||
|
* Might need to do a "setenv SystemRoot \\WINNT" in your .cshrc
|
||||||
|
* to get things like %SystemRoot%\\System32\\service.exe to load.
|
||||||
|
*
|
||||||
|
* Will only work for shared address space. How should the service
|
||||||
|
* args be transferred when address spaces are separated?
|
||||||
|
*
|
||||||
|
* Can only start one service at a time.
|
||||||
|
*
|
||||||
|
* Has no concept of priviledge.
|
||||||
|
*
|
||||||
* RETURNS STD
|
* RETURNS STD
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -354,8 +546,89 @@ BOOL WINAPI
|
||||||
StartServiceW( SC_HANDLE hService, DWORD dwNumServiceArgs,
|
StartServiceW( SC_HANDLE hService, DWORD dwNumServiceArgs,
|
||||||
LPCWSTR *lpServiceArgVectors )
|
LPCWSTR *lpServiceArgVectors )
|
||||||
{
|
{
|
||||||
FIXME("(%d,%ld,%p): stub\n",hService,dwNumServiceArgs,
|
CHAR path[MAX_PATH],str[MAX_PATH];
|
||||||
|
DWORD type,size;
|
||||||
|
long r;
|
||||||
|
HANDLE data,wait;
|
||||||
|
PROCESS_INFORMATION procinfo;
|
||||||
|
STARTUPINFOA startupinfo;
|
||||||
|
|
||||||
|
TRACE("(%d,%ld,%p)\n",hService,dwNumServiceArgs,
|
||||||
lpServiceArgVectors);
|
lpServiceArgVectors);
|
||||||
|
|
||||||
|
size = sizeof str;
|
||||||
|
r = RegQueryValueExA(hService, "ImagePath", NULL, &type, (LPVOID)str, &size);
|
||||||
|
if (r!=ERROR_SUCCESS)
|
||||||
|
return FALSE;
|
||||||
|
ExpandEnvironmentStringsA(str,path,sizeof path);
|
||||||
|
|
||||||
|
TRACE("Starting service %s\n", debugstr_a(path) );
|
||||||
|
|
||||||
|
data = CreateSemaphoreA(NULL,1,1,"ADVAPI32_ServiceStartData");
|
||||||
|
if(data == ERROR_INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
data = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, "ADVAPI32_ServiceStartData");
|
||||||
|
if(data == 0)
|
||||||
|
{
|
||||||
|
ERR("Couldn't create data semaphore\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wait = CreateSemaphoreA(NULL,0,1,"ADVAPI32_WaitServiceStart");
|
||||||
|
{
|
||||||
|
wait = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, "ADVAPI32_ServiceStartData");
|
||||||
|
if(wait == 0)
|
||||||
|
{
|
||||||
|
ERR("Couldn't create wait semaphore\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: lpServiceArgsVectors need to be stored and returned to
|
||||||
|
* the service when it calls StartServiceCtrlDispatcher
|
||||||
|
*
|
||||||
|
* Chuck these in a global (yuk) so we can pass them to
|
||||||
|
* another process - address space separation will break this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
r = WaitForSingleObject(data,INFINITE);
|
||||||
|
|
||||||
|
if( r == WAIT_FAILED)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
start_dwNumServiceArgs = dwNumServiceArgs;
|
||||||
|
start_lpServiceArgVectors = lpServiceArgVectors;
|
||||||
|
|
||||||
|
ZeroMemory(&startupinfo,sizeof(STARTUPINFOA));
|
||||||
|
startupinfo.cb = sizeof(STARTUPINFOA);
|
||||||
|
|
||||||
|
r = CreateProcessA(path,
|
||||||
|
NULL,
|
||||||
|
NULL, /* process security attribs */
|
||||||
|
NULL, /* thread security attribs */
|
||||||
|
FALSE, /* inherit handles */
|
||||||
|
0, /* creation flags */
|
||||||
|
NULL, /* environment */
|
||||||
|
NULL, /* current directory */
|
||||||
|
&startupinfo, /* startup info */
|
||||||
|
&procinfo); /* process info */
|
||||||
|
|
||||||
|
if(r == FALSE)
|
||||||
|
{
|
||||||
|
ERR("Couldn't start process\n");
|
||||||
|
/* ReleaseSemaphore(data, 1, NULL);
|
||||||
|
return FALSE; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* docs for StartServiceCtrlDispatcher say this should be 30 sec */
|
||||||
|
r = WaitForSingleObject(wait,30000);
|
||||||
|
|
||||||
|
ReleaseSemaphore(data, 1, NULL);
|
||||||
|
|
||||||
|
if( r == WAIT_FAILED)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,9 +657,9 @@ QueryServiceStatus( SC_HANDLE hService, LPSERVICE_STATUS lpservicestatus )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
lpservicestatus->dwServiceType = val;
|
lpservicestatus->dwServiceType = val;
|
||||||
|
|
||||||
/* FIXME: how are these determined or read from the registry? */
|
/* 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->dwControlsAccepted = 0;
|
||||||
lpservicestatus->dwWin32ExitCode = NO_ERROR;
|
lpservicestatus->dwWin32ExitCode = NO_ERROR;
|
||||||
lpservicestatus->dwServiceSpecificExitCode = 0;
|
lpservicestatus->dwServiceSpecificExitCode = 0;
|
||||||
|
|
|
@ -27,8 +27,8 @@ typedef struct _SERVICE_STATUS {
|
||||||
|
|
||||||
/* Service main function prototype */
|
/* Service main function prototype */
|
||||||
|
|
||||||
typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTIONA)(DWORD,LPSTR);
|
typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTIONA)(DWORD,LPSTR*);
|
||||||
typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR);
|
typedef VOID (CALLBACK *LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR*);
|
||||||
DECL_WINELIB_TYPE_AW(LPSERVICE_MAIN_FUNCTION)
|
DECL_WINELIB_TYPE_AW(LPSERVICE_MAIN_FUNCTION)
|
||||||
|
|
||||||
/* Service start table */
|
/* Service start table */
|
||||||
|
|
Loading…
Reference in New Issue