ReactOS  0.4.15-dev-2714-g4864c87
dosdev.c File Reference
#include "basesrv.h"
#include <debug.h>
Include dependency graph for dosdev.c:

Go to the source code of this file.

Classes

struct  _BSM_REQUEST
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _BSM_REQUEST BSM_REQUEST
 
typedef struct _BSM_REQUESTPBSM_REQUEST
 

Functions

 LONG (WINAPI *PBROADCASTSYSTEMMESSAGEEXW)(DWORD
 
VOID BaseInitDefineDosDevice (VOID)
 
VOID BaseCleanupDefineDosDevice (VOID)
 
NTSTATUS GetCallerLuid (PLUID CallerLuid)
 
NTSTATUS IsGlobalSymbolicLink (HANDLE LinkHandle, PBOOLEAN IsGlobal)
 
BOOLEAN CheckForGlobalDriveLetter (SHORT DriveLetter)
 
NTSTATUS SendWinStationBSM (DWORD Flags, LPDWORD Recipients, UINT Message, WPARAM wParam, LPARAM lParam)
 
NTSTATUS BroadcastDriveLetterChange (LONG DriveLetter, BOOLEAN RemoveDefinition, PLUID BroadcastLuid)
 
ULONG NTAPI BaseSrvBSMThread (PVOID StartupContext)
 
NTSTATUS CreateBSMThread (VOID)
 
NTSTATUS AddBSMRequest (LONG DriveLetter, BOOLEAN RemoveDefinition, PLUID BroadcastLuid)
 
 CSR_API (BaseSrvDefineDosDevice)
 

Variables

static RTL_CRITICAL_SECTION BaseDefineDosDeviceCritSec
 
RTL_CRITICAL_SECTION BaseSrvDDDBSMCritSec
 
PBSM_REQUEST BSM_Request_Queue = NULL
 
PBSM_REQUEST BSM_Request_Queue_End = NULL
 
ULONG BaseSrvpBSMThreadCount = 0
 
 LPDWORD
 
 UINT
 
 WPARAM
 
 LPARAM
 
 PBSMINFO = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file dosdev.c.

Typedef Documentation

◆ BSM_REQUEST

◆ PBSM_REQUEST

Function Documentation

◆ AddBSMRequest()

NTSTATUS AddBSMRequest ( LONG  DriveLetter,
BOOLEAN  RemoveDefinition,
PLUID  BroadcastLuid 
)

Definition at line 391 of file dosdev.c.

394 {
395  LUID CallerLuid;
397  LUID SystemLuid = SYSTEM_LUID;
399 
400  /* We need a broadcast LUID */
401  if (BroadcastLuid == NULL)
402  {
404  }
405 
406  /*
407  * If LUID mappings are not enabled, this call makes no sense
408  * It should not happen though
409  */
411  {
412  return STATUS_ACCESS_DENIED;
413  }
414 
415  /* Get our caller LUID (not the broadcaster!) */
416  Status = GetCallerLuid(&CallerLuid);
417  if (!NT_SUCCESS(Status))
418  {
419  return Status;
420  }
421 
422  /* System cannot create LUID mapped drives - thus broadcast makes no sense */
423  if (!RtlEqualLuid(&CallerLuid, &SystemLuid))
424  {
425  return STATUS_ACCESS_DENIED;
426  }
427 
428  /* Allocate our request */
430  if (Request == NULL)
431  {
432  return STATUS_NO_MEMORY;
433  }
434 
435  /* Initialize it */
436  Request->DriveLetter = DriveLetter;
437  Request->RemoveDefinition = RemoveDefinition;
438  RtlCopyLuid(&Request->BroadcastLuid, BroadcastLuid);
439  Request->Next = NULL;
440 
441  /* And queue it */
443 
444  /* At the end of the queue if not empty */
446  {
448  }
449  /* Otherwise, initialize the queue */
450  else
451  {
453  }
454 
455  /* We're in FIFO mode */
457 
458  /* If we don't have a messaging thread running, then start one */
459  if (BaseSrvpBSMThreadCount >= 1)
460  {
462  }
463  else
464  {
467  }
468 
469  return Status;
470 }
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
struct _BSM_REQUEST * Next
Definition: dosdev.c:18
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
BOOLEAN LUIDDeviceMapsEnabled
Definition: base.h:133
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
PBSM_REQUEST BSM_Request_Queue
Definition: dosdev.c:28
#define SYSTEM_LUID
Definition: setypes.h:672
HANDLE BaseSrvHeap
Definition: init.c:29
PBSM_REQUEST BSM_Request_Queue_End
Definition: dosdev.c:28
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSTATUS CreateBSMThread(VOID)
Definition: dosdev.c:369
#define NULL
Definition: types.h:112
ULONG BaseSrvpBSMThreadCount
Definition: dosdev.c:29
NTSYSAPI void WINAPI RtlCopyLuid(PLUID, const LUID *)
RTL_CRITICAL_SECTION BaseSrvDDDBSMCritSec
Definition: dosdev.c:27
NTSTATUS GetCallerLuid(PLUID CallerLuid)
Definition: dosdev.c:45

Referenced by CSR_API().

◆ BaseCleanupDefineDosDevice()

VOID BaseCleanupDefineDosDevice ( VOID  )

Definition at line 39 of file dosdev.c.

40 {
42 }
static RTL_CRITICAL_SECTION BaseDefineDosDeviceCritSec
Definition: dosdev.c:26
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)

Referenced by DllMain().

◆ BaseInitDefineDosDevice()

VOID BaseInitDefineDosDevice ( VOID  )

Definition at line 34 of file dosdev.c.

