ReactOS 0.4.16-dev-297-gc569aee
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 PWSTR *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 144 of file api.c.

145{
146 PCSR_THREAD CsrThread = NULL;
149 PCSR_API_CONNECTINFO ConnectInfo = &ApiMessage->ConnectionInfo;
150 BOOLEAN AllowConnection = FALSE;
151 REMOTE_PORT_VIEW RemotePortView;
153
154 /* Acquire the Process Lock */
156
157 /* Lookup the CSR Thread */
158 CsrThread = CsrLocateThreadByClientId(NULL, &ApiMessage->Header.ClientId);
159
160 /* Check if we have a thread */
161 if (CsrThread)
162 {
163 /* Get the Process and make sure we have it as well */
164 CsrProcess = CsrThread->Process;
165 if (CsrProcess)
166 {
167 /* Reference the Process */
169
170 /* Attach the Shared Section */
172 if (NT_SUCCESS(Status))
173 {
174 /* Allow the connection and return debugging flag */
175 ConnectInfo->DebugFlags = CsrDebug;
176 AllowConnection = TRUE;
177 }
178
179 /* Dereference the Process */
181 }
182 }
183
184 /* Release the Process Lock */
186
187 /* Setup the Port View Structure */
188 RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
189 RemotePortView.ViewSize = 0;
190 RemotePortView.ViewBase = NULL;
191
192 /* Save the Process ID */
193 ConnectInfo->ServerProcessId = NtCurrentTeb()->ClientId.UniqueProcess;
194
195 /* Accept the Connection */
196 ASSERT(!AllowConnection || CsrProcess);
198 AllowConnection ? UlongToPtr(CsrProcess->SequenceNumber) : 0,
199 &ApiMessage->Header,
200 AllowConnection,
201 NULL,
202 &RemotePortView);
203 if (!NT_SUCCESS(Status))
204 {
205 DPRINT1("CSRSS: NtAcceptConnectPort - failed. Status == %X\n", Status);
206 }
207 else if (AllowConnection)
208 {
209 if (CsrDebug & 2)
210 {
211 DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n",
212 ApiMessage->Header.ClientId.UniqueProcess,
213 ApiMessage->Header.ClientId.UniqueThread,
214 RemotePortView.ViewBase,
215 RemotePortView.ViewSize);
216 }
217
218 /* Set some Port Data in the Process */
219 CsrProcess->ClientPort = ServerPort;
220 CsrProcess->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase;
221 CsrProcess->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase +
222 (ULONG_PTR)RemotePortView.ViewSize);
223
224 /* Complete the connection */
226 if (!NT_SUCCESS(Status))
227 {
228 DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status);
229 }
230 }
231 else
232 {
233 DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
234 ApiMessage->Header.ClientId.UniqueProcess,
235 ApiMessage->Header.ClientId.UniqueThread);
236 }
237
238 /* Return status to caller */
239 return Status;
240}
static const INTERNET_PORT ServerPort
Definition: CWebService.cpp:11
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
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
NTSTATUS NTAPI NtCompleteConnectPort(IN HANDLE PortHandle)
Definition: complete.c:423
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
Status
Definition: gdiplustypes.h:25
#define NtCurrentTeb
#define ASSERT(a)
Definition: mode.c:44
struct _REMOTE_PORT_VIEW REMOTE_PORT_VIEW
#define STATUS_SUCCESS
Definition: shellext.h:65
HANDLE ServerProcessId
Definition: csrmsg.h:57
PCSR_PROCESS Process
Definition: csrsrv.h:69
NTSTATUS NTAPI CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL, OUT PCSR_API_CONNECTINFO ConnectInfo)
Definition: server.c:482
ULONG CsrDebug
Definition: init.c:23
PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, IN PCLIENT_ID ClientId)
Definition: thredsup.c:182
VOID NTAPI CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:233
#define CsrAcquireProcessLock()
Definition: api.h:12
#define CsrReleaseProcessLock()
Definition: api.h:15
VOID NTAPI CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
Definition: procsup.c:159
uint32_t ULONG_PTR
Definition: typedefs.h:65
PKPROCESS CsrProcess
Definition: videoprt.c:39

Referenced by CsrApiRequestThread().

◆ CsrApiPortInitialize()

NTSTATUS NTAPI CsrApiPortInitialize ( VOID  )

Definition at line 900 of file api.c.

901{
902 ULONG Size;
905 HANDLE hRequestEvent, hThread;
907 PLIST_ENTRY ListHead, NextEntry;
909
910 /* Calculate how much space we'll need for the Port Name */
911 Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR);
912
913 /* Create the buffer for it */
916
917 /* Setup the rest of the empty string */
923 if (CsrDebug & 1)
924 {
925 DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName);
926 DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) == %ld\n",
927 sizeof(CSR_API_CONNECTINFO), sizeof(CSR_API_MESSAGE));
928 }
929
930 /* FIXME: Create a Security Descriptor */
931
932 /* Initialize the Attributes */
935 0,
936 NULL,
937 NULL /* FIXME: Use the Security Descriptor */);
938
939 /* Create the Port Object */
942 sizeof(CSR_API_CONNECTINFO),
943 sizeof(CSR_API_MESSAGE),
944 16 * PAGE_SIZE);
945 if (NT_SUCCESS(Status))
946 {
947 /* Create the event the Port Thread will use */
948 Status = NtCreateEvent(&hRequestEvent,
950 NULL,
952 FALSE);
953 if (NT_SUCCESS(Status))
954 {
955 /* Create the Request Thread */
957 NULL,
958 TRUE,
959 0,
960 0,
961 0,
963 (PVOID)hRequestEvent,
964 &hThread,
965 &ClientId);
966 if (NT_SUCCESS(Status))
967 {
968 /* Add this as a static thread to CSRSRV */
970
971 /* Get the Thread List Pointers */
972 ListHead = &CsrRootProcess->ThreadList;
973 NextEntry = ListHead->Flink;
974
975 /* Start looping the list */
976 while (NextEntry != ListHead)
977 {
978 /* Get the Thread */
980
981 /* Start it up */
982 Status = NtResumeThread(ServerThread->ThreadHandle, NULL);
983
984 /* Is this a Server Thread? */
986 {
987 /* If so, then wait for it to initialize */
988 Status = NtWaitForSingleObject(hRequestEvent, FALSE, NULL);
990 }
991
992 /* Next thread */
993 NextEntry = NextEntry->Flink;
994 }
995
996 /* We don't need this anymore */
997 NtClose(hRequestEvent);
998 }
999 }
1000 }
1001
1002 /* Return */
1003 return Status;
1004}
UINT CALLBACK ServerThread(_Inout_ PVOID Parameter)
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define CSR_PORT_NAME
Definition: csrmsg.h:17
PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags)
Definition: thredsup.c:512
@ CsrThreadIsServerThread
Definition: csrsrv.h:107
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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)
HANDLE hThread
Definition: wizard.c:28
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
@ SynchronizationEvent
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:96
NTSTATUS NTAPI NtCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:222
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
unsigned short USHORT
Definition: pedump.c:61
#define UNICODE_PATH_SEP
Definition: srv.h:49
LIST_ENTRY ThreadList
Definition: csrsrv.h:40
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
HANDLE CsrApiPort
Definition: connect.c:27
UNICODE_STRING CsrApiPortName
Definition: api.c:22
NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter)
Definition: api.c:336
PCSR_PROCESS CsrRootProcess
Definition: procsup.c:22
UNICODE_STRING CsrDirectoryName
Definition: init.c:27
HANDLE CsrHeap
Definition: init.c:25
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
static int Link(const char **args)
Definition: vfdcmd.c:2414
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by CsrServerInitialization().

