1a676d64945039dbd264efd3fa3618a49680da34
[reactos.git] / subsystems / win / basesrv / server.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS/Win32 base enviroment subsystem server
4 * FILE: subsystems/win/basesrv/server.c
5 * PURPOSE: Initialization
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 */
8
9 #include "basesrv.h"
10
11 #define NDEBUG
12 #include <debug.h>
13
14
15 extern NTSTATUS CallProcessCreated(PCSR_PROCESS, PCSR_PROCESS); // TODO: Import it from csrsrv/init.c
16
17 CSR_API(BaseSrvCreateProcess)
18 {
19 NTSTATUS Status;
20 HANDLE ProcessHandle, ThreadHandle;
21 PCSR_THREAD CsrThread;
22 PCSR_PROCESS Process, NewProcess;
23 ULONG Flags, VdmPower = 0, DebugFlags = 0;
24
25 /* Get the current client thread */
26 CsrThread = CsrGetClientThread();
27 ASSERT(CsrThread != NULL);
28
29 Process = CsrThread->Process;
30
31 /* Extract the flags out of the process handle */
32 Flags = (ULONG_PTR)ApiMessage->Data.CreateProcessRequest.ProcessHandle & 3;
33 ApiMessage->Data.CreateProcessRequest.ProcessHandle = (HANDLE)((ULONG_PTR)ApiMessage->Data.CreateProcessRequest.ProcessHandle & ~3);
34
35 /* Duplicate the process handle */
36 Status = NtDuplicateObject(Process->ProcessHandle,
37 ApiMessage->Data.CreateProcessRequest.ProcessHandle,
38 NtCurrentProcess(),
39 &ProcessHandle,
40 0,
41 0,
42 DUPLICATE_SAME_ACCESS);
43 if (!NT_SUCCESS(Status))
44 {
45 DPRINT1("Failed to duplicate process handle\n");
46 return Status;
47 }
48
49 /* Duplicate the thread handle */
50 Status = NtDuplicateObject(Process->ProcessHandle,
51 ApiMessage->Data.CreateProcessRequest.ThreadHandle,
52 NtCurrentProcess(),
53 &ThreadHandle,
54 0,
55 0,
56 DUPLICATE_SAME_ACCESS);
57 if (!NT_SUCCESS(Status))
58 {
59 DPRINT1("Failed to duplicate process handle\n");
60 NtClose(ProcessHandle);
61 return Status;
62 }
63
64 /* See if this is a VDM process */
65 if (VdmPower)
66 {
67 /* Request VDM powers */
68 Status = NtSetInformationProcess(ProcessHandle,
69 ProcessWx86Information,
70 &VdmPower,
71 sizeof(VdmPower));
72 if (!NT_SUCCESS(Status))
73 {
74 DPRINT1("Failed to get VDM powers\n");
75 NtClose(ProcessHandle);
76 NtClose(ThreadHandle);
77 return Status;
78 }
79 }
80
81 /* Convert some flags. FIXME: More need conversion */
82 if (ApiMessage->Data.CreateProcessRequest.CreationFlags & CREATE_NEW_PROCESS_GROUP)
83 {
84 DebugFlags |= CsrProcessCreateNewGroup;
85 }
86
87 /* FIXME: SxS Stuff */
88
89 /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
90 Status = CsrCreateProcess(ProcessHandle,
91 ThreadHandle,
92 &ApiMessage->Data.CreateProcessRequest.ClientId,
93 Process->NtSession,
94 DebugFlags,
95 NULL);
96 if (Status == STATUS_THREAD_IS_TERMINATING)
97 {
98 DPRINT1("Thread already dead\n");
99 return Status;
100 }
101
102 /* Check for other failures */
103 if (!NT_SUCCESS(Status))
104 {
105 DPRINT1("Failed to create process/thread structures: %lx\n", Status);
106 return Status;
107 }
108
109 /* FIXME: Should notify user32 */
110
111 /* FIXME: VDM vodoo */
112
113 /* ReactOS Compatibility */
114 Status = CsrLockProcessByClientId(ApiMessage->Data.CreateProcessRequest.ClientId.UniqueProcess, &NewProcess);
115 ASSERT(Status == STATUS_SUCCESS);
116 if (!(ApiMessage->Data.CreateProcessRequest.CreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)))
117 {
118 NewProcess->ParentConsole = Process->Console;
119 NewProcess->bInheritHandles = ApiMessage->Data.CreateProcessRequest.bInheritHandles;
120 }
121 RtlInitializeCriticalSection(&NewProcess->HandleTableLock);
122 CallProcessCreated(Process, NewProcess);
123 CsrUnlockProcess(NewProcess);
124
125 /* Return the result of this operation */
126 return Status;
127 }
128
129 CSR_API(BaseSrvCreateThread)
130 {
131 PCSR_THREAD CurrentThread;
132 HANDLE ThreadHandle;
133 NTSTATUS Status;
134 PCSR_PROCESS CsrProcess;
135
136 /* Get the current CSR thread */
137 CurrentThread = CsrGetClientThread();
138 if (!CurrentThread)
139 {
140 DPRINT1("Server Thread TID: [%lx.%lx]\n",
141 ApiMessage->Data.CreateThreadRequest.ClientId.UniqueProcess,
142 ApiMessage->Data.CreateThreadRequest.ClientId.UniqueThread);
143 return STATUS_SUCCESS; // server-to-server
144 }
145
146 /* Get the CSR Process for this request */
147 CsrProcess = CurrentThread->Process;
148 if (CsrProcess->ClientId.UniqueProcess !=
149 ApiMessage->Data.CreateThreadRequest.ClientId.UniqueProcess)
150 {
151 /* This is a remote thread request -- is it within the server itself? */
152 if (ApiMessage->Data.CreateThreadRequest.ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
153 {
154 /* Accept this without any further work */
155 return STATUS_SUCCESS;
156 }
157
158 /* Get the real CSR Process for the remote thread's process */
159 Status = CsrLockProcessByClientId(ApiMessage->Data.CreateThreadRequest.ClientId.UniqueProcess,
160 &CsrProcess);
161 if (!NT_SUCCESS(Status)) return Status;
162 }
163
164 /* Duplicate the thread handle so we can own it */
165 Status = NtDuplicateObject(CurrentThread->Process->ProcessHandle,
166 ApiMessage->Data.CreateThreadRequest.ThreadHandle,
167 NtCurrentProcess(),
168 &ThreadHandle,
169 0,
170 0,
171 DUPLICATE_SAME_ACCESS);
172 if (NT_SUCCESS(Status))
173 {
174 /* Call CSRSRV to tell it about the new thread */
175 Status = CsrCreateThread(CsrProcess,
176 ThreadHandle,
177 &ApiMessage->Data.CreateThreadRequest.ClientId);
178 }
179
180 /* Unlock the process and return */
181 if (CsrProcess != CurrentThread->Process) CsrUnlockProcess(CsrProcess);
182 return Status;
183 }
184
185 CSR_API(BaseSrvGetTempFile)
186 {
187 static UINT CsrGetTempFileUnique = 0;
188
189 /* Return 16-bits ID */
190 ApiMessage->Data.GetTempFile.UniqueID = (++CsrGetTempFileUnique & 0xFFFF);
191
192 DPRINT("Returning: %u\n", ApiMessage->Data.GetTempFile.UniqueID);
193
194 return STATUS_SUCCESS;
195 }
196
197 CSR_API(BaseSrvExitProcess)
198 {
199 PCSR_THREAD CsrThread = CsrGetClientThread();
200 ASSERT(CsrThread != NULL);
201
202 /* Set magic flag so we don't reply this message back */
203 ApiMessage->ApiNumber = 0xBABE;
204
205 /* Remove the CSR_THREADs and CSR_PROCESS */
206 return CsrDestroyProcess(&CsrThread->ClientId,
207 (NTSTATUS)ApiMessage->Data.TerminateProcessRequest.uExitCode);
208 }
209
210 CSR_API(BaseSrvGetProcessShutdownParam)
211 {
212 PCSR_THREAD CsrThread = CsrGetClientThread();
213 ASSERT(CsrThread);
214
215 ApiMessage->Data.GetShutdownParametersRequest.Level = CsrThread->Process->ShutdownLevel;
216 ApiMessage->Data.GetShutdownParametersRequest.Flags = CsrThread->Process->ShutdownFlags;
217
218 return STATUS_SUCCESS;
219 }
220
221 CSR_API(BaseSrvSetProcessShutdownParam)
222 {
223 PCSR_THREAD CsrThread = CsrGetClientThread();
224 ASSERT(CsrThread);
225
226 CsrThread->Process->ShutdownLevel = ApiMessage->Data.SetShutdownParametersRequest.Level;
227 CsrThread->Process->ShutdownFlags = ApiMessage->Data.SetShutdownParametersRequest.Flags;
228
229 return STATUS_SUCCESS;
230 }
231
232
233 /***
234 *** Sound sentry
235 ***/
236
237 typedef BOOL (WINAPI *PUSER_SOUND_SENTRY)(VOID);
238 BOOL NTAPI FirstSoundSentry(VOID);
239
240 PUSER_SOUND_SENTRY _UserSoundSentry = FirstSoundSentry;
241
242 BOOL
243 NTAPI
244 FailSoundSentry(VOID)
245 {
246 /* In case the function can't be found/is unimplemented */
247 return FALSE;
248 }
249
250 BOOL
251 NTAPI
252 FirstSoundSentry(VOID)
253 {
254 UNICODE_STRING DllString = RTL_CONSTANT_STRING(L"winsrv");
255 STRING FuncString = RTL_CONSTANT_STRING("_UserSoundSentry");
256 HANDLE DllHandle;
257 NTSTATUS Status;
258 PUSER_SOUND_SENTRY NewSoundSentry = FailSoundSentry;
259
260 /* Load winsrv manually */
261 Status = LdrGetDllHandle(NULL, NULL, &DllString, &DllHandle);
262 if (NT_SUCCESS(Status))
263 {
264 /* If it was found, get SoundSentry export */
265 Status = LdrGetProcedureAddress(DllHandle,
266 &FuncString,
267 0,
268 (PVOID*)&NewSoundSentry);
269 }
270
271 /* Set it as the callback for the future, and call it */
272 _UserSoundSentry = NewSoundSentry;
273 return _UserSoundSentry();
274 }
275
276 CSR_API(BaseSrvSoundSentryNotification)
277 {
278 /* Call the API and see if it succeeds */
279 return _UserSoundSentry() ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
280 }
281
282
283 /***
284 *** Dos Devices (C) Pierre Schweitzer (pierre.schweitzer@reactos.org)
285 ***/
286
287 typedef struct tagCSRSS_DOS_DEVICE_HISTORY_ENTRY
288 {
289 UNICODE_STRING Device;
290 UNICODE_STRING Target;
291 LIST_ENTRY Entry;
292 } CSRSS_DOS_DEVICE_HISTORY_ENTRY, *PCSRSS_DOS_DEVICE_HISTORY_ENTRY;
293
294 LIST_ENTRY DosDeviceHistory;
295 RTL_CRITICAL_SECTION BaseDefineDosDeviceCritSec;
296
297 CSR_API(BaseSrvDefineDosDevice)
298 {
299 OBJECT_ATTRIBUTES ObjectAttributes;
300 HANDLE LinkHandle = NULL;
301 NTSTATUS Status;
302 UNICODE_STRING DeviceName = {0};
303 UNICODE_STRING RequestDeviceName = {0};
304 UNICODE_STRING LinkTarget = {0};
305 PUNICODE_STRING RequestLinkTarget;
306 ULONG Length;
307 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
308 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
309 PSECURITY_DESCRIPTOR SecurityDescriptor;
310 PACL Dacl;
311 PSID AdminSid;
312 PSID SystemSid;
313 PSID WorldSid;
314 ULONG SidLength;
315 PCSRSS_DOS_DEVICE_HISTORY_ENTRY HistoryEntry;
316 PLIST_ENTRY Entry;
317 PLIST_ENTRY ListHead;
318 BOOLEAN Matched, AddHistory;
319 DWORD dwFlags;
320 PWSTR lpBuffer;
321
322 DPRINT("CsrDefineDosDevice entered, Flags:%d, DeviceName:%wZ, TargetName:%wZ\n",
323 ApiMessage->Data.DefineDosDeviceRequest.dwFlags,
324 &ApiMessage->Data.DefineDosDeviceRequest.DeviceName,
325 &ApiMessage->Data.DefineDosDeviceRequest.TargetName);
326
327 Matched = AddHistory = FALSE;
328 HistoryEntry = NULL;
329 AdminSid = SystemSid = WorldSid = NULL;
330 SecurityDescriptor = NULL;
331 ListHead = &DosDeviceHistory;
332 dwFlags = ApiMessage->Data.DefineDosDeviceRequest.dwFlags;
333
334 /* Validate the flags */
335 if ( (dwFlags & 0xFFFFFFF0) ||
336 ((dwFlags & DDD_EXACT_MATCH_ON_REMOVE) &&
337 ! (dwFlags & DDD_REMOVE_DEFINITION)) )
338 {
339 return STATUS_INVALID_PARAMETER;
340 }
341
342 Status = RtlEnterCriticalSection(&BaseDefineDosDeviceCritSec);
343 if (! NT_SUCCESS(Status))
344 {
345 DPRINT1("RtlEnterCriticalSection() failed (Status %lx)\n",
346 Status);
347 return Status;
348 }
349
350 _SEH2_TRY
351 {
352 Status =
353 RtlUpcaseUnicodeString(&RequestDeviceName,
354 &ApiMessage->Data.DefineDosDeviceRequest.DeviceName,
355 TRUE);
356 if (! NT_SUCCESS(Status))
357 _SEH2_LEAVE;
358
359 RequestLinkTarget =
360 &ApiMessage->Data.DefineDosDeviceRequest.TargetName;
361 lpBuffer = (PWSTR) RtlAllocateHeap(Win32CsrApiHeap,
362 HEAP_ZERO_MEMORY,
363 RequestDeviceName.MaximumLength + 5 * sizeof(WCHAR));
364 if (! lpBuffer)
365 {
366 DPRINT1("Failed to allocate memory\n");
367 Status = STATUS_NO_MEMORY;
368 _SEH2_LEAVE;
369 }
370
371 swprintf(lpBuffer,
372 L"\\??\\%wZ",
373 &RequestDeviceName);
374 RtlInitUnicodeString(&DeviceName,
375 lpBuffer);
376 InitializeObjectAttributes(&ObjectAttributes,
377 &DeviceName,
378 OBJ_CASE_INSENSITIVE,
379 NULL,
380 NULL);
381 Status = NtOpenSymbolicLinkObject(&LinkHandle,
382 DELETE | 0x1,
383 &ObjectAttributes);
384 if (NT_SUCCESS(Status))
385 {
386 Status = NtQuerySymbolicLinkObject(LinkHandle,
387 &LinkTarget,
388 &Length);
389 if (! NT_SUCCESS(Status) &&
390 Status == STATUS_BUFFER_TOO_SMALL)
391 {
392 LinkTarget.Length = 0;
393 LinkTarget.MaximumLength = Length;
394 LinkTarget.Buffer = (PWSTR)
395 RtlAllocateHeap(Win32CsrApiHeap,
396 HEAP_ZERO_MEMORY,
397 Length);
398 if (! LinkTarget.Buffer)
399 {
400 DPRINT1("Failed to allocate memory\n");
401 Status = STATUS_NO_MEMORY;
402 _SEH2_LEAVE;
403 }
404
405 Status = NtQuerySymbolicLinkObject(LinkHandle,
406 &LinkTarget,
407 &Length);
408 }
409
410 if (! NT_SUCCESS(Status))
411 {
412 DPRINT1("NtQuerySymbolicLinkObject(%wZ) failed (Status %lx)\n",
413 &DeviceName, Status);
414 _SEH2_LEAVE;
415 }
416
417 if ((dwFlags & DDD_REMOVE_DEFINITION))
418 {
419 /* If no target name specified we remove the current symlink target */
420 if (RequestLinkTarget->Length == 0)
421 Matched = TRUE;
422 else
423 {
424 if (dwFlags & DDD_EXACT_MATCH_ON_REMOVE)
425 Matched = ! RtlCompareUnicodeString(RequestLinkTarget,
426 &LinkTarget,
427 TRUE);
428 else
429 Matched = RtlPrefixUnicodeString(RequestLinkTarget,
430 &LinkTarget,
431 TRUE);
432 }
433
434 if (Matched && IsListEmpty(ListHead))
435 {
436 /* Current symlink target macthed and there is nothing to revert to */
437 RequestLinkTarget = NULL;
438 }
439 else if (Matched && ! IsListEmpty(ListHead))
440 {
441 /* Fetch the first history entry we come across for the device name */
442 /* This will become the current symlink target for the device name */
443 Matched = FALSE;
444 Entry = ListHead->Flink;
445 while (Entry != ListHead)
446 {
447 HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
448 CONTAINING_RECORD(Entry,
449 CSRSS_DOS_DEVICE_HISTORY_ENTRY,
450 Entry);
451 Matched =
452 ! RtlCompareUnicodeString(&RequestDeviceName,
453 &HistoryEntry->Device,
454 FALSE);
455 if (Matched)
456 {
457 RemoveEntryList(&HistoryEntry->Entry);
458 RequestLinkTarget = &HistoryEntry->Target;
459 break;
460 }
461 Entry = Entry->Flink;
462 HistoryEntry = NULL;
463 }
464
465 /* Nothing to revert to so delete the symlink */
466 if (! Matched)
467 RequestLinkTarget = NULL;
468 }
469 else if (! Matched)
470 {
471 /* Locate a previous symlink target as we did not get a hit earlier */
472 /* If we find one we need to remove it */
473 Entry = ListHead->Flink;
474 while (Entry != ListHead)
475 {
476 HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
477 CONTAINING_RECORD(Entry,
478 CSRSS_DOS_DEVICE_HISTORY_ENTRY,
479 Entry);
480 Matched =
481 ! RtlCompareUnicodeString(&RequestDeviceName,
482 &HistoryEntry->Device,
483 FALSE);
484 if (! Matched)
485 {
486 HistoryEntry = NULL;
487 Entry = Entry->Flink;
488 continue;
489 }
490
491 Matched = FALSE;
492 if (dwFlags & DDD_EXACT_MATCH_ON_REMOVE)
493 {
494 if (! RtlCompareUnicodeString(RequestLinkTarget,
495 &HistoryEntry->Target,
496 TRUE))
497 {
498 Matched = TRUE;
499 }
500 }
501 else if (RtlPrefixUnicodeString(RequestLinkTarget,
502 &HistoryEntry->Target,
503 TRUE))
504 {
505 Matched = TRUE;
506 }
507
508 if (Matched)
509 {
510 RemoveEntryList(&HistoryEntry->Entry);
511 break;
512 }
513 Entry = Entry->Flink;
514 HistoryEntry = NULL;
515 }
516
517 /* Leave existing symlink as is */
518 if (! Matched)
519 Status = STATUS_OBJECT_NAME_NOT_FOUND;
520 else
521 Status = STATUS_SUCCESS;
522 _SEH2_LEAVE;
523 }
524 }
525 else
526 {
527 AddHistory = TRUE;
528 }
529
530 Status = NtMakeTemporaryObject(LinkHandle);
531 if (! NT_SUCCESS(Status))
532 {
533 DPRINT1("NtMakeTemporaryObject(%wZ) failed (Status %lx)\n",
534 &DeviceName, Status);
535 _SEH2_LEAVE;
536 }
537
538 Status = NtClose(LinkHandle);
539 LinkHandle = NULL;
540 if (! NT_SUCCESS(Status))
541 {
542 DPRINT1("NtClose(%wZ) failed (Status %lx)\n",
543 &DeviceName, Status);
544 _SEH2_LEAVE;
545 }
546 }
547
548 /* Don't create symlink if we don't have a target */
549 if (! RequestLinkTarget || RequestLinkTarget->Length == 0)
550 _SEH2_LEAVE;
551
552 if (AddHistory)
553 {
554 HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
555 RtlAllocateHeap(Win32CsrApiHeap,
556 HEAP_ZERO_MEMORY,
557 sizeof(CSRSS_DOS_DEVICE_HISTORY_ENTRY));
558 if (! HistoryEntry)
559 {
560 DPRINT1("Failed to allocate memory\n");
561 Status = STATUS_NO_MEMORY;
562 _SEH2_LEAVE;
563 }
564
565 HistoryEntry->Target.Buffer =
566 RtlAllocateHeap(Win32CsrApiHeap,
567 HEAP_ZERO_MEMORY,
568 LinkTarget.Length);
569 if (! HistoryEntry->Target.Buffer)
570 {
571 DPRINT1("Failed to allocate memory\n");
572 Status = STATUS_NO_MEMORY;
573 _SEH2_LEAVE;
574 }
575 HistoryEntry->Target.Length =
576 HistoryEntry->Target.MaximumLength =
577 LinkTarget.Length;
578 RtlCopyUnicodeString(&HistoryEntry->Target,
579 &LinkTarget);
580
581 HistoryEntry->Device.Buffer =
582 RtlAllocateHeap(Win32CsrApiHeap,
583 HEAP_ZERO_MEMORY,
584 RequestDeviceName.Length);
585 if (! HistoryEntry->Device.Buffer)
586 {
587 DPRINT1("Failed to allocate memory\n");
588 Status = STATUS_NO_MEMORY;
589 _SEH2_LEAVE;
590 }
591 HistoryEntry->Device.Length =
592 HistoryEntry->Device.MaximumLength =
593 RequestDeviceName.Length;
594 RtlCopyUnicodeString(&HistoryEntry->Device,
595 &RequestDeviceName);
596
597 /* Remember previous symlink target for this device */
598 InsertHeadList(ListHead,
599 &HistoryEntry->Entry);
600 HistoryEntry = NULL;
601 }
602
603 RtlAllocateAndInitializeSid(&WorldAuthority,
604 1,
605 SECURITY_WORLD_RID,
606 SECURITY_NULL_RID,
607 SECURITY_NULL_RID,
608 SECURITY_NULL_RID,
609 SECURITY_NULL_RID,
610 SECURITY_NULL_RID,
611 SECURITY_NULL_RID,
612 SECURITY_NULL_RID,
613 &WorldSid);
614
615 RtlAllocateAndInitializeSid(&SystemAuthority,
616 1,
617 SECURITY_LOCAL_SYSTEM_RID,
618 SECURITY_NULL_RID,
619 SECURITY_NULL_RID,
620 SECURITY_NULL_RID,
621 SECURITY_NULL_RID,
622 SECURITY_NULL_RID,
623 SECURITY_NULL_RID,
624 SECURITY_NULL_RID,
625 &SystemSid);
626
627 RtlAllocateAndInitializeSid(&SystemAuthority,
628 2,
629 SECURITY_BUILTIN_DOMAIN_RID,
630 DOMAIN_ALIAS_RID_ADMINS,
631 SECURITY_NULL_RID,
632 SECURITY_NULL_RID,
633 SECURITY_NULL_RID,
634 SECURITY_NULL_RID,
635 SECURITY_NULL_RID,
636 SECURITY_NULL_RID,
637 &AdminSid);
638
639 SidLength = RtlLengthSid(SystemSid) +
640 RtlLengthSid(AdminSid) +
641 RtlLengthSid(WorldSid);
642 Length = sizeof(ACL) + SidLength + 3 * sizeof(ACCESS_ALLOWED_ACE);
643
644 SecurityDescriptor = RtlAllocateHeap(Win32CsrApiHeap,
645 0,
646 SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
647 if (! SecurityDescriptor)
648 {
649 DPRINT1("Failed to allocate memory\n");
650 Status = STATUS_NO_MEMORY;
651 _SEH2_LEAVE;
652 }
653
654 Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
655 Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
656 SECURITY_DESCRIPTOR_REVISION);
657 if (! NT_SUCCESS(Status))
658 {
659 DPRINT1("RtlCreateSecurityDescriptor() failed (Status %lx)\n",
660 Status);
661 _SEH2_LEAVE;
662 }
663
664 Status = RtlCreateAcl(Dacl,
665 Length,
666 ACL_REVISION);
667 if (! NT_SUCCESS(Status))
668 {
669 DPRINT1("RtlCreateAcl() failed (Status %lx)\n",
670 Status);
671 _SEH2_LEAVE;
672 }
673
674 (void) RtlAddAccessAllowedAce(Dacl,
675 ACL_REVISION,
676 GENERIC_ALL,
677 SystemSid);
678 (void) RtlAddAccessAllowedAce(Dacl,
679 ACL_REVISION,
680 GENERIC_ALL,
681 AdminSid);
682 (void) RtlAddAccessAllowedAce(Dacl,
683 ACL_REVISION,
684 STANDARD_RIGHTS_READ,
685 WorldSid);
686
687 Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
688 TRUE,
689 Dacl,
690 FALSE);
691 if (! NT_SUCCESS(Status))
692 {
693 DPRINT1("RtlSetDaclSecurityDescriptor() failed (Status %lx)\n",
694 Status);
695 _SEH2_LEAVE;
696 }
697
698 InitializeObjectAttributes(&ObjectAttributes,
699 &DeviceName,
700 OBJ_CASE_INSENSITIVE,
701 NULL,
702 SecurityDescriptor);
703 Status = NtCreateSymbolicLinkObject(&LinkHandle,
704 SYMBOLIC_LINK_ALL_ACCESS,
705 &ObjectAttributes,
706 RequestLinkTarget);
707 if (NT_SUCCESS(Status))
708 {
709 Status = NtMakePermanentObject(LinkHandle);
710 if (! NT_SUCCESS(Status))
711 {
712 DPRINT1("NtMakePermanentObject(%wZ) failed (Status %lx)\n",
713 &DeviceName, Status);
714 }
715 }
716 else
717 {
718 DPRINT1("NtCreateSymbolicLinkObject(%wZ) failed (Status %lx)\n",
719 &DeviceName, Status);
720 }
721 }
722 _SEH2_FINALLY
723 {
724 (void) RtlLeaveCriticalSection(&BaseDefineDosDeviceCritSec);
725 if (DeviceName.Buffer)
726 (void) RtlFreeHeap(Win32CsrApiHeap,
727 0,
728 DeviceName.Buffer);
729 if (LinkTarget.Buffer)
730 (void) RtlFreeHeap(Win32CsrApiHeap,
731 0,
732 LinkTarget.Buffer);
733 if (SecurityDescriptor)
734 (void) RtlFreeHeap(Win32CsrApiHeap,
735 0,
736 SecurityDescriptor);
737 if (LinkHandle)
738 (void) NtClose(LinkHandle);
739 if (SystemSid)
740 (void) RtlFreeSid(SystemSid);
741 if (AdminSid)
742 (void) RtlFreeSid(AdminSid);
743 if (WorldSid)
744 (void) RtlFreeSid(WorldSid);
745 RtlFreeUnicodeString(&RequestDeviceName);
746 if (HistoryEntry)
747 {
748 if (HistoryEntry->Target.Buffer)
749 (void) RtlFreeHeap(Win32CsrApiHeap,
750 0,
751 HistoryEntry->Target.Buffer);
752 if (HistoryEntry->Device.Buffer)
753 (void) RtlFreeHeap(Win32CsrApiHeap,
754 0,
755 HistoryEntry->Device.Buffer);
756 (void) RtlFreeHeap(Win32CsrApiHeap,
757 0,
758 HistoryEntry);
759 }
760 }
761 _SEH2_END
762
763 DPRINT("CsrDefineDosDevice Exit, Statux: 0x%x\n", Status);
764 return Status;
765 }
766
767 VOID BaseCleanupDefineDosDevice(VOID)
768 {
769 PLIST_ENTRY Entry, ListHead;
770 PCSRSS_DOS_DEVICE_HISTORY_ENTRY HistoryEntry;
771
772 (void) RtlDeleteCriticalSection(&BaseDefineDosDeviceCritSec);
773
774 ListHead = &DosDeviceHistory;
775 Entry = ListHead->Flink;
776 while (Entry != ListHead)
777 {
778 HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
779 CONTAINING_RECORD(Entry,
780 CSRSS_DOS_DEVICE_HISTORY_ENTRY,
781 Entry);
782 Entry = Entry->Flink;
783
784 if (HistoryEntry)
785 {
786 if (HistoryEntry->Target.Buffer)
787 (void) RtlFreeHeap(Win32CsrApiHeap,
788 0,
789 HistoryEntry->Target.Buffer);
790 if (HistoryEntry->Device.Buffer)
791 (void) RtlFreeHeap(Win32CsrApiHeap,
792 0,
793 HistoryEntry->Device.Buffer);
794 (void) RtlFreeHeap(Win32CsrApiHeap,
795 0,
796 HistoryEntry);
797 }
798 }
799 }
800
801
802
803
804
805
806 /* PUBLIC API *****************************************************************/
807
808 NTSTATUS NTAPI BaseSetProcessCreateNotify(IN BASE_PROCESS_CREATE_NOTIFY_ROUTINE ProcessCreateNotifyProc)
809 {
810 DPRINT("BASESRV: %s(%08lx) called\n", __FUNCTION__, ProcessCreateNotifyProc);
811 return STATUS_NOT_IMPLEMENTED;
812 }
813
814 /* EOF */