ReactOS  0.4.15-dev-1197-g8081ba9
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 }
_In_ WDFREQUEST Request
Definition: cdrom.h:1234
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)
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
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
Status
Definition: gdiplustypes.h:24
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
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)
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
Status
Definition: gdiplustypes.h:24
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
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
struct TraceInfo Info
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#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
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
NTSTATUS SendWinStationBSM(DWORD Flags, LPDWORD Recipients, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: dosdev.c:215
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DBT_DEVTYP_VOLUME
Definition: dbt.h:21
Status
Definition: gdiplustypes.h:24
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
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:1056
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
Status
Definition: gdiplustypes.h:24
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 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:931
#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
smooth NULL
Definition: ftsmooth.c:416
#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)

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 0
518  /* FIXME: Check why it fails.... */
519  if (!CsrValidateMessageBuffer(ApiMessage,
520  (PVOID*)&DefineDosDeviceRequest->DeviceName,
521  DefineDosDeviceRequest->DeviceName.Length,
522  1) ||
523  (DefineDosDeviceRequest->DeviceName.Length & 1) != 0 ||
524  !CsrValidateMessageBuffer(ApiMessage,
525  (PVOID*)&DefineDosDeviceRequest->TargetPath,
526  (DefineDosDeviceRequest->TargetPath.Length != 0 ? sizeof(UNICODE_NULL) : 0) + DefineDosDeviceRequest->TargetPath.Length,
527  1) ||
528  (DefineDosDeviceRequest->TargetPath.Length & 1) != 0)
529  {
531  }
532 #endif
533 
534  DPRINT("BaseSrvDefineDosDevice entered, Flags:%d, DeviceName:%wZ (%d), TargetPath:%wZ (%d)\n",
535  DefineDosDeviceRequest->Flags,
536  &DefineDosDeviceRequest->DeviceName,
537  DefineDosDeviceRequest->DeviceName.Length,
538  &DefineDosDeviceRequest->TargetPath,
539  DefineDosDeviceRequest->TargetPath.Length);
540 
541  /*
542  * Allocate a buffer big enough to contain:
543  * - device name
544  * - targets
545  */
546  lpBuffer = RtlAllocateHeap(BaseSrvHeap, 0, 0x2000);
547  if (lpBuffer == NULL)
548  {
549  return STATUS_NO_MEMORY;
550  }
551 
552  /* Enter our critical section */
554  if (!NT_SUCCESS(Status))
555  {
556  DPRINT1("RtlEnterCriticalSection() failed (Status %lx)\n",
557  Status);
559  return Status;
560  }
561 
562  LinkHandle = 0;
563  /* Does the caller wants to remove definition? */
564  RemoveDefinition = !!(DefineDosDeviceRequest->Flags & DDD_REMOVE_DEFINITION);
565  _SEH2_TRY
566  {
567  /* First of all, check if that's a drive letter device amongst LUID mappings */
568  if (BaseStaticServerData->LUIDDeviceMapsEnabled && !(DefineDosDeviceRequest->Flags & DDD_NO_BROADCAST_SYSTEM))
569  {
570  if (DefineDosDeviceRequest->DeviceName.Buffer != NULL &&
571  DefineDosDeviceRequest->DeviceName.Length == 2 * sizeof(WCHAR) &&
572  DefineDosDeviceRequest->DeviceName.Buffer[1] == L':')
573  {
574  Letter = DefineDosDeviceRequest->DeviceName.Buffer[0];
575 
576  /* Handle both lower cases and upper cases */
577  AbsLetter = Letter - L'a';
578  if (AbsLetter < 26 && AbsLetter >= 0)
579  {
581  }
582 
583  AbsLetter = Letter - L'A';
584  if (AbsLetter < 26)
585  {
586  /* That's a letter! */
587  DriveLetter = TRUE;
588  }
589  }
590  }
591 
592  /* We can only broadcast drive letters in case of LUID mappings */
593  if (DefineDosDeviceRequest->Flags & DDD_LUID_BROADCAST_DRIVE &&
594  !DriveLetter)
595  {
597  _SEH2_LEAVE;
598  }
599 
600  /* First usage of our buffer: create device name */
601  CchLength = _snwprintf(lpBuffer, 0x1000, L"\\??\\%wZ", &DefineDosDeviceRequest->DeviceName);
602  CchLengthLeft = 0x1000 - 1 - CchLength; /* UNICODE_NULL */
603  CurrentBuffer = lpBuffer + CchLength + 1; /* UNICODE_NULL */
605 
606  /* And prepare to open it */
608  &DeviceName,
610  NULL,
611  NULL);
612 
613  /* Assume it's OK and has a target to deal with */
614  HandleTarget = TRUE;
615 
616  /* Move to the client context if the mapping was local */
618  {
620  _SEH2_LEAVE;
621  }
622 
623  /*
624  * While impersonating the caller, also get its LUID.
625  * This is mandatory in case we have a driver letter,
626  * Because we're in the case we've got LUID mapping
627  * enabled and broadcasting enabled. LUID will be required
628  * for the latter
629  */
630  if (DriveLetter)
631  {
632  Status = GetCallerLuid(&CallerLuid);
633  if (NT_SUCCESS(Status))
634  {
635  Broadcast = TRUE;
636  }
637  }
638 
639  /* Now, open the device */
640  Status = NtOpenSymbolicLinkObject(&LinkHandle,
643 
644  /* And get back to our context */
645  CsrRevertToSelf();
646 
647  /* In case of LUID broadcast, do nothing but return to trigger broadcast */
648  if (DefineDosDeviceRequest->Flags & DDD_LUID_BROADCAST_DRIVE)
649  {
650  /* Zero handle in case of a failure */
651  if (!NT_SUCCESS(Status))
652  {
653  LinkHandle = 0;
654  }
655 
656  /* If removal was asked, and no object found: the remval was successful */
657  if (RemoveDefinition && Status == STATUS_OBJECT_NAME_NOT_FOUND)
658  {
660  }
661 
662  /* We're done here, nothing more to do */
663  _SEH2_LEAVE;
664  }
665 
666  /* If device was not found */
668  {
669  /* No handle */
670  LinkHandle = 0;
671 
672  /* If we were asked to remove... */
673  if (RemoveDefinition)
674  {
675  /*
676  * If caller asked to pop first entry, nothing specific,
677  * then, we can consider this as a success
678  */
679  if (DefineDosDeviceRequest->TargetPath.Length == 0)
680  {
682  }
683 
684  /* We're done, nothing to change */
685  _SEH2_LEAVE;
686  }
687 
688  /* There's no target to handle */
689  HandleTarget = FALSE;
690 
691  /*
692  * We'll consider, that's a success
693  * Failing to open the device doesn't prevent
694  * from creating it later on to create
695  * the linking.
696  */
698  }
699  else
700  {
701  /* Unexpected failure, forward to caller */
702  if (!NT_SUCCESS(Status))
703  {
704  _SEH2_LEAVE;
705  }
706 
707  /* If LUID mapping enabled */
709  {
710  /* Check if that's global link */
711  Status = IsGlobalSymbolicLink(LinkHandle, &IsGlobal);
712  if (!NT_SUCCESS(Status))
713  {
714  _SEH2_LEAVE;
715  }
716 
717  /* If so, change our device name namespace to GLOBAL?? for link creation */
718  if (IsGlobal)
719  {
720  CchLength = _snwprintf(lpBuffer, 0x1000, L"\\GLOBAL??\\%wZ", &DefineDosDeviceRequest->DeviceName);
721  CchLengthLeft = 0x1000 - 1 - CchLength; /* UNICODE_NULL */
722  CurrentBuffer = lpBuffer + CchLength + 1; /* UNICODE_NULL */
723 
724  DeviceName.Length = CchLength * sizeof(WCHAR);
725  DeviceName.MaximumLength = CchLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
726  }
727  }
728  }
729 
730  /* If caller provided a target */
731  if (DefineDosDeviceRequest->TargetPath.Length != 0)
732  {
733  /* Make sure it's null terminated */
734  DefineDosDeviceRequest->TargetPath.Buffer[DefineDosDeviceRequest->TargetPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
735 
736  /* Compute its size */
737  TargetLength = wcslen(DefineDosDeviceRequest->TargetPath.Buffer);
738 
739  /* And make sure it fits our buffer */
740  if (TargetLength + 1 >= CchLengthLeft)
741  {
743  _SEH2_LEAVE;
744  }
745 
746  /* Copy it to our internal buffer */
747  RtlMoveMemory(CurrentBuffer, DefineDosDeviceRequest->TargetPath.Buffer, TargetLength * sizeof(WCHAR) + sizeof(UNICODE_NULL));
748  TargetBuffer = CurrentBuffer;
749 
750  /* Update our buffer status */
751  CchLengthLeft -= (TargetLength + 1);
752  CurrentBuffer += (TargetLength + 1);
753  }
754  /* Otherwise, zero everything */
755  else
756  {
757  TargetBuffer = NULL;
758  TargetLength = 0;
759  }
760 
761  /* If we opened the device, then, handle its current target */
762  if (HandleTarget)
763  {
764  /* Query it with our internal buffer */
765  LinkTarget.Length = 0;
766  LinkTarget.MaximumLength = CchLengthLeft * sizeof(WCHAR);
768 
769  Status = NtQuerySymbolicLinkObject(LinkHandle,
770  &LinkTarget,
771  &Length);
772  /* If we overflow, give up */
774  {
776  }
777  /* In case of a failure, bye bye */
778  if (!NT_SUCCESS(Status))
779  {
780  _SEH2_LEAVE;
781  }
782 
783  /*
784  * Properly null it for MULTI_SZ if needed
785  * Always update max length with
786  * the need size
787  * This is needed to hand relatively "small"
788  * strings to Ob and avoid killing ourselves
789  * on the next query
790  */
791  CchLength = Length / sizeof(WCHAR);
792  if (CchLength < 2 ||
793  CurrentBuffer[CchLength - 2] != UNICODE_NULL ||
794  CurrentBuffer[CchLength - 1] != UNICODE_NULL)
795  {
796  CurrentBuffer[CchLength] = UNICODE_NULL;
798  }
799  else
800  {
802  }
803  }
804  /* There's no target, and we're asked to remove, so null target */
805  else if (RemoveDefinition)
806  {
808  }
809  /* There's a target provided - new device, update buffer */
810  else
811  {
812  RtlInitUnicodeString(&LinkTarget, CurrentBuffer - TargetLength - 1);
813  }
814 
815  /*
816  * We no longer need old symlink, just drop it, we'll recreate it now
817  * with updated target.
818  * The benefit of it is that if caller asked us to drop last target, then
819  * the device is removed and not dangling
820  */
821  if (LinkHandle != 0)
822  {
823  Status = NtMakeTemporaryObject(LinkHandle);
824  NtClose(LinkHandle);
825  LinkHandle = 0;
826  }
827 
828  /* At this point, we must have no failure */
829  if (!NT_SUCCESS(Status))
830  {
831  _SEH2_LEAVE;
832  }
833 
834  /*
835  * If we have to remove definition, let's start to browse our
836  * target to actually drop it.
837  */
838  if (RemoveDefinition)
839  {
840  /* We'll browse our multi sz string */
841  RemoveFound = FALSE;
842  CurrentPtr = LinkTarget.Buffer;
843  InterPtr = LinkTarget.Buffer;
844  while (*CurrentPtr != UNICODE_NULL)
845  {
846  CchLength = 0;
847  OrigPtr = CurrentPtr;
848  /* First, find next string */
849  while (TRUE)
850  {
851  CurrentChar = *CurrentPtr;
852  ++CurrentPtr;
853 
854  if (CurrentChar == UNICODE_NULL)
855  {
856  break;
857  }
858 
859  ++CchLength;
860  }
861 
862  /* This check is a bit tricky, but dead useful:
863  * If on the previous loop, we found the caller provided target
864  * in our list, then, we'll move current entry over the found one
865  * So that, it gets deleted.
866  * Also, if we don't find caller entry in our entries, then move
867  * current entry in the string if a previous one got deleted
868  */
869  if (RemoveFound ||
870  ((!(DefineDosDeviceRequest->Flags & DDD_EXACT_MATCH_ON_REMOVE) ||
871  TargetLength != CchLength || _wcsicmp(OrigPtr, TargetBuffer) != 0) &&
872  ((DefineDosDeviceRequest->Flags & DDD_EXACT_MATCH_ON_REMOVE) ||
873  (TargetLength != 0 && _wcsnicmp(OrigPtr, TargetBuffer, TargetLength) != 0))))
874  {
875  if (InterPtr != OrigPtr)
876  {
877  RtlMoveMemory(InterPtr, OrigPtr, sizeof(WCHAR) * CchLength + sizeof(UNICODE_NULL));
878  }
879 
880  InterPtr += (CchLength + 1);
881  }
882  else
883  {
884  /* Match case! Remember for next loop turn and to delete it */
885  RemoveFound = TRUE;
886  }
887  }
888 
889  /*
890  * Drop last entry, as required (pop)
891  * If there was a match previously, everything
892  * is already moved, so we're just nulling
893  * the end of the string
894  * If there was no match, this is the pop
895  */
896  *InterPtr = UNICODE_NULL;
897  ++InterPtr;
898 
899  /* Compute new target length */
900  TargetLength = wcslen(LinkTarget.Buffer) * sizeof(WCHAR);
901  /*
902  * If it's empty, quit
903  * Beware, here, we quit with STATUS_SUCCESS, and that's expected!
904  * In case we dropped last target entry, then, it's empty
905  * and there's no need to recreate the device we deleted previously
906  */
907  if (TargetLength == 0)
908  {
909  _SEH2_LEAVE;
910  }
911 
912  /* Update our target string */
913  LinkTarget.Length = TargetLength;
915  }
916  /* If that's not a removal, just update the target to include new target */
917  else if (HandleTarget)
918  {
919  LinkTarget.Buffer = LinkTarget.Buffer - TargetLength - 1;
920  LinkTarget.Length = TargetLength * sizeof(WCHAR);
921  LinkTarget.MaximumLength += (TargetLength * sizeof(WCHAR) + sizeof(UNICODE_NULL));
922  TargetLength *= sizeof(WCHAR);
923  }
924  /* No changes */
925  else
926  {
927  TargetLength = LinkTarget.Length;
928  }
929 
930  /* Make sure we don't create empty symlink */
931  if (TargetLength == 0)
932  {
933  _SEH2_LEAVE;
934  }
935 
936  /* Initialize our SIDs for symlink ACLs */
938  1,
947  &WorldSid);
948  if (!NT_SUCCESS(Status))
949  {
950  _SEH2_LEAVE;
951  }
952 
954  1,
963  &SystemSid);
964  if (!NT_SUCCESS(Status))
965  {
967  _SEH2_LEAVE;
968  }
969 
970  /* Initialize our SD (on stack) */
973 
974  /* And our ACL (still on stack) */
975  RtlCreateAcl(&Dacl.Dacl, sizeof(Dacl), ACL_REVISION);
976 
977  /*
978  * For access mask, if we have no session ID, or if
979  * protection mode is disabled, make them wide open
980  */
981  if (SessionId == 0 ||
982  (ProtectionMode & 3) == 0)
983  {
985  }
986  else
987  {
989  }
990 
991  /* Setup the ACL */
994 
995  /* Drop SIDs */
997  RtlFreeSid(SystemSid);
998 
999  /* Link DACL to the SD */
1001 
1002  /* And set it in the OA used for creation */
1003  ObjectAttributes.SecurityDescriptor = &SecurityDescriptor;
1004 
1005  /*
1006  * If LUID and not global, we need to impersonate the caller
1007  * to make it local.
1008  */
1010  {
1011  if (!IsGlobal)
1012  {
1013  if (!CsrImpersonateClient(NULL))
1014  {
1016  _SEH2_LEAVE;
1017  }
1018  }
1019  }
1020  /* The object will be permanent */
1021  else
1022  {
1023  ObjectAttributes.Attributes |= OBJ_PERMANENT;
1024  }
1025 
1026  /* (Re)Create the symbolic link/device */
1027  Status = NtCreateSymbolicLinkObject(&LinkHandle,
1030  &LinkTarget);
1031 
1032  /* Revert to self if required */
1033  if (BaseStaticServerData->LUIDDeviceMapsEnabled && !IsGlobal)
1034  {
1035  CsrRevertToSelf();
1036  }
1037 
1038  /* In case of a success, make object permanent for LUID links */
1039  if (NT_SUCCESS(Status))
1040  {
1042  {
1043  Status = NtMakePermanentObject(LinkHandle);
1044  }
1045 
1046  /* Close the link */
1047  NtClose(LinkHandle);
1048 
1049  /*
1050  * Specific failure case here:
1051  * We were asked to remove something
1052  * but we didn't find the something
1053  * (we recreated the symlink hence the fail here!)
1054  * so fail with appropriate status
1055  */
1056  if (RemoveDefinition && !RemoveFound)
1057  {
1059  }
1060  }
1061 
1062  /* We closed link, don't double close */
1063  LinkHandle = 0;
1064  }
1066  {
1067  /* If we need to close the link, do it now */
1068  if (LinkHandle != 0)
1069  {
1070  NtClose(LinkHandle);
1071  }
1072 
1073  /* Free our internal buffer */
1075 
1076  /* Broadcast drive letter creation */
1077  if (DriveLetter && Status == STATUS_SUCCESS && Broadcast)
1078  {
1079  LUID SystemLuid = SYSTEM_LUID;
1080 
1081  /* If that's a global drive, broadcast as system */
1082  if (IsGlobal)
1083  {
1084  RtlCopyLuid(&CallerLuid, &SystemLuid);
1085  }
1086 
1087  /* Broadcast the event */
1088  AddBSMRequest(AbsLetter, RemoveDefinition, &CallerLuid);
1089 
1090  /*
1091  * If we removed drive, and the drive was shadowing a global one
1092  * broadcast the arrival of the global drive (as system - global)
1093  */
1094  if (RemoveDefinition && !RtlEqualLuid(&CallerLuid, &SystemLuid))
1095  {
1096  if (CheckForGlobalDriveLetter(AbsLetter))
1097  {
1098  AddBSMRequest(AbsLetter, FALSE, &CallerLuid);
1099  }
1100  }
1101  }
1102 
1103  /* Done! */
1105  }
1106  _SEH2_END;
1107 
1108  return Status;
1109 }
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
#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:505
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:507
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:1426
_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:1056
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)
WCHAR DeviceName[]
Definition: adapter.cpp:21
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
#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:173
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,...)
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
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
__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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#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
Status
Definition: gdiplustypes.h:24
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
#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:508
#define SECURITY_RESTRICTED_CODE_RID
Definition: setypes.h:541
#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:931
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _SEH2_LEAVE
Definition: filesup.c:20
BOOLEAN CheckForGlobalDriveLetter(SHORT DriveLetter)
Definition: dosdev.c:162
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSTATUS GetCallerLuid(PLUID CallerLuid)
Definition: dosdev.c:45
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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:506
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
smooth NULL
Definition: ftsmooth.c:416
_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:1839
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
#define NtCurrentProcess()
Definition: nt_native.h:1657
#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:3399
#define READ_CONTROL
Definition: nt_native.h:58
Status
Definition: gdiplustypes.h:24
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:3858
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
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#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
Status
Definition: gdiplustypes.h:24
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
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 _SEH2_LEAVE
Definition: filesup.c:20
return STATUS_SUCCESS
Definition: btrfs.c:3014

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 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#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().