Open named pipe to SCM

svn path=/trunk/; revision=2310
This commit is contained in:
Casper Hornstrup 2001-10-21 19:06:42 +00:00
parent f611cbbe42
commit 75ebd197fa
4 changed files with 354 additions and 176 deletions

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.19 2001/08/21 20:13:05 chorns Exp $ # $Id: makefile,v 1.20 2001/10/21 19:06:42 chorns Exp $
PATH_TO_TOP = ../.. PATH_TO_TOP = ../..
@ -8,6 +8,8 @@ TARGET_NAME = advapi32
TARGET_SDKLIBS = ntdll.a kernel32.a TARGET_SDKLIBS = ntdll.a kernel32.a
# TARGET_CFLAGS = -DUNICODE
TARGET_BASE = 0x77dc0000 TARGET_BASE = 0x77dc0000
MISC_OBJECTS=\ MISC_OBJECTS=\

View file

@ -1,4 +1,4 @@
/* $Id: scm.c,v 1.7 2001/06/25 14:19:56 ekohl Exp $ /* $Id: scm.c,v 1.8 2001/10/21 19:06:42 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -100,18 +100,18 @@ SC_HANDLE
STDCALL STDCALL
CreateServiceA( CreateServiceA(
SC_HANDLE hSCManager, SC_HANDLE hSCManager,
LPCTSTR lpServiceName, LPCSTR lpServiceName,
LPCTSTR lpDisplayName, LPCSTR lpDisplayName,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
DWORD dwServiceType, DWORD dwServiceType,
DWORD dwStartType, DWORD dwStartType,
DWORD dwErrorControl, DWORD dwErrorControl,
LPCTSTR lpBinaryPathName, LPCSTR lpBinaryPathName,
LPCTSTR lpLoadOrderGroup, LPCSTR lpLoadOrderGroup,
LPDWORD lpdwTagId, LPDWORD lpdwTagId,
LPCTSTR lpDependencies, LPCSTR lpDependencies,
LPCTSTR lpServiceStartName, LPCSTR lpServiceStartName,
LPCTSTR lpPassword LPCSTR lpPassword
) )
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
@ -410,35 +410,112 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
LPCWSTR lpDatabaseName, LPCWSTR lpDatabaseName,
DWORD dwDesiredAccess) DWORD dwDesiredAccess)
{ {
HANDLE h; HANDLE hPipe;
DWORD dwMode;
if (lpMachineName == NULL || BOOL fSuccess;
wcslen(lpMachineName) == 0) LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
{
if (lpDatabaseName != NULL && if (lpMachineName == NULL || wcslen(lpMachineName) == 0)
wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) {
{ if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
return(NULL); {
} return(NULL);
}
h = CreateFileW(L"\\\\.\\pipe\\ntsrvctrl", // Try to open a named pipe; wait for it, if necessary
dwDesiredAccess, while (1)
0, {
NULL, hPipe = CreateFileW(
OPEN_EXISTING, lpszPipeName, // pipe name
0, dwDesiredAccess,
NULL); 0, // no sharing
if (h == INVALID_HANDLE_VALUE) NULL, // no security attributes
{ OPEN_EXISTING, // opens existing pipe
return(NULL); 0, // default attributes
} NULL); // no template file
return(h); // Break if the pipe handle is valid
}
else if (hPipe != INVALID_HANDLE_VALUE)
{ break;
return(NULL);
} // Exit if an error other than ERROR_PIPE_BUSY occurs
if (GetLastError() != ERROR_PIPE_BUSY)
{
return(NULL);
}
// All pipe instances are busy, so wait for 20 seconds
if (!WaitNamedPipeW(lpszPipeName, 20000))
{
return(NULL);
}
}
// The pipe connected; change to message-read mode
dwMode = PIPE_READMODE_MESSAGE;
fSuccess = SetNamedPipeHandleState(
hPipe, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
if (!fSuccess)
{
CloseHandle(hPipe);
return(NULL);
}
#if 0
// Send a message to the pipe server
lpvMessage = (argc > 1) ? argv[1] : "default message";
fSuccess = WriteFile(
hPipe, // pipe handle
lpvMessage, // message
strlen(lpvMessage) + 1, // message length
&cbWritten, // bytes written
NULL); // not overlapped
if (!fSuccess)
{
CloseHandle(hPipe);
return(NULL);
}
do
{
// Read from the pipe
fSuccess = ReadFile(
hPipe, // pipe handle
chBuf, // buffer to receive reply
512, // size of buffer
&cbRead, // number of bytes read
NULL); // not overlapped
if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
break;
// Reply from the pipe is written to STDOUT.
if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
chBuf, cbRead, &cbWritten, NULL))
{
break;
}
} while (!fSuccess); // repeat loop if ERROR_MORE_DATA
//CloseHandle(hPipe);
#endif
return(hPipe);
}
else
{
/* FIXME: Connect to remote SCM */
return(NULL);
}
} }

