ReactOS  0.4.14-dev-1007-g90d795b
api.c File Reference
#include "srv.h"
#include <ndk/kefuncs.h>
#include <debug.h>
Include dependency graph for api.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI CsrCallServerFromServer (IN PCSR_API_MESSAGE ReceiveMsg, IN OUT PCSR_API_MESSAGE ReplyMsg)
 
NTSTATUS NTAPI CsrApiHandleConnectionRequest (IN PCSR_API_MESSAGE ApiMessage)
 
NTSTATUS NTAPI CsrpCheckRequestThreads (VOID)
 
NTSTATUS NTAPI CsrApiRequestThread (IN PVOID Parameter)
 
NTSTATUS NTAPI CsrApiPortInitialize (VOID)
 
PCSR_THREAD NTAPI CsrConnectToUser (VOID)
 
HANDLE NTAPI CsrQueryApiPort (VOID)
 
BOOLEAN NTAPI CsrCaptureArguments (IN PCSR_THREAD CsrThread, IN PCSR_API_MESSAGE ApiMessage)
 
VOID NTAPI CsrReleaseCapturedArguments (IN PCSR_API_MESSAGE ApiMessage)
 
BOOLEAN NTAPI CsrValidateMessageBuffer (IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
 
BOOLEAN NTAPI CsrValidateMessageString (IN PCSR_API_MESSAGE ApiMessage, IN LPWSTR *MessageString)
 

Variables

BOOLEAN(* CsrClientThreadSetup )(VOID) = NULL
 
UNICODE_STRING CsrApiPortName
 
volatile ULONG CsrpStaticThreadCount
 
volatile ULONG CsrpDynamicThreadTotal
 
ULONG CsrMaxApiRequestThreads
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file api.c.

Function Documentation

◆ CsrApiHandleConnectionRequest()

NTSTATUS NTAPI CsrApiHandleConnectionRequest ( IN PCSR_API_MESSAGE  ApiMessage)

Definition at line 140 of file api.c.

141 {
142  PCSR_THREAD CsrThread = 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 */
165 
166  /* Attach the Shared Section */
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 */
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 }
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _Outptr_ PFLT_PORT * ServerPort
Definition: fltkernel.h:1873
LONG NTSTATUS
Definition: precomp.h:26
ULONG CsrDebug
Definition: init.c:23
PKPROCESS CsrProcess
Definition: videoprt.c:37
#define CsrReleaseProcessLock()
Definition: api.h:15
uint32_t ULONG_PTR
Definition: typedefs.h:64
PCSR_PROCESS Process
Definition: csrsrv.h:69
HANDLE ServerProcessId
Definition: csrmsg.h:57
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _REMOTE_PORT_VIEW REMOTE_PORT_VIEW
#define UlongToPtr(u)
Definition: config.h:106
NTSTATUS NTAPI CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL, OUT PCSR_API_CONNECTINFO ConnectInfo)
Definition: server.c:456
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CsrAcquireProcessLock()
Definition: api.h:12
PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, IN PCLIENT_ID ClientId)
Definition: thredsup.c:182
Status
Definition: gdiplustypes.h:24
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI NtCompleteConnectPort(IN HANDLE PortHandle)
Definition: complete.c:421
#define ULONG_PTR
Definition: config.h:101
VOID NTAPI CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:232
return STATUS_SUCCESS
Definition: btrfs.c:2938
VOID NTAPI CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
Definition: procsup.c:159

Referenced by CsrApiRequestThread().

◆ CsrApiPortInitialize()

NTSTATUS NTAPI CsrApiPortInitialize ( VOID  )