35 {
37 }
static RTL_CRITICAL_SECTION BaseDefineDosDeviceCritSec
Definition: dosdev.c:26
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)

Referenced by CSR_SERVER_DLL_INIT().

◆ BaseSrvBSMThread()

ULONG NTAPI BaseSrvBSMThread ( PVOID  StartupContext)

Definition at line 314 of file dosdev.c.

315 {
318  PBSM_REQUEST CurrentRequest;
319 
320  /* We have a thread */
321  ExitStatus = 0;
324 
325  while (TRUE)
326  {
327  /* If we flushed the queue, job done */
328  if (BSM_Request_Queue == NULL)
329  {
330  break;
331  }
332 
333  /* Queue current request, and remove it from the queue */
334  CurrentRequest = BSM_Request_Queue;
336 
337  /* If that was the last request, NULLify queue end */
338  if (BSM_Request_Queue == NULL)
339  {
341  }
342 
344 
345  /* Broadcast the message */
347  CurrentRequest->RemoveDefinition,
348  &CurrentRequest->BroadcastLuid);
349 
350  /* Reflect the last entry status on stop */
351  CurrentRequest->Next = NULL;
352  ExitStatus = Status;
353 
354  RtlFreeHeap(BaseSrvHeap, 0, CurrentRequest);
356  }
357 
358  /* Here, we've flushed the queue, quit the user thread */
361 
362  NtCurrentTeb()->FreeStackOnTermination = TRUE;
364 
365  return ExitStatus;
366 }
LUID BroadcastLuid
Definition: dosdev.c:19
NTSTATUS BroadcastDriveLetterChange(LONG DriveLetter, BOOLEAN RemoveDefinition, PLUID BroadcastLuid)
Definition: dosdev.c:226
LONG RemoveDefinition
Definition: dosdev.c:21
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define NtCurrentThread()
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
struct _BSM_REQUEST * Next
Definition: dosdev.c:18
LONG DriveLetter
Definition: dosdev.c:20
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
Status
Definition: gdiplustypes.h:24
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
PBSM_REQUEST BSM_Request_Queue
Definition: dosdev.c:28
HANDLE BaseSrvHeap
Definition: init.c:29
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
PBSM_REQUEST BSM_Request_Queue_End
Definition: dosdev.c:28
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:859
#define NULL
Definition: types.h:112
ULONG BaseSrvpBSMThreadCount
Definition: dosdev.c:29
unsigned int ULONG
Definition: retypes.h:1
RTL_CRITICAL_SECTION BaseSrvDDDBSMCritSec
Definition: dosdev.c:27

Referenced by CreateBSMThread().

◆ BroadcastDriveLetterChange()

NTSTATUS BroadcastDriveLetterChange ( LONG  DriveLetter,
BOOLEAN  RemoveDefinition,
PLUID  BroadcastLuid 
)

Definition at line 226 of file dosdev.c.