View file

@ -1,4 +1,4 @@
/* $Id: sctrl.c,v 1.2 2001/06/25 14:19:56 ekohl Exp $ /* $Id: sctrl.c,v 1.3 2001/10/21 19:06:42 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -19,7 +19,10 @@
typedef struct typedef struct
{ {
DWORD ThreadId; DWORD ThreadId;
UNICODE_STRING ServiceName;
SERVICE_STATUS ServiceStatus;
LPHANDLER_FUNCTION Handler;
} ACTIVE_SERVICE, *PACTIVE_SERVICE; } ACTIVE_SERVICE, *PACTIVE_SERVICE;
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
@ -30,6 +33,39 @@ static PHANDLE ActiveServicesThreadHandles;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
PACTIVE_SERVICE
ScLookupServiceByThreadId(
DWORD ThreadId)
{
DWORD i;
for (i = 0; i < ActiveServiceCount; i++)
{
if (ActiveServices[i].ThreadId == ThreadId)
{
return &ActiveServices[i];
}
}
return NULL;
}
DWORD
WINAPI
ScServiceMainStub(
LPVOID Context)
{
LPSERVICE_MAIN_FUNCTION lpServiceProc = (LPSERVICE_MAIN_FUNCTION)Context;
/* FIXME: Send argc and argv (from command line) as arguments */
(lpServiceProc)(0, NULL);
return ERROR_SUCCESS;
}
/********************************************************************** /**********************************************************************
* RegisterServiceCtrlHandlerA * RegisterServiceCtrlHandlerA
*/ */
@ -43,12 +79,16 @@ SERVICE_STATUS_HANDLE STDCALL RegisterServiceCtrlHandlerA(
SERVICE_STATUS_HANDLE SHandle; SERVICE_STATUS_HANDLE SHandle;
RtlInitAnsiString(&ServiceNameA, (LPSTR)lpServiceName); RtlInitAnsiString(&ServiceNameA, (LPSTR)lpServiceName);
RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE); if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
{
SetLastError(ERROR_OUTOFMEMORY);
return (SERVICE_STATUS_HANDLE)0;
}
SHandle = RegisterServiceCtrlHandlerW(ServiceNameU.Buffer, SHandle = RegisterServiceCtrlHandlerW(ServiceNameU.Buffer,
lpHandlerProc); lpHandlerProc);
RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceNameU.Buffer); RtlFreeUnicodeString(&ServiceNameU);
return(SHandle); return(SHandle);
} }
@ -61,8 +101,15 @@ SERVICE_STATUS_HANDLE STDCALL RegisterServiceCtrlHandlerW(
LPCWSTR lpServiceName, LPCWSTR lpServiceName,
LPHANDLER_FUNCTION lpHandlerProc) LPHANDLER_FUNCTION lpHandlerProc)
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); PACTIVE_SERVICE Service;
return 0;
/* FIXME: Locate active service entry from name */
Service = &ActiveServices[0];
Service->Handler = lpHandlerProc;
return (SERVICE_STATUS_HANDLE)Service->ThreadId;
} }
@ -102,61 +149,85 @@ BOOL
STDCALL STDCALL
SetServiceStatus( SetServiceStatus(
SERVICE_STATUS_HANDLE hServiceStatus, SERVICE_STATUS_HANDLE hServiceStatus,
LPSERVICE_STATUS lpServiceStatus LPSERVICE_STATUS lpServiceStatus)
)
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); PACTIVE_SERVICE Service;
return FALSE;
Service = ScLookupServiceByThreadId((DWORD)hServiceStatus);
if (!Service)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
RtlCopyMemory(
&Service->ServiceStatus,
lpServiceStatus,
sizeof(SERVICE_STATUS));
return TRUE;
} }
/********************************************************************** /**********************************************************************
* StartServiceCtrlDispatcherA * StartServiceCtrlDispatcherA
*/ */
BOOL STDCALL StartServiceCtrlDispatcherA( BOOL STDCALL StartServiceCtrlDispatcherA(
LPSERVICE_TABLE_ENTRYA lpServiceStartTable) LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
{ {
LPSERVICE_TABLE_ENTRYW ServiceStartTableW; LPSERVICE_TABLE_ENTRYW ServiceStartTableW;
ANSI_STRING ServiceNameA; ANSI_STRING ServiceNameA;
UNICODE_STRING ServiceNameW; UNICODE_STRING ServiceNameW;
ULONG i; ULONG i, j;
ULONG Count; ULONG Count;
BOOL b; BOOL b;
i = 0; i = 0;
while (lpServiceStartTable[i].lpServiceProc != NULL) while (lpServiceStartTable[i].lpServiceProc != NULL)
{ {
i++; i++;
} }
Count = i; Count = i;
ServiceStartTableW = RtlAllocateHeap(RtlGetProcessHeap(), ServiceStartTableW = RtlAllocateHeap(
HEAP_ZERO_MEMORY, RtlGetProcessHeap(),
sizeof(SERVICE_TABLE_ENTRYW) * Count); HEAP_ZERO_MEMORY,
for (i = 0; i < Count; i++) sizeof(SERVICE_TABLE_ENTRYW) * Count);
{ for (i = 0; i < Count; i++)
RtlInitAnsiString(&ServiceNameA, {
lpServiceStartTable[i].lpServiceName); RtlInitAnsiString(
RtlAnsiStringToUnicodeString(&ServiceNameW, &ServiceNameA,
&ServiceNameA, lpServiceStartTable[i].lpServiceName);
TRUE); if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(
ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer; &ServiceNameW,
ServiceStartTableW[i].lpServiceProc = &ServiceNameA,
lpServiceStartTable[i].lpServiceProc; TRUE)))
} {
for (j = 0; j < i; j++)
b = StartServiceCtrlDispatcherW(ServiceStartTableW); {
RtlInitUnicodeString(
for (i = 0; i < Count; i++) &ServiceNameW,
{ ServiceStartTableW[j].lpServiceName);
RtlFreeHeap(RtlGetProcessHeap(), RtlFreeUnicodeString(&ServiceNameW);
0, }
ServiceStartTableW[i].lpServiceName); RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW);
} SetLastError(ERROR_OUTOFMEMORY);
RtlFreeHeap(RtlGetProcessHeap(), return FALSE;
0, }
ServiceStartTableW); ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer;
ServiceStartTableW[i].lpServiceProc =
return(b); lpServiceStartTable[i].lpServiceProc;
}
b = StartServiceCtrlDispatcherW(ServiceStartTableW);
for (i = 0; i < Count; i++)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW[i].lpServiceName);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW);
return b;
} }
@ -166,71 +237,90 @@ BOOL STDCALL StartServiceCtrlDispatcherA(
BOOL STDCALL StartServiceCtrlDispatcherW( BOOL STDCALL StartServiceCtrlDispatcherW(
LPSERVICE_TABLE_ENTRYW lpServiceStartTable) LPSERVICE_TABLE_ENTRYW lpServiceStartTable)
{ {
ULONG i; ULONG i;
HANDLE h; HANDLE h;
DWORD Tid; DWORD Tid;
DWORD r; DWORD r;
i = 0; i = 0;
while (lpServiceStartTable[i].lpServiceProc != NULL) while (lpServiceStartTable[i].lpServiceProc != NULL)
{ {
i++; i++;
} }
ActiveServiceCount = i; ActiveServiceCount = i;
ActiveServices = RtlAllocateHeap(GetProcessHeap(), ActiveServices = RtlAllocateHeap(
HEAP_ZERO_MEMORY, RtlGetProcessHeap(),
ActiveServiceCount * HEAP_ZERO_MEMORY,
sizeof(ACTIVE_SERVICE)); ActiveServiceCount *
ActiveServicesThreadHandles = RtlAllocateHeap(GetProcessHeap(), sizeof(ACTIVE_SERVICE));
HEAP_ZERO_MEMORY, if (!ActiveServices)
(ActiveServiceCount + 1) * {
sizeof(HANDLE)); return FALSE;
}
for (i = 0; i<ActiveServiceCount; i++)
{ ActiveServicesThreadHandles = RtlAllocateHeap(
h = CreateThread(NULL, RtlGetProcessHeap(),
0, HEAP_ZERO_MEMORY,
(LPTHREAD_START_ROUTINE)lpServiceStartTable[i].lpServiceProc, (ActiveServiceCount + 1) *
NULL, sizeof(HANDLE));
0, if (!ActiveServicesThreadHandles)
&Tid); {
if (h == INVALID_HANDLE_VALUE) RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices);
{ ActiveServices = NULL;
return(FALSE); return FALSE;
} }
ActiveServicesThreadHandles[i + 1] = h;
ActiveServices[i].ThreadId = Tid; for (i = 0; i<ActiveServiceCount; i++)
} {
h = CreateThread(
while (ActiveServiceCount > 0) NULL,
{ 0,
r = WaitForMultipleObjects(ActiveServiceCount + 1, ScServiceMainStub,
ActiveServicesThreadHandles, lpServiceStartTable[i].lpServiceProc,
FALSE, 0,
INFINITE); &Tid);
if (r == WAIT_OBJECT_0) if (h == INVALID_HANDLE_VALUE)
{ {
/* Received message from the scm */ RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServicesThreadHandles);
} ActiveServicesThreadHandles = NULL;
else if (r > WAIT_OBJECT_0 && RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices);
r < (WAIT_OBJECT_0 + ActiveServiceCount)) ActiveServices = NULL;
{ return(FALSE);
/* A service died */ }
ActiveServicesThreadHandles[i + 1] = h;
ActiveServiceCount--; ActiveServices[i].ThreadId = Tid;
ActiveServicesThreadHandles[r - WAIT_OBJECT_0 - 1] = }
ActiveServicesThreadHandles[ActiveServiceCount + 1];
memcpy(&ActiveServices[r - WAIT_OBJECT_0 - 2], while (ActiveServiceCount > 0)
&ActiveServices[ActiveServiceCount], {
sizeof(ACTIVE_SERVICE)); r = WaitForMultipleObjects(
} ActiveServiceCount + 1,
else ActiveServicesThreadHandles,
{ FALSE,
/* Bail */ INFINITE);
} if (r == WAIT_OBJECT_0)
} {
return(TRUE); /* Received message from the scm */
}
else if (r > WAIT_OBJECT_0 && r < (WAIT_OBJECT_0 + ActiveServiceCount))
{
/* A service died */
ActiveServiceCount--;
ActiveServicesThreadHandles[r - WAIT_OBJECT_0 - 1] =
ActiveServicesThreadHandles[ActiveServiceCount + 1];
RtlCopyMemory(
&ActiveServices[r - WAIT_OBJECT_0 - 2],
&ActiveServices[ActiveServiceCount],
sizeof(ACTIVE_SERVICE));
}
else
{
/* Bail */
}
}
return TRUE;
} }