Definition at line 882 of file api.c.

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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define TRUE
Definition: types.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
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
#define CSR_PORT_NAME
Definition: csrmsg.h:17
static int Link(const char **args)
Definition: vfdcmd.c:2414
PCSR_PROCESS CsrRootProcess
Definition: procsup.c:22
PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags)
Definition: thredsup.c:511
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
UINT CALLBACK ServerThread(_Inout_ PVOID Parameter)
smooth NULL
Definition: ftsmooth.c:416
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 NtCurrentProcess()
Definition: nt_native.h:1657
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
NTSTATUS NTAPI NtCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:212
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter)
Definition: api.c:331
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:118
UNICODE_STRING CsrDirectoryName
Definition: init.c:27
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)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
HANDLE CsrApiPort
Definition: connect.c:21
unsigned short USHORT
Definition: pedump.c:61
LIST_ENTRY ThreadList
Definition: csrsrv.h:40
#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)
HANDLE hThread
Definition: wizard.c:27
#define DPRINT1
Definition: precomp.h:8
UNICODE_STRING CsrApiPortName
Definition: api.c:22
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
HANDLE CsrHeap
Definition: init.c:25
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

Referenced by CsrServerInitialization().

◆ CsrApiRequestThread()

NTSTATUS NTAPI CsrApiRequestThread ( IN PVOID  Parameter)

Definition at line 331 of file api.c.

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;
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 */
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 }
ULONG HighestApiSupported
Definition: csrsrv.h:223
VOID NTAPI CsrLockedReferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:154
ULONG Win32ClientInfo[31]
Definition: compat.h:504
ULONG Response
Definition: extypes.h:670
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI CsrCaptureArguments(IN PCSR_THREAD CsrThread, IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:1104
LARGE_INTEGER CreateTime
Definition: lpctypes.h:270
NTSTATUS ReturnedStatus
Definition: dbgktypes.h:210
PVOID CsrClientThread
Definition: compat.h:502
LONG NTSTATUS
Definition: precomp.h:26
#define NtCurrentThread()
ULONG CsrDebug
Definition: init.c:23
NTSTATUS NTAPI CsrDestroyProcess(IN PCLIENT_ID Cid, IN NTSTATUS ExitStatus)
Definition: procsup.c:734
ANSI_STRING Name
Definition: csrsrv.h:218
PKPROCESS CsrProcess
Definition: videoprt.c:37
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:241
HANDLE UniqueProcess
Definition: compat.h:482
void DbgBreakPoint()
Definition: mach.c:553
#define CSR_SERVER_DLL_MAX
Definition: api.h:34
#define CsrReleaseProcessLock()
Definition: api.h:15
PCSR_THREAD NTAPI CsrConnectToUser(VOID)
Definition: api.c:1003
#define DBG_CONTINUE
Definition: ntstatus.h:47
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
_SEH2_TRY
Definition: create.c:4250
NTSTATUS NTAPI NtReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE ReplyMessage)
Definition: reply.c:190
CLIENT_ID ClientId
Definition: compat.h:496
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
VOID NTAPI CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:1235
#define STATUS_INVALID_CID
Definition: ntstatus.h:234
ULONG CountOfOwnedCriticalSections
Definition: compat.h:501
VOID NTAPI CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:467
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
smooth NULL
Definition: ftsmooth.c:416
CSR_API_NUMBER ApiNumber
Definition: csrmsg.h:111
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:879
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:458
LARGE_INTEGER CreateTime
Definition: csrsrv.h:65
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CLIENT_ID ClientId
Definition: csrsrv.h:68
CLIENT_ID RealClientId
Definition: compat.h:518
#define CSR_API_NUMBER_TO_SERVER_ID(ApiNumber)
Definition: csrmsg.h:40
HANDLE UniqueThread
Definition: compat.h:483
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PCSR_HARDERROR_CALLBACK HardErrorCallback
Definition: csrsrv.h:237
#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
volatile ULONG CsrpStaticThreadCount
Definition: api.c:23
PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, IN PCLIENT_ID ClientId)
Definition: thredsup.c:182
Status
Definition: gdiplustypes.h:24
HANDLE CsrApiPort
Definition: connect.c:21
ULONG ApiBase
Definition: csrsrv.h:222
Definition: compat.h:492
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 InterlockedIncrementUL(Addend)
Definition: ex.h:1513
struct _DBGKM_MSG * PDBGKM_MSG
volatile ULONG CsrpDynamicThreadTotal
Definition: api.c:24
enum _CSR_REPLY_CODE CSR_REPLY_CODE
CLIENT_ID ClientId
Definition: winternl.h:1751
#define DPRINT1
Definition: precomp.h:8
PCSR_API_ROUTINE * DispatchTable
Definition: csrsrv.h:224
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI CsrpCheckRequestThreads(VOID)
Definition: api.c:254
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
return STATUS_SUCCESS
Definition: btrfs.c:2938
PORT_MESSAGE Header
Definition: csrmsg.h:104
#define STATUS_ILLEGAL_FUNCTION
Definition: ntstatus.h:397
#define STATUS_ABANDONED
Definition: ntstatus.h:75
PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]
Definition: server.c:20
LONGLONG QuadPart
Definition: typedefs.h:113

