[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
This commit is contained in:
Hermès Bélusca-Maïto 2014-12-17 22:22:05 +00:00
parent 6268701e22
commit 672f036f93
9 changed files with 144 additions and 84 deletions

View file

@ -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
{

View file

@ -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;

View file

@ -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;
}

View file

@ -14,13 +14,14 @@
/* C Headers */
#include <stdio.h>
/* 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 <windef.h>
#include <winbase.h>
#include <wingdi.h>
@ -30,28 +31,30 @@
#include <ddeml.h>
#include <dde.h>
#include <windowsx.h>
/* Undocumented user definitions*/
#include <undocuser.h>
#define NTOS_MODE_USER
#include <ndk/kefuncs.h>
#include <ndk/obfuncs.h>
#include <ndk/rtlfuncs.h>
/* CSRSS Header */
#include <csr/csr.h>
#include <win/winmsg.h>
/* PSEH for SEH Support */
#include <pseh/pseh2.h>
/* Public Win32K Headers */
#include <ntusrtyp.h>
#include <ntuser.h>
#include <callback.h>
/* Undocumented user definitions*/
#include <undocuser.h>
/* CSRSS Header */
#include <csr/csr.h>
#include <win/winmsg.h>
/* WINE Headers */
#include <wine/unicode.h>
/* SEH Support with PSEH */
#include <pseh/pseh2.h>
/* Internal User32 Headers */
#include "user32p.h"

View file

@ -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];

View file

@ -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,

View file

@ -211,8 +211,6 @@ CallNextHookEx(
PHOOK pHook, phkNext;
LRESULT lResult = 0;
//GetConnected();
ClientInfo = GetWin32ClientInfo();
if (!ClientInfo->phkCurrent) return 0;

View file

@ -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)

View file

@ -32,12 +32,12 @@
#include <ndk/psfuncs.h>
#include <ndk/rtlfuncs.h>
/* Public Win32K Headers */
#include <ntuser.h>
/* PSEH for SEH Support */
#include <pseh/pseh2.h>
/* Public Win32K Headers */
#include <ntuser.h>
/* CSRSS Header */
#include <csr/csrsrv.h>