View file

@ -1,4 +1,4 @@
/* $Id: npipe.c,v 1.7 2001/10/20 15:28:03 ekohl Exp $ /* $Id: npipe.c,v 1.8 2001/10/21 19:06:42 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -345,25 +345,29 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
NPFS_SET_STATE SetState; NPFS_SET_STATE SetState;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
NTSTATUS Status; NTSTATUS Status;
#if 0
Status = NtFsControlFile(hNamedPipe, Status = NtFsControlFile(hNamedPipe,
NULL, NULL,
NULL, NULL,
NULL, NULL,
&Iosb, &Iosb,
FSCTL_GET_STATE, FSCTL_PIPE_GET_STATE,
NULL, NULL,
0, 0,
&GetState, &GetState,
sizeof(GetState)); sizeof(NPFS_GET_STATE));
if (!NT_SUCCESS(Status)) if (Status == STATUS_PENDING)
{ {
SetLastErrorByStatus (Status); Status = NtWaitForSingleObject(hNamedPipe,
return(FALSE); FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
} }
#endif
if (lpMode != NULL) if (lpMode != NULL)
{ {
if ((*lpMode) & PIPE_READMODE_MESSAGE) if ((*lpMode) & PIPE_READMODE_MESSAGE)
@ -410,25 +414,30 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
{ {
SetState.Timeout = GetState.Timeout; SetState.Timeout = GetState.Timeout;
} }
#if 0
Status = NtFsControlFile(hNamedPipe, Status = NtFsControlFile(hNamedPipe,
NULL, NULL,
NULL, NULL,
NULL, NULL,
&Iosb, &Iosb,
FSCTL_SET_STATE, FSCTL_PIPE_SET_STATE,
&SetState, &SetState,
sizeof(SetState), sizeof(NPFS_SET_STATE),
NULL, NULL,
0); 0);
if (!NT_SUCCESS(Status)) if (Status == STATUS_PENDING)
{ {
SetLastErrorByStatus (Status); Status = NtWaitForSingleObject(hNamedPipe,
return(FALSE); FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
} }
#endif
return(TRUE); return(TRUE);
} }