229 {
230  HANDLE hUser32;
232  UNICODE_STRING User32U;
233  ANSI_STRING ProcedureName;
234  DWORD Recipients, Flags, wParam;
235  LUID SystemLuid = SYSTEM_LUID;
236  BSMINFO Info;
238 
239  /* We need a broadcast LUID */
240  if (BroadcastLuid == NULL)
241  {
243  }
244 
245  /* Get the Csr procedure, and keep it forever */
246  if (PBROADCASTSYSTEMMESSAGEEXW == NULL)
247  {
248  hUser32 = NULL;
249  RtlInitUnicodeString(&User32U, L"user32");
250  Status = LdrGetDllHandle(NULL, NULL, &User32U, &hUser32);
251  if (hUser32 != NULL && NT_SUCCESS(Status))
252  {
253  RtlInitString(&ProcedureName, "CsrBroadcastSystemMessageExW");
254  Status = LdrGetProcedureAddress(hUser32,
255  &ProcedureName,
256  0,
257  (PVOID *)&PBROADCASTSYSTEMMESSAGEEXW);
258  if (!NT_SUCCESS(Status))
259  {
260  PBROADCASTSYSTEMMESSAGEEXW = NULL;
261  }
262  }
263 
264  /* If we failed to get broadcast procedure, no more actions left */
265  if (PBROADCASTSYSTEMMESSAGEEXW == NULL)
266  {
267  return Status;
268  }
269  }
270 
271  /* Initialize broadcast info */
272  Info.cbSize = sizeof(BSMINFO);
273  Info.hdesk = 0;
274  Info.hwnd = 0;
275  RtlCopyLuid(&Info.luid, BroadcastLuid);
276 
277  /* Initialize volume information */
278  Volume.dbcv_size = sizeof(DEV_BROADCAST_VOLUME);
279  Volume.dbcv_devicetype = DBT_DEVTYP_VOLUME;
280  Volume.dbcv_reserved = 0;
281  Volume.dbcv_unitmask = 1 << DriveLetter;
282  Volume.dbcv_flags = DBTF_NET;
283 
284  /* Wide broadcast */
285  Recipients = BSM_APPLICATIONS | BSM_ALLDESKTOPS;
287 
288  /*
289  * If we don't broadcast as system, it's not a global drive
290  * notification, then mark it as LUID mapped drive
291  */
292  if (!RtlEqualLuid(&Info.luid, &SystemLuid))
293  {
294  Flags |= BSF_LUID;
295  }
296 
297  /* Set event type */
298  wParam = RemoveDefinition ? DBT_DEVICEREMOVECOMPLETE : DBT_DEVICEARRIVAL;
299 
300  /* And broadcast! */
301  Status = PBROADCASTSYSTEMMESSAGEEXW(Flags, &Recipients, WM_DEVICECHANGE, wParam, (LPARAM)&Volume, &Info);
302 
303  /* If the drive is global, notify Winsta */
304  if (!(Flags & BSF_LUID))
305  {
307  }
308 
309  return Status;
310 }
#define BSF_FORCEIFHUNG
Definition: dbt.h:54
NTSTATUS NTAPI LdrGetDllHandle(IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle)
Definition: ldrapi.c:805
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define BSF_NOTIMEOUTIFNOTHUNG
Definition: dbt.h:57
#define BSF_NOHANG
Definition: dbt.h:56
WPARAM wParam
Definition: combotst.c:138
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
#define DBT_DEVICEREMOVECOMPLETE
Definition: dbt.h:16
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
LONG_PTR LPARAM
Definition: windef.h:208
Status
Definition: gdiplustypes.h:24
NTSTATUS SendWinStationBSM(DWORD Flags, LPDWORD Recipients, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: dosdev.c:215
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DBT_DEVTYP_VOLUME
Definition: dbt.h:21
static const WCHAR L[]
Definition: oid.c:1250
#define SYSTEM_LUID
Definition: setypes.h:672
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
#define DBT_DEVICEARRIVAL
Definition: dbt.h:12
#define NULL
Definition: types.h:112
struct _DEV_BROADCAST_VOLUME DEV_BROADCAST_VOLUME
#define WM_DEVICECHANGE
Definition: winuser.h:1793
NTSYSAPI void WINAPI RtlCopyLuid(PLUID, const LUID *)
#define BSM_ALLDESKTOPS
Definition: dbt.h:49
#define DBTF_NET
Definition: dbt.h:44
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define BSM_APPLICATIONS
Definition: dbt.h:48

Referenced by BaseSrvBSMThread().

◆ CheckForGlobalDriveLetter()

BOOLEAN CheckForGlobalDriveLetter ( SHORT  DriveLetter)

Definition at line 162 of file dosdev.c.

163 {
164  WCHAR Path[8];
166  BOOLEAN IsGlobal;
167  UNICODE_STRING PathU;
168  HANDLE SymbolicLinkHandle;
170 
171  /* Setup our drive path */
172  wcsncpy(Path, L"\\??\\X:", (sizeof(L"\\??\\X:") / sizeof(WCHAR)));
173  Path[4] = DriveLetter + L'A';
174  Path[6] = UNICODE_NULL;
175 
176  /* Prepare everything to open the link */
177  RtlInitUnicodeString(&PathU, Path);
179  &PathU,
181  NULL,
182  NULL);
183 
184  /* Impersonate the caller */
186  {
187  return FALSE;
188  }
189 
190  /* Open our drive letter */
191  Status = NtOpenSymbolicLinkObject(&SymbolicLinkHandle,
194 
195  CsrRevertToSelf();
196 
197  if (!NT_SUCCESS(Status))
198  {
199  return FALSE;
200  }
201 
202  /* Check whether it's global */
203  Status = IsGlobalSymbolicLink(SymbolicLinkHandle, &IsGlobal);
204  NtClose(SymbolicLinkHandle);
205 
206  if (!NT_SUCCESS(Status))
207  {
208  return FALSE;
209  }
210 
211  return IsGlobal;
212 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI CsrRevertToSelf(VOID)
Definition: procsup.c:1057
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
NTSTATUS IsGlobalSymbolicLink(HANDLE LinkHandle, PBOOLEAN IsGlobal)
Definition: dosdev.c:96
static const WCHAR L[]
Definition: oid.c:1250
PRTL_UNICODE_STRING_BUFFER Path
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
#define NULL
Definition: types.h:112
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread)
Definition: procsup.c:932
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

Referenced by CSR_API().

◆ CreateBSMThread()

NTSTATUS CreateBSMThread ( VOID  )

Definition at line 369 of file dosdev.c.

370 {
371  /* This can only be true for LUID mappings */
373  {
374  return STATUS_ACCESS_DENIED;
375  }
376 
377  /* Create our user thread */
379  NULL,
380  FALSE,
381  0,
382  0,
383  0,
385  NULL,
386  NULL,
387  NULL);
388 }
ULONG NTAPI BaseSrvBSMThread(PVOID StartupContext)
Definition: dosdev.c:314
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
#define FALSE
Definition: types.h:117
BOOLEAN LUIDDeviceMapsEnabled
Definition: base.h:133
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
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)
#define NULL
Definition: types.h:112

Referenced by AddBSMRequest().

◆ CSR_API()

CSR_API ( BaseSrvDefineDosDevice  )

Definition at line 474 of file dosdev.c.

