+++ /dev/null
-/*
- * subsystems/win32/csrss/csrsrv/api/wapi.c
- *
- * CSRSS port message processing
- *
- * ReactOS Operating System
- *
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <srv.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* GLOBALS *******************************************************************/
-
-static unsigned ApiDefinitionsCount = 0;
-static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
-UNICODE_STRING CsrApiPortName;
-volatile LONG CsrpStaticThreadCount;
-volatile LONG CsrpDynamicThreadTotal;
-extern ULONG CsrMaxApiRequestThreads;
-
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS FASTCALL
-CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
-{
- unsigned NewCount;
- PCSRSS_API_DEFINITION Scan;
- PCSRSS_API_DEFINITION New;
-
- DPRINT("CSR: %s called\n", __FUNCTION__);
-
- NewCount = 0;
- for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
- {
- NewCount++;
- }
-
- New = RtlAllocateHeap(CsrHeap, 0,
- (ApiDefinitionsCount + NewCount)
- * sizeof(CSRSS_API_DEFINITION));
- if (NULL == New)
- {
- DPRINT1("Unable to allocate memory\n");
- return STATUS_NO_MEMORY;
- }
- if (0 != ApiDefinitionsCount)
- {
- RtlCopyMemory(New, ApiDefinitions,
- ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION));
- RtlFreeHeap(CsrHeap, 0, ApiDefinitions);
- }
- RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
- NewCount * sizeof(CSRSS_API_DEFINITION));
- ApiDefinitions = New;
- ApiDefinitionsCount += NewCount;
-
- return STATUS_SUCCESS;
-}
-
-VOID
-FASTCALL
-CsrApiCallHandler(PCSR_PROCESS ProcessData,
- PCSR_API_MESSAGE Request)
-{
- unsigned DefIndex;
- ULONG Type;
-
- DPRINT("CSR: Calling handler for type: %x.\n", Request->Type);
- Type = Request->Type & 0xFFFF; /* FIXME: USE MACRO */
- DPRINT("CSR: API Number: %x ServerID: %x\n",Type, Request->Type >> 16);
-
- /* FIXME: Extract DefIndex instead of looping */
- for (DefIndex = 0; DefIndex < ApiDefinitionsCount; DefIndex++)
- {
- if (ApiDefinitions[DefIndex].Type == Type)
- {
- if (Request->Header.u1.s1.DataLength < ApiDefinitions[DefIndex].MinRequestSize)
- {
- DPRINT1("Request type %d min request size %d actual %d\n",
- Type, ApiDefinitions[DefIndex].MinRequestSize,
- Request->Header.u1.s1.DataLength);
- Request->Status = STATUS_INVALID_PARAMETER;
- }
- else
- {
- Request->Status = (ApiDefinitions[DefIndex].Handler)(ProcessData, Request);
- }
- return;
- }
- }
- DPRINT1("CSR: Unknown request type 0x%x\n", Request->Type);
- Request->Status = STATUS_INVALID_SYSTEM_SERVICE;
-}
-
-VOID
-CallHardError(IN PCSR_THREAD ThreadData,
- IN PHARDERROR_MSG HardErrorMessage);
-
-static
-VOID
-NTAPI
-CsrHandleHardError(IN PCSR_THREAD ThreadData,
- IN OUT PHARDERROR_MSG Message)
-{
- DPRINT1("CSR: received hard error %lx\n", Message->Status);
-
- /* Call the hard error handler in win32csr */
- CallHardError(ThreadData, Message);
-}
-
-/*++
- * @name CsrCallServerFromServer
- * @implemented NT4
- *
- * The CsrCallServerFromServer routine calls a CSR API from within a server.
- * It avoids using LPC messages since the request isn't coming from a client.
- *
- * @param ReceiveMsg
- * Pointer to the CSR API Message to send to the server.
- *
- * @param ReplyMsg
- * Pointer to the CSR API Message to receive from the server.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_ILLEGAL_FUNCTION
- * if the opcode is invalid, or STATUS_ACCESS_VIOLATION if there
- * was a problem executing the API.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg,
- PCSR_API_MESSAGE ReplyMsg)
-{
-#if 0 // real code
- ULONG ServerId;
- PCSR_SERVER_DLL ServerDll;
- ULONG ApiId;
- ULONG Reply;
- NTSTATUS Status;
-
- /* Get the Server ID */
- ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg->Opcode);
-
- /* Make sure that the ID is within limits, and the Server DLL loaded */
- if ((ServerId >= CSR_SERVER_DLL_MAX) ||
- (!(ServerDll = CsrLoadedServerDll[ServerId])))
- {
- /* We are beyond the Maximum Server ID */
- DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", ServerId, ServerDll);
- ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
- return STATUS_ILLEGAL_FUNCTION;
- }
- else
- {
- /* Get the API ID */
- ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg->Opcode);
-
- /* Normalize it with our Base ID */
- ApiId -= ServerDll->ApiBase;
-
- /* Make sure that the ID is within limits, and the entry exists */
- if ((ApiId >= ServerDll->HighestApiSupported) ||
- ((ServerDll->ValidTable) && !(ServerDll->ValidTable[ApiId])))
- {
- /* We are beyond the Maximum API ID, or it doesn't exist */
- DPRINT1("CSRSS: %lx (%s) is invalid ApiTableIndex for %Z or is an "
- "invalid API to call from the server.\n",
- ServerDll->ValidTable[ApiId],
- ((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ?
- ServerDll->NameTable[ApiId] : "*** UNKNOWN ***", &ServerDll->Name);
- DbgBreakPoint();
- ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
- return STATUS_ILLEGAL_FUNCTION;
- }
- }
-
- if (CsrDebug & 2)
- {
- DPRINT1("CSRSS: %s Api Request received from server process\n",
- ServerDll->NameTable[ApiId]);
- }
-
- /* Validation complete, start SEH */
- _SEH2_TRY
- {
- /* Call the API and get the result */
- Status = (ServerDll->DispatchTable[ApiId])(ReceiveMsg, &Reply);
-
- /* Return the result, no matter what it is */
- ReplyMsg->Status = Status;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* If we got an exception, return access violation */
- ReplyMsg->Status = STATUS_ACCESS_VIOLATION;
- }
- _SEH2_END;
-
- /* Return success */
- return STATUS_SUCCESS;
-
-#else // Hacky reactos code
-
- PCSR_PROCESS ProcessData;
-
- /* Get the Process Data */
- CsrLockProcessByClientId(&ReceiveMsg->Header.ClientId.UniqueProcess, &ProcessData);
- if (!ProcessData)
- {
- DPRINT1("Message: Unable to find data for process 0x%x\n",
- ReceiveMsg->Header.ClientId.UniqueProcess);
- return STATUS_NOT_SUPPORTED;
- }
-
- /* Validation complete, start SEH */
- _SEH2_TRY
- {
- /* Call the API and get the result */
- CsrApiCallHandler(ProcessData, ReplyMsg);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* If we got an exception, return access violation */
- ReplyMsg->Status = STATUS_ACCESS_VIOLATION;
- }
- _SEH2_END;
-
- /* Release the process reference */
- CsrUnlockProcess(ProcessData);
-
- /* Return success */
- return STATUS_SUCCESS;
-#endif
-}
-
-/*++
- * @name CsrApiPortInitialize
- *
- * The CsrApiPortInitialize routine initializes the LPC Port used for
- * communications with the Client/Server Runtime (CSR) and initializes the
- * static thread that will handle connection requests and APIs.
- *
- * @param None
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrApiPortInitialize(VOID)
-{
- ULONG Size;
- OBJECT_ATTRIBUTES ObjectAttributes;
- NTSTATUS Status;
- HANDLE hRequestEvent, hThread;
- CLIENT_ID ClientId;
- PLIST_ENTRY ListHead, NextEntry;
- PCSR_THREAD ServerThread;
-
- /* Calculate how much space we'll need for the Port Name */
- Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR);
-
- /* Create the buffer for it */
- CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
- if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY;
-
- /* Setup the rest of the empty string */
- CsrApiPortName.Length = 0;
- CsrApiPortName.MaximumLength = (USHORT)Size;
- RtlAppendUnicodeStringToString(&CsrApiPortName, &CsrDirectoryName);
- RtlAppendUnicodeToString(&CsrApiPortName, UNICODE_PATH_SEP);
- RtlAppendUnicodeToString(&CsrApiPortName, CSR_PORT_NAME);
- if (CsrDebug & 1)
- {
- DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName);
- DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) == %ld\n",
- sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE));
- }
-
- /* FIXME: Create a Security Descriptor */
-
- /* Initialize the Attributes */
- InitializeObjectAttributes(&ObjectAttributes,
- &CsrApiPortName,
- 0,
- NULL,
- NULL /* FIXME*/);
-
- /* Create the Port Object */
- Status = NtCreatePort(&CsrApiPort,
- &ObjectAttributes,
- LPC_MAX_DATA_LENGTH, // hack ; sizeof(CSR_CONNECTION_INFO),
- LPC_MAX_MESSAGE_LENGTH, // hack ; sizeof(CSR_API_MESSAGE),
- 16 * PAGE_SIZE);
- if (NT_SUCCESS(Status))
- {
- /* Create the event the Port Thread will use */
- Status = NtCreateEvent(&hRequestEvent,
- EVENT_ALL_ACCESS,
- NULL,
- SynchronizationEvent,
- FALSE);
- if (NT_SUCCESS(Status))
- {
- /* Create the Request Thread */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- TRUE,
- 0,
- 0,
- 0,
- (PVOID)ClientConnectionThread,//CsrApiRequestThread,
- (PVOID)hRequestEvent,
- &hThread,
- &ClientId);
- if (NT_SUCCESS(Status))
- {
- /* Add this as a static thread to CSRSRV */
- CsrAddStaticServerThread(hThread, &ClientId, CsrThreadIsServerThread);
-
- /* Get the Thread List Pointers */
- ListHead = &CsrRootProcess->ThreadList;
- NextEntry = ListHead->Flink;
-
- /* Start looping the list */
- while (NextEntry != ListHead)
- {
- /* Get the Thread */
- ServerThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
-
- /* Start it up */
- Status = NtResumeThread(ServerThread->ThreadHandle, NULL);
-
- /* Is this a Server Thread? */
- if (ServerThread->Flags & CsrThreadIsServerThread)
- {
- /* If so, then wait for it to initialize */
- Status = NtWaitForSingleObject(hRequestEvent, FALSE, NULL);
- ASSERT(NT_SUCCESS(Status));
- }
-
- /* Next thread */
- NextEntry = NextEntry->Flink;
- }
-
- /* We don't need this anymore */
- NtClose(hRequestEvent);
- }
- }
- }
-
- /* Return */
- return Status;
-}
-
-PBASE_STATIC_SERVER_DATA BaseStaticServerData;
-
-NTSTATUS
-NTAPI
-CreateBaseAcls(OUT PACL* Dacl,
- OUT PACL* RestrictedDacl)
-{
- PSID SystemSid, WorldSid, RestrictedSid;
- SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
- SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
- NTSTATUS Status;
- UCHAR KeyValueBuffer[0x40];
- PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
- UNICODE_STRING KeyName;
- ULONG ProtectionMode = 0;
- ULONG AclLength, ResultLength;
- HANDLE hKey;
- OBJECT_ATTRIBUTES ObjectAttributes;
-
- /* Open the Session Manager Key */
- RtlInitUnicodeString(&KeyName, SM_REG_KEY);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
- if (NT_SUCCESS(Status))
- {
- /* Read the key value */
- RtlInitUnicodeString(&KeyName, L"ProtectionMode");
- Status = NtQueryValueKey(hKey,
- &KeyName,
- KeyValuePartialInformation,
- KeyValueBuffer,
- sizeof(KeyValueBuffer),
- &ResultLength);
-
- /* Make sure it's what we expect it to be */
- KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
- if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
- (*(PULONG)KeyValuePartialInfo->Data))
- {
- /* Save the Protection Mode */
- ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
- }
-
- /* Close the handle */
- NtClose(hKey);
- }
-
- /* Allocate the System SID */
- Status = RtlAllocateAndInitializeSid(&NtAuthority,
- 1, SECURITY_LOCAL_SYSTEM_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &SystemSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Allocate the World SID */
- Status = RtlAllocateAndInitializeSid(&WorldAuthority,
- 1, SECURITY_WORLD_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &WorldSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Allocate the restricted SID */
- Status = RtlAllocateAndInitializeSid(&NtAuthority,
- 1, SECURITY_RESTRICTED_CODE_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &RestrictedSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Allocate one ACL with 3 ACEs each for one SID */
- AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
- RtlLengthSid(SystemSid) +
- RtlLengthSid(RestrictedSid) +
- RtlLengthSid(WorldSid);
- *Dacl = RtlAllocateHeap(CsrHeap, 0, AclLength);
- ASSERT(*Dacl != NULL);
-
- /* Set the correct header fields */
- Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2);
- ASSERT(NT_SUCCESS(Status));
-
- /* Give the appropriate rights to each SID */
- /* FIXME: Should check SessionId/ProtectionMode */
- Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Now allocate the restricted DACL */
- *RestrictedDacl = RtlAllocateHeap(CsrHeap, 0, AclLength);
- ASSERT(*RestrictedDacl != NULL);
-
- /* Initialize it */
- Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2);
- ASSERT(NT_SUCCESS(Status));
-
- /* And add the same ACEs as before */
- /* FIXME: Not really fully correct */
- Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* The SIDs are captured, can free them now */
- RtlFreeHeap(CsrHeap, 0, SystemSid);
- RtlFreeHeap(CsrHeap, 0, WorldSid);
- RtlFreeHeap(CsrHeap, 0, RestrictedSid);
- return Status;
-}
-
-VOID
-WINAPI
-BasepFakeStaticServerData(VOID)
-{
- NTSTATUS Status;
- WCHAR Buffer[MAX_PATH];
- PWCHAR HeapBuffer;
- UNICODE_STRING SystemRootString;
- UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
- UNICODE_STRING BaseSrvCSDString;
- UNICODE_STRING BaseSrvWindowsDirectory;
- UNICODE_STRING BaseSrvWindowsSystemDirectory;
- UNICODE_STRING BnoString;
- OBJECT_ATTRIBUTES ObjectAttributes;
- ULONG SessionId;
- HANDLE BaseSrvNamedObjectDirectory;
- HANDLE BaseSrvRestrictedObjectDirectory;
- PACL BnoDacl, BnoRestrictedDacl;
- PSECURITY_DESCRIPTOR BnoSd;
- HANDLE SymHandle;
- UNICODE_STRING DirectoryName, SymlinkName;
- ULONG LuidEnabled;
- RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] =
- {
- {
- NULL,
- RTL_QUERY_REGISTRY_DIRECT,
- L"CSDVersion",
- &BaseSrvCSDString
- },
- {0}
- };
-
- /* Get the session ID */
- SessionId = NtCurrentPeb()->SessionId;
-
- /* Get the Windows directory */
- RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer));
- Status = RtlExpandEnvironmentStrings_U(NULL,
- &UnexpandedSystemRootString,
- &SystemRootString,
- NULL);
- ASSERT(NT_SUCCESS(Status));
-
- /* Create the base directory */
- Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL;
- Status = RtlCreateUnicodeString(&BaseSrvWindowsDirectory,
- SystemRootString.Buffer);
- ASSERT(NT_SUCCESS(Status));
-
- /* Create the system directory */
- wcscat(SystemRootString.Buffer, L"\\system32");
- Status = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory,
- SystemRootString.Buffer);
- ASSERT(NT_SUCCESS(Status));
-
- /* FIXME: Check Session ID */
- wcscpy(Buffer, L"\\BaseNamedObjects");
- RtlInitUnicodeString(&BnoString, Buffer);
-
- /* Allocate the server data */
- BaseStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap,
- HEAP_ZERO_MEMORY,
- sizeof(BASE_STATIC_SERVER_DATA));
- ASSERT(BaseStaticServerData != NULL);
-
- /* Process timezone information */
- BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
- BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
- Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
- &BaseStaticServerData->TimeOfDay,
- sizeof(BaseStaticServerData->TimeOfDay),
- NULL);
- ASSERT(NT_SUCCESS(Status));
-
- /* Make a shared heap copy of the Windows directory */
- BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
- HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap,
- 0,
- BaseSrvWindowsDirectory.MaximumLength);
- ASSERT(HeapBuffer);
- RtlCopyMemory(HeapBuffer,
- BaseStaticServerData->WindowsDirectory.Buffer,
- BaseSrvWindowsDirectory.MaximumLength);
- BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;
-
- /* Make a shared heap copy of the System directory */
- BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
- HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap,
- 0,
- BaseSrvWindowsSystemDirectory.MaximumLength);
- ASSERT(HeapBuffer);
- RtlCopyMemory(HeapBuffer,
- BaseStaticServerData->WindowsSystemDirectory.Buffer,
- BaseSrvWindowsSystemDirectory.MaximumLength);
- BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;
-
- /* This string is not used */
- RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
- NULL,
- 0);
-
- /* Make a shared heap copy of the BNO directory */
- BaseStaticServerData->NamedObjectDirectory = BnoString;
- BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
- sizeof(UNICODE_NULL);
- HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap,
- 0,
- BaseStaticServerData->NamedObjectDirectory.MaximumLength);
- ASSERT(HeapBuffer);
- RtlCopyMemory(HeapBuffer,
- BaseStaticServerData->NamedObjectDirectory.Buffer,
- BaseStaticServerData->NamedObjectDirectory.MaximumLength);
- BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;
-
- /*
- * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
- * and MaximumLength of the CSD String, since the same UNICODE_STRING is
- * being queried twice, the first time as a ULONG!
- *
- * Somehow, in Windows this doesn't cause a buffer overflow, but it might
- * in ReactOS, so this code is disabled until someone figures out WTF.
- */
- BaseStaticServerData->CSDNumber = 0;
- BaseStaticServerData->RCNumber = 0;
-
- /* Initialize the CSD string and query its value from the registry */
- RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
- Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
- L"",
- BaseServerRegistryConfigurationTable,
- NULL,
- NULL);
- if (NT_SUCCESS(Status))
- {
- /* Copy into the shared buffer */
- wcsncpy(BaseStaticServerData->CSDVersion,
- BaseSrvCSDString.Buffer,
- BaseSrvCSDString.Length / sizeof(WCHAR));
- }
- else
- {
- /* NULL-terminate to indicate nothing is there */
- BaseStaticServerData->CSDVersion[0] = UNICODE_NULL;
- }
-
- /* Cache the system information */
- Status = NtQuerySystemInformation(SystemBasicInformation,
- &BaseStaticServerData->SysInfo,
- sizeof(BaseStaticServerData->SysInfo),
- NULL);
- ASSERT(NT_SUCCESS(Status));
-
- /* FIXME: Should query the registry for these */
- BaseStaticServerData->DefaultSeparateVDM = FALSE;
- BaseStaticServerData->IsWowTaskReady = FALSE;
-
- /* Allocate a security descriptor and create it */
- BnoSd = RtlAllocateHeap(CsrHeap, 0, 1024);
- ASSERT(BnoSd);
- Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION);
- ASSERT(NT_SUCCESS(Status));
-
- /* Create the BNO and \Restricted DACLs */
- Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl);
- ASSERT(NT_SUCCESS(Status));
-
- /* Set the BNO DACL as active for now */
- Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE);
- ASSERT(NT_SUCCESS(Status));
-
- /* Create the BNO directory */
- RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
- InitializeObjectAttributes(&ObjectAttributes,
- &BnoString,
- OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
- NULL,
- BnoSd);
- Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- ASSERT(NT_SUCCESS(Status));
-
- /* Check if we are session 0 */
- if (!SessionId)
- {
- /* Mark this as a session 0 directory */
- Status = NtSetInformationObject(BaseSrvNamedObjectDirectory,
- ObjectSessionInformation,
- NULL,
- 0);
- ASSERT(NT_SUCCESS(Status));
- }
-
- /* Check if LUID device maps are enabled */
- Status = NtQueryInformationProcess(NtCurrentProcess(),
- ProcessLUIDDeviceMapsEnabled,
- &LuidEnabled,
- sizeof(LuidEnabled),
- NULL);
- ASSERT(NT_SUCCESS(Status));
- BaseStaticServerData->LUIDDeviceMapsEnabled = LuidEnabled;
- if (!BaseStaticServerData->LUIDDeviceMapsEnabled)
- {
- /* Make Global point back to BNO */
- RtlInitUnicodeString(&DirectoryName, L"Global");
- RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects");
- InitializeObjectAttributes(&ObjectAttributes,
- &DirectoryName,
- OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
- BaseSrvNamedObjectDirectory,
- BnoSd);
- Status = NtCreateSymbolicLinkObject(&SymHandle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes,
- &SymlinkName);
- if ((NT_SUCCESS(Status)) && !(SessionId)) NtClose(SymHandle);
-
- /* Make local point back to \Sessions\x\BNO */
- RtlInitUnicodeString(&DirectoryName, L"Local");
- ASSERT(SessionId == 0);
- InitializeObjectAttributes(&ObjectAttributes,
- &DirectoryName,
- OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
- BaseSrvNamedObjectDirectory,
- BnoSd);
- Status = NtCreateSymbolicLinkObject(&SymHandle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes,
- &SymlinkName);
- if ((NT_SUCCESS(Status)) && !(SessionId)) NtClose(SymHandle);
-
- /* Make Session point back to BNOLINKS */
- RtlInitUnicodeString(&DirectoryName, L"Session");
- RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS");
- InitializeObjectAttributes(&ObjectAttributes,
- &DirectoryName,
- OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
- BaseSrvNamedObjectDirectory,
- BnoSd);
- Status = NtCreateSymbolicLinkObject(&SymHandle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes,
- &SymlinkName);
- if ((NT_SUCCESS(Status)) && !(SessionId)) NtClose(SymHandle);
-
- /* Create the BNO\Restricted directory and set the restricted DACL */
- RtlInitUnicodeString(&DirectoryName, L"Restricted");
- Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE);
- ASSERT(NT_SUCCESS(Status));
- InitializeObjectAttributes(&ObjectAttributes,
- &DirectoryName,
- OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
- BaseSrvNamedObjectDirectory,
- BnoSd);
- Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- ASSERT(NT_SUCCESS(Status));
- }
-
- /* Finally, set the pointer */
- CsrSrvSharedStaticServerData[CSR_CONSOLE] = BaseStaticServerData;
-}
-
-NTSTATUS WINAPI
-CsrpHandleConnectionRequest(PPORT_MESSAGE Request)
-{
- NTSTATUS Status;
- HANDLE ServerPort = NULL;//, ServerThread = NULL;
- PCSR_PROCESS ProcessData = NULL;
- REMOTE_PORT_VIEW RemotePortView;
-// CLIENT_ID ClientId;
- BOOLEAN AllowConnection = FALSE;
- PCSR_CONNECTION_INFO ConnectInfo;
- ServerPort = NULL;
-
- DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
-
- ConnectInfo = (PCSR_CONNECTION_INFO)(Request + 1);
-
- /* Save the process ID */
- RtlZeroMemory(ConnectInfo, sizeof(CSR_CONNECTION_INFO));
-
- CsrLockProcessByClientId(Request->ClientId.UniqueProcess, &ProcessData);
- if (!ProcessData)
- {
- DPRINT1("CSRSRV: Unknown process: %lx. Will be rejecting connection\n",
- Request->ClientId.UniqueProcess);
- }
-
- if ((ProcessData) && (ProcessData != CsrRootProcess))
- {
- /* Attach the Shared Section */
- Status = CsrSrvAttachSharedSection(ProcessData, ConnectInfo);
- if (NT_SUCCESS(Status))
- {
- DPRINT("Connection ok\n");
- AllowConnection = TRUE;
- }
- else
- {
- DPRINT1("Shared section map failed: %lx\n", Status);
- }
- }
- else if (ProcessData == CsrRootProcess)
- {
- AllowConnection = TRUE;
- }
-
- /* Release the process */
- if (ProcessData) CsrUnlockProcess(ProcessData);
-
- /* Setup the Port View Structure */
- RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
- RemotePortView.ViewSize = 0;
- RemotePortView.ViewBase = NULL;
-
- /* Save the Process ID */
- ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess;
-
- Status = NtAcceptConnectPort(&ServerPort,
- AllowConnection ? UlongToPtr(ProcessData->SequenceNumber) : 0,
- Request,
- AllowConnection,
- NULL,
- &RemotePortView);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtAcceptConnectPort - failed. Status == %X\n", Status);
- }
- else if (AllowConnection)
- {
- if (CsrDebug & 2)
- {
- DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n",
- Request->ClientId.UniqueProcess,
- Request->ClientId.UniqueThread,
- RemotePortView.ViewBase,
- RemotePortView.ViewSize);
- }
-
- /* Set some Port Data in the Process */
- ProcessData->ClientPort = ServerPort;
- ProcessData->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase;
- ProcessData->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase +
- (ULONG_PTR)RemotePortView.ViewSize);
-
- /* Complete the connection */
- Status = NtCompleteConnectPort(ServerPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status);
- }
- }
- else
- {
- DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
- Request->ClientId.UniqueProcess,
- Request->ClientId.UniqueThread);
- }
-
- return Status;
-}
-
-/*++
- * @name CsrConnectToUser
- * @implemented NT4
- *
- * The CsrConnectToUser connects to the User subsystem.
- *
- * @param None
- *
- * @return A pointer to the CSR Thread
- *
- * @remarks None.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrConnectToUser(VOID)
-{
- PTEB Teb = NtCurrentTeb();
- PCSR_THREAD CsrThread;
-#if 0
- NTSTATUS Status;
- ANSI_STRING DllName;
- UNICODE_STRING TempName;
- HANDLE hUser32;
- STRING StartupName;
-
- /* Check if we didn't already find it */
- if (!CsrClientThreadSetup)
- {
- /* Get the DLL Handle for user32.dll */
- RtlInitAnsiString(&DllName, "user32");
- RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE);
- Status = LdrGetDllHandle(NULL,
- NULL,
- &TempName,
- &hUser32);
- RtlFreeUnicodeString(&TempName);
-
- /* If we got teh handle, get the Client Thread Startup Entrypoint */
- if (NT_SUCCESS(Status))
- {
- RtlInitAnsiString(&StartupName,"ClientThreadSetup");
- Status = LdrGetProcedureAddress(hUser32,
- &StartupName,
- 0,
- (PVOID)&CsrClientThreadSetup);
- }
- }
-
- /* Connect to user32 */
- CsrClientThreadSetup();
-#endif
- /* Save pointer to this thread in TEB */
- CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
- if (CsrThread) Teb->CsrClientThread = CsrThread;
-
- /* Return it */
- return CsrThread;
-}
-
-/*++
- * @name CsrpCheckRequestThreads
- *
- * The CsrpCheckRequestThreads routine checks if there are no more threads
- * to handle CSR API Requests, and creates a new thread if possible, to
- * avoid starvation.
- *
- * @param None.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * if a new thread couldn't be created.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrpCheckRequestThreads(VOID)
-{
- HANDLE hThread;
- CLIENT_ID ClientId;
- NTSTATUS Status;
-
- /* Decrease the count, and see if we're out */
- if (!(_InterlockedDecrement(&CsrpStaticThreadCount)))
- {
- /* Check if we've still got space for a Dynamic Thread */
- if (CsrpDynamicThreadTotal < CsrMaxApiRequestThreads)
- {
- /* Create a new dynamic thread */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- TRUE,
- 0,
- 0,
- 0,
- (PVOID)ClientConnectionThread,//CsrApiRequestThread,
- NULL,
- &hThread,
- &ClientId);
- /* Check success */
- if (NT_SUCCESS(Status))
- {
- /* Increase the thread counts */
- _InterlockedIncrement(&CsrpStaticThreadCount);
- _InterlockedIncrement(&CsrpDynamicThreadTotal);
-
- /* Add a new server thread */
- if (CsrAddStaticServerThread(hThread,
- &ClientId,
- CsrThreadIsServerThread))
- {
- /* Activate it */
- NtResumeThread(hThread, NULL);
- }
- else
- {
- /* Failed to create a new static thread */
- _InterlockedDecrement(&CsrpStaticThreadCount);
- _InterlockedDecrement(&CsrpDynamicThreadTotal);
-
- /* Terminate it */
- DPRINT1("Failing\n");
- NtTerminateThread(hThread, 0);
- NtClose(hThread);
-
- /* Return */
- return STATUS_UNSUCCESSFUL;
- }
- }
- }
- }
-
- /* Success */
- return STATUS_SUCCESS;
-}
-
-VOID
-WINAPI
-ClientConnectionThread(IN PVOID Parameter)
-{
- PTEB Teb = NtCurrentTeb();
- LARGE_INTEGER TimeOut;
- NTSTATUS Status;
- BYTE RawRequest[LPC_MAX_DATA_LENGTH];
- PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
- PCSR_API_MESSAGE Reply;
- PCSR_PROCESS CsrProcess;
- PCSR_THREAD ServerThread, CsrThread;
- ULONG MessageType;
- HANDLE ReplyPort;
- PDBGKM_MSG DebugMessage;
- PHARDERROR_MSG HardErrorMsg;
- PCLIENT_DIED_MSG ClientDiedMsg;
- DPRINT("CSR: %s called\n", __FUNCTION__);
-
- /* Setup LPC loop port and message */
- Reply = NULL;
- ReplyPort = CsrApiPort;
-
- /* Connect to user32 */
- while (!CsrConnectToUser())
- {
- /* Set up the timeout for the connect (30 seconds) */
- TimeOut.QuadPart = -30 * 1000 * 1000 * 10;
-
- /* Keep trying until we get a response */
- Teb->Win32ClientInfo[0] = 0;
- NtDelayExecution(FALSE, &TimeOut);
- }
-
- /* Get our thread */
- ServerThread = Teb->CsrClientThread;
-
- /* If we got an event... */
- if (Parameter)
- {
- /* Set it, to let stuff waiting on us load */
- Status = NtSetEvent((HANDLE)Parameter, NULL);
- ASSERT(NT_SUCCESS(Status));
-
- /* Increase the Thread Counts */
- _InterlockedIncrement(&CsrpStaticThreadCount);
- _InterlockedIncrement(&CsrpDynamicThreadTotal);
- }
-
- /* Now start the loop */
- while (TRUE)
- {
- /* Make sure the real CID is set */
- Teb->RealClientId = Teb->ClientId;
-
- /* Debug check */
- if (Teb->CountOfOwnedCriticalSections)
- {
- DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu critical sections\n",
- Teb->CountOfOwnedCriticalSections);
- DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n",
- Request, Reply);
- DbgBreakPoint();
- }
-
- /* Send the reply and wait for a new request */
- DPRINT("Replying to: %lx (%lx)\n", ReplyPort, CsrApiPort);
- Status = NtReplyWaitReceivePort(ReplyPort,
- 0,
- &Reply->Header,
- &Request->Header);
- /* Check if we didn't get success */
- if (Status != STATUS_SUCCESS)
- {
- /* Was it a failure or another success code? */
- if (!NT_SUCCESS(Status))
- {
- /* Check for specific status cases */
- if ((Status != STATUS_INVALID_CID) &&
- (Status != STATUS_UNSUCCESSFUL) &&
- ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
- {
- /* Notify the debugger */
- DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
- DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort);
- }
-
- /* We failed big time, so start out fresh */
- Reply = NULL;
- ReplyPort = CsrApiPort;
- DPRINT1("failed: %lx\n", Status);
- continue;
- }
- else
- {
- /* A bizare "success" code, just try again */
- DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status);
- continue;
- }
- }
-
- /* Use whatever Client ID we got */
- Teb->RealClientId = Request->Header.ClientId;
-
- /* Get the Message Type */
- MessageType = Request->Header.u2.s2.Type;
-
- /* Handle connection requests */
- if (MessageType == LPC_CONNECTION_REQUEST)
- {
- /* Handle the Connection Request */
- DPRINT("Accepting new connection\n");
- CsrpHandleConnectionRequest((PPORT_MESSAGE)Request);
- Reply = NULL;
- ReplyPort = CsrApiPort;
- continue;
- }
-
- /* It's some other kind of request. Get the lock for the lookup */
- CsrAcquireProcessLock();
-
- /* Now do the lookup to get the CSR_THREAD */
- CsrThread = CsrLocateThreadByClientId(&CsrProcess,
- &Request->Header.ClientId);
-
- /* Did we find a thread? */
- if (!CsrThread)
- {
- /* This wasn't a CSR Thread, release lock */
- CsrReleaseProcessLock();
-
- /* If this was an exception, handle it */
- if (MessageType == LPC_EXCEPTION)
- {
- DPRINT1("Exception from unknown thread, just continue\n");
- Reply = Request;
- ReplyPort = CsrApiPort;
- Reply->Status = DBG_CONTINUE;
- }
- else if (MessageType == LPC_PORT_CLOSED ||
- MessageType == LPC_CLIENT_DIED)
- {
- /* The Client or Port are gone, loop again */
- DPRINT("Death from unknown thread, just continue\n");
- Reply = NULL;
- ReplyPort = CsrApiPort;
- }
- else if (MessageType == LPC_ERROR_EVENT)
- {
- /* If it's a hard error, handle this too */
- DPRINT1("Hard error from unknown thread, call handlers\n");
-HandleHardError:
- HardErrorMsg = (PHARDERROR_MSG)Request;
-
- /* Default it to unhandled */
- HardErrorMsg->Response = ResponseNotHandled;
-
- /* Check if there are free api threads */
- CsrpCheckRequestThreads();
- if (CsrpStaticThreadCount)
- {
- CsrHandleHardError(CsrThread, (PHARDERROR_MSG)Request);
- }
-
- /* If the response was 0xFFFFFFFF, we'll ignore it */
- if (HardErrorMsg->Response == 0xFFFFFFFF)
- {
- Reply = NULL;
- ReplyPort = CsrApiPort;
- }
- else
- {
- if (CsrThread) CsrDereferenceThread(CsrThread);
- Reply = Request;
- ReplyPort = CsrApiPort;
- }
- }
- else if (MessageType == LPC_REQUEST)
- {
- /* This is an API Message coming from a non-CSR Thread */
- DPRINT1("No thread found for request %lx and clientID %lx.%lx\n",
- Request->Type & 0xFFFF,
- Request->Header.ClientId.UniqueProcess,
- Request->Header.ClientId.UniqueThread);
- Reply = Request;
- ReplyPort = CsrApiPort;
- Reply->Status = STATUS_ILLEGAL_FUNCTION;
- }
- else if (MessageType == LPC_DATAGRAM)
- {
- DPRINT1("Kernel datagram: not yet supported\n");
- Reply = NULL;
- ReplyPort = CsrApiPort;
- }
- else
- {
- /* Some other ignored message type */
- Reply = NULL;
- ReplyPort = CsrApiPort;
- }
-
- /* Keep going */
- continue;
- }
-
- /* We have a valid thread, was this an LPC Request? */
- if (MessageType != LPC_REQUEST)
- {
- /* It's not an API, check if the client died */
- if (MessageType == LPC_CLIENT_DIED)
- {
- /* Get the information and check if it matches our thread */
- ClientDiedMsg = (PCLIENT_DIED_MSG)Request;
- if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart)
- {
- /* Reference the thread */
- CsrLockedReferenceThread(CsrThread);
-
- /* Destroy the thread in the API Message */
- CsrDestroyThread(&Request->Header.ClientId);
-
- /* Check if the thread was actually ourselves */
- if (CsrProcess->ThreadCount == 1)
- {
- /* Kill the process manually here */
- DPRINT1("Last thread\n");
- CsrDestroyProcess(&CsrThread->ClientId, 0);
- }
-
- /* Remove our extra reference */
- CsrLockedDereferenceThread(CsrThread);
- }
-
- /* Release the lock and keep looping */
- CsrReleaseProcessLock();
- Reply = NULL;
- ReplyPort = CsrApiPort;
- continue;
- }
-
- /* Reference the thread and release the lock */
- CsrLockedReferenceThread(CsrThread);
- CsrReleaseProcessLock();
-
- /* If this was an exception, handle it */
- if (MessageType == LPC_EXCEPTION)
- {
- /* Kill the process */
- DPRINT1("Exception in %lx.%lx. Killing...\n",
- Request->Header.ClientId.UniqueProcess,
- Request->Header.ClientId.UniqueThread);
- NtTerminateProcess(CsrProcess->ProcessHandle, STATUS_ABANDONED);
-
- /* Destroy it from CSR */
- CsrDestroyProcess(&Request->Header.ClientId, STATUS_ABANDONED);
-
- /* Return a Debug Message */
- DebugMessage = (PDBGKM_MSG)Request;
- DebugMessage->ReturnedStatus = DBG_CONTINUE;
- Reply = Request;
- ReplyPort = CsrApiPort;
-
- /* Remove our extra reference */
- CsrDereferenceThread(CsrThread);
- }
- else if (MessageType == LPC_ERROR_EVENT)
- {
- DPRINT1("Hard error from known CSR thread... handling\n");
- goto HandleHardError;
- }
- else
- {
- /* Something else */
- DPRINT1("Unhandled message type: %lx\n", MessageType);
- CsrDereferenceThread(CsrThread);
- Reply = NULL;
- }
-
- /* Keep looping */
- continue;
- }
-
- /* We got an API Request */
- CsrLockedReferenceThread(CsrThread);
- CsrReleaseProcessLock();
-
- /* Assume success */
- Reply = Request;
- Request->Status = STATUS_SUCCESS;
-
- /* Now we reply to a particular client */
- ReplyPort = CsrThread->Process->ClientPort;
-
- DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
- Request->Type,
- Request->Header.ClientId.UniqueThread);
-
- /* Validation complete, start SEH */
- _SEH2_TRY
- {
- /* Make sure we have enough threads */
- CsrpCheckRequestThreads();
-
- /* Set the client thread pointer */
- NtCurrentTeb()->CsrClientThread = CsrThread;
-
- /* Call the Handler */
- CsrApiCallHandler(CsrThread->Process, Request);
-
- /* Increase the static thread count */
- _InterlockedIncrement(&CsrpStaticThreadCount);
-
- /* Restore the server thread */
- NtCurrentTeb()->CsrClientThread = ServerThread;
-
- /* Check if this is a dead client now */
- if (Request->Type == 0xBABE)
- {
- /* Reply to the death message */
- NtReplyPort(ReplyPort, &Reply->Header);
-
- /* Reply back to the API port now */
- ReplyPort = CsrApiPort;
- Reply = NULL;
-
- /* Drop the reference */
- CsrDereferenceThread(CsrThread);
- }
- else
- {
- /* Drop the reference */
- CsrDereferenceThread(CsrThread);
- }
- }
- _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
- {
- Reply = NULL;
- ReplyPort = CsrApiPort;
- }
- _SEH2_END;
- }
-
- /* Close the port and exit the thread */
- // NtClose(ServerPort);
-
- DPRINT1("CSR: %s done\n", __FUNCTION__);
- /* We're out of the loop for some reason, terminate! */
- NtTerminateThread(NtCurrentThread(), Status);
- //return Status;
-}
-
-/*++
- * @name CsrReleaseCapturedArguments
- * @implemented NT5.1
- *
- * The CsrReleaseCapturedArguments routine releases a Capture Buffer
- * that was previously captured with CsrCaptureArguments.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message containing the Capture Buffer
- * that needs to be released.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
-{
- PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer;
- SIZE_T BufferDistance;
- ULONG PointerCount;
- ULONG_PTR **PointerOffsets, *CurrentPointer;
-
- /* Get the capture buffers */
- RemoteCaptureBuffer = ApiMessage->CsrCaptureData;
- LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer;
-
- /* Free the previous one */
- RemoteCaptureBuffer->PreviousCaptureBuffer = NULL;
-
- /* Find out the difference between the two buffers */
- BufferDistance = (ULONG_PTR)LocalCaptureBuffer - (ULONG_PTR)RemoteCaptureBuffer;
-
- /* Save the pointer count and offset pointer */
- PointerCount = RemoteCaptureBuffer->PointerCount;
- PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1);
-
- /* Start the loop */
- while (PointerCount)
- {
- /* Get the current pointer */
- CurrentPointer = *PointerOffsets++;
- if (CurrentPointer)
- {
- /* Add it to the CSR Message structure */
- CurrentPointer += (ULONG_PTR)ApiMessage;
-
- /* Modify the pointer to take into account its new position */
- *CurrentPointer += BufferDistance;
- }
-
- /* Move to the next Pointer */
- PointerCount--;
- }
-
- /* Copy the data back */
- RtlMoveMemory(LocalCaptureBuffer, RemoteCaptureBuffer, RemoteCaptureBuffer->Size);
-
- /* Free our allocated buffer */
- RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
-}
-
-/* EOF */