◆ CsrApiRequestThread()

NTSTATUS NTAPI CsrApiRequestThread ( IN PVOID  Parameter)

Definition at line 336 of file api.c.

337{
338 PTEB Teb = NtCurrentTeb();
339 LARGE_INTEGER TimeOut;
340 PCSR_THREAD CurrentThread, CsrThread;
342 CSR_REPLY_CODE ReplyCode;
343 PCSR_API_MESSAGE ReplyMsg;
344 CSR_API_MESSAGE ReceiveMsg;
346 PHARDERROR_MSG HardErrorMsg;
347 PVOID PortContext;
348 PCSR_SERVER_DLL ServerDll;
349 PCLIENT_DIED_MSG ClientDiedMsg;
350 PDBGKM_MSG DebugMessage;
351 ULONG ServerId, ApiId, MessageType, i;
352 HANDLE ReplyPort;
353
354 /* Setup LPC loop port and message */
355 ReplyMsg = NULL;
356 ReplyPort = CsrApiPort;
357
358 /* Connect to user32 */
359 while (!CsrConnectToUser())
360 {
361 /* Set up the timeout for the connect (30 seconds) */
362 TimeOut.QuadPart = -30 * 1000 * 1000 * 10;
363
364 /* Keep trying until we get a response */
365 Teb->Win32ClientInfo[0] = 0;
366 NtDelayExecution(FALSE, &TimeOut);
367 }
368
369 /* Get our thread */
370 CurrentThread = Teb->CsrClientThread;
371
372 /* If we got an event... */
373 if (Parameter)
374 {
375 /* Set it, to let stuff waiting on us load */
378
379 /* Increase the Thread Counts */
382 }
383
384 /* Now start the loop */
385 while (TRUE)
386 {
387 /* Make sure the real CID is set */
388 Teb->RealClientId = Teb->ClientId;
389
390#ifdef CSR_DBG
391 /* Debug check */
393 {
394 DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu critical sections\n",
396 DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n",
397 &ReceiveMsg, ReplyMsg);
399 }
400#endif
401
402 /* Wait for a message to come through */
403 Status = NtReplyWaitReceivePort(ReplyPort,
404 &PortContext,
405 &ReplyMsg->Header,
406 &ReceiveMsg.Header);
407
408 /* Check if we didn't get success */
409 if (Status != STATUS_SUCCESS)
410 {
411 /* Was it a failure or another success code? */
412 if (!NT_SUCCESS(Status))
413 {
414#ifdef CSR_DBG
415 /* Check for specific status cases */
416 if ((Status != STATUS_INVALID_CID) &&
418 ((Status != STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
419 {
420 /* Notify the debugger */
421 DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
422 DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort);
423 }
424#endif
425
426 /* We failed big time, so start out fresh */
427 ReplyMsg = NULL;
428 ReplyPort = CsrApiPort;
429 continue;
430 }
431 else
432 {
433 /* A strange "success" code, just try again */
434 DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status);
435 continue;
436 }
437 }
438
439 // ASSERT(ReceiveMsg.Header.u1.s1.TotalLength >= sizeof(PORT_MESSAGE));
440 // ASSERT(ReceiveMsg.Header.u1.s1.TotalLength < sizeof(ReceiveMsg));
441
442 /* Use whatever Client ID we got */
443 Teb->RealClientId = ReceiveMsg.Header.ClientId;
444
445 /* Get the Message Type */
446 MessageType = ReceiveMsg.Header.u2.s2.Type;
447
448 /* Handle connection requests */
449 if (MessageType == LPC_CONNECTION_REQUEST)
450 {
451 /* Handle the Connection Request */
453
454 ReplyMsg = NULL;
455 ReplyPort = CsrApiPort;
456 continue;
457 }
458
459 /* It's some other kind of request. Get the lock for the lookup */
461
462 /* Now do the lookup to get the CSR_THREAD */
464 &ReceiveMsg.Header.ClientId);
465
466 /* Did we find a thread? */
467 if (!CsrThread)
468 {
469 /* This wasn't a CSR Thread, release lock */
471
472 /* If this was an exception, handle it */
473 if (MessageType == LPC_EXCEPTION)
474 {
475 ReplyMsg = &ReceiveMsg;
476 ReplyPort = CsrApiPort;
477 ReplyMsg->Status = DBG_CONTINUE;
478 }
479 else if (MessageType == LPC_PORT_CLOSED ||
480 MessageType == LPC_CLIENT_DIED)
481 {
482 /* The Client or Port are gone, loop again */
483 ReplyMsg = NULL;
484 ReplyPort = CsrApiPort;
485 }
486 else if (MessageType == LPC_ERROR_EVENT)
487 {
488 /* If it's a hard error, handle this too */
489 HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg;
490
491 /* Default it to unhandled */
492 HardErrorMsg->Response = ResponseNotHandled;
493
494 /* Check if there are free api threads */
497 {
498 /* Loop every Server DLL */
499 for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
500 {
501 /* Get the Server DLL */
502 ServerDll = CsrLoadedServerDll[i];
503
504 /* Check if it's valid and if it has a Hard Error Callback */
505 if ((ServerDll) && (ServerDll->HardErrorCallback))
506 {
507 /* Call it */
508 ServerDll->HardErrorCallback(NULL /* == CsrThread */, HardErrorMsg);
509
510 /* If it's handled, get out of here */
511 if (HardErrorMsg->Response != ResponseNotHandled) break;
512 }
513 }
514 }
515
516 /* Increase the thread count */
518
519 /* If the response was 0xFFFFFFFF, we'll ignore it */
520 if (HardErrorMsg->Response == 0xFFFFFFFF)
521 {
522 ReplyMsg = NULL;
523 ReplyPort = CsrApiPort;
524 }
525 else
526 {
527 ReplyMsg = &ReceiveMsg;
528 ReplyPort = CsrApiPort;
529 }
530 }
531 else if (MessageType == LPC_REQUEST)
532 {
533 /* This is an API Message coming from a non-CSR Thread */
534 ReplyMsg = &ReceiveMsg;
535 ReplyPort = CsrApiPort;
537 }
538 else if (MessageType == LPC_DATAGRAM)
539 {
540 /* This is an API call, get the Server ID */
541 ServerId = CSR_API_NUMBER_TO_SERVER_ID(ReceiveMsg.ApiNumber);
542
543 /* Make sure that the ID is within limits, and the Server DLL loaded */
544 ServerDll = NULL;
545 if ((ServerId >= CSR_SERVER_DLL_MAX) ||
546 (!(ServerDll = CsrLoadedServerDll[ServerId])))
547 {
548 /* We are beyond the Maximum Server ID */
549#ifdef CSR_DBG
550 DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
551 ServerId, ServerDll);
552 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
553#endif
554 ReplyMsg = NULL;
555 ReplyPort = CsrApiPort;
556 continue;
557 }
558
559 /* Get the API ID, normalized with our Base ID */
560 ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase;
561
562 /* Make sure that the ID is within limits, and the entry exists */
563 if (ApiId >= ServerDll->HighestApiSupported)
564 {
565 /* We are beyond the Maximum API ID, or it doesn't exist */
566#ifdef CSR_DBG
567 DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
569 &ServerDll->Name);
570#endif
571 ReplyPort = CsrApiPort;
572 ReplyMsg = NULL;
573 continue;
574 }
575
576#ifdef CSR_DBG
577 if (CsrDebug & 2)
578 {
579 DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n",
581 ReceiveMsg.Header.ClientId.UniqueProcess,
582 ReceiveMsg.Header.ClientId.UniqueThread,
583 ServerDll->NameTable[ApiId],
584 NULL);
585 }
586#endif
587
588 /* Assume success */
589 ReceiveMsg.Status = STATUS_SUCCESS;
590
591 /* Validation complete, start SEH */
593 {
594 /* Make sure we have enough threads */
596
597 /* Call the API and get the reply code */
598 ReplyMsg = NULL;
599 ReplyPort = CsrApiPort;
600 ServerDll->DispatchTable[ApiId](&ReceiveMsg, &ReplyCode);
601
602 /* Increase the static thread count */
604 }
606 {
607 ReplyMsg = NULL;
608 ReplyPort = CsrApiPort;
609 }
610 _SEH2_END;
611 }
612 else
613 {
614 /* Some other ignored message type */
615 ReplyMsg = NULL;
616 ReplyPort = CsrApiPort;
617 }
618
619 /* Keep going */
620 continue;
621 }
622
623 /* We have a valid thread, was this an LPC Request? */
624 if (MessageType != LPC_REQUEST)
625 {
626 /* It's not an API, check if the client died */
627 if (MessageType == LPC_CLIENT_DIED)
628 {
629 /* Get the information and check if it matches our thread */
630 ClientDiedMsg = (PCLIENT_DIED_MSG)&ReceiveMsg;
631 if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart)
632 {
633 /* Now we reply to the dying client */
634 ReplyPort = CsrThread->Process->ClientPort;
635
636 /* Reference the thread */
637 CsrLockedReferenceThread(CsrThread);
638
639 /* Destroy the thread in the API Message */
640 CsrDestroyThread(&ReceiveMsg.Header.ClientId);
641
642 /* Check if the thread was actually ourselves */
643 if (CsrProcess->ThreadCount == 1)
644 {
645 /* Kill the process manually here */
646 CsrDestroyProcess(&CsrThread->ClientId, 0);
647 }
648
649 /* Remove our extra reference */
651 }
652
653 /* Release the lock and keep looping */
655
656 ReplyMsg = NULL;
657 ReplyPort = CsrApiPort;
658 continue;
659 }
660
661 /* Reference the thread and release the lock */
662 CsrLockedReferenceThread(CsrThread);
664
665 /* Check if this was an exception */
666 if (MessageType == LPC_EXCEPTION)
667 {
668 /* Kill the process */
670
671 /* Destroy it from CSR */
673
674 /* Return a Debug Message */
675 DebugMessage = (PDBGKM_MSG)&ReceiveMsg;
676 DebugMessage->ReturnedStatus = DBG_CONTINUE;
677 ReplyMsg = &ReceiveMsg;
678 ReplyPort = CsrApiPort;
679
680 /* Remove our extra reference */
681 CsrDereferenceThread(CsrThread);
682 }
683 else if (MessageType == LPC_ERROR_EVENT)
684 {
685 /* If it's a hard error, handle this too */
686 HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg;
687
688 /* Default it to unhandled */
689 HardErrorMsg->Response = ResponseNotHandled;
690
691 /* Check if there are free api threads */
694 {
695 /* Loop every Server DLL */
696 for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
697 {
698 /* Get the Server DLL */
699 ServerDll = CsrLoadedServerDll[i];
700
701 /* Check if it's valid and if it has a Hard Error Callback */
702 if ((ServerDll) && (ServerDll->HardErrorCallback))
703 {
704 /* Call it */
705 ServerDll->HardErrorCallback(CsrThread, HardErrorMsg);
706
707 /* If it's handled, get out of here */
708 if (HardErrorMsg->Response != ResponseNotHandled) break;
709 }
710 }
711 }
712
713 /* Increase the thread count */
715
716 /* If the response was 0xFFFFFFFF, we'll ignore it */
717 if (HardErrorMsg->Response == 0xFFFFFFFF)
718 {
719 ReplyMsg = NULL;
720 ReplyPort = CsrApiPort;
721 }
722 else
723 {
724 CsrDereferenceThread(CsrThread);
725 ReplyMsg = &ReceiveMsg;
726 ReplyPort = CsrApiPort;
727 }
728 }
729 else
730 {
731 /* Something else */
732 CsrDereferenceThread(CsrThread);
733 ReplyMsg = NULL;
734 }
735
736 /* Keep looping */
737 continue;
738 }
739
740 /* We got an API Request */
741 CsrLockedReferenceThread(CsrThread);
743
744 /* This is an API call, get the Server ID */
745 ServerId = CSR_API_NUMBER_TO_SERVER_ID(ReceiveMsg.ApiNumber);
746
747 /* Make sure that the ID is within limits, and the Server DLL loaded */
748 ServerDll = NULL;
749 if ((ServerId >= CSR_SERVER_DLL_MAX) ||
750 (!(ServerDll = CsrLoadedServerDll[ServerId])))
751 {
752 /* We are beyond the Maximum Server ID */
753#ifdef CSR_DBG
754 DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
755 ServerId, ServerDll);
756 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
757#endif
758 ReplyPort = CsrApiPort;
759 ReplyMsg = &ReceiveMsg;
761 CsrDereferenceThread(CsrThread);
762 continue;
763 }
764
765 /* Get the API ID, normalized with our Base ID */
766 ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase;
767
768 /* Make sure that the ID is within limits, and the entry exists */
769 if (ApiId >= ServerDll->HighestApiSupported)
770 {
771#ifdef CSR_DBG
772 /* We are beyond the Maximum API ID, or it doesn't exist */
773 DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
775 &ServerDll->Name);
776#endif
777 ReplyPort = CsrApiPort;
778 ReplyMsg = &ReceiveMsg;
780 CsrDereferenceThread(CsrThread);
781 continue;
782 }
783
784#ifdef CSR_DBG
785 if (CsrDebug & 2)
786 {
787 DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x, Process %08x - %08x\n",
789 ReceiveMsg.Header.ClientId.UniqueProcess,
790 ReceiveMsg.Header.ClientId.UniqueThread,
791 ServerDll->NameTable[ApiId],
792 CsrThread,
793 CsrThread->Process,
794 CsrProcess);
795 }
796#endif
797
798 /* Assume success */
799 ReplyMsg = &ReceiveMsg;
800 ReceiveMsg.Status = STATUS_SUCCESS;
801
802 /* Now we reply to a particular client */
803 ReplyPort = CsrThread->Process->ClientPort;
804
805 /* Check if there's a capture buffer */
806 if (ReceiveMsg.CsrCaptureData)
807 {
808 /* Capture the arguments */
809 if (!CsrCaptureArguments(CsrThread, &ReceiveMsg))
810 {
811 /* Ignore this message if we failed to get the arguments */
812 CsrDereferenceThread(CsrThread);
813 continue;
814 }
815 }
816
817 /* Validation complete, start SEH */
819 {
820 /* Make sure we have enough threads */
822
823 Teb->CsrClientThread = CsrThread;
824
825 /* Call the API, get the reply code and return the result */
826 ReplyCode = CsrReplyImmediately;
827 ReplyMsg->Status = ServerDll->DispatchTable[ApiId](&ReceiveMsg, &ReplyCode);
828
829 /* Increase the static thread count */
831
832 Teb->CsrClientThread = CurrentThread;
833
834 if (ReplyCode == CsrReplyAlreadySent)
835 {
836 if (ReceiveMsg.CsrCaptureData)
837 {
838 CsrReleaseCapturedArguments(&ReceiveMsg);
839 }
840 ReplyMsg = NULL;
841 ReplyPort = CsrApiPort;
842 CsrDereferenceThread(CsrThread);
843 }
844 else if (ReplyCode == CsrReplyDeadClient)
845 {
846 /* Reply to the death message */
847 NTSTATUS Status2;
848 Status2 = NtReplyPort(ReplyPort, &ReplyMsg->Header);
849 if (!NT_SUCCESS(Status2))
850 DPRINT1("CSRSS: Error while replying to the death message, Status 0x%lx\n", Status2);
851
852 /* Reply back to the API port now */
853 ReplyMsg = NULL;
854 ReplyPort = CsrApiPort;
855 CsrDereferenceThread(CsrThread);
856 }
857 else if (ReplyCode == CsrReplyPending)
858 {
859 ReplyMsg = NULL;
860 ReplyPort = CsrApiPort;
861 }
862 else
863 {
864 if (ReceiveMsg.CsrCaptureData)
865 {
866 CsrReleaseCapturedArguments(&ReceiveMsg);
867 }
868 CsrDereferenceThread(CsrThread);
869 }
870 }
872 {
873 ReplyMsg = NULL;
874 ReplyPort = CsrApiPort;
875 }
876 _SEH2_END;
877 }
878
879 /* We're out of the loop for some reason, terminate! */
881 return Status;
882}
#define NtCurrentPeb()
Definition: FLS.c:22
#define CSR_API_NUMBER_TO_API_ID(ApiNumber)
Definition: csrmsg.h:43
#define CSR_API_NUMBER_TO_SERVER_ID(ApiNumber)
Definition: csrmsg.h:40
EXCEPTION_DISPOSITION NTAPI CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: server.c:643
NTSTATUS NTAPI CsrDestroyProcess(IN PCLIENT_ID Cid, IN NTSTATUS ExitStatus)
Definition: procsup.c:735
enum _CSR_REPLY_CODE CSR_REPLY_CODE
NTSTATUS NTAPI CsrDestroyThread(IN PCLIENT_ID Cid)
Definition: thredsup.c:814
VOID NTAPI CsrDereferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:776
@ CsrReplyAlreadySent
Definition: csrsrv.h:134
@ CsrReplyImmediately
Definition: csrsrv.h:131
@ CsrReplyDeadClient
Definition: csrsrv.h:133
@ CsrReplyPending
Definition: csrsrv.h:132
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
struct _DBGKM_MSG * PDBGKM_MSG
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1527
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
NTSYSAPI void WINAPI DbgBreakPoint(void)
struct _CLIENT_DIED_MSG * PCLIENT_DIED_MSG
#define LPC_ERROR_EVENT
Definition: port.c:101
#define LPC_EXCEPTION
Definition: port.c:99
#define LPC_CLIENT_DIED
Definition: port.c:98
#define LPC_REQUEST
Definition: port.c:93
#define LPC_DATAGRAM
Definition: port.c:95
#define LPC_CONNECTION_REQUEST
Definition: port.c:102
#define LPC_PORT_CLOSED
Definition: port.c:97
struct _HARDERROR_MSG * PHARDERROR_MSG
@ ResponseNotHandled
Definition: extypes.h:200
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1279
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:876
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
NTSTATUS NTAPI NtReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE ReplyMessage)
Definition: reply.c:190
NTSTATUS NTAPI NtReplyWaitReceivePort(IN HANDLE PortHandle, OUT PVOID *PortContext OPTIONAL, IN PPORT_MESSAGE ReplyMessage OPTIONAL, OUT PPORT_MESSAGE ReceiveMessage)
Definition: reply.c:743
#define STATUS_INVALID_CID
Definition: ntstatus.h:248
#define DBG_CONTINUE
Definition: ntstatus.h:47
#define STATUS_ABANDONED
Definition: ntstatus.h:75
#define STATUS_ILLEGAL_FUNCTION
Definition: ntstatus.h:411
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
LARGE_INTEGER CreateTime
Definition: lpctypes.h:270
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
NTSTATUS Status
Definition: csrmsg.h:110
PCSR_CAPTURE_BUFFER CsrCaptureData
Definition: csrmsg.h:108
PORT_MESSAGE Header
Definition: csrmsg.h:102
CSR_API_NUMBER ApiNumber
Definition: csrmsg.h:109
HANDLE ClientPort
Definition: csrsrv.h:43
PCSR_HARDERROR_CALLBACK HardErrorCallback
Definition: csrsrv.h:237
ULONG HighestApiSupported
Definition: csrsrv.h:223
ANSI_STRING Name
Definition: csrsrv.h:218
PCSR_API_ROUTINE * DispatchTable
Definition: csrsrv.h:224
ULONG ApiBase
Definition: csrsrv.h:222
LARGE_INTEGER CreateTime
Definition: csrsrv.h:65
CLIENT_ID ClientId
Definition: csrsrv.h:68
NTSTATUS ReturnedStatus
Definition: dbgktypes.h:210
ULONG Response
Definition: extypes.h:670
CLIENT_ID ClientId
Definition: winternl.h:1751
Definition: compat.h:836
ULONG Win32ClientInfo[31]
Definition: compat.h:847
ULONG CountOfOwnedCriticalSections
Definition: compat.h:844
CLIENT_ID ClientId
Definition: compat.h:839
CLIENT_ID RealClientId
Definition: compat.h:861
PVOID CsrClientThread
Definition: compat.h:845
VOID NTAPI CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:1337
volatile ULONG CsrpStaticThreadCount
Definition: api.c:23
NTSTATUS NTAPI CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:144
volatile ULONG CsrpDynamicThreadTotal
Definition: api.c:24
PCSR_THREAD NTAPI CsrConnectToUser(VOID)
Definition: api.c:1021
NTSTATUS NTAPI CsrpCheckRequestThreads(VOID)
Definition: api.c:259
BOOLEAN NTAPI CsrCaptureArguments(IN PCSR_THREAD CsrThread, IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:1123
VOID NTAPI CsrLockedReferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:154
VOID NTAPI CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:467
#define CSR_SERVER_DLL_MAX
Definition: api.h:34
PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]
Definition: server.c:20
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336
#define NtCurrentThread()

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 = NULL;
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#ifdef CSR_DBG
68 DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
69 ServerId, ServerDll);
70 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
71#endif
72 ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
74 }
75 else
76 {
77 /* Get the API ID, normalized with our Base ID */
78 ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg->ApiNumber) - ServerDll->ApiBase;
79
80 /* Make sure that the ID is within limits, and the entry exists */
81 if ((ApiId >= ServerDll->HighestApiSupported) ||
82 ((ServerDll->ValidTable) && !(ServerDll->ValidTable[ApiId])))
83 {
84 /* We are beyond the Maximum API ID, or it doesn't exist */
85#ifdef CSR_DBG
86 DPRINT1("API: %d\n", ApiId);
87 DPRINT1("CSRSS: %lx (%s) is invalid ApiTableIndex for %Z or is an "
88 "invalid API to call from the server.\n",
89 ApiId,
90 ((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ?
91 ServerDll->NameTable[ApiId] : "*** UNKNOWN ***",
92 &ServerDll->Name);
93 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
94#endif
95 ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
97 }
98 }
99
100#ifdef CSR_DBG
101 if (CsrDebug & 2)
102 {
103 DPRINT1("CSRSS: %s Api Request received from server process\n",
104 ServerDll->NameTable[ApiId]);
105 }
106#endif
107
108 /* Validation complete, start SEH */
110 {
111 /* Call the API, get the reply code and return the result */
112 ReplyMsg->Status = ServerDll->DispatchTable[ApiId](ReceiveMsg, &ReplyCode);
113 }
115 {
116 /* If we got an exception, return access violation */
117 ReplyMsg->Status = STATUS_ACCESS_VIOLATION;
118 }
119 _SEH2_END;
120
121 /* Return success */
122 return STATUS_SUCCESS;
123}
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
PBOOLEAN ValidTable
Definition: csrsrv.h:225