475 {
477  PBASE_DEFINE_DOS_DEVICE DefineDosDeviceRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.DefineDosDeviceRequest;
479  HANDLE LinkHandle;
482  ULONG Length;
485  PSID SystemSid;
486  PSID WorldSid;
487  PWSTR lpBuffer;
488  WCHAR Letter;
489  SHORT AbsLetter;
490  BOOLEAN DriveLetter = FALSE;
491  BOOLEAN RemoveDefinition;
492  BOOLEAN HandleTarget;
493  BOOLEAN Broadcast = FALSE;
494  BOOLEAN IsGlobal = FALSE;
495  ULONG CchLengthLeft;
496  ULONG CchLength;
497  ULONG TargetLength;
498  PWSTR TargetBuffer;
500  /* We store them on the stack, they are known in advance */
501  union {
503  UCHAR Buffer[20];
505  union {
506  ACL Dacl;
507  UCHAR Buffer[256];
508  } Dacl;
510  LUID CallerLuid;
511  WCHAR * CurrentPtr;
512  WCHAR CurrentChar;
513  PWSTR OrigPtr;
514  PWSTR InterPtr;
515  BOOLEAN RemoveFound;
516 
517  if (!CsrValidateMessageBuffer(ApiMessage,
518  (PVOID*)&DefineDosDeviceRequest->DeviceName.Buffer,
519  DefineDosDeviceRequest->DeviceName.Length,
520  sizeof(BYTE)) ||
521  (DefineDosDeviceRequest->DeviceName.Length & 1) != 0 ||
522  !CsrValidateMessageBuffer(ApiMessage,
523  (PVOID*)&DefineDosDeviceRequest->TargetPath.Buffer,
524  DefineDosDeviceRequest->TargetPath.Length +
525  (DefineDosDeviceRequest->TargetPath.Length != 0
526  ? sizeof(UNICODE_NULL) : 0),
527  sizeof(BYTE)) ||
528  (DefineDosDeviceRequest->TargetPath.Length & 1) != 0)
529  {
531  }
532 
533  DPRINT("BaseSrvDefineDosDevice entered, Flags:%d, DeviceName:%wZ (%d), TargetPath:%wZ (%d)\n",
534  DefineDosDeviceRequest->Flags,
535  &DefineDosDeviceRequest->DeviceName,
536  DefineDosDeviceRequest->DeviceName.Length,
537  &DefineDosDeviceRequest->TargetPath,
538  DefineDosDeviceRequest->TargetPath.Length);
539 
540  /*
541  * Allocate a buffer big enough to contain:
542  * - device name
543  * - targets
544  */
545  lpBuffer = RtlAllocateHeap(BaseSrvHeap, 0, 0x2000);
546  if (lpBuffer == NULL)
547  {
548  return STATUS_NO_MEMORY;
549  }
550 
551  /* Enter our critical section */
553  if (!NT_SUCCESS(Status))
554  {
555  DPRINT1("RtlEnterCriticalSection() failed (Status %lx)\n",
556  Status);
558  return Status;
559  }
560 
561  LinkHandle = 0;
562  /* Does the caller wants to remove definition? */
563  RemoveDefinition = !!(DefineDosDeviceRequest->Flags & DDD_REMOVE_DEFINITION);
564  _SEH2_TRY
565  {
566  /* First of all, check if that's a drive letter device amongst LUID mappings */
567  if (BaseStaticServerData->LUIDDeviceMapsEnabled && !(DefineDosDeviceRequest->Flags & DDD_NO_BROADCAST_SYSTEM))
568  {
569  if (DefineDosDeviceRequest->DeviceName.Buffer != NULL &&
570  DefineDosDeviceRequest->DeviceName.Length == 2 * sizeof(WCHAR) &&
571  DefineDosDeviceRequest->DeviceName.Buffer[1] == L':')
572  {
573  Letter = DefineDosDeviceRequest->DeviceName.Buffer[0];
574 
575  /* Handle both lower cases and upper cases */
576  AbsLetter = Letter - L'a';
577  if (AbsLetter < 26 && AbsLetter >= 0)
578  {
580  }
581 
582  AbsLetter = Letter - L'A';
583  if (AbsLetter < 26)
584  {
585  /* That's a letter! */
586  DriveLetter = TRUE;
587  }
588  }
589  }
590 
591  /* We can only broadcast drive letters in case of LUID mappings */
592  if (DefineDosDeviceRequest->Flags & DDD_LUID_BROADCAST_DRIVE &&
593  !DriveLetter)
594  {
596  _SEH2_LEAVE;
597  }
598 
599  /* First usage of our buffer: create device name */
600  CchLength = _snwprintf(lpBuffer, 0x1000, L"\\??\\%wZ", &DefineDosDeviceRequest->DeviceName);
601  CchLengthLeft = 0x1000 - 1 - CchLength; /* UNICODE_NULL */
602  CurrentBuffer = lpBuffer + CchLength + 1; /* UNICODE_NULL */
604 
605  /* And prepare to open it */
607  &DeviceName,
609  NULL,
610  NULL);
611 
612  /* Assume it's OK and has a target to deal with */
613  HandleTarget = TRUE;
614 
615  /* Move to the client context if the mapping was local */
617  {
619  _SEH2_LEAVE;
620  }
621 
622  /*
623  * While impersonating the caller, also get its LUID.
624  * This is mandatory in case we have a driver letter,
625  * Because we're in the case we've got LUID mapping
626  * enabled and broadcasting enabled. LUID will be required
627  * for the latter
628  */
629  if (DriveLetter)
630  {
631  Status = GetCallerLuid(&CallerLuid);
632  if (NT_SUCCESS(Status))
633  {
634  Broadcast = TRUE;
635  }
636  }
637 
638  /* Now, open the device */
639  Status = NtOpenSymbolicLinkObject(&LinkHandle,
642 
643  /* And get back to our context */
644  CsrRevertToSelf();
645 
646  /* In case of LUID broadcast, do nothing but return to trigger broadcast */
647  if (DefineDosDeviceRequest->Flags & DDD_LUID_BROADCAST_DRIVE)
648  {
649  /* Zero handle in case of a failure */
650  if (!NT_SUCCESS(Status))
651  {
652  LinkHandle = 0;
653  }
654 
655  /* If removal was asked, and no object found: the remval was successful */
656  if (RemoveDefinition && Status == STATUS_OBJECT_NAME_NOT_FOUND)
657  {
659  }
660 
661  /* We're done here, nothing more to do */
662  _SEH2_LEAVE;
663  }
664 
665  /* If device was not found */
667  {
668  /* No handle */
669  LinkHandle = 0;
670 
671  /* If we were asked to remove... */
672  if (RemoveDefinition)
673  {
674  /*
675  * If caller asked to pop first entry, nothing specific,
676  * then, we can consider this as a success
677  */
678  if (DefineDosDeviceRequest->TargetPath.Length == 0)
679  {
681  }
682 
683  /* We're done, nothing to change */
684  _SEH2_LEAVE;
685  }
686 
687  /* There's no target to handle */
688  HandleTarget = FALSE;
689 
690  /*
691  * We'll consider, that's a success
692  * Failing to open the device doesn't prevent
693  * from creating it later on to create
694  * the linking.
695  */
697  }
698  else
699  {
700  /* Unexpected failure, forward to caller */
701  if (!NT_SUCCESS(Status))
702  {
703  _SEH2_LEAVE;
704  }
705 
706  /* If LUID mapping enabled */
708  {
709  /* Check if that's global link */
710  Status = IsGlobalSymbolicLink(LinkHandle, &IsGlobal);
711  if (!NT_SUCCESS(Status))
712  {
713  _SEH2_LEAVE;
714  }
715 
716  /* If so, change our device name namespace to GLOBAL?? for link creation */
717  if (IsGlobal)
718  {
719  CchLength = _snwprintf(lpBuffer, 0x1000, L"\\GLOBAL??\\%wZ", &DefineDosDeviceRequest->DeviceName);
720  CchLengthLeft = 0x1000 - 1 - CchLength; /* UNICODE_NULL */
721  CurrentBuffer = lpBuffer + CchLength + 1; /* UNICODE_NULL */
722 
723  DeviceName.Length = CchLength * sizeof(WCHAR);
724  DeviceName.MaximumLength = CchLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
725  }
726  }
727  }
728 
729  /* If caller provided a target */
730  if (DefineDosDeviceRequest->TargetPath.Length != 0)
731  {
732  /* Make sure it's null terminated */
733  DefineDosDeviceRequest->TargetPath.Buffer[DefineDosDeviceRequest->TargetPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
734 
735  /* Compute its size */
736  TargetLength = wcslen(DefineDosDeviceRequest->TargetPath.Buffer);
737 
738  /* And make sure it fits our buffer */
739  if (TargetLength + 1 >= CchLengthLeft)
740  {
742  _SEH2_LEAVE;
743  }
744 
745  /* Copy it to our internal buffer */
746  RtlMoveMemory(CurrentBuffer, DefineDosDeviceRequest->TargetPath.Buffer, TargetLength * sizeof(WCHAR) + sizeof(UNICODE_NULL));
747  TargetBuffer = CurrentBuffer;
748 
749  /* Update our buffer status */
750  CchLengthLeft -= (TargetLength + 1);
751  CurrentBuffer += (TargetLength + 1);
752  }
753  /* Otherwise, zero everything */
754  else
755  {
756  TargetBuffer = NULL;
757  TargetLength = 0;
758  }
759 
760  /* If we opened the device, then, handle its current target */
761  if (HandleTarget)
762  {
763  /* Query it with our internal buffer */
764  LinkTarget.Length = 0;
765  LinkTarget.MaximumLength = CchLengthLeft * sizeof(WCHAR);
767 
768  Status = NtQuerySymbolicLinkObject(LinkHandle,
769  &LinkTarget,
770  &Length);
771  /* If we overflow, give up */
773  {
775  }
776  /* In case of a failure, bye bye */
777  if (!NT_SUCCESS(Status))
778  {
779  _SEH2_LEAVE;
780  }
781 
782  /*
783  * Properly null it for MULTI_SZ if needed
784  * Always update max length with
785  * the need size
786  * This is needed to hand relatively "small"
787  * strings to Ob and avoid killing ourselves
788  * on the next query
789  */
790  CchLength = Length / sizeof(WCHAR);
791  if (CchLength < 2 ||
792  CurrentBuffer[CchLength - 2] != UNICODE_NULL ||
793  CurrentBuffer[CchLength - 1] != UNICODE_NULL)
794  {
795  CurrentBuffer[CchLength] = UNICODE_NULL;
797  }
798  else
799  {
801  }
802  }
803  /* There's no target, and we're asked to remove, so null target */
804  else if (RemoveDefinition)
805  {
807  }
808  /* There's a target provided - new device, update buffer */
809  else
810  {
811  RtlInitUnicodeString(&LinkTarget, CurrentBuffer - TargetLength - 1);
812  }
813 
814  /*
815  * We no longer need old symlink, just drop it, we'll recreate it now
816  * with updated target.
817  * The benefit of it is that if caller asked us to drop last target, then
818  * the device is removed and not dangling
819  */
820  if (LinkHandle != 0)
821  {
822  Status = NtMakeTemporaryObject(LinkHandle);
823  NtClose(LinkHandle);
824  LinkHandle = 0;
825  }
826 
827  /* At this point, we must have no failure */
828  if (!NT_SUCCESS(Status))
829  {
830  _SEH2_LEAVE;
831  }
832 
833  /*
834  * If we have to remove definition, let's start to browse our
835  * target to actually drop it.
836  */
837  if (RemoveDefinition)
838  {
839  /* We'll browse our multi sz string */
840  RemoveFound = FALSE;
841  CurrentPtr = LinkTarget.Buffer;
842  InterPtr = LinkTarget.Buffer;
843  while (*CurrentPtr != UNICODE_NULL)
844  {
845  CchLength = 0;
846  OrigPtr = CurrentPtr;
847  /* First, find next string */
848  while (TRUE)
849  {
850  CurrentChar = *CurrentPtr;
851  ++CurrentPtr;
852 
853  if (CurrentChar == UNICODE_NULL)
854  {
855  break;
856  }
857 
858  ++CchLength;
859  }
860 
861  /* This check is a bit tricky, but dead useful:
862  * If on the previous loop, we found the caller provided target
863  * in our list, then, we'll move current entry over the found one
864  * So that, it gets deleted.
865  * Also, if we don't find caller entry in our entries, then move
866  * current entry in the string if a previous one got deleted
867  */
868  if (RemoveFound ||
869  ((!(DefineDosDeviceRequest->Flags & DDD_EXACT_MATCH_ON_REMOVE) ||
870  TargetLength != CchLength || _wcsicmp(OrigPtr, TargetBuffer) != 0) &&
871  ((DefineDosDeviceRequest->Flags & DDD_EXACT_MATCH_ON_REMOVE) ||
872  (TargetLength != 0 && _wcsnicmp(OrigPtr, TargetBuffer, TargetLength) != 0))))
873  {
874  if (InterPtr != OrigPtr)
875  {
876  RtlMoveMemory(InterPtr, OrigPtr, sizeof(WCHAR) * CchLength + sizeof(UNICODE_NULL));
877  }
878 
879  InterPtr += (CchLength + 1);
880  }
881  else
882  {
883  /* Match case! Remember for next loop turn and to delete it */
884  RemoveFound = TRUE;
885  }
886  }
887 
888  /*
889  * Drop last entry, as required (pop)
890  * If there was a match previously, everything
891  * is already moved, so we're just nulling
892  * the end of the string
893  * If there was no match, this is the pop
894  */
895  *InterPtr = UNICODE_NULL;
896  ++InterPtr;
897 
898  /* Compute new target length */
899  TargetLength = wcslen(LinkTarget.Buffer) * sizeof(WCHAR);
900  /*
901  * If it's empty, quit
902  * Beware, here, we quit with STATUS_SUCCESS, and that's expected!
903  * In case we dropped last target entry, then, it's empty
904  * and there's no need to recreate the device we deleted previously
905  */
906  if (TargetLength == 0)
907  {
908  _SEH2_LEAVE;
909  }
910 
911  /* Update our target string */
912  LinkTarget.Length = TargetLength;
914  }
915  /* If that's not a removal, just update the target to include new target */
916  else if (HandleTarget)
917  {
918  LinkTarget.Buffer = LinkTarget.Buffer - TargetLength - 1;
919  LinkTarget.Length = TargetLength * sizeof(WCHAR);
920  LinkTarget.MaximumLength += (TargetLength * sizeof(WCHAR) + sizeof(UNICODE_NULL));
921  TargetLength *= sizeof(WCHAR);
922  }
923  /* No changes */
924  else
925  {
926  TargetLength = LinkTarget.Length;
927  }
928 
929  /* Make sure we don't create empty symlink */
930  if (TargetLength == 0)
931  {
932  _SEH2_LEAVE;
933  }
934 
935  /* Initialize our SIDs for symlink ACLs */
937  1,
946  &WorldSid);
947  if (!NT_SUCCESS(Status))
948  {
949  _SEH2_LEAVE;
950  }
951 
953  1,
962  &SystemSid);
963  if (!NT_SUCCESS(Status))
964  {
966  _SEH2_LEAVE;
967  }
968 
969  /* Initialize our SD (on stack) */
972 
973  /* And our ACL (still on stack) */
974  RtlCreateAcl(&Dacl.Dacl, sizeof(Dacl), ACL_REVISION);
975 
976  /*
977  * For access mask, if we have no session ID, or if
978  * protection mode is disabled, make them wide open
979  */
980  if (SessionId == 0 ||
981  (ProtectionMode & 3) == 0)
982  {
984  }
985  else
986  {
988  }
989 
990  /* Setup the ACL */
993 
994  /* Drop SIDs */
996  RtlFreeSid(SystemSid);
997 
998  /* Link DACL to the SD */
1000 
1001  /* And set it in the OA used for creation */
1002  ObjectAttributes.SecurityDescriptor = &SecurityDescriptor;
1003 
1004  /*
1005  * If LUID and not global, we need to impersonate the caller
1006  * to make it local.
1007  */
1009  {
1010  if (!IsGlobal)
1011  {
1012  if (!CsrImpersonateClient(NULL))
1013  {
1015  _SEH2_LEAVE;
1016  }
1017  }
1018  }
1019  /* The object will be permanent */
1020  else
1021  {
1022  ObjectAttributes.Attributes |= OBJ_PERMANENT;
1023  }
1024 
1025  /* (Re)Create the symbolic link/device */
1026  Status = NtCreateSymbolicLinkObject(&LinkHandle,
1029  &LinkTarget);
1030 
1031  /* Revert to self if required */
1032  if (BaseStaticServerData->LUIDDeviceMapsEnabled && !IsGlobal)
1033  {
1034  CsrRevertToSelf();
1035  }
1036 
1037  /* In case of a success, make object permanent for LUID links */
1038  if (NT_SUCCESS(Status))
1039  {
1041  {
1042  Status = NtMakePermanentObject(LinkHandle);
1043  }
1044 
1045  /* Close the link */
1046  NtClose(LinkHandle);
1047 
1048  /*
1049  * Specific failure case here:
1050  * We were asked to remove something
1051  * but we didn't find the something
1052  * (we recreated the symlink hence the fail here!)
1053  * so fail with appropriate status
1054  */
1055  if (RemoveDefinition && !RemoveFound)
1056  {
1058  }
1059  }
1060 
1061  /* We closed link, don't double close */
1062  LinkHandle = 0;
1063  }
1065  {
1066  /* If we need to close the link, do it now */
1067  if (LinkHandle != 0)
1068  {
1069  NtClose(LinkHandle);
1070  }
1071 
1072  /* Free our internal buffer */
1074 
1075  /* Broadcast drive letter creation */
1076  if (DriveLetter && Status == STATUS_SUCCESS && Broadcast)
1077  {
1078  LUID SystemLuid = SYSTEM_LUID;
1079 
1080  /* If that's a global drive, broadcast as system */
1081  if (IsGlobal)
1082  {
1083  RtlCopyLuid(&CallerLuid, &SystemLuid);
1084  }
1085 
1086  /* Broadcast the event */
1087  AddBSMRequest(AbsLetter, RemoveDefinition, &CallerLuid);
1088 
1089  /*
1090  * If we removed drive, and the drive was shadowing a global one
1091  * broadcast the arrival of the global drive (as system - global)
1092  */
1093  if (RemoveDefinition && !RtlEqualLuid(&CallerLuid, &SystemLuid))
1094  {
1095  if (CheckForGlobalDriveLetter(AbsLetter))
1096  {
1097  AddBSMRequest(AbsLetter, FALSE, &CallerLuid);
1098  }
1099  }
1100  }
1101 
1102  /* Done! */
1104  }
1105  _SEH2_END;
1106 
1107  return Status;
1108 }
static ACPI_BUFFER CurrentBuffer
UNICODE_STRING TargetPath
Definition: basemsg.h:257
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define DDD_REMOVE_DEFINITION
Definition: winbase.h:521
uint16_t * PWSTR
Definition: typedefs.h:56
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
ULONG SessionId
Definition: dllmain.c:28
LONG NTSTATUS
Definition: precomp.h:26
#define DDD_NO_BROADCAST_SYSTEM
Definition: winbase.h:523
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
BOOLEAN NTAPI CsrRevertToSelf(VOID)
Definition: procsup.c:1057
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSTATUS AddBSMRequest(LONG DriveLetter, BOOLEAN RemoveDefinition, PLUID BroadcastLuid)
Definition: dosdev.c:391
NTSTATUS NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1385
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
NTSYSAPI WCHAR NTAPI RtlUpcaseUnicodeChar(WCHAR Source)
NTSYSAPI NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
NTSTATUS NTAPI NtMakePermanentObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1422
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_SEH2_TRY
Definition: create.c:4226
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
static RTL_CRITICAL_SECTION BaseDefineDosDeviceCritSec
Definition: dosdev.c:26
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
short SHORT
Definition: pedump.c:59
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
UNICODE_STRING DeviceName
Definition: basemsg.h:256
struct _BASE_API_MESSAGE * PBASE_API_MESSAGE
unsigned char BOOLEAN
BOOLEAN LUIDDeviceMapsEnabled
Definition: base.h:133
#define ACL_REVISION2
Definition: setypes.h:43
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
Definition: bufpool.h:45
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:526
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:499
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
#define SECURITY_NULL_RID
Definition: setypes.h:512
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1552
unsigned char UCHAR
Definition: xmlstorage.h:181
ULONG ProtectionMode
Definition: init.c:34
NTSTATUS IsGlobalSymbolicLink(HANDLE LinkHandle, PBOOLEAN IsGlobal)
Definition: dosdev.c:96
static const WCHAR L[]
Definition: oid.c:1250
WCHAR Letter
PSID WorldSid
Definition: globals.c:15
#define OBJ_PERMANENT
Definition: winternl.h:226
unsigned char BYTE
Definition: xxhash.c:193
#define SYSTEM_LUID
Definition: setypes.h:672
HANDLE BaseSrvHeap
Definition: init.c:29
_SEH2_END
Definition: create.c:4400
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
_SEH2_FINALLY
Definition: create.c:4371
#define DDD_LUID_BROADCAST_DRIVE
Definition: winbase.h:524
#define SECURITY_RESTRICTED_CODE_RID
Definition: setypes.h:541
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
#define ACL_REVISION
Definition: setypes.h:39
NTSYSAPI void WINAPI RtlCopyLuid(PLUID, const LUID *)
unsigned int ULONG
Definition: retypes.h:1
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread)
Definition: procsup.c:932
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_LEAVE
Definition: filesup.c:20
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN CheckForGlobalDriveLetter(SHORT DriveLetter)
Definition: dosdev.c:162
NTSTATUS GetCallerLuid(PLUID CallerLuid)
Definition: dosdev.c:45
ULONG ACCESS_MASK
Definition: nt_native.h:40
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define DELETE
Definition: nt_native.h:57
#define DDD_EXACT_MATCH_ON_REMOVE
Definition: winbase.h:522
static SID_IDENTIFIER_AUTHORITY SystemAuthority
Definition: msgina.c:38

