ReactOS  0.4.13-dev-259-g5ca9c9c
api.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Client/Server Runtime SubSystem
4  * FILE: subsystems/win32/csrsrv/api.c
5  * PURPOSE: CSR Server DLL API LPC Implementation
6  * "\Windows\ApiPort" port process management functions
7  * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include "srv.h"
13 
14 #include <ndk/kefuncs.h>
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 /* GLOBALS ********************************************************************/
20 
26 
27 /* FUNCTIONS ******************************************************************/
28 
29 /*++
30  * @name CsrCallServerFromServer
31  * @implemented NT4
32  *
33  * The CsrCallServerFromServer routine calls a CSR API from within a server.
34  * It avoids using LPC messages since the request isn't coming from a client.
35  *
36  * @param ReceiveMsg
37  * Pointer to the CSR API Message to send to the server.
38  *
39  * @param ReplyMsg
40  * Pointer to the CSR API Message to receive from the server.
41  *
42  * @return STATUS_SUCCESS in case of success, STATUS_ILLEGAL_FUNCTION
43  * if the ApiNumber is invalid, or STATUS_ACCESS_VIOLATION if there
44  * was a problem executing the API.
45  *
46  * @remarks None.
47  *
48  *--*/
50 NTAPI
52  IN OUT PCSR_API_MESSAGE ReplyMsg)
53 {
54  ULONG ServerId;
55  PCSR_SERVER_DLL ServerDll;
56  ULONG ApiId;
58 
59  /* Get the Server ID */
60  ServerId = CSR_API_NUMBER_TO_SERVER_ID(ReceiveMsg->ApiNumber);
61 
62  /* Make sure that the ID is within limits, and the Server DLL loaded */
63  if ((ServerId >= CSR_SERVER_DLL_MAX) ||
64  (!(ServerDll = CsrLoadedServerDll[ServerId])))
65  {
66  /* We are beyond the Maximum Server ID */
67  DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", ServerId, ServerDll);
68  ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
70  }
71  else
72  {
73  /* Get the API ID, normalized with our Base ID */
74  ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg->ApiNumber) - ServerDll->ApiBase;
75 
76  /* Make sure that the ID is within limits, and the entry exists */
77  if ((ApiId >= ServerDll->HighestApiSupported) ||
78  ((ServerDll->ValidTable) && !(ServerDll->ValidTable[ApiId])))
79  {
80  /* We are beyond the Maximum API ID, or it doesn't exist */
81  DPRINT1("API: %d\n", ApiId);
82 #ifdef CSR_DBG
83  DPRINT1("CSRSS: %lx (%s) is invalid ApiTableIndex for %Z or is an "
84  "invalid API to call from the server.\n",
85  ApiId,
86  ((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ?
87  ServerDll->NameTable[ApiId] : "*** UNKNOWN ***",
88  &ServerDll->Name);
89 #endif
90  // DbgBreakPoint();
91  ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
93  }
94  }
95 
96 #ifdef CSR_DBG
97  if (CsrDebug & 2)
98  {
99  DPRINT1("CSRSS: %s Api Request received from server process\n",
100  ServerDll->NameTable[ApiId]);
101  }
102 #endif
103 
104  /* Validation complete, start SEH */
105  _SEH2_TRY
106  {
107  /* Call the API, get the reply code and return the result */
108  ReplyMsg->Status = ServerDll->DispatchTable[ApiId](ReceiveMsg, &ReplyCode);
109  }
111  {
112  /* If we got an exception, return access violation */
113  ReplyMsg->Status = STATUS_ACCESS_VIOLATION;
114  }
115  _SEH2_END;
116 
117  /* Return success */
118  return STATUS_SUCCESS;
119 }
120 
121 /*++
122  * @name CsrApiHandleConnectionRequest
123  *
124  * The CsrApiHandleConnectionRequest routine handles and accepts a new
125  * connection request to the CSR API LPC Port.
126  *
127  * @param ApiMessage
128  * Pointer to the incoming CSR API Message which contains the
129  * connection request.
130  *
131  * @return STATUS_SUCCESS in case of success, or status code which caused
132  * the routine to error.
133  *
134  * @remarks This routine is responsible for attaching the Shared Section to
135  * new clients connecting to CSR.
136  *
137  *--*/
138 NTSTATUS
139 NTAPI
141 {
142  PCSR_THREAD CsrThread = NULL;
143  PCSR_PROCESS CsrProcess = NULL;
145  PCSR_API_CONNECTINFO ConnectInfo = &ApiMessage->ConnectionInfo;
146  BOOLEAN AllowConnection = FALSE;
147  REMOTE_PORT_VIEW RemotePortView;
149 
150  /* Acquire the Process Lock */
152 
153  /* Lookup the CSR Thread */
154  CsrThread = CsrLocateThreadByClientId(NULL, &ApiMessage->Header.ClientId);
155 
156  /* Check if we have a thread */
157  if (CsrThread)
158  {
159  /* Get the Process and make sure we have it as well */
160  CsrProcess = CsrThread->Process;
161  if (CsrProcess)
162  {
163  /* Reference the Process */
164  CsrLockedReferenceProcess(CsrProcess);
165 
166  /* Attach the Shared Section */
167  Status = CsrSrvAttachSharedSection(CsrProcess, ConnectInfo);
168  if (NT_SUCCESS(Status))
169  {
170  /* Allow the connection and return debugging flag */
171  ConnectInfo->DebugFlags = CsrDebug;
172  AllowConnection = TRUE;
173  }
174 
175  /* Dereference the Process */
176  CsrLockedDereferenceProcess(CsrProcess);
177  }
178  }
179 
180  /* Release the Process Lock */
182 
183  /* Setup the Port View Structure */
184  RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
185  RemotePortView.ViewSize = 0;
186  RemotePortView.ViewBase = NULL;
187 
188  /* Save the Process ID */
189  ConnectInfo->ServerProcessId = NtCurrentTeb()->ClientId.UniqueProcess;
190 
191  /* Accept the Connection */
193  AllowConnection ? UlongToPtr(CsrProcess->SequenceNumber) : 0,
194  &ApiMessage->Header,
195  AllowConnection,
196  NULL,
197  &RemotePortView);
198  if (!NT_SUCCESS(Status))
199  {
200  DPRINT1("CSRSS: NtAcceptConnectPort - failed. Status == %X\n", Status);
201  }
202  else if (AllowConnection)
203  {
204  if (CsrDebug & 2)
205  {
206  DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n",
207  ApiMessage->Header.ClientId.UniqueProcess,
208  ApiMessage->Header.ClientId.UniqueThread,
209  RemotePortView.ViewBase,
210  RemotePortView.ViewSize);
211  }
212 
213  /* Set some Port Data in the Process */
214  CsrProcess->ClientPort = ServerPort;
215  CsrProcess->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase;
216  CsrProcess->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase +
217  (ULONG_PTR)RemotePortView.ViewSize);
218 
219  /* Complete the connection */
221  if (!NT_SUCCESS(Status))
222  {
223  DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status);
224  }
225  }
226  else
227  {
228  DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
229  ApiMessage->Header.ClientId.UniqueProcess,
230  ApiMessage->Header.ClientId.UniqueThread);
231  }
232 
233  /* Return status to caller */
234  return Status;
235 }
236 
237 /*++
238  * @name CsrpCheckRequestThreads
239  *
240  * The CsrpCheckRequestThreads routine checks if there are no more threads
241  * to handle CSR API Requests, and creates a new thread if possible, to
242  * avoid starvation.
243  *
244  * @param None.
245  *
246  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
247  * if a new thread couldn't be created.
248  *
249  * @remarks None.
250  *
251  *--*/
252 NTSTATUS
253 NTAPI
255 {
256  HANDLE hThread;
259 
260  /* Decrease the count, and see if we're out */
262  {
263  /* Check if we've still got space for a Dynamic Thread */
265  {
266  /* Create a new dynamic thread */
268  NULL,
269  TRUE,
270  0,
271  0,
272  0,
274  NULL,
275  &hThread,
276  &ClientId);
277  /* Check success */
278  if (NT_SUCCESS(Status))
279  {
280  /* Increase the thread counts */
283 
284  /* Add a new server thread */
286  &ClientId,
288  {
289  /* Activate it */
291  }
292  else
293  {
294  /* Failed to create a new static thread */
297 
298  /* Terminate it */
299  DPRINT1("Failing\n");
301  NtClose(hThread);
302 
303  /* Return */
304  return STATUS_UNSUCCESSFUL;
305  }
306  }
307  }
308  }
309 
310  /* Success */
311  return STATUS_SUCCESS;
312 }
313 
314 /*++
315  * @name CsrApiRequestThread
316  *
317  * The CsrApiRequestThread routine handles incoming messages or connection
318  * requests on the CSR API LPC Port.
319  *
320  * @param Parameter
321  * System-default user-defined parameter. Unused.
322  *
323  * @return The thread exit code, if the thread is terminated.
324  *
325  * @remarks Before listening on the port, the routine will first attempt
326  * to connect to the user subsystem.
327  *
328  *--*/
329 NTSTATUS
330 NTAPI
332 {
333  PTEB Teb = NtCurrentTeb();
334  LARGE_INTEGER TimeOut;
335  PCSR_THREAD CurrentThread, CsrThread;
337  CSR_REPLY_CODE ReplyCode;
338  PCSR_API_MESSAGE ReplyMsg;
339  CSR_API_MESSAGE ReceiveMsg;
340  PCSR_PROCESS CsrProcess;
341  PHARDERROR_MSG HardErrorMsg;
342  PVOID PortContext;
343  PCSR_SERVER_DLL ServerDll;
344  PCLIENT_DIED_MSG ClientDiedMsg;
345  PDBGKM_MSG DebugMessage;
346  ULONG ServerId, ApiId, MessageType, i;
347  HANDLE ReplyPort;
348 
349  /* Setup LPC loop port and message */
350  ReplyMsg = NULL;
351  ReplyPort = CsrApiPort;
352 
353  /* Connect to user32 */
354  while (!CsrConnectToUser())
355  {
356  /* Set up the timeout for the connect (30 seconds) */
357  TimeOut.QuadPart = -30 * 1000 * 1000 * 10;
358 
359  /* Keep trying until we get a response */
360  Teb->Win32ClientInfo[0] = 0;
361  NtDelayExecution(FALSE, &TimeOut);
362  }
363 
364  /* Get our thread */
365  CurrentThread = Teb->CsrClientThread;
366 
367  /* If we got an event... */
368  if (Parameter)
369  {
370  /* Set it, to let stuff waiting on us load */
373 
374  /* Increase the Thread Counts */
377  }
378 
379  /* Now start the loop */
380  while (TRUE)
381  {
382  /* Make sure the real CID is set */
383  Teb->RealClientId = Teb->ClientId;
384 
385  /* Debug check */
387  {
388  DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu critical sections\n",
390  DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n",
391  &ReceiveMsg, ReplyMsg);
392  DbgBreakPoint();
393  }
394 
395  /* Wait for a message to come through */
396  Status = NtReplyWaitReceivePort(ReplyPort,
397  &PortContext,
398  &ReplyMsg->Header,
399  &ReceiveMsg.Header);
400 
401  /* Check if we didn't get success */
402  if (Status != STATUS_SUCCESS)
403  {
404  /* Was it a failure or another success code? */
405  if (!NT_SUCCESS(Status))
406  {
407  /* Check for specific status cases */
408  if ((Status != STATUS_INVALID_CID) &&
410  ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
411  {
412  /* Notify the debugger */
413  DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
414  DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort);
415  }
416 
417  /* We failed big time, so start out fresh */
418  ReplyMsg = NULL;
419  ReplyPort = CsrApiPort;
420  continue;
421  }
422  else
423  {
424  /* A strange "success" code, just try again */
425  DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status);
426  continue;
427  }
428  }
429 
430  /* Use whatever Client ID we got */
431  Teb->RealClientId = ReceiveMsg.Header.ClientId;
432 
433  /* Get the Message Type */
434  MessageType = ReceiveMsg.Header.u2.s2.Type;
435 
436  /* Handle connection requests */
437  if (MessageType == LPC_CONNECTION_REQUEST)
438  {
439  /* Handle the Connection Request */
440  CsrApiHandleConnectionRequest(&ReceiveMsg);
441 
442  ReplyMsg = NULL;
443  ReplyPort = CsrApiPort;
444  continue;
445  }
446 
447  /* It's some other kind of request. Get the lock for the lookup */
449 
450  /* Now do the lookup to get the CSR_THREAD */
451  CsrThread = CsrLocateThreadByClientId(&CsrProcess,
452  &ReceiveMsg.Header.ClientId);
453 
454  /* Did we find a thread? */
455  if (!CsrThread)
456  {
457  /* This wasn't a CSR Thread, release lock */
459 
460  /* If this was an exception, handle it */
461  if (MessageType == LPC_EXCEPTION)
462  {
463  ReplyMsg = &ReceiveMsg;
464  ReplyPort = CsrApiPort;
465  ReplyMsg->Status = DBG_CONTINUE;
466  }
467  else if (MessageType == LPC_PORT_CLOSED ||
468  MessageType == LPC_CLIENT_DIED)
469  {
470  /* The Client or Port are gone, loop again */
471  ReplyMsg = NULL;
472  ReplyPort = CsrApiPort;
473  }
474  else if (MessageType == LPC_ERROR_EVENT)
475  {
476  /* If it's a hard error, handle this too */
477  HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg;
478 
479  /* Default it to unhandled */
480  HardErrorMsg->Response = ResponseNotHandled;
481 
482  /* Check if there are free api threads */
485  {
486  /* Loop every Server DLL */
487  for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
488  {
489  /* Get the Server DLL */
490  ServerDll = CsrLoadedServerDll[i];
491 
492  /* Check if it's valid and if it has a Hard Error Callback */
493  if ((ServerDll) && (ServerDll->HardErrorCallback))
494  {
495  /* Call it */
496  ServerDll->HardErrorCallback(NULL /* == CsrThread */, HardErrorMsg);
497 
498  /* If it's handled, get out of here */
499  if (HardErrorMsg->Response != ResponseNotHandled) break;
500  }
501  }
502  }
503 
504  /* Increase the thread count */
506 
507  /* If the response was 0xFFFFFFFF, we'll ignore it */
508  if (HardErrorMsg->Response == 0xFFFFFFFF)
509  {
510  ReplyMsg = NULL;
511  ReplyPort = CsrApiPort;
512  }
513  else
514  {
515  ReplyMsg = &ReceiveMsg;
516  ReplyPort = CsrApiPort;
517  }
518  }
519  else if (MessageType == LPC_REQUEST)
520  {
521  /* This is an API Message coming from a non-CSR Thread */
522  ReplyMsg = &ReceiveMsg;
523  ReplyPort = CsrApiPort;
524  ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
525  }
526  else if (MessageType == LPC_DATAGRAM)
527  {
528  /* This is an API call, get the Server ID */
529  ServerId = CSR_API_NUMBER_TO_SERVER_ID(ReceiveMsg.ApiNumber);
530 
531  /* Make sure that the ID is within limits, and the Server DLL loaded */
532  ServerDll = NULL;
533  if ((ServerId >= CSR_SERVER_DLL_MAX) ||
534  (!(ServerDll = CsrLoadedServerDll[ServerId])))
535  {
536  /* We are beyond the Maximum Server ID */
537  DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
538  ServerId, ServerDll);
539  // DbgBreakPoint();
540 
541  ReplyMsg = NULL;
542  ReplyPort = CsrApiPort;
543  continue;
544  }
545 
546  /* Get the API ID, normalized with our Base ID */
547  ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase;
548 
549  /* Make sure that the ID is within limits, and the entry exists */
550  if (ApiId >= ServerDll->HighestApiSupported)
551  {
552  /* We are beyond the Maximum API ID, or it doesn't exist */
553  DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
555  &ServerDll->Name);
556 
557  ReplyPort = CsrApiPort;
558  ReplyMsg = NULL;
559  continue;
560  }
561 
562 #ifdef CSR_DBG
563  if (CsrDebug & 2)
564  {
565  DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n",
566  Teb->ClientId.UniqueThread,
567  ReceiveMsg.Header.ClientId.UniqueProcess,
568  ReceiveMsg.Header.ClientId.UniqueThread,
569  ServerDll->NameTable[ApiId],
570  NULL);
571  }
572 #endif
573 
574  /* Assume success */
575  ReceiveMsg.Status = STATUS_SUCCESS;
576 
577  /* Validation complete, start SEH */
578  _SEH2_TRY
579  {
580  /* Make sure we have enough threads */
582 
583  /* Call the API and get the reply code */
584  ReplyMsg = NULL;
585  ReplyPort = CsrApiPort;
586  ServerDll->DispatchTable[ApiId](&ReceiveMsg, &ReplyCode);
587 
588  /* Increase the static thread count */
590  }
592  {
593  ReplyMsg = NULL;
594  ReplyPort = CsrApiPort;
595  }
596  _SEH2_END;
597  }
598  else
599  {
600  /* Some other ignored message type */
601  ReplyMsg = NULL;
602  ReplyPort = CsrApiPort;
603  }
604 
605  /* Keep going */
606  continue;
607  }
608 
609  /* We have a valid thread, was this an LPC Request? */
610  if (MessageType != LPC_REQUEST)
611  {
612  /* It's not an API, check if the client died */
613  if (MessageType == LPC_CLIENT_DIED)
614  {
615  /* Get the information and check if it matches our thread */
616  ClientDiedMsg = (PCLIENT_DIED_MSG)&ReceiveMsg;
617  if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart)
618  {
619  /* Now we reply to the dying client */
620  ReplyPort = CsrThread->Process->ClientPort;
621 
622  /* Reference the thread */
623  CsrLockedReferenceThread(CsrThread);
624 
625  /* Destroy the thread in the API Message */
626  CsrDestroyThread(&ReceiveMsg.Header.ClientId);
627 
628  /* Check if the thread was actually ourselves */
629  if (CsrProcess->ThreadCount == 1)
630  {
631  /* Kill the process manually here */
632  CsrDestroyProcess(&CsrThread->ClientId, 0);
633  }
634 
635  /* Remove our extra reference */
636  CsrLockedDereferenceThread(CsrThread);
637  }
638 
639  /* Release the lock and keep looping */
641 
642  ReplyMsg = NULL;
643  ReplyPort = CsrApiPort;
644  continue;
645  }
646 
647  /* Reference the thread and release the lock */
648  CsrLockedReferenceThread(CsrThread);
650 
651  /* Check if this was an exception */
652  if (MessageType == LPC_EXCEPTION)
653  {
654  /* Kill the process */
656 
657  /* Destroy it from CSR */
659 
660  /* Return a Debug Message */
661  DebugMessage = (PDBGKM_MSG)&ReceiveMsg;
662  DebugMessage->ReturnedStatus = DBG_CONTINUE;
663  ReplyMsg = &ReceiveMsg;
664  ReplyPort = CsrApiPort;
665 
666  /* Remove our extra reference */
667  CsrDereferenceThread(CsrThread);
668  }
669  else if (MessageType == LPC_ERROR_EVENT)
670  {
671  /* If it's a hard error, handle this too */
672  HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg;
673 
674  /* Default it to unhandled */
675  HardErrorMsg->Response = ResponseNotHandled;
676 
677  /* Check if there are free api threads */
680  {
681  /* Loop every Server DLL */
682  for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
683  {
684  /* Get the Server DLL */
685  ServerDll = CsrLoadedServerDll[i];
686 
687  /* Check if it's valid and if it has a Hard Error Callback */
688  if ((ServerDll) && (ServerDll->HardErrorCallback))
689  {
690  /* Call it */
691  ServerDll->HardErrorCallback(CsrThread, HardErrorMsg);
692 
693  /* If it's handled, get out of here */
694  if (HardErrorMsg->Response != ResponseNotHandled) break;
695  }
696  }
697  }
698 
699  /* Increase the thread count */
701 
702  /* If the response was 0xFFFFFFFF, we'll ignore it */
703  if (HardErrorMsg->Response == 0xFFFFFFFF)
704  {
705  ReplyMsg = NULL;
706  ReplyPort = CsrApiPort;
707  }
708  else
709  {
710  CsrDereferenceThread(CsrThread);
711  ReplyMsg = &ReceiveMsg;
712  ReplyPort = CsrApiPort;
713  }
714  }
715  else
716  {
717  /* Something else */
718  CsrDereferenceThread(CsrThread);
719  ReplyMsg = NULL;
720  }
721 
722  /* Keep looping */
723  continue;
724  }
725 
726  /* We got an API Request */
727  CsrLockedReferenceThread(CsrThread);
729 
730  /* This is an API call, get the Server ID */
731  ServerId = CSR_API_NUMBER_TO_SERVER_ID(ReceiveMsg.ApiNumber);
732 
733  /* Make sure that the ID is within limits, and the Server DLL loaded */
734  ServerDll = NULL;
735  if ((ServerId >= CSR_SERVER_DLL_MAX) ||
736  (!(ServerDll = CsrLoadedServerDll[ServerId])))
737  {
738  /* We are beyond the Maximum Server ID */
739  DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
740  ServerId, ServerDll);
741  // DbgBreakPoint();
742 
743  ReplyPort = CsrApiPort;
744  ReplyMsg = &ReceiveMsg;
745  ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
746  CsrDereferenceThread(CsrThread);
747  continue;
748  }
749 
750  /* Get the API ID, normalized with our Base ID */
751  ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase;
752 
753  /* Make sure that the ID is within limits, and the entry exists */
754  if (ApiId >= ServerDll->HighestApiSupported)
755  {
756  /* We are beyond the Maximum API ID, or it doesn't exist */
757  DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
759  &ServerDll->Name);
760 
761  ReplyPort = CsrApiPort;
762  ReplyMsg = &ReceiveMsg;
763  ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
764  CsrDereferenceThread(CsrThread);
765  continue;
766  }
767 
768 #ifdef CSR_DBG
769  if (CsrDebug & 2)
770  {
771  DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x, Process %08x - %08x\n",
772  Teb->ClientId.UniqueThread,
773  ReceiveMsg.Header.ClientId.UniqueProcess,
774  ReceiveMsg.Header.ClientId.UniqueThread,
775  ServerDll->NameTable[ApiId],
776  CsrThread,
777  CsrThread->Process,
778  CsrProcess);
779  }
780 #endif
781 
782  /* Assume success */
783  ReplyMsg = &ReceiveMsg;
784  ReceiveMsg.Status = STATUS_SUCCESS;
785 
786  /* Now we reply to a particular client */
787  ReplyPort = CsrThread->Process->ClientPort;
788 
789  /* Check if there's a capture buffer */
790  if (ReceiveMsg.CsrCaptureData)
791  {
792  /* Capture the arguments */
793  if (!CsrCaptureArguments(CsrThread, &ReceiveMsg))
794  {
795  /* Ignore this message if we failed to get the arguments */
796  CsrDereferenceThread(CsrThread);
797  continue;
798  }
799  }
800 
801  /* Validation complete, start SEH */
802  _SEH2_TRY
803  {
804  /* Make sure we have enough threads */
806 
807  Teb->CsrClientThread = CsrThread;
808 
809  /* Call the API, get the reply code and return the result */
810  ReplyCode = CsrReplyImmediately;
811  ReplyMsg->Status = ServerDll->DispatchTable[ApiId](&ReceiveMsg, &ReplyCode);
812 
813  /* Increase the static thread count */
815 
816  Teb->CsrClientThread = CurrentThread;
817 
818  if (ReplyCode == CsrReplyAlreadySent)
819  {
820  if (ReceiveMsg.CsrCaptureData)
821  {
822  CsrReleaseCapturedArguments(&ReceiveMsg);
823  }
824  ReplyMsg = NULL;
825  ReplyPort = CsrApiPort;
826  CsrDereferenceThread(CsrThread);
827  }
828  else if (ReplyCode == CsrReplyDeadClient)
829  {
830  /* Reply to the death message */
831  NtReplyPort(ReplyPort, &ReplyMsg->Header);
832 
833  /* Reply back to the API port now */
834  ReplyMsg = NULL;
835  ReplyPort = CsrApiPort;
836 
837  CsrDereferenceThread(CsrThread);
838  }
839  else if (ReplyCode == CsrReplyPending)
840  {
841  ReplyMsg = NULL;
842  ReplyPort = CsrApiPort;
843  }
844  else
845  {
846  if (ReceiveMsg.CsrCaptureData)
847  {
848  CsrReleaseCapturedArguments(&ReceiveMsg);
849  }
850  CsrDereferenceThread(CsrThread);
851  }
852  }
854  {
855  ReplyMsg = NULL;
856  ReplyPort = CsrApiPort;
857  }
858  _SEH2_END;
859  }
860 
861  /* We're out of the loop for some reason, terminate! */
863  return Status;
864 }
865 
866 /*++
867  * @name CsrApiPortInitialize
868  *
869  * The CsrApiPortInitialize routine initializes the LPC Port used for
870  * communications with the Client/Server Runtime (CSR) and initializes the
871  * static thread that will handle connection requests and APIs.
872  *
873  * @param None
874  *
875  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
876  *
877  * @remarks None.
878  *
879  *--*/
880 NTSTATUS
881 NTAPI
883 {
884  ULONG Size;
887  HANDLE hRequestEvent, hThread;
889  PLIST_ENTRY ListHead, NextEntry;
891 
892  /* Calculate how much space we'll need for the Port Name */
893  Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR);
894 
895  /* Create the buffer for it */
898 
899  /* Setup the rest of the empty string */
905  if (CsrDebug & 1)
906  {
907  DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName);
908  DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) == %ld\n",
909  sizeof(CSR_API_CONNECTINFO), sizeof(CSR_API_MESSAGE));
910  }
911 
912  /* FIXME: Create a Security Descriptor */
913 
914  /* Initialize the Attributes */
917  0,
918  NULL,
919  NULL /* FIXME: Use the Security Descriptor */);
920 
921  /* Create the Port Object */
924  sizeof(CSR_API_CONNECTINFO),
925  sizeof(CSR_API_MESSAGE),
926  16 * PAGE_SIZE);
927  if (NT_SUCCESS(Status))
928  {
929  /* Create the event the Port Thread will use */
930  Status = NtCreateEvent(&hRequestEvent,
932  NULL,
934  FALSE);
935  if (NT_SUCCESS(Status))
936  {
937  /* Create the Request Thread */
939  NULL,
940  TRUE,
941  0,
942  0,
943  0,
945  (PVOID)hRequestEvent,
946  &hThread,
947  &ClientId);
948  if (NT_SUCCESS(Status))
949  {
950  /* Add this as a static thread to CSRSRV */
952 
953  /* Get the Thread List Pointers */
954  ListHead = &CsrRootProcess->ThreadList;
955  NextEntry = ListHead->Flink;
956 
957  /* Start looping the list */
958  while (NextEntry != ListHead)
959  {
960  /* Get the Thread */
962 
963  /* Start it up */
964  Status = NtResumeThread(ServerThread->ThreadHandle, NULL);
965 
966  /* Is this a Server Thread? */
968  {
969  /* If so, then wait for it to initialize */
970  Status = NtWaitForSingleObject(hRequestEvent, FALSE, NULL);
972  }
973 
974  /* Next thread */
975  NextEntry = NextEntry->Flink;
976  }
977 
978  /* We don't need this anymore */
979  NtClose(hRequestEvent);
980  }
981  }
982  }
983 
984  /* Return */
985  return Status;
986 }
987 
988 /*++
989  * @name CsrConnectToUser
990  * @implemented NT4
991  *
992  * The CsrConnectToUser connects to the User subsystem.
993  *
994  * @param None
995  *
996  * @return A pointer to the CSR Thread
997  *
998  * @remarks None.
999  *
1000  *--*/
1002 NTAPI
1004 {
1005  NTSTATUS Status;
1006  ANSI_STRING DllName;
1007  UNICODE_STRING TempName;
1008  HANDLE hUser32;
1009  STRING StartupName;
1010  PTEB Teb = NtCurrentTeb();
1011  PCSR_THREAD CsrThread;
1012  BOOLEAN Connected;
1013 
1014  /* Check if we didn't already find it */
1015  if (!CsrClientThreadSetup)
1016  {
1017  /* Get the DLL Handle for user32.dll */
1018  RtlInitAnsiString(&DllName, "user32");
1019  RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE);
1021  NULL,
1022  &TempName,
1023  &hUser32);
1024  RtlFreeUnicodeString(&TempName);
1025 
1026  /* If we got the handle, get the Client Thread Startup Entrypoint */
1027  if (NT_SUCCESS(Status))
1028  {
1029  RtlInitAnsiString(&StartupName,"ClientThreadSetup");
1030  Status = LdrGetProcedureAddress(hUser32,
1031  &StartupName,
1032  0,
1034  }
1035  }
1036 
1037  /* Connect to user32 */
1038  _SEH2_TRY
1039  {
1040  Connected = CsrClientThreadSetup();
1041  }
1043  {
1044  Connected = FALSE;
1045  } _SEH2_END;
1046 
1047  if (!Connected)
1048  {
1049  DPRINT1("CSRSS: CsrConnectToUser failed\n");
1050  return NULL;
1051  }
1052 
1053  /* Save pointer to this thread in TEB */
1055  CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
1057  if (CsrThread) Teb->CsrClientThread = CsrThread;
1058 
1059  /* Return it */
1060  return CsrThread;
1061 }
1062 
1063 /*++
1064  * @name CsrQueryApiPort
1065  * @implemented NT4
1066  *
1067  * The CsrQueryApiPort routine returns a handle to the CSR API LPC port.
1068  *
1069  * @param None.
1070  *
1071  * @return A handle to the port.
1072  *
1073  * @remarks None.
1074  *
1075  *--*/
1076 HANDLE
1077 NTAPI
1079 {
1080  return CsrApiPort;
1081 }
1082 
1083 /*++
1084  * @name CsrCaptureArguments
1085  * @implemented NT5.1
1086  *
1087  * The CsrCaptureArguments routine validates a CSR Capture Buffer and
1088  * re-captures it into a server CSR Capture Buffer.
1089  *
1090  * @param CsrThread
1091  * Pointer to the CSR Thread performing the validation.
1092  *
1093  * @param ApiMessage
1094  * Pointer to the CSR API Message containing the Capture Buffer
1095  * that needs to be validated.
1096  *
1097  * @return TRUE if validation succeeded, FALSE otherwise.
1098  *
1099  * @remarks None.
1100  *
1101  *--*/
1102 BOOLEAN
1103 NTAPI
1105  IN PCSR_API_MESSAGE ApiMessage)
1106 {
1107  PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL, RemoteCaptureBuffer = NULL;
1108  SIZE_T BufferDistance;
1109  ULONG Length = 0;
1110  ULONG PointerCount;
1111  PULONG_PTR OffsetPointer;
1112  ULONG_PTR CurrentOffset;
1113 
1114  /* Use SEH to make sure this is valid */
1115  _SEH2_TRY
1116  {
1117  /* Get the buffer we got from whoever called NTDLL */
1118  LocalCaptureBuffer = ApiMessage->CsrCaptureData;
1119  Length = LocalCaptureBuffer->Size;
1120 
1121  /* Now check if the buffer is inside our mapped section */
1122  if (((ULONG_PTR)LocalCaptureBuffer < CsrThread->Process->ClientViewBase) ||
1123  (((ULONG_PTR)LocalCaptureBuffer + Length) >= CsrThread->Process->ClientViewBounds))
1124  {
1125  /* Return failure */
1126  DPRINT1("*** CSRSS: CaptureBuffer outside of ClientView\n");
1127  ApiMessage->Status = STATUS_INVALID_PARAMETER;
1128  _SEH2_YIELD(return FALSE);
1129  }
1130 
1131  /* Check if the Length is valid */
1132  if ((FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) +
1133  (LocalCaptureBuffer->PointerCount * sizeof(PVOID)) > Length) ||
1134  (LocalCaptureBuffer->PointerCount > MAXUSHORT))
1135  {
1136  /* Return failure */
1137  DPRINT1("*** CSRSS: CaptureBuffer %p has bad length\n", LocalCaptureBuffer);
1138  DbgBreakPoint();
1139  ApiMessage->Status = STATUS_INVALID_PARAMETER;
1140  _SEH2_YIELD(return FALSE);
1141  }
1142  }
1144  {
1145  /* Return failure */
1146  ApiMessage->Status = STATUS_INVALID_PARAMETER;
1147  _SEH2_YIELD(return FALSE);
1148  } _SEH2_END;
1149 
1150  /* We validated the incoming buffer, now allocate the remote one */
1151  RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
1152  if (!RemoteCaptureBuffer)
1153  {
1154  /* We're out of memory */
1155  ApiMessage->Status = STATUS_NO_MEMORY;
1156  return FALSE;
1157  }
1158 
1159  /* Copy the client's buffer */
1160  RtlMoveMemory(RemoteCaptureBuffer, LocalCaptureBuffer, Length);
1161 
1162  /* Calculate the difference between our buffer and the client's */
1163  BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer;
1164 
1165  /*
1166  * All the pointer offsets correspond to pointers which point
1167  * to the remote data buffer instead of the local one.
1168  */
1169  PointerCount = RemoteCaptureBuffer->PointerCount;
1170  OffsetPointer = RemoteCaptureBuffer->PointerOffsetsArray;
1171  while (PointerCount--)
1172  {
1173  CurrentOffset = *OffsetPointer;
1174 
1175  if (CurrentOffset != 0)
1176  {
1177  /* Get the pointer corresponding to the offset */
1178  CurrentOffset += (ULONG_PTR)ApiMessage;
1179 
1180  /* Validate the bounds of the current pointed pointer */
1181  if ((*(PULONG_PTR)CurrentOffset >= CsrThread->Process->ClientViewBase) &&
1182  (*(PULONG_PTR)CurrentOffset < CsrThread->Process->ClientViewBounds))
1183  {
1184  /* Modify the pointed pointer to take into account its new position */
1185  *(PULONG_PTR)CurrentOffset += BufferDistance;
1186  }
1187  else
1188  {
1189  /* Invalid pointer, fail */
1190  DPRINT1("*** CSRSS: CaptureBuffer MessagePointer outside of ClientView\n");
1191  DbgBreakPoint();
1192  ApiMessage->Status = STATUS_INVALID_PARAMETER;
1193  }
1194  }
1195 
1196  ++OffsetPointer;
1197  }
1198 
1199  /* Check if we got success */
1200  if (ApiMessage->Status != STATUS_SUCCESS)
1201  {
1202  /* Failure. Free the buffer and return */
1203  RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
1204  return FALSE;
1205  }
1206  else
1207  {
1208  /* Success, save the previous buffer and use the remote capture buffer */
1209  RemoteCaptureBuffer->PreviousCaptureBuffer = LocalCaptureBuffer;
1210  ApiMessage->CsrCaptureData = RemoteCaptureBuffer;
1211  }
1212 
1213  /* Success */
1214  return TRUE;
1215 }
1216 
1217 /*++
1218  * @name CsrReleaseCapturedArguments
1219  * @implemented NT5.1
1220  *
1221  * The CsrReleaseCapturedArguments routine releases a Capture Buffer
1222  * that was previously captured with CsrCaptureArguments.
1223  *
1224  * @param ApiMessage
1225  * Pointer to the CSR API Message containing the Capture Buffer
1226  * that needs to be released.
1227  *
1228  * @return None.
1229  *
1230  * @remarks None.
1231  *
1232  *--*/
1233 VOID
1234 NTAPI
1236 {
1237  PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer;
1238  SIZE_T BufferDistance;
1239  ULONG PointerCount;
1240  PULONG_PTR OffsetPointer;
1241  ULONG_PTR CurrentOffset;
1242 
1243  /* Get the remote capture buffer */
1244  RemoteCaptureBuffer = ApiMessage->CsrCaptureData;
1245 
1246  /* Do not continue if there is no captured buffer */
1247  if (!RemoteCaptureBuffer) return;
1248 
1249  /* If there is one, get the corresponding local capture buffer */
1250  LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer;
1251 
1252  /* Free the previous one and use again the local capture buffer */
1253  RemoteCaptureBuffer->PreviousCaptureBuffer = NULL;
1254  ApiMessage->CsrCaptureData = LocalCaptureBuffer;
1255 
1256  /* Calculate the difference between our buffer and the client's */
1257  BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer;
1258 
1259  /*
1260  * All the pointer offsets correspond to pointers which point
1261  * to the local data buffer instead of the remote one (revert
1262  * the logic of CsrCaptureArguments).
1263  */
1264  PointerCount = RemoteCaptureBuffer->PointerCount;
1265  OffsetPointer = RemoteCaptureBuffer->PointerOffsetsArray;
1266  while (PointerCount--)
1267  {
1268  CurrentOffset = *OffsetPointer;
1269 
1270  if (CurrentOffset != 0)
1271  {
1272  /* Get the pointer corresponding to the offset */
1273  CurrentOffset += (ULONG_PTR)ApiMessage;
1274 
1275  /* Modify the pointed pointer to take into account its new position */
1276  *(PULONG_PTR)CurrentOffset -= BufferDistance;
1277  }
1278 
1279  ++OffsetPointer;
1280  }
1281 
1282  /* Copy the data back */
1283  RtlMoveMemory(LocalCaptureBuffer, RemoteCaptureBuffer, RemoteCaptureBuffer->Size);
1284 
1285  /* Free our allocated buffer */
1286  RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
1287 }
1288 
1289 /*++
1290  * @name CsrValidateMessageBuffer
1291  * @implemented NT5.1
1292  *
1293  * The CsrValidateMessageBuffer routine validates a captured message buffer
1294  * present in the CSR Api Message
1295  *
1296  * @param ApiMessage
1297  * Pointer to the CSR API Message containing the CSR Capture Buffer.
1298  *
1299  * @param Buffer
1300  * Pointer to the message buffer to validate.
1301  *
1302  * @param ElementCount
1303  * Number of elements contained in the message buffer.
1304  *
1305  * @param ElementSize
1306  * Size of each element.
1307  *
1308  * @return TRUE if validation succeeded, FALSE otherwise.
1309  *
1310  * @remarks None.
1311  *
1312  *--*/
1313 BOOLEAN
1314 NTAPI
1316  IN PVOID *Buffer,
1317  IN ULONG ElementCount,
1318  IN ULONG ElementSize)
1319 {
1320  PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData;
1321  SIZE_T BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage;
1322  ULONG PointerCount;
1323  PULONG_PTR OffsetPointer;
1324 
1325  /*
1326  * Check whether we have a valid buffer pointer, elements
1327  * of non-trivial size and that we don't overflow.
1328  */
1329  if (!Buffer || ElementSize == 0 ||
1330  (ULONGLONG)ElementCount * ElementSize > (ULONGLONG)0xFFFFFFFF)
1331  {
1332  return FALSE;
1333  }
1334 
1335  /* Check if didn't get a buffer and there aren't any arguments to check */
1336  // if (!*Buffer && (ElementCount * ElementSize == 0))
1337  if (!*Buffer && ElementCount == 0) // Here ElementSize != 0 therefore only ElementCount can be == 0
1338  return TRUE;
1339 
1340  /* Check if we have no capture buffer */
1341  if (!CaptureBuffer)
1342  {
1343  /*
1344  * In this case, check only the Process ID
1345  * and if there is a match, we succeed.
1346  */
1347  if (NtCurrentTeb()->ClientId.UniqueProcess ==
1348  ApiMessage->Header.ClientId.UniqueProcess)
1349  {
1350  return TRUE;
1351  }
1352  }
1353  else
1354  {
1355  /* Make sure that there is still space left in the buffer */
1356  if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) >=
1357  (ElementCount * ElementSize))
1358  {
1359  /* Perform the validation test */
1360  PointerCount = CaptureBuffer->PointerCount;
1361  OffsetPointer = CaptureBuffer->PointerOffsetsArray;
1362  while (PointerCount--)
1363  {
1364  /*
1365  * The pointer offset must be equal to the delta between
1366  * the addresses of the buffer and of the API message.
1367  */
1368  if (*OffsetPointer == BufferDistance)
1369  {
1370  return TRUE;
1371  }
1372  ++OffsetPointer;
1373  }
1374  }
1375  }
1376 
1377  /* Failure */
1378  DPRINT1("CSRSRV: Bad message buffer %p\n", ApiMessage);
1379  DbgBreakPoint();
1380  return FALSE;
1381 }
1382 
1383 /*++
1384  * @name CsrValidateMessageString
1385  * @implemented NT5.1
1386  *
1387  * The CsrValidateMessageString validates a captured Wide-Character String
1388  * present in a CSR API Message.
1389  *
1390  * @param ApiMessage
1391  * Pointer to the CSR API Message containing the CSR Capture Buffer.
1392  *
1393  * @param MessageString
1394  * Pointer to the buffer containing the string to validate.
1395  *
1396  * @return TRUE if validation succeeded, FALSE otherwise.
1397  *
1398  * @remarks None.
1399  *
1400  *--*/
1401 BOOLEAN
1402 NTAPI
1404  IN LPWSTR *MessageString)
1405 {
1406  if (MessageString)
1407  {
1408  return CsrValidateMessageBuffer(ApiMessage,
1409  (PVOID*)MessageString,
1410  wcslen(*MessageString) + 1,
1411  sizeof(WCHAR));
1412  }
1413  else
1414  {
1415  return FALSE;
1416  }
1417 }
1418 
1419 /* EOF */
ULONG HighestApiSupported
Definition: csrsrv.h:223
VOID NTAPI CsrLockedReferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:154
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
ULONG Win32ClientInfo[31]
Definition: compat.h:496
ULONG Response
Definition: extypes.h:670
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI LdrGetDllHandle(IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle)
Definition: ldrapi.c:805
BOOLEAN NTAPI CsrCaptureArguments(IN PCSR_THREAD CsrThread, IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:1104
USHORT MaximumLength
Definition: env_spec_w32.h:370
LARGE_INTEGER CreateTime
Definition: lpctypes.h:270
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS ReturnedStatus
Definition: dbgktypes.h:210
PVOID CsrClientThread
Definition: compat.h:494
_Must_inspect_result_ _Outptr_ PFLT_PORT * ServerPort
Definition: fltkernel.h:1873
BOOLEAN(* CsrClientThreadSetup)(VOID)
Definition: api.c:21
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
#define NtCurrentThread()
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:100
ULONG CsrDebug
Definition: init.c:23
NTSTATUS NTAPI CsrDestroyProcess(IN PCLIENT_ID Cid, IN NTSTATUS ExitStatus)
Definition: procsup.c:734
ULONG_PTR ClientViewBounds
Definition: csrsrv.h:45
#define CSR_PORT_NAME
Definition: csrmsg.h:17
ANSI_STRING Name
Definition: csrsrv.h:218
VOID NTAPI CsrDereferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:775
PCSR_CAPTURE_BUFFER CsrCaptureData
Definition: csrmsg.h:110
_In_ PVOID Parameter
Definition: ldrtypes.h:240
HANDLE UniqueProcess
Definition: compat.h:474
void DbgBreakPoint()
Definition: mach.c:558
#define CSR_SERVER_DLL_MAX
Definition: api.h:34
#define CsrReleaseProcessLock()
Definition: api.h:15
PCSR_THREAD NTAPI CsrConnectToUser(VOID)
Definition: api.c:1003
static int Link(const char **args)
Definition: vfdcmd.c:2414
#define DBG_CONTINUE
Definition: ntstatus.h:47
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
_SEH2_TRY
Definition: create.c:4250
NTSTATUS NTAPI NtReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE ReplyMessage)
Definition: reply.c:190
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:63
CLIENT_ID ClientId
Definition: compat.h:488
PCSR_PROCESS CsrRootProcess
Definition: procsup.c:22
BOOLEAN NTAPI CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage, IN LPWSTR *MessageString)
Definition: api.c:1403
EXCEPTION_DISPOSITION NTAPI CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: server.c:606
PCSR_PROCESS Process
Definition: csrsrv.h:69
struct _CLIENT_DIED_MSG * PCLIENT_DIED_MSG
NTSTATUS NTAPI CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:140
NTSTATUS Status
Definition: csrmsg.h:112
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags)
Definition: thredsup.c:511
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
HANDLE ServerProcessId
Definition: csrmsg.h:57
VOID NTAPI CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:1235
#define STATUS_INVALID_CID
Definition: ntstatus.h:234
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
ULONG CountOfOwnedCriticalSections
Definition: compat.h:493
VOID NTAPI CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:467
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
HANDLE ProcessHandle
Definition: csrsrv.h:46
NTSTATUS NTAPI CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, IN OUT PCSR_API_MESSAGE ReplyMsg)
Definition: api.c:51
unsigned char BOOLEAN
UINT CALLBACK ServerThread(_Inout_ PVOID Parameter)
smooth NULL
Definition: ftsmooth.c:416
struct _REMOTE_PORT_VIEW REMOTE_PORT_VIEW
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1315
Definition: bufpool.h:45
CSR_API_NUMBER ApiNumber
Definition: csrmsg.h:111
HANDLE NTAPI CsrQueryApiPort(VOID)
Definition: api.c:1078
ULONG ThreadCount
Definition: csrsrv.h:55
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define UlongToPtr(u)
Definition: config.h:106
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:879
#define NtCurrentProcess()
Definition: nt_native.h:1657
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
NTSTATUS NTAPI CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL, OUT PCSR_API_CONNECTINFO ConnectInfo)
Definition: server.c:456
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
NTSTATUS NTAPI NtAcceptConnectPort(OUT PHANDLE PortHandle, IN PVOID PortContext OPTIONAL, IN PPORT_MESSAGE ReplyMessage, IN BOOLEAN AcceptConnection, IN OUT PPORT_VIEW ServerView OPTIONAL, OUT PREMOTE_PORT_VIEW ClientView OPTIONAL)
Definition: complete.c:40
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
NTSTATUS NTAPI NtCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:212
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:458
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
LARGE_INTEGER CreateTime
Definition: csrsrv.h:65
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CLIENT_ID ClientId
Definition: csrsrv.h:68
ULONG SequenceNumber
Definition: csrsrv.h:47
uint64_t ULONGLONG
Definition: typedefs.h:65
ULONG CsrMaxApiRequestThreads
Definition: init.c:34
CLIENT_ID RealClientId
Definition: compat.h:510
struct _CSR_CAPTURE_BUFFER * PreviousCaptureBuffer
Definition: csrmsg.h:95
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define CSR_API_NUMBER_TO_SERVER_ID(ApiNumber)
Definition: csrmsg.h:40
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
HANDLE UniqueThread
Definition: compat.h:475
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PCSR_HARDERROR_CALLBACK HardErrorCallback
Definition: csrsrv.h:237
std::wstring STRING
Definition: fontsub.cpp:33
#define CsrAcquireProcessLock()
Definition: api.h:12
NTSTATUS NTAPI NtReplyWaitReceivePort(IN HANDLE PortHandle, OUT PVOID *PortContext OPTIONAL, IN PPORT_MESSAGE ReplyMessage OPTIONAL, OUT PPORT_MESSAGE ReceiveMessage)
Definition: reply.c:743
#define CSR_API_NUMBER_TO_API_ID(ApiNumber)
Definition: csrmsg.h:43
NTSTATUS NTAPI CsrDestroyThread(IN PCLIENT_ID Cid)
Definition: thredsup.c:813
NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter)
Definition: api.c:331
#define VOID
Definition: acefi.h:82
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1510
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
UNICODE_STRING CsrDirectoryName
Definition: init.c:27
volatile ULONG CsrpStaticThreadCount
Definition: api.c:23
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(_In_ PVOID ThreadContext, _Out_ HANDLE *OutThreadHandle, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2, _Reserved_ PVOID Reserved3, _Reserved_ PVOID Reserved4, _Reserved_ PVOID Reserved5, _Reserved_ PVOID Reserved6, _Reserved_ PVOID Reserved7, _Reserved_ PVOID Reserved8)
PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, IN PCLIENT_ID ClientId)
Definition: thredsup.c:182
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, IN PCLIENT_ID Cid)
Definition: thredsup.c:248
Status
Definition: gdiplustypes.h:24
HANDLE CsrApiPort
Definition: connect.c:21
ULONG ApiBase
Definition: csrsrv.h:222
ULONG PointerCount
Definition: csrmsg.h:96
ULONG_PTR SIZE_T
Definition: typedefs.h:78
Definition: compat.h:484
HANDLE ClientPort
Definition: csrsrv.h:43
_SEH2_END
Definition: create.c:4424
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
struct _HARDERROR_MSG * PHARDERROR_MSG
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
unsigned short USHORT
Definition: pedump.c:61
LIST_ENTRY ThreadList
Definition: csrsrv.h:40
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1513
#define UNICODE_PATH_SEP
Definition: connect.c:33
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
struct _DBGKM_MSG * PDBGKM_MSG
volatile ULONG CsrpDynamicThreadTotal
Definition: api.c:24
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
enum _CSR_REPLY_CODE CSR_REPLY_CODE
CLIENT_ID ClientId
Definition: winternl.h:1751
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
HANDLE hThread
Definition: wizard.c:27
#define MAXUSHORT
Definition: typedefs.h:81
#define DPRINT1
Definition: precomp.h:8
PCSR_API_ROUTINE * DispatchTable
Definition: csrsrv.h:224
UNICODE_STRING CsrApiPortName
Definition: api.c:22
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
NTSTATUS NTAPI NtCompleteConnectPort(IN HANDLE PortHandle)
Definition: complete.c:421
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI CsrpCheckRequestThreads(VOID)
Definition: api.c:254
NTSTATUS NTAPI CsrApiPortInitialize(VOID)
Definition: api.c:882
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
VOID NTAPI CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:232
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
HANDLE CsrHeap
Definition: init.c:25
WCHAR * LPWSTR
Definition: xmlstorage.h:184
return STATUS_SUCCESS
Definition: btrfs.c:2745
PORT_MESSAGE Header
Definition: csrmsg.h:104
#define STATUS_ILLEGAL_FUNCTION
Definition: ntstatus.h:397
#define STATUS_ABANDONED
Definition: ntstatus.h:75
VOID NTAPI CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
Definition: procsup.c:159
ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]
Definition: csrmsg.h:98
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PBOOLEAN ValidTable
Definition: csrsrv.h:225
PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]
Definition: server.c:20
LONGLONG QuadPart
Definition: typedefs.h:112
ULONG_PTR ClientViewBase
Definition: csrsrv.h:44
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)