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 = ../..
@ -8,6 +8,8 @@ TARGET_NAME = advapi32
TARGET_SDKLIBS = ntdll.a kernel32.a
# TARGET_CFLAGS = -DUNICODE
TARGET_BASE = 0x77dc0000
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
* PROJECT: ReactOS system libraries
@ -100,18 +100,18 @@ SC_HANDLE
STDCALL
CreateServiceA(
SC_HANDLE hSCManager,
LPCTSTR lpServiceName,
LPCTSTR lpDisplayName,
LPCSTR lpServiceName,
LPCSTR lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCTSTR lpBinaryPathName,
LPCTSTR lpLoadOrderGroup,
LPCSTR lpBinaryPathName,
LPCSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCTSTR lpDependencies,
LPCTSTR lpServiceStartName,
LPCTSTR lpPassword
LPCSTR lpDependencies,
LPCSTR lpServiceStartName,
LPCSTR lpPassword
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
@ -410,35 +410,112 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
LPCWSTR lpDatabaseName,
DWORD dwDesiredAccess)
{
HANDLE h;
if (lpMachineName == NULL ||
wcslen(lpMachineName) == 0)
{
if (lpDatabaseName != NULL &&
wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
{
return(NULL);
}
HANDLE hPipe;
DWORD dwMode;
BOOL fSuccess;
LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
if (lpMachineName == NULL || wcslen(lpMachineName) == 0)
{
if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
{
return(NULL);
}
h = CreateFileW(L"\\\\.\\pipe\\ntsrvctrl",
dwDesiredAccess,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (h == INVALID_HANDLE_VALUE)
{
return(NULL);
}
return(h);
}
else
{
return(NULL);
}
// Try to open a named pipe; wait for it, if necessary
while (1)
{
hPipe = CreateFileW(
lpszPipeName, // pipe name
dwDesiredAccess,
0, // no sharing
NULL, // no security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
// Break if the pipe handle is valid
if (hPipe != INVALID_HANDLE_VALUE)
break;
// 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
* PROJECT: ReactOS system libraries
@ -19,7 +19,10 @@
typedef struct
{
DWORD ThreadId;
DWORD ThreadId;
UNICODE_STRING ServiceName;
SERVICE_STATUS ServiceStatus;
LPHANDLER_FUNCTION Handler;
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
/* GLOBALS *******************************************************************/
@ -30,6 +33,39 @@ static PHANDLE ActiveServicesThreadHandles;
/* 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
*/
@ -43,12 +79,16 @@ SERVICE_STATUS_HANDLE STDCALL RegisterServiceCtrlHandlerA(
SERVICE_STATUS_HANDLE SHandle;
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,
lpHandlerProc);
RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceNameU.Buffer);
RtlFreeUnicodeString(&ServiceNameU);
return(SHandle);
}
@ -61,8 +101,15 @@ SERVICE_STATUS_HANDLE STDCALL RegisterServiceCtrlHandlerW(
LPCWSTR lpServiceName,
LPHANDLER_FUNCTION lpHandlerProc)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
PACTIVE_SERVICE Service;
/* 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
SetServiceStatus(
SERVICE_STATUS_HANDLE hServiceStatus,
LPSERVICE_STATUS lpServiceStatus
)
LPSERVICE_STATUS lpServiceStatus)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
PACTIVE_SERVICE Service;
Service = ScLookupServiceByThreadId((DWORD)hServiceStatus);
if (!Service)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
RtlCopyMemory(
&Service->ServiceStatus,
lpServiceStatus,
sizeof(SERVICE_STATUS));
return TRUE;
}
/**********************************************************************
* StartServiceCtrlDispatcherA
*/
BOOL STDCALL StartServiceCtrlDispatcherA(
LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
{
LPSERVICE_TABLE_ENTRYW ServiceStartTableW;
ANSI_STRING ServiceNameA;
UNICODE_STRING ServiceNameW;
ULONG i;
ULONG Count;
BOOL b;
i = 0;
while (lpServiceStartTable[i].lpServiceProc != NULL)
{
i++;
}
Count = i;
ServiceStartTableW = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(SERVICE_TABLE_ENTRYW) * Count);
for (i = 0; i < Count; i++)
{
RtlInitAnsiString(&ServiceNameA,
lpServiceStartTable[i].lpServiceName);
RtlAnsiStringToUnicodeString(&ServiceNameW,
&ServiceNameA,
TRUE);
ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer;
ServiceStartTableW[i].lpServiceProc =
lpServiceStartTable[i].lpServiceProc;
}
b = StartServiceCtrlDispatcherW(ServiceStartTableW);
for (i = 0; i < Count; i++)
{
RtlFreeHeap(RtlGetProcessHeap(),
0,
ServiceStartTableW[i].lpServiceName);
}
RtlFreeHeap(RtlGetProcessHeap(),
0,
ServiceStartTableW);
return(b);
LPSERVICE_TABLE_ENTRYW ServiceStartTableW;
ANSI_STRING ServiceNameA;
UNICODE_STRING ServiceNameW;
ULONG i, j;
ULONG Count;
BOOL b;
i = 0;
while (lpServiceStartTable[i].lpServiceProc != NULL)
{
i++;
}
Count = i;
ServiceStartTableW = RtlAllocateHeap(
RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(SERVICE_TABLE_ENTRYW) * Count);
for (i = 0; i < Count; i++)
{
RtlInitAnsiString(
&ServiceNameA,
lpServiceStartTable[i].lpServiceName);
if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(
&ServiceNameW,
&ServiceNameA,
TRUE)))
{
for (j = 0; j < i; j++)
{
RtlInitUnicodeString(
&ServiceNameW,
ServiceStartTableW[j].lpServiceName);
RtlFreeUnicodeString(&ServiceNameW);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW);
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer;
ServiceStartTableW[i].lpServiceProc =
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(
LPSERVICE_TABLE_ENTRYW lpServiceStartTable)
{
ULONG i;
HANDLE h;
DWORD Tid;
DWORD r;
i = 0;
while (lpServiceStartTable[i].lpServiceProc != NULL)
{
i++;
}
ActiveServiceCount = i;
ActiveServices = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
ActiveServiceCount *
sizeof(ACTIVE_SERVICE));
ActiveServicesThreadHandles = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
(ActiveServiceCount + 1) *
sizeof(HANDLE));
for (i = 0; i<ActiveServiceCount; i++)
{
h = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)lpServiceStartTable[i].lpServiceProc,
NULL,
0,
&Tid);
if (h == INVALID_HANDLE_VALUE)
{
return(FALSE);
}
ActiveServicesThreadHandles[i + 1] = h;
ActiveServices[i].ThreadId = Tid;
}
while (ActiveServiceCount > 0)
{
r = WaitForMultipleObjects(ActiveServiceCount + 1,
ActiveServicesThreadHandles,
FALSE,
INFINITE);
if (r == WAIT_OBJECT_0)
{
/* 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];
memcpy(&ActiveServices[r - WAIT_OBJECT_0 - 2],
&ActiveServices[ActiveServiceCount],
sizeof(ACTIVE_SERVICE));
}
else
{
/* Bail */
}
}
return(TRUE);
ULONG i;
HANDLE h;
DWORD Tid;
DWORD r;
i = 0;
while (lpServiceStartTable[i].lpServiceProc != NULL)
{
i++;
}
ActiveServiceCount = i;
ActiveServices = RtlAllocateHeap(
RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
ActiveServiceCount *
sizeof(ACTIVE_SERVICE));
if (!ActiveServices)
{
return FALSE;
}
ActiveServicesThreadHandles = RtlAllocateHeap(
RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
(ActiveServiceCount + 1) *
sizeof(HANDLE));
if (!ActiveServicesThreadHandles)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices);
ActiveServices = NULL;
return FALSE;
}
for (i = 0; i<ActiveServiceCount; i++)
{
h = CreateThread(
NULL,
0,
ScServiceMainStub,
lpServiceStartTable[i].lpServiceProc,
0,
&Tid);
if (h == INVALID_HANDLE_VALUE)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServicesThreadHandles);
ActiveServicesThreadHandles = NULL;
RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices);
ActiveServices = NULL;
return(FALSE);
}
ActiveServicesThreadHandles[i + 1] = h;
ActiveServices[i].ThreadId = Tid;
}
while (ActiveServiceCount > 0)
{
r = WaitForMultipleObjects(
ActiveServiceCount + 1,
ActiveServicesThreadHandles,
FALSE,
INFINITE);
if (r == WAIT_OBJECT_0)
{
/* 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
* PROJECT: ReactOS system libraries
@ -345,25 +345,29 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
NPFS_SET_STATE SetState;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
#if 0
Status = NtFsControlFile(hNamedPipe,
NULL,
NULL,
NULL,
&Iosb,
FSCTL_GET_STATE,
FSCTL_PIPE_GET_STATE,
NULL,
0,
&GetState,
sizeof(GetState));
if (!NT_SUCCESS(Status))
sizeof(NPFS_GET_STATE));
if (Status == STATUS_PENDING)
{
SetLastErrorByStatus (Status);
return(FALSE);
Status = NtWaitForSingleObject(hNamedPipe,
FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
#endif
if (lpMode != NULL)
{
if ((*lpMode) & PIPE_READMODE_MESSAGE)
@ -410,25 +414,30 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
{
SetState.Timeout = GetState.Timeout;
}
#if 0
Status = NtFsControlFile(hNamedPipe,
NULL,
NULL,
NULL,
&Iosb,
FSCTL_SET_STATE,
FSCTL_PIPE_SET_STATE,
&SetState,
sizeof(SetState),
sizeof(NPFS_SET_STATE),
NULL,
0);
if (!NT_SUCCESS(Status))
if (Status == STATUS_PENDING)
{
SetLastErrorByStatus (Status);
return(FALSE);
Status = NtWaitForSingleObject(hNamedPipe,
FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
#endif
return(TRUE);
return(TRUE);
}