◆ GetCallerLuid()

NTSTATUS GetCallerLuid ( PLUID  CallerLuid)

Definition at line 45 of file dosdev.c.

46 {
50  TOKEN_STATISTICS TokenInformation;
51 
52  /* We need an output buffer */
53  if (CallerLuid == NULL)
54  {
56  }
57 
58  /* Open thread token */
59  TokenHandle = 0;
60  ReturnLength = 0;
63  FALSE, &TokenHandle);
64  /* If we fail, open process token */
65  if (Status == STATUS_NO_TOKEN)
66  {
69  &TokenHandle);
70  }
71 
72  /* In case of a success get caller LUID and copy it back */
73  if (NT_SUCCESS(Status))
74  {
77  &TokenInformation,
78  sizeof(TokenInformation),
79  &ReturnLength);
80  if (NT_SUCCESS(Status))
81  {
82  RtlCopyLuid(CallerLuid, &TokenInformation.AuthenticationId);
83  }
84  }
85 
86  /* Close token handle */
87  if (TokenHandle != 0)
88  {
90  }
91 
92  return Status;
93 }
LUID AuthenticationId
Definition: setypes.h:1033
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define NtCurrentThread()
NTSTATUS NTAPI NtOpenProcessToken(IN HANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, OUT PHANDLE TokenHandle)
Definition: security.c:350
#define FALSE
Definition: types.h:117
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtQueryInformationToken(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID TokenInformation, _In_ ULONG TokenInformationLength, _Out_ PULONG ReturnLength)
Definition: token.c:2373
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
#define TOKEN_QUERY
Definition: setypes.h:874
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_NO_TOKEN
Definition: ntstatus.h:360
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
#define READ_CONTROL
Definition: nt_native.h:58
#define NULL
Definition: types.h:112
NTSYSAPI void WINAPI RtlCopyLuid(PLUID, const LUID *)
NTSTATUS NTAPI NtOpenThreadToken(IN HANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN BOOLEAN OpenAsSelf, OUT PHANDLE TokenHandle)
Definition: token.c:4393
unsigned int ULONG
Definition: retypes.h:1

