- Downgrade some DPRINT1s to DPRINTs.
[reactos.git] / reactos / subsystems / win32 / csrss / csrsrv / api / wapi.c
1 /* $Id$
2 *
3 * subsystems/win32/csrss/csrsrv/api/wapi.c
4 *
5 * CSRSS port message processing
6 *
7 * ReactOS Operating System
8 *
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <srv.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* GLOBALS *******************************************************************/
19
20 extern HANDLE hApiPort;
21
22 HANDLE CsrssApiHeap = (HANDLE) 0;
23
24 static unsigned ApiDefinitionsCount = 0;
25 static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
26
27 /* FUNCTIONS *****************************************************************/
28
29 NTSTATUS FASTCALL
30 CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
31 {
32 unsigned NewCount;
33 PCSRSS_API_DEFINITION Scan;
34 PCSRSS_API_DEFINITION New;
35
36 DPRINT("CSR: %s called\n", __FUNCTION__);
37
38 NewCount = 0;
39 for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
40 {
41 NewCount++;
42 }
43
44 New = RtlAllocateHeap(CsrssApiHeap, 0,
45 (ApiDefinitionsCount + NewCount)
46 * sizeof(CSRSS_API_DEFINITION));
47 if (NULL == New)
48 {
49 DPRINT1("Unable to allocate memory\n");
50 return STATUS_NO_MEMORY;
51 }
52 if (0 != ApiDefinitionsCount)
53 {
54 RtlCopyMemory(New, ApiDefinitions,
55 ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION));
56 RtlFreeHeap(CsrssApiHeap, 0, ApiDefinitions);
57 }
58 RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
59 NewCount * sizeof(CSRSS_API_DEFINITION));
60 ApiDefinitions = New;
61 ApiDefinitionsCount += NewCount;
62
63 return STATUS_SUCCESS;
64 }
65
66 VOID
67 FASTCALL
68 CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
69 PCSR_API_MESSAGE Request)
70 {
71 unsigned DefIndex;
72 ULONG Type;
73
74 DPRINT("CSR: Calling handler for type: %x.\n", Request->Type);
75 Type = Request->Type & 0xFFFF; /* FIXME: USE MACRO */
76 DPRINT("CSR: API Number: %x ServerID: %x\n",Type, Request->Type >> 16);
77
78 /* FIXME: Extract DefIndex instead of looping */
79 for (DefIndex = 0; DefIndex < ApiDefinitionsCount; DefIndex++)
80 {
81 if (ApiDefinitions[DefIndex].Type == Type)
82 {
83 if (Request->Header.u1.s1.DataLength < ApiDefinitions[DefIndex].MinRequestSize)
84 {
85 DPRINT1("Request type %d min request size %d actual %d\n",
86 Type, ApiDefinitions[DefIndex].MinRequestSize,
87 Request->Header.u1.s1.DataLength);
88 Request->Status = STATUS_INVALID_PARAMETER;
89 }
90 else
91 {
92 Request->Status = (ApiDefinitions[DefIndex].Handler)(ProcessData, Request);
93 }
94 return;
95 }
96 }
97 DPRINT1("CSR: Unknown request type 0x%x\n", Request->Type);
98 Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
99 Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
100 Request->Status = STATUS_INVALID_SYSTEM_SERVICE;
101 }
102
103 BOOL
104 CallHardError(IN PCSRSS_PROCESS_DATA ProcessData,
105 IN PHARDERROR_MSG HardErrorMessage);
106
107 static
108 VOID
109 NTAPI
110 CsrHandleHardError(IN PCSRSS_PROCESS_DATA ProcessData,
111 IN OUT PHARDERROR_MSG Message)
112 {
113 DPRINT1("CSR: received hard error %lx\n", Message->Status);
114
115 /* Call the hard error handler in win32csr */
116 (VOID)CallHardError(ProcessData, Message);
117 }
118
119 PVOID CsrSrvSharedSectionHeap;
120 PVOID CsrSrvSharedSectionBase;
121 PVOID *CsrSrvSharedStaticServerData;
122 ULONG CsrSrvSharedSectionSize;
123 HANDLE CsrSrvSharedSection;
124
125 /*++
126 * @name CsrSrvCreateSharedSection
127 *
128 * The CsrSrvCreateSharedSection creates the Shared Section that all CSR Server
129 * DLLs and Clients can use to share data.
130 *
131 * @param ParameterValue
132 * Specially formatted string from our registry command-line which
133 * specifies various arguments for the shared section.
134 *
135 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
136 * othwerwise.
137 *
138 * @remarks None.
139 *
140 *--*/
141 NTSTATUS
142 NTAPI
143 CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
144 {
145 PCHAR SizeValue = ParameterValue;
146 ULONG Size;
147 NTSTATUS Status;
148 LARGE_INTEGER SectionSize;
149 ULONG ViewSize = 0;
150 SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
151 PPEB Peb = NtCurrentPeb();
152
153 /* ReactOS Hackssss */
154 Status = NtQuerySystemInformation(SystemBasicInformation,
155 &CsrNtSysInfo,
156 sizeof(SYSTEM_BASIC_INFORMATION),
157 NULL);
158 ASSERT(NT_SUCCESS(Status));
159
160 /* Find the first comma, and null terminate */
161 while (*SizeValue)
162 {
163 if (*SizeValue == ',')
164 {
165 *SizeValue++ = '\0';
166 break;
167 }
168 else
169 {
170 SizeValue++;
171 }
172 }
173
174 /* Make sure it's valid */
175 if (!*SizeValue) return STATUS_INVALID_PARAMETER;
176
177 /* Convert it to an integer */
178 Status = RtlCharToInteger(SizeValue, 0, &Size);
179 if (!NT_SUCCESS(Status)) return Status;
180
181 /* Multiply by 1024 entries and round to page size */
182 CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize);
183 DPRINT1("Size: %lx\n", CsrSrvSharedSectionSize);
184
185 /* Create the Secion */
186 SectionSize.LowPart = CsrSrvSharedSectionSize;
187 SectionSize.HighPart = 0;
188 Status = NtCreateSection(&CsrSrvSharedSection,
189 SECTION_ALL_ACCESS,
190 NULL,
191 &SectionSize,
192 PAGE_EXECUTE_READWRITE,
193 SEC_BASED | SEC_RESERVE,
194 NULL);
195 if (!NT_SUCCESS(Status)) return Status;
196
197 /* Map the section */
198 Status = NtMapViewOfSection(CsrSrvSharedSection,
199 NtCurrentProcess(),
200 &CsrSrvSharedSectionBase,
201 0,
202 0,
203 NULL,
204 &ViewSize,
205 ViewUnmap,
206 MEM_TOP_DOWN,
207 PAGE_EXECUTE_READWRITE);
208 if(!NT_SUCCESS(Status))
209 {
210 /* Fail */
211 NtClose(CsrSrvSharedSection);
212 return(Status);
213 }
214
215 /* FIXME: Write the value to registry */
216
217 /* The Heap is the same place as the Base */
218 CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase;
219
220 /* Create the heap */
221 if (!(RtlCreateHeap(HEAP_ZERO_MEMORY,
222 CsrSrvSharedSectionHeap,
223 CsrSrvSharedSectionSize,
224 PAGE_SIZE,
225 0,
226 0)))
227 {
228 /* Failure, unmap section and return */
229 NtUnmapViewOfSection(NtCurrentProcess(),
230 CsrSrvSharedSectionBase);
231 NtClose(CsrSrvSharedSection);
232 return STATUS_NO_MEMORY;
233 }
234
235 /* Now allocate space from the heap for the Shared Data */
236 CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap,
237 0,
238 4 * // HAX CSR_SERVER_DLL_MAX *
239 sizeof(PVOID));
240
241 /* Write the values to the PEB */
242 Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase;
243 Peb->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap;
244 Peb->ReadOnlyStaticServerData = CsrSrvSharedStaticServerData;
245
246 /* Return */
247 return STATUS_SUCCESS;
248 }
249
250 /*++
251 * @name CsrSrvAttachSharedSection
252 *
253 * The CsrSrvAttachSharedSection maps the CSR Shared Section into a new
254 * CSR Process' address space, and returns the pointers to the section
255 * through the Connection Info structure.
256 *
257 * @param CsrProcess
258 * Pointer to the CSR Process that is attempting a connection.
259 *
260 * @param ConnectInfo
261 * Pointer to the CSR Connection Info structure for the incoming
262 * connection.
263 *
264 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
265 * othwerwise.
266 *
267 * @remarks None.
268 *
269 *--*/
270 NTSTATUS
271 NTAPI
272 CsrSrvAttachSharedSection(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL,
273 OUT PCSR_CONNECTION_INFO ConnectInfo)
274 {
275 NTSTATUS Status;
276 ULONG ViewSize = 0;
277
278 /* Check if we have a process */
279 if (CsrProcess)
280 {
281 /* Map the section into this process */
282 DPRINT("CSR Process Handle: %p. CSR Process: %p\n", CsrProcess->Process, CsrProcess);
283 Status = NtMapViewOfSection(CsrSrvSharedSection,
284 CsrProcess->Process,
285 &CsrSrvSharedSectionBase,
286 0,
287 0,
288 NULL,
289 &ViewSize,
290 ViewUnmap,
291 SEC_NO_CHANGE,
292 PAGE_EXECUTE_READ);
293 if (Status == STATUS_CONFLICTING_ADDRESSES)
294 {
295 /* I Think our csrss tries to connect to itself... */
296 DPRINT1("Multiple mapping hack\n");
297 Status = STATUS_SUCCESS;
298 }
299 if (!NT_SUCCESS(Status)) return Status;
300 }
301
302 /* Write the values in the Connection Info structure */
303 ConnectInfo->SharedSectionBase = CsrSrvSharedSectionBase;
304 ConnectInfo->SharedSectionHeap = CsrSrvSharedSectionHeap;
305 ConnectInfo->SharedSectionData = CsrSrvSharedStaticServerData;
306
307 /* Return success */
308 return STATUS_SUCCESS;
309 }
310
311 PBASE_STATIC_SERVER_DATA BaseStaticServerData;
312
313 VOID
314 WINAPI
315 BasepFakeStaticServerData(VOID)
316 {
317 NTSTATUS Status;
318 WCHAR Buffer[MAX_PATH];
319 PWCHAR HeapBuffer;
320 UNICODE_STRING SystemRootString;
321 UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
322 UNICODE_STRING BaseSrvCSDString;
323 UNICODE_STRING BaseSrvWindowsDirectory;
324 UNICODE_STRING BaseSrvWindowsSystemDirectory;
325 UNICODE_STRING BnoString;
326 RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] =
327 {
328 {
329 NULL,
330 RTL_QUERY_REGISTRY_DIRECT,
331 L"CSDVersion",
332 &BaseSrvCSDString
333 },
334 {0}
335 };
336
337 /* Get the Windows directory */
338 RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer));
339 Status = RtlExpandEnvironmentStrings_U(NULL,
340 &UnexpandedSystemRootString,
341 &SystemRootString,
342 NULL);
343 DPRINT1("Status: %lx. Root: %wZ\n", Status, &SystemRootString);
344 ASSERT(NT_SUCCESS(Status));
345
346 /* Create the base directory */
347 Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL;
348 Status = RtlCreateUnicodeString(&BaseSrvWindowsDirectory,
349 SystemRootString.Buffer);
350 ASSERT(NT_SUCCESS(Status));
351
352 /* Create the system directory */
353 wcscat(SystemRootString.Buffer, L"\\system32");
354 Status = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory,
355 SystemRootString.Buffer);
356 ASSERT(NT_SUCCESS(Status));
357
358 /* FIXME: Check Session ID */
359 wcscpy(Buffer, L"\\BaseNamedObjects");
360 RtlInitUnicodeString(&BnoString, Buffer);
361
362 /* Allocate the server data */
363 BaseStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap,
364 HEAP_ZERO_MEMORY,
365 sizeof(BASE_STATIC_SERVER_DATA));
366 ASSERT(BaseStaticServerData != NULL);
367
368 /* Process timezone information */
369 BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
370 BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
371 Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
372 &BaseStaticServerData->TimeOfDay,
373 sizeof(BaseStaticServerData->TimeOfDay),
374 NULL);
375 ASSERT(NT_SUCCESS(Status));
376
377 /* Make a shared heap copy of the Windows directory */
378 BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
379 HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap,
380 0,
381 BaseSrvWindowsDirectory.MaximumLength);
382 ASSERT(HeapBuffer);
383 RtlCopyMemory(HeapBuffer,
384 BaseStaticServerData->WindowsDirectory.Buffer,
385 BaseSrvWindowsDirectory.MaximumLength);
386 BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;
387
388 /* Make a shared heap copy of the System directory */
389 BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
390 HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap,
391 0,
392 BaseSrvWindowsSystemDirectory.MaximumLength);
393 ASSERT(HeapBuffer);
394 RtlCopyMemory(HeapBuffer,
395 BaseStaticServerData->WindowsSystemDirectory.Buffer,
396 BaseSrvWindowsSystemDirectory.MaximumLength);
397 BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;
398
399 /* This string is not used */
400 RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
401 NULL,
402 0);
403
404 /* Make a shared heap copy of the BNO directory */
405 BaseStaticServerData->NamedObjectDirectory = BnoString;
406 BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
407 sizeof(UNICODE_NULL);
408 HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap,
409 0,
410 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
411 ASSERT(HeapBuffer);
412 RtlCopyMemory(HeapBuffer,
413 BaseStaticServerData->NamedObjectDirectory.Buffer,
414 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
415 BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;
416
417 /*
418 * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
419 * and MaximumLength of the CSD String, since the same UNICODE_STRING is
420 * being queried twice, the first time as a ULONG!
421 *
422 * Somehow, in Windows this doesn't cause a buffer overflow, but it might
423 * in ReactOS, so this code is disabled until someone figures out WTF.
424 */
425 BaseStaticServerData->CSDNumber = 0;
426 BaseStaticServerData->RCNumber = 0;
427
428 /* Initialize the CSD string and query its value from the registry */
429 RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
430 Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
431 L"",
432 BaseServerRegistryConfigurationTable,
433 NULL,
434 NULL);
435 if (NT_SUCCESS(Status))
436 {
437 /* Copy into the shared buffer */
438 wcsncpy(BaseStaticServerData->CSDVersion,
439 BaseSrvCSDString.Buffer,
440 BaseSrvCSDString.Length / sizeof(WCHAR));
441 }
442 else
443 {
444 /* NULL-terminate to indicate nothing is there */
445 BaseStaticServerData->CSDVersion[0] = UNICODE_NULL;
446 }
447
448 /* Cache the system information */
449 Status = NtQuerySystemInformation(SystemBasicInformation,
450 &BaseStaticServerData->SysInfo,
451 sizeof(BaseStaticServerData->SysInfo),
452 NULL);
453 ASSERT(NT_SUCCESS(Status));
454
455 /* FIXME: Should query the registry for these */
456 BaseStaticServerData->DefaultSeparateVDM = FALSE;
457 BaseStaticServerData->IsWowTaskReady = FALSE;
458 BaseStaticServerData->LUIDDeviceMapsEnabled = FALSE;
459
460 /* FIXME: Symlinks */
461
462 /* Finally, set the pointer */
463 CsrSrvSharedStaticServerData[CSR_CONSOLE] = BaseStaticServerData;
464 }
465
466 NTSTATUS WINAPI
467 CsrpHandleConnectionRequest (PPORT_MESSAGE Request,
468 IN HANDLE hApiListenPort)
469 {
470 NTSTATUS Status;
471 HANDLE ServerPort = NULL, ServerThread = NULL;
472 PCSRSS_PROCESS_DATA ProcessData = NULL;
473 REMOTE_PORT_VIEW LpcRead;
474 CLIENT_ID ClientId;
475 BOOLEAN AllowConnection = FALSE;
476 PCSR_CONNECTION_INFO ConnectInfo;
477 LpcRead.Length = sizeof(LpcRead);
478 ServerPort = NULL;
479
480 DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
481
482 ConnectInfo = (PCSR_CONNECTION_INFO)(Request + 1);
483
484 /* Save the process ID */
485 RtlZeroMemory(ConnectInfo, sizeof(CSR_CONNECTION_INFO));
486 ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess;
487
488 ProcessData = CsrGetProcessData(Request->ClientId.UniqueProcess);
489 if (ProcessData == NULL)
490 {
491 ProcessData = CsrCreateProcessData(Request->ClientId.UniqueProcess);
492 if (ProcessData == NULL)
493 {
494 DPRINT1("Unable to allocate or find data for process 0x%x\n",
495 Request->ClientId.UniqueProcess);
496 }
497 }
498
499 if (ProcessData->Process == NULL)
500 {
501 OBJECT_ATTRIBUTES ObjectAttributes;
502
503 InitializeObjectAttributes(&ObjectAttributes,
504 NULL,
505 0,
506 NULL,
507 NULL);
508 DPRINT1("WARNING: CSR PROCESS WITH NO CSR PROCESS HANDLE???\n");
509 ClientId.UniqueThread = 0;
510 Status = NtOpenProcess(&ProcessData->Process,
511 PROCESS_ALL_ACCESS,
512 &ObjectAttributes,
513 &Request->ClientId);
514 DPRINT1("Status: %lx. Handle: %lx\n", Status, ProcessData->Process);
515 }
516
517 if (ProcessData)
518 {
519 /* Attach the Shared Section */
520 Status = CsrSrvAttachSharedSection(ProcessData, ConnectInfo);
521 if (NT_SUCCESS(Status))
522 {
523 DPRINT("Connection ok\n");
524 AllowConnection = TRUE;
525 }
526 else
527 {
528 DPRINT1("Shared section map failed: %lx\n", Status);
529 }
530 }
531
532 Status = NtAcceptConnectPort(&ServerPort,
533 NULL,
534 Request,
535 AllowConnection,
536 0,
537 & LpcRead);
538 if (!NT_SUCCESS(Status))
539 {
540 DPRINT1("CSR: NtAcceptConnectPort() failed\n");
541 return Status;
542 }
543
544 ProcessData->CsrSectionViewBase = LpcRead.ViewBase;
545 ProcessData->CsrSectionViewSize = LpcRead.ViewSize;
546 ProcessData->ServerCommunicationPort = ServerPort;
547
548 if (AllowConnection) Status = NtCompleteConnectPort(ServerPort);
549 if (!NT_SUCCESS(Status))
550 {
551 DPRINT1("CSR: NtCompleteConnectPort() failed\n");
552 return Status;
553 }
554
555 Status = RtlCreateUserThread(NtCurrentProcess(),
556 NULL,
557 TRUE,
558 0,
559 0,
560 0,
561 (PTHREAD_START_ROUTINE)ClientConnectionThread,
562 ServerPort,
563 & ServerThread,
564 &ClientId);
565 if (!NT_SUCCESS(Status))
566 {
567 DPRINT1("CSR: Unable to create server thread\n");
568 return Status;
569 }
570
571 CsrAddStaticServerThread(ServerThread, &ClientId, 0);
572
573 NtResumeThread(ServerThread, NULL);
574
575 NtClose(ServerThread);
576
577 Status = STATUS_SUCCESS;
578 DPRINT("CSR: %s done\n", __FUNCTION__);
579 return Status;
580 }
581
582 PCSR_THREAD
583 NTAPI
584 CsrConnectToUser(VOID)
585 {
586 PTEB Teb = NtCurrentTeb();
587 PCSR_THREAD CsrThread;
588 #if 0
589 NTSTATUS Status;
590 ANSI_STRING DllName;
591 UNICODE_STRING TempName;
592 HANDLE hUser32;
593 STRING StartupName;
594
595 /* Check if we didn't already find it */
596 if (!CsrClientThreadSetup)
597 {
598 /* Get the DLL Handle for user32.dll */
599 RtlInitAnsiString(&DllName, "user32");
600 RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE);
601 Status = LdrGetDllHandle(NULL,
602 NULL,
603 &TempName,
604 &hUser32);
605 RtlFreeUnicodeString(&TempName);
606
607 /* If we got teh handle, get the Client Thread Startup Entrypoint */
608 if (NT_SUCCESS(Status))
609 {
610 RtlInitAnsiString(&StartupName,"ClientThreadSetup");
611 Status = LdrGetProcedureAddress(hUser32,
612 &StartupName,
613 0,
614 (PVOID)&CsrClientThreadSetup);
615 }
616 }
617
618 /* Connect to user32 */
619 CsrClientThreadSetup();
620 #endif
621 /* Save pointer to this thread in TEB */
622 CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
623 if (CsrThread) Teb->CsrClientThread = CsrThread;
624
625 /* Return it */
626 return CsrThread;
627 }
628
629 VOID
630 WINAPI
631 ClientConnectionThread(HANDLE ServerPort)
632 {
633 NTSTATUS Status;
634 BYTE RawRequest[LPC_MAX_DATA_LENGTH];
635 PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
636 PCSR_API_MESSAGE Reply;
637 PCSRSS_PROCESS_DATA ProcessData;
638 PCSR_THREAD ServerThread;
639
640 DPRINT("CSR: %s called\n", __FUNCTION__);
641
642 /* Connect to user32 */
643 while (!CsrConnectToUser())
644 {
645 /* Keep trying until we get a response */
646 NtCurrentTeb()->Win32ClientInfo[0] = 0;
647 //NtDelayExecution(FALSE, &TimeOut);
648 }
649
650 /* Reply must be NULL at the first call to NtReplyWaitReceivePort */
651 ServerThread = NtCurrentTeb()->CsrClientThread;
652 Reply = NULL;
653
654 /* Loop and reply/wait for a new message */
655 for (;;)
656 {
657 /* Send the reply and wait for a new request */
658 Status = NtReplyWaitReceivePort(hApiPort,
659 0,
660 &Reply->Header,
661 &Request->Header);
662 /* Client died, continue */
663 if (Status == STATUS_INVALID_CID)
664 {
665 Reply = NULL;
666 continue;
667 }
668
669 if (!NT_SUCCESS(Status))
670 {
671 DPRINT1("NtReplyWaitReceivePort failed: %lx\n", Status);
672 break;
673 }
674
675 /* If the connection was closed, handle that */
676 if (Request->Header.u2.s2.Type == LPC_PORT_CLOSED)
677 {
678 DPRINT("Port died, oh well\n");
679 CsrFreeProcessData( Request->Header.ClientId.UniqueProcess );
680 break;
681 }
682
683 if (Request->Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
684 {
685 CsrpHandleConnectionRequest((PPORT_MESSAGE)Request, ServerPort);
686 Reply = NULL;
687 continue;
688 }
689
690 if (Request->Header.u2.s2.Type == LPC_CLIENT_DIED)
691 {
692 DPRINT("Client died, oh well\n");
693 Reply = NULL;
694 continue;
695 }
696
697 if ((Request->Header.u2.s2.Type != LPC_ERROR_EVENT) &&
698 (Request->Header.u2.s2.Type != LPC_REQUEST))
699 {
700 DPRINT1("CSR: received message %d\n", Request->Header.u2.s2.Type);
701 Reply = NULL;
702 continue;
703 }
704
705 DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
706 Request->Type,
707 Request->Header.ClientId.UniqueThread);
708
709 /* Get the Process Data */
710 ProcessData = CsrGetProcessData(Request->Header.ClientId.UniqueProcess);
711 if (ProcessData == NULL)
712 {
713 DPRINT1("Message %d: Unable to find data for process 0x%x\n",
714 Request->Header.u2.s2.Type,
715 Request->Header.ClientId.UniqueProcess);
716 break;
717 }
718 if (ProcessData->Terminated)
719 {
720 DPRINT1("Message %d: process %d already terminated\n",
721 Request->Type, Request->Header.ClientId.UniqueProcess);
722 continue;
723 }
724
725 /* Check if we got a hard error */
726 if (Request->Header.u2.s2.Type == LPC_ERROR_EVENT)
727 {
728 /* Call the Handler */
729 CsrHandleHardError(ProcessData, (PHARDERROR_MSG)Request);
730 }
731 else
732 {
733 PCSR_THREAD Thread;
734 PCSRSS_PROCESS_DATA Process = NULL;
735
736 //DPRINT1("locate thread %lx/%lx\n", Request->Header.ClientId.UniqueProcess, Request->Header.ClientId.UniqueThread);
737 Thread = CsrLocateThreadByClientId(&Process, &Request->Header.ClientId);
738 //DPRINT1("Thread found: %p %p\n", Thread, Process);
739
740 /* Call the Handler */
741 if (Thread) NtCurrentTeb()->CsrClientThread = Thread;
742 CsrApiCallHandler(ProcessData, Request);
743 if (Thread) NtCurrentTeb()->CsrClientThread = ServerThread;
744 }
745
746 /* Send back the reply */
747 Reply = Request;
748 }
749
750 /* Close the port and exit the thread */
751 // NtClose(ServerPort);
752
753 DPRINT("CSR: %s done\n", __FUNCTION__);
754 RtlExitUserThread(STATUS_SUCCESS);
755 }
756
757 /**********************************************************************
758 * NAME
759 * ServerSbApiPortThread/1
760 *
761 * DESCRIPTION
762 * Handle connection requests from SM to the port
763 * "\Windows\SbApiPort". We will accept only one
764 * connection request (from the SM).
765 */
766 DWORD WINAPI
767 ServerSbApiPortThread (HANDLE hSbApiPortListen)
768 {
769 HANDLE hConnectedPort = (HANDLE) 0;
770 PORT_MESSAGE Request;
771 PVOID Context = NULL;
772 NTSTATUS Status = STATUS_SUCCESS;
773 PPORT_MESSAGE Reply = NULL;
774
775 DPRINT("CSR: %s called\n", __FUNCTION__);
776
777 RtlZeroMemory(&Request, sizeof(PORT_MESSAGE));
778 Status = NtListenPort (hSbApiPortListen, & Request);
779
780 if (!NT_SUCCESS(Status))
781 {
782 DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
783 __FUNCTION__, Status);
784 } else {
785 DPRINT("-- 1\n");
786 Status = NtAcceptConnectPort(&hConnectedPort,
787 NULL,
788 &Request,
789 TRUE,
790 NULL,
791 NULL);
792 if(!NT_SUCCESS(Status))
793 {
794 DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
795 __FUNCTION__, Status);
796 } else {
797 DPRINT("-- 2\n");
798 Status = NtCompleteConnectPort (hConnectedPort);
799 if(!NT_SUCCESS(Status))
800 {
801 DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
802 __FUNCTION__, Status);
803 } else {
804 DPRINT("-- 3\n");
805 /*
806 * Tell the init thread the SM gave the
807 * green light for boostrapping.
808 */
809 Status = NtSetEvent (hBootstrapOk, NULL);
810 if(!NT_SUCCESS(Status))
811 {
812 DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
813 __FUNCTION__, Status);
814 }
815 /* Wait for messages from the SM */
816 DPRINT("-- 4\n");
817 while (TRUE)
818 {
819 Status = NtReplyWaitReceivePort(hConnectedPort,
820 Context,
821 Reply,
822 &Request);
823 if(!NT_SUCCESS(Status))
824 {
825 DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
826 __FUNCTION__, Status);
827 break;
828 }
829
830 switch (Request.u2.s2.Type) //fix .h PORT_MESSAGE_TYPE(Request))
831 {
832 /* TODO */
833 default:
834 DPRINT1("CSR: %s received message (type=%d)\n",
835 __FUNCTION__, Request.u2.s2.Type);
836 }
837 DPRINT("-- 5\n");
838 }
839 }
840 }
841 }
842
843 DPRINT("CSR: %s: terminating!\n", __FUNCTION__);
844 if(hConnectedPort) NtClose (hConnectedPort);
845 NtClose (hSbApiPortListen);
846 NtTerminateThread (NtCurrentThread(), Status);
847 return 0;
848 }
849
850 /* EOF */