ReactOS  0.4.14-dev-608-gd495a4f
csr.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Win32k subsystem
4  * PURPOSE: Interface between Win32k and USERSRV
5  * FILE: win32ss/user/ntuser/csr.c
6  * PROGRAMMER: Hermes Belusca-Maito (hermes.belusca@sfr.fr), based on
7  * the original code by Ge van Geldorp (ge@gse.nl) and by
8  * the CSR code in NTDLL.
9  */
10 
11 #include <win32k.h>
12 
13 DBG_DEFAULT_CHANNEL(UserCsr);
14 
18 
19 VOID
20 InitCsrProcess(VOID /*IN PEPROCESS CsrProcess*/)
21 {
22  /* Save the EPROCESS of CSRSS */
24  // gpepCSRSS = CsrProcess;
26 }
27 
28 VOID
30 {
31  if (gpepCSRSS)
33 
34  gpepCSRSS = NULL;
35 }
36 
38 InitCsrApiPort(IN HANDLE CsrPortHandle)
39 {
41 
42  Status = ObReferenceObjectByHandle(CsrPortHandle,
43  0,
44  /* * */LpcPortObjectType, // or NULL,
45  UserMode,
46  &CsrApiPort,
47  NULL);
48  if (!NT_SUCCESS(Status))
49  {
50  CsrApiPort = NULL;
51  ERR("Failed to set CSR API Port.\n");
52  }
53 
54  return Status;
55 }
56 
57 VOID
59 {
60  if (CsrApiPort)
62 
63  CsrApiPort = NULL;
64 }
65 
66 /*
67  * Function copied from ntdll/csr/connect.c::CsrClientCallServer
68  * and adapted for kernel-mode.
69  *
70  * NOTE: This is really a co_* function!
71  */
73 NTAPI
75  IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL,
76  IN CSR_API_NUMBER ApiNumber,
78 {
80 #if 0
81  ULONG PointerCount;
82  PULONG_PTR OffsetPointer;
83 #endif
84 
85  /* Do we have a connection to CSR yet? */
86  if (!CsrApiPort)
88 
89  /* Fill out the Port Message Header */
90  ApiMessage->Header.u2.ZeroInit = 0;
91  ApiMessage->Header.u1.s1.TotalLength = FIELD_OFFSET(CSR_API_MESSAGE, Data) + DataLength;
92  ApiMessage->Header.u1.s1.DataLength = ApiMessage->Header.u1.s1.TotalLength -
93  sizeof(ApiMessage->Header);
94 
95  /* Fill out the CSR Header */
96  ApiMessage->ApiNumber = ApiNumber;
97  ApiMessage->CsrCaptureData = NULL;
98 
99  TRACE("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n",
100  ApiNumber,
101  ApiMessage->Header.u1.s1.DataLength,
102  ApiMessage->Header.u1.s1.TotalLength);
103 
104 #if 0
105  /* Check if we got a Capture Buffer */
106  if (CaptureBuffer)
107  {
108  /*
109  * We have to convert from our local (client) view
110  * to the remote (server) view.
111  */
112  ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
113  ((ULONG_PTR)CaptureBuffer + CsrPortMemoryDelta);
114 
115  /* Lock the buffer. */
116  CaptureBuffer->BufferEnd = NULL;
117 
118  /*
119  * Each client pointer inside the CSR message is converted into
120  * a server pointer, and each pointer to these message pointers
121  * is converted into an offset.
122  */
123  PointerCount = CaptureBuffer->PointerCount;
124  OffsetPointer = CaptureBuffer->PointerOffsetsArray;
125  while (PointerCount--)
126  {
127  if (*OffsetPointer != 0)
128  {
129  *(PULONG_PTR)*OffsetPointer += CsrPortMemoryDelta;
130  *OffsetPointer -= (ULONG_PTR)ApiMessage;
131  }
132  ++OffsetPointer;
133  }
134  }
135 #endif
136 
137  UserLeaveCo();
138 
139  /* Send the LPC Message */
140 
141  // The wait logic below is subject to change in the future. One can
142  // imagine adding an external parameter to CsrClientCallServer, or write
143  // two versions of CsrClientCallServer, synchronous and asynchronous.
145  {
147  &ApiMessage->Header);
148  }
149  else
150  {
152  &ApiMessage->Header,
153  &ApiMessage->Header);
154  }
155 
156  UserEnterCo();
157 
158 #if 0
159  /* Check if we got a Capture Buffer */
160  if (CaptureBuffer)
161  {
162  /*
163  * We have to convert back from the remote (server) view
164  * to our local (client) view.
165  */
166  ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
167  ((ULONG_PTR)ApiMessage->CsrCaptureData - CsrPortMemoryDelta);
168 
169  /*
170  * Convert back the offsets into pointers to CSR message
171  * pointers, and convert back these message server pointers
172  * into client pointers.
173  */
174  PointerCount = CaptureBuffer->PointerCount;
175  OffsetPointer = CaptureBuffer->PointerOffsetsArray;
176  while (PointerCount--)
177  {
178  if (*OffsetPointer != 0)
179  {
180  *OffsetPointer += (ULONG_PTR)ApiMessage;
181  *(PULONG_PTR)*OffsetPointer -= CsrPortMemoryDelta;
182  }
183  ++OffsetPointer;
184  }
185  }
186 #endif
187 
188  /* Check for success */
189  if (!NT_SUCCESS(Status))
190  {
191  /* We failed. Overwrite the return value with the failure. */
192  ERR("LPC Failed: %lx\n", Status);
193  ApiMessage->Status = Status;
194  }
195 
196  /* Return the CSR Result */
197  TRACE("Got back: 0x%lx\n", ApiMessage->Status);
198  return ApiMessage->Status;
199 }
200 
201 /*
202  * UserSystemThreadProc
203  *
204  * Called form dedicated thread in CSRSS. RIT is started in context of this
205  * thread because it needs valid Win32 process with TEB initialized.
206  */
208 {
209  DWORD Type;
210 
212  {
213  ERR("gdwPendingSystemThreads is 0!\n");
214  return 0;
215  }
216 
217  /* Decide which thread this will be */
219  Type = ST_RIT;
222  else
224 
225  ASSERT(Type);
226 
227  /* We will handle one of these threads right here so unmark it as pending */
229 
230  UserLeave();
231 
232  TRACE("UserSystemThreadProc: %d\n", Type);
233 
234  switch (Type)
235  {
236  case ST_RIT: RawInputThreadMain(); break;
237  case ST_DESKTOP_THREAD: DesktopThreadMain(); break;
238  case ST_GHOST_THREAD: UserGhostThreadEntry(); break;
239  default: ERR("Wrong type: %x\n", Type);
240  }
241 
242  UserEnterShared();
243 
244  return 0;
245 }
246 
248 {
249  USER_API_MESSAGE ApiMessage;
250  PUSER_CREATE_SYSTEM_THREAD pCreateThreadRequest = &ApiMessage.Data.CreateSystemThreadRequest;
251 
252  TRACE("UserCreateSystemThread: %d\n", Type);
253 
255 
257  {
258  ERR("System thread 0x%x already pending for creation\n", Type);
259  return TRUE;
260  }
261 
262  /* We can't pass a parameter to the new thread so mark what the new thread needs to do */
264 
265  /* Ask winsrv to create a new system thread. This new thread will enter win32k again calling UserSystemThreadProc */
266  pCreateThreadRequest->bRemote = FALSE;
268  NULL,
270  sizeof(USER_CREATE_SYSTEM_THREAD));
271  if (!NT_SUCCESS(ApiMessage.Status))
272  {
273  ERR("Csr call failed!\n");
274  return FALSE;
275  }
276 
277  return TRUE;
278 }
279 
280 /* EOF */
ULONG CSR_API_NUMBER
Definition: csrmsg.h:35
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
#define IN
Definition: typedefs.h:38
DWORD gdwPendingSystemThreads
Definition: csr.c:17
#define TRUE
Definition: types.h:120
BOOL UserCreateSystemThread(DWORD Type)
Definition: csr.c:247
Type
Definition: Type.h:6
VOID NTAPI RawInputThreadMain(VOID)
Definition: input.c:124
VOID ResetCsrProcess(VOID)
Definition: csr.c:29
#define USERSRV_SERVERDLL_INDEX
Definition: winmsg.h:15
PEPROCESS gpepCSRSS
Definition: csr.c:15
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS NTAPI LpcRequestWaitReplyPort(IN PVOID PortObject, IN PPORT_MESSAGE LpcRequest, OUT PPORT_MESSAGE LpcReply)
Definition: send.c:178
NTSTATUS InitCsrApiPort(IN HANDLE CsrPortHandle)
Definition: csr.c:38
#define STATUS_INVALID_PORT_HANDLE
Definition: ntstatus.h:288
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS Status
Definition: csrmsg.h:112
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PVOID CsrApiPort
Definition: csr.c:16
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD UserSystemThreadProc(BOOL bRemoteProcess)
Definition: csr.c:207
#define UserLeaveCo
Definition: ntuser.h:10
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
struct _CSR_CAPTURE_BUFFER * PCSR_CAPTURE_BUFFER
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
NTSTATUS NTAPI LpcRequestPort(IN PVOID PortObject, IN PPORT_MESSAGE LpcMessage)
Definition: send.c:22
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ST_GHOST_THREAD
Definition: csr.h:37
unsigned long DWORD
Definition: ntddk_ex.h:95
#define UserEnterCo
Definition: ntuser.h:9
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG_PTR CsrPortMemoryDelta
Definition: connect.c:24
VOID NTAPI DesktopThreadMain(VOID)
Definition: desktop.c:1508
union _USER_API_MESSAGE::@3414 Data
NTSTATUS NTAPI CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength)
Definition: csr.c:74
VOID ResetCsrApiPort(VOID)
Definition: csr.c:58
#define ST_RIT
Definition: csr.h:35
Status
Definition: gdiplustypes.h:24
VOID InitCsrProcess(VOID)
Definition: csr.c:20
#define ERR(fmt,...)
Definition: debug.h:109
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
BOOL FASTCALL UserIsEnteredExclusive(VOID)
Definition: ntuser.c:231
USER_CREATE_SYSTEM_THREAD CreateSystemThreadRequest
Definition: winmsg.h:106
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
VOID NTAPI UserGhostThreadEntry(VOID)
Definition: ghost.c:27
#define ST_DESKTOP_THREAD
Definition: csr.h:36
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
DBG_DEFAULT_CHANNEL(UserCsr)
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68