Referenced by AddBSMRequest(), and CSR_API().

◆ IsGlobalSymbolicLink()

NTSTATUS IsGlobalSymbolicLink ( HANDLE  LinkHandle,
PBOOLEAN  IsGlobal 
)

Definition at line 96 of file dosdev.c.

98 {
101  UNICODE_STRING GlobalString;
102  OBJECT_NAME_INFORMATION NameInfo, *PNameInfo;
103 
104  /* We need both parameters */
105  if (LinkHandle == 0 || IsGlobal == NULL)
106  {
108  }
109 
110  PNameInfo = NULL;
111  _SEH2_TRY
112  {
113  /* Query handle information */
114  Status = NtQueryObject(LinkHandle,
116  &NameInfo,
117  0,
118  &ReturnLength);
119  /* Only failure we tolerate is length mismatch */
121  {
122  /* Allocate big enough buffer */
123  PNameInfo = RtlAllocateHeap(BaseSrvHeap, 0, ReturnLength);
124  if (PNameInfo == NULL)
125  {
127  _SEH2_LEAVE;
128  }
129 
130  /* Query again handle information */
131  Status = NtQueryObject(LinkHandle,
133  PNameInfo,
134  ReturnLength,
135  &ReturnLength);
136 
137  /*
138  * If it succeed, check we have Global??
139  * If so, return success
140  */
141  if (NT_SUCCESS(Status))
142  {
143  RtlInitUnicodeString(&GlobalString, L"\\GLOBAL??");
144  *IsGlobal = RtlPrefixUnicodeString(&GlobalString, &PNameInfo->Name, FALSE);
146  }
147  }
148  }
150  {
151  if (PNameInfo != NULL)
152  {
153  RtlFreeHeap(BaseSrvHeap, 0, PNameInfo);
154  }
155  }
156  _SEH2_END;
157 
158  return Status;
159 }
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
UNICODE_STRING Name
Definition: nt_native.h:1270
_SEH2_TRY
Definition: create.c:4226
#define FALSE
Definition: types.h:117
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NtQueryObject(IN HANDLE Handle, IN OBJECT_INFO_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength)
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
HANDLE BaseSrvHeap
Definition: init.c:29
_SEH2_END
Definition: create.c:4400
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
_SEH2_FINALLY
Definition: create.c:4371
#define NULL
Definition: types.h:112
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_LEAVE
Definition: filesup.c:20

