ReactOS  0.4.14-dev-342-gdc047f9
unc.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for unc.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN FsRtlpIsDfsEnabled (VOID)
 
NTSTATUS FsRtlpOpenDev (OUT PHANDLE DeviceHandle, IN PCWSTR DeviceName)
 
VOID FsRtlpSetSymbolicLink (IN PCUNICODE_STRING DeviceName)
 
NTSTATUS FsRtlpRegisterProviderWithMUP (IN HANDLE MupHandle, IN PCUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported)
 
VOID NTAPI FsRtlDeregisterUncProvider (IN HANDLE Handle)
 
NTSTATUS NTAPI FsRtlRegisterUncProvider (OUT PHANDLE Handle, IN PCUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported)
 

Variables

KSEMAPHORE FsRtlpUncSemaphore
 
ULONG FsRtlpRedirs = 0
 
struct {
   HANDLE   MupHandle
 
   HANDLE   NullHandle
 
   UNICODE_STRING   RedirectorDeviceName
 
   BOOLEAN   MailslotsSupported
 
FsRtlpDRD
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file unc.c.

Function Documentation

◆ FsRtlDeregisterUncProvider()

VOID NTAPI FsRtlDeregisterUncProvider ( IN HANDLE  Handle)

Definition at line 202 of file unc.c.

203 {
204  PAGED_CODE();
205 
206  /* We won't work on invalid input */
207  if (Handle == INVALID_HANDLE_VALUE || Handle == 0)
208  {
209  return;
210  }
211 
213 
214  /* Sanity check: we need to have providers */
215  ASSERT(FsRtlpRedirs > 0);
216 
217  /* At that point, we had only one provider at a time */
218  if (Handle == (HANDLE)FsRtlpDRD.NullHandle)
219  {
220  /* Free its name if possible (it might have been overtaken in case of
221  * registration of other UNC provider */
222  if (FsRtlpDRD.RedirectorDeviceName.Buffer != NULL)
223  {
224  ExFreePoolWithTag(FsRtlpDRD.RedirectorDeviceName.Buffer, TAG_UNC);
225  FsRtlpDRD.RedirectorDeviceName.Buffer = NULL;
226  }
227 
228  /* Close the handle to MUP */
229  if (FsRtlpDRD.MupHandle != INVALID_HANDLE_VALUE)
230  {
231  ZwClose(FsRtlpDRD.MupHandle);
232  FsRtlpDRD.MupHandle = INVALID_HANDLE_VALUE;
233  }
234 
235  /* Last handle isn't required anymore */
236  FsRtlpDRD.NullHandle = INVALID_HANDLE_VALUE;
237  }
238 
239  /* One less provider */
240  --FsRtlpRedirs;
241 
242  /* In case we reach no provider anylonger, reset the symbolic link */
243  if (FsRtlpRedirs == 0)
244  {
246  }
247 
249 
250  /* Final note:
251  * NULL device handle and 'normal' MUP device handle are not closed by
252  * FsRtl. It's up to the user to close them afterwards.
253  * If the handle is leaked, MUP will never be notified about the
254  * unregistration.
255  */
256 }
ULONG FsRtlpRedirs
Definition: unc.c:17
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define TAG_UNC
Definition: tag.h:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
KSEMAPHORE FsRtlpUncSemaphore
Definition: unc.c:15
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE Handle
Definition: extypes.h:390
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct @1691 FsRtlpDRD
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID FsRtlpSetSymbolicLink(IN PCUNICODE_STRING DeviceName)
Definition: unc.c:117

◆ FsRtlpIsDfsEnabled()

BOOLEAN FsRtlpIsDfsEnabled ( VOID  )

Definition at line 28 of file unc.c.

29 {
30  HANDLE Key;
31  ULONG Length;
35  struct
36  {
38  ULONG KeyValue;
39  } KeyQueryOutput;
40 
41  /* You recognize MuppIsDfsEnabled()! Congratz :-) */
42  KeyName.Buffer = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup";
43  KeyName.Length = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup") - sizeof(UNICODE_NULL);
44  KeyName.MaximumLength = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup");
45 
46  /* Simply query registry to get whether DFS is disabled.
47  * If DFS isn't disabled from registry side, assume it is enabled
48  * and go through MUP.
49  * MUP itself might disable it, but that's not our concern
50  * any longer
51  */
53  &KeyName,
55  NULL,
56  NULL);
57  Status = ZwOpenKey(&Key, KEY_READ, &ObjectAttributes);
58  if (!NT_SUCCESS(Status))
59  {
60  return TRUE;
61  }
62 
63  KeyName.Buffer = L"DisableDfs";
64  KeyName.Length = sizeof(L"DisableDfs") - sizeof(UNICODE_NULL);
65  KeyName.MaximumLength = sizeof(L"DisableDfs");
66 
67  Status = ZwQueryValueKey(Key, &KeyName, KeyValuePartialInformation, &KeyQueryOutput, sizeof(KeyQueryOutput), &Length);
68  ZwClose(Key);
69  if (!NT_SUCCESS(Status) || KeyQueryOutput.KeyInfo.Type != REG_DWORD)
70  {
71  return TRUE;
72  }
73 
74  return ((*(PULONG)KeyQueryOutput.KeyInfo.Data) != 1);
75 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define TRUE
Definition: types.h:120
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define REG_DWORD
Definition: sdbapi.c:596

Referenced by FsRtlRegisterUncProvider().

◆ FsRtlpOpenDev()

NTSTATUS FsRtlpOpenDev ( OUT PHANDLE  DeviceHandle,
IN PCWSTR  DeviceName 
)

Definition at line 78 of file unc.c.

80 {
82  UNICODE_STRING StrDeviceName;
85 
86  PAGED_CODE();
87 
88  /* Just open the device and return the obtained handle */
89  RtlInitUnicodeString(&StrDeviceName, DeviceName);
91  &StrDeviceName,
92  0,
93  NULL,
94  NULL);
95  Status = ZwCreateFile(DeviceHandle,
99  NULL,
102  FILE_OPEN, 0, NULL, 0);
103  if (NT_SUCCESS(Status))
104  {
106  }
107 
108  if (!NT_SUCCESS(Status))
109  {
111  }
112 
113  return Status;
114 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
LONG NTSTATUS
Definition: precomp.h:26
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define PAGED_CODE()
Definition: video.h:57
#define FILE_SHARE_READ
Definition: compat.h:125
#define GENERIC_WRITE
Definition: nt_native.h:90
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

Referenced by FsRtlRegisterUncProvider().

◆ FsRtlpRegisterProviderWithMUP()

NTSTATUS FsRtlpRegisterProviderWithMUP ( IN HANDLE  MupHandle,
IN PCUNICODE_STRING  RedirectorDeviceName,
IN BOOLEAN  MailslotsSupported 
)

Definition at line 135 of file unc.c.

138 {
142  PMUP_PROVIDER_REGISTRATION_INFO RegistrationInfo;
143 
144  PAGED_CODE();
145 
146  DPRINT1("FsRtlpRegisterProviderWithMUP(%p, %wZ, %u)\n", (PVOID)MupHandle, RedirectorDeviceName, MailslotsSupported);
147 
148  /* We have to be able to store the name and the registration information */
151  if (RegistrationInfo == NULL)
152  {
154  }
155 
156  /* Set the information about the provider (including its name) */
159  RegistrationInfo->MailslotsSupported = MailslotsSupported;
160  RtlCopyMemory((PWSTR)((ULONG_PTR)RegistrationInfo + RegistrationInfo->RedirectorDeviceNameOffset),
162 
163  /* Call MUP with the registration FSCTL */
166  RegistrationInfo, BufferSize, NULL, 0);
167  if (Status == STATUS_PENDING)
168  {
170  }
171 
172  if (NT_SUCCESS(Status))
173  {
175  }
176 
177  /* And we're done! */
179  ExFreePoolWithTag(RegistrationInfo, TAG_UNC);
180 
181  return Status;
182 }
HANDLE MupHandle
Definition: unc.c:21
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
uint16_t * PWSTR
Definition: typedefs.h:54
#define TAG_UNC
Definition: tag.h:33
LONG NTSTATUS
Definition: precomp.h:26
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
struct _MUP_PROVIDER_REGISTRATION_INFO MUP_PROVIDER_REGISTRATION_INFO
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN MailslotsSupported
Definition: unc.c:24
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define BufferSize
Definition: classpnp.h:419
#define FSCTL_MUP_REGISTER_PROVIDER
Definition: muptypes.h:12
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
UNICODE_STRING RedirectorDeviceName
Definition: unc.c:23
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

Referenced by FsRtlRegisterUncProvider().

◆ FsRtlpSetSymbolicLink()

VOID FsRtlpSetSymbolicLink ( IN PCUNICODE_STRING  DeviceName)

Definition at line 117 of file unc.c.

118 {
120  UNICODE_STRING UncDevice;
121 
122  PAGED_CODE();
123 
124  /* Delete the old link, and set the new one if we have a name */
125  RtlInitUnicodeString(&UncDevice, L"\\DosDevices\\UNC");
126  IoDeleteSymbolicLink(&UncDevice);
127  if (DeviceName != NULL)
128  {
131  }
132 }
LONG NTSTATUS
Definition: precomp.h:26
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

Referenced by FsRtlDeregisterUncProvider(), and FsRtlRegisterUncProvider().

◆ FsRtlRegisterUncProvider()

NTSTATUS NTAPI FsRtlRegisterUncProvider ( OUT PHANDLE  Handle,
IN PCUNICODE_STRING  RedirectorDeviceName,
IN BOOLEAN  MailslotsSupported 
)

Definition at line 280 of file unc.c.

283 {
286  UNICODE_STRING MupString;
287 
288  PAGED_CODE();
289 
290  DPRINT1("FsRtlRegisterUncProvider(%p, %wZ, %u)\n", Handle, RedirectorDeviceName, MailslotsSupported);
291 
293 
294  /* In case no provider was registered yet, check for DFS present.
295  * If DFS is present, we need to go with MUP, whatever the case
296  */
297  if (FsRtlpRedirs == 0)
298  {
299  if (FsRtlpIsDfsEnabled())
300  {
301  DPRINT1("DFS is not disabled. Going through MUP\n");
302 
303  /* We've to go with MUP, make sure our internal structure doesn't
304  * contain any leftover data and raise redirs to one, to make sure
305  * we use MUP.
306  */
307  RtlZeroMemory(&FsRtlpDRD, sizeof(FsRtlpDRD));
308  FsRtlpRedirs = 1;
309  }
310  }
311 
312  /* In case no UNC provider was already registered,
313  * We'll proceed without MUP and directly redirect
314  * UNC to the provider.
315  */
316  if (FsRtlpRedirs == 0)
317  {
318  /* As we don't provide MUP, just give a handle to NULL device */
319  Status = FsRtlpOpenDev(&DeviceHandle, L"\\Device\\Null");
320  if (!NT_SUCCESS(Status))
321  {
322  goto Cleanup;
323  }
324 
325  /* Allocate a buffer big enough to keep a local copy of UNC provider device */
327  if (FsRtlpDRD.RedirectorDeviceName.Buffer == NULL)
328  {
330  goto Cleanup;
331  }
332 
333  FsRtlpDRD.RedirectorDeviceName.Length = RedirectorDeviceName->Length;
334  FsRtlpDRD.RedirectorDeviceName.MaximumLength = RedirectorDeviceName->MaximumLength;
336 
337  /* We don't have MUP, and copy provider information */
338  FsRtlpDRD.MupHandle = INVALID_HANDLE_VALUE;
339  FsRtlpDRD.MailslotsSupported = MailslotsSupported;
340  FsRtlpDRD.NullHandle = DeviceHandle;
341 
342  /* Set DOS device UNC to use provider device */
344  }
345  else
346  {
347  /* We (will) have several providers, MUP is required */
348  Status = FsRtlpOpenDev(&DeviceHandle, L"\\Device\\Mup");
349  if (!NT_SUCCESS(Status))
350  {
351  /* Opening MUP may have failed because the driver was not loaded, so load it and retry */
352  RtlInitUnicodeString(&MupString, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup");
353  ZwLoadDriver(&MupString);
354  Status = FsRtlpOpenDev(&DeviceHandle, L"\\Device\\Mup");
355  if (!NT_SUCCESS(Status))
356  {
357  goto Cleanup;
358  }
359  }
360 
361  /* In case we had a single provider till now, we have to forward the old provider to MUP
362  * And then, register the new one to MUP as well
363  */
364  if (FsRtlpDRD.RedirectorDeviceName.Buffer != NULL)
365  {
366  /* We will only continue if we can register previous provider in MUP */
367  Status = FsRtlpRegisterProviderWithMUP(DeviceHandle, &FsRtlpDRD.RedirectorDeviceName, FsRtlpDRD.MailslotsSupported);
368  if (!NT_SUCCESS(Status))
369  {
370  goto Cleanup;
371  }
372 
373  /* Save our Mup handle for later usage */
374  FsRtlpDRD.MupHandle = DeviceHandle;
375 
376  /* Release information about previous provider */
377  ExFreePoolWithTag(FsRtlpDRD.RedirectorDeviceName.Buffer, TAG_UNC);
378  FsRtlpDRD.RedirectorDeviceName.Buffer = NULL;
379 
380  /* Re-open MUP to have a handle to give back to the user */
381  Status = FsRtlpOpenDev(&DeviceHandle, L"\\Device\\Mup");
382  if (!NT_SUCCESS(Status))
383  {
384  goto Cleanup;
385  }
386  }
387 
388  /* Redirect UNC DOS device to MUP */
389  RtlInitUnicodeString(&MupString, L"\\Device\\Mup");
390  FsRtlpSetSymbolicLink(&MupString);
391 
392  /* Register new provider */
394  }
395 
396 Cleanup:
397 
398  /* In case of success, increment number of providers and return handle
399  * to the device pointed by UNC DOS device
400  */
401  if (NT_SUCCESS(Status))
402  {
403  ++FsRtlpRedirs;
404  *Handle = DeviceHandle;
405  }
406  else
407  {
408  /* Cleanup in case of failure */
410  {
412  }
413 
415  }
416 
418  return Status;
419 }
NTSTATUS FsRtlpRegisterProviderWithMUP(IN HANDLE MupHandle, IN PCUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported)
Definition: unc.c:135
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
ULONG FsRtlpRedirs
Definition: unc.c:17
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define TAG_UNC
Definition: tag.h:33
LONG NTSTATUS
Definition: precomp.h:26
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
KSEMAPHORE FsRtlpUncSemaphore
Definition: unc.c:15
BOOLEAN MailslotsSupported
Definition: unc.c:24
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS FsRtlpOpenDev(OUT PHANDLE DeviceHandle, IN PCWSTR DeviceName)
Definition: unc.c:78
_In_ HANDLE Handle
Definition: extypes.h:390
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BOOLEAN FsRtlpIsDfsEnabled(VOID)
Definition: unc.c:28
static const WCHAR L[]
Definition: oid.c:1250
static const WCHAR Cleanup[]
Definition: register.c:80
Status
Definition: gdiplustypes.h:24
struct @1691 FsRtlpDRD
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define DPRINT1
Definition: precomp.h:8
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID FsRtlpSetSymbolicLink(IN PCUNICODE_STRING DeviceName)
Definition: unc.c:117
UNICODE_STRING RedirectorDeviceName
Definition: unc.c:23

Referenced by RxStartMinirdr().

Variable Documentation

◆ FsRtlpDRD

struct { ... } FsRtlpDRD

◆ FsRtlpRedirs

ULONG FsRtlpRedirs = 0

Definition at line 17 of file unc.c.

Referenced by FsRtlDeregisterUncProvider(), and FsRtlRegisterUncProvider().

◆ FsRtlpUncSemaphore

KSEMAPHORE FsRtlpUncSemaphore

Definition at line 15 of file unc.c.

Referenced by FsRtlDeregisterUncProvider(), FsRtlInitSystem(), and FsRtlRegisterUncProvider().

◆ MailslotsSupported

BOOLEAN MailslotsSupported

Definition at line 24 of file unc.c.

Referenced by FsRtlpRegisterProviderWithMUP(), and FsRtlRegisterUncProvider().

◆ MupHandle

HANDLE MupHandle

Definition at line 21 of file unc.c.

Referenced by FsRtlpRegisterProviderWithMUP().

◆ NullHandle

HANDLE NullHandle

Definition at line 22 of file unc.c.

◆ RedirectorDeviceName