mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
423 lines
13 KiB
423 lines
13 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
srvloadr.c
|
|
|
|
Abstract:
|
|
|
|
This is the server DLL loader module for the Server side of the Client
|
|
Server Runtime Subsystem (CSRSS)
|
|
|
|
Author:
|
|
|
|
Steve Wood (stevewo) 08-Oct-1990
|
|
|
|
Environment:
|
|
|
|
User Mode Only
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "csrsrv.h"
|
|
|
|
EXCEPTION_DISPOSITION
|
|
CsrUnhandledExceptionFilter(
|
|
struct _EXCEPTION_POINTERS *ExceptionInfo
|
|
)
|
|
{
|
|
|
|
UNICODE_STRING UnicodeParameter;
|
|
ULONG Parameters[ 4 ];
|
|
ULONG Response;
|
|
BOOLEAN WasEnabled;
|
|
NTSTATUS Status;
|
|
|
|
//
|
|
// Terminating will cause sm's wait to sense that we crashed. This will
|
|
// result in a clean shutdown due to sm's hard error logic
|
|
//
|
|
|
|
//
|
|
// We are hosed, so raise a fata system error to shutdown the system.
|
|
// (Basically a user mode KeBugCheck).
|
|
//
|
|
|
|
Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
|
|
(BOOLEAN)TRUE,
|
|
TRUE,
|
|
&WasEnabled
|
|
);
|
|
|
|
if (Status == STATUS_NO_TOKEN) {
|
|
|
|
//
|
|
// No thread token, use the process token
|
|
//
|
|
|
|
Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
|
|
(BOOLEAN)TRUE,
|
|
FALSE,
|
|
&WasEnabled
|
|
);
|
|
}
|
|
|
|
RtlInitUnicodeString( &UnicodeParameter, L"Windows SubSystem" );
|
|
Parameters[ 0 ] = (ULONG)&UnicodeParameter;
|
|
Parameters[ 1 ] = (ULONG)ExceptionInfo->ExceptionRecord->ExceptionCode;
|
|
Parameters[ 2 ] = (ULONG)ExceptionInfo->ExceptionRecord->ExceptionAddress;
|
|
Parameters[ 3 ] = (ULONG)ExceptionInfo->ContextRecord;
|
|
Status = NtRaiseHardError( STATUS_SYSTEM_PROCESS_TERMINATED,
|
|
4,
|
|
1,
|
|
Parameters,
|
|
OptionShutdownSystem,
|
|
&Response
|
|
);
|
|
|
|
//
|
|
// If this returns, giveup
|
|
//
|
|
|
|
NtTerminateProcess(NtCurrentProcess(),ExceptionInfo->ExceptionRecord->ExceptionCode);
|
|
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
|
}
|
|
|
|
NTSTATUS
|
|
CsrLoadServerDll(
|
|
IN PCH ModuleName,
|
|
IN PCH InitRoutineString,
|
|
IN ULONG ServerDllIndex
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
ANSI_STRING ModuleNameString;
|
|
UNICODE_STRING ModuleNameString_U;
|
|
HANDLE ModuleHandle;
|
|
PCSR_SERVER_DLL LoadedServerDll;
|
|
STRING ProcedureNameString;
|
|
PCSR_SERVER_DLL_INIT_ROUTINE ServerDllInitialization;
|
|
ULONG n;
|
|
|
|
if (ServerDllIndex > CSR_MAX_SERVER_DLL) {
|
|
return( STATUS_TOO_MANY_NAMES );
|
|
}
|
|
|
|
if (CsrLoadedServerDll[ ServerDllIndex ] != NULL) {
|
|
return( STATUS_INVALID_PARAMETER );
|
|
}
|
|
|
|
RtlInitAnsiString( &ModuleNameString, ModuleName );
|
|
Status = RtlAnsiStringToUnicodeString(&ModuleNameString_U, &ModuleNameString, TRUE);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
if (ServerDllIndex != CSRSRV_SERVERDLL_INDEX) {
|
|
Status = LdrLoadDll( UNICODE_NULL, NULL, &ModuleNameString_U, &ModuleHandle );
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
|
|
PUNICODE_STRING ErrorStrings[2];
|
|
UNICODE_STRING ErrorDllPath;
|
|
ULONG ErrorResponse;
|
|
NTSTATUS ErrorStatus;
|
|
|
|
ErrorStrings[0] = &ModuleNameString_U;
|
|
ErrorStrings[1] = &ErrorDllPath;
|
|
RtlInitUnicodeString(&ErrorDllPath,L"Default Load Path");
|
|
|
|
//
|
|
// need to get image name
|
|
//
|
|
|
|
ErrorStatus = NtRaiseHardError(
|
|
(NTSTATUS)STATUS_DLL_NOT_FOUND,
|
|
2,
|
|
0x00000003,
|
|
(PULONG)ErrorStrings,
|
|
OptionOk,
|
|
&ErrorResponse
|
|
);
|
|
|
|
}
|
|
RtlFreeUnicodeString(&ModuleNameString_U);
|
|
if (!NT_SUCCESS( Status )) {
|
|
return( Status );
|
|
}
|
|
}
|
|
else {
|
|
ModuleHandle = NULL;
|
|
}
|
|
|
|
n = sizeof( *LoadedServerDll ) + ModuleNameString.MaximumLength;
|
|
|
|
LoadedServerDll = RtlAllocateHeap( CsrHeap, MAKE_TAG( INIT_TAG ), n );
|
|
if (LoadedServerDll == NULL) {
|
|
if (ModuleHandle != NULL) {
|
|
LdrUnloadDll( ModuleHandle );
|
|
}
|
|
|
|
return( STATUS_NO_MEMORY );
|
|
}
|
|
|
|
RtlZeroMemory( LoadedServerDll, n );
|
|
LoadedServerDll->SharedStaticServerData = CsrSrvSharedSectionHeap;
|
|
LoadedServerDll->Length = n;
|
|
LoadedServerDll->CsrInitializationEvent = CsrInitializationEvent;
|
|
LoadedServerDll->ModuleName.Length = ModuleNameString.Length;
|
|
LoadedServerDll->ModuleName.MaximumLength = ModuleNameString.MaximumLength;
|
|
LoadedServerDll->ModuleName.Buffer = (PCH)(LoadedServerDll+1);
|
|
if (ModuleNameString.Length != 0) {
|
|
strncpy( LoadedServerDll->ModuleName.Buffer,
|
|
ModuleNameString.Buffer,
|
|
ModuleNameString.Length
|
|
);
|
|
}
|
|
|
|
LoadedServerDll->ServerDllIndex = ServerDllIndex;
|
|
LoadedServerDll->ModuleHandle = ModuleHandle;
|
|
|
|
if (ModuleHandle != NULL) {
|
|
|
|
RtlInitString(
|
|
&ProcedureNameString,
|
|
(InitRoutineString == NULL) ? "ServerDllInitialization" : InitRoutineString);
|
|
|
|
Status = LdrGetProcedureAddress( ModuleHandle,
|
|
&ProcedureNameString,
|
|
(ULONG) NULL,
|
|
(PVOID *) &ServerDllInitialization
|
|
);
|
|
}
|
|
else {
|
|
ServerDllInitialization = CsrServerDllInitialization;
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
try {
|
|
Status = (*ServerDllInitialization)( LoadedServerDll );
|
|
}
|
|
except ( CsrUnhandledExceptionFilter( GetExceptionInformation() ) ){
|
|
Status = GetExceptionCode();
|
|
}
|
|
if (NT_SUCCESS( Status )) {
|
|
CsrTotalPerProcessDataLength += QUAD_ALIGN(LoadedServerDll->PerProcessDataLength);
|
|
CsrTotalPerThreadDataLength += QUAD_ALIGN(LoadedServerDll->PerThreadDataLength);
|
|
|
|
CsrLoadedServerDll[ LoadedServerDll->ServerDllIndex ] =
|
|
LoadedServerDll;
|
|
if ( LoadedServerDll->SharedStaticServerData != CsrSrvSharedSectionHeap ) {
|
|
CsrSrvSharedStaticServerData[LoadedServerDll->ServerDllIndex] = LoadedServerDll->SharedStaticServerData;
|
|
}
|
|
}
|
|
else {
|
|
if (ModuleHandle != NULL) {
|
|
LdrUnloadDll( ModuleHandle );
|
|
}
|
|
|
|
RtlFreeHeap( CsrHeap, 0, LoadedServerDll );
|
|
}
|
|
}
|
|
else {
|
|
if (ModuleHandle != NULL) {
|
|
LdrUnloadDll( ModuleHandle );
|
|
}
|
|
|
|
RtlFreeHeap( CsrHeap, 0, LoadedServerDll );
|
|
}
|
|
|
|
return( Status );
|
|
}
|
|
|
|
|
|
ULONG
|
|
CsrSrvClientConnect(
|
|
IN OUT PCSR_API_MSG m,
|
|
IN OUT PCSR_REPLY_STATUS ReplyStatus
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PCSR_CLIENTCONNECT_MSG a = (PCSR_CLIENTCONNECT_MSG)&m->u.ApiMessageData;
|
|
PCSR_SERVER_DLL LoadedServerDll;
|
|
|
|
*ReplyStatus = CsrReplyImmediate;
|
|
|
|
if (a->ServerDllIndex > CSR_MAX_SERVER_DLL) {
|
|
return( (ULONG)STATUS_TOO_MANY_NAMES );
|
|
}
|
|
else
|
|
if (CsrLoadedServerDll[ a->ServerDllIndex ] == NULL) {
|
|
return( (ULONG)STATUS_INVALID_PARAMETER );
|
|
}
|
|
else {
|
|
LoadedServerDll = CsrLoadedServerDll[ a->ServerDllIndex ];
|
|
|
|
if (LoadedServerDll->ConnectRoutine) {
|
|
|
|
Status = (LoadedServerDll->ConnectRoutine)(
|
|
(CSR_SERVER_QUERYCLIENTTHREAD())->Process,
|
|
a->ConnectionInformation,
|
|
&a->ConnectionInformationLength
|
|
);
|
|
}
|
|
else {
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return( (ULONG)Status );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
CsrSrvCreateSharedSection(
|
|
IN PCH SizeParameter
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
LARGE_INTEGER SectionSize;
|
|
ULONG ViewSize;
|
|
ULONG HandleTableSize;
|
|
ULONG HeapSize;
|
|
PCH s;
|
|
|
|
s = SizeParameter;
|
|
while (*s) {
|
|
if (*s == ',') {
|
|
*s++ = '\0';
|
|
break;
|
|
}
|
|
else {
|
|
s++;
|
|
}
|
|
}
|
|
|
|
|
|
if (!*s) {
|
|
return( STATUS_INVALID_PARAMETER );
|
|
}
|
|
|
|
Status = RtlCharToInteger( SizeParameter,
|
|
(ULONG)NULL,
|
|
&HandleTableSize
|
|
);
|
|
if (NT_SUCCESS( Status )) {
|
|
Status = RtlCharToInteger( SizeParameter,
|
|
(ULONG)NULL,
|
|
&HeapSize
|
|
);
|
|
}
|
|
if (!NT_SUCCESS( Status )) {
|
|
return( Status );
|
|
}
|
|
|
|
|
|
HandleTableSize = ROUND_UP_TO_PAGES( HandleTableSize * 1024 );
|
|
HeapSize = ROUND_UP_TO_PAGES( HeapSize * 1024 );
|
|
CsrSrvSharedSectionSize = HandleTableSize + HeapSize;
|
|
|
|
SectionSize.LowPart = CsrSrvSharedSectionSize;
|
|
SectionSize.HighPart = 0;
|
|
Status = NtCreateSection( &CsrSrvSharedSection,
|
|
SECTION_ALL_ACCESS,
|
|
(POBJECT_ATTRIBUTES) NULL,
|
|
&SectionSize,
|
|
PAGE_EXECUTE_READWRITE,
|
|
SEC_BASED | SEC_RESERVE,
|
|
(HANDLE) NULL
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
return( Status );
|
|
}
|
|
|
|
ViewSize = 0;
|
|
CsrSrvSharedSectionBase = NULL;
|
|
Status = NtMapViewOfSection( CsrSrvSharedSection,
|
|
NtCurrentProcess(),
|
|
&CsrSrvSharedSectionBase,
|
|
0, // Zerobits?
|
|
0,
|
|
NULL,
|
|
&ViewSize,
|
|
ViewUnmap,
|
|
MEM_TOP_DOWN,
|
|
PAGE_EXECUTE_READWRITE
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
NtClose( CsrSrvSharedSection );
|
|
return( Status );
|
|
}
|
|
CsrSrvSharedSectionHeap = (PVOID)
|
|
((ULONG)CsrSrvSharedSectionBase + HandleTableSize );
|
|
|
|
if (RtlCreateHeap( HEAP_ZERO_MEMORY | HEAP_CLASS_7,
|
|
CsrSrvSharedSectionHeap,
|
|
HeapSize,
|
|
4*1024,
|
|
0,
|
|
0
|
|
) == NULL
|
|
) {
|
|
NtUnmapViewOfSection( NtCurrentProcess(),
|
|
CsrSrvSharedSectionBase
|
|
);
|
|
NtClose( CsrSrvSharedSection );
|
|
return( STATUS_NO_MEMORY );
|
|
}
|
|
|
|
CsrSharedBaseTag = RtlCreateTagHeap( CsrSrvSharedSectionHeap,
|
|
0,
|
|
L"CSRSHR!",
|
|
L"!CSRSHR\0"
|
|
L"INIT\0"
|
|
);
|
|
CsrSrvSharedStaticServerData = (PVOID *)RtlAllocateHeap(
|
|
CsrSrvSharedSectionHeap,
|
|
MAKE_SHARED_TAG( SHR_INIT_TAG ),
|
|
CSR_MAX_SERVER_DLL * sizeof(PVOID)
|
|
);
|
|
|
|
NtCurrentPeb()->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase;
|
|
NtCurrentPeb()->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap;
|
|
NtCurrentPeb()->ReadOnlyStaticServerData = (PVOID *)CsrSrvSharedStaticServerData;
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
CsrSrvAttachSharedSection(
|
|
IN PCSR_PROCESS Process OPTIONAL,
|
|
OUT PCSR_API_CONNECTINFO p
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG ViewSize;
|
|
|
|
if (ARGUMENT_PRESENT( Process )) {
|
|
ViewSize = 0;
|
|
Status = NtMapViewOfSection( CsrSrvSharedSection,
|
|
Process->ProcessHandle,
|
|
&CsrSrvSharedSectionBase,
|
|
0,
|
|
0,
|
|
NULL,
|
|
&ViewSize,
|
|
ViewUnmap,
|
|
SEC_NO_CHANGE,
|
|
PAGE_EXECUTE_READ
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
return( Status );
|
|
}
|
|
}
|
|
|
|
p->SharedSectionBase = CsrSrvSharedSectionBase;
|
|
p->SharedSectionHeap = CsrSrvSharedSectionHeap;
|
|
p->SharedStaticServerData = CsrSrvSharedStaticServerData;
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|