Referenced by CheckForGlobalDriveLetter(), and CSR_API().

◆ LONG()

LONG ( WINAPI PBROADCASTSYSTEMMESSAGEEXW)

◆ SendWinStationBSM()

NTSTATUS SendWinStationBSM ( DWORD  Flags,
LPDWORD  Recipients,
UINT  Message,
WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 215 of file dosdev.c.

220 {
222  return STATUS_NOT_IMPLEMENTED;
223 }
return STATUS_NOT_IMPLEMENTED
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by BroadcastDriveLetterChange().

Variable Documentation

◆ BaseDefineDosDeviceCritSec

RTL_CRITICAL_SECTION BaseDefineDosDeviceCritSec
static

Definition at line 26 of file dosdev.c.

Referenced by BaseCleanupDefineDosDevice(), BaseInitDefineDosDevice(), and CSR_API().

◆ BaseSrvDDDBSMCritSec

RTL_CRITICAL_SECTION BaseSrvDDDBSMCritSec

Definition at line 27 of file dosdev.c.

Referenced by AddBSMRequest(), BaseInitializeStaticServerData(), and BaseSrvBSMThread().

◆ BaseSrvpBSMThreadCount

ULONG BaseSrvpBSMThreadCount = 0

Definition at line 29 of file dosdev.c.

Referenced by AddBSMRequest(), and BaseSrvBSMThread().

◆ BSM_Request_Queue

PBSM_REQUEST BSM_Request_Queue = NULL

Definition at line 28 of file dosdev.c.

Referenced by AddBSMRequest(), and BaseSrvBSMThread().

◆ BSM_Request_Queue_End

PBSM_REQUEST BSM_Request_Queue_End = NULL

Definition at line 28 of file dosdev.c.

Referenced by AddBSMRequest(), and BaseSrvBSMThread().

◆ LPARAM

Definition at line 30 of file dosdev.c.

Referenced by DefineDosDeviceW().

◆ LPDWORD

Definition at line 30 of file dosdev.c.

Referenced by DefineDosDeviceW().

◆ PBSMINFO

PBSMINFO = NULL

Definition at line 30 of file dosdev.c.

◆ UINT

Definition at line 30 of file dosdev.c.

Referenced by DefineDosDeviceW().

◆ WPARAM

Definition at line 30 of file dosdev.c.

Referenced by DefineDosDeviceW().