+++ /dev/null
-
-include_directories(
- include
- ${REACTOS_SOURCE_DIR}/include/reactos/subsys
- ${REACTOS_SOURCE_DIR}/include/reactos/drivers)
-
-add_executable(csrss2 main.c csr.rc)
-
-set_module_type(csrss2 nativecui)
-target_link_libraries(csrss2 nt)
-add_importlibs(csrss2 ntdll csrsrv2)
-add_dependencies(csrss2 psdk bugcodes)
-add_cd_file(TARGET csrss2 DESTINATION reactos/system32 FOR all)
-
-add_subdirectory(csrsrv)
-
+++ /dev/null
-#define REACTOS_STR_FILE_DESCRIPTION "Client/Server Runtime Process\0"
-#define REACTOS_STR_INTERNAL_NAME "csrss\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "csrss.exe\0"
-#include <reactos/version.rc>
+++ /dev/null
-
-include_directories(${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include)
-include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys)
-
-spec2def(csrsrv2.dll csrsrv2.spec ADD_IMPORTLIB)
-
-list(APPEND SOURCE
- api.c
- init.c
- process.c
- server.c
- session.c
- thread.c
- wait.c
- csrsrv.rc
- ${CMAKE_CURRENT_BINARY_DIR}/csrsrv2.def)
-
-add_library(csrsrv2 SHARED ${SOURCE})
-
-target_link_libraries(csrsrv2 ${PSEH_LIB} smlib)
-
-set_module_type(csrsrv2 nativedll)
-
-add_importlibs(csrsrv2 ntdll)
-
-add_pch(csrsrv2 srv.h)
-
-add_dependencies(csrsrv2 psdk bugcodes)
-add_cd_file(TARGET csrsrv2 DESTINATION reactos/system32 FOR all)
-
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrsrv/api.c
- * PURPOSE: CSR Server DLL API LPC Implementation
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-BOOLEAN (*CsrClientThreadSetup)(VOID) = NULL;
-ULONG CsrMaxApiRequestThreads;
-UNICODE_STRING CsrSbApiPortName;
-UNICODE_STRING CsrApiPortName;
-HANDLE CsrSbApiPort;
-HANDLE CsrApiPort;
-PCSR_THREAD CsrSbApiRequestThreadPtr;
-volatile LONG CsrpStaticThreadCount;
-volatile LONG CsrpDynamicThreadTotal;
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @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)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 */
- NtTerminateThread(hThread,0);
- NtClose(hThread);
-
- /* Return */
- return STATUS_UNSUCCESSFUL;
- }
- }
- }
- }
-
- /* Success */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSbApiPortInitialize
- *
- * The CsrSbApiPortInitialize routine initializes the LPC Port used for
- * communications with the Session Manager (SM) and initializes the static
- * thread that will handle connection requests and APIs.
- *
- * @param None
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSbApiPortInitialize(VOID)
-{
- ULONG Size;
- PSECURITY_DESCRIPTOR PortSd;
- OBJECT_ATTRIBUTES ObjectAttributes;
- NTSTATUS Status;
- HANDLE hRequestThread;
- CLIENT_ID ClientId;
-
- /* Calculate how much space we'll need for the Port Name */
- Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR);
-
- /* Create the buffer for it */
- CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
- if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY;
-
- /* Setup the rest of the empty string */
- CsrSbApiPortName.Length = 0;
- CsrSbApiPortName.MaximumLength = (USHORT)Size;
-
- /* Now append the full port name */
- RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName);
- RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP);
- RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME);
- if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName);
-
- /* Create Security Descriptor for this Port */
- Status = CsrCreateLocalSystemSD(&PortSd);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Initialize the Attributes */
- InitializeObjectAttributes(&ObjectAttributes,
- &CsrSbApiPortName,
- 0,
- NULL,
- PortSd);
-
- /* Create the Port Object */
- Status = NtCreatePort(&CsrSbApiPort,
- &ObjectAttributes,
- sizeof(SB_CONNECTION_INFO),
- sizeof(SB_API_MSG),
- 32 * sizeof(SB_API_MSG));
- if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd);
-
- if (NT_SUCCESS(Status))
- {
- /* Create the Thread to handle the API Requests */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- TRUE,
- 0,
- 0,
- 0,
- (PVOID)CsrSbApiRequestThread,
- NULL,
- &hRequestThread,
- &ClientId);
- if (NT_SUCCESS(Status))
- {
- /* Add it as a Static Server Thread */
- CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread,
- &ClientId,
- 0);
-
- /* Activate it */
- Status = NtResumeThread(hRequestThread, NULL);
- }
- }
-
- return Status;
-}
-
-/*++
- * @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
- * othwerwise.
- *
- * @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,
- sizeof(CSR_CONNECTION_INFO),
- 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)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;
-}
-
-/*++
- * @name CsrApiRequestThread
- *
- * The CsrApiRequestThread routine handles incoming messages or connection
- * requests on the CSR API LPC Port.
- *
- * @param Parameter
- * System-default user-defined parameter. Unused.
- *
- * @return The thread exit code, if the thread is terminated.
- *
- * @remarks Before listening on the port, the routine will first attempt
- * to connect to the user subsystem.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrApiRequestThread(IN PVOID Parameter)
-{
- PTEB Teb = NtCurrentTeb();
- LARGE_INTEGER TimeOut;
- PCSR_THREAD CurrentThread, CsrThread;
- NTSTATUS Status;
- PCSR_API_MESSAGE ReplyMsg;
- CSR_API_MESSAGE ReceiveMsg;
- PCSR_PROCESS CsrProcess;
- PHARDERROR_MSG HardErrorMsg;
- PVOID PortContext;
- PCSR_SERVER_DLL ServerDll;
- PCLIENT_DIED_MSG ClientDiedMsg;
- PDBGKM_MSG DebugMessage;
- ULONG ServerId, ApiId, Reply, MessageType, i;
- HANDLE ReplyPort;
-
- /* Setup LPC loop port and message */
- ReplyMsg = 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 */
- CurrentThread = 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",
- &ReceiveMsg, ReplyMsg);
- DbgBreakPoint();
- }
-
- /* Wait for a message to come through */
- Status = NtReplyWaitReceivePort(ReplyPort,
- &PortContext,
- &ReplyMsg->Header,
- &ReceiveMsg.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 */
- ReplyMsg = NULL;
- ReplyPort = CsrApiPort;
- 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 = ReceiveMsg.Header.ClientId;
-
- /* Get the Message Type */
- MessageType = ReceiveMsg.Header.u2.s2.Type;
-
- /* Handle connection requests */
- if (MessageType == LPC_CONNECTION_REQUEST)
- {
- /* Handle the Connection Request */
- CsrApiHandleConnectionRequest(&ReceiveMsg);
- ReplyPort = CsrApiPort;
- ReplyMsg = NULL;
- 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,
- &ReceiveMsg.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)
- {
- ReplyMsg = &ReceiveMsg;
- ReplyPort = CsrApiPort;
- ReplyMsg->Status = DBG_CONTINUE;
- }
- else if (MessageType == LPC_PORT_CLOSED ||
- MessageType == LPC_CLIENT_DIED)
- {
- /* The Client or Port are gone, loop again */
- ReplyMsg = NULL;
- ReplyPort = CsrApiPort;
- }
- else if (MessageType == LPC_ERROR_EVENT)
- {
- /* If it's a hard error, handle this too */
- HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg;
-
- /* Default it to unhandled */
- HardErrorMsg->Response = ResponseNotHandled;
-
- /* Check if there are free api threads */
- CsrpCheckRequestThreads();
- if (CsrpStaticThreadCount)
- {
- /* Loop every Server DLL */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the Server DLL */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Check if it's valid and if it has a Hard Error Callback */
- if ((ServerDll) && (ServerDll->HardErrorCallback))
- {
- /* Call it */
- ServerDll->HardErrorCallback(NULL, HardErrorMsg);
-
- /* If it's handled, get out of here */
- if (HardErrorMsg->Response != ResponseNotHandled) break;
- }
- }
- }
-
- /* Increase the thread count */
- _InterlockedIncrement(&CsrpStaticThreadCount);
-
- /* If the response was 0xFFFFFFFF, we'll ignore it */
- if (HardErrorMsg->Response == 0xFFFFFFFF)
- {
- ReplyMsg = NULL;
- ReplyPort = CsrApiPort;
- }
- else
- {
- ReplyMsg = &ReceiveMsg;
- }
- }
- else if (MessageType == LPC_REQUEST)
- {
- /* This is an API Message coming from a non-CSR Thread */
- ReplyMsg = &ReceiveMsg;
- ReplyPort = CsrApiPort;
- ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
- }
- else if (MessageType == LPC_DATAGRAM)
- {
- /* This is an API call, 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 */
- ServerDll = NULL;
- 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);
- DbgBreakPoint();
- ReplyPort = CsrApiPort;
- ReplyMsg = NULL;
- continue;
- }
-
- /* 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)
- {
- /* We are beyond the Maximum API ID, or it doesn't exist */
- DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
- CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode),
- &ServerDll->Name);
- ReplyPort = CsrApiPort;
- ReplyMsg = NULL;
- continue;
- }
-
- if (CsrDebug & 2)
- {
- DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n",
- Teb->ClientId.UniqueThread,
- ReceiveMsg.Header.ClientId.UniqueProcess,
- ReceiveMsg.Header.ClientId.UniqueThread,
- ServerDll->NameTable[ApiId],
- NULL);
- }
-
- /* Assume success */
- ReceiveMsg.Status = STATUS_SUCCESS;
-
- /* Validation complete, start SEH */
- _SEH2_TRY
- {
- /* Make sure we have enough threads */
- CsrpCheckRequestThreads();
-
- /* Call the API and get the result */
- ReplyMsg = NULL;
- ReplyPort = CsrApiPort;
- ServerDll->DispatchTable[ApiId](&ReceiveMsg, &Reply);
-
- /* Increase the static thread count */
- _InterlockedIncrement(&CsrpStaticThreadCount);
- }
- _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
- {
- ReplyMsg = NULL;
- ReplyPort = CsrApiPort;
- }
- _SEH2_END;
- }
- else
- {
- /* Some other ignored message type */
- ReplyMsg = 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)&ReceiveMsg;
- if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart)
- {
- /* Reference the thread */
- CsrLockedReferenceThread(CsrThread);
-
- /* Destroy the thread in the API Message */
- CsrDestroyThread(&ReceiveMsg.Header.ClientId);
-
- /* Check if the thread was actually ourselves */
- if (CsrProcess->ThreadCount == 1)
- {
- /* Kill the process manually here */
- CsrDestroyProcess(&CsrThread->ClientId, 0);
- }
-
- /* Remove our extra reference */
- CsrLockedDereferenceThread(CsrThread);
- }
-
- /* Release the lock and keep looping */
- CsrReleaseProcessLock();
- ReplyMsg = NULL;
- ReplyPort = CsrApiPort;
- continue;
- }
-
- /* Reference the thread and release the lock */
- CsrLockedReferenceThread(CsrThread);
- CsrReleaseProcessLock();
-
- /* Check if this was an exception */
- if (MessageType == LPC_EXCEPTION)
- {
- /* Kill the process */
- NtTerminateProcess(CsrProcess->ProcessHandle, STATUS_ABANDONED);
-
- /* Destroy it from CSR */
- CsrDestroyProcess(&ReceiveMsg.Header.ClientId, STATUS_ABANDONED);
-
- /* Return a Debug Message */
- DebugMessage = (PDBGKM_MSG)&ReceiveMsg;
- DebugMessage->ReturnedStatus = DBG_CONTINUE;
- ReplyMsg = &ReceiveMsg;
- ReplyPort = CsrApiPort;
-
- /* Remove our extra reference */
- CsrDereferenceThread(CsrThread);
- }
- else if (MessageType == LPC_ERROR_EVENT)
- {
- /* If it's a hard error, handle this too */
- HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg;
-
- /* Default it to unhandled */
- HardErrorMsg->Response = ResponseNotHandled;
-
- /* Check if there are free api threads */
- CsrpCheckRequestThreads();
- if (CsrpStaticThreadCount)
- {
- /* Loop every Server DLL */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the Server DLL */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Check if it's valid and if it has a Hard Error Callback */
- if ((ServerDll) && (ServerDll->HardErrorCallback))
- {
- /* Call it */
- ServerDll->HardErrorCallback(CsrThread, HardErrorMsg);
-
- /* If it's handled, get out of here */
- if (HardErrorMsg->Response != ResponseNotHandled) break;
- }
- }
- }
-
- /* Increase the thread count */
- _InterlockedIncrement(&CsrpStaticThreadCount);
-
- /* If the response was 0xFFFFFFFF, we'll ignore it */
- if (HardErrorMsg->Response == 0xFFFFFFFF)
- {
- ReplyMsg = NULL;
- ReplyPort = CsrApiPort;
- }
- else
- {
- CsrDereferenceThread(CsrThread);
- ReplyMsg = &ReceiveMsg;
- ReplyPort = CsrApiPort;
- }
- }
- else
- {
- /* Something else */
- CsrDereferenceThread(CsrThread);
- ReplyMsg = NULL;
- }
-
- /* Keep looping */
- continue;
- }
-
- /* We got an API Request */
- CsrLockedReferenceThread(CsrThread);
- CsrReleaseProcessLock();
-
- /* This is an API call, 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 */
- ServerDll = NULL;
- 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);
- DbgBreakPoint();
-
- ReplyPort = CsrApiPort;
- ReplyMsg = &ReceiveMsg;
- ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
- CsrDereferenceThread(CsrThread);
- continue;
- }
-
- /* 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)
- {
- /* We are beyond the Maximum API ID, or it doesn't exist */
- DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
- CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode),
- &ServerDll->Name);
-
- ReplyPort = CsrApiPort;
- ReplyMsg = &ReceiveMsg;
- ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
- CsrDereferenceThread(CsrThread);
- continue;
- }
-
- if (CsrDebug & 2)
- {
- DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n",
- Teb->ClientId.UniqueThread,
- ReceiveMsg.Header.ClientId.UniqueProcess,
- ReceiveMsg.Header.ClientId.UniqueThread,
- ServerDll->NameTable[ApiId],
- CsrThread);
- }
-
- /* Assume success */
- ReplyMsg = &ReceiveMsg;
- ReceiveMsg.Status = STATUS_SUCCESS;
-
- /* Now we reply to a particular client */
- ReplyPort = CsrThread->Process->ClientPort;
-
- /* Check if there's a capture buffer */
- if (ReceiveMsg.CsrCaptureData)
- {
- /* Capture the arguments */
- if (!CsrCaptureArguments(CsrThread, &ReceiveMsg))
- {
- /* Ignore this message if we failed to get the arguments */
- CsrDereferenceThread(CsrThread);
- continue;
- }
- }
-
- /* Validation complete, start SEH */
- _SEH2_TRY
- {
- /* Make sure we have enough threads */
- CsrpCheckRequestThreads();
-
- Teb->CsrClientThread = CsrThread;
-
- /* Call the API and get the result */
- Reply = 0;
- ServerDll->DispatchTable[ApiId](&ReceiveMsg, &Reply);
-
- /* Increase the static thread count */
- _InterlockedIncrement(&CsrpStaticThreadCount);
-
- Teb->CsrClientThread = CurrentThread;
-
- if (Reply == 3)
- {
- ReplyMsg = NULL;
- if (ReceiveMsg.CsrCaptureData)
- {
- CsrReleaseCapturedArguments(&ReceiveMsg);
- }
- CsrDereferenceThread(CsrThread);
- ReplyPort = CsrApiPort;
- }
- else if (Reply == 2)
- {
- NtReplyPort(ReplyPort, &ReplyMsg->Header);
- ReplyPort = CsrApiPort;
- ReplyMsg = NULL;
- CsrDereferenceThread(CsrThread);
- }
- else if (Reply == 1)
- {
- ReplyPort = CsrApiPort;
- ReplyMsg = NULL;
- }
- else
- {
- if (ReceiveMsg.CsrCaptureData)
- {
- CsrReleaseCapturedArguments(&ReceiveMsg);
- }
- CsrDereferenceThread(CsrThread);
- }
- }
- _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
- {
- ReplyMsg = NULL;
- ReplyPort = CsrApiPort;
- }
- _SEH2_END;
- }
-
- /* We're out of the loop for some reason, terminate! */
- NtTerminateThread(NtCurrentThread(), Status);
- return Status;
-}
-
-/*++
- * @name CsrApiHandleConnectionRequest
- *
- * The CsrApiHandleConnectionRequest routine handles and accepts a new
- * connection request to the CSR API LPC Port.
- *
- * @param ApiMessage
- * Pointer to the incoming CSR API Message which contains the
- * connection request.
- *
- * @return STATUS_SUCCESS in case of success, or status code which caused
- * the routine to error.
- *
- * @remarks This routine is responsible for attaching the Shared Section to
- * new clients connecting to CSR.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
-{
- PCSR_THREAD CsrThread = NULL;
- PCSR_PROCESS CsrProcess = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- PCSR_CONNECTION_INFO ConnectInfo = &ApiMessage->ConnectionInfo;
- BOOLEAN AllowConnection = FALSE;
- REMOTE_PORT_VIEW RemotePortView;
- HANDLE hPort;
-
- /* Acquire the Process Lock */
- CsrAcquireProcessLock();
-
- /* Lookup the CSR Thread */
- CsrThread = CsrLocateThreadByClientId(NULL, &ApiMessage->Header.ClientId);
-
- /* Check if we have a thread */
- if (CsrThread)
- {
- /* Get the Process */
- CsrProcess = CsrThread->Process;
-
- /* Make sure we have a Process as well */
- if (CsrProcess)
- {
- /* Reference the Process */
- CsrLockedReferenceProcess(CsrThread->Process);
-
- /* Release the lock */
- CsrReleaseProcessLock();
-
- /* Duplicate the Object Directory */
- Status = NtDuplicateObject(NtCurrentProcess(),
- CsrObjectDirectory,
- CsrProcess->ProcessHandle,
- &ConnectInfo->ObjectDirectory,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS |
- DUPLICATE_SAME_ATTRIBUTES);
-
- /* Acquire the lock */
- CsrAcquireProcessLock();
-
- /* Check for success */
- if (NT_SUCCESS(Status))
- {
- /* Attach the Shared Section */
- Status = CsrSrvAttachSharedSection(CsrProcess, ConnectInfo);
-
- /* Check how this went */
- if (NT_SUCCESS(Status)) AllowConnection = TRUE;
- }
-
- /* Dereference the project */
- CsrLockedDereferenceProcess(CsrProcess);
- }
- }
-
- /* Release the lock */
- CsrReleaseProcessLock();
-
- /* 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;
-
- /* Accept the Connection */
- Status = NtAcceptConnectPort(&hPort,
- AllowConnection ? UlongToPtr(CsrProcess->SequenceNumber) : 0,
- &ApiMessage->Header,
- 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",
- ApiMessage->Header.ClientId.UniqueProcess,
- ApiMessage->Header.ClientId.UniqueThread,
- RemotePortView.ViewBase,
- RemotePortView.ViewSize);
- }
-
- /* Set some Port Data in the Process */
- CsrProcess->ClientPort = hPort;
- CsrProcess->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase;
- CsrProcess->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase +
- (ULONG_PTR)RemotePortView.ViewSize);
-
- /* Complete the connection */
- Status = NtCompleteConnectPort(hPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status);
- }
- }
- else
- {
- DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
- ApiMessage->Header.ClientId.UniqueProcess,
- ApiMessage->Header.ClientId.UniqueThread);
- }
-
- /* Return status to caller */
- return Status;
-}
-
-/*++
- * @name CsrSbApiRequestThread
- *
- * The CsrSbApiRequestThread routine handles incoming messages or connection
- * requests on the SM API LPC Port.
- *
- * @param Parameter
- * System-default user-defined parameter. Unused.
- *
- * @return The thread exit code, if the thread is terminated.
- *
- * @remarks Before listening on the port, the routine will first attempt
- * to connect to the user subsystem.
- *
- *--*/
-VOID
-NTAPI
-CsrSbApiRequestThread(IN PVOID Parameter)
-{
- NTSTATUS Status;
- SB_API_MSG ReceiveMsg;
- PSB_API_MSG ReplyMsg = NULL;
- PVOID PortContext;
- ULONG MessageType;
-
- /* Start the loop */
- while (TRUE)
- {
- /* Wait for a message to come in */
- Status = NtReplyWaitReceivePort(CsrSbApiPort,
- &PortContext,
- &ReplyMsg->h,
- &ReceiveMsg.h);
-
- /* Check if we didn't get success */
- if (Status != STATUS_SUCCESS)
- {
- /* If we only got a warning, keep going */
- if (NT_SUCCESS(Status)) continue;
-
- /* We failed big time, so start out fresh */
- ReplyMsg = NULL;
- DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
- continue;
- }
-
- /* Save the message type */
- MessageType = ReceiveMsg.h.u2.s2.Type;
-
- /* Check if this is a connection request */
- if (MessageType == LPC_CONNECTION_REQUEST)
- {
- /* Handle connection request */
- CsrSbApiHandleConnectionRequest(&ReceiveMsg);
-
- /* Start over */
- ReplyMsg = NULL;
- continue;
- }
-
- /* Check if the port died */
- if (MessageType == LPC_PORT_CLOSED)
- {
- /* Close the handle if we have one */
- if (PortContext) NtClose((HANDLE)PortContext);
-
- /* Client died, start over */
- ReplyMsg = NULL;
- continue;
- }
- else if (MessageType == LPC_CLIENT_DIED)
- {
- /* Client died, start over */
- ReplyMsg = NULL;
- continue;
- }
-
- /*
- * It's an API Message, check if it's within limits. If it's not, the
- * NT Behaviour is to set this to the Maximum API.
- */
- if (ReceiveMsg.ApiNumber > SbpMaxApiNumber)
- {
- ReceiveMsg.ApiNumber = SbpMaxApiNumber;
- DPRINT1("CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber);
- }
-
- /* Reuse the message */
- ReplyMsg = &ReceiveMsg;
-
- /* Make sure that the message is supported */
- if (ReceiveMsg.ApiNumber < SbpMaxApiNumber)
- {
- /* Call the API */
- if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg))
- {
- /* It failed, so return nothing */
- ReplyMsg = NULL;
- }
- }
- else
- {
- /* We don't support this API Number */
- ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED;
- }
- }
-}
-
-/*++
- * @name CsrSbApiHandleConnectionRequest
- *
- * The CsrSbApiHandleConnectionRequest routine handles and accepts a new
- * connection request to the SM API LPC Port.
- *
- * @param ApiMessage
- * Pointer to the incoming CSR API Message which contains the
- * connection request.
- *
- * @return STATUS_SUCCESS in case of success, or status code which caused
- * the routine to error.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message)
-{
- NTSTATUS Status;
- REMOTE_PORT_VIEW RemotePortView;
- HANDLE hPort;
-
- /* Set the Port View Structure Length */
- RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
-
- /* Accept the connection */
- Status = NtAcceptConnectPort(&hPort,
- NULL,
- (PPORT_MESSAGE)Message,
- TRUE,
- NULL,
- &RemotePortView);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status);
- return Status;
- }
-
- /* Complete the Connection */
- Status = NtCompleteConnectPort(hPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status);
- }
-
- /* Return status */
- return Status;
-}
-
-/* PUBLIC FUNCTIONS **********************************************************/
-
-/*++
- * @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)
-{
- 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;
-}
-
-/*++
- * @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)
-{
- NTSTATUS Status;
- ANSI_STRING DllName;
- UNICODE_STRING TempName;
- HANDLE hUser32;
- STRING StartupName;
- PTEB Teb = NtCurrentTeb();
- PCSR_THREAD CsrThread;
- BOOLEAN Connected;
-
- /* 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 */
- _SEH2_TRY
- {
- Connected = CsrClientThreadSetup();
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Connected = FALSE;
- } _SEH2_END;
-
- if (!Connected)
- {
- DPRINT1("CSRSS: CsrConnectToUser failed\n");
- return NULL;
- }
-
- /* Save pointer to this thread in TEB */
- CsrAcquireProcessLock();
- CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
- CsrReleaseProcessLock();
- if (CsrThread) Teb->CsrClientThread = CsrThread;
-
- /* Return it */
- return CsrThread;
-}
-
-/*++
- * @name CsrQueryApiPort
- * @implemented NT4
- *
- * The CsrQueryApiPort routine returns a handle to the CSR API LPC port.
- *
- * @param None.
- *
- * @return A handle to the port.
- *
- * @remarks None.
- *
- *--*/
-HANDLE
-NTAPI
-CsrQueryApiPort(VOID)
-{
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
- return CsrApiPort;
-}
-
-/*++
- * @name CsrCaptureArguments
- * @implemented NT5.1
- *
- * The CsrCaptureArguments routine validates a CSR Capture Buffer and
- * re-captures it into a server CSR Capture Buffer.
- *
- * @param CsrThread
- * Pointer to the CSR Thread performing the validation.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message containing the Capture Buffer
- * that needs to be validated.
- *
- * @return TRUE if validation succeeded, FALSE otherwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrCaptureArguments(IN PCSR_THREAD CsrThread,
- IN PCSR_API_MESSAGE ApiMessage)
-{
- PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL, RemoteCaptureBuffer = NULL;
- ULONG LocalLength = 0, PointerCount = 0;
- SIZE_T BufferDistance = 0;
- ULONG_PTR **PointerOffsets = NULL, *CurrentPointer = NULL;
-
- /* Use SEH to make sure this is valid */
- _SEH2_TRY
- {
- /* Get the buffer we got from whoever called NTDLL */
- LocalCaptureBuffer = ApiMessage->CsrCaptureData;
- LocalLength = LocalCaptureBuffer->Size;
-
- /* Now check if the buffer is inside our mapped section */
- if (((ULONG_PTR)LocalCaptureBuffer < CsrThread->Process->ClientViewBase) ||
- (((ULONG_PTR)LocalCaptureBuffer + LocalLength) >= CsrThread->Process->ClientViewBounds))
- {
- /* Return failure */
- DPRINT1("*** CSRSS: CaptureBuffer outside of ClientView\n");
- ApiMessage->Status = STATUS_INVALID_PARAMETER;
- _SEH2_YIELD(return FALSE);
- }
-
- /* Check if the Length is valid */
- if (((LocalCaptureBuffer->PointerCount * 4 + sizeof(CSR_CAPTURE_BUFFER)) >
- LocalLength) ||(LocalLength > MAXWORD))
- {
- /* Return failure */
- DPRINT1("*** CSRSS: CaptureBuffer %p has bad length\n", LocalCaptureBuffer);
- DbgBreakPoint();
- ApiMessage->Status = STATUS_INVALID_PARAMETER;
- _SEH2_YIELD(return FALSE);
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Return failure */
- ApiMessage->Status = STATUS_INVALID_PARAMETER;
- _SEH2_YIELD(return FALSE);
- } _SEH2_END;
-
- /* We validated the incoming buffer, now allocate the remote one */
- RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, 0, LocalLength);
- if (!RemoteCaptureBuffer)
- {
- /* We're out of memory */
- ApiMessage->Status = STATUS_NO_MEMORY;
- return FALSE;
- }
-
- /* Copy the client's buffer */
- RtlMoveMemory(RemoteCaptureBuffer, LocalCaptureBuffer, LocalLength);
-
- /* Copy the length */
- RemoteCaptureBuffer->Size = LocalLength;
-
- /* Calculate the difference between our buffer and the client's */
- BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer;
-
- /* Save the pointer count and offset pointer */
- PointerCount = RemoteCaptureBuffer->PointerCount;
- PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1);
-
- /* Start the loop */
- while (PointerCount)
- {
- /* Get the current pointer */
- if ((CurrentPointer = *PointerOffsets++))
- {
- /* Add it to the CSR Message structure */
- CurrentPointer += (ULONG_PTR)ApiMessage;
-
- /* Validate the bounds of the current pointer */
- if ((*CurrentPointer >= CsrThread->Process->ClientViewBase) &&
- (*CurrentPointer < CsrThread->Process->ClientViewBounds))
- {
- /* Modify the pointer to take into account its new position */
- *CurrentPointer += BufferDistance;
- }
- else
- {
- /* Invalid pointer, fail */
- DPRINT1("*** CSRSS: CaptureBuffer MessagePointer outside of ClientView\n");
- DbgBreakPoint();
- ApiMessage->Status = STATUS_INVALID_PARAMETER;
- }
- }
-
- /* Move to the next Pointer */
- PointerCount--;
- }
-
- /* Check if we got success */
- if (ApiMessage->Status != STATUS_SUCCESS)
- {
- /* Failure. Free the buffer and return*/
- RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
- return FALSE;
- }
- else
- {
- /* Success, save the previous buffer */
- RemoteCaptureBuffer->PreviousCaptureBuffer = LocalCaptureBuffer;
- ApiMessage->CsrCaptureData = RemoteCaptureBuffer;
- }
-
- /* Success */
- return TRUE;
-}
-
-/*++
- * @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);
-}
-
-/*++
- * @name CsrValidateMessageBuffer
- * @implemented NT5.1
- *
- * The CsrValidateMessageBuffer routine validates a captured message buffer
- * present in the CSR Api Message
- *
- * @param ApiMessage
- * Pointer to the CSR API Message containing the CSR Capture Buffer.
- *
- * @param Buffer
- * Pointer to the message buffer to validate.
- *
- * @param ArgumentSize
- * Size of the message to check.
- *
- * @param ArgumentCount
- * Number of messages to check.
- *
- * @return TRUE if validation suceeded, FALSE otherwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
- IN PVOID *Buffer,
- IN ULONG ArgumentSize,
- IN ULONG ArgumentCount)
-{
- PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData;
- SIZE_T BufferDistance;
- ULONG PointerCount, i;
- ULONG_PTR **PointerOffsets, *CurrentPointer;
-
- /* Make sure there are some arguments */
- if (!ArgumentCount) return FALSE;
-
- /* Check if didn't get a buffer and there aren't any arguments to check */
- if (!(*Buffer) && (!(ArgumentCount * ArgumentSize))) return TRUE;
-
- /* Check if we have no capture buffer */
- if (!CaptureBuffer)
- {
- /* In this case, check only the Process ID */
- if (NtCurrentTeb()->ClientId.UniqueProcess ==
- ApiMessage->Header.ClientId.UniqueProcess)
- {
- /* There is a match, validation succeeded */
- return TRUE;
- }
- }
- else
- {
- /* Make sure that there is still space left in the buffer */
- if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) <
- (ArgumentCount * ArgumentSize))
- {
- /* Find out the difference between the two buffers */
- BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage;
-
- /* Save the pointer count */
- PointerCount = CaptureBuffer->PointerCount;
- PointerOffsets = (ULONG_PTR**)(CaptureBuffer + 1);
-
- /* Start the loop */
- for (i = 0; i < PointerCount; i++)
- {
- /* Get the current pointer */
- CurrentPointer = *PointerOffsets++;
-
- /* Check if its' equal to the difference */
- if (*CurrentPointer == BufferDistance) return TRUE;
- }
- }
- }
-
- /* Failure */
- DbgPrint("CSRSRV: Bad message buffer %p\n", ApiMessage);
- DbgBreakPoint();
- return FALSE;
-}
-
-/*++
- * @name CsrValidateMessageString
- * @implemented NT5.1
- *
- * The CsrValidateMessageString validates a captured Wide-Character String
- * present in a CSR API Message.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message containing the CSR Capture Buffer.
- *
- * @param MessageString
- * Pointer to the buffer containing the string to validate.
- *
- * @return TRUE if validation suceeded, FALSE otherwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage,
- IN LPWSTR *MessageString)
-{
- DPRINT1("CSRSRV: %s called\n", __FUNCTION__);
- return FALSE;
-}
-
-/* EOF */
+++ /dev/null
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION "ReactOS CSR Core Server\0"
-#define REACTOS_STR_INTERNAL_NAME "csrsrv\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "csrsrv.dll\0"
-#include <reactos/version.rc>
+++ /dev/null
-@ stdcall CsrAddStaticServerThread(ptr ptr long)
-@ stdcall CsrCallServerFromServer(ptr ptr)
-@ stdcall CsrConnectToUser()
-@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
-@ stdcall CsrCreateRemoteThread(ptr ptr)
-@ stdcall CsrCreateThread(ptr ptr ptr long)
-@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
-@ stdcall CsrDebugProcess(ptr)
-@ stdcall CsrDebugProcessStop(ptr)
-@ stdcall CsrDereferenceProcess(ptr)
-@ stdcall CsrDereferenceThread(ptr)
-@ stdcall CsrDereferenceWait(ptr)
-@ stdcall CsrDestroyProcess(ptr long)
-@ stdcall CsrDestroyThread(ptr)
-@ stdcall CsrExecServerThread(ptr long)
-@ stdcall CsrGetProcessLuid(ptr ptr)
-@ stdcall CsrImpersonateClient(ptr)
-@ stdcall CsrLockProcessByClientId(ptr ptr)
-@ stdcall CsrLockThreadByClientId(ptr ptr)
-@ stdcall CsrMoveSatisfiedWait(ptr ptr)
-@ stdcall CsrNotifyWait(ptr long ptr ptr)
-@ stdcall CsrPopulateDosDevices()
-@ stdcall CsrQueryApiPort()
-@ stdcall CsrReferenceThread(ptr)
-@ stdcall CsrRevertToSelf()
-@ stdcall CsrServerInitialization(long ptr)
-@ stdcall CsrSetBackgroundPriority(ptr)
-@ stdcall CsrSetCallingSpooler(long)
-@ stdcall CsrSetForegroundPriority(ptr)
-@ stdcall CsrShutdownProcesses(ptr long)
-@ stdcall CsrUnhandledExceptionFilter(ptr)
-@ stdcall CsrUnlockProcess(ptr)
-@ stdcall CsrUnlockThread(ptr)
-@ stdcall CsrValidateMessageBuffer(ptr ptr long long)
-@ stdcall CsrValidateMessageString(ptr ptr)
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrsrv/init.c
- * PURPOSE: CSR Server DLL Initialization
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-HANDLE CsrObjectDirectory;
-ULONG SessionId;
-BOOLEAN CsrProfileControl;
-UNICODE_STRING CsrDirectoryName;
-HANDLE CsrHeap;
-HANDLE BNOLinksDirectory;
-HANDLE SessionObjectDirectory;
-HANDLE DosDevicesDirectory;
-HANDLE CsrInitializationEvent;
-SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
-ULONG CsrDebug;
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @name CsrParseServerCommandLine
- *
- * The CsrParseServerCommandLine routine parses the CSRSS command-line in the
- * registry and performs operations for each entry found.
- *
- * @param ArgumentCount
- * Number of arguments on the command line.
- *
- * @param Arguments
- * Array of arguments.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-FASTCALL
-CsrParseServerCommandLine(IN ULONG ArgumentCount,
- IN PCHAR Arguments[])
-{
- NTSTATUS Status;
- PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString;
- ULONG i, DllIndex;
- ANSI_STRING AnsiString;
- OBJECT_ATTRIBUTES ObjectAttributes;
-
- /* Set the Defaults */
- CsrTotalPerProcessDataLength = 0;
- CsrObjectDirectory = 0;
- CsrMaxApiRequestThreads = 16;
-
- /* Save our Session ID, and create a Directory for it */
- SessionId = NtCurrentPeb()->SessionId;
- Status = CsrCreateSessionObjectDirectory(SessionId);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
- Status);
-
- /* It's not fatal if the session ID isn't zero */
- if (SessionId) return Status;
- ASSERT(NT_SUCCESS(Status));
- }
-
- /* Loop through every argument */
- for (i = 1; i < ArgumentCount; i++)
- {
- /* Split Name and Value */
- ParameterName = Arguments[i];
- ParameterValue = NULL;
- ParameterValue = strchr(ParameterName, '=');
- if (ParameterValue) *ParameterValue++ = ANSI_NULL;
- DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue);
-
- /* Check for Object Directory */
- if (!_stricmp(ParameterName, "ObjectDirectory"))
- {
- /* Check if a session ID is specified */
- if (SessionId)
- {
- DPRINT1("Sessions not yet implemented\n");
- ASSERT(SessionId);
- }
-
- /* Initialize the directory name */
- RtlInitAnsiString(&AnsiString, ParameterValue);
- Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName,
- &AnsiString,
- TRUE);
- ASSERT(NT_SUCCESS(Status) || SessionId != 0);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Create it */
- InitializeObjectAttributes(&ObjectAttributes,
- &CsrDirectoryName,
- OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
- NULL,
- NULL);
- Status = NtCreateDirectoryObject(&CsrObjectDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Secure it */
- Status = CsrSetDirectorySecurity(CsrObjectDirectory);
- if (!NT_SUCCESS(Status)) return Status;
- }
- else if (!_stricmp(ParameterName, "SubSystemType"))
- {
- /* Ignored */
- }
- else if (!_stricmp(ParameterName, "MaxRequestThreads"))
- {
- Status = RtlCharToInteger(ParameterValue,
- 0,
- &CsrMaxApiRequestThreads);
- }
- else if (!_stricmp(ParameterName, "RequestThreads"))
- {
- /* Ignored */
- Status = STATUS_SUCCESS;
- }
- else if (!_stricmp(ParameterName, "ProfileControl"))
- {
- /* Ignored */
- }
- else if (!_stricmp(ParameterName, "SharedSection"))
- {
- /* Craete the Section */
- Status = CsrSrvCreateSharedSection(ParameterValue);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
- ParameterName, ParameterValue, Status);
- return Status;
- }
-
- /* Load us */
- Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER);
- }
- else if (!_stricmp(ParameterName, "ServerDLL"))
- {
- /* Loop the command line */
- EntryPoint = NULL;
- Status = STATUS_INVALID_PARAMETER;
- ServerString = ParameterValue;
- while (*ServerString)
- {
- /* Check for the Entry Point */
- if ((*ServerString == ':') && (!EntryPoint))
- {
- /* Found it. Add a nullchar and save it */
- *ServerString++ = ANSI_NULL;
- EntryPoint = ServerString;
- }
-
- /* Check for the Dll Index */
- if (*ServerString++ == ',') break;
- }
-
- /* Did we find something to load? */
- if (!*ServerString)
- {
- DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
- ParameterValue, Status);
- return Status;
- }
-
- /* Convert it to a ULONG */
- Status = RtlCharToInteger(ServerString, 10, &DllIndex);
-
- /* Add a null char if it was valid */
- if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL;
-
- /* Load it */
- if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint);
- Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
- ParameterValue, Status);
- return Status;
- }
- }
- else if (!_stricmp(ParameterName, "Windows"))
- {
- /* Ignored */
- }
- else
- {
- /* Invalid parameter on the command line */
- Status = STATUS_INVALID_PARAMETER;
- }
- }
-
- /* Return status */
- return Status;
-}
-
-/*++
- * @name CsrCreateLocalSystemSD
- *
- * The CsrCreateLocalSystemSD routine creates a Security Descriptor for
- * the local account with PORT_ALL_ACCESS.
- *
- * @param LocalSystemSd
- * Pointer to a pointer to the security descriptor to create.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
-{
- SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
- PSID SystemSid;
- ULONG Length;
- PSECURITY_DESCRIPTOR SystemSd;
- PACL Dacl;
- NTSTATUS Status;
-
- /* Initialize the System SID */
- RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
- SECURITY_LOCAL_SYSTEM_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &SystemSid);
-
- /* Get the length of the SID */
- Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
-
- /* Allocate a buffer for the Security Descriptor, with SID and DACL */
- SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
-
- /* Set the pointer to the DACL */
- Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
-
- /* Now create the SD itself */
- Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SystemSd);
- return Status;
- }
-
- /* Create the DACL for it*/
- RtlCreateAcl(Dacl, Length, ACL_REVISION2);
-
- /* Create the ACE */
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SystemSd);
- return Status;
- }
-
- /* Clear the DACL in the SD */
- Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SystemSd);
- return Status;
- }
-
- /* Free the SID and return*/
- RtlFreeSid(SystemSid);
- *LocalSystemSd = SystemSd;
- return Status;
-}
-
-/*++
- * @name GetDosDevicesProtection
- *
- * The GetDosDevicesProtection creates a security descriptor for the DOS Devices
- * Object Directory.
- *
- * @param DosDevicesSd
- * Pointer to the Security Descriptor to return.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks Depending on the DOS Devices Protection Mode (set in the registry),
- * regular users may or may not have full access to the directory.
- *
- *--*/
-NTSTATUS
-NTAPI
-GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
-{
- SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
- SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
- SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
- PSID WorldSid, CreatorSid, AdminSid, SystemSid;
- UCHAR KeyValueBuffer[0x40];
- PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
- UNICODE_STRING KeyName;
- ULONG ProtectionMode = 0;
- OBJECT_ATTRIBUTES ObjectAttributes;
- PACL Dacl;
- PACCESS_ALLOWED_ACE Ace;
- HANDLE hKey;
- NTSTATUS Status;
- ULONG ResultLength, SidLength, AclLength;
-
- /* Create the SD */
- Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION);
- ASSERT(NT_SUCCESS(Status));
-
- /* Initialize the System SID */
- Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
- SECURITY_LOCAL_SYSTEM_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &SystemSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Initialize the World SID */
- Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1,
- SECURITY_WORLD_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &WorldSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Initialize the Admin SID */
- Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- 0, 0, 0, 0, 0, 0,
- &AdminSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Initialize the Creator SID */
- Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
- SECURITY_CREATOR_OWNER_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &CreatorSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* 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);
- }
-
- /* Check the Protection Mode */
- if (ProtectionMode & 3)
- {
- /* Calculate SID Lengths */
- SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) +
- RtlLengthSid(AdminSid);
- AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
-
- /* Allocate memory for the DACL */
- Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
- ASSERT(Dacl != NULL);
-
- /* Build the ACL and add 3 ACEs */
- Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Edit the ACEs to make them inheritable */
- Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace);
- ASSERT(NT_SUCCESS(Status));
- Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
- Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace);
- ASSERT(NT_SUCCESS(Status));
- Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
- Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
- ASSERT(NT_SUCCESS(Status));
- Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
-
- /* Set this DACL with the SD */
- Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
- ASSERT(NT_SUCCESS(Status));
- goto Quickie;
- }
- else
- {
- /* Calculate SID Lengths */
- SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid);
- AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
-
- /* Allocate memory for the DACL */
- Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
- ASSERT(Dacl != NULL);
-
- /* Build the ACL and add 3 ACEs */
- Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Edit the last ACE to make it inheritable */
- Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
- ASSERT(NT_SUCCESS(Status));
- Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
-
- /* Set this DACL with the SD */
- Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
- ASSERT(NT_SUCCESS(Status));
- goto Quickie;
- }
-
-/* FIXME: failure cases! Fail: */
- /* Free the memory */
- RtlFreeHeap(CsrHeap, 0, Dacl);
-
-/* FIXME: semi-failure cases! Quickie: */
-Quickie:
- /* Free the SIDs */
- RtlFreeSid(SystemSid);
- RtlFreeSid(WorldSid);
- RtlFreeSid(AdminSid);
- RtlFreeSid(CreatorSid);
-
- /* Return */
- return Status;
-}
-
-/*++
- * @name FreeDosDevicesProtection
- *
- * The FreeDosDevicesProtection frees the security descriptor that was created
- * by GetDosDevicesProtection
- *
- * @param DosDevicesSd
- * Pointer to the security descriptor to free.
-
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd)
-{
- PACL Dacl;
- BOOLEAN Present, Default;
- NTSTATUS Status;
-
- /* Get the DACL corresponding to this SD */
- Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default);
- ASSERT(NT_SUCCESS(Status));
- ASSERT(Present);
- ASSERT(Dacl != NULL);
-
- /* Free it */
- if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl);
-}
-
-/*++
- * @name CsrCreateSessionObjectDirectory
- *
- * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects,
- * Session and Dos Devices directories for the specified session.
- *
- * @param Session
- * Session ID for which to create the directories.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateSessionObjectDirectory(IN ULONG Session)
-{
- WCHAR SessionBuffer[512], BnoBuffer[512];
- UNICODE_STRING SessionString, BnoString;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE BnoHandle;
- SECURITY_DESCRIPTOR DosDevicesSd;
- NTSTATUS Status;
-
- /* Generate the Session BNOLINKS Directory name */
- swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT);
- RtlInitUnicodeString(&SessionString, SessionBuffer);
-
- /* Create it */
- InitializeObjectAttributes(&ObjectAttributes,
- &SessionString,
- OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtCreateDirectoryObject(&BNOLinksDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
- "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
- return Status;
- }
-
- /* Now add the Session ID */
- swprintf(SessionBuffer, L"%ld", Session);
- RtlInitUnicodeString(&SessionString, SessionBuffer);
-
- /* Check if this is the first Session */
- if (Session)
- {
- /* Not the first, so the name will be slighly more complex */
- swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session);
- RtlInitUnicodeString(&BnoString, BnoBuffer);
- }
- else
- {
- /* Use the direct name */
- RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
- }
-
- /* Create the symlink */
- InitializeObjectAttributes(&ObjectAttributes,
- &SessionString,
- OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
- BNOLinksDirectory,
- NULL);
- Status = NtCreateSymbolicLinkObject(&BnoHandle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes,
- &BnoString);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in "
- "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
- return Status;
- }
-
- /* Create the \DosDevices Security Descriptor */
- Status = GetDosDevicesProtection(&DosDevicesSd);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Now create a directory for this session */
- swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session);
- RtlInitUnicodeString(&SessionString, SessionBuffer);
-
- /* Create the directory */
- InitializeObjectAttributes(&ObjectAttributes,
- &SessionString,
- OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
- 0,
- &DosDevicesSd);
- Status = NtCreateDirectoryObject(&SessionObjectDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
- "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
- FreeDosDevicesProtection(&DosDevicesSd);
- return Status;
- }
-
- /* Next, create a directory for this session's DOS Devices */
- RtlInitUnicodeString(&SessionString, L"DosDevices");
- InitializeObjectAttributes(&ObjectAttributes,
- &SessionString,
- OBJ_CASE_INSENSITIVE,
- SessionObjectDirectory,
- &DosDevicesSd);
- Status = NtCreateDirectoryObject(&DosDevicesDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
- "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
- }
-
- /* Release the Security Descriptor */
- FreeDosDevicesProtection(&DosDevicesSd);
-
- /* Return */
- return Status;
-}
-
-/*++
- * @name CsrSetProcessSecurity
- *
- * The CsrSetProcessSecurity routine protects access to the CSRSS process
- * from unauthorized tampering.
- *
- * @param None.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSetProcessSecurity(VOID)
-{
- NTSTATUS Status;
- HANDLE hToken, hProcess = NtCurrentProcess();
- ULONG ReturnLength, Length;
- PTOKEN_USER TokenInfo = NULL;
- PSECURITY_DESCRIPTOR ProcSd = NULL;
- PACL Dacl;
- PSID UserSid;
-
- /* Open our token */
- Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Get the Token User Length */
- NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
-
- /* Allocate space for it */
- TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
- if (!TokenInfo)
- {
- Status = STATUS_NO_MEMORY;
- goto Quickie;
- }
-
- /* Now query the data */
- Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length);
- NtClose(hToken);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Now check the SID Length */
- UserSid = TokenInfo->User.Sid;
- ReturnLength = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
-
- /* Allocate a buffer for the Security Descriptor, with SID and DACL */
- ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
- if (!ProcSd)
- {
- Status = STATUS_NO_MEMORY;
- goto Quickie;
- }
-
- /* Set the pointer to the DACL */
- Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
-
- /* Now create the SD itself */
- Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Create the DACL for it*/
- RtlCreateAcl(Dacl, Length, ACL_REVISION2);
-
- /* Create the ACE */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- PROCESS_VM_READ | PROCESS_VM_WRITE |
- PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
- PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
- PROCESS_QUERY_INFORMATION | READ_CONTROL,
- UserSid);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Clear the DACL in the SD */
- Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Write the SD into the Process */
- Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
-
- /* Free the memory and return */
-Quickie:
- if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
- RtlFreeHeap(CsrHeap, 0, TokenInfo);
- return Status;
-}
-
-/*++
- * @name CsrSetDirectorySecurity
- *
- * The CsrSetDirectorySecurity routine sets the security descriptor for the
- * specified Object Directory.
- *
- * @param ObjectDirectory
- * Handle fo the Object Directory to protect.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSetDirectorySecurity(IN HANDLE ObjectDirectory)
-{
- /* FIXME: Implement */
- return STATUS_SUCCESS;
-}
-
-/* PUBLIC FUNCTIONS **********************************************************/
-
-/*++
- * @name CsrServerInitialization
- * @implemented NT4
- *
- * The CsrServerInitialization routine is the native (not Server) entrypoint
- * of this Server DLL. It serves as the entrypoint for csrss.
- *
- * @param ArgumentCount
- * Number of arguments on the command line.
- *
- * @param Arguments
- * Array of arguments from the command line.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrServerInitialization(IN ULONG ArgumentCount,
- IN PCHAR Arguments[])
-{
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG i = 0;
- PVOID ProcessData;
- PCSR_SERVER_DLL ServerDll;
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
-
- /* Create the Init Event */
- Status = NtCreateEvent(&CsrInitializationEvent,
- EVENT_ALL_ACCESS,
- NULL,
- SynchronizationEvent,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Cache System Basic Information so we don't always request it */
- Status = NtQuerySystemInformation(SystemBasicInformation,
- &CsrNtSysInfo,
- sizeof(SYSTEM_BASIC_INFORMATION),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Save our Heap */
- CsrHeap = RtlGetProcessHeap();
-
- /* Set our Security Descriptor to protect the process */
- Status = CsrSetProcessSecurity();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Set up Session Support */
- Status = CsrInitializeNtSessionList();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Set up Process Support */
- Status = CsrInitializeProcessStructure();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Parse the command line */
- Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* All Server DLLs are now loaded, allocate a heap for the Root Process */
- ProcessData = RtlAllocateHeap(CsrHeap,
- HEAP_ZERO_MEMORY,
- CsrTotalPerProcessDataLength);
- if (!ProcessData)
- {
- DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n",
- __FUNCTION__, STATUS_NO_MEMORY);
- return STATUS_NO_MEMORY;
- }
-
- /*
- * Our Root Process was never officially initalized, so write the data
- * for each Server DLL manually.
- */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current Server */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Is it loaded, and does it have per process data? */
- if ((ServerDll) && (ServerDll->SizeOfProcessData))
- {
- /* It does, give it part of our allocated heap */
- CsrRootProcess->ServerData[i] = ProcessData;
-
- /* Move to the next heap position */
- ProcessData = (PVOID)((ULONG_PTR)ProcessData +
- ServerDll->SizeOfProcessData);
- }
- else
- {
- /* Nothing for this Server DLL */
- CsrRootProcess->ServerData[i] = NULL;
- }
- }
-
- /* Now initialize the Root Process manually as well */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current Server */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Is it loaded, and does it a callback for new processes? */
- if ((ServerDll) && (ServerDll->NewProcessCallback))
- {
- /* Call the callback */
- ServerDll->NewProcessCallback(NULL, CsrRootProcess);
- }
- }
-
- /* Now initialize our API Port */
- Status = CsrApiPortInitialize();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Initialize the API Port for SM communication */
- Status = CsrSbApiPortInitialize();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* We're all set! Connect to SM! */
- Status = SmConnectToSm(&CsrSbApiPortName,
- CsrSbApiPort,
- IMAGE_SUBSYSTEM_WINDOWS_GUI,
- &CsrSmApiPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Finito! Signal the event */
- Status = NtSetEvent(CsrInitializationEvent, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Close the event handle now */
- NtClose(CsrInitializationEvent);
-
- /* Have us handle Hard Errors */
- Status = NtSetDefaultHardErrorPort(CsrApiPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Return status */
- return Status;
-}
-
-/*++
- * @name CsrPopulateDosDevices
- * @unimplemented NT5.1
- *
- * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
- * to populate the Dos Devices Object Directory for the session.
- *
- * @param None.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrPopulateDosDevices(VOID)
-{
- DPRINT1("Deprecated API\n");
- return;
-}
-
-BOOL
-NTAPI
-DllMain(IN HANDLE hDll,
- IN DWORD dwReason,
- IN LPVOID lpReserved)
-{
- /* We don't do much */
- UNREFERENCED_PARAMETER(hDll);
- UNREFERENCED_PARAMETER(dwReason);
- UNREFERENCED_PARAMETER(lpReserved);
- return TRUE;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrsrv/process.c
- * PURPOSE: CSR Server DLL Process Implementation
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-PCSR_PROCESS CsrRootProcess = NULL;
-RTL_CRITICAL_SECTION CsrProcessLock;
-ULONG CsrProcessSequenceCount = 5;
-ULONG CsrTotalPerProcessDataLength;
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @name ProtectHandle
- * @implemented NT5.2
- *
- * The ProtectHandle routine protects an object handle against closure.
- *
- * @return TRUE or FALSE.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-ProtectHandle(IN HANDLE ObjectHandle)
-{
- NTSTATUS Status;
- OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
-
- /* Query current state */
- Status = NtQueryObject(ObjectHandle,
- ObjectHandleFlagInformation,
- &HandleInfo,
- sizeof(HandleInfo),
- NULL);
- if (NT_SUCCESS(Status))
- {
- /* Enable protect from close */
- HandleInfo.ProtectFromClose = TRUE;
- Status = NtSetInformationObject(ObjectHandle,
- ObjectHandleFlagInformation,
- &HandleInfo,
- sizeof(HandleInfo));
- if (NT_SUCCESS(Status)) return TRUE;
- }
-
- /* We failed to or set the state */
- return FALSE;
-}
-
-/*++
- * @name UnProtectHandle
- * @implemented NT5.2
- *
- * The UnProtectHandle routine unprotects an object handle against closure.
- *
- * @return TRUE or FALSE.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-UnProtectHandle(IN HANDLE ObjectHandle)
-{
- NTSTATUS Status;
- OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
-
- /* Query current state */
- Status = NtQueryObject(ObjectHandle,
- ObjectHandleFlagInformation,
- &HandleInfo,
- sizeof(HandleInfo),
- NULL);
- if (NT_SUCCESS(Status))
- {
- /* Disable protect from close */
- HandleInfo.ProtectFromClose = FALSE;
- Status = NtSetInformationObject(ObjectHandle,
- ObjectHandleFlagInformation,
- &HandleInfo,
- sizeof(HandleInfo));
- if (NT_SUCCESS(Status)) return TRUE;
- }
-
- /* We failed to or set the state */
- return FALSE;
-}
-
-/*++
- * @name CsrAllocateProcess
- * @implemented NT4
- *
- * The CsrAllocateProcess routine allocates a new CSR Process object.
- *
- * @return Pointer to the newly allocated CSR Process.
- *
- * @remarks None.
- *
- *--*/
-PCSR_PROCESS
-NTAPI
-CsrAllocateProcess(VOID)
-{
- PCSR_PROCESS CsrProcess;
- ULONG TotalSize;
-
- /* Calculate the amount of memory this should take */
- TotalSize = sizeof(CSR_PROCESS) +
- (CSR_SERVER_DLL_MAX * sizeof(PVOID)) +
- CsrTotalPerProcessDataLength;
-
- /* Allocate a Process */
- CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize);
- if (!CsrProcess) return NULL;
-
- /* Handle the Sequence Number and protect against overflow */
- CsrProcess->SequenceNumber = CsrProcessSequenceCount++;
- if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5;
-
- /* Increase the reference count */
- CsrProcess->ReferenceCount++;
-
- /* Initialize the Thread List */
- InitializeListHead(&CsrProcess->ThreadList);
-
- /* Return the Process */
- return CsrProcess;
-}
-
-/*++
- * @name CsrServerInitialization
- * @implemented NT4
- *
- * The CsrInitializeProcessStructure routine sets up support for CSR Processes
- * and CSR Threads.
- *
- * @param None.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrInitializeProcessStructure(VOID)
-{
- NTSTATUS Status;
- ULONG i;
-
- /* Initialize the Lock */
- Status = RtlInitializeCriticalSection(&CsrProcessLock);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Set up the Root Process */
- CsrRootProcess = CsrAllocateProcess();
- if (!CsrRootProcess) return STATUS_NO_MEMORY;
-
- /* Set up the minimal information for it */
- InitializeListHead(&CsrRootProcess->ListLink);
- CsrRootProcess->ProcessHandle = (HANDLE)-1;
- CsrRootProcess->ClientId = NtCurrentTeb()->ClientId;
-
- /* Initialize the Thread Hash List */
- for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]);
-
- /* Initialize the Wait Lock */
- return RtlInitializeCriticalSection(&CsrWaitListsLock);
-}
-
-/*++
- * @name CsrDeallocateProcess
- *
- * The CsrDeallocateProcess frees the memory associated with a CSR Process.
- *
- * @param CsrProcess
- * Pointer to the CSR Process to be freed.
- *
- * @return None.
- *
- * @remarks Do not call this routine. It is reserved for the internal
- * thread management routines when a CSR Process has been cleanly
- * dereferenced and killed.
- *
- *--*/
-VOID
-NTAPI
-CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* Free the process object from the heap */
- RtlFreeHeap(CsrHeap, 0, CsrProcess);
-}
-
-/*++
- * @name CsrInsertProcess
- *
- * The CsrInsertProcess routine inserts a CSR Process into the Process List
- * and notifies Server DLLs of the creation of a new CSR Process.
- *
- * @param Parent
- * Optional pointer to the CSR Process creating this CSR Process.
- *
- * @param CurrentProcess
- * Optional pointer to the current CSR Process.
- *
- * @param CsrProcess
- * Pointer to the CSR Process which is to be inserted.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
- IN PCSR_PROCESS CurrentProcess OPTIONAL,
- IN PCSR_PROCESS CsrProcess)
-{
- PCSR_SERVER_DLL ServerDll;
- ULONG i;
- ASSERT(ProcessStructureListLocked());
-
- /* Set the parent */
- CsrProcess->Parent = Parent;
-
- /* Insert it into the Root List */
- InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink);
-
- /* Notify the Server DLLs */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current Server DLL */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Make sure it's valid and that it has callback */
- if ((ServerDll) && (ServerDll->NewProcessCallback))
- {
- ServerDll->NewProcessCallback(CurrentProcess, CsrProcess);
- }
- }
-}
-
-/*++
- * @name CsrLockedDereferenceProcess
- *
- * The CsrLockedDereferenceProcess dereferences a CSR Process while the
- * Process Lock is already being held.
- *
- * @param CsrProcess
- * Pointer to the CSR Process to be dereferenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
-{
- LONG LockCount;
-
- /* Decrease reference count */
- LockCount = --CsrProcess->ReferenceCount;
- ASSERT(LockCount >= 0);
- if (!LockCount)
- {
- /* Call the generic cleanup code */
- CsrProcessRefcountZero(CsrProcess);
- CsrAcquireProcessLock();
- }
-}
-
-/*++
- * @name CsrLockedReferenceProcess
- *
- * The CsrLockedReferenceProcess refences a CSR Process while the
- * Process Lock is already being held.
- *
- * @param CsrProcess
- * Pointer to the CSR Process to be referenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* Increment the reference count */
- ++CsrProcess->ReferenceCount;
-}
-
-/*++
- * @name CsrRemoveProcess
- *
- * The CsrRemoveProcess function undoes a CsrInsertProcess operation and
- * removes the CSR Process from the Process List and notifies Server DLLs
- * of this removal.
- *
- * @param CsrProcess
- * Pointer to the CSR Process to remove.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrRemoveProcess(IN PCSR_PROCESS CsrProcess)
-{
- PCSR_SERVER_DLL ServerDll;
- ULONG i;
- ASSERT(ProcessStructureListLocked());
-
- /* Remove us from the Process List */
- RemoveEntryList(&CsrProcess->ListLink);
-
- /* Release the lock */
- CsrReleaseProcessLock();
-
- /* Loop every Server DLL */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the Server DLL */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Check if it's valid and if it has a Disconnect Callback */
- if ((ServerDll) && (ServerDll->DisconnectCallback))
- {
- /* Call it */
- ServerDll->DisconnectCallback(CsrProcess);
- }
- }
-}
-
-/*++
- * @name CsrProcessRefcountZero
- *
- * The CsrProcessRefcountZero routine is executed when a CSR Process has lost
- * all its active references. It removes and de-allocates the CSR Process.
- *
- * @param CsrProcess
- * Pointer to the CSR Process that is to be deleted.
- *
- * @return None.
- *
- * @remarks Do not call this routine. It is reserved for the internal
- * thread management routines when a CSR Process has lost all
- * its references.
- *
- * This routine is called with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess)
-{
- /* Remove the Process from the list */
- CsrRemoveProcess(CsrProcess);
-
- /* Check if there's a session */
- if (CsrProcess->NtSession)
- {
- /* Dereference the Session */
- CsrDereferenceNtSession(CsrProcess->NtSession, 0);
- }
-
- /* Close the Client Port if there is one */
- if (CsrProcess->ClientPort) NtClose(CsrProcess->ClientPort);
-
- /* Close the process handle */
- NtClose(CsrProcess->ProcessHandle);
-
- /* Free the Proces Object */
- CsrDeallocateProcess(CsrProcess);
-}
-
-/*++
- * @name CsrpSetToNormalPriority
- *
- * The CsrpSetToNormalPriority routine sets the current NT Process'
- * priority to the normal priority for CSR Processes.
- *
- * @param None.
- *
- * @return None.
- *
- * @remarks The "Normal" Priority corresponds to the Normal Forground
- * Priority (9) plus a boost of 4.
- *
- *--*/
-VOID
-NTAPI
-CsrpSetToNormalPriority(VOID)
-{
- KPRIORITY BasePriority = (8 + 1) + 4;
-
- /* Set the Priority */
- NtSetInformationProcess(NtCurrentProcess(),
- ProcessBasePriority,
- &BasePriority,
- sizeof(KPRIORITY));
-}
-
-/*++
- * @name CsrpSetToShutdownPriority
- *
- * The CsrpSetToShutdownPriority routine sets the current NT Process'
- * priority to the boosted priority for CSR Processes doing shutdown.
- * Additonally, it acquires the Shutdown Privilege required for shutdown.
- *
- * @param None.
- *
- * @return None.
- *
- * @remarks The "Shutdown" Priority corresponds to the Normal Forground
- * Priority (9) plus a boost of 6.
- *
- *--*/
-VOID
-NTAPI
-CsrpSetToShutdownPriority(VOID)
-{
- KPRIORITY SetBasePriority = (8 + 1) + 6;
- BOOLEAN Old;
-
- /* Get the shutdown privilege */
- if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
- TRUE,
- FALSE,
- &Old)))
- {
- /* Set the Priority */
- NtSetInformationProcess(NtCurrentProcess(),
- ProcessBasePriority,
- &SetBasePriority,
- sizeof(KPRIORITY));
- }
-}
-
-/*++
- * @name FindProcessForShutdown
- *
- * The FindProcessForShutdown routine returns a CSR Process which is ready
- * to be shutdown, and sets the appropriate shutdown flags for it.
- *
- * @param CallerLuid
- * Pointer to the LUID of the CSR Process calling this routine.
- *
- * @return Pointer to a CSR Process which is ready to be shutdown.
- *
- * @remarks None.
- *
- *--*/
-PCSR_PROCESS
-NTAPI
-FindProcessForShutdown(IN PLUID CallerLuid)
-{
- PLIST_ENTRY NextEntry;
- LUID ProcessLuid;
- NTSTATUS Status;
- LUID SystemLuid = SYSTEM_LUID;
- PCSR_PROCESS CsrProcess;
- PCSR_THREAD CsrThread;
- PCSR_PROCESS ReturnCsrProcess = NULL;
- ULONG Level = 0;
-
- /* Set the List Pointers */
- NextEntry = CsrRootProcess->ListLink.Flink;
- while (NextEntry != &CsrRootProcess->ListLink)
- {
- /* Get the process */
- CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
-
- /* Move to the next entry */
- NextEntry = NextEntry->Flink;
-
- /* Skip this process if it's already been processed*/
- if (CsrProcess->Flags & CsrProcessSkipShutdown) continue;
-
- /* Get the LUID of this Process */
- Status = CsrGetProcessLuid(CsrProcess->ProcessHandle, &ProcessLuid);
-
- /* Check if we didn't get access to the LUID */
- if (Status == STATUS_ACCESS_DENIED)
- {
- /* Check if we have any threads */
- if (CsrProcess->ThreadCount)
- {
- /* Impersonate one of the threads and retry */
- CsrThread = CONTAINING_RECORD(CsrProcess->ThreadList.Flink,
- CSR_THREAD,
- Link);
- CsrImpersonateClient(CsrThread);
- Status = CsrGetProcessLuid(NULL, &ProcessLuid);
- CsrRevertToSelf();
- }
- }
-
- if (!NT_SUCCESS(Status))
- {
- /* We didn't have access, so skip it */
- CsrProcess->Flags |= CsrProcessSkipShutdown;
- continue;
- }
-
- /* Check if this is the System LUID */
- if (RtlEqualLuid(&ProcessLuid, &SystemLuid))
- {
- /* Mark this process */
- CsrProcess->ShutdownFlags |= CsrShutdownSystem;
- }
- else if (!RtlEqualLuid(&ProcessLuid, CallerLuid))
- {
- /* Our LUID doesn't match with the caller's */
- CsrProcess->ShutdownFlags |= CsrShutdownOther;
- }
-
- /* Check if we're past the previous level */
- if ((CsrProcess->ShutdownLevel > Level) || !(ReturnCsrProcess))
- {
- /* Update the level */
- Level = CsrProcess->ShutdownLevel;
-
- /* Set the final process */
- ReturnCsrProcess = CsrProcess;
- }
- }
-
- /* Check if we found a process */
- if (ReturnCsrProcess)
- {
- /* Skip this one next time */
- ReturnCsrProcess->Flags |= CsrProcessSkipShutdown;
- }
-
- return ReturnCsrProcess;
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-/*++
- * @name CsrCreateProcess
- * @implemented NT4
- *
- * Do nothing for 500ms.
- *
- * @param ArgumentCount
- * Description of the parameter. Wrapped to more lines on ~70th
- * column.
- *
- * @param Arguments
- * Description of the parameter. Wrapped to more lines on ~70th
- * column.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateProcess(IN HANDLE hProcess,
- IN HANDLE hThread,
- IN PCLIENT_ID ClientId,
- IN PCSR_NT_SESSION NtSession,
- IN ULONG Flags,
- IN PCLIENT_ID DebugCid)
-{
- PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
- CLIENT_ID CurrentCid;
- PCSR_PROCESS CurrentProcess;
- PVOID ProcessData;
- ULONG i;
- PCSR_PROCESS CsrProcess;
- NTSTATUS Status;
- PCSR_THREAD CsrThread;
- KERNEL_USER_TIMES KernelTimes;
-
- /* Get the current CID and lock Processes */
- CurrentCid = CurrentThread->ClientId;
- CsrAcquireProcessLock();
-
- /* Get the current CSR Thread */
- CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
- if (!CurrentThread)
- {
- /* We've failed to locate the thread */
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Allocate a new Process Object */
- CsrProcess = CsrAllocateProcess();
- if (!CsrProcess)
- {
- /* Couldn't allocate Process */
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Inherit the Process Data */
- CurrentProcess = CurrentThread->Process;
- ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX];
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Check if the DLL is Loaded and has Per Process Data */
- if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
- {
- /* Set the pointer */
- CsrProcess->ServerData[i] = ProcessData;
-
- /* Copy the Data */
- RtlMoveMemory(ProcessData,
- CurrentProcess->ServerData[i],
- CsrLoadedServerDll[i]->SizeOfProcessData);
-
- /* Update next data pointer */
- ProcessData = (PVOID)((ULONG_PTR)ProcessData +
- CsrLoadedServerDll[i]->SizeOfProcessData);
- }
- else
- {
- /* No data for this Server */
- CsrProcess->ServerData[i] = NULL;
- }
- }
-
- /* Set the Exception port to us */
- Status = NtSetInformationProcess(hProcess,
- ProcessExceptionPort,
- &CsrApiPort,
- sizeof(HANDLE));
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* If Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
- if (!(Flags & CsrProcessCreateNewGroup))
- {
- /* Create new data */
- CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess);
- CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber;
- }
- else
- {
- /* Copy it from the current process */
- CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId;
- CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence;
- }
-
- /* Check if this is a console process */
- if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp;
-
- /* Mask out non-debug flags */
- Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags);
-
- /* Check if every process will be debugged */
- if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren))
- {
- /* Pass it on to the current process */
- CsrProcess->DebugFlags = CsrDebugProcessChildren;
- CsrProcess->DebugCid = CurrentProcess->DebugCid;
- }
-
- /* Check if Debugging was used on this process */
- if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid))
- {
- /* Save the debug flag used */
- CsrProcess->DebugFlags = Flags;
-
- /* Save the CID */
- CsrProcess->DebugCid = *DebugCid;
- }
-
- /* Check if we debugging is enabled */
- if (CsrProcess->DebugFlags)
- {
- /* Set the Debug Port to us */
- Status = NtSetInformationProcess(hProcess,
- ProcessDebugPort,
- &CsrApiPort,
- sizeof(HANDLE));
- ASSERT(NT_SUCCESS(Status));
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
- }
-
- /* Get the Thread Create Time */
- Status = NtQueryInformationThread(hThread,
- ThreadTimes,
- (PVOID)&KernelTimes,
- sizeof(KernelTimes),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Allocate a CSR Thread Structure */
- CsrThread = CsrAllocateThread(CsrProcess);
- if (!CsrThread)
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Save the data we have */
- CsrThread->CreateTime = KernelTimes.CreateTime;
- CsrThread->ClientId = *ClientId;
- CsrThread->ThreadHandle = hThread;
- ProtectHandle(hThread);
- CsrThread->Flags = 0;
-
- /* Insert the Thread into the Process */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Reference the session */
- CsrReferenceNtSession(NtSession);
- CsrProcess->NtSession = NtSession;
-
- /* Setup Process Data */
- CsrProcess->ClientId = *ClientId;
- CsrProcess->ProcessHandle = hProcess;
- CsrProcess->ShutdownLevel = 0x280;
-
- /* Set the Priority to Background */
- CsrSetBackgroundPriority(CsrProcess);
-
- /* Insert the Process */
- CsrInsertProcess(NULL, CurrentProcess, CsrProcess);
-
- /* Release lock and return */
- CsrReleaseProcessLock();
- return Status;
-}
-
-/*++
- * @name CsrDebugProcess
- * @implemented NT4
- *
- * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is
- * exported only for compatibility with older CSR Server DLLs.
- *
- * @param CsrProcess
- * Deprecated.
- *
- * @return Deprecated
- *
- * @remarks Deprecated.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDebugProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* CSR does not handle debugging anymore */
- DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
- return STATUS_UNSUCCESSFUL;
-}
-
-/*++
- * @name CsrServerInitialization
- * @implemented NT4
- *
- * The CsrDebugProcessStop routine is deprecated in NT 5.1 and higher. It is
- * exported only for compatibility with older CSR Server DLLs.
- *
- * @param CsrProcess
- * Deprecated.
- *
- * @return Deprecated
- *
- * @remarks Deprecated.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess)
-{
- /* CSR does not handle debugging anymore */
- DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
- return STATUS_UNSUCCESSFUL;
-}
-
-/*++
- * @name CsrDereferenceProcess
- * @implemented NT4
- *
- * The CsrDereferenceProcess routine removes a reference from a CSR Process.
- *
- * @param CsrThread
- * Pointer to the CSR Process to dereference.
- *
- * @return None.
- *
- * @remarks If the reference count has reached zero (ie: the CSR Process has
- * no more active references), it will be deleted.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess)
-{
- LONG LockCount;
-
- /* Acquire process lock */
- CsrAcquireProcessLock();
-
- /* Decrease reference count */
- LockCount = --CsrProcess->ReferenceCount;
- ASSERT(LockCount >= 0);
- if (!LockCount)
- {
- /* Call the generic cleanup code */
- CsrProcessRefcountZero(CsrProcess);
- }
- else
- {
- /* Just release the lock */
- CsrReleaseProcessLock();
- }
-}
-
-/*++
- * @name CsrDestroyProcess
- * @implemented NT4
- *
- * The CsrDestroyProcess routine destroys the CSR Process corresponding to
- * a given Client ID.
- *
- * @param Cid
- * Pointer to the Client ID Structure corresponding to the CSR
- * Process which is about to be destroyed.
- *
- * @param ExitStatus
- * Unused.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
- * if the CSR Process is already terminating.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDestroyProcess(IN PCLIENT_ID Cid,
- IN NTSTATUS ExitStatus)
-{
- PCSR_THREAD CsrThread;
- PCSR_PROCESS CsrProcess;
- CLIENT_ID ClientId = *Cid;
- PLIST_ENTRY NextEntry;
-
- /* Acquire lock */
- CsrAcquireProcessLock();
-
- /* Find the thread */
- CsrThread = CsrLocateThreadByClientId(&CsrProcess, &ClientId);
-
- /* Make sure we got one back, and that it's not already gone */
- if (!(CsrThread) || (CsrProcess->Flags & CsrProcessTerminating))
- {
- /* Release the lock and return failure */
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Set the terminated flag */
- CsrProcess->Flags |= CsrProcessTerminating;
-
- /* Get the List Pointers */
- NextEntry = CsrProcess->ThreadList.Flink;
- while (NextEntry != &CsrProcess->ThreadList)
- {
- /* Get the current thread entry */
- CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
-
- /* Make sure the thread isn't already dead */
- if (CsrThread->Flags & CsrThreadTerminated)
- {
- NextEntry = NextEntry->Flink;
- continue;
- }
-
- /* Set the Terminated flag */
- CsrThread->Flags |= CsrThreadTerminated;
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Do we have an active wait block? */
- if (CsrThread->WaitBlock)
- {
- /* Notify waiters of termination */
- CsrNotifyWaitBlock(CsrThread->WaitBlock,
- NULL,
- NULL,
- NULL,
- CsrProcessTerminating,
- TRUE);
- }
-
- /* Release the Wait Lock */
- CsrReleaseWaitLock();
-
- /* Dereference the thread */
- CsrLockedDereferenceThread(CsrThread);
- NextEntry = CsrProcess->ThreadList.Flink;
- }
-
- /* Release the Process Lock and return success */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrGetProcessLuid
- * @implemented NT4
- *
- * Do nothing for 500ms.
- *
- * @param hProcess
- * Optional handle to the process whose LUID should be returned.
- *
- * @param Luid
- * Pointer to a LUID Pointer which will receive the CSR Process' LUID
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks If hProcess is not supplied, then the current thread's token will
- * be used. If that too is missing, then the current process' token
- * will be used.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
- PLUID Luid)
-{
- HANDLE hToken = NULL;
- NTSTATUS Status;
- ULONG Length;
- PTOKEN_STATISTICS TokenStats;
-
- /* Check if we have a handle to a CSR Process */
- if (!hProcess)
- {
- /* We don't, so try opening the Thread's Token */
- Status = NtOpenThreadToken(NtCurrentThread(),
- TOKEN_QUERY,
- FALSE,
- &hToken);
-
- /* Check for success */
- if (!NT_SUCCESS(Status))
- {
- /* If we got some other failure, then return and quit */
- if (Status != STATUS_NO_TOKEN) return Status;
-
- /* We don't have a Thread Token, use a Process Token */
- hProcess = NtCurrentProcess();
- hToken = NULL;
- }
- }
-
- /* Check if we have a token by now */
- if (!hToken)
- {
- /* No token yet, so open the Process Token */
- Status = NtOpenProcessToken(hProcess,
- TOKEN_QUERY,
- &hToken);
- if (!NT_SUCCESS(Status)) return Status;
- }
-
- /* Now get the size we'll need for the Token Information */
- Status = NtQueryInformationToken(hToken,
- TokenStatistics,
- NULL,
- 0,
- &Length);
-
- /* Allocate memory for the Token Info */
- TokenStats = RtlAllocateHeap(CsrHeap, 0, Length);
- if (!TokenStats)
- {
- /* Fail and close the token */
- NtClose(hToken);
- return STATUS_NO_MEMORY;
- }
-
- /* Now query the information */
- Status = NtQueryInformationToken(hToken,
- TokenStatistics,
- TokenStats,
- Length,
- &Length);
-
- /* Close the handle */
- NtClose(hToken);
-
- /* Check for success to return the LUID */
- if (NT_SUCCESS(Status)) *Luid = TokenStats->AuthenticationId;
-
- /* Free the query information */
- RtlFreeHeap(CsrHeap, 0, TokenStats);
-
- /* Return the Status */
- return Status;
-}
-
-/*++
- * @name CsrLockProcessByClientId
- * @implemented NT4
- *
- * The CsrLockProcessByClientId routine locks the CSR Process corresponding
- * to the given Process ID and optionally returns it.
- *
- * @param Pid
- * Process ID corresponding to the CSR Process which will be locked.
- *
- * @param CsrProcess
- * Optional pointer to a CSR Process pointer which will hold the
- * CSR Process corresponding to the given Process ID.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks Locking a CSR Process is defined as acquiring an extra
- * reference to it and returning with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrLockProcessByClientId(IN HANDLE Pid,
- OUT PCSR_PROCESS *CsrProcess)
-{
- PLIST_ENTRY NextEntry;
- PCSR_PROCESS CurrentProcess = NULL;
- NTSTATUS Status;
-
- /* Acquire the lock */
- CsrAcquireProcessLock();
-
- /* Assume failure */
- ASSERT(CsrProcess != NULL);
- *CsrProcess = NULL;
-
- /* Setup the List Pointers */
- NextEntry = &CsrRootProcess->ListLink;
- do
- {
- /* Get the Process */
- CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
-
- /* Check for PID Match */
- if (CurrentProcess->ClientId.UniqueProcess == Pid)
- {
- Status = STATUS_SUCCESS;
- break;
- }
-
- /* Next entry */
- NextEntry = NextEntry->Flink;
- } while (NextEntry != &CsrRootProcess->ListLink);
-
- /* Check if we didn't find it in the list */
- if (!NT_SUCCESS(Status))
- {
- /* Nothing found, release the lock */
- CsrReleaseProcessLock();
- }
- else
- {
- /* Lock the found process and return it */
- CsrLockedReferenceProcess(CurrentProcess);
- *CsrProcess = CurrentProcess;
- }
-
- /* Return the result */
- return Status;
-}
-
-/*++
- * @name CsrSetForegroundPriority
- * @implemented NT4
- *
- * The CsrSetForegroundPriority routine sets the priority for the given CSR
- * Process as a Foreground priority.
- *
- * @param CsrProcess
- * Pointer to the CSR Process whose priority will be modified.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
-{
- PROCESS_PRIORITY_CLASS PriorityClass;
-
- /* Set the Foreground bit on */
- PriorityClass.Foreground = TRUE;
-
- /* Set the new Priority */
- NtSetInformationProcess(CsrProcess->ProcessHandle,
- ProcessPriorityClass,
- &PriorityClass,
- sizeof(PriorityClass));
-}
-
-/*++
- * @name CsrSetBackgroundPriority
- * @implemented NT4
- *
- * The CsrSetBackgroundPriority routine sets the priority for the given CSR
- * Process as a Background priority.
- *
- * @param CsrProcess
- * Pointer to the CSR Process whose priority will be modified.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
-{
- PROCESS_PRIORITY_CLASS PriorityClass;
-
- /* Set the Foreground bit off */
- PriorityClass.Foreground = FALSE;
-
- /* Set the new Priority */
- NtSetInformationProcess(CsrProcess->ProcessHandle,
- ProcessPriorityClass,
- &PriorityClass,
- sizeof(PriorityClass));
-}
-
-/*++
- * @name CsrShutdownProcesses
- * @implemented NT4
- *
- * The CsrShutdownProcesses routine shuts down every CSR Process possible
- * and calls each Server DLL's shutdown notification.
- *
- * @param CallerLuid
- * Pointer to the LUID of the CSR Process that is ordering the
- * shutdown.
- *
- * @param Flags
- * Flags to send to the shutdown notification routine.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrShutdownProcesses(IN PLUID CallerLuid,
- IN ULONG Flags)
-{
- PLIST_ENTRY NextEntry;
- PCSR_PROCESS CsrProcess;
- NTSTATUS Status;
- BOOLEAN FirstTry;
- ULONG i;
- PCSR_SERVER_DLL ServerDll;
- ULONG Result = 0; /* Intentionally invalid enumeratee to silence compiler warning */
-
- /* Acquire process lock */
- CsrAcquireProcessLock();
-
- /* Add shutdown flag */
- CsrRootProcess->ShutdownFlags |= CsrShutdownSystem;
-
- /* Get the list pointers */
- NextEntry = CsrRootProcess->ListLink.Flink;
- while (NextEntry != &CsrRootProcess->ListLink)
- {
- /* Get the Process */
- CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
-
- /* Remove the skip flag, set shutdown flags to 0*/
- CsrProcess->Flags &= ~CsrProcessSkipShutdown;
- CsrProcess->ShutdownFlags = 0;
-
- /* Move to the next */
- NextEntry = NextEntry->Flink;
- }
-
- /* Set shudown Priority */
- CsrpSetToShutdownPriority();
-
- /* Start looping */
- while (TRUE)
- {
- /* Find the next process to shutdown */
- CsrProcess = FindProcessForShutdown(CallerLuid);
- if (!CsrProcess) break;
-
- /* Increase reference to process */
- CsrProcess->ReferenceCount++;
-
- FirstTry = TRUE;
- while (TRUE)
- {
- /* Loop all the servers */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current server */
- ServerDll = CsrLoadedServerDll[i];
- if ((ServerDll) && (ServerDll->ShutdownProcessCallback))
- {
- /* Release the lock, make the callback, and acquire it back */
- CsrReleaseProcessLock();
- Result = ServerDll->ShutdownProcessCallback(CsrProcess,
- Flags,
- FirstTry);
- CsrAcquireProcessLock();
-
- /* Check the result */
- if (Result == CsrShutdownCsrProcess)
- {
- /* The callback unlocked the process */
- break;
- }
- else if (Result == CsrShutdownCancelled)
- {
- /* Check if this was a forced shutdown */
- if (Flags & EWX_FORCE)
- {
- DPRINT1("Process %x cancelled forced shutdown (Dll = %d)\n",
- CsrProcess->ClientId.UniqueProcess, i);
- DbgBreakPoint();
- }
-
- /* Shutdown was cancelled, unlock and exit */
- CsrReleaseProcessLock();
- Status = STATUS_CANCELLED;
- goto Quickie;
- }
- }
- }
-
- /* No matches during the first try, so loop again */
- if ((FirstTry) && (Result == CsrShutdownNonCsrProcess))
- {
- FirstTry = FALSE;
- continue;
- }
-
- /* Second try, break out */
- break;
- }
-
- /* We've reached the final loop here, so dereference */
- if (i == CSR_SERVER_DLL_MAX) CsrLockedDereferenceProcess(CsrProcess);
- }
-
- /* Success path */
- CsrReleaseProcessLock();
- Status = STATUS_SUCCESS;
-
-Quickie:
- /* Return to normal priority */
- CsrpSetToNormalPriority();
- return Status;
-}
-
-/*++
- * @name CsrUnlockProcess
- * @implemented NT4
- *
- * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation.
- *
- * @param CsrProcess
- * Pointer to a previously locked CSR Process.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks This routine must be called with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* Dereference the process */
- CsrLockedDereferenceProcess(CsrProcess);
-
- /* Release the lock and return */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrsrv/server.c
- * PURPOSE: CSR Server DLL Server Functions
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-PCSR_API_ROUTINE CsrServerApiDispatchTable[5] =
-{
- CsrSrvClientConnect,
- CsrSrvUnusedFunction,
- CsrSrvUnusedFunction,
- CsrSrvIdentifyAlertableThread,
- CsrSrvSetPriorityClass
-};
-
-BOOLEAN CsrServerApiServerValidTable[5] =
-{
- TRUE,
- FALSE,
- TRUE,
- TRUE,
- TRUE
-};
-
-PCHAR CsrServerApiNameTable[5] =
-{
- "ClientConnect",
- "ThreadConnect",
- "ProfileControl",
- "IdentifyAlertableThread",
- "SetPriorityClass"
-};
-
-PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
-PVOID CsrSrvSharedSectionHeap;
-PVOID CsrSrvSharedSectionBase;
-PVOID *CsrSrvSharedStaticServerData;
-ULONG CsrSrvSharedSectionSize;
-HANDLE CsrSrvSharedSection;
-
-/* PRIVATE FUNCTIONS**********************************************************/
-
-/*++
- * @name CsrLoadServerDll
- * @implemented NT4
- *
- * The CsrLoadServerDll routine loads a CSR Server DLL and calls its entrypoint
- *
- * @param DllString
- * Pointer to the CSR Server DLL to load and call.
- *
- * @param EntryPoint
- * Pointer to the name of the server's initialization function. If
- * this parameter is NULL, the default ServerDllInitialize will be
- * assumed.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrLoadServerDll(IN PCHAR DllString,
- IN PCHAR EntryPoint OPTIONAL,
- IN ULONG ServerId)
-{
- NTSTATUS Status;
- ANSI_STRING DllName;
- UNICODE_STRING TempString, ErrorString;
- ULONG_PTR Parameters[2];
- HANDLE hServerDll = NULL;
- ULONG Size;
- PCSR_SERVER_DLL ServerDll;
- STRING EntryPointString;
- PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure;
- ULONG Response;
-
- /* Check if it's beyond the maximum we support */
- if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES;
-
- /* Check if it's already been loaded */
- if (CsrLoadedServerDll[ServerId]) return STATUS_INVALID_PARAMETER;
-
- /* Convert the name to Unicode */
- ASSERT(DllString != NULL);
- RtlInitAnsiString(&DllName, DllString);
- Status = RtlAnsiStringToUnicodeString(&TempString, &DllName, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* If we are loading ourselves, don't actually load us */
- if (ServerId != CSR_SRV_SERVER)
- {
- /* Load the DLL */
- Status = LdrLoadDll(NULL, 0, &TempString, &hServerDll);
- if (!NT_SUCCESS(Status))
- {
- /* Setup error parameters */
- Parameters[0] = (ULONG_PTR)&TempString;
- Parameters[1] = (ULONG_PTR)&ErrorString;
- RtlInitUnicodeString(&ErrorString, L"Default Load Path");
-
- /* Send a hard error */
- NtRaiseHardError(Status,
- 2,
- 3,
- Parameters,
- OptionOk,
- &Response);
- }
-
- /* Get rid of the string */
- RtlFreeUnicodeString(&TempString);
- if (!NT_SUCCESS(Status)) return Status;
- }
-
- /* Allocate a CSR DLL Object */
- Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength;
- ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size);
- if (!ServerDll)
- {
- if (hServerDll) LdrUnloadDll(hServerDll);
- return STATUS_NO_MEMORY;
- }
-
- /* Set up the Object */
- ServerDll->Length = Size;
- ServerDll->SharedSection = CsrSrvSharedSectionHeap;
- ServerDll->Event = CsrInitializationEvent;
- ServerDll->Name.Length = DllName.Length;
- ServerDll->Name.MaximumLength = DllName.MaximumLength;
- ServerDll->Name.Buffer = (PCHAR)(ServerDll + 1);
- if (DllName.Length)
- {
- strncpy(ServerDll->Name.Buffer, DllName.Buffer, DllName.Length);
- }
- ServerDll->ServerId = ServerId;
- ServerDll->ServerHandle = hServerDll;
-
- /* Now get the entrypoint */
- if (hServerDll)
- {
- /* Initialize a string for the entrypoint, or use the default */
- RtlInitAnsiString(&EntryPointString,
- !(EntryPoint) ? "ServerDllInitialization" :
- EntryPoint);
-
- /* Get a pointer to it */
- Status = LdrGetProcedureAddress(hServerDll,
- &EntryPointString,
- 0,
- (PVOID)&ServerDllInitProcedure);
- }
- else
- {
- /* No handle, so we are loading ourselves */
- ServerDllInitProcedure = CsrServerDllInitialization;
- Status = STATUS_SUCCESS;
- }
-
- /* Check if we got the pointer, and call it */
- if (NT_SUCCESS(Status))
- {
- /* Get the result from the Server DLL */
- Status = ServerDllInitProcedure(ServerDll);
-
- /* Check for Success */
- if (NT_SUCCESS(Status))
- {
- /*
- * Add this Server's Per-Process Data Size to the total that each
- * process will need.
- */
- CsrTotalPerProcessDataLength += ServerDll->SizeOfProcessData;
-
- /* Save the pointer in our list */
- CsrLoadedServerDll[ServerDll->ServerId] = ServerDll;
-
- /* Does it use our generic heap? */
- if (ServerDll->SharedSection != CsrSrvSharedSectionHeap)
- {
- /* No, save the pointer to its shared section in our list */
- CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection;
- }
- }
- else
- {
- /* Use shared failure code */
- goto LoadFailed;
- }
- }
- else
- {
-LoadFailed:
- /* Server Init failed, unload it */
- if (hServerDll) LdrUnloadDll(hServerDll);
-
- /* Delete the Object */
- RtlFreeHeap(CsrHeap, 0, ServerDll);
- }
-
- /* Return to caller */
- return Status;
-}
-
-/*++
- * @name CsrServerDllInitialization
- * @implemented NT4
- *
- * The CsrServerDllInitialization is the initialization routine for
- * the this Server DLL.
- *
- * @param LoadedServerDll
- * Pointer to the CSR Server DLL structure representing this Server DLL.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll)
-{
- /* Setup the DLL Object */
- LoadedServerDll->ApiBase = 0;
- LoadedServerDll->HighestApiSupported = 5;
- LoadedServerDll->DispatchTable = CsrServerApiDispatchTable;
- LoadedServerDll->ValidTable = CsrServerApiServerValidTable;
- LoadedServerDll->NameTable = CsrServerApiNameTable;
- LoadedServerDll->SizeOfProcessData = 0;
- LoadedServerDll->ConnectCallback = NULL;
- LoadedServerDll->DisconnectCallback = NULL;
-
- /* All done */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvClientConnect
- *
- * The CsrSrvClientConnect CSR API handles a new connection to a server DLL.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message for this request.
- *
- * @param Reply
- * Optional reply to this request.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_INVALID_PARAMETER
- * or STATUS_TOO_MANY_NAMES in case of failure.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply OPTIONAL)
-{
- NTSTATUS Status;
- PCSR_CLIENT_CONNECT ClientConnect;
- PCSR_SERVER_DLL ServerDll;
- PCSR_PROCESS CurrentProcess = ((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process;
-
- /* Load the Message, set default reply */
- ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect;
- *Reply = 0;
-
- /* Validate the ServerID */
- if (ClientConnect->ServerId >= CSR_SERVER_DLL_MAX)
- {
- return STATUS_TOO_MANY_NAMES;
- }
- else if (!CsrLoadedServerDll[ClientConnect->ServerId])
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Validate the Message Buffer */
- if (!(CsrValidateMessageBuffer(ApiMessage,
- ClientConnect->ConnectionInfo,
- ClientConnect->ConnectionInfoSize,
- 1)))
- {
- /* Fail due to buffer overflow or other invalid buffer */
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Load the Server DLL */
- ServerDll = CsrLoadedServerDll[ClientConnect->ServerId];
-
- /* Check if it has a Connect Callback */
- if (ServerDll->ConnectCallback)
- {
- /* Call the callback */
- Status = ServerDll->ConnectCallback(CurrentProcess,
- ClientConnect->ConnectionInfo,
- &ClientConnect->ConnectionInfoSize);
- }
- else
- {
- /* Assume success */
- Status = STATUS_SUCCESS;
- }
-
- /* Return status */
- return Status;
-}
-
-/*++
- * @name CsrSrvCreateSharedSection
- *
- * The CsrSrvCreateSharedSection creates the Shared Section that all CSR Server
- * DLLs and Clients can use to share data.
- *
- * @param ParameterValue
- * Specially formatted string from our registry command-line which
- * specifies various arguments for the shared section.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
-{
- PCHAR SizeValue = ParameterValue;
- ULONG Size;
- NTSTATUS Status;
- LARGE_INTEGER SectionSize;
- ULONG ViewSize = 0;
- PPEB Peb = NtCurrentPeb();
-
- /* If there's no parameter, fail */
- if (!ParameterValue) return STATUS_INVALID_PARAMETER;
-
- /* Find the first comma, and null terminate */
- while (*SizeValue)
- {
- if (*SizeValue == ',')
- {
- *SizeValue++ = ANSI_NULL;
- break;
- }
- else
- {
- SizeValue++;
- }
- }
-
- /* Make sure it's valid */
- if (!*SizeValue) return STATUS_INVALID_PARAMETER;
-
- /* Convert it to an integer */
- Status = RtlCharToInteger(SizeValue, 0, &Size);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Multiply by 1024 entries and round to page size */
- CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize);
-
- /* Create the Secion */
- SectionSize.LowPart = CsrSrvSharedSectionSize;
- SectionSize.HighPart = 0;
- Status = NtCreateSection(&CsrSrvSharedSection,
- SECTION_ALL_ACCESS,
- NULL,
- &SectionSize,
- PAGE_EXECUTE_READWRITE,
- SEC_BASED | SEC_RESERVE,
- NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Map the section */
- Status = NtMapViewOfSection(CsrSrvSharedSection,
- NtCurrentProcess(),
- &CsrSrvSharedSectionBase,
- 0,
- 0,
- NULL,
- &ViewSize,
- ViewUnmap,
- MEM_TOP_DOWN,
- PAGE_EXECUTE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- NtClose(CsrSrvSharedSection);
- return Status;
- }
-
- /* FIXME: Write the value to registry */
-
- /* The Heap is the same place as the Base */
- CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase;
-
- /* Create the heap */
- if (!(RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_CLASS_7,
- CsrSrvSharedSectionHeap,
- CsrSrvSharedSectionSize,
- PAGE_SIZE,
- 0,
- 0)))
- {
- /* Failure, unmap section and return */
- NtUnmapViewOfSection(NtCurrentProcess(), CsrSrvSharedSectionBase);
- NtClose(CsrSrvSharedSection);
- return STATUS_NO_MEMORY;
- }
-
- /* Now allocate space from the heap for the Shared Data */
- CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap,
- 0,
- CSR_SERVER_DLL_MAX *
- sizeof(PVOID));
- if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY;
-
- /* Write the values to the PEB */
- Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase;
- Peb->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap;
- Peb->ReadOnlyStaticServerData = CsrSrvSharedStaticServerData;
-
- /* Return */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvAttachSharedSection
- *
- * The CsrSrvAttachSharedSection maps the CSR Shared Section into a new
- * CSR Process' address space, and returns the pointers to the section
- * through the Connection Info structure.
- *
- * @param CsrProcess
- * Pointer to the CSR Process that is attempting a connection.
- *
- * @param ConnectInfo
- * Pointer to the CSR Connection Info structure for the incoming
- * connection.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL,
- OUT PCSR_CONNECTION_INFO ConnectInfo)
-{
- NTSTATUS Status;
- ULONG ViewSize = 0;
-
- /* Check if we have a process */
- if (CsrProcess)
- {
- /* Map the sectio into this process */
- Status = NtMapViewOfSection(CsrSrvSharedSection,
- CsrProcess->ProcessHandle,
- &CsrSrvSharedSectionBase,
- 0,
- 0,
- NULL,
- &ViewSize,
- ViewUnmap,
- SEC_NO_CHANGE,
- PAGE_EXECUTE_READ);
- if (!NT_SUCCESS(Status)) return Status;
- }
-
- /* Write the values in the Connection Info structure */
- ConnectInfo->SharedSectionBase = CsrSrvSharedSectionBase;
- ConnectInfo->SharedSectionHeap = CsrSrvSharedSectionHeap;
- ConnectInfo->SharedSectionData = CsrSrvSharedStaticServerData;
-
- /* Return success */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvIdentifyAlertableThread
- * @implemented NT4
- *
- * The CsrSrvIdentifyAlertableThread CSR API marks a CSR Thread as alertable.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message for this request.
- *
- * @param Reply
- * Pointer to an optional reply to this request.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvIdentifyAlertableThread(IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply)
-{
- PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread;
-
- /* Set the alertable flag */
- CsrThread->Flags |= CsrThreadAltertable;
-
- /* Return success */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvSetPriorityClass
- * @implemented NT4
- *
- * The CsrSrvSetPriorityClass CSR API is deprecated.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message for this request.
- *
- * @param Reply
- * Pointer to an optional reply to this request.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvSetPriorityClass(IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply)
-{
- /* Deprecated */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvUnusedFunction
- * @implemented NT4
- *
- * The CsrSrvUnusedFunction CSR API is a stub for deprecated APIs.
- *
- * The CsrSrvSetPriorityClass CSR API is deprecated.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message for this request.
- *
- * @param Reply
- * Pointer to an optional reply to this request.
- *
- * @return STATUS_INVALID_PARAMETER.
- *
- * @remarks CsrSrvSetPriorityClass does not use this stub because it must
- * return success.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvUnusedFunction(IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply)
-{
- /* Deprecated */
- return STATUS_INVALID_PARAMETER;
-}
-
-/* PUBLIC FUNCTIONS***********************************************************/
-
-/*++
- * @name CsrSetCallingSpooler
- * @implemented NT4
- *
- * the CsrSetCallingSpooler routine is deprecated.
- *
- * @param Reserved
- * Deprecated
- *
- * @return None.
- *
- * @remarks This routine was used in archaic versions of NT for Printer Drivers.
- *
- *--*/
-VOID
-NTAPI
-CsrSetCallingSpooler(ULONG Reserved)
-{
- /* Deprecated */
- return;
-}
-
-/*++
- * @name CsrUnhandledExceptionFilter
- * @implemented NT5
- *
- * The CsrUnhandledExceptionFilter routine handles all exceptions
- * within SEH-protected blocks.
- *
- * @param ExceptionPointers
- * System-defined Argument.
- *
- * @return EXCEPTION_EXECUTE_HANDLER.
- *
- * @remarks None.
- *
- *--*/
-LONG
-NTAPI
-CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
-{
- SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo;
- EXCEPTION_DISPOSITION Result = EXCEPTION_EXECUTE_HANDLER;
- BOOLEAN OldValue;
- NTSTATUS Status;
- UNICODE_STRING ErrorSource;
- ULONG_PTR ErrorParameters[4];
- ULONG Response;
-
- /* Check if a debugger is installed */
- Status = NtQuerySystemInformation(SystemKernelDebuggerInformation,
- &DebuggerInfo,
- sizeof(DebuggerInfo),
- NULL);
-
- /* Check if this is Session 0, and the Debugger is Enabled */
- if ((NtCurrentPeb()->SessionId) && (NT_SUCCESS(Status)) &&
- (DebuggerInfo.KernelDebuggerEnabled))
- {
- /* Call the Unhandled Exception Filter */
- if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) !=
- EXCEPTION_CONTINUE_EXECUTION)
- {
- /* We're going to raise an error. Get Shutdown Privilege first */
- Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
- TRUE,
- TRUE,
- &OldValue);
-
- /* Use the Process token if that failed */
- if (Status == STATUS_NO_TOKEN)
- {
- Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
- TRUE,
- FALSE,
- &OldValue);
- }
-
- /* Initialize our Name String */
- RtlInitUnicodeString(&ErrorSource, L"Windows SubSystem");
-
- /* Set the parameters */
- ErrorParameters[0] = (ULONG_PTR)&ErrorSource;
- ErrorParameters[1] = ExceptionInfo->ExceptionRecord->ExceptionCode;
- ErrorParameters[2] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
- ErrorParameters[3] = (ULONG_PTR)ExceptionInfo->ContextRecord;
-
- /* Bugcheck */
- Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
- 4,
- 1,
- ErrorParameters,
- OptionShutdownSystem,
- &Response);
- }
-
- /* Just terminate us */
- NtTerminateProcess(NtCurrentProcess(),
- ExceptionInfo->ExceptionRecord->ExceptionCode);
- }
-
- return Result;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrsrv/session.c
- * PURPOSE: CSR Server DLL Session Implementation
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-RTL_CRITICAL_SECTION CsrNtSessionLock;
-LIST_ENTRY CsrNtSessionList;
-HANDLE CsrSmApiPort;
-
-PSB_API_ROUTINE CsrServerSbApiDispatch[5] =
-{
- CsrSbCreateSession,
- CsrSbTerminateSession,
- CsrSbForeignSessionComplete,
- CsrSbCreateProcess,
- NULL
-};
-
-PCHAR CsrServerSbApiName[5] =
-{
- "SbCreateSession",
- "SbTerminateSession",
- "SbForeignSessionComplete",
- "SbCreateProcess",
- "Unknown Csr Sb Api Number"
-};
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @name CsrInitializeNtSessionList
- *
- * The CsrInitializeNtSessionList routine sets up support for CSR Sessions.
- *
- * @param None
- *
- * @return None
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrInitializeNtSessionList(VOID)
-{
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
-
- /* Initialize the Session List */
- InitializeListHead(&CsrNtSessionList);
-
- /* Initialize the Session Lock */
- return RtlInitializeCriticalSection(&CsrNtSessionLock);
-}
-
-/*++
- * @name CsrAllocateNtSession
- *
- * The CsrAllocateNtSession routine allocates a new CSR NT Session.
- *
- * @param SessionId
- * Session ID of the CSR NT Session to allocate.
- *
- * @return Pointer to the newly allocated CSR NT Session.
- *
- * @remarks None.
- *
- *--*/
-PCSR_NT_SESSION
-NTAPI
-CsrAllocateNtSession(IN ULONG SessionId)
-{
- PCSR_NT_SESSION NtSession;
-
- /* Allocate an NT Session Object */
- NtSession = RtlAllocateHeap(CsrHeap, 0, sizeof(CSR_NT_SESSION));
- if (NtSession)
- {
- /* Setup the Session Object */
- NtSession->SessionId = SessionId;
- NtSession->ReferenceCount = 1;
-
- /* Insert it into the Session List */
- CsrAcquireNtSessionLock();
- InsertHeadList(&CsrNtSessionList, &NtSession->SessionLink);
- CsrReleaseNtSessionLock();
- }
- else
- {
- ASSERT(NtSession != NULL);
- }
-
- /* Return the Session (or NULL) */
- return NtSession;
-}
-
-/*++
- * @name CsrReferenceNtSession
- *
- * The CsrReferenceNtSession increases the reference count of a CSR NT Session.
- *
- * @param Session
- * Pointer to the CSR NT Session to reference.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrReferenceNtSession(IN PCSR_NT_SESSION Session)
-{
- /* Acquire the lock */
- CsrAcquireNtSessionLock();
-
- /* Sanity checks */
- ASSERT(!IsListEmpty(&Session->SessionLink));
- ASSERT(Session->SessionId != 0);
- ASSERT(Session->ReferenceCount != 0);
-
- /* Increase the reference count */
- Session->ReferenceCount++;
-
- /* Release the lock */
- CsrReleaseNtSessionLock();
-}
-
-/*++
- * @name CsrDereferenceNtSession
- *
- * The CsrDereferenceNtSession decreases the reference count of a
- * CSR NT Session.
- *
- * @param Session
- * Pointer to the CSR NT Session to reference.
- *
- * @param ExitStatus
- * If this is the last reference to the session, this argument
- * specifies the exit status.
- *
- * @return None.
- *
- * @remarks CsrDereferenceNtSession will complete the session if
- * the last reference to it has been closed.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceNtSession(IN PCSR_NT_SESSION Session,
- IN NTSTATUS ExitStatus)
-{
- /* Acquire the lock */
- CsrAcquireNtSessionLock();
-
- /* Sanity checks */
- ASSERT(!IsListEmpty(&Session->SessionLink));
- ASSERT(Session->SessionId != 0);
- ASSERT(Session->ReferenceCount != 0);
-
- /* Dereference the Session Object */
- if (!(--Session->ReferenceCount))
- {
- /* Remove it from the list */
- RemoveEntryList(&Session->SessionLink);
-
- /* Release the lock */
- CsrReleaseNtSessionLock();
-
- /* Tell SM that we're done here */
- SmSessionComplete(CsrSmApiPort, Session->SessionId, ExitStatus);
-
- /* Free the Session Object */
- RtlFreeHeap(CsrHeap, 0, Session);
- }
- else
- {
- /* Release the lock, the Session is still active */
- CsrReleaseNtSessionLock();
- }
-}
-
-
-/* SESSION MANAGER FUNCTIONS**************************************************/
-
-/*++
- * @name CsrSbCreateSession
- *
- * The CsrSbCreateSession API is called by the Session Manager whenever a new
- * session is created.
- *
- * @param ApiMessage
- * Pointer to the Session Manager API Message.
- *
- * @return TRUE in case of success, FALSE othwerwise.
- *
- * @remarks The CsrSbCreateSession routine will initialize a new CSR NT
- * Session and allocate a new CSR Process for the subsystem process.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
-{
- PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
- HANDLE hProcess, hThread;
- PCSR_PROCESS CsrProcess;
- NTSTATUS Status;
- KERNEL_USER_TIMES KernelTimes;
- PCSR_THREAD CsrThread;
- PVOID ProcessData;
- ULONG i;
-
- /* Save the Process and Thread Handles */
- hProcess = CreateSession->ProcessInfo.ProcessHandle;
- hThread = CreateSession->ProcessInfo.ThreadHandle;
-
- /* Lock the Processes */
- CsrAcquireProcessLock();
-
- /* Allocate a new process */
- CsrProcess = CsrAllocateProcess();
- if (!CsrProcess)
- {
- /* Fail */
- ApiMessage->ReturnValue = STATUS_NO_MEMORY;
- CsrReleaseProcessLock();
- return TRUE;
- }
-
- /* Set the exception port */
- Status = NtSetInformationProcess(hProcess,
- ProcessExceptionPort,
- &CsrApiPort,
- sizeof(HANDLE));
-
- /* Check for success */
- if (!NT_SUCCESS(Status))
- {
- /* Fail the request */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
-
- /* Strange as it seems, NTSTATUSes are actually returned */
- return (BOOLEAN)STATUS_NO_MEMORY;
- }
-
- /* Get the Create Time */
- Status = NtQueryInformationThread(hThread,
- ThreadTimes,
- &KernelTimes,
- sizeof(KERNEL_USER_TIMES),
- NULL);
-
- /* Check for success */
- if (!NT_SUCCESS(Status))
- {
- /* Fail the request */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
-
- /* Strange as it seems, NTSTATUSes are actually returned */
- return (BOOLEAN)Status;
- }
-
- /* Allocate a new Thread */
- CsrThread = CsrAllocateThread(CsrProcess);
- if (!CsrThread)
- {
- /* Fail the request */
- CsrDeallocateProcess(CsrProcess);
- ApiMessage->ReturnValue = STATUS_NO_MEMORY;
- CsrReleaseProcessLock();
- return TRUE;
- }
-
- /* Setup the Thread Object */
- CsrThread->CreateTime = KernelTimes.CreateTime;
- CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
- CsrThread->ThreadHandle = hThread;
- ProtectHandle(hThread);
- CsrThread->Flags = 0;
-
- /* Insert it into the Process List */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Setup Process Data */
- CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
- CsrProcess->ProcessHandle = hProcess;
- CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
-
- /* Set the Process Priority */
- CsrSetBackgroundPriority(CsrProcess);
-
- /* Get the first data location */
- ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
-
- /* Loop every DLL */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Check if the DLL is loaded and has Process Data */
- if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
- {
- /* Write the pointer to the data */
- CsrProcess->ServerData[i] = ProcessData;
-
- /* Move to the next data location */
- ProcessData = (PVOID)((ULONG_PTR)ProcessData +
- CsrLoadedServerDll[i]->SizeOfProcessData);
- }
- else
- {
- /* Nothing for this Process */
- CsrProcess->ServerData[i] = NULL;
- }
- }
-
- /* Insert the Process */
- CsrInsertProcess(NULL, NULL, CsrProcess);
-
- /* Activate the Thread */
- ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);
-
- /* Release lock and return */
- CsrReleaseProcessLock();
- return TRUE;
-}
-
-/*++
- * @name CsrSbForeignSessionComplete
- *
- * The CsrSbForeignSessionComplete API is called by the Session Manager
- * whenever a foreign session is completed (ie: terminated).
- *
- * @param ApiMessage
- * Pointer to the Session Manager API Message.
- *
- * @return TRUE in case of success, FALSE othwerwise.
- *
- * @remarks The CsrSbForeignSessionComplete API is not yet implemented.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage)
-{
- /* Deprecated/Unimplemented in NT */
- ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
- return TRUE;
-}
-
-/*++
- * @name CsrSbTerminateSession
- *
- * The CsrSbTerminateSession API is called by the Session Manager
- * whenever a foreign session should be destroyed.
- *
- * @param ApiMessage
- * Pointer to the Session Manager API Message.
- *
- * @return TRUE in case of success, FALSE othwerwise.
- *
- * @remarks The CsrSbTerminateSession API is not yet implemented.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrSbTerminateSession(IN PSB_API_MSG ApiMessage)
-{
- ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
- return TRUE;
-}
-
-/*++
- * @name CsrSbCreateProcess
- *
- * The CsrSbCreateProcess API is called by the Session Manager
- * whenever a foreign session is created and a new process should be started.
- *
- * @param ApiMessage
- * Pointer to the Session Manager API Message.
- *
- * @return TRUE in case of success, FALSE othwerwise.
- *
- * @remarks The CsrSbCreateProcess API is not yet implemented.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrSbCreateProcess(IN PSB_API_MSG ApiMessage)
-{
- ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
- return TRUE;
-}
-
-/* EOF */
+++ /dev/null
-#ifndef _SRV_H
-#define _SRV_H
-
-/* PSDK/NDK Headers */
-#define NTOS_MODE_USER
-#include <stdio.h>
-#define WIN32_NO_STATUS
-#include <windows.h>
-#include <winnt.h>
-#include <ndk/ntndk.h>
-
-/* CSR Header */
-#include <csr/server.h>
-#include <sm/smmsg.h>
-
-/* PSEH for SEH Support */
-#include <pseh/pseh2.h>
-
-/* DEFINES *******************************************************************/
-
-#define CSR_SERVER_DLL_MAX 4
-
-#define CsrAcquireProcessLock() \
- RtlEnterCriticalSection(&CsrProcessLock);
-
-#define CsrReleaseProcessLock() \
- RtlLeaveCriticalSection(&CsrProcessLock);
-
-#define CsrAcquireWaitLock() \
- RtlEnterCriticalSection(&CsrWaitListsLock);
-
-#define CsrReleaseWaitLock() \
- RtlLeaveCriticalSection(&CsrWaitListsLock);
-
-#define CsrAcquireNtSessionLock() \
- RtlEnterCriticalSection(&CsrNtSessionLock)
-
-#define CsrReleaseNtSessionLock() \
- RtlLeaveCriticalSection(&CsrNtSessionLock)
-
-#define CsrHashThread(t) \
- (HandleToUlong(t)&(256 - 1))
-
-#define ProcessStructureListLocked() \
- (CsrProcessLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
-
-#define SM_REG_KEY \
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager"
-
-#define SESSION_ROOT L"\\Sessions"
-#define GLOBAL_ROOT L"\\GLOBAL??"
-#define SYMLINK_NAME L"SymbolicLink"
-#define SB_PORT_NAME L"SbAbiPort"
-#define CSR_PORT_NAME L"ApiPort"
-#define UNICODE_PATH_SEP L"\\"
-
-#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
-#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
-
-/* DATA **********************************************************************/
-
-extern ULONG CsrTotalPerProcessDataLength;
-extern ULONG CsrMaxApiRequestThreads;
-extern PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
-extern PCSR_PROCESS CsrRootProcess;
-extern UNICODE_STRING CsrSbApiPortName;
-extern UNICODE_STRING CsrApiPortName;
-extern HANDLE CsrSbApiPort;
-extern HANDLE CsrSmApiPort;
-extern HANDLE CsrApiPort;
-extern HANDLE CsrHeap;
-extern RTL_CRITICAL_SECTION CsrProcessLock;
-extern RTL_CRITICAL_SECTION CsrWaitListsLock;
-extern LIST_ENTRY CsrThreadHashTable[256];
-extern HANDLE CsrInitializationEvent;
-extern SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
-extern UNICODE_STRING CsrDirectoryName;
-extern HANDLE CsrObjectDirectory;
-extern PSB_API_ROUTINE CsrServerSbApiDispatch[5];
-extern ULONG CsrDebug;
-
-/* FUNCTIONS *****************************************************************/
-
-/* FIXME: Public APIs should go in the CSR Server Include */
-BOOLEAN
-NTAPI
-CsrCaptureArguments(
- IN PCSR_THREAD CsrThread,
- IN PCSR_API_MESSAGE ApiMessage
-);
-
-NTSTATUS
-NTAPI
-CsrLoadServerDll(
- IN PCHAR DllString,
- IN PCHAR EntryPoint,
- IN ULONG ServerId
-);
-
-NTSTATUS
-NTAPI
-CsrServerInitialization(
- ULONG ArgumentCount,
- PCHAR Arguments[]
-);
-
-BOOLEAN
-NTAPI
-UnProtectHandle(IN HANDLE ObjectHandle);
-
-VOID
-NTAPI
-CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess);
-
-VOID
-NTAPI
-CsrLockedReferenceThread(IN PCSR_THREAD CsrThread);
-
-NTSTATUS
-NTAPI
-CsrCreateSessionObjectDirectory(IN ULONG SessionId);
-
-NTSTATUS
-NTAPI
-CsrCreateObjectDirectory(IN PCHAR ObjectDirectory);
-
-NTSTATUS
-NTAPI
-CsrSrvCreateSharedSection(IN PCHAR ParameterValue);
-
-NTSTATUS
-NTAPI
-CsrInitializeNtSessionList(VOID);
-
-NTSTATUS
-NTAPI
-CsrInitializeProcessStructure(VOID);
-
-NTSTATUS
-NTAPI
-CsrApiPortInitialize(VOID);
-
-NTSTATUS
-NTAPI
-CsrSbApiPortInitialize(VOID);
-
-BOOLEAN
-NTAPI
-CsrSbCreateSession(IN PSB_API_MSG ApiMessage);
-
-BOOLEAN
-NTAPI
-CsrSbTerminateSession(IN PSB_API_MSG ApiMessage);
-
-BOOLEAN
-NTAPI
-CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage);
-
-BOOLEAN
-NTAPI
-CsrSbCreateProcess(IN PSB_API_MSG ApiMessage);
-
-PCSR_PROCESS
-NTAPI
-CsrAllocateProcess(VOID);
-
-PCSR_THREAD
-NTAPI
-CsrAllocateThread(IN PCSR_PROCESS CsrProcess);
-
-VOID
-NTAPI
-CsrInsertThread(
- IN PCSR_PROCESS Process,
- IN PCSR_THREAD Thread
-);
-
-VOID
-NTAPI
-CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess);
-
-VOID
-NTAPI
-CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess);
-
-NTSTATUS
-NTAPI
-CsrGetProcessLuid(
- HANDLE hProcess,
- PLUID Luid
-);
-
-BOOLEAN
-NTAPI
-CsrImpersonateClient(IN PCSR_THREAD CsrThread);
-
-BOOLEAN
-NTAPI
-CsrRevertToSelf(VOID);
-
-PCSR_THREAD
-NTAPI
-CsrLocateThreadByClientId(
- OUT PCSR_PROCESS *Process,
- IN PCLIENT_ID ClientId
-);
-
-VOID
-NTAPI
-CsrDereferenceNtSession(
- IN PCSR_NT_SESSION Session,
- NTSTATUS ExitStatus
-);
-
-VOID
-NTAPI
-CsrReferenceNtSession(PCSR_NT_SESSION Session);
-
-VOID
-NTAPI
-CsrLockedDereferenceThread(PCSR_THREAD CsrThread);
-
-VOID
-NTAPI
-CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess);
-
-NTSTATUS
-NTAPI
-CsrLockProcessByClientId(
- IN HANDLE Pid,
- OUT PCSR_PROCESS *CsrProcess OPTIONAL
-);
-
-NTSTATUS
-NTAPI
-CsrUnlockProcess(PCSR_PROCESS CsrProcess);
-
-NTSTATUS
-NTAPI
-CsrSrvClientConnect(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-NTSTATUS
-NTAPI
-CsrSrvUnusedFunction(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-NTSTATUS
-NTAPI
-CsrSrvIdentifyAlertableThread(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-NTSTATUS
-NTAPI
-CsrSrvSetPriorityClass(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-NTSTATUS
-NTAPI
-CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll);
-
-VOID
-NTAPI
-CsrDereferenceThread(PCSR_THREAD CsrThread);
-
-VOID
-NTAPI
-CsrSbApiRequestThread(IN PVOID Parameter);
-
-NTSTATUS
-NTAPI
-CsrApiRequestThread(IN PVOID Parameter);
-
-BOOLEAN
-NTAPI
-ProtectHandle(IN HANDLE ObjectHandle);
-
-PCSR_THREAD
-NTAPI
-CsrAddStaticServerThread(
- IN HANDLE hThread,
- IN PCLIENT_ID ClientId,
- IN ULONG ThreadFlags
-);
-
-PCSR_THREAD
-NTAPI
-CsrConnectToUser(VOID);
-
-PCSR_THREAD
-NTAPI
-CsrLocateThreadInProcess(
- IN PCSR_PROCESS CsrProcess OPTIONAL,
- IN PCLIENT_ID Cid
-);
-
-NTSTATUS
-NTAPI
-CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message);
-
-NTSTATUS
-NTAPI
-CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage);
-
-NTSTATUS
-NTAPI
-CsrSrvAttachSharedSection(
- IN PCSR_PROCESS CsrProcess OPTIONAL,
- OUT PCSR_CONNECTION_INFO ConnectInfo
-);
-
-VOID
-NTAPI
-CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage);
-
-BOOLEAN
-NTAPI
-CsrNotifyWaitBlock(
- IN PCSR_WAIT_BLOCK WaitBlock,
- IN PLIST_ENTRY WaitList,
- IN PVOID WaitArgument1,
- IN PVOID WaitArgument2,
- IN ULONG WaitFlags,
- IN BOOLEAN DereferenceThread
-);
-
-VOID
-NTAPI
-CsrDereferenceProcess(PCSR_PROCESS CsrProcess);
-
-VOID
-NTAPI
-CsrInsertProcess(
- IN PCSR_PROCESS Parent OPTIONAL,
- IN PCSR_PROCESS CurrentProcess OPTIONAL,
- IN PCSR_PROCESS CsrProcess
-);
-
-NTSTATUS
-NTAPI
-CsrPopulateDosDevicesDirectory(
- IN HANDLE DosDevicesDirectory,
- IN PPROCESS_DEVICEMAP_INFORMATION DeviceMap
-);
-
-BOOLEAN
-NTAPI
-CsrValidateMessageBuffer(
- IN PCSR_API_MESSAGE ApiMessage,
- IN PVOID *Buffer,
- IN ULONG ArgumentSize,
- IN ULONG ArgumentCount
-);
-
-NTSTATUS
-NTAPI
-CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd);
-
-NTSTATUS
-NTAPI
-CsrDestroyThread(IN PCLIENT_ID Cid);
-
-NTSTATUS
-NTAPI
-CsrDestroyProcess(
- IN PCLIENT_ID Cid,
- IN NTSTATUS ExitStatus
-);
-
-LONG
-NTAPI
-CsrUnhandledExceptionFilter(
- IN PEXCEPTION_POINTERS ExceptionInfo
-);
-
-VOID
-NTAPI
-CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess);
-
-VOID
-NTAPI
-CsrThreadRefcountZero(IN PCSR_THREAD CsrThread);
-
-NTSTATUS
-NTAPI
-CsrSetDirectorySecurity(IN HANDLE ObjectDirectory);
-#endif
+++ /dev/null
-/*
- * CSRSRV Status
- */
-
-/* Organization
- *
- * api.c - Handles the LPC Reply/Request Threads which wait on Sb and Csr APIs.
- * Also in charge of creating those threads and setting up the ports.
- * Finally, it provides external APIs for validating the API buffers
- * and doing server-to-server API calls.
- *
- * init.c - Handles initialization of CSRSRV, including command-line parsing,
- * loading the Server DLLs, creating the Session Directories, setting
- * up the DosDevices Object Directory, and initializing each component.
- *
- * process.c - Handles all internal functions dealing with the CSR Process Object,
- * including de/allocation, de/referencing, un/locking, prority, and
- * lookups. Also handles all external APIs which touch the CSR Process Object.
- *
- * server.c - Handles all internal functions related to loading and managing Server
- * DLLs, as well as the routines handling the Shared Static Memory Section.
- * Holds the API Dispatch/Valid/Name Tables and the public CSR_SERVER API
- * interface. Also home of the SEH handler.
- *
- * session.c - Handles all internal functions dealing with the CSR Session Object,
- * including de/allocation, de/referencing, and un/locking. Holds the SB API
- * Dispatch/Name Tables and the public CsrSv API Interface for commmunication
- * with the Session Manager.
- *
- * thread.c - Handles all internal functions dealing with the CSR Thread Object,
- * including de/allocation, de/referencing, un/locking, impersonation, and
- * lookups. Also handles all external APIs which touch the CSR Thread Object.
- *
- * wait.c - Handles all internal functions dealing with the CSR Wait Object,
- * including de/allocation, de/referencing and un/locking. Also implements
- * the external Wait API for creating, removing and/or notifying waits.
- */
-
-/* Exported APIs, their location, and their status
- * CsrAddStaticServerThread 753E679E 1 - server.c - IMPLEMENTED
- * CsrCallServerFromServer 753E4FD9 2 - api.c - IMPLEMENTED
- * CsrConnectToUser 753E4E48 3 - api.c - IMPLEMENTED
- * CsrCreateProcess 753E6FD3 4 - process.c - IMPLEMENTED
- * CsrCreateRemoteThread 753E73BD 5 - thread.c - IMPLEMENTED
- * CsrCreateThread 753E72DA 6 - thread.c - IMPLEMENTED
- * CsrCreateWait 753E770E 7 - wait.c - IMPLEMENTED
- * CsrDebugProcess 753E7682 8 - process.c - IMPLEMENTED
- * CsrDebugProcessStop 753E768A 9 - process.c - IMPLEMENTED
- * CsrDereferenceProcess 753E6281 10 - process.c - IMPLEMENTED
- * CsrDereferenceThread 753E6964 11 - thread.c - IMPLEMENTED
- * CsrDereferenceWait 753E7886 12 - wait.c - IMPLEMENTED
- * CsrDestroyProcess 753E7225 13 - process.c - IMPLEMENTED
- * CsrDestroyThread 753E7478 14 - thread.c - IMPLEMENTED
- * CsrExecServerThread 753E6841 15 - thread.c - IMPLEMENTED
- * CsrGetProcessLuid 753E632F 16 - process.c - IMPLEMENTED
- * CsrImpersonateClient 753E60F8 17 - thread.c - IMPLEMENTED
- * CsrLockProcessByClientId 753E668F 18 - process.c - IMPLEMENTED
- * CsrLockThreadByClientId 753E6719 19 - thread.c - IMPLEMENTED
- * CsrMoveSatisfiedWait 753E7909 20 - wait.c - IMPLEMENTED
- * CsrNotifyWait 753E782F 21 - wait.c - IMPLEMENTED
- * CsrPopulateDosDevices 753E37A5 22 - init.c - IMPLEMENTED
- * CsrQueryApiPort 753E4E42 23 - api.c - IMPLEMENTED
- * CsrReferenceThread 753E61E5 24 - thread.c - IMPLEMENTED
- * CsrRevertToSelf 753E615A 25 - thread.c - IMPLEMENTED
- * CsrServerInitialization 753E3D75 26 - server.c - IMPLEMENTED
- * CsrSetBackgroundPriority 753E5E87 27 - process.c - IMPLEMENTED
- * CsrSetCallingSpooler 753E6425 28 - server.c - IMPLEMENTED
- * CsrSetForegroundPriority 753E5E67 29 - process.c - IMPLEMENTED
- * CsrShutdownProcesses 753E7547 30 - process.c - IMPLEMENTED
- * CsrUnhandledExceptionFilter 753E3FE3 31 - server.c - IMPLEMENTED
- * CsrUnlockProcess 753E66FD 32 - process.c - IMPLEMENTED
- * CsrUnlockThread 753E7503 33 - thread.c - IMPLEMENTED
- * CsrValidateMessageBuffer 753E528D 34 - api.c - IMPLEMENTED
- * CsrValidateMessageString 753E5323 35 - api.c - UNIMPLEMENTED
- */
-
-/* Public CSR API Interface Status (server.c)
- * CsrSrvClientConnect - IMPLEMENTED
- * CsrSrvUnusedFunction - IMPLEMENTED
- * CsrSrvIdentifyAlertableThread - IMPLEMENTED
- * CsrSrvSetPriorityClass - IMPLEMENTED
- */
-
-/* Public SB API Interface Status (session.c)
- * CsrSbCreateSession - IMPLEMENTED
- * CsrSbForeignSessionComplete - IMPLEMENTED
- * CsrSbTerminateSession - UNIMPLEMENTED
- * CsrSbCreateProcess - UNIMPLEMENTED
- */
-
-/* What's missing:
- *
- * - SMSS needs to be partly re-written to match some things done here.
- * Among other things, SmConnectToSm, SmCompleteSession and the other
- * Sm* Exported APIs have to be properly implemented, as well as the
- * callback calling and SM LPC APIs. [DONE!]
- *
- * - NTDLL needs to get the Csr* routines properly implemented. [DONE!]
- *
- * - KERNEL32, USER32 need to register with their servers properly.
- * Additionally, user32 needs to have ClientThreadStartup implemented
- * properly and do the syscall NtUserInitialize (I think) which also
- * needs to be implemented in win32k.sys. All this should be less then
- * 100 lines of code. [KERNEL32 50% DONE, USER32 NOT DONE]
- *
- * - The skeleton code for winsrv and basesrv which connects with CSR/CSRSRV
- * needs to be written. [NOT DONE]
- *
- * - The kernel's LPC implementation needs to be made compatible. [DONE!]
- */
-
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrsrv/thread.c
- * PURPOSE: CSR Server DLL Thread Implementation
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-LIST_ENTRY CsrThreadHashTable[256];
-SECURITY_QUALITY_OF_SERVICE CsrSecurityQos =
-{
- sizeof(SECURITY_QUALITY_OF_SERVICE),
- SecurityImpersonation,
- SECURITY_STATIC_TRACKING,
- FALSE
-};
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @name CsrAllocateThread
- *
- * The CsrAllocateThread routine allocates a new CSR Thread object.
- *
- * @param CsrProcess
- * Pointer to the CSR Process which will contain this CSR Thread.
- *
- * @return Pointer to the newly allocated CSR Thread.
- *
- * @remarks None.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrAllocateThread(IN PCSR_PROCESS CsrProcess)
-{
- PCSR_THREAD CsrThread;
-
- /* Allocate the structure */
- CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD));
- if (!CsrThread) return NULL;
-
- /* Reference the Thread and Process */
- CsrThread->ReferenceCount++;
- CsrProcess->ReferenceCount++;
-
- /* Set the Parent Process */
- CsrThread->Process = CsrProcess;
-
- /* Return Thread */
- return CsrThread;
-}
-
-/*++
- * @name CsrLocateThreadByClientId
- *
- * The CsrLocateThreadByClientId routine locates the CSR Thread and,
- * optionally, its parent CSR Process, corresponding to a Client ID.
- *
- * @param Process
- * Optional pointer to a CSR Process pointer which will contain
- * the CSR Thread's parent.
- *
- * @param ClientId
- * Pointer to a Client ID structure containing the Unique Thread ID
- * to look up.
- *
- * @return Pointer to the CSR Thread corresponding to this CID, or NULL if
- * none was found.
- *
- * @remarks None.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
- IN PCLIENT_ID ClientId)
-{
- ULONG i;
- PLIST_ENTRY NextEntry;
- PCSR_THREAD FoundThread;
- ASSERT(ProcessStructureListLocked());
-
- /* Hash the Thread */
- i = CsrHashThread(ClientId->UniqueThread);
-
- /* Set the list pointers */
- NextEntry = CsrThreadHashTable[i].Flink;
-
- /* Star the loop */
- while (NextEntry != &CsrThreadHashTable[i])
- {
- /* Get the thread */
- FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
-
- /* Compare the CID */
- if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId)
- {
- /* Match found, return the process */
- *Process = FoundThread->Process;
-
- /* Return thread too */
- return FoundThread;
- }
-
- /* Next */
- NextEntry = NextEntry->Flink;
- }
-
- /* Nothing found */
- return NULL;
-}
-
-/*++
- * @name CsrLocateThreadInProcess
- *
- * The CsrLocateThreadInProcess routine locates the CSR Thread
- * corresponding to a Client ID inside a specific CSR Process.
- *
- * @param Process
- * Optional pointer to the CSR Process which contains the CSR Thread
- * that will be looked up.
- *
- * @param ClientId
- * Pointer to a Client ID structure containing the Unique Thread ID
- * to look up.
- *
- * @return Pointer to the CSR Thread corresponding to this CID, or NULL if
- * none was found.
- *
- * @remarks If the CsrProcess argument is NULL, the lookup will be done inside
- * CsrRootProcess.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL,
- IN PCLIENT_ID Cid)
-{
- PLIST_ENTRY NextEntry;
- PCSR_THREAD FoundThread = NULL;
-
- /* Use the Root Process if none was specified */
- if (!CsrProcess) CsrProcess = CsrRootProcess;
-
- /* Save the List pointers */
- NextEntry = CsrProcess->ThreadList.Flink;
-
- /* Start the Loop */
- while (NextEntry != &CsrProcess->ThreadList)
- {
- /* Get Thread Entry */
- FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
-
- /* Check for TID Match */
- if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break;
-
- /* Next entry */
- NextEntry = NextEntry->Flink;
- }
-
- /* Return what we found */
- return FoundThread;
-}
-
-/*++
- * @name CsrInsertThread
- *
- * The CsrInsertThread routine inserts a CSR Thread into its parent's
- * Thread List and into the Thread Hash Table.
- *
- * @param Process
- * Pointer to the CSR Process containing this CSR Thread.
- *
- * @param Thread
- * Pointer to the CSR Thread to be inserted.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrInsertThread(IN PCSR_PROCESS Process,
- IN PCSR_THREAD Thread)
-{
- ULONG i;
- ASSERT(ProcessStructureListLocked());
-
- /* Insert it into the Regular List */
- InsertTailList(&Process->ThreadList, &Thread->Link);
-
- /* Increase Thread Count */
- Process->ThreadCount++;
-
- /* Hash the Thread */
- i = CsrHashThread(Thread->ClientId.UniqueThread);
-
- /* Insert it there too */
- InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks);
-}
-
-/*++
- * @name CsrDeallocateThread
- *
- * The CsrDeallocateThread frees the memory associated with a CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to be freed.
- *
- * @return None.
- *
- * @remarks Do not call this routine. It is reserved for the internal
- * thread management routines when a CSR Thread has been cleanly
- * dereferenced and killed.
- *
- *--*/
-VOID
-NTAPI
-CsrDeallocateThread(IN PCSR_THREAD CsrThread)
-{
- /* Free the process object from the heap */
- ASSERT(CsrThread->WaitBlock == NULL);
- RtlFreeHeap(CsrHeap, 0, CsrThread);
-}
-
-/*++
- * @name CsrLockedReferenceThread
- *
- * The CsrLockedReferenceThread refences a CSR Thread while the
- * Process Lock is already being held.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to be referenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedReferenceThread(IN PCSR_THREAD CsrThread)
-{
- /* Increment the reference count */
- ++CsrThread->ReferenceCount;
-}
-
-/*++
- * @name CsrLockedDereferenceThread
- *
- * The CsrLockedDereferenceThread derefences a CSR Thread while the
- * Process Lock is already being held.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to be dereferenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
-{
- LONG LockCount;
-
- /* Decrease reference count */
- LockCount = --CsrThread->ReferenceCount;
- ASSERT(LockCount >= 0);
- if (!LockCount)
- {
- /* Call the generic cleanup code */
- CsrThreadRefcountZero(CsrThread);
- CsrAcquireProcessLock();
- }
-}
-
-/*++
- * @name CsrRemoveThread
- *
- * The CsrRemoveThread function undoes a CsrInsertThread operation and
- * removes the CSR Thread from the the Hash Table and Thread List.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to remove.
- *
- * @return None.
- *
- * @remarks If this CSR Thread is the last one inside a CSR Process, the
- * parent will be dereferenced and the CsrProcessLastThreadTerminated
- * flag will be set.
- *
- * After executing this routine, the CSR Thread will have the
- * CsrThreadInTermination flag set.
- *
- *--*/
-VOID
-NTAPI
-CsrRemoveThread(IN PCSR_THREAD CsrThread)
-{
- ASSERT(ProcessStructureListLocked());
-
- /* Remove it from the List */
- RemoveEntryList(&CsrThread->Link);
-
- /* Decreate the thread count of the process */
- --CsrThread->Process->ThreadCount;
-
- /* Remove it from the Hash List as well */
- if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks);
-
- /* Check if this is the last Thread */
- if (!CsrThread->Process->ThreadCount)
- {
- /* Check if it's not already been marked for deletion */
- if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated))
- {
- /* Let everyone know this process is about to lose the thread */
- CsrThread->Process->Flags |= CsrProcessLastThreadTerminated;
-
- /* Reference the Process */
- CsrLockedDereferenceProcess(CsrThread->Process);
- }
- }
-
- /* Mark the thread for deletion */
- CsrThread->Flags |= CsrThreadInTermination;
-}
-
-/*++
- * @name CsrThreadRefcountZero
- *
- * The CsrThreadRefcountZero routine is executed when a CSR Thread has lost
- * all its active references. It removes and de-allocates the CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread that is to be deleted.
- *
- * @return None.
- *
- * @remarks Do not call this routine. It is reserved for the internal
- * thread management routines when a CSR Thread has lost all
- * its references.
- *
- * This routine is called with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)
-{
- PCSR_PROCESS CsrProcess = CsrThread->Process;
- NTSTATUS Status;
-
- /* Remove this thread */
- CsrRemoveThread(CsrThread);
-
- /* Release the Process Lock */
- CsrReleaseProcessLock();
-
- /* Close the NT Thread Handle */
- UnProtectHandle(CsrThread->ThreadHandle);
- Status = NtClose(CsrThread->ThreadHandle);
- ASSERT(NT_SUCCESS(Status));
-
- /* De-allocate the CSR Thread Object */
- CsrDeallocateThread(CsrThread);
-
- /* Remove a reference from the process */
- CsrDereferenceProcess(CsrProcess);
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-/*++
- * @name CsrAddStaticServerThread
- * @implemented NT4
- *
- * The CsrAddStaticServerThread routine adds a new CSR Thread to the
- * CSR Server Process (CsrRootProcess).
- *
- * @param hThread
- * Handle to an existing NT Thread to which to associate this
- * CSR Thread.
- *
- * @param ClientId
- * Pointer to the Client ID structure of the NT Thread to associate
- * with this CSR Thread.
- *
- * @param ThreadFlags
- * Initial CSR Thread Flags to associate to this CSR Thread. Usually
- * CsrThreadIsServerThread.
- *
- * @return Pointer to the newly allocated CSR Thread.
- *
- * @remarks None.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrAddStaticServerThread(IN HANDLE hThread,
- IN PCLIENT_ID ClientId,
- IN ULONG ThreadFlags)
-{
- PCSR_THREAD CsrThread;
-
- /* Get the Lock */
- CsrAcquireProcessLock();
-
- /* Allocate the Server Thread */
- CsrThread = CsrAllocateThread(CsrRootProcess);
- if (CsrThread)
- {
- /* Setup the Object */
- CsrThread->ThreadHandle = hThread;
- ProtectHandle(hThread);
- CsrThread->ClientId = *ClientId;
- CsrThread->Flags = ThreadFlags;
-
- /* Insert it into the Thread List */
- InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link);
-
- /* Increment the thread count */
- CsrRootProcess->ThreadCount++;
- }
- else
- {
- DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread);
- }
-
- /* Release the Process Lock and return */
- CsrReleaseProcessLock();
- return CsrThread;
-}
-
-/*++
- * @name CsrCreateRemoteThread
- * @implemented NT4
- *
- * The CsrCreateRemoteThread routine creates a CSR Thread object for
- * an NT Thread which is not part of the current NT Process.
- *
- * @param hThread
- * Handle to an existing NT Thread to which to associate this
- * CSR Thread.
- *
- * @param ClientId
- * Pointer to the Client ID structure of the NT Thread to associate
- * with this CSR Thread.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateRemoteThread(IN HANDLE hThread,
- IN PCLIENT_ID ClientId)
-{
- NTSTATUS Status;
- HANDLE ThreadHandle;
- PCSR_THREAD CsrThread;
- PCSR_PROCESS CsrProcess;
- KERNEL_USER_TIMES KernelTimes;
-
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
-
- /* Get the Thread Create Time */
- Status = NtQueryInformationThread(hThread,
- ThreadTimes,
- &KernelTimes,
- sizeof(KernelTimes),
- NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Lock the Owner Process */
- Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, &CsrProcess);
-
- /* Make sure the thread didn't terminate */
- if (KernelTimes.ExitTime.QuadPart)
- {
- /* Unlock the process and return */
- CsrUnlockProcess(CsrProcess);
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Allocate a CSR Thread Structure */
- CsrThread = CsrAllocateThread(CsrProcess);
- if (!CsrThread)
- {
- DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
- CsrUnlockProcess(CsrProcess);
- return STATUS_NO_MEMORY;
- }
-
- /* Duplicate the Thread Handle */
- Status = NtDuplicateObject(NtCurrentProcess(),
- hThread,
- NtCurrentProcess(),
- &ThreadHandle,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS);
- /* Allow failure */
- if (!NT_SUCCESS(Status)) ThreadHandle = hThread;
-
- /* Save the data we have */
- CsrThread->CreateTime = KernelTimes.CreateTime;
- CsrThread->ClientId = *ClientId;
- CsrThread->ThreadHandle = ThreadHandle;
- ProtectHandle(ThreadHandle);
- CsrThread->Flags = 0;
-
- /* Insert the Thread into the Process */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Release the lock and return */
- CsrUnlockProcess(CsrProcess);
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrCreateThread
- * @implemented NT4
- *
- * The CsrCreateThread routine creates a CSR Thread object for an NT Thread.
- *
- * @param CsrProcess
- * Pointer to the CSR Process which will contain the CSR Thread.
- *
- * @param hThread
- * Handle to an existing NT Thread to which to associate this
- * CSR Thread.
- *
- * @param ClientId
- * Pointer to the Client ID structure of the NT Thread to associate
- * with this CSR Thread.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateThread(IN PCSR_PROCESS CsrProcess,
- IN HANDLE hThread,
- IN PCLIENT_ID ClientId,
- IN BOOLEAN HaveClient)
-{
- NTSTATUS Status;
- PCSR_THREAD CsrThread, CurrentThread;
- PCSR_PROCESS CurrentProcess;
- CLIENT_ID CurrentCid;
- KERNEL_USER_TIMES KernelTimes;
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
-
- if (HaveClient)
- {
- /* Get the current thread and CID */
- CurrentThread = NtCurrentTeb()->CsrClientThread;
- CurrentCid = CurrentThread->ClientId;
-
- /* Acquire the Process Lock */
- CsrAcquireProcessLock();
-
- /* Get the current Process and make sure the Thread is valid with this CID */
- CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
- if (!CurrentThread)
- {
- DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
- }
- }
- else
- {
- /* Acquire the Process Lock */
- CsrAcquireProcessLock();
- }
-
- /* Get the Thread Create Time */
- Status = NtQueryInformationThread(hThread,
- ThreadTimes,
- (PVOID)&KernelTimes,
- sizeof(KernelTimes),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- CsrReleaseProcessLock();
- return Status;
- }
-
- /* Allocate a CSR Thread Structure */
- CsrThread = CsrAllocateThread(CsrProcess);
- if (!CsrThread)
- {
- DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Save the data we have */
- CsrThread->CreateTime = KernelTimes.CreateTime;
- CsrThread->ClientId = *ClientId;
- CsrThread->ThreadHandle = hThread;
- ProtectHandle(hThread);
- CsrThread->Flags = 0;
-
- /* Insert the Thread into the Process */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Release the lock and return */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrDereferenceThread
- * @implemented NT4
- *
- * The CsrDereferenceThread routine removes a reference from a CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to dereference.
- *
- * @return None.
- *
- * @remarks If the reference count has reached zero (ie: the CSR Thread has
- * no more active references), it will be deleted.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceThread(IN PCSR_THREAD CsrThread)
-{
- /* Acquire process lock */
- CsrAcquireProcessLock();
-
- /* Decrease reference count */
- ASSERT(CsrThread->ReferenceCount > 0);
- if (!(--CsrThread->ReferenceCount))
- {
- /* Call the generic cleanup code */
- CsrThreadRefcountZero(CsrThread);
- }
- else
- {
- /* Just release the lock */
- CsrReleaseProcessLock();
- }
-}
-
-/*++
- * @name CsrExecServerThread
- * @implemented NT4
- *
- * The CsrExecServerThread routine creates an NT Thread and then
- * initializes a CSR Thread for it.
- *
- * @param ThreadHandler
- * Pointer to the thread's startup routine.
- *
- * @param Flags
- * Initial CSR Thread Flags to set to the CSR Thread.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks This routine is similar to CsrAddStaticServerThread, but it
- * also creates an NT Thread instead of expecting one to already
- * exist.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrExecServerThread(IN PVOID ThreadHandler,
- IN ULONG Flags)
-{
- PCSR_THREAD CsrThread;
- HANDLE hThread;
- CLIENT_ID ClientId;
- NTSTATUS Status;
-
- /* Acquire process lock */
- CsrAcquireProcessLock();
-
- /* Allocate a CSR Thread in the Root Process */
- ASSERT(CsrRootProcess != NULL);
- CsrThread = CsrAllocateThread(CsrRootProcess);
- if (!CsrThread)
- {
- /* Fail */
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Create the Thread */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- FALSE,
- 0,
- 0,
- 0,
- ThreadHandler,
- NULL,
- &hThread,
- &ClientId);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- CsrDeallocateThread(CsrThread);
- CsrReleaseProcessLock();
- return Status;
- }
-
- /* Setup the Thread Object */
- CsrThread->ThreadHandle = hThread;
- ProtectHandle(hThread);
- CsrThread->ClientId = ClientId;
- CsrThread->Flags = Flags;
-
- /* Insert it into the Thread List */
- InsertHeadList(&CsrRootProcess->ThreadList, &CsrThread->Link);
-
- /* Increase the thread count */
- CsrRootProcess->ThreadCount++;
-
- /* Return */
- CsrReleaseProcessLock();
- return Status;
-}
-
-/*++
- * @name CsrDestroyThread
- * @implemented NT4
- *
- * The CsrDestroyThread routine destroys the CSR Thread corresponding to
- * a given Thread ID.
- *
- * @param Cid
- * Pointer to the Client ID Structure corresponding to the CSR
- * Thread which is about to be destroyed.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
- * if the CSR Thread is already terminating.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDestroyThread(IN PCLIENT_ID Cid)
-{
- CLIENT_ID ClientId = *Cid;
- PCSR_THREAD CsrThread;
- PCSR_PROCESS CsrProcess;
-
- /* Acquire lock */
- CsrAcquireProcessLock();
-
- /* Find the thread */
- CsrThread = CsrLocateThreadByClientId(&CsrProcess,
- &ClientId);
-
- /* Make sure we got one back, and that it's not already gone */
- if (!CsrThread || CsrThread->Flags & CsrThreadTerminated)
- {
- /* Release the lock and return failure */
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Set the terminated flag */
- CsrThread->Flags |= CsrThreadTerminated;
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Do we have an active wait block? */
- if (CsrThread->WaitBlock)
- {
- /* Notify waiters of termination */
- CsrNotifyWaitBlock(CsrThread->WaitBlock,
- NULL,
- NULL,
- NULL,
- CsrProcessTerminating,
- TRUE);
- }
-
- /* Release the Wait Lock */
- CsrReleaseWaitLock();
-
- /* Dereference the thread */
- CsrLockedDereferenceThread(CsrThread);
-
- /* Release the Process Lock and return success */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrImpersonateClient
- * @implemented NT4
- *
- * The CsrImpersonateClient will impersonate the given CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to impersonate.
- *
- * @return TRUE if impersionation suceeded, false otherwise.
- *
- * @remarks Impersonation can be recursive.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrImpersonateClient(IN PCSR_THREAD CsrThread)
-{
- NTSTATUS Status;
- PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
-
- /* Use the current thread if none given */
- if (!CsrThread) CsrThread = CurrentThread;
-
- /* Still no thread, something is wrong */
- if (!CsrThread) return FALSE;
-
- /* Make the call */
- Status = NtImpersonateThread(NtCurrentThread(),
- CsrThread->ThreadHandle,
- &CsrSecurityQos);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status);
- if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint();
- return FALSE;
- }
-
- /* Increase the impersonation count for the current thread and return */
- if (CurrentThread) ++CurrentThread->ImpersonationCount;
- return TRUE;
-}
-
-/*++
- * @name CsrRevertToSelf
- * @implemented NT4
- *
- * The CsrRevertToSelf routine will attempt to remove an active impersonation.
- *
- * @param None.
- *
- * @return TRUE if the reversion was succesful, false otherwise.
- *
- * @remarks Impersonation can be recursive; as such, the impersonation token
- * will only be deleted once the CSR Thread's impersonaton count
- * has reached zero.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrRevertToSelf(VOID)
-{
- NTSTATUS Status;
- PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
- HANDLE ImpersonationToken = NULL;
-
- /* Check if we have a Current Thread */
- if (CurrentThread)
- {
- /* Make sure impersonation is on */
- if (!CurrentThread->ImpersonationCount)
- {
- DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n");
- DbgBreakPoint();
- return FALSE;
- }
- else if (--CurrentThread->ImpersonationCount > 0)
- {
- /* Success; impersonation count decreased but still not zero */
- return TRUE;
- }
- }
-
- /* Impersonation has been totally removed, revert to ourselves */
- Status = NtSetInformationThread(NtCurrentThread(),
- ThreadImpersonationToken,
- &ImpersonationToken,
- sizeof(HANDLE));
-
- /* Return TRUE or FALSE */
- ASSERT(NT_SUCCESS(Status));
- return NT_SUCCESS(Status);
-}
-
-/*++
- * @name CsrLockThreadByClientId
- * @implemented NT4
- *
- * The CsrLockThreadByClientId routine locks the CSR Thread corresponding
- * to the given Thread ID and optionally returns it.
- *
- * @param Tid
- * Thread ID corresponding to the CSR Thread which will be locked.
- *
- * @param CsrThread
- * Optional pointer to a CSR Thread pointer which will hold the
- * CSR Thread corresponding to the given Thread ID.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks Locking a CSR Thread is defined as acquiring an extra
- * reference to it and returning with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrLockThreadByClientId(IN HANDLE Tid,
- OUT PCSR_THREAD *CsrThread)
-{
- PLIST_ENTRY NextEntry;
- PCSR_THREAD CurrentThread = NULL;
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- ULONG i;
-
- /* Acquire the lock */
- CsrAcquireProcessLock();
-
- /* Assume failure */
- ASSERT(CsrThread != NULL);
- *CsrThread = NULL;
-
- /* Convert to Hash */
- i = CsrHashThread(Tid);
-
- /* Setup the List Pointers */
- NextEntry = CsrThreadHashTable[i].Flink;
-
- /* Start Loop */
- while (NextEntry != &CsrThreadHashTable[i])
- {
- /* Get the Process */
- CurrentThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
-
- /* Check for PID Match */
- if ((CurrentThread->ClientId.UniqueThread == Tid) &&
- !(CurrentThread->Flags & CsrThreadTerminated))
- {
- /* Get out of here */
- break;
- }
-
- /* Next entry */
- NextEntry = NextEntry->Flink;
- }
-
- /* Nothing found if we got back to the list */
- if (NextEntry == &CsrThreadHashTable[i]) CurrentThread = NULL;
-
- /* Did the loop find something? */
- if (CurrentThread)
- {
- /* Reference the found thread */
- Status = STATUS_SUCCESS;
- CurrentThread->ReferenceCount++;
- *CsrThread = CurrentThread;
- }
- else
- {
- /* Nothing found, release the lock */
- Status = STATUS_UNSUCCESSFUL;
- CsrReleaseProcessLock();
- }
-
- /* Return the status */
- return Status;
-}
-
-/*++
- * @name CsrReferenceThread
- * @implemented NT4
- *
- * The CsrReferenceThread routine increases the active reference count of
- * a CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread whose reference count will be increased.
- *
- * @return None.
- *
- * @remarks Do not use this routine if the Process Lock is already held.
- *
- *--*/
-VOID
-NTAPI
-CsrReferenceThread(PCSR_THREAD CsrThread)
-{
- /* Acquire process lock */
- CsrAcquireProcessLock();
-
- /* Sanity checks */
- ASSERT(CsrThread->Flags & CsrThreadTerminated); // CSR_THREAD_DESTROYED in ASSERT
- ASSERT(CsrThread->ReferenceCount != 0);
-
- /* Increment reference count */
- CsrThread->ReferenceCount++;
-
- /* Release the lock */
- CsrReleaseProcessLock();
-}
-
-/*++
- * @name CsrUnlockThread
- * @implemented NT4
- *
- * The CsrUnlockThread undoes a previous CsrLockThreadByClientId operation.
- *
- * @param CsrThread
- * Pointer to a previously locked CSR Thread.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks This routine must be called with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrUnlockThread(PCSR_THREAD CsrThread)
-{
- /* Dereference the Thread */
- ASSERT(ProcessStructureListLocked());
- CsrLockedDereferenceThread(CsrThread);
-
- /* Release the lock and return */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrsrv/wait.c
- * PURPOSE: CSR Server DLL Wait Implementation
- * PROGRAMMERS: Emanuele Aliberti
- * Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-RTL_CRITICAL_SECTION CsrWaitListsLock;
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @name CsrInitializeWait
- *
- * The CsrInitializeWait routine initializes a CSR Wait Object.
- *
- * @param WaitFunction
- * Pointer to the function that will handle this wait.
- *
- * @param CsrWaitThread
- * Pointer to the CSR Thread that will perform the wait.
- *
- * @param WaitApiMessage
- * Pointer to the CSR API Message associated to this wait.
- *
- * @param WaitContext
- * Pointer to a user-defined parameter associated to this wait.
- *
- * @param NewWaitBlock
- * Pointed to the initialized CSR Wait Block for this wait.
- *
- * @return TRUE in case of success, FALSE othwerwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction,
- IN PCSR_THREAD CsrWaitThread,
- IN OUT PCSR_API_MESSAGE WaitApiMessage,
- IN PVOID WaitContext,
- OUT PCSR_WAIT_BLOCK *NewWaitBlock)
-{
- ULONG Size;
- PCSR_WAIT_BLOCK WaitBlock;
-
- /* Calculate the size of the wait block */
- Size = sizeof(CSR_WAIT_BLOCK) -
- sizeof(WaitBlock->WaitApiMessage) +
- WaitApiMessage->Header.u1.s1.TotalLength;
-
- /* Allocate the Wait Block */
- WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size);
- if (!WaitBlock)
- {
- /* Fail */
- WaitApiMessage->Status = STATUS_NO_MEMORY;
- return FALSE;
- }
-
- /* Initialize it */
- WaitBlock->Size = Size;
- WaitBlock->WaitThread = CsrWaitThread;
- WaitBlock->WaitContext = WaitContext;
- WaitBlock->WaitFunction = WaitFunction;
- WaitBlock->UserWaitList.Flink = NULL;
- WaitBlock->UserWaitList.Blink = NULL;
- WaitBlock->WaitList = WaitBlock->UserWaitList;
-
- /* Copy the message */
- RtlMoveMemory(&WaitBlock->WaitApiMessage,
- WaitApiMessage,
- WaitApiMessage->Header.u1.s1.TotalLength);
-
- /* Return the block */
- *NewWaitBlock = WaitBlock;
- return TRUE;
-}
-
-/*++
- * @name CsrNotifyWaitBlock
- *
- * The CsrNotifyWaitBlock routine calls the wait function for a registered
- * CSR Wait Block, and replies to the attached CSR API Message, if any.
- *
- * @param WaitBlock
- * Pointer to the CSR Wait Block
- *
- * @param WaitList
- * Pointer to the wait list for this wait.
- *
- * @param WaitArgument[1-2]
- * User-defined values to pass to the wait function.
- *
- * @param WaitFlags
- * Wait flags for this wait.
- *
- * @param DereferenceThread
- * Specifies whether the CSR Thread should be dereferenced at the
- * end of this wait.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks After a wait block is notified, the wait function becomes invalid.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
- IN PLIST_ENTRY WaitList,
- IN PVOID WaitArgument1,
- IN PVOID WaitArgument2,
- IN ULONG WaitFlags,
- IN BOOLEAN DereferenceThread)
-{
- /* Call the wait function */
- if ((WaitBlock->WaitFunction)(WaitList,
- WaitBlock->WaitThread,
- &WaitBlock->WaitApiMessage,
- WaitBlock->WaitContext,
- WaitArgument1,
- WaitArgument2,
- WaitFlags))
- {
- /* The wait is done, clear the block */
- WaitBlock->WaitThread->WaitBlock = NULL;
-
- /* Check for captured arguments */
- if (WaitBlock->WaitApiMessage.CsrCaptureData)
- {
- /* Release them */
- CsrReleaseCapturedArguments(&WaitBlock->WaitApiMessage);
- }
-
- /* Reply to the port */
- NtReplyPort(WaitBlock->WaitThread->Process->ClientPort,
- (PPORT_MESSAGE)&WaitBlock->WaitApiMessage);
-
- /* Check if we should dereference the thread */
- if (DereferenceThread)
- {
- /* Remove it from the Wait List */
- if (WaitBlock->WaitList.Flink)
- {
- RemoveEntryList(&WaitBlock->WaitList);
- }
-
- /* Remove it from the User Wait List */
- if (WaitBlock->UserWaitList.Flink)
- {
- RemoveEntryList(&WaitBlock->UserWaitList);
- }
-
- /* Dereference teh thread */
- CsrDereferenceThread(WaitBlock->WaitThread);
-
- /* Free the wait block */
- RtlFreeHeap(CsrHeap, 0, WaitBlock);
- }
- else
- {
- /* The wait is complete, but the thread is being kept alive */
- WaitBlock->WaitFunction = NULL;
- }
-
- /* The wait suceeded */
- return TRUE;
- }
-
- /* The wait failed */
- return FALSE;
-}
-
-/* PUBLIC FUNCTIONS **********************************************************/
-
-/*++
- * @name CsrCreateWait
- * @implemented NT4
- *
- * The CsrCreateWait routine creates a CSR Wait.
- *
- * @param WaitList
- * Pointer to a list entry of the waits to associate.
- *
- * @param WaitFunction
- * Pointer to the function that will handle this wait.
- *
- * @param CsrWaitThread
- * Pointer to the CSR Thread that will perform the wait.
- *
- * @param WaitApiMessage
- * Pointer to the CSR API Message associated to this wait.
- *
- * @param WaitContext
- * Pointer to a user-defined parameter associated to this wait.
- *
- * @param UserWaitList
- * Pointer to a list entry of the user-defined waits to associate.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrCreateWait(IN PLIST_ENTRY WaitList,
- IN CSR_WAIT_FUNCTION WaitFunction,
- IN PCSR_THREAD CsrWaitThread,
- IN OUT PCSR_API_MESSAGE WaitApiMessage,
- IN PVOID WaitContext,
- IN PLIST_ENTRY UserWaitList OPTIONAL)
-{
- PCSR_WAIT_BLOCK WaitBlock;
-
- /* Initialize the wait */
- if (!CsrInitializeWait(WaitFunction,
- CsrWaitThread,
- WaitApiMessage,
- WaitContext,
- &WaitBlock))
- {
- return FALSE;
- }
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Make sure the thread wasn't destroyed */
- if (CsrWaitThread->Flags & CsrThreadTerminated)
- {
- /* Fail the wait */
- RtlFreeHeap(CsrHeap, 0, WaitBlock);
- CsrReleaseWaitLock();
- return FALSE;
- }
-
- /* Insert the wait in the queue */
- InsertTailList(WaitList, &WaitBlock->WaitList);
-
- /* Insert the User Wait too, if one was given */
- if (UserWaitList) InsertTailList(UserWaitList, &WaitBlock->UserWaitList);
-
- /* Return */
- CsrReleaseWaitLock();
- return TRUE;
-}
-
-/*++
- * @name CsrDereferenceWait
- * @implemented NT4
- *
- * The CsrDereferenceWait routine derefences a CSR Wait Block.
- *
- * @param WaitList
- * Pointer to the Wait List associated to the wait.
-
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceWait(IN PLIST_ENTRY WaitList)
-{
- PLIST_ENTRY NextEntry;
- PCSR_WAIT_BLOCK WaitBlock;
-
- /* Acquire the Process and Wait Locks */
- CsrAcquireProcessLock();
- CsrAcquireWaitLock();
-
- /* Set the list pointers */
- NextEntry = WaitList->Flink;
-
- /* Start the loop */
- while (NextEntry != WaitList)
- {
- /* Get the wait block */
- WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
-
- /* Move to the next entry */
- NextEntry = NextEntry->Flink;
-
- /* Check if there's no Wait Routine */
- if (!WaitBlock->WaitFunction)
- {
- /* Remove it from the Wait List */
- if (WaitBlock->WaitList.Flink)
- {
- RemoveEntryList(&WaitBlock->WaitList);
- }
-
- /* Remove it from the User Wait List */
- if (WaitBlock->UserWaitList.Flink)
- {
- RemoveEntryList(&WaitBlock->UserWaitList);
- }
-
- /* Dereference the thread waiting on it */
- CsrDereferenceThread(WaitBlock->WaitThread);
-
- /* Free the block */
- RtlFreeHeap(CsrHeap, 0, WaitBlock);
- }
- }
-
- /* Release the locks */
- CsrReleaseWaitLock();
- CsrReleaseProcessLock();
-}
-
-/*++
- * @name CsrMoveSatisfiedWait
- * @implemented NT5
- *
- * The CsrMoveSatisfiedWait routine moves satisfied waits from a wait list
- * to another list entry.
- *
- * @param NewEntry
- * Pointer to a list entry where the satisfied waits will be added.
- *
- * @param WaitList
- * Pointer to a list entry to analyze for satisfied waits.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry,
- IN PLIST_ENTRY WaitList)
-{
- PLIST_ENTRY NextEntry;
- PCSR_WAIT_BLOCK WaitBlock;
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Set the List pointers */
- NextEntry = WaitList->Flink;
-
- /* Start looping */
- while (NextEntry != WaitList)
- {
- /* Get the Wait block */
- WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
-
- /* Go to the next entry */
- NextEntry = NextEntry->Flink;
-
- /* Check if there is a Wait Callback */
- if (WaitBlock->WaitFunction)
- {
- /* Remove it from the Wait Block Queue */
- RemoveEntryList(&WaitBlock->WaitList);
-
- /* Insert the new entry */
- InsertTailList(&WaitBlock->WaitList, NewEntry);
- }
- }
-
- /* Release the wait lock */
- CsrReleaseWaitLock();
-}
-
-/*++
- * @name CsrNotifyWait
- * @implemented NT4
- *
- * The CsrNotifyWait notifies a CSR Wait Block.
- *
- * @param WaitList
- * Pointer to the list entry for this wait.
- *
- * @param WaitType
- * Type of the wait to perform, either WaitAny or WaitAll.
- *
- * @param WaitArgument[1-2]
- * User-defined argument to pass on to the wait function.
- *
- * @return TRUE in case of success, FALSE othwerwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrNotifyWait(IN PLIST_ENTRY WaitList,
- IN ULONG WaitType,
- IN PVOID WaitArgument1,
- IN PVOID WaitArgument2)
-{
- PLIST_ENTRY NextEntry;
- PCSR_WAIT_BLOCK WaitBlock;
- BOOLEAN NotifySuccess = FALSE;
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Set the List pointers */
- NextEntry = WaitList->Flink;
-
- /* Start looping */
- while (NextEntry != WaitList)
- {
- /* Get the Wait block */
- WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
-
- /* Go to the next entry */
- NextEntry = NextEntry->Flink;
-
- /* Check if there is a Wait Callback */
- if (WaitBlock->WaitFunction)
- {
- /* Notify the Waiter */
- NotifySuccess |= CsrNotifyWaitBlock(WaitBlock,
- WaitList,
- WaitArgument1,
- WaitArgument2,
- 0,
- FALSE);
-
- /* We've already done a wait, so leave unless this is a Wait All */
- if (WaitType != WaitAll) break;
- }
- }
-
- /* Release the wait lock and return */
- CsrReleaseWaitLock();
- return NotifySuccess;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrss.c
- * PURPOSE: CSR Executable
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#define WIN32_NO_STATUS
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-#include <csr/server.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-VOID
-NTAPI
-CsrpSetDefaultProcessHardErrorMode (VOID)
-{
- ULONG DefaultHardErrorMode = 0;
-
- /* Disable hard errors */
- NtSetInformationProcess(NtCurrentProcess(),
- ProcessDefaultHardErrorMode,
- &DefaultHardErrorMode,
- sizeof(DefaultHardErrorMode));
-}
-
-/*
- * Note: Standard entrypoint for Native C Programs.
- * The OS backend (NtProcessStartup) which calls this routine is
- * implemented in a CRT-like static library (much like mainCRTStartup).
- * Do NOT manually add the NtProcessStartup entrypoint or anything else.
- */
-int
-_cdecl
-_main(int argc,
- char *argv[],
- char *envp[],
- int DebugFlag)
-{
- KPRIORITY BasePriority = (8 + 1) + 4;
- NTSTATUS Status;
- ULONG Response;
- UNREFERENCED_PARAMETER(envp);
- UNREFERENCED_PARAMETER(DebugFlag);
-
- /* Set the Priority */
- NtSetInformationProcess(NtCurrentProcess(),
- ProcessBasePriority,
- &BasePriority,
- sizeof(KPRIORITY));
-
- /* Give us IOPL so that we can access the VGA registers */
- Status = NtSetInformationProcess(NtCurrentProcess(),
- ProcessUserModeIOPL,
- NULL,
- 0);
- if (!NT_SUCCESS(Status))
- {
- /* Raise a hard error */
- DPRINT1("CSRSS: Could not raise IOPL: %x\n", Status);
- Status = NtRaiseHardError(STATUS_IO_PRIVILEGE_FAILED,
- 0,
- 0,
- NULL,
- OptionOk,
- &Response);
- }
-
- /* Initialize CSR through CSRSRV */
- Status = CsrServerInitialization(argc, argv);
- if (!NT_SUCCESS(Status))
- {
- /* Kill us */
- DPRINT1("CSRSS: CsrServerInitialization failed:% lx\n", Status);
- NtTerminateProcess(NtCurrentProcess(), Status);
- }
-
- /* Disable errors */
- CsrpSetDefaultProcessHardErrorMode();
-
- /* If this is Session 0, make sure killing us bugchecks the system */
- if (!NtCurrentPeb()->SessionId) RtlSetProcessIsCritical(TRUE, NULL, FALSE);
-
- /* Kill this thread. CSRSRV keeps us going */
- NtTerminateThread(NtCurrentThread(), Status);
- return 0;
-}
-
-/* EOF */
+++ /dev/null
-
-include_directories(${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include)
-include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys)
-
-spec2def(csrsrv.dll csrsrv.spec ADD_IMPORTLIB)
-
-list(APPEND SOURCE
- api/process.c
- api/user.c
- api/wapi.c
- procsup.c
- thredsup.c
- init.c
- wait.c
- session.c
- server.c
- ${CMAKE_CURRENT_BINARY_DIR}/csrsrv.def)
-
-add_library(csrsrv SHARED ${SOURCE})
-
-target_link_libraries(csrsrv ${PSEH_LIB} smlib)
-
-set_module_type(csrsrv nativedll)
-
-add_importlibs(csrsrv ntdll smdll)
-
-add_pch(csrsrv srv.h)
-
-add_dependencies(csrsrv psdk bugcodes)
-add_cd_file(TARGET csrsrv DESTINATION reactos/system32 FOR all)
-
+++ /dev/null
-/*
- * subsystems/win32/csrss/csrsrv/api/process.c
- *
- * "\windows\ApiPort" port process management functions
- *
- * ReactOS Operating System
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <srv.h>
-
-#define NDEBUG
-#include <debug.h>
-
-extern NTSTATUS CallProcessCreated(PCSR_PROCESS, PCSR_PROCESS);
-
-/* GLOBALS *******************************************************************/
-
-/* FUNCTIONS *****************************************************************/
-
-/**********************************************************************
- * CSRSS API
- *********************************************************************/
-
-CSR_API(CsrSrvCreateProcess)
-{
- NTSTATUS Status;
- HANDLE ProcessHandle, ThreadHandle;
- PCSR_THREAD CsrThread;
- PCSR_PROCESS NewProcessData;
- ULONG Flags, VdmPower = 0, DebugFlags = 0;
-
- /* Get the current client thread */
- CsrThread = NtCurrentTeb()->CsrClientThread;
- ASSERT(CsrThread != NULL);
-
- /* Extract the flags out of the process handle */
- Flags = (ULONG_PTR)Request->Data.CreateProcessRequest.ProcessHandle & 3;
- Request->Data.CreateProcessRequest.ProcessHandle = (HANDLE)((ULONG_PTR)Request->Data.CreateProcessRequest.ProcessHandle & ~3);
-
- /* Duplicate the process handle */
- Status = NtDuplicateObject(CsrThread->Process->ProcessHandle,
- Request->Data.CreateProcessRequest.ProcessHandle,
- NtCurrentProcess(),
- &ProcessHandle,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to duplicate process handle\n");
- return Status;
- }
-
- /* Duplicate the thread handle */
- Status = NtDuplicateObject(CsrThread->Process->ProcessHandle,
- Request->Data.CreateProcessRequest.ThreadHandle,
- NtCurrentProcess(),
- &ThreadHandle,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to duplicate process handle\n");
- NtClose(ProcessHandle);
- return Status;
- }
-
- /* See if this is a VDM process */
- if (VdmPower)
- {
- /* Request VDM powers */
- Status = NtSetInformationProcess(ProcessHandle,
- ProcessWx86Information,
- &VdmPower,
- sizeof(VdmPower));
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get VDM powers\n");
- NtClose(ProcessHandle);
- NtClose(ThreadHandle);
- return Status;
- }
- }
-
- /* Convert some flags. FIXME: More need conversion */
- if (Request->Data.CreateProcessRequest.CreationFlags & CREATE_NEW_PROCESS_GROUP)
- {
- DebugFlags |= CsrProcessCreateNewGroup;
- }
-
- /* FIXME: SxS Stuff */
-
- /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
- Status = CsrCreateProcess(ProcessHandle,
- ThreadHandle,
- &Request->Data.CreateProcessRequest.ClientId,
- CsrThread->Process->NtSession,
- DebugFlags,
- NULL);
- if (Status == STATUS_THREAD_IS_TERMINATING)
- {
- DPRINT1("Thread already dead\n");
- return Status;
- }
-
- /* Check for other failures */
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create process/thread structures: %lx\n", Status);
- return Status;
- }
-
- /* FIXME: Should notify user32 */
-
- /* FIXME: VDM vodoo */
-
- /* ReactOS Compatibility */
- Status = CsrLockProcessByClientId(Request->Data.CreateProcessRequest.ClientId.UniqueProcess, &NewProcessData);
- ASSERT(Status == STATUS_SUCCESS);
- if (!(Request->Data.CreateProcessRequest.CreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)))
- {
- NewProcessData->ParentConsole = ProcessData->Console;
- NewProcessData->bInheritHandles = Request->Data.CreateProcessRequest.bInheritHandles;
- }
- RtlInitializeCriticalSection(&NewProcessData->HandleTableLock);
- CallProcessCreated(ProcessData, NewProcessData);
- CsrUnlockProcess(NewProcessData);
-
- /* Return the result of this operation */
- return Status;
-}
-
-CSR_API(CsrSrvCreateThread)
-{
- PCSR_THREAD CurrentThread;
- HANDLE ThreadHandle;
- NTSTATUS Status;
- PCSR_PROCESS CsrProcess;
-
- /* Get the current CSR thread */
- CurrentThread = NtCurrentTeb()->CsrClientThread;
- if (!CurrentThread)
- {
- DPRINT1("Server Thread TID: [%lx.%lx]\n",
- Request->Data.CreateThreadRequest.ClientId.UniqueProcess,
- Request->Data.CreateThreadRequest.ClientId.UniqueThread);
- return STATUS_SUCCESS; // server-to-server
- }
-
- /* Get the CSR Process for this request */
- CsrProcess = CurrentThread->Process;
- if (CsrProcess->ClientId.UniqueProcess !=
- Request->Data.CreateThreadRequest.ClientId.UniqueProcess)
- {
- /* This is a remote thread request -- is it within the server itself? */
- if (Request->Data.CreateThreadRequest.ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
- {
- /* Accept this without any further work */
- return STATUS_SUCCESS;
- }
-
- /* Get the real CSR Process for the remote thread's process */
- Status = CsrLockProcessByClientId(Request->Data.CreateThreadRequest.ClientId.UniqueProcess,
- &CsrProcess);
- if (!NT_SUCCESS(Status)) return Status;
- }
-
- /* Duplicate the thread handle so we can own it */
- Status = NtDuplicateObject(CurrentThread->Process->ProcessHandle,
- Request->Data.CreateThreadRequest.ThreadHandle,
- NtCurrentProcess(),
- &ThreadHandle,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS);
- if (NT_SUCCESS(Status))
- {
- /* Call CSRSRV to tell it about the new thread */
- Status = CsrCreateThread(CsrProcess,
- ThreadHandle,
- &Request->Data.CreateThreadRequest.ClientId);
- }
-
- /* Unlock the process and return */
- if (CsrProcess != CurrentThread->Process) CsrUnlockProcess(CsrProcess);
- return Status;
-}
-
-CSR_API(CsrTerminateProcess)
-{
- PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread;
- ASSERT(CsrThread != NULL);
-
- /* Set magic flag so we don't reply this message back */
- Request->Type = 0xBABE;
-
- /* Remove the CSR_THREADs and CSR_PROCESS */
- return CsrDestroyProcess(&CsrThread->ClientId,
- (NTSTATUS)Request->Data.TerminateProcessRequest.uExitCode);
-}
-
-CSR_API(CsrConnectProcess)
-{
-
- return(STATUS_SUCCESS);
-}
-
-CSR_API(CsrGetShutdownParameters)
-{
-
- Request->Data.GetShutdownParametersRequest.Level = ProcessData->ShutdownLevel;
- Request->Data.GetShutdownParametersRequest.Flags = ProcessData->ShutdownFlags;
-
- return(STATUS_SUCCESS);
-}
-
-CSR_API(CsrSetShutdownParameters)
-{
-
- ProcessData->ShutdownLevel = Request->Data.SetShutdownParametersRequest.Level;
- ProcessData->ShutdownFlags = Request->Data.SetShutdownParametersRequest.Flags;
-
- return(STATUS_SUCCESS);
-}
-
-/* EOF */
+++ /dev/null
-/*
- * subsystems/win32/csrss/csrsrv/api/user.c
- *
- * User functions
- *
- * ReactOS Operating System
- *
- * PROGRAMMER: Eric Kohl
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <srv.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* GLOBALS *******************************************************************/
-
-static BOOLEAN ServicesProcessIdValid = FALSE;
-static ULONG_PTR ServicesProcessId;
-
-
-/* FUNCTIONS *****************************************************************/
-
-CSR_API(CsrRegisterServicesProcess)
-{
- if (ServicesProcessIdValid == TRUE)
- {
- /* Only accept a single call */
- return STATUS_INVALID_PARAMETER;
- }
- else
- {
- ServicesProcessId = (ULONG_PTR)Request->Data.RegisterServicesProcessRequest.ProcessId;
- ServicesProcessIdValid = TRUE;
- return STATUS_SUCCESS;
- }
-}
-
-/* EOF */
+++ /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 */
+++ /dev/null
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION "Client/Server Runtime SubSystem Process\0"
-#define REACTOS_STR_INTERNAL_NAME "csrsrv\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "csrsrv.dll\0"
-#include <reactos/version.rc>
+++ /dev/null
-@ stdcall CsrAddStaticServerThread(ptr ptr long)
-@ stdcall CsrCallServerFromServer(ptr ptr)
-;@ stdcall CsrConnectToUser()
-;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
-@ stdcall CsrCreateRemoteThread(ptr ptr)
-@ stdcall CsrCreateThread(ptr ptr ptr)
-;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
-;@ stdcall CsrDebugProcess(ptr)
-;@ stdcall CsrDebugProcessStop(ptr)
-;@ stdcall CsrDereferenceProcess(ptr)
-;@ stdcall CsrDereferenceThread(ptr)
-;@ stdcall CsrDereferenceWait(ptr)
-;@ stdcall CsrDestroyProcess(ptr long)
-;@ stdcall CsrDestroyThread(ptr)
-@ stdcall CsrEnumProcesses(ptr ptr) ; Temporary hack
-;@ stdcall CsrExecServerThread(ptr long)
-@ stdcall CsrGetProcessLuid(ptr ptr)
-@ stdcall CsrImpersonateClient(ptr)
-@ stdcall CsrLockProcessByClientId(ptr ptr)
-;@ stdcall CsrLockThreadByClientId(ptr ptr)
-;@ stdcall CsrMoveSatisfiedWait(ptr ptr)
-;@ stdcall CsrNotifyWait(ptr long ptr ptr)
-;@ stdcall CsrPopulateDosDevices()
-;@ stdcall CsrQueryApiPort()
-;@ stdcall CsrReferenceThread(ptr)
-@ stdcall CsrRevertToSelf()
-@ stdcall CsrServerInitialization(long ptr)
-;@ stdcall CsrSetBackgroundPriority(ptr)
-;@ stdcall CsrSetCallingSpooler(long)
-;@ stdcall CsrSetForegroundPriority(ptr)
-;@ stdcall CsrShutdownProcesses(ptr long)
-;@ stdcall CsrUnhandledExceptionFilter(ptr)
-@ stdcall CsrUnlockProcess(ptr)
-;@ stdcall CsrUnlockThread(ptr)
-;@ stdcall CsrValidateMessageBuffer(ptr ptr long long)
-;@ stdcall CsrValidateMessageString(ptr ptr)
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/include/api.h
- * PURPOSE: CSRSS API interface
- */
-
-#pragma once
-
-#define NTOS_MODE_USER
-#include <ndk/psfuncs.h>
-#include <ndk/rtlfuncs.h>
-
-#include <csrss/csrss.h>
-
-#define CSR_SRV_SERVER 0
-#define CSR_SERVER_DLL_MAX 4
-#define LOCK RtlEnterCriticalSection(&ProcessDataLock)
-#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
-#define CsrAcquireProcessLock() LOCK
-#define CsrReleaseProcessLock() UNLOCK
-#define ProcessStructureListLocked() \
- (ProcessDataLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
-
-#define CsrAcquireWaitLock() \
- RtlEnterCriticalSection(&CsrWaitListsLock);
-
-#define CsrReleaseWaitLock() \
- RtlLeaveCriticalSection(&CsrWaitListsLock);
-
-#define CsrAcquireNtSessionLock() \
- RtlEnterCriticalSection(&CsrNtSessionLock);
-
-#define CsrReleaseNtSessionLock() \
- RtlLeaveCriticalSection(&CsrNtSessionLock);
-
-typedef enum _CSR_THREAD_FLAGS
-{
- CsrThreadAltertable = 0x1,
- CsrThreadInTermination = 0x2,
- CsrThreadTerminated = 0x4,
- CsrThreadIsServerThread = 0x10
-} CSR_THREAD_FLAGS, *PCSR_THREAD_FLAGS;
-
-typedef enum _SHUTDOWN_RESULT
-{
- CsrShutdownCsrProcess = 1,
- CsrShutdownNonCsrProcess,
- CsrShutdownCancelled
-} SHUTDOWN_RESULT, *PSHUTDOWN_RESULT;
-
-typedef enum _CSR_SHUTDOWN_FLAGS
-{
- CsrShutdownSystem = 4,
- CsrShutdownOther = 8
-} CSR_SHUTDOWN_FLAGS, *PCSR_SHUTDOWN_FLAGS;
-
-typedef enum _CSR_DEBUG_FLAGS
-{
- CsrDebugOnlyThisProcess = 1,
- CsrDebugProcessChildren = 2
-} CSR_PROCESS_DEBUG_FLAGS, *PCSR_PROCESS_DEBUG_FLAGS;
-
-typedef enum _CSR_PROCESS_FLAGS
-{
- CsrProcessTerminating = 0x1,
- CsrProcessSkipShutdown = 0x2,
- CsrProcessNormalPriority = 0x10,
- CsrProcessIdlePriority = 0x20,
- CsrProcessHighPriority = 0x40,
- CsrProcessRealtimePriority = 0x80,
- CsrProcessCreateNewGroup = 0x100,
- CsrProcessTerminated = 0x200,
- CsrProcessLastThreadTerminated = 0x400,
- CsrProcessIsConsoleApp = 0x800
-} CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS;
-
-#define CsrProcessPriorityFlags (CsrProcessNormalPriority | \
- CsrProcessIdlePriority | \
- CsrProcessHighPriority | \
- CsrProcessRealtimePriority)
-
-typedef struct _CSRSS_CON_PROCESS_DATA
-{
- HANDLE ConsoleEvent;
- struct tagCSRSS_CONSOLE *Console;
- struct tagCSRSS_CONSOLE *ParentConsole;
- BOOL bInheritHandles;
- RTL_CRITICAL_SECTION HandleTableLock;
- ULONG HandleTableSize;
- struct _CSRSS_HANDLE *HandleTable;
- PCONTROLDISPATCHER CtrlDispatcher;
- LIST_ENTRY ConsoleLink;
-} CSRSS_CON_PROCESS_DATA, *PCSRSS_CON_PROCESS_DATA;
-
-typedef struct _CSR_NT_SESSION
-{
- ULONG ReferenceCount;
- LIST_ENTRY SessionLink;
- ULONG SessionId;
-} CSR_NT_SESSION, *PCSR_NT_SESSION;
-
-typedef struct _CSR_PROCESS
-{
- CLIENT_ID ClientId;
- LIST_ENTRY ListLink;
- LIST_ENTRY ThreadList;
- struct _CSR_PROCESS *Parent;
- PCSR_NT_SESSION NtSession;
- ULONG ExpectedVersion;
- HANDLE ClientPort;
- ULONG_PTR ClientViewBase;
- ULONG_PTR ClientViewBounds;
- HANDLE ProcessHandle;
- ULONG SequenceNumber;
- ULONG Flags;
- ULONG DebugFlags;
- CLIENT_ID DebugCid;
- ULONG ReferenceCount;
- ULONG ProcessGroupId;
- ULONG ProcessGroupSequence;
- ULONG fVDM;
- ULONG ThreadCount;
- ULONG PriorityClass;
- ULONG Reserved;
- ULONG ShutdownLevel;
- ULONG ShutdownFlags;
-// PVOID ServerData[ANYSIZE_ARRAY];
- CSRSS_CON_PROCESS_DATA;
-} CSR_PROCESS, *PCSR_PROCESS;
-
-typedef struct _CSR_THREAD
-{
- LARGE_INTEGER CreateTime;
- LIST_ENTRY Link;
- LIST_ENTRY HashLinks;
- CLIENT_ID ClientId;
- PCSR_PROCESS Process;
- struct _CSR_WAIT_BLOCK *WaitBlock;
- HANDLE ThreadHandle;
- ULONG Flags;
- ULONG ReferenceCount;
- ULONG ImpersonationCount;
-} CSR_THREAD, *PCSR_THREAD;
-
-typedef
-BOOLEAN
-(*CSR_WAIT_FUNCTION)(
- IN PLIST_ENTRY WaitList,
- IN PCSR_THREAD WaitThread,
- IN PCSR_API_MESSAGE WaitApiMessage,
- IN PVOID WaitContext,
- IN PVOID WaitArgument1,
- IN PVOID WaitArgument2,
- IN ULONG WaitFlags
-);
-
-typedef struct _CSR_WAIT_BLOCK
-{
- ULONG Size;
- LIST_ENTRY WaitList;
- LIST_ENTRY UserWaitList;
- PVOID WaitContext;
- PCSR_THREAD WaitThread;
- CSR_WAIT_FUNCTION WaitFunction;
- CSR_API_MESSAGE WaitApiMessage;
-} CSR_WAIT_BLOCK, *PCSR_WAIT_BLOCK;
-
-typedef
-NTSTATUS
-(NTAPI *PCSR_CONNECT_CALLBACK)(
- IN PCSR_PROCESS CsrProcess,
- IN OUT PVOID ConnectionInfo,
- IN OUT PULONG ConnectionInfoLength
-);
-
-typedef
-VOID
-(NTAPI *PCSR_DISCONNECT_CALLBACK)(IN PCSR_PROCESS CsrProcess);
-
-typedef
-NTSTATUS
-(NTAPI *PCSR_NEWPROCESS_CALLBACK)(
- IN PCSR_PROCESS Parent,
- IN PCSR_PROCESS CsrProcess
-);
-
-typedef
-VOID
-(NTAPI *PCSR_HARDERROR_CALLBACK)(
- IN PCSR_THREAD CsrThread,
- IN PHARDERROR_MSG HardErrorMessage
-);
-
-typedef
-ULONG
-(NTAPI *PCSR_SHUTDOWNPROCESS_CALLBACK)(
- IN PCSR_PROCESS CsrProcess,
- IN ULONG Flags,
- IN BOOLEAN FirstPhase
-);
-
-typedef
-NTSTATUS
-(NTAPI *PCSR_API_ROUTINE)(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-typedef struct _CSR_SERVER_DLL
-{
- ULONG Length;
- HANDLE Event;
- ANSI_STRING Name;
- HANDLE ServerHandle;
- ULONG ServerId;
- ULONG Unknown;
- ULONG ApiBase;
- ULONG HighestApiSupported;
- PCSR_API_ROUTINE *DispatchTable;
- PBOOLEAN ValidTable;
- PCHAR *NameTable;
- ULONG SizeOfProcessData;
- PCSR_CONNECT_CALLBACK ConnectCallback;
- PCSR_DISCONNECT_CALLBACK DisconnectCallback;
- PCSR_HARDERROR_CALLBACK HardErrorCallback;
- PVOID SharedSection;
- PCSR_NEWPROCESS_CALLBACK NewProcessCallback;
- PCSR_SHUTDOWNPROCESS_CALLBACK ShutdownProcessCallback;
- ULONG Unknown2[3];
-} CSR_SERVER_DLL, *PCSR_SERVER_DLL;
-
-typedef
-NTSTATUS
-(NTAPI *PCSR_SERVER_DLL_INIT_CALLBACK)(IN PCSR_SERVER_DLL ServerDll);
-
-
-typedef NTSTATUS (WINAPI *CSRSS_API_PROC)(PCSR_PROCESS ProcessData,
- PCSR_API_MESSAGE Request);
-
-typedef struct _CSRSS_API_DEFINITION
-{
- ULONG Type;
- ULONG MinRequestSize;
- CSRSS_API_PROC Handler;
-} CSRSS_API_DEFINITION, *PCSRSS_API_DEFINITION;
-
-#define CSRSS_DEFINE_API(Func, Handler) \
- { Func, sizeof(CSRSS_##Func), Handler }
-
-typedef struct _CSRSS_LISTEN_DATA
-{
- HANDLE ApiPortHandle;
- ULONG ApiDefinitionsCount;
- PCSRSS_API_DEFINITION *ApiDefinitions;
-} CSRSS_LISTEN_DATA, *PCSRSS_LISTEN_DATA;
-
-#define CSR_API(n) NTSTATUS WINAPI n ( \
- PCSR_PROCESS ProcessData, \
- PCSR_API_MESSAGE Request)
-
-/* init.c */
-extern HANDLE hBootstrapOk;
-NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]);
-
-/* api/process.c */
-CSR_API(CsrConnectProcess);
-CSR_API(CsrSrvCreateProcess);
-CSR_API(CsrTerminateProcess);
-CSR_API(CsrSrvCreateThread);
-CSR_API(CsrGetShutdownParameters);
-CSR_API(CsrSetShutdownParameters);
-
-VOID
-NTAPI
-CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess);
-
-PCSR_THREAD
-NTAPI
-CsrAllocateThread(IN PCSR_PROCESS CsrProcess);
-
-PCSR_PROCESS
-NTAPI
-CsrAllocateProcess(VOID);
-
-VOID
-NTAPI
-CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess);
-
-VOID
-NTAPI
-CsrRemoveProcess(IN PCSR_PROCESS CsrProcess);
-
-VOID
-NTAPI
-CsrDereferenceThread(IN PCSR_THREAD CsrThread);
-
-VOID
-NTAPI
-CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
- IN PCSR_PROCESS CurrentProcess OPTIONAL,
- IN PCSR_PROCESS CsrProcess);
-
-
-/* api/wapi.c */
-NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions);
-VOID FASTCALL CsrApiCallHandler(PCSR_PROCESS ProcessData,
- PCSR_API_MESSAGE Request);
-VOID WINAPI CsrSbApiRequestThread (PVOID PortHandle);
-VOID NTAPI ClientConnectionThread(HANDLE ServerPort);
-
-VOID
-NTAPI
-CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage);
-
-extern HANDLE CsrApiPort;
-extern HANDLE CsrSmApiPort;
-extern HANDLE CsrSbApiPort;
-extern LIST_ENTRY CsrThreadHashTable[256];
-extern PCSR_PROCESS CsrRootProcess;
-extern RTL_CRITICAL_SECTION ProcessDataLock, CsrWaitListsLock;
-extern UNICODE_STRING CsrDirectoryName;
-extern ULONG CsrDebug;
-extern ULONG CsrTotalPerProcessDataLength;
-extern SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
-extern PVOID CsrSrvSharedSectionHeap;
-extern PVOID *CsrSrvSharedStaticServerData;
-extern HANDLE CsrInitializationEvent;
-extern PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
-extern ULONG CsrMaxApiRequestThreads;
-
-NTSTATUS
-NTAPI
-CsrApiPortInitialize(VOID);
-
-NTSTATUS
-NTAPI
-CsrCreateProcess(IN HANDLE hProcess,
- IN HANDLE hThread,
- IN PCLIENT_ID ClientId,
- IN PCSR_NT_SESSION NtSession,
- IN ULONG Flags,
- IN PCLIENT_ID DebugCid);
-
-BOOLEAN
-NTAPI
-ProtectHandle(IN HANDLE ObjectHandle);
-
-VOID
-NTAPI
-CsrInsertThread(IN PCSR_PROCESS Process,
-IN PCSR_THREAD Thread);
-
-VOID
-NTAPI
-CsrLockedReferenceThread(IN PCSR_THREAD CsrThread);
-
-/* api/process.c */
-typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSR_PROCESS ProcessData,
- PVOID Context);
-NTSTATUS WINAPI CsrInitializeProcessStructure(VOID);
-
-NTSTATUS WINAPI CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context);
-PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags);
-PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, IN PCLIENT_ID Cid);
-PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, IN PCLIENT_ID ClientId);
-NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSR_PROCESS *CsrProcess OPTIONAL);
-NTSTATUS NTAPI CsrCreateThread(IN PCSR_PROCESS CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId);
-NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess);
-
-//hack
-VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread);
-
-NTSTATUS
-NTAPI
-CsrInitializeNtSessionList(VOID);
-
-NTSTATUS
-NTAPI
-CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL,
-OUT PCSR_CONNECTION_INFO ConnectInfo);
-
-NTSTATUS
-NTAPI
-CsrSrvCreateSharedSection(IN PCHAR ParameterValue);
-
-NTSTATUS
-NTAPI
-CsrSrvClientConnect(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-NTSTATUS
-NTAPI
-CsrSrvUnusedFunction(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-NTSTATUS
-NTAPI
-CsrSrvIdentifyAlertableThread(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-NTSTATUS
-NTAPI
-CsrSrvSetPriorityClass(
- IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply
-);
-
-NTSTATUS
-NTAPI
-CsrDestroyProcess(IN PCLIENT_ID Cid,
-IN NTSTATUS ExitStatus);
-
-NTSTATUS
-NTAPI
-CsrDestroyThread(IN PCLIENT_ID Cid);
-
-VOID
-NTAPI
-CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread);
-
-BOOLEAN
-NTAPI
-CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
- IN PLIST_ENTRY WaitList,
- IN PVOID WaitArgument1,
- IN PVOID WaitArgument2,
- IN ULONG WaitFlags,
- IN BOOLEAN DereferenceThread);
-
-VOID
-NTAPI
-CsrReferenceNtSession(IN PCSR_NT_SESSION Session);
-
-LONG
-NTAPI
-CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo);
-
-VOID
-NTAPI
-CsrDereferenceNtSession(IN PCSR_NT_SESSION Session,
-IN NTSTATUS ExitStatus);
-
-VOID
-NTAPI
-CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess);
-
-VOID
-NTAPI
-CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess);
-
-NTSTATUS
-NTAPI
-CsrLoadServerDll(IN PCHAR DllString,
- IN PCHAR EntryPoint OPTIONAL,
- IN ULONG ServerId);
-
-/* api/user.c */
-CSR_API(CsrRegisterServicesProcess);
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/include/csrplugin.h
- * PURPOSE: CSRSS plugin interface
- */
-
-/*
- * CSRSS is a native application and can only implicitly link against native
- * DLLs. Since e.g. user32.dll and gdi32.dll are win32 DLLs and not native
- * DLLs it is not possible to call functions in those DLLs directly from
- * CSRSS.
- * However, it is possible to explicitly load a non-native DLL. Such a DLL
- * can then in turn be implicitly linked against other DLLs in its own
- * subsystem.
- */
-
-#pragma once
-
-#include "api.h"
-
-typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESSES_PROC)(CSRSS_ENUM_PROCESS_PROC EnumProc,
- PVOID Context);
-
-typedef struct tagCSRSS_EXPORTED_FUNCS
-{
- CSRSS_ENUM_PROCESSES_PROC CsrEnumProcessesProc;
-} CSRSS_EXPORTED_FUNCS, *PCSRSS_EXPORTED_FUNCS;
-
-typedef BOOL (WINAPI *CSRPLUGIN_INIT_COMPLETE_PROC)(void);
-
-typedef VOID (WINAPI *CSRPLUGIN_HARDERROR_PROC)(IN PCSR_THREAD ThreadData,
- IN PHARDERROR_MSG HardErrorMessage);
-
-typedef NTSTATUS (WINAPI *CSRPLUGIN_PROCESS_INHERIT_PROC)(IN PCSR_PROCESS SourceProcessData,
- IN PCSR_PROCESS TargetProcessData);
-
-typedef ULONG (WINAPI *CSRPLUGIN_PROCESS_DELETED_PROC)(IN PCSR_PROCESS ProcessData, IN ULONG Unused, IN BOOLEAN Flag);
-
-typedef struct tagCSRSS_SERVER_PROCS
-{
- CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
- CSRPLUGIN_HARDERROR_PROC HardErrorProc;
- CSRPLUGIN_PROCESS_INHERIT_PROC ProcessInheritProc;
- CSRPLUGIN_PROCESS_DELETED_PROC ProcessDeletedProc;
-} CSRPLUGIN_SERVER_PROCS, *PCSRPLUGIN_SERVER_PROCS;
-
-typedef BOOL (WINAPI *CSRPLUGIN_INITIALIZE_PROC)(PCSRSS_API_DEFINITION *ApiDefinitions,
- PCSRPLUGIN_SERVER_PROCS ServerProcs);
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsystems/win32/csrss/csrsrv/init.c
- * PURPOSE: CSR Server DLL Initialization
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- * ReactOS Portable Systems Group
- */
-
-/* INCLUDES *******************************************************************/
-
-#include "srv.h"
-#define NDEBUG
-#include <debug.h>
-
-/* DATA ***********************************************************************/
-
-HANDLE CsrHeap = (HANDLE) 0;
-HANDLE CsrObjectDirectory = (HANDLE) 0;
-UNICODE_STRING CsrDirectoryName;
-UNICODE_STRING CsrSbApiPortName;
-HANDLE CsrSbApiPort = 0;
-PCSR_THREAD CsrSbApiRequestThreadPtr;
-HANDLE CsrSmApiPort;
-HANDLE hSbApiPort = (HANDLE) 0;
-HANDLE CsrApiPort = (HANDLE) 0;
-ULONG CsrDebug = 0;//0xFFFFFFFF;
-ULONG CsrMaxApiRequestThreads;
-ULONG CsrTotalPerProcessDataLength;
-ULONG SessionId;
-HANDLE BNOLinksDirectory;
-HANDLE SessionObjectDirectory;
-HANDLE DosDevicesDirectory;
-HANDLE CsrInitializationEvent;
-SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
-
-/* PRIVATE FUNCTIONS **********************************************************/
-
-VOID
-CallHardError(IN PCSR_THREAD ThreadData,
- IN PHARDERROR_MSG HardErrorMessage)
-{
- unsigned i;
- PCSR_SERVER_DLL ServerDll;
-
- DPRINT("CSR: %s called\n", __FUNCTION__);
-
- /* Notify the Server DLLs */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current Server DLL */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Make sure it's valid and that it has callback */
- if ((ServerDll) && (ServerDll->HardErrorCallback))
- {
- ServerDll->HardErrorCallback(ThreadData, HardErrorMessage);
- }
- }
-}
-
-NTSTATUS
-CallProcessCreated(IN PCSR_PROCESS SourceProcessData,
- IN PCSR_PROCESS TargetProcessData)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- unsigned i;
- PCSR_SERVER_DLL ServerDll;
-
- DPRINT("CSR: %s called\n", __FUNCTION__);
-
- /* Notify the Server DLLs */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current Server DLL */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Make sure it's valid and that it has callback */
- if ((ServerDll) && (ServerDll->NewProcessCallback))
- {
- Status = ServerDll->NewProcessCallback(SourceProcessData, TargetProcessData);
- }
- }
-
- return Status;
-}
-
-CSRSS_API_DEFINITION NativeDefinitions[] =
- {
- CSRSS_DEFINE_API(CREATE_PROCESS, CsrSrvCreateProcess),
- CSRSS_DEFINE_API(CREATE_THREAD, CsrSrvCreateThread),
- CSRSS_DEFINE_API(TERMINATE_PROCESS, CsrTerminateProcess),
- CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess),
- CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess),
- CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS, CsrGetShutdownParameters),
- CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters),
- { 0, 0, NULL }
- };
-
-/* === INIT ROUTINES === */
-
-VOID
-WINAPI
-BasepFakeStaticServerData(VOID);
-
-/*++
- * @name CsrSetProcessSecurity
- *
- * The CsrSetProcessSecurity routine protects access to the CSRSS process
- * from unauthorized tampering.
- *
- * @param None.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSetProcessSecurity(VOID)
-{
- NTSTATUS Status;
- HANDLE hToken, hProcess = NtCurrentProcess();
- ULONG Length;
- PTOKEN_USER TokenInfo = NULL;
- PSECURITY_DESCRIPTOR ProcSd = NULL;
- PACL Dacl;
- PSID UserSid;
-
- /* Open our token */
- Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Get the Token User Length */
- NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
-
- /* Allocate space for it */
- TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
- if (!TokenInfo)
- {
- Status = STATUS_NO_MEMORY;
- goto Quickie;
- }
-
- /* Now query the data */
- Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length);
- NtClose(hToken);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Now check the SID Length */
- UserSid = TokenInfo->User.Sid;
- Length = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
-
- /* Allocate a buffer for the Security Descriptor, with SID and DACL */
- ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
- if (!ProcSd)
- {
- Status = STATUS_NO_MEMORY;
- goto Quickie;
- }
-
- /* Set the pointer to the DACL */
- Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
-
- /* Now create the SD itself */
- Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status);
- goto Quickie;
- }
-
- /* Create the DACL for it*/
- Status = RtlCreateAcl(Dacl, Length, ACL_REVISION2);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status);
- goto Quickie;
- }
-
- /* Create the ACE */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- PROCESS_VM_READ | PROCESS_VM_WRITE |
- PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
- PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
- PROCESS_QUERY_INFORMATION | READ_CONTROL,
- UserSid);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status);
- goto Quickie;
- }
-
- /* Clear the DACL in the SD */
- Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status);
- goto Quickie;
- }
-
- /* Write the SD into the Process */
- Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status);
- goto Quickie;
- }
-
- /* Free the memory and return */
-Quickie:
- if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
- RtlFreeHeap(CsrHeap, 0, TokenInfo);
- return Status;
-}
-
-/*++
- * @name CsrSetDirectorySecurity
- *
- * The CsrSetDirectorySecurity routine sets the security descriptor for the
- * specified Object Directory.
- *
- * @param ObjectDirectory
- * Handle fo the Object Directory to protect.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSetDirectorySecurity(IN HANDLE ObjectDirectory)
-{
- /* FIXME: Implement */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name GetDosDevicesProtection
- *
- * The GetDosDevicesProtection creates a security descriptor for the DOS Devices
- * Object Directory.
- *
- * @param DosDevicesSd
- * Pointer to the Security Descriptor to return.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks Depending on the DOS Devices Protection Mode (set in the registry),
- * regular users may or may not have full access to the directory.
- *
- *--*/
-NTSTATUS
-NTAPI
-GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
-{
- SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
- SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
- SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
- PSID WorldSid, CreatorSid, AdminSid, SystemSid;
- UCHAR KeyValueBuffer[0x40];
- PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
- UNICODE_STRING KeyName;
- ULONG ProtectionMode = 0;
- OBJECT_ATTRIBUTES ObjectAttributes;
- PACL Dacl;
- PACCESS_ALLOWED_ACE Ace;
- HANDLE hKey;
- NTSTATUS Status;
- ULONG ResultLength, SidLength, AclLength;
-
- /* Create the SD */
- Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION);
- ASSERT(NT_SUCCESS(Status));
-
- /* Initialize the System SID */
- Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
- SECURITY_LOCAL_SYSTEM_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &SystemSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Initialize the World SID */
- Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1,
- SECURITY_WORLD_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &WorldSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Initialize the Admin SID */
- Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- 0, 0, 0, 0, 0, 0,
- &AdminSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Initialize the Creator SID */
- Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
- SECURITY_CREATOR_OWNER_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &CreatorSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* 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);
- }
-
- /* Check the Protection Mode */
- if (ProtectionMode & 3)
- {
- /* Calculate SID Lengths */
- SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) +
- RtlLengthSid(AdminSid);
- AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
-
- /* Allocate memory for the DACL */
- Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
- ASSERT(Dacl != NULL);
-
- /* Build the ACL and add 3 ACEs */
- Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Edit the ACEs to make them inheritable */
- Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace);
- ASSERT(NT_SUCCESS(Status));
- Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
- Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace);
- ASSERT(NT_SUCCESS(Status));
- Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
- Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
- ASSERT(NT_SUCCESS(Status));
- Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
-
- /* Set this DACL with the SD */
- Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
- ASSERT(NT_SUCCESS(Status));
- goto Quickie;
- }
- else
- {
- /* Calculate SID Lengths */
- SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid);
- AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
-
- /* Allocate memory for the DACL */
- Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
- ASSERT(Dacl != NULL);
-
- /* Build the ACL and add 3 ACEs */
- Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
- ASSERT(NT_SUCCESS(Status));
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid);
- ASSERT(NT_SUCCESS(Status));
-
- /* Edit the last ACE to make it inheritable */
- Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
- ASSERT(NT_SUCCESS(Status));
- Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
-
- /* Set this DACL with the SD */
- Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
- ASSERT(NT_SUCCESS(Status));
- goto Quickie;
- }
-
-/* FIXME: failure cases! Fail: */
- /* Free the memory */
- RtlFreeHeap(CsrHeap, 0, Dacl);
-
-/* FIXME: semi-failure cases! Quickie: */
-Quickie:
- /* Free the SIDs */
- RtlFreeSid(SystemSid);
- RtlFreeSid(WorldSid);
- RtlFreeSid(AdminSid);
- RtlFreeSid(CreatorSid);
-
- /* Return */
- return Status;
-}
-
-/*++
- * @name FreeDosDevicesProtection
- *
- * The FreeDosDevicesProtection frees the security descriptor that was created
- * by GetDosDevicesProtection
- *
- * @param DosDevicesSd
- * Pointer to the security descriptor to free.
-
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd)
-{
- PACL Dacl;
- BOOLEAN Present, Default;
- NTSTATUS Status;
-
- /* Get the DACL corresponding to this SD */
- Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default);
- ASSERT(NT_SUCCESS(Status));
- ASSERT(Present);
- ASSERT(Dacl != NULL);
-
- /* Free it */
- if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl);
-}
-
-/*++
- * @name CsrCreateSessionObjectDirectory
- *
- * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects,
- * Session and Dos Devices directories for the specified session.
- *
- * @param Session
- * Session ID for which to create the directories.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateSessionObjectDirectory(IN ULONG Session)
-{
- WCHAR SessionBuffer[512], BnoBuffer[512];
- UNICODE_STRING SessionString, BnoString;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE BnoHandle;
- SECURITY_DESCRIPTOR DosDevicesSd;
- NTSTATUS Status;
-
- /* Generate the Session BNOLINKS Directory name */
- swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT);
- RtlInitUnicodeString(&SessionString, SessionBuffer);
-
- /* Create it */
- InitializeObjectAttributes(&ObjectAttributes,
- &SessionString,
- OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtCreateDirectoryObject(&BNOLinksDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
- "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
- return Status;
- }
-
- /* Now add the Session ID */
- swprintf(SessionBuffer, L"%ld", Session);
- RtlInitUnicodeString(&SessionString, SessionBuffer);
-
- /* Check if this is the first Session */
- if (Session)
- {
- /* Not the first, so the name will be slighly more complex */
- swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session);
- RtlInitUnicodeString(&BnoString, BnoBuffer);
- }
- else
- {
- /* Use the direct name */
- RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
- }
-
- /* Create the symlink */
- InitializeObjectAttributes(&ObjectAttributes,
- &SessionString,
- OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
- BNOLinksDirectory,
- NULL);
- Status = NtCreateSymbolicLinkObject(&BnoHandle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes,
- &BnoString);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in "
- "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
- return Status;
- }
-
- /* Create the \DosDevices Security Descriptor */
- Status = GetDosDevicesProtection(&DosDevicesSd);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Now create a directory for this session */
- swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session);
- RtlInitUnicodeString(&SessionString, SessionBuffer);
-
- /* Create the directory */
- InitializeObjectAttributes(&ObjectAttributes,
- &SessionString,
- OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
- 0,
- &DosDevicesSd);
- Status = NtCreateDirectoryObject(&SessionObjectDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
- "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
- FreeDosDevicesProtection(&DosDevicesSd);
- return Status;
- }
-
- /* Next, create a directory for this session's DOS Devices */
- RtlInitUnicodeString(&SessionString, L"DosDevices");
- InitializeObjectAttributes(&ObjectAttributes,
- &SessionString,
- OBJ_CASE_INSENSITIVE,
- SessionObjectDirectory,
- &DosDevicesSd);
- Status = NtCreateDirectoryObject(&DosDevicesDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
- "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
- }
-
- /* Release the Security Descriptor */
- FreeDosDevicesProtection(&DosDevicesSd);
-
- /* Return */
- return Status;
-}
-
-/*++
- * @name CsrParseServerCommandLine
- *
- * The CsrParseServerCommandLine routine parses the CSRSS command-line in the
- * registry and performs operations for each entry found.
- *
- * @param ArgumentCount
- * Number of arguments on the command line.
- *
- * @param Arguments
- * Array of arguments.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-FASTCALL
-CsrParseServerCommandLine(IN ULONG ArgumentCount,
- IN PCHAR Arguments[])
-{
- NTSTATUS Status;
- PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString;
- ULONG i, DllIndex;
- ANSI_STRING AnsiString;
- OBJECT_ATTRIBUTES ObjectAttributes;
-
- /* Set the Defaults */
- CsrTotalPerProcessDataLength = 0;
- CsrObjectDirectory = NULL;
- CsrMaxApiRequestThreads = 16;
-
- /* Save our Session ID, and create a Directory for it */
- SessionId = NtCurrentPeb()->SessionId;
- Status = CsrCreateSessionObjectDirectory(SessionId);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
- Status);
-
- /* It's not fatal if the session ID isn't zero */
- if (SessionId) return Status;
- ASSERT(NT_SUCCESS(Status));
- }
-
- /* Loop through every argument */
- for (i = 1; i < ArgumentCount; i++)
- {
- /* Split Name and Value */
- ParameterName = Arguments[i];
- ParameterValue = NULL;
- ParameterValue = strchr(ParameterName, '=');
- if (ParameterValue) *ParameterValue++ = ANSI_NULL;
-
- /* Check for Object Directory */
- if (!_stricmp(ParameterName, "ObjectDirectory"))
- {
- /* Check if a session ID is specified */
- if (SessionId)
- {
- DPRINT1("Sessions not yet implemented\n");
- ASSERT(SessionId);
- }
-
- /* Initialize the directory name */
- RtlInitAnsiString(&AnsiString, ParameterValue);
- Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName,
- &AnsiString,
- TRUE);
- ASSERT(NT_SUCCESS(Status) || SessionId != 0);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Create it */
- InitializeObjectAttributes(&ObjectAttributes,
- &CsrDirectoryName,
- OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
- NULL,
- NULL);
- Status = NtCreateDirectoryObject(&CsrObjectDirectory,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Secure it */
- Status = CsrSetDirectorySecurity(CsrObjectDirectory);
- if (!NT_SUCCESS(Status)) return Status;
- }
- else if (!_stricmp(ParameterName, "SubSystemType"))
- {
- /* Ignored */
- }
- else if (!_stricmp(ParameterName, "MaxRequestThreads"))
- {
- Status = RtlCharToInteger(ParameterValue,
- 0,
- &CsrMaxApiRequestThreads);
- }
- else if (!_stricmp(ParameterName, "RequestThreads"))
- {
- /* Ignored */
- Status = STATUS_SUCCESS;
- }
- else if (!_stricmp(ParameterName, "ProfileControl"))
- {
- /* Ignored */
- }
- else if (!_stricmp(ParameterName, "SharedSection"))
- {
- /* Create the Section */
- Status = CsrSrvCreateSharedSection(ParameterValue);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
- ParameterName, ParameterValue, Status);
- return Status;
- }
-
- /* Load us */
- Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER);
- }
- else if (!_stricmp(ParameterName, "ServerDLL"))
- {
- /* Loop the command line */
- EntryPoint = NULL;
- Status = STATUS_INVALID_PARAMETER;
- ServerString = ParameterValue;
- while (*ServerString)
- {
- /* Check for the Entry Point */
- if ((*ServerString == ':') && (!EntryPoint))
- {
- /* Found it. Add a nullchar and save it */
- *ServerString++ = ANSI_NULL;
- EntryPoint = ServerString;
- }
-
- /* Check for the Dll Index */
- if (*ServerString++ == ',') break;
- }
-
- /* Did we find something to load? */
- if (!*ServerString)
- {
- DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
- ParameterValue, Status);
- return Status;
- }
-
- /* Convert it to a ULONG */
- Status = RtlCharToInteger(ServerString, 10, &DllIndex);
-
- /* Add a null char if it was valid */
- if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL;
-
- /* Load it */
- if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint);
-
- /* Hackito ergo sum */
- Status = STATUS_SUCCESS;
- if (strstr(ParameterValue, "basesrv"))
- {
- DPRINT1("Fake basesrv init\n");
- BasepFakeStaticServerData();
- }
-// else
-// {
-// Status = CsrLoadServerDll(ParameterValue, EntryPoint, 2);
-// }
- // Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
- ParameterValue, Status);
- return Status;
- }
- }
- else if (!_stricmp(ParameterName, "Windows"))
- {
- /* Ignored */
- }
- else
- {
- /* Invalid parameter on the command line */
- Status = STATUS_INVALID_PARAMETER;
- }
- }
-
- /* Return status */
- return Status;
-}
-
-/*++
- * @name CsrCreateLocalSystemSD
- *
- * The CsrCreateLocalSystemSD routine creates a Security Descriptor for
- * the local account with PORT_ALL_ACCESS.
- *
- * @param LocalSystemSd
- * Pointer to a pointer to the security descriptor to create.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
-{
- SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
- PSID SystemSid;
- ULONG Length;
- PSECURITY_DESCRIPTOR SystemSd;
- PACL Dacl;
- NTSTATUS Status;
-
- /* Initialize the System SID */
- RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
- SECURITY_LOCAL_SYSTEM_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &SystemSid);
-
- /* Get the length of the SID */
- Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
-
- /* Allocate a buffer for the Security Descriptor, with SID and DACL */
- SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
-
- /* Set the pointer to the DACL */
- Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
-
- /* Now create the SD itself */
- Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SystemSd);
- return Status;
- }
-
- /* Create the DACL for it */
- RtlCreateAcl(Dacl, Length, ACL_REVISION2);
-
- /* Create the ACE */
- Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SystemSd);
- return Status;
- }
-
- /* Clear the DACL in the SD */
- Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SystemSd);
- return Status;
- }
-
- /* Free the SID and return*/
- RtlFreeSid(SystemSid);
- *LocalSystemSd = SystemSd;
- return Status;
-}
-
-/*++
- * @name CsrSbApiPortInitialize
- *
- * The CsrSbApiPortInitialize routine initializes the LPC Port used for
- * communications with the Session Manager (SM) 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
-CsrSbApiPortInitialize(VOID)
-{
- ULONG Size;
- PSECURITY_DESCRIPTOR PortSd;
- OBJECT_ATTRIBUTES ObjectAttributes;
- NTSTATUS Status;
- HANDLE hRequestThread;
- CLIENT_ID ClientId;
-
- /* Calculate how much space we'll need for the Port Name */
- Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR);
-
- /* Create the buffer for it */
- CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
- if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY;
-
- /* Setup the rest of the empty string */
- CsrSbApiPortName.Length = 0;
- CsrSbApiPortName.MaximumLength = (USHORT)Size;
-
- /* Now append the full port name */
- RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName);
- RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP);
- RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME);
- if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName);
-
- /* Create Security Descriptor for this Port */
- Status = CsrCreateLocalSystemSD(&PortSd);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Initialize the Attributes */
- InitializeObjectAttributes(&ObjectAttributes,
- &CsrSbApiPortName,
- 0,
- NULL,
- PortSd);
-
- /* Create the Port Object */
- Status = NtCreatePort(&CsrSbApiPort,
- &ObjectAttributes,
- sizeof(SB_CONNECTION_INFO),
- sizeof(SB_API_MSG),
- 32 * sizeof(SB_API_MSG));
- if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd);
-
- if (NT_SUCCESS(Status))
- {
- /* Create the Thread to handle the API Requests */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- TRUE,
- 0,
- 0,
- 0,
- (PVOID)CsrSbApiRequestThread,
- NULL,
- &hRequestThread,
- &ClientId);
- if (NT_SUCCESS(Status))
- {
- /* Add it as a Static Server Thread */
- CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread,
- &ClientId,
- 0);
-
- /* Activate it */
- Status = NtResumeThread(hRequestThread, NULL);
- }
- }
-
- return Status;
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-/*++
- * @name CsrServerInitialization
- * @implemented NT4
- *
- * The CsrServerInitialization routine is the native (not Server) entrypoint
- * of this Server DLL. It serves as the entrypoint for csrss.
- *
- * @param ArgumentCount
- * Number of arguments on the command line.
- *
- * @param Arguments
- * Array of arguments from the command line.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrServerInitialization(IN ULONG ArgumentCount,
- IN PCHAR Arguments[])
-{
- NTSTATUS Status = STATUS_SUCCESS;
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
-
- /* Create the Init Event */
- Status = NtCreateEvent(&CsrInitializationEvent,
- EVENT_ALL_ACCESS,
- NULL,
- SynchronizationEvent,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Cache System Basic Information so we don't always request it */
- Status = NtQuerySystemInformation(SystemBasicInformation,
- &CsrNtSysInfo,
- sizeof(SYSTEM_BASIC_INFORMATION),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Save our Heap */
- CsrHeap = RtlGetProcessHeap();
-
- /* Set our Security Descriptor to protect the process */
- Status = CsrSetProcessSecurity();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Set up Session Support */
- Status = CsrInitializeNtSessionList();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Set up Process Support */
- Status = CsrInitializeProcessStructure();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Parse the command line */
- Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- Status = CsrApiRegisterDefinitions(NativeDefinitions);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrApiRegisterDefinitions", Status);
- }
-
- /* Now initialize our API Port */
- Status = CsrApiPortInitialize();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Initialize Win32csr */
- Status = CsrLoadServerDll("win32csr", "Win32CsrInitialization", 2);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrLoadServerDll", Status);
- }
-
- /* Initialize the API Port for SM communication */
- Status = CsrSbApiPortInitialize();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* We're all set! Connect to SM! */
- Status = SmConnectToSm(&CsrSbApiPortName,
- CsrSbApiPort,
- IMAGE_SUBSYSTEM_WINDOWS_GUI,
- &CsrSmApiPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Finito! Signal the event */
- Status = NtSetEvent(CsrInitializationEvent, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Close the event handle now */
- NtClose(CsrInitializationEvent);
-
- /* Have us handle Hard Errors */
- Status = NtSetDefaultHardErrorPort(CsrApiPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Return status */
- return Status;
-}
-
-/*++
- * @name CsrPopulateDosDevices
- * @unimplemented NT5.1
- *
- * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
- * to populate the Dos Devices Object Directory for the session.
- *
- * @param None.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrPopulateDosDevices(VOID)
-{
- DPRINT1("Deprecated API\n");
- return;
-}
-
-BOOL
-NTAPI
-DllMain(IN HANDLE hDll,
- IN DWORD dwReason,
- IN LPVOID lpReserved)
-{
- /* We don't do much */
- UNREFERENCED_PARAMETER(hDll);
- UNREFERENCED_PARAMETER(dwReason);
- UNREFERENCED_PARAMETER(lpReserved);
- return TRUE;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsystems/win32/csrss/csrsrv/procsup.c
- * PURPOSE: CSR Process Management
- * PROGRAMMERS: ReactOS Portable Systems Group
- * Alex Ionescu
- */
-
-/* INCLUDES *******************************************************************/
-
-#include <srv.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* GLOBALS ********************************************************************/
-
-RTL_CRITICAL_SECTION ProcessDataLock;
-PCSR_PROCESS CsrRootProcess = NULL;
-SECURITY_QUALITY_OF_SERVICE CsrSecurityQos =
-{
- sizeof(SECURITY_QUALITY_OF_SERVICE),
- SecurityImpersonation,
- SECURITY_STATIC_TRACKING,
- FALSE
-};
-ULONG CsrProcessSequenceCount = 5;
-extern ULONG CsrTotalPerProcessDataLength;
-
-/* FUNCTIONS ******************************************************************/
-
-VOID
-NTAPI
-CsrSetToNormalPriority(VOID)
-{
- KPRIORITY BasePriority = (8 + 1) + 4;
-
- /* Set the Priority */
- NtSetInformationProcess(NtCurrentProcess(),
- ProcessBasePriority,
- &BasePriority,
- sizeof(KPRIORITY));
-}
-
-VOID
-NTAPI
-CsrSetToShutdownPriority(VOID)
-{
- KPRIORITY SetBasePriority = (8 + 1) + 6;
- BOOLEAN Old;
-
- /* Get the shutdown privilege */
- if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
- TRUE,
- FALSE,
- &Old)))
- {
- /* Set the Priority */
- NtSetInformationProcess(NtCurrentProcess(),
- ProcessBasePriority,
- &SetBasePriority,
- sizeof(KPRIORITY));
- }
-}
-
-/*++
- * @name CsrGetProcessLuid
- * @implemented NT4
- *
- * Do nothing for 500ms.
- *
- * @param hProcess
- * Optional handle to the process whose LUID should be returned.
- *
- * @param Luid
- * Pointer to a LUID Pointer which will receive the CSR Process' LUID
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks If hProcess is not supplied, then the current thread's token will
- * be used. If that too is missing, then the current process' token
- * will be used.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
- PLUID Luid)
-{
- HANDLE hToken = NULL;
- NTSTATUS Status;
- ULONG Length;
- PTOKEN_STATISTICS TokenStats;
-
- /* Check if we have a handle to a CSR Process */
- if (!hProcess)
- {
- /* We don't, so try opening the Thread's Token */
- Status = NtOpenThreadToken(NtCurrentThread(),
- TOKEN_QUERY,
- FALSE,
- &hToken);
-
- /* Check for success */
- if (!NT_SUCCESS(Status))
- {
- /* If we got some other failure, then return and quit */
- if (Status != STATUS_NO_TOKEN) return Status;
-
- /* We don't have a Thread Token, use a Process Token */
- hProcess = NtCurrentProcess();
- hToken = NULL;
- }
- }
-
- /* Check if we have a token by now */
- if (!hToken)
- {
- /* No token yet, so open the Process Token */
- Status = NtOpenProcessToken(hProcess,
- TOKEN_QUERY,
- &hToken);
- if (!NT_SUCCESS(Status))
- {
- /* Still no token, return the error */
- return Status;
- }
- }
-
- /* Now get the size we'll need for the Token Information */
- Status = NtQueryInformationToken(hToken,
- TokenStatistics,
- NULL,
- 0,
- &Length);
-
- /* Allocate memory for the Token Info */
- if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length)))
- {
- /* Fail and close the token */
- NtClose(hToken);
- return STATUS_NO_MEMORY;
- }
-
- /* Now query the information */
- Status = NtQueryInformationToken(hToken,
- TokenStatistics,
- TokenStats,
- Length,
- &Length);
-
- /* Close the handle */
- NtClose(hToken);
-
- /* Check for success */
- if (NT_SUCCESS(Status))
- {
- /* Return the LUID */
- *Luid = TokenStats->AuthenticationId;
- }
-
- /* Free the query information */
- RtlFreeHeap(CsrHeap, 0, TokenStats);
-
- /* Return the Status */
- return Status;
-}
-
-/*++
- * @name CsrImpersonateClient
- * @implemented NT4
- *
- * The CsrImpersonateClient will impersonate the given CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to impersonate.
- *
- * @return TRUE if impersionation suceeded, false otherwise.
- *
- * @remarks Impersonation can be recursive.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrImpersonateClient(IN PCSR_THREAD CsrThread)
-{
- NTSTATUS Status;
- PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
-
- /* Use the current thread if none given */
- if (!CsrThread) CsrThread = CurrentThread;
-
- /* Still no thread, something is wrong */
- if (!CsrThread)
- {
- /* Failure */
- return FALSE;
- }
-
- /* Make the call */
- Status = NtImpersonateThread(NtCurrentThread(),
- CsrThread->ThreadHandle,
- &CsrSecurityQos);
-
- if (!NT_SUCCESS(Status))
- {
- /* Failure */
-/*
- DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status);
- if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint();
-*/
- return FALSE;
- }
-
- /* Increase the impersonation count for the current thread */
- if (CurrentThread) ++CurrentThread->ImpersonationCount;
-
- /* Return Success */
- return TRUE;
-}
-
-/*++
- * @name CsrRevertToSelf
- * @implemented NT4
- *
- * The CsrRevertToSelf routine will attempt to remove an active impersonation.
- *
- * @param None.
- *
- * @return TRUE if the reversion was succesful, false otherwise.
- *
- * @remarks Impersonation can be recursive; as such, the impersonation token
- * will only be deleted once the CSR Thread's impersonaton count
- * has reached zero.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrRevertToSelf(VOID)
-{
- NTSTATUS Status;
- PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
- HANDLE ImpersonationToken = NULL;
-
- /* Check if we have a Current Thread */
- if (CurrentThread)
- {
- /* Make sure impersonation is on */
- if (!CurrentThread->ImpersonationCount)
- {
- // DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n");
- return FALSE;
- }
- else if (--CurrentThread->ImpersonationCount > 0)
- {
- /* Success; impersonation count decreased but still not zero */
- return TRUE;
- }
- }
-
- /* Impersonation has been totally removed, revert to ourselves */
- Status = NtSetInformationThread(NtCurrentThread(),
- ThreadImpersonationToken,
- &ImpersonationToken,
- sizeof(HANDLE));
-
- /* Return TRUE or FALSE */
- return NT_SUCCESS(Status);
-}
-
-/*++
- * @name FindProcessForShutdown
- *
- * The FindProcessForShutdown routine returns a CSR Process which is ready
- * to be shutdown, and sets the appropriate shutdown flags for it.
- *
- * @param CallerLuid
- * Pointer to the LUID of the CSR Process calling this routine.
- *
- * @return Pointer to a CSR Process which is ready to be shutdown.
- *
- * @remarks None.
- *
- *--*/
-PCSR_PROCESS
-NTAPI
-FindProcessForShutdown(IN PLUID CallerLuid)
-{
- PCSR_PROCESS CsrProcess, ReturnCsrProcess = NULL;
- // PCSR_THREAD CsrThread;
- NTSTATUS Status;
- ULONG Level = 0;
- LUID ProcessLuid;
- LUID SystemLuid = SYSTEM_LUID;
- // BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE;
- PLIST_ENTRY NextEntry;
-
- /* Set the List Pointers */
- NextEntry = CsrRootProcess->ListLink.Flink;
- while (NextEntry != &CsrRootProcess->ListLink)
- {
- /* Get the process */
- CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
-
- /* Move to the next entry */
- NextEntry = NextEntry->Flink;
-
- /* Skip this process if it's already been processed */
- if (CsrProcess->Flags & CsrProcessSkipShutdown) continue;
-
- /* Get the LUID of this Process */
- Status = CsrGetProcessLuid(CsrProcess->ProcessHandle, &ProcessLuid);
-
- /* Check if we didn't get access to the LUID */
- if (Status == STATUS_ACCESS_DENIED)
- {
- /* FIXME:Check if we have any threads */
-/*
- if (CsrProcess->ThreadCount)
- {
- /\* Impersonate one of the threads and retry *\/
- CsrThread = CONTAINING_RECORD(CsrProcess->ThreadList.Flink,
- CSR_THREAD,
- Link);
- CsrImpersonateClient(CsrThread);
- Status = CsrGetProcessLuid(NULL, &ProcessLuid);
- CsrRevertToSelf();
- }
-*/
- }
-
- if (!NT_SUCCESS(Status))
- {
- /* We didn't have access, so skip it */
- CsrProcess->Flags |= CsrProcessSkipShutdown;
- continue;
- }
-
- /* Check if this is the System LUID */
- if ((/*IsSystemLuid =*/ RtlEqualLuid(&ProcessLuid, &SystemLuid)))
- {
- /* Mark this process */
- CsrProcess->ShutdownFlags |= CsrShutdownSystem;
- }
- else if (!(/*IsOurLuid =*/ RtlEqualLuid(&ProcessLuid, CallerLuid)))
- {
- /* Our LUID doesn't match with the caller's */
- CsrProcess->ShutdownFlags |= CsrShutdownOther;
- }
-
- /* Check if we're past the previous level */
- if (CsrProcess->ShutdownLevel > Level /* || !ReturnCsrProcess */)
- {
- /* Update the level */
- Level = CsrProcess->ShutdownLevel;
-
- /* Set the final process */
- ReturnCsrProcess = CsrProcess;
- }
- }
-
- /* Check if we found a process */
- if (ReturnCsrProcess)
- {
- /* Skip this one next time */
- ReturnCsrProcess->Flags |= CsrProcessSkipShutdown;
- }
-
- return ReturnCsrProcess;
-}
-
-/* This is really "CsrShutdownProcess", mostly */
-NTSTATUS
-WINAPI
-CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc,
- IN PVOID Context)
-{
- PVOID* RealContext = (PVOID*)Context;
- PLUID CallerLuid = RealContext[0];
- PCSR_PROCESS CsrProcess = NULL;
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- BOOLEAN FirstTry;
- PLIST_ENTRY NextEntry;
- ULONG Result = 0;
-
- /* Acquire process lock */
- CsrAcquireProcessLock();
-
- /* Get the list pointers */
- NextEntry = CsrRootProcess->ListLink.Flink;
- while (NextEntry != &CsrRootProcess->ListLink)
- {
- /* Get the Process */
- CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
-
- /* Remove the skip flag, set shutdown flags to 0*/
- CsrProcess->Flags &= ~CsrProcessSkipShutdown;
- CsrProcess->ShutdownFlags = 0;
-
- /* Move to the next */
- NextEntry = NextEntry->Flink;
- }
-
- /* Set shudown Priority */
- CsrSetToShutdownPriority();
-
- /* Loop all processes */
- //DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart);
-
- /* Start looping */
- while (TRUE)
- {
- /* Find the next process to shutdown */
- FirstTry = TRUE;
- if (!(CsrProcess = FindProcessForShutdown(CallerLuid)))
- {
- /* Done, quit */
- CsrReleaseProcessLock();
- Status = STATUS_SUCCESS;
- goto Quickie;
- }
-
-LoopAgain:
- /* Release the lock, make the callback, and acquire it back */
- //DPRINT1("Found process: %lx\n", CsrProcess->ClientId.UniqueProcess);
- CsrReleaseProcessLock();
- Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry));
- CsrAcquireProcessLock();
-
- /* Check the result */
- //DPRINT1("Result: %d\n", Result);
- if (Result == CsrShutdownCsrProcess)
- {
- /* The callback unlocked the process */
- break;
- }
- else if (Result == CsrShutdownNonCsrProcess)
- {
- /* A non-CSR process, the callback didn't touch it */
- //continue;
- }
- else if (Result == CsrShutdownCancelled)
- {
- /* Shutdown was cancelled, unlock and exit */
- CsrReleaseProcessLock();
- Status = STATUS_CANCELLED;
- goto Quickie;
- }
-
- /* No matches during the first try, so loop again */
- if (FirstTry && Result == CsrShutdownNonCsrProcess)
- {
- FirstTry = FALSE;
- goto LoopAgain;
- }
- }
-
-Quickie:
- /* Return to normal priority */
- CsrSetToNormalPriority();
- return Status;
-}
-
-/*++
- * @name CsrProcessRefcountZero
- *
- * The CsrProcessRefcountZero routine is executed when a CSR Process has lost
- * all its active references. It removes and de-allocates the CSR Process.
- *
- * @param CsrProcess
- * Pointer to the CSR Process that is to be deleted.
- *
- * @return None.
- *
- * @remarks Do not call this routine. It is reserved for the internal
- * thread management routines when a CSR Process has lost all
- * its references.
- *
- * This routine is called with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess)
-{
- ASSERT(ProcessStructureListLocked());
-
- /* Remove the Process from the list */
- CsrRemoveProcess(CsrProcess);
-
- /* Check if there's a session */
- if (CsrProcess->NtSession)
- {
- /* Dereference the Session */
- CsrDereferenceNtSession(CsrProcess->NtSession, 0);
- }
-
- /* Close the Client Port if there is one */
- if (CsrProcess->ClientPort) NtClose(CsrProcess->ClientPort);
-
- /* Close the process handle */
- NtClose(CsrProcess->ProcessHandle);
-
- /* Free the Proces Object */
- CsrDeallocateProcess(CsrProcess);
-}
-
-/*++
- * @name CsrLockedDereferenceProcess
- *
- * The CsrLockedDereferenceProcess dereferences a CSR Process while the
- * Process Lock is already being held.
- *
- * @param CsrProcess
- * Pointer to the CSR Process to be dereferenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
-{
- LONG LockCount;
-
- /* Decrease reference count */
- LockCount = --CsrProcess->ReferenceCount;
- ASSERT(LockCount >= 0);
- if (!LockCount)
- {
- /* Call the generic cleanup code */
- DPRINT1("Should kill process: %p\n", CsrProcess);
- CsrProcessRefcountZero(CsrProcess);
- CsrAcquireProcessLock();
- }
-}
-
-/*++
- * @name CsrDereferenceProcess
- * @implemented NT4
- *
- * The CsrDereferenceProcess routine removes a reference from a CSR Process.
- *
- * @param CsrThread
- * Pointer to the CSR Process to dereference.
- *
- * @return None.
- *
- * @remarks If the reference count has reached zero (ie: the CSR Process has
- * no more active references), it will be deleted.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess)
-{
- LONG LockCount;
-
- /* Acquire process lock */
- CsrAcquireProcessLock();
-
- /* Decrease reference count */
- LockCount = --CsrProcess->ReferenceCount;
- ASSERT(LockCount >= 0);
- if (!LockCount)
- {
- /* Call the generic cleanup code */
- CsrProcessRefcountZero(CsrProcess);
- }
- else
- {
- /* Just release the lock */
- CsrReleaseProcessLock();
- }
-}
-
-/*++
- * @name CsrDestroyProcess
- * @implemented NT4
- *
- * The CsrDestroyProcess routine destroys the CSR Process corresponding to
- * a given Client ID.
- *
- * @param Cid
- * Pointer to the Client ID Structure corresponding to the CSR
- * Process which is about to be destroyed.
- *
- * @param ExitStatus
- * Unused.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
- * if the CSR Process is already terminating.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDestroyProcess(IN PCLIENT_ID Cid,
- IN NTSTATUS ExitStatus)
-{
- PCSR_THREAD CsrThread;
- PCSR_PROCESS CsrProcess;
- CLIENT_ID ClientId = *Cid;
- PLIST_ENTRY NextEntry;
-
- /* Acquire lock */
- CsrAcquireProcessLock();
-
- /* Find the thread */
- CsrThread = CsrLocateThreadByClientId(&CsrProcess, &ClientId);
-
- /* Make sure we got one back, and that it's not already gone */
- if (!(CsrThread) || (CsrProcess->Flags & CsrProcessTerminating))
- {
- /* Release the lock and return failure */
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Set the terminated flag */
- CsrProcess->Flags |= CsrProcessTerminating;
-
- /* Get the List Pointers */
- NextEntry = CsrProcess->ThreadList.Flink;
- while (NextEntry != &CsrProcess->ThreadList)
- {
- /* Get the current thread entry */
- CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
-
- /* Make sure the thread isn't already dead */
- if (CsrThread->Flags & CsrThreadTerminated)
- {
- NextEntry = NextEntry->Flink;
- continue;
- }
-
- /* Set the Terminated flag */
- CsrThread->Flags |= CsrThreadTerminated;
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Do we have an active wait block? */
- if (CsrThread->WaitBlock)
- {
- /* Notify waiters of termination */
- CsrNotifyWaitBlock(CsrThread->WaitBlock,
- NULL,
- NULL,
- NULL,
- CsrProcessTerminating,
- TRUE);
- }
-
- /* Release the Wait Lock */
- CsrReleaseWaitLock();
-
- /* Dereference the thread */
- CsrLockedDereferenceThread(CsrThread);
- NextEntry = CsrProcess->ThreadList.Flink;
- }
-
- /* Release the Process Lock and return success */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrCreateProcess
- * @implemented NT4
- *
- * Do nothing for 500ms.
- *
- * @param ArgumentCount
- * Description of the parameter. Wrapped to more lines on ~70th
- * column.
- *
- * @param Arguments
- * Description of the parameter. Wrapped to more lines on ~70th
- * column.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateProcess(IN HANDLE hProcess,
- IN HANDLE hThread,
- IN PCLIENT_ID ClientId,
- IN PCSR_NT_SESSION NtSession,
- IN ULONG Flags,
- IN PCLIENT_ID DebugCid)
-{
- PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
- CLIENT_ID CurrentCid;
- PCSR_PROCESS CurrentProcess;
-// PVOID ProcessData;
-// ULONG i;
- PCSR_PROCESS CsrProcess;
- NTSTATUS Status;
- PCSR_THREAD CsrThread;
- KERNEL_USER_TIMES KernelTimes;
-
- /* Get the current CID and lock Processes */
- CurrentCid = CurrentThread->ClientId;
- CsrAcquireProcessLock();
-
- /* Get the current CSR Thread */
- CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
- if (!CurrentThread)
- {
- /* We've failed to locate the thread */
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Allocate a new Process Object */
- CsrProcess = CsrAllocateProcess();
- if (!CsrProcess)
- {
- /* Couldn't allocate Process */
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
-#if 0
- /* Inherit the Process Data */
- CurrentProcess = CurrentThread->Process;
- ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX];
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Check if the DLL is Loaded and has Per Process Data */
- if ((CsrLoadedServerDll[i]) && (CsrLoadedServerDll[i]->SizeOfProcessData))
- {
- /* Set the pointer */
- CsrProcess->ServerData[i] = ProcessData;
-
- /* Copy the Data */
- RtlMoveMemory(ProcessData,
- CurrentProcess->ServerData[i],
- CsrLoadedServerDll[i]->SizeOfProcessData);
-
- /* Update next data pointer */
- ProcessData = (PVOID)((ULONG_PTR)ProcessData +
- CsrLoadedServerDll[i]->SizeOfProcessData);
- }
- else
- {
- /* No data for this Server */
- CsrProcess->ServerData[i] = NULL;
- }
- }
-#endif
-
- /* Set the Exception port to us */
- Status = NtSetInformationProcess(hProcess,
- ProcessExceptionPort,
- &CsrApiPort,
- sizeof(HANDLE));
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* If Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
- if (!(Flags & CsrProcessCreateNewGroup))
- {
- /* Create new data */
- CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess);
- CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber;
- }
- else
- {
- /* Copy it from the current process */
- CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId;
- CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence;
- }
-
- /* Check if this is a console process */
- if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp;
-
- /* Mask out non-debug flags */
- Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags);
-
- /* Check if every process will be debugged */
- if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren))
- {
- /* Pass it on to the current process */
- CsrProcess->DebugFlags = CsrDebugProcessChildren;
- CsrProcess->DebugCid = CurrentProcess->DebugCid;
- }
-
- /* Check if Debugging was used on this process */
- if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid))
- {
- /* Save the debug flag used */
- CsrProcess->DebugFlags = Flags;
-
- /* Save the CID */
- CsrProcess->DebugCid = *DebugCid;
- }
-
- /* Check if we debugging is enabled */
- if (CsrProcess->DebugFlags)
- {
- /* Set the Debug Port to us */
- Status = NtSetInformationProcess(hProcess,
- ProcessDebugPort,
- &CsrApiPort,
- sizeof(HANDLE));
- ASSERT(NT_SUCCESS(Status));
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
- }
-
- /* Get the Thread Create Time */
- Status = NtQueryInformationThread(hThread,
- ThreadTimes,
- (PVOID)&KernelTimes,
- sizeof(KernelTimes),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Allocate a CSR Thread Structure */
- CsrThread = CsrAllocateThread(CsrProcess);
- if (!CsrThread)
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Save the data we have */
- CsrThread->CreateTime = KernelTimes.CreateTime;
- CsrThread->ClientId = *ClientId;
- CsrThread->ThreadHandle = hThread;
- ProtectHandle(hThread);
- CsrThread->Flags = 0;
-
- /* Insert the Thread into the Process */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Reference the session */
- CsrReferenceNtSession(NtSession);
- CsrProcess->NtSession = NtSession;
-
- /* Setup Process Data */
- CsrProcess->ClientId = *ClientId;
- CsrProcess->ProcessHandle = hProcess;
- CsrProcess->ShutdownLevel = 0x280;
-
- /* Set the Priority to Background */
- CsrSetBackgroundPriority(CsrProcess);
-
- /* Insert the Process */
- CsrInsertProcess(NULL, CurrentProcess, CsrProcess);
-
- /* Release lock and return */
- CsrReleaseProcessLock();
- return Status;
-}
-
-/*++
- * @name CsrUnlockProcess
- * @implemented NT4
- *
- * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation.
- *
- * @param CsrProcess
- * Pointer to a previously locked CSR Process.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks This routine must be called with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* Dereference the process */
- CsrLockedDereferenceProcess(CsrProcess);
-
- /* Release the lock and return */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSetBackgroundPriority
- * @implemented NT4
- *
- * The CsrSetBackgroundPriority routine sets the priority for the given CSR
- * Process as a Background priority.
- *
- * @param CsrProcess
- * Pointer to the CSR Process whose priority will be modified.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
-{
- PROCESS_PRIORITY_CLASS PriorityClass;
-
- /* Set the Foreground bit off */
- PriorityClass.Foreground = FALSE;
-
- /* Set the new Priority */
- NtSetInformationProcess(CsrProcess->ProcessHandle,
- ProcessPriorityClass,
- &PriorityClass,
- sizeof(PriorityClass));
-}
-
-/*++
- * @name CsrAllocateProcess
- * @implemented NT4
- *
- * The CsrAllocateProcess routine allocates a new CSR Process object.
- *
- * @return Pointer to the newly allocated CSR Process.
- *
- * @remarks None.
- *
- *--*/
-PCSR_PROCESS
-NTAPI
-CsrAllocateProcess(VOID)
-{
- PCSR_PROCESS CsrProcess;
- ULONG TotalSize;
-
- /* Calculate the amount of memory this should take */
- TotalSize = sizeof(CSR_PROCESS) +
- (CSR_SERVER_DLL_MAX * sizeof(PVOID)) +
- CsrTotalPerProcessDataLength;
-
- /* Allocate a Process */
- CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize);
- if (!CsrProcess) return NULL;
-
- /* Handle the Sequence Number and protect against overflow */
- CsrProcess->SequenceNumber = CsrProcessSequenceCount++;
- if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5;
-
- /* Increase the reference count */
- CsrProcess->ReferenceCount++;
-
- /* Initialize the Thread List */
- InitializeListHead(&CsrProcess->ThreadList);
-
- /* Return the Process */
- return CsrProcess;
-}
-
-/*++
- * @name CsrLockedReferenceProcess
- *
- * The CsrLockedReferenceProcess references a CSR Process while the
- * Process Lock is already being held.
- *
- * @param CsrProcess
- * Pointer to the CSR Process to be referenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* Increment the reference count */
- ++CsrProcess->ReferenceCount;
-}
-
-/*++
- * @name CsrInitializeProcessStructure
- * @implemented NT4
- *
- * The CsrInitializeProcessStructure routine sets up support for CSR Processes
- * and CSR Threads.
- *
- * @param None.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrInitializeProcessStructure(VOID)
-{
- NTSTATUS Status;
- ULONG i;
-
- /* Initialize the Lock */
- Status = RtlInitializeCriticalSection(&ProcessDataLock);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Set up the Root Process */
- CsrRootProcess = CsrAllocateProcess();
- if (!CsrRootProcess) return STATUS_NO_MEMORY;
-
- /* Set up the minimal information for it */
- InitializeListHead(&CsrRootProcess->ListLink);
- CsrRootProcess->ProcessHandle = (HANDLE)-1;
- CsrRootProcess->ClientId = NtCurrentTeb()->ClientId;
-
- /* Initialize the Thread Hash List */
- for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]);
-
- /* Initialize the Wait Lock */
- return RtlInitializeCriticalSection(&CsrWaitListsLock);
-}
-
-/*++
- * @name CsrDeallocateProcess
- *
- * The CsrDeallocateProcess frees the memory associated with a CSR Process.
- *
- * @param CsrProcess
- * Pointer to the CSR Process to be freed.
- *
- * @return None.
- *
- * @remarks Do not call this routine. It is reserved for the internal
- * thread management routines when a CSR Process has been cleanly
- * dereferenced and killed.
- *
- *--*/
-VOID
-NTAPI
-CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* Free the process object from the heap */
- RtlFreeHeap(CsrHeap, 0, CsrProcess);
-}
-
-/*++
- * @name CsrRemoveProcess
- *
- * The CsrRemoveProcess function undoes a CsrInsertProcess operation and
- * removes the CSR Process from the Process List and notifies Server DLLs
- * of this removal.
- *
- * @param CsrProcess
- * Pointer to the CSR Process to remove.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrRemoveProcess(IN PCSR_PROCESS CsrProcess)
-{
- PCSR_SERVER_DLL ServerDll;
- ULONG i;
- ASSERT(ProcessStructureListLocked());
-
- /* Remove us from the Process List */
- RemoveEntryList(&CsrProcess->ListLink);
-
- /* Release the lock */
- CsrReleaseProcessLock();
-
- /* Loop every Server DLL */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the Server DLL */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Check if it's valid and if it has a Disconnect Callback */
- if ((ServerDll) && (ServerDll->DisconnectCallback))
- {
- /* Call it */
- ServerDll->DisconnectCallback(CsrProcess);
- }
- }
-}
-
-/*++
- * @name CsrInsertProcess
- *
- * The CsrInsertProcess routine inserts a CSR Process into the Process List
- * and notifies Server DLLs of the creation of a new CSR Process.
- *
- * @param Parent
- * Optional pointer to the CSR Process creating this CSR Process.
- *
- * @param CurrentProcess
- * Optional pointer to the current CSR Process.
- *
- * @param CsrProcess
- * Pointer to the CSR Process which is to be inserted.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
- IN PCSR_PROCESS CurrentProcess OPTIONAL,
- IN PCSR_PROCESS CsrProcess)
-{
-#if 0
- PCSR_SERVER_DLL ServerDll;
- ULONG i;
-#endif
- ASSERT(ProcessStructureListLocked());
-
- /* Set the parent */
- CsrProcess->Parent = Parent;
-
- /* Insert it into the Root List */
- InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink);
-#if 0
- /* Notify the Server DLLs */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current Server DLL */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Make sure it's valid and that it has callback */
- if ((ServerDll) && (ServerDll->NewProcessCallback))
- {
- ServerDll->NewProcessCallback(CurrentProcess, CsrProcess);
- }
- }
-#endif
-}
-
-/*++
- * @name CsrLockProcessByClientId
- * @implemented NT4
- *
- * The CsrLockProcessByClientId routine locks the CSR Process corresponding
- * to the given Process ID and optionally returns it.
- *
- * @param Pid
- * Process ID corresponding to the CSR Process which will be locked.
- *
- * @param CsrProcess
- * Optional pointer to a CSR Process pointer which will hold the
- * CSR Process corresponding to the given Process ID.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks Locking a CSR Process is defined as acquiring an extra
- * reference to it and returning with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrLockProcessByClientId(IN HANDLE Pid,
- OUT PCSR_PROCESS *CsrProcess)
-{
- PLIST_ENTRY NextEntry;
- PCSR_PROCESS CurrentProcess = NULL;
- NTSTATUS Status;
-
- /* Acquire the lock */
- CsrAcquireProcessLock();
-
- /* Assume failure */
- ASSERT(CsrProcess != NULL);
- *CsrProcess = NULL;
-
- /* Setup the List Pointers */
- NextEntry = &CsrRootProcess->ListLink;
- do
- {
- /* Get the Process */
- CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
-
- /* Check for PID Match */
- if (CurrentProcess->ClientId.UniqueProcess == Pid)
- {
- Status = STATUS_SUCCESS;
- break;
- }
-
- /* Next entry */
- NextEntry = NextEntry->Flink;
- } while (NextEntry != &CsrRootProcess->ListLink);
-
- /* Check if we didn't find it in the list */
- if (!NT_SUCCESS(Status))
- {
- /* Nothing found, release the lock */
- CsrReleaseProcessLock();
- }
- else
- {
- /* Lock the found process and return it */
- CsrLockedReferenceProcess(CurrentProcess);
- *CsrProcess = CurrentProcess;
- }
-
- /* Return the result */
- return Status;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsystems/win32/csrss/csrsrv/server.c
- * PURPOSE: CSR Server DLL Server Functions
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-PCSR_API_ROUTINE CsrServerApiDispatchTable[5] =
-{
- CsrSrvClientConnect,
- CsrSrvUnusedFunction,
- CsrSrvUnusedFunction,
- CsrSrvIdentifyAlertableThread,
- CsrSrvSetPriorityClass
-};
-
-BOOLEAN CsrServerApiServerValidTable[5] =
-{
- TRUE,
- FALSE,
- TRUE,
- TRUE,
- TRUE
-};
-
-PCHAR CsrServerApiNameTable[5] =
-{
- "ClientConnect",
- "ThreadConnect",
- "ProfileControl",
- "IdentifyAlertableThread",
- "SetPriorityClass"
-};
-
-PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
-PVOID CsrSrvSharedSectionHeap;
-PVOID CsrSrvSharedSectionBase;
-PVOID *CsrSrvSharedStaticServerData;
-ULONG CsrSrvSharedSectionSize;
-HANDLE CsrSrvSharedSection;
-
-/* PRIVATE FUNCTIONS**********************************************************/
-
-/*++
- * @name CsrServerDllInitialization
- * @implemented NT4
- *
- * The CsrServerDllInitialization is the initialization routine for
- * the this Server DLL.
- *
- * @param LoadedServerDll
- * Pointer to the CSR Server DLL structure representing this Server DLL.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll)
-{
- /* Setup the DLL Object */
- LoadedServerDll->ApiBase = 0;
- LoadedServerDll->HighestApiSupported = CsrpMaxApiNumber;
- LoadedServerDll->DispatchTable = CsrServerApiDispatchTable;
- LoadedServerDll->ValidTable = CsrServerApiServerValidTable;
- LoadedServerDll->NameTable = CsrServerApiNameTable;
- LoadedServerDll->SizeOfProcessData = 0;
- LoadedServerDll->ConnectCallback = NULL;
- LoadedServerDll->DisconnectCallback = NULL;
-
- /* All done */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrLoadServerDll
- * @implemented NT4
- *
- * The CsrLoadServerDll routine loads a CSR Server DLL and calls its entrypoint
- *
- * @param DllString
- * Pointer to the CSR Server DLL to load and call.
- *
- * @param EntryPoint
- * Pointer to the name of the server's initialization function. If
- * this parameter is NULL, the default ServerDllInitialize will be
- * assumed.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrLoadServerDll(IN PCHAR DllString,
- IN PCHAR EntryPoint OPTIONAL,
- IN ULONG ServerId)
-{
- NTSTATUS Status;
- ANSI_STRING DllName;
- UNICODE_STRING TempString, ErrorString;
- ULONG_PTR Parameters[2];
- HANDLE hServerDll = NULL;
- ULONG Size;
- PCSR_SERVER_DLL ServerDll;
- STRING EntryPointString;
- PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure;
- ULONG Response;
-
- /* Check if it's beyond the maximum we support */
- if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES;
-
- /* Check if it's already been loaded */
- if (CsrLoadedServerDll[ServerId]) return STATUS_INVALID_PARAMETER;
-
- /* Convert the name to Unicode */
- ASSERT(DllString != NULL);
- RtlInitAnsiString(&DllName, DllString);
- Status = RtlAnsiStringToUnicodeString(&TempString, &DllName, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* If we are loading ourselves, don't actually load us */
- if (ServerId != CSR_SRV_SERVER)
- {
- /* Load the DLL */
- Status = LdrLoadDll(NULL, 0, &TempString, &hServerDll);
- if (!NT_SUCCESS(Status))
- {
- /* Setup error parameters */
- Parameters[0] = (ULONG_PTR)&TempString;
- Parameters[1] = (ULONG_PTR)&ErrorString;
- RtlInitUnicodeString(&ErrorString, L"Default Load Path");
-
- /* Send a hard error */
- NtRaiseHardError(Status,
- 2,
- 3,
- Parameters,
- OptionOk,
- &Response);
- }
-
- /* Get rid of the string */
- RtlFreeUnicodeString(&TempString);
- if (!NT_SUCCESS(Status)) return Status;
- }
-
- /* Allocate a CSR DLL Object */
- Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength;
- ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size);
- if (!ServerDll)
- {
- if (hServerDll) LdrUnloadDll(hServerDll);
- return STATUS_NO_MEMORY;
- }
-
- /* Set up the Object */
- ServerDll->Length = Size;
- ServerDll->SharedSection = CsrSrvSharedSectionHeap;
- ServerDll->Event = CsrInitializationEvent;
- ServerDll->Name.Length = DllName.Length;
- ServerDll->Name.MaximumLength = DllName.MaximumLength;
- ServerDll->Name.Buffer = (PCHAR)(ServerDll + 1);
- if (DllName.Length)
- {
- strncpy(ServerDll->Name.Buffer, DllName.Buffer, DllName.Length);
- }
- ServerDll->ServerId = ServerId;
- ServerDll->ServerHandle = hServerDll;
-
- /* Now get the entrypoint */
- if (hServerDll)
- {
- /* Initialize a string for the entrypoint, or use the default */
- RtlInitAnsiString(&EntryPointString,
- !(EntryPoint) ? "ServerDllInitialization" :
- EntryPoint);
-
- /* Get a pointer to it */
- Status = LdrGetProcedureAddress(hServerDll,
- &EntryPointString,
- 0,
- (PVOID)&ServerDllInitProcedure);
- }
- else
- {
- /* No handle, so we are loading ourselves */
- ServerDllInitProcedure = CsrServerDllInitialization;
- Status = STATUS_SUCCESS;
- }
-
- /* Check if we got the pointer, and call it */
- if (NT_SUCCESS(Status))
- {
- /* Get the result from the Server DLL */
- Status = ServerDllInitProcedure(ServerDll);
-
- /* Check for Success */
- if (NT_SUCCESS(Status))
- {
- /*
- * Add this Server's Per-Process Data Size to the total that each
- * process will need.
- */
- CsrTotalPerProcessDataLength += ServerDll->SizeOfProcessData;
-
- /* Save the pointer in our list */
- CsrLoadedServerDll[ServerDll->ServerId] = ServerDll;
-
- /* Does it use our generic heap? */
- if (ServerDll->SharedSection != CsrSrvSharedSectionHeap)
- {
- /* No, save the pointer to its shared section in our list */
- CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection;
- }
-
- /* ReactOS Specific hax */
- if (ServerDll->HighestApiSupported == 0xDEADBABE)
- {
- Status = CsrApiRegisterDefinitions((PVOID)ServerDll->DispatchTable);
- }
- }
- else
- {
- /* Use shared failure code */
- goto LoadFailed;
- }
- }
- else
- {
-LoadFailed:
- /* Server Init failed, unload it */
- if (hServerDll) LdrUnloadDll(hServerDll);
-
- /* Delete the Object */
- RtlFreeHeap(CsrHeap, 0, ServerDll);
- }
-
- /* Return to caller */
- return Status;
-}
-
-/*++
- * @name CsrSrvClientConnect
- *
- * The CsrSrvClientConnect CSR API handles a new connection to a server DLL.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message for this request.
- *
- * @param Reply
- * Optional reply to this request.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_INVALID_PARAMETER
- * or STATUS_TOO_MANY_NAMES in case of failure.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply OPTIONAL)
-{
- /* Hack */
- return STATUS_SUCCESS;
-#if 0
- NTSTATUS Status;
- PCSR_CLIENT_CONNECT ClientConnect;
- PCSR_SERVER_DLL ServerDll;
- PCSR_PROCESS CurrentProcess = ((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process;
-
- /* Load the Message, set default reply */
- ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect;
- *Reply = 0;
-
- /* Validate the ServerID */
- if (ClientConnect->ServerId >= CSR_SERVER_DLL_MAX)
- {
- return STATUS_TOO_MANY_NAMES;
- }
- else if (!CsrLoadedServerDll[ClientConnect->ServerId])
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Validate the Message Buffer */
- if (!(CsrValidateMessageBuffer(ApiMessage,
- ClientConnect->ConnectionInfo,
- ClientConnect->ConnectionInfoSize,
- 1)))
- {
- /* Fail due to buffer overflow or other invalid buffer */
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Load the Server DLL */
- ServerDll = CsrLoadedServerDll[ClientConnect->ServerId];
-
- /* Check if it has a Connect Callback */
- if (ServerDll->ConnectCallback)
- {
- /* Call the callback */
- Status = ServerDll->ConnectCallback(CurrentProcess,
- ClientConnect->ConnectionInfo,
- &ClientConnect->ConnectionInfoSize);
- }
- else
- {
- /* Assume success */
- Status = STATUS_SUCCESS;
- }
-
- /* Return status */
- return Status;
-#endif
-}
-
-/*++
- * @name CsrSrvCreateSharedSection
- *
- * The CsrSrvCreateSharedSection creates the Shared Section that all CSR Server
- * DLLs and Clients can use to share data.
- *
- * @param ParameterValue
- * Specially formatted string from our registry command-line which
- * specifies various arguments for the shared section.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
-{
- PCHAR SizeValue = ParameterValue;
- ULONG Size;
- NTSTATUS Status;
- LARGE_INTEGER SectionSize;
- ULONG ViewSize = 0;
- PPEB Peb = NtCurrentPeb();
-
- /* If there's no parameter, fail */
- if (!ParameterValue) return STATUS_INVALID_PARAMETER;
-
- /* Find the first comma, and null terminate */
- while (*SizeValue)
- {
- if (*SizeValue == ',')
- {
- *SizeValue++ = ANSI_NULL;
- break;
- }
- else
- {
- SizeValue++;
- }
- }
-
- /* Make sure it's valid */
- if (!*SizeValue) return STATUS_INVALID_PARAMETER;
-
- /* Convert it to an integer */
- Status = RtlCharToInteger(SizeValue, 0, &Size);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Multiply by 1024 entries and round to page size */
- CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize);
-
- /* Create the Secion */
- SectionSize.LowPart = CsrSrvSharedSectionSize;
- SectionSize.HighPart = 0;
- Status = NtCreateSection(&CsrSrvSharedSection,
- SECTION_ALL_ACCESS,
- NULL,
- &SectionSize,
- PAGE_EXECUTE_READWRITE,
- SEC_BASED | SEC_RESERVE,
- NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Map the section */
- Status = NtMapViewOfSection(CsrSrvSharedSection,
- NtCurrentProcess(),
- &CsrSrvSharedSectionBase,
- 0,
- 0,
- NULL,
- &ViewSize,
- ViewUnmap,
- MEM_TOP_DOWN,
- PAGE_EXECUTE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- NtClose(CsrSrvSharedSection);
- return Status;
- }
-
- /* FIXME: Write the value to registry */
-
- /* The Heap is the same place as the Base */
- CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase;
-
- /* Create the heap */
- if (!(RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_CLASS_7,
- CsrSrvSharedSectionHeap,
- CsrSrvSharedSectionSize,
- PAGE_SIZE,
- 0,
- 0)))
- {
- /* Failure, unmap section and return */
- NtUnmapViewOfSection(NtCurrentProcess(), CsrSrvSharedSectionBase);
- NtClose(CsrSrvSharedSection);
- return STATUS_NO_MEMORY;
- }
-
- /* Now allocate space from the heap for the Shared Data */
- CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap,
- 0,
- CSR_SERVER_DLL_MAX *
- sizeof(PVOID));
- if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY;
-
- /* Write the values to the PEB */
- Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase;
- Peb->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap;
- Peb->ReadOnlyStaticServerData = CsrSrvSharedStaticServerData;
-
- /* Return */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvAttachSharedSection
- *
- * The CsrSrvAttachSharedSection maps the CSR Shared Section into a new
- * CSR Process' address space, and returns the pointers to the section
- * through the Connection Info structure.
- *
- * @param CsrProcess
- * Pointer to the CSR Process that is attempting a connection.
- *
- * @param ConnectInfo
- * Pointer to the CSR Connection Info structure for the incoming
- * connection.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL,
- OUT PCSR_CONNECTION_INFO ConnectInfo)
-{
- NTSTATUS Status;
- ULONG ViewSize = 0;
-
- /* Check if we have a process */
- if (CsrProcess)
- {
- /* Map the section into this process */
- DPRINT("CSR Process Handle: %p. CSR Process: %p\n", CsrProcess->ProcessHandle, CsrProcess);
- Status = NtMapViewOfSection(CsrSrvSharedSection,
- CsrProcess->ProcessHandle,
- &CsrSrvSharedSectionBase,
- 0,
- 0,
- NULL,
- &ViewSize,
- ViewUnmap,
- SEC_NO_CHANGE,
- PAGE_EXECUTE_READ);
- if (!NT_SUCCESS(Status)) return Status;
- }
-
- /* Write the values in the Connection Info structure */
- ConnectInfo->SharedSectionBase = CsrSrvSharedSectionBase;
- ConnectInfo->SharedSectionHeap = CsrSrvSharedSectionHeap;
- ConnectInfo->SharedSectionData = CsrSrvSharedStaticServerData;
-
- /* Return success */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvIdentifyAlertableThread
- * @implemented NT4
- *
- * The CsrSrvIdentifyAlertableThread CSR API marks a CSR Thread as alertable.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message for this request.
- *
- * @param Reply
- * Pointer to an optional reply to this request.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvIdentifyAlertableThread(IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply)
-{
- PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread;
-
- /* Set the alertable flag */
- CsrThread->Flags |= CsrThreadAltertable;
-
- /* Return success */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvSetPriorityClass
- * @implemented NT4
- *
- * The CsrSrvSetPriorityClass CSR API is deprecated.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message for this request.
- *
- * @param Reply
- * Pointer to an optional reply to this request.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvSetPriorityClass(IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply)
-{
- /* Deprecated */
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSrvUnusedFunction
- * @implemented NT4
- *
- * The CsrSrvUnusedFunction CSR API is a stub for deprecated APIs.
- *
- * The CsrSrvSetPriorityClass CSR API is deprecated.
- *
- * @param ApiMessage
- * Pointer to the CSR API Message for this request.
- *
- * @param Reply
- * Pointer to an optional reply to this request.
- *
- * @return STATUS_INVALID_PARAMETER.
- *
- * @remarks CsrSrvSetPriorityClass does not use this stub because it must
- * return success.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSrvUnusedFunction(IN OUT PCSR_API_MESSAGE ApiMessage,
- IN OUT PULONG Reply)
-{
- /* Deprecated */
- return STATUS_INVALID_PARAMETER;
-}
-
-/* PUBLIC FUNCTIONS***********************************************************/
-
-/*++
- * @name CsrSetCallingSpooler
- * @implemented NT4
- *
- * the CsrSetCallingSpooler routine is deprecated.
- *
- * @param Reserved
- * Deprecated
- *
- * @return None.
- *
- * @remarks This routine was used in archaic versions of NT for Printer Drivers.
- *
- *--*/
-VOID
-NTAPI
-CsrSetCallingSpooler(ULONG Reserved)
-{
- /* Deprecated */
- return;
-}
-
-/*++
- * @name CsrUnhandledExceptionFilter
- * @implemented NT5
- *
- * The CsrUnhandledExceptionFilter routine handles all exceptions
- * within SEH-protected blocks.
- *
- * @param ExceptionPointers
- * System-defined Argument.
- *
- * @return EXCEPTION_EXECUTE_HANDLER.
- *
- * @remarks None.
- *
- *--*/
-LONG
-NTAPI
-CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
-{
- SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo;
- EXCEPTION_DISPOSITION Result = EXCEPTION_EXECUTE_HANDLER;
- BOOLEAN OldValue;
- NTSTATUS Status;
- UNICODE_STRING ErrorSource;
- ULONG_PTR ErrorParameters[4];
- ULONG Response;
-
- /* Check if a debugger is installed */
- Status = NtQuerySystemInformation(SystemKernelDebuggerInformation,
- &DebuggerInfo,
- sizeof(DebuggerInfo),
- NULL);
-
- /* Check if this is Session 0, and the Debugger is Enabled */
- if ((NtCurrentPeb()->SessionId) && (NT_SUCCESS(Status)) &&
- (DebuggerInfo.KernelDebuggerEnabled))
- {
- /* Call the Unhandled Exception Filter */
- if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) !=
- EXCEPTION_CONTINUE_EXECUTION)
- {
- /* We're going to raise an error. Get Shutdown Privilege first */
- Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
- TRUE,
- TRUE,
- &OldValue);
-
- /* Use the Process token if that failed */
- if (Status == STATUS_NO_TOKEN)
- {
- Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
- TRUE,
- FALSE,
- &OldValue);
- }
-
- /* Initialize our Name String */
- RtlInitUnicodeString(&ErrorSource, L"Windows SubSystem");
-
- /* Set the parameters */
- ErrorParameters[0] = (ULONG_PTR)&ErrorSource;
- ErrorParameters[1] = ExceptionInfo->ExceptionRecord->ExceptionCode;
- ErrorParameters[2] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
- ErrorParameters[3] = (ULONG_PTR)ExceptionInfo->ContextRecord;
-
- /* Bugcheck */
- Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
- 4,
- 1,
- ErrorParameters,
- OptionShutdownSystem,
- &Response);
- }
-
- /* Just terminate us */
- NtTerminateProcess(NtCurrentProcess(),
- ExceptionInfo->ExceptionRecord->ExceptionCode);
- }
-
- return Result;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsystems/win32/csrss/csrsrv/session.c
- * PURPOSE: CSR Server DLL Session Implementation
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-RTL_CRITICAL_SECTION CsrNtSessionLock;
-LIST_ENTRY CsrNtSessionList;
-
-PCHAR CsrServerSbApiName[5] =
-{
- "SbCreateSession",
- "SbTerminateSession",
- "SbForeignSessionComplete",
- "SbCreateProcess",
- "Unknown Csr Sb Api Number"
-};
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @name CsrInitializeNtSessionList
- *
- * The CsrInitializeNtSessionList routine sets up support for CSR Sessions.
- *
- * @param None
- *
- * @return None
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrInitializeNtSessionList(VOID)
-{
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
-
- /* Initialize the Session List */
- InitializeListHead(&CsrNtSessionList);
-
- /* Initialize the Session Lock */
- return RtlInitializeCriticalSection(&CsrNtSessionLock);
-}
-
-/*++
- * @name CsrAllocateNtSession
- *
- * The CsrAllocateNtSession routine allocates a new CSR NT Session.
- *
- * @param SessionId
- * Session ID of the CSR NT Session to allocate.
- *
- * @return Pointer to the newly allocated CSR NT Session.
- *
- * @remarks None.
- *
- *--*/
-PCSR_NT_SESSION
-NTAPI
-CsrAllocateNtSession(IN ULONG SessionId)
-{
- PCSR_NT_SESSION NtSession;
-
- /* Allocate an NT Session Object */
- NtSession = RtlAllocateHeap(CsrHeap, 0, sizeof(CSR_NT_SESSION));
- if (NtSession)
- {
- /* Setup the Session Object */
- NtSession->SessionId = SessionId;
- NtSession->ReferenceCount = 1;
-
- /* Insert it into the Session List */
- CsrAcquireNtSessionLock();
- InsertHeadList(&CsrNtSessionList, &NtSession->SessionLink);
- CsrReleaseNtSessionLock();
- }
- else
- {
- ASSERT(NtSession != NULL);
- }
-
- /* Return the Session (or NULL) */
- return NtSession;
-}
-
-/*++
- * @name CsrReferenceNtSession
- *
- * The CsrReferenceNtSession increases the reference count of a CSR NT Session.
- *
- * @param Session
- * Pointer to the CSR NT Session to reference.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrReferenceNtSession(IN PCSR_NT_SESSION Session)
-{
- /* Acquire the lock */
- CsrAcquireNtSessionLock();
-
- /* Sanity checks */
- ASSERT(!IsListEmpty(&Session->SessionLink));
- ASSERT(Session->SessionId != 0);
- ASSERT(Session->ReferenceCount != 0);
-
- /* Increase the reference count */
- Session->ReferenceCount++;
-
- /* Release the lock */
- CsrReleaseNtSessionLock();
-}
-
-/*++
- * @name CsrDereferenceNtSession
- *
- * The CsrDereferenceNtSession decreases the reference count of a
- * CSR NT Session.
- *
- * @param Session
- * Pointer to the CSR NT Session to reference.
- *
- * @param ExitStatus
- * If this is the last reference to the session, this argument
- * specifies the exit status.
- *
- * @return None.
- *
- * @remarks CsrDereferenceNtSession will complete the session if
- * the last reference to it has been closed.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceNtSession(IN PCSR_NT_SESSION Session,
- IN NTSTATUS ExitStatus)
-{
- /* Acquire the lock */
- CsrAcquireNtSessionLock();
-
- /* Sanity checks */
- ASSERT(!IsListEmpty(&Session->SessionLink));
- ASSERT(Session->SessionId != 0);
- ASSERT(Session->ReferenceCount != 0);
-
- /* Dereference the Session Object */
- if (!(--Session->ReferenceCount))
- {
- /* Remove it from the list */
- RemoveEntryList(&Session->SessionLink);
-
- /* Release the lock */
- CsrReleaseNtSessionLock();
-
- /* Tell SM that we're done here */
- SmSessionComplete(CsrSmApiPort, Session->SessionId, ExitStatus);
-
- /* Free the Session Object */
- RtlFreeHeap(CsrHeap, 0, Session);
- }
- else
- {
- /* Release the lock, the Session is still active */
- CsrReleaseNtSessionLock();
- }
-}
-
-/* SESSION MANAGER FUNCTIONS**************************************************/
-
-/*++
- * @name CsrSbCreateSession
- *
- * The CsrSbCreateSession API is called by the Session Manager whenever a new
- * session is created.
- *
- * @param ApiMessage
- * Pointer to the Session Manager API Message.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks The CsrSbCreateSession routine will initialize a new CSR NT
- * Session and allocate a new CSR Process for the subsystem process.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
-{
- PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
- HANDLE hProcess, hThread;
- PCSR_PROCESS CsrProcess;
- NTSTATUS Status;
- KERNEL_USER_TIMES KernelTimes;
- PCSR_THREAD CsrThread;
- //PVOID ProcessData;
- //ULONG i;
-
- /* Save the Process and Thread Handles */
- hProcess = CreateSession->ProcessInfo.ProcessHandle;
- hThread = CreateSession->ProcessInfo.ThreadHandle;
-
- /* Lock the Processes */
- CsrAcquireProcessLock();
-
- /* Allocate a new process */
- CsrProcess = CsrAllocateProcess();
- if (!CsrProcess)
- {
- /* Fail */
- ApiMessage->ReturnValue = STATUS_NO_MEMORY;
- CsrReleaseProcessLock();
- return TRUE;
- }
-
- /* Set the exception port */
- Status = NtSetInformationProcess(hProcess,
- ProcessExceptionPort,
- &CsrApiPort,
- sizeof(HANDLE));
-
- /* Check for success */
- if (!NT_SUCCESS(Status))
- {
- /* Fail the request */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
-
- /* Strange as it seems, NTSTATUSes are actually returned */
- return (BOOLEAN)STATUS_NO_MEMORY;
- }
-
- /* Get the Create Time */
- Status = NtQueryInformationThread(hThread,
- ThreadTimes,
- &KernelTimes,
- sizeof(KERNEL_USER_TIMES),
- NULL);
-
- /* Check for success */
- if (!NT_SUCCESS(Status))
- {
- /* Fail the request */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
-
- /* Strange as it seems, NTSTATUSes are actually returned */
- return (BOOLEAN)Status;
- }
-
- /* Allocate a new Thread */
- CsrThread = CsrAllocateThread(CsrProcess);
- if (!CsrThread)
- {
- /* Fail the request */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
-
- ApiMessage->ReturnValue = STATUS_NO_MEMORY;
- return TRUE;
- }
-
- /* Setup the Thread Object */
- CsrThread->CreateTime = KernelTimes.CreateTime;
- CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
- CsrThread->ThreadHandle = hThread;
- ProtectHandle(hThread);
- CsrThread->Flags = 0;
-
- /* Insert it into the Process List */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Setup Process Data */
- CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
- CsrProcess->ProcessHandle = hProcess;
- CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
-
- /* Set the Process Priority */
- CsrSetBackgroundPriority(CsrProcess);
-#if 0
- /* Get the first data location */
- ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
-
- /* Loop every DLL */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Check if the DLL is loaded and has Process Data */
- if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
- {
- /* Write the pointer to the data */
- CsrProcess->ServerData[i] = ProcessData;
-
- /* Move to the next data location */
- ProcessData = (PVOID)((ULONG_PTR)ProcessData +
- CsrLoadedServerDll[i]->SizeOfProcessData);
- }
- else
- {
- /* Nothing for this Process */
- CsrProcess->ServerData[i] = NULL;
- }
- }
-#else
- /* HACKZ: should go in BaseSrv part of CreateCallback done in Insert below */
- RtlInitializeCriticalSection(&CsrProcess->HandleTableLock);
-#endif
- /* Insert the Process */
- CsrInsertProcess(NULL, NULL, CsrProcess);
-
- /* Activate the Thread */
- ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);
-
- /* Release lock and return */
- CsrReleaseProcessLock();
- return TRUE;
-}
-
-/*++
- * @name CsrSbForeignSessionComplete
- *
- * The CsrSbForeignSessionComplete API is called by the Session Manager
- * whenever a foreign session is completed (ie: terminated).
- *
- * @param ApiMessage
- * Pointer to the Session Manager API Message.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks The CsrSbForeignSessionComplete API is not yet implemented.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage)
-{
- /* Deprecated/Unimplemented in NT */
- ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
- return TRUE;
-}
-
-/*++
- * @name CsrSbTerminateSession
- *
- * The CsrSbTerminateSession API is called by the Session Manager
- * whenever a foreign session should be destroyed.
- *
- * @param ApiMessage
- * Pointer to the Session Manager API Message.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks The CsrSbTerminateSession API is not yet implemented.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrSbTerminateSession(IN PSB_API_MSG ApiMessage)
-{
- ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
- return TRUE;
-}
-
-/*++
- * @name CsrSbCreateProcess
- *
- * The CsrSbCreateProcess API is called by the Session Manager
- * whenever a foreign session is created and a new process should be started.
- *
- * @param ApiMessage
- * Pointer to the Session Manager API Message.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks The CsrSbCreateProcess API is not yet implemented.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrSbCreateProcess(IN PSB_API_MSG ApiMessage)
-{
- ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
- return TRUE;
-}
-
-PSB_API_ROUTINE CsrServerSbApiDispatch[5] =
-{
- CsrSbCreateSession,
- CsrSbTerminateSession,
- CsrSbForeignSessionComplete,
- CsrSbCreateProcess,
- NULL
-};
-
-/*++
- * @name CsrSbApiHandleConnectionRequest
- *
- * The CsrSbApiHandleConnectionRequest routine handles and accepts a new
- * connection request to the SM API LPC Port.
- *
- * @param ApiMessage
- * Pointer to the incoming CSR API Message which contains the
- * connection request.
- *
- * @return STATUS_SUCCESS in case of success, or status code which caused
- * the routine to error.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message)
-{
- NTSTATUS Status;
- REMOTE_PORT_VIEW RemotePortView;
- HANDLE hPort;
-
- /* Set the Port View Structure Length */
- RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
-
- /* Accept the connection */
- Status = NtAcceptConnectPort(&hPort,
- NULL,
- (PPORT_MESSAGE)Message,
- TRUE,
- NULL,
- &RemotePortView);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status);
- return Status;
- }
-
- /* Complete the Connection */
- Status = NtCompleteConnectPort(hPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status);
- }
-
- /* Return status */
- return Status;
-}
-
-/*++
- * @name CsrSbApiRequestThread
- *
- * The CsrSbApiRequestThread routine handles incoming messages or connection
- * requests on the SM API LPC Port.
- *
- * @param Parameter
- * System-default user-defined parameter. Unused.
- *
- * @return The thread exit code, if the thread is terminated.
- *
- * @remarks Before listening on the port, the routine will first attempt
- * to connect to the user subsystem.
- *
- *--*/
-VOID
-NTAPI
-CsrSbApiRequestThread(IN PVOID Parameter)
-{
- NTSTATUS Status;
- SB_API_MSG ReceiveMsg;
- PSB_API_MSG ReplyMsg = NULL;
- PVOID PortContext;
- ULONG MessageType;
-
- /* Start the loop */
- while (TRUE)
- {
- /* Wait for a message to come in */
- Status = NtReplyWaitReceivePort(CsrSbApiPort,
- &PortContext,
- &ReplyMsg->h,
- &ReceiveMsg.h);
-
- /* Check if we didn't get success */
- if (Status != STATUS_SUCCESS)
- {
- /* If we only got a warning, keep going */
- if (NT_SUCCESS(Status)) continue;
-
- /* We failed big time, so start out fresh */
- ReplyMsg = NULL;
- DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
- continue;
- }
-
- /* Save the message type */
- MessageType = ReceiveMsg.h.u2.s2.Type;
-
- /* Check if this is a connection request */
- if (MessageType == LPC_CONNECTION_REQUEST)
- {
- /* Handle connection request */
- CsrSbApiHandleConnectionRequest(&ReceiveMsg);
-
- /* Start over */
- ReplyMsg = NULL;
- continue;
- }
-
- /* Check if the port died */
- if (MessageType == LPC_PORT_CLOSED)
- {
- /* Close the handle if we have one */
- if (PortContext) NtClose((HANDLE)PortContext);
-
- /* Client died, start over */
- ReplyMsg = NULL;
- continue;
- }
- else if (MessageType == LPC_CLIENT_DIED)
- {
- /* Client died, start over */
- ReplyMsg = NULL;
- continue;
- }
-
- /*
- * It's an API Message, check if it's within limits. If it's not, the
- * NT Behaviour is to set this to the Maximum API.
- */
- if (ReceiveMsg.ApiNumber > SbpMaxApiNumber)
- {
- ReceiveMsg.ApiNumber = SbpMaxApiNumber;
- DPRINT1("CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber);
- }
-
- /* Reuse the message */
- ReplyMsg = &ReceiveMsg;
-
- /* Make sure that the message is supported */
- if (ReceiveMsg.ApiNumber < SbpMaxApiNumber)
- {
- /* Call the API */
- if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg))
- {
- /* It failed, so return nothing */
- ReplyMsg = NULL;
- }
- }
- else
- {
- /* We don't support this API Number */
- ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED;
- }
- }
-}
-
-/* EOF */
+++ /dev/null
-#ifndef _SRV_H
-#define _SRV_H
-
-/* PSDK/NDK Headers */
-#define NTOS_MODE_USER
-#include <stdio.h>
-#define WIN32_NO_STATUS
-#include <windef.h>
-#include <winbase.h>
-#include <wincon.h>
-#include <winreg.h>
-#include <ndk/setypes.h>
-#include <ndk/sefuncs.h>
-#include <ndk/exfuncs.h>
-#include <ndk/cmfuncs.h>
-#include <ndk/obfuncs.h>
-#include <ndk/lpctypes.h>
-#include <ndk/lpcfuncs.h>
-#include <ndk/kefuncs.h>
-#include <ndk/dbgktypes.h>
-#include <ndk/mmfuncs.h>
-#include <ndk/umfuncs.h>
-
-/* CSR Header */
-//#include <csr/server.h>
-
-/* PSEH for SEH Support */
-#include <pseh/pseh2.h>
-
-/* Subsystem Manager Header */
-#include <sm/helper.h>
-#include <sm/smmsg.h>
-
-/* Internal CSRSS Headers */
-#include <api.h>
-#include <csrplugin.h>
-
-extern HANDLE CsrHeap;
-
-#define SM_REG_KEY \
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager"
-
-#define SESSION_ROOT L"\\Sessions"
-#define GLOBAL_ROOT L"\\GLOBAL??"
-#define SYMLINK_NAME L"SymbolicLink"
-#define SB_PORT_NAME L"SbAbiPort"
-#define CSR_PORT_NAME L"ApiPort"
-#define UNICODE_PATH_SEP L"\\"
-
-/* Defines */
-#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
-#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
-
-#endif
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsystems/win32/csrss/csrsrv/thredsup.c
- * PURPOSE: CSR Server DLL Thread Implementation
- * PROGRAMMERS: ReactOS Portable Systems Group
- * Alex Ionescu
- */
-
-/* INCLUDES *******************************************************************/
-
-#include <srv.h>
-
-#define NDEBUG
-#include <debug.h>
-
-#define CsrHashThread(t) \
- (HandleToUlong(t)&(256 - 1))
-
-/* GLOBALS ********************************************************************/
-
-LIST_ENTRY CsrThreadHashTable[256];
-
-/* FUNCTIONS ******************************************************************/
-
-/*++
- * @name ProtectHandle
- * @implemented NT5.2
- *
- * The ProtectHandle routine protects an object handle against closure.
- *
- * @return TRUE or FALSE.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-ProtectHandle(IN HANDLE ObjectHandle)
-{
- NTSTATUS Status;
- OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
-
- /* Query current state */
- Status = NtQueryObject(ObjectHandle,
- ObjectHandleFlagInformation,
- &HandleInfo,
- sizeof(HandleInfo),
- NULL);
- if (NT_SUCCESS(Status))
- {
- /* Enable protect from close */
- HandleInfo.ProtectFromClose = TRUE;
- Status = NtSetInformationObject(ObjectHandle,
- ObjectHandleFlagInformation,
- &HandleInfo,
- sizeof(HandleInfo));
- if (NT_SUCCESS(Status)) return TRUE;
- }
-
- /* We failed to or set the state */
- return FALSE;
-}
-
-/*++
- * @name UnProtectHandle
- * @implemented NT5.2
- *
- * The UnProtectHandle routine unprotects an object handle against closure.
- *
- * @return TRUE or FALSE.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-UnProtectHandle(IN HANDLE ObjectHandle)
-{
- NTSTATUS Status;
- OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
-
- /* Query current state */
- Status = NtQueryObject(ObjectHandle,
- ObjectHandleFlagInformation,
- &HandleInfo,
- sizeof(HandleInfo),
- NULL);
- if (NT_SUCCESS(Status))
- {
- /* Disable protect from close */
- HandleInfo.ProtectFromClose = FALSE;
- Status = NtSetInformationObject(ObjectHandle,
- ObjectHandleFlagInformation,
- &HandleInfo,
- sizeof(HandleInfo));
- if (NT_SUCCESS(Status)) return TRUE;
- }
-
- /* We failed to or set the state */
- return FALSE;
-}
-
-/*++
- * @name CsrAllocateThread
- *
- * The CsrAllocateThread routine allocates a new CSR Thread object.
- *
- * @param CsrProcess
- * Pointer to the CSR Process which will contain this CSR Thread.
- *
- * @return Pointer to the newly allocated CSR Thread.
- *
- * @remarks None.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrAllocateThread(IN PCSR_PROCESS CsrProcess)
-{
- PCSR_THREAD CsrThread;
-
- /* Allocate the structure */
- CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD));
- if (!CsrThread) return(NULL);
-
- /* Reference the Thread and Process */
- CsrThread->ReferenceCount++;
- CsrProcess->ReferenceCount++;
-
- /* Set the Parent Process */
- CsrThread->Process = CsrProcess;
-
- /* Return Thread */
- return CsrThread;
-}
-
-/*++
- * @name CsrLockedReferenceThread
- *
- * The CsrLockedReferenceThread references a CSR Thread while the
- * Process Lock is already being held.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to be referenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedReferenceThread(IN PCSR_THREAD CsrThread)
-{
- /* Increment the reference count */
- ++CsrThread->ReferenceCount;
-}
-
-/*++
- * @name CsrLocateThreadByClientId
- *
- * The CsrLocateThreadByClientId routine locates the CSR Thread and,
- * optionally, its parent CSR Process, corresponding to a Client ID.
- *
- * @param Process
- * Optional pointer to a CSR Process pointer which will contain
- * the CSR Thread's parent.
- *
- * @param ClientId
- * Pointer to a Client ID structure containing the Unique Thread ID
- * to look up.
- *
- * @return Pointer to the CSR Thread corresponding to this CID, or NULL if
- * none was found.
- *
- * @remarks None.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
- IN PCLIENT_ID ClientId)
-{
- ULONG i;
- PLIST_ENTRY ListHead, NextEntry;
- PCSR_THREAD FoundThread;
- // ASSERT(ProcessStructureListLocked());
-
- /* Hash the Thread */
- i = CsrHashThread(ClientId->UniqueThread);
-
- /* Set the list pointers */
- ListHead = &CsrThreadHashTable[i];
- NextEntry = ListHead->Flink;
-
- /* Star the loop */
- while (NextEntry != ListHead)
- {
- /* Get the thread */
- FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
-
- /* Compare the CID */
- if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread)
- {
- /* Match found, return the process */
- *Process = FoundThread->Process;
-
- /* Return thread too */
-// DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process);
- return FoundThread;
- }
-
- /* Next */
- NextEntry = NextEntry->Flink;
- }
-
- /* Nothing found */
- return NULL;
-}
-
-/*++
- * @name CsrLocateThreadInProcess
- *
- * The CsrLocateThreadInProcess routine locates the CSR Thread
- * corresponding to a Client ID inside a specific CSR Process.
- *
- * @param Process
- * Optional pointer to the CSR Process which contains the CSR Thread
- * that will be looked up.
- *
- * @param ClientId
- * Pointer to a Client ID structure containing the Unique Thread ID
- * to look up.
- *
- * @return Pointer to the CSR Thread corresponding to this CID, or NULL if
- * none was found.
- *
- * @remarks If the CsrProcess argument is NULL, the lookup will be done inside
- * CsrRootProcess.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL,
- IN PCLIENT_ID Cid)
-{
- PLIST_ENTRY ListHead, NextEntry;
- PCSR_THREAD FoundThread = NULL;
-
- /* Use the Root Process if none was specified */
- if (!CsrProcess) CsrProcess = CsrRootProcess;
-
- /* Save the List pointers */
-// DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount);
- ListHead = &CsrProcess->ThreadList;
- NextEntry = ListHead->Flink;
-
- /* Start the Loop */
- while (NextEntry != ListHead)
- {
- /* Get Thread Entry */
- FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
-
- /* Check for TID Match */
- if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break;
-
- /* Next entry */
- NextEntry = NextEntry->Flink;
- }
-
- /* Return what we found */
-// DPRINT1("Found: %p\n", FoundThread);
- return FoundThread;
-}
-
-/*++
- * @name CsrInsertThread
- *
- * The CsrInsertThread routine inserts a CSR Thread into its parent's
- * Thread List and into the Thread Hash Table.
- *
- * @param Process
- * Pointer to the CSR Process containing this CSR Thread.
- *
- * @param Thread
- * Pointer to the CSR Thread to be inserted.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrInsertThread(IN PCSR_PROCESS Process,
- IN PCSR_THREAD Thread)
-{
- ULONG i;
- // ASSERT(ProcessStructureListLocked());
-
- /* Insert it into the Regular List */
- InsertTailList(&Process->ThreadList, &Thread->Link);
-
- /* Increase Thread Count */
- Process->ThreadCount++;
-
- /* Hash the Thread */
- i = CsrHashThread(Thread->ClientId.UniqueThread);
-// DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i);
-
- /* Insert it there too */
- InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks);
-}
-
-/*++
- * @name CsrDeallocateThread
- *
- * The CsrDeallocateThread frees the memory associated with a CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to be freed.
- *
- * @return None.
- *
- * @remarks Do not call this routine. It is reserved for the internal
- * thread management routines when a CSR Thread has been cleanly
- * dereferenced and killed.
- *
- *--*/
-VOID
-NTAPI
-CsrDeallocateThread(IN PCSR_THREAD CsrThread)
-{
- /* Free the process object from the heap */
- // ASSERT(CsrThread->WaitBlock == NULL);
- RtlFreeHeap(CsrHeap, 0, CsrThread);
-}
-
-/*++
- * @name CsrRemoveThread
- *
- * The CsrRemoveThread function undoes a CsrInsertThread operation and
- * removes the CSR Thread from the the Hash Table and Thread List.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to remove.
- *
- * @return None.
- *
- * @remarks If this CSR Thread is the last one inside a CSR Process, the
- * parent will be dereferenced and the CsrProcessLastThreadTerminated
- * flag will be set.
- *
- * After executing this routine, the CSR Thread will have the
- * CsrThreadInTermination flag set.
- *
- *--*/
-VOID
-NTAPI
-CsrRemoveThread(IN PCSR_THREAD CsrThread)
-{
- ASSERT(ProcessStructureListLocked());
-
- /* Remove it from the List */
- RemoveEntryList(&CsrThread->Link);
-
- /* Decreate the thread count of the process */
- CsrThread->Process->ThreadCount--;
-
- /* Remove it from the Hash List as well */
- if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks);
-
- /* Check if this is the last Thread */
- if (!CsrThread->Process->ThreadCount)
- {
- /* Check if it's not already been marked for deletion */
- if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated))
- {
- /* Let everyone know this process is about to lose the thread */
- CsrThread->Process->Flags |= CsrProcessLastThreadTerminated;
-
- /* Reference the Process */
- CsrLockedDereferenceProcess(CsrThread->Process);
- }
- }
-
- /* Mark the thread for deletion */
- CsrThread->Flags |= CsrThreadInTermination;
-}
-
-/*++
- * @name CsrCreateRemoteThread
- * @implemented NT4
- *
- * The CsrCreateRemoteThread routine creates a CSR Thread object for
- * an NT Thread which is not part of the current NT Process.
- *
- * @param hThread
- * Handle to an existing NT Thread to which to associate this
- * CSR Thread.
- *
- * @param ClientId
- * Pointer to the Client ID structure of the NT Thread to associate
- * with this CSR Thread.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateRemoteThread(IN HANDLE hThread,
- IN PCLIENT_ID ClientId)
-{
- NTSTATUS Status;
- HANDLE ThreadHandle;
- PCSR_THREAD CsrThread;
- PCSR_PROCESS CsrProcess;
- KERNEL_USER_TIMES KernelTimes;
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
-
- /* Get the Thread Create Time */
- Status = NtQueryInformationThread(hThread,
- ThreadTimes,
- &KernelTimes,
- sizeof(KernelTimes),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to query thread times: %lx\n", Status);
- return Status;
- }
-
- /* Lock the Owner Process */
- Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, &CsrProcess);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("No known process for %lx\n", ClientId->UniqueProcess);
- return Status;
- }
-
- /* Make sure the thread didn't terminate */
- if (KernelTimes.ExitTime.QuadPart)
- {
- /* Unlock the process and return */
- CsrUnlockProcess(CsrProcess);
- DPRINT1("Dead thread: %I64x\n", KernelTimes.ExitTime.QuadPart);
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Allocate a CSR Thread Structure */
- CsrThread = CsrAllocateThread(CsrProcess);
- if (!CsrThread)
- {
- DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
- CsrUnlockProcess(CsrProcess);
- return STATUS_NO_MEMORY;
- }
-
- /* Duplicate the Thread Handle */
- Status = NtDuplicateObject(NtCurrentProcess(),
- hThread,
- NtCurrentProcess(),
- &ThreadHandle,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS);
- /* Allow failure */
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Thread duplication failed: %lx\n", Status);
- ThreadHandle = hThread;
- }
-
- /* Save the data we have */
- CsrThread->CreateTime = KernelTimes.CreateTime;
- CsrThread->ClientId = *ClientId;
- CsrThread->ThreadHandle = ThreadHandle;
- ProtectHandle(ThreadHandle);
- CsrThread->Flags = 0;
-
- /* Insert the Thread into the Process */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Release the lock and return */
- CsrUnlockProcess(CsrProcess);
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrThreadRefcountZero
- *
- * The CsrThreadRefcountZero routine is executed when a CSR Thread has lost
- * all its active references. It removes and de-allocates the CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread that is to be deleted.
- *
- * @return None.
- *
- * @remarks Do not call this routine. It is reserved for the internal
- * thread management routines when a CSR Thread has lost all
- * its references.
- *
- * This routine is called with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)
-{
- PCSR_PROCESS CsrProcess = CsrThread->Process;
- NTSTATUS Status;
- ASSERT(ProcessStructureListLocked());
-
- /* Remove this thread */
- CsrRemoveThread(CsrThread);
-
- /* Release the Process Lock */
- CsrReleaseProcessLock();
-
- /* Close the NT Thread Handle */
- if (CsrThread->ThreadHandle)
- {
- UnProtectHandle(CsrThread->ThreadHandle);
- Status = NtClose(CsrThread->ThreadHandle);
- ASSERT(NT_SUCCESS(Status));
- }
-
- /* De-allocate the CSR Thread Object */
- CsrDeallocateThread(CsrThread);
-
- /* Remove a reference from the process */
- CsrDereferenceProcess(CsrProcess);
-}
-
-/*++
- * @name CsrDestroyThread
- * @implemented NT4
- *
- * The CsrDestroyThread routine destroys the CSR Thread corresponding to
- * a given Thread ID.
- *
- * @param Cid
- * Pointer to the Client ID Structure corresponding to the CSR
- * Thread which is about to be destroyed.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
- * if the CSR Thread is already terminating.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDestroyThread(IN PCLIENT_ID Cid)
-{
- CLIENT_ID ClientId = *Cid;
- PCSR_THREAD CsrThread;
- PCSR_PROCESS CsrProcess;
-
- /* Acquire lock */
- CsrAcquireProcessLock();
-
- /* Find the thread */
- CsrThread = CsrLocateThreadByClientId(&CsrProcess,
- &ClientId);
-
- /* Make sure we got one back, and that it's not already gone */
- if (!CsrThread || CsrThread->Flags & CsrThreadTerminated)
- {
- /* Release the lock and return failure */
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Set the terminated flag */
- CsrThread->Flags |= CsrThreadTerminated;
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Do we have an active wait block? */
- if (CsrThread->WaitBlock)
- {
- /* Notify waiters of termination */
- CsrNotifyWaitBlock(CsrThread->WaitBlock,
- NULL,
- NULL,
- NULL,
- CsrProcessTerminating,
- TRUE);
- }
-
- /* Release the Wait Lock */
- CsrReleaseWaitLock();
-
- /* Dereference the thread */
- CsrLockedDereferenceThread(CsrThread);
-
- /* Release the Process Lock and return success */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrLockedDereferenceThread
- *
- * The CsrLockedDereferenceThread dereferences a CSR Thread while the
- * Process Lock is already being held.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to be dereferenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
-{
- LONG LockCount;
-
- /* Decrease reference count */
- LockCount = --CsrThread->ReferenceCount;
- ASSERT(LockCount >= 0);
- if (!LockCount)
- {
- /* Call the generic cleanup code */
- CsrThreadRefcountZero(CsrThread);
- CsrAcquireProcessLock();
- }
-}
-
-/*++
- * @name CsrCreateThread
- * @implemented NT4
- *
- * The CsrCreateThread routine creates a CSR Thread object for an NT Thread.
- *
- * @param CsrProcess
- * Pointer to the CSR Process which will contain the CSR Thread.
- *
- * @param hThread
- * Handle to an existing NT Thread to which to associate this
- * CSR Thread.
- *
- * @param ClientId
- * Pointer to the Client ID structure of the NT Thread to associate
- * with this CSR Thread.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateThread(IN PCSR_PROCESS CsrProcess,
- IN HANDLE hThread,
- IN PCLIENT_ID ClientId)
-{
- PCSR_THREAD CsrThread;
- PCSR_PROCESS CurrentProcess;
- PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
- CLIENT_ID CurrentCid;
- KERNEL_USER_TIMES KernelTimes;
-
- /* Get the current thread and CID */
- CurrentCid = CurrentThread->ClientId;
-
- /* Acquire the Process Lock */
- CsrAcquireProcessLock();
-
- /* Get the current Process and make sure the Thread is valid with this CID */
- CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
- &CurrentCid);
-
- /* Something is wrong if we get an empty thread back */
- if (!CurrentThread)
- {
- DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
- }
-
- /* Get the Thread Create Time */
- NtQueryInformationThread(hThread,
- ThreadTimes,
- (PVOID)&KernelTimes,
- sizeof(KernelTimes),
- NULL);
-
- /* Allocate a CSR Thread Structure */
- if (!(CsrThread = CsrAllocateThread(CsrProcess)))
- {
- DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Save the data we have */
- CsrThread->CreateTime = KernelTimes.CreateTime;
- CsrThread->ClientId = *ClientId;
- CsrThread->ThreadHandle = hThread;
- CsrThread->Flags = 0;
-
- /* Insert the Thread into the Process */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Release the lock and return */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrAddStaticServerThread
- * @implemented NT4
- *
- * The CsrAddStaticServerThread routine adds a new CSR Thread to the
- * CSR Server Process (CsrRootProcess).
- *
- * @param hThread
- * Handle to an existing NT Thread to which to associate this
- * CSR Thread.
- *
- * @param ClientId
- * Pointer to the Client ID structure of the NT Thread to associate
- * with this CSR Thread.
- *
- * @param ThreadFlags
- * Initial CSR Thread Flags to associate to this CSR Thread. Usually
- * CsrThreadIsServerThread.
- *
- * @return Pointer to the newly allocated CSR Thread.
- *
- * @remarks None.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrAddStaticServerThread(IN HANDLE hThread,
- IN PCLIENT_ID ClientId,
- IN ULONG ThreadFlags)
-{
- PCSR_THREAD CsrThread;
-
- /* Get the Lock */
- CsrAcquireProcessLock();
-
- /* Allocate the Server Thread */
- CsrThread = CsrAllocateThread(CsrRootProcess);
- if (CsrThread)
- {
- /* Setup the Object */
- CsrThread->ThreadHandle = hThread;
- ProtectHandle(hThread);
- CsrThread->ClientId = *ClientId;
- CsrThread->Flags = ThreadFlags;
-
- /* Insert it into the Thread List */
- InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link);
-
- /* Increment the thread count */
- CsrRootProcess->ThreadCount++;
- }
- else
- {
- DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread);
- }
-
- /* Release the Process Lock and return */
- CsrReleaseProcessLock();
- return CsrThread;
-}
-
-/*++
- * @name CsrDereferenceThread
- * @implemented NT4
- *
- * The CsrDereferenceThread routine removes a reference from a CSR Thread.
- *
- * @param CsrThread
- * Pointer to the CSR Thread to dereference.
- *
- * @return None.
- *
- * @remarks If the reference count has reached zero (ie: the CSR Thread has
- * no more active references), it will be deleted.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceThread(IN PCSR_THREAD CsrThread)
-{
- /* Acquire process lock */
- CsrAcquireProcessLock();
-
- /* Decrease reference count */
- ASSERT(CsrThread->ReferenceCount > 0);
- if (!(--CsrThread->ReferenceCount))
- {
- /* Call the generic cleanup code */
- CsrThreadRefcountZero(CsrThread);
- }
- else
- {
- /* Just release the lock */
- CsrReleaseProcessLock();
- }
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsystems/win32/csrss/csrsrv/wait.c
- * PURPOSE: CSR Server DLL Wait Implementation
- * PROGRAMMERS: Emanuele Aliberti
- * Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-RTL_CRITICAL_SECTION CsrWaitListsLock;
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @name CsrInitializeWait
- *
- * The CsrInitializeWait routine initializes a CSR Wait Object.
- *
- * @param WaitFunction
- * Pointer to the function that will handle this wait.
- *
- * @param CsrWaitThread
- * Pointer to the CSR Thread that will perform the wait.
- *
- * @param WaitApiMessage
- * Pointer to the CSR API Message associated to this wait.
- *
- * @param WaitContext
- * Pointer to a user-defined parameter associated to this wait.
- *
- * @param NewWaitBlock
- * Pointed to the initialized CSR Wait Block for this wait.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction,
- IN PCSR_THREAD CsrWaitThread,
- IN OUT PCSR_API_MESSAGE WaitApiMessage,
- IN PVOID WaitContext,
- OUT PCSR_WAIT_BLOCK *NewWaitBlock)
-{
- ULONG Size;
- PCSR_WAIT_BLOCK WaitBlock;
-
- /* Calculate the size of the wait block */
- Size = sizeof(CSR_WAIT_BLOCK) -
- sizeof(WaitBlock->WaitApiMessage) +
- WaitApiMessage->Header.u1.s1.TotalLength;
-
- /* Allocate the Wait Block */
- WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size);
- if (!WaitBlock)
- {
- /* Fail */
- WaitApiMessage->Status = STATUS_NO_MEMORY;
- return FALSE;
- }
-
- /* Initialize it */
- WaitBlock->Size = Size;
- WaitBlock->WaitThread = CsrWaitThread;
- WaitBlock->WaitContext = WaitContext;
- WaitBlock->WaitFunction = WaitFunction;
- WaitBlock->UserWaitList.Flink = NULL;
- WaitBlock->UserWaitList.Blink = NULL;
- WaitBlock->WaitList = WaitBlock->UserWaitList;
-
- /* Copy the message */
- RtlMoveMemory(&WaitBlock->WaitApiMessage,
- WaitApiMessage,
- WaitApiMessage->Header.u1.s1.TotalLength);
-
- /* Return the block */
- *NewWaitBlock = WaitBlock;
- return TRUE;
-}
-
-/*++
- * @name CsrNotifyWaitBlock
- *
- * The CsrNotifyWaitBlock routine calls the wait function for a registered
- * CSR Wait Block, and replies to the attached CSR API Message, if any.
- *
- * @param WaitBlock
- * Pointer to the CSR Wait Block
- *
- * @param WaitList
- * Pointer to the wait list for this wait.
- *
- * @param WaitArgument[1-2]
- * User-defined values to pass to the wait function.
- *
- * @param WaitFlags
- * Wait flags for this wait.
- *
- * @param DereferenceThread
- * Specifies whether the CSR Thread should be dereferenced at the
- * end of this wait.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks After a wait block is notified, the wait function becomes invalid.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
- IN PLIST_ENTRY WaitList,
- IN PVOID WaitArgument1,
- IN PVOID WaitArgument2,
- IN ULONG WaitFlags,
- IN BOOLEAN DereferenceThread)
-{
- /* Call the wait function */
- if ((WaitBlock->WaitFunction)(WaitList,
- WaitBlock->WaitThread,
- &WaitBlock->WaitApiMessage,
- WaitBlock->WaitContext,
- WaitArgument1,
- WaitArgument2,
- WaitFlags))
- {
- /* The wait is done, clear the block */
- WaitBlock->WaitThread->WaitBlock = NULL;
-
- /* Check for captured arguments */
- if (WaitBlock->WaitApiMessage.CsrCaptureData)
- {
- /* Release them */
- CsrReleaseCapturedArguments(&WaitBlock->WaitApiMessage);
- }
-
- /* Reply to the port */
- NtReplyPort(WaitBlock->WaitThread->Process->ClientPort,
- (PPORT_MESSAGE)&WaitBlock->WaitApiMessage);
-
- /* Check if we should dereference the thread */
- if (DereferenceThread)
- {
- /* Remove it from the Wait List */
- if (WaitBlock->WaitList.Flink)
- {
- RemoveEntryList(&WaitBlock->WaitList);
- }
-
- /* Remove it from the User Wait List */
- if (WaitBlock->UserWaitList.Flink)
- {
- RemoveEntryList(&WaitBlock->UserWaitList);
- }
-
- /* Dereference teh thread */
- CsrDereferenceThread(WaitBlock->WaitThread);
-
- /* Free the wait block */
- RtlFreeHeap(CsrHeap, 0, WaitBlock);
- }
- else
- {
- /* The wait is complete, but the thread is being kept alive */
- WaitBlock->WaitFunction = NULL;
- }
-
- /* The wait suceeded */
- return TRUE;
- }
-
- /* The wait failed */
- return FALSE;
-}
-
-/* PUBLIC FUNCTIONS **********************************************************/
-
-/*++
- * @name CsrCreateWait
- * @implemented NT4
- *
- * The CsrCreateWait routine creates a CSR Wait.
- *
- * @param WaitList
- * Pointer to a list entry of the waits to associate.
- *
- * @param WaitFunction
- * Pointer to the function that will handle this wait.
- *
- * @param CsrWaitThread
- * Pointer to the CSR Thread that will perform the wait.
- *
- * @param WaitApiMessage
- * Pointer to the CSR API Message associated to this wait.
- *
- * @param WaitContext
- * Pointer to a user-defined parameter associated to this wait.
- *
- * @param UserWaitList
- * Pointer to a list entry of the user-defined waits to associate.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrCreateWait(IN PLIST_ENTRY WaitList,
- IN CSR_WAIT_FUNCTION WaitFunction,
- IN PCSR_THREAD CsrWaitThread,
- IN OUT PCSR_API_MESSAGE WaitApiMessage,
- IN PVOID WaitContext,
- IN PLIST_ENTRY UserWaitList OPTIONAL)
-{
- PCSR_WAIT_BLOCK WaitBlock;
-
- /* Initialize the wait */
- if (!CsrInitializeWait(WaitFunction,
- CsrWaitThread,
- WaitApiMessage,
- WaitContext,
- &WaitBlock))
- {
- return FALSE;
- }
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Make sure the thread wasn't destroyed */
- if (CsrWaitThread->Flags & CsrThreadTerminated)
- {
- /* Fail the wait */
- RtlFreeHeap(CsrHeap, 0, WaitBlock);
- CsrReleaseWaitLock();
- return FALSE;
- }
-
- /* Insert the wait in the queue */
- InsertTailList(WaitList, &WaitBlock->WaitList);
-
- /* Insert the User Wait too, if one was given */
- if (UserWaitList) InsertTailList(UserWaitList, &WaitBlock->UserWaitList);
-
- /* Return */
- CsrReleaseWaitLock();
- return TRUE;
-}
-
-/*++
- * @name CsrDereferenceWait
- * @implemented NT4
- *
- * The CsrDereferenceWait routine dereferences a CSR Wait Block.
- *
- * @param WaitList
- * Pointer to the Wait List associated to the wait.
-
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceWait(IN PLIST_ENTRY WaitList)
-{
- PLIST_ENTRY NextEntry;
- PCSR_WAIT_BLOCK WaitBlock;
-
- /* Acquire the Process and Wait Locks */
- CsrAcquireProcessLock();
- CsrAcquireWaitLock();
-
- /* Set the list pointers */
- NextEntry = WaitList->Flink;
-
- /* Start the loop */
- while (NextEntry != WaitList)
- {
- /* Get the wait block */
- WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
-
- /* Move to the next entry */
- NextEntry = NextEntry->Flink;
-
- /* Check if there's no Wait Routine */
- if (!WaitBlock->WaitFunction)
- {
- /* Remove it from the Wait List */
- if (WaitBlock->WaitList.Flink)
- {
- RemoveEntryList(&WaitBlock->WaitList);
- }
-
- /* Remove it from the User Wait List */
- if (WaitBlock->UserWaitList.Flink)
- {
- RemoveEntryList(&WaitBlock->UserWaitList);
- }
-
- /* Dereference the thread waiting on it */
- CsrDereferenceThread(WaitBlock->WaitThread);
-
- /* Free the block */
- RtlFreeHeap(CsrHeap, 0, WaitBlock);
- }
- }
-
- /* Release the locks */
- CsrReleaseWaitLock();
- CsrReleaseProcessLock();
-}
-
-/*++
- * @name CsrMoveSatisfiedWait
- * @implemented NT5
- *
- * The CsrMoveSatisfiedWait routine moves satisfied waits from a wait list
- * to another list entry.
- *
- * @param NewEntry
- * Pointer to a list entry where the satisfied waits will be added.
- *
- * @param WaitList
- * Pointer to a list entry to analyze for satisfied waits.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry,
- IN PLIST_ENTRY WaitList)
-{
- PLIST_ENTRY NextEntry;
- PCSR_WAIT_BLOCK WaitBlock;
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Set the List pointers */
- NextEntry = WaitList->Flink;
-
- /* Start looping */
- while (NextEntry != WaitList)
- {
- /* Get the Wait block */
- WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
-
- /* Go to the next entry */
- NextEntry = NextEntry->Flink;
-
- /* Check if there is a Wait Callback */
- if (WaitBlock->WaitFunction)
- {
- /* Remove it from the Wait Block Queue */
- RemoveEntryList(&WaitBlock->WaitList);
-
- /* Insert the new entry */
- InsertTailList(&WaitBlock->WaitList, NewEntry);
- }
- }
-
- /* Release the wait lock */
- CsrReleaseWaitLock();
-}
-
-/*++
- * @name CsrNotifyWait
- * @implemented NT4
- *
- * The CsrNotifyWait notifies a CSR Wait Block.
- *
- * @param WaitList
- * Pointer to the list entry for this wait.
- *
- * @param WaitType
- * Type of the wait to perform, either WaitAny or WaitAll.
- *
- * @param WaitArgument[1-2]
- * User-defined argument to pass on to the wait function.
- *
- * @return TRUE in case of success, FALSE otherwise.
- *
- * @remarks None.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrNotifyWait(IN PLIST_ENTRY WaitList,
- IN ULONG WaitType,
- IN PVOID WaitArgument1,
- IN PVOID WaitArgument2)
-{
- PLIST_ENTRY NextEntry;
- PCSR_WAIT_BLOCK WaitBlock;
- BOOLEAN NotifySuccess = FALSE;
-
- /* Acquire the Wait Lock */
- CsrAcquireWaitLock();
-
- /* Set the List pointers */
- NextEntry = WaitList->Flink;
-
- /* Start looping */
- while (NextEntry != WaitList)
- {
- /* Get the Wait block */
- WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
-
- /* Go to the next entry */
- NextEntry = NextEntry->Flink;
-
- /* Check if there is a Wait Callback */
- if (WaitBlock->WaitFunction)
- {
- /* Notify the Waiter */
- NotifySuccess |= CsrNotifyWaitBlock(WaitBlock,
- WaitList,
- WaitArgument1,
- WaitArgument2,
- 0,
- FALSE);
-
- /* We've already done a wait, so leave unless this is a Wait All */
- if (WaitType != WaitAll) break;
- }
- }
-
- /* Release the wait lock and return */
- CsrReleaseWaitLock();
- return NotifySuccess;
-}
-
-/* EOF */
+++ /dev/null
-
-include_directories(
- BEFORE .
- ${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include
- ${REACTOS_SOURCE_DIR}/include/reactos/subsys
- ${REACTOS_SOURCE_DIR}/include/reactos/drivers
- ${REACTOS_SOURCE_DIR}/dll/cpl/console
- ${REACTOS_SOURCE_DIR}/win32ss/include)
-
-spec2def(win32csr.dll win32csr.spec)
-
-list(APPEND SOURCE
- alias.c
- coninput.c
- conoutput.c
- console.c
- desktopbg.c
- dllmain.c
- exitros.c
- file.c
- guiconsole.c
- handle.c
- harderror.c
- lineinput.c
- tuiconsole.c
- win32csr.rc
- ${CMAKE_CURRENT_BINARY_DIR}/win32csr.def)
-
-add_library(win32csr SHARED ${SOURCE})
-target_link_libraries(win32csr win32ksys ${PSEH_LIB})
-set_module_type(win32csr win32dll)
-add_importlibs(win32csr psapi msvcrt kernel32 ntdll csrsrv)
-add_delay_importlibs(win32csr user32 gdi32 advapi32)
-add_pch(win32csr w32csr.h)
-add_dependencies(win32csr bugcodes)
-add_cd_file(TARGET win32csr DESTINATION reactos/system32 FOR all)
+++ /dev/null
-/*
- * PROJECT: ReactOS CSRSS
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/win32/csrss/api/alias.c
- * PURPOSE: CSRSS alias support functions
- * COPYRIGHT: Christoph Wittich
- * Johannes Anderwald
- *
- */
-
-
-/* INCLUDES ******************************************************************/
-
-#define NDEBUG
-#include "w32csr.h"
-#include <debug.h>
-
-typedef struct tagALIAS_ENTRY
-{
- LPCWSTR lpSource;
- LPCWSTR lpTarget;
- struct tagALIAS_ENTRY * Next;
-} ALIAS_ENTRY, *PALIAS_ENTRY;
-
-
-typedef struct tagALIAS_HEADER
-{
- LPCWSTR lpExeName;
- PALIAS_ENTRY Data;
- struct tagALIAS_HEADER * Next;
-
-} ALIAS_HEADER, *PALIAS_HEADER;
-
-static
-PALIAS_HEADER
-IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName)
-{
- while(RootHeader)
- {
- INT diff = _wcsicmp(RootHeader->lpExeName, lpExeName);
- if (!diff)
- return RootHeader;
-
- if (diff > 0)
- break;
-
- RootHeader = RootHeader->Next;
- }
- return NULL;
-}
-
-PALIAS_HEADER
-IntCreateAliasHeader(LPCWSTR lpExeName)
-{
- PALIAS_HEADER Entry;
- UINT dwLength = wcslen(lpExeName) + 1;
-
- Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength);
- if (!Entry)
- return Entry;
-
- Entry->lpExeName = (LPCWSTR)(Entry + 1);
- wcscpy((WCHAR*)Entry->lpExeName, lpExeName);
- Entry->Data = NULL;
- Entry->Next = NULL;
- return Entry;
-}
-
-VOID
-IntInsertAliasHeader(PALIAS_HEADER * RootHeader, PALIAS_HEADER NewHeader)
-{
- PALIAS_HEADER CurrentHeader;
- PALIAS_HEADER *LastLink = RootHeader;
-
- while ((CurrentHeader = *LastLink) != NULL)
- {
- INT Diff = _wcsicmp(NewHeader->lpExeName, CurrentHeader->lpExeName);
- if (Diff < 0)
- {
- break;
- }
- LastLink = &CurrentHeader->Next;
- }
-
- *LastLink = NewHeader;
- NewHeader->Next = CurrentHeader;
-}
-
-PALIAS_ENTRY
-IntGetAliasEntry(PALIAS_HEADER Header, LPCWSTR lpSrcName)
-{
- PALIAS_ENTRY RootHeader;
-
- if (Header == NULL)
- return NULL;
-
- RootHeader = Header->Data;
- while(RootHeader)
- {
- INT diff;
- DPRINT("IntGetAliasEntry>lpSource %S\n", RootHeader->lpSource);
- diff = _wcsicmp(RootHeader->lpSource, lpSrcName);
- if (!diff)
- return RootHeader;
-
- if (diff > 0)
- break;
-
- RootHeader = RootHeader->Next;
- }
- return NULL;
-}
-
-
-VOID
-IntInsertAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY NewEntry)
-{
- PALIAS_ENTRY CurrentEntry;
- PALIAS_ENTRY *LastLink = &Header->Data;
-
- while ((CurrentEntry = *LastLink) != NULL)
- {
- INT Diff = _wcsicmp(NewEntry->lpSource, CurrentEntry->lpSource);
- if (Diff < 0)
- {
- break;
- }
- LastLink = &CurrentEntry->Next;
- }
-
- *LastLink = NewEntry;
- NewEntry->Next = CurrentEntry;
-}
-
-PALIAS_ENTRY
-IntCreateAliasEntry(LPCWSTR lpSource, LPCWSTR lpTarget)
-{
- UINT dwSource;
- UINT dwTarget;
- PALIAS_ENTRY Entry;
-
- dwSource = wcslen(lpSource) + 1;
- dwTarget = wcslen(lpTarget) + 1;
-
- Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget));
- if (!Entry)
- return Entry;
-
- Entry->lpSource = (LPCWSTR)(Entry + 1);
- wcscpy((LPWSTR)Entry->lpSource, lpSource);
- Entry->lpTarget = Entry->lpSource + dwSource;
- wcscpy((LPWSTR)Entry->lpTarget, lpTarget);
- Entry->Next = NULL;
-
- return Entry;
-}
-
-UINT
-IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader)
-{
- UINT length = 0;
-
- while(RootHeader)
- {
- length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR);
- RootHeader = RootHeader->Next;
- }
- if (length)
- length += sizeof(WCHAR); // last entry entry is terminated with 2 zero bytes
-
- return length;
-}
-
-UINT
-IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT TargetBufferSize)
-{
- UINT Offset = 0;
- UINT Length;
-
- TargetBufferSize /= sizeof(WCHAR);
- while(RootHeader)
- {
- Length = wcslen(RootHeader->lpExeName) + 1;
- if (TargetBufferSize > Offset + Length)
- {
- wcscpy(&TargetBuffer[Offset], RootHeader->lpExeName);
- Offset += Length;
- }
- else
- {
- break;
- }
- RootHeader = RootHeader->Next;
- }
- Length = min(Offset+1, TargetBufferSize);
- TargetBuffer[Length] = L'\0';
- return Length * sizeof(WCHAR);
-}
-
-UINT
-IntGetAllConsoleAliasesLength(PALIAS_HEADER Header)
-{
- UINT Length = 0;
- PALIAS_ENTRY CurEntry = Header->Data;
-
- while(CurEntry)
- {
- Length += wcslen(CurEntry->lpSource);
- Length += wcslen(CurEntry->lpTarget);
- Length += 2; // zero byte and '='
- CurEntry = CurEntry->Next;
- }
-
- if (Length)
- {
- return (Length+1) * sizeof(WCHAR);
- }
- return 0;
-}
-UINT
-IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBufferLength)
-{
- PALIAS_ENTRY CurEntry = Header->Data;
- UINT Offset = 0;
- UINT SrcLength, TargetLength;
-
- TargetBufferLength /= sizeof(WCHAR);
- while(CurEntry)
- {
- SrcLength = wcslen(CurEntry->lpSource) + 1;
- TargetLength = wcslen(CurEntry->lpTarget) + 1;
- if (Offset + TargetLength + SrcLength >= TargetBufferLength)
- break;
-
- wcscpy(&TargetBuffer[Offset], CurEntry->lpSource);
- Offset += SrcLength;
- TargetBuffer[Offset] = L'=';
- wcscpy(&TargetBuffer[Offset], CurEntry->lpTarget);
- Offset += TargetLength;
-
- CurEntry = CurEntry->Next;
- }
- TargetBuffer[Offset] = L'\0';
- return Offset * sizeof(WCHAR);
-}
-VOID
-IntDeleteAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY Entry)
-{
- PALIAS_ENTRY *LastLink = &Header->Data;
- PALIAS_ENTRY CurEntry;
-
- while ((CurEntry = *LastLink) != NULL)
- {
- if (CurEntry == Entry)
- {
- *LastLink = Entry->Next;
- RtlFreeHeap(Win32CsrApiHeap, 0, Entry);
- return;
- }
- LastLink = &CurEntry->Next;
- }
-}
-VOID
-IntDeleteAllAliases(PALIAS_HEADER RootHeader)
-{
- PALIAS_HEADER Header, NextHeader;
- PALIAS_ENTRY Entry, NextEntry;
- for (Header = RootHeader; Header; Header = NextHeader)
- {
- NextHeader = Header->Next;
- for (Entry = Header->Data; Entry; Entry = NextEntry)
- {
- NextEntry = Entry->Next;
- RtlFreeHeap(Win32CsrApiHeap, 0, Entry);
- }
- RtlFreeHeap(Win32CsrApiHeap, 0, Header);
- }
-}
-
-CSR_API(CsrAddConsoleAlias)
-{
- PCSRSS_CONSOLE Console;
- PALIAS_HEADER Header;
- PALIAS_ENTRY Entry;
- WCHAR * lpExeName;
- WCHAR * lpSource;
- WCHAR * lpTarget;
- //ULONG TotalLength;
- //WCHAR * Ptr;
-
- //TotalLength = Request->Data.AddConsoleAlias.SourceLength + Request->Data.AddConsoleAlias.ExeLength + Request->Data.AddConsoleAlias.TargetLength;
- //Ptr = (WCHAR*)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
-
- lpSource = (WCHAR*)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
- lpExeName = (WCHAR*)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE) + Request->Data.AddConsoleAlias.SourceLength * sizeof(WCHAR));
- lpTarget = (Request->Data.AddConsoleAlias.TargetLength != 0 ? lpExeName + Request->Data.AddConsoleAlias.ExeLength : NULL);
-
- DPRINT("CsrAddConsoleAlias entered Request %p lpSource %p lpExeName %p lpTarget %p\n", Request, lpSource, lpExeName, lpTarget);
-
- if (lpExeName == NULL || lpSource == NULL)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (!NT_SUCCESS(Request->Status))
- {
- return Request->Status;
- }
-
- Header = IntFindAliasHeader(Console->Aliases, lpExeName);
- if (!Header && lpTarget != NULL)
- {
- Header = IntCreateAliasHeader(lpExeName);
- if (!Header)
- {
- ConioUnlockConsole(Console);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- IntInsertAliasHeader(&Console->Aliases, Header);
- }
-
- if (lpTarget == NULL) // delete the entry
- {
- Entry = IntGetAliasEntry(Header, lpSource);
- if (Entry)
- {
- IntDeleteAliasEntry(Header, Entry);
- Request->Status = STATUS_SUCCESS;
- }
- else
- {
- Request->Status = STATUS_INVALID_PARAMETER;
- }
- ConioUnlockConsole(Console);
- return Request->Status;
- }
-
- Entry = IntCreateAliasEntry(lpSource, lpTarget);
-
- if (!Entry)
- {
- ConioUnlockConsole(Console);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- IntInsertAliasEntry(Header, Entry);
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrGetConsoleAlias)
-{
- PCSRSS_CONSOLE Console;
- PALIAS_HEADER Header;
- PALIAS_ENTRY Entry;
- UINT Length;
- WCHAR * lpExeName;
- WCHAR * lpSource;
- WCHAR * lpTarget;
-
- lpSource = (LPWSTR)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
- lpExeName = lpSource + Request->Data.GetConsoleAlias.SourceLength;
- lpTarget = Request->Data.GetConsoleAlias.TargetBuffer;
-
-
- DPRINT("CsrGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n",
- lpExeName, lpSource, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength);
-
- if (Request->Data.GetConsoleAlias.ExeLength == 0 || lpTarget == NULL ||
- Request->Data.GetConsoleAlias.TargetBufferLength == 0 || Request->Data.GetConsoleAlias.SourceLength == 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (!NT_SUCCESS(Request->Status))
- {
- return Request->Status;
- }
-
- Header = IntFindAliasHeader(Console->Aliases, lpExeName);
- if (!Header)
- {
- ConioUnlockConsole(Console);
- return STATUS_INVALID_PARAMETER;
- }
-
- Entry = IntGetAliasEntry(Header, lpSource);
- if (!Entry)
- {
- ConioUnlockConsole(Console);
- return STATUS_INVALID_PARAMETER;
- }
-
- Length = (wcslen(Entry->lpTarget)+1) * sizeof(WCHAR);
- if (Length > Request->Data.GetConsoleAlias.TargetBufferLength)
- {
- ConioUnlockConsole(Console);
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- if (!Win32CsrValidateBuffer(ProcessData, lpTarget,
- Request->Data.GetConsoleAlias.TargetBufferLength, 1))
- {
- ConioUnlockConsole(Console);
- return STATUS_ACCESS_VIOLATION;
- }
-
- wcscpy(lpTarget, Entry->lpTarget);
- Request->Data.GetConsoleAlias.BytesWritten = Length;
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrGetAllConsoleAliases)
-{
- PCSRSS_CONSOLE Console;
- ULONG BytesWritten;
- PALIAS_HEADER Header;
-
- if (Request->Data.GetAllConsoleAlias.lpExeName == NULL)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (!NT_SUCCESS(Request->Status))
- {
- return Request->Status;
- }
-
- Header = IntFindAliasHeader(Console->Aliases, Request->Data.GetAllConsoleAlias.lpExeName);
- if (!Header)
- {
- ConioUnlockConsole(Console);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (IntGetAllConsoleAliasesLength(Header) > Request->Data.GetAllConsoleAlias.AliasBufferLength)
- {
- ConioUnlockConsole(Console);
- return STATUS_BUFFER_OVERFLOW;
- }
-
- if (!Win32CsrValidateBuffer(ProcessData,
- Request->Data.GetAllConsoleAlias.AliasBuffer,
- Request->Data.GetAllConsoleAlias.AliasBufferLength,
- 1))
- {
- ConioUnlockConsole(Console);
- return STATUS_ACCESS_VIOLATION;
- }
-
- BytesWritten = IntGetAllConsoleAliases(Header,
- Request->Data.GetAllConsoleAlias.AliasBuffer,
- Request->Data.GetAllConsoleAlias.AliasBufferLength);
-
- Request->Data.GetAllConsoleAlias.BytesWritten = BytesWritten;
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrGetAllConsoleAliasesLength)
-{
- PCSRSS_CONSOLE Console;
- PALIAS_HEADER Header;
- UINT Length;
-
- if (Request->Data.GetAllConsoleAliasesLength.lpExeName == NULL)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (!NT_SUCCESS(Request->Status))
- {
- return Request->Status;
- }
-
- Header = IntFindAliasHeader(Console->Aliases, Request->Data.GetAllConsoleAliasesLength.lpExeName);
- if (!Header)
- {
- ConioUnlockConsole(Console);
- return STATUS_INVALID_PARAMETER;
- }
-
- Length = IntGetAllConsoleAliasesLength(Header);
- Request->Data.GetAllConsoleAliasesLength.Length = Length;
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrGetConsoleAliasesExes)
-{
- PCSRSS_CONSOLE Console;
- UINT BytesWritten;
- UINT ExesLength;
-
- DPRINT("CsrGetConsoleAliasesExes entered\n");
-
- Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (!NT_SUCCESS(Request->Status))
- {
- return Request->Status;
- }
-
- ExesLength = IntGetConsoleAliasesExesLength(Console->Aliases);
-
- if (ExesLength > Request->Data.GetConsoleAliasesExes.Length)
- {
- ConioUnlockConsole(Console);
- return STATUS_BUFFER_OVERFLOW;
- }
-
- if (Request->Data.GetConsoleAliasesExes.ExeNames == NULL)
- {
- ConioUnlockConsole(Console);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (!Win32CsrValidateBuffer(ProcessData,
- Request->Data.GetConsoleAliasesExes.ExeNames,
- Request->Data.GetConsoleAliasesExes.Length,
- 1))
- {
- ConioUnlockConsole(Console);
- return STATUS_ACCESS_VIOLATION;
- }
-
- BytesWritten = IntGetConsoleAliasesExes(Console->Aliases,
- Request->Data.GetConsoleAliasesExes.ExeNames,
- Request->Data.GetConsoleAliasesExes.Length);
-
- Request->Data.GetConsoleAliasesExes.BytesWritten = BytesWritten;
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrGetConsoleAliasesExesLength)
-{
- PCSRSS_CONSOLE Console;
- DPRINT("CsrGetConsoleAliasesExesLength entered\n");
-
- Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (NT_SUCCESS(Request->Status))
- {
- Request->Data.GetConsoleAliasesExesLength.Length = IntGetConsoleAliasesExesLength(Console->Aliases);
- ConioUnlockConsole(Console);
- }
- return Request->Status;
-}
+++ /dev/null
-/*
- * reactos/subsys/csrss/win32csr/conio.c
- *
- * Console I/O functions
- *
- * ReactOS Operating System
- */
-
-/* INCLUDES ******************************************************************/
-
-#define NDEBUG
-#include "w32csr.h"
-#include <debug.h>
-
-/* GLOBALS *******************************************************************/
-
-#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
- WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
-
-#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
- MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
-
-/* FUNCTIONS *****************************************************************/
-
-CSR_API(CsrReadConsole)
-{
- PLIST_ENTRY CurrentEntry;
- ConsoleInput *Input;
- PCHAR Buffer;
- PWCHAR UnicodeBuffer;
- ULONG i = 0;
- ULONG nNumberOfCharsToRead, CharSize;
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("CsrReadConsole\n");
-
- CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
-
- nNumberOfCharsToRead = Request->Data.ReadConsoleRequest.NrCharactersToRead;
-
- Buffer = (PCHAR)Request->Data.ReadConsoleRequest.Buffer;
- UnicodeBuffer = (PWCHAR)Buffer;
- if (!Win32CsrValidateBuffer(ProcessData, Buffer, nNumberOfCharsToRead, CharSize))
- return STATUS_ACCESS_VIOLATION;
-
- if (Request->Data.ReadConsoleRequest.NrCharactersRead * sizeof(WCHAR) > nNumberOfCharsToRead * CharSize)
- return STATUS_INVALID_PARAMETER;
-
- Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
- &Console, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent;
-
- Status = STATUS_PENDING; /* we haven't read anything (yet) */
- if (Console->Mode & ENABLE_LINE_INPUT)
- {
- if (Console->LineBuffer == NULL)
- {
- /* Starting a new line */
- Console->LineMaxSize = max(256, nNumberOfCharsToRead);
- Console->LineBuffer = HeapAlloc(Win32CsrApiHeap, 0, Console->LineMaxSize * sizeof(WCHAR));
- if (Console->LineBuffer == NULL)
- {
- Status = STATUS_NO_MEMORY;
- goto done;
- }
- Console->LineComplete = FALSE;
- Console->LineUpPressed = FALSE;
- Console->LineInsertToggle = 0;
- Console->LineWakeupMask = Request->Data.ReadConsoleRequest.CtrlWakeupMask;
- Console->LineSize = Request->Data.ReadConsoleRequest.NrCharactersRead;
- Console->LinePos = Console->LineSize;
- /* pre-filling the buffer is only allowed in the Unicode API,
- * so we don't need to worry about conversion */
- memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
- if (Console->LineSize == Console->LineMaxSize)
- {
- Console->LineComplete = TRUE;
- Console->LinePos = 0;
- }
- }
-
- /* If we don't have a complete line yet, process the pending input */
- while (!Console->LineComplete && !IsListEmpty(&Console->InputEvents))
- {
- /* remove input event from queue */
- CurrentEntry = RemoveHeadList(&Console->InputEvents);
- if (IsListEmpty(&Console->InputEvents))
- {
- ResetEvent(Console->ActiveEvent);
- }
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
- /* only pay attention to key down */
- if (KEY_EVENT == Input->InputEvent.EventType
- && Input->InputEvent.Event.KeyEvent.bKeyDown)
- {
- LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
- Request->Data.ReadConsoleRequest.ControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
- }
- HeapFree(Win32CsrApiHeap, 0, Input);
- }
-
- /* Check if we have a complete line to read from */
- if (Console->LineComplete)
- {
- while (i < nNumberOfCharsToRead && Console->LinePos != Console->LineSize)
- {
- WCHAR Char = Console->LineBuffer[Console->LinePos++];
- if (Request->Data.ReadConsoleRequest.Unicode)
- UnicodeBuffer[i++] = Char;
- else
- ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char);
- }
- if (Console->LinePos == Console->LineSize)
- {
- /* Entire line has been read */
- HeapFree(Win32CsrApiHeap, 0, Console->LineBuffer);
- Console->LineBuffer = NULL;
- }
- Status = STATUS_SUCCESS;
- }
- }
- else
- {
- /* Character input */
- while (i < nNumberOfCharsToRead && !IsListEmpty(&Console->InputEvents))
- {
- /* remove input event from queue */
- CurrentEntry = RemoveHeadList(&Console->InputEvents);
- if (IsListEmpty(&Console->InputEvents))
- {
- ResetEvent(Console->ActiveEvent);
- }
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
- /* only pay attention to valid ascii chars, on key down */
- if (KEY_EVENT == Input->InputEvent.EventType
- && Input->InputEvent.Event.KeyEvent.bKeyDown
- && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
- {
- WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
- if (Request->Data.ReadConsoleRequest.Unicode)
- UnicodeBuffer[i++] = Char;
- else
- ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char);
- Status = STATUS_SUCCESS; /* did read something */
- }
- HeapFree(Win32CsrApiHeap, 0, Input);
- }
- }
-done:
- Request->Data.ReadConsoleRequest.NrCharactersRead = i;
- ConioUnlockConsole(Console);
-
- return Status;
-}
-
-static VOID FASTCALL
-ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
-{
- if (InputEvent->EventType == KEY_EVENT)
- {
- WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
- InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
- ConsoleInputUnicodeCharToAnsiChar(Console,
- &InputEvent->Event.KeyEvent.uChar.AsciiChar,
- &UnicodeChar);
- }
-}
-
-static NTSTATUS FASTCALL
-ConioProcessChar(PCSRSS_CONSOLE Console,
- PINPUT_RECORD InputEvent)
-{
- ConsoleInput *ConInRec;
-
- /* Check for pause or unpause */
- if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
- {
- WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
- if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
- {
- DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
- if (Console->Mode & ENABLE_LINE_INPUT &&
- (vk == VK_PAUSE || (vk == 'S' &&
- (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
- !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
- {
- ConioPause(Console, PAUSED_FROM_KEYBOARD);
- return STATUS_SUCCESS;
- }
- }
- else
- {
- if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
- vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
- {
- ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
- return STATUS_SUCCESS;
- }
- }
- }
-
- /* add event to the queue */
- ConInRec = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
- if (ConInRec == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
- ConInRec->InputEvent = *InputEvent;
- InsertTailList(&Console->InputEvents, &ConInRec->ListEntry);
- SetEvent(Console->ActiveEvent);
- return STATUS_SUCCESS;
-}
-
-static DWORD FASTCALL
-ConioGetShiftState(PBYTE KeyState)
-{
- DWORD ssOut = 0;
-
- if (KeyState[VK_CAPITAL] & 1)
- ssOut |= CAPSLOCK_ON;
-
- if (KeyState[VK_NUMLOCK] & 1)
- ssOut |= NUMLOCK_ON;
-
- if (KeyState[VK_SCROLL] & 1)
- ssOut |= SCROLLLOCK_ON;
-
- if (KeyState[VK_SHIFT] & 0x80)
- ssOut |= SHIFT_PRESSED;
-
- if (KeyState[VK_LCONTROL] & 0x80)
- ssOut |= LEFT_CTRL_PRESSED;
- if (KeyState[VK_RCONTROL] & 0x80)
- ssOut |= RIGHT_CTRL_PRESSED;
-
- if (KeyState[VK_LMENU] & 0x80)
- ssOut |= LEFT_ALT_PRESSED;
- if (KeyState[VK_RMENU] & 0x80)
- ssOut |= RIGHT_ALT_PRESSED;
-
- return ssOut;
-}
-
-VOID WINAPI
-ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
-{
- static BYTE KeyState[256] = { 0 };
- /* MSDN mentions that you should use the last virtual key code received
- * when putting a virtual key identity to a WM_CHAR message since multiple
- * or translated keys may be involved. */
- static UINT LastVirtualKey = 0;
- DWORD ShiftState;
- UINT RepeatCount;
- WCHAR UnicodeChar;
- UINT VirtualKeyCode;
- UINT VirtualScanCode;
- BOOL Down = FALSE;
- INPUT_RECORD er;
- BOOLEAN Fake; // synthesized, not a real event
- BOOLEAN NotChar; // message should not be used to return a character
-
- RepeatCount = 1;
- VirtualScanCode = (msg->lParam >> 16) & 0xff;
- Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
- msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
-
- GetKeyboardState(KeyState);
- ShiftState = ConioGetShiftState(KeyState);
-
- if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
- {
- VirtualKeyCode = LastVirtualKey;
- UnicodeChar = msg->wParam;
- }
- else
- {
- WCHAR Chars[2];
- INT RetChars = 0;
-
- VirtualKeyCode = msg->wParam;
- RetChars = ToUnicodeEx(VirtualKeyCode,
- VirtualScanCode,
- KeyState,
- Chars,
- 2,
- 0,
- 0);
- UnicodeChar = (1 == RetChars ? Chars[0] : 0);
- }
-
- er.EventType = KEY_EVENT;
- er.Event.KeyEvent.bKeyDown = Down;
- er.Event.KeyEvent.wRepeatCount = RepeatCount;
- er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
- er.Event.KeyEvent.dwControlKeyState = ShiftState;
- er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
- er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
-
- if (TextMode)
- {
- if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
- && VK_TAB == VirtualKeyCode)
- {
- if (Down)
- {
- TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
- }
-
- return;
- }
- else if (VK_MENU == VirtualKeyCode && ! Down)
- {
- if (TuiSwapConsole(0))
- {
- return;
- }
- }
- }
- else
- {
- if ((ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) || KeyState[VK_MENU] & 0x80) &&
- (VirtualKeyCode == VK_ESCAPE || VirtualKeyCode == VK_TAB || VirtualKeyCode == VK_SPACE))
- {
- DefWindowProcW( msg->hwnd, msg->message, msg->wParam, msg->lParam);
- return;
- }
- }
-
- if (NULL == Console)
- {
- DPRINT1("No Active Console!\n");
- return;
- }
-
- Fake = UnicodeChar &&
- (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
- msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
- NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
- if (NotChar)
- LastVirtualKey = msg->wParam;
-
- DPRINT ("csrss: %s %s %s %s %02x %02x '%lc' %04x\n",
- Down ? "down" : "up ",
- (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
- "char" : "key ",
- Fake ? "fake" : "real",
- NotChar ? "notc" : "char",
- VirtualScanCode,
- VirtualKeyCode,
- (UnicodeChar >= L' ') ? UnicodeChar : L'.',
- ShiftState);
-
- if (Fake)
- return;
-
- /* process Ctrl-C and Ctrl-Break */
- if (Console->Mode & ENABLE_PROCESSED_INPUT &&
- er.Event.KeyEvent.bKeyDown &&
- ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
- (er.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
- (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80))
- {
- PCSR_PROCESS current;
- PLIST_ENTRY current_entry;
- DPRINT1("Console_Api Ctrl-C\n");
- current_entry = Console->ProcessList.Flink;
- while (current_entry != &Console->ProcessList)
- {
- current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
- current_entry = current_entry->Flink;
- ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
- }
- if (Console->LineBuffer && !Console->LineComplete)
- {
- /* Line input is in progress; end it */
- Console->LinePos = Console->LineSize = 0;
- Console->LineComplete = TRUE;
- }
- return;
- }
-
- if (0 != (er.Event.KeyEvent.dwControlKeyState
- & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
- && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode
- || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode))
- {
- if (er.Event.KeyEvent.bKeyDown)
- {
- /* scroll up or down */
- if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode)
- {
- /* only scroll up if there is room to scroll up into */
- if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1)
- {
- Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
- Console->ActiveBuffer->MaxY - 1) %
- Console->ActiveBuffer->MaxY;
- Console->ActiveBuffer->CurrentY++;
- }
- }
- else
- {
- /* only scroll down if there is room to scroll down into */
- if (Console->ActiveBuffer->CurrentY != 0)
- {
- Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
- Console->ActiveBuffer->MaxY;
- Console->ActiveBuffer->CurrentY--;
- }
- }
- ConioDrawConsole(Console);
- }
- return;
- }
- ConioProcessChar(Console, &er);
-}
-
-CSR_API(CsrReadInputEvent)
-{
- PLIST_ENTRY CurrentEntry;
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
- BOOLEAN Done = FALSE;
- ConsoleInput *Input;
-
- DPRINT("CsrReadInputEvent\n");
-
- Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent;
-
- Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- /* only get input if there is any */
- CurrentEntry = Console->InputEvents.Flink;
- while (CurrentEntry != &Console->InputEvents)
- {
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
- CurrentEntry = CurrentEntry->Flink;
-
- if (Done)
- {
- Request->Data.ReadInputRequest.MoreEvents = TRUE;
- break;
- }
-
- RemoveEntryList(&Input->ListEntry);
-
- if (!Done)
- {
- Request->Data.ReadInputRequest.Input = Input->InputEvent;
- if (Request->Data.ReadInputRequest.Unicode == FALSE)
- {
- ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input);
- }
- Done = TRUE;
- }
-
- HeapFree(Win32CsrApiHeap, 0, Input);
- }
-
- if (Done)
- Status = STATUS_SUCCESS;
- else
- Status = STATUS_PENDING;
-
- if (IsListEmpty(&Console->InputEvents))
- {
- ResetEvent(Console->ActiveEvent);
- }
-
- ConioUnlockConsole(Console);
-
- return Status;
-}
-
-CSR_API(CsrFlushInputBuffer)
-{
- PLIST_ENTRY CurrentEntry;
- PCSRSS_CONSOLE Console;
- ConsoleInput* Input;
- NTSTATUS Status;
-
- DPRINT("CsrFlushInputBuffer\n");
-
- Status = ConioLockConsole(ProcessData,
- Request->Data.FlushInputBufferRequest.ConsoleInput,
- &Console,
- GENERIC_WRITE);
- if(! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- /* Discard all entries in the input event queue */
- while (!IsListEmpty(&Console->InputEvents))
- {
- CurrentEntry = RemoveHeadList(&Console->InputEvents);
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
- /* Destroy the event */
- HeapFree(Win32CsrApiHeap, 0, Input);
- }
- ResetEvent(Console->ActiveEvent);
-
- ConioUnlockConsole(Console);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrGetNumberOfConsoleInputEvents)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PLIST_ENTRY CurrentItem;
- DWORD NumEvents;
-
- DPRINT("CsrGetNumberOfConsoleInputEvents\n");
-
- Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- CurrentItem = Console->InputEvents.Flink;
- NumEvents = 0;
-
- /* If there are any events ... */
- while (CurrentItem != &Console->InputEvents)
- {
- CurrentItem = CurrentItem->Flink;
- NumEvents++;
- }
-
- ConioUnlockConsole(Console);
-
- Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents;
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrPeekConsoleInput)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- DWORD Length;
- PLIST_ENTRY CurrentItem;
- PINPUT_RECORD InputRecord;
- ConsoleInput* Item;
- UINT NumItems;
-
- DPRINT("CsrPeekConsoleInput\n");
-
- Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
- if(! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord;
- Length = Request->Data.PeekConsoleInputRequest.Length;
-
- if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD)))
- {
- ConioUnlockConsole(Console);
- return STATUS_ACCESS_VIOLATION;
- }
-
- NumItems = 0;
-
- if (! IsListEmpty(&Console->InputEvents))
- {
- CurrentItem = Console->InputEvents.Flink;
-
- while (CurrentItem != &Console->InputEvents && NumItems < Length)
- {
- Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
-
- ++NumItems;
- *InputRecord = Item->InputEvent;
-
- if (Request->Data.PeekConsoleInputRequest.Unicode == FALSE)
- {
- ConioInputEventToAnsi(Console, InputRecord);
- }
-
- InputRecord++;
- CurrentItem = CurrentItem->Flink;
- }
- }
-
- ConioUnlockConsole(Console);
-
- Request->Data.PeekConsoleInputRequest.Length = NumItems;
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrWriteConsoleInput)
-{
- PINPUT_RECORD InputRecord;
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
- DWORD Length;
- DWORD i;
-
- DPRINT("CsrWriteConsoleInput\n");
-
- Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
- Length = Request->Data.WriteConsoleInputRequest.Length;
-
- if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD)))
- {
- ConioUnlockConsole(Console);
- return STATUS_ACCESS_VIOLATION;
- }
-
- for (i = 0; i < Length && NT_SUCCESS(Status); i++)
- {
- if (!Request->Data.WriteConsoleInputRequest.Unicode &&
- InputRecord->EventType == KEY_EVENT)
- {
- CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar;
- ConsoleInputAnsiCharToUnicodeChar(Console,
- &InputRecord->Event.KeyEvent.uChar.UnicodeChar,
- &AsciiChar);
- }
- Status = ConioProcessChar(Console, InputRecord++);
- }
-
- ConioUnlockConsole(Console);
-
- Request->Data.WriteConsoleInputRequest.Length = i;
-
- return Status;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/include/conio.h
- * PURPOSE: CSRSS internal console I/O interface
- */
-
-#pragma once
-
-#include "api.h"
-#include "win32csr.h"
-
-#define CSR_DEFAULT_CURSOR_SIZE 25
-
-/* Object type magic numbers */
-
-#define CONIO_CONSOLE_MAGIC 0x00000001
-#define CONIO_SCREEN_BUFFER_MAGIC 0x00000002
-
-/************************************************************************
- * Screen buffer structure represents the win32 screen buffer object. *
- * Internally, the portion of the buffer being shown CAN loop past the *
- * bottom of the virtual buffer and wrap around to the top. Win32 does *
- * not do this. I decided to do this because it eliminates the need to *
- * do a massive memcpy() to scroll the contents of the buffer up to *
- * scroll the screen on output, instead I just shift down the position *
- * to be displayed, and let it wrap around to the top again. *
- * The VirtualY member keeps track of the top Y coord that win32 *
- * clients THINK is currently being displayed, because they think that *
- * when the display reaches the bottom of the buffer and another line *
- * being printed causes another line to scroll down, that the buffer IS *
- * memcpy()'s up, and the bottom of the buffer is still displayed, but *
- * internally, I just wrap back to the top of the buffer. *
- ***********************************************************************/
-
-typedef struct tagCSRSS_SCREEN_BUFFER
-{
- Object_t Header; /* Object header */
- BYTE *Buffer; /* pointer to screen buffer */
- USHORT MaxX, MaxY; /* size of the entire scrollback buffer */
- USHORT ShowX, ShowY; /* beginning offset for the actual display area */
- ULONG CurrentX; /* Current X cursor position */
- ULONG CurrentY; /* Current Y cursor position */
- WORD DefaultAttrib; /* default char attribute */
- USHORT VirtualY; /* top row of buffer being displayed, reported to callers */
- CONSOLE_CURSOR_INFO CursorInfo;
- USHORT Mode;
- LIST_ENTRY ListEntry; /* entry in console's list of buffers */
-} CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER;
-
-typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE;
-
-typedef struct tagCSRSS_CONSOLE_VTBL
-{
- VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
- VOID (WINAPI *WriteStream)(PCSRSS_CONSOLE Console, SMALL_RECT *Block, LONG CursorStartX, LONG CursorStartY,
- UINT ScrolledLines, CHAR *Buffer, UINT Length);
- VOID (WINAPI *DrawRegion)(PCSRSS_CONSOLE Console, SMALL_RECT *Region);
- BOOL (WINAPI *SetCursorInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
- BOOL (WINAPI *SetScreenInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer,
- UINT OldCursorX, UINT OldCursorY);
- BOOL (WINAPI *UpdateScreenInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
- BOOL (WINAPI *ChangeTitle)(PCSRSS_CONSOLE Console);
- VOID (WINAPI *CleanupConsole)(PCSRSS_CONSOLE Console);
- BOOL (WINAPI *ChangeIcon)(PCSRSS_CONSOLE Console, HICON hWindowIcon);
- NTSTATUS (WINAPI *ResizeBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size);
-} CSRSS_CONSOLE_VTBL, *PCSRSS_CONSOLE_VTBL;
-
-typedef struct tagCSRSS_CONSOLE
-{
- Object_t Header; /* Object header */
- LONG ReferenceCount;
- CRITICAL_SECTION Lock;
- PCSRSS_CONSOLE Prev, Next; /* Next and Prev consoles in console wheel */
- HANDLE ActiveEvent;
- LIST_ENTRY InputEvents; /* List head for input event queue */
- PWCHAR LineBuffer; /* current line being input, in line buffered mode */
- WORD LineMaxSize; /* maximum size of line in characters (including CR+LF) */
- WORD LineSize; /* current size of line */
- WORD LinePos; /* current position within line */
- BOOLEAN LineComplete; /* user pressed enter, ready to send back to client */
- BOOLEAN LineUpPressed;
- BOOLEAN LineInsertToggle; /* replace character over cursor instead of inserting */
- ULONG LineWakeupMask; /* bitmap of which control characters will end line input */
- LIST_ENTRY HistoryBuffers;
- WORD HistoryBufferSize; /* size for newly created history buffers */
- WORD NumberOfHistoryBuffers; /* maximum number of history buffers allowed */
- BOOLEAN HistoryNoDup; /* remove old duplicate history entries */
- LIST_ENTRY BufferList; /* List of all screen buffers for this console */
- PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
- WORD Mode; /* Console mode flags */
- UNICODE_STRING Title; /* Title of console */
- DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */
- HWND hWindow;
- COORD Size;
- PVOID PrivateData;
- UINT CodePage;
- UINT OutputCodePage;
- PCSRSS_CONSOLE_VTBL Vtbl;
- LIST_ENTRY ProcessList;
- struct tagALIAS_HEADER *Aliases;
- CONSOLE_SELECTION_INFO Selection;
- BYTE PauseFlags;
- HANDLE UnpauseEvent;
-} CSRSS_CONSOLE;
-
-typedef struct ConsoleInput_t
-{
- LIST_ENTRY ListEntry;
- INPUT_RECORD InputEvent;
-} ConsoleInput;
-
-/* CONSOLE_SELECTION_INFO dwFlags values */
-#define CONSOLE_NO_SELECTION 0x0
-#define CONSOLE_SELECTION_IN_PROGRESS 0x1
-#define CONSOLE_SELECTION_NOT_EMPTY 0x2
-#define CONSOLE_MOUSE_SELECTION 0x4
-#define CONSOLE_MOUSE_DOWN 0x8
-/* HistoryFlags values */
-#define HISTORY_NO_DUP_FLAG 0x1
-
-/* PauseFlags values (internal only) */
-#define PAUSED_FROM_KEYBOARD 0x1
-#define PAUSED_FROM_SCROLLBAR 0x2
-#define PAUSED_FROM_SELECTION 0x4
-
-#define ConioInitScreenBuffer(Console, Buff) (Console)->Vtbl->InitScreenBuffer((Console), (Buff))
-#define ConioDrawRegion(Console, Region) (Console)->Vtbl->DrawRegion((Console), (Region))
-#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
- (Console)->Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
- (ScrolledLines), (Buffer), (Length))
-#define ConioSetCursorInfo(Console, Buff) (Console)->Vtbl->SetCursorInfo((Console), (Buff))
-#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \
- (Console)->Vtbl->SetScreenInfo((Console), (Buff), (OldCursorX), (OldCursorY))
-#define ConioUpdateScreenInfo(Console, Buff) \
- (Console)->Vtbl->UpdateScreenInfo(Console, Buff)
-#define ConioChangeTitle(Console) (Console)->Vtbl->ChangeTitle(Console)
-#define ConioCleanupConsole(Console) (Console)->Vtbl->CleanupConsole(Console)
-#define ConioChangeIcon(Console, hWindowIcon) (Console)->Vtbl->ChangeIcon(Console, hWindowIcon)
-#define ConioResizeBuffer(Console, Buff, Size) (Console)->Vtbl->ResizeBuffer(Console, Buff, Size)
-
-/* console.c */
-NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSR_PROCESS ProcessData, PCSRSS_CONSOLE *Console);
-VOID WINAPI ConioDeleteConsole(Object_t *Object);
-VOID WINAPI CsrInitConsoleSupport(VOID);
-VOID FASTCALL ConioPause(PCSRSS_CONSOLE Console, UINT Flags);
-VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags);
-VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCSR_PROCESS ProcessData);
-VOID FASTCALL ConioConsoleCtrlEventTimeout(DWORD Event, PCSR_PROCESS ProcessData,
- DWORD Timeout);
-CSR_API(CsrAllocConsole);
-CSR_API(CsrFreeConsole);
-CSR_API(CsrSetConsoleMode);
-CSR_API(CsrGetConsoleMode);
-CSR_API(CsrSetTitle);
-CSR_API(CsrGetTitle);
-CSR_API(CsrHardwareStateProperty);
-CSR_API(CsrGetConsoleWindow);
-CSR_API(CsrSetConsoleIcon);
-CSR_API(CsrGetConsoleCodePage);
-CSR_API(CsrSetConsoleCodePage);
-CSR_API(CsrGetConsoleOutputCodePage);
-CSR_API(CsrSetConsoleOutputCodePage);
-CSR_API(CsrGetProcessList);
-CSR_API(CsrGenerateCtrlEvent);
-CSR_API(CsrGetConsoleSelectionInfo);
-
-/* coninput.c */
-#define ConioLockConsole(ProcessData, Handle, Ptr, Access) \
- Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_CONSOLE_MAGIC)
-#define ConioUnlockConsole(Console) \
- Win32CsrUnlockObject((Object_t *) Console)
-void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode);
-CSR_API(CsrReadConsole);
-CSR_API(CsrReadInputEvent);
-CSR_API(CsrFlushInputBuffer);
-CSR_API(CsrGetNumberOfConsoleInputEvents);
-CSR_API(CsrPeekConsoleInput);
-CSR_API(CsrWriteConsoleInput);
-
-/* conoutput.c */
-#define ConioRectHeight(Rect) \
- (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1)
-#define ConioRectWidth(Rect) \
- (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1)
-#define ConioLockScreenBuffer(ProcessData, Handle, Ptr, Access) \
- Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_SCREEN_BUFFER_MAGIC)
-#define ConioUnlockScreenBuffer(Buff) \
- Win32CsrUnlockObject((Object_t *) Buff)
-PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y);
-VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console);
-NTSTATUS FASTCALL ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
- CHAR *Buffer, DWORD Length, BOOL Attrib);
-NTSTATUS FASTCALL CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer);
-VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer);
-DWORD FASTCALL ConioEffectiveCursorSize(PCSRSS_CONSOLE Console, DWORD Scale);
-
-CSR_API(CsrWriteConsole);
-CSR_API(CsrGetScreenBufferInfo);
-CSR_API(CsrSetCursor);
-CSR_API(CsrWriteConsoleOutputChar);
-CSR_API(CsrFillOutputChar);
-CSR_API(CsrWriteConsoleOutputAttrib);
-CSR_API(CsrFillOutputAttrib);
-CSR_API(CsrGetCursorInfo);
-CSR_API(CsrSetCursorInfo);
-CSR_API(CsrSetTextAttrib);
-CSR_API(CsrCreateScreenBuffer);
-CSR_API(CsrSetScreenBuffer);
-CSR_API(CsrWriteConsoleOutput);
-CSR_API(CsrScrollConsoleScreenBuffer);
-CSR_API(CsrReadConsoleOutputChar);
-CSR_API(CsrReadConsoleOutputAttrib);
-CSR_API(CsrReadConsoleOutput);
-CSR_API(CsrSetScreenBufferSize);
-
-/* alias.c */
-VOID IntDeleteAllAliases(struct tagALIAS_HEADER *RootHeader);
-CSR_API(CsrAddConsoleAlias);
-CSR_API(CsrGetConsoleAlias);
-CSR_API(CsrGetAllConsoleAliases);
-CSR_API(CsrGetAllConsoleAliasesLength);
-CSR_API(CsrGetConsoleAliasesExes);
-CSR_API(CsrGetConsoleAliasesExesLength);
-
-/* lineinput.c */
-struct tagHISTORY_BUFFER;
-VOID FASTCALL HistoryDeleteBuffer(struct tagHISTORY_BUFFER *Hist);
-CSR_API(CsrGetCommandHistoryLength);
-CSR_API(CsrGetCommandHistory);
-CSR_API(CsrExpungeCommandHistory);
-CSR_API(CsrSetHistoryNumberCommands);
-CSR_API(CsrGetHistoryInfo);
-CSR_API(CsrSetHistoryInfo);
-VOID FASTCALL LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent);
-
-/* EOF */
+++ /dev/null
-/*
- * reactos/subsys/csrss/win32csr/conio.c
- *
- * Console I/O functions
- *
- * ReactOS Operating System
- */
-
-/* INCLUDES ******************************************************************/
-
-#define NDEBUG
-#include "w32csr.h"
-#include <debug.h>
-
-/* GLOBALS *******************************************************************/
-
-#define ConioInitRect(Rect, top, left, bottom, right) \
- ((Rect)->Top) = top; \
- ((Rect)->Left) = left; \
- ((Rect)->Bottom) = bottom; \
- ((Rect)->Right) = right
-
-#define ConioIsRectEmpty(Rect) \
- (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
-
-#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
- WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
-
-#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
- MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
-
-/* FUNCTIONS *****************************************************************/
-
-PBYTE FASTCALL
-ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
-{
- return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)];
-}
-
-static VOID FASTCALL
-ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff)
-{
- PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY);
- UINT Pos;
-
- for (Pos = 0; Pos < Buff->MaxX; Pos++)
- {
- /* Fill the cell */
- *Ptr++ = ' ';
- *Ptr++ = Buff->DefaultAttrib;
- }
-}
-
-NTSTATUS FASTCALL
-CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
- PCSRSS_SCREEN_BUFFER Buffer)
-{
- DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY);
-
- Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
- Buffer->Header.Console = Console;
- Buffer->Header.HandleCount = 0;
- Buffer->ShowX = 0;
- Buffer->ShowY = 0;
- Buffer->VirtualY = 0;
- Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2);
- if (NULL == Buffer->Buffer)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- ConioInitScreenBuffer(Console, Buffer);
- /* initialize buffer to be empty with default attributes */
- for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
- {
- ClearLineBuffer(Buffer);
- }
- Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
- Buffer->CurrentX = 0;
- Buffer->CurrentY = 0;
-
- InsertHeadList(&Console->BufferList, &Buffer->ListEntry);
- return STATUS_SUCCESS;
-}
-
-static VOID FASTCALL
-ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, UINT *ScrolledLines)
-{
- /* If we hit bottom, slide the viewable screen */
- if (++Buff->CurrentY == Buff->MaxY)
- {
- Buff->CurrentY--;
- if (++Buff->VirtualY == Buff->MaxY)
- {
- Buff->VirtualY = 0;
- }
- (*ScrolledLines)++;
- ClearLineBuffer(Buff);
- if (UpdateRect->Top != 0)
- {
- UpdateRect->Top--;
- }
- }
- UpdateRect->Left = 0;
- UpdateRect->Right = Buff->MaxX - 1;
- UpdateRect->Bottom = Buff->CurrentY;
-}
-
-NTSTATUS FASTCALL
-ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
- CHAR *Buffer, DWORD Length, BOOL Attrib)
-{
- UINT i;
- PBYTE Ptr;
- SMALL_RECT UpdateRect;
- LONG CursorStartX, CursorStartY;
- UINT ScrolledLines;
-
- CursorStartX = Buff->CurrentX;
- CursorStartY = Buff->CurrentY;
- UpdateRect.Left = Buff->MaxX;
- UpdateRect.Top = Buff->CurrentY;
- UpdateRect.Right = -1;
- UpdateRect.Bottom = Buff->CurrentY;
- ScrolledLines = 0;
-
- for (i = 0; i < Length; i++)
- {
- if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
- {
- /* --- LF --- */
- if (Buffer[i] == '\n')
- {
- Buff->CurrentX = 0;
- ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
- continue;
- }
- /* --- BS --- */
- else if (Buffer[i] == '\b')
- {
- /* Only handle BS if we're not on the first pos of the first line */
- if (0 != Buff->CurrentX || 0 != Buff->CurrentY)
- {
- if (0 == Buff->CurrentX)
- {
- /* slide virtual position up */
- Buff->CurrentX = Buff->MaxX - 1;
- Buff->CurrentY--;
- UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY);
- }
- else
- {
- Buff->CurrentX--;
- }
- Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
- Ptr[0] = ' ';
- Ptr[1] = Buff->DefaultAttrib;
- UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX);
- UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX);
- }
- continue;
- }
- /* --- CR --- */
- else if (Buffer[i] == '\r')
- {
- Buff->CurrentX = 0;
- UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX);
- UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX);
- continue;
- }
- /* --- TAB --- */
- else if (Buffer[i] == '\t')
- {
- UINT EndX;
-
- UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX);
- EndX = (Buff->CurrentX + 8) & ~7;
- if (EndX > Buff->MaxX)
- {
- EndX = Buff->MaxX;
- }
- Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
- while (Buff->CurrentX < EndX)
- {
- *Ptr++ = ' ';
- *Ptr++ = Buff->DefaultAttrib;
- Buff->CurrentX++;
- }
- UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX - 1);
- if (Buff->CurrentX == Buff->MaxX)
- {
- if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
- {
- Buff->CurrentX = 0;
- ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
- }
- else
- {
- Buff->CurrentX--;
- }
- }
- continue;
- }
- }
- UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX);
- UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX);
- Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
- Ptr[0] = Buffer[i];
- if (Attrib)
- {
- Ptr[1] = Buff->DefaultAttrib;
- }
- Buff->CurrentX++;
- if (Buff->CurrentX == Buff->MaxX)
- {
- if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
- {
- Buff->CurrentX = 0;
- ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
- }
- else
- {
- Buff->CurrentX = CursorStartX;
- }
- }
- }
-
- if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer)
- {
- ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines,
- Buffer, Length);
- }
-
- return STATUS_SUCCESS;
-}
-
-__inline BOOLEAN ConioGetIntersection(
- SMALL_RECT *Intersection,
- SMALL_RECT *Rect1,
- SMALL_RECT *Rect2)
-{
- if (ConioIsRectEmpty(Rect1) ||
- (ConioIsRectEmpty(Rect2)) ||
- (Rect1->Top > Rect2->Bottom) ||
- (Rect1->Left > Rect2->Right) ||
- (Rect1->Bottom < Rect2->Top) ||
- (Rect1->Right < Rect2->Left))
- {
- /* The rectangles do not intersect */
- ConioInitRect(Intersection, 0, -1, 0, -1);
- return FALSE;
- }
-
- ConioInitRect(Intersection,
- max(Rect1->Top, Rect2->Top),
- max(Rect1->Left, Rect2->Left),
- min(Rect1->Bottom, Rect2->Bottom),
- min(Rect1->Right, Rect2->Right));
-
- return TRUE;
-}
-
-__inline BOOLEAN ConioGetUnion(
- SMALL_RECT *Union,
- SMALL_RECT *Rect1,
- SMALL_RECT *Rect2)
-{
- if (ConioIsRectEmpty(Rect1))
- {
- if (ConioIsRectEmpty(Rect2))
- {
- ConioInitRect(Union, 0, -1, 0, -1);
- return FALSE;
- }
- else
- {
- *Union = *Rect2;
- }
- }
- else if (ConioIsRectEmpty(Rect2))
- {
- *Union = *Rect1;
- }
- else
- {
- ConioInitRect(Union,
- min(Rect1->Top, Rect2->Top),
- min(Rect1->Left, Rect2->Left),
- max(Rect1->Bottom, Rect2->Bottom),
- max(Rect1->Right, Rect2->Right));
- }
-
- return TRUE;
-}
-
-/* Move from one rectangle to another. We must be careful about the order that
- * this is done, to avoid overwriting parts of the source before they are moved. */
-static VOID FASTCALL
-ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
- SMALL_RECT *SrcRegion,
- SMALL_RECT *DstRegion,
- SMALL_RECT *ClipRegion,
- WORD Fill)
-{
- int Width = ConioRectWidth(SrcRegion);
- int Height = ConioRectHeight(SrcRegion);
- int SX, SY;
- int DX, DY;
- int XDelta, YDelta;
- int i, j;
-
- SY = SrcRegion->Top;
- DY = DstRegion->Top;
- YDelta = 1;
- if (SY < DY)
- {
- /* Moving down: work from bottom up */
- SY = SrcRegion->Bottom;
- DY = DstRegion->Bottom;
- YDelta = -1;
- }
- for (i = 0; i < Height; i++)
- {
- PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY);
- PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY);
-
- SX = SrcRegion->Left;
- DX = DstRegion->Left;
- XDelta = 1;
- if (SX < DX)
- {
- /* Moving right: work from right to left */
- SX = SrcRegion->Right;
- DX = DstRegion->Right;
- XDelta = -1;
- }
- for (j = 0; j < Width; j++)
- {
- WORD Cell = SRow[SX];
- if (SX >= ClipRegion->Left && SX <= ClipRegion->Right
- && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom)
- {
- SRow[SX] = Fill;
- }
- if (DX >= ClipRegion->Left && DX <= ClipRegion->Right
- && DY >= ClipRegion->Top && DY <= ClipRegion->Bottom)
- {
- DRow[DX] = Cell;
- }
- SX += XDelta;
- DX += XDelta;
- }
- SY += YDelta;
- DY += YDelta;
- }
-}
-
-CSR_API(CsrWriteConsole)
-{
- NTSTATUS Status;
- PCHAR Buffer;
- PCSRSS_SCREEN_BUFFER Buff;
- PCSRSS_CONSOLE Console;
- DWORD Written = 0;
- ULONG Length;
- ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
-
- DPRINT("CsrWriteConsole\n");
-
- if (Request->Header.u1.s1.TotalLength
- < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)
- + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize))
- {
- DPRINT1("Invalid request size\n");
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- if (Console->UnpauseEvent)
- {
- Status = NtDuplicateObject(GetCurrentProcess(), Console->UnpauseEvent,
- ProcessData->ProcessHandle, &Request->Data.WriteConsoleRequest.UnpauseEvent,
- SYNCHRONIZE, 0, 0);
- ConioUnlockScreenBuffer(Buff);
- return NT_SUCCESS(Status) ? STATUS_PENDING : Status;
- }
-
- if(Request->Data.WriteConsoleRequest.Unicode)
- {
- Length = WideCharToMultiByte(Console->OutputCodePage, 0,
- (PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
- Request->Data.WriteConsoleRequest.NrCharactersToWrite,
- NULL, 0, NULL, NULL);
- Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length);
- if (Buffer)
- {
- WideCharToMultiByte(Console->OutputCodePage, 0,
- (PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
- Request->Data.WriteConsoleRequest.NrCharactersToWrite,
- Buffer, Length, NULL, NULL);
- }
- else
- {
- Status = STATUS_NO_MEMORY;
- }
- }
- else
- {
- Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer;
- }
-
- if (Buffer)
- {
- if (NT_SUCCESS(Status))
- {
- Status = ConioWriteConsole(Console, Buff, Buffer,
- Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
- if (NT_SUCCESS(Status))
- {
- Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
- }
- }
- if (Request->Data.WriteConsoleRequest.Unicode)
- {
- RtlFreeHeap(GetProcessHeap(), 0, Buffer);
- }
- }
- ConioUnlockScreenBuffer(Buff);
-
- Request->Data.WriteConsoleRequest.NrCharactersWritten = Written;
-
- return Status;
-}
-
-VOID WINAPI
-ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer)
-{
- PCSRSS_CONSOLE Console = Buffer->Header.Console;
-
- RemoveEntryList(&Buffer->ListEntry);
- if (Buffer == Console->ActiveBuffer)
- {
- /* Deleted active buffer; switch to most recently created */
- Console->ActiveBuffer = NULL;
- if (!IsListEmpty(&Console->BufferList))
- {
- Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CSRSS_SCREEN_BUFFER, ListEntry);
- ConioDrawConsole(Console);
- }
- }
-
- HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
- HeapFree(Win32CsrApiHeap, 0, Buffer);
-}
-
-VOID FASTCALL
-ConioDrawConsole(PCSRSS_CONSOLE Console)
-{
- SMALL_RECT Region;
-
- ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1);
-
- ConioDrawRegion(Console, &Region);
-}
-
-CSR_API(CsrGetScreenBufferInfo)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- PCONSOLE_SCREEN_BUFFER_INFO pInfo;
-
- DPRINT("CsrGetScreenBufferInfo\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
- pInfo = &Request->Data.ScreenBufferInfoRequest.Info;
- pInfo->dwSize.X = Buff->MaxX;
- pInfo->dwSize.Y = Buff->MaxY;
- pInfo->dwCursorPosition.X = Buff->CurrentX;
- pInfo->dwCursorPosition.Y = Buff->CurrentY;
- pInfo->wAttributes = Buff->DefaultAttrib;
- pInfo->srWindow.Left = Buff->ShowX;
- pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1;
- pInfo->srWindow.Top = Buff->ShowY;
- pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1;
- pInfo->dwMaximumWindowSize.X = Buff->MaxX;
- pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrSetCursor)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- LONG OldCursorX, OldCursorY;
- LONG NewCursorX, NewCursorY;
-
- DPRINT("CsrSetCursor\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- NewCursorX = Request->Data.SetCursorRequest.Position.X;
- NewCursorY = Request->Data.SetCursorRequest.Position.Y;
- if (NewCursorX < 0 || NewCursorX >= Buff->MaxX ||
- NewCursorY < 0 || NewCursorY >= Buff->MaxY)
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_INVALID_PARAMETER;
- }
- OldCursorX = Buff->CurrentX;
- OldCursorY = Buff->CurrentY;
- Buff->CurrentX = NewCursorX;
- Buff->CurrentY = NewCursorY;
- if (Buff == Console->ActiveBuffer)
- {
- if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-static VOID FASTCALL
-ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start, UINT Length)
-{
- if (Buff->MaxX <= Start->X + Length)
- {
- UpdateRect->Left = 0;
- }
- else
- {
- UpdateRect->Left = Start->X;
- }
- if (Buff->MaxX <= Start->X + Length)
- {
- UpdateRect->Right = Buff->MaxX - 1;
- }
- else
- {
- UpdateRect->Right = Start->X + Length - 1;
- }
- UpdateRect->Top = Start->Y;
- UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX;
- if (Buff->MaxY <= UpdateRect->Bottom)
- {
- UpdateRect->Bottom = Buff->MaxY - 1;
- }
-}
-
-CSR_API(CsrWriteConsoleOutputChar)
-{
- NTSTATUS Status;
- PCHAR String, tmpString = NULL;
- PBYTE Buffer;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD X, Y, Length, CharSize, Written = 0;
- SMALL_RECT UpdateRect;
-
- DPRINT("CsrWriteConsoleOutputChar\n");
-
- CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
-
- if (Request->Header.u1.s1.TotalLength
- < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
- + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize))
- {
- DPRINT1("Invalid request size\n");
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConioLockScreenBuffer(ProcessData,
- Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
- &Buff,
- GENERIC_WRITE);
- if (NT_SUCCESS(Status))
- {
- Console = Buff->Header.Console;
- if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
- {
- Length = WideCharToMultiByte(Console->OutputCodePage, 0,
- (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
- Request->Data.WriteConsoleOutputCharRequest.Length,
- NULL, 0, NULL, NULL);
- tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length);
- if (String)
- {
- WideCharToMultiByte(Console->OutputCodePage, 0,
- (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
- Request->Data.WriteConsoleOutputCharRequest.Length,
- String, Length, NULL, NULL);
- }
- else
- {
- Status = STATUS_NO_MEMORY;
- }
- }
- else
- {
- String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String;
- }
-
- if (String)
- {
- if (NT_SUCCESS(Status))
- {
- X = Request->Data.WriteConsoleOutputCharRequest.Coord.X;
- Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
- Length = Request->Data.WriteConsoleOutputCharRequest.Length;
- Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
- while (Length--)
- {
- *Buffer = *String++;
- Written++;
- Buffer += 2;
- if (++X == Buff->MaxX)
- {
- if (++Y == Buff->MaxY)
- {
- Y = 0;
- Buffer = Buff->Buffer;
- }
- X = 0;
- }
- }
- if (Buff == Console->ActiveBuffer)
- {
- ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord,
- Request->Data.WriteConsoleOutputCharRequest.Length);
- ConioDrawRegion(Console, &UpdateRect);
- }
-
- Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X;
- Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
-
- }
- if (Request->Data.WriteConsoleRequest.Unicode)
- {
- RtlFreeHeap(GetProcessHeap(), 0, tmpString);
- }
- }
- ConioUnlockScreenBuffer(Buff);
- }
- Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written;
- return Status;
-}
-
-CSR_API(CsrFillOutputChar)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD X, Y, Length, Written = 0;
- CHAR Char;
- PBYTE Buffer;
- SMALL_RECT UpdateRect;
-
- DPRINT("CsrFillOutputChar\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- X = Request->Data.FillOutputRequest.Position.X;
- Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY;
- Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
- if(Request->Data.FillOutputRequest.Unicode)
- ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar);
- else
- Char = Request->Data.FillOutputRequest.Char.AsciiChar;
- Length = Request->Data.FillOutputRequest.Length;
- while (Length--)
- {
- *Buffer = Char;
- Buffer += 2;
- Written++;
- if (++X == Buff->MaxX)
- {
- if (++Y == Buff->MaxY)
- {
- Y = 0;
- Buffer = Buff->Buffer;
- }
- X = 0;
- }
- }
-
- if (Buff == Console->ActiveBuffer)
- {
- ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position,
- Request->Data.FillOutputRequest.Length);
- ConioDrawRegion(Console, &UpdateRect);
- }
-
- ConioUnlockScreenBuffer(Buff);
- Length = Request->Data.FillOutputRequest.Length;
- Request->Data.FillOutputRequest.NrCharactersWritten = Length;
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrWriteConsoleOutputAttrib)
-{
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- PUCHAR Buffer;
- PWORD Attribute;
- int X, Y, Length;
- NTSTATUS Status;
- SMALL_RECT UpdateRect;
-
- DPRINT("CsrWriteConsoleOutputAttrib\n");
-
- if (Request->Header.u1.s1.TotalLength
- < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
- + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD))
- {
- DPRINT1("Invalid request size\n");
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConioLockScreenBuffer(ProcessData,
- Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
- &Buff,
- GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X;
- Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
- Length = Request->Data.WriteConsoleOutputAttribRequest.Length;
- Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1];
- Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute;
- while (Length--)
- {
- *Buffer = (UCHAR)(*Attribute++);
- Buffer += 2;
- if (++X == Buff->MaxX)
- {
- if (++Y == Buff->MaxY)
- {
- Y = 0;
- Buffer = Buff->Buffer + 1;
- }
- X = 0;
- }
- }
-
- if (Buff == Console->ActiveBuffer)
- {
- ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord,
- Request->Data.WriteConsoleOutputAttribRequest.Length);
- ConioDrawRegion(Console, &UpdateRect);
- }
-
- Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X;
- Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrFillOutputAttrib)
-{
- PCSRSS_SCREEN_BUFFER Buff;
- PUCHAR Buffer;
- NTSTATUS Status;
- int X, Y, Length;
- UCHAR Attr;
- SMALL_RECT UpdateRect;
- PCSRSS_CONSOLE Console;
-
- DPRINT("CsrFillOutputAttrib\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- X = Request->Data.FillOutputAttribRequest.Coord.X;
- Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
- Length = Request->Data.FillOutputAttribRequest.Length;
- Attr = Request->Data.FillOutputAttribRequest.Attribute;
- Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1];
- while (Length--)
- {
- *Buffer = Attr;
- Buffer += 2;
- if (++X == Buff->MaxX)
- {
- if (++Y == Buff->MaxY)
- {
- Y = 0;
- Buffer = Buff->Buffer + 1;
- }
- X = 0;
- }
- }
-
- if (Buff == Console->ActiveBuffer)
- {
- ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord,
- Request->Data.FillOutputAttribRequest.Length);
- ConioDrawRegion(Console, &UpdateRect);
- }
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-DWORD FASTCALL
-ConioEffectiveCursorSize(PCSRSS_CONSOLE Console, DWORD Scale)
-{
- DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
- /* If line input in progress, perhaps adjust for insert toggle */
- if (Console->LineBuffer && !Console->LineComplete && Console->LineInsertToggle)
- return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
- return Size;
-}
-
-CSR_API(CsrGetCursorInfo)
-{
- PCSRSS_SCREEN_BUFFER Buff;
- NTSTATUS Status;
-
- DPRINT("CsrGetCursorInfo\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible;
- Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize;
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrSetCursorInfo)
-{
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD Size;
- BOOL Visible;
- NTSTATUS Status;
-
- DPRINT("CsrSetCursorInfo\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
- Visible = Request->Data.SetCursorInfoRequest.Info.bVisible;
- if (Size < 1)
- {
- Size = 1;
- }
- if (100 < Size)
- {
- Size = 100;
- }
-
- if (Size != Buff->CursorInfo.dwSize
- || (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible))
- {
- Buff->CursorInfo.dwSize = Size;
- Buff->CursorInfo.bVisible = Visible;
-
- if (! ConioSetCursorInfo(Console, Buff))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrSetTextAttrib)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
-
- DPRINT("CsrSetTextAttrib\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
- if (Buff == Console->ActiveBuffer)
- {
- if (! ConioUpdateScreenInfo(Console, Buff))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrCreateScreenBuffer)
-{
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- NTSTATUS Status;
-
- DPRINT("CsrCreateScreenBuffer\n");
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
-
- if (Buff != NULL)
- {
- if (Console->ActiveBuffer)
- {
- Buff->MaxX = Console->ActiveBuffer->MaxX;
- Buff->MaxY = Console->ActiveBuffer->MaxY;
- Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible;
- Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize;
- }
- else
- {
- Buff->CursorInfo.bVisible = TRUE;
- Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
- }
-
- if (Buff->MaxX == 0)
- {
- Buff->MaxX = 80;
- }
-
- if (Buff->MaxY == 0)
- {
- Buff->MaxY = 25;
- }
-
- Status = CsrInitConsoleScreenBuffer(Console, Buff);
- if (NT_SUCCESS(Status))
- {
- Status = Win32CsrInsertObject(ProcessData,
- &Request->Data.CreateScreenBufferRequest.OutputHandle,
- &Buff->Header,
- Request->Data.CreateScreenBufferRequest.Access,
- Request->Data.CreateScreenBufferRequest.Inheritable,
- Request->Data.CreateScreenBufferRequest.ShareMode);
- }
- }
- else
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- ConioUnlockConsole(Console);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return Status;
-}
-
-CSR_API(CsrSetScreenBuffer)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
-
- DPRINT("CsrSetScreenBuffer\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- if (Buff == Console->ActiveBuffer)
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_SUCCESS;
- }
-
- /* If old buffer has no handles, it's now unreferenced */
- if (Console->ActiveBuffer->Header.HandleCount == 0)
- {
- ConioDeleteScreenBuffer(Console->ActiveBuffer);
- }
- /* tie console to new buffer */
- Console->ActiveBuffer = Buff;
- /* Redraw the console */
- ConioDrawConsole(Console);
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrWriteConsoleOutput)
-{
- SHORT i, X, Y, SizeX, SizeY;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- SMALL_RECT ScreenBuffer;
- CHAR_INFO* CurCharInfo;
- SMALL_RECT WriteRegion;
- CHAR_INFO* CharInfo;
- COORD BufferCoord;
- COORD BufferSize;
- NTSTATUS Status;
- PBYTE Ptr;
-
- DPRINT("CsrWriteConsoleOutput\n");
-
- Status = ConioLockScreenBuffer(ProcessData,
- Request->Data.WriteConsoleOutputRequest.ConsoleHandle,
- &Buff,
- GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
- BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord;
- CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo;
- if (!Win32CsrValidateBuffer(ProcessData, CharInfo,
- BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO)))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_ACCESS_VIOLATION;
- }
- WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion;
-
- SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
- SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion));
- WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
- WriteRegion.Right = WriteRegion.Left + SizeX - 1;
-
- /* Make sure WriteRegion is inside the screen buffer */
- ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
- if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
- {
- ConioUnlockScreenBuffer(Buff);
-
- /* It is okay to have a WriteRegion completely outside the screen buffer.
- No data is written then. */
- return STATUS_SUCCESS;
- }
-
- for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++)
- {
- CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
- Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y);
- for (X = WriteRegion.Left; X <= WriteRegion.Right; X++)
- {
- CHAR AsciiChar;
- if (Request->Data.WriteConsoleOutputRequest.Unicode)
- {
- ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
- }
- else
- {
- AsciiChar = CurCharInfo->Char.AsciiChar;
- }
- *Ptr++ = AsciiChar;
- *Ptr++ = CurCharInfo->Attributes;
- CurCharInfo++;
- }
- }
-
- ConioDrawRegion(Console, &WriteRegion);
-
- ConioUnlockScreenBuffer(Buff);
-
- Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.Left + SizeX - 1;
- Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
- Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.Left;
- Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.Top;
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrScrollConsoleScreenBuffer)
-{
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- SMALL_RECT ScreenBuffer;
- SMALL_RECT SrcRegion;
- SMALL_RECT DstRegion;
- SMALL_RECT UpdateRegion;
- SMALL_RECT ScrollRectangle;
- SMALL_RECT ClipRectangle;
- NTSTATUS Status;
- HANDLE ConsoleHandle;
- BOOLEAN UseClipRectangle;
- COORD DestinationOrigin;
- CHAR_INFO Fill;
- CHAR FillChar;
-
- DPRINT("CsrScrollConsoleScreenBuffer\n");
-
- ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle;
- UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle;
- DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin;
- Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill;
-
- Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- ScrollRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle;
-
- /* Make sure source rectangle is inside the screen buffer */
- ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
- if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_SUCCESS;
- }
-
- /* If the source was clipped on the left or top, adjust the destination accordingly */
- if (ScrollRectangle.Left < 0)
- {
- DestinationOrigin.X -= ScrollRectangle.Left;
- }
- if (ScrollRectangle.Top < 0)
- {
- DestinationOrigin.Y -= ScrollRectangle.Top;
- }
-
- if (UseClipRectangle)
- {
- ClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle;
- if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_SUCCESS;
- }
- }
- else
- {
- ClipRectangle = ScreenBuffer;
- }
-
- ConioInitRect(&DstRegion,
- DestinationOrigin.Y,
- DestinationOrigin.X,
- DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
- DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1);
-
- if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode)
- ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar);
- else
- FillChar = Fill.Char.AsciiChar;
-
- ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar);
-
- if (Buff == Console->ActiveBuffer)
- {
- ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion);
- if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle))
- {
- /* Draw update region */
- ConioDrawRegion(Console, &UpdateRegion);
- }
- }
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrReadConsoleOutputChar)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD Xpos, Ypos;
- PCHAR ReadBuffer;
- DWORD i;
- ULONG CharSize;
- CHAR Char;
-
- DPRINT("CsrReadConsoleOutputChar\n");
-
- ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String;
-
- CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X;
- Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
-
- for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i)
- {
- Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
-
- if(Request->Data.ReadConsoleOutputCharRequest.Unicode)
- {
- ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char);
- ReadBuffer += sizeof(WCHAR);
- }
- else
- *(ReadBuffer++) = Char;
-
- Xpos++;
-
- if (Xpos == Buff->MaxX)
- {
- Xpos = 0;
- Ypos++;
-
- if (Ypos == Buff->MaxY)
- {
- Ypos = 0;
- }
- }
- }
-
- *ReadBuffer = 0;
- Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos;
- Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
-
- ConioUnlockScreenBuffer(Buff);
-
- Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize;
- if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
- {
- DPRINT1("Length won't fit in message\n");
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-CSR_API(CsrReadConsoleOutputAttrib)
-{
- NTSTATUS Status;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD Xpos, Ypos;
- PWORD ReadBuffer;
- DWORD i;
- DWORD CurrentLength;
-
- DPRINT("CsrReadConsoleOutputAttrib\n");
-
- ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute;
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X;
- Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
-
- for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i)
- {
- *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1];
-
- ReadBuffer++;
- Xpos++;
-
- if (Xpos == Buff->MaxX)
- {
- Xpos = 0;
- Ypos++;
-
- if (Ypos == Buff->MaxY)
- {
- Ypos = 0;
- }
- }
- }
-
- *ReadBuffer = 0;
-
- Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos;
- Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
-
- ConioUnlockScreenBuffer(Buff);
-
- CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
- + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD);
- if (CurrentLength > sizeof(CSR_API_MESSAGE))
- {
- DPRINT1("Length won't fit in message\n");
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrReadConsoleOutput)
-{
- PCHAR_INFO CharInfo;
- PCHAR_INFO CurCharInfo;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD SizeX, SizeY;
- NTSTATUS Status;
- COORD BufferSize;
- COORD BufferCoord;
- SMALL_RECT ReadRegion;
- SMALL_RECT ScreenRect;
- DWORD i;
- PBYTE Ptr;
- LONG X, Y;
- UINT CodePage;
-
- DPRINT("CsrReadConsoleOutput\n");
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
- ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion;
- BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize;
- BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord;
-
- /* FIXME: Is this correct? */
- CodePage = ProcessData->Console->OutputCodePage;
-
- if (!Win32CsrValidateBuffer(ProcessData, CharInfo,
- BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO)))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_ACCESS_VIOLATION;
- }
-
- SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
- SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion));
- ReadRegion.Bottom = ReadRegion.Top + SizeY;
- ReadRegion.Right = ReadRegion.Left + SizeX;
-
- ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX);
- if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_SUCCESS;
- }
-
- for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y)
- {
- CurCharInfo = CharInfo + (i * BufferSize.X);
-
- Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y);
- for (X = ReadRegion.Left; X < ReadRegion.Right; ++X)
- {
- if (Request->Data.ReadConsoleOutputRequest.Unicode)
- {
- MultiByteToWideChar(CodePage, 0,
- (PCHAR)Ptr++, 1,
- &CurCharInfo->Char.UnicodeChar, 1);
- }
- else
- {
- CurCharInfo->Char.AsciiChar = *Ptr++;
- }
- CurCharInfo->Attributes = *Ptr++;
- ++CurCharInfo;
- }
- }
-
- ConioUnlockScreenBuffer(Buff);
-
- Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.Left + SizeX - 1;
- Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1;
- Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.Left;
- Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.Top;
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrSetScreenBufferSize)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
-
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size);
- ConioUnlockScreenBuffer(Buff);
-
- return Status;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * reactos/subsys/csrss/win32csr/conio.c
- *
- * Console I/O functions
- *
- * ReactOS Operating System
- */
-
-/* INCLUDES ******************************************************************/
-
-#define NDEBUG
-#include "w32csr.h"
-#include <debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS FASTCALL
-ConioConsoleFromProcessData(PCSR_PROCESS ProcessData, PCSRSS_CONSOLE *Console)
-{
- PCSRSS_CONSOLE ProcessConsole;
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- ProcessConsole = ProcessData->Console;
-
- if (!ProcessConsole)
- {
- *Console = NULL;
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_HANDLE;
- }
-
- InterlockedIncrement(&ProcessConsole->ReferenceCount);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- EnterCriticalSection(&(ProcessConsole->Lock));
- *Console = ProcessConsole;
-
- return STATUS_SUCCESS;
-}
-
-VOID FASTCALL
-ConioConsoleCtrlEventTimeout(DWORD Event, PCSR_PROCESS ProcessData, DWORD Timeout)
-{
- HANDLE Thread;
-
- DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ClientId.UniqueProcess);
-
- if (ProcessData->CtrlDispatcher)
- {
-
- Thread = CreateRemoteThread(ProcessData->ProcessHandle, NULL, 0,
- (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
- UlongToPtr(Event), 0, NULL);
- if (NULL == Thread)
- {
- DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
- return;
- }
- WaitForSingleObject(Thread, Timeout);
- CloseHandle(Thread);
- }
-}
-
-VOID FASTCALL
-ConioConsoleCtrlEvent(DWORD Event, PCSR_PROCESS ProcessData)
-{
- ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
-}
-
-static NTSTATUS WINAPI
-CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
-{
- NTSTATUS Status;
- SECURITY_ATTRIBUTES SecurityAttributes;
- PCSRSS_SCREEN_BUFFER NewBuffer;
- BOOL GuiMode;
- WCHAR Title[255];
- HINSTANCE hInst;
-
- Console->Title.MaximumLength = Console->Title.Length = 0;
- Console->Title.Buffer = NULL;
-
- hInst = GetModuleHandleW(L"win32csr");
- if (LoadStringW(hInst,IDS_COMMAND_PROMPT,Title,sizeof(Title)/sizeof(Title[0])))
- {
- RtlCreateUnicodeString(&Console->Title, Title);
- }
- else
- {
- RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
- }
-
- Console->ReferenceCount = 0;
- Console->LineBuffer = NULL;
- Console->Header.Type = CONIO_CONSOLE_MAGIC;
- Console->Header.Console = Console;
- Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
- InitializeListHead(&Console->BufferList);
- Console->ActiveBuffer = NULL;
- InitializeListHead(&Console->InputEvents);
- InitializeListHead(&Console->HistoryBuffers);
- Console->CodePage = GetOEMCP();
- Console->OutputCodePage = GetOEMCP();
-
- SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
- SecurityAttributes.lpSecurityDescriptor = NULL;
- SecurityAttributes.bInheritHandle = TRUE;
-
- Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
- if (NULL == Console->ActiveEvent)
- {
- RtlFreeUnicodeString(&Console->Title);
- return STATUS_UNSUCCESSFUL;
- }
- Console->PrivateData = NULL;
- InitializeCriticalSection(&Console->Lock);
-
- GuiMode = DtbgIsDesktopVisible();
-
- /* allocate console screen buffer */
- NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
- if (NULL == NewBuffer)
- {
- RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Lock);
- CloseHandle(Console->ActiveEvent);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- /* init screen buffer with defaults */
- NewBuffer->CursorInfo.bVisible = TRUE;
- NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
- /* make console active, and insert into console list */
- Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
-
- /*
- * If we are not in GUI-mode, start the text-mode console. If we fail,
- * try to start the GUI-mode console (win32k will automatically switch
- * to graphical mode, therefore no additional code is needed).
- */
- if (!GuiMode)
- {
- DPRINT1("WIN32CSR: Opening text-mode console\n");
- Status = TuiInitConsole(Console);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status);
- GuiMode = TRUE;
- }
- }
-
- /*
- * Try to open the GUI-mode console. Two cases are possible:
- * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
- * failed and we start GUI-mode console.
- * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
- * succeeded BUT we failed at starting text-mode console. Then GuiMode
- * was switched to TRUE in order to try to open the console in GUI-mode.
- */
- if (GuiMode)
- {
- DPRINT1("WIN32CSR: Opening GUI-mode console\n");
- Status = GuiInitConsole(Console, ShowCmd);
- if (!NT_SUCCESS(Status))
- {
- HeapFree(Win32CsrApiHeap,0, NewBuffer);
- RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Lock);
- CloseHandle(Console->ActiveEvent);
- DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status);
- return Status;
- }
- }
-
- Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
- if (!NT_SUCCESS(Status))
- {
- ConioCleanupConsole(Console);
- RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Lock);
- CloseHandle(Console->ActiveEvent);
- HeapFree(Win32CsrApiHeap, 0, NewBuffer);
- DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
- return Status;
- }
-
- /* copy buffer contents to screen */
- ConioDrawConsole(Console);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrAllocConsole)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status = STATUS_SUCCESS;
- BOOLEAN NewConsole = FALSE;
-
- DPRINT("CsrAllocConsole\n");
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (ProcessData->Console)
- {
- DPRINT1("Process already has a console\n");
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_PARAMETER;
- }
-
- /* If we don't need a console, then get out of here */
- if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
- {
- DPRINT("No console needed\n");
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_SUCCESS;
- }
-
- /* If we already have one, then don't create a new one... */
- if (!Request->Data.AllocConsoleRequest.Console ||
- Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole)
- {
- /* Allocate a console structure */
- NewConsole = TRUE;
- Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE));
- if (NULL == Console)
- {
- DPRINT1("Not enough memory for console\n");
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_NO_MEMORY;
- }
- /* initialize list head */
- InitializeListHead(&Console->ProcessList);
- /* insert process data required for GUI initialization */
- InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
- /* Initialize the Console */
- Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.ShowCmd);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Console init failed\n");
- HeapFree(Win32CsrApiHeap, 0, Console);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return Status;
- }
- }
- else
- {
- /* Reuse our current console */
- Console = Request->Data.AllocConsoleRequest.Console;
- }
-
- /* Set the Process Console */
- ProcessData->Console = Console;
-
- /* Return it to the caller */
- Request->Data.AllocConsoleRequest.Console = Console;
-
- /* Add a reference count because the process is tied to the console */
- _InterlockedIncrement(&Console->ReferenceCount);
-
- if (NewConsole || !ProcessData->bInheritHandles)
- {
- /* Insert the Objects */
- Status = Win32CsrInsertObject(ProcessData,
- &Request->Data.AllocConsoleRequest.InputHandle,
- &Console->Header,
- GENERIC_READ | GENERIC_WRITE,
- TRUE,
- FILE_SHARE_READ | FILE_SHARE_WRITE);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to insert object\n");
- ConioDeleteConsole((Object_t *) Console);
- ProcessData->Console = 0;
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return Status;
- }
-
- Status = Win32CsrInsertObject(ProcessData,
- &Request->Data.AllocConsoleRequest.OutputHandle,
- &Console->ActiveBuffer->Header,
- GENERIC_READ | GENERIC_WRITE,
- TRUE,
- FILE_SHARE_READ | FILE_SHARE_WRITE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to insert object\n");
- ConioDeleteConsole((Object_t *) Console);
- Win32CsrReleaseObject(ProcessData,
- Request->Data.AllocConsoleRequest.InputHandle);
- ProcessData->Console = 0;
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return Status;
- }
- }
-
- /* Duplicate the Event */
- if (!DuplicateHandle(GetCurrentProcess(),
- ProcessData->Console->ActiveEvent,
- ProcessData->ProcessHandle,
- &ProcessData->ConsoleEvent,
- EVENT_ALL_ACCESS,
- FALSE,
- 0))
- {
- DPRINT1("DuplicateHandle() failed: %lu\n", GetLastError());
- ConioDeleteConsole((Object_t *) Console);
- if (NewConsole || !ProcessData->bInheritHandles)
- {
- Win32CsrReleaseObject(ProcessData,
- Request->Data.AllocConsoleRequest.OutputHandle);
- Win32CsrReleaseObject(ProcessData,
- Request->Data.AllocConsoleRequest.InputHandle);
- }
- ProcessData->Console = 0;
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return Status;
- }
-
- /* Set the Ctrl Dispatcher */
- ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
- DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
-
- if (!NewConsole)
- {
- /* Insert into the list if it has not been added */
- InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
- }
-
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrFreeConsole)
-{
- Win32CsrReleaseConsole(ProcessData);
- return STATUS_SUCCESS;
-}
-
-VOID WINAPI
-ConioDeleteConsole(Object_t *Object)
-{
- PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
- ConsoleInput *Event;
-
- DPRINT("ConioDeleteConsole\n");
-
- /* Drain input event queue */
- while (Console->InputEvents.Flink != &Console->InputEvents)
- {
- Event = (ConsoleInput *) Console->InputEvents.Flink;
- Console->InputEvents.Flink = Console->InputEvents.Flink->Flink;
- Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents;
- HeapFree(Win32CsrApiHeap, 0, Event);
- }
-
- ConioCleanupConsole(Console);
- if (Console->LineBuffer)
- RtlFreeHeap(Win32CsrApiHeap, 0, Console->LineBuffer);
- while (!IsListEmpty(&Console->HistoryBuffers))
- HistoryDeleteBuffer((struct tagHISTORY_BUFFER *)Console->HistoryBuffers.Flink);
-
- ConioDeleteScreenBuffer(Console->ActiveBuffer);
- if (!IsListEmpty(&Console->BufferList))
- {
- DPRINT1("BUG: screen buffer list not empty\n");
- }
-
- CloseHandle(Console->ActiveEvent);
- if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
- DeleteCriticalSection(&Console->Lock);
- RtlFreeUnicodeString(&Console->Title);
- IntDeleteAllAliases(Console->Aliases);
- HeapFree(Win32CsrApiHeap, 0, Console);
-}
-
-VOID WINAPI
-CsrInitConsoleSupport(VOID)
-{
- DPRINT("CSR: CsrInitConsoleSupport()\n");
-
- /* Should call LoadKeyboardLayout */
-}
-
-VOID FASTCALL
-ConioPause(PCSRSS_CONSOLE Console, UINT Flags)
-{
- Console->PauseFlags |= Flags;
- if (!Console->UnpauseEvent)
- Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-}
-
-VOID FASTCALL
-ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags)
-{
- Console->PauseFlags &= ~Flags;
- if (Console->PauseFlags == 0 && Console->UnpauseEvent)
- {
- SetEvent(Console->UnpauseEvent);
- CloseHandle(Console->UnpauseEvent);
- Console->UnpauseEvent = NULL;
- }
-}
-
-CSR_API(CsrSetConsoleMode)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
-
- DPRINT("CsrSetConsoleMode\n");
-
- Status = Win32CsrLockObject(ProcessData,
- Request->Data.SetConsoleModeRequest.ConsoleHandle,
- (Object_t **) &Console, GENERIC_WRITE, 0);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Buff = (PCSRSS_SCREEN_BUFFER)Console;
- if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
- {
- Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID;
- }
- else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type)
- {
- Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID;
- }
- else
- {
- Status = STATUS_INVALID_HANDLE;
- }
-
- Win32CsrUnlockObject((Object_t *)Console);
-
- return Status;
-}
-
-CSR_API(CsrGetConsoleMode)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */
-
- DPRINT("CsrGetConsoleMode\n");
-
- Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
- (Object_t **) &Console, GENERIC_READ, 0);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Status = STATUS_SUCCESS;
- Buff = (PCSRSS_SCREEN_BUFFER) Console;
- if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
- {
- Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode;
- }
- else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type)
- {
- Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode;
- }
- else
- {
- Status = STATUS_INVALID_HANDLE;
- }
-
- Win32CsrUnlockObject((Object_t *)Console);
- return Status;
-}
-
-CSR_API(CsrSetTitle)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- PWCHAR Buffer;
-
- DPRINT("CsrSetTitle\n");
-
- if (!Win32CsrValidateBuffer(ProcessData, Request->Data.SetTitleRequest.Title,
- Request->Data.SetTitleRequest.Length, 1))
- {
- return STATUS_ACCESS_VIOLATION;
- }
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if(NT_SUCCESS(Status))
- {
- Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length);
- if (Buffer)
- {
- /* copy title to console */
- RtlFreeUnicodeString(&Console->Title);
- Console->Title.Buffer = Buffer;
- Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length;
- memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length);
- if (! ConioChangeTitle(Console))
- {
- Status = STATUS_UNSUCCESSFUL;
- }
- else
- {
- Status = STATUS_SUCCESS;
- }
- }
- else
- {
- Status = STATUS_NO_MEMORY;
- }
- ConioUnlockConsole(Console);
- }
-
- return Status;
-}
-
-CSR_API(CsrGetTitle)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
- DWORD Length;
-
- DPRINT("CsrGetTitle\n");
-
-
- if (!Win32CsrValidateBuffer(ProcessData, Request->Data.GetTitleRequest.Title,
- Request->Data.GetTitleRequest.Length, 1))
- {
- return STATUS_ACCESS_VIOLATION;
- }
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Can't get console\n");
- return Status;
- }
-
- /* Copy title of the console to the user title buffer */
- if (Request->Data.GetTitleRequest.Length >= sizeof(WCHAR))
- {
- Length = min(Request->Data.GetTitleRequest.Length - sizeof(WCHAR), Console->Title.Length);
- memcpy(Request->Data.GetTitleRequest.Title, Console->Title.Buffer, Length);
- Request->Data.GetTitleRequest.Title[Length / sizeof(WCHAR)] = L'\0';
- }
-
- Request->Data.GetTitleRequest.Length = Console->Title.Length;
-
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
-}
-
-/**********************************************************************
- * HardwareStateProperty
- *
- * DESCRIPTION
- * Set/Get the value of the HardwareState and switch
- * between direct video buffer ouput and GDI windowed
- * output.
- * ARGUMENTS
- * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
- * object. We use the same object to Request.
- * NOTE
- * ConsoleHwState has the correct size to be compatible
- * with NT's, but values are not.
- */
-static NTSTATUS FASTCALL
-SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
-{
- DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
-
- if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
- ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
- {
- if (Console->HardwareState != ConsoleHwState)
- {
- /* TODO: implement switching from full screen to windowed mode */
- /* TODO: or back; now simply store the hardware state */
- Console->HardwareState = ConsoleHwState;
- }
-
- return STATUS_SUCCESS;
- }
-
- return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
-}
-
-CSR_API(CsrHardwareStateProperty)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("CsrHardwareStateProperty\n");
-
- Status = ConioLockConsole(ProcessData,
- Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
- &Console,
- GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
- return Status;
- }
-
- switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
- {
- case CONSOLE_HARDWARE_STATE_GET:
- Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState;
- break;
-
- case CONSOLE_HARDWARE_STATE_SET:
- DPRINT("Setting console hardware state.\n");
- Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
- break;
-
- default:
- Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
- break;
- }
-
- ConioUnlockConsole(Console);
-
- return Status;
-}
-
-CSR_API(CsrGetConsoleWindow)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("CsrGetConsoleWindow\n");
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow;
- ConioUnlockConsole(Console);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrSetConsoleIcon)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("CsrSetConsoleIcon\n");
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon)
- ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
- ConioUnlockConsole(Console);
-
- return Status;
-}
-
-CSR_API(CsrGetConsoleCodePage)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("CsrGetConsoleCodePage\n");
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Request->Data.GetConsoleCodePage.CodePage = Console->CodePage;
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrSetConsoleCodePage)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("CsrSetConsoleCodePage\n");
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
- {
- Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
- }
-
- ConioUnlockConsole(Console);
- return STATUS_INVALID_PARAMETER;
-}
-
-CSR_API(CsrGetConsoleOutputCodePage)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("CsrGetConsoleOutputCodePage\n");
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrSetConsoleOutputCodePage)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("CsrSetConsoleOutputCodePage\n");
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
- {
- Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
- ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
- }
-
- ConioUnlockConsole(Console);
- return STATUS_INVALID_PARAMETER;
-}
-
-CSR_API(CsrGetProcessList)
-{
- PDWORD Buffer;
- PCSRSS_CONSOLE Console;
- PCSR_PROCESS current;
- PLIST_ENTRY current_entry;
- ULONG nItems = 0;
- NTSTATUS Status;
-
- DPRINT("CsrGetProcessList\n");
-
- Buffer = Request->Data.GetProcessListRequest.ProcessId;
- if (!Win32CsrValidateBuffer(ProcessData, Buffer, Request->Data.GetProcessListRequest.nMaxIds, sizeof(DWORD)))
- return STATUS_ACCESS_VIOLATION;
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- for (current_entry = Console->ProcessList.Flink;
- current_entry != &Console->ProcessList;
- current_entry = current_entry->Flink)
- {
- current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
- if (++nItems <= Request->Data.GetProcessListRequest.nMaxIds)
- {
- *Buffer++ = HandleToUlong(current->ClientId.UniqueProcess);
- }
- }
-
- ConioUnlockConsole(Console);
-
- Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems;
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrGenerateCtrlEvent)
-{
- PCSRSS_CONSOLE Console;
- PCSR_PROCESS current;
- PLIST_ENTRY current_entry;
- DWORD Group;
- NTSTATUS Status;
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Group = Request->Data.GenerateCtrlEvent.ProcessGroup;
- Status = STATUS_INVALID_PARAMETER;
- for (current_entry = Console->ProcessList.Flink;
- current_entry != &Console->ProcessList;
- current_entry = current_entry->Flink)
- {
- current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
- if (Group == 0 || current->ProcessGroupId == Group)
- {
- ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current);
- Status = STATUS_SUCCESS;
- }
- }
-
- ConioUnlockConsole(Console);
-
- return Status;
-}
-
-CSR_API(CsrGetConsoleSelectionInfo)
-{
- NTSTATUS Status;
- PCSRSS_CONSOLE Console;
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (NT_SUCCESS(Status))
- {
- memset(&Request->Data.GetConsoleSelectionInfo.Info, 0, sizeof(CONSOLE_SELECTION_INFO));
- if (Console->Selection.dwFlags != 0)
- Request->Data.GetConsoleSelectionInfo.Info = Console->Selection;
- ConioUnlockConsole(Console);
- }
- return Status;
-}
-
-/* EOF */
+++ /dev/null
-#define NDEBUG
-
-#include "w32csr.h"
-#include <debug.h>
-
-CSR_API(CsrCreateDesktop)
-{
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrShowDesktop)
-{
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrHideDesktop)
-{
- return STATUS_SUCCESS;
-}
-
-BOOL
-FASTCALL DtbgIsDesktopVisible(VOID)
-{
- return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/include/destkopbg.h
- * PURPOSE: CSRSS internal desktop background window interface
- */
-
-#pragma once
-
-#include "api.h"
-
-/* Api functions */
-CSR_API(CsrCreateDesktop);
-CSR_API(CsrShowDesktop);
-CSR_API(CsrHideDesktop);
-CSR_API(CsrRegisterSystemClasses);
-
-BOOL FASTCALL DtbgIsDesktopVisible(VOID);
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/dllmain.c
- * PURPOSE: Initialization
- * PROGRAMMERS: Dmitry Philippov (shedon@mail.ru)
- */
-
-/* INCLUDES ******************************************************************/
-#define NDEBUG
-#include "w32csr.h"
-#include "file.h"
-#include <debug.h>
-
-/* Not defined in any header file */
-extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check);
-extern LIST_ENTRY DosDeviceHistory;
-extern RTL_CRITICAL_SECTION Win32CsrDefineDosDeviceCritSec;
-
-/* GLOBALS *******************************************************************/
-
-HANDLE Win32CsrApiHeap;
-HINSTANCE Win32CsrDllHandle = NULL;
-
-static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] =
-{
- CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetHandle),
- CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetHandle),
- CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle),
- CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle),
- CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle),
- CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle),
- CSRSS_DEFINE_API(WRITE_CONSOLE, CsrWriteConsole),
- CSRSS_DEFINE_API(READ_CONSOLE, CsrReadConsole),
- CSRSS_DEFINE_API(ALLOC_CONSOLE, CsrAllocConsole),
- CSRSS_DEFINE_API(FREE_CONSOLE, CsrFreeConsole),
- CSRSS_DEFINE_API(SCREEN_BUFFER_INFO, CsrGetScreenBufferInfo),
- CSRSS_DEFINE_API(SET_CURSOR, CsrSetCursor),
- CSRSS_DEFINE_API(FILL_OUTPUT, CsrFillOutputChar),
- CSRSS_DEFINE_API(READ_INPUT, CsrReadInputEvent),
- CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT_CHAR, CsrWriteConsoleOutputChar),
- CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CsrWriteConsoleOutputAttrib),
- CSRSS_DEFINE_API(FILL_OUTPUT_ATTRIB, CsrFillOutputAttrib),
- CSRSS_DEFINE_API(GET_CURSOR_INFO, CsrGetCursorInfo),
- CSRSS_DEFINE_API(SET_CURSOR_INFO, CsrSetCursorInfo),
- CSRSS_DEFINE_API(SET_ATTRIB, CsrSetTextAttrib),
- CSRSS_DEFINE_API(GET_CONSOLE_MODE, CsrGetConsoleMode),
- CSRSS_DEFINE_API(SET_CONSOLE_MODE, CsrSetConsoleMode),
- CSRSS_DEFINE_API(CREATE_SCREEN_BUFFER, CsrCreateScreenBuffer),
- CSRSS_DEFINE_API(SET_SCREEN_BUFFER, CsrSetScreenBuffer),
- CSRSS_DEFINE_API(SET_TITLE, CsrSetTitle),
- CSRSS_DEFINE_API(GET_TITLE, CsrGetTitle),
- CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT, CsrWriteConsoleOutput),
- CSRSS_DEFINE_API(FLUSH_INPUT_BUFFER, CsrFlushInputBuffer),
- CSRSS_DEFINE_API(SCROLL_CONSOLE_SCREEN_BUFFER, CsrScrollConsoleScreenBuffer),
- CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT_CHAR, CsrReadConsoleOutputChar),
- CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT_ATTRIB, CsrReadConsoleOutputAttrib),
- CSRSS_DEFINE_API(GET_NUM_INPUT_EVENTS, CsrGetNumberOfConsoleInputEvents),
- CSRSS_DEFINE_API(EXIT_REACTOS, CsrExitReactos),
- CSRSS_DEFINE_API(PEEK_CONSOLE_INPUT, CsrPeekConsoleInput),
- CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT, CsrReadConsoleOutput),
- CSRSS_DEFINE_API(WRITE_CONSOLE_INPUT, CsrWriteConsoleInput),
- CSRSS_DEFINE_API(SETGET_CONSOLE_HW_STATE, CsrHardwareStateProperty),
- CSRSS_DEFINE_API(GET_CONSOLE_WINDOW, CsrGetConsoleWindow),
- CSRSS_DEFINE_API(CREATE_DESKTOP, CsrCreateDesktop),
- CSRSS_DEFINE_API(SHOW_DESKTOP, CsrShowDesktop),
- CSRSS_DEFINE_API(HIDE_DESKTOP, CsrHideDesktop),
- CSRSS_DEFINE_API(SET_CONSOLE_ICON, CsrSetConsoleIcon),
- CSRSS_DEFINE_API(SET_LOGON_NOTIFY_WINDOW, CsrSetLogonNotifyWindow),
- CSRSS_DEFINE_API(REGISTER_LOGON_PROCESS, CsrRegisterLogonProcess),
- CSRSS_DEFINE_API(GET_CONSOLE_CP, CsrGetConsoleCodePage),
- CSRSS_DEFINE_API(SET_CONSOLE_CP, CsrSetConsoleCodePage),
- CSRSS_DEFINE_API(GET_CONSOLE_OUTPUT_CP, CsrGetConsoleOutputCodePage),
- CSRSS_DEFINE_API(SET_CONSOLE_OUTPUT_CP, CsrSetConsoleOutputCodePage),
- CSRSS_DEFINE_API(GET_PROCESS_LIST, CsrGetProcessList),
- CSRSS_DEFINE_API(ADD_CONSOLE_ALIAS, CsrAddConsoleAlias),
- CSRSS_DEFINE_API(GET_CONSOLE_ALIAS, CsrGetConsoleAlias),
- CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES, CsrGetAllConsoleAliases),
- CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CsrGetAllConsoleAliasesLength),
- CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES, CsrGetConsoleAliasesExes),
- CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength),
- CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent),
- CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize),
- CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO, CsrGetConsoleSelectionInfo),
- CSRSS_DEFINE_API(GET_COMMAND_HISTORY_LENGTH, CsrGetCommandHistoryLength),
- CSRSS_DEFINE_API(GET_COMMAND_HISTORY, CsrGetCommandHistory),
- CSRSS_DEFINE_API(EXPUNGE_COMMAND_HISTORY, CsrExpungeCommandHistory),
- CSRSS_DEFINE_API(SET_HISTORY_NUMBER_COMMANDS, CsrSetHistoryNumberCommands),
- CSRSS_DEFINE_API(GET_HISTORY_INFO, CsrGetHistoryInfo),
- CSRSS_DEFINE_API(SET_HISTORY_INFO, CsrSetHistoryInfo),
- CSRSS_DEFINE_API(GET_TEMP_FILE, CsrGetTempFile),
- CSRSS_DEFINE_API(DEFINE_DOS_DEVICE, CsrDefineDosDevice),
- CSRSS_DEFINE_API(SOUND_SENTRY, CsrSoundSentry),
- { 0, 0, NULL }
-};
-
-static HHOOK hhk = NULL;
-
-/* FUNCTIONS *****************************************************************/
-
-LRESULT
-CALLBACK
-KeyboardHookProc(
- int nCode,
- WPARAM wParam,
- LPARAM lParam)
-{
- return CallNextHookEx(hhk, nCode, wParam, lParam);
-}
-
-ULONG
-InitializeVideoAddressSpace(VOID)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
- NTSTATUS Status;
- HANDLE PhysMemHandle;
- PVOID BaseAddress;
- LARGE_INTEGER Offset;
- SIZE_T ViewSize;
- CHAR IVTAndBda[1024+256];
-
- /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
- BaseAddress = 0;
- ViewSize = 1024 * 1024;
- Status = ZwFreeVirtualMemory(NtCurrentProcess(),
- &BaseAddress,
- &ViewSize,
- MEM_RELEASE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
- return 0;
- }
-
- /* Open the physical memory section */
- InitializeObjectAttributes(&ObjectAttributes,
- &PhysMemName,
- 0,
- NULL,
- NULL);
- Status = ZwOpenSection(&PhysMemHandle,
- SECTION_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
- return 0;
- }
-
- /* Map the BIOS and device registers into the address space */
- Offset.QuadPart = 0xa0000;
- ViewSize = 0x100000 - 0xa0000;
- BaseAddress = (PVOID)0xa0000;
- Status = ZwMapViewOfSection(PhysMemHandle,
- NtCurrentProcess(),
- &BaseAddress,
- 0,
- ViewSize,
- &Offset,
- &ViewSize,
- ViewUnmap,
- 0,
- PAGE_EXECUTE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Couldn't map physical memory (%x)\n", Status);
- ZwClose(PhysMemHandle);
- return 0;
- }
-
- /* Close physical memory section handle */
- ZwClose(PhysMemHandle);
-
- if (BaseAddress != (PVOID)0xa0000)
- {
- DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
- BaseAddress);
- return 0;
- }
-
- /* Allocate some low memory to use for the non-BIOS
- * parts of the v86 mode address space
- */
- BaseAddress = (PVOID)0x1;
- ViewSize = 0xa0000 - 0x1000;
- Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
- &BaseAddress,
- 0,
- &ViewSize,
- MEM_RESERVE | MEM_COMMIT,
- PAGE_EXECUTE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
- return 0;
- }
- if (BaseAddress != (PVOID)0x0)
- {
- DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
- BaseAddress);
- return 0;
- }
-
- /* Get the real mode IVT and BDA from the kernel */
- Status = NtVdmControl(VdmInitialize, IVTAndBda);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtVdmControl failed (status %x)\n", Status);
- return 0;
- }
-
- /* Return success */
- return 1;
-}
-
-/**********************************************************************
- * CsrpInitVideo/3
- *
- * TODO: we need a virtual device for sessions other than
- * TODO: the console one
- */
-NTSTATUS
-CsrpInitVideo (VOID)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1");
- IO_STATUS_BLOCK Iosb;
- HANDLE VideoHandle = (HANDLE) 0;
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT("CSR: %s called\n", __FUNCTION__);
-
- InitializeVideoAddressSpace();
-
- InitializeObjectAttributes(&ObjectAttributes,
- &DeviceName,
- 0,
- NULL,
- NULL);
- Status = NtOpenFile(&VideoHandle,
- FILE_ALL_ACCESS,
- &ObjectAttributes,
- &Iosb,
- 0,
- 0);
- if (NT_SUCCESS(Status))
- {
- NtClose(VideoHandle);
- }
- return Status;
-}
-
-BOOL WINAPI
-DllMain(HANDLE hDll,
- DWORD dwReason,
- LPVOID lpReserved)
-{
- if (DLL_PROCESS_ATTACH == dwReason)
- {
- Win32CsrDllHandle = hDll;
-//
-// HACK HACK HACK ReactOS to BOOT! Initialization BUG ALERT! See bug 5655.
-//
- hhk = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, NULL, 0);
-// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
-// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
-// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
- }
-
- if (DLL_PROCESS_DETACH == dwReason)
- {
- CsrCleanupDefineDosDevice();
- }
- return TRUE;
-}
-
-/* Ensure that a captured buffer is safe to access */
-BOOL FASTCALL
-Win32CsrValidateBuffer(PCSR_PROCESS ProcessData, PVOID Buffer,
- SIZE_T NumElements, SIZE_T ElementSize)
-{
- /* Check that the following conditions are true:
- * 1. The start of the buffer is somewhere within the process's
- * shared memory section view.
- * 2. The remaining space in the view is at least as large as the buffer.
- * (NB: Please don't try to "optimize" this by using multiplication
- * instead of division; remember that 2147483648 * 2 = 0.)
- * 3. The buffer is DWORD-aligned.
- */
- ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->ClientViewBase;
- if (Offset >= ProcessData->ClientViewBounds
- || NumElements > (ProcessData->ClientViewBounds - Offset) / ElementSize
- || (Offset & (sizeof(DWORD) - 1)) != 0)
- {
- DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n",
- Buffer, NumElements, ElementSize,
- ProcessData->ClientViewBase, ProcessData->ClientViewBounds);
- return FALSE;
- }
- return TRUE;
-}
-
-NTSTATUS FASTCALL
-Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc,
- PVOID Context)
-{
- return CsrEnumProcesses(EnumProc, Context);
-}
-
-VOID
-WINAPI
-PrivateCsrssManualGuiCheck(LONG Check)
-{
- NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK);
-}
-
-DWORD
-WINAPI
-CreateSystemThreads(PVOID pParam)
-{
- NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
- DPRINT1("This thread should not terminate!\n");
- return 0;
-}
-
-NTSTATUS
-WINAPI
-Win32CsrInitialization(IN PCSR_SERVER_DLL ServerDll)
-{
- HANDLE ServerThread;
- CLIENT_ID ClientId;
- NTSTATUS Status;
- UINT i;
-
- Win32CsrApiHeap = RtlGetProcessHeap();
-
- CsrpInitVideo();
-
- NtUserInitialize(0, NULL, NULL);
-
- PrivateCsrssManualGuiCheck(0);
- CsrInitConsoleSupport();
-
- /* HACK */
- ServerDll->DispatchTable = (PVOID)Win32CsrApiDefinitions;
- ServerDll->HighestApiSupported = 0xDEADBABE;
-
- ServerDll->HardErrorCallback = Win32CsrHardError;
- ServerDll->NewProcessCallback = Win32CsrDuplicateHandleTable;
- ServerDll->DisconnectCallback = Win32CsrReleaseConsole;
-
- RtlInitializeCriticalSection(&Win32CsrDefineDosDeviceCritSec);
- InitializeListHead(&DosDeviceHistory);
-
- /* Start the Raw Input Thread and the Desktop Thread */
- for (i = 0; i < 2; ++i)
- {
- Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)i, &ServerThread, &ClientId);
- if (NT_SUCCESS(Status))
- {
- NtResumeThread(ServerThread, NULL);
- NtClose(ServerThread);
- }
- else
- DPRINT1("Cannot start Raw Input Thread!\n");
- }
-
- return STATUS_SUCCESS;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSRSS subsystem
- * FILE: subsys/csrss/win32csr/exitros.c
- * PURPOSE: Logout/shutdown
- */
-
-/* INCLUDES ******************************************************************/
-#define NDEBUG
-#include "w32csr.h"
-#include <sddl.h>
-#include "resource.h"
-#include <debug.h>
-
-static HANDLE LogonProcess = NULL;
-
-CSR_API(CsrRegisterLogonProcess)
-{
- if (Request->Data.RegisterLogonProcessRequest.Register)
- {
- if (0 != LogonProcess)
- {
- return STATUS_LOGON_SESSION_EXISTS;
- }
- LogonProcess = Request->Data.RegisterLogonProcessRequest.ProcessId;
- }
- else
- {
- if (Request->Header.ClientId.UniqueProcess != LogonProcess)
- {
- DPRINT1("Current logon process 0x%x, can't deregister from process 0x%x\n",
- LogonProcess, Request->Header.ClientId.UniqueProcess);
- return STATUS_NOT_LOGON_PROCESS;
- }
- LogonProcess = 0;
- }
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrSetLogonNotifyWindow)
-{
- return STATUS_SUCCESS;
-}
-
-typedef struct tagSHUTDOWN_SETTINGS
-{
- BOOL AutoEndTasks;
- DWORD HungAppTimeout;
- DWORD WaitToKillAppTimeout;
-} SHUTDOWN_SETTINGS, *PSHUTDOWN_SETTINGS;
-
-#define DEFAULT_AUTO_END_TASKS FALSE
-#define DEFAULT_HUNG_APP_TIMEOUT 5000
-#define DEFAULT_WAIT_TO_KILL_APP_TIMEOUT 20000
-
-typedef struct tagNOTIFY_CONTEXT
-{
- DWORD ProcessId;
- UINT Msg;
- WPARAM wParam;
- LPARAM lParam;
- HDESK Desktop;
- HDESK OldDesktop;
- DWORD StartTime;
- DWORD QueryResult;
- HWND Dlg;
- DWORD EndNowResult;
- BOOL ShowUI;
- HANDLE UIThread;
- HWND WndClient;
- PSHUTDOWN_SETTINGS ShutdownSettings;
- LPTHREAD_START_ROUTINE SendMessageProc;
-} NOTIFY_CONTEXT, *PNOTIFY_CONTEXT;
-
-#define QUERY_RESULT_ABORT 0
-#define QUERY_RESULT_CONTINUE 1
-#define QUERY_RESULT_TIMEOUT 2
-#define QUERY_RESULT_ERROR 3
-#define QUERY_RESULT_FORCE 4
-
-static void FASTCALL
-UpdateProgressBar(HWND ProgressBar, PNOTIFY_CONTEXT NotifyContext)
-{
- DWORD Passed;
-
- Passed = GetTickCount() - NotifyContext->StartTime;
- Passed -= NotifyContext->ShutdownSettings->HungAppTimeout;
- if (NotifyContext->ShutdownSettings->WaitToKillAppTimeout < Passed)
- {
- Passed = NotifyContext->ShutdownSettings->WaitToKillAppTimeout;
- }
- SendMessageW(ProgressBar, PBM_SETPOS, Passed / 2, 0);
-}
-
-static INT_PTR CALLBACK
-EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
- INT_PTR Result;
- PNOTIFY_CONTEXT NotifyContext;
- HWND ProgressBar;
- DWORD TitleLength;
- int Len;
- LPWSTR Title;
-
- switch(Msg)
- {
- case WM_INITDIALOG:
- NotifyContext = (PNOTIFY_CONTEXT) lParam;
- NotifyContext->EndNowResult = QUERY_RESULT_ABORT;
- SetWindowLongPtrW(Dlg, DWLP_USER, (LONG_PTR) lParam);
- TitleLength = SendMessageW(NotifyContext->WndClient, WM_GETTEXTLENGTH,
- 0, 0) +
- GetWindowTextLengthW(Dlg);
- Title = HeapAlloc(Win32CsrApiHeap, 0, (TitleLength + 1) * sizeof(WCHAR));
- if (NULL != Title)
- {
- Len = GetWindowTextW(Dlg, Title, TitleLength + 1);
- SendMessageW(NotifyContext->WndClient, WM_GETTEXT,
- TitleLength + 1 - Len, (LPARAM) (Title + Len));
- SetWindowTextW(Dlg, Title);
- HeapFree(Win32CsrApiHeap, 0, Title);
- }
- ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS);
- SendMessageW(ProgressBar, PBM_SETRANGE32, 0,
- NotifyContext->ShutdownSettings->WaitToKillAppTimeout / 2);
- UpdateProgressBar(ProgressBar, NotifyContext);
- SetTimer(Dlg, 0, 200, NULL);
- Result = FALSE;
- break;
-
- case WM_TIMER:
- NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER);
- ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS);
- UpdateProgressBar(ProgressBar, NotifyContext);
- Result = TRUE;
- break;
-
- case WM_COMMAND:
- if (BN_CLICKED == HIWORD(wParam) && IDC_END_NOW == LOWORD(wParam))
- {
- NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER);
- NotifyContext->EndNowResult = QUERY_RESULT_FORCE;
- SendMessageW(Dlg, WM_CLOSE, 0, 0);
- Result = TRUE;
- }
- else
- {
- Result = FALSE;
- }
- break;
-
- case WM_CLOSE:
- DestroyWindow(Dlg);
- Result = TRUE;
- break;
-
- case WM_DESTROY:
- NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER);
- NotifyContext->Dlg = NULL;
- KillTimer(Dlg, 0);
- PostQuitMessage(NotifyContext->EndNowResult);
- Result = TRUE;
- break;
-
- default:
- Result = FALSE;
- break;
- }
-
- return Result;
-}
-
-typedef void (WINAPI *INITCOMMONCONTROLS_PROC)(void);
-
-static void
-CallInitCommonControls()
-{
- static BOOL Initialized = FALSE;
- HMODULE Lib;
- INITCOMMONCONTROLS_PROC InitProc;
-
- if (Initialized)
- {
- return;
- }
-
- Lib = LoadLibraryW(L"COMCTL32.DLL");
- if (NULL == Lib)
- {
- return;
- }
- InitProc = (INITCOMMONCONTROLS_PROC) GetProcAddress(Lib, "InitCommonControls");
- if (NULL == InitProc)
- {
- return;
- }
-
- (*InitProc)();
-
- Initialized = TRUE;
-}
-
-static DWORD WINAPI
-EndNowThreadProc(LPVOID Parameter)
-{
- PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) Parameter;
- MSG Msg;
-
- SetThreadDesktop(NotifyContext->Desktop);
- SwitchDesktop(NotifyContext->Desktop);
- CallInitCommonControls();
- NotifyContext->Dlg = CreateDialogParam(GetModuleHandleW(L"win32csr"),
- MAKEINTRESOURCE(IDD_END_NOW), NULL,
- EndNowDlgProc, (LPARAM) NotifyContext);
- if (NULL == NotifyContext->Dlg)
- {
- return 0;
- }
- ShowWindow(NotifyContext->Dlg, SW_SHOWNORMAL);
-
- while (GetMessageW(&Msg, NULL, 0, 0))
- {
- if (! IsDialogMessage(NotifyContext->Dlg, &Msg))
- {
- TranslateMessage(&Msg);
- DispatchMessageW(&Msg);
- }
- }
-
- return Msg.wParam;
-}
-
-typedef struct tagMESSAGE_CONTEXT
-{
- HWND Wnd;
- UINT Msg;
- WPARAM wParam;
- LPARAM lParam;
- DWORD Timeout;
-} MESSAGE_CONTEXT, *PMESSAGE_CONTEXT;
-
-static DWORD WINAPI
-SendQueryEndSession(LPVOID Parameter)
-{
- PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter;
- DWORD_PTR Result;
-
- if (SendMessageTimeoutW(Context->Wnd, WM_QUERYENDSESSION, Context->wParam,
- Context->lParam, SMTO_NORMAL, Context->Timeout,
- &Result))
- {
- return Result ? QUERY_RESULT_CONTINUE : QUERY_RESULT_ABORT;
- }
-
- return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR;
-}
-
-static DWORD WINAPI
-SendEndSession(LPVOID Parameter)
-{
- PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter;
- DWORD_PTR Result;
-
- if (Context->wParam)
- {
- if (SendMessageTimeoutW(Context->Wnd, WM_ENDSESSION, Context->wParam,
- Context->lParam, SMTO_NORMAL, Context->Timeout,
- &Result))
- {
- return QUERY_RESULT_CONTINUE;
- }
- return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR;
- }
- else
- {
- SendMessage(Context->Wnd, WM_ENDSESSION, Context->wParam,
- Context->lParam);
- return QUERY_RESULT_CONTINUE;
- }
-}
-
-static BOOL CALLBACK
-NotifyTopLevelEnum(HWND Wnd, LPARAM lParam)
-{
- PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) lParam;
- MESSAGE_CONTEXT MessageContext;
- DWORD Now, Passed;
- DWORD Timeout, WaitStatus;
- DWORD ProcessId;
- HANDLE MessageThread;
- HANDLE Threads[2];
-
- if (0 == GetWindowThreadProcessId(Wnd, &ProcessId))
- {
- NotifyContext->QueryResult = QUERY_RESULT_ERROR;
- return FALSE;
- }
-
- if (ProcessId == NotifyContext->ProcessId)
- {
- Now = GetTickCount();
- if (0 == NotifyContext->StartTime)
- {
- NotifyContext->StartTime = Now;
- }
- /* Note: Passed is computed correctly even when GetTickCount() wraps due
- to unsigned arithmetic */
- Passed = Now - NotifyContext->StartTime;
- MessageContext.Wnd = Wnd;
- MessageContext.Msg = NotifyContext->Msg;
- MessageContext.wParam = NotifyContext->wParam;
- MessageContext.lParam = NotifyContext->lParam;
- MessageContext.Timeout = NotifyContext->ShutdownSettings->HungAppTimeout;
- if (! NotifyContext->ShutdownSettings->AutoEndTasks)
- {
- MessageContext.Timeout += NotifyContext->ShutdownSettings->WaitToKillAppTimeout;
- }
- if (Passed < MessageContext.Timeout)
- {
- MessageContext.Timeout -= Passed;
- MessageThread = CreateThread(NULL, 0, NotifyContext->SendMessageProc,
- (LPVOID) &MessageContext, 0, NULL);
- if (NULL == MessageThread)
- {
- NotifyContext->QueryResult = QUERY_RESULT_ERROR;
- return FALSE;
- }
- Timeout = NotifyContext->ShutdownSettings->HungAppTimeout;
- if (Passed < Timeout)
- {
- Timeout -= Passed;
- WaitStatus = WaitForSingleObjectEx(MessageThread, Timeout, FALSE);
- }
- else
- {
- WaitStatus = WAIT_TIMEOUT;
- }
- if (WAIT_TIMEOUT == WaitStatus)
- {
- NotifyContext->WndClient = Wnd;
- if (NULL == NotifyContext->UIThread && NotifyContext->ShowUI)
- {
- NotifyContext->UIThread = CreateThread(NULL, 0,
- EndNowThreadProc,
- (LPVOID) NotifyContext,
- 0, NULL);
- }
- Threads[0] = MessageThread;
- Threads[1] = NotifyContext->UIThread;
- WaitStatus = WaitForMultipleObjectsEx(NULL == NotifyContext->UIThread ?
- 1 : 2,
- Threads, FALSE, INFINITE,
- FALSE);
- if (WAIT_OBJECT_0 == WaitStatus)
- {
- if (! GetExitCodeThread(MessageThread, &NotifyContext->QueryResult))
- {
- NotifyContext->QueryResult = QUERY_RESULT_ERROR;
- }
- }
- else if (WAIT_OBJECT_0 + 1 == WaitStatus)
- {
- if (! GetExitCodeThread(NotifyContext->UIThread,
- &NotifyContext->QueryResult))
- {
- NotifyContext->QueryResult = QUERY_RESULT_ERROR;
- }
- }
- else
- {
- NotifyContext->QueryResult = QUERY_RESULT_ERROR;
- }
- if (WAIT_OBJECT_0 != WaitStatus)
- {
- TerminateThread(MessageThread, QUERY_RESULT_TIMEOUT);
- }
- }
- else if (WAIT_OBJECT_0 == WaitStatus)
- {
- if (! GetExitCodeThread(MessageThread,
- &NotifyContext->QueryResult))
- {
- NotifyContext->QueryResult = QUERY_RESULT_ERROR;
- }
- }
- else
- {
- NotifyContext->QueryResult = QUERY_RESULT_ERROR;
- }
- CloseHandle(MessageThread);
- }
- else
- {
- NotifyContext->QueryResult = QUERY_RESULT_TIMEOUT;
- }
- }
-
- return QUERY_RESULT_CONTINUE == NotifyContext->QueryResult;
-}
-
-static BOOL CALLBACK
-NotifyDesktopEnum(LPWSTR DesktopName, LPARAM lParam)
-{
- PNOTIFY_CONTEXT Context = (PNOTIFY_CONTEXT) lParam;
-
- Context->Desktop = OpenDesktopW(DesktopName, 0, FALSE,
- DESKTOP_ENUMERATE | DESKTOP_SWITCHDESKTOP);
- if (NULL == Context->Desktop)
- {
- DPRINT1("OpenDesktop failed with error %d\n", GetLastError());
- Context->QueryResult = QUERY_RESULT_ERROR;
- return FALSE;
- }
-
- Context->OldDesktop = GetThreadDesktop(GetCurrentThreadId());
- SwitchDesktop(Context->Desktop);
-
- EnumDesktopWindows(Context->Desktop, NotifyTopLevelEnum, lParam);
-
- SwitchDesktop(Context->OldDesktop);
-
- CloseDesktop(Context->Desktop);
-
- return QUERY_RESULT_CONTINUE == Context->QueryResult;
-}
-
-static BOOL FASTCALL
-NotifyTopLevelWindows(PNOTIFY_CONTEXT Context)
-{
- HWINSTA WindowStation;
-
- WindowStation = GetProcessWindowStation();
- if (NULL == WindowStation)
- {
- DPRINT1("GetProcessWindowStation failed with error %d\n", GetLastError());
- return TRUE;
- }
-
- EnumDesktopsW(WindowStation, NotifyDesktopEnum, (LPARAM) Context);
-
- return TRUE;
-}
-
-static BOOL FASTCALL
-NotifyAndTerminateProcess(PCSR_PROCESS ProcessData,
- PSHUTDOWN_SETTINGS ShutdownSettings,
- UINT Flags)
-{
- NOTIFY_CONTEXT Context;
- HANDLE Process;
- DWORD QueryResult = QUERY_RESULT_CONTINUE;
-
- Context.QueryResult = QUERY_RESULT_CONTINUE;
-
- if (0 == (Flags & EWX_FORCE))
- {
- if (NULL != ProcessData->Console)
- {
- ConioConsoleCtrlEventTimeout(CTRL_LOGOFF_EVENT, ProcessData,
- ShutdownSettings->WaitToKillAppTimeout);
- }
- else
- {
- Context.ProcessId = (DWORD_PTR) ProcessData->ClientId.UniqueProcess;
- Context.wParam = 0;
- Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ?
- ENDSESSION_LOGOFF : 0);
- Context.StartTime = 0;
- Context.UIThread = NULL;
- Context.ShowUI = DtbgIsDesktopVisible();
- Context.Dlg = NULL;
- Context.ShutdownSettings = ShutdownSettings;
- Context.SendMessageProc = SendQueryEndSession;
-
- NotifyTopLevelWindows(&Context);
-
- Context.wParam = (QUERY_RESULT_ABORT != Context.QueryResult);
- Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ?
- ENDSESSION_LOGOFF : 0);
- Context.SendMessageProc = SendEndSession;
- Context.ShowUI = DtbgIsDesktopVisible() &&
- (QUERY_RESULT_ABORT != Context.QueryResult);
- QueryResult = Context.QueryResult;
- Context.QueryResult = QUERY_RESULT_CONTINUE;
-
- NotifyTopLevelWindows(&Context);
-
- if (NULL != Context.UIThread)
- {
- if (NULL != Context.Dlg)
- {
- SendMessageW(Context.Dlg, WM_CLOSE, 0, 0);
- }
- else
- {
- TerminateThread(Context.UIThread, QUERY_RESULT_ERROR);
- }
- CloseHandle(Context.UIThread);
- }
- }
-
- if (QUERY_RESULT_ABORT == QueryResult)
- {
- return FALSE;
- }
- }
-
- /* Terminate this process */
- Process = OpenProcess(PROCESS_TERMINATE, FALSE,
- (DWORD_PTR) ProcessData->ClientId.UniqueProcess);
- if (NULL == Process)
- {
- DPRINT1("Unable to open process %d, error %d\n", ProcessData->ClientId.UniqueProcess,
- GetLastError());
- return TRUE;
- }
- TerminateProcess(Process, 0);
- CloseHandle(Process);
-
- return TRUE;
-}
-
-typedef struct tagPROCESS_ENUM_CONTEXT
-{
- UINT ProcessCount;
- PCSR_PROCESS *ProcessData;
- TOKEN_ORIGIN TokenOrigin;
- DWORD ShellProcess;
- DWORD CsrssProcess;
-} PROCESS_ENUM_CONTEXT, *PPROCESS_ENUM_CONTEXT;
-
-static NTSTATUS WINAPI
-ExitReactosProcessEnum(PCSR_PROCESS ProcessData, PVOID Data)
-{
- HANDLE Process;
- HANDLE Token;
- TOKEN_ORIGIN Origin;
- DWORD ReturnLength;
- PPROCESS_ENUM_CONTEXT Context = (PPROCESS_ENUM_CONTEXT) Data;
- PCSR_PROCESS *NewData;
-
- /* Do not kill winlogon or csrss */
- if ((DWORD_PTR) ProcessData->ClientId.UniqueProcess == Context->CsrssProcess ||
- ProcessData->ClientId.UniqueProcess == LogonProcess)
- {
- return STATUS_SUCCESS;
- }
-
- /* Get the login session of this process */
- Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
- (DWORD_PTR) ProcessData->ClientId.UniqueProcess);
- if (NULL == Process)
- {
- DPRINT1("Unable to open process %d, error %d\n", ProcessData->ClientId.UniqueProcess,
- GetLastError());
- return STATUS_UNSUCCESSFUL;
- }
-
- if (! OpenProcessToken(Process, TOKEN_QUERY, &Token))
- {
- DPRINT1("Unable to open token for process %d, error %d\n",
- ProcessData->ClientId.UniqueProcess, GetLastError());
- CloseHandle(Process);
- return STATUS_UNSUCCESSFUL;
- }
- CloseHandle(Process);
-
- if (! GetTokenInformation(Token, TokenOrigin, &Origin,
- sizeof(TOKEN_ORIGIN), &ReturnLength))
- {
- DPRINT1("GetTokenInformation failed for process %d with error %d\n",
- ProcessData->ClientId.UniqueProcess, GetLastError());
- CloseHandle(Token);
- return STATUS_UNSUCCESSFUL;
- }
- CloseHandle(Token);
-
- /* This process will be killed if it's in the correct logon session */
- if (RtlEqualLuid(&(Context->TokenOrigin.OriginatingLogonSession),
- &(Origin.OriginatingLogonSession)))
- {
- /* Kill the shell process last */
- if ((DWORD_PTR) ProcessData->ClientId.UniqueProcess == Context->ShellProcess)
- {
- ProcessData->ShutdownLevel = 0;
- }
- NewData = HeapAlloc(Win32CsrApiHeap, 0, (Context->ProcessCount + 1)
- * sizeof(PCSR_PROCESS));
- if (NULL == NewData)
- {
- return STATUS_NO_MEMORY;
- }
- if (0 != Context->ProcessCount)
- {
- memcpy(NewData, Context->ProcessData,
- Context->ProcessCount * sizeof(PCSR_PROCESS));
- HeapFree(Win32CsrApiHeap, 0, Context->ProcessData);
- }
- Context->ProcessData = NewData;
- Context->ProcessData[Context->ProcessCount] = ProcessData;
- Context->ProcessCount++;
- }
-
- return STATUS_SUCCESS;
-}
-
-static int
-ProcessDataCompare(const void *Elem1, const void *Elem2)
-{
- const PCSR_PROCESS *ProcessData1 = (PCSR_PROCESS *) Elem1;
- const PCSR_PROCESS *ProcessData2 = (PCSR_PROCESS *) Elem2;
-
- if ((*ProcessData1)->ShutdownLevel < (*ProcessData2)->ShutdownLevel)
- {
- return +1;
- }
- else if ((*ProcessData2)->ShutdownLevel < (*ProcessData1)->ShutdownLevel)
- {
- return -1;
- }
- else if ((*ProcessData1)->ClientId.UniqueProcess < (*ProcessData2)->ClientId.UniqueProcess)
- {
- return +1;
- }
- else if ((*ProcessData2)->ClientId.UniqueProcess < (*ProcessData1)->ClientId.UniqueProcess)
- {
- return -1;
- }
-
- return 0;
-}
-
-static DWORD FASTCALL
-GetShutdownSetting(HKEY DesktopKey, LPCWSTR ValueName, DWORD DefaultValue)
-{
- BYTE ValueBuffer[16];
- LONG ErrCode;
- DWORD Type;
- DWORD ValueSize;
- UNICODE_STRING StringValue;
- ULONG Value;
-
- ValueSize = sizeof(ValueBuffer);
- ErrCode = RegQueryValueExW(DesktopKey, ValueName, NULL, &Type, ValueBuffer,
- &ValueSize);
- if (ERROR_SUCCESS != ErrCode)
- {
- DPRINT("GetShutdownSetting for %S failed with error code %ld\n",
- ValueName, ErrCode);
- return DefaultValue;
- }
-
- if (REG_SZ == Type)
- {
- RtlInitUnicodeString(&StringValue, (LPCWSTR) ValueBuffer);
- if (! NT_SUCCESS(RtlUnicodeStringToInteger(&StringValue, 10, &Value)))
- {
- DPRINT1("Unable to convert value %S for setting %S\n",
- StringValue.Buffer, ValueName);
- return DefaultValue;
- }
- return (DWORD) Value;
- }
- else if (REG_DWORD == Type)
- {
- return *((DWORD *) ValueBuffer);
- }
-
- DPRINT1("Unexpected registry type %d for setting %S\n", Type, ValueName);
- return DefaultValue;
-}
-
-static void FASTCALL
-LoadShutdownSettings(PSID Sid, PSHUTDOWN_SETTINGS ShutdownSettings)
-{
- static WCHAR Subkey[] = L"\\Control Panel\\Desktop";
- LPWSTR StringSid;
- WCHAR InitialKeyName[128];
- LPWSTR KeyName;
- HKEY DesktopKey;
- LONG ErrCode;
-
- ShutdownSettings->AutoEndTasks = DEFAULT_AUTO_END_TASKS;
- ShutdownSettings->HungAppTimeout = DEFAULT_HUNG_APP_TIMEOUT;
- ShutdownSettings->WaitToKillAppTimeout = DEFAULT_WAIT_TO_KILL_APP_TIMEOUT;
-
- if (! ConvertSidToStringSidW(Sid, &StringSid))
- {
- DPRINT1("ConvertSidToStringSid failed with error %d, using default shutdown settings\n",
- GetLastError());
- return;
- }
- if (wcslen(StringSid) + wcslen(Subkey) + 1 <=
- sizeof(InitialKeyName) / sizeof(WCHAR))
- {
- KeyName = InitialKeyName;
- }
- else
- {
- KeyName = HeapAlloc(Win32CsrApiHeap, 0,
- (wcslen(StringSid) + wcslen(Subkey) + 1) *
- sizeof(WCHAR));
- if (NULL == KeyName)
- {
- DPRINT1("Failed to allocate memory, using default shutdown settings\n");
- LocalFree(StringSid);
- return;
- }
- }
- wcscat(wcscpy(KeyName, StringSid), Subkey);
- LocalFree(StringSid);
-
- ErrCode = RegOpenKeyExW(HKEY_USERS, KeyName, 0, KEY_QUERY_VALUE, &DesktopKey);
- if (KeyName != InitialKeyName)
- {
- HeapFree(Win32CsrApiHeap, 0, KeyName);
- }
- if (ERROR_SUCCESS != ErrCode)
- {
- DPRINT1("RegOpenKeyEx failed with error %ld, using default shutdown settings\n", ErrCode);
- return;
- }
-
- ShutdownSettings->AutoEndTasks = (BOOL) GetShutdownSetting(DesktopKey, L"AutoEndTasks",
- (DWORD) DEFAULT_AUTO_END_TASKS);
- ShutdownSettings->HungAppTimeout = GetShutdownSetting(DesktopKey,
- L"HungAppTimeout",
- DEFAULT_HUNG_APP_TIMEOUT);
- ShutdownSettings->WaitToKillAppTimeout = GetShutdownSetting(DesktopKey,
- L"WaitToKillAppTimeout",
- DEFAULT_WAIT_TO_KILL_APP_TIMEOUT);
-
- RegCloseKey(DesktopKey);
-}
-
-static NTSTATUS FASTCALL
-InternalExitReactos(DWORD ProcessId, DWORD ThreadId, UINT Flags)
-{
- HANDLE CallerThread;
- HANDLE CallerToken;
- NTSTATUS Status;
- PROCESS_ENUM_CONTEXT Context;
- DWORD ReturnLength;
- HWND ShellWnd;
- UINT ProcessIndex;
- char FixedUserInfo[64];
- TOKEN_USER *UserInfo;
- SHUTDOWN_SETTINGS ShutdownSettings;
-
- if (ProcessId != (DWORD_PTR) LogonProcess)
- {
- DPRINT1("Internal ExitWindowsEx call not from winlogon\n");
- return STATUS_ACCESS_DENIED;
- }
-
- DPRINT1("FIXME: Need to close all user processes!\n");
- return STATUS_SUCCESS;
-
- CallerThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, ThreadId);
- if (NULL == CallerThread)
- {
- DPRINT1("OpenThread failed with error %d\n", GetLastError());
- return STATUS_UNSUCCESSFUL;
- }
- if (! OpenThreadToken(CallerThread, TOKEN_QUERY, FALSE, &CallerToken))
- {
- DPRINT1("OpenThreadToken failed with error %d\n", GetLastError());
- CloseHandle(CallerThread);
- return STATUS_UNSUCCESSFUL;
- }
- CloseHandle(CallerThread);
-
- Context.ProcessCount = 0;
- Context.ProcessData = NULL;
- if (! GetTokenInformation(CallerToken, TokenOrigin, &Context.TokenOrigin,
- sizeof(TOKEN_ORIGIN), &ReturnLength))
- {
- DPRINT1("GetTokenInformation failed with error %d\n", GetLastError());
- CloseHandle(CallerToken);
- return STATUS_UNSUCCESSFUL;
- }
- if (! GetTokenInformation(CallerToken, TokenUser, FixedUserInfo,
- sizeof(FixedUserInfo), &ReturnLength))
- {
- if (sizeof(FixedUserInfo) < ReturnLength)
- {
- UserInfo = HeapAlloc(Win32CsrApiHeap, 0, ReturnLength);
- if (NULL == UserInfo)
- {
- DPRINT1("Unable to allocate %u bytes for user info\n",
- (unsigned) ReturnLength);
- CloseHandle(CallerToken);
- return STATUS_NO_MEMORY;
- }
- if (! GetTokenInformation(CallerToken, TokenUser, UserInfo,
- ReturnLength, &ReturnLength))
- {
- DPRINT1("GetTokenInformation failed with error %d\n",
- GetLastError());
- HeapFree(Win32CsrApiHeap, 0, UserInfo);
- CloseHandle(CallerToken);
- return STATUS_UNSUCCESSFUL;
- }
- }
- else
- {
- DPRINT1("GetTokenInformation failed with error %d\n", GetLastError());
- CloseHandle(CallerToken);
- return STATUS_UNSUCCESSFUL;
- }
- }
- else
- {
- UserInfo = (TOKEN_USER *) FixedUserInfo;
- }
- CloseHandle(CallerToken);
- LoadShutdownSettings(UserInfo->User.Sid, &ShutdownSettings);
- if (UserInfo != (TOKEN_USER *) FixedUserInfo)
- {
- HeapFree(Win32CsrApiHeap, 0, UserInfo);
- }
- Context.CsrssProcess = GetCurrentProcessId();
- ShellWnd = GetShellWindow();
- if (NULL == ShellWnd)
- {
- DPRINT("No shell present\n");
- Context.ShellProcess = 0;
- }
- else if (0 == GetWindowThreadProcessId(ShellWnd, &Context.ShellProcess))
- {
- DPRINT1("Can't get process id of shell window\n");
- Context.ShellProcess = 0;
- }
-
- Status = Win32CsrEnumProcesses(ExitReactosProcessEnum, &Context);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to enumerate registered processes, status 0x%x\n",
- Status);
- if (NULL != Context.ProcessData)
- {
- HeapFree(Win32CsrApiHeap, 0, Context.ProcessData);
- }
- return Status;
- }
-
- qsort(Context.ProcessData, Context.ProcessCount, sizeof(PCSR_PROCESS),
- ProcessDataCompare);
-
- /* Terminate processes, stop if we find one kicking and screaming it doesn't
- want to die */
- Status = STATUS_SUCCESS;
- for (ProcessIndex = 0;
- ProcessIndex < Context.ProcessCount && NT_SUCCESS(Status);
- ProcessIndex++)
- {
- if (! NotifyAndTerminateProcess(Context.ProcessData[ProcessIndex],
- &ShutdownSettings, Flags))
- {
- Status = STATUS_REQUEST_ABORTED;
- }
- }
-
- /* Cleanup */
- if (NULL != Context.ProcessData)
- {
- HeapFree(Win32CsrApiHeap, 0, Context.ProcessData);
- }
-
- return Status;
-}
-
-static NTSTATUS FASTCALL
-UserExitReactos(DWORD UserProcessId, UINT Flags)
-{
- NTSTATUS Status;
-
- /* FIXME Inside 2000 says we should impersonate the caller here */
- Status = NtUserCallTwoParam (UserProcessId, Flags, TWOPARAM_ROUTINE_EXITREACTOS);
-
- /* If the message isn't handled, the return value is 0, so 0 doesn't indicate
- success. Success is indicated by a 1 return value, if anything besides 0
- or 1 it's a NTSTATUS value */
- if (1 == Status)
- {
- Status = STATUS_SUCCESS;
- }
- else if (0 == Status)
- {
- Status = STATUS_NOT_IMPLEMENTED;
- }
-
- return Status;
-}
-
-CSR_API(CsrExitReactos)
-{
- if (0 == (Request->Data.ExitReactosRequest.Flags & EWX_INTERNAL_FLAG))
- {
- return UserExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess,
- Request->Data.ExitReactosRequest.Flags);
- }
- else
- {
- return InternalExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess,
- (DWORD_PTR) Request->Header.ClientId.UniqueThread,
- Request->Data.ExitReactosRequest.Flags);
- }
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/file.c
- * PURPOSE: File handling
- * PROGRAMMERS: Pierre Schweitzer (pierre.schweitzer@reactos.org)
- * NOTE: Belongs to basesrv.dll
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <w32csr.h>
-#define NDEBUG
-#include <debug.h>
-#include "file.h"
-
-/* GLOBALS *******************************************************************/
-
-typedef BOOL (WINAPI *PUSER_SOUND_SENTRY)(VOID);
-BOOL
-WINAPI
-FirstSoundSentry(VOID);
-
-UINT CsrGetTempFileUnique;
-LIST_ENTRY DosDeviceHistory;
-RTL_CRITICAL_SECTION Win32CsrDefineDosDeviceCritSec;
-PUSER_SOUND_SENTRY _UserSoundSentry = FirstSoundSentry;
-
-/* FUNCTIONS *****************************************************************/
-
-BOOL
-WINAPI
-FailSoundSentry(VOID)
-{
- /* In case the function can't be found/is unimplemented */
- return FALSE;
-}
-
-BOOL
-WINAPI
-FirstSoundSentry(VOID)
-{
- UNICODE_STRING DllString = RTL_CONSTANT_STRING(L"winsrv");
- STRING FuncString = RTL_CONSTANT_STRING("_UserSoundSentry");
- HANDLE DllHandle;
- NTSTATUS Status;
- PUSER_SOUND_SENTRY NewSoundSentry = FailSoundSentry;
-
- /* Load winsrv manually */
- Status = LdrGetDllHandle(NULL, NULL, &DllString, &DllHandle);
- if (NT_SUCCESS(Status))
- {
- /* If it was found, get SoundSentry export */
- Status = LdrGetProcedureAddress(DllHandle,
- &FuncString,
- 0,
- (PVOID*)&NewSoundSentry);
- }
-
- /* Set it as the callback for the future, and call it */
- _UserSoundSentry = NewSoundSentry;
- return _UserSoundSentry();
-}
-
-CSR_API(CsrSoundSentry)
-{
- /* Call the API and see if it suceeds */
- return _UserSoundSentry() ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
-}
-
-CSR_API(CsrGetTempFile)
-{
- DPRINT("CsrGetTempFile entered\n");
-
- /* Return 16-bits ID */
- Request->Data.GetTempFile.UniqueID = (++CsrGetTempFileUnique & 0xFFFF);
-
- DPRINT("Returning: %u\n", Request->Data.GetTempFile.UniqueID);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrDefineDosDevice)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE LinkHandle = NULL;
- NTSTATUS Status;
- UNICODE_STRING DeviceName = {0};
- UNICODE_STRING RequestDeviceName = {0};
- UNICODE_STRING LinkTarget = {0};
- PUNICODE_STRING RequestLinkTarget;
- ULONG Length;
- SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
- SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
- PSECURITY_DESCRIPTOR SecurityDescriptor;
- PACL Dacl;
- PSID AdminSid;
- PSID SystemSid;
- PSID WorldSid;
- ULONG SidLength;
- PCSRSS_DOS_DEVICE_HISTORY_ENTRY HistoryEntry;
- PLIST_ENTRY Entry;
- PLIST_ENTRY ListHead;
- BOOLEAN Matched, AddHistory;
- DWORD dwFlags;
- PWSTR lpBuffer;
-
- DPRINT("CsrDefineDosDevice entered, Flags:%d, DeviceName:%wZ, TargetName:%wZ\n",
- Request->Data.DefineDosDeviceRequest.dwFlags,
- &Request->Data.DefineDosDeviceRequest.DeviceName,
- &Request->Data.DefineDosDeviceRequest.TargetName);
-
- Matched = AddHistory = FALSE;
- HistoryEntry = NULL;
- AdminSid = SystemSid = WorldSid = NULL;
- SecurityDescriptor = NULL;
- ListHead = &DosDeviceHistory;
- dwFlags = Request->Data.DefineDosDeviceRequest.dwFlags;
-
- /* Validate the flags */
- if ( (dwFlags & 0xFFFFFFF0) ||
- ((dwFlags & DDD_EXACT_MATCH_ON_REMOVE) &&
- ! (dwFlags & DDD_REMOVE_DEFINITION)) )
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = RtlEnterCriticalSection(&Win32CsrDefineDosDeviceCritSec);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("RtlEnterCriticalSection() failed (Status %lx)\n",
- Status);
- return Status;
- }
-
- _SEH2_TRY
- {
- Status =
- RtlUpcaseUnicodeString(&RequestDeviceName,
- &Request->Data.DefineDosDeviceRequest.DeviceName,
- TRUE);
- if (! NT_SUCCESS(Status))
- _SEH2_LEAVE;
-
- RequestLinkTarget =
- &Request->Data.DefineDosDeviceRequest.TargetName;
- lpBuffer = (PWSTR) RtlAllocateHeap(Win32CsrApiHeap,
- HEAP_ZERO_MEMORY,
- RequestDeviceName.MaximumLength + 5 * sizeof(WCHAR));
- if (! lpBuffer)
- {
- DPRINT1("Failed to allocate memory\n");
- Status = STATUS_NO_MEMORY;
- _SEH2_LEAVE;
- }
-
- swprintf(lpBuffer,
- L"\\??\\%wZ",
- &RequestDeviceName);
- RtlInitUnicodeString(&DeviceName,
- lpBuffer);
- InitializeObjectAttributes(&ObjectAttributes,
- &DeviceName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtOpenSymbolicLinkObject(&LinkHandle,
- DELETE | 0x1,
- &ObjectAttributes);
- if (NT_SUCCESS(Status))
- {
- Status = NtQuerySymbolicLinkObject(LinkHandle,
- &LinkTarget,
- &Length);
- if (! NT_SUCCESS(Status) &&
- Status == STATUS_BUFFER_TOO_SMALL)
- {
- LinkTarget.Length = 0;
- LinkTarget.MaximumLength = Length;
- LinkTarget.Buffer = (PWSTR)
- RtlAllocateHeap(Win32CsrApiHeap,
- HEAP_ZERO_MEMORY,
- Length);
- if (! LinkTarget.Buffer)
- {
- DPRINT1("Failed to allocate memory\n");
- Status = STATUS_NO_MEMORY;
- _SEH2_LEAVE;
- }
-
- Status = NtQuerySymbolicLinkObject(LinkHandle,
- &LinkTarget,
- &Length);
- }
-
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("NtQuerySymbolicLinkObject(%wZ) failed (Status %lx)\n",
- &DeviceName, Status);
- _SEH2_LEAVE;
- }
-
- if ((dwFlags & DDD_REMOVE_DEFINITION))
- {
- /* If no target name specified we remove the current symlink target */
- if (RequestLinkTarget->Length == 0)
- Matched = TRUE;
- else
- {
- if (dwFlags & DDD_EXACT_MATCH_ON_REMOVE)
- Matched = ! RtlCompareUnicodeString(RequestLinkTarget,
- &LinkTarget,
- TRUE);
- else
- Matched = RtlPrefixUnicodeString(RequestLinkTarget,
- &LinkTarget,
- TRUE);
- }
-
- if (Matched && IsListEmpty(ListHead))
- {
- /* Current symlink target macthed and there is nothing to revert to */
- RequestLinkTarget = NULL;
- }
- else if (Matched && ! IsListEmpty(ListHead))
- {
- /* Fetch the first history entry we come across for the device name */
- /* This will become the current symlink target for the device name */
- Matched = FALSE;
- Entry = ListHead->Flink;
- while (Entry != ListHead)
- {
- HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
- CONTAINING_RECORD(Entry,
- CSRSS_DOS_DEVICE_HISTORY_ENTRY,
- Entry);
- Matched =
- ! RtlCompareUnicodeString(&RequestDeviceName,
- &HistoryEntry->Device,
- FALSE);
- if (Matched)
- {
- RemoveEntryList(&HistoryEntry->Entry);
- RequestLinkTarget = &HistoryEntry->Target;
- break;
- }
- Entry = Entry->Flink;
- HistoryEntry = NULL;
- }
-
- /* Nothing to revert to so delete the symlink */
- if (! Matched)
- RequestLinkTarget = NULL;
- }
- else if (! Matched)
- {
- /* Locate a previous symlink target as we did not get a hit earlier */
- /* If we find one we need to remove it */
- Entry = ListHead->Flink;
- while (Entry != ListHead)
- {
- HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
- CONTAINING_RECORD(Entry,
- CSRSS_DOS_DEVICE_HISTORY_ENTRY,
- Entry);
- Matched =
- ! RtlCompareUnicodeString(&RequestDeviceName,
- &HistoryEntry->Device,
- FALSE);
- if (! Matched)
- {
- HistoryEntry = NULL;
- Entry = Entry->Flink;
- continue;
- }
-
- Matched = FALSE;
- if (dwFlags & DDD_EXACT_MATCH_ON_REMOVE)
- {
- if (! RtlCompareUnicodeString(RequestLinkTarget,
- &HistoryEntry->Target,
- TRUE))
- {
- Matched = TRUE;
- }
- }
- else if (RtlPrefixUnicodeString(RequestLinkTarget,
- &HistoryEntry->Target,
- TRUE))
- {
- Matched = TRUE;
- }
-
- if (Matched)
- {
- RemoveEntryList(&HistoryEntry->Entry);
- break;
- }
- Entry = Entry->Flink;
- HistoryEntry = NULL;
- }
-
- /* Leave existing symlink as is */
- if (! Matched)
- Status = STATUS_OBJECT_NAME_NOT_FOUND;
- else
- Status = STATUS_SUCCESS;
- _SEH2_LEAVE;
- }
- }
- else
- {
- AddHistory = TRUE;
- }
-
- Status = NtMakeTemporaryObject(LinkHandle);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("NtMakeTemporaryObject(%wZ) failed (Status %lx)\n",
- &DeviceName, Status);
- _SEH2_LEAVE;
- }
-
- Status = NtClose(LinkHandle);
- LinkHandle = NULL;
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("NtClose(%wZ) failed (Status %lx)\n",
- &DeviceName, Status);
- _SEH2_LEAVE;
- }
- }
-
- /* Don't create symlink if we don't have a target */
- if (! RequestLinkTarget || RequestLinkTarget->Length == 0)
- _SEH2_LEAVE;
-
- if (AddHistory)
- {
- HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
- RtlAllocateHeap(Win32CsrApiHeap,
- HEAP_ZERO_MEMORY,
- sizeof(CSRSS_DOS_DEVICE_HISTORY_ENTRY));
- if (! HistoryEntry)
- {
- DPRINT1("Failed to allocate memory\n");
- Status = STATUS_NO_MEMORY;
- _SEH2_LEAVE;
- }
-
- HistoryEntry->Target.Buffer =
- RtlAllocateHeap(Win32CsrApiHeap,
- HEAP_ZERO_MEMORY,
- LinkTarget.Length);
- if (! HistoryEntry->Target.Buffer)
- {
- DPRINT1("Failed to allocate memory\n");
- Status = STATUS_NO_MEMORY;
- _SEH2_LEAVE;
- }
- HistoryEntry->Target.Length =
- HistoryEntry->Target.MaximumLength =
- LinkTarget.Length;
- RtlCopyUnicodeString(&HistoryEntry->Target,
- &LinkTarget);
-
- HistoryEntry->Device.Buffer =
- RtlAllocateHeap(Win32CsrApiHeap,
- HEAP_ZERO_MEMORY,
- RequestDeviceName.Length);
- if (! HistoryEntry->Device.Buffer)
- {
- DPRINT1("Failed to allocate memory\n");
- Status = STATUS_NO_MEMORY;
- _SEH2_LEAVE;
- }
- HistoryEntry->Device.Length =
- HistoryEntry->Device.MaximumLength =
- RequestDeviceName.Length;
- RtlCopyUnicodeString(&HistoryEntry->Device,
- &RequestDeviceName);
-
- /* Remember previous symlink target for this device */
- InsertHeadList(ListHead,
- &HistoryEntry->Entry);
- HistoryEntry = NULL;
- }
-
- RtlAllocateAndInitializeSid(&WorldAuthority,
- 1,
- SECURITY_WORLD_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- &WorldSid);
-
- RtlAllocateAndInitializeSid(&SystemAuthority,
- 1,
- SECURITY_LOCAL_SYSTEM_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- &SystemSid);
-
- RtlAllocateAndInitializeSid(&SystemAuthority,
- 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- SECURITY_NULL_RID,
- &AdminSid);
-
- SidLength = RtlLengthSid(SystemSid) +
- RtlLengthSid(AdminSid) +
- RtlLengthSid(WorldSid);
- Length = sizeof(ACL) + SidLength + 3 * sizeof(ACCESS_ALLOWED_ACE);
-
- SecurityDescriptor = RtlAllocateHeap(Win32CsrApiHeap,
- 0,
- SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
- if (! SecurityDescriptor)
- {
- DPRINT1("Failed to allocate memory\n");
- Status = STATUS_NO_MEMORY;
- _SEH2_LEAVE;
- }
-
- Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
- Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("RtlCreateSecurityDescriptor() failed (Status %lx)\n",
- Status);
- _SEH2_LEAVE;
- }
-
- Status = RtlCreateAcl(Dacl,
- Length,
- ACL_REVISION);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("RtlCreateAcl() failed (Status %lx)\n",
- Status);
- _SEH2_LEAVE;
- }
-
- (void) RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- SystemSid);
- (void) RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- AdminSid);
- (void) RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- STANDARD_RIGHTS_READ,
- WorldSid);
-
- Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
- TRUE,
- Dacl,
- FALSE);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("RtlSetDaclSecurityDescriptor() failed (Status %lx)\n",
- Status);
- _SEH2_LEAVE;
- }
-
- InitializeObjectAttributes(&ObjectAttributes,
- &DeviceName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- SecurityDescriptor);
- Status = NtCreateSymbolicLinkObject(&LinkHandle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes,
- RequestLinkTarget);
- if (NT_SUCCESS(Status))
- {
- Status = NtMakePermanentObject(LinkHandle);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("NtMakePermanentObject(%wZ) failed (Status %lx)\n",
- &DeviceName, Status);
- }
- }
- else
- {
- DPRINT1("NtCreateSymbolicLinkObject(%wZ) failed (Status %lx)\n",
- &DeviceName, Status);
- }
- }
- _SEH2_FINALLY
- {
- (void) RtlLeaveCriticalSection(&Win32CsrDefineDosDeviceCritSec);
- if (DeviceName.Buffer)
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- DeviceName.Buffer);
- if (LinkTarget.Buffer)
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- LinkTarget.Buffer);
- if (SecurityDescriptor)
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- SecurityDescriptor);
- if (LinkHandle)
- (void) NtClose(LinkHandle);
- if (SystemSid)
- (void) RtlFreeSid(SystemSid);
- if (AdminSid)
- (void) RtlFreeSid(AdminSid);
- if (WorldSid)
- (void) RtlFreeSid(WorldSid);
- RtlFreeUnicodeString(&RequestDeviceName);
- if (HistoryEntry)
- {
- if (HistoryEntry->Target.Buffer)
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- HistoryEntry->Target.Buffer);
- if (HistoryEntry->Device.Buffer)
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- HistoryEntry->Device.Buffer);
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- HistoryEntry);
- }
- }
- _SEH2_END
-
- DPRINT("CsrDefineDosDevice Exit, Statux: 0x%x\n", Status);
- return Status;
-}
-
-void CsrCleanupDefineDosDevice(void)
-{
- PLIST_ENTRY Entry, ListHead;
- PCSRSS_DOS_DEVICE_HISTORY_ENTRY HistoryEntry;
-
- (void) RtlDeleteCriticalSection(&Win32CsrDefineDosDeviceCritSec);
-
- ListHead = &DosDeviceHistory;
- Entry = ListHead->Flink;
- while (Entry != ListHead)
- {
- HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
- CONTAINING_RECORD(Entry,
- CSRSS_DOS_DEVICE_HISTORY_ENTRY,
- Entry);
- Entry = Entry->Flink;
-
- if (HistoryEntry)
- {
- if (HistoryEntry->Target.Buffer)
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- HistoryEntry->Target.Buffer);
- if (HistoryEntry->Device.Buffer)
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- HistoryEntry->Device.Buffer);
- (void) RtlFreeHeap(Win32CsrApiHeap,
- 0,
- HistoryEntry);
- }
- }
-}
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsystem/win32/csrss/win32csr/file.h
- * PURPOSE: File handling
- * PROGRAMMERS: Pierre Schweitzer (pierre.schweitzer@reactos.org)
- * NOTE: Belongs to basesrv.dll
- */
-
-#pragma once
-
-#include "api.h"
-
-typedef struct tagCSRSS_DOS_DEVICE_HISTORY_ENTRY
-{
- UNICODE_STRING Device;
- UNICODE_STRING Target;
- LIST_ENTRY Entry;
-} CSRSS_DOS_DEVICE_HISTORY_ENTRY, *PCSRSS_DOS_DEVICE_HISTORY_ENTRY;
-
-/* Api functions */
-CSR_API(CsrGetTempFile);
-CSR_API(CsrDefineDosDevice);
-
-/* functions */
-void CsrCleanupDefineDosDevice();
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/guiconsole.c
- * PURPOSE: Implementation of gui-mode consoles
- */
-
-/* INCLUDES ******************************************************************/
-
-#define NDEBUG
-#include "w32csr.h"
-#include <debug.h>
-
-/* Not defined in any header file */
-extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check);
-
-/* GLOBALS *******************************************************************/
-
-typedef struct GUI_CONSOLE_DATA_TAG
-{
- HFONT Font;
- unsigned CharWidth;
- unsigned CharHeight;
- BOOL CursorBlinkOn;
- BOOL ForceCursorOff;
- CRITICAL_SECTION Lock;
- HMODULE ConsoleLibrary;
- HANDLE hGuiInitEvent;
- WCHAR FontName[LF_FACESIZE];
- DWORD FontSize;
- DWORD FontWeight;
- DWORD FullScreen;
- DWORD QuickEdit;
- DWORD InsertMode;
- DWORD WindowPosition;
- DWORD UseRasterFonts;
- COLORREF ScreenText;
- COLORREF ScreenBackground;
- COLORREF PopupBackground;
- COLORREF PopupText;
- COLORREF Colors[16];
- WCHAR szProcessName[MAX_PATH];
- BOOL WindowSizeLock;
- POINT OldCursor;
-} GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
-
-#ifndef WM_APP
-#define WM_APP 0x8000
-#endif
-#define PM_CREATE_CONSOLE (WM_APP + 1)
-#define PM_DESTROY_CONSOLE (WM_APP + 2)
-
-#define CURSOR_BLINK_TIME 500
-#define DEFAULT_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
-
-static BOOL ConsInitialized = FALSE;
-static HWND NotifyWnd;
-
-typedef struct _GUICONSOLE_MENUITEM
-{
- UINT uID;
- const struct _GUICONSOLE_MENUITEM *SubMenu;
- WORD wCmdID;
-} GUICONSOLE_MENUITEM, *PGUICONSOLE_MENUITEM;
-
-static const GUICONSOLE_MENUITEM GuiConsoleEditMenuItems[] =
-{
- { IDS_MARK, NULL, ID_SYSTEM_EDIT_MARK },
- { IDS_COPY, NULL, ID_SYSTEM_EDIT_COPY },
- { IDS_PASTE, NULL, ID_SYSTEM_EDIT_PASTE },
- { IDS_SELECTALL, NULL, ID_SYSTEM_EDIT_SELECTALL },
- { IDS_SCROLL, NULL, ID_SYSTEM_EDIT_SCROLL },
- { IDS_FIND, NULL, ID_SYSTEM_EDIT_FIND },
-
- { 0, NULL, 0 } /* End of list */
-};
-
-static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems[] =
-{
- { (UINT)-1, NULL, 0 }, /* Separator */
- { IDS_EDIT, GuiConsoleEditMenuItems, 0 },
- { IDS_DEFAULTS, NULL, ID_SYSTEM_DEFAULTS },
- { IDS_PROPERTIES, NULL, ID_SYSTEM_PROPERTIES },
-
- { 0, NULL, 0 } /* End of list */
-};
-
-static const COLORREF s_Colors[] =
-{
- RGB(0, 0, 0),
- RGB(0, 0, 128),
- RGB(0, 128, 0),
- RGB(0, 128, 128),
- RGB(128, 0, 0),
- RGB(128, 0, 128),
- RGB(128, 128, 0),
- RGB(192, 192, 192),
- RGB(128, 128, 128),
- RGB(0, 0, 255),
- RGB(0, 255, 0),
- RGB(0, 255, 255),
- RGB(255, 0, 0),
- RGB(255, 0, 255),
- RGB(255, 255, 0),
- RGB(255, 255, 255)
-};
-
-#define GuiConsoleRGBFromAttribute(GuiData, Attribute) ((GuiData)->Colors[(Attribute) & 0xF])
-
-/* FUNCTIONS *****************************************************************/
-
-static VOID
-GuiConsoleAppendMenuItems(HMENU hMenu,
- const GUICONSOLE_MENUITEM *Items)
-{
- UINT i = 0;
- WCHAR szMenuString[255];
- HMENU hSubMenu;
- HINSTANCE hInst = GetModuleHandleW(L"win32csr");
-
- do
- {
- if (Items[i].uID != (UINT)-1)
- {
- if (LoadStringW(hInst,
- Items[i].uID,
- szMenuString,
- sizeof(szMenuString) / sizeof(szMenuString[0])) > 0)
- {
- if (Items[i].SubMenu != NULL)
- {
- hSubMenu = CreatePopupMenu();
- if (hSubMenu != NULL)
- {
- GuiConsoleAppendMenuItems(hSubMenu,
- Items[i].SubMenu);
-
- if (!AppendMenuW(hMenu,
- MF_STRING | MF_POPUP,
- (UINT_PTR)hSubMenu,
- szMenuString))
- {
- DestroyMenu(hSubMenu);
- }
- }
- }
- else
- {
- AppendMenuW(hMenu,
- MF_STRING,
- Items[i].wCmdID,
- szMenuString);
- }
- }
- }
- else
- {
- AppendMenuW(hMenu,
- MF_SEPARATOR,
- 0,
- NULL);
- }
- i++;
- } while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
-}
-
-static VOID
-GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console)
-{
- HMENU hMenu;
- hMenu = GetSystemMenu(Console->hWindow,
- FALSE);
- if (hMenu != NULL)
- {
- GuiConsoleAppendMenuItems(hMenu,
- GuiConsoleMainMenuItems);
- DrawMenuBar(Console->hWindow);
- }
-}
-
-static VOID
-GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData)
-{
- *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA);
- *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
-}
-
-static BOOL
-GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired)
-{
- HANDLE hProcessToken = NULL;
- HANDLE hProcess;
-
- BYTE Buffer[256];
- DWORD Length = 0;
- UNICODE_STRING SidName;
- LONG res;
- PTOKEN_USER TokUser;
-
- hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId);
- if (!hProcess)
- {
- DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError());
- return FALSE;
- }
-
- if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
- {
- DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError());
- CloseHandle(hProcess);
- return FALSE;
- }
-
- if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length))
- {
- DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError());
- CloseHandle(hProcessToken);
- CloseHandle(hProcess);
- return FALSE;
- }
-
- TokUser = ((PTOKEN_USER)Buffer)->User.Sid;
- if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE)))
- {
- DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError());
- CloseHandle(hProcessToken);
- CloseHandle(hProcess);
- return FALSE;
- }
-
- res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult);
- RtlFreeUnicodeString(&SidName);
-
- CloseHandle(hProcessToken);
- if (res != ERROR_SUCCESS)
- {
- CloseHandle(hProcess);
- return FALSE;
- }
-
- if (hProcHandle)
- *hProcHandle = hProcess;
- else
- CloseHandle(hProcess);
-
- return TRUE;
-}
-
-static BOOL
-GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate)
-{
- WCHAR szProcessName[MAX_PATH];
- WCHAR szBuffer[MAX_PATH];
- UINT fLength, wLength;
- DWORD dwBitmask, dwLength;
- WCHAR CurDrive[] = { 'A',':', 0 };
- HANDLE hProcess;
- HKEY hKey;
- WCHAR * ptr;
-
- /*
- * console properties are stored under
- * HKCU\Console\*
- *
- * There are 3 ways to store console properties
- *
- * 1. use console title as subkey name
- * i.e. cmd.exe
- *
- * 2. use application name as subkey name
- *
- * 3. use unexpanded path to console application.
- * i.e. %SystemRoot%_system32_cmd.exe
- */
-
- DPRINT("GuiConsoleOpenUserSettings entered\n");
-
- if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired))
- {
- DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n");
- return FALSE;
- }
-
- /* FIXME we do not getting the process name so no menu will be loading, why ?*/
- fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR));
- CloseHandle(hProcess);
-
- //DPRINT1("szProcessName3 : %S\n",szProcessName);
-
- if (!fLength)
- {
- DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(), ProcessId);
- return FALSE;
- }
- /*
- * try the process name as path
- */
-
- ptr = wcsrchr(szProcessName, L'\\');
- wcscpy(GuiData->szProcessName, ptr);
-
- swprintf(szBuffer, L"Console%s",ptr);
- DPRINT("#1 Path : %S\n", szBuffer);
-
- if (bCreate)
- {
- if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS)
- {
- RegCloseKey(hKey);
- return TRUE;
- }
- RegCloseKey(hKey);
- return FALSE;
- }
-
- if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
- {
- RegCloseKey(hKey);
- return TRUE;
- }
-
- /*
- * try the "Shortcut to processname" as path
- * FIXME: detect wheter the process was started as a shortcut
- */
-
- swprintf(szBuffer, L"Console\\Shortcut to %S", ptr);
- DPRINT("#2 Path : %S\n", szBuffer);
- if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
- {
- swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr);
- RegCloseKey(hKey);
- return TRUE;
- }
-
- /*
- * if the path contains \\Device\\HarddiskVolume1\... remove it
- */
-
- if (szProcessName[0] == L'\\')
- {
- dwBitmask = GetLogicalDrives();
- while(dwBitmask)
- {
- if (dwBitmask & 0x1)
- {
- dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH);
- if (dwLength)
- {
- if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR)))
- {
- wcscpy(szProcessName, CurDrive);
- RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1);
- break;
- }
- }
- }
- dwBitmask = (dwBitmask >> 1);
- CurDrive[0]++;
- }
- }
-
- /*
- * last attempt: check whether the file is under %SystemRoot%
- * and use path like Console\%SystemRoot%_dir_dir2_file.exe
- */
-
- wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH);
- if (wLength)
- {
- if (!wcsncmp(szProcessName, szBuffer, wLength))
- {
- /* replace slashes by underscores */
- while((ptr = wcschr(szProcessName, L'\\')))
- ptr[0] = L'_';
-
- swprintf(szBuffer, L"Console\\%%SystemRoot%%%S", &szProcessName[wLength]);
- DPRINT("#3 Path : %S\n", szBuffer);
- if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
- {
- swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]);
- RegCloseKey(hKey);
- return TRUE;
- }
- }
- }
- RegCloseKey(hKey);
- return FALSE;
-}
-
-static VOID
-GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData)
-{
- HKEY hKey;
- PCSR_PROCESS ProcessData;
-
- if (Console->ProcessList.Flink == &Console->ProcessList)
- {
- DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n");
- return;
- }
- ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSR_PROCESS, ConsoleLink);
- if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ClientId.UniqueProcess), &hKey, KEY_READ | KEY_WRITE, TRUE))
- {
- return;
- }
-
- if (Console->ActiveBuffer->CursorInfo.dwSize <= 1)
- {
- RegDeleteKeyW(hKey, L"CursorSize");
- }
- else
- {
- RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD));
- }
-
- if (Console->NumberOfHistoryBuffers == 5)
- {
- RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers");
- }
- else
- {
- DWORD Temp = Console->NumberOfHistoryBuffers;
- RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD));
- }
-
- if (Console->HistoryBufferSize == 50)
- {
- RegDeleteKeyW(hKey, L"HistoryBufferSize");
- }
- else
- {
- DWORD Temp = Console->HistoryBufferSize;
- RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD));
- }
-
- if (GuiData->FullScreen == FALSE)
- {
- RegDeleteKeyW(hKey, L"FullScreen");
- }
- else
- {
- RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD));
- }
-
- if ( GuiData->QuickEdit == FALSE)
- {
- RegDeleteKeyW(hKey, L"QuickEdit");
- }
- else
- {
- RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD));
- }
-
- if (GuiData->InsertMode == TRUE)
- {
- RegDeleteKeyW(hKey, L"InsertMode");
- }
- else
- {
- RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD));
- }
-
- if (Console->HistoryNoDup == FALSE)
- {
- RegDeleteKeyW(hKey, L"HistoryNoDup");
- }
- else
- {
- DWORD Temp = Console->HistoryNoDup;
- RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD));
- }
-
- if (GuiData->ScreenText == RGB(192, 192, 192))
- {
- /*
- * MS uses console attributes instead of real color
- */
- RegDeleteKeyW(hKey, L"ScreenText");
- }
- else
- {
- RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF));
- }
-
- if (GuiData->ScreenBackground == RGB(0, 0, 0))
- {
- RegDeleteKeyW(hKey, L"ScreenBackground");
- }
- else
- {
- RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF));
- }
-
- RegCloseKey(hKey);
-}
-
-static void
-GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer)
-{
- DWORD dwNumSubKeys = 0;
- DWORD dwIndex;
- DWORD dwValueName;
- DWORD dwValue;
- DWORD dwType;
- WCHAR szValueName[MAX_PATH];
- WCHAR szValue[LF_FACESIZE] = L"\0";
- DWORD Value;
-
- if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
- {
- DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n");
- return;
- }
-
- DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys);
-
- for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++)
- {
- dwValue = sizeof(Value);
- dwValueName = MAX_PATH;
-
- if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS)
- {
- if (dwType == REG_SZ)
- {
- /*
- * retry in case of string value
- */
- dwValue = sizeof(szValue);
- dwValueName = LF_FACESIZE;
- if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
- break;
- }
- else
- break;
- }
- if (!wcscmp(szValueName, L"CursorSize"))
- {
- if (Value == 0x32)
- {
- Buffer->CursorInfo.dwSize = Value;
- }
- else if (Value == 0x64)
- {
- Buffer->CursorInfo.dwSize = Value;
- }
- }
- else if (!wcscmp(szValueName, L"ScreenText"))
- {
- GuiData->ScreenText = Value;
- }
- else if (!wcscmp(szValueName, L"ScreenBackground"))
- {
- GuiData->ScreenBackground = Value;
- }
- else if (!wcscmp(szValueName, L"FaceName"))
- {
- wcscpy(GuiData->FontName, szValue);
- }
- else if (!wcscmp(szValueName, L"FontSize"))
- {
- GuiData->FontSize = Value;
- }
- else if (!wcscmp(szValueName, L"FontWeight"))
- {
- GuiData->FontWeight = Value;
- }
- else if (!wcscmp(szValueName, L"HistoryNoDup"))
- {
- Console->HistoryNoDup = Value;
- }
- else if (!wcscmp(szValueName, L"WindowSize"))
- {
- Console->Size.X = LOWORD(Value);
- Console->Size.Y = HIWORD(Value);
- }
- else if (!wcscmp(szValueName, L"ScreenBufferSize"))
- {
- if(Buffer)
- {
- Buffer->MaxX = LOWORD(Value);
- Buffer->MaxY = HIWORD(Value);
- }
- }
- else if (!wcscmp(szValueName, L"FullScreen"))
- {
- GuiData->FullScreen = Value;
- }
- else if (!wcscmp(szValueName, L"QuickEdit"))
- {
- GuiData->QuickEdit = Value;
- }
- else if (!wcscmp(szValueName, L"InsertMode"))
- {
- GuiData->InsertMode = Value;
- }
- }
-}
-static VOID
-GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer)
-{
- /*
- * init guidata with default properties
- */
-
- wcscpy(GuiData->FontName, L"DejaVu Sans Mono");
- GuiData->FontSize = 0x0008000C; // font is 8x12
- GuiData->FontWeight = FW_NORMAL;
- GuiData->FullScreen = FALSE;
- GuiData->QuickEdit = FALSE;
- GuiData->InsertMode = TRUE;
- GuiData->ScreenText = RGB(192, 192, 192);
- GuiData->ScreenBackground = RGB(0, 0, 0);
- GuiData->PopupText = RGB(128, 0, 128);
- GuiData->PopupBackground = RGB(255, 255, 255);
- GuiData->WindowPosition = UINT_MAX;
- GuiData->UseRasterFonts = TRUE;
- memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors));
-
- Console->HistoryBufferSize = 50;
- Console->NumberOfHistoryBuffers = 5;
- Console->HistoryNoDup = FALSE;
- Console->Size.X = 80;
- Console->Size.Y = 25;
-
- if (Buffer)
- {
- Buffer->MaxX = 80;
- Buffer->MaxY = 300;
- Buffer->CursorInfo.bVisible = TRUE;
- Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
- }
-}
-
-VOID
-FASTCALL
-GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd)
-{
- SCROLLINFO sInfo;
- PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
-
- DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
- DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
-
- /* set scrollbar sizes */
- sInfo.cbSize = sizeof(SCROLLINFO);
- sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
- sInfo.nMin = 0;
- if (Console->ActiveBuffer->MaxY > Console->Size.Y)
- {
- sInfo.nMax = Console->ActiveBuffer->MaxY - 1;
- sInfo.nPage = Console->Size.Y;
- sInfo.nPos = Console->ActiveBuffer->ShowY;
- SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE);
- Width += GetSystemMetrics(SM_CXVSCROLL);
- ShowScrollBar(hwnd, SB_VERT, TRUE);
- }
- else
- {
- ShowScrollBar(hwnd, SB_VERT, FALSE);
- }
-
- if (Console->ActiveBuffer->MaxX > Console->Size.X)
- {
- sInfo.nMax = Console->ActiveBuffer->MaxX - 1;
- sInfo.nPage = Console->Size.X;
- sInfo.nPos = Console->ActiveBuffer->ShowX;
- SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE);
- Height += GetSystemMetrics(SM_CYHSCROLL);
- ShowScrollBar(hwnd, SB_HORZ, TRUE);
-
- }
- else
- {
- ShowScrollBar(hwnd, SB_HORZ, FALSE);
- }
-
- SetWindowPos(hwnd, NULL, 0, 0, Width, Height,
- SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
-}
-
-static BOOL
-GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
-{
- PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams;
- PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData;
- HDC Dc;
- HFONT OldFont;
- TEXTMETRICW Metrics;
- SIZE CharSize;
- PCSR_PROCESS ProcessData;
- HKEY hKey;
-
- Console->hWindow = hWnd;
-
- if (NULL == GuiData)
- {
- DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
- return FALSE;
- }
-
- GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer);
- if (Console->ProcessList.Flink != &Console->ProcessList)
- {
- ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSR_PROCESS, ConsoleLink);
- if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ClientId.UniqueProcess), &hKey, KEY_READ, FALSE))
- {
- GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer);
- RegCloseKey(hKey);
- }
- }
-
- InitializeCriticalSection(&GuiData->Lock);
-
- GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize),
- 0, //HIWORD(GuiData->FontSize),
- 0,
- TA_BASELINE,
- GuiData->FontWeight,
- FALSE,
- FALSE,
- FALSE,
- OEM_CHARSET,
- OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE,
- GuiData->FontName);
- if (NULL == GuiData->Font)
- {
- DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
- DeleteCriticalSection(&GuiData->Lock);
- HeapFree(Win32CsrApiHeap, 0, GuiData);
- return FALSE;
- }
- Dc = GetDC(hWnd);
- if (NULL == Dc)
- {
- DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
- DeleteObject(GuiData->Font);
- DeleteCriticalSection(&GuiData->Lock);
- HeapFree(Win32CsrApiHeap, 0, GuiData);
- return FALSE;
- }
- OldFont = SelectObject(Dc, GuiData->Font);
- if (NULL == OldFont)
- {
- DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
- ReleaseDC(hWnd, Dc);
- DeleteObject(GuiData->Font);
- DeleteCriticalSection(&GuiData->Lock);
- HeapFree(Win32CsrApiHeap, 0, GuiData);
- return FALSE;
- }
- if (! GetTextMetricsW(Dc, &Metrics))
- {
- DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
- SelectObject(Dc, OldFont);
- ReleaseDC(hWnd, Dc);
- DeleteObject(GuiData->Font);
- DeleteCriticalSection(&GuiData->Lock);
- HeapFree(Win32CsrApiHeap, 0, GuiData);
- return FALSE;
- }
- GuiData->CharWidth = Metrics.tmMaxCharWidth;
- GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
-
- /* Measure real char width more precisely if possible. */
- if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize))
- GuiData->CharWidth = CharSize.cx;
-
- SelectObject(Dc, OldFont);
-
- ReleaseDC(hWnd, Dc);
- GuiData->CursorBlinkOn = TRUE;
- GuiData->ForceCursorOff = FALSE;
-
- DPRINT("Console %p GuiData %p\n", Console, GuiData);
- Console->PrivateData = GuiData;
- SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console);
-
- SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
- GuiConsoleCreateSysMenu(Console);
-
- GuiData->WindowSizeLock = TRUE;
- GuiConsoleInitScrollbar(Console, hWnd);
- GuiData->WindowSizeLock = FALSE;
-
- SetEvent(GuiData->hGuiInitEvent);
-
- return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create);
-}
-
-static VOID
-SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect)
-{
- PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
- PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
- Rect->left = (SmallRect->Left - Buffer->ShowX) * GuiData->CharWidth;
- Rect->top = (SmallRect->Top - Buffer->ShowY) * GuiData->CharHeight;
- Rect->right = (SmallRect->Right + 1 - Buffer->ShowX) * GuiData->CharWidth;
- Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ShowY) * GuiData->CharHeight;
-}
-
-static VOID
-GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord)
-{
- RECT oldRect, newRect;
- HWND hWnd = Console->hWindow;
-
- SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection);
-
- if(coord != NULL)
- {
- SMALL_RECT rc;
- /* exchange left/top with right/bottom if required */
- rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X);
- rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y);
- rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X);
- rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y);
-
- SmallRectToRect(Console, &newRect, &rc);
-
- if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
- {
- if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0)
- {
- HRGN rgn1, rgn2;
-
- /* calculate the region that needs to be updated */
- if((rgn1 = CreateRectRgnIndirect(&oldRect)))
- {
- if((rgn2 = CreateRectRgnIndirect(&newRect)))
- {
- if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
- {
- InvalidateRgn(hWnd, rgn1, FALSE);
- }
-
- DeleteObject(rgn2);
- }
- DeleteObject(rgn1);
- }
- }
- }
- else
- {
- InvalidateRect(hWnd, &newRect, FALSE);
- }
- Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY;
- Console->Selection.srSelection = rc;
- ConioPause(Console, PAUSED_FROM_SELECTION);
- }
- else
- {
- /* clear the selection */
- if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
- {
- InvalidateRect(hWnd, &oldRect, FALSE);
- }
- Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
- ConioUnpause(Console, PAUSED_FROM_SELECTION);
- }
-}
-
-
-static VOID
-GuiConsolePaint(PCSRSS_CONSOLE Console,
- PGUI_CONSOLE_DATA GuiData,
- HDC hDC,
- PRECT rc)
-{
- PCSRSS_SCREEN_BUFFER Buff;
- ULONG TopLine, BottomLine, LeftChar, RightChar;
- ULONG Line, Char, Start;
- PBYTE From;
- PWCHAR To;
- BYTE LastAttribute, Attribute;
- ULONG CursorX, CursorY, CursorHeight;
- HBRUSH CursorBrush, OldBrush;
- HFONT OldFont;
-
- Buff = Console->ActiveBuffer;
-
- EnterCriticalSection(&Buff->Header.Console->Lock);
-
- TopLine = rc->top / GuiData->CharHeight + Buff->ShowY;
- BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buff->ShowY;
- LeftChar = rc->left / GuiData->CharWidth + Buff->ShowX;
- RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + Buff->ShowX;
- LastAttribute = ConioCoordToPointer(Buff, LeftChar, TopLine)[1];
-
- SetTextColor(hDC, GuiConsoleRGBFromAttribute(GuiData, LastAttribute));
- SetBkColor(hDC, GuiConsoleRGBFromAttribute(GuiData, LastAttribute >> 4));
-
- if (BottomLine >= Buff->MaxY) BottomLine = Buff->MaxY - 1;
- if (RightChar >= Buff->MaxX) RightChar = Buff->MaxX - 1;
-
- OldFont = SelectObject(hDC,
- GuiData->Font);
-
- for (Line = TopLine; Line <= BottomLine; Line++)
- {
- WCHAR LineBuffer[80];
- From = ConioCoordToPointer(Buff, LeftChar, Line);
- Start = LeftChar;
- To = LineBuffer;
-
- for (Char = LeftChar; Char <= RightChar; Char++)
- {
- if (*(From + 1) != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR)))
- {
- TextOutW(hDC,
- (Start - Buff->ShowX) * GuiData->CharWidth,
- (Line - Buff->ShowY) * GuiData->CharHeight,
- LineBuffer,
- Char - Start);
- Start = Char;
- To = LineBuffer;
- Attribute = *(From + 1);
- if (Attribute != LastAttribute)
- {
- SetTextColor(hDC, GuiConsoleRGBFromAttribute(GuiData, Attribute));
- SetBkColor(hDC, GuiConsoleRGBFromAttribute(GuiData, Attribute >> 4));
- LastAttribute = Attribute;
- }
- }
-
- MultiByteToWideChar(Console->OutputCodePage,
- 0,
- (PCHAR)From,
- 1,
- To,
- 1);
- To++;
- From += 2;
- }
-
- TextOutW(hDC,
- (Start - Buff->ShowX) * GuiData->CharWidth,
- (Line - Buff->ShowY) * GuiData->CharHeight,
- LineBuffer,
- RightChar - Start + 1);
- }
-
- if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn &&
- !GuiData->ForceCursorOff)
- {
- CursorX = Buff->CurrentX;
- CursorY = Buff->CurrentY;
- if (LeftChar <= CursorX && CursorX <= RightChar &&
- TopLine <= CursorY && CursorY <= BottomLine)
- {
- CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight);
- From = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY) + 1;
-
- if (*From != DEFAULT_ATTRIB)
- {
- CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(GuiData, *From));
- }
- else
- {
- CursorBrush = CreateSolidBrush(GuiData->ScreenText);
- }
-
- OldBrush = SelectObject(hDC,
- CursorBrush);
- PatBlt(hDC,
- (CursorX - Buff->ShowX) * GuiData->CharWidth,
- (CursorY - Buff->ShowY) * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
- GuiData->CharWidth,
- CursorHeight,
- PATCOPY);
- SelectObject(hDC,
- OldBrush);
- DeleteObject(CursorBrush);
- }
- }
-
- LeaveCriticalSection(&Buff->Header.Console->Lock);
-
- SelectObject(hDC,
- OldFont);
-}
-
-static VOID
-GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
-{
- HDC hDC;
- PAINTSTRUCT ps;
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
-
- hDC = BeginPaint(hWnd, &ps);
- if (hDC != NULL &&
- ps.rcPaint.left < ps.rcPaint.right &&
- ps.rcPaint.top < ps.rcPaint.bottom)
- {
- GuiConsoleGetDataPointers(hWnd,
- &Console,
- &GuiData);
- if (Console != NULL && GuiData != NULL &&
- Console->ActiveBuffer != NULL)
- {
- if (Console->ActiveBuffer->Buffer != NULL)
- {
- EnterCriticalSection(&GuiData->Lock);
-
- GuiConsolePaint(Console,
- GuiData,
- hDC,
- &ps.rcPaint);
-
- if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
- {
- RECT rc;
- SmallRectToRect(Console, &rc, &Console->Selection.srSelection);
-
- /* invert the selection */
- if (IntersectRect(&rc,
- &ps.rcPaint,
- &rc))
- {
- PatBlt(hDC,
- rc.left,
- rc.top,
- rc.right - rc.left,
- rc.bottom - rc.top,
- DSTINVERT);
- }
- }
-
- LeaveCriticalSection(&GuiData->Lock);
- }
- }
-
- }
- EndPaint(hWnd, &ps);
-}
-
-static VOID
-GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- MSG Message;
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- Message.hwnd = hWnd;
- Message.message = msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
-
- if(msg == WM_CHAR || msg == WM_SYSKEYDOWN)
- {
- /* clear the selection */
- GuiConsoleUpdateSelection(Console, NULL);
- }
-
- ConioProcessKey(&Message, Console, FALSE);
-}
-
-static VOID WINAPI
-GuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region)
-{
- RECT RegionRect;
- SmallRectToRect(Console, &RegionRect, Region);
- InvalidateRect(Console->hWindow, &RegionRect, FALSE);
-}
-
-static VOID
-GuiInvalidateCell(PCSRSS_CONSOLE Console, UINT x, UINT y)
-{
- SMALL_RECT CellRect = { x, y, x, y };
- GuiDrawRegion(Console, &CellRect);
-}
-
-static VOID WINAPI
-GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY,
- UINT ScrolledLines, CHAR *Buffer, UINT Length)
-{
- PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
- PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
- LONG CursorEndX, CursorEndY;
- RECT ScrollRect;
-
- if (NULL == Console->hWindow || NULL == GuiData)
- {
- return;
- }
-
- if (0 != ScrolledLines)
- {
- ScrollRect.left = 0;
- ScrollRect.top = 0;
- ScrollRect.right = Console->Size.X * GuiData->CharWidth;
- ScrollRect.bottom = Region->Top * GuiData->CharHeight;
-
- ScrollWindowEx(Console->hWindow,
- 0,
- -(ScrolledLines * GuiData->CharHeight),
- &ScrollRect,
- NULL,
- NULL,
- NULL,
- SW_INVALIDATE);
- }
-
- GuiDrawRegion(Console, Region);
-
- if (CursorStartX < Region->Left || Region->Right < CursorStartX
- || CursorStartY < Region->Top || Region->Bottom < CursorStartY)
- {
- GuiInvalidateCell(Console, CursorStartX, CursorStartY);
- }
-
- CursorEndX = Buff->CurrentX;
- CursorEndY = Buff->CurrentY;
- if ((CursorEndX < Region->Left || Region->Right < CursorEndX
- || CursorEndY < Region->Top || Region->Bottom < CursorEndY)
- && (CursorEndX != CursorStartX || CursorEndY != CursorStartY))
- {
- GuiInvalidateCell(Console, CursorEndX, CursorEndY);
- }
-
- // Set up the update timer (very short interval) - this is a "hack" for getting the OS to
- // repaint the window without having it just freeze up and stay on the screen permanently.
- GuiData->CursorBlinkOn = TRUE;
- SetTimer(Console->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
-}
-
-static BOOL WINAPI
-GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
-{
- if (Console->ActiveBuffer == Buff)
- {
- GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
- }
-
- return TRUE;
-}
-
-static BOOL WINAPI
-GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
-{
- if (Console->ActiveBuffer == Buff)
- {
- /* Redraw char at old position (removes cursor) */
- GuiInvalidateCell(Console, OldCursorX, OldCursorY);
- /* Redraw char at new position (shows cursor) */
- GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
- }
-
- return TRUE;
-}
-
-static BOOL WINAPI
-GuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
-{
- PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
-
- if (Console->ActiveBuffer == Buff)
- {
- GuiData->ScreenText = GuiConsoleRGBFromAttribute(GuiData, Buff->DefaultAttrib);
- GuiData->ScreenBackground = GuiConsoleRGBFromAttribute(GuiData, Buff->DefaultAttrib >> 4);
- }
-
- return TRUE;
-}
-
-static VOID
-GuiConsoleHandleTimer(HWND hWnd)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- PCSRSS_SCREEN_BUFFER Buff;
-
- SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL);
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-
- Buff = Console->ActiveBuffer;
- GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
- GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn;
-
- if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY))
- {
- SCROLLINFO xScroll;
- int OldScrollX = -1, OldScrollY = -1;
- int NewScrollX = -1, NewScrollY = -1;
-
- xScroll.cbSize = sizeof(SCROLLINFO);
- xScroll.fMask = SIF_POS;
- // Capture the original position of the scroll bars and save them.
- if(GetScrollInfo(hWnd, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos;
- if(GetScrollInfo(hWnd, SB_VERT, &xScroll))OldScrollY = xScroll.nPos;
-
- // If we successfully got the info for the horizontal scrollbar
- if(OldScrollX >= 0)
- {
- if((Buff->CurrentX < Buff->ShowX)||(Buff->CurrentX >= (Buff->ShowX + Console->Size.X)))
- {
- // Handle the horizontal scroll bar
- if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1;
- else NewScrollX = 0;
- }
- else
- {
- NewScrollX = OldScrollX;
- }
- }
- // If we successfully got the info for the vertical scrollbar
- if(OldScrollY >= 0)
- {
- if((Buff->CurrentY < Buff->ShowY) || (Buff->CurrentY >= (Buff->ShowY + Console->Size.Y)))
- {
- // Handle the vertical scroll bar
- if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1;
- else NewScrollY = 0;
- }
- else
- {
- NewScrollY = OldScrollY;
- }
- }
-
- // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area
- // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar
- // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling)
- // and their associated scrollbar is left alone.
- if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY))
- {
- Buff->ShowX = NewScrollX;
- Buff->ShowY = NewScrollY;
- ScrollWindowEx(hWnd,
- (OldScrollX - NewScrollX) * GuiData->CharWidth,
- (OldScrollY - NewScrollY) * GuiData->CharHeight,
- NULL,
- NULL,
- NULL,
- NULL,
- SW_INVALIDATE);
- if(NewScrollX >= 0)
- {
- xScroll.nPos = NewScrollX;
- SetScrollInfo(hWnd, SB_HORZ, &xScroll, TRUE);
- }
- if(NewScrollY >= 0)
- {
- xScroll.nPos = NewScrollY;
- SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE);
- }
- UpdateWindow(hWnd);
- GuiData->OldCursor.x = Buff->CurrentX;
- GuiData->OldCursor.y = Buff->CurrentY;
- }
- }
-}
-
-static VOID
-GuiConsoleHandleClose(HWND hWnd)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- PLIST_ENTRY current_entry;
- PCSR_PROCESS current;
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-
- EnterCriticalSection(&Console->Lock);
-
- current_entry = Console->ProcessList.Flink;
- while (current_entry != &Console->ProcessList)
- {
- current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
- current_entry = current_entry->Flink;
-
- /* FIXME: Windows will wait up to 5 seconds for the thread to exit.
- * We shouldn't wait here, though, since the console lock is entered.
- * A copy of the thread list probably needs to be made. */
- ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current);
- }
-
- LeaveCriticalSection(&Console->Lock);
-}
-
-static VOID
-GuiConsoleHandleNcDestroy(HWND hWnd)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
-
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- KillTimer(hWnd, 1);
- Console->PrivateData = NULL;
- DeleteCriticalSection(&GuiData->Lock);
- GetSystemMenu(hWnd, TRUE);
- if (GuiData->ConsoleLibrary)
- FreeLibrary(GuiData->ConsoleLibrary);
-
- HeapFree(Win32CsrApiHeap, 0, GuiData);
-}
-
-static COORD
-PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam)
-{
- PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
- PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
- COORD Coord;
- Coord.X = Buffer->ShowX + ((short)LOWORD(lParam) / (int)GuiData->CharWidth);
- Coord.Y = Buffer->ShowY + ((short)HIWORD(lParam) / (int)GuiData->CharHeight);
-
- /* Clip coordinate to ensure it's inside buffer */
- if (Coord.X < 0) Coord.X = 0;
- else if (Coord.X >= Buffer->MaxX) Coord.X = Buffer->MaxX - 1;
- if (Coord.Y < 0) Coord.Y = 0;
- else if (Coord.Y >= Buffer->MaxY) Coord.Y = Buffer->MaxY - 1;
- return Coord;
-}
-
-static VOID
-GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- if (Console == NULL || GuiData == NULL) return;
-
- Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam);
-
- SetCapture(hWnd);
-
- Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
-
- GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor);
-}
-
-static VOID
-GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- COORD c;
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- if (Console == NULL || GuiData == NULL) return;
- if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
-
- c = PointToCoord(Console, lParam);
-
- Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
-
- GuiConsoleUpdateSelection(Console, &c);
-
- ReleaseCapture();
-}
-
-static VOID
-GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- COORD c;
-
- if (!(wParam & MK_LBUTTON)) return;
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- if (Console == NULL || GuiData == NULL) return;
- if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
-
- c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */
-
- GuiConsoleUpdateSelection(Console, &c);
-}
-
-static VOID
-GuiConsoleCopy(HWND hWnd, PCSRSS_CONSOLE Console)
-{
- if (OpenClipboard(hWnd) == TRUE)
- {
- HANDLE hData;
- PBYTE ptr;
- LPSTR data, dstPos;
- ULONG selWidth, selHeight;
- ULONG xPos, yPos, size;
-
- selWidth = Console->Selection.srSelection.Right - Console->Selection.srSelection.Left + 1;
- selHeight = Console->Selection.srSelection.Bottom - Console->Selection.srSelection.Top + 1;
- DPRINT("Selection is (%d|%d) to (%d|%d)\n",
- Console->Selection.srSelection.Left,
- Console->Selection.srSelection.Top,
- Console->Selection.srSelection.Right,
- Console->Selection.srSelection.Bottom);
-
- /* Basic size for one line and termination */
- size = selWidth + 1;
- if (selHeight > 0)
- {
- /* Multiple line selections have to get \r\n appended */
- size += ((selWidth + 2) * (selHeight - 1));
- }
-
- /* Allocate memory, it will be passed to the system and may not be freed here */
- hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
- if (hData == NULL)
- {
- CloseClipboard();
- return;
- }
- data = GlobalLock(hData);
- if (data == NULL)
- {
- CloseClipboard();
- return;
- }
-
- DPRINT("Copying %dx%d selection\n", selWidth, selHeight);
- dstPos = data;
-
- for (yPos = 0; yPos < selHeight; yPos++)
- {
- ptr = ConioCoordToPointer(Console->ActiveBuffer,
- Console->Selection.srSelection.Left,
- yPos + Console->Selection.srSelection.Top);
- /* Copy only the characters, leave attributes alone */
- for (xPos = 0; xPos < selWidth; xPos++)
- {
- dstPos[xPos] = ptr[xPos * 2];
- }
- dstPos += selWidth;
- if (yPos != (selHeight - 1))
- {
- strcat(data, "\r\n");
- dstPos += 2;
- }
- }
-
- DPRINT("Setting data <%s> to clipboard\n", data);
- GlobalUnlock(hData);
-
- EmptyClipboard();
- SetClipboardData(CF_TEXT, hData);
- CloseClipboard();
- }
-}
-
-static VOID
-GuiConsolePaste(HWND hWnd, PCSRSS_CONSOLE Console)
-{
- if (OpenClipboard(hWnd) == TRUE)
- {
- HANDLE hData;
- LPSTR str;
- size_t len;
-
- hData = GetClipboardData(CF_TEXT);
- if (hData == NULL)
- {
- CloseClipboard();
- return;
- }
-
- str = GlobalLock(hData);
- if (str == NULL)
- {
- CloseClipboard();
- return;
- }
- DPRINT("Got data <%s> from clipboard\n", str);
- len = strlen(str);
-
- ConioWriteConsole(Console, Console->ActiveBuffer, str, len, TRUE);
-
- GlobalUnlock(hData);
- CloseClipboard();
- }
-}
-
-static VOID
-GuiConsoleRightMouseDown(HWND hWnd)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- if (Console == NULL || GuiData == NULL) return;
-
- if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY))
- {
- GuiConsolePaste(hWnd, Console);
- }
- else
- {
- GuiConsoleCopy(hWnd, Console);
-
- /* Clear the selection */
- GuiConsoleUpdateSelection(Console, NULL);
- }
-
-}
-
-
-static VOID
-GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData)
-{
- PCSRSS_CONSOLE Console;
- APPLET_PROC CPLFunc;
- TCHAR szBuffer[MAX_PATH];
- ConsoleInfo SharedInfo;
-
- DPRINT("GuiConsoleShowConsoleProperties entered\n");
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-
- if (GuiData == NULL)
- {
- DPRINT("GuiConsoleGetDataPointers failed\n");
- return;
- }
-
- if (GuiData->ConsoleLibrary == NULL)
- {
- GetWindowsDirectory(szBuffer,MAX_PATH);
- _tcscat(szBuffer, _T("\\system32\\console.dll"));
- GuiData->ConsoleLibrary = LoadLibrary(szBuffer);
-
- if (GuiData->ConsoleLibrary == NULL)
- {
- DPRINT1("failed to load console.dll");
- return;
- }
- }
-
- CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet"));
- if (!CPLFunc)
- {
- DPRINT("Error: Console.dll misses CPlApplet export\n");
- return;
- }
-
- /* setup struct */
- SharedInfo.InsertMode = GuiData->InsertMode;
- SharedInfo.HistoryBufferSize = Console->HistoryBufferSize;
- SharedInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
- SharedInfo.ScreenText = GuiData->ScreenText;
- SharedInfo.ScreenBackground = GuiData->ScreenBackground;
- SharedInfo.PopupText = GuiData->PopupText;
- SharedInfo.PopupBackground = GuiData->PopupBackground;
- SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y);
- SharedInfo.WindowPosition = GuiData->WindowPosition;
- SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY);
- SharedInfo.UseRasterFonts = GuiData->UseRasterFonts;
- SharedInfo.FontSize = (DWORD)GuiData->FontSize;
- SharedInfo.FontWeight = GuiData->FontWeight;
- SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
- SharedInfo.HistoryNoDup = Console->HistoryNoDup;
- SharedInfo.FullScreen = GuiData->FullScreen;
- SharedInfo.QuickEdit = GuiData->QuickEdit;
- memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors));
-
- if (!CPLFunc(hWnd, CPL_INIT, 0, 0))
- {
- DPRINT("Error: failed to initialize console.dll\n");
- return;
- }
-
- if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1)
- {
- DPRINT("Error: console.dll returned unexpected CPL count\n");
- return;
- }
-
- CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults);
-}
-static LRESULT
-GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- LRESULT Ret = TRUE;
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- COORD bottomRight = { 0, 0 };
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-
- switch(wParam)
- {
- case ID_SYSTEM_EDIT_MARK:
- DPRINT1("Marking not handled yet\n");
- break;
-
- case ID_SYSTEM_EDIT_COPY:
- GuiConsoleCopy(hWnd, Console);
- break;
-
- case ID_SYSTEM_EDIT_PASTE:
- GuiConsolePaste(hWnd, Console);
- break;
-
- case ID_SYSTEM_EDIT_SELECTALL:
- bottomRight.X = Console->Size.X - 1;
- bottomRight.Y = Console->Size.Y - 1;
- GuiConsoleUpdateSelection(Console, &bottomRight);
- break;
-
- case ID_SYSTEM_EDIT_SCROLL:
- DPRINT1("Scrolling is not handled yet\n");
- break;
-
- case ID_SYSTEM_EDIT_FIND:
- DPRINT1("Finding is not handled yet\n");
- break;
-
- case ID_SYSTEM_DEFAULTS:
- GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData);
- break;
-
- case ID_SYSTEM_PROPERTIES:
- GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData);
- break;
-
- default:
- Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam);
- break;
- }
- return Ret;
-}
-
-static VOID
-GuiConsoleGetMinMaxInfo(HWND hWnd, PMINMAXINFO minMaxInfo)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- DWORD windx, windy;
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- if((Console == NULL)|| (GuiData == NULL)) return;
-
- windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
- windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
-
- minMaxInfo->ptMinTrackSize.x = windx;
- minMaxInfo->ptMinTrackSize.y = windy;
-
- windx = (Console->ActiveBuffer->MaxX) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
- windy = (Console->ActiveBuffer->MaxY) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
-
- if(Console->Size.X < Console->ActiveBuffer->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar
- if(Console->Size.Y < Console->ActiveBuffer->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar
-
- minMaxInfo->ptMaxTrackSize.x = windx;
- minMaxInfo->ptMaxTrackSize.y = windy;
-}
-static VOID
-GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- if((Console == NULL) || (GuiData == NULL)) return;
-
- if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED))
- {
- PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
- DWORD windx, windy, charx, chary;
-
- GuiData->WindowSizeLock = TRUE;
-
- windx = LOWORD(lParam);
- windy = HIWORD(lParam);
-
- // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar)
- if(Console->Size.X < Buff->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar
- if(Console->Size.Y < Buff->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar
-
- charx = windx / GuiData->CharWidth;
- chary = windy / GuiData->CharHeight;
-
- // Character alignment (round size up or down)
- if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
- if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
-
- // Compensate for added scroll bars in new window
- if(charx < Buff->MaxX)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar
- if(chary < Buff->MaxY)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar
-
- charx = windx / GuiData->CharWidth;
- chary = windy / GuiData->CharHeight;
-
- // Character alignment (round size up or down)
- if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
- if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
-
- // Resize window
- if((charx != Console->Size.X) || (chary != Console->Size.Y))
- {
- Console->Size.X = (charx <= Buff->MaxX) ? charx : Buff->MaxX;
- Console->Size.Y = (chary <= Buff->MaxY) ? chary : Buff->MaxY;
- }
-
- GuiConsoleInitScrollbar(Console, hWnd);
-
- // Adjust the start of the visible area if we are attempting to show nonexistent areas
- if((Buff->MaxX - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->MaxX - Console->Size.X;
- if((Buff->MaxY - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->MaxY - Console->Size.Y;
- InvalidateRect(hWnd, NULL, TRUE);
-
- GuiData->WindowSizeLock = FALSE;
- }
-}
-
-VOID
-FASTCALL
-GuiConsoleHandleScrollbarMenu(VOID)
-{
- HMENU hMenu;
-
- hMenu = CreatePopupMenu();
- if (hMenu == NULL)
- {
- DPRINT("CreatePopupMenu failed\n");
- return;
- }
- //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE);
- //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
- //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP);
- //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM);
- //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
- //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP);
- //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN);
- //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
- //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP);
- //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN);
-
-}
-
-static NTSTATUS WINAPI
-GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size)
-{
- BYTE * Buffer;
- DWORD Offset = 0;
- BYTE * OldPtr;
- USHORT CurrentY;
- BYTE * OldBuffer;
-#if HAVE_WMEMSET
- USHORT value = MAKEWORD(' ', ScreenBuffer->DefaultAttrib);
-#endif
- DWORD diff;
- DWORD i;
-
- /* Buffer size is not allowed to be smaller than window size */
- if (Size.X < Console->Size.X || Size.Y < Console->Size.Y)
- return STATUS_INVALID_PARAMETER;
-
- if (Size.X == ScreenBuffer->MaxX && Size.Y == ScreenBuffer->MaxY)
- return STATUS_SUCCESS;
-
- Buffer = HeapAlloc(Win32CsrApiHeap, 0, Size.X * Size.Y * 2);
- if (!Buffer)
- return STATUS_NO_MEMORY;
-
- DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->MaxX, ScreenBuffer->MaxY, Size.X, Size.Y);
- OldBuffer = ScreenBuffer->Buffer;
-
- for (CurrentY = 0; CurrentY < ScreenBuffer->MaxY && CurrentY < Size.Y; CurrentY++)
- {
- OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY);
- if (Size.X <= ScreenBuffer->MaxX)
- {
- /* reduce size */
- RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2);
- Offset += (Size.X * 2);
- }
- else
- {
- /* enlarge size */
- RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->MaxX * 2);
- Offset += (ScreenBuffer->MaxX * 2);
-
- diff = Size.X - ScreenBuffer->MaxX;
- /* zero new part of it */
-#if HAVE_WMEMSET
- wmemset((WCHAR*)&Buffer[Offset], value, diff);
-#else
- for (i = 0; i < diff; i++)
- {
- Buffer[Offset++] = ' ';
- Buffer[Offset++] = ScreenBuffer->DefaultAttrib;
- }
-#endif
- }
- }
-
- if (Size.Y > ScreenBuffer->MaxY)
- {
- diff = Size.X * (Size.Y - ScreenBuffer->MaxY);
-#if HAVE_WMEMSET
- wmemset((WCHAR*)&Buffer[Offset], value, diff);
-#else
- for (i = 0; i < diff; i++)
- {
- Buffer[Offset++] = ' ';
- Buffer[Offset++] = ScreenBuffer->DefaultAttrib;
- }
-#endif
- }
-
- (void)InterlockedExchangePointer((PVOID volatile *)&ScreenBuffer->Buffer, Buffer);
- HeapFree(Win32CsrApiHeap, 0, OldBuffer);
- ScreenBuffer->MaxX = Size.X;
- ScreenBuffer->MaxY = Size.Y;
- ScreenBuffer->VirtualY = 0;
-
- /* Ensure cursor and window are within buffer */
- if (ScreenBuffer->CurrentX >= Size.X)
- ScreenBuffer->CurrentX = Size.X - 1;
- if (ScreenBuffer->CurrentY >= Size.Y)
- ScreenBuffer->CurrentY = Size.Y - 1;
- if (ScreenBuffer->ShowX > Size.X - Console->Size.X)
- ScreenBuffer->ShowX = Size.X - Console->Size.X;
- if (ScreenBuffer->ShowY > Size.Y - Console->Size.Y)
- ScreenBuffer->ShowY = Size.Y - Console->Size.Y;
-
- /* TODO: Should update scrollbar, but can't use anything that
- * calls SendMessage or it could cause deadlock */
-
- return STATUS_SUCCESS;
-}
-
-static VOID
-GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo)
-{
- DWORD windx, windy;
- PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
- COORD BufSize;
- BOOL SizeChanged = FALSE;
-
- EnterCriticalSection(&Console->Lock);
-
- /* apply text / background color */
- GuiData->ScreenText = pConInfo->ScreenText;
- GuiData->ScreenBackground = pConInfo->ScreenBackground;
-
- /* apply cursor size */
- ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100);
-
- windx = LOWORD(pConInfo->WindowSize);
- windy = HIWORD(pConInfo->WindowSize);
-
- if (windx != Console->Size.X || windy != Console->Size.Y)
- {
- /* resize window */
- Console->Size.X = windx;
- Console->Size.Y = windy;
- SizeChanged = TRUE;
- }
-
- BufSize.X = LOWORD(pConInfo->ScreenBuffer);
- BufSize.Y = HIWORD(pConInfo->ScreenBuffer);
- if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY)
- {
- if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize)))
- SizeChanged = TRUE;
- }
-
- if (SizeChanged)
- {
- GuiData->WindowSizeLock = TRUE;
- GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow);
- GuiData->WindowSizeLock = FALSE;
- }
-
- LeaveCriticalSection(&Console->Lock);
- InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
-}
-
-static
-LRESULT
-GuiConsoleHandleScroll(HWND hwnd, UINT uMsg, WPARAM wParam)
-{
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- PGUI_CONSOLE_DATA GuiData;
- SCROLLINFO sInfo;
- int fnBar;
- int old_pos, Maximum;
- PUSHORT pShowXY;
-
- GuiConsoleGetDataPointers(hwnd, &Console, &GuiData);
- if (Console == NULL || GuiData == NULL)
- return FALSE;
- Buff = Console->ActiveBuffer;
-
- if (uMsg == WM_HSCROLL)
- {
- fnBar = SB_HORZ;
- Maximum = Buff->MaxX - Console->Size.X;
- pShowXY = &Buff->ShowX;
- }
- else
- {
- fnBar = SB_VERT;
- Maximum = Buff->MaxY - Console->Size.Y;
- pShowXY = &Buff->ShowY;
- }
-
- /* set scrollbar sizes */
- sInfo.cbSize = sizeof(SCROLLINFO);
- sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS;
-
- if (!GetScrollInfo(hwnd, fnBar, &sInfo))
- {
- return FALSE;
- }
-
- old_pos = sInfo.nPos;
-
- switch(LOWORD(wParam))
- {
- case SB_LINELEFT:
- sInfo.nPos -= 1;
- break;
-
- case SB_LINERIGHT:
- sInfo.nPos += 1;
- break;
-
- case SB_PAGELEFT:
- sInfo.nPos -= sInfo.nPage;
- break;
-
- case SB_PAGERIGHT:
- sInfo.nPos += sInfo.nPage;
- break;
-
- case SB_THUMBTRACK:
- sInfo.nPos = sInfo.nTrackPos;
- ConioPause(Console, PAUSED_FROM_SCROLLBAR);
- break;
-
- case SB_THUMBPOSITION:
- ConioUnpause(Console, PAUSED_FROM_SCROLLBAR);
- break;
-
- case SB_TOP:
- sInfo.nPos = sInfo.nMin;
- break;
-
- case SB_BOTTOM:
- sInfo.nPos = sInfo.nMax;
- break;
-
- default:
- break;
- }
-
- sInfo.nPos = max(sInfo.nPos, 0);
- sInfo.nPos = min(sInfo.nPos, Maximum);
-
- if (old_pos != sInfo.nPos)
- {
- USHORT OldX = Buff->ShowX;
- USHORT OldY = Buff->ShowY;
- *pShowXY = sInfo.nPos;
-
- ScrollWindowEx(hwnd,
- (OldX - Buff->ShowX) * GuiData->CharWidth,
- (OldY - Buff->ShowY) * GuiData->CharHeight,
- NULL,
- NULL,
- NULL,
- NULL,
- SW_INVALIDATE);
-
- sInfo.fMask = SIF_POS;
- SetScrollInfo(hwnd, fnBar, &sInfo, TRUE);
-
- UpdateWindow(hwnd);
- }
- return 0;
-}
-
-static LRESULT CALLBACK
-GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- LRESULT Result = 0;
- PGUI_CONSOLE_DATA GuiData = NULL;
- PCSRSS_CONSOLE Console = NULL;
-
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-
- switch(msg)
- {
- case WM_NCCREATE:
- Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam);
- break;
- case WM_PAINT:
- GuiConsoleHandlePaint(hWnd, (HDC)wParam);
- break;
- case WM_KEYDOWN:
- case WM_KEYUP:
- case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
- case WM_CHAR:
- GuiConsoleHandleKey(hWnd, msg, wParam, lParam);
- break;
- case WM_TIMER:
- GuiConsoleHandleTimer(hWnd);
- break;
- case WM_CLOSE:
- GuiConsoleHandleClose(hWnd);
- break;
- case WM_NCDESTROY:
- GuiConsoleHandleNcDestroy(hWnd);
- break;
- case WM_LBUTTONDOWN:
- GuiConsoleLeftMouseDown(hWnd, lParam);
- break;
- case WM_LBUTTONUP:
- GuiConsoleLeftMouseUp(hWnd, lParam);
- break;
- case WM_RBUTTONDOWN:
- GuiConsoleRightMouseDown(hWnd);
- break;
- case WM_MOUSEMOVE:
- GuiConsoleMouseMove(hWnd, wParam, lParam);
- break;
- case WM_SYSCOMMAND:
- Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam);
- break;
- case WM_HSCROLL:
- case WM_VSCROLL:
- Result = GuiConsoleHandleScroll(hWnd, msg, wParam);
- break;
- case WM_GETMINMAXINFO:
- GuiConsoleGetMinMaxInfo(hWnd, (PMINMAXINFO)lParam);
- break;
- case WM_SIZE:
- GuiConsoleResize(hWnd, wParam, lParam);
- break;
- case PM_APPLY_CONSOLE_INFO:
- GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam);
- if (lParam)
- {
- GuiConsoleWriteUserSettings(Console, GuiData);
- }
- break;
- default:
- Result = DefWindowProcW(hWnd, msg, wParam, lParam);
- break;
- }
-
- return Result;
-}
-
-static LRESULT CALLBACK
-GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- HWND NewWindow;
- LONG WindowCount;
- MSG Msg;
- PWCHAR Buffer, Title;
- PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam;
-
-
-
- switch(msg)
- {
- case WM_CREATE:
- SetWindowLongW(hWnd, GWL_USERDATA, 0);
- return 0;
- case PM_CREATE_CONSOLE:
- Buffer = HeapAlloc(Win32CsrApiHeap, 0,
- Console->Title.Length + sizeof(WCHAR));
- if (NULL != Buffer)
- {
- memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
- Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
- Title = Buffer;
- }
- else
- {
- Title = L"";
- }
- NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
- L"ConsoleWindowClass",
- Title,
- WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- (HINSTANCE) GetModuleHandleW(NULL),
- (PVOID) Console);
- if (NULL != Buffer)
- {
- HeapFree(Win32CsrApiHeap, 0, Buffer);
- }
- if (NULL != NewWindow)
- {
- SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
- ShowWindow(NewWindow, (int)wParam);
- }
- return (LRESULT) NewWindow;
- case PM_DESTROY_CONSOLE:
- /* Window creation is done using a PostMessage(), so it's possible that the
- * window that we want to destroy doesn't exist yet. So first empty the message
- * queue */
- while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&Msg);
- DispatchMessageW(&Msg);
- }
- DestroyWindow(Console->hWindow);
- Console->hWindow = NULL;
- WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
- WindowCount--;
- SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
- if (0 == WindowCount)
- {
- NotifyWnd = NULL;
- DestroyWindow(hWnd);
- PrivateCsrssManualGuiCheck(-1);
- PostQuitMessage(0);
- }
- return 0;
- default:
- return DefWindowProcW(hWnd, msg, wParam, lParam);
- }
-}
-
-static DWORD WINAPI
-GuiConsoleGuiThread(PVOID Data)
-{
- MSG msg;
- PHANDLE GraphicsStartupEvent = (PHANDLE) Data;
-
- NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify",
- L"",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- (HINSTANCE) GetModuleHandleW(NULL),
- NULL);
- if (NULL == NotifyWnd)
- {
- PrivateCsrssManualGuiCheck(-1);
- SetEvent(*GraphicsStartupEvent);
- return 1;
- }
-
- SetEvent(*GraphicsStartupEvent);
-
- while(GetMessageW(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- }
-
- return 1;
-}
-
-static BOOL
-GuiInit(VOID)
-{
- WNDCLASSEXW wc;
-
- if (NULL == NotifyWnd)
- {
- PrivateCsrssManualGuiCheck(+1);
- }
-
- wc.cbSize = sizeof(WNDCLASSEXW);
- wc.lpszClassName = L"Win32CsrCreateNotify";
- wc.lpfnWndProc = GuiConsoleNotifyWndProc;
- wc.style = 0;
- wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
- wc.hIcon = NULL;
- wc.hCursor = NULL;
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hIconSm = NULL;
- if (RegisterClassExW(&wc) == 0)
- {
- DPRINT1("Failed to register notify wndproc\n");
- return FALSE;
- }
-
- wc.cbSize = sizeof(WNDCLASSEXW);
- wc.lpszClassName = L"ConsoleWindowClass";
- wc.lpfnWndProc = GuiConsoleWndProc;
- wc.style = 0;
- wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
- wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1));
- wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW);
- wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
- wc.lpszMenuName = NULL;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON,
- GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
- LR_SHARED);
- if (RegisterClassExW(&wc) == 0)
- {
- DPRINT1("Failed to register console wndproc\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static VOID WINAPI
-GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
-{
- Buffer->DefaultAttrib = DEFAULT_ATTRIB;
-}
-
-static BOOL WINAPI
-GuiChangeTitle(PCSRSS_CONSOLE Console)
-{
- PWCHAR Buffer, Title;
-
- Buffer = HeapAlloc(Win32CsrApiHeap, 0,
- Console->Title.Length + sizeof(WCHAR));
- if (NULL != Buffer)
- {
- memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
- Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
- Title = Buffer;
- }
- else
- {
- Title = L"";
- }
-
- SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title);
-
- if (NULL != Buffer)
- {
- HeapFree(Win32CsrApiHeap, 0, Buffer);
- }
-
- return TRUE;
-}
-
-static BOOL WINAPI
-GuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon)
-{
- SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon);
- SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon);
-
- return TRUE;
-}
-
-static VOID WINAPI
-GuiCleanupConsole(PCSRSS_CONSOLE Console)
-{
- SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console);
-}
-
-static CSRSS_CONSOLE_VTBL GuiVtbl =
-{
- GuiInitScreenBuffer,
- GuiWriteStream,
- GuiDrawRegion,
- GuiSetCursorInfo,
- GuiSetScreenInfo,
- GuiUpdateScreenInfo,
- GuiChangeTitle,
- GuiCleanupConsole,
- GuiChangeIcon,
- GuiResizeBuffer,
-};
-
-NTSTATUS FASTCALL
-GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
-{
- HANDLE GraphicsStartupEvent;
- HANDLE ThreadHandle;
- PGUI_CONSOLE_DATA GuiData;
-
- if (! ConsInitialized)
- {
- ConsInitialized = TRUE;
- if (! GuiInit())
- {
- ConsInitialized = FALSE;
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- Console->Vtbl = &GuiVtbl;
- if (NULL == NotifyWnd)
- {
- GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
- if (NULL == GraphicsStartupEvent)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- ThreadHandle = CreateThread(NULL,
- 0,
- GuiConsoleGuiThread,
- (PVOID) &GraphicsStartupEvent,
- 0,
- NULL);
- if (NULL == ThreadHandle)
- {
- CloseHandle(GraphicsStartupEvent);
- DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
- return STATUS_UNSUCCESSFUL;
- }
- SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
- CloseHandle(ThreadHandle);
-
- WaitForSingleObject(GraphicsStartupEvent, INFINITE);
- CloseHandle(GraphicsStartupEvent);
-
- if (NULL == NotifyWnd)
- {
- DPRINT1("Win32Csr: Failed to create notification window.\n");
- return STATUS_UNSUCCESSFUL;
- }
- }
- GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
- sizeof(GUI_CONSOLE_DATA));
- if (!GuiData)
- {
- DPRINT1("Win32Csr: Failed to create GUI_CONSOLE_DATA\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Console->PrivateData = (PVOID) GuiData;
- /*
- * we need to wait untill the GUI has been fully initialized
- * to retrieve custom settings i.e. WindowSize etc..
- * Ideally we could use SendNotifyMessage for this but its not
- * yet implemented.
- *
- */
- GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
- /* create console */
- PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, ShowCmd, (LPARAM) Console);
-
- /* wait untill initialization has finished */
- WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
- DPRINT("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y);
- CloseHandle(GuiData->hGuiInitEvent);
- GuiData->hGuiInitEvent = NULL;
-
- return STATUS_SUCCESS;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/guiconsole.h
- * PURPOSE: Interface to GUI consoles
- */
-
-#include "api.h"
-
-#define CONGUI_MIN_WIDTH 10
-#define CONGUI_MIN_HEIGHT 10
-#define CONGUI_UPDATE_TIME 0
-#define CONGUI_UPDATE_TIMER 1
-
-NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible);
-VOID FASTCALL GuiConsoleHandleScrollbarMenu(VOID);
-
-/*EOF*/
+++ /dev/null
-/*
- * reactos/subsys/csrss/api/handle.c
- *
- * CSRSS handle functions
- *
- * ReactOS Operating System
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <w32csr.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-static
-BOOL
-CsrIsConsoleHandle(HANDLE Handle)
-{
- return ((ULONG_PTR)Handle & 0x10000003) == 0x3;
-}
-
-static INT
-AdjustHandleCounts(PCSRSS_HANDLE Entry, INT Change)
-{
- Object_t *Object = Entry->Object;
- if (Entry->Access & GENERIC_READ) Object->AccessRead += Change;
- if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change;
- if (!(Entry->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change;
- if (!(Entry->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change;
- Object->HandleCount += Change;
- return Object->HandleCount;
-}
-
-static VOID
-Win32CsrCreateHandleEntry(
- PCSRSS_HANDLE Entry)
-{
- Object_t *Object = Entry->Object;
- EnterCriticalSection(&Object->Console->Lock);
- AdjustHandleCounts(Entry, +1);
- LeaveCriticalSection(&Object->Console->Lock);
-}
-
-static VOID
-Win32CsrCloseHandleEntry(
- PCSRSS_HANDLE Entry)
-{
- Object_t *Object = Entry->Object;
- if (Object != NULL)
- {
- PCSRSS_CONSOLE Console = Object->Console;
- EnterCriticalSection(&Console->Lock);
- /* If the last handle to a screen buffer is closed, delete it */
- if (AdjustHandleCounts(Entry, -1) == 0
- && Object->Type == CONIO_SCREEN_BUFFER_MAGIC)
- {
- PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object;
- /* ...unless it's the only buffer left. Windows allows deletion
- * even of the last buffer, but having to deal with a lack of
- * any active buffer might be error-prone. */
- if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink)
- ConioDeleteScreenBuffer(Buffer);
- }
- LeaveCriticalSection(&Console->Lock);
- Entry->Object = NULL;
- }
-}
-
-NTSTATUS
-FASTCALL
-Win32CsrReleaseObject(
- PCSR_PROCESS ProcessData,
- HANDLE Handle)
-{
- ULONG_PTR h = (ULONG_PTR)Handle >> 2;
- Object_t *Object;
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (h >= ProcessData->HandleTableSize
- || (Object = ProcessData->HandleTable[h].Object) == NULL)
- {
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_HANDLE;
- }
- Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-FASTCALL
-Win32CsrLockObject(PCSR_PROCESS ProcessData,
- HANDLE Handle,
- Object_t **Object,
- DWORD Access,
- LONG Type)
-{
- ULONG_PTR h = (ULONG_PTR)Handle >> 2;
-
- DPRINT("CsrGetObject, Object: %x, %x, %x\n",
- Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
- || (*Object = ProcessData->HandleTable[h].Object) == NULL
- || ~ProcessData->HandleTable[h].Access & Access
- || (Type != 0 && (*Object)->Type != Type))
- {
- DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_HANDLE;
- }
- _InterlockedIncrement(&(*Object)->Console->ReferenceCount);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
- EnterCriticalSection(&((*Object)->Console->Lock));
- return STATUS_SUCCESS;
-}
-
-VOID
-FASTCALL
-Win32CsrUnlockObject(Object_t *Object)
-{
- PCSRSS_CONSOLE Console = Object->Console;
- LeaveCriticalSection(&Console->Lock);
- /* dec ref count */
- if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
- ConioDeleteConsole(&Console->Header);
-}
-
-VOID
-WINAPI
-Win32CsrReleaseConsole(
- PCSR_PROCESS ProcessData)
-{
- PCSRSS_CONSOLE Console;
- ULONG i;
-
- /* Close all console handles and detach process from console */
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
-
- for (i = 0; i < ProcessData->HandleTableSize; i++)
- Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
- ProcessData->HandleTableSize = 0;
- RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable);
- ProcessData->HandleTable = NULL;
-
- Console = ProcessData->Console;
- if (Console != NULL)
- {
- ProcessData->Console = NULL;
- EnterCriticalSection(&Console->Lock);
- RemoveEntryList(&ProcessData->ConsoleLink);
- LeaveCriticalSection(&Console->Lock);
- if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
- ConioDeleteConsole(&Console->Header);
- //CloseHandle(ProcessData->ConsoleEvent);
- //ProcessData->ConsoleEvent = NULL;
- }
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-}
-
-NTSTATUS
-FASTCALL
-Win32CsrInsertObject(
- PCSR_PROCESS ProcessData,
- PHANDLE Handle,
- Object_t *Object,
- DWORD Access,
- BOOL Inheritable,
- DWORD ShareMode)
-{
- ULONG i;
- PCSRSS_HANDLE Block;
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
-
- for (i = 0; i < ProcessData->HandleTableSize; i++)
- {
- if (ProcessData->HandleTable[i].Object == NULL)
- {
- break;
- }
- }
- if (i >= ProcessData->HandleTableSize)
- {
- Block = RtlAllocateHeap(Win32CsrApiHeap,
- HEAP_ZERO_MEMORY,
- (ProcessData->HandleTableSize + 64) * sizeof(CSRSS_HANDLE));
- if (Block == NULL)
- {
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return(STATUS_UNSUCCESSFUL);
- }
- RtlCopyMemory(Block,
- ProcessData->HandleTable,
- ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE));
- RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable);
- ProcessData->HandleTable = Block;
- ProcessData->HandleTableSize += 64;
- }
- ProcessData->HandleTable[i].Object = Object;
- ProcessData->HandleTable[i].Access = Access;
- ProcessData->HandleTable[i].Inheritable = Inheritable;
- ProcessData->HandleTable[i].ShareMode = ShareMode;
- Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]);
- *Handle = UlongToHandle((i << 2) | 0x3);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS
-WINAPI
-Win32CsrDuplicateHandleTable(
- PCSR_PROCESS SourceProcessData,
- PCSR_PROCESS TargetProcessData)
-{
- ULONG i;
-
- /* Only inherit if the flag was set */
- if (!TargetProcessData->bInheritHandles) return STATUS_SUCCESS;
-
- if (TargetProcessData->HandleTableSize)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);
-
- /* we are called from CreateProcessData, it isn't necessary to lock the target process data */
-
- TargetProcessData->HandleTable = RtlAllocateHeap(Win32CsrApiHeap,
- HEAP_ZERO_MEMORY,
- SourceProcessData->HandleTableSize
- * sizeof(CSRSS_HANDLE));
- if (TargetProcessData->HandleTable == NULL)
- {
- RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
- return(STATUS_UNSUCCESSFUL);
- }
- TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
- for (i = 0; i < SourceProcessData->HandleTableSize; i++)
- {
- if (SourceProcessData->HandleTable[i].Object != NULL &&
- SourceProcessData->HandleTable[i].Inheritable)
- {
- TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
- Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]);
- }
- }
- RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
- return(STATUS_SUCCESS);
-}
-
-CSR_API(CsrGetHandle)
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- Request->Data.GetInputHandleRequest.Handle = INVALID_HANDLE_VALUE;
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (ProcessData->Console)
- {
- DWORD DesiredAccess = Request->Data.GetInputHandleRequest.Access;
- DWORD ShareMode = Request->Data.GetInputHandleRequest.ShareMode;
-
- PCSRSS_CONSOLE Console = ProcessData->Console;
- Object_t *Object;
-
- EnterCriticalSection(&Console->Lock);
- if (Request->Type == GET_OUTPUT_HANDLE)
- Object = &Console->ActiveBuffer->Header;
- else
- Object = &Console->Header;
-
- if (((DesiredAccess & GENERIC_READ) && Object->ExclusiveRead != 0) ||
- ((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite != 0) ||
- (!(ShareMode & FILE_SHARE_READ) && Object->AccessRead != 0) ||
- (!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite != 0))
- {
- DPRINT1("Sharing violation\n");
- Status = STATUS_SHARING_VIOLATION;
- }
- else
- {
- Status = Win32CsrInsertObject(ProcessData,
- &Request->Data.GetInputHandleRequest.Handle,
- Object,
- DesiredAccess,
- Request->Data.GetInputHandleRequest.Inheritable,
- ShareMode);
- }
- LeaveCriticalSection(&Console->Lock);
- }
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
- return Status;
-}
-
-CSR_API(CsrCloseHandle)
-{
- return Win32CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle);
-}
-
-CSR_API(CsrVerifyHandle)
-{
- ULONG_PTR Index;
- NTSTATUS Status = STATUS_SUCCESS;
-
- Index = (ULONG_PTR)Request->Data.VerifyHandleRequest.Handle >> 2;
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (Index >= ProcessData->HandleTableSize ||
- ProcessData->HandleTable[Index].Object == NULL)
- {
- DPRINT("CsrVerifyObject failed\n");
- Status = STATUS_INVALID_HANDLE;
- }
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
- return Status;
-}
-
-CSR_API(CsrDuplicateHandle)
-{
- ULONG_PTR Index;
- PCSRSS_HANDLE Entry;
- DWORD DesiredAccess;
-
- Index = (ULONG_PTR)Request->Data.DuplicateHandleRequest.Handle >> 2;
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (Index >= ProcessData->HandleTableSize
- || (Entry = &ProcessData->HandleTable[Index])->Object == NULL)
- {
- DPRINT1("Couldn't dup invalid handle %p\n", Request->Data.DuplicateHandleRequest.Handle);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_HANDLE;
- }
-
- if (Request->Data.DuplicateHandleRequest.Options & DUPLICATE_SAME_ACCESS)
- {
- DesiredAccess = Entry->Access;
- }
- else
- {
- DesiredAccess = Request->Data.DuplicateHandleRequest.Access;
- /* Make sure the source handle has all the desired flags */
- if (~Entry->Access & DesiredAccess)
- {
- DPRINT1("Handle %p only has access %X; requested %X\n",
- Request->Data.DuplicateHandleRequest.Handle, Entry->Access, DesiredAccess);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_PARAMETER;
- }
- }
-
- Request->Status = Win32CsrInsertObject(ProcessData,
- &Request->Data.DuplicateHandleRequest.Handle,
- Entry->Object,
- DesiredAccess,
- Request->Data.DuplicateHandleRequest.Inheritable,
- Entry->ShareMode);
- if (NT_SUCCESS(Request->Status)
- && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE)
- {
- Win32CsrCloseHandleEntry(Entry);
- }
-
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return Request->Status;
-}
-
-CSR_API(CsrGetInputWaitHandle)
-{
- Request->Data.GetConsoleInputWaitHandle.InputWaitHandle = ProcessData->ConsoleEvent;
- return STATUS_SUCCESS;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/dllmain.c
- * PURPOSE: Initialization
- * PROGRAMMERS: Dmitry Philippov (shedon@mail.ru)
- * Timo Kreuzer (timo.kreuzer@reactos.org)
- */
-
-/* INCLUDES ******************************************************************/
-
-#define NDEBUG
-#include "w32csr.h"
-#include <debug.h>
-#include <strsafe.h>
-
-#define IDTRYAGAIN 10
-#define IDCONTINUE 11
-
-/* FUNCTIONS *****************************************************************/
-
-static
-NTSTATUS
-CsrpGetClientFileName(
- OUT PUNICODE_STRING ClientFileNameU,
- HANDLE hProcess)
-{
- PLIST_ENTRY ModuleListHead;
- PLIST_ENTRY Entry;
- PLDR_DATA_TABLE_ENTRY Module;
- PPEB_LDR_DATA Ldr;
- PROCESS_BASIC_INFORMATION ClientBasicInfo;
- LDR_DATA_TABLE_ENTRY ModuleData;
- PVOID ClientDllBase;
- NTSTATUS Status;
- PPEB Peb;
-
- /* Initialize string */
- ClientFileNameU->MaximumLength = 0;
- ClientFileNameU->Length = 0;
- ClientFileNameU->Buffer = NULL;
-
- /* Query process information */
- Status = NtQueryInformationProcess(hProcess,
- ProcessBasicInformation,
- &ClientBasicInfo,
- sizeof(ClientBasicInfo),
- NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- Peb = ClientBasicInfo.PebBaseAddress;
- if (!Peb) return STATUS_UNSUCCESSFUL;
-
- Status = NtReadVirtualMemory(hProcess, &Peb->Ldr, &Ldr, sizeof(Ldr), NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- ModuleListHead = &Ldr->InLoadOrderModuleList;
- Status = NtReadVirtualMemory(hProcess,
- &ModuleListHead->Flink,
- &Entry,
- sizeof(Entry),
- NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- if (Entry == ModuleListHead) return STATUS_UNSUCCESSFUL;
-
- Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
-
- Status = NtReadVirtualMemory(hProcess,
- Module,
- &ModuleData,
- sizeof(ModuleData),
- NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- Status = NtReadVirtualMemory(hProcess,
- &Peb->ImageBaseAddress,
- &ClientDllBase,
- sizeof(ClientDllBase),
- NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- if (ClientDllBase != ModuleData.DllBase) return STATUS_UNSUCCESSFUL;
-
- ClientFileNameU->MaximumLength = ModuleData.BaseDllName.MaximumLength;
- ClientFileNameU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- ClientFileNameU->MaximumLength);
-
- Status = NtReadVirtualMemory(hProcess,
- ModuleData.BaseDllName.Buffer,
- ClientFileNameU->Buffer,
- ClientFileNameU->MaximumLength,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, ClientFileNameU->Buffer);
- ClientFileNameU->Buffer = NULL;
- ClientFileNameU->MaximumLength = 0;
- return Status;
- }
-
- ClientFileNameU->Length = wcslen(ClientFileNameU->Buffer)*sizeof(wchar_t);
- DPRINT("ClientFileNameU=\'%wZ\'\n", &ClientFileNameU);
-
- return STATUS_SUCCESS;
-}
-
-static
-VOID
-CsrpFreeStringParameters(
- IN OUT PULONG_PTR Parameters,
- IN PHARDERROR_MSG HardErrorMessage)
-{
- ULONG nParam;
-
- /* Loop all parameters */
- for (nParam = 0; nParam < HardErrorMessage->NumberOfParameters; nParam++)
- {
- /* Check if the current parameter is a string */
- if (HardErrorMessage->UnicodeStringParameterMask & (1 << nParam) && Parameters[nParam])
- {
- /* Free the string buffer */
- RtlFreeHeap(RtlGetProcessHeap(), 0, (PVOID)Parameters[nParam]);
- }
- }
-}
-
-static
-NTSTATUS
-CsrpCaptureStringParameters(
- OUT PULONG_PTR Parameters,
- OUT PULONG SizeOfAllUnicodeStrings,
- IN PHARDERROR_MSG HardErrorMessage,
- HANDLE hProcess)
-{
- ULONG nParam, Size = 0;
- NTSTATUS Status = STATUS_SUCCESS;
- UNICODE_STRING TempStringU, ParamStringU;
- ANSI_STRING TempStringA;
-
- /* Read all strings from client space */
- for (nParam = 0; nParam < HardErrorMessage->NumberOfParameters; nParam++)
- {
- Parameters[nParam] = 0;
-
- /* Check if the current parameter is a unicode string */
- if (HardErrorMessage->UnicodeStringParameterMask & (1 << nParam))
- {
- /* Read the UNICODE_STRING from the process memory */
- Status = NtReadVirtualMemory(hProcess,
- (PVOID)HardErrorMessage->Parameters[nParam],
- &ParamStringU,
- sizeof(ParamStringU),
- NULL);
-
- if (!NT_SUCCESS(Status))
- break;
-
- /* Allocate a buffer for the string */
- TempStringU.MaximumLength = ParamStringU.Length;
- TempStringU.Length = ParamStringU.Length;
- TempStringU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- TempStringU.MaximumLength);
-
- if (!TempStringU.Buffer)
- {
- DPRINT1("Cannot allocate memory %u\n", TempStringU.MaximumLength);
- Status = STATUS_NO_MEMORY;
- }
-
- /* Read the string buffer from the process memory */
- Status = NtReadVirtualMemory(hProcess,
- ParamStringU.Buffer,
- TempStringU.Buffer,
- ParamStringU.Length,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtReadVirtualMemory failed with code: %lx\n", Status);
- RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
- break;
- }
-
- DPRINT("ParamString=\'%wZ\'\n", &TempStringU);
-
- /* Allocate a buffer for converted to ANSI string */
- TempStringA.MaximumLength = RtlUnicodeStringToAnsiSize(&TempStringU);
- TempStringA.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- TempStringA.MaximumLength);
-
- if (!TempStringA.Buffer)
- {
- DPRINT1("Cannot allocate memory %u\n", TempStringA.MaximumLength);
- RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
- Status = STATUS_NO_MEMORY;
- break;
- }
-
- /* Convert string to ANSI and free temporary buffer */
- Status = RtlUnicodeStringToAnsiString(&TempStringA, &TempStringU, FALSE);
- RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringA.Buffer);
- break;
- }
-
- /* Note: RtlUnicodeStringToAnsiString returns NULL terminated string */
- Parameters[nParam] = (ULONG_PTR)TempStringA.Buffer;
- Size += TempStringU.Length;
- }
- else
- {
- /* It's not a unicode string */
- Parameters[nParam] = HardErrorMessage->Parameters[nParam];
- }
- }
-
- if (!NT_SUCCESS(Status))
- {
- CsrpFreeStringParameters(Parameters, HardErrorMessage);
- return Status;
- }
-
- *SizeOfAllUnicodeStrings = Size;
- return Status;
-}
-
-static
-NTSTATUS
-CsrpFormatMessages(
- OUT PUNICODE_STRING TextStringU,
- OUT PUNICODE_STRING CaptionStringU,
- IN PULONG_PTR Parameters,
- IN ULONG SizeOfStrings,
- IN PHARDERROR_MSG Message,
- IN HANDLE hProcess)
-{
- NTSTATUS Status;
- UNICODE_STRING FileNameU, TempStringU, FormatU;
- ANSI_STRING FormatA;
- PMESSAGE_RESOURCE_ENTRY MessageResource;
- PWSTR FormatString;
- ULONG Size, ExceptionCode;
-
- /* Get the file name of the client process */
- CsrpGetClientFileName(&FileNameU, hProcess);
-
- /* Check if we have a file name */
- if (!FileNameU.Buffer)
- {
- /* No, use system */
- RtlInitUnicodeString(&FileNameU, L"System");
- }
-
- /* Get text string of the error code */
- Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
- (ULONG_PTR)RT_MESSAGETABLE,
- LANG_NEUTRAL,
- Message->Status,
- &MessageResource);
-
- if (NT_SUCCESS(Status))
- {
- if (MessageResource->Flags)
- {
- RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
- FormatA.Buffer = NULL;
- }
- else
- {
- RtlInitAnsiString(&FormatA, (PCHAR)MessageResource->Text);
- RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
- }
- }
- else
- {
- /* Fall back to hardcoded value */
- RtlInitUnicodeString(&FormatU, L"Unknown Hard Error");
- FormatA.Buffer = NULL;
- }
-
- FormatString = FormatU.Buffer;
-
- /* Check whether a caption exists */
- if (FormatString[0] == L'{')
- {
- /* Set caption start */
- TempStringU.Buffer = ++FormatString;
-
- /* Get size of the caption */
- for (Size = 0; *FormatString != 0 && *FormatString != L'}'; Size++)
- FormatString++;
-
- /* Skip '}', '\r', '\n' */
- FormatString += 3;
-
- TempStringU.Length = Size * sizeof(WCHAR);
- TempStringU.MaximumLength = TempStringU.Length;
- }
- else
- {
- /* FIXME: Set string based on severity */
- RtlInitUnicodeString(&TempStringU, L"Application Error");
- }
-
- /* Calculate buffer length for the caption */
- CaptionStringU->MaximumLength = FileNameU.Length + TempStringU.Length +
- 4 * sizeof(WCHAR);
-
- /* Allocate a buffer for the caption */
- CaptionStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- CaptionStringU->MaximumLength);
-
- /* Append the file name, seperator and the caption text */
- CaptionStringU->Length = 0;
- RtlAppendUnicodeStringToString(CaptionStringU, &FileNameU);
- RtlAppendUnicodeToString(CaptionStringU, L" - ");
- RtlAppendUnicodeStringToString(CaptionStringU, &TempStringU);
-
- /* Zero terminate the buffer */
- CaptionStringU->Buffer[CaptionStringU->Length / sizeof(WCHAR)] = 0;
-
- /* Free the file name buffer */
- RtlFreeUnicodeString(&FileNameU);
-
- /* Check if this is an exception message */
- if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
- {
- ExceptionCode = Parameters[0];
-
- /* Handle special cases */
- if (ExceptionCode == STATUS_ACCESS_VIOLATION)
- {
- Parameters[0] = Parameters[1];
- Parameters[1] = Parameters[3];
- if (Parameters[2]) Parameters[2] = (ULONG_PTR)L"written";
- else Parameters[2] = (ULONG_PTR)L"read";
- MessageResource = NULL;
- }
- else if (ExceptionCode == STATUS_IN_PAGE_ERROR)
- {
- Parameters[0] = Parameters[1];
- Parameters[1] = Parameters[3];
- MessageResource = NULL;
- }
- else
- {
- /* Fall back to hardcoded value */
- Parameters[2] = Parameters[1];
- Parameters[1] = Parameters[0];
- Parameters[0] = (ULONG_PTR)L"unknown software exception";
- }
-
- if (!MessageResource)
- {
- /* Get text string of the exception code */
- Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
- (ULONG_PTR)RT_MESSAGETABLE,
- LANG_NEUTRAL,
- ExceptionCode,
- &MessageResource);
-
- if (NT_SUCCESS(Status))
- {
- if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);
-
- if (MessageResource->Flags)
- {
- RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
- FormatA.Buffer = NULL;
- }
- else
- {
- RtlInitAnsiString(&FormatA, (PCHAR)MessageResource->Text);
- RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
- }
- FormatString = FormatU.Buffer;
- }
- else
- {
- /* Fall back to hardcoded value */
- Parameters[2] = Parameters[1];
- Parameters[1] = Parameters[0];
- Parameters[0] = (ULONG_PTR)L"unknown software exception";
- }
- }
- }
-
- /* Calculate length of text buffer */
- TextStringU->MaximumLength = FormatU.Length + SizeOfStrings + 42 * sizeof(WCHAR);
-
- /* Allocate a buffer for the text */
- TextStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- TextStringU->MaximumLength);
-
- /* Wrap in SEH to protect from invalid string parameters */
- _SEH2_TRY
- {
- /* Print the string into the buffer */
- StringCbPrintfW(TextStringU->Buffer,
- TextStringU->MaximumLength,
- FormatString,
- Parameters[0],
- Parameters[1],
- Parameters[2],
- Parameters[3]);
- Status = STATUS_SUCCESS;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Set error and free buffers */
- Status = _SEH2_GetExceptionCode();
- RtlFreeHeap(RtlGetProcessHeap(), 0, TextStringU->Buffer);
- RtlFreeHeap(RtlGetProcessHeap(), 0, CaptionStringU->Buffer);
- }
- _SEH2_END
-
- if (NT_SUCCESS(Status))
- {
- TextStringU->Length = wcslen(TextStringU->Buffer) * sizeof(WCHAR);
- }
-
- if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);
-
- return Status;
-}
-
-static
-ULONG
-CsrpMessageBox(
- PWSTR Text,
- PWSTR Caption,
- ULONG ValidResponseOptions,
- ULONG Severity)
-{
- ULONG Type, MessageBoxResponse;
-
- /* Set the message box type */
- switch (ValidResponseOptions)
- {
- case OptionAbortRetryIgnore:
- Type = MB_ABORTRETRYIGNORE;
- break;
- case OptionOk:
- Type = MB_OK;
- break;
- case OptionOkCancel:
- Type = MB_OKCANCEL;
- break;
- case OptionRetryCancel:
- Type = MB_RETRYCANCEL;
- break;
- case OptionYesNo:
- Type = MB_YESNO;
- break;
- case OptionYesNoCancel:
- Type = MB_YESNOCANCEL;
- break;
- case OptionShutdownSystem:
- Type = MB_RETRYCANCEL; // FIXME???
- break;
- /* Anything else is invalid */
- default:
- return ResponseNotHandled;
- }
-
- /* Set severity */
- if (Severity == STATUS_SEVERITY_INFORMATIONAL) Type |= MB_ICONINFORMATION;
- else if (Severity == STATUS_SEVERITY_WARNING) Type |= MB_ICONWARNING;
- else if (Severity == STATUS_SEVERITY_ERROR) Type |= MB_ICONERROR;
-
- Type |= MB_SYSTEMMODAL | MB_SETFOREGROUND;
-
- DPRINT("Text = '%S', Caption = '%S', Severity = %d, Type = 0x%lx\n",
- Text, Caption, Severity, Type);
-
- /* Display a message box */
- MessageBoxResponse = MessageBoxW(0, Text, Caption, Type);
-
- /* Return response value */
- switch (MessageBoxResponse)
- {
- case IDOK: return ResponseOk;
- case IDCANCEL: return ResponseCancel;
- case IDYES: return ResponseYes;
- case IDNO: return ResponseNo;
- case IDABORT: return ResponseAbort;
- case IDIGNORE: return ResponseIgnore;
- case IDRETRY: return ResponseRetry;
- case IDTRYAGAIN: return ResponseTryAgain;
- case IDCONTINUE: return ResponseContinue;
- }
-
- return ResponseNotHandled;
-}
-
-VOID
-WINAPI
-Win32CsrHardError(
- IN PCSR_THREAD ThreadData,
- IN PHARDERROR_MSG Message)
-{
-#if DBG
- PCSR_PROCESS ProcessData = ThreadData->Process;
-#endif
- ULONG_PTR Parameters[MAXIMUM_HARDERROR_PARAMETERS];
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING TextU, CaptionU;
- NTSTATUS Status;
- HANDLE hProcess;
- ULONG Size;
-
- /* Default to not handled */
- ASSERT(ProcessData != NULL);
- Message->Response = ResponseNotHandled;
-
- /* Make sure we don't have too many parameters */
- if (Message->NumberOfParameters > MAXIMUM_HARDERROR_PARAMETERS)
- Message->NumberOfParameters = MAXIMUM_HARDERROR_PARAMETERS;
-
- /* Initialize object attributes */
- InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
-
- /* Open client process */
- Status = NtOpenProcess(&hProcess,
- PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
- &ObjectAttributes,
- &Message->h.ClientId);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtOpenProcess failed with code: %lx\n", Status);
- return;
- }
-
- /* Capture all string parameters from the process memory */
- Status = CsrpCaptureStringParameters(Parameters, &Size, Message, hProcess);
- if (!NT_SUCCESS(Status))
- {
- NtClose(hProcess);
- return;
- }
-
- /* Format the caption and message box text */
- Status = CsrpFormatMessages(&TextU,
- &CaptionU,
- Parameters,
- Size,
- Message,
- hProcess);
-
- /* Cleanup */
- CsrpFreeStringParameters(Parameters, Message);
- NtClose(hProcess);
-
- if (!NT_SUCCESS(Status))
- {
- return;
- }
-
- /* Display the message box */
- Message->Response = CsrpMessageBox(TextU.Buffer,
- CaptionU.Buffer,
- Message->ValidResponseOptions,
- (ULONG)Message->Status >> 30);
-
- RtlFreeUnicodeString(&TextU);
- RtlFreeUnicodeString(&CaptionU);
-
- return;
-}
-
+++ /dev/null
-/*
- * PROJECT: ReactOS CSRSS subsystem
- * FILE: subsystems/win32/csrss/win32csr/lang/bg-BG.rc
- * PURPOSE: Bulgarian resource file
- */
-
-LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Ïðåêðàòÿâàíå íà ïðèëîæåíèå - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Ïðåêðàòÿâàíå íà ïðèëîæåíèåòî... Ïî÷àêàéòå",IDC_STATIC,7,7,186,11
- CONTROL "Õîä",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Àêî ðåøèòå äà çàòâîðèòå ïðèëîæåíèåòî âåäíàãà, ùå èçãóáèòå âñè÷êè íåçàïèñàíè äàííè. Çà äà ïðåêðàòèòå ïðèëîæåíèåòî âåäíàãà, íàòèñíåòå \84Ïðåêðàòÿâàíå âåäíàãà\84.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Ïðåêðàòÿâàíå âåäíàãà",IDC_END_NOW,150,71,60,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Ïðåêðàòÿâàíå íà ïðèëîæåíèå - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Îòêàç",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Ïðåêðàòÿâàíå âåäíàãà",IDC_END_NOW,150,71,60,17
- LTEXT "Ïðèëîæåíèåòî íå îòãîâàðÿ",IDC_STATIC,7,7,178,8
- LTEXT "Çà äà ñå âúðíåòå â ÐåàêòÎÑ è äà ïðîâåðèòå ñúñòîÿíèåòî íà ïðèëîæåíèåòî, íàòèñíåòå \84Îòêàç\93.",
- IDC_STATIC,7,26,178,16
- LTEXT "Àêî ðåøèòå äà çàòâîðèòå ïðèëîæåíèåòî âåäíàãà, ùå èçãóáèòå âñè÷êè íåçàïèñàíè äàííè. Çà äà ïðåêðàòèòå ïðèëîæåíèåòî âåäíàãà, íàòèñíåòå \84Ïðåêðàòÿâàíå âåäíàãà\93.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Îáðàáîòêà"
- IDS_MARK "Îòáåëÿçâàíå"
- IDS_COPY "Çàïîìíÿíå\tEnter"
- IDS_PASTE "Ïîñòàâÿíå"
- IDS_SELECTALL "Èçáîð íà âñè÷êî"
- IDS_SCROLL "Ïðåëèñòâàíå"
- IDS_FIND "Òúðñåíå..."
- IDS_DEFAULTS "Ïîäðàçáèðàíè"
- IDS_PROPERTIES "Ñâîéñòâà"
- IDS_SCROLLHERE "Ïðåëèñòâàíå òóê"
- IDS_SCROLLTOP "Ïðåëèñòâàíå äî ãîðå"
- IDS_SCROLLBOTTOM "Ïðåëèñòâàíå äî äîëó"
- IDS_SCROLLPAGE_UP "Ãîðíà ñòðàíèöà"
- IDS_SCROLLPAGE_DOWN "Äîëíà ñòðàíèöà"
- IDS_SCROLLUP "Ïðåëèñòâàíå íàãîðå"
- IDS_SCROLLDOWN "Ïðåëèñòâàíå íàäîëó"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-/* FILE: subsystems/win32/csrss/win32csr/lang/cs-CZ.rc
- * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com)
- * UPDATED: 2011-04-09
- */
-
-LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Ukonèit program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Probíhá ukonèení programu... Èekejte, prosím",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "IPokud zvolíte okam\9eité ukonèení programu, v\9aechna neulo\9eená data budou ztracena. Kliknutím na Ukonèit okam\9eitì ukonèíte program.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Ukonèit okam\9eitì",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Ukonèit program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Storno",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Ukonèit okam\9eitì",IDC_END_NOW,78,98,43,17
- LTEXT "Tento program neodpovídá",IDC_STATIC,7,7,178,8
- LTEXT "Kliknutím na Storno se lze vrátit do systému ReactOS a ovìøit stav programu",
- IDC_STATIC,7,26,178,16
- LTEXT "Pokud zvolíte okam\9eité ukonèení programu, v\9aechna neulo\9eená data budou ztracena. Kliknutím na Ukonèit okam\9eitì ukonèíte program.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Upravit"
- IDS_MARK "Oznaèit"
- IDS_COPY "Kopírovat\tEnter"
- IDS_PASTE "Vlo\9eit"
- IDS_SELECTALL "Oznaèit v\9ae"
- IDS_SCROLL "Posunout"
- IDS_FIND "Najít..."
- IDS_DEFAULTS "Výchozí"
- IDS_PROPERTIES "Vlastnosti"
- IDS_SCROLLHERE "Posunout sem"
- IDS_SCROLLTOP "Posunout na zaèátek"
- IDS_SCROLLBOTTOM "Posunout na konec"
- IDS_SCROLLPAGE_UP "O stránku vý\9ae"
- IDS_SCROLLPAGE_DOWN "O stránku ní\9ee"
- IDS_SCROLLUP "Posunout nahoru"
- IDS_SCROLLDOWN "Posunout dolù"
-
- IDS_COMMAND_PROMPT "Pøíkazový øádek"
-END
+++ /dev/null
-LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Programm beenden - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Programm wird beendet...",IDC_STATIC,7,7,186,11
- CONTROL "Fortschritt",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Wenn Sie das Programm sofort beenden, werden Sie eventuell ungespeicherte Daten verlieren. Um das Programm zu beenden, wählen Sie Jetzt beenden.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "J&etzt beenden",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Programm beenden - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Abbechen",IDCANCEL,142,98,43,17
- PUSHBUTTON "J&etzt beenden",IDC_END_NOW,78,98,43,17
- LTEXT "Das Programm reagiert nicht",IDC_STATIC,7,7,178,8
- LTEXT "Um zu ReactOS zurückzukehren und den Status der Anwendung zu überprüfen, wählen Sie Abbrechen.",
- IDC_STATIC,7,26,178,16
- LTEXT "Wenn Sie das Programm sofort beenden, werden Sie eventuell ungespeicherte Daten verlieren. Um das Programm zu beenden, wählen Sie Jetzt beenden.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Bearbeiten"
- IDS_MARK "Markieren"
- IDS_COPY "Kopieren\tEnter"
- IDS_PASTE "Einfügen"
- IDS_SELECTALL "Alles auswählen"
- IDS_SCROLL "Scrollen"
- IDS_FIND "Suchen..."
- IDS_DEFAULTS "Standardwerte"
- IDS_PROPERTIES "Eigenschaften"
- IDS_SCROLLHERE "Hier scrollen"
- IDS_SCROLLTOP "Ganz nach oben scrollen"
- IDS_SCROLLBOTTOM "Ganz nach unten scrollen"
- IDS_SCROLLPAGE_UP "Seite nach oben"
- IDS_SCROLLPAGE_DOWN "Seite nach unten"
- IDS_SCROLLUP "Nach oben scrollen"
- IDS_SCROLLDOWN "Nach unten scrollen"
-
- IDS_COMMAND_PROMPT "Eingabeaufforderung"
-END
+++ /dev/null
-LANGUAGE LANG_GREEK, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Êëåßóéìï ðñïãñÜììáôïò - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Êëåßóéìï ðñïãñÜììáôïò... Ðáñáêáëþ ðåñéìÝíåôå",IDC_STATIC,7,7,186,11
- CONTROL "Ðñüïäïò",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Áí êëåßóåôå ôçí åöáñìïãÞ ôþñá , èá ÷Üóåôå üëá ôá ìç áðïèçêåõìÝíá äåäïìÝíá. Ãéá íá êëåßóåôå ôï ðñüãñáììá ôþñá, ðáôÞóôå 'Êëåßóéìï Ôþñá'.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Êëåßóéìï Ôþñá",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Êëåßóçìï ðñïãñÜììáôïò - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "¢êõñï",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Êëåßóéìï Ôþñá",IDC_END_NOW,78,98,43,17
- LTEXT "Ôï ðñüãñáììá äåí áðïêñßíåôáé",IDC_STATIC,7,7,178,8
- LTEXT "Ãéá íá åðéóôñÝøåôå óôï ReactOS êáé íá åëÝãîåôå ôçí êáôÜóôáóç ôïõ ðñïãñÜììáôïò, ðáôÞóôå '¢êõñï'",
- IDC_STATIC,7,26,178,16
- LTEXT "Áí êëåßóåôå ôçí åöáñìïãÞ ôþñá , èá ÷Üóåôå üëá ôá ìç áðïèçêåõìÝíá äåäïìÝíá. Ãéá íá êëåßóåôå ôï ðñüãñáììá ôþñá, ðáôÞóôå 'Êëåßóéìï Ôþñá'.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Åðåîåñãáóßá"
- IDS_MARK "ÌáñêÜñéóìá"
- IDS_COPY "ÁíôéãñáöÞ\tEnter"
- IDS_PASTE "Åðéêüëëçóç"
- IDS_SELECTALL "ÅðéëïãÞ üëùí"
- IDS_SCROLL "Êýëéóç"
- IDS_FIND "Åýñåóç..."
- IDS_DEFAULTS "ÐñïåðéëïãÞ"
- IDS_PROPERTIES "Éäéüôçôåò"
- IDS_SCROLLHERE "Êýëéóç åäþ"
- IDS_SCROLLTOP "Áñ÷Þ"
- IDS_SCROLLBOTTOM "ÔÝëïò"
- IDS_SCROLLPAGE_UP "Ðñïçãïýìåíç óåëßäá"
- IDS_SCROLLPAGE_DOWN "Åðüìåíç óåëßäá"
- IDS_SCROLLUP "Êýëéóç ðÜíù"
- IDS_SCROLLDOWN "Êýëéóç êÜôù"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "End Program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Ending Program... Please wait",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "If you choose to end the program immediately, you will lose any unsaved data. To end the program now, click End Now.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&End Now",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "End Program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Cancel",IDCANCEL,142,98,43,17
- PUSHBUTTON "&End Now",IDC_END_NOW,78,98,43,17
- LTEXT "This program is not responding",IDC_STATIC,7,7,178,8
- LTEXT "To return to ReactOS and check the status of the program, click Cancel",
- IDC_STATIC,7,26,178,16
- LTEXT "If you choose to end the program immediately, you will lose any unsaved data. To end the program now, click End Now",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Edit"
- IDS_MARK "Mark"
- IDS_COPY "Copy\tEnter"
- IDS_PASTE "Paste"
- IDS_SELECTALL "Select All"
- IDS_SCROLL "Scroll"
- IDS_FIND "Find..."
- IDS_DEFAULTS "Defaults"
- IDS_PROPERTIES "Properties"
- IDS_SCROLLHERE "Scroll here"
- IDS_SCROLLTOP "Scroll top"
- IDS_SCROLLBOTTOM "Scroll bottom"
- IDS_SCROLLPAGE_UP "Page up"
- IDS_SCROLLPAGE_DOWN "Page down"
- IDS_SCROLLUP "Scroll up"
- IDS_SCROLLDOWN "Scroll down"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-/*
- *Spanish Language resource file
- * Traducido por: Javier Remacha 2008-26-01
- */
-
-LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Finalizar programa - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Finalizando programa... Por favor, espere",IDC_STATIC,7,7,186,11
- CONTROL "Progreso",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Si elige finalizar el programa ahora, perderá todos los datos no guardados. Para finalizar el programa ahora, haga clic en Finalizar ahora.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Finalizar ahora",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Finalizar programa - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Cancelar",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Finalizar ahora",IDC_END_NOW,78,98,43,17
- LTEXT "Este programa no responde",IDC_STATIC,7,7,178,8
- LTEXT "Para volver a ReactOS y ver el estado del programa, haga clic en Cancelar",
- IDC_STATIC,7,26,178,16
- LTEXT "Si elige finalizar el programa ahora, perderá todos los datos no guardados. Para finalizar el programa ahora, haga clic en Finalizar ahora.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Editar"
- IDS_MARK "Marcar"
- IDS_COPY "Copiar\tIntroducir"
- IDS_PASTE "Pegar"
- IDS_SELECTALL "Seleccionar Todo"
- IDS_SCROLL "Desplazar"
- IDS_FIND "Buscar..."
- IDS_DEFAULTS "Por defecto"
- IDS_PROPERTIES "Propiedades"
- IDS_SCROLLHERE "Desplazar aquí"
- IDS_SCROLLTOP "Desplazar hasta arriba"
- IDS_SCROLLBOTTOM "Desplazar hasta abajo"
- IDS_SCROLLPAGE_UP "Subir página"
- IDS_SCROLLPAGE_DOWN "Bajar página"
- IDS_SCROLLUP "Desplazar arriba"
- IDS_SCROLLDOWN "Desplazar abajo"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Fin du programme - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Termine le programme... Veuillez patienter",IDC_STATIC,7,7,186,11
- CONTROL "Avancement",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Si vous choisissez de terminer le programme immédiatement, vous perdrez toutes les données non sauvegardées. Pour terminer le programme maintenant, cliquez sur Terminer maintenant.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "T&erminer maintenant",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Fin du programme - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Annuler",IDCANCEL,142,98,43,17
- PUSHBUTTON "T&erminer maintenant",IDC_END_NOW,78,98,43,17
- LTEXT "Ce programme ne répond pas",IDC_STATIC,7,7,178,8
- LTEXT "Pour retourner à ReactOS et vérifier l'état du programme, cliquez sur Annuler",
- IDC_STATIC,7,26,178,16
- LTEXT "Si vous choisissez de terminer le programme immédiatement, vous perdrez toutes les données non sauvegardées. Pour terminer le programme maintenant, cliquez sur Terminer maintenant",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-/* Fixme : Translation could be really improved, with context
- La traduction pourrait réellement être améliorée grâce au contexte */
-STRINGTABLE
-BEGIN
- IDS_EDIT "Éditer"
- IDS_MARK "Marquer"
- IDS_COPY "Copier\tEntrée"
- IDS_PASTE "Coller"
- IDS_SELECTALL "Tout sélectionner"
- IDS_SCROLL "Défiler"
- IDS_FIND "Trouver..."
- IDS_DEFAULTS "Défauts"
- IDS_PROPERTIES "Propriétés"
- IDS_SCROLLHERE "Défiler ici"
- IDS_SCROLLTOP "Défiler tout en haut"
- IDS_SCROLLBOTTOM "Défiler tout en bas"
- IDS_SCROLLPAGE_UP "Page précédente"
- IDS_SCROLLPAGE_DOWN "Page suivante"
- IDS_SCROLLUP "Défiler en haut"
- IDS_SCROLLDOWN "Défiler en bas"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "סיום תכנית - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "מסיים תכנית... נא להמתין",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "If you choose to end the program immediately, you will lose any unsaved data. To end the program now, click End Now.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "סיים כעת",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "סיום תכנית - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "ביטול",IDCANCEL,142,98,43,17
- PUSHBUTTON "סיים כעת",IDC_END_NOW,78,98,43,17
- LTEXT "התכנית אינה מגיבה",IDC_STATIC,7,7,178,8
- LTEXT "To return to ReactOS and check the status of the program, click Cancel",
- IDC_STATIC,7,26,178,16
- LTEXT "If you choose to end the program immediately, you will lose any unsaved data. To end the program now, click End Now",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "ערוך"
- IDS_MARK "סמן"
- IDS_COPY "העתק\tEnter"
- IDS_PASTE "הדבק"
- IDS_SELECTALL "בחר הכל"
- IDS_SCROLL "גלול"
- IDS_FIND "מצא..."
- IDS_DEFAULTS "ברירת מחדל"
- IDS_PROPERTIES "מאפיינים"
- IDS_SCROLLHERE "גלול לכאן"
- IDS_SCROLLTOP "גלול למעלה"
- IDS_SCROLLBOTTOM "גלול למטה"
- IDS_SCROLLPAGE_UP "עמוד מעלה"
- IDS_SCROLLPAGE_DOWN "עמוד מטה"
- IDS_SCROLLUP "גלול מעלה"
- IDS_SCROLLDOWN "גלול מטה"
-
- IDS_COMMAND_PROMPT "שורת הפקודה"
-END
+++ /dev/null
-LANGUAGE LANG_INDONESIAN, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Akhir Program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Mengakhiri Program... Harap menunggu",IDC_STATIC,7,7,186,11
- CONTROL "Progres",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Jika anda memilih untuk segera mengakhiri program, anda akan kehilangan data yang belum disimpan. Untuk mengakhiri program sekarang, klik Akhiri Sekarang.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Akhiri Sekarang",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Mengakhiri Program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Batal",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Akhiri Sekarang",IDC_END_NOW,78,98,43,17
- LTEXT "Program ini tidak merespon",IDC_STATIC,7,7,178,8
- LTEXT "Untuk kembali ke ReactOS dan memeriksa status program, klik Batal",
- IDC_STATIC,7,26,178,16
- LTEXT "Jika anda memilih untuk segera mengakhiri program, anda akan kehilangan data yang belum disimpan. Untuk mengakhiri program sekarang, klik Akhiri Sekarang.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Edit"
- IDS_MARK "Tandai"
- IDS_COPY "Copy\tEnter"
- IDS_PASTE "Paste"
- IDS_SELECTALL "Pilih Semua"
- IDS_SCROLL "Gulung"
- IDS_FIND "Cari..."
- IDS_DEFAULTS "Standar"
- IDS_PROPERTIES "Properti"
- IDS_SCROLLHERE "Gulung ke Sini"
- IDS_SCROLLTOP "Gulung ke Atas"
- IDS_SCROLLBOTTOM "Gulung ke Bawah"
- IDS_SCROLLPAGE_UP "Halaman Naik"
- IDS_SCROLLPAGE_DOWN "Halaman Turun"
- IDS_SCROLLUP "Gulung Naik"
- IDS_SCROLLDOWN "Gulung Turun"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-/*
-* PROJECT: ReactOS Client/Server Runtime subsystem
-* LICENSE: GPL - See COPYING in the top level directory
-* FILE: subsystems/win32/csrss/win32csr/lang/it-IT.rc
-* PURPOSE: Italian Translation of subsystems/win32/csrss/win32csr/lang/en-US.rc
-* PROGRAMMERS:
-* Copyright (C) 2007 Daniele Forsi (dforsi at gmail.com) Italian Translation
-*/
-
-LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Arresto del programma - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Arresto del programma... Attendere",IDC_STATIC,7,7,186,11
- CONTROL "Progresso",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Se si sceglie di terminare il programma immediatamente, si perderanno tutti i dati non salvati. Per terminare il programma ora, selezionare Termina ora.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "T&ermina ora",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Arresto del programma - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Annulla",IDCANCEL,142,98,43,17
- PUSHBUTTON "T&ermina ora",IDC_END_NOW,78,98,43,17
- LTEXT "Il programma non risponde",IDC_STATIC,7,7,178,8
- LTEXT "Per tornare a ReactOS e controllare lo stato del programma, selezionare Annulla",
- IDC_STATIC,7,26,178,16
- LTEXT "Se si sceglie di terminare il programma immediatamente, si perderanno tutti i dati non salvati. Per terminare il programma ora, selezionare Termina ora.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Modifica"
- IDS_MARK "Seleziona"
- IDS_COPY "Copia\tInvio"
- IDS_PASTE "Incolla"
- IDS_SELECTALL "Seleziona tutto"
- IDS_SCROLL "Scorri"
- IDS_FIND "Trova..."
- IDS_DEFAULTS "Impostazioni predefinite"
- IDS_PROPERTIES "Proprietà"
- IDS_SCROLLHERE "Scorri qui"
- IDS_SCROLLTOP "Scorri in cima"
- IDS_SCROLLBOTTOM "Scorri in fondo"
- IDS_SCROLLPAGE_UP "Pagina sù"
- IDS_SCROLLPAGE_DOWN "Pagina giù"
- IDS_SCROLLUP "Scorri sù"
- IDS_SCROLLDOWN "Scorri giù"
-
- IDS_COMMAND_PROMPT "Prompt dei commandi"
-END
+++ /dev/null
-LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\83v\83\8d\83O\83\89\83\80\82Ì\8fI\97¹ - "
-FONT 9, "MS UI Gothic"
-BEGIN
- LTEXT "\83v\83\8d\83O\83\89\83\80\82ð\8fI\97¹\82µ\82Ä\82¢\82Ü\82·... \82µ\82Î\82ç\82\82¨\91Ò\82¿\82\82¾\82³\82¢",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "\83v\83\8d\83O\83\89\83\80\82ð\82·\82®\82É\8fI\97¹\82³\82¹\82é\82æ\82¤\91I\91ð\82µ\82½\8fê\8d\87\81A\95Û\91¶\82³\82ê\82Ä\82¢\82È\82¢\83f\81[\83^\82Í\82·\82×\82Ä\8e¸\82í\82ê\82Ü\82·\81B\83v\83\8d\83O\83\89\83\80\82ð\8fI\97¹\82·\82é\82É\82Í[\82·\82®\82É\8fI\97¹]\82ð\83N\83\8a\83b\83N\82µ\82Ä\82\82¾\82³\82¢\81B",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "\82·\82®\82É\8fI\97¹(&E)",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\83v\83\8d\83O\83\89\83\80\82Ì\8fI\97¹ - "
-FONT 9, "MS UI Gothic"
-BEGIN
- DEFPUSHBUTTON "\83L\83\83\83\93\83Z\83\8b",IDCANCEL,142,98,43,17
- PUSHBUTTON "\82·\82®\82É\8fI\97¹(&E)",IDC_END_NOW,78,98,43,17
- LTEXT "\82±\82Ì\83v\83\8d\83O\83\89\83\80\82Í\89\9e\93\9a\82µ\82Ä\82¢\82Ü\82¹\82ñ",IDC_STATIC,7,7,178,8
- LTEXT "ReactOS \82É\96ß\82Á\82Ä\83v\83\8d\83O\83\89\83\80\82Ì\8fó\91Ô\82ð\8am\94F\82·\82é\82É\82Í[\83L\83\83\83\93\83Z\83\8b]\82ð\83N\83\8a\83b\83N\82µ\82Ä\82\82¾\82³\82¢",
- IDC_STATIC,7,26,178,16
- LTEXT "\83v\83\8d\83O\83\89\83\80\82ð\82·\82®\82É\8fI\97¹\82³\82¹\82é\82æ\82¤\91I\91ð\82µ\82½\8fê\8d\87\81A\95Û\91¶\82³\82ê\82Ä\82¢\82È\82¢\83f\81[\83^\82Í\82·\82×\82Ä\8e¸\82í\82ê\82Ü\82·\81B\83v\83\8d\83O\83\89\83\80\82ð\92¼\82¿\82É\8fI\97¹\82·\82é\82É\82Í[\82·\82®\82É\8fI\97¹]\82ð\83N\83\8a\83b\83N\82µ\82Ä\82\82¾\82³\82¢",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 9, "MS UI Gothic", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "\95Ò\8fW"
- IDS_MARK "\94Í\88Í\8ew\92è"
- IDS_COPY "\83R\83s\81[\tEnter"
- IDS_PASTE "\93\\\82è\95t\82¯"
- IDS_SELECTALL "\82·\82×\82Ä\91I\91ð"
- IDS_SCROLL "\83X\83N\83\8d\81[\83\8b"
- IDS_FIND "\8c\9f\8dõ..."
- IDS_DEFAULTS "\8bK\92è\92l"
- IDS_PROPERTIES "\83v\83\8d\83p\83e\83B"
- IDS_SCROLLHERE "\82±\82±\82É\83X\83N\83\8d\81[\83\8b"
- IDS_SCROLLTOP "\88ê\94Ô\8fã\82É\83X\83N\83\8d\81[\83\8b"
- IDS_SCROLLBOTTOM "\88ê\94Ô\89º\82É\83X\83N\83\8d\81[\83\8b"
- IDS_SCROLLPAGE_UP "Page up"
- IDS_SCROLLPAGE_DOWN "Page down"
- IDS_SCROLLUP "\8fã\82É\83X\83N\83\8d\81[\83\8b"
- IDS_SCROLLDOWN "\89º\82É\83X\83N\83\8d\81[\83\8b"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Avslutt program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Avslutt Program... Vennligst vent",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Hvis du velger å avslutte programmet øyeblikkelig, vil du miste alt data som ikke er lagret. For å avslutte programmet nå, Trykk på Avslutt nå.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Avslutt nå",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Avslutt program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Avbryt",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Avslutt nå",IDC_END_NOW,78,98,43,17
- LTEXT "Programmet svarer ikke",IDC_STATIC,7,7,178,8
- LTEXT "For å returnere til ReactOS for å sjekke statusen på programmet, trykk på avbryt",
- IDC_STATIC,7,26,178,16
- LTEXT "Hvis du velger å avslutte programmet øyeblikkelig, vil du miste alt data som ikke er lagret. For å avslutte programmet nå, Trykk på Avslutt nå",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Rediger"
- IDS_MARK "Merk"
- IDS_COPY "Kopier\tEnter"
- IDS_PASTE "Lim inn"
- IDS_SELECTALL "Velg alt"
- IDS_SCROLL "Rull"
- IDS_FIND "Finn..."
- IDS_DEFAULTS "Standard"
- IDS_PROPERTIES "Egenskaper"
- IDS_SCROLLHERE "Rull her"
- IDS_SCROLLTOP "Rull til toppen"
- IDS_SCROLLBOTTOM "Rull knapp"
- IDS_SCROLLPAGE_UP "Side opp"
- IDS_SCROLLPAGE_DOWN "Side ned"
- IDS_SCROLLUP "Rull opp"
- IDS_SCROLLDOWN "Rull ned"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-/*
- * translated by xrogers
- * xxrogers@users.sourceforge.net
- * https://sourceforge.net/projects/reactospl
- * translation update by Olaf Siejka (Caemyr), Apr 2011
- * UTF-8 conversion by Caemyr (May, 2011)
- */
-
-LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Zakończ program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Trwa zamykanie programu... Proszę czekać",IDC_STATIC,7,7,186,11
- CONTROL "Postęp",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Jeśli zdecydujesz się zamknąć program natychmiastowo, utracisz wszelkie niezapisane dane. Aby zakończyć program, wciśnij Zakończ teraz.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Zakończ teraz",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Zakończ program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Anuluj",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Zakończ teraz",IDC_END_NOW,78,98,43,17
- LTEXT "Wybrany program nie odpowiada",IDC_STATIC,7,7,178,8
- LTEXT "Aby powrócić do ReactOS i sprawdzić status programu, kliknij Anuluj",
- IDC_STATIC,7,26,178,16
- LTEXT "Jeśli zdecydujesz się zamknąć program natychmiastowo, utracisz wszelkie niezapisane dane. Aby zakończyć program, wciśnij Zakończ teraz.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Edytuj"
- IDS_MARK "Zaznacz"
- IDS_COPY "Kopiuj\tWejdź"
- IDS_PASTE "Wklej"
- IDS_SELECTALL "Zaznacz wszystko"
- IDS_SCROLL "Przewiń"
- IDS_FIND "Znajdź..."
- IDS_DEFAULTS "Ustawienia domyślne"
- IDS_PROPERTIES "Właściwości"
- IDS_SCROLLHERE "Przewiń tutaj"
- IDS_SCROLLTOP "Przewiń na początek"
- IDS_SCROLLBOTTOM "Przewiń na koniec"
- IDS_SCROLLPAGE_UP "Poprzednia strona"
- IDS_SCROLLPAGE_DOWN "Następna strona"
- IDS_SCROLLUP "Przewiń do góry"
- IDS_SCROLLDOWN "Przewiń na dół"
-
- IDS_COMMAND_PROMPT "Wiersz polecenia"
-END
+++ /dev/null
-/* Translation and UTF-8 Conversion by mkbu95 <mkbu95@gmail.com> (May, 2012) */
-
-LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Finalizar Programa - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Finalizando Programa... Por favor aguarde",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Se você finalizar o programa imediatamente, você irá perder qualquer alteração não salva. Para finalizar o programa agora, pressione Finalizar Agora.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Finalizar Agora",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Finalizar Programa - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Cancelar",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Finalizar Agora",IDC_END_NOW,78,98,43,17
- LTEXT "O programa não está respondendo",IDC_STATIC,7,7,178,8
- LTEXT "Parar retornar ao ReactOS e verificar o estado do programa, pressione Cancelar",
- IDC_STATIC,7,26,178,16
- LTEXT "Se você finalizar o programa imediatamente, você irá perder qualquer alteração não salva. Para finalizar o programa agora, pressione Finalizar Agora",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Editar"
- IDS_MARK "Marcar"
- IDS_COPY "Copiar\tEnter"
- IDS_PASTE "Colar"
- IDS_SELECTALL "Selecionar Tudo"
- IDS_SCROLL "Rolar"
- IDS_FIND "Procurar..."
- IDS_DEFAULTS "Padrões"
- IDS_PROPERTIES "Propriedades"
- IDS_SCROLLHERE "Rolar aqui"
- IDS_SCROLLTOP "Rolar até o topo"
- IDS_SCROLLBOTTOM "Rolar até o fim"
- IDS_SCROLLPAGE_UP "Page up"
- IDS_SCROLLPAGE_DOWN "Page down"
- IDS_SCROLLUP "Scroll up"
- IDS_SCROLLDOWN "Scroll down"
-
- IDS_COMMAND_PROMPT "Prompt de Comando"
-END
+++ /dev/null
-/*
- * FILE: subsystems/win32/csrss/win32csr/lang/ro-RO.rc
- * ReactOS Project (http://www.reactos.org)
- * TRANSLATOR: Fulea Ștefan (PM on ReactOS Forum at fulea.stefan)
- * CHANGE LOG: 2011-10-16 initial translation
- */
-
-LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Terminare execuție - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Terminare execuție… așteptați",IDC_STATIC,7,7,186,11
- CONTROL "Progress", IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Dacă alegeți închiderea forțată, riscați pierderi de date. Pentru a forța închiderea, apăsați „Termină forțat”.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "Termină &forțat",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Terminare execuție - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "A&nulează", IDCANCEL,142,98,43,17
- PUSHBUTTON "Termină &forțat",IDC_END_NOW,78,98,43,17
- LTEXT "Acest program nu răspunde",IDC_STATIC,7,7,178,8
- LTEXT "Pentru a vă întoarce în ReactOS și a verifica starea programului, apăsați „Anulează”",
- IDC_STATIC,7,26,178,16
- LTEXT "Dacă alegeți închiderea imediată a programului, riscați pierderi de date. Pentru a forța închiderea, apăsați „Termină forțat”.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Editare"
- IDS_MARK "Marchează"
- IDS_COPY "Copiază\tEnter"
- IDS_PASTE "Lipește"
- IDS_SELECTALL "Selectează tot"
- IDS_SCROLL "Derulează"
- IDS_FIND "Găsire…"
- IDS_DEFAULTS "Implicite"
- IDS_PROPERTIES "Proprietăți"
- IDS_SCROLLHERE "Derulează aici"
- IDS_SCROLLTOP "Derulează la început"
- IDS_SCROLLBOTTOM "Derulează la sfârșit"
- IDS_SCROLLPAGE_UP "Pagina anterioară"
- IDS_SCROLLPAGE_DOWN "Pagina următoare"
- IDS_SCROLLUP "Derulează în sus"
- IDS_SCROLLDOWN "Derulează în jos"
-
- IDS_COMMAND_PROMPT "Linie de comandă"
-END
+++ /dev/null
-LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Завершение программы - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Завершение программы... Пажалуйста подождите",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Если вы завершите программу сейчас, то вы можете потерять несохраненные данные. Чтобы завешить программу сейчас нажмите ""Завершить""",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Завешить",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Завершение программы - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Отмена",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Завершить",IDC_END_NOW,78,98,43,17
- LTEXT "Эта программа не отвечает",IDC_STATIC,7,7,178,8
- LTEXT "Для возврата в ReactOS и сохранения данных нажмите ""Отмена""",
- IDC_STATIC,7,26,178,16
- LTEXT "Если вы завершите программу сейчас, то вы можете потерять несохраненные данные. Чтобы завешить программу сейчас нажмите ""Завершить""",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Изменить"
- IDS_MARK "Пометить"
- IDS_COPY "Копировать\tEnter"
- IDS_PASTE "Вставить"
- IDS_SELECTALL "Выделить все"
- IDS_SCROLL "Прокрутить"
- IDS_FIND "Искать..."
- IDS_DEFAULTS "Умолчания"
- IDS_PROPERTIES "Свойства"
- IDS_SCROLLHERE "Scroll Here"
- IDS_SCROLLTOP "Scroll Top"
- IDS_SCROLLBOTTOM "Прокрутить вниз"
- IDS_SCROLLPAGE_UP "Вверх страницы"
- IDS_SCROLLPAGE_DOWN "Вниз страницы"
- IDS_SCROLLUP "Прокрутить вверх"
- IDS_SCROLLDOWN "Scroll Down"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-/* TRANSLATOR: Mário Kaèmár /Mario Kacmar/ aka Kario (kario@szm.sk)
- * DATE OF TR: 29-05-2008
- * LastChange: 12-04-2011
- */
-
-LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Ukonèenie programu - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Ukonèujem program... Poèkajte, prosím.",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Ak zvolíte okam\9eité ukonèenie programu, stratíte v\9aetky neulo\9eené údaje. Ak chcete program ukonèi\9d okam\9eite, kliknite na tlaèidlo Ukonèi\9d ihneï.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Ukonèi\9d ihneï",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Ukonèenie programu - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Zru\9ai\9d",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Ukonèi\9d ihneï",IDC_END_NOW,78,98,43,17
- LTEXT "Tento program neodpovedá.",IDC_STATIC,7,7,178,8
- LTEXT "Pre návrat do systému ReactOS a overenie stavu programu kliknite na tlaèidlo Zru\9ai\9d.",
- IDC_STATIC,7,26,178,16
- LTEXT "Ak zvolíte okam\9eité ukonèenie programu, stratíte v\9aetky neulo\9eené údaje. Ak chcete program ukonèi\9d okam\9eite, kliknite na tlaèidlo Ukonèi\9d ihneï.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Upravi\9d"
- IDS_MARK "Oznaèi\9d"
- IDS_COPY "Kopírova\9d\tEnter"
- IDS_PASTE "Vlo\9ei\9d"
- IDS_SELECTALL "Vybra\9d v\9aetko"
- IDS_SCROLL "Rolova\9d"
- IDS_FIND "Nájs\9d..." //Find
- IDS_DEFAULTS "Predvolené" //Defaults
- IDS_PROPERTIES "Vlastnosti"
- IDS_SCROLLHERE "Rolova\9d sem"
- IDS_SCROLLTOP "K hornému okraju"
- IDS_SCROLLBOTTOM "K dolnému okraju"
- IDS_SCROLLPAGE_UP "O stránku vy\9a\9aie"
- IDS_SCROLLPAGE_DOWN "O stránku ni\9e\9aie"
- IDS_SCROLLUP "Rolova\9d nahor"
- IDS_SCROLLDOWN "Rolova\9d nadol"
-
- IDS_COMMAND_PROMPT "Príkazový riadok"
-END
+++ /dev/null
-/*
- * PROJECT: ReactOS CSRSS subsystem
- * FILE: subsystems/win32/csrss/win32csr/lang/sv-SE.rc
- * PURPOSE: Swedish resource file
- * Translation: Jaix Bly
- */
-
-LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "End Program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Avsluta Program... Var vänlig vänta",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Om du väljer att avsluta programmet omedelbart kommer du att förlora all osparad data. För att avsluta programmet, klicka Avsluta nu.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Avsluta Nu",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Avsluta Program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Avbryt",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Avsluta Nu",IDC_END_NOW,78,98,43,17
- LTEXT "Detta programmet svarar inte",IDC_STATIC,7,7,178,8
- LTEXT "För att återgå till ReactOS och undersöka programmets status klicka Avbryt",
- IDC_STATIC,7,26,178,16
- LTEXT "m du väljer att avsluta programmet omedelbart kommer du att förlora all osparad data. För att avsluta programmet, klicka Avsluta nu.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Redigera"
- IDS_MARK "Markera"
- IDS_COPY "Kopiera\tEnter"
- IDS_PASTE "Klistra in"
- IDS_SELECTALL "Markera Allt"
- IDS_SCROLL "Skrolla"
- IDS_FIND "Sök..."
- IDS_DEFAULTS "Ursprunglig"
- IDS_PROPERTIES "Egenskaper"
- IDS_SCROLLHERE "Skrolla hit"
- IDS_SCROLLTOP "Skrolla till topp"
- IDS_SCROLLBOTTOM "Skrolla till botten"
- IDS_SCROLLPAGE_UP "Sida upp"
- IDS_SCROLLPAGE_DOWN "Sida ner"
- IDS_SCROLLUP "Skrolla upp"
- IDS_SCROLLDOWN "Skrolla ner"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-/*
- * Turkish resources
- *
- * Copyright 2012 Arda Tanrikulu <ardatanrikulu@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Programı Sonlandır - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Program Sonlandırılıyor... Lütfen bekleyin",IDC_STATIC,7,7,186,11
- CONTROL "İşlem",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Programı hemen kapatmayı seçerseniz, kaydedilmemiş veriyi kaybedersiniz. Programdan şimdi çıkmak için Şimdi Sonlandır'ı tıklatın.",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Şimdi Sonlandır",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "End Program - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "İptal",IDCANCEL,142,98,43,17
- PUSHBUTTON "Şimdi Sonlandır",IDC_END_NOW,78,98,43,17
- LTEXT "Bu program yanıt vermiyor.",IDC_STATIC,7,7,178,8
- LTEXT "ReactOS'a dönmek ve programın durumunu denetlemek için İptal'i tıklatın.",
- IDC_STATIC,7,26,178,16
- LTEXT "Programı hemen kapatmayı seçerseniz, kaydedilmemiş veriyi kaybedersiniz. Programdan şimdi çıkmak için Şimdi Sonlandır'ı tıklatın.",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Düzenle"
- IDS_MARK "İşaretle"
- IDS_COPY "Kopyala\tEnter"
- IDS_PASTE "Yapıştır"
- IDS_SELECTALL "Tümünü Seç"
- IDS_SCROLL "Yuvarla"
- IDS_FIND "Bul..."
- IDS_DEFAULTS "Varsayılanlar"
- IDS_PROPERTIES "Özellikler"
- IDS_SCROLLHERE "Buraya yuvarla"
- IDS_SCROLLTOP "Üste yuvarla"
- IDS_SCROLLBOTTOM "Alta yuvarla"
- IDS_SCROLLPAGE_UP "Sayfa yukarı"
- IDS_SCROLLPAGE_DOWN "Sayfa aşağı"
- IDS_SCROLLUP "Yukarı yuvarla"
- IDS_SCROLLDOWN "Aşağı yuvarla"
-
- IDS_COMMAND_PROMPT "Komut İstemi"
-END
+++ /dev/null
-/*
- * PROJECT: ReactOS CSRSS subsystem
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/win32/csrss/win32csr/lang/uk-UA.rc
- * PURPOSE: Ukraianian resource file
- * TRANSLATOR: Artem Reznikov
- */
-
-LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Завершення програми - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Завершення програми... Зачекайте",IDC_STATIC,7,7,186,11
- CONTROL "Прогрес",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Якщо завершити програму негайно, то можна втратити всі незбережені дані. Щоб завершити програму зараз, натисніть 'Завершити зараз'",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "&Завершити зараз",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Завершення програми - "
-FONT 8, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "Скасувати",IDCANCEL,142,98,43,17
- PUSHBUTTON "&Завершити зараз",IDC_END_NOW,78,98,43,17
- LTEXT "Ця програма не відповідає",IDC_STATIC,7,7,178,8
- LTEXT "Щоб повернутися у ReactOS і перевірити стан програми, натисніть 'Скасувати'",
- IDC_STATIC,7,26,178,16
- LTEXT "Якщо завершити програму негайно, то можна втратити всі незбережені дані. Щоб завершити програму зараз, натисніть 'Завершити зараз'",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "Редагувати"
- IDS_MARK "Виділити"
- IDS_COPY "Копіювати\tEnter"
- IDS_PASTE "Вставити"
- IDS_SELECTALL "Виділити все"
- IDS_SCROLL "Прокрутити"
- IDS_FIND "Знайти..."
- IDS_DEFAULTS "Замовчування"
- IDS_PROPERTIES "Властивості"
- IDS_SCROLLHERE "Прокрутити сюди"
- IDS_SCROLLTOP "Прокрутити на початок"
- IDS_SCROLLBOTTOM "Прокрутити на кінець"
- IDS_SCROLLPAGE_UP "Попередня сотрінка"
- IDS_SCROLLPAGE_DOWN "Наступна сторінка"
- IDS_SCROLLUP "Прокрутити догори"
- IDS_SCROLLDOWN "Прокрутити донизу"
-
- IDS_COMMAND_PROMPT "Командний рядок"
-END
+++ /dev/null
-LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "ÖÕÖ¹³ÌÐò - "
-FONT 9, "MS Shell Dlg"
-BEGIN
- LTEXT "ÕýÔÚÖÕÖ¹³ÌÐò... ÇëµÈ´ý",IDC_STATIC,7,7,186,11
- CONTROL "½ø³Ì",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "Èç¹ûÄúÑ¡ÔñÁ¢¼´ÖÕÖ¹³ÌÐò£¬Äú½«Ê§È¥ËùÓÐδ±£´æµÄÊý¾Ý¡£ÈôÒªÁ¢¼´½áÊø³ÌÐò£¬µ¥»÷¡°Á¢¼´ÖÕÖ¹¡±¡£",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "Á¢¼´ÖÕÖ¹(&E)",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "ÖÕÖ¹³ÌÐò - "
-FONT 9, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "È¡Ïû",IDCANCEL,142,98,43,17
- PUSHBUTTON "Á¢¼´ÖÕÖ¹(&E)",IDC_END_NOW,78,98,43,17
- LTEXT "´Ë³ÌÐò²¢Î´ÏìÓ¦",IDC_STATIC,7,7,178,8
- LTEXT "ÈôÒª·µ»ØÖÁ ReactOS ²¢¼ì²é¸Ã³ÌÐòµÄ״̬£¬Çëµã»÷¡°È¡Ïû¡±¡£",
- IDC_STATIC,7,26,178,16
- LTEXT "Èç¹ûÄúÑ¡ÔñÁ¢¼´ÖÕÖ¹³ÌÐò£¬Äú½«Ê§È¥ËùÓÐδ±£´æµÄÊý¾Ý¡£ÈôÒªÁ¢¼´½áÊø³ÌÐò£¬µ¥»÷¡°Á¢¼´ÖÕÖ¹¡±¡£",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 9, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "±à¼"
- IDS_MARK "񈬀"
- IDS_COPY "¸´ÖÆ\tEnter"
- IDS_PASTE "ð¤Ìù"
- IDS_SELECTALL "È«²¿Ñ¡Ôñ"
- IDS_SCROLL "¹ö¶¯"
- IDS_FIND "²éÕÒ..."
- IDS_DEFAULTS "ĬÈÏ"
- IDS_PROPERTIES "ÊôÐÔ"
- IDS_SCROLLHERE "¹ö¶¯µ½´Ë"
- IDS_SCROLLTOP "¹ö¶¯ÖÁ¶¥¶Ë"
- IDS_SCROLLBOTTOM "¹ö¶¯ÖÁÄ©¶Ë"
- IDS_SCROLLPAGE_UP "ÉÏÒ»Ò³"
- IDS_SCROLLPAGE_DOWN "ÏÂÒ»Ò³"
- IDS_SCROLLUP "ÏòÉϹö¶¯"
- IDS_SCROLLDOWN "ÏòϹö¶¯"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
-
-IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "µ²§ôµ{¦¡"
-FONT 9, "MS Shell Dlg"
-BEGIN
- LTEXT "¥¿¦bµ²§ôµ{¦¡... ½Ðµyµ¥",IDC_STATIC,7,7,186,11
- CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
- 7,20,186,13
- LTEXT "¦pªG±z¿ï¾Ü¥ß§Yµ²§ôµ{¦¡¡A±z±N¥¢¥h©Ò¦³¥¼Àx¦sªº¸ê®Æ¡CYn¥ß§Yµ²§ôµ{¦¡¡A½Ð«ö¤U¡§¥ß§Yµ²§ô¡¨¡C",
- IDC_STATIC,7,40,186,26
- DEFPUSHBUTTON "¥ß§Yµ²§ô(&E)",IDC_END_NOW,150,71,43,17
-END
-
-IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
-STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "µ²§ôµ{¦¡ - "
-FONT 9, "MS Shell Dlg"
-BEGIN
- DEFPUSHBUTTON "¨ú®ø",IDCANCEL,142,98,43,17
- PUSHBUTTON "¥ß§Yµ²§ô(&E) ",IDC_END_NOW,78,98,43,17
- LTEXT "¦¹µ{¦¡¨Ã¥¼ÅTÀ³",IDC_STATIC,7,7,178,8
- LTEXT "Ynªð¦^¦Ü ReactOS ¨ÃÀ˵øµ{¦¡ªºª¬ºA¡A½Ð«ö¤U¡§¨ú®ø¡¨",
- IDC_STATIC,7,26,178,16
- LTEXT "¦pªG±z¿ï¾Ü¥ß§Yµ²§ôµ{¦¡¡A±z±N¥¢¥h©Ò¦³¥¼Àx¦sªº¸ê®Æ¡CYn¥ß§Yµ²§ôµ{¦¡¡A½Ð«ö¤U¡§¥ß§Yµ²§ô¡¨¡C",
- IDC_STATIC,7,53,178,26
-END
-
-IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
-STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-FONT 9, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
-END
-
-STRINGTABLE
-BEGIN
- IDS_EDIT "½s¿è"
- IDS_MARK "¼Ð°O"
- IDS_COPY "½Æ»s\tEnter"
- IDS_PASTE "ÂH¶K"
- IDS_SELECTALL "¥þ³¡¿ï¾Ü"
- IDS_SCROLL "ºu°Ê"
- IDS_FIND "´M§ä..."
- IDS_DEFAULTS "¹w³]"
- IDS_PROPERTIES "ÄÝ©Ê"
- IDS_SCROLLHERE "ºu°Ê¨ì¦¹ "
- IDS_SCROLLTOP "ºu°Ê¨ì³»¸m"
- IDS_SCROLLBOTTOM "ºu°Ê¨ì¥½ºÝ"
- IDS_SCROLLPAGE_UP "¤W¤@¶"
- IDS_SCROLLPAGE_DOWN "¤U¤@¶"
- IDS_SCROLLUP "¦V¤Wºu°Ê"
- IDS_SCROLLDOWN "¦V¤Uºu°Ê"
-
- IDS_COMMAND_PROMPT "Command Prompt"
-END
+++ /dev/null
-/*
- * PROJECT: ReactOS CSRSS
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/win32/csrss/win32csr/lineinput.c
- * PURPOSE: Console line input functions
- * PROGRAMMERS: Jeffrey Morlan
- */
-
-/* INCLUDES ******************************************************************/
-
-#define NDEBUG
-#include "w32csr.h"
-#include <debug.h>
-
-typedef struct tagHISTORY_BUFFER
-{
- LIST_ENTRY ListEntry;
- WORD Position;
- WORD MaxEntries;
- WORD NumEntries;
- PUNICODE_STRING Entries;
- UNICODE_STRING ExeName;
-} HISTORY_BUFFER, *PHISTORY_BUFFER;
-
-/* FUNCTIONS *****************************************************************/
-
-static PHISTORY_BUFFER
-HistoryCurrentBuffer(PCSRSS_CONSOLE Console)
-{
- /* TODO: use actual EXE name sent from process that called ReadConsole */
- UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" };
- PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
- PHISTORY_BUFFER Hist;
-
- for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
- {
- Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
- if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE))
- return Hist;
- }
-
- /* Couldn't find the buffer, create a new one */
- Hist = HeapAlloc(Win32CsrApiHeap, 0, sizeof(HISTORY_BUFFER) + ExeName.Length);
- if (!Hist)
- return NULL;
- Hist->MaxEntries = Console->HistoryBufferSize;
- Hist->NumEntries = 0;
- Hist->Entries = HeapAlloc(Win32CsrApiHeap, 0, Hist->MaxEntries * sizeof(UNICODE_STRING));
- if (!Hist->Entries)
- {
- HeapFree(Win32CsrApiHeap, 0, Hist);
- return NULL;
- }
- Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length;
- Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
- memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length);
- InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
- return Hist;
-}
-
-static VOID
-HistoryAddEntry(PCSRSS_CONSOLE Console)
-{
- UNICODE_STRING NewEntry;
- PHISTORY_BUFFER Hist;
- INT i;
-
- NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR);
- NewEntry.Buffer = Console->LineBuffer;
-
- if (!(Hist = HistoryCurrentBuffer(Console)))
- return;
-
- /* Don't add blank or duplicate entries */
- if (NewEntry.Length == 0 || Hist->MaxEntries == 0 ||
- (Hist->NumEntries > 0 &&
- RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], &NewEntry, FALSE)))
- {
- return;
- }
-
- if (Console->HistoryNoDup)
- {
- /* Check if this line has been entered before */
- for (i = Hist->NumEntries - 1; i >= 0; i--)
- {
- if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE))
- {
- /* Just rotate the list to bring this entry to the end */
- NewEntry = Hist->Entries[i];
- memmove(&Hist->Entries[i], &Hist->Entries[i + 1],
- (Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING));
- Hist->Entries[Hist->NumEntries - 1] = NewEntry;
- Hist->Position = Hist->NumEntries - 1;
- return;
- }
- }
- }
-
- if (Hist->NumEntries == Hist->MaxEntries)
- {
- /* List is full, remove oldest entry */
- RtlFreeUnicodeString(&Hist->Entries[0]);
- memmove(&Hist->Entries[0], &Hist->Entries[1],
- --Hist->NumEntries * sizeof(UNICODE_STRING));
- }
-
- if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry, &Hist->Entries[Hist->NumEntries])))
- Hist->NumEntries++;
- Hist->Position = Hist->NumEntries - 1;
-}
-
-static VOID
-HistoryGetCurrentEntry(PCSRSS_CONSOLE Console, PUNICODE_STRING Entry)
-{
- PHISTORY_BUFFER Hist;
- if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0)
- Entry->Length = 0;
- else
- *Entry = Hist->Entries[Hist->Position];
-}
-
-static PHISTORY_BUFFER
-HistoryFindBuffer(PCSRSS_CONSOLE Console, PUNICODE_STRING ExeName)
-{
- PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
- while (Entry != &Console->HistoryBuffers)
- {
- /* For the history APIs, the caller is allowed to give only part of the name */
- PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
- if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE))
- return Hist;
- Entry = Entry->Flink;
- }
- return NULL;
-}
-
-VOID FASTCALL
-HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
-{
- if (!Hist)
- return;
- while (Hist->NumEntries != 0)
- RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]);
- HeapFree(Win32CsrApiHeap, 0, Hist->Entries);
- RemoveEntryList(&Hist->ListEntry);
- HeapFree(Win32CsrApiHeap, 0, Hist);
-}
-
-CSR_API(CsrGetCommandHistoryLength)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
- PHISTORY_BUFFER Hist;
- ULONG Length = 0;
- INT i;
-
- if (!Win32CsrValidateBuffer(ProcessData,
- Request->Data.GetCommandHistoryLength.ExeName.Buffer,
- Request->Data.GetCommandHistoryLength.ExeName.Length, 1))
- {
- return STATUS_ACCESS_VIOLATION;
- }
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (NT_SUCCESS(Status))
- {
- Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName);
- if (Hist)
- {
- for (i = 0; i < Hist->NumEntries; i++)
- Length += Hist->Entries[i].Length + sizeof(WCHAR);
- }
- Request->Data.GetCommandHistoryLength.Length = Length;
- ConioUnlockConsole(Console);
- }
- return Status;
-}
-
-CSR_API(CsrGetCommandHistory)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
- PHISTORY_BUFFER Hist;
- PBYTE Buffer = (PBYTE)Request->Data.GetCommandHistory.History;
- ULONG BufferSize = Request->Data.GetCommandHistory.Length;
- INT i;
-
- if (!Win32CsrValidateBuffer(ProcessData, Buffer, BufferSize, 1) ||
- !Win32CsrValidateBuffer(ProcessData,
- Request->Data.GetCommandHistory.ExeName.Buffer,
- Request->Data.GetCommandHistory.ExeName.Length, 1))
- {
- return STATUS_ACCESS_VIOLATION;
- }
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (NT_SUCCESS(Status))
- {
- Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName);
- if (Hist)
- {
- for (i = 0; i < Hist->NumEntries; i++)
- {
- if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR)))
- {
- Status = STATUS_BUFFER_OVERFLOW;
- break;
- }
- memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length);
- Buffer += Hist->Entries[i].Length;
- *(PWCHAR)Buffer = L'\0';
- Buffer += sizeof(WCHAR);
- }
- }
- Request->Data.GetCommandHistory.Length = Buffer - (PBYTE)Request->Data.GetCommandHistory.History;
- ConioUnlockConsole(Console);
- }
- return Status;
-}
-
-CSR_API(CsrExpungeCommandHistory)
-{
- PCSRSS_CONSOLE Console;
- PHISTORY_BUFFER Hist;
- NTSTATUS Status;
-
- if (!Win32CsrValidateBuffer(ProcessData,
- Request->Data.ExpungeCommandHistory.ExeName.Buffer,
- Request->Data.ExpungeCommandHistory.ExeName.Length, 1))
- {
- return STATUS_ACCESS_VIOLATION;
- }
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (NT_SUCCESS(Status))
- {
- Hist = HistoryFindBuffer(Console, &Request->Data.ExpungeCommandHistory.ExeName);
- HistoryDeleteBuffer(Hist);
- ConioUnlockConsole(Console);
- }
- return Status;
-}
-
-CSR_API(CsrSetHistoryNumberCommands)
-{
- PCSRSS_CONSOLE Console;
- PHISTORY_BUFFER Hist;
- NTSTATUS Status;
- WORD MaxEntries = Request->Data.SetHistoryNumberCommands.NumCommands;
- PUNICODE_STRING OldEntryList, NewEntryList;
-
- if (!Win32CsrValidateBuffer(ProcessData,
- Request->Data.SetHistoryNumberCommands.ExeName.Buffer,
- Request->Data.SetHistoryNumberCommands.ExeName.Length, 1))
- {
- return STATUS_ACCESS_VIOLATION;
- }
-
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (NT_SUCCESS(Status))
- {
- Hist = HistoryFindBuffer(Console, &Request->Data.SetHistoryNumberCommands.ExeName);
- if (Hist)
- {
- OldEntryList = Hist->Entries;
- NewEntryList = HeapAlloc(Win32CsrApiHeap, 0,
- MaxEntries * sizeof(UNICODE_STRING));
- if (!NewEntryList)
- {
- Status = STATUS_NO_MEMORY;
- }
- else
- {
- /* If necessary, shrink by removing oldest entries */
- for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
- {
- RtlFreeUnicodeString(Hist->Entries++);
- Hist->Position += (Hist->Position == 0);
- }
-
- Hist->MaxEntries = MaxEntries;
- Hist->Entries = memcpy(NewEntryList, Hist->Entries,
- Hist->NumEntries * sizeof(UNICODE_STRING));
- HeapFree(Win32CsrApiHeap, 0, OldEntryList);
- }
- }
- ConioUnlockConsole(Console);
- }
- return Status;
-}
-
-CSR_API(CsrGetHistoryInfo)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (NT_SUCCESS(Status))
- {
- Request->Data.SetHistoryInfo.HistoryBufferSize = Console->HistoryBufferSize;
- Request->Data.SetHistoryInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
- Request->Data.SetHistoryInfo.dwFlags = Console->HistoryNoDup;
- ConioUnlockConsole(Console);
- }
- return Status;
-}
-
-CSR_API(CsrSetHistoryInfo)
-{
- PCSRSS_CONSOLE Console;
- NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (NT_SUCCESS(Status))
- {
- Console->HistoryBufferSize = (WORD)Request->Data.SetHistoryInfo.HistoryBufferSize;
- Console->NumberOfHistoryBuffers = (WORD)Request->Data.SetHistoryInfo.NumberOfHistoryBuffers;
- Console->HistoryNoDup = Request->Data.SetHistoryInfo.dwFlags & HISTORY_NO_DUP_FLAG;
- ConioUnlockConsole(Console);
- }
- return Status;
-}
-
-static VOID
-LineInputSetPos(PCSRSS_CONSOLE Console, UINT Pos)
-{
- if (Pos != Console->LinePos && Console->Mode & ENABLE_ECHO_INPUT)
- {
- PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
- UINT OldCursorX = Buffer->CurrentX;
- UINT OldCursorY = Buffer->CurrentY;
- INT XY = OldCursorY * Buffer->MaxX + OldCursorX;
-
- XY += (Pos - Console->LinePos);
- if (XY < 0)
- XY = 0;
- else if (XY >= Buffer->MaxY * Buffer->MaxX)
- XY = Buffer->MaxY * Buffer->MaxX - 1;
-
- Buffer->CurrentX = XY % Buffer->MaxX;
- Buffer->CurrentY = XY / Buffer->MaxX;
- ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY);
- }
-
- Console->LinePos = Pos;
-}
-
-static VOID
-LineInputEdit(PCSRSS_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion)
-{
- UINT Pos = Console->LinePos;
- UINT NewSize = Console->LineSize - NumToDelete + NumToInsert;
- INT i;
-
- /* Make sure there's always enough room for ending \r\n */
- if (NewSize + 2 > Console->LineMaxSize)
- return;
-
- memmove(&Console->LineBuffer[Pos + NumToInsert],
- &Console->LineBuffer[Pos + NumToDelete],
- (Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR));
- memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR));
-
- if (Console->Mode & ENABLE_ECHO_INPUT)
- {
- for (i = Pos; i < NewSize; i++)
- {
- CHAR AsciiChar;
- WideCharToMultiByte(Console->OutputCodePage, 0,
- &Console->LineBuffer[i], 1,
- &AsciiChar, 1, NULL, NULL);
- ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE);
- }
- for (; i < Console->LineSize; i++)
- {
- ConioWriteConsole(Console, Console->ActiveBuffer, " ", 1, TRUE);
- }
- Console->LinePos = i;
- }
-
- Console->LineSize = NewSize;
- LineInputSetPos(Console, Pos + NumToInsert);
-}
-
-static VOID
-LineInputRecallHistory(PCSRSS_CONSOLE Console, INT Offset)
-{
- PHISTORY_BUFFER Hist;
-
- if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0)
- return;
-
- Offset += Hist->Position;
- Offset = max(Offset, 0);
- Offset = min(Offset, Hist->NumEntries - 1);
- Hist->Position = Offset;
-
- LineInputSetPos(Console, 0);
- LineInputEdit(Console, Console->LineSize,
- Hist->Entries[Offset].Length / sizeof(WCHAR),
- Hist->Entries[Offset].Buffer);
-}
-
-VOID FASTCALL
-LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
-{
- UINT Pos = Console->LinePos;
- PHISTORY_BUFFER Hist;
- UNICODE_STRING Entry;
- INT HistPos;
-
- switch (KeyEvent->wVirtualKeyCode)
- {
- case VK_ESCAPE:
- /* Clear entire line */
- LineInputSetPos(Console, 0);
- LineInputEdit(Console, Console->LineSize, 0, NULL);
- return;
- case VK_HOME:
- /* Move to start of line. With ctrl, erase everything left of cursor */
- LineInputSetPos(Console, 0);
- if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- LineInputEdit(Console, Pos, 0, NULL);
- return;
- case VK_END:
- /* Move to end of line. With ctrl, erase everything right of cursor */
- if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
- else
- LineInputSetPos(Console, Console->LineSize);
- return;
- case VK_LEFT:
- /* Move left. With ctrl, move to beginning of previous word */
- if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- {
- while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
- while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
- }
- else
- {
- Pos -= (Pos > 0);
- }
- LineInputSetPos(Console, Pos);
- return;
- case VK_RIGHT:
- case VK_F1:
- /* Move right. With ctrl, move to beginning of next word */
- if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- {
- while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
- while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
- LineInputSetPos(Console, Pos);
- return;
- }
- else
- {
- /* Recall one character (but don't overwrite current line) */
- HistoryGetCurrentEntry(Console, &Entry);
- if (Pos < Console->LineSize)
- LineInputSetPos(Console, Pos + 1);
- else if (Pos * sizeof(WCHAR) < Entry.Length)
- LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
- }
- return;
- case VK_INSERT:
- /* Toggle between insert and overstrike */
- Console->LineInsertToggle = !Console->LineInsertToggle;
- ConioSetCursorInfo(Console, Console->ActiveBuffer);
- return;
- case VK_DELETE:
- /* Remove character to right of cursor */
- if (Pos != Console->LineSize)
- LineInputEdit(Console, 1, 0, NULL);
- return;
- case VK_PRIOR:
- /* Recall first history entry */
- LineInputRecallHistory(Console, -((WORD)-1));
- return;
- case VK_NEXT:
- /* Recall last history entry */
- LineInputRecallHistory(Console, +((WORD)-1));
- return;
- case VK_UP:
- case VK_F5:
- /* Recall previous history entry. On first time, actually recall the
- * current (usually last) entry; on subsequent times go back. */
- LineInputRecallHistory(Console, Console->LineUpPressed ? -1 : 0);
- Console->LineUpPressed = TRUE;
- return;
- case VK_DOWN:
- /* Recall next history entry */
- LineInputRecallHistory(Console, +1);
- return;
- case VK_F3:
- /* Recall remainder of current history entry */
- HistoryGetCurrentEntry(Console, &Entry);
- if (Pos * sizeof(WCHAR) < Entry.Length)
- {
- UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
- UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
- LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
- }
- return;
- case VK_F6:
- /* Insert a ^Z character */
- KeyEvent->uChar.UnicodeChar = 26;
- break;
- case VK_F7:
- if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
- HistoryDeleteBuffer(HistoryCurrentBuffer(Console));
- return;
- case VK_F8:
- /* Search for history entries starting with input. */
- if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0)
- return;
-
- /* Like Up/F5, on first time start from current (usually last) entry,
- * but on subsequent times start at previous entry. */
- if (Console->LineUpPressed)
- Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
- Console->LineUpPressed = TRUE;
-
- Entry.Length = Console->LinePos * sizeof(WCHAR);
- Entry.Buffer = Console->LineBuffer;
-
- /* Keep going backwards, even wrapping around to the end,
- * until we get back to starting point */
- HistPos = Hist->Position;
- do
- {
- if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
- {
- Hist->Position = HistPos;
- LineInputEdit(Console, Console->LineSize - Pos,
- Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
- &Hist->Entries[HistPos].Buffer[Pos]);
- /* Cursor stays where it was */
- LineInputSetPos(Console, Pos);
- return;
- }
- if (--HistPos < 0) HistPos += Hist->NumEntries;
- } while (HistPos != Hist->Position);
- return;
- }
-
- if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT)
- {
- /* backspace handling - if processed input enabled then we handle it here
- * otherwise we treat it like a normal char. */
- if (Pos > 0)
- {
- LineInputSetPos(Console, Pos - 1);
- LineInputEdit(Console, 1, 0, NULL);
- }
- }
- else if (KeyEvent->uChar.UnicodeChar == L'\r')
- {
- HistoryAddEntry(Console);
-
- /* TODO: Expand aliases */
-
- LineInputSetPos(Console, Console->LineSize);
- Console->LineBuffer[Console->LineSize++] = L'\r';
- if (Console->Mode & ENABLE_ECHO_INPUT)
- ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE);
-
- /* Add \n if processed input. There should usually be room for it,
- * but an exception to the rule exists: the buffer could have been
- * pre-filled with LineMaxSize - 1 characters. */
- if (Console->Mode & ENABLE_PROCESSED_INPUT &&
- Console->LineSize < Console->LineMaxSize)
- {
- Console->LineBuffer[Console->LineSize++] = L'\n';
- if (Console->Mode & ENABLE_ECHO_INPUT)
- ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE);
- }
- Console->LineComplete = TRUE;
- Console->LinePos = 0;
- }
- else if (KeyEvent->uChar.UnicodeChar != L'\0')
- {
- if (KeyEvent->uChar.UnicodeChar < 0x20 &&
- Console->LineWakeupMask & (1 << KeyEvent->uChar.UnicodeChar))
- {
- /* Control key client wants to handle itself (e.g. for tab completion) */
- Console->LineBuffer[Console->LineSize++] = L' ';
- Console->LineBuffer[Console->LinePos] = KeyEvent->uChar.UnicodeChar;
- Console->LineComplete = TRUE;
- Console->LinePos = 0;
- }
- else
- {
- /* Normal character */
- BOOL Overstrike = Console->LineInsertToggle && Console->LinePos != Console->LineSize;
- LineInputEdit(Console, Overstrike, 1, &KeyEvent->uChar.UnicodeChar);
- }
- }
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Win32 subsystem
- * FILE: subsys/csrss/win32csr/resource.h
- * PURPOSE: Resource #defines
- */
-
-#pragma once
-
-#define IDD_END_NOW 10
-#define IDD_NOT_RESPONDING 11
-#define IDD_SWITCH_APP 12
-
-#define IDC_STATIC -1
-#define IDC_PROGRESS 101
-#define IDC_END_NOW 102
-#define IDC_STATIC_CUR_APP 103
-
-
-#define ID_SYSTEM_EDIT_MARK 1001
-#define ID_SYSTEM_EDIT_COPY 1002
-#define ID_SYSTEM_EDIT_PASTE 1003
-#define ID_SYSTEM_EDIT_SELECTALL 1004
-#define ID_SYSTEM_EDIT_SCROLL 1005
-#define ID_SYSTEM_EDIT_FIND 1006
-#define ID_SYSTEM_DEFAULTS 1007
-#define ID_SYSTEM_PROPERTIES 1008
-
-#define NCPOPUP_MENU 103
-
-#define IDS_EDIT 204
-#define IDS_MARK 205
-#define IDS_COPY 206
-#define IDS_PASTE 207
-#define IDS_SELECTALL 208
-#define IDS_SCROLL 209
-#define IDS_FIND 210
-#define IDS_DEFAULTS 211
-#define IDS_PROPERTIES 212
-
-//scrollbar resource ids
-#define IDS_SCROLLHERE 304
-#define IDS_SCROLLTOP 305
-#define IDS_SCROLLBOTTOM 306
-#define IDS_SCROLLPAGE_UP 307
-#define IDS_SCROLLPAGE_DOWN 308
-#define IDS_SCROLLUP 309
-#define IDS_SCROLLDOWN 310
-
-#define IDS_COMMAND_PROMPT 500
-
-/* EOF */
+++ /dev/null
-LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
-
-1 ICON DISCARDABLE res/terminal.ico
-
-#ifdef LANGUAGE_BG_BG
- #include "lang/bg-BG.rc"
-#endif
-#ifdef LANGUAGE_CS_CZ
- #include "lang/cs-CZ.rc"
-#endif
-#ifdef LANGUAGE_DE_DE
- #include "lang/de-DE.rc"
-#endif
-#ifdef LANGUAGE_EL_GR
- #include "lang/el-GR.rc"
-#endif
-#ifdef LANGUAGE_EN_US
- #include "lang/en-US.rc"
-#endif
-#ifdef LANGUAGE_ES_ES
- #include "lang/es-ES.rc"
-#endif
-#ifdef LANGUAGE_FR_FR
- #include "lang/fr-FR.rc"
-#endif
-#ifdef LANGUAGE_ID_ID
- #include "lang/id-ID.rc"
-#endif
-#ifdef LANGUAGE_IT_IT
- #include "lang/it-IT.rc"
-#endif
-#ifdef LANGUAGE_JA_JP
- #include "lang/ja-JP.rc"
-#endif
-#ifdef LANGUAGE_NB_NO
- #include "lang/no-NO.rc"
-#endif
-#ifdef LANGUAGE_SK_SK
- #include "lang/sk-SK.rc"
-#endif
-#ifdef LANGUAGE_SV_SE
- #include "lang/sv-SE.rc"
-#endif
-#ifdef LANGUAGE_ZH_CN
- #include "lang/zh-CN.rc"
-#endif
-#ifdef LANGUAGE_ZH_TW
- #include "lang/zh-TW.rc"
-#endif
-
-// UTF-8
-#pragma code_page(65001)
-#ifdef LANGUAGE_HE_IL
- #include "lang/he-IL.rc"
-#endif
-#ifdef LANGUAGE_PL_PL
- #include "lang/pl-PL.rc"
-#endif
-#ifdef LANGUAGE_PT_BR
- #include "lang/pt-BR.rc"
-#endif
-#ifdef LANGUAGE_RO_RO
- #include "lang/ro-RO.rc"
-#endif
-#ifdef LANGUAGE_RU_RU
- #include "lang/ru-RU.rc"
-#endif
-#ifdef LANGUAGE_UK_UA
- #include "lang/uk-UA.rc"
-#endif
-#ifdef LANGUAGE_TR_TR
- #include "lang/tr-TR.rc"
-#endif
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/tuiconsole.c
- * PURPOSE: Implementation of text-mode consoles
- */
-
-#define NDEBUG
-#include "w32csr.h"
-#include <debug.h>
-
-CRITICAL_SECTION ActiveConsoleLock;
-static COORD PhysicalConsoleSize;
-static HANDLE ConsoleDeviceHandle;
-static PCSRSS_CONSOLE ActiveConsole;
-
-static BOOL ConsInitialized = FALSE;
-
-static LRESULT CALLBACK
-TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- if (msg == WM_ACTIVATE)
- {
- if (LOWORD(wParam) != WA_INACTIVE)
- {
- SetFocus(hWnd);
- ConioDrawConsole(ActiveConsole);
- }
- }
- return DefWindowProcW(hWnd, msg, wParam, lParam);
-}
-
-static BOOL FASTCALL
-TuiStartService(LPCWSTR lpServiceName)
-{
- SC_HANDLE hSCManager = NULL;
- SC_HANDLE hService = NULL;
- BOOL ret = FALSE;
-
- hSCManager = OpenSCManagerW(NULL, NULL, 0);
- if (hSCManager == NULL)
- goto cleanup;
-
- hService = OpenServiceW(hSCManager, lpServiceName, SERVICE_START);
- if (hService == NULL)
- goto cleanup;
-
- ret = StartServiceW(hService, 0, NULL);
- if (!ret)
- goto cleanup;
-
- ret = TRUE;
-
-cleanup:
- if (hSCManager != NULL)
- CloseServiceHandle(hSCManager);
- if (hService != NULL)
- CloseServiceHandle(hService);
- return ret;
-}
-
-static BOOL FASTCALL
-TuiInit(DWORD OemCP)
-{
- CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
- DWORD BytesReturned;
- WNDCLASSEXW wc;
- USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
-
- TuiStartService(L"Blue");
-
- ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL,
- OPEN_EXISTING, 0, NULL);
- if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
- {
- DPRINT1("Failed to open BlueScreen.\n");
- return FALSE;
- }
-
- if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
- &OemCP, sizeof(OemCP), NULL, 0,
- &BytesReturned, NULL))
- {
- DPRINT1("Failed to load the font for codepage %d\n", OemCP);
- /* Let's suppose the font is good enough to continue */
- }
-
- if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
- &TextAttribute, sizeof(TextAttribute), NULL, 0,
- &BytesReturned, NULL))
- {
- DPRINT1("Failed to set text attribute\n");
- }
-
- ActiveConsole = NULL;
- InitializeCriticalSection(&ActiveConsoleLock);
- if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
- NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
- {
- DPRINT1("Failed to get console info\n");
- return FALSE;
- }
- PhysicalConsoleSize = ScrInfo.dwSize;
-
- RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
- wc.cbSize = sizeof(WNDCLASSEXW);
- wc.lpszClassName = L"TuiConsoleWindowClass";
- wc.lpfnWndProc = TuiConsoleWndProc;
- wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
- if (RegisterClassExW(&wc) == 0)
- {
- DPRINT1("Failed to register console wndproc\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static VOID WINAPI
-TuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
-{
- Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
-}
-
-static void FASTCALL
-TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *Region)
-{
- UINT SrcDelta, DestDelta;
- LONG i;
- PBYTE Src, SrcEnd;
-
- Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
- SrcDelta = Buff->MaxX * 2;
- SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2;
- DestDelta = ConioRectWidth(Region) * 2;
- for (i = Region->Top; i <= Region->Bottom; i++)
- {
- memcpy(Dest, Src, DestDelta);
- Src += SrcDelta;
- if (SrcEnd <= Src)
- {
- Src -= Buff->MaxY * Buff->MaxX * 2;
- }
- Dest += DestDelta;
- }
-}
-
-static VOID WINAPI
-TuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region)
-{
- DWORD BytesReturned;
- PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
- PCONSOLE_DRAW ConsoleDraw;
- UINT ConsoleDrawSize;
-
- if (ActiveConsole != Console)
- {
- return;
- }
-
- ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
- (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
- ConsoleDraw = HeapAlloc(Win32CsrApiHeap, 0, ConsoleDrawSize);
- if (NULL == ConsoleDraw)
- {
- DPRINT1("HeapAlloc failed\n");
- return;
- }
- ConsoleDraw->X = Region->Left;
- ConsoleDraw->Y = Region->Top;
- ConsoleDraw->SizeX = ConioRectWidth(Region);
- ConsoleDraw->SizeY = ConioRectHeight(Region);
- ConsoleDraw->CursorX = Buff->CurrentX;
- ConsoleDraw->CursorY = Buff->CurrentY;
-
- TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
-
- if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
- NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
- {
- DPRINT1("Failed to draw console\n");
- HeapFree(Win32CsrApiHeap, 0, ConsoleDraw);
- return;
- }
-
- HeapFree(Win32CsrApiHeap, 0, ConsoleDraw);
-}
-
-static VOID WINAPI
-TuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY,
- UINT ScrolledLines, CHAR *Buffer, UINT Length)
-{
- DWORD BytesWritten;
- PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
-
- if (ActiveConsole->ActiveBuffer != Buff)
- {
- return;
- }
-
- if (! WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
- {
- DPRINT1("Error writing to BlueScreen\n");
- }
-}
-
-static BOOL WINAPI
-TuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
-{
- CONSOLE_CURSOR_INFO Info;
- DWORD BytesReturned;
-
- if (ActiveConsole->ActiveBuffer != Buff)
- {
- return TRUE;
- }
-
- Info.dwSize = ConioEffectiveCursorSize(Console, 100);
- Info.bVisible = Buff->CursorInfo.bVisible;
-
- if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
- &Info, sizeof(Info), NULL, 0, &BytesReturned, NULL))
- {
- DPRINT1( "Failed to set cursor info\n" );
- return FALSE;
- }
-
- return TRUE;
-}
-
-static BOOL WINAPI
-TuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
-{
- CONSOLE_SCREEN_BUFFER_INFO Info;
- DWORD BytesReturned;
-
- if (ActiveConsole->ActiveBuffer != Buff)
- {
- return TRUE;
- }
-
- Info.dwCursorPosition.X = Buff->CurrentX;
- Info.dwCursorPosition.Y = Buff->CurrentY;
- Info.wAttributes = Buff->DefaultAttrib;
-
- if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
- &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
- &BytesReturned, NULL))
- {
- DPRINT1( "Failed to set cursor position\n" );
- return FALSE;
- }
-
- return TRUE;
-}
-
-static BOOL WINAPI
-TuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
-{
- return TRUE;
-}
-
-static BOOL WINAPI
-TuiChangeTitle(PCSRSS_CONSOLE Console)
-{
- return TRUE;
-}
-
-static VOID WINAPI
-TuiCleanupConsole(PCSRSS_CONSOLE Console)
-{
- DestroyWindow(Console->hWindow);
-
- EnterCriticalSection(&ActiveConsoleLock);
-
- /* Switch to next console */
- if (ActiveConsole == Console)
- {
- ActiveConsole = Console->Next != Console ? Console->Next : NULL;
- }
-
- if (Console->Next != Console)
- {
- Console->Prev->Next = Console->Next;
- Console->Next->Prev = Console->Prev;
- }
- LeaveCriticalSection(&ActiveConsoleLock);
-
- if (NULL != ActiveConsole)
- {
- ConioDrawConsole(ActiveConsole);
- }
-}
-
-static BOOL WINAPI
-TuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon)
-{
- return TRUE;
-}
-
-static NTSTATUS WINAPI
-TuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-DWORD WINAPI
-TuiConsoleThread (PVOID Data)
-{
- PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Data;
- HWND NewWindow;
- MSG msg;
-
- NewWindow = CreateWindowW(L"TuiConsoleWindowClass",
- Console->Title.Buffer,
- 0,
- -32000, -32000, 0, 0,
- NULL, NULL,
- (HINSTANCE) GetModuleHandleW(NULL),
- (PVOID) Console);
- Console->hWindow = NewWindow;
- if (NULL == NewWindow)
- {
- DPRINT1("CSR: Unable to create console window\n");
- return 1;
- }
-
- SetForegroundWindow(Console->hWindow);
-
- while (TRUE)
- {
- GetMessageW(&msg, 0, 0, 0);
- DispatchMessage(&msg);
- TranslateMessage(&msg);
-
- if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
- msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
- msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)
- {
- ConioProcessKey(&msg, Console, TRUE);
- }
- }
-
- return 0;
-}
-
-static CSRSS_CONSOLE_VTBL TuiVtbl =
-{
- TuiInitScreenBuffer,
- TuiWriteStream,
- TuiDrawRegion,
- TuiSetCursorInfo,
- TuiSetScreenInfo,
- TuiUpdateScreenInfo,
- TuiChangeTitle,
- TuiCleanupConsole,
- TuiChangeIcon,
- TuiResizeBuffer,
-};
-
-NTSTATUS FASTCALL
-TuiInitConsole(PCSRSS_CONSOLE Console)
-{
- HANDLE ThreadHandle;
-
- if (! ConsInitialized)
- {
- ConsInitialized = TRUE;
- if (! TuiInit(Console->CodePage))
- {
- ConsInitialized = FALSE;
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- Console->Vtbl = &TuiVtbl;
- Console->hWindow = NULL;
- Console->Size = PhysicalConsoleSize;
- Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X;
- Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y;
-
- ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TuiConsoleThread,
- Console, 0, NULL);
- if (NULL == ThreadHandle)
- {
- DPRINT1("CSR: Unable to create console thread\n");
- return STATUS_UNSUCCESSFUL;
- }
- CloseHandle(ThreadHandle);
-
- EnterCriticalSection(&ActiveConsoleLock);
- if (NULL != ActiveConsole)
- {
- Console->Prev = ActiveConsole;
- Console->Next = ActiveConsole->Next;
- ActiveConsole->Next->Prev = Console;
- ActiveConsole->Next = Console;
- }
- else
- {
- Console->Prev = Console;
- Console->Next = Console;
- }
- ActiveConsole = Console;
- LeaveCriticalSection(&ActiveConsoleLock);
-
- return STATUS_SUCCESS;
-}
-
-PCSRSS_CONSOLE FASTCALL
-TuiGetFocusConsole(VOID)
-{
- return ActiveConsole;
-}
-
-BOOL FASTCALL
-TuiSwapConsole(int Next)
-{
- static PCSRSS_CONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */
- DWORD BytesReturned;
- ANSI_STRING Title;
- void * Buffer;
- COORD *pos;
-
- if (0 != Next)
- {
- /* alt-tab, swap consoles */
- /* move SwapConsole to next console, and print its title */
- EnterCriticalSection(&ActiveConsoleLock);
- if (! SwapConsole)
- {
- SwapConsole = ActiveConsole;
- }
-
- SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev);
- Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title);
- Title.Length = 0;
- Buffer = HeapAlloc(Win32CsrApiHeap,
- 0,
- sizeof(COORD) + Title.MaximumLength);
- pos = (COORD *)Buffer;
- Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD ));
-
- RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE);
- pos->Y = PhysicalConsoleSize.Y / 2;
- pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
- /* redraw the console to clear off old title */
- ConioDrawConsole(ActiveConsole);
- if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
- NULL, 0, Buffer, sizeof(COORD) + Title.Length,
- &BytesReturned, NULL))
- {
- DPRINT1( "Error writing to console\n" );
- }
- HeapFree(Win32CsrApiHeap, 0, Buffer);
- LeaveCriticalSection(&ActiveConsoleLock);
-
- return TRUE;
- }
- else if (NULL != SwapConsole)
- {
- EnterCriticalSection(&ActiveConsoleLock);
- if (SwapConsole != ActiveConsole)
- {
- /* first remove swapconsole from the list */
- SwapConsole->Prev->Next = SwapConsole->Next;
- SwapConsole->Next->Prev = SwapConsole->Prev;
- /* now insert before activeconsole */
- SwapConsole->Next = ActiveConsole;
- SwapConsole->Prev = ActiveConsole->Prev;
- ActiveConsole->Prev->Next = SwapConsole;
- ActiveConsole->Prev = SwapConsole;
- }
- ActiveConsole = SwapConsole;
- SwapConsole = NULL;
- ConioDrawConsole(ActiveConsole);
- LeaveCriticalSection(&ActiveConsoleLock);
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/tuiconsole.h
- * PURPOSE: Interface to text-mode consoles
- */
-
-#include "api.h"
-
-extern NTSTATUS FASTCALL TuiInitConsole(PCSRSS_CONSOLE Console);
-extern PCSRSS_CONSOLE FASTCALL TuiGetFocusConsole(VOID);
-extern BOOL FASTCALL TuiSwapConsole(int Next);
-
-/* EOF */
+++ /dev/null
-/* PSDK/NDK Headers */
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-#include <stdio.h>
-#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#include <wingdi.h>
-#include <winnls.h>
-#include <winreg.h>
-#include <winsvc.h>
-#include <wincon.h>
-#define NTOS_MODE_USER
-#include <ndk/iofuncs.h>
-#include <ndk/kefuncs.h>
-#include <ndk/mmfuncs.h>
-#include <ndk/obfuncs.h>
-#include <ndk/umfuncs.h>
-#include <psapi.h>
-
-/* External Winlogon Header */
-#include <winlogon.h>
-
-/* Internal CSRSS Headers */
-#include <conio.h>
-#include <csrplugin.h>
-#include <desktopbg.h>
-#include "guiconsole.h"
-#include "tuiconsole.h"
-
-/* Public Win32K Headers */
-#include <ntuser.h>
-
-#include "resource.h"
-
-/* shared header with console.dll */
-#include "console.h"
-
-VOID
-WINAPI
-Win32CsrHardError(
- IN PCSR_THREAD ThreadData,
- IN PHARDERROR_MSG Message);
-
-/* EOF */
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/win32csr.h
- * PURPOSE: Interface to win32csr.dll
- */
-
-#pragma once
-
-#include <objbase.h>
-
-extern HANDLE Win32CsrApiHeap;
-extern HINSTANCE Win32CsrDllHandle;
-
-typedef struct Object_tt
-{
- LONG Type;
- struct tagCSRSS_CONSOLE *Console;
- LONG AccessRead, AccessWrite;
- LONG ExclusiveRead, ExclusiveWrite;
- LONG HandleCount;
-} Object_t;
-
-typedef struct _CSRSS_HANDLE
-{
- Object_t *Object;
- DWORD Access;
- BOOL Inheritable;
- DWORD ShareMode;
-} CSRSS_HANDLE, *PCSRSS_HANDLE;
-
-typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object);
-
-typedef struct tagCSRSS_OBJECT_DEFINITION
-{
- LONG Type;
- CSR_CLEANUP_OBJECT_PROC CsrCleanupObjectProc;
-} CSRSS_OBJECT_DEFINITION, *PCSRSS_OBJECT_DEFINITION;
-
-/* handle.c */
-NTSTATUS FASTCALL Win32CsrInsertObject(PCSR_PROCESS ProcessData,
- PHANDLE Handle,
- Object_t *Object,
- DWORD Access,
- BOOL Inheritable,
- DWORD ShareMode);
-NTSTATUS FASTCALL Win32CsrLockObject(PCSR_PROCESS ProcessData,
- HANDLE Handle,
- Object_t **Object,
- DWORD Access,
- long Type);
-VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
-NTSTATUS FASTCALL Win32CsrReleaseObject(PCSR_PROCESS ProcessData,
- HANDLE Object);
-VOID WINAPI Win32CsrReleaseConsole(PCSR_PROCESS ProcessData);
-NTSTATUS WINAPI Win32CsrDuplicateHandleTable(PCSR_PROCESS SourceProcessData,
- PCSR_PROCESS TargetProcessData);
-CSR_API(CsrGetHandle);
-CSR_API(CsrCloseHandle);
-CSR_API(CsrVerifyHandle);
-CSR_API(CsrDuplicateHandle);
-CSR_API(CsrGetInputWaitHandle);
-
-BOOL FASTCALL Win32CsrValidateBuffer(PCSR_PROCESS ProcessData,
- PVOID Buffer,
- SIZE_T NumElements,
- SIZE_T ElementSize);
-NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc,
- PVOID Context);
-
-/* exitros.c */
-CSR_API(CsrExitReactos);
-CSR_API(CsrSetLogonNotifyWindow);
-CSR_API(CsrRegisterLogonProcess);
-
-CSR_API(CsrSoundSentry);
-
-/* EOF */
+++ /dev/null
-#include <windef.h>
-#include <winuser.h>
-
-#include "resource.h"
-
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION "CSRSS subsystem usermode code\0"
-#define REACTOS_STR_INTERNAL_NAME "win32csr\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "win32csr.dll\0"
-#include <reactos/version.rc>
-
-#include "rsrc.rc"
+++ /dev/null
-@ stdcall Win32CsrInitialization(ptr)