From 46e2b227f29da08f97a16687cf72dd7f83940d95 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 6 Oct 2013 13:33:17 +0000 Subject: [PATCH] [CSR] During my investigations for making working Win2k3 csrsrv.dll (or other CSR servers) into ROS (to compare our behaviour with our own csrsrv.dll and Win2k3 one), I hit a problem: if I test a checked-build version of csrsrv (or other CSR servers), everything was fine when they were loaded, but if I use a release-build version (i.e. without any debug information), I systematically hit a memory access violation which was traced back to the moment when a CSR server's CsrInitialization entry point was called. So I did the experiment, where I used our (debug-build) csrsrv with a free-build win2k3 CSR server dll (it was winsrv.dll, and I retested with basesrv.dll after). I hit the access violation. But if I took a debug-build version of winsrv.dll, everything was OK. I then added in our csrsrv' server.c file the following line (around line 212 of the current file version): DPRINT1("%s ; ServerDll->ValidTable = 0x%p ; ServerDll->NameTable = 0x%p ; ServerDll->SizeOfProcessData = %d ; ServerDll->ConnectCallback = 0x%p\n", DllString, ServerDll->ValidTable, ServerDll->NameTable, ServerDll->SizeOfProcessData, ServerDll->ConnectCallback); and I saw that, when using a debug-build win2k3 CSR server, everything was fine (in particular the ServerDll->SizeOfProcessData member contained a reasonable value, e.g. a size of 88 bytes), whereas if I used a free-build version, I got an off-by-one problem, with the ServerDll->ValidTable pointer valid but the ServerDll->NameTable member being equal to 88 (i.e. invalid pointer) and the ServerDll->SizeOfProcessData member being equal to a very large value, which looked like a pointer value. After more investigations, I saw that in debug-build CSR servers the list of API names were stored, whereas it was not the case in free-build versions. Therefore I concluded that the API names table was included *ONLY* in debug builds and not in release builds. Hence, to be able to test in ROS either debug-builds or release-builds versions of Windows CSR servers in ROS (and vice-versa), I introduced a #define called CSR_DBG, which is defined only if the DBG macro is != 0, and which is not defined otherwise. When the CSR_DBG flag is defined, API names tables are added in CSR servers and otherwise, they are not. Therefore, we are now able to test debug-build Windows CSR servers in ROS (the default possibility) or free-build versions of these CSR servers (but first, we have to build the other ones without the CSR_DBG flag, to avoid the off-by-one problem described above). svn path=/trunk/; revision=60560 --- reactos/include/reactos/subsys/csr/csrsrv.h | 21 +++++++++++++++++++- reactos/subsystems/win/basesrv/init.c | 8 ++++++++ reactos/subsystems/win32/csrsrv/api.c | 8 ++++++++ reactos/subsystems/win32/csrsrv/api.h | 4 +++- reactos/subsystems/win32/csrsrv/init.c | 4 +++- reactos/subsystems/win32/csrsrv/server.c | 22 ++++++++++++++------- reactos/win32ss/user/winsrv/consrv/init.c | 9 ++++++++- reactos/win32ss/user/winsrv/usersrv/init.c | 9 ++++++++- 8 files changed, 73 insertions(+), 12 deletions(-) diff --git a/reactos/include/reactos/subsys/csr/csrsrv.h b/reactos/include/reactos/subsys/csr/csrsrv.h index 6c89d146e76..8634d3cf834 100644 --- a/reactos/include/reactos/subsys/csr/csrsrv.h +++ b/reactos/include/reactos/subsys/csr/csrsrv.h @@ -10,6 +10,14 @@ #ifndef _CSRSRV_H #define _CSRSRV_H +/* + * The CSR_DBG macro is defined for building CSR Servers + * with extended debugging information. + */ +#if DBG +#define CSR_DBG +#endif + #include "csrmsg.h" @@ -215,7 +223,14 @@ typedef struct _CSR_SERVER_DLL ULONG HighestApiSupported; PCSR_API_ROUTINE *DispatchTable; PBOOLEAN ValidTable; // Table of booleans which describe whether or not a server function call is valid when it is called via CsrCallServerFromServer. +/* + * On Windows Server 2003, CSR Servers contain + * the API Names Table only in Debug Builds. + */ +#ifdef CSR_DBG PCHAR *NameTable; +#endif + ULONG SizeOfProcessData; PCSR_CONNECT_CALLBACK ConnectCallback; PCSR_DISCONNECT_CALLBACK DisconnectCallback; @@ -226,7 +241,11 @@ typedef struct _CSR_SERVER_DLL ULONG Unknown2[3]; } CSR_SERVER_DLL, *PCSR_SERVER_DLL; #ifndef _WIN64 -C_ASSERT(FIELD_OFFSET(CSR_SERVER_DLL, SharedSection) == 0x3C); + #ifdef CSR_DBG + C_ASSERT(FIELD_OFFSET(CSR_SERVER_DLL, SharedSection) == 0x3C); + #else + C_ASSERT(FIELD_OFFSET(CSR_SERVER_DLL, SharedSection) == 0x38); + #endif #endif typedef diff --git a/reactos/subsystems/win/basesrv/init.c b/reactos/subsystems/win/basesrv/init.c index 6489ca8c276..b08d6bc5c69 100644 --- a/reactos/subsystems/win/basesrv/init.c +++ b/reactos/subsystems/win/basesrv/init.c @@ -97,6 +97,11 @@ BOOLEAN BaseServerApiServerValidTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMB TRUE, // BaseSrvNlsGetUserInfo }; +/* + * On Windows Server 2003, CSR Servers contain + * the API Names Table only in Debug Builds. + */ +#ifdef CSR_DBG PCHAR BaseServerApiNameTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] = { "BaseCreateProcess", @@ -131,6 +136,7 @@ PCHAR BaseServerApiNameTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] = "BaseRegisterThread", "BaseNlsGetUserInfo", }; +#endif /* FUNCTIONS ******************************************************************/ @@ -567,7 +573,9 @@ CSR_SERVER_DLL_INIT(ServerDllInitialization) LoadedServerDll->HighestApiSupported = BasepMaxApiNumber; LoadedServerDll->DispatchTable = BaseServerApiDispatchTable; LoadedServerDll->ValidTable = BaseServerApiServerValidTable; +#ifdef CSR_DBG LoadedServerDll->NameTable = BaseServerApiNameTable; +#endif LoadedServerDll->SizeOfProcessData = 0; LoadedServerDll->ConnectCallback = NULL; LoadedServerDll->DisconnectCallback = NULL; diff --git a/reactos/subsystems/win32/csrsrv/api.c b/reactos/subsystems/win32/csrsrv/api.c index dee6bd7c93d..55f8c9d3bbb 100644 --- a/reactos/subsystems/win32/csrsrv/api.c +++ b/reactos/subsystems/win32/csrsrv/api.c @@ -77,23 +77,27 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, { /* We are beyond the Maximum API ID, or it doesn't exist */ DPRINT1("API: %d\n", ApiId); +#ifdef CSR_DBG DPRINT1("CSRSS: %lx (%s) is invalid ApiTableIndex for %Z or is an " "invalid API to call from the server.\n", ApiId, ((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ? ServerDll->NameTable[ApiId] : "*** UNKNOWN ***", &ServerDll->Name); +#endif // DbgBreakPoint(); ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION; return STATUS_ILLEGAL_FUNCTION; } } +#ifdef CSR_DBG if (CsrDebug & 2) { DPRINT1("CSRSS: %s Api Request received from server process\n", ServerDll->NameTable[ApiId]); } +#endif /* Validation complete, start SEH */ _SEH2_TRY @@ -577,6 +581,7 @@ CsrApiRequestThread(IN PVOID Parameter) continue; } +#ifdef CSR_DBG if (CsrDebug & 2) { DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n", @@ -586,6 +591,7 @@ CsrApiRequestThread(IN PVOID Parameter) ServerDll->NameTable[ApiId], NULL); } +#endif /* Assume success */ ReceiveMsg.Status = STATUS_SUCCESS; @@ -781,6 +787,7 @@ CsrApiRequestThread(IN PVOID Parameter) continue; } +#ifdef CSR_DBG if (CsrDebug & 2) { DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x, Process %08x - %08x\n", @@ -792,6 +799,7 @@ CsrApiRequestThread(IN PVOID Parameter) CsrThread->Process, CsrProcess); } +#endif /* Assume success */ ReplyMsg = &ReceiveMsg; diff --git a/reactos/subsystems/win32/csrsrv/api.h b/reactos/subsystems/win32/csrsrv/api.h index 6bf294475ff..5171b09860e 100644 --- a/reactos/subsystems/win32/csrsrv/api.h +++ b/reactos/subsystems/win32/csrsrv/api.h @@ -41,6 +41,9 @@ extern RTL_CRITICAL_SECTION CsrProcessLock, CsrWaitListsLock; #define CSR_SERVER_DLL_MAX 4 +// Debug Flag +extern ULONG CsrDebug; + extern HANDLE hBootstrapOk; extern HANDLE CsrApiPort; extern HANDLE CsrSmApiPort; @@ -49,7 +52,6 @@ extern HANDLE CsrSbApiPort; extern LIST_ENTRY CsrThreadHashTable[NUMBER_THREAD_HASH_BUCKETS]; extern PCSR_PROCESS CsrRootProcess; extern UNICODE_STRING CsrDirectoryName; -extern ULONG CsrDebug; extern ULONG CsrTotalPerProcessDataLength; extern SYSTEM_BASIC_INFORMATION CsrNtSysInfo; extern HANDLE CsrHeap; diff --git a/reactos/subsystems/win32/csrsrv/init.c b/reactos/subsystems/win32/csrsrv/init.c index 4b08d5feeb4..fb8b393ab17 100644 --- a/reactos/subsystems/win32/csrsrv/init.c +++ b/reactos/subsystems/win32/csrsrv/init.c @@ -16,6 +16,9 @@ /* DATA ***********************************************************************/ +// Debug Flag +ULONG CsrDebug = 0; // 0xFFFFFFFF; + HANDLE CsrHeap = NULL; HANDLE CsrObjectDirectory = NULL; UNICODE_STRING CsrDirectoryName; @@ -25,7 +28,6 @@ PCSR_THREAD CsrSbApiRequestThreadPtr; HANDLE CsrSmApiPort = NULL; HANDLE hSbApiPort = NULL; HANDLE CsrApiPort = NULL; -ULONG CsrDebug = 0; // 0xFFFFFFFF; ULONG CsrMaxApiRequestThreads; ULONG CsrTotalPerProcessDataLength; ULONG SessionId; diff --git a/reactos/subsystems/win32/csrsrv/server.c b/reactos/subsystems/win32/csrsrv/server.c index 213165a6f72..5efeb0d7c96 100644 --- a/reactos/subsystems/win32/csrsrv/server.c +++ b/reactos/subsystems/win32/csrsrv/server.c @@ -15,6 +15,13 @@ /* DATA ***********************************************************************/ +PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]; +PVOID CsrSrvSharedSectionHeap = NULL; +PVOID CsrSrvSharedSectionBase = NULL; +PVOID *CsrSrvSharedStaticServerData = NULL; +ULONG CsrSrvSharedSectionSize = 0; +HANDLE CsrSrvSharedSection = NULL; + PCSR_API_ROUTINE CsrServerApiDispatchTable[CsrpMaxApiNumber] = { CsrSrvClientConnect, @@ -33,6 +40,11 @@ BOOLEAN CsrServerApiServerValidTable[CsrpMaxApiNumber] = TRUE }; +/* + * On Windows Server 2003, CSR Servers contain + * the API Names Table only in Debug Builds. + */ +#ifdef CSR_DBG PCHAR CsrServerApiNameTable[CsrpMaxApiNumber] = { "ClientConnect", @@ -41,13 +53,7 @@ PCHAR CsrServerApiNameTable[CsrpMaxApiNumber] = "IdentifyAlertableThread", "SetPriorityClass" }; - -PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]; -PVOID CsrSrvSharedSectionHeap = NULL; -PVOID CsrSrvSharedSectionBase = NULL; -PVOID *CsrSrvSharedStaticServerData = NULL; -ULONG CsrSrvSharedSectionSize = 0; -HANDLE CsrSrvSharedSection = NULL; +#endif /* PRIVATE FUNCTIONS **********************************************************/ @@ -73,7 +79,9 @@ CSR_SERVER_DLL_INIT(CsrServerDllInitialization) LoadedServerDll->HighestApiSupported = CsrpMaxApiNumber; LoadedServerDll->DispatchTable = CsrServerApiDispatchTable; LoadedServerDll->ValidTable = CsrServerApiServerValidTable; +#ifdef CSR_DBG LoadedServerDll->NameTable = CsrServerApiNameTable; +#endif LoadedServerDll->SizeOfProcessData = 0; LoadedServerDll->ConnectCallback = NULL; LoadedServerDll->DisconnectCallback = NULL; diff --git a/reactos/win32ss/user/winsrv/consrv/init.c b/reactos/win32ss/user/winsrv/consrv/init.c index 10522953f39..a8365f53d18 100644 --- a/reactos/win32ss/user/winsrv/consrv/init.c +++ b/reactos/win32ss/user/winsrv/consrv/init.c @@ -218,6 +218,11 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber - CONSRV_FIRST_API // FALSE, // SrvConsoleClientConnect, }; +/* + * On Windows Server 2003, CSR Servers contain + * the API Names Table only in Debug Builds. + */ +#ifdef CSR_DBG PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER] = { "OpenConsole", @@ -313,7 +318,7 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER] // "SetScreenBufferInfo", // "ConsoleClientConnect", }; - +#endif /* FUNCTIONS ******************************************************************/ @@ -532,7 +537,9 @@ CSR_SERVER_DLL_INIT(ConServerDllInitialization) LoadedServerDll->HighestApiSupported = ConsolepMaxApiNumber; LoadedServerDll->DispatchTable = ConsoleServerApiDispatchTable; LoadedServerDll->ValidTable = ConsoleServerApiServerValidTable; +#ifdef CSR_DBG LoadedServerDll->NameTable = ConsoleServerApiNameTable; +#endif LoadedServerDll->SizeOfProcessData = sizeof(CONSOLE_PROCESS_DATA); LoadedServerDll->ConnectCallback = ConSrvConnect; LoadedServerDll->DisconnectCallback = ConSrvDisconnect; diff --git a/reactos/win32ss/user/winsrv/usersrv/init.c b/reactos/win32ss/user/winsrv/usersrv/init.c index 7749d7424ec..acffbc43a9c 100644 --- a/reactos/win32ss/user/winsrv/usersrv/init.c +++ b/reactos/win32ss/user/winsrv/usersrv/init.c @@ -57,6 +57,11 @@ BOOLEAN UserServerApiServerValidTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMB // FALSE, // SrvGetSetShutdownBlockReason }; +/* + * On Windows Server 2003, CSR Servers contain + * the API Names Table only in Debug Builds. + */ +#ifdef CSR_DBG PCHAR UserServerApiNameTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] = { "SrvExitWindowsEx", @@ -73,7 +78,7 @@ PCHAR UserServerApiNameTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] = // "SrvConsoleHandleOperation", // "SrvGetSetShutdownBlockReason", }; - +#endif /* FUNCTIONS ******************************************************************/ @@ -291,7 +296,9 @@ CSR_SERVER_DLL_INIT(UserServerDllInitialization) LoadedServerDll->HighestApiSupported = UserpMaxApiNumber; LoadedServerDll->DispatchTable = UserServerApiDispatchTable; LoadedServerDll->ValidTable = UserServerApiServerValidTable; +#ifdef CSR_DBG LoadedServerDll->NameTable = UserServerApiNameTable; +#endif LoadedServerDll->SizeOfProcessData = 0; LoadedServerDll->ConnectCallback = NULL; LoadedServerDll->DisconnectCallback = NULL; -- 2.17.1