From 672f036f93e7e28c34ebc75a01888e47a1f99d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Wed, 17 Dec 2014 22:22:05 +0000 Subject: [PATCH] [HEADERS] - Play around and declare USERSRV_API_CONNECTINFO (CSR-style-name connect info structure type) as an alias to USERCONNECT (win32k-style-name) structure that is used to perform... "connections" between user32 and winsrv/win32k subsystem. [WIN32K] - Make UserThreadCsrApiPort case of NtUserSetInformationThread return success to make usersrv happy (while saving CSR port handle in win32k is still not implemented). [USER32] - Clean up "a bit" DllMain, call CsrClientConnectToServer to connect to usersrv (copy-paste of what we do in kernel32 for base and console connection) and now determine properly whether we are doing server-to-server calls (i.e. properly set gfServerProcess). - Reorganize GdiDllInitialize calls and put them all to the end of DllMain instead. - No need to support DLL_THREAD_ATTACH/DETACH so call the magic DisableThreadLibraryCalls function. [USERSRV] - Implement UserClientConnect with the patch of Timo CORE-7505: it gives a CSR port handle to win32k (if not already done), then do process connection. CORE-7505 svn path=/trunk/; revision=65710 --- reactos/include/reactos/subsys/win/winmsg.h | 9 ++ reactos/win32ss/include/ntuser.h | 6 + reactos/win32ss/user/ntuser/ntstubs.c | 5 +- reactos/win32ss/user/user32/include/user32.h | 23 ++-- reactos/win32ss/user/user32/misc/desktop.c | 1 - reactos/win32ss/user/user32/misc/dllmain.c | 136 +++++++++++-------- reactos/win32ss/user/user32/windows/hook.c | 2 - reactos/win32ss/user/winsrv/usersrv/init.c | 40 +++++- reactos/win32ss/user/winsrv/winsrv.h | 6 +- 9 files changed, 144 insertions(+), 84 deletions(-) diff --git a/reactos/include/reactos/subsys/win/winmsg.h b/reactos/include/reactos/subsys/win/winmsg.h index a2d28b79a33..eaa8fd3c3dc 100644 --- a/reactos/include/reactos/subsys/win/winmsg.h +++ b/reactos/include/reactos/subsys/win/winmsg.h @@ -35,6 +35,15 @@ typedef enum _USERSRV_API_NUMBER UserpMaxApiNumber } USERSRV_API_NUMBER, *PUSERSRV_API_NUMBER; +/* The USERCONNECT structure is defined in win32ss/include/ntuser.h */ +#define _USERSRV_API_CONNECTINFO _USERCONNECT +#define USERSRV_API_CONNECTINFO USERCONNECT +#define PUSERSRV_API_CONNECTINFO PUSERCONNECT + +#if defined(_M_IX86) +C_ASSERT(sizeof(USERSRV_API_CONNECTINFO) == 0x124); +#endif + typedef struct _USER_EXIT_REACTOS { diff --git a/reactos/win32ss/include/ntuser.h b/reactos/win32ss/include/ntuser.h index 2bf8b10d203..1016c102ded 100644 --- a/reactos/win32ss/include/ntuser.h +++ b/reactos/win32ss/include/ntuser.h @@ -1022,6 +1022,7 @@ typedef struct _SHAREDINFO WNDMSG DefWindowSpecMsgs; } SHAREDINFO, *PSHAREDINFO; +/* See also the USERSRV_API_CONNECTINFO #define in include/reactos/subsys/win/winmsg.h */ typedef struct _USERCONNECT { ULONG ulVersion; @@ -1033,6 +1034,11 @@ typedef struct _USERCONNECT // WinNT 5.0 compatible user32 / win32k #define USER_VERSION MAKELONG(0x0000, 0x0005) +#if defined(_M_IX86) +C_ASSERT(sizeof(USERCONNECT) == 0x124); +#endif + + typedef struct tagGETCLIPBDATA { UINT uFmtRet; diff --git a/reactos/win32ss/user/ntuser/ntstubs.c b/reactos/win32ss/user/ntuser/ntstubs.c index 67eafb4adb0..b3da24eb6fb 100644 --- a/reactos/win32ss/user/ntuser/ntstubs.c +++ b/reactos/win32ss/user/ntuser/ntstubs.c @@ -513,7 +513,7 @@ NtUserConsoleControl( NTSTATUS Status = STATUS_SUCCESS; /* Allow only Console Server to perform this operation (via CSRSS) */ - if (gpepCSRSS != PsGetCurrentProcess()) + if (PsGetCurrentProcess() != gpepCSRSS) return STATUS_ACCESS_DENIED; UserEnterExclusive(); @@ -931,7 +931,8 @@ NtUserSetInformationThread(IN HANDLE ThreadHandle, { ERR("Set CSR API Port for Win32k\n"); STUB; - Status = STATUS_NOT_IMPLEMENTED; + // Return success to make usersrv happy. + Status = STATUS_SUCCESS; break; } diff --git a/reactos/win32ss/user/user32/include/user32.h b/reactos/win32ss/user/user32/include/user32.h index 3a7cdbd2283..6a4dc33c595 100644 --- a/reactos/win32ss/user/user32/include/user32.h +++ b/reactos/win32ss/user/user32/include/user32.h @@ -14,13 +14,14 @@ /* C Headers */ #include -/* SDK/NDK Headers */ +/* PSDK/NDK Headers */ + #define _USER32_ #define OEMRESOURCE -#define NTOS_MODE_USER #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H + #include #include #include @@ -30,28 +31,30 @@ #include #include #include + +/* Undocumented user definitions*/ +#include + +#define NTOS_MODE_USER #include #include #include -/* CSRSS Header */ -#include -#include +/* PSEH for SEH Support */ +#include /* Public Win32K Headers */ #include #include #include -/* Undocumented user definitions*/ -#include +/* CSRSS Header */ +#include +#include /* WINE Headers */ #include -/* SEH Support with PSEH */ -#include - /* Internal User32 Headers */ #include "user32p.h" diff --git a/reactos/win32ss/user/user32/misc/desktop.c b/reactos/win32ss/user/user32/misc/desktop.c index b86f3d0c502..00375993440 100644 --- a/reactos/win32ss/user/user32/misc/desktop.c +++ b/reactos/win32ss/user/user32/misc/desktop.c @@ -128,7 +128,6 @@ LogFontW2A(LPLOGFONTA pA, CONST LOGFONTW *pW) int WINAPI RealGetSystemMetrics(int nIndex) { - //GetConnected(); //FIXME("Global Server Data -> %x\n",gpsi); if (nIndex < 0 || nIndex >= SM_CMETRICS) return 0; return gpsi->aiSysMet[nIndex]; diff --git a/reactos/win32ss/user/user32/misc/dllmain.c b/reactos/win32ss/user/user32/misc/dllmain.c index 416534bb81e..5ffcc230944 100644 --- a/reactos/win32ss/user/user32/misc/dllmain.c +++ b/reactos/win32ss/user/user32/misc/dllmain.c @@ -186,17 +186,6 @@ UnloadAppInitDlls() } } -BOOL -InitThread(VOID) -{ - return TRUE; -} - -VOID -CleanupThread(VOID) -{ -} - PVOID apfnDispatch[USER32_CALLBACK_MAXIMUM + 1] = { User32CallWindowProcFromKernel, @@ -250,7 +239,8 @@ ClientThreadSetup(VOID) // CsrConnectToUser, we'll pretend we "did something" here. Then the rest will // continue as normal. // - //UNIMPLEMENTED; + + UNIMPLEMENTED; return TRUE; } @@ -274,9 +264,7 @@ Init(VOID) gHandleEntries = SharedPtrToUser(gHandleTable->handles); RtlInitializeCriticalSection(&gcsUserApiHook); - gfServerProcess = FALSE; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess); - //CsrClientConnectToServer(L"\\Windows", 0, NULL, 0, &gfServerProcess); //ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta); /* Allocate an index for user32 thread local data. */ @@ -288,9 +276,7 @@ Init(VOID) if (MenuInit()) { InitializeCriticalSection(&U32AccelCacheLock); - GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); LoadAppInitDlls(); - return TRUE; } MessageCleanup(); @@ -304,13 +290,12 @@ Init(VOID) VOID Cleanup(VOID) { - DeleteCriticalSection(&U32AccelCacheLock); - MenuCleanup(); - MessageCleanup(); - DeleteFrameBrushes(); - UnloadAppInitDlls(); - GdiDllInitialize(NULL, DLL_PROCESS_DETACH, NULL); - TlsFree(User32TlsIndex); + DeleteCriticalSection(&U32AccelCacheLock); + MenuCleanup(); + MessageCleanup(); + DeleteFrameBrushes(); + UnloadAppInitDlls(); + TlsFree(User32TlsIndex); } INT WINAPI @@ -319,57 +304,90 @@ DllMain( IN ULONG dwReason, IN PVOID reserved) { - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - User32Instance = hInstanceDll; - if (!RegisterClientPFN()) - { - return FALSE; - } + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + { + +#define WIN_OBJ_DIR L"\\Windows" +#define SESSION_DIR L"\\Sessions" + + NTSTATUS Status; + USERSRV_API_CONNECTINFO ConnectInfo; // USERCONNECT + ULONG ConnectInfoSize = sizeof(ConnectInfo); + WCHAR SessionDir[256]; + + /* Cache the PEB and Session ID */ + PPEB Peb = NtCurrentPeb(); + ULONG SessionId = Peb->SessionId; // gSessionId + + /* Don't bother us for each thread */ + DisableThreadLibraryCalls(hInstanceDll); + + /* Setup the Object Directory path */ + if (!SessionId) + { + /* Use the raw path */ + wcscpy(SessionDir, WIN_OBJ_DIR); + } + else + { + /* Use the session path */ + swprintf(SessionDir, + L"%ws\\%ld%ws", + SESSION_DIR, + SessionId, + WIN_OBJ_DIR); + } + + /* Connect to the USER Server */ + Status = CsrClientConnectToServer(SessionDir, + USERSRV_SERVERDLL_INDEX, + &ConnectInfo, + &ConnectInfoSize, + &gfServerProcess); + if (!NT_SUCCESS(Status)) + { + ERR("Failed to connect to CSR (Status %lx)\n", Status); + return FALSE; + } + + User32Instance = hInstanceDll; + + if (!RegisterClientPFN()) + return FALSE; + + if (!Init()) + return FALSE; + + break; + } + + case DLL_PROCESS_DETACH: + { + if (hImmInstance) + FreeLibrary(hImmInstance); - if (!Init()) - return FALSE; - if (!InitThread()) - { Cleanup(); - return FALSE; - } - break; + break; + } + } - case DLL_THREAD_ATTACH: - if (!InitThread()) - return FALSE; - break; - - case DLL_THREAD_DETACH: - CleanupThread(); - break; - - case DLL_PROCESS_DETACH: - if (hImmInstance) FreeLibrary(hImmInstance); - CleanupThread(); - Cleanup(); - break; - } - - return TRUE; + /* Finally init GDI */ + return GdiDllInitialize(hInstanceDll, dwReason, reserved); } - +// FIXME: This function seems to be unused... VOID FASTCALL GetConnected(VOID) { USERCONNECT UserCon; -// ERR("GetConnected\n"); if ((PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo == NULL) NtUserGetThreadState(THREADSTATE_GETTHREADINFO); if (gpsi && g_ppi) return; -// FIXME HAX: Due to the "Dll Initialization Bug" we have to call this too. - GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); NtUserProcessConnect( NtCurrentProcess(), &UserCon, diff --git a/reactos/win32ss/user/user32/windows/hook.c b/reactos/win32ss/user/user32/windows/hook.c index b44eff708fe..3816128da2a 100644 --- a/reactos/win32ss/user/user32/windows/hook.c +++ b/reactos/win32ss/user/user32/windows/hook.c @@ -211,8 +211,6 @@ CallNextHookEx( PHOOK pHook, phkNext; LRESULT lResult = 0; - //GetConnected(); - ClientInfo = GetWin32ClientInfo(); if (!ClientInfo->phkCurrent) return 0; diff --git a/reactos/win32ss/user/winsrv/usersrv/init.c b/reactos/win32ss/user/winsrv/usersrv/init.c index c6a7f8d0fc9..fc199b9bea6 100644 --- a/reactos/win32ss/user/winsrv/usersrv/init.c +++ b/reactos/win32ss/user/winsrv/usersrv/init.c @@ -24,6 +24,9 @@ HINSTANCE UserServerDllInstance = NULL; HANDLE ghPowerRequestEvent; HANDLE ghMediaRequestEvent; +/* Copy of CSR Port handle for win32k */ +HANDLE CsrApiPort = NULL; + /* Memory */ HANDLE UserServerHeap = NULL; // Our own heap. @@ -140,17 +143,35 @@ UserClientConnect(IN PCSR_PROCESS CsrProcess, IN OUT PVOID ConnectionInfo, IN OUT PULONG ConnectionInfoLength) { + NTSTATUS Status; + // PUSERCONNECT + PUSERSRV_API_CONNECTINFO ConnectInfo = (PUSERSRV_API_CONNECTINFO)ConnectionInfo; + DPRINT1("UserClientConnect\n"); -#if 0 - // NTSTATUS Status = STATUS_SUCCESS; - PBASESRV_API_CONNECTINFO ConnectInfo = (PBASESRV_API_CONNECTINFO)ConnectionInfo; + /* Check if we don't have an API port yet */ + if (CsrApiPort == NULL) + { + /* Query the API port and save it globally */ + CsrApiPort = CsrQueryApiPort(); + /* Inform win32k about the API port */ + Status = NtUserSetInformationThread(NtCurrentThread(), + UserThreadCsrApiPort, + &CsrApiPort, + sizeof(CsrApiPort)); + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + + /* Check connection info validity */ if ( ConnectionInfo == NULL || ConnectionInfoLength == NULL || *ConnectionInfoLength != sizeof(*ConnectInfo) ) { - DPRINT1("BASESRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n", + DPRINT1("USERSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n", ConnectionInfo, ConnectionInfoLength, ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1, @@ -158,9 +179,14 @@ UserClientConnect(IN PCSR_PROCESS CsrProcess, return STATUS_INVALID_PARAMETER; } -#else - return STATUS_SUCCESS; -#endif + + /* Pass the request to win32k */ + ConnectInfo->dwDispatchCount = 0; // gDispatchTableValues; + Status = NtUserProcessConnect(CsrProcess->ProcessHandle, + ConnectInfo, + *ConnectionInfoLength); + + return Status; } CSR_SERVER_DLL_INIT(UserServerDllInitialization) diff --git a/reactos/win32ss/user/winsrv/winsrv.h b/reactos/win32ss/user/winsrv/winsrv.h index 6aa95e3e6ed..48666c3b371 100644 --- a/reactos/win32ss/user/winsrv/winsrv.h +++ b/reactos/win32ss/user/winsrv/winsrv.h @@ -32,12 +32,12 @@ #include #include -/* Public Win32K Headers */ -#include - /* PSEH for SEH Support */ #include +/* Public Win32K Headers */ +#include + /* CSRSS Header */ #include