◆ CsrCaptureArguments()

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

Definition at line 1123 of file api.c.

1125{
1126 PCSR_PROCESS CsrProcess = CsrThread->Process;
1127 PCSR_CAPTURE_BUFFER ClientCaptureBuffer, ServerCaptureBuffer = NULL;
1128 ULONG_PTR EndOfClientBuffer;
1129 SIZE_T SizeOfBufferThroughOffsetsArray;
1130 SIZE_T BufferDistance;
1131 ULONG Length;
1132 ULONG PointerCount;
1133 PULONG_PTR OffsetPointer;
1134 ULONG_PTR CurrentOffset;
1135
1136 /* Get the buffer we got from whoever called NTDLL */
1137 ClientCaptureBuffer = ApiMessage->CsrCaptureData;
1138
1139 /* Use SEH to validate and capture the client buffer */
1140 _SEH2_TRY
1141 {
1142 /* Check whether at least the buffer's header is inside our mapped section */
1143 if ( ((ULONG_PTR)ClientCaptureBuffer < CsrProcess->ClientViewBase) ||
1144 (((ULONG_PTR)ClientCaptureBuffer + FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray))
1145 >= CsrProcess->ClientViewBounds) )
1146 {
1147#ifdef CSR_DBG
1148 DPRINT1("*** CSRSS: CaptureBuffer outside of ClientView 1\n");
1149 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1150#endif
1151 /* Return failure */
1152 ApiMessage->Status = STATUS_INVALID_PARAMETER;
1153 _SEH2_YIELD(return FALSE);
1154 }
1155
1156 /* Capture the buffer length */
1157 Length = ((volatile CSR_CAPTURE_BUFFER*)ClientCaptureBuffer)->Size;
1158
1159 /*
1160 * Now check if the remaining of the buffer is inside our mapped section.
1161 * Take also care for any possible wrap-around of the buffer end-address.
1162 */
1163 EndOfClientBuffer = (ULONG_PTR)ClientCaptureBuffer + Length;
1164 if ( (EndOfClientBuffer < (ULONG_PTR)ClientCaptureBuffer) ||
1165 (EndOfClientBuffer >= CsrProcess->ClientViewBounds) )
1166 {
1167#ifdef CSR_DBG
1168 DPRINT1("*** CSRSS: CaptureBuffer outside of ClientView 2\n");
1169 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1170#endif
1171 /* Return failure */
1172 ApiMessage->Status = STATUS_INVALID_PARAMETER;
1173 _SEH2_YIELD(return FALSE);
1174 }
1175
1176 /* Capture the pointer count */
1177 PointerCount = ((volatile CSR_CAPTURE_BUFFER*)ClientCaptureBuffer)->PointerCount;
1178
1179 /*
1180 * Check whether the total buffer size and the pointer count are consistent
1181 * -- the array of offsets must be contained inside the buffer.
1182 */
1183 SizeOfBufferThroughOffsetsArray =
1184 FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) +
1185 (PointerCount * sizeof(PVOID));
1186 if ( (PointerCount > MAXUSHORT) ||
1187 (SizeOfBufferThroughOffsetsArray > Length) )
1188 {
1189#ifdef CSR_DBG
1190 DPRINT1("*** CSRSS: CaptureBuffer %p has bad length\n", ClientCaptureBuffer);
1191 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1192#endif
1193 /* Return failure */
1194 ApiMessage->Status = STATUS_INVALID_PARAMETER;
1195 _SEH2_YIELD(return FALSE);
1196 }
1197 }
1199 {
1200#ifdef CSR_DBG
1201 DPRINT1("*** CSRSS: Took exception during capture %x\n", _SEH2_GetExceptionCode());
1202 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1203#endif
1204 /* Return failure */
1205 ApiMessage->Status = STATUS_INVALID_PARAMETER;
1206 _SEH2_YIELD(return FALSE);
1207 }
1208 _SEH2_END;
1209
1210 /* We validated the client buffer, now allocate the server buffer */
1211 ServerCaptureBuffer = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
1212 if (!ServerCaptureBuffer)
1213 {
1214 /* We're out of memory */
1215 ApiMessage->Status = STATUS_NO_MEMORY;
1216 return FALSE;
1217 }
1218
1219 /*
1220 * Copy the client's buffer and ensure we use the correct buffer length
1221 * and pointer count we captured and used for validation earlier on.
1222 */
1223 _SEH2_TRY
1224 {
1225 RtlMoveMemory(ServerCaptureBuffer, ClientCaptureBuffer, Length);
1226 }
1228 {
1229#ifdef CSR_DBG
1230 DPRINT1("*** CSRSS: Took exception during capture %x\n", _SEH2_GetExceptionCode());
1231 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1232#endif
1233 /* Failure, free the buffer and return */
1234 RtlFreeHeap(CsrHeap, 0, ServerCaptureBuffer);
1235 ApiMessage->Status = STATUS_INVALID_PARAMETER;
1236 _SEH2_YIELD(return FALSE);
1237 }
1238 _SEH2_END;
1239
1240 ServerCaptureBuffer->Size = Length;
1241 ServerCaptureBuffer->PointerCount = PointerCount;
1242
1243 /* Calculate the difference between our buffer and the client's */
1244 BufferDistance = (ULONG_PTR)ServerCaptureBuffer - (ULONG_PTR)ClientCaptureBuffer;
1245
1246 /*
1247 * All the pointer offsets correspond to pointers that point
1248 * to the server data buffer instead of the client one.
1249 */
1250 // PointerCount = ServerCaptureBuffer->PointerCount;
1251 OffsetPointer = ServerCaptureBuffer->PointerOffsetsArray;
1252 while (PointerCount--)
1253 {
1254 CurrentOffset = *OffsetPointer;
1255
1256 if (CurrentOffset != 0)
1257 {
1258 /*
1259 * Check whether the offset is pointer-aligned and whether
1260 * it points inside CSR_API_MESSAGE::Data.ApiMessageData.
1261 */
1262 if ( ((CurrentOffset & (sizeof(PVOID)-1)) != 0) ||
1263 (CurrentOffset < FIELD_OFFSET(CSR_API_MESSAGE, Data.ApiMessageData)) ||
1264 (CurrentOffset >= sizeof(CSR_API_MESSAGE)) )
1265 {
1266#ifdef CSR_DBG
1267 DPRINT1("*** CSRSS: CaptureBuffer MessagePointer outside of message\n");
1268 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1269#endif
1270 /* Invalid pointer, fail */
1271 ApiMessage->Status = STATUS_INVALID_PARAMETER;
1272 break;
1273 }
1274
1275 /* Get the pointer corresponding to the offset */
1276 CurrentOffset += (ULONG_PTR)ApiMessage;
1277
1278 /* Validate the bounds of the current pointed pointer */
1279 if ( (*(PULONG_PTR)CurrentOffset >= ((ULONG_PTR)ClientCaptureBuffer +
1280 SizeOfBufferThroughOffsetsArray)) &&
1281 (*(PULONG_PTR)CurrentOffset <= (EndOfClientBuffer - sizeof(PVOID))) )
1282 {
1283 /* Modify the pointed pointer to take into account its new position */
1284 *(PULONG_PTR)CurrentOffset += BufferDistance;
1285 }
1286 else
1287 {
1288#ifdef CSR_DBG
1289 DPRINT1("*** CSRSS: CaptureBuffer MessagePointer outside of ClientView\n");
1290 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1291#endif
1292 /* Invalid pointer, fail */
1293 ApiMessage->Status = STATUS_INVALID_PARAMETER;
1294 break;
1295 }
1296 }
1297
1298 ++OffsetPointer;
1299 }
1300
1301 /* Check if we got success */
1302 if (ApiMessage->Status != STATUS_SUCCESS)
1303 {
1304 /* Failure, free the buffer and return */
1305 RtlFreeHeap(CsrHeap, 0, ServerCaptureBuffer);
1306 return FALSE;
1307 }
1308 else
1309 {
1310 /* Success, save the previous buffer and use the server capture buffer */
1311 ServerCaptureBuffer->PreviousCaptureBuffer = ClientCaptureBuffer;
1312 ApiMessage->CsrCaptureData = ServerCaptureBuffer;
1313 }
1314
1315 /* Success */
1316 return TRUE;
1317}
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
ULONG PointerCount
Definition: csrmsg.h:94
ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]
Definition: csrmsg.h:96
struct _CSR_CAPTURE_BUFFER * PreviousCaptureBuffer
Definition: csrmsg.h:93
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define MAXUSHORT
Definition: typedefs.h:83
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by CsrApiRequestThread().

