ReactOS 0.4.15-dev-8100-g1887773
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);
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}
#define PAGED_CODE()
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
ULONG Handle
Definition: gdb_input.c:15
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define TAG_UNC
Definition: tag.h:47
ULONG FsRtlpRedirs
Definition: unc.c:17
struct @1742 FsRtlpDRD
VOID FsRtlpSetSymbolicLink(IN PCUNICODE_STRING DeviceName)
Definition: unc.c:117
KSEMAPHORE FsRtlpUncSemaphore
Definition: unc.c:15
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Executive
Definition: ketypes.h:415

◆ FsRtlpIsDfsEnabled()

BOOLEAN FsRtlpIsDfsEnabled ( VOID  )

Definition at line 28 of file unc.c.

29{
30 HANDLE Key;
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}
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_READ
Definition: nt_native.h:1023
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
#define REG_DWORD
Definition: sdbapi.c:596
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699

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}
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define FILE_OPEN
Definition: from_kernel.h:54
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define GENERIC_WRITE
Definition: nt_native.h:90
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275

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}
#define DPRINT1
Definition: precomp.h:8
#define BufferSize
Definition: mmc.h:75
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define FSCTL_MUP_REGISTER_PROVIDER
Definition: muptypes.h:12
struct _MUP_PROVIDER_REGISTRATION_INFO MUP_PROVIDER_REGISTRATION_INFO
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define STATUS_PENDING
Definition: ntstatus.h:82
uint16_t * PWSTR
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
HANDLE MupHandle
Definition: unc.c:21
UNICODE_STRING RedirectorDeviceName
Definition: unc.c:23
BOOLEAN MailslotsSupported
Definition: unc.c:24
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

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}

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 */
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 */
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
396Cleanup:
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;
405 }
406 else
407 {
408 /* Cleanup in case of failure */
410 {
412 }
413
415 }
416
418 return Status;
419}
static const WCHAR Cleanup[]
Definition: register.c:80
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
NTSTATUS FsRtlpOpenDev(OUT PHANDLE DeviceHandle, IN PCWSTR DeviceName)
Definition: unc.c:78
BOOLEAN FsRtlpIsDfsEnabled(VOID)
Definition: unc.c:28
NTSTATUS FsRtlpRegisterProviderWithMUP(IN HANDLE MupHandle, IN PCUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported)
Definition: unc.c:135

Referenced by RxStartMinirdr().

Variable Documentation

◆ 

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