diff --git a/dll/ntdll/csr/connect.c b/dll/ntdll/csr/connect.c index 236ac26a82e..2303aaaf0ef 100644 --- a/dll/ntdll/csr/connect.c +++ b/dll/ntdll/csr/connect.c @@ -433,7 +433,7 @@ CsrClientConnectToServer(PWSTR ObjectDirectory, /* Call CSR */ Status = CsrClientCallServer(&ApiMessage, CaptureBuffer, - CSR_CREATE_API_NUMBER(CSR_SRV_DLL, CsrpClientConnect), + CSR_CREATE_API_NUMBER(CSRSRV_SERVERDLL_INDEX, CsrpClientConnect), sizeof(CSR_CLIENT_CONNECT)); /* Status = CsrClientCallServer(&ApiMessage, diff --git a/dll/ntdll/include/ntdll.h b/dll/ntdll/include/ntdll.h index c2bef832a84..b972e5beb96 100644 --- a/dll/ntdll/include/ntdll.h +++ b/dll/ntdll/include/ntdll.h @@ -42,8 +42,7 @@ #include "ntdllp.h" /* CSRSS Header */ -#include -#include // FIXME: data header. +#include /* PSEH */ #include diff --git a/include/reactos/subsys/csrss/client.h b/include/reactos/subsys/csr/csrcl.h similarity index 88% rename from include/reactos/subsys/csrss/client.h rename to include/reactos/subsys/csr/csrcl.h index 251296ef332..ef6a89d347c 100644 --- a/include/reactos/subsys/csrss/client.h +++ b/include/reactos/subsys/csr/csrcl.h @@ -6,10 +6,10 @@ * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ -#ifndef _CSRCLIENT_H -#define _CSRCLIENT_H +#ifndef _CSRCL_H +#define _CSRCL_H -#include "msg.h" +#include "csrmsg.h" /* BOOLEAN @@ -59,13 +59,6 @@ CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN ULONG StringLength, OUT PVOID* CapturedData); -BOOLEAN -NTAPI -CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, - IN PVOID* Buffer, - IN ULONG ArgumentSize, - IN ULONG ArgumentCount); - VOID NTAPI CsrProbeForRead(IN PVOID Address, diff --git a/include/reactos/subsys/csr/csrmsg.h b/include/reactos/subsys/csr/csrmsg.h new file mode 100644 index 00000000000..8598db3e24d --- /dev/null +++ b/include/reactos/subsys/csr/csrmsg.h @@ -0,0 +1,144 @@ +/* + * PROJECT: ReactOS Native Headers + * FILE: include/subsys/csrss/msg.h + * PURPOSE: Public Definitions for communication + * between CSR Clients and Servers. + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#ifndef _CSRMSG_H +#define _CSRMSG_H + +#pragma once + + +#define CSR_PORT_NAME L"ApiPort" // CSR_API_PORT_NAME + + +#define CSRSRV_SERVERDLL_INDEX 0 +#define CSRSRV_FIRST_API_NUMBER 0 + +typedef enum _CSRSRV_API_NUMBER +{ + CsrpClientConnect = CSRSRV_FIRST_API_NUMBER, + CsrpThreadConnect, + CsrpProfileControl, + CsrpIdentifyAlertable, + CsrpSetPriorityClass, + + CsrpMaxApiNumber +} CSRSRV_API_NUMBER, *PCSRSRV_API_NUMBER; + + +/* +typedef union _CSR_API_NUMBER +{ + WORD Index; + WORD Subsystem; +} CSR_API_NUMBER, *PCSR_API_NUMBER; +*/ +typedef ULONG CSR_API_NUMBER; + +#define CSR_CREATE_API_NUMBER(ServerId, ApiId) \ + (CSR_API_NUMBER)(((ServerId) << 16) | (ApiId)) + +#define CSR_API_NUMBER_TO_SERVER_ID(ApiNumber) \ + (ULONG)((ULONG)(ApiNumber) >> 16) + +#define CSR_API_NUMBER_TO_API_ID(ApiNumber) \ + (ULONG)((ULONG)(ApiNumber) & 0xFFFF) + + +typedef struct _CSR_CONNECTION_INFO +{ + ULONG Version; + ULONG Unknown; + HANDLE ObjectDirectory; + PVOID SharedSectionBase; + PVOID SharedSectionHeap; + PVOID SharedSectionData; + ULONG DebugFlags; + ULONG Unknown2[3]; + HANDLE ProcessId; +} CSR_CONNECTION_INFO, *PCSR_CONNECTION_INFO; + +typedef struct _CSR_IDENTIFY_ALTERTABLE_THREAD +{ + CLIENT_ID Cid; +} CSR_IDENTIFY_ALTERTABLE_THREAD, *PCSR_IDENTIFY_ALTERTABLE_THREAD; + +typedef struct _CSR_SET_PRIORITY_CLASS +{ + HANDLE hProcess; + ULONG PriorityClass; +} CSR_SET_PRIORITY_CLASS, *PCSR_SET_PRIORITY_CLASS; + +typedef struct _CSR_CLIENT_CONNECT +{ + ULONG ServerId; + PVOID ConnectionInfo; + ULONG ConnectionInfoSize; +} CSR_CLIENT_CONNECT, *PCSR_CLIENT_CONNECT; + +typedef struct _CSR_CAPTURE_BUFFER +{ + ULONG Size; + struct _CSR_CAPTURE_BUFFER *PreviousCaptureBuffer; + ULONG PointerCount; + ULONG_PTR BufferEnd; + ULONG_PTR PointerArray[1]; // MessagePointerOffsets // Offsets within CSR_API_MSG of pointers +} CSR_CAPTURE_BUFFER, *PCSR_CAPTURE_BUFFER; + + +#include "csrss.h" // remove it when the data structures are not used anymore. + +/* Keep in sync with definition below. */ +// #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)) + +typedef struct _CSR_API_MESSAGE +{ + PORT_MESSAGE Header; + union + { + CSR_CONNECTION_INFO ConnectionInfo; // Uniquely used in csrss/csrsrv for internal signaling (opening a new connection). + struct + { + PCSR_CAPTURE_BUFFER CsrCaptureData; + CSR_API_NUMBER ApiNumber; + ULONG Status; // ReturnValue; // NTSTATUS Status + ULONG Reserved; + union + { + CSR_CLIENT_CONNECT CsrClientConnect; + + CSR_SET_PRIORITY_CLASS SetPriorityClass; + CSR_IDENTIFY_ALTERTABLE_THREAD IdentifyAlertableThread; + + // ULONG_PTR ApiMessageData[39]; //// what to do ???? + + /*** Temporary ***/ +#if 1 + CSRSS_REGISTER_SERVICES_PROCESS RegisterServicesProcessRequest; + CSRSS_EXIT_REACTOS ExitReactosRequest; + CSRSS_CLOSE_HANDLE CloseHandleRequest; + CSRSS_VERIFY_HANDLE VerifyHandleRequest; + CSRSS_DUPLICATE_HANDLE DuplicateHandleRequest; + + CSRSS_CREATE_DESKTOP CreateDesktopRequest; + CSRSS_SHOW_DESKTOP ShowDesktopRequest; + CSRSS_HIDE_DESKTOP HideDesktopRequest; + CSRSS_SET_LOGON_NOTIFY_WINDOW SetLogonNotifyWindowRequest; + CSRSS_REGISTER_LOGON_PROCESS RegisterLogonProcessRequest; + CSRSS_GET_INPUT_WAIT_HANDLE GetConsoleInputWaitHandle; + CSRSS_GET_PROCESS_LIST GetProcessListRequest; +#endif + /*****************/ + } Data; + }; + }; +} CSR_API_MESSAGE, *PCSR_API_MESSAGE; + +#endif // _CSRMSG_H + +/* EOF */ diff --git a/include/reactos/subsys/csrss/server.h b/include/reactos/subsys/csr/csrsrv.h similarity index 62% rename from include/reactos/subsys/csrss/server.h rename to include/reactos/subsys/csr/csrsrv.h index e5d1280deb8..07080e503ab 100644 --- a/include/reactos/subsys/csrss/server.h +++ b/include/reactos/subsys/csr/csrsrv.h @@ -1,20 +1,24 @@ /* * PROJECT: ReactOS Native Headers - * FILE: include/subsys/csrss/server.h + * FILE: include/subsys/csrss/csrsrv.h * PURPOSE: Public Definitions for CSR Servers * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ -#ifndef _CSRSERVER_H -#define _CSRSERVER_H +#ifndef _CSRSRV_H +#define _CSRSRV_H +// see http://code.google.com/p/ontl/source/browse/branches/x64/ntl/nt/csr.hxx?r=67 + +/* #ifdef _MSC_VER #pragma warning(push) #pragma warning (disable:4201) #endif +*/ -#include "msg.h" +#include "csrmsg.h" /* TYPES **********************************************************************/ @@ -64,7 +68,7 @@ typedef struct _CSR_PROCESS ULONG Reserved; ULONG ShutdownLevel; ULONG ShutdownFlags; -// PVOID ServerData[ANYSIZE_ARRAY]; + PVOID ServerData[ANYSIZE_ARRAY]; // ServerDllPerProcessData // One structure per CSR server. CSRSS_CON_PROCESS_DATA; //// FIXME: Remove it after we activate the previous member. } CSR_PROCESS, *PCSR_PROCESS; @@ -172,9 +176,10 @@ NTSTATUS OUT PULONG Reply ); -#define CSR_API(n) NTSTATUS NTAPI n ( \ +#define CSR_API(n) NTSTATUS NTAPI n( \ IN OUT PCSR_API_MESSAGE ApiMessage, \ OUT PULONG Reply) + // IN OUT PCSR_REPLY_STATUS ReplyStatus) typedef NTSTATUS @@ -218,8 +223,8 @@ typedef struct _CSR_SERVER_DLL HANDLE ServerHandle; ULONG ServerId; ULONG Unknown; - ULONG ApiBase; - ULONG HighestApiSupported; + ULONG ApiBase; // ApiNumberBase + ULONG HighestApiSupported; // MaxApiNumber PCSR_API_ROUTINE *DispatchTable; PBOOLEAN ValidTable; PCHAR *NameTable; @@ -227,7 +232,7 @@ typedef struct _CSR_SERVER_DLL PCSR_CONNECT_CALLBACK ConnectCallback; PCSR_DISCONNECT_CALLBACK DisconnectCallback; PCSR_HARDERROR_CALLBACK HardErrorCallback; - PVOID SharedSection; + PVOID SharedSection; // SharedStaticServerData PCSR_NEWPROCESS_CALLBACK NewProcessCallback; PCSR_SHUTDOWNPROCESS_CALLBACK ShutdownProcessCallback; ULONG Unknown2[3]; @@ -240,51 +245,150 @@ typedef NTSTATUS (NTAPI *PCSR_SERVER_DLL_INIT_CALLBACK)(IN PCSR_SERVER_DLL LoadedServerDll); -/* -NTSTATUS -NTAPI -CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll); -*/ +#define CSR_SERVER_DLL_INIT(n) NTSTATUS NTAPI n(IN PCSR_SERVER_DLL LoadedServerDll) /* PROTOTYPES ****************************************************************/ -NTSTATUS -NTAPI -CsrServerInitialization( - IN ULONG ArgumentCount, - IN PCHAR Arguments[] -); - /////////// BOOLEAN NTAPI -CsrCaptureArguments( - IN PCSR_THREAD CsrThread, - IN PCSR_API_MESSAGE ApiMessage -); +CsrCaptureArguments(IN PCSR_THREAD CsrThread, + IN PCSR_API_MESSAGE ApiMessage); VOID NTAPI CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage); ////////// + + +NTSTATUS +NTAPI +CsrServerInitialization(IN ULONG ArgumentCount, + IN PCHAR Arguments[]); + PCSR_THREAD NTAPI -CsrAddStaticServerThread( - IN HANDLE hThread, - IN PCLIENT_ID ClientId, - IN ULONG ThreadFlags -); +CsrAddStaticServerThread(IN HANDLE hThread, + IN PCLIENT_ID ClientId, + IN ULONG ThreadFlags); + +NTSTATUS +NTAPI +CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, + IN OUT PCSR_API_MESSAGE ReplyMsg); PCSR_THREAD NTAPI CsrConnectToUser(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); + +NTSTATUS +NTAPI +CsrCreateRemoteThread(IN HANDLE hThread, + IN PCLIENT_ID ClientId); + +NTSTATUS +NTAPI +CsrCreateThread(IN PCSR_PROCESS CsrProcess, + IN HANDLE hThread, + IN PCLIENT_ID ClientId); + +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); + +NTSTATUS +NTAPI +CsrDebugProcess(IN PCSR_PROCESS CsrProcess); + +NTSTATUS +NTAPI +CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess); + +VOID +NTAPI +CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess); + +VOID +NTAPI +CsrDereferenceThread(IN PCSR_THREAD CsrThread); + +VOID +NTAPI +CsrDereferenceWait(IN PLIST_ENTRY WaitList); + +NTSTATUS +NTAPI +CsrDestroyProcess(IN PCLIENT_ID Cid, + IN NTSTATUS ExitStatus); + +NTSTATUS +NTAPI +CsrDestroyThread(IN PCLIENT_ID Cid); + +NTSTATUS +NTAPI +CsrExecServerThread(IN PVOID ThreadHandler, + IN ULONG Flags); + +NTSTATUS +NTAPI +CsrGetProcessLuid(IN HANDLE hProcess OPTIONAL, + OUT PLUID Luid); + BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread); +NTSTATUS +NTAPI +CsrLockProcessByClientId(IN HANDLE Pid, + OUT PCSR_PROCESS *CsrProcess OPTIONAL); + +NTSTATUS +NTAPI +CsrLockThreadByClientId(IN HANDLE Tid, + OUT PCSR_THREAD *CsrThread); + +VOID +NTAPI +CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry, + IN PLIST_ENTRY WaitList); + +BOOLEAN +NTAPI +CsrNotifyWait(IN PLIST_ENTRY WaitList, + IN ULONG WaitType, + IN PVOID WaitArgument1, + IN PVOID WaitArgument2); + +VOID +NTAPI +CsrPopulateDosDevices(VOID); + +HANDLE +NTAPI +CsrQueryApiPort(VOID); + +VOID +NTAPI +CsrReferenceThread(IN PCSR_THREAD CsrThread); + BOOLEAN NTAPI CsrRevertToSelf(VOID); @@ -293,17 +397,48 @@ VOID NTAPI CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess); -LONG +VOID NTAPI -CsrUnhandledExceptionFilter( - IN PEXCEPTION_POINTERS ExceptionInfo -); +CsrSetCallingSpooler(ULONG Reserved); +VOID +NTAPI +CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess); +NTSTATUS +NTAPI +CsrShutdownProcesses(IN PLUID CallerLuid, + IN ULONG Flags); +EXCEPTION_DISPOSITION +NTAPI +CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo); + +NTSTATUS +NTAPI +CsrUnlockProcess(IN PCSR_PROCESS CsrProcess); + +NTSTATUS +NTAPI +CsrUnlockThread(IN PCSR_THREAD CsrThread); + +BOOLEAN +NTAPI +CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, + IN PVOID *Buffer, + IN ULONG ArgumentSize, + IN ULONG ArgumentCount); + +BOOLEAN +NTAPI +CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage, + IN LPWSTR *MessageString); + +/* #ifdef _MSC_VER #pragma warning(pop) #endif +*/ #endif // _CSRSERVER_H diff --git a/include/reactos/subsys/csrss/csrss.h b/include/reactos/subsys/csr/csrss.h similarity index 98% rename from include/reactos/subsys/csrss/csrss.h rename to include/reactos/subsys/csr/csrss.h index c3f233d0450..485533b5a62 100644 --- a/include/reactos/subsys/csrss/csrss.h +++ b/include/reactos/subsys/csr/csrss.h @@ -10,7 +10,7 @@ #define CONSOLE_OUTPUT_MODE_VALID (0x03) -#define CSR_CSRSS_SECTION_SIZE (65536) +#define CSR_CSRSS_SECTION_SIZE (65536) typedef VOID (CALLBACK *PCONTROLDISPATCHER)(DWORD); diff --git a/include/reactos/subsys/csrss/msg.h b/include/reactos/subsys/csrss/msg.h deleted file mode 100644 index 1f77ba35afe..00000000000 --- a/include/reactos/subsys/csrss/msg.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * PROJECT: ReactOS Native Headers - * FILE: include/subsys/csrss/msg.h - * PURPOSE: Public Definitions for communication - * between CSR Clients and Servers. - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * Hermes Belusca-Maito (hermes.belusca@sfr.fr) - */ - -#ifndef _CSRMSG_H -#define _CSRMSG_H - -typedef struct _CSR_CONNECTION_INFO -{ - ULONG Version; - ULONG Unknown; - HANDLE ObjectDirectory; - PVOID SharedSectionBase; - PVOID SharedSectionHeap; - PVOID SharedSectionData; - ULONG DebugFlags; - ULONG Unknown2[3]; - HANDLE ProcessId; -} CSR_CONNECTION_INFO, *PCSR_CONNECTION_INFO; - -typedef struct _CSR_IDENTIFY_ALTERTABLE_THREAD -{ - CLIENT_ID Cid; -} CSR_IDENTIFY_ALTERTABLE_THREAD, *PCSR_IDENTIFY_ALTERTABLE_THREAD; - -typedef struct _CSR_SET_PRIORITY_CLASS -{ - HANDLE hProcess; - ULONG PriorityClass; -} CSR_SET_PRIORITY_CLASS, *PCSR_SET_PRIORITY_CLASS; - -typedef struct _CSR_CLIENT_CONNECT -{ - ULONG ServerId; - PVOID ConnectionInfo; - ULONG ConnectionInfoSize; -} CSR_CLIENT_CONNECT, *PCSR_CLIENT_CONNECT; - -typedef struct _CSR_CAPTURE_BUFFER -{ - ULONG Size; - struct _CSR_CAPTURE_BUFFER *PreviousCaptureBuffer; - ULONG PointerCount; - ULONG_PTR BufferEnd; - ULONG_PTR PointerArray[1]; -} CSR_CAPTURE_BUFFER, *PCSR_CAPTURE_BUFFER; - -/* -typedef union _CSR_API_NUMBER -{ - WORD Index; - WORD Subsystem; -} CSR_API_NUMBER, *PCSR_API_NUMBER; -*/ -typedef ULONG CSR_API_NUMBER; - -#include "csrss.h" // remove it when the data structures are not used anymore. - -/* Keep in sync with definition below. */ -// #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)) - -typedef struct _CSR_API_MESSAGE -{ - PORT_MESSAGE Header; - union - { - CSR_CONNECTION_INFO ConnectionInfo; - struct - { - PCSR_CAPTURE_BUFFER CsrCaptureData; - CSR_API_NUMBER ApiNumber; - ULONG Status; - ULONG Reserved; - union - { - CSR_CLIENT_CONNECT CsrClientConnect; - - CSR_SET_PRIORITY_CLASS SetPriorityClass; - CSR_IDENTIFY_ALTERTABLE_THREAD IdentifyAlertableThread; - - /*** Temporary ***/ -#if 1 - CSRSS_CREATE_PROCESS CreateProcessRequest; - CSRSS_CREATE_THREAD CreateThreadRequest; - CSRSS_TERMINATE_PROCESS TerminateProcessRequest; - CSRSS_CONNECT_PROCESS ConnectRequest; - CSRSS_WRITE_CONSOLE WriteConsoleRequest; - CSRSS_READ_CONSOLE ReadConsoleRequest; - CSRSS_ALLOC_CONSOLE AllocConsoleRequest; - CSRSS_SCREEN_BUFFER_INFO ScreenBufferInfoRequest; - CSRSS_SET_CURSOR SetCursorRequest; - CSRSS_FILL_OUTPUT FillOutputRequest; - CSRSS_READ_INPUT ReadInputRequest; - CSRSS_WRITE_CONSOLE_OUTPUT_CHAR WriteConsoleOutputCharRequest; - CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB WriteConsoleOutputAttribRequest; - CSRSS_FILL_OUTPUT_ATTRIB FillOutputAttribRequest; - CSRSS_SET_CURSOR_INFO SetCursorInfoRequest; - CSRSS_GET_CURSOR_INFO GetCursorInfoRequest; - CSRSS_SET_ATTRIB SetAttribRequest; - CSRSS_SET_CONSOLE_MODE SetConsoleModeRequest; - CSRSS_GET_CONSOLE_MODE GetConsoleModeRequest; - CSRSS_CREATE_SCREEN_BUFFER CreateScreenBufferRequest; - CSRSS_SET_SCREEN_BUFFER SetScreenBufferRequest; - CSRSS_SET_TITLE SetTitleRequest; - CSRSS_GET_TITLE GetTitleRequest; - CSRSS_WRITE_CONSOLE_OUTPUT WriteConsoleOutputRequest; - CSRSS_FLUSH_INPUT_BUFFER FlushInputBufferRequest; - CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER ScrollConsoleScreenBufferRequest; - CSRSS_READ_CONSOLE_OUTPUT_CHAR ReadConsoleOutputCharRequest; - CSRSS_READ_CONSOLE_OUTPUT_ATTRIB ReadConsoleOutputAttribRequest; - CSRSS_GET_NUM_INPUT_EVENTS GetNumInputEventsRequest; - CSRSS_REGISTER_SERVICES_PROCESS RegisterServicesProcessRequest; - CSRSS_EXIT_REACTOS ExitReactosRequest; - CSRSS_SET_SHUTDOWN_PARAMETERS SetShutdownParametersRequest; - CSRSS_GET_SHUTDOWN_PARAMETERS GetShutdownParametersRequest; - CSRSS_PEEK_CONSOLE_INPUT PeekConsoleInputRequest; - CSRSS_READ_CONSOLE_OUTPUT ReadConsoleOutputRequest; - CSRSS_WRITE_CONSOLE_INPUT WriteConsoleInputRequest; - CSRSS_GET_INPUT_HANDLE GetInputHandleRequest; - CSRSS_GET_OUTPUT_HANDLE GetOutputHandleRequest; - CSRSS_CLOSE_HANDLE CloseHandleRequest; - CSRSS_VERIFY_HANDLE VerifyHandleRequest; - CSRSS_DUPLICATE_HANDLE DuplicateHandleRequest; - CSRSS_SETGET_CONSOLE_HW_STATE ConsoleHardwareStateRequest; - CSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest; - CSRSS_CREATE_DESKTOP CreateDesktopRequest; - CSRSS_SHOW_DESKTOP ShowDesktopRequest; - CSRSS_HIDE_DESKTOP HideDesktopRequest; - CSRSS_SET_CONSOLE_ICON SetConsoleIconRequest; - CSRSS_SET_LOGON_NOTIFY_WINDOW SetLogonNotifyWindowRequest; - CSRSS_REGISTER_LOGON_PROCESS RegisterLogonProcessRequest; - CSRSS_GET_CONSOLE_CP GetConsoleCodePage; - CSRSS_SET_CONSOLE_CP SetConsoleCodePage; - CSRSS_GET_CONSOLE_OUTPUT_CP GetConsoleOutputCodePage; - CSRSS_SET_CONSOLE_OUTPUT_CP SetConsoleOutputCodePage; - CSRSS_GET_INPUT_WAIT_HANDLE GetConsoleInputWaitHandle; - CSRSS_GET_PROCESS_LIST GetProcessListRequest; - CSRSS_ADD_CONSOLE_ALIAS AddConsoleAlias; - CSRSS_GET_CONSOLE_ALIAS GetConsoleAlias; - CSRSS_GET_ALL_CONSOLE_ALIASES GetAllConsoleAlias; - CSRSS_GET_ALL_CONSOLE_ALIASES_LENGTH GetAllConsoleAliasesLength; - CSRSS_GET_CONSOLE_ALIASES_EXES GetConsoleAliasesExes; - CSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength; - CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent; - CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize; - CSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo; - CSRSS_GET_COMMAND_HISTORY_LENGTH GetCommandHistoryLength; - CSRSS_GET_COMMAND_HISTORY GetCommandHistory; - CSRSS_EXPUNGE_COMMAND_HISTORY ExpungeCommandHistory; - CSRSS_SET_HISTORY_NUMBER_COMMANDS SetHistoryNumberCommands; - CSRSS_GET_HISTORY_INFO GetHistoryInfo; - CSRSS_SET_HISTORY_INFO SetHistoryInfo; - CSRSS_GET_TEMP_FILE GetTempFile; - CSRSS_DEFINE_DOS_DEVICE DefineDosDeviceRequest; - CSRSS_SOUND_SENTRY SoundSentryRequest; - CSRSS_UPDATE_VDM_ENTRY UpdateVdmEntry; - CSRSS_GET_VDM_EXIT_CODE GetVdmExitCode; - CSRSS_CHECK_VDM CheckVdm; -#endif - /*****************/ - } Data; - }; - }; -} CSR_API_MESSAGE, *PCSR_API_MESSAGE; - -/*** old *** -typedef struct _CSR_API_MESSAGE -{ - PORT_MESSAGE Header; - PVOID CsrCaptureData; - ULONG Type; - NTSTATUS Status; - union - { - CSRSS_CREATE_PROCESS CreateProcessRequest; - CSRSS_CREATE_THREAD CreateThreadRequest; - CSRSS_TERMINATE_PROCESS TerminateProcessRequest; - CSRSS_CONNECT_PROCESS ConnectRequest; - - . . . . . . . . . . . . . . . - - CSRSS_GET_VDM_EXIT_CODE GetVdmExitCode; - CSRSS_CHECK_VDM CheckVdm; - } Data; -} CSR_API_MESSAGE, *PCSR_API_MESSAGE; - -***/ - - - - -#define CSR_PORT_NAME L"ApiPort" - -/**** move these defines elsewhere ****/ - -#define CSR_SRV_SERVER 0 -#define CSR_SERVER_DLL_MAX 4 - -/**************************************/ - - - -#define CSR_CREATE_API_NUMBER(ServerId, ApiId) \ - (CSR_API_NUMBER)(((ServerId) << 16) | (ApiId)) - -#define CSR_API_NUMBER_TO_SERVER_ID(ApiNumber) \ - (ULONG)((ULONG)(ApiNumber) >> 16) - -#define CSR_API_NUMBER_TO_API_ID(ApiNumber) \ - (ULONG)((ULONG)(ApiNumber) & 0xFFFF) - -#endif // _CSRMSG_H - -/* EOF */ diff --git a/include/reactos/subsys/win/console.h b/include/reactos/subsys/win/conmsg.h similarity index 74% rename from include/reactos/subsys/win/console.h rename to include/reactos/subsys/win/conmsg.h index 6bb57852a94..c99946f2e33 100644 --- a/include/reactos/subsys/win/console.h +++ b/include/reactos/subsys/win/conmsg.h @@ -2,18 +2,26 @@ * CSRSS Console management structures. */ -#ifndef __CSRCONS_H__ -#define __CSRCONS_H__ +#ifndef __CONMSG_H__ +#define __CONMSG_H__ +#pragma once + +// Remove it. #include +#define CONSRV_SERVERDLL_INDEX 2 +#define CONSRV_FIRST_API_NUMBER 512 +/* w32 console server - move to con.h */ +CSR_SERVER_DLL_INIT(ConServerDllInitialization); + +// Windows NT 4 table, adapted from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_NT +// It is for testing purposes. After that I will update it to 2k3 version and add stubs. +typedef enum _CONSRV_API_NUMBER +{ + BasepCreateProcess = CONSRV_FIRST_API_NUMBER, -#define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)) -#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)) -#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)) -#define CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)) -#define CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)) #define WRITE_CONSOLE (0x2) #define READ_CONSOLE (0x3) @@ -70,9 +78,17 @@ #define SET_HISTORY_INFO (0x47) + BasepMaxApiNumber +} CONSRV_API_NUMBER, *PCONSRV_API_NUMBER; +#define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)) +#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)) +#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)) +#define CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)) +#define CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)) + typedef struct { HANDLE ConsoleHandle; @@ -453,77 +469,72 @@ typedef struct UINT CodePage; } CSRSS_SET_CONSOLE_OUTPUT_CP, *PCSRSS_SET_CONSOLE_OUTPUT_CP; +typedef struct _CONSOLE_API_MESSAGE +{ + PORT_MESSAGE Header; + PCSR_CAPTURE_BUFFER CsrCaptureData; + CSR_API_NUMBER ApiNumber; + ULONG Status; // ReturnValue; // NTSTATUS Status + ULONG Reserved; + union + { + CSRSS_WRITE_CONSOLE WriteConsoleRequest; + CSRSS_READ_CONSOLE ReadConsoleRequest; + CSRSS_ALLOC_CONSOLE AllocConsoleRequest; + CSRSS_FREE_CONSOLE FreeConsoleRequest; + CSRSS_SCREEN_BUFFER_INFO ScreenBufferInfoRequest; + CSRSS_SET_CURSOR SetCursorRequest; + CSRSS_FILL_OUTPUT FillOutputRequest; + CSRSS_FILL_OUTPUT_ATTRIB FillOutputAttribRequest; + CSRSS_READ_INPUT ReadInputRequest; + CSRSS_WRITE_CONSOLE_OUTPUT_CHAR WriteConsoleOutputCharRequest; + CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB WriteConsoleOutputAttribRequest; + CSRSS_GET_CURSOR_INFO GetCursorInfoRequest; + CSRSS_SET_CURSOR_INFO SetCursorInfoRequest; + CSRSS_SET_ATTRIB SetAttribRequest; + CSRSS_SET_CONSOLE_MODE SetConsoleModeRequest; + CSRSS_GET_CONSOLE_MODE GetConsoleModeRequest; + CSRSS_CREATE_SCREEN_BUFFER CreateScreenBufferRequest; + CSRSS_SET_SCREEN_BUFFER SetScreenBufferRequest; + CSRSS_SET_TITLE SetTitleRequest; + CSRSS_GET_TITLE GetTitleRequest; + CSRSS_WRITE_CONSOLE_OUTPUT WriteConsoleOutputRequest; + CSRSS_FLUSH_INPUT_BUFFER FlushInputBufferRequest; + CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER ScrollConsoleScreenBufferRequest; + CSRSS_READ_CONSOLE_OUTPUT_CHAR ReadConsoleOutputCharRequest; + CSRSS_READ_CONSOLE_OUTPUT_ATTRIB ReadConsoleOutputAttribRequest; + CSRSS_PEEK_CONSOLE_INPUT PeekConsoleInputRequest; + CSRSS_READ_CONSOLE_OUTPUT ReadConsoleOutputRequest; + CSRSS_WRITE_CONSOLE_INPUT WriteConsoleInputRequest; + CSRSS_GET_INPUT_HANDLE GetInputHandleRequest; + CSRSS_GET_OUTPUT_HANDLE GetOutputHandleRequest; + CSRSS_SETGET_CONSOLE_HW_STATE ConsoleHardwareStateRequest; + CSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest; + CSRSS_SET_CONSOLE_ICON SetConsoleIconRequest; + CSRSS_ADD_CONSOLE_ALIAS AddConsoleAlias; + CSRSS_GET_CONSOLE_ALIAS GetConsoleAlias; + CSRSS_GET_ALL_CONSOLE_ALIASES GetAllConsoleAlias; + CSRSS_GET_ALL_CONSOLE_ALIASES_LENGTH GetAllConsoleAliasesLength; + CSRSS_GET_CONSOLE_ALIASES_EXES GetConsoleAliasesExes; + CSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength; + CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent; + CSRSS_GET_NUM_INPUT_EVENTS GetNumInputEventsRequest; + CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize; + CSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo; + CSRSS_GET_COMMAND_HISTORY_LENGTH GetCommandHistoryLength; + CSRSS_GET_COMMAND_HISTORY GetCommandHistory; + CSRSS_EXPUNGE_COMMAND_HISTORY ExpungeCommandHistory; + CSRSS_SET_HISTORY_NUMBER_COMMANDS SetHistoryNumberCommands; + CSRSS_GET_HISTORY_INFO GetHistoryInfo; + CSRSS_SET_HISTORY_INFO SetHistoryInfo; + CSRSS_GET_CONSOLE_CP GetConsoleCodePage; + CSRSS_SET_CONSOLE_CP SetConsoleCodePage; + CSRSS_GET_CONSOLE_OUTPUT_CP GetConsoleOutputCodePage; + CSRSS_SET_CONSOLE_OUTPUT_CP SetConsoleOutputCodePage; + } Data; +} CONSOLE_API_MESSAGE, *PCONSOLE_API_MESSAGE; - - - - - - - - - -#if 0 - - CSRSS_WRITE_CONSOLE WriteConsoleRequest; - CSRSS_READ_CONSOLE ReadConsoleRequest; - CSRSS_ALLOC_CONSOLE AllocConsoleRequest; - CSRSS_FREE_CONSOLE FreeConsoleRequest; - CSRSS_SCREEN_BUFFER_INFO ScreenBufferInfoRequest; - CSRSS_SET_CURSOR SetCursorRequest; - CSRSS_FILL_OUTPUT FillOutputRequest; - CSRSS_FILL_OUTPUT_ATTRIB FillOutputAttribRequest; - CSRSS_READ_INPUT ReadInputRequest; - CSRSS_WRITE_CONSOLE_OUTPUT_CHAR WriteConsoleOutputCharRequest; - CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB WriteConsoleOutputAttribRequest; - CSRSS_GET_CURSOR_INFO GetCursorInfoRequest; - CSRSS_SET_CURSOR_INFO SetCursorInfoRequest; - CSRSS_SET_ATTRIB SetAttribRequest; - CSRSS_SET_CONSOLE_MODE SetConsoleModeRequest; - CSRSS_GET_CONSOLE_MODE GetConsoleModeRequest; - CSRSS_CREATE_SCREEN_BUFFER CreateScreenBufferRequest; - CSRSS_SET_SCREEN_BUFFER SetScreenBufferRequest; - CSRSS_SET_TITLE SetTitleRequest; - CSRSS_GET_TITLE GetTitleRequest; - CSRSS_WRITE_CONSOLE_OUTPUT WriteConsoleOutputRequest; - CSRSS_FLUSH_INPUT_BUFFER FlushInputBufferRequest; - CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER ScrollConsoleScreenBufferRequest; - CSRSS_READ_CONSOLE_OUTPUT_CHAR ReadConsoleOutputCharRequest; - CSRSS_READ_CONSOLE_OUTPUT_ATTRIB ReadConsoleOutputAttribRequest; - CSRSS_PEEK_CONSOLE_INPUT PeekConsoleInputRequest; - CSRSS_READ_CONSOLE_OUTPUT ReadConsoleOutputRequest; - CSRSS_WRITE_CONSOLE_INPUT WriteConsoleInputRequest; - CSRSS_GET_INPUT_HANDLE GetInputHandleRequest; - CSRSS_GET_OUTPUT_HANDLE GetOutputHandleRequest; - CSRSS_SETGET_CONSOLE_HW_STATE ConsoleHardwareStateRequest; - CSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest; - CSRSS_SET_CONSOLE_ICON SetConsoleIconRequest; - CSRSS_ADD_CONSOLE_ALIAS AddConsoleAlias; - CSRSS_GET_CONSOLE_ALIAS GetConsoleAlias; - CSRSS_GET_ALL_CONSOLE_ALIASES GetAllConsoleAlias; - CSRSS_GET_ALL_CONSOLE_ALIASES_LENGTH GetAllConsoleAliasesLength; - CSRSS_GET_CONSOLE_ALIASES_EXES GetConsoleAliasesExes; - CSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength; - CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent; - CSRSS_GET_NUM_INPUT_EVENTS GetNumInputEventsRequest; - CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize; - CSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo; - CSRSS_GET_COMMAND_HISTORY_LENGTH GetCommandHistoryLength; - CSRSS_GET_COMMAND_HISTORY GetCommandHistory; - CSRSS_EXPUNGE_COMMAND_HISTORY ExpungeCommandHistory; - CSRSS_SET_HISTORY_NUMBER_COMMANDS SetHistoryNumberCommands; - CSRSS_GET_HISTORY_INFO GetHistoryInfo; - CSRSS_SET_HISTORY_INFO SetHistoryInfo; - CSRSS_GET_CONSOLE_CP GetConsoleCodePage; - CSRSS_SET_CONSOLE_CP SetConsoleCodePage; - CSRSS_GET_CONSOLE_OUTPUT_CP GetConsoleOutputCodePage; - CSRSS_SET_CONSOLE_OUTPUT_CP SetConsoleOutputCodePage; - -#endif - - - -#endif // __CSRCONS_H__ +#endif // __CONMSG_H__ /* EOF */ diff --git a/include/reactos/subsys/win/windows.h b/include/reactos/subsys/win/windows.h deleted file mode 100644 index 5883ff4c1e1..00000000000 --- a/include/reactos/subsys/win/windows.h +++ /dev/null @@ -1,14 +0,0 @@ -#if !defined(__INCLUDE_WIN_WINDOWS_H) -#define __INCLUDE_WIN_WINDOWS_H - -#include - -/* w32 console server */ -CSR_SERVER_DLL_INIT(ConServerDllInitialization); - -/* w32 user server */ -CSR_SERVER_DLL_INIT(UserServerDllInitialization); - -#endif /* ndef __INCLUDE_WIN_WINDOWS_H */ - - diff --git a/include/reactos/subsys/win/winmsg.h b/include/reactos/subsys/win/winmsg.h new file mode 100644 index 00000000000..716620394ab --- /dev/null +++ b/include/reactos/subsys/win/winmsg.h @@ -0,0 +1,15 @@ + +#ifndef __WINMSG_H__ +#define __WINMSG_H__ + +#pragma once + +#define USERSRV_SERVERDLL_INDEX 3 +#define USERSRV_FIRST_API_NUMBER 1024 + +/* w32 user server - move to win.h */ +CSR_SERVER_DLL_INIT(UserServerDllInitialization); + +#endif // __WINMSG_H__ + +/* EOF */ diff --git a/subsystems/win32/csrsrv/CMakeLists.txt b/subsystems/win32/csrsrv/CMakeLists.txt index 0fabebe4bc0..81048de31d8 100644 --- a/subsystems/win32/csrsrv/CMakeLists.txt +++ b/subsystems/win32/csrsrv/CMakeLists.txt @@ -5,15 +5,14 @@ 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 + api.c init.c - wait.c - session.c + procsup.c server.c + session.c + thredsup.c + user.c + wait.c ${CMAKE_CURRENT_BINARY_DIR}/csrsrv.def) add_library(csrsrv SHARED ${SOURCE}) diff --git a/subsystems/win32/csrsrv/api/wapi.c b/subsystems/win32/csrsrv/api.c similarity index 50% rename from subsystems/win32/csrsrv/api/wapi.c rename to subsystems/win32/csrsrv/api.c index e88c6022718..47dfeae5e7b 100644 --- a/subsystems/win32/csrsrv/api/wapi.c +++ b/subsystems/win32/csrsrv/api.c @@ -1,16 +1,15 @@ /* - * subsystems/win32/csrss/csrsrv/api/wapi.c - * - * "\windows\ApiPort" port process management functions - * CSRSS port message processing - * - * ReactOS Operating System - * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS CSR Sub System + * FILE: subsystems/win32/csrsrv/api.c + * PURPOSE: CSR Server DLL API LPC Implementation + * "\windows\ApiPort" port process management functions + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) */ /* INCLUDES ******************************************************************/ -#include +#include "srv.h" #define NDEBUG #include @@ -19,6 +18,8 @@ static unsigned ApiDefinitionsCount = 0; static PCSRSS_API_DEFINITION ApiDefinitions = NULL; + +BOOLEAN (*CsrClientThreadSetup)(VOID) = NULL; UNICODE_STRING CsrApiPortName; volatile LONG CsrpStaticThreadCount; volatile LONG CsrpDynamicThreadTotal; @@ -112,6 +113,7 @@ VOID CallHardError(IN PCSR_THREAD ThreadData, IN PHARDERROR_MSG HardErrorMessage); +#if 0 static VOID NTAPI @@ -123,6 +125,7 @@ CsrHandleHardError(IN PCSR_THREAD ThreadData, /* Call the hard error handler in win32csr */ CallHardError(ThreadData, Message); } +#endif /*++ * @name CsrCallServerFromServer @@ -146,8 +149,8 @@ CsrHandleHardError(IN PCSR_THREAD ThreadData, *--*/ NTSTATUS NTAPI -CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg, - PCSR_API_MESSAGE ReplyMsg) +CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, + IN OUT PCSR_API_MESSAGE ReplyMsg) { #if 1 // Real code ULONG ServerId; @@ -157,7 +160,7 @@ CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg, NTSTATUS Status; /* Get the Server ID */ - ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg->ApiNumber); + ServerId = CSR_API_NUMBER_TO_SERVER_ID(ReceiveMsg->ApiNumber); /* Make sure that the ID is within limits, and the Server DLL loaded */ if ((ServerId >= CSR_SERVER_DLL_MAX) || @@ -254,292 +257,85 @@ CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg, } /*++ - * @name CsrApiPortInitialize + * @name CsrApiHandleConnectionRequest * - * 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. + * The CsrApiHandleConnectionRequest routine handles and accepts a new + * connection request to the CSR API LPC Port. * - * @param None + * @param ApiMessage + * Pointer to the incoming CSR API Message which contains the + * connection request. * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * otherwise. + * @return STATUS_SUCCESS in case of success, or status code which caused + * the routine to error. * - * @remarks None. + * @remarks This routine is responsible for attaching the Shared Section to + * new clients connecting to CSR. * *--*/ NTSTATUS NTAPI -CsrApiPortInitialize(VOID) +CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage) { - ULONG Size; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS Status; - HANDLE hRequestEvent, hThread; - CLIENT_ID ClientId; - PLIST_ENTRY ListHead, NextEntry; - PCSR_THREAD ServerThread; + 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; - /* Calculate how much space we'll need for the Port Name */ - Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR); + /* Acquire the Process Lock */ + CsrAcquireProcessLock(); - /* Create the buffer for it */ - CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size); - if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY; + /* Lookup the CSR Thread */ + CsrThread = CsrLocateThreadByClientId(NULL, &ApiMessage->Header.ClientId); - /* 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) + /* Check if we have a thread */ + if (CsrThread) { - 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)); - } + /* Get the Process */ + CsrProcess = CsrThread->Process; - /* 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)) + /* Make sure we have a Process as well */ + if (CsrProcess) { - /* Create the Request Thread */ - Status = RtlCreateUserThread(NtCurrentProcess(), - NULL, - TRUE, - 0, - 0, - 0, - (PVOID)ClientConnectionThread,//CsrApiRequestThread, - (PVOID)hRequestEvent, - &hThread, - &ClientId); + /* 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)) { - /* Add this as a static thread to CSRSRV */ - CsrAddStaticServerThread(hThread, &ClientId, CsrThreadIsServerThread); + /* Attach the Shared Section */ + Status = CsrSrvAttachSharedSection(CsrProcess, ConnectInfo); - /* 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); + /* Check how this went */ + if (NT_SUCCESS(Status)) AllowConnection = TRUE; } + + /* Dereference the project */ + CsrLockedDereferenceProcess(CsrProcess); } } - /* 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; -} - -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); + /* Release the lock */ + CsrReleaseProcessLock(); /* Setup the Port View Structure */ RemotePortView.Length = sizeof(REMOTE_PORT_VIEW); @@ -549,9 +345,10 @@ CsrpHandleConnectionRequest(PPORT_MESSAGE Request) /* Save the Process ID */ ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess; - Status = NtAcceptConnectPort(&ServerPort, - AllowConnection ? UlongToPtr(ProcessData->SequenceNumber) : 0, - Request, + /* Accept the Connection */ + Status = NtAcceptConnectPort(&hPort, + AllowConnection ? UlongToPtr(CsrProcess->SequenceNumber) : 0, + &ApiMessage->Header, AllowConnection, NULL, &RemotePortView); @@ -564,20 +361,20 @@ CsrpHandleConnectionRequest(PPORT_MESSAGE Request) if (CsrDebug & 2) { DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n", - Request->ClientId.UniqueProcess, - Request->ClientId.UniqueThread, + ApiMessage->Header.ClientId.UniqueProcess, + ApiMessage->Header.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); + 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(ServerPort); + Status = NtCompleteConnectPort(hPort); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status); @@ -586,73 +383,14 @@ CsrpHandleConnectionRequest(PPORT_MESSAGE Request) else { DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n", - Request->ClientId.UniqueProcess, - Request->ClientId.UniqueThread); + ApiMessage->Header.ClientId.UniqueProcess, + ApiMessage->Header.ClientId.UniqueThread); } + /* Return status to caller */ 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 * @@ -689,7 +427,7 @@ CsrpCheckRequestThreads(VOID) 0, 0, 0, - (PVOID)ClientConnectionThread,//CsrApiRequestThread, + (PVOID)CsrApiRequestThread, NULL, &hThread, &ClientId); @@ -730,9 +468,546 @@ CsrpCheckRequestThreads(VOID) return STATUS_SUCCESS; } -VOID -WINAPI -ClientConnectionThread(IN PVOID Parameter) +/*++ + * @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) +#if 1 +{ + 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_API_NUMBER_TO_SERVER_ID(ReceiveMsg.ApiNumber); + + /* 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_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber); + + /* 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_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber), + &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_API_NUMBER_TO_SERVER_ID(ReceiveMsg.ApiNumber); + + /* 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_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber); + + /* 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_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber), + &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; +} +#else { PTEB Teb = NtCurrentTeb(); LARGE_INTEGER TimeOut; @@ -1082,6 +1357,459 @@ HandleHardError: NtTerminateThread(NtCurrentThread(), Status); //return Status; } +#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)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; +} + +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) +{ + 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 @@ -1147,4 +1875,116 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage) 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 */ diff --git a/subsystems/win32/csrsrv/api/process.c b/subsystems/win32/csrsrv/api/process.c deleted file mode 100644 index 97f5a8e4e72..00000000000 --- a/subsystems/win32/csrsrv/api/process.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * subsystems/win32/csrss/csrsrv/api/process.c - * - * - * - * ReactOS Operating System - */ - -/* INCLUDES ******************************************************************/ - -#include - -#define NDEBUG -#include - - - -/* GLOBALS *******************************************************************/ - -/* FUNCTIONS *****************************************************************/ - -/********************************************************************** - * CSRSS API - *********************************************************************/ - -/*** - *** Some APIs from here will go to basesrv.dll, some others to winsrv.dll. - *** Furthermore, this structure uses the old definition of APIs list. - *** The new one is in fact three arrays, one of APIs pointers, one other of - *** corresponding indexes, and the third one of names (not very efficient...). - ***/ - -/* EOF */ diff --git a/subsystems/win32/csrsrv/csrsrv.spec b/subsystems/win32/csrsrv/csrsrv.spec index 32fb504c63f..b2244491a05 100644 --- a/subsystems/win32/csrsrv/csrsrv.spec +++ b/subsystems/win32/csrsrv/csrsrv.spec @@ -12,7 +12,7 @@ @ stdcall CsrDereferenceWait(ptr) @ stdcall CsrDestroyProcess(ptr long) @ stdcall CsrDestroyThread(ptr) -@ stdcall CsrEnumProcesses(ptr ptr) ;;;;;;; Temporary hack used in win32csr, to be removed +;@ stdcall CsrEnumProcesses(ptr ptr) ;;;;;;; Temporary hack used in win32csr, to be removed @ stdcall CsrExecServerThread(ptr long) @ stdcall CsrGetProcessLuid(ptr ptr) @ stdcall CsrImpersonateClient(ptr) diff --git a/subsystems/win32/csrsrv/include/api.h b/subsystems/win32/csrsrv/include/api.h index a621d9cad36..ea22ddcbbb0 100644 --- a/subsystems/win32/csrsrv/include/api.h +++ b/subsystems/win32/csrsrv/include/api.h @@ -11,9 +11,11 @@ #include #include -#include +#include +extern RTL_CRITICAL_SECTION CsrProcessLock, CsrWaitListsLock; + #define CsrAcquireProcessLock() \ RtlEnterCriticalSection(&CsrProcessLock); @@ -36,7 +38,12 @@ RtlLeaveCriticalSection(&CsrNtSessionLock); +#define CSR_SERVER_DLL_MAX 4 + +/*** + *** Old structure. Deprecated. + ***/ typedef struct _CSRSS_API_DEFINITION { ULONG ApiID; @@ -49,6 +56,7 @@ typedef struct _CSRSS_API_DEFINITION + typedef struct _CSRSS_LISTEN_DATA { HANDLE ApiPortHandle; @@ -64,22 +72,66 @@ typedef struct _CSRSS_LISTEN_DATA ******************************************************************************/ - -/* init.c */ extern HANDLE hBootstrapOk; -NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]); +extern HANDLE CsrApiPort; +extern HANDLE CsrSmApiPort; +extern HANDLE CsrSbApiPort; +extern LIST_ENTRY CsrThreadHashTable[256]; +extern PCSR_PROCESS CsrRootProcess; +extern UNICODE_STRING CsrDirectoryName; +extern ULONG CsrDebug; +extern ULONG CsrTotalPerProcessDataLength; +extern SYSTEM_BASIC_INFORMATION CsrNtSysInfo; +extern HANDLE CsrHeap; +extern PVOID CsrSrvSharedSectionHeap; +extern PVOID *CsrSrvSharedStaticServerData; +extern HANDLE CsrInitializationEvent; +extern PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]; +extern ULONG CsrMaxApiRequestThreads; -/* api/process.c */ -CSR_API(CsrConnectProcess); -CSR_API(BaseSrvCreateProcess); -CSR_API(BaseSrvExitProcess); -CSR_API(BaseSrvCreateThread); -CSR_API(BaseSrvGetProcessShutdownParam); -CSR_API(BaseSrvSetProcessShutdownParam); +/****************************************************/ +extern UNICODE_STRING CsrSbApiPortName; +extern UNICODE_STRING CsrApiPortName; +extern RTL_CRITICAL_SECTION CsrProcessLock; +extern RTL_CRITICAL_SECTION CsrWaitListsLock; +extern HANDLE CsrObjectDirectory; +extern PSB_API_ROUTINE CsrServerSbApiDispatch[5]; +/****************************************************/ + + + +CSR_API(CsrSrvClientConnect); +CSR_API(CsrSrvUnusedFunction); +CSR_API(CsrSrvIdentifyAlertableThread); +CSR_API(CsrSrvSetPriorityClass); +CSR_API(SrvRegisterServicesProcess); + + +/*** + +BOOLEAN +NTAPI +CsrCaptureArguments( + IN PCSR_THREAD CsrThread, + IN PCSR_API_MESSAGE ApiMessage +); VOID NTAPI -CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess); +CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage); + +NTSTATUS +NTAPI +CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll); + +***/ + +NTSTATUS +NTAPI +CsrLoadServerDll(IN PCHAR DllString, + IN PCHAR EntryPoint OPTIONAL, + IN ULONG ServerId); + PCSR_THREAD NTAPI @@ -97,10 +149,6 @@ VOID NTAPI CsrRemoveProcess(IN PCSR_PROCESS CsrProcess); -VOID -NTAPI -CsrDereferenceThread(IN PCSR_THREAD CsrThread); - VOID NTAPI CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, @@ -108,69 +156,66 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, IN PCSR_PROCESS CsrProcess); -/* api/wapi.c */ NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions); VOID FASTCALL CsrApiCallHandler(IN OUT PCSR_API_MESSAGE ApiMessage, OUT PULONG Reply); -VOID WINAPI CsrSbApiRequestThread (PVOID PortHandle); -VOID NTAPI ClientConnectionThread(HANDLE ServerPort); -extern HANDLE CsrApiPort; -extern HANDLE CsrSmApiPort; -extern HANDLE CsrSbApiPort; -extern LIST_ENTRY CsrThreadHashTable[256]; -extern PCSR_PROCESS CsrRootProcess; -extern RTL_CRITICAL_SECTION CsrProcessLock, 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 +CsrApiRequestThread(IN PVOID Parameter); // HANDLE ServerPort ?? + +VOID +NTAPI +CsrSbApiRequestThread(IN PVOID Parameter); 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); +BOOLEAN +NTAPI +UnProtectHandle(IN HANDLE ObjectHandle); + VOID NTAPI CsrInsertThread(IN PCSR_PROCESS Process, -IN PCSR_THREAD Thread); + IN PCSR_THREAD Thread); + +VOID +NTAPI +CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess); 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 +NTAPI +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); +// NTSTATUS WINAPI CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, +// PVOID Context); +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); -//hack -VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread); +// HACK +VOID +NTAPI +CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess); + +// HACK +VOID +NTAPI +CsrThreadRefcountZero(IN PCSR_THREAD CsrThread); NTSTATUS NTAPI @@ -179,48 +224,15 @@ CsrInitializeNtSessionList(VOID); NTSTATUS NTAPI CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL, -OUT PCSR_CONNECTION_INFO ConnectInfo); + OUT PCSR_CONNECTION_INFO ConnectInfo); NTSTATUS NTAPI CsrSrvCreateSharedSection(IN PCHAR ParameterValue); -NTSTATUS +VOID 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); +CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess); VOID NTAPI @@ -239,30 +251,63 @@ 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); + 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); +CsrCreateSessionObjectDirectory(IN ULONG SessionId); -/* api/user.c */ -CSR_API(SrvRegisterServicesProcess); +NTSTATUS +NTAPI +CsrCreateObjectDirectory(IN PCHAR ObjectDirectory); + +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); + +NTSTATUS +NTAPI +CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message); + +NTSTATUS +NTAPI +CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage); + +/** this API is used with CsrPopulateDosDevices, deprecated in r55585. +NTSTATUS +NTAPI +CsrPopulateDosDevicesDirectory(IN HANDLE DosDevicesDirectory, + IN PPROCESS_DEVICEMAP_INFORMATION DeviceMap); +**/ + +NTSTATUS +NTAPI +CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd); + +NTSTATUS +NTAPI +CsrSetDirectorySecurity(IN HANDLE ObjectDirectory); /* EOF */ diff --git a/subsystems/win32/csrsrv/include/csrplugin.h b/subsystems/win32/csrsrv/include/csrplugin.h index 07c6b36889b..053410d7ca2 100644 --- a/subsystems/win32/csrsrv/include/csrplugin.h +++ b/subsystems/win32/csrsrv/include/csrplugin.h @@ -18,15 +18,21 @@ #pragma once #include -#include "api.h" +#include +//#include "api.h" + +/* typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESSES_PROC)(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context); +typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSR_PROCESS ProcessData, + 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); diff --git a/subsystems/win32/csrsrv/init.c b/subsystems/win32/csrsrv/init.c index 6be1bbd3aad..a15bfdafb48 100644 --- a/subsystems/win32/csrsrv/init.c +++ b/subsystems/win32/csrsrv/init.c @@ -16,15 +16,15 @@ /* DATA ***********************************************************************/ -HANDLE CsrHeap = (HANDLE) 0; -HANDLE CsrObjectDirectory = (HANDLE) 0; +HANDLE CsrHeap = NULL; +HANDLE CsrObjectDirectory = NULL; UNICODE_STRING CsrDirectoryName; UNICODE_STRING CsrSbApiPortName; -HANDLE CsrSbApiPort = 0; +HANDLE CsrSbApiPort = NULL; PCSR_THREAD CsrSbApiRequestThreadPtr; -HANDLE CsrSmApiPort; -HANDLE hSbApiPort = (HANDLE) 0; -HANDLE CsrApiPort = (HANDLE) 0; +HANDLE CsrSmApiPort = NULL; +HANDLE hSbApiPort = NULL; +HANDLE CsrApiPort = NULL; ULONG CsrDebug = 0;//0xFFFFFFFF; ULONG CsrMaxApiRequestThreads; ULONG CsrTotalPerProcessDataLength; @@ -35,6 +35,7 @@ HANDLE DosDevicesDirectory; HANDLE CsrInitializationEvent; SYSTEM_BASIC_INFORMATION CsrNtSysInfo; + /* PRIVATE FUNCTIONS **********************************************************/ VOID @@ -60,34 +61,6 @@ CallHardError(IN PCSR_THREAD ThreadData, } } -#if 0 -NTSTATUS -CallProcessCreated(IN PCSR_PROCESS SourceProcessData, - IN PCSR_PROCESS TargetProcessData) -{ - NTSTATUS Status = STATUS_SUCCESS; - ULONG 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; -} -#endif - CSRSS_API_DEFINITION NativeDefinitions[] = { CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, SrvRegisterServicesProcess), // winsrv.dll @@ -928,7 +901,6 @@ CsrSbApiPortInitialize(VOID) } - /* PUBLIC FUNCTIONS ***********************************************************/ /*++ @@ -1103,7 +1075,7 @@ VOID NTAPI CsrPopulateDosDevices(VOID) { - DPRINT1("Deprecated API\n"); + DPRINT1("Deprecated API in r55585.\n"); return; } diff --git a/subsystems/win32/csrsrv/procsup.c b/subsystems/win32/csrsrv/procsup.c index 52a44279867..37961450c25 100644 --- a/subsystems/win32/csrsrv/procsup.c +++ b/subsystems/win32/csrsrv/procsup.c @@ -498,344 +498,6 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, /* PUBLIC FUNCTIONS ***********************************************************/ -/*++ - * @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 = CsrGetClientThread(); - - /* 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 = CsrGetClientThread(); - 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 */ - return NT_SUCCESS(Status); -} - -/*++ - * @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 @@ -1048,60 +710,339 @@ CsrCreateProcess(IN HANDLE hProcess, } /*++ - * @name CsrUnlockProcess + * @name CsrDebugProcess * @implemented NT4 * - * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation. + * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is + * exported only for compatibility with older CSR Server DLLs. * * @param CsrProcess - * Pointer to a previously locked CSR Process. + * Deprecated. * - * @return STATUS_SUCCESS. + * @return Deprecated * - * @remarks This routine must be called with the Process Lock held. + * @remarks Deprecated. * *--*/ NTSTATUS NTAPI -CsrUnlockProcess(IN PCSR_PROCESS CsrProcess) +CsrDebugProcess(IN PCSR_PROCESS CsrProcess) { - /* Dereference the process */ - CsrLockedDereferenceProcess(CsrProcess); + /* CSR does not handle debugging anymore */ + DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess); + return STATUS_UNSUCCESSFUL; +} - /* Release the lock and return */ +/*++ + * @name CsrDebugProcessStop + * @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 CsrSetBackgroundPriority + * @name CsrGetProcessLuid * @implemented NT4 * - * The CsrSetBackgroundPriority routine sets the priority for the given CSR - * Process as a Background priority. + * Do nothing for 500ms. * - * @param CsrProcess - * Pointer to the CSR Process whose priority will be modified. + * @param hProcess + * Optional handle to the process whose LUID should be returned. * - * @return None. + * @param Luid + * Pointer to a LUID Pointer which will receive the CSR Process' LUID * - * @remarks None. + * @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. * *--*/ -VOID +NTSTATUS NTAPI -CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess) +CsrGetProcessLuid(IN HANDLE hProcess OPTIONAL, + OUT PLUID Luid) { - PROCESS_PRIORITY_CLASS PriorityClass; + HANDLE hToken = NULL; + NTSTATUS Status; + ULONG Length; + PTOKEN_STATISTICS TokenStats; - /* Set the Foreground bit off */ - PriorityClass.Foreground = FALSE; + /* 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); - /* Set the new Priority */ - NtSetInformationProcess(CsrProcess->ProcessHandle, - ProcessPriorityClass, - &PriorityClass, - sizeof(PriorityClass)); + /* 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 = CsrGetClientThread(); + + /* 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; } /*++ @@ -1176,6 +1117,118 @@ CsrLockProcessByClientId(IN HANDLE Pid, return Status; } +/*++ + * @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 = CsrGetClientThread(); + 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 */ + return NT_SUCCESS(Status); +} + +/*++ + * @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 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 CsrShutdownProcesses * @implemented NT4 @@ -1231,7 +1284,8 @@ CsrShutdownProcesses(IN PLUID CallerLuid, } /* Set shudown Priority */ - CsrpSetToShutdownPriority(); + // CsrpSetToShutdownPriority(); + CsrSetToShutdownPriority(); /* Start looping */ while (TRUE) @@ -1305,11 +1359,14 @@ CsrShutdownProcesses(IN PLUID CallerLuid, Quickie: /* Return to normal priority */ - CsrpSetToNormalPriority(); + // CsrpSetToNormalPriority(); + CsrSetToNormalPriority(); + return Status; } /* FIXME: Temporary hack. This is really "CsrShutdownProcess", mostly. Used by win32csr */ +#if 0 NTSTATUS WINAPI CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc, @@ -1400,84 +1457,32 @@ Quickie: CsrSetToNormalPriority(); return Status; } +#endif /*++ - * @name CsrDebugProcess + * @name CsrUnlockProcess * @implemented NT4 * - * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is - * exported only for compatibility with older CSR Server DLLs. + * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation. * * @param CsrProcess - * Deprecated. + * Pointer to a previously locked CSR Process. * - * @return Deprecated + * @return STATUS_SUCCESS. * - * @remarks Deprecated. + * @remarks This routine must be called with the Process Lock held. * *--*/ NTSTATUS NTAPI -CsrDebugProcess(IN PCSR_PROCESS CsrProcess) +CsrUnlockProcess(IN PCSR_PROCESS CsrProcess) { - /* CSR does not handle debugging anymore */ - DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess); - return STATUS_UNSUCCESSFUL; -} + /* Dereference the process */ + CsrLockedDereferenceProcess(CsrProcess); -/*++ - * @name CsrDebugProcessStop - * @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 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)); + /* Release the lock and return */ + CsrReleaseProcessLock(); + return STATUS_SUCCESS; } /* EOF */ diff --git a/subsystems/win32/csrsrv/server.c b/subsystems/win32/csrsrv/server.c index ea149b815de..8954c4dfcb4 100644 --- a/subsystems/win32/csrsrv/server.c +++ b/subsystems/win32/csrsrv/server.c @@ -15,24 +15,6 @@ /* DATA **********************************************************************/ -/*** Must go elsewhere ***/ -#define CSR_SERVER_DLL_MAX 4 - -#define CSRSRV_SERVERDLL_INDEX 0 -#define CSRSRV_FIRST_API_NUMBER 0 - -typedef enum _CSR_SRV_API_NUMBER -{ - CsrpClientConnect = CSRSRV_FIRST_API_NUMBER, - CsrpThreadConnect, - CsrpProfileControl, - CsrpIdentifyAlertable, - CsrpSetPriorityClass, - - CsrpMaxApiNumber -} CSR_SRV_API_NUMBER, *PCSR_SRV_API_NUMBER; -/*************************/ - PCSR_API_ROUTINE CsrServerApiDispatchTable[CsrpMaxApiNumber] = { CsrSrvClientConnect, @@ -186,7 +168,7 @@ CsrLoadServerDll(IN PCHAR DllString, /* Set up the Object */ ServerDll->Length = Size; - ServerDll->SharedSection = CsrSrvSharedSectionHeap; + ServerDll->SharedSection = CsrSrvSharedSectionHeap; // Send to the server dll our shared heap pointer. ServerDll->Event = CsrInitializationEvent; ServerDll->Name.Length = DllName.Length; ServerDll->Name.MaximumLength = DllName.MaximumLength; @@ -297,7 +279,7 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage, PCSR_PROCESS CurrentProcess = CsrGetClientThread()->Process; /* Load the Message, set default reply */ - ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect; + ClientConnect = &ApiMessage->Data.CsrClientConnect; *Reply = 0; /* Validate the ServerID */ diff --git a/subsystems/win32/csrsrv/session.c b/subsystems/win32/csrsrv/session.c index 66d273f845b..9c932496a2d 100644 --- a/subsystems/win32/csrsrv/session.c +++ b/subsystems/win32/csrsrv/session.c @@ -543,7 +543,7 @@ CsrSbApiRequestThread(IN PVOID Parameter) { ReceiveMsg.ApiNumber = SbpMaxApiNumber; DPRINT1("CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber); - } + } /* Reuse the message */ ReplyMsg = &ReceiveMsg; diff --git a/subsystems/win32/csrsrv/srv.h b/subsystems/win32/csrsrv/srv.h index 94d6dfcb6af..f74588c3dbd 100644 --- a/subsystems/win32/csrsrv/srv.h +++ b/subsystems/win32/csrsrv/srv.h @@ -10,7 +10,7 @@ #include /* CSR Header */ -//#include +#include /* PSEH for SEH Support */ #include @@ -20,11 +20,10 @@ #include /* Internal CSRSS Headers */ -#include -#include - -extern HANDLE CsrHeap; +#include "include/api.h" +#include "include/csrplugin.h" +/* Defines */ #define SM_REG_KEY \ L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager" @@ -35,7 +34,6 @@ extern HANDLE CsrHeap; #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)) diff --git a/subsystems/win32/csrsrv/thredsup.c b/subsystems/win32/csrsrv/thredsup.c index 72566f8efc1..63246516657 100644 --- a/subsystems/win32/csrsrv/thredsup.c +++ b/subsystems/win32/csrsrv/thredsup.c @@ -472,6 +472,67 @@ CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread) /* 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 @@ -573,75 +634,6 @@ CsrCreateRemoteThread(IN HANDLE hThread, return STATUS_SUCCESS; } -/*++ - * @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 CsrCreateThread * @implemented NT4 @@ -798,67 +790,6 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, } #endif -/*++ - * @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 @@ -895,6 +826,74 @@ CsrDereferenceThread(IN PCSR_THREAD CsrThread) } } +/*++ + * @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 CsrExecServerThread diff --git a/subsystems/win32/csrsrv/api/user.c b/subsystems/win32/csrsrv/user.c similarity index 66% rename from subsystems/win32/csrsrv/api/user.c rename to subsystems/win32/csrsrv/user.c index 770e5194d84..dbd3fd4f6ca 100644 --- a/subsystems/win32/csrsrv/api/user.c +++ b/subsystems/win32/csrsrv/user.c @@ -25,16 +25,16 @@ static ULONG_PTR ServicesProcessId; CSR_API(SrvRegisterServicesProcess) { - if (ServicesProcessIdValid == TRUE) + if (ServicesProcessIdValid == TRUE) { - /* Only accept a single call */ - return STATUS_INVALID_PARAMETER; + /* Only accept a single call */ + return STATUS_INVALID_PARAMETER; } - else + else { - ServicesProcessId = (ULONG_PTR)ApiMessage->Data.RegisterServicesProcessRequest.ProcessId; - ServicesProcessIdValid = TRUE; - return STATUS_SUCCESS; + ServicesProcessId = (ULONG_PTR)ApiMessage->Data.RegisterServicesProcessRequest.ProcessId; + ServicesProcessIdValid = TRUE; + return STATUS_SUCCESS; } } diff --git a/subsystems/win32/csrss/CMakeLists.txt b/subsystems/win32/csrss/CMakeLists.txt index 6aa701dd919..869461fc1d8 100644 --- a/subsystems/win32/csrss/CMakeLists.txt +++ b/subsystems/win32/csrss/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories( - include + ${REACTOS_SOURCE_DIR}/subsystems/win32/csrsrv/include ${REACTOS_SOURCE_DIR}/include/reactos/subsys) add_executable(csrss csrss.c csrss.rc) diff --git a/subsystems/win32/csrss/csrss.c b/subsystems/win32/csrss/csrss.c index 110b95ccfba..82143d6e5c6 100644 --- a/subsystems/win32/csrss/csrss.c +++ b/subsystems/win32/csrss/csrss.c @@ -13,8 +13,8 @@ #include #define NTOS_MODE_USER #include -#include -// #include + +#include #define NDEBUG #include