◆ CsrConnectToUser()

PCSR_THREAD NTAPI CsrConnectToUser ( VOID  )

Definition at line 1021 of file api.c.

1022{
1024 ANSI_STRING DllName;
1025 UNICODE_STRING TempName;
1026 HANDLE hUser32;
1027 STRING StartupName;
1028 PTEB Teb = NtCurrentTeb();
1029 PCSR_THREAD CsrThread;
1030 BOOLEAN Connected;
1031
1032 /* Check if we didn't already find it */
1034 {
1035 /* Get the DLL Handle for user32.dll */
1036 RtlInitAnsiString(&DllName, "user32");
1037 RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE);
1039 NULL,
1040 &TempName,
1041 &hUser32);
1042 RtlFreeUnicodeString(&TempName);
1043
1044 /* If we got the handle, get the Client Thread Startup Entrypoint */
1045 if (NT_SUCCESS(Status))
1046 {
1047 RtlInitAnsiString(&StartupName,"ClientThreadSetup");
1049 &StartupName,
1050 0,
1052 }
1053 }
1054
1055 /* Connect to user32 */
1056 _SEH2_TRY
1057 {
1058 Connected = CsrClientThreadSetup();
1059 }
1061 {
1062 Connected = FALSE;
1063 }
1064 _SEH2_END;
1065
1066 if (!Connected)
1067 {
1068 DPRINT1("CSRSS: CsrConnectToUser failed\n");
1069 return NULL;
1070 }
1071
1072 /* Save pointer to this thread in TEB */
1074 CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
1076 if (CsrThread) Teb->CsrClientThread = CsrThread;
1077
1078 /* Return it */
1079 return CsrThread;
1080}
std::wstring STRING
Definition: fontsub.cpp:33
NTSTATUS NTAPI LdrGetDllHandle(_In_opt_ PWSTR DllPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *DllHandle)
Definition: ldrapi.c:770
NTSTATUS NTAPI LdrGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress)
Definition: ldrapi.c:789
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
BOOLEAN(* CsrClientThreadSetup)(VOID)
Definition: api.c:21
PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, IN PCLIENT_ID Cid)
Definition: thredsup.c:248

Referenced by CsrApiRequestThread(), and GuiConsoleInputThread().

◆ CsrpCheckRequestThreads()

NTSTATUS NTAPI CsrpCheckRequestThreads ( VOID  )

Definition at line 259 of file api.c.

260{
264
265 /* Decrease the count, and see if we're out */
267 {
268 /* Check if we've still got space for a Dynamic Thread */
270 {
271 /* Create a new dynamic thread */
273 NULL,
274 TRUE,
275 0,
276 0,
277 0,
279 NULL,
280 &hThread,
281 &ClientId);
282 /* Check success */
283 if (NT_SUCCESS(Status))
284 {
285 /* Increase the thread counts */
288
289 /* Add a new server thread */
291 &ClientId,
293 {
294 /* Activate it */
296 }
297 else
298 {
299 /* Failed to create a new static thread */
302
303 /* Terminate it */
304 DPRINT1("Failing\n");
307
308 /* Return */
309 return STATUS_UNSUCCESSFUL;
310 }
311 }
312 }
313 }
314
315 /* Success */
316 return STATUS_SUCCESS;
317}
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1524
ULONG CsrMaxApiRequestThreads
Definition: init.c:38

Referenced by CsrApiRequestThread().

◆ CsrQueryApiPort()

HANDLE NTAPI CsrQueryApiPort ( VOID  )

Definition at line 1097 of file api.c.

1098{
1099 return CsrApiPort;
1100}

Referenced by CSR_API(), and UserClientConnect().

◆ CsrReleaseCapturedArguments()

VOID NTAPI CsrReleaseCapturedArguments ( IN PCSR_API_MESSAGE  ApiMessage)

Definition at line 1337 of file api.c.

1338{
1339 PCSR_CAPTURE_BUFFER ServerCaptureBuffer, ClientCaptureBuffer;
1340 SIZE_T BufferDistance;
1341 ULONG PointerCount;
1342 PULONG_PTR OffsetPointer;
1343 ULONG_PTR CurrentOffset;
1344
1345 /* Get the server capture buffer */
1346 ServerCaptureBuffer = ApiMessage->CsrCaptureData;
1347
1348 /* Do not continue if there is no captured buffer */
1349 if (!ServerCaptureBuffer) return;
1350
1351 /* If there is one, get the corresponding client capture buffer */
1352 ClientCaptureBuffer = ServerCaptureBuffer->PreviousCaptureBuffer;
1353
1354 /* Free the previous one and use again the client capture buffer */
1355 ServerCaptureBuffer->PreviousCaptureBuffer = NULL;
1356 ApiMessage->CsrCaptureData = ClientCaptureBuffer;
1357
1358 /* Calculate the difference between our buffer and the client's */
1359 BufferDistance = (ULONG_PTR)ServerCaptureBuffer - (ULONG_PTR)ClientCaptureBuffer;
1360
1361 /*
1362 * All the pointer offsets correspond to pointers that point
1363 * to the client data buffer instead of the server one (reverse
1364 * the logic of CsrCaptureArguments()).
1365 */
1366 PointerCount = ServerCaptureBuffer->PointerCount;
1367 OffsetPointer = ServerCaptureBuffer->PointerOffsetsArray;
1368 while (PointerCount--)
1369 {
1370 CurrentOffset = *OffsetPointer;
1371
1372 if (CurrentOffset != 0)
1373 {
1374 /* Get the pointer corresponding to the offset */
1375 CurrentOffset += (ULONG_PTR)ApiMessage;
1376
1377 /* Modify the pointed pointer to take into account its new position */
1378 *(PULONG_PTR)CurrentOffset -= BufferDistance;
1379 }
1380
1381 ++OffsetPointer;
1382 }
1383
1384 /* Copy the data back into the client buffer */
1385 _SEH2_TRY
1386 {
1387 RtlMoveMemory(ClientCaptureBuffer, ServerCaptureBuffer, ServerCaptureBuffer->Size);
1388 }
1390 {
1391#ifdef CSR_DBG
1392 DPRINT1("*** CSRSS: Took exception during release %x\n", _SEH2_GetExceptionCode());
1393 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1394#endif
1395 /* Return failure */
1396 ApiMessage->Status = _SEH2_GetExceptionCode();
1397 }
1398 _SEH2_END;
1399
1400 /* Free our allocated buffer */
1401 RtlFreeHeap(CsrHeap, 0, ServerCaptureBuffer);
1402}

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 1430 of file api.c.