Referenced by CsrApiPortInitialize(), and CsrpCheckRequestThreads().

◆ CsrCallServerFromServer()

NTSTATUS NTAPI CsrCallServerFromServer ( IN PCSR_API_MESSAGE  ReceiveMsg,
IN OUT PCSR_API_MESSAGE  ReplyMsg 
)

Definition at line 51 of file api.c.

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 }
ULONG HighestApiSupported
Definition: csrsrv.h:223
ULONG CsrDebug
Definition: init.c:23
ANSI_STRING Name
Definition: csrsrv.h:218
#define CSR_SERVER_DLL_MAX
Definition: api.h:34
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define CSR_API_NUMBER_TO_SERVER_ID(ApiNumber)
Definition: csrmsg.h:40
#define CSR_API_NUMBER_TO_API_ID(ApiNumber)
Definition: csrmsg.h:43
ULONG ApiBase
Definition: csrsrv.h:222
_SEH2_END
Definition: create.c:4424
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
enum _CSR_REPLY_CODE CSR_REPLY_CODE
#define DPRINT1
Definition: precomp.h:8
PCSR_API_ROUTINE * DispatchTable
Definition: csrsrv.h:224
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define STATUS_ILLEGAL_FUNCTION
Definition: ntstatus.h:397
PBOOLEAN ValidTable
Definition: csrsrv.h:225
PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]
Definition: server.c:20

◆ CsrCaptureArguments()

BOOLEAN NTAPI CsrCaptureArguments ( IN PCSR_THREAD  CsrThread,
IN PCSR_API_MESSAGE  ApiMessage 
)

Definition at line 1104 of file api.c.

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 }
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
void DbgBreakPoint()
Definition: mach.c:553
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ULONG PointerCount
Definition: csrmsg.h:96
ULONG_PTR SIZE_T
Definition: typedefs.h:79
_SEH2_END
Definition: create.c:4424
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define MAXUSHORT
Definition: typedefs.h:82
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:64
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
HANDLE CsrHeap
Definition: init.c:25
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by CsrApiRequestThread().

◆ CsrConnectToUser()

PCSR_THREAD NTAPI CsrConnectToUser ( VOID  )

Definition at line 1003 of file api.c.

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 }
#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
PVOID CsrClientThread
Definition: compat.h:502
BOOLEAN(* CsrClientThreadSetup)(VOID)
Definition: api.c:21
LONG NTSTATUS
Definition: precomp.h:26
#define CsrReleaseProcessLock()
Definition: api.h:15
_SEH2_TRY
Definition: create.c:4250
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
CLIENT_ID ClientId
Definition: compat.h:496
#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
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
std::wstring STRING
Definition: fontsub.cpp:33
#define CsrAcquireProcessLock()
Definition: api.h:12
PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, IN PCLIENT_ID Cid)
Definition: thredsup.c:248
Status
Definition: gdiplustypes.h:24
Definition: compat.h:492
_SEH2_END
Definition: create.c:4424
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define DPRINT1
Definition: precomp.h:8
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6

