ReactOS  0.4.14-dev-55-g2da92ac
mup.c
Go to the documentation of this file.
1 /*
2  * ReactOS kernel
3  * Copyright (C) 2002 ReactOS Team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT: See COPYING in the top level directory
21  * PROJECT: ReactOS kernel
22  * FILE: drivers/filesystems/mup/mup.c
23  * PURPOSE: Multi UNC Provider
24  * PROGRAMMER: Eric Kohl
25  * Pierre Schweitzer (pierre@reactos.org)
26  */
27 
28 /* INCLUDES *****************************************************************/
29 
30 #include "mup.h"
31 
32 #define NDEBUG
33 #include <debug.h>
34 
35 INIT_FUNCTION
37 NTAPI
41 );
42 
43 INIT_FUNCTION
44 VOID
46  VOID
47 );
48 
49 INIT_FUNCTION
50 VOID
53 );
54 
55 #if defined(ALLOC_PRAGMA)
56 #pragma alloc_text(INIT, DriverEntry)
57 #pragma alloc_text(INIT, MupInitializeData)
58 #pragma alloc_text(INIT, MupInitializeVcb)
59 #endif
60 
79 
80 /* FUNCTIONS ****************************************************************/
81 
82 INIT_FUNCTION
83 VOID
85 {
90  MupProviderCount = 0;
95  MupKnownPrefixTimeout.QuadPart = 9000000000LL;
97 }
98 
99 VOID
101 {
106 }
107 
108 INIT_FUNCTION
109 VOID
111 {
112  RtlZeroMemory(Vcb, sizeof(MUP_VCB));
113  Vcb->NodeType = NODE_TYPE_VCB;
114  Vcb->NodeStatus = NODE_STATUS_HEALTHY;
115  Vcb->NodeReferences = 1;
116  Vcb->NodeSize = sizeof(MUP_VCB);
117 }
118 
119 BOOLEAN
121 {
122  HANDLE Key;
123  ULONG Length;
127  struct
128  {
130  ULONG KeyValue;
131  } KeyQueryOutput;
132 
133  /* You recognize FsRtlpIsDfsEnabled()! Congratz :-) */
134  KeyName.Buffer = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup";
135  KeyName.Length = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup") - sizeof(UNICODE_NULL);
136  KeyName.MaximumLength = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup");
137 
138  /* Simply query registry to know whether we have to disable DFS.
139  * Unless explicitly stated in registry, we will try to enable DFS.
140  */
142  &KeyName,
144  NULL,
145  NULL);
146 
147  Status = ZwOpenKey(&Key, KEY_READ, &ObjectAttributes);
148  if (!NT_SUCCESS(Status))
149  {
150  return TRUE;
151  }
152 
153  KeyName.Buffer = L"DisableDfs";
154  KeyName.Length = sizeof(L"DisableDfs") - sizeof(UNICODE_NULL);
155  KeyName.MaximumLength = sizeof(L"DisableDfs");
156 
157  Status = ZwQueryValueKey(Key, &KeyName, KeyValuePartialInformation, &KeyQueryOutput, sizeof(KeyQueryOutput), &Length);
158  ZwClose(Key);
159  if (!NT_SUCCESS(Status) || KeyQueryOutput.KeyInfo.Type != REG_DWORD)
160  {
161  return TRUE;
162  }
163 
164  return ((ULONG_PTR)KeyQueryOutput.KeyInfo.Data != 1);
165 }
166 
167 VOID
169 {
170  LARGE_INTEGER CurrentTime;
171 
172  /* Just get now + our allowed timeout */
173  KeQuerySystemTime(&CurrentTime);
174  EntryTime->QuadPart = CurrentTime.QuadPart + MupKnownPrefixTimeout.QuadPart;
175 }
176 
177 PMUP_CCB
179 {
180  PMUP_CCB Ccb;
181 
183  if (Ccb == NULL)
184  {
185  return NULL;
186  }
187 
188  Ccb->NodeStatus = NODE_STATUS_HEALTHY;
189  Ccb->NodeReferences = 1;
190  Ccb->NodeType = NODE_TYPE_CCB;
191  Ccb->NodeSize = sizeof(MUP_CCB);
192 
193  return Ccb;
194 }
195 
196 PMUP_FCB
198 {
199  PMUP_FCB Fcb;
200 
202  if (Fcb == NULL)
203  {
204  return NULL;
205  }
206 
207  Fcb->NodeStatus = NODE_STATUS_HEALTHY;
208  Fcb->NodeReferences = 1;
209  Fcb->NodeType = NODE_TYPE_FCB;
210  Fcb->NodeSize = sizeof(MUP_FCB);
211  InitializeListHead(&Fcb->CcbList);
212 
213  return Fcb;
214 }
215 
216 PMUP_MIC
218 {
219  PMUP_MIC MasterIoContext;
220 
221  MasterIoContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(MUP_MIC), TAG_MUP);
222  if (MasterIoContext == NULL)
223  {
224  return NULL;
225  }
226 
227  MasterIoContext->NodeStatus = NODE_STATUS_HEALTHY;
228  MasterIoContext->NodeReferences = 1;
229  MasterIoContext->NodeType = NODE_TYPE_MIC;
230  MasterIoContext->NodeSize = sizeof(MUP_MIC);
231 
232  return MasterIoContext;
233 }
234 
235 PMUP_UNC
236 MupAllocateUncProvider(ULONG RedirectorDeviceNameLength)
237 {
238  PMUP_UNC UncProvider;
239 
240  UncProvider = ExAllocatePoolWithTag(PagedPool, sizeof(MUP_UNC) + RedirectorDeviceNameLength, TAG_MUP);
241  if (UncProvider == NULL)
242  {
243  return NULL;
244  }
245 
246  UncProvider->NodeReferences = 0;
247  UncProvider->NodeType = NODE_TYPE_UNC;
248  UncProvider->NodeStatus = NODE_STATUS_HEALTHY;
249  UncProvider->NodeSize = sizeof(MUP_UNC) + RedirectorDeviceNameLength;
250  UncProvider->Registered = FALSE;
251 
252  return UncProvider;
253 }
254 
255 PMUP_PFX
257 {
259  ULONG PrefixSize;
260 
261  PrefixSize = sizeof(MUP_PFX) + PrefixLength;
263  if (Prefix == NULL)
264  {
265  return NULL;
266  }
267 
268  RtlZeroMemory(Prefix, PrefixSize);
269  Prefix->NodeType = NODE_TYPE_PFX;
270  Prefix->NodeStatus = NODE_STATUS_HEALTHY;
271  Prefix->NodeReferences = 1;
272  Prefix->NodeSize = PrefixSize;
273 
274  /* If we got a prefix, initialize the string */
275  if (PrefixLength != 0)
276  {
277  Prefix->AcceptedPrefix.Buffer = (PVOID)((ULONG_PTR)Prefix + sizeof(MUP_PFX));
278  Prefix->AcceptedPrefix.Length = PrefixLength;
279  Prefix->AcceptedPrefix.MaximumLength = PrefixLength;
280  }
281  /* Otherwise, mark the fact that the allocation will be external */
282  else
283  {
284  Prefix->ExternalAlloc = TRUE;
285  }
286 
287  Prefix->KeepExtraRef = FALSE;
288  /* Already init timeout to have one */
289  MupCalculateTimeout(&Prefix->ValidityTimeout);
290 
291  return Prefix;
292 }
293 
294 PMUP_MQC
296 {
297  PMUP_MQC MasterQueryContext;
298 
299  MasterQueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(MUP_MQC), TAG_MUP);
300  if (MasterQueryContext == NULL)
301  {
302  return NULL;
303  }
304 
305  MasterQueryContext->NodeStatus = NODE_STATUS_HEALTHY;
306  MasterQueryContext->NodeReferences = 1;
307  MasterQueryContext->NodeType = NODE_TYPE_MQC;
308  MasterQueryContext->NodeSize = sizeof(MUP_MQC);
309  InitializeListHead(&MasterQueryContext->QueryPathList);
310  InitializeListHead(&MasterQueryContext->MQCListEntry);
311  ExInitializeResourceLite(&MasterQueryContext->QueryPathListLock);
312 
313  return MasterQueryContext;
314 }
315 
316 ULONG
318 {
319  ULONG Type;
320  PMUP_FCB Fcb;
321 
323  *pFcb = FileObject->FsContext;
324  *pCcb = FileObject->FsContext2;
325  Fcb = *pFcb;
326 
327  if (Fcb == NULL)
328  {
330  return 0;
331  }
332 
333  Type = Fcb->NodeType;
334  if ((Type != NODE_TYPE_VCB && Type != NODE_TYPE_FCB) || (Fcb->NodeStatus != NODE_STATUS_HEALTHY && Fcb->NodeStatus != NODE_STATUS_CLEANUP))
335  {
336  *pFcb = 0;
338  return 0;
339  }
340 
341  ++Fcb->NodeReferences;
343 
344  return Type;
345 }
346 
347 VOID
349 {
351 }
352 
353 VOID
355 {
356  /* Just dereference and delete if no references left */
357  if (InterlockedDecrement(&Fcb->NodeReferences) == 0)
358  {
359  MupFreeNode(Fcb);
360  }
361 }
362 
363 VOID
365 {
366  /* Just dereference and delete (and clean) if no references left */
367  if (InterlockedDecrement(&Ccb->NodeReferences) == 0)
368  {
370  RemoveEntryList(&Ccb->CcbListEntry);
374  MupFreeNode(Ccb);
375  }
376 }
377 
378 VOID
380 {
381  /* We cannot reach the point where no references are left */
382  if (InterlockedDecrement(&Vcb->NodeReferences) == 0)
383  {
384  KeBugCheckEx(FILE_SYSTEM, 3, 0, 0, 0);
385  }
386 }
387 
388 NTSTATUS
390  PNTSTATUS NewStatus)
391 {
392  PIRP Irp;
394  PIO_STACK_LOCATION Stack;
395 
397 
398  if (NewStatus != NULL)
399  {
400  /* Save last status, depending on whether it failed or not */
401  if (!NT_SUCCESS(*NewStatus))
402  {
403  MasterIoContext->LastFailed = *NewStatus;
404  }
405  else
406  {
407  MasterIoContext->LastSuccess = STATUS_SUCCESS;
408  }
409  }
410 
411  if (InterlockedDecrement(&MasterIoContext->NodeReferences) != 0)
412  {
413  return STATUS_PENDING;
414  }
415 
416  Irp = MasterIoContext->Irp;
418  if (Stack->MajorFunction == IRP_MJ_WRITE)
419  {
420  Irp->IoStatus.Information = Stack->Parameters.Write.Length;
421  }
422  else
423  {
424  Irp->IoStatus.Information = 0;
425  }
426 
427  /* In case we never had any success (init is a failure), get the last failed status */
428  if (!NT_SUCCESS(MasterIoContext->LastSuccess))
429  {
430  Status = MasterIoContext->LastFailed;
431  }
432 
433  Irp->IoStatus.Status = Status;
435  MupDereferenceFcb(MasterIoContext->Fcb);
436  MupFreeNode(MasterIoContext);
437 
438  return Status;
439 }
440 
441 VOID
443 {
444  InterlockedExchangeAdd(&UncProvider->NodeReferences, -1);
445 }
446 
447 VOID
449 {
450  /* Just dereference and delete (and clean) if no references left */
451  if (InterlockedDecrement(&Prefix->NodeReferences) == 0)
452  {
453  if (Prefix->InTable)
454  {
455  RtlRemoveUnicodePrefix(&MupPrefixTable, &Prefix->PrefixTableEntry);
456  RemoveEntryList(&Prefix->PrefixListEntry);
457  }
458 
459  if (Prefix->ExternalAlloc && Prefix->AcceptedPrefix.Buffer != NULL)
460  {
461  ExFreePoolWithTag(Prefix->AcceptedPrefix.Buffer, TAG_MUP);
462  }
463 
464  if (Prefix->UncProvider)
465  {
466  MupDereferenceUncProvider(Prefix->UncProvider);
467  }
468 
470  }
471 }
472 
473 VOID
475 {
476  RtlRemoveUnicodePrefix(&MupPrefixTable, &Prefix->PrefixTableEntry);
477  RemoveEntryList(&Prefix->PrefixListEntry);
478  Prefix->InTable = FALSE;
480 }
481 
482 VOID
484 {
487 
488  /* Browse the prefix table */
490  for (Entry = MupPrefixList.Flink;
491  Entry != &MupPrefixList;
492  Entry = Entry->Flink)
493  {
494  Prefix = CONTAINING_RECORD(Entry, MUP_PFX, PrefixListEntry);
495 
496  /* And remove any entry in it */
497  if (Prefix->InTable)
498  {
500  }
501  }
503 }
504 
505 VOID
507  PIRP Irp,
508  PMUP_VCB Vcb)
509 {
511 
512  /* Check we're not doing anything wrong first */
513  if (Vcb->NodeStatus != NODE_STATUS_HEALTHY || Vcb->NodeType != NODE_TYPE_VCB)
514  {
516  }
517 
518  /* Remove share access */
520 
522 }
523 
524 VOID
526  PIRP Irp,
527  PMUP_FCB Fcb)
528 {
530  PMUP_CCB Ccb;
531 
533  /* Check we're not doing anything wrong first */
534  if (Fcb->NodeStatus != NODE_STATUS_HEALTHY || Fcb->NodeType != NODE_TYPE_FCB)
535  {
537  }
538  Fcb->NodeStatus = NODE_STATUS_CLEANUP;
540 
541  /* Dereference any CCB associated with the FCB */
543  for (Entry = Fcb->CcbList.Flink;
544  Entry != &Fcb->CcbList;
545  Entry = Entry->Flink)
546  {
547  Ccb = CONTAINING_RECORD(Entry, MUP_CCB, CcbListEntry);
551  }
553 }
554 
555 NTSTATUS
557  PIRP Irp,
558  PFORWARDED_IO_CONTEXT FwdCtxt)
559 {
561 
562  Status = Irp->IoStatus.Status;
563 
564  /* Just free everything we had allocated */
565  if (Irp->MdlAddress != NULL)
566  {
567  MmUnlockPages(Irp->MdlAddress);
568  IoFreeMdl(Irp->MdlAddress);
569  }
570 
571  if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
572  {
573  ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, TAG_MUP);
574  }
575 
576  IoFreeIrp(Irp);
577 
578  /* Dereference the master context
579  * The upper IRP will be completed once all the lower IRPs are done
580  * (and thus, references count reaches 0)
581  */
582  MupDereferenceCcb(FwdCtxt->Ccb);
584  ExFreePoolWithTag(FwdCtxt, TAG_MUP);
585 
587 }
588 
589 VOID
590 NTAPI
592 {
594 
596 }
597 
598 NTSTATUS
599 NTAPI
601  PIRP Irp,
602  PVOID Context)
603 {
604  PFORWARDED_IO_CONTEXT FwdCtxt;
605 
606  /* If we're at DISPATCH_LEVEL, we cannot complete, defer completion */
608  {
610  }
611  else
612  {
613  FwdCtxt = (PFORWARDED_IO_CONTEXT)Context;
614 
617  }
618 
620 }
621 
622 NTSTATUS
624  PMUP_CCB Ccb,
625  PMUP_MIC MasterIoContext)
626 {
627  PMDL Mdl;
628  PIRP LowerIrp;
630  PIO_STACK_LOCATION Stack;
632  PFORWARDED_IO_CONTEXT FwdCtxt;
633 
635  LowerIrp = NULL;
636  Mdl = NULL;
637 
638  /* Allocate a context for the completion routine */
640  if (FwdCtxt == NULL)
641  {
643  goto Cleanup;
644  }
645 
646  /* Init it */
647  FwdCtxt->DeviceObject = NULL;
648  FwdCtxt->Irp = NULL;
649 
650  /* Allocate the IRP */
653  if (LowerIrp == NULL)
654  {
656  goto Cleanup;
657  }
658 
659  /* Initialize it */
660  LowerIrp->Tail.Overlay.OriginalFileObject = Ccb->FileObject;
661  LowerIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
662  LowerIrp->RequestorMode = KernelMode;
663 
664  /* Copy the stack of the request we received to the IRP we'll pass below */
665  Stack = IoGetNextIrpStackLocation(LowerIrp);
667  Stack->FileObject = Ccb->FileObject;
668  /* Setup flags according to the FO */
669  if (Ccb->FileObject->Flags & FO_WRITE_THROUGH)
670  {
671  Stack->Flags = SL_WRITE_THROUGH;
672  }
673 
674  _SEH2_TRY
675  {
676  /* Does the device requires we do buffered IOs? */
678  {
679  LowerIrp->AssociatedIrp.SystemBuffer = NULL;
680 
681  if (Stack->Parameters.Write.Length == 0)
682  {
683  LowerIrp->Flags = IRP_BUFFERED_IO;
684  }
685  /* If we have data to pass */
686  else
687  {
688  /* If it's coming from usermode, probe first */
689  if (Irp->RequestorMode == UserMode)
690  {
691  ProbeForRead(Irp->UserBuffer, Stack->Parameters.Write.Length, sizeof(UCHAR));
692  }
693 
694  /* Allocate the buffer */
695  LowerIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPoolCacheAligned,
696  Stack->Parameters.Write.Length,
697  TAG_MUP);
698  if (LowerIrp->AssociatedIrp.SystemBuffer == NULL)
699  {
701  }
702 
703  /* And copy input (remember, we've to free!) */
704  RtlMoveMemory(LowerIrp->AssociatedIrp.SystemBuffer, Irp->UserBuffer, Stack->Parameters.Write.Length);
705  LowerIrp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
706  }
707  }
708  else
709  {
710  if (!(DeviceObject->Flags & DO_DIRECT_IO))
711  {
712  LowerIrp->UserBuffer = Irp->UserBuffer;
713  }
714  else
715  {
716  /* For direct IOs, allocate an MDL and pass it */
717  if (Stack->Parameters.Write.Length != 0)
718  {
719  Mdl = IoAllocateMdl(Irp->UserBuffer, Stack->Parameters.Write.Length, FALSE, TRUE, LowerIrp);
720  if (Mdl == NULL)
721  {
723  }
724 
725  MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoReadAccess);
726  }
727  }
728  }
729 
730  /* Fix flags in the IRP */
732  {
733  LowerIrp->Flags |= IRP_WRITE_OPERATION | IRP_NOCACHE;
734  }
735  else
736  {
737  LowerIrp->Flags |= IRP_WRITE_OPERATION;
738  }
739 
740  FwdCtxt->Ccb = Ccb;
741  FwdCtxt->MasterIoContext = MasterIoContext;
742 
744  ++MasterIoContext->NodeReferences;
746 
747  /* Set out completion routine */
749  /* And call the device with our brand new IRP */
750  Status = IoCallDriver(Ccb->DeviceObject, LowerIrp);
751  }
753  {
755  }
756  _SEH2_END;
757 
758 Cleanup:
759  if (!NT_SUCCESS(Status))
760  {
761  if (FwdCtxt != NULL)
762  {
763  ExFreePoolWithTag(FwdCtxt, TAG_MUP);
764  }
765 
766  if (LowerIrp != NULL)
767  {
768  if (LowerIrp->AssociatedIrp.SystemBuffer == NULL)
769  {
770  ExFreePoolWithTag(LowerIrp->AssociatedIrp.SystemBuffer, TAG_MUP);
771  }
772 
773  IoFreeIrp(LowerIrp);
774  }
775 
776  if (Mdl != NULL)
777  {
778  IoFreeMdl(Mdl);
779  }
780  }
781 
782  return Status;
783 }
784 
785 NTSTATUS
786 NTAPI
788  PIRP Irp)
789 {
790  PMUP_FCB Fcb;
791  PMUP_CCB Ccb;
794  PMUP_CCB FcbListCcb;
795  BOOLEAN CcbLockAcquired;
796  PMUP_MIC MasterIoContext;
797  PIO_STACK_LOCATION Stack;
798 
799  /* If DFS is enabled, check if that's for DFS and is so relay */
800  if (MupEnableDfs && DeviceObject->DeviceType == FILE_DEVICE_DFS)
801  {
803  }
804 
806 
808 
809  /* Write request is only possible for a mailslot, we need a FCB */
811  if (Fcb == NULL || Fcb->NodeType != NODE_TYPE_FCB)
812  {
815  goto Complete;
816  }
817 
818  /* Allocate a context */
819  MasterIoContext = MupAllocateMasterIoContext();
820  if (MasterIoContext == NULL)
821  {
824  goto Complete;
825  }
826 
827  /* Mark the IRP pending and init the context */
829  MasterIoContext->Irp = Irp;
830  /* Init with a failure to catch if we ever succeed */
831  MasterIoContext->LastSuccess = STATUS_UNSUCCESSFUL;
832  /* Init with the worth failure possible */
833  MasterIoContext->LastFailed = STATUS_BAD_NETWORK_PATH;
834  MasterIoContext->Fcb = Fcb;
835 
836  _SEH2_TRY
837  {
839  CcbLockAcquired = TRUE;
840 
841  /* For all the CCB (ie, the mailslots) we have */
842  for (Entry = Fcb->CcbList.Flink;
843  Entry != &Fcb->CcbList;
844  Entry = Entry->Flink)
845  {
846  FcbListCcb = CONTAINING_RECORD(Entry, MUP_CCB, CcbListEntry);
848  CcbLockAcquired = FALSE;
849 
851  ++FcbListCcb->NodeReferences;
853 
854  /* Forward the write request */
855  BuildAndSubmitIrp(Irp, FcbListCcb, MasterIoContext);
857  CcbLockAcquired = TRUE;
858  }
859 
861  CcbLockAcquired = FALSE;
862  }
864  {
865  if (CcbLockAcquired)
866  {
868  }
869  }
870  _SEH2_END;
871 
872  /* And done */
873  MupDereferenceMasterIoContext(MasterIoContext, NULL);
875 
876  return STATUS_PENDING;
877 
878 Complete:
879  /* Failure case */
880  Irp->IoStatus.Status = Status;
882  return Status;
883 }
884 
885 PMUP_UNC
887  ULONG ProviderOrder)
888 {
889  PMUP_UNC UncProvider;
890  ULONG StrLen, NameLen;
891 
892  /* Just allocate the node */
893  NameLen = wcslen(DeviceName);
894  StrLen = NameLen * sizeof(WCHAR);
895  UncProvider = MupAllocateUncProvider(StrLen);
896  if (UncProvider == NULL)
897  {
898  return NULL;
899  }
900 
901  /* And init it */
902  UncProvider->DeviceName.MaximumLength = StrLen;
903  UncProvider->DeviceName.Length = StrLen;
904  UncProvider->DeviceName.Buffer = (PWSTR)((ULONG_PTR)UncProvider + sizeof(MUP_UNC));
905  UncProvider->ProviderOrder = ProviderOrder;
906  RtlMoveMemory(UncProvider->DeviceName.Buffer, DeviceName, StrLen);
907 
908  /* And add it to the global list
909  * We're using tail here so that when called from registry init,
910  * the providers with highest priority will be in the head of
911  * the list
912  */
914  InsertTailList(&MupProviderList, &UncProvider->ProviderListEntry);
916 
917  return UncProvider;
918 }
919 
920 VOID
922  ULONG ProviderOrder)
923 {
929  ULONG NameLen, StrLen, ResultLength;
930 
931  /* Get the information about the provider from registry */
932  NameLen = wcslen(ProviderName);
933  StrLen = NameLen * sizeof(WCHAR) + sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") + sizeof(L"\\NetworkProvider");
934  Key.Buffer = ExAllocatePoolWithTag(PagedPool, StrLen, TAG_MUP);
935  if (Key.Buffer == NULL)
936  {
937  return;
938  }
939 
940  RtlMoveMemory(Key.Buffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"));
941  Key.MaximumLength = StrLen;
942  Key.Length = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") - sizeof(UNICODE_NULL);
943  RtlAppendUnicodeToString(&Key, ProviderName);
944  RtlAppendUnicodeToString(&Key, L"\\NetworkProvider");
945 
947  &Key,
949  NULL,
950  NULL);
952  ExFreePoolWithTag(Key.Buffer, TAG_MUP);
953  if (!NT_SUCCESS(Status))
954  {
955  return;
956  }
957 
958  RtlInitUnicodeString(&Value, L"DeviceName");
959  Status = ZwQueryValueKey(KeyHandle, &Value, KeyValueFullInformation, NULL, 0, &ResultLength);
961  {
963  if (Info == NULL)
964  {
966  return;
967  }
968 
970  }
971  else
972  {
973  Info = NULL;
974  }
975 
977 
978  /* And create the provider
979  * It will remain unregistered until FsRTL receives a registration request and forwards
980  * it to MUP
981  */
982  if (NT_SUCCESS(Status))
983  {
984  ASSERT(Info != NULL);
985  AddUnregisteredProvider((PWSTR)((ULONG_PTR)Info + Info->DataOffset), ProviderOrder);
986  }
987 
988  if (Info != NULL)
989  {
991  }
992 }
993 
994 VOID
996 {
997  BOOLEAN End;
1000  PWSTR Providers, Coma;
1002  ULONG ResultLength, ProviderCount;
1004  UNICODE_STRING NetworkProvider, ProviderOrder;
1005 
1006  /* Open the registry to get the order of the providers */
1007  RtlInitUnicodeString(&NetworkProvider, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\NetworkProvider\\Order");
1009  &NetworkProvider,
1011  NULL,
1012  NULL);
1014  if (!NT_SUCCESS(Status))
1015  {
1016  return;
1017  }
1018 
1019  RtlInitUnicodeString(&ProviderOrder, L"ProviderOrder");
1020  Status = ZwQueryValueKey(KeyHandle, &ProviderOrder, KeyValueFullInformation, NULL, 0, &ResultLength);
1022  {
1024  if (Info == NULL)
1025  {
1026  ZwClose(KeyHandle);
1027  return;
1028  }
1029 
1030  Status = ZwQueryValueKey(KeyHandle, &ProviderOrder, KeyValueFullInformation, Info, ResultLength, &ResultLength);
1031  }
1032  else
1033  {
1034  Info = NULL;
1035  }
1036 
1037  ZwClose(KeyHandle);
1038 
1039  if (NT_SUCCESS(Status))
1040  {
1041  ASSERT(Info != NULL);
1042 
1043  Providers = (PWSTR)((ULONG_PTR)Info + Info->DataOffset);
1044  End = FALSE;
1045  ProviderCount = 0;
1046 
1047  /* For all the providers we got (coma-separated list), just create a provider node with the right order
1048  * The order is just the order of the list
1049  * First has highest priority (0) and then, get lower and lower priority
1050  * The highest number is the lowest priority
1051  */
1052  do
1053  {
1054  Coma = wcschr(Providers, L',');
1055  if (Coma != NULL)
1056  {
1057  *Coma = UNICODE_NULL;
1058  }
1059  else
1060  {
1061  End = TRUE;
1062  }
1063 
1064  InitializeProvider(Providers, ProviderCount);
1065  ++ProviderCount;
1066 
1067  Providers = Coma + 1;
1068  } while (!End);
1069  }
1070 
1071  if (Info != NULL)
1072  {
1074  }
1075 }
1076 
1077 PMUP_UNC
1079 {
1081  PMUP_UNC UncProvider;
1082 
1083  /* Browse the list of all the providers nodes we have */
1085  for (Entry = MupProviderList.Flink; Entry != &MupProviderList; Entry = Entry->Flink)
1086  {
1087  UncProvider = CONTAINING_RECORD(Entry, MUP_UNC, ProviderListEntry);
1088 
1089  /* If one matches the device and is not registered, that's ours! */
1090  if (!UncProvider->Registered && RtlEqualUnicodeString(RedirectorDeviceName, &UncProvider->DeviceName, TRUE))
1091  {
1092  UncProvider->NodeStatus = NODE_STATUS_HEALTHY;
1093  break;
1094  }
1095  }
1096 
1097  if (Entry == &MupProviderList)
1098  {
1099  UncProvider = NULL;
1100  }
1102 
1103  return UncProvider;
1104 }
1105 
1106 NTSTATUS
1108  PIRP Irp)
1109 
1110 {
1111  BOOLEAN New;
1112  PMUP_FCB Fcb;
1113  PMUP_CCB Ccb;
1114  NTSTATUS Status;
1116  PIO_STACK_LOCATION Stack;
1118  PMUP_UNC UncProvider, ListEntry;
1121  OBJECT_HANDLE_INFORMATION HandleInfo;
1123 
1124  DPRINT1("RegisterUncProvider(%p, %p)\n", DeviceObject, Irp);
1125  New = FALSE;
1126 
1127  /* Check whether providers order was already initialized */
1129  if (MupOrderInitialized)
1130  {
1132  }
1133  else
1134  {
1135  /* They weren't, so do it */
1139  }
1140 
1142 
1143  /* This can only happen with a volume open */
1144  if (MupDecodeFileObject(Stack->FileObject, &Fcb, &Ccb) != NODE_TYPE_VCB)
1145  {
1146  Irp->IoStatus.Status = STATUS_INVALID_HANDLE;
1148 
1149  return STATUS_INVALID_HANDLE;
1150  }
1151 
1152  /* Get the registration information */
1153  RegInfo = (PMUP_PROVIDER_REGISTRATION_INFO)Irp->AssociatedIrp.SystemBuffer;
1154  _SEH2_TRY
1155  {
1159 
1160  /* Have we got already a node for it? (Like from previous init) */
1162  if (UncProvider == NULL)
1163  {
1164  /* If we don't, allocate a new one */
1165  New = TRUE;
1166  UncProvider = MupAllocateUncProvider(RegInfo->RedirectorDeviceNameLength);
1167  if (UncProvider == NULL)
1168  {
1170  _SEH2_LEAVE;
1171  }
1172 
1173  /* Set it up */
1176  UncProvider->DeviceName.Buffer = (PWSTR)((ULONG_PTR)UncProvider + sizeof(MUP_UNC));
1177 
1178  /* As it wasn't in registry for order, give the lowest priority possible */
1179  UncProvider->ProviderOrder = MAXLONG;
1181  }
1182 
1183  /* Continue registration */
1184  UncProvider->MailslotsSupported = RegInfo->MailslotsSupported;
1185  ++UncProvider->NodeReferences;
1186 
1187  /* Open a handle to the device */
1189  &UncProvider->DeviceName,
1191  NULL,
1192  NULL);
1193  Status = NtOpenFile(&UncProvider->DeviceHandle,
1194  FILE_TRAVERSE,
1196  &IoStatusBlock,
1199  if (NT_SUCCESS(Status))
1200  {
1202  }
1203 
1204  /* And return the provider (as CCB) */
1205  if (NT_SUCCESS(Status))
1206  {
1207  Stack->FileObject->FsContext2 = UncProvider;
1208  Status = ObReferenceObjectByHandle(UncProvider->DeviceHandle, 0, NULL, KernelMode, (PVOID *)&UncProvider->FileObject, &HandleInfo);
1209  if (!NT_SUCCESS(Status))
1210  {
1211  NtClose(UncProvider->DeviceHandle);
1212  }
1213  }
1214 
1215  if (!NT_SUCCESS(Status))
1216  {
1217  MupDereferenceUncProvider(UncProvider);
1218  }
1219  else
1220  {
1221  UncProvider->DeviceObject = IoGetRelatedDeviceObject(UncProvider->FileObject);
1222 
1223  /* Now, insert the provider in our global list
1224  * They are sorted by order
1225  */
1227  ++MupProviderCount;
1228  if (New)
1229  {
1230  for (Entry = MupProviderList.Flink; Entry != &MupProviderList; Entry = Entry->Flink)
1231  {
1232  ListEntry = CONTAINING_RECORD(Entry, MUP_UNC, ProviderListEntry);
1233 
1234  if (UncProvider->ProviderOrder < ListEntry->ProviderOrder)
1235  {
1236  break;
1237  }
1238  }
1239 
1240  InsertTailList(Entry, &UncProvider->ProviderListEntry);
1241  }
1242  UncProvider->Registered = TRUE;
1245 
1246  DPRINT1("UNC provider %wZ registered\n", &UncProvider->DeviceName);
1247  }
1248  }
1250  {
1252  {
1254  }
1255 
1257 
1258  Irp->IoStatus.Status = Status;
1260  }
1261  _SEH2_END;
1262 
1263  return Status;
1264 }
1265 
1266 NTSTATUS
1267 NTAPI
1269  PIRP Irp)
1270 {
1271  NTSTATUS Status;
1272  PIO_STACK_LOCATION Stack;
1273 
1275 
1276  _SEH2_TRY
1277  {
1278  /* MUP only understands a single FSCTL code: registering UNC provider */
1279  if (Stack->Parameters.FileSystemControl.FsControlCode == FSCTL_MUP_REGISTER_PROVIDER)
1280  {
1281  /* It obviously has to come from a driver/kernelmode thread */
1282  if (Irp->RequestorMode == UserMode)
1283  {
1285 
1286  Irp->IoStatus.Status = Status;
1288 
1289  _SEH2_LEAVE;
1290  }
1291 
1293  }
1294  else
1295  {
1296  /* If that's an unknown FSCTL code, maybe it's for DFS, pass it */
1297  if (!MupEnableDfs)
1298  {
1300 
1301  Irp->IoStatus.Status = Status;
1303 
1304  _SEH2_LEAVE;
1305  }
1306 
1308  }
1309  }
1311  {
1313  }
1314  _SEH2_END;
1315 
1316  return Status;
1317 }
1318 
1319 VOID
1321  PMUP_FCB Fcb,
1322  PMUP_CCB Ccb)
1323 {
1324  FileObject->FsContext = Fcb;
1325  FileObject->FsContext2 = Ccb;
1326 }
1327 
1328 NTSTATUS
1330  PMUP_UNC UncProvider)
1331 {
1332  PWSTR FullPath;
1334 
1335  DPRINT1("Rerouting %wZ with %wZ\n", &FileObject->FileName, &UncProvider->DeviceName);
1336 
1337  /* Get the full path name (device name first, and requested file name appended) */
1338  TotalLength = UncProvider->DeviceName.Length + FileObject->FileName.Length;
1339  if (TotalLength > MAXUSHORT)
1340  {
1341  return STATUS_NAME_TOO_LONG;
1342  }
1343 
1344  /* Allocate a buffer big enough */
1346  if (FullPath == NULL)
1347  {
1349  }
1350 
1351  /* Create the full path */
1352  RtlMoveMemory(FullPath, UncProvider->DeviceName.Buffer, UncProvider->DeviceName.Length);
1353  RtlMoveMemory((PWSTR)((ULONG_PTR)FullPath + UncProvider->DeviceName.Length), FileObject->FileName.Buffer, FileObject->FileName.Length);
1354 
1355  /* And redo the path in the file object */
1356  ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1357  FileObject->FileName.Buffer = FullPath;
1358  FileObject->FileName.MaximumLength = TotalLength;
1359  FileObject->FileName.Length = FileObject->FileName.MaximumLength;
1360 
1361  /* Ob, please reparse to open the correct file at the right place, thanks! :-) */
1362  return STATUS_REPARSE;
1363 }
1364 
1365 NTSTATUS
1367 {
1368  PMUP_FCB Fcb;
1369  HANDLE Handle;
1371  PMUP_CCB Ccb = NULL;
1372  PMUP_UNC UncProvider;
1373  UNICODE_STRING FullPath;
1375  PIO_STACK_LOCATION Stack;
1376  NTSTATUS Status, LastFailed;
1377  ULONG TotalLength, LastOrder;
1380  OBJECT_HANDLE_INFORMATION HandleInfo;
1381  BOOLEAN Locked, Referenced, CcbInitialized;
1382 
1383  Fcb = MupCreateFcb();
1384  if (Fcb == NULL)
1385  {
1387  }
1388 
1390  FileObject = Stack->FileObject;
1391  Locked = FALSE;
1392  Referenced = FALSE;
1393  CcbInitialized = FALSE;
1394  LastFailed = STATUS_NO_SUCH_FILE;
1395  LastOrder = (ULONG)-1;
1396 
1397  _SEH2_TRY
1398  {
1400  Locked = TRUE;
1401 
1402  /* Associate our FCB with the FO */
1405 
1406  /* Now, broadcast the open to any UNC provider that supports mailslots */
1407  for (Entry = MupProviderList.Flink; Entry != &MupProviderList; Entry = Entry->Flink)
1408  {
1409  UncProvider = CONTAINING_RECORD(Entry, MUP_UNC, ProviderListEntry);
1410  ++UncProvider->NodeReferences;
1411  Referenced = TRUE;
1412 
1414  Locked = FALSE;
1415 
1416  TotalLength = UncProvider->DeviceName.Length + FileObject->FileName.Length;
1417  if (UncProvider->MailslotsSupported && TotalLength <= MAXUSHORT)
1418  {
1419  /* Provide the correct name for the mailslot (ie, happened the device name of the provider) */
1421  if (FullPath.Buffer == NULL)
1422  {
1424  }
1425 
1426  FullPath.Length = TotalLength;
1427  FullPath.MaximumLength = TotalLength;
1428  RtlMoveMemory(FullPath.Buffer, UncProvider->DeviceName.Buffer, UncProvider->DeviceName.Length);
1429  RtlMoveMemory((PWSTR)((ULONG_PTR)FullPath.Buffer + UncProvider->DeviceName.Length),
1430  FileObject->FileName.Buffer,
1431  FileObject->FileName.Length);
1432 
1433  /* And just forward the creation request */
1435  &FullPath,
1437  NULL,
1438  NULL);
1440  Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_SIMPLE_RIGHTS_MASK,
1442  &IoStatusBlock,
1443  NULL,
1444  Stack->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS,
1445  Stack->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS,
1446  FILE_OPEN,
1447  Stack->Parameters.Create.Options & FILE_VALID_SET_FLAGS,
1448  NULL,
1449  0,
1451  NULL,
1453 
1454  ExFreePoolWithTag(FullPath.Buffer, TAG_MUP);
1455 
1456  /* If opening succeed */
1457  if (NT_SUCCESS(Status))
1458  {
1460 
1461  /* Create a CCB */
1462  Ccb = MupCreateCcb();
1463  if (Ccb == NULL)
1464  {
1466  }
1467 
1468  /* And associated a FO to it */
1469  if (NT_SUCCESS(Status))
1470  {
1471  Status = ObReferenceObjectByHandle(Handle, 0, 0, 0, (PVOID *)&Ccb->FileObject, &HandleInfo);
1472  ZwClose(Handle);
1473  }
1474  }
1475 
1476  /* If we failed, remember the last failed status of the higher priority provider */
1477  if (!NT_SUCCESS(Status))
1478  {
1479  if (UncProvider->ProviderOrder <= LastOrder)
1480  {
1481  LastOrder = UncProvider->ProviderOrder;
1482  LastFailed = Status;
1483  }
1484  }
1485  /* Otherwise, properly attach our CCB to the mailslot */
1486  else
1487  {
1488  Ccb->DeviceObject = IoGetRelatedDeviceObject(Ccb->FileObject);
1489  Ccb->Fcb = Fcb;
1490 
1492  Locked = TRUE;
1493  ++Fcb->NodeReferences;
1495  Locked = FALSE;
1496  CcbInitialized = TRUE;
1497 
1498  InsertTailList(&Fcb->CcbList, &Ccb->CcbListEntry);
1499  }
1500  }
1501 
1503  Locked = TRUE;
1504  MupDereferenceUncProvider(UncProvider);
1505  Referenced = FALSE;
1506  }
1507 
1509  Locked = FALSE;
1510  }
1512  {
1514  }
1515  _SEH2_END;
1516 
1517  /* If we at least opened one mailslot, return success */
1518  Status = (CcbInitialized ? STATUS_SUCCESS : LastFailed);
1519 
1520  if (Referenced)
1521  {
1522  MupDereferenceUncProvider(UncProvider);
1523  }
1524 
1525  if (Locked)
1526  {
1528  }
1529 
1530  /* In case of failure, don't leak CCB */
1531  if (!NT_SUCCESS(Status) && Ccb != NULL)
1532  {
1533  MupFreeNode(Ccb);
1534  }
1535 
1536  return Status;
1537 }
1538 
1539 PIRP
1541  PVOID Context,
1542  ULONG MajorFunction,
1543  ULONG IoctlCode,
1545  ULONG InputBufferSize,
1547  ULONG OutputBufferSize,
1549 {
1550  PIRP Irp;
1551  PIO_STACK_LOCATION Stack;
1553 
1554  if (InputBuffer == NULL)
1555  {
1556  return NULL;
1557  }
1558 
1559  /* Get the device object */
1561  /* Allocate the IRP (with one more location for us */
1563  if (Irp == NULL)
1564  {
1565  return NULL;
1566  }
1567 
1568  /* Skip our location */
1570  /* Setup the IRP */
1571  Irp->Tail.Overlay.OriginalFileObject = FileObject;
1572  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1574 
1575  /* Setup the stack */
1576  Stack = IoGetNextIrpStackLocation(Irp);
1577  Stack->MajorFunction = MajorFunction;
1578  Stack->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferSize;
1579  Stack->Parameters.DeviceIoControl.InputBufferLength = InputBufferSize;
1580  Stack->Parameters.DeviceIoControl.IoControlCode = IoctlCode;
1581  Stack->MinorFunction = 0;
1582  Stack->FileObject = FileObject;
1583  Stack->DeviceObject = DeviceObject;
1584 
1585  switch (IO_METHOD_FROM_CTL_CODE(IoctlCode))
1586  {
1587  case METHOD_BUFFERED:
1588  /* If it's buffered, just pass the buffers we got */
1589  Irp->MdlAddress = NULL;
1590  Irp->AssociatedIrp.SystemBuffer = InputBuffer;
1591  Irp->UserBuffer = OutputBuffer;
1593 
1594  if (OutputBuffer != NULL)
1595  {
1596  Irp->Flags |= IRP_INPUT_OPERATION;
1597  }
1598  break;
1599 
1600  case METHOD_IN_DIRECT:
1601  case METHOD_OUT_DIRECT:
1602  /* Otherwise, allocate an MDL */
1603  if (IoAllocateMdl(InputBuffer, InputBufferSize, FALSE, FALSE, Irp) == NULL)
1604  {
1605  IoFreeIrp(Irp);
1606  return NULL;
1607  }
1608 
1609  Irp->AssociatedIrp.SystemBuffer = InputBuffer;
1610  Irp->Flags = IRP_BUFFERED_IO;
1612  break;
1613 
1614  case METHOD_NEITHER:
1615  /* Or pass the buffers */
1616  Irp->UserBuffer = OutputBuffer;
1617  Irp->MdlAddress = NULL;
1618  Irp->AssociatedIrp.SystemBuffer = NULL;
1619  Stack->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
1620  break;
1621  }
1622 
1623  return Irp;
1624 }
1625 
1626 VOID
1628 {
1629  ExDeleteResourceLite(&MasterQueryContext->QueryPathListLock);
1630  ExFreePoolWithTag(MasterQueryContext, TAG_MUP);
1631 }
1632 
1633 NTSTATUS
1635 {
1636  LONG References;
1637  NTSTATUS Status;
1638  BOOLEAN KeepExtraRef;
1639 
1641  --MasterQueryContext->NodeReferences;
1642  References = MasterQueryContext->NodeReferences;
1644 
1645  if (References != 0)
1646  {
1647  DPRINT("Still having refs (%ld)\n", References);
1648  return STATUS_PENDING;
1649  }
1650 
1651  /* We HAVE an IRP to complete. It cannot be NULL
1652  * Please, help preserving kittens, don't provide NULL IRPs.
1653  */
1654  if (MasterQueryContext->Irp == NULL)
1655  {
1657  }
1658 
1660  RemoveEntryList(&MasterQueryContext->MQCListEntry);
1662 
1664  KeepExtraRef = MasterQueryContext->Prefix->KeepExtraRef;
1665  MupDereferenceKnownPrefix(MasterQueryContext->Prefix);
1666 
1667  /* We found a provider? */
1668  if (MasterQueryContext->LatestProvider != NULL)
1669  {
1670  /* With a successful status? */
1671  if (MasterQueryContext->LatestStatus == STATUS_SUCCESS)
1672  {
1673  /* Then, it's time to reroute, someone accepted to handle the file creation request! */
1674  if (!KeepExtraRef)
1675  {
1676  MupDereferenceKnownPrefix(MasterQueryContext->Prefix);
1677  }
1678 
1680  /* Reroute & complete :-) */
1681  Status = MupRerouteOpen(MasterQueryContext->FileObject, MasterQueryContext->LatestProvider);
1682  goto Complete;
1683  }
1684  else
1685  {
1686  MupDereferenceUncProvider(MasterQueryContext->LatestProvider);
1687  }
1688  }
1689 
1690  MupDereferenceKnownPrefix(MasterQueryContext->Prefix);
1692 
1693  /* Return the highest failed status we had */
1694  Status = MasterQueryContext->LatestStatus;
1695 
1696 Complete:
1697  /* In finally, complete the IRP for real! */
1698  MasterQueryContext->Irp->IoStatus.Status = Status;
1699  IoCompleteRequest(MasterQueryContext->Irp, IO_DISK_INCREMENT);
1700 
1701  MasterQueryContext->Irp = NULL;
1702  MupFreeMasterQueryContext(MasterQueryContext);
1703 
1704  return Status;
1705 }
1706 
1707 NTSTATUS
1708 NTAPI
1710  PIRP Irp,
1711  PVOID Context)
1712 {
1713  PMUP_PFX Prefix;
1714  ULONG LatestPos, Pos;
1715  PWSTR AcceptedPrefix;
1716  PMUP_MQC MasterQueryContext;
1717  NTSTATUS Status, TableStatus;
1718  PQUERY_PATH_CONTEXT QueryContext;
1719  PQUERY_PATH_RESPONSE QueryResponse;
1720 
1721  /* Get all the data from our query to the provider */
1722  QueryContext = (PQUERY_PATH_CONTEXT)Context;
1723  QueryResponse = (PQUERY_PATH_RESPONSE)QueryContext->QueryPathRequest;
1724  MasterQueryContext = QueryContext->MasterQueryContext;
1725  Status = Irp->IoStatus.Status;
1726 
1727  DPRINT("Reply from %wZ: %u (Status: %lx)\n", &QueryContext->UncProvider->DeviceName, QueryResponse->LengthAccepted, Status);
1728 
1729  ExAcquireResourceExclusiveLite(&MasterQueryContext->QueryPathListLock, TRUE);
1730  RemoveEntryList(&QueryContext->QueryPathListEntry);
1731 
1732  /* If the driver returned a success, and an acceptance length */
1733  if (NT_SUCCESS(Status) && QueryResponse->LengthAccepted > 0)
1734  {
1735  Prefix = MasterQueryContext->Prefix;
1736 
1737  /* Check if we already found a provider from a previous iteration */
1738  if (MasterQueryContext->LatestProvider != NULL)
1739  {
1740  /* If the current provider has a lower priority (ie, a greater order), then, bailout and keep previous one */
1741  if (QueryContext->UncProvider->ProviderOrder >= MasterQueryContext->LatestProvider->ProviderOrder)
1742  {
1743  MupDereferenceUncProvider(QueryContext->UncProvider);
1744  goto Cleanup;
1745  }
1746 
1747  /* Otherwise, if the prefix was in the prefix table, just drop it:
1748  * we have a provider which supersedes the accepted prefix, so leave
1749  * room for the new prefix/provider
1750  */
1752  if (Prefix->InTable)
1753  {
1754  RtlRemoveUnicodePrefix(&MupPrefixTable, &Prefix->PrefixTableEntry);
1755  RemoveEntryList(&Prefix->PrefixListEntry);
1756  Prefix->InTable = FALSE;
1757  }
1759 
1760  Prefix->KeepExtraRef = FALSE;
1761 
1762  /* Release data associated with the current prefix, if any
1763  * We'll renew them with the new accepted prefix
1764  */
1765  if (Prefix->AcceptedPrefix.Length != 0 && Prefix->AcceptedPrefix.Buffer != NULL)
1766  {
1767  ExFreePoolWithTag(Prefix->AcceptedPrefix.Buffer, TAG_MUP);
1768  Prefix->AcceptedPrefix.MaximumLength = 0;
1769  Prefix->AcceptedPrefix.Length = 0;
1770  Prefix->AcceptedPrefix.Buffer = NULL;
1771  Prefix->ExternalAlloc = FALSE;
1772  }
1773 
1774  /* If there was also a provider, drop it, the new one
1775  * is different
1776  */
1777  if (Prefix->UncProvider != NULL)
1778  {
1779  MupDereferenceUncProvider(Prefix->UncProvider);
1780  Prefix->UncProvider = NULL;
1781  }
1782  }
1783 
1784  /* Now, set our information about the provider that accepted the prefix */
1785  MasterQueryContext->LatestProvider = QueryContext->UncProvider;
1786  MasterQueryContext->LatestStatus = Status;
1787 
1788  if (MasterQueryContext->FileObject->FsContext2 != (PVOID)DFS_DOWNLEVEL_OPEN_CONTEXT)
1789  {
1790  /* Allocate a buffer for the prefix */
1791  AcceptedPrefix = ExAllocatePoolWithTag(PagedPool, QueryResponse->LengthAccepted, TAG_MUP);
1792  if (AcceptedPrefix == NULL)
1793  {
1794  Prefix->InTable = FALSE;
1795  }
1796  else
1797  {
1798  /* Set it up to the accepted length */
1799  RtlMoveMemory(AcceptedPrefix, MasterQueryContext->FileObject->FileName.Buffer, QueryResponse->LengthAccepted);
1800  Prefix->UncProvider = MasterQueryContext->LatestProvider;
1801  Prefix->AcceptedPrefix.Buffer = AcceptedPrefix;
1802  Prefix->AcceptedPrefix.Length = QueryResponse->LengthAccepted;
1803  Prefix->AcceptedPrefix.MaximumLength = QueryResponse->LengthAccepted;
1804  Prefix->ExternalAlloc = TRUE;
1805 
1806  /* Insert the accepted prefix in the table of known prefixes */
1807  DPRINT1("%wZ accepted %wZ\n", &Prefix->UncProvider->DeviceName, &Prefix->AcceptedPrefix);
1809  if (RtlInsertUnicodePrefix(&MupPrefixTable, &Prefix->AcceptedPrefix, &Prefix->PrefixTableEntry))
1810  {
1811  InsertHeadList(&MupPrefixList, &Prefix->PrefixListEntry);
1812  Prefix->InTable = TRUE;
1813  Prefix->KeepExtraRef = TRUE;
1814  }
1815  else
1816  {
1817  Prefix->InTable = FALSE;
1818  }
1820  }
1821  }
1822  }
1823  else
1824  {
1825  MupDereferenceUncProvider(QueryContext->UncProvider);
1826 
1827  /* We failed and didn't find any provider over the latest iterations */
1828  if (MasterQueryContext->LatestProvider == NULL)
1829  {
1830  /* If we had a success though (broken provider?) set our failed status */
1831  if (NT_SUCCESS(MasterQueryContext->LatestStatus))
1832  {
1833  MasterQueryContext->LatestStatus = Status;
1834  }
1835  else
1836  {
1837  TableStatus = MupOrderedErrorList[0];
1838  LatestPos = 0;
1839 
1840  /* Otherwise, time to compare statuses, between the latest failed
1841  * and the current failure.
1842  * We have an order table of failed status: the deeper you go in the
1843  * table, the more the error is critical.
1844  * Our goal is to return the most critical status that was returned by
1845  * any of the providers
1846  */
1847 
1848  /* Look for latest status position */
1849  while (TableStatus != 0 && TableStatus != MasterQueryContext->LatestStatus)
1850  {
1851  ++LatestPos;
1852  TableStatus = MupOrderedErrorList[LatestPos];
1853  }
1854 
1855  /* If at pos 0, the new status is likely more critical */
1856  if (LatestPos == 0)
1857  {
1858  MasterQueryContext->LatestStatus = Status;
1859  }
1860  else
1861  {
1862  /* Otherwise, find position of the new status in the table */
1863  Pos = 0;
1864  do
1865  {
1866  if (Status == MupOrderedErrorList[Pos])
1867  {
1868  break;
1869  }
1870 
1871  ++Pos;
1872  }
1873  while (Pos < LatestPos);
1874 
1875  /* If it has a higher position (more critical), return it */
1876  if (Pos >= LatestPos)
1877  {
1878  MasterQueryContext->LatestStatus = Status;
1879  }
1880  }
1881  }
1882  }
1883  }
1884 
1885 Cleanup:
1886  ExFreePoolWithTag(QueryResponse, TAG_MUP);
1887  ExFreePoolWithTag(QueryContext, TAG_MUP);
1888  IoFreeIrp(Irp);
1889 
1890  ExReleaseResourceLite(&MasterQueryContext->QueryPathListLock);
1891  MupDereferenceMasterQueryContext(MasterQueryContext);
1892 
1894 }
1895 
1896 NTSTATUS
1899  PIO_SECURITY_CONTEXT SecurityContext)
1900 {
1901  LONG Len;
1902  WCHAR Cur;
1903  PWSTR Name;
1904  PIRP QueryIrp;
1905  NTSTATUS Status;
1906  PMUP_PFX Prefix;
1908  PMUP_UNC UncProvider;
1909  PIO_STACK_LOCATION Stack;
1910  LARGE_INTEGER CurrentTime;
1911  PMUP_MQC MasterQueryContext;
1912  PQUERY_PATH_CONTEXT QueryContext;
1913  PQUERY_PATH_REQUEST QueryPathRequest;
1915  BOOLEAN Locked, Referenced, BreakOnFirst;
1916 
1917  /* We cannot open a file without a name */
1918  if (FileObject->FileName.Length == 0)
1919  {
1920  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1922 
1924  }
1925 
1926  DPRINT1("Request for opening: %wZ\n", &FileObject->FileName);
1927 
1928  Referenced = FALSE;
1929  BreakOnFirst = TRUE;
1931 
1933  /* First, try to see if that's a prefix we already know */
1935  if (TableEntry != NULL)
1936  {
1938 
1939  DPRINT("Matching prefix found: %wZ\n", &Prefix->AcceptedPrefix);
1940 
1941  /* If so, check whether the prefix is still valid */
1942  KeQuerySystemTime(&CurrentTime);
1943  if (Prefix->ValidityTimeout.QuadPart < CurrentTime.QuadPart)
1944  {
1945  /* It is: so, update its validity period and reroute file opening */
1946  MupCalculateTimeout(&Prefix->ValidityTimeout);
1947  Status = MupRerouteOpen(FileObject, Prefix->UncProvider);
1949 
1950  if (Status == STATUS_REPARSE)
1951  {
1952  Irp->IoStatus.Information = FILE_SUPERSEDED;
1953  }
1954 
1955  Irp->IoStatus.Status = Status;
1957 
1958  return Status;
1959  }
1960 
1961  /* When here, we found a matching prefix, but expired, remove it from the table
1962  * We'll redo a full search
1963  */
1964  if (Prefix->InTable)
1965  {
1967  }
1968  }
1970 
1972  /* First of all, start looking for a mailslot */
1973  if (FileObject->FileName.Buffer[0] == L'\\' && Stack->MajorFunction != IRP_MJ_CREATE)
1974  {
1975  Name = &FileObject->FileName.Buffer[1];
1976  Len = FileObject->FileName.Length;
1977 
1978  /* Skip the remote destination name */
1979  do
1980  {
1981  Len -= sizeof(WCHAR);
1982  if (Len <= 0)
1983  {
1984  break;
1985  }
1986 
1987  Cur = *Name;
1988  ++Name;
1989  } while (Cur != L'\\');
1990  Len -= sizeof(WCHAR);
1991 
1992  /* If we still have room for "Mailslot" to fit */
1993  if (Len >= (sizeof(L"Mailslot") - sizeof(UNICODE_NULL)))
1994  {
1995  /* Get the len in terms of chars count */
1996  Len /= sizeof(WCHAR);
1997  if (Len > ((sizeof(L"Mailslot") - sizeof(UNICODE_NULL)) / sizeof(WCHAR)))
1998  {
1999  Len = (sizeof(L"Mailslot") - sizeof(UNICODE_NULL)) / sizeof(WCHAR);
2000  }
2001 
2002  /* It's indeed a mailslot opening! */
2003  if (_wcsnicmp(Name, L"Mailslot", Len) == 0)
2004  {
2005  /* Broadcast open */
2007  if (Status == STATUS_REPARSE)
2008  {
2009  Irp->IoStatus.Information = FILE_SUPERSEDED;
2010  }
2011 
2012  Irp->IoStatus.Status = Status;
2014 
2015  return Status;
2016  }
2017  }
2018  }
2019 
2020  /* Ok, at that point, that's a regular MUP opening (if no DFS) */
2021  if (!MupEnableDfs || FileObject->FsContext2 == (PVOID)DFS_DOWNLEVEL_OPEN_CONTEXT)
2022  {
2023  /* We won't complete immediately */
2025 
2026  /* Allocate a new prefix for our search */
2028  if (Prefix == NULL)
2029  {
2030  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2032 
2033  return STATUS_PENDING;
2034  }
2035 
2036  /* Allocate a context for our search */
2037  MasterQueryContext = MupAllocateMasterQueryContext();
2038  if (MasterQueryContext == NULL)
2039  {
2041 
2042  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2044 
2045  return STATUS_PENDING;
2046  }
2047 
2048  MasterQueryContext->Irp = Irp;
2049  MasterQueryContext->FileObject = FileObject;
2050  MasterQueryContext->LatestProvider = NULL;
2051  MasterQueryContext->Prefix = Prefix;
2052  MasterQueryContext->LatestStatus = STATUS_BAD_NETWORK_PATH;
2054  InsertTailList(&MupMasterQueryList, &MasterQueryContext->MQCListEntry);
2055  ++Prefix->NodeReferences;
2057 
2058  _SEH2_TRY
2059  {
2061  Locked = TRUE;
2062 
2063  /* Now, we will browse all the providers we know, to ask for their accepted prefix regarding the path */
2064  for (Entry = MupProviderList.Flink; Entry != &MupProviderList; Entry = Entry->Flink)
2065  {
2066  UncProvider = CONTAINING_RECORD(Entry, MUP_UNC, ProviderListEntry);
2067 
2068  ++UncProvider->NodeReferences;
2069  Referenced = TRUE;
2070 
2072  Locked = FALSE;
2073 
2074  /* We will obviously only query registered providers */
2075  if (UncProvider->Registered)
2076  {
2077  /* We will issue an IOCTL_REDIR_QUERY_PATH, so allocate input buffer */
2078  QueryPathRequest = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.Length + sizeof(QUERY_PATH_REQUEST), TAG_MUP);
2079  if (QueryPathRequest == NULL)
2080  {
2082  }
2083 
2084  /* Allocate a context for IRP completion routine
2085  * In case a prefix matches the path, the reroute will happen
2086  * in the completion routine, when we have return from the provider
2087  */
2088  QueryContext = ExAllocatePoolWithTag(PagedPool, sizeof(QUERY_PATH_CONTEXT), TAG_MUP);
2089  if (QueryContext == NULL)
2090  {
2091  ExFreePoolWithTag(QueryPathRequest, TAG_MUP);
2093  }
2094 
2095  InitializeListHead(&QueryContext->QueryPathListEntry);
2096  QueryContext->MasterQueryContext = MasterQueryContext;
2097  QueryContext->QueryPathRequest = QueryPathRequest;
2098  QueryPathRequest->PathNameLength = FileObject->FileName.Length;
2099  QueryPathRequest->SecurityContext = SecurityContext;
2100  RtlMoveMemory(QueryPathRequest->FilePathName, FileObject->FileName.Buffer, FileObject->FileName.Length);
2101 
2102  /* Build our IRP for the query */
2103  QueryIrp = MupBuildIoControlRequest(UncProvider->FileObject,
2104  QueryContext,
2107  QueryPathRequest,
2108  FileObject->FileName.Length + sizeof(QUERY_PATH_REQUEST),
2109  QueryPathRequest,
2110  sizeof(QUERY_PATH_RESPONSE),
2112  if (QueryIrp == NULL)
2113  {
2114  ExFreePoolWithTag(QueryContext, TAG_MUP);
2115  ExFreePoolWithTag(QueryPathRequest, TAG_MUP);
2117  }
2118 
2119  QueryIrp->RequestorMode = KernelMode;
2120  QueryContext->UncProvider = UncProvider;
2121  QueryContext->Irp = QueryIrp;
2122 
2124  ++UncProvider->NodeReferences;
2125  ++MasterQueryContext->NodeReferences;
2127 
2128  ExAcquireResourceExclusiveLite(&MasterQueryContext->QueryPathListLock, TRUE);
2129  InsertTailList(&MasterQueryContext->QueryPathList, &QueryContext->QueryPathListEntry);
2130  ExReleaseResourceLite(&MasterQueryContext->QueryPathListLock);
2131 
2132  /* Query the provider !*/
2133  DPRINT1("Requesting UNC provider: %wZ\n", &UncProvider->DeviceName);
2134  DPRINT("Calling: %wZ\n", &UncProvider->DeviceObject->DriverObject->DriverName);
2135  Status = IoCallDriver(UncProvider->DeviceObject, QueryIrp);
2136  }
2137 
2139  Locked = TRUE;
2140 
2141  /* We're done with that provider */
2142  MupDereferenceUncProvider(UncProvider);
2143  Referenced = FALSE;
2144 
2145  /* If query went fine on the first request, just break and leave */
2146  if (BreakOnFirst && Status == STATUS_SUCCESS)
2147  {
2148  break;
2149  }
2150 
2151  BreakOnFirst = FALSE;
2152  }
2153  }
2155  {
2157  {
2158  MasterQueryContext->LatestStatus = STATUS_INSUFFICIENT_RESOURCES;
2159  }
2160 
2161  if (Referenced)
2162  {
2163  MupDereferenceUncProvider(UncProvider);
2164  }
2165 
2166  if (Locked)
2167  {
2169  }
2170 
2171  MupDereferenceMasterQueryContext(MasterQueryContext);
2172 
2174  }
2175  _SEH2_END;
2176  }
2177  else
2178  {
2179  UNIMPLEMENTED;
2181  }
2182 
2183  return Status;
2184 }
2185 
2186 NTSTATUS
2191 {
2192  NTSTATUS Status;
2193 
2194  DPRINT1("Opening MUP\n");
2195 
2197  _SEH2_TRY
2198  {
2199  /* Update share access, increase reference count, and associated VCB to the FO, that's it! */
2201  if (NT_SUCCESS(Status))
2202  {
2203  ++Vcb->NodeReferences;
2206  }
2207  }
2209  {
2211  }
2212  _SEH2_END;
2213 
2214  return Status;
2215 }
2216 
2217 NTSTATUS
2218 NTAPI
2220  PIRP Irp)
2221 {
2222  NTSTATUS Status;
2223  PIO_STACK_LOCATION Stack;
2224  PFILE_OBJECT FileObject, RelatedFileObject;
2225 
2227 
2228  _SEH2_TRY
2229  {
2230  /* If DFS is enabled, check if that's for DFS and is so relay */
2231  if (MupEnableDfs && (DeviceObject->DeviceType == FILE_DEVICE_DFS || DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM))
2232  {
2234  }
2235  else
2236  {
2238  FileObject = Stack->FileObject;
2239  RelatedFileObject = FileObject->RelatedFileObject;
2240 
2241  /* If we have a file name or if the associated FCB of the related FO isn't the VCB, then, it's a regular opening */
2242  if (FileObject->FileName.Length != 0 || (RelatedFileObject != NULL && ((PMUP_FCB)(RelatedFileObject->FsContext))->NodeType != NODE_TYPE_VCB))
2243  {
2244  Status = CreateRedirectedFile(Irp, FileObject, Stack->Parameters.Create.SecurityContext);
2245  }
2246  /* Otherwise, it's just a volume open */
2247  else
2248  {
2250  FileObject,
2251  Stack->Parameters.Create.SecurityContext->DesiredAccess,
2252  Stack->Parameters.Create.ShareAccess);
2253 
2254  Irp->IoStatus.Information = FILE_OPENED;
2255  Irp->IoStatus.Status = Status;
2257  }
2258  }
2259  }
2261  {
2263 
2264  Irp->IoStatus.Status = Status;
2266  }
2267  _SEH2_END;
2268 
2270 
2271  return Status;
2272 }
2273 
2274 VOID
2276 {
2278 
2279  /* If the node was still valid, reregister the UNC provider */
2280  if (UncProvider->NodeStatus == NODE_STATUS_HEALTHY)
2281  {
2282  UncProvider->NodeStatus = NODE_STATUS_CLEANUP;
2283  UncProvider->Registered = FALSE;
2285 
2286  if (UncProvider->FileObject != NULL)
2287  {
2288  ZwClose(UncProvider->DeviceHandle);
2289  ObDereferenceObject(UncProvider->FileObject);
2290  }
2291  }
2292  else
2293  {
2295  }
2296 }
2297 
2298 NTSTATUS
2299 NTAPI
2301  PIRP Irp)
2302 {
2303  ULONG Type;
2304  PMUP_FCB Fcb;
2305  PMUP_CCB Ccb;
2306  NTSTATUS Status;
2307  PIO_STACK_LOCATION Stack;
2308 
2309  /* If DFS is enabled, check if that's for DFS and is so relay */
2310  if (MupEnableDfs)
2311  {
2312  if (DeviceObject->DeviceType == FILE_DEVICE_DFS || DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM)
2313  {
2314  return DfsFsdCleanup(DeviceObject, Irp);
2315  }
2316  }
2317 
2319 
2320  _SEH2_TRY
2321  {
2323  Type = MupDecodeFileObject(Stack->FileObject, &Fcb, &Ccb);
2324  switch (Type)
2325  {
2326  case NODE_TYPE_VCB:
2327  /* If we got a VCB, clean it up */
2329 
2330  Irp->IoStatus.Status = STATUS_SUCCESS;
2332 
2334 
2335  /* If Ccb is not null, then, it's a UNC provider node */
2336  if (Ccb)
2337  {
2338  /* Close it, and dereference */
2342  --MupProviderCount;
2344  }
2345 
2347  break;
2348 
2349  case NODE_TYPE_FCB:
2350  /* If the node wasn't already cleaned, do it */
2351  if (Fcb->NodeStatus == NODE_STATUS_HEALTHY)
2352  {
2355  }
2356  else
2357  {
2359  }
2360 
2361  Irp->IoStatus.Status = STATUS_SUCCESS;
2363 
2365  break;
2366 
2367  default:
2369 
2370  Irp->IoStatus.Status = Status;
2372 
2373  break;
2374  }
2375  }
2377  {
2379  }
2380  _SEH2_END;
2381 
2383 
2384  return Status;
2385 }
2386 
2387 NTSTATUS
2389  PIRP Irp,
2390  PMUP_VCB Vcb,
2392 {
2394 
2395  /* Remove FCB, UNC from FO */
2398 
2400 
2401  return STATUS_SUCCESS;
2402 }
2403 
2404 NTSTATUS
2406  PIRP Irp,
2407  PMUP_FCB Fcb,
2409 {
2411 
2412  /* Remove FCB, CCB from FO */
2415 
2417 
2418  return STATUS_SUCCESS;
2419 }
2420 
2421 NTSTATUS
2422 NTAPI
2424  PIRP Irp)
2425 {
2426  PMUP_FCB Fcb;
2427  PMUP_CCB Ccb;
2428  NTSTATUS Status;
2429  PIO_STACK_LOCATION Stack;
2430 
2431  /* If DFS is enabled, check if that's for DFS and is so relay */
2432  if (MupEnableDfs)
2433  {
2434  if (DeviceObject->DeviceType == FILE_DEVICE_DFS || DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM)
2435  {
2436  return DfsFsdClose(DeviceObject, Irp);
2437  }
2438  }
2439 
2441 
2442  _SEH2_TRY
2443  {
2444  /* Get our internal structures from FO */
2446  MupDecodeFileObject(Stack->FileObject, &Fcb, &Ccb);
2447  if (Fcb == NULL)
2448  {
2450 
2451  Irp->IoStatus.Status = Status;
2453 
2454  _SEH2_LEAVE;
2455  }
2456 
2457  /* If we got the VCB, that's a volume close */
2458  if (Fcb->NodeType == NODE_TYPE_VCB)
2459  {
2461  }
2462  /* Otherwise close the FCB */
2463  else if (Fcb->NodeType == NODE_TYPE_FCB)
2464  {
2467  }
2468  else
2469  {
2471 
2472  Irp->IoStatus.Status = Status;
2474 
2475  _SEH2_LEAVE;
2476  }
2477 
2478  Irp->IoStatus.Status = STATUS_SUCCESS;
2480  }
2482  {
2484  }
2485  _SEH2_END;
2486 
2488 
2489  return Status;
2490 }
2491 
2492 VOID
2493 NTAPI
2495 {
2497 
2498  if (MupEnableDfs)
2499  {
2501  }
2502 
2504 }
2505 
2506 /*
2507  * FUNCTION: Called by the system to initialize the driver
2508  * ARGUMENTS:
2509  * DriverObject = object describing this driver
2510  * RegistryPath = path to our configuration entries
2511  * RETURNS: Success or failure
2512  */
2513 INIT_FUNCTION
2514 NTSTATUS
2515 NTAPI
2518 {
2519  NTSTATUS Status;
2520  UNICODE_STRING MupString;
2522 
2523  /* Only initialize global state of the driver
2524  * Other inits will happen when required
2525  */
2527 
2528  /* Check if DFS is disabled */
2530  /* If it's not disabled but when cannot init, disable it */
2532  {
2533  MupEnableDfs = FALSE;
2534  }
2535 
2536  /* Create the MUP device */
2537  RtlInitUnicodeString(&MupString, L"\\Device\\Mup");
2539  if (!NT_SUCCESS(Status))
2540  {
2541  if (MupEnableDfs)
2542  {
2544  }
2545 
2547 
2548  return Status;
2549  }
2550 
2551  /* Set our MJ */
2560 
2561  /* And finish init */
2564 
2565  return STATUS_SUCCESS;
2566 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
LONG NodeReferences
Definition: mup.h:109
* PNTSTATUS
Definition: strlen.c:14
BOOLEAN MuppIsDfsEnabled(VOID)
Definition: mup.c:120
NTSTATUS NTAPI DfsVolumePassThrough(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:42
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
const uint16_t * PCWSTR
Definition: typedefs.h:55
NTSTATUS MupCloseFcb(PDEVICE_OBJECT DeviceObject, PIRP Irp, PMUP_FCB Fcb, PFILE_OBJECT FileObject)
Definition: mup.c:2405
VOID MupSetFileObject(PFILE_OBJECT FileObject, PMUP_FCB Fcb, PMUP_CCB Ccb)
Definition: mup.c:1320
ULONG ProviderOrder
Definition: mup.h:82
#define TRUE
Definition: types.h:120
NTSTATUS BuildAndSubmitIrp(PIRP Irp, PMUP_CCB Ccb, PMUP_MIC MasterIoContext)
Definition: mup.c:623
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
BOOLEAN MupEnableDfs
Definition: mup.c:72
ULONG NodeSize
Definition: mup.h:110
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define LL
Definition: tui.h:85
#define STATUS_REDIRECTOR_NOT_STARTED
Definition: ntstatus.h:473
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
WORK_QUEUE_ITEM WorkQueueItem
Definition: mup.h:125
#define FsRtlEnterFileSystem
#define IRP_MJ_CREATE_MAILSLOT
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
PVOID NTAPI ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: expool.c:2939
Type
Definition: Type.h:6
struct _QUERY_PATH_RESPONSE * PQUERY_PATH_RESPONSE
VOID MupDereferenceKnownPrefix(PMUP_PFX Prefix)
Definition: mup.c:448
ERESOURCE MupGlobalLock
Definition: mup.c:61
struct _Entry Entry
Definition: kefuncs.h:640
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
UNICODE_PREFIX_TABLE MupPrefixTable
Definition: mup.c:68
#define FsRtlExitFileSystem
PIRP Irp
Definition: mup.h:65
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
LIST_ENTRY ProviderListEntry
Definition: mup.h:77
#define MAXLONG
Definition: umtypes.h:116
USHORT MaximumLength
Definition: env_spec_w32.h:370
PFILE_OBJECT FileObject
Definition: ntfs.h:516
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
Definition: mup.h:59
NTSTATUS DfsFsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:56
struct _MUP_UNC MUP_UNC
_In_ PIRP Irp
Definition: csq.h:116
#define KEY_READ
Definition: nt_native.h:1023
#define FILE_DEVICE_DFS_FILE_SYSTEM
Definition: winioctl.h:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NodeReferences
Definition: mup.h:75
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
VOID NTAPI MupUnload(PDRIVER_OBJECT DriverObject)
Definition: mup.c:2494
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_ATTRIBUTE_VALID_FLAGS
Definition: nt_native.h:714
VOID NTAPI RtlRemoveUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable, PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry)
ULONG NodeStatus
Definition: mup.h:62
_In_ __drv_aliasesMem PSTRING _Out_ PPREFIX_TABLE_ENTRY PrefixTableEntry
Definition: rtlfuncs.h:1631
struct _QUERY_PATH_CONTEXT * PQUERY_PATH_CONTEXT
#define NODE_STATUS_CLEANUP
Definition: mup.h:26
LONG NTSTATUS
Definition: precomp.h:26
ush Pos
Definition: deflate.h:92
_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)
struct _MUP_MQC MUP_MQC
#define FILE_OPENED
Definition: nt_native.h:769
#define FILE_SUPERSEDED
Definition: nt_native.h:768
INIT_FUNCTION VOID MupInitializeVcb(PMUP_VCB Vcb)
Definition: mup.c:110
struct _MUP_VCB MUP_VCB
#define New(t)
Definition: rtf.h:1086
#define IRP_NOCACHE
NTSTATUS LastSuccess
Definition: mup.h:66
#define ExRaiseStatus
Definition: ntoskrnl.h:95
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define FILE_VALID_SET_FLAGS
Definition: nt_native.h:762
LONG NodeReferences
Definition: mup.h:51
VOID MupUninitializeData()
Definition: mup.c:100
unsigned short Length
Definition: sprintf.c:451
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
ERESOURCE MupCcbListLock
Definition: mup.c:63
VOID MupDereferenceVcb(PMUP_VCB Vcb)
Definition: mup.c:379
LIST_ENTRY QueryPathListEntry
Definition: mup.h:135
VOID NTAPI RtlInitializeUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable)
NTSTATUS DfsFsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:72
PDEVICE_OBJECT DeviceObject
Definition: mup.h:80
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
LIST_ENTRY MupMasterQueryList
Definition: mup.c:67
HANDLE DeviceHandle
Definition: mup.h:79
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1735
#define InsertTailList(ListHead, Entry)
_In_ ULONG TotalLength
Definition: usbdlib.h:145
NTSTATUS OpenMupFileSystem(PMUP_VCB Vcb, PFILE_OBJECT FileObject, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: mup.c:2187
PMUP_MIC MupAllocateMasterIoContext(VOID)
Definition: mup.c:217
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK _In_ USHORT ShareAccess
Definition: create.c:4157
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3477
NTSTATUS MupCloseVcb(PDEVICE_OBJECT DeviceObject, PIRP Irp, PMUP_VCB Vcb, PFILE_OBJECT FileObject)
Definition: mup.c:2388
INIT_FUNCTION NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: mup.c:2516
ULONG MupProviderCount
Definition: mup.c:70
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
struct TraceInfo Info
NTSTATUS MupDereferenceMasterIoContext(PMUP_MIC MasterIoContext, PNTSTATUS NewStatus)
Definition: mup.c:389
CHAR InputBuffer[80]
Definition: conmgr.c:33
#define FILE_SHARE_READ
Definition: compat.h:125
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
BOOLEAN Registered
Definition: mup.h:84
LONG NodeReferences
Definition: mup.h:63
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_SEH2_TRY
Definition: create.c:4250
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
Definition: mup.h:28
#define NODE_TYPE_UNC
Definition: mup.h:18
struct _MUP_FCB MUP_FCB
#define FILE_TRAVERSE
Definition: nt_native.h:643
ERESOURCE MupPrefixTableLock
Definition: mup.c:62
NTSTATUS DfsFsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:49
PMUP_PFX Prefix
Definition: mup.h:115
void * Buffer
Definition: sprintf.c:453
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
#define METHOD_NEITHER
Definition: nt_native.h:597
UNICODE_STRING DeviceName
Definition: mup.h:78
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
PMUP_PFX MupAllocatePrefixEntry(ULONG PrefixLength)
Definition: mup.c:256
long LONG
Definition: pedump.c:60
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:509
NTSTATUS MupOrderedErrorList[]
Definition: mup.c:74
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:260
INIT_FUNCTION VOID MupInitializeData(VOID)
Definition: mup.c:84
NTSTATUS NTAPI MupCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:2300
struct _MUP_PFX MUP_PFX
Definition: rtltypes.h:617
PQUERY_PATH_REQUEST QueryPathRequest
Definition: mup.h:134
LARGE_INTEGER MupKnownPrefixTimeout
Definition: mup.c:69
ULONG NodeType
Definition: mup.h:61
struct NameRec_ * Name
Definition: cdprocs.h:464
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_BAD_NETWORK_PATH
Definition: ntstatus.h:412
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PDEVICE_OBJECT DeviceObject
Definition: mup.h:126
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS CreateRedirectedFile(PIRP Irp, PFILE_OBJECT FileObject, PIO_SECURITY_CONTEXT SecurityContext)
Definition: mup.c:1897
VOID MupCloseUncProvider(PMUP_UNC UncProvider)
Definition: mup.c:2275
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
LIST_ENTRY QueryPathList
Definition: mup.h:117
void DPRINT(...)
Definition: polytest.cpp:61
PMUP_UNC UncProvider
Definition: mup.h:133
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507
VOID MupCalculateTimeout(PLARGE_INTEGER EntryTime)
Definition: mup.c:168
PIRP Irp
Definition: mup.h:111
Definition: mup.h:37
ERESOURCE MupVcbLock
Definition: mup.c:64
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
void * PVOID
Definition: retypes.h:9
PMUP_FCB MupCreateFcb(VOID)
Definition: mup.c:197
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
NTSTATUS DfsFsdCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:64
#define InterlockedExchangeAdd
Definition: interlocked.h:181
Definition: mup.h:47
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PMUP_UNC MupAllocateUncProvider(ULONG RedirectorDeviceNameLength)
Definition: mup.c:236
ULONG NodeSize
Definition: mup.h:64
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:484
NTSTATUS MupDereferenceMasterQueryContext(PMUP_MQC MasterQueryContext)
Definition: mup.c:1634
NTSTATUS CommonForwardedIoCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFORWARDED_IO_CONTEXT FwdCtxt)
Definition: mup.c:556
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
Definition: mup.h:105
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE Handle
Definition: extypes.h:390
#define METHOD_OUT_DIRECT
Definition: nt_native.h:596
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
PMUP_FCB Fcb
Definition: mup.h:68
ULONG NodeType
Definition: mup.h:107
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define STATUS_BAD_NETWORK_NAME
Definition: ntstatus.h:426
VOID MupDereferenceUncProvider(PMUP_UNC UncProvider)
Definition: mup.c:442
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
PFILE_OBJECT FileObject
Definition: mup.h:112
VOID MupFreeMasterQueryContext(PMUP_MQC MasterQueryContext)
Definition: mup.c:1627
NTSTATUS NTAPI MupFsControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:1268
__wchar_t WCHAR
Definition: xmlstorage.h:180
ERESOURCE QueryPathListLock
Definition: mup.h:114
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define NODE_TYPE_FCB
Definition: vfat.h:439
ULONG MupDecodeFileObject(PFILE_OBJECT FileObject, PMUP_FCB *pFcb, PMUP_CCB *pCcb)
Definition: mup.c:317
#define FILE_DEVICE_DFS
Definition: winioctl.h:111
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define IRP_MJ_FILE_SYSTEM_CONTROL
PFILE_OBJECT FileObject
Definition: mup.h:81
#define Vcb
Definition: cdprocs.h:1425
PMUP_MIC MasterIoContext
Definition: mup.h:124
#define TAG_MUP
Definition: mup.h:13
NTSTATUS LastFailed
Definition: mup.h:67
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
VOID MupRemoveKnownPrefixEntry(PMUP_PFX Prefix)
Definition: mup.c:474
LIST_ENTRY MQCListEntry
Definition: mup.h:118
#define Len
Definition: deflate.h:82
PUNICODE_PREFIX_TABLE_ENTRY NTAPI RtlFindUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable, PUNICODE_STRING FullName, ULONG CaseInsensitiveIndex)
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define FSCTL_MUP_REGISTER_PROVIDER
Definition: muptypes.h:12
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Definition: mup.h:71
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1955
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
Definition: mup.h:87
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSTATUS LatestStatus
Definition: mup.h:116
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NODE_TYPE_PFX
Definition: mup.h:19
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NODE_TYPE_VCB
Definition: mup.h:17
struct _MUP_PROVIDER_REGISTRATION_INFO * PMUP_PROVIDER_REGISTRATION_INFO
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID MupFreeNode(PVOID Node)
Definition: mup.c:348
PMUP_MQC MupAllocateMasterQueryContext(VOID)
Definition: mup.c:295
VOID MupDereferenceCcb(PMUP_CCB Ccb)
Definition: mup.c:364
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID MupCleanupVcb(PDEVICE_OBJECT DeviceObject, PIRP Irp, PMUP_VCB Vcb)
Definition: mup.c:506
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
NTSTATUS NTAPI MupForwardIoRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:787
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
#define FILE_SIMPLE_RIGHTS_MASK
Definition: mup.h:15
VOID MupDereferenceFcb(PMUP_FCB Fcb)
Definition: mup.c:354
NTSTATUS NTAPI MupCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:2219
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
LIST_ENTRY MupProviderList
Definition: mup.c:65
BOOLEAN NTAPI RtlInsertUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable, PUNICODE_STRING Prefix, PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry)
Definition: typedefs.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG NodeStatus
Definition: mup.h:108
PMUP_UNC AddUnregisteredProvider(PCWSTR DeviceName, ULONG ProviderOrder)
Definition: mup.c:886
#define FILE_SHARE_VALID_FLAGS
Definition: nt_native.h:683
PMUP_UNC LatestProvider
Definition: mup.h:113
Status
Definition: gdiplustypes.h:24
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define FILE_OPEN
Definition: from_kernel.h:54
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
NTSTATUS MupRerouteOpen(PFILE_OBJECT FileObject, PMUP_UNC UncProvider)
Definition: mup.c:1329
LIST_ENTRY MupPrefixList
Definition: mup.c:66
NTSTATUS NTAPI IoCheckShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess, IN BOOLEAN Update)
Definition: file.c:3389
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PIO_SECURITY_CONTEXT SecurityContext
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define IOCTL_REDIR_QUERY_PATH
_SEH2_END
Definition: create.c:4424
#define IRP_INPUT_OPERATION
#define IRP_BUFFERED_IO
VOID NTAPI DeferredForwardedIoCompletionRoutine(PVOID Context)
Definition: mup.c:591
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
unsigned short USHORT
Definition: pedump.c:61
#define IO_METHOD_FROM_CTL_CODE(C)
Definition: mup.h:11
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BOOLEAN MailslotsSupported
Definition: mup.h:83
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
struct _FORWARDED_IO_CONTEXT * PFORWARDED_IO_CONTEXT
VOID MupInvalidatePrefixTable(VOID)
Definition: mup.c:483
#define METHOD_BUFFERED
Definition: nt_native.h:594
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
struct _FCB::@693::@696 Fcb
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
_SEH2_FINALLY
Definition: create.c:4395
#define STATUS_REPARSE
Definition: ntstatus.h:83
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
ULONG NodeSize
Definition: mup.h:76
PMUP_UNC MupCheckForUnregisteredProvider(PUNICODE_STRING RedirectorDeviceName)
Definition: mup.c:1078
#define NODE_TYPE_MQC
Definition: mup.h:23
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PMUP_MQC MasterQueryContext
Definition: mup.h:132
#define NODE_TYPE_MIC
Definition: mup.h:22
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2480
PDEVICE_OBJECT mupDeviceObject
Definition: mup.c:73
#define MAXUSHORT
Definition: typedefs.h:81
#define SL_WRITE_THROUGH
Definition: iotypes.h:1781
#define DFS_DOWNLEVEL_OPEN_CONTEXT
Definition: dfs.h:7
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ typedef _In_ ULONG TableEntry
Definition: iotypes.h:3947
NTSTATUS NTAPI IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options)
Definition: file.c:3009
#define IRP_DEALLOCATE_BUFFER
#define IRP_MJ_CLEANUP
NTSTATUS BroadcastOpen(PIRP Irp)
Definition: mup.c:1366
NTSTATUS NTAPI QueryPathCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: mup.c:1709
struct _MUP_MIC MUP_MIC
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
INIT_FUNCTION NTSTATUS DfsDriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: dfs.c:87
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
#define NODE_TYPE_CCB
Definition: mup.h:21
struct _MUP_CCB MUP_CCB
VOID MupCleanupFcb(PDEVICE_OBJECT DeviceObject, PIRP Irp, PMUP_FCB Fcb)
Definition: mup.c:525
_In_ PIRP _In_opt_ PVOID _In_opt_ POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine
Definition: fsrtlfuncs.h:673
ULONG ERESOURCE
Definition: env_spec_w32.h:594
ULONG NodeStatus
Definition: mup.h:74
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSTATUS NTAPI MupClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:2423
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
VOID InitializeProvider(PCWSTR ProviderName, ULONG ProviderOrder)
Definition: mup.c:921
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
PIRP MupBuildIoControlRequest(PFILE_OBJECT FileObject, PVOID Context, ULONG MajorFunction, ULONG IoctlCode, PVOID InputBuffer, ULONG InputBufferSize, PVOID OutputBuffer, ULONG OutputBufferSize, PIO_COMPLETION_ROUTINE CompletionRoutine)
Definition: mup.c:1540
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define IRP_WRITE_OPERATION
#define _SEH2_LEAVE
Definition: filesup.c:20
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
#define NODE_STATUS_HEALTHY
Definition: mup.h:25
BOOLEAN KeepExtraRef
Definition: mup.h:100
return STATUS_SUCCESS
Definition: btrfs.c:2966
unsigned short MaximumLength
Definition: sprintf.c:452
IoMarkIrpPending(Irp)
#define REG_DWORD
Definition: sdbapi.c:596
PMUP_CCB MupCreateCcb(VOID)
Definition: mup.c:178
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID MupGetProviderInformation(VOID)
Definition: mup.c:995
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
HRESULT Create([out]ITransactionReceiver **ppReceiver)
NTSTATUS NTAPI ForwardedIoCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: mup.c:600
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
#define FILE_DEVICE_MULTI_UNC_PROVIDER
Definition: winioctl.h:121
ULONG ACCESS_MASK
Definition: nt_native.h:40
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107
BOOLEAN MupOrderInitialized
Definition: mup.c:71
ULONG NodeType
Definition: mup.h:73
#define IRP_MJ_CREATE_NAMED_PIPE
NTSTATUS RegisterUncProvider(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:1107
LONGLONG QuadPart
Definition: typedefs.h:112
PMUP_CCB Ccb
Definition: mup.h:123
UNICODE_STRING RedirectorDeviceName
Definition: unc.c:23
#define FO_WRITE_THROUGH
Definition: iotypes.h:1736
VOID DfsUnload(PDRIVER_OBJECT DriverObject)
Definition: dfs.c:80
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: dlist.c:348