mirror of
https://github.com/reactos/reactos.git
synced 2024-07-17 18:06:11 +00:00
[SERVICES/ADVAPI32]
Pass the service start argument vector to the started service main function. ANSI services are not supported yet. svn path=/trunk/; revision=53564
This commit is contained in:
parent
1a358ac727
commit
ff2da6c81c
|
@ -1002,6 +1002,8 @@ ScmSendStartCommand(PSERVICE Service,
|
||||||
DWORD dwReadCount = 0;
|
DWORD dwReadCount = 0;
|
||||||
DWORD dwError = ERROR_SUCCESS;
|
DWORD dwError = ERROR_SUCCESS;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
PWSTR *pOffPtr;
|
||||||
|
PWSTR pArgPtr;
|
||||||
|
|
||||||
DPRINT("ScmSendStartCommand() called\n");
|
DPRINT("ScmSendStartCommand() called\n");
|
||||||
|
|
||||||
|
@ -1043,16 +1045,25 @@ ScmSendStartCommand(PSERVICE Service,
|
||||||
/* Copy argument list */
|
/* Copy argument list */
|
||||||
if (argc > 0 && argv != NULL)
|
if (argc > 0 && argv != NULL)
|
||||||
{
|
{
|
||||||
// Ptr += wcslen(Service->lpServiceName) + 1;
|
Ptr += wcslen(Service->lpServiceName) + 1;
|
||||||
// Ptr = ALIGN_UP_POINTER(Ptr, LPWSTR);
|
pOffPtr = (PWSTR*)ALIGN_UP_POINTER(Ptr, PWSTR);
|
||||||
|
pArgPtr = (PWSTR)((ULONG_PTR)pOffPtr + argc * sizeof(PWSTR));
|
||||||
|
|
||||||
// ControlPacket->dwArgumentsOffset = (DWORD)((INT_PTR)Ptr - (INT_PTR)ControlPacket);
|
ControlPacket->dwArgumentsCount = argc;
|
||||||
|
ControlPacket->dwArgumentsOffset = (DWORD)((ULONG_PTR)pOffPtr - (ULONG_PTR)ControlPacket);
|
||||||
|
|
||||||
|
DPRINT("dwArgumentsCount: %lu\n", ControlPacket->dwArgumentsCount);
|
||||||
|
DPRINT("dwArgumentsOffset: %lu\n", ControlPacket->dwArgumentsOffset);
|
||||||
|
|
||||||
#if 0
|
for (i = 0; i < argc; i++)
|
||||||
memcpy(Ptr, Arguments, ArgsLength);
|
{
|
||||||
Ptr += ArgsLength;
|
wcscpy(pArgPtr, argv[i]);
|
||||||
#endif
|
*pOffPtr = (PWSTR)((ULONG_PTR)pArgPtr - (ULONG_PTR)pOffPtr);
|
||||||
|
DPRINT("offset: %p\n", *pOffPtr);
|
||||||
|
|
||||||
|
pArgPtr += wcslen(argv[i]) + 1;
|
||||||
|
pOffPtr++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the start command */
|
/* Send the start command */
|
||||||
|
|
|
@ -18,20 +18,35 @@ WINE_DEFAULT_DEBUG_CHANNEL(advapi);
|
||||||
|
|
||||||
/* TYPES *********************************************************************/
|
/* TYPES *********************************************************************/
|
||||||
|
|
||||||
|
typedef struct _SERVICE_THREAD_PARAMSA
|
||||||
|
{
|
||||||
|
LPSERVICE_MAIN_FUNCTIONA lpServiceMain;
|
||||||
|
DWORD dwArgCount;
|
||||||
|
LPSTR *lpArgVector;
|
||||||
|
} SERVICE_THREAD_PARAMSA, *PSERVICE_THREAD_PARAMSA;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _SERVICE_THREAD_PARAMSW
|
||||||
|
{
|
||||||
|
LPSERVICE_MAIN_FUNCTIONW lpServiceMain;
|
||||||
|
DWORD dwArgCount;
|
||||||
|
LPWSTR *lpArgVector;
|
||||||
|
} SERVICE_THREAD_PARAMSW, *PSERVICE_THREAD_PARAMSW;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _ACTIVE_SERVICE
|
typedef struct _ACTIVE_SERVICE
|
||||||
{
|
{
|
||||||
SERVICE_STATUS_HANDLE hServiceStatus;
|
SERVICE_STATUS_HANDLE hServiceStatus;
|
||||||
UNICODE_STRING ServiceName;
|
UNICODE_STRING ServiceName;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
LPSERVICE_MAIN_FUNCTIONA lpFuncA;
|
SERVICE_THREAD_PARAMSA A;
|
||||||
LPSERVICE_MAIN_FUNCTIONW lpFuncW;
|
SERVICE_THREAD_PARAMSW W;
|
||||||
} Main;
|
} ThreadParams;
|
||||||
LPHANDLER_FUNCTION HandlerFunction;
|
LPHANDLER_FUNCTION HandlerFunction;
|
||||||
LPHANDLER_FUNCTION_EX HandlerFunctionEx;
|
LPHANDLER_FUNCTION_EX HandlerFunctionEx;
|
||||||
LPVOID HandlerContext;
|
LPVOID HandlerContext;
|
||||||
BOOL bUnicode;
|
BOOL bUnicode;
|
||||||
LPWSTR Arguments;
|
|
||||||
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
|
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,122 +163,40 @@ ScLookupServiceByServiceName(LPCWSTR lpServiceName)
|
||||||
static DWORD WINAPI
|
static DWORD WINAPI
|
||||||
ScServiceMainStub(LPVOID Context)
|
ScServiceMainStub(LPVOID Context)
|
||||||
{
|
{
|
||||||
PACTIVE_SERVICE lpService;
|
PACTIVE_SERVICE lpService = (PACTIVE_SERVICE)Context;
|
||||||
DWORD dwArgCount = 0;
|
|
||||||
DWORD dwLength = 0;
|
|
||||||
DWORD dwLen;
|
|
||||||
LPWSTR lpPtr;
|
|
||||||
|
|
||||||
lpService = (PACTIVE_SERVICE)Context;
|
|
||||||
|
|
||||||
TRACE("ScServiceMainStub() called\n");
|
TRACE("ScServiceMainStub() called\n");
|
||||||
|
|
||||||
/* Count arguments */
|
/* Call the main service routine and free the arguments vector */
|
||||||
lpPtr = lpService->Arguments;
|
|
||||||
while (*lpPtr)
|
|
||||||
{
|
|
||||||
TRACE("arg: %S\n", lpPtr);
|
|
||||||
dwLen = wcslen(lpPtr) + 1;
|
|
||||||
dwArgCount++;
|
|
||||||
dwLength += dwLen;
|
|
||||||
lpPtr += dwLen;
|
|
||||||
}
|
|
||||||
TRACE("dwArgCount: %ld\ndwLength: %ld\n", dwArgCount, dwLength);
|
|
||||||
|
|
||||||
/* Build the argument vector and call the main service routine */
|
|
||||||
if (lpService->bUnicode)
|
if (lpService->bUnicode)
|
||||||
{
|
{
|
||||||
LPWSTR *lpArgVector;
|
(lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount,
|
||||||
LPWSTR Ptr;
|
lpService->ThreadParams.W.lpArgVector);
|
||||||
|
|
||||||
lpArgVector = HeapAlloc(GetProcessHeap(),
|
if (lpService->ThreadParams.A.lpArgVector != NULL)
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
(dwArgCount + 1) * sizeof(LPWSTR));
|
|
||||||
if (lpArgVector == NULL)
|
|
||||||
return ERROR_OUTOFMEMORY;
|
|
||||||
|
|
||||||
dwArgCount = 0;
|
|
||||||
Ptr = lpService->Arguments;
|
|
||||||
while (*Ptr)
|
|
||||||
{
|
{
|
||||||
lpArgVector[dwArgCount] = Ptr;
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
lpService->ThreadParams.W.lpArgVector);
|
||||||
|
|
||||||
dwArgCount++;
|
lpService->ThreadParams.W.lpArgVector = NULL;
|
||||||
Ptr += (wcslen(Ptr) + 1);
|
lpService->ThreadParams.W.dwArgCount = 0;
|
||||||
}
|
}
|
||||||
lpArgVector[dwArgCount] = NULL;
|
|
||||||
|
|
||||||
(lpService->Main.lpFuncW)(dwArgCount, lpArgVector);
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(),
|
|
||||||
0,
|
|
||||||
lpArgVector);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LPSTR *lpArgVector;
|
(lpService->ThreadParams.A.lpServiceMain)(lpService->ThreadParams.A.dwArgCount,
|
||||||
LPSTR Ptr;
|
lpService->ThreadParams.A.lpArgVector);
|
||||||
LPSTR AnsiString;
|
|
||||||
DWORD AnsiLength;
|
|
||||||
|
|
||||||
AnsiLength = WideCharToMultiByte(CP_ACP,
|
if (lpService->ThreadParams.A.lpArgVector != NULL)
|
||||||
0,
|
|
||||||
lpService->Arguments,
|
|
||||||
dwLength,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
if (AnsiLength == 0)
|
|
||||||
return ERROR_INVALID_PARAMETER; /* ? */
|
|
||||||
|
|
||||||
AnsiString = HeapAlloc(GetProcessHeap(),
|
|
||||||
0,
|
|
||||||
AnsiLength + 1);
|
|
||||||
if (AnsiString == NULL)
|
|
||||||
return ERROR_OUTOFMEMORY;
|
|
||||||
|
|
||||||
WideCharToMultiByte(CP_ACP,
|
|
||||||
0,
|
|
||||||
lpService->Arguments,
|
|
||||||
dwLength,
|
|
||||||
AnsiString,
|
|
||||||
AnsiLength,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
AnsiString[AnsiLength] = ANSI_NULL;
|
|
||||||
|
|
||||||
lpArgVector = HeapAlloc(GetProcessHeap(),
|
|
||||||
0,
|
|
||||||
(dwArgCount + 1) * sizeof(LPSTR));
|
|
||||||
if (lpArgVector == NULL)
|
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(),
|
HeapFree(GetProcessHeap(),
|
||||||
0,
|
0,
|
||||||
AnsiString);
|
lpService->ThreadParams.A.lpArgVector);
|
||||||
return ERROR_OUTOFMEMORY;
|
|
||||||
|
lpService->ThreadParams.A.lpArgVector = NULL;
|
||||||
|
lpService->ThreadParams.A.dwArgCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwArgCount = 0;
|
|
||||||
Ptr = AnsiString;
|
|
||||||
while (*Ptr)
|
|
||||||
{
|
|
||||||
lpArgVector[dwArgCount] = Ptr;
|
|
||||||
|
|
||||||
dwArgCount++;
|
|
||||||
Ptr += (strlen(Ptr) + 1);
|
|
||||||
}
|
|
||||||
lpArgVector[dwArgCount] = NULL;
|
|
||||||
|
|
||||||
(lpService->Main.lpFuncA)(dwArgCount, lpArgVector);
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(),
|
|
||||||
0,
|
|
||||||
lpArgVector);
|
|
||||||
HeapFree(GetProcessHeap(),
|
|
||||||
0,
|
|
||||||
AnsiString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
@ -350,9 +283,8 @@ ScStartService(PACTIVE_SERVICE lpService,
|
||||||
{
|
{
|
||||||
HANDLE ThreadHandle;
|
HANDLE ThreadHandle;
|
||||||
DWORD ThreadId;
|
DWORD ThreadId;
|
||||||
PWSTR pServiceName;
|
LPWSTR *lpArgW;
|
||||||
PWSTR Ptr;
|
DWORD i;
|
||||||
DWORD dwArgumentsSize;
|
|
||||||
|
|
||||||
TRACE("ScStartService() called\n");
|
TRACE("ScStartService() called\n");
|
||||||
TRACE("Size: %lu\n", ControlPacket->dwSize);
|
TRACE("Size: %lu\n", ControlPacket->dwSize);
|
||||||
|
@ -361,43 +293,106 @@ ScStartService(PACTIVE_SERVICE lpService,
|
||||||
/* Set the service status handle */
|
/* Set the service status handle */
|
||||||
lpService->hServiceStatus = ControlPacket->hServiceStatus;
|
lpService->hServiceStatus = ControlPacket->hServiceStatus;
|
||||||
|
|
||||||
pServiceName = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
|
if (lpService->bUnicode == TRUE)
|
||||||
|
{
|
||||||
|
lpService->ThreadParams.W.dwArgCount = ControlPacket->dwArgumentsCount;
|
||||||
|
lpService->ThreadParams.W.lpArgVector = NULL;
|
||||||
|
|
||||||
/* Get the service name size */
|
if (ControlPacket->dwArgumentsOffset > 0)
|
||||||
dwArgumentsSize = (wcslen(pServiceName) + 1) * sizeof(WCHAR);
|
{
|
||||||
|
lpService->ThreadParams.W.lpArgVector =
|
||||||
|
HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
ControlPacket->dwSize - ControlPacket->dwArgumentsOffset);
|
||||||
|
if (lpService->ThreadParams.W.lpArgVector == NULL)
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
/* Get the size of the service start arguments */
|
memcpy(lpService->ThreadParams.W.lpArgVector,
|
||||||
if (ControlPacket->dwArgumentsCount > 0 &&
|
((PBYTE)ControlPacket + ControlPacket->dwArgumentsOffset),
|
||||||
ControlPacket->dwArgumentsOffset != 0)
|
ControlPacket->dwSize - ControlPacket->dwArgumentsOffset);
|
||||||
|
|
||||||
|
lpArgW = lpService->ThreadParams.W.lpArgVector;
|
||||||
|
for (i = 0; i < lpService->ThreadParams.W.dwArgCount; i++)
|
||||||
|
{
|
||||||
|
*lpArgW = (LPWSTR)((ULONG_PTR)lpArgW + (ULONG_PTR)*lpArgW);
|
||||||
|
lpArgW++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
|
lpService->ThreadParams.A.dwArgCount = 0;
|
||||||
|
lpService->ThreadParams.A.lpArgVector = NULL;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
dwArgumentSize += (wcslen(...) + 1) * sizeof(WCHAR);
|
LPSTR *lpArgVector;
|
||||||
|
LPSTR Ptr;
|
||||||
|
LPSTR AnsiString;
|
||||||
|
DWORD AnsiLength;
|
||||||
|
|
||||||
|
AnsiLength = WideCharToMultiByte(CP_ACP,
|
||||||
|
0,
|
||||||
|
lpService->Arguments,
|
||||||
|
dwLength,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (AnsiLength == 0)
|
||||||
|
return ERROR_INVALID_PARAMETER; /* ? */
|
||||||
|
|
||||||
|
AnsiString = HeapAlloc(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
AnsiLength + 1);
|
||||||
|
if (AnsiString == NULL)
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
|
WideCharToMultiByte(CP_ACP,
|
||||||
|
0,
|
||||||
|
lpService->Arguments,
|
||||||
|
dwLength,
|
||||||
|
AnsiString,
|
||||||
|
AnsiLength,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
AnsiString[AnsiLength] = ANSI_NULL;
|
||||||
|
|
||||||
|
lpArgVector = HeapAlloc(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
(dwArgCount + 1) * sizeof(LPSTR));
|
||||||
|
if (lpArgVector == NULL)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
AnsiString);
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwArgCount = 0;
|
||||||
|
Ptr = AnsiString;
|
||||||
|
while (*Ptr)
|
||||||
|
{
|
||||||
|
lpArgVector[dwArgCount] = Ptr;
|
||||||
|
|
||||||
|
dwArgCount++;
|
||||||
|
Ptr += (strlen(Ptr) + 1);
|
||||||
|
}
|
||||||
|
lpArgVector[dwArgCount] = NULL;
|
||||||
|
|
||||||
|
(lpService->ThreadParams.A.lpServiceMain)(dwArgCount, lpArgVector);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
lpArgVector);
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
AnsiString);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
lpService->Arguments = HeapAlloc(GetProcessHeap(),
|
/* Invoke the services entry point and implement the command loop */
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
dwArgumentsSize + sizeof(WCHAR));
|
|
||||||
if (lpService->Arguments == NULL)
|
|
||||||
return ERROR_OUTOFMEMORY;
|
|
||||||
|
|
||||||
Ptr = lpService->Arguments;
|
|
||||||
|
|
||||||
/* Add the service name as first argument */
|
|
||||||
wcscpy(Ptr, pServiceName);
|
|
||||||
Ptr += (wcslen(pServiceName) + 1);
|
|
||||||
|
|
||||||
/* Add service start arguments */
|
|
||||||
if (ControlPacket->dwArgumentsCount > 0 &&
|
|
||||||
ControlPacket->dwArgumentsOffset != 0)
|
|
||||||
{
|
|
||||||
/* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
*Ptr = 0;
|
|
||||||
|
|
||||||
/* invoke the services entry point and implement the command loop */
|
|
||||||
ThreadHandle = CreateThread(NULL,
|
ThreadHandle = CreateThread(NULL,
|
||||||
0,
|
0,
|
||||||
ScServiceMainStub,
|
ScServiceMainStub,
|
||||||
|
@ -405,7 +400,33 @@ ScStartService(PACTIVE_SERVICE lpService,
|
||||||
CREATE_SUSPENDED,
|
CREATE_SUSPENDED,
|
||||||
&ThreadId);
|
&ThreadId);
|
||||||
if (ThreadHandle == NULL)
|
if (ThreadHandle == NULL)
|
||||||
|
{
|
||||||
|
/* Free the arguments vector */
|
||||||
|
if (lpService->bUnicode)
|
||||||
|
{
|
||||||
|
if (lpService->ThreadParams.W.lpArgVector != NULL)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
lpService->ThreadParams.W.lpArgVector);
|
||||||
|
lpService->ThreadParams.W.lpArgVector = NULL;
|
||||||
|
lpService->ThreadParams.W.dwArgCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lpService->ThreadParams.A.lpArgVector != NULL)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
lpService->ThreadParams.A.lpArgVector);
|
||||||
|
lpService->ThreadParams.A.lpArgVector = NULL;
|
||||||
|
lpService->ThreadParams.A.dwArgCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ERROR_SERVICE_NO_THREAD;
|
return ERROR_SERVICE_NO_THREAD;
|
||||||
|
}
|
||||||
|
|
||||||
ResumeThread(ThreadHandle);
|
ResumeThread(ThreadHandle);
|
||||||
CloseHandle(ThreadHandle);
|
CloseHandle(ThreadHandle);
|
||||||
|
@ -432,13 +453,6 @@ ScControlService(PACTIVE_SERVICE lpService,
|
||||||
(lpService->HandlerFunctionEx)(ControlPacket->dwControl, 0, NULL, NULL);
|
(lpService->HandlerFunctionEx)(ControlPacket->dwControl, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ControlPacket->dwControl == SERVICE_CONTROL_STOP)
|
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(),
|
|
||||||
0,
|
|
||||||
lpService->Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("ScControlService() done\n");
|
TRACE("ScControlService() done\n");
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
@ -820,7 +834,7 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
|
||||||
{
|
{
|
||||||
RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
|
RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
|
||||||
lpServiceStartTable[i].lpServiceName);
|
lpServiceStartTable[i].lpServiceName);
|
||||||
lpActiveServices[i].Main.lpFuncA = lpServiceStartTable[i].lpServiceProc;
|
lpActiveServices[i].ThreadParams.A.lpServiceMain = lpServiceStartTable[i].lpServiceProc;
|
||||||
lpActiveServices[i].hServiceStatus = 0;
|
lpActiveServices[i].hServiceStatus = 0;
|
||||||
lpActiveServices[i].bUnicode = FALSE;
|
lpActiveServices[i].bUnicode = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -915,7 +929,7 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
|
||||||
{
|
{
|
||||||
RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
|
RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
|
||||||
lpServiceStartTable[i].lpServiceName);
|
lpServiceStartTable[i].lpServiceName);
|
||||||
lpActiveServices[i].Main.lpFuncW = lpServiceStartTable[i].lpServiceProc;
|
lpActiveServices[i].ThreadParams.W.lpServiceMain = lpServiceStartTable[i].lpServiceProc;
|
||||||
lpActiveServices[i].hServiceStatus = 0;
|
lpActiveServices[i].hServiceStatus = 0;
|
||||||
lpActiveServices[i].bUnicode = TRUE;
|
lpActiveServices[i].bUnicode = TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue