ReactOS 0.4.15-dev-7924-g5949c20
api.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Client/Server Runtime SubSystem
4 * FILE: subsystems/win32/csrsrv/api.c
5 * PURPOSE: CSR Server DLL API LPC Implementation
6 * "\Windows\ApiPort" port process management functions
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 */
9
10/* INCLUDES *******************************************************************/
11
12#include "srv.h"
13
14#include <ndk/kefuncs.h>
15
16#define NDEBUG
17#include <debug.h>
18
19/* GLOBALS ********************************************************************/
20
26
27/* FUNCTIONS ******************************************************************/
28
29/*++
30 * @name CsrCallServerFromServer
31 * @implemented NT4
32 *
33 * The CsrCallServerFromServer routine calls a CSR API from within a server.
34 * It avoids using LPC messages since the request isn't coming from a client.
35 *
36 * @param ReceiveMsg
37 * Pointer to the CSR API Message to send to the server.
38 *
39 * @param ReplyMsg
40 * Pointer to the CSR API Message to receive from the server.
41 *
42 * @return STATUS_SUCCESS in case of success, STATUS_ILLEGAL_FUNCTION
43 * if the ApiNumber is invalid, or STATUS_ACCESS_VIOLATION if there
44 * was a problem executing the API.
45 *
46 * @remarks None.
47 *
48 *--*/
52 IN OUT PCSR_API_MESSAGE ReplyMsg)
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}
124
125/*++
126 * @name CsrApiHandleConnectionRequest
127 *
128 * The CsrApiHandleConnectionRequest routine handles and accepts a new
129 * connection request to the CSR API LPC Port.
130 *
131 * @param ApiMessage
132 * Pointer to the incoming CSR API Message which contains the
133 * connection request.
134 *
135 * @return STATUS_SUCCESS in case of success, or status code which caused
136 * the routine to error.
137 *
138 * @remarks This routine is responsible for attaching the Shared Section to
139 * new clients connecting to CSR.
140 *
141 *--*/
143NTAPI
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}
241
242/*++
243 * @name CsrpCheckRequestThreads
244 *
245 * The CsrpCheckRequestThreads routine checks if there are no more threads
246 * to handle CSR API Requests, and creates a new thread if possible, to
247 * avoid starvation.
248 *
249 * @param None.
250 *
251 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
252 * if a new thread couldn't be created.
253 *
254 * @remarks None.
255 *
256 *--*/
258NTAPI
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}
318
319/*++
320 * @name CsrApiRequestThread
321 *
322 * The CsrApiRequestThread routine handles incoming messages or connection
323 * requests on the CSR API LPC Port.
324 *
325 * @param Parameter
326 * System-default user-defined parameter. Unused.
327 *
328 * @return The thread exit code, if the thread is terminated.
329 *
330 * @remarks Before listening on the port, the routine will first attempt
331 * to connect to the user subsystem.
332 *
333 *--*/
335NTAPI
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}
883
884/*++
885 * @name CsrApiPortInitialize
886 *
887 * The CsrApiPortInitialize routine initializes the LPC Port used for
888 * communications with the Client/Server Runtime (CSR) and initializes the
889 * static thread that will handle connection requests and APIs.
890 *
891 * @param None
892 *
893 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
894 *
895 * @remarks None.
896 *
897 *--*/
899NTAPI
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}
1005
1006/*++
1007 * @name CsrConnectToUser
1008 * @implemented NT4
1009 *
1010 * The CsrConnectToUser connects to the User subsystem.
1011 *
1012 * @param None
1013 *
1014 * @return A pointer to the CSR Thread
1015 *
1016 * @remarks None.
1017 *
1018 *--*/
1020NTAPI
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}
1081
1082/*++
1083 * @name CsrQueryApiPort
1084 * @implemented NT4
1085 *
1086 * The CsrQueryApiPort routine returns a handle to the CSR API LPC port.
1087 *
1088 * @param None.
1089 *
1090 * @return A handle to the port.
1091 *
1092 * @remarks None.
1093 *
1094 *--*/
1095HANDLE
1096NTAPI
1098{
1099 return CsrApiPort;
1100}
1101
1102/*++
1103 * @name CsrCaptureArguments
1104 * @implemented NT5.1
1105 *
1106 * The CsrCaptureArguments routine validates a CSR Capture Buffer and
1107 * re-captures it into a server CSR Capture Buffer.
1108 *
1109 * @param CsrThread
1110 * Pointer to the CSR Thread performing the validation.
1111 *
1112 * @param ApiMessage
1113 * Pointer to the CSR API Message containing the Capture Buffer
1114 * that needs to be validated.
1115 *
1116 * @return TRUE if validation succeeded, FALSE otherwise.
1117 *
1118 * @remarks None.
1119 *
1120 *--*/
1121BOOLEAN
1122NTAPI
1124 IN PCSR_API_MESSAGE ApiMessage)
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}
1318
1319/*++
1320 * @name CsrReleaseCapturedArguments
1321 * @implemented NT5.1
1322 *
1323 * The CsrReleaseCapturedArguments routine releases a Capture Buffer
1324 * that was previously captured with CsrCaptureArguments.
1325 *
1326 * @param ApiMessage
1327 * Pointer to the CSR API Message containing the Capture Buffer
1328 * that needs to be released.
1329 *
1330 * @return None.
1331 *
1332 * @remarks None.
1333 *
1334 *--*/
1335VOID
1336NTAPI
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}
1403
1404/*++
1405 * @name CsrValidateMessageBuffer
1406 * @implemented NT5.1
1407 *
1408 * The CsrValidateMessageBuffer routine validates a captured message buffer
1409 * present in the CSR Api Message
1410 *
1411 * @param ApiMessage
1412 * Pointer to the CSR API Message containing the CSR Capture Buffer.
1413 *
1414 * @param Buffer
1415 * Pointer to the message buffer to validate.
1416 *
1417 * @param ElementCount
1418 * Number of elements contained in the message buffer.
1419 *
1420 * @param ElementSize
1421 * Size of each element.
1422 *
1423 * @return TRUE if validation succeeded, FALSE otherwise.
1424 *
1425 * @remarks None.
1426 *
1427 *--*/
1428BOOLEAN
1429NTAPI
1431 IN PVOID *Buffer,
1432 IN ULONG ElementCount,
1433 IN ULONG ElementSize)
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}
1496
1497/*++
1498 * @name CsrValidateMessageString
1499 * @implemented NT5.1
1500 *
1501 * The CsrValidateMessageString validates a captured Wide-Character String
1502 * present in a CSR API Message.
1503 *
1504 * @param ApiMessage
1505 * Pointer to the CSR API Message containing the CSR Capture Buffer.
1506 *
1507 * @param MessageString
1508 * Pointer to the buffer containing the string to validate.
1509 *
1510 * @return TRUE if validation succeeded, FALSE otherwise.
1511 *
1512 * @remarks None.
1513 *
1514 *--*/
1515BOOLEAN
1516NTAPI
1518 IN PWSTR *MessageString)
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}
1532
1533/* EOF */
static const INTERNET_PORT ServerPort
Definition: CWebService.cpp:11
#define NtCurrentPeb()
Definition: FLS.c:22
UINT CALLBACK ServerThread(_Inout_ PVOID Parameter)
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
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
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define CSR_API_NUMBER_TO_API_ID(ApiNumber)
Definition: csrmsg.h:43
#define CSR_PORT_NAME
Definition: csrmsg.h:17
#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
PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags)
Definition: thredsup.c:512
@ CsrReplyAlreadySent
Definition: csrsrv.h:134
@ CsrReplyImmediately
Definition: csrsrv.h:131
@ CsrReplyDeadClient
Definition: csrsrv.h:133
@ CsrReplyPending
Definition: csrsrv.h:132
@ CsrThreadIsServerThread
Definition: csrsrv.h:107
struct _DBGKM_MSG * PDBGKM_MSG
#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:32
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1524
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1527
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
std::wstring STRING
Definition: fontsub.cpp:33
Status
Definition: gdiplustypes.h:25
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
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define NtCurrentTeb
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
NTSTATUS NTAPI LdrGetDllHandle(_In_opt_ PWSTR DllPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *DllHandle)
Definition: ldrapi.c:810
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:829
struct _CLIENT_DIED_MSG * PCLIENT_DIED_MSG
#define ASSERT(a)
Definition: mode.c:44
#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
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
struct _HARDERROR_MSG * PHARDERROR_MSG
@ ResponseNotHandled
Definition: extypes.h:200
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)
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1279
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:876
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ SynchronizationEvent
struct _REMOTE_PORT_VIEW REMOTE_PORT_VIEW
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
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 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
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_INVALID_CID
Definition: ntstatus.h:248
#define DBG_CONTINUE
Definition: ntstatus.h:47
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_ABANDONED
Definition: ntstatus.h:75
#define STATUS_ILLEGAL_FUNCTION
Definition: ntstatus.h:411
#define BOOLEAN
Definition: pedump.c:73
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define STATUS_SUCCESS
Definition: shellext.h:65
#define UNICODE_PATH_SEP
Definition: srv.h:49
LARGE_INTEGER CreateTime
Definition: lpctypes.h:270
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
HANDLE ServerProcessId
Definition: csrmsg.h:57
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
ULONG PointerCount
Definition: csrmsg.h:94
ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]
Definition: csrmsg.h:96
struct _CSR_CAPTURE_BUFFER * PreviousCaptureBuffer
Definition: csrmsg.h:93
LIST_ENTRY ThreadList
Definition: csrsrv.h:40
HANDLE ClientPort
Definition: csrsrv.h:43
PCSR_HARDERROR_CALLBACK HardErrorCallback
Definition: csrsrv.h:237
ULONG HighestApiSupported
Definition: csrsrv.h:223
PBOOLEAN ValidTable
Definition: csrsrv.h:225
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
PCSR_PROCESS Process
Definition: csrsrv.h:69
NTSTATUS ReturnedStatus
Definition: dbgktypes.h:210
ULONG Response
Definition: extypes.h:670
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
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
USHORT MaximumLength
Definition: env_spec_w32.h:370
HANDLE CsrApiPort
Definition: connect.c:27
BOOLEAN(* CsrClientThreadSetup)(VOID)
Definition: api.c:21
HANDLE NTAPI CsrQueryApiPort(VOID)
Definition: api.c:1097
VOID NTAPI CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:1337
UNICODE_STRING CsrApiPortName
Definition: api.c:22
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430
volatile ULONG CsrpStaticThreadCount
Definition: api.c:23
NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter)
Definition: api.c:336
NTSTATUS NTAPI CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
Definition: api.c:144
volatile ULONG CsrpDynamicThreadTotal
Definition: api.c:24
NTSTATUS NTAPI CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, IN OUT PCSR_API_MESSAGE ReplyMsg)
Definition: api.c:51
NTSTATUS NTAPI CsrApiPortInitialize(VOID)
Definition: api.c:900
ULONG CsrMaxApiRequestThreads
Definition: init.c:38
BOOLEAN NTAPI CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage, IN PWSTR *MessageString)
Definition: api.c:1517
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
PCSR_PROCESS CsrRootProcess
Definition: procsup.c:22
VOID NTAPI CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:467
UNICODE_STRING CsrDirectoryName
Definition: init.c:27
NTSTATUS NTAPI CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL, OUT PCSR_API_CONNECTINFO ConnectInfo)
Definition: server.c:482
PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, IN PCLIENT_ID Cid)
Definition: thredsup.c:248
ULONG CsrDebug
Definition: init.c:23
#define CSR_SERVER_DLL_MAX
Definition: api.h:34
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
HANDLE CsrHeap
Definition: init.c:25
PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]
Definition: server.c:20
#define CsrReleaseProcessLock()
Definition: api.h:15
VOID NTAPI CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
Definition: procsup.c:159
uint16_t * PWSTR
Definition: typedefs.h:56
#define MAXULONG
Definition: typedefs.h:251
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
static int Link(const char **args)
Definition: vfdcmd.c:2414
PKPROCESS CsrProcess
Definition: videoprt.c:39
_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
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NtCurrentThread()