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.
693 lines
21 KiB
693 lines
21 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"
|
|
#include "windows.h"
|
|
|
|
#ifdef _IA64_
|
|
#include <ntia64.h>
|
|
#endif // _IA64_
|
|
|
|
EXCEPTION_DISPOSITION
|
|
CsrUnhandledExceptionFilter(
|
|
struct _EXCEPTION_POINTERS *ExceptionInfo
|
|
)
|
|
{
|
|
UNICODE_STRING UnicodeParameter;
|
|
ULONG_PTR Parameters[ 4 ];
|
|
ULONG Response;
|
|
BOOLEAN WasEnabled;
|
|
NTSTATUS Status;
|
|
LONG lReturn = EXCEPTION_EXECUTE_HANDLER;
|
|
SYSTEM_KERNEL_DEBUGGER_INFORMATION KernelDebuggerInfo;
|
|
|
|
//
|
|
// 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
|
|
//
|
|
|
|
Status = NtQuerySystemInformation( SystemKernelDebuggerInformation,
|
|
&KernelDebuggerInfo,
|
|
sizeof(KernelDebuggerInfo),
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Under Hydra, we don't want to shutdown the system just
|
|
// because the Win32 subsystem is going away. In case of non-console CSRSS,
|
|
// causing the process to terminate is sufficient.
|
|
//
|
|
if ((NtCurrentPeb()->SessionId == 0) ||
|
|
(NT_SUCCESS(Status) && KernelDebuggerInfo.KernelDebuggerEnabled)) {
|
|
|
|
lReturn = RtlUnhandledExceptionFilter(ExceptionInfo);
|
|
|
|
if (lReturn != EXCEPTION_CONTINUE_EXECUTION)
|
|
{
|
|
//
|
|
// We are hosed, so raise a fatal 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_PTR)&UnicodeParameter;
|
|
Parameters[ 1 ] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionCode;
|
|
Parameters[ 2 ] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
|
|
Parameters[ 3 ] = (ULONG_PTR)ExceptionInfo->ContextRecord;
|
|
Status = NtRaiseHardError( STATUS_SYSTEM_PROCESS_TERMINATED,
|
|
4,
|
|
1,
|
|
Parameters,
|
|
OptionShutdownSystem,
|
|
&Response
|
|
);
|
|
}
|
|
}
|
|
|
|
if (lReturn != EXCEPTION_CONTINUE_EXECUTION)
|
|
{
|
|
//
|
|
// If this returns, giveup
|
|
//
|
|
|
|
NtTerminateProcess(NtCurrentProcess(),ExceptionInfo->ExceptionRecord->ExceptionCode);
|
|
}
|
|
|
|
return lReturn;
|
|
}
|
|
|
|
|
|
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 );
|
|
}
|
|
|
|
ASSERT( ModuleName != NULL );
|
|
RtlInitAnsiString( &ModuleNameString, ModuleName );
|
|
|
|
if (ServerDllIndex != CSRSRV_SERVERDLL_INDEX) {
|
|
Status = RtlAnsiStringToUnicodeString(&ModuleNameString_U, &ModuleNameString, TRUE);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
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_PTR)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->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,
|
|
0,
|
|
(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 += (ULONG)QUAD_ALIGN(LoadedServerDll->PerProcessDataLength);
|
|
|
|
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( STATUS_TOO_MANY_NAMES );
|
|
}
|
|
|
|
if (CsrLoadedServerDll[ a->ServerDllIndex ] == NULL) {
|
|
return( STATUS_INVALID_PARAMETER );
|
|
}
|
|
|
|
if (!CsrValidateMessageBuffer(m, &a->ConnectionInformation, a->ConnectionInformationLength, sizeof(BYTE))) {
|
|
return( STATUS_INVALID_PARAMETER );
|
|
}
|
|
|
|
LoadedServerDll = CsrLoadedServerDll[ a->ServerDllIndex ];
|
|
|
|
if (LoadedServerDll->ConnectRoutine) {
|
|
|
|
Status = (LoadedServerDll->ConnectRoutine)(
|
|
(CSR_SERVER_QUERYCLIENTTHREAD())->Process,
|
|
a->ConnectionInformation,
|
|
&a->ConnectionInformationLength
|
|
);
|
|
}
|
|
else {
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
return( Status );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
CsrSrvCreateSharedSection(
|
|
IN PCH SizeParameter
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
LARGE_INTEGER SectionSize;
|
|
SIZE_T ViewSize;
|
|
ULONG HeapSize;
|
|
ULONG AllocationAttributes;
|
|
PCH s;
|
|
ULONG FirstCsr = (NtCurrentPeb()->SessionId == 0);
|
|
|
|
#if defined(_WIN64)
|
|
PVOID BaseAddress;
|
|
SIZE_T RegionSize;
|
|
#endif
|
|
|
|
if (SizeParameter == NULL) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
s = SizeParameter;
|
|
while (*s) {
|
|
if (*s == ',') {
|
|
*s++ = '\0';
|
|
break;
|
|
}
|
|
else {
|
|
s++;
|
|
}
|
|
}
|
|
|
|
|
|
if (!*s) {
|
|
return( STATUS_INVALID_PARAMETER );
|
|
}
|
|
|
|
Status = RtlCharToInteger( SizeParameter,
|
|
0,
|
|
&HeapSize
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
return( Status );
|
|
}
|
|
|
|
HeapSize = ROUND_UP_TO_PAGES( HeapSize * 1024 );
|
|
CsrSrvSharedSectionSize = HeapSize;
|
|
|
|
SectionSize.LowPart = CsrSrvSharedSectionSize;
|
|
SectionSize.HighPart = 0;
|
|
|
|
if (FirstCsr) {
|
|
AllocationAttributes = SEC_BASED | SEC_RESERVE;
|
|
}
|
|
else {
|
|
AllocationAttributes = SEC_RESERVE;
|
|
}
|
|
|
|
Status = NtCreateSection( &CsrSrvSharedSection,
|
|
SECTION_ALL_ACCESS,
|
|
(POBJECT_ATTRIBUTES) NULL,
|
|
&SectionSize,
|
|
PAGE_EXECUTE_READWRITE,
|
|
AllocationAttributes,
|
|
(HANDLE) NULL
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
return( Status );
|
|
}
|
|
|
|
ViewSize = 0;
|
|
|
|
#if defined(_WIN64)
|
|
CsrSrvSharedSectionBase = (PVOID)CSR_SYSTEM_SHARED_ADDRESS;
|
|
#else
|
|
if (FirstCsr) {
|
|
CsrSrvSharedSectionBase = NULL;
|
|
}
|
|
else {
|
|
|
|
//
|
|
// Retrieve the value of CsrSrvSharedSectionBase from registry
|
|
// This is saved by the First CSRSS process and used by others
|
|
//
|
|
|
|
|
|
HANDLE hKey;
|
|
OBJECT_ATTRIBUTES Obja;
|
|
ULONG Attributes;
|
|
UNICODE_STRING KeyName;
|
|
|
|
Attributes = OBJ_CASE_INSENSITIVE;
|
|
|
|
RtlInitUnicodeString( &KeyName, CSR_BASE_PATH );
|
|
|
|
InitializeObjectAttributes(&Obja,
|
|
&KeyName,
|
|
Attributes,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = NtOpenKey(&hKey,
|
|
KEY_READ,
|
|
&Obja);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
ULONG BufferLength;
|
|
ULONG ResultLength;
|
|
BYTE PrivateKeyValueInformation[ sizeof( KEY_VALUE_PARTIAL_INFORMATION ) +
|
|
+ sizeof(DWORD) ];
|
|
|
|
BufferLength = sizeof( PrivateKeyValueInformation );
|
|
|
|
RtlInitUnicodeString( &KeyName, L"CsrSrvSharedSectionBase" );
|
|
|
|
if (NT_SUCCESS(Status = NtQueryValueKey( hKey,
|
|
&KeyName,
|
|
KeyValuePartialInformation,
|
|
PrivateKeyValueInformation,
|
|
BufferLength,
|
|
&ResultLength
|
|
))) {
|
|
|
|
RtlCopyMemory( &CsrSrvSharedSectionBase,
|
|
(( PKEY_VALUE_PARTIAL_INFORMATION )
|
|
PrivateKeyValueInformation )->Data,
|
|
(( PKEY_VALUE_PARTIAL_INFORMATION )
|
|
PrivateKeyValueInformation )->DataLength
|
|
);
|
|
|
|
}
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
NtClose(hKey);
|
|
|
|
}
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
return Status;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
#if defined(_WIN64)
|
|
|
|
//
|
|
// For compatibility reasons, on Win64 the csrss shared section
|
|
// needs to be at an address below 2GB. Since it is difficult to
|
|
// find an address in the middle of the address space that is
|
|
// guaranteed to be available in all processes, the memory
|
|
// manager reserves an address at the top of the 2GB range.
|
|
// To use this memory, CSRSS first unreserves the memory and
|
|
// then maps in the section. A possible race condition exists
|
|
// if another thread tries to allocate the memory at the same
|
|
// time, but this is highly unlikely since in the current NT
|
|
// code the mapping and unmapping will always occur in DLL_PROCESS_ATTACH
|
|
// in kernel32.dll. This code executes when the first thread
|
|
// of the process is initialized, and all newly created threads
|
|
// are blocked untill this code completes.
|
|
//
|
|
|
|
BaseAddress = (PVOID)CSR_SYSTEM_SHARED_ADDRESS;
|
|
RegionSize = CsrSrvSharedSectionSize;
|
|
|
|
Status = NtFreeVirtualMemory(NtCurrentProcess(),
|
|
&BaseAddress,
|
|
&RegionSize,
|
|
MEM_RELEASE
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
NtClose( CsrSrvSharedSection );
|
|
return Status;
|
|
}
|
|
#endif
|
|
|
|
Status = NtMapViewOfSection( CsrSrvSharedSection,
|
|
NtCurrentProcess(),
|
|
&CsrSrvSharedSectionBase,
|
|
0, // Zerobits?
|
|
0,
|
|
NULL,
|
|
&ViewSize,
|
|
ViewUnmap,
|
|
MEM_TOP_DOWN,
|
|
PAGE_EXECUTE_READWRITE
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
|
|
#if defined(_WIN64)
|
|
|
|
//
|
|
// For this code to execute, either the race condition
|
|
// described above occured for some unknown reason or
|
|
// the memory manager or process is corrupt. With the lack
|
|
// of an atomic uncommit and map, the best that can be done is
|
|
// try to reallocate the memory. If this fails, everything
|
|
// is hopeless.
|
|
//
|
|
|
|
BaseAddress = (PVOID)CSR_SYSTEM_SHARED_ADDRESS;
|
|
RegionSize = CsrSrvSharedSectionSize;
|
|
NtAllocateVirtualMemory(NtCurrentProcess(),
|
|
&BaseAddress,
|
|
0,
|
|
&RegionSize,
|
|
MEM_RESERVE,
|
|
PAGE_READONLY
|
|
);
|
|
#endif
|
|
|
|
NtClose( CsrSrvSharedSection );
|
|
return( Status );
|
|
}
|
|
CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase;
|
|
|
|
if (IsTerminalServer() && FirstCsr) {
|
|
//
|
|
//save CsrSrvSharedSectionBase in registry for other csrs
|
|
//
|
|
HKEY hKey;
|
|
OBJECT_ATTRIBUTES Obja;
|
|
ULONG Attributes;
|
|
UNICODE_STRING KeyName;
|
|
DWORD dwDisposition;
|
|
|
|
Attributes = OBJ_CASE_INSENSITIVE;
|
|
|
|
RtlInitUnicodeString( &KeyName, CSR_BASE_PATH );
|
|
|
|
InitializeObjectAttributes(&Obja,
|
|
&KeyName,
|
|
Attributes,
|
|
NULL,
|
|
NULL);
|
|
|
|
|
|
Status = NtCreateKey(&hKey,
|
|
KEY_WRITE,
|
|
&Obja,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_VOLATILE,
|
|
&dwDisposition);
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
RtlInitUnicodeString( &KeyName, L"CsrSrvSharedSectionBase" );
|
|
|
|
Status = NtSetValueKey(
|
|
hKey,
|
|
&KeyName,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&CsrSrvSharedSectionBase,
|
|
sizeof(CsrSrvSharedSectionBase)
|
|
);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
NtClose(hKey);
|
|
} else {
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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)
|
|
);
|
|
|
|
if (CsrSrvSharedStaticServerData == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
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;
|
|
SIZE_T ViewSize;
|
|
|
|
#if defined(_WIN64)
|
|
PVOID BaseAddress;
|
|
SIZE_T RegionSize;
|
|
#endif
|
|
|
|
if (ARGUMENT_PRESENT( Process )) {
|
|
|
|
#if defined(_WIN64)
|
|
|
|
BaseAddress = (PVOID)CSR_SYSTEM_SHARED_ADDRESS;
|
|
RegionSize = CsrSrvSharedSectionSize;
|
|
|
|
Status = NtFreeVirtualMemory(Process->ProcessHandle,
|
|
&BaseAddress,
|
|
&RegionSize,
|
|
MEM_RELEASE
|
|
);
|
|
if(!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
#endif
|
|
|
|
ViewSize = 0;
|
|
Status = NtMapViewOfSection( CsrSrvSharedSection,
|
|
Process->ProcessHandle,
|
|
&CsrSrvSharedSectionBase,
|
|
0,
|
|
0,
|
|
NULL,
|
|
&ViewSize,
|
|
ViewUnmap,
|
|
SEC_NO_CHANGE,
|
|
PAGE_EXECUTE_READ
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
|
|
#if defined(_WIN64)
|
|
BaseAddress = (PVOID)CSR_SYSTEM_SHARED_ADDRESS;
|
|
RegionSize = CsrSrvSharedSectionSize;
|
|
|
|
NtAllocateVirtualMemory(Process->ProcessHandle,
|
|
&BaseAddress,
|
|
0,
|
|
&RegionSize,
|
|
MEM_RESERVE,
|
|
PAGE_READONLY
|
|
);
|
|
#endif
|
|
|
|
return( Status );
|
|
}
|
|
}
|
|
|
|
p->SharedSectionBase = CsrSrvSharedSectionBase;
|
|
p->SharedSectionHeap = CsrSrvSharedSectionHeap;
|
|
p->SharedStaticServerData = CsrSrvSharedStaticServerData;
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|