1434{
1435 PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData;
1436 SIZE_T BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage;
1437 ULONG PointerCount;
1438 PULONG_PTR OffsetPointer;
1439
1440 /*
1441 * Check whether we have a valid buffer pointer, elements
1442 * of non-trivial size and that we don't overflow.
1443 */
1444 if (!Buffer || ElementSize == 0 ||
1445 (ULONGLONG)ElementCount * ElementSize > (ULONGLONG)MAXULONG)
1446 {
1447 return FALSE;
1448 }
1449
1450 /* Check if didn't get a buffer and there aren't any arguments to check */
1451 // if (!*Buffer && (ElementCount * ElementSize == 0))
1452 if (!*Buffer && ElementCount == 0) // Here ElementSize != 0 therefore only ElementCount can be == 0
1453 return TRUE;
1454
1455 /* Check if we have no capture buffer */
1456 if (!CaptureBuffer)
1457 {
1458 /* In this case, succeed only if the caller is CSRSS */
1459 if (NtCurrentTeb()->ClientId.UniqueProcess ==
1460 ApiMessage->Header.ClientId.UniqueProcess)
1461 {
1462 return TRUE;
1463 }
1464 }
1465 else
1466 {
1467 /* Make sure that there is still space left in the capture buffer */
1468 if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) >=
1469 (ElementCount * ElementSize))
1470 {
1471 /* Perform the validation test */
1472 PointerCount = CaptureBuffer->PointerCount;
1473 OffsetPointer = CaptureBuffer->PointerOffsetsArray;
1474 while (PointerCount--)
1475 {
1476 /*
1477 * Find in the array, the pointer offset (from the
1478 * API message) that corresponds to the buffer.
1479 */
1480 if (*OffsetPointer == BufferDistance)
1481 {
1482 return TRUE;
1483 }
1484 ++OffsetPointer;
1485 }
1486 }
1487 }
1488
1489 /* Failure */
1490#ifdef CSR_DBG
1491 DPRINT1("CSRSRV: Bad message buffer %p\n", ApiMessage);
1492 if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
1493#endif
1494 return FALSE;
1495}
Definition: bufpool.h:45
#define MAXULONG
Definition: typedefs.h:251
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by CON_API(), CON_API_NOCONSOLE(), CSR_API(), and CsrValidateMessageString().

◆ CsrValidateMessageString()

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

Definition at line 1517 of file api.c.

1519{
1520 if (MessageString)
1521 {
1522 return CsrValidateMessageBuffer(ApiMessage,
1523 (PVOID*)MessageString,
1524 wcslen(*MessageString) + 1,
1525 sizeof(WCHAR));
1526 }
1527 else
1528 {
1529 return FALSE;
1530 }
1531}
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430

Variable Documentation

◆ CsrApiPortName

UNICODE_STRING CsrApiPortName

Definition at line 22 of file api.c.

Referenced by CsrApiPortInitialize().

◆ CsrClientThreadSetup

BOOLEAN(* CsrClientThreadSetup) (VOID) ( VOID  ) = NULL

Definition at line 21 of file api.c.

Referenced by CsrConnectToUser().

◆ CsrMaxApiRequestThreads

ULONG CsrMaxApiRequestThreads
extern

Definition at line 38 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().