Referenced by CsrApiRequestThread(), and GuiConsoleInputThread().

◆ CsrpCheckRequestThreads()

NTSTATUS NTAPI CsrpCheckRequestThreads ( VOID  )

Definition at line 254 of file api.c.

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 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags)
Definition: thredsup.c:511
smooth NULL
Definition: ftsmooth.c:416
#define NtCurrentProcess()
Definition: nt_native.h:1657
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
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG CsrMaxApiRequestThreads
Definition: init.c:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter)
Definition: api.c:331
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1510
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)
Status
Definition: gdiplustypes.h:24
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1513
volatile ULONG CsrpDynamicThreadTotal
Definition: api.c:24
HANDLE hThread
Definition: wizard.c:27
#define DPRINT1
Definition: precomp.h:8
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by CsrApiRequestThread().

◆ CsrQueryApiPort()

HANDLE NTAPI CsrQueryApiPort ( VOID  )

Definition at line 1078 of file api.c.

1079 {
1080  return CsrApiPort;
1081 }
HANDLE CsrApiPort
Definition: connect.c:21

Referenced by CSR_API(), and UserClientConnect().

◆ CsrReleaseCapturedArguments()

VOID NTAPI CsrReleaseCapturedArguments ( IN PCSR_API_MESSAGE  ApiMessage)

Definition at line 1235 of file api.c.

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 }
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG_PTR
Definition: typedefs.h:64
smooth NULL
Definition: ftsmooth.c:416
struct _CSR_CAPTURE_BUFFER * PreviousCaptureBuffer
Definition: csrmsg.h:95
ULONG PointerCount
Definition: csrmsg.h:96
ULONG_PTR SIZE_T
Definition: typedefs.h:79
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:64
HANDLE CsrHeap
Definition: init.c:25
ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]
Definition: csrmsg.h:98

Referenced by CsrApiRequestThread(), and CsrNotifyWaitBlock().

◆ CsrValidateMessageBuffer()

BOOLEAN NTAPI CsrValidateMessageBuffer ( IN PCSR_API_MESSAGE  ApiMessage,
IN PVOID Buffer,
IN ULONG  ElementCount,
IN ULONG  ElementSize 
)

Definition at line 1315 of file api.c.

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 }
#define TRUE
Definition: types.h:120
void DbgBreakPoint()
Definition: mach.c:553
uint32_t ULONG_PTR
Definition: typedefs.h:64
Definition: bufpool.h:45
uint64_t ULONGLONG
Definition: typedefs.h:66
ULONG_PTR SIZE_T
Definition: typedefs.h:79
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:64

Referenced by CSR_API(), and CsrValidateMessageString().

◆ CsrValidateMessageString()

BOOLEAN NTAPI CsrValidateMessageString ( IN PCSR_API_MESSAGE  ApiMessage,
IN LPWSTR MessageString 
)

Definition at line 1403 of file api.c.

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 }
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1315
__wchar_t WCHAR
Definition: xmlstorage.h:180
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)

Variable Documentation

◆ CsrApiPortName

UNICODE_STRING CsrApiPortName

Definition at line 22 of file api.c.

Referenced by CsrApiPortInitialize().

◆ CsrClientThreadSetup

BOOLEAN(* CsrClientThreadSetup) (VOID) = NULL

Definition at line 21 of file api.c.

Referenced by CsrConnectToUser().

◆ CsrMaxApiRequestThreads

ULONG CsrMaxApiRequestThreads

Definition at line 34 of file init.c.

Referenced by CsrpCheckRequestThreads().

◆ CsrpDynamicThreadTotal

volatile ULONG CsrpDynamicThreadTotal

Definition at line 24 of file api.c.

Referenced by CsrApiRequestThread(), and CsrpCheckRequestThreads().

◆ CsrpStaticThreadCount

volatile ULONG CsrpStaticThreadCount

Definition at line 23 of file api.c.

Referenced by CsrApiRequestThread(), and CsrpCheckRequestThreads().