2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS/Win32 Base enviroment Subsystem Server
4 * FILE: subsystems/win/basesrv/server.c
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
15 // extern NTSTATUS CallProcessCreated(PCSR_PROCESS, PCSR_PROCESS); // TODO: Import it from csrsrv/init.c
16 // Remove it and correct csrsrv instead...
19 CallProcessCreated(IN PCSR_PROCESS SourceProcessData
,
20 IN PCSR_PROCESS TargetProcessData
)
22 NTSTATUS Status
= STATUS_SUCCESS
;
24 PCSR_SERVER_DLL ServerDll
;
26 DPRINT("CSR: %s called\n", __FUNCTION__
);
28 /* Notify the Server DLLs */
29 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
31 /* Get the current Server DLL */
32 ServerDll
= CsrLoadedServerDll
[i
];
34 /* Make sure it's valid and that it has callback */
35 if ((ServerDll
) && (ServerDll
->NewProcessCallback
))
37 Status
= ServerDll
->NewProcessCallback(SourceProcessData
, TargetProcessData
);
45 CSR_API(BaseSrvCreateProcess
)
48 PBASE_CREATE_PROCESS CreateProcessRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.CreateProcessRequest
;
49 HANDLE ProcessHandle
, ThreadHandle
;
50 PCSR_THREAD CsrThread
;
51 PCSR_PROCESS Process
; // , NewProcess;
52 ULONG
/* Flags, */ VdmPower
= 0, DebugFlags
= 0;
54 /* Get the current client thread */
55 CsrThread
= CsrGetClientThread();
56 ASSERT(CsrThread
!= NULL
);
58 Process
= CsrThread
->Process
;
60 /* Extract the flags out of the process handle */
61 // Flags = (ULONG_PTR)CreateProcessRequest->ProcessHandle & 3;
62 CreateProcessRequest
->ProcessHandle
= (HANDLE
)((ULONG_PTR
)CreateProcessRequest
->ProcessHandle
& ~3);
64 /* Duplicate the process handle */
65 Status
= NtDuplicateObject(Process
->ProcessHandle
,
66 CreateProcessRequest
->ProcessHandle
,
71 DUPLICATE_SAME_ACCESS
);
72 if (!NT_SUCCESS(Status
))
74 DPRINT1("Failed to duplicate process handle\n");
78 /* Duplicate the thread handle */
79 Status
= NtDuplicateObject(Process
->ProcessHandle
,
80 CreateProcessRequest
->ThreadHandle
,
85 DUPLICATE_SAME_ACCESS
);
86 if (!NT_SUCCESS(Status
))
88 DPRINT1("Failed to duplicate process handle\n");
89 NtClose(ProcessHandle
);
93 /* See if this is a VDM process */
96 /* Request VDM powers */
97 Status
= NtSetInformationProcess(ProcessHandle
,
98 ProcessWx86Information
,
101 if (!NT_SUCCESS(Status
))
103 DPRINT1("Failed to get VDM powers\n");
104 NtClose(ProcessHandle
);
105 NtClose(ThreadHandle
);
110 /* Convert some flags. FIXME: More need conversion */
111 if (CreateProcessRequest
->CreationFlags
& CREATE_NEW_PROCESS_GROUP
)
113 DebugFlags
|= CsrProcessCreateNewGroup
;
116 /* FIXME: SxS Stuff */
118 /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
119 Status
= CsrCreateProcess(ProcessHandle
,
121 &CreateProcessRequest
->ClientId
,
125 if (Status
== STATUS_THREAD_IS_TERMINATING
)
127 DPRINT1("Thread already dead\n");
131 /* Check for other failures */
132 if (!NT_SUCCESS(Status
))
134 DPRINT1("Failed to create process/thread structures: %lx\n", Status
);
138 /* FIXME: Should notify user32 */
140 /* FIXME: VDM vodoo */
142 /* ReactOS Compatibility */
144 Status
= CsrLockProcessByClientId(CreateProcessRequest
->ClientId
.UniqueProcess
, &NewProcess
);
145 ASSERT(Status
== STATUS_SUCCESS
);
146 if (!(CreateProcessRequest
->CreationFlags
& (CREATE_NEW_CONSOLE
| DETACHED_PROCESS
)))
148 NewProcess
->ParentConsole
= Process
->Console
;
149 NewProcess
->bInheritHandles
= CreateProcessRequest
->bInheritHandles
;
151 RtlInitializeCriticalSection(&NewProcess
->HandleTableLock
);
152 CallProcessCreated(Process
, NewProcess
);
153 CsrUnlockProcess(NewProcess
);
156 /* Return the result of this operation */
160 CSR_API(BaseSrvCreateThread
)
163 PBASE_CREATE_THREAD CreateThreadRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.CreateThreadRequest
;
164 PCSR_THREAD CurrentThread
;
166 PCSR_PROCESS CsrProcess
;
168 /* Get the current CSR thread */
169 CurrentThread
= CsrGetClientThread();
172 DPRINT1("Server Thread TID: [%lx.%lx]\n",
173 CreateThreadRequest
->ClientId
.UniqueProcess
,
174 CreateThreadRequest
->ClientId
.UniqueThread
);
175 return STATUS_SUCCESS
; // server-to-server
178 /* Get the CSR Process for this request */
179 CsrProcess
= CurrentThread
->Process
;
180 if (CsrProcess
->ClientId
.UniqueProcess
!=
181 CreateThreadRequest
->ClientId
.UniqueProcess
)
183 /* This is a remote thread request -- is it within the server itself? */
184 if (CreateThreadRequest
->ClientId
.UniqueProcess
== NtCurrentTeb()->ClientId
.UniqueProcess
)
186 /* Accept this without any further work */
187 return STATUS_SUCCESS
;
190 /* Get the real CSR Process for the remote thread's process */
191 Status
= CsrLockProcessByClientId(CreateThreadRequest
->ClientId
.UniqueProcess
,
193 if (!NT_SUCCESS(Status
)) return Status
;
196 /* Duplicate the thread handle so we can own it */
197 Status
= NtDuplicateObject(CurrentThread
->Process
->ProcessHandle
,
198 CreateThreadRequest
->ThreadHandle
,
203 DUPLICATE_SAME_ACCESS
);
204 if (NT_SUCCESS(Status
))
206 /* Call CSRSRV to tell it about the new thread */
207 Status
= CsrCreateThread(CsrProcess
,
209 &CreateThreadRequest
->ClientId
);
212 /* Unlock the process and return */
213 if (CsrProcess
!= CurrentThread
->Process
) CsrUnlockProcess(CsrProcess
);
217 CSR_API(BaseSrvGetTempFile
)
219 static UINT CsrGetTempFileUnique
= 0;
220 PBASE_GET_TEMP_FILE GetTempFile
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.GetTempFile
;
222 /* Return 16-bits ID */
223 GetTempFile
->UniqueID
= (++CsrGetTempFileUnique
& 0xFFFF);
225 DPRINT("Returning: %u\n", GetTempFile
->UniqueID
);
227 return STATUS_SUCCESS
;
230 CSR_API(BaseSrvExitProcess
)
232 PCSR_THREAD CsrThread
= CsrGetClientThread();
233 ASSERT(CsrThread
!= NULL
);
235 /* Set magic flag so we don't reply this message back */
236 ApiMessage
->ApiNumber
= 0xBABE;
238 /* Remove the CSR_THREADs and CSR_PROCESS */
239 return CsrDestroyProcess(&CsrThread
->ClientId
,
240 (NTSTATUS
)((PBASE_API_MESSAGE
)ApiMessage
)->Data
.ExitProcessRequest
.uExitCode
);
243 CSR_API(BaseSrvGetProcessShutdownParam
)
245 PBASE_GET_PROCESS_SHUTDOWN_PARAMS GetShutdownParametersRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.GetShutdownParametersRequest
;
246 PCSR_THREAD CsrThread
= CsrGetClientThread();
249 GetShutdownParametersRequest
->Level
= CsrThread
->Process
->ShutdownLevel
;
250 GetShutdownParametersRequest
->Flags
= CsrThread
->Process
->ShutdownFlags
;
252 return STATUS_SUCCESS
;
255 CSR_API(BaseSrvSetProcessShutdownParam
)
257 PBASE_SET_PROCESS_SHUTDOWN_PARAMS SetShutdownParametersRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.SetShutdownParametersRequest
;
258 PCSR_THREAD CsrThread
= CsrGetClientThread();
261 CsrThread
->Process
->ShutdownLevel
= SetShutdownParametersRequest
->Level
;
262 CsrThread
->Process
->ShutdownFlags
= SetShutdownParametersRequest
->Flags
;
264 return STATUS_SUCCESS
;
272 typedef BOOL (WINAPI
*PUSER_SOUND_SENTRY
)(VOID
);
273 BOOL NTAPI
FirstSoundSentry(VOID
);
275 PUSER_SOUND_SENTRY _UserSoundSentry
= FirstSoundSentry
;
279 FailSoundSentry(VOID
)
281 /* In case the function can't be found/is unimplemented */
287 FirstSoundSentry(VOID
)
289 UNICODE_STRING DllString
= RTL_CONSTANT_STRING(L
"winsrv");
290 STRING FuncString
= RTL_CONSTANT_STRING("_UserSoundSentry");
293 PUSER_SOUND_SENTRY NewSoundSentry
= FailSoundSentry
;
295 /* Load winsrv manually */
296 Status
= LdrGetDllHandle(NULL
, NULL
, &DllString
, &DllHandle
);
297 if (NT_SUCCESS(Status
))
299 /* If it was found, get SoundSentry export */
300 Status
= LdrGetProcedureAddress(DllHandle
,
303 (PVOID
*)&NewSoundSentry
);
306 /* Set it as the callback for the future, and call it */
307 _UserSoundSentry
= NewSoundSentry
;
308 return _UserSoundSentry();
311 CSR_API(BaseSrvSoundSentryNotification
)
313 /* Call the API and see if it succeeds */
314 return _UserSoundSentry() ? STATUS_SUCCESS
: STATUS_ACCESS_DENIED
;
319 *** Dos Devices (C) Pierre Schweitzer (pierre.schweitzer@reactos.org)
322 typedef struct tagBASE_DOS_DEVICE_HISTORY_ENTRY
324 UNICODE_STRING Device
;
325 UNICODE_STRING Target
;
327 } BASE_DOS_DEVICE_HISTORY_ENTRY
, *PBASE_DOS_DEVICE_HISTORY_ENTRY
;
329 LIST_ENTRY DosDeviceHistory
;
330 RTL_CRITICAL_SECTION BaseDefineDosDeviceCritSec
;
332 VOID
BaseCleanupDefineDosDevice(VOID
)
334 PLIST_ENTRY Entry
, ListHead
;
335 PBASE_DOS_DEVICE_HISTORY_ENTRY HistoryEntry
;
337 (void) RtlDeleteCriticalSection(&BaseDefineDosDeviceCritSec
);
339 ListHead
= &DosDeviceHistory
;
340 Entry
= ListHead
->Flink
;
341 while (Entry
!= ListHead
)
343 HistoryEntry
= (PBASE_DOS_DEVICE_HISTORY_ENTRY
)
344 CONTAINING_RECORD(Entry
,
345 BASE_DOS_DEVICE_HISTORY_ENTRY
,
347 Entry
= Entry
->Flink
;
351 if (HistoryEntry
->Target
.Buffer
)
352 (void) RtlFreeHeap(BaseSrvHeap
,
354 HistoryEntry
->Target
.Buffer
);
355 if (HistoryEntry
->Device
.Buffer
)
356 (void) RtlFreeHeap(BaseSrvHeap
,
358 HistoryEntry
->Device
.Buffer
);
359 (void) RtlFreeHeap(BaseSrvHeap
,
366 CSR_API(BaseSrvDefineDosDevice
)
369 PBASE_DEFINE_DOS_DEVICE DefineDosDeviceRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.DefineDosDeviceRequest
;
370 OBJECT_ATTRIBUTES ObjectAttributes
;
371 HANDLE LinkHandle
= NULL
;
372 UNICODE_STRING DeviceName
= {0};
373 UNICODE_STRING RequestDeviceName
= {0};
374 UNICODE_STRING LinkTarget
= {0};
375 PUNICODE_STRING RequestLinkTarget
;
377 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
378 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
379 PSECURITY_DESCRIPTOR SecurityDescriptor
;
385 PBASE_DOS_DEVICE_HISTORY_ENTRY HistoryEntry
;
387 PLIST_ENTRY ListHead
;
388 BOOLEAN Matched
, AddHistory
;
392 DPRINT("CsrDefineDosDevice entered, Flags:%d, DeviceName:%wZ, TargetName:%wZ\n",
393 DefineDosDeviceRequest
->dwFlags
,
394 &DefineDosDeviceRequest
->DeviceName
,
395 &DefineDosDeviceRequest
->TargetName
);
397 Matched
= AddHistory
= FALSE
;
399 AdminSid
= SystemSid
= WorldSid
= NULL
;
400 SecurityDescriptor
= NULL
;
401 ListHead
= &DosDeviceHistory
;
402 dwFlags
= DefineDosDeviceRequest
->dwFlags
;
404 /* Validate the flags */
405 if ( (dwFlags
& 0xFFFFFFF0) ||
406 ((dwFlags
& DDD_EXACT_MATCH_ON_REMOVE
) &&
407 ! (dwFlags
& DDD_REMOVE_DEFINITION
)) )
409 return STATUS_INVALID_PARAMETER
;
412 Status
= RtlEnterCriticalSection(&BaseDefineDosDeviceCritSec
);
413 if (! NT_SUCCESS(Status
))
415 DPRINT1("RtlEnterCriticalSection() failed (Status %lx)\n",
423 RtlUpcaseUnicodeString(&RequestDeviceName
,
424 &DefineDosDeviceRequest
->DeviceName
,
426 if (! NT_SUCCESS(Status
))
429 RequestLinkTarget
= &DefineDosDeviceRequest
->TargetName
;
430 lpBuffer
= (PWSTR
) RtlAllocateHeap(BaseSrvHeap
,
432 RequestDeviceName
.MaximumLength
+ 5 * sizeof(WCHAR
));
435 DPRINT1("Failed to allocate memory\n");
436 Status
= STATUS_NO_MEMORY
;
443 RtlInitUnicodeString(&DeviceName
,
445 InitializeObjectAttributes(&ObjectAttributes
,
447 OBJ_CASE_INSENSITIVE
,
450 Status
= NtOpenSymbolicLinkObject(&LinkHandle
,
453 if (NT_SUCCESS(Status
))
455 Status
= NtQuerySymbolicLinkObject(LinkHandle
,
458 if (! NT_SUCCESS(Status
) &&
459 Status
== STATUS_BUFFER_TOO_SMALL
)
461 LinkTarget
.Length
= 0;
462 LinkTarget
.MaximumLength
= Length
;
463 LinkTarget
.Buffer
= (PWSTR
)
464 RtlAllocateHeap(BaseSrvHeap
,
467 if (! LinkTarget
.Buffer
)
469 DPRINT1("Failed to allocate memory\n");
470 Status
= STATUS_NO_MEMORY
;
474 Status
= NtQuerySymbolicLinkObject(LinkHandle
,
479 if (! NT_SUCCESS(Status
))
481 DPRINT1("NtQuerySymbolicLinkObject(%wZ) failed (Status %lx)\n",
482 &DeviceName
, Status
);
486 if ((dwFlags
& DDD_REMOVE_DEFINITION
))
488 /* If no target name specified we remove the current symlink target */
489 if (RequestLinkTarget
->Length
== 0)
493 if (dwFlags
& DDD_EXACT_MATCH_ON_REMOVE
)
494 Matched
= ! RtlCompareUnicodeString(RequestLinkTarget
,
498 Matched
= RtlPrefixUnicodeString(RequestLinkTarget
,
503 if (Matched
&& IsListEmpty(ListHead
))
505 /* Current symlink target macthed and there is nothing to revert to */
506 RequestLinkTarget
= NULL
;
508 else if (Matched
&& ! IsListEmpty(ListHead
))
510 /* Fetch the first history entry we come across for the device name */
511 /* This will become the current symlink target for the device name */
513 Entry
= ListHead
->Flink
;
514 while (Entry
!= ListHead
)
516 HistoryEntry
= (PBASE_DOS_DEVICE_HISTORY_ENTRY
)
517 CONTAINING_RECORD(Entry
,
518 BASE_DOS_DEVICE_HISTORY_ENTRY
,
521 ! RtlCompareUnicodeString(&RequestDeviceName
,
522 &HistoryEntry
->Device
,
526 RemoveEntryList(&HistoryEntry
->Entry
);
527 RequestLinkTarget
= &HistoryEntry
->Target
;
530 Entry
= Entry
->Flink
;
534 /* Nothing to revert to so delete the symlink */
536 RequestLinkTarget
= NULL
;
540 /* Locate a previous symlink target as we did not get a hit earlier */
541 /* If we find one we need to remove it */
542 Entry
= ListHead
->Flink
;
543 while (Entry
!= ListHead
)
545 HistoryEntry
= (PBASE_DOS_DEVICE_HISTORY_ENTRY
)
546 CONTAINING_RECORD(Entry
,
547 BASE_DOS_DEVICE_HISTORY_ENTRY
,
550 ! RtlCompareUnicodeString(&RequestDeviceName
,
551 &HistoryEntry
->Device
,
556 Entry
= Entry
->Flink
;
561 if (dwFlags
& DDD_EXACT_MATCH_ON_REMOVE
)
563 if (! RtlCompareUnicodeString(RequestLinkTarget
,
564 &HistoryEntry
->Target
,
570 else if (RtlPrefixUnicodeString(RequestLinkTarget
,
571 &HistoryEntry
->Target
,
579 RemoveEntryList(&HistoryEntry
->Entry
);
582 Entry
= Entry
->Flink
;
586 /* Leave existing symlink as is */
588 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
590 Status
= STATUS_SUCCESS
;
599 Status
= NtMakeTemporaryObject(LinkHandle
);
600 if (! NT_SUCCESS(Status
))
602 DPRINT1("NtMakeTemporaryObject(%wZ) failed (Status %lx)\n",
603 &DeviceName
, Status
);
607 Status
= NtClose(LinkHandle
);
609 if (! NT_SUCCESS(Status
))
611 DPRINT1("NtClose(%wZ) failed (Status %lx)\n",
612 &DeviceName
, Status
);
617 /* Don't create symlink if we don't have a target */
618 if (! RequestLinkTarget
|| RequestLinkTarget
->Length
== 0)
623 HistoryEntry
= (PBASE_DOS_DEVICE_HISTORY_ENTRY
)
624 RtlAllocateHeap(BaseSrvHeap
,
626 sizeof(BASE_DOS_DEVICE_HISTORY_ENTRY
));
629 DPRINT1("Failed to allocate memory\n");
630 Status
= STATUS_NO_MEMORY
;
634 HistoryEntry
->Target
.Buffer
=
635 RtlAllocateHeap(BaseSrvHeap
,
638 if (! HistoryEntry
->Target
.Buffer
)
640 DPRINT1("Failed to allocate memory\n");
641 Status
= STATUS_NO_MEMORY
;
644 HistoryEntry
->Target
.Length
=
645 HistoryEntry
->Target
.MaximumLength
=
647 RtlCopyUnicodeString(&HistoryEntry
->Target
,
650 HistoryEntry
->Device
.Buffer
=
651 RtlAllocateHeap(BaseSrvHeap
,
653 RequestDeviceName
.Length
);
654 if (! HistoryEntry
->Device
.Buffer
)
656 DPRINT1("Failed to allocate memory\n");
657 Status
= STATUS_NO_MEMORY
;
660 HistoryEntry
->Device
.Length
=
661 HistoryEntry
->Device
.MaximumLength
=
662 RequestDeviceName
.Length
;
663 RtlCopyUnicodeString(&HistoryEntry
->Device
,
666 /* Remember previous symlink target for this device */
667 InsertHeadList(ListHead
,
668 &HistoryEntry
->Entry
);
672 RtlAllocateAndInitializeSid(&WorldAuthority
,
684 RtlAllocateAndInitializeSid(&SystemAuthority
,
686 SECURITY_LOCAL_SYSTEM_RID
,
696 RtlAllocateAndInitializeSid(&SystemAuthority
,
698 SECURITY_BUILTIN_DOMAIN_RID
,
699 DOMAIN_ALIAS_RID_ADMINS
,
708 SidLength
= RtlLengthSid(SystemSid
) +
709 RtlLengthSid(AdminSid
) +
710 RtlLengthSid(WorldSid
);
711 Length
= sizeof(ACL
) + SidLength
+ 3 * sizeof(ACCESS_ALLOWED_ACE
);
713 SecurityDescriptor
= RtlAllocateHeap(BaseSrvHeap
,
715 SECURITY_DESCRIPTOR_MIN_LENGTH
+ Length
);
716 if (! SecurityDescriptor
)
718 DPRINT1("Failed to allocate memory\n");
719 Status
= STATUS_NO_MEMORY
;
723 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ SECURITY_DESCRIPTOR_MIN_LENGTH
);
724 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
725 SECURITY_DESCRIPTOR_REVISION
);
726 if (! NT_SUCCESS(Status
))
728 DPRINT1("RtlCreateSecurityDescriptor() failed (Status %lx)\n",
733 Status
= RtlCreateAcl(Dacl
,
736 if (! NT_SUCCESS(Status
))
738 DPRINT1("RtlCreateAcl() failed (Status %lx)\n",
743 (void) RtlAddAccessAllowedAce(Dacl
,
747 (void) RtlAddAccessAllowedAce(Dacl
,
751 (void) RtlAddAccessAllowedAce(Dacl
,
753 STANDARD_RIGHTS_READ
,
756 Status
= RtlSetDaclSecurityDescriptor(SecurityDescriptor
,
760 if (! NT_SUCCESS(Status
))
762 DPRINT1("RtlSetDaclSecurityDescriptor() failed (Status %lx)\n",
767 InitializeObjectAttributes(&ObjectAttributes
,
769 OBJ_CASE_INSENSITIVE
,
772 Status
= NtCreateSymbolicLinkObject(&LinkHandle
,
773 SYMBOLIC_LINK_ALL_ACCESS
,
776 if (NT_SUCCESS(Status
))
778 Status
= NtMakePermanentObject(LinkHandle
);
779 if (! NT_SUCCESS(Status
))
781 DPRINT1("NtMakePermanentObject(%wZ) failed (Status %lx)\n",
782 &DeviceName
, Status
);
787 DPRINT1("NtCreateSymbolicLinkObject(%wZ) failed (Status %lx)\n",
788 &DeviceName
, Status
);
793 (void) RtlLeaveCriticalSection(&BaseDefineDosDeviceCritSec
);
794 if (DeviceName
.Buffer
)
795 (void) RtlFreeHeap(BaseSrvHeap
,
798 if (LinkTarget
.Buffer
)
799 (void) RtlFreeHeap(BaseSrvHeap
,
802 if (SecurityDescriptor
)
803 (void) RtlFreeHeap(BaseSrvHeap
,
807 (void) NtClose(LinkHandle
);
809 (void) RtlFreeSid(SystemSid
);
811 (void) RtlFreeSid(AdminSid
);
813 (void) RtlFreeSid(WorldSid
);
814 RtlFreeUnicodeString(&RequestDeviceName
);
817 if (HistoryEntry
->Target
.Buffer
)
818 (void) RtlFreeHeap(BaseSrvHeap
,
820 HistoryEntry
->Target
.Buffer
);
821 if (HistoryEntry
->Device
.Buffer
)
822 (void) RtlFreeHeap(BaseSrvHeap
,
824 HistoryEntry
->Device
.Buffer
);
825 (void) RtlFreeHeap(BaseSrvHeap
,
832 DPRINT("CsrDefineDosDevice Exit, Statux: 0x%x\n", Status
);
841 /* PUBLIC API *****************************************************************/
843 NTSTATUS NTAPI
BaseSetProcessCreateNotify(IN BASE_PROCESS_CREATE_NOTIFY_ROUTINE ProcessCreateNotifyProc
)
845 DPRINT("BASESRV: %s(%08lx) called\n", __FUNCTION__
, ProcessCreateNotifyProc
);
846 return STATUS_NOT_IMPLEMENTED
;