ReactOS  0.4.15-dev-3163-gf17c2c0
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 
53 
54 /* FUNCTIONS ****************************************************************/
55 
56 CODE_SEG("INIT")
57 VOID
59 {
64  MupProviderCount = 0;
69  MupKnownPrefixTimeout.QuadPart = 9000000000LL;
71 }
72 
73 VOID
75 {
80 }
81 
82 CODE_SEG("INIT")
83 VOID
85 {
86  RtlZeroMemory(Vcb, sizeof(MUP_VCB));
87  Vcb->NodeType = NODE_TYPE_VCB;
88  Vcb->NodeStatus = NODE_STATUS_HEALTHY;
89  Vcb->NodeReferences = 1;
90  Vcb->NodeSize = sizeof(MUP_VCB);
91 }
92 
93 BOOLEAN
95 {
96  HANDLE Key;
97  ULONG Length;
101  struct
102  {
104  ULONG KeyValue;
105  } KeyQueryOutput;
106 
107  /* You recognize FsRtlpIsDfsEnabled()! Congratz :-) */
108  KeyName.Buffer = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup";
109  KeyName.Length = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup") - sizeof(UNICODE_NULL);
110  KeyName.MaximumLength = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup");
111 
112  /* Simply query registry to know whether we have to disable DFS.
113  * Unless explicitly stated in registry, we will try to enable DFS.
114  */
116  &KeyName,
118  NULL,
119  NULL);
120 
121  Status = ZwOpenKey(&Key, KEY_READ, &ObjectAttributes);
122  if (!NT_SUCCESS(Status))
123  {
124  return TRUE;
125  }
126 
127  KeyName.Buffer = L"DisableDfs";
128  KeyName.Length = sizeof(L"DisableDfs") - sizeof(UNICODE_NULL);
129  KeyName.MaximumLength = sizeof(L"DisableDfs");
130 
131  Status = ZwQueryValueKey(Key, &KeyName, KeyValuePartialInformation, &KeyQueryOutput, sizeof(KeyQueryOutput), &Length);
132  ZwClose(Key);
133  if (!NT_SUCCESS(Status) || KeyQueryOutput.KeyInfo.Type != REG_DWORD)
134  {
135  return TRUE;
136  }
137 
138  return ((ULONG_PTR)KeyQueryOutput.KeyInfo.Data != 1);
139 }
140 
141 VOID
143 {
144  LARGE_INTEGER CurrentTime;
145 
146  /* Just get now + our allowed timeout */
147  KeQuerySystemTime(&CurrentTime);
148  EntryTime->QuadPart = CurrentTime.QuadPart + MupKnownPrefixTimeout.QuadPart;
149 }
150 
151 PMUP_CCB
153 {
154  PMUP_CCB Ccb;
155 
157  if (Ccb == NULL)
158  {
159  return NULL;
160  }
161 
162  Ccb->NodeStatus = NODE_STATUS_HEALTHY;
163  Ccb->NodeReferences = 1;
164  Ccb->NodeType = NODE_TYPE_CCB;
165  Ccb->NodeSize = sizeof(MUP_CCB);
166 
167  return Ccb;
168 }
169 
170 PMUP_FCB
172 {
173  PMUP_FCB Fcb;
174 
176  if (Fcb == NULL)
177  {
178  return NULL;
179  }
180 
181  Fcb->NodeStatus = NODE_STATUS_HEALTHY;
182  Fcb->NodeReferences = 1;
183  Fcb->NodeType = NODE_TYPE_FCB;
184  Fcb->NodeSize = sizeof(MUP_FCB);
185  InitializeListHead(&Fcb->CcbList);
186 
187  return Fcb;
188 }
189 
190 PMUP_MIC
192 {
193  PMUP_MIC MasterIoContext;
194 
195  MasterIoContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(MUP_MIC), TAG_MUP);
196  if (MasterIoContext == NULL)
197  {
198  return NULL;
199  }
200 
201  MasterIoContext->NodeStatus = NODE_STATUS_HEALTHY;
202  MasterIoContext->NodeReferences = 1;
203  MasterIoContext->NodeType = NODE_TYPE_MIC;
204  MasterIoContext->NodeSize = sizeof(MUP_MIC);
205 
206  return MasterIoContext;
207 }
208 
209 PMUP_UNC
210 MupAllocateUncProvider(ULONG RedirectorDeviceNameLength)
211 {
212  PMUP_UNC UncProvider;
213 
214  UncProvider = ExAllocatePoolWithTag(PagedPool, sizeof(MUP_UNC) + RedirectorDeviceNameLength, TAG_MUP);
215  if (UncProvider == NULL)
216  {
217  return NULL;
218  }
219 
220  UncProvider->NodeReferences = 0;
221  UncProvider->NodeType = NODE_TYPE_UNC;
222  UncProvider->NodeStatus = NODE_STATUS_HEALTHY;
223  UncProvider->NodeSize = sizeof(MUP_UNC) + RedirectorDeviceNameLength;
224  UncProvider->Registered = FALSE;
225 
226  return UncProvider;
227 }
228 
229 PMUP_PFX
231 {
233  ULONG PrefixSize;
234 
235  PrefixSize = sizeof(MUP_PFX) + PrefixLength;
237  if (Prefix == NULL)
238  {
239  return NULL;
240  }
241 
242  RtlZeroMemory(Prefix, PrefixSize);
243  Prefix->NodeType = NODE_TYPE_PFX;
244  Prefix->NodeStatus = NODE_STATUS_HEALTHY;
245  Prefix->NodeReferences = 1;
246  Prefix->NodeSize = PrefixSize;
247 
248  /* If we got a prefix, initialize the string */
249  if (PrefixLength != 0)
250  {
251  Prefix->AcceptedPrefix.Buffer = (PVOID)((ULONG_PTR)Prefix + sizeof(MUP_PFX));
252  Prefix->AcceptedPrefix.Length = PrefixLength;
253  Prefix->AcceptedPrefix.MaximumLength = PrefixLength;
254  }
255  /* Otherwise, mark the fact that the allocation will be external */
256  else
257  {
258  Prefix->ExternalAlloc = TRUE;
259  }
260 
261  Prefix->KeepExtraRef = FALSE;
262  /* Already init timeout to have one */
263  MupCalculateTimeout(&Prefix->ValidityTimeout);
264 
265  return Prefix;
266 }
267 
268 PMUP_MQC
270 {
271  PMUP_MQC MasterQueryContext;
272 
273  MasterQueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(MUP_MQC), TAG_MUP);
274  if (MasterQueryContext == NULL)
275  {
276  return NULL;
277  }
278 
279  MasterQueryContext->NodeStatus = NODE_STATUS_HEALTHY;
280  MasterQueryContext->NodeReferences = 1;
281  MasterQueryContext->NodeType = NODE_TYPE_MQC;
282  MasterQueryContext->NodeSize = sizeof(MUP_MQC);
283  InitializeListHead(&MasterQueryContext->QueryPathList);
284  InitializeListHead(&MasterQueryContext->MQCListEntry);
285  ExInitializeResourceLite(&MasterQueryContext->QueryPathListLock);
286 
287  return MasterQueryContext;
288 }
289 
290 ULONG
292 {
293  ULONG Type;
294  PMUP_FCB Fcb;
295 
297  *pFcb = FileObject->FsContext;
298  *pCcb = FileObject->FsContext2;
299  Fcb = *pFcb;
300 
301  if (Fcb == NULL)
302  {
304  return 0;
305  }
306 
307  Type = Fcb->NodeType;
308  if ((Type != NODE_TYPE_VCB && Type != NODE_TYPE_FCB) || (Fcb->NodeStatus != NODE_STATUS_HEALTHY && Fcb->NodeStatus != NODE_STATUS_CLEANUP))
309  {
310  *pFcb = 0;
312  return 0;
313  }
314 
315  ++Fcb->NodeReferences;
317 
318  return Type;
319 }
320 
321 VOID
323 {
325 }
326 
327 VOID
329 {
330  /* Just dereference and delete if no references left */
331  if (InterlockedDecrement(&Fcb->NodeReferences) == 0)
332  {
333  MupFreeNode(Fcb);
334  }
335 }
336 
337 VOID
339 {
340  /* Just dereference and delete (and clean) if no references left */
341  if (InterlockedDecrement(&Ccb->NodeReferences) == 0)
342  {
344  RemoveEntryList(&Ccb->CcbListEntry);
348  MupFreeNode(Ccb);
349  }
350 }
351 
352 VOID
354 {
355  /* We cannot reach the point where no references are left */
356  if (InterlockedDecrement(&Vcb->NodeReferences) == 0)
357  {
358  KeBugCheckEx(FILE_SYSTEM, 3, 0, 0, 0);
359  }
360 }
361 
362 NTSTATUS
364  PNTSTATUS NewStatus)
365 {
366  PIRP Irp;
369 
371 
372  if (NewStatus != NULL)
373  {
374  /* Save last status, depending on whether it failed or not */
375  if (!NT_SUCCESS(*NewStatus))
376  {
377  MasterIoContext->LastFailed = *NewStatus;
378  }
379  else
380  {
381  MasterIoContext->LastSuccess = STATUS_SUCCESS;
382  }
383  }
384 
385  if (InterlockedDecrement(&MasterIoContext->NodeReferences) != 0)
386  {
387  return STATUS_PENDING;
388  }
389 
390  Irp = MasterIoContext->Irp;
392  if (Stack->MajorFunction == IRP_MJ_WRITE)
393  {
394  Irp->IoStatus.Information = Stack->Parameters.Write.Length;
395  }
396  else
397  {
398  Irp->IoStatus.Information = 0;
399  }
400 
401  /* In case we never had any success (init is a failure), get the last failed status */
402  if (!NT_SUCCESS(MasterIoContext->LastSuccess))
403  {
404  Status = MasterIoContext->LastFailed;
405  }
406 
407  Irp->IoStatus.Status = Status;
409  MupDereferenceFcb(MasterIoContext->Fcb);
410  MupFreeNode(MasterIoContext);
411 
412  return Status;
413 }
414 
415 VOID
417 {
418  InterlockedExchangeAdd(&UncProvider->NodeReferences, -1);
419 }
420 
421 VOID
423 {
424  /* Just dereference and delete (and clean) if no references left */
425  if (InterlockedDecrement(&Prefix->NodeReferences) == 0)
426  {
427  if (Prefix->InTable)
428  {
429  RtlRemoveUnicodePrefix(&MupPrefixTable, &Prefix->PrefixTableEntry);
430  RemoveEntryList(&Prefix->PrefixListEntry);
431  }
432 
433  if (Prefix->ExternalAlloc && Prefix->AcceptedPrefix.Buffer != NULL)
434  {
435  ExFreePoolWithTag(Prefix->AcceptedPrefix.Buffer, TAG_MUP);
436  }
437 
438  if (Prefix->UncProvider)
439  {
440  MupDereferenceUncProvider(Prefix->UncProvider);
441  }
442 
444  }
445 }
446 
447 VOID
449 {
450  RtlRemoveUnicodePrefix(&MupPrefixTable, &Prefix->PrefixTableEntry);
451  RemoveEntryList(&Prefix->PrefixListEntry);
452  Prefix->InTable = FALSE;
454 }
455 
456 VOID
458 {
461 
462  /* Browse the prefix table */
464  for (Entry = MupPrefixList.Flink;
465  Entry != &MupPrefixList;
466  Entry = Entry->Flink)
467  {
468  Prefix = CONTAINING_RECORD(Entry, MUP_PFX, PrefixListEntry);
469 
470  /* And remove any entry in it */
471  if (Prefix->InTable)
472  {
474  }
475  }
477 }
478 
479 VOID
481  PIRP Irp,
482  PMUP_VCB Vcb)
483 {
485 
486  /* Check we're not doing anything wrong first */
487  if (Vcb->NodeStatus != NODE_STATUS_HEALTHY || Vcb->NodeType != NODE_TYPE_VCB)
488  {
490  }
491 
492  /* Remove share access */
494 
496 }
497 
498 VOID
500  PIRP Irp,
501  PMUP_FCB Fcb)
502 {
504  PMUP_CCB Ccb;
505 
507  /* Check we're not doing anything wrong first */
508  if (Fcb->NodeStatus != NODE_STATUS_HEALTHY || Fcb->NodeType != NODE_TYPE_FCB)
509  {
511  }
512  Fcb->NodeStatus = NODE_STATUS_CLEANUP;
514 
515  /* Dereference any CCB associated with the FCB */
517  for (Entry = Fcb->CcbList.Flink;
518  Entry != &Fcb->CcbList;
519  Entry = Entry->Flink)
520  {
521  Ccb = CONTAINING_RECORD(Entry, MUP_CCB, CcbListEntry);
525  }
527 }
528 
529 NTSTATUS
531  PIRP Irp,
532  PFORWARDED_IO_CONTEXT FwdCtxt)
533 {
535 
536  Status = Irp->IoStatus.Status;
537 
538  /* Just free everything we had allocated */
539  if (Irp->MdlAddress != NULL)
540  {
541  MmUnlockPages(Irp->MdlAddress);
542  IoFreeMdl(Irp->MdlAddress);
543  }
544 
545  if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
546  {
547  ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, TAG_MUP);
548  }
549 
550  IoFreeIrp(Irp);
551 
552  /* Dereference the master context
553  * The upper IRP will be completed once all the lower IRPs are done
554  * (and thus, references count reaches 0)
555  */
556  MupDereferenceCcb(FwdCtxt->Ccb);
558  ExFreePoolWithTag(FwdCtxt, TAG_MUP);
559 
561 }
562 
563 VOID
564 NTAPI
566 {
568 
570 }
571 
572 NTSTATUS
573 NTAPI
575  PIRP Irp,
576  PVOID Context)
577 {
578  PFORWARDED_IO_CONTEXT FwdCtxt;
579 
580  /* If we're at DISPATCH_LEVEL, we cannot complete, defer completion */
582  {
584  }
585  else
586  {
587  FwdCtxt = (PFORWARDED_IO_CONTEXT)Context;
588 
591  }
592 
594 }
595 
596 NTSTATUS
598  PMUP_CCB Ccb,
599  PMUP_MIC MasterIoContext)
600 {
601  PMDL Mdl;
602  PIRP LowerIrp;
606  PFORWARDED_IO_CONTEXT FwdCtxt;
607 
609  LowerIrp = NULL;
610  Mdl = NULL;
611 
612  /* Allocate a context for the completion routine */
614  if (FwdCtxt == NULL)
615  {
617  goto Cleanup;
618  }
619 
620  /* Init it */
621  FwdCtxt->DeviceObject = NULL;
622  FwdCtxt->Irp = NULL;
623 
624  /* Allocate the IRP */
626  LowerIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
627  if (LowerIrp == NULL)
628  {
630  goto Cleanup;
631  }
632 
633  /* Initialize it */
634  LowerIrp->Tail.Overlay.OriginalFileObject = Ccb->FileObject;
635  LowerIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
636  LowerIrp->RequestorMode = KernelMode;
637 
638  /* Copy the stack of the request we received to the IRP we'll pass below */
639  Stack = IoGetNextIrpStackLocation(LowerIrp);
641  Stack->FileObject = Ccb->FileObject;
642  /* Setup flags according to the FO */
643  if (Ccb->FileObject->Flags & FO_WRITE_THROUGH)
644  {
645  Stack->Flags = SL_WRITE_THROUGH;
646  }
647 
648  _SEH2_TRY
649  {
650  /* Does the device requires we do buffered IOs? */
651  if (DeviceObject->Flags & DO_BUFFERED_IO)
652  {
653  LowerIrp->AssociatedIrp.SystemBuffer = NULL;
654 
655  if (Stack->Parameters.Write.Length == 0)
656  {
657  LowerIrp->Flags = IRP_BUFFERED_IO;
658  }
659  /* If we have data to pass */
660  else
661  {
662  /* If it's coming from usermode, probe first */
663  if (Irp->RequestorMode == UserMode)
664  {
665  ProbeForRead(Irp->UserBuffer, Stack->Parameters.Write.Length, sizeof(UCHAR));
666  }
667 
668  /* Allocate the buffer */
669  LowerIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPoolCacheAligned,
670  Stack->Parameters.Write.Length,
671  TAG_MUP);
672  if (LowerIrp->AssociatedIrp.SystemBuffer == NULL)
673  {
675  }
676 
677  /* And copy input (remember, we've to free!) */
678  RtlMoveMemory(LowerIrp->AssociatedIrp.SystemBuffer, Irp->UserBuffer, Stack->Parameters.Write.Length);
679  LowerIrp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
680  }
681  }
682  else
683  {
684  if (!(DeviceObject->Flags & DO_DIRECT_IO))
685  {
686  LowerIrp->UserBuffer = Irp->UserBuffer;
687  }
688  else
689  {
690  /* For direct IOs, allocate an MDL and pass it */
691  if (Stack->Parameters.Write.Length != 0)
692  {
693  Mdl = IoAllocateMdl(Irp->UserBuffer, Stack->Parameters.Write.Length, FALSE, TRUE, LowerIrp);
694  if (Mdl == NULL)
695  {
697  }
698 
699  MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoReadAccess);
700  }
701  }
702  }
703 
704  /* Fix flags in the IRP */
706  {
707  LowerIrp->Flags |= IRP_WRITE_OPERATION | IRP_NOCACHE;
708  }
709  else
710  {
711  LowerIrp->Flags |= IRP_WRITE_OPERATION;
712  }
713 
714  FwdCtxt->Ccb = Ccb;
715  FwdCtxt->MasterIoContext = MasterIoContext;
716 
718  ++MasterIoContext->NodeReferences;
720 
721  /* Set out completion routine */
723  /* And call the device with our brand new IRP */
724  Status = IoCallDriver(Ccb->DeviceObject, LowerIrp);
725  }
727  {
729  }
730  _SEH2_END;
731 
732 Cleanup:
733  if (!NT_SUCCESS(Status))
734  {
735  if (FwdCtxt != NULL)
736  {
737  ExFreePoolWithTag(FwdCtxt, TAG_MUP);
738  }
739 
740  if (LowerIrp != NULL)
741  {
742  if (LowerIrp->AssociatedIrp.SystemBuffer == NULL)
743  {
744  ExFreePoolWithTag(LowerIrp->AssociatedIrp.SystemBuffer, TAG_MUP);
745  }
746 
747  IoFreeIrp(LowerIrp);
748  }
749 
750  if (Mdl != NULL)
751  {
752  IoFreeMdl(Mdl);
753  }
754  }
755 
756  return Status;
757 }
758 
759 NTSTATUS
760 NTAPI
762  PIRP Irp)
763 {
764  PMUP_FCB Fcb;
765  PMUP_CCB Ccb;
768  PMUP_CCB FcbListCcb;
769  BOOLEAN CcbLockAcquired;
770  PMUP_MIC MasterIoContext;
772 
773  /* If DFS is enabled, check if that's for DFS and is so relay */
774  if (MupEnableDfs && DeviceObject->DeviceType == FILE_DEVICE_DFS)
775  {
777  }
778 
780 
782 
783  /* Write request is only possible for a mailslot, we need a FCB */
784  MupDecodeFileObject(Stack->FileObject, &Fcb, &Ccb);
785  if (Fcb == NULL || Fcb->NodeType != NODE_TYPE_FCB)
786  {
789  goto Complete;
790  }
791 
792  /* Allocate a context */
793  MasterIoContext = MupAllocateMasterIoContext();
794  if (MasterIoContext == NULL)
795  {
798  goto Complete;
799  }
800 
801  /* Mark the IRP pending and init the context */
803  MasterIoContext->Irp = Irp;
804  /* Init with a failure to catch if we ever succeed */
805  MasterIoContext->LastSuccess = STATUS_UNSUCCESSFUL;
806  /* Init with the worth failure possible */
807  MasterIoContext->LastFailed = STATUS_BAD_NETWORK_PATH;
808  MasterIoContext->Fcb = Fcb;
809 
810  _SEH2_TRY
811  {
813  CcbLockAcquired = TRUE;
814 
815  /* For all the CCB (ie, the mailslots) we have */
816  for (Entry = Fcb->CcbList.Flink;
817  Entry != &Fcb->CcbList;
818  Entry = Entry->Flink)
819  {
820  FcbListCcb = CONTAINING_RECORD(Entry, MUP_CCB, CcbListEntry);
822  CcbLockAcquired = FALSE;
823 
825  ++FcbListCcb->NodeReferences;
827 
828  /* Forward the write request */
829  BuildAndSubmitIrp(Irp, FcbListCcb, MasterIoContext);
831  CcbLockAcquired = TRUE;
832  }
833 
835  CcbLockAcquired = FALSE;
836  }
838  {
839  if (CcbLockAcquired)
840  {
842  }
843  }
844  _SEH2_END;
845 
846  /* And done */
847  MupDereferenceMasterIoContext(MasterIoContext, NULL);
849 
850  return STATUS_PENDING;
851 
852 Complete:
853  /* Failure case */
854  Irp->IoStatus.Status = Status;
856  return Status;
857 }
858 
859 PMUP_UNC
861  ULONG ProviderOrder)
862 {
863  PMUP_UNC UncProvider;
864  ULONG StrLen, NameLen;
865 
866  /* Just allocate the node */
867  NameLen = wcslen(DeviceName);
868  StrLen = NameLen * sizeof(WCHAR);
869  UncProvider = MupAllocateUncProvider(StrLen);
870  if (UncProvider == NULL)
871  {
872  return NULL;
873  }
874 
875  /* And init it */
876  UncProvider->DeviceName.MaximumLength = StrLen;
877  UncProvider->DeviceName.Length = StrLen;
878  UncProvider->DeviceName.Buffer = (PWSTR)((ULONG_PTR)UncProvider + sizeof(MUP_UNC));
879  UncProvider->ProviderOrder = ProviderOrder;
880  RtlMoveMemory(UncProvider->DeviceName.Buffer, DeviceName, StrLen);
881 
882  /* And add it to the global list
883  * We're using tail here so that when called from registry init,
884  * the providers with highest priority will be in the head of
885  * the list
886  */
888  InsertTailList(&MupProviderList, &UncProvider->ProviderListEntry);
890 
891  return UncProvider;
892 }
893 
894 VOID
896  ULONG ProviderOrder)
897 {
903  ULONG NameLen, StrLen, ResultLength;
904 
905  /* Get the information about the provider from registry */
906  NameLen = wcslen(ProviderName);
907  StrLen = NameLen * sizeof(WCHAR) + sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") + sizeof(L"\\NetworkProvider");
908  Key.Buffer = ExAllocatePoolWithTag(PagedPool, StrLen, TAG_MUP);
909  if (Key.Buffer == NULL)
910  {
911  return;
912  }
913 
914  RtlMoveMemory(Key.Buffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"));
915  Key.MaximumLength = StrLen;
916  Key.Length = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") - sizeof(UNICODE_NULL);
917  RtlAppendUnicodeToString(&Key, ProviderName);
918  RtlAppendUnicodeToString(&Key, L"\\NetworkProvider");
919 
921  &Key,
923  NULL,
924  NULL);
926  ExFreePoolWithTag(Key.Buffer, TAG_MUP);
927  if (!NT_SUCCESS(Status))
928  {
929  return;
930  }
931 
932  RtlInitUnicodeString(&Value, L"DeviceName");
933  Status = ZwQueryValueKey(KeyHandle, &Value, KeyValueFullInformation, NULL, 0, &ResultLength);
935  {
937  if (Info == NULL)
938  {
940  return;
941  }
942 
944  }
945  else
946  {
947  Info = NULL;
948  }
949 
951 
952  /* And create the provider
953  * It will remain unregistered until FsRTL receives a registration request and forwards
954  * it to MUP
955  */
956  if (NT_SUCCESS(Status))
957  {
958  ASSERT(Info != NULL);
959  AddUnregisteredProvider((PWSTR)((ULONG_PTR)Info + Info->DataOffset), ProviderOrder);
960  }
961 
962  if (Info != NULL)
963  {
965  }
966 }
967 
968 VOID
970 {
971  BOOLEAN End;
974  PWSTR Providers, Coma;
976  ULONG ResultLength, ProviderCount;
978  UNICODE_STRING NetworkProvider, ProviderOrder;
979 
980  /* Open the registry to get the order of the providers */
981  RtlInitUnicodeString(&NetworkProvider, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\NetworkProvider\\Order");
983  &NetworkProvider,
985  NULL,
986  NULL);
988  if (!NT_SUCCESS(Status))
989  {
990  return;
991  }
992 
993  RtlInitUnicodeString(&ProviderOrder, L"ProviderOrder");
994  Status = ZwQueryValueKey(KeyHandle, &ProviderOrder, KeyValueFullInformation, NULL, 0, &ResultLength);
996  {
998  if (Info == NULL)
999  {
1000  ZwClose(KeyHandle);
1001  return;
1002  }
1003 
1004  Status = ZwQueryValueKey(KeyHandle, &ProviderOrder, KeyValueFullInformation, Info, ResultLength, &ResultLength);
1005  }
1006  else
1007  {
1008  Info = NULL;
1009  }
1010 
1011  ZwClose(KeyHandle);
1012 
1013  if (NT_SUCCESS(Status))
1014  {
1015  ASSERT(Info != NULL);
1016 
1017  Providers = (PWSTR)((ULONG_PTR)Info + Info->DataOffset);
1018  End = FALSE;
1019  ProviderCount = 0;
1020 
1021  /* For all the providers we got (coma-separated list), just create a provider node with the right order
1022  * The order is just the order of the list
1023  * First has highest priority (0) and then, get lower and lower priority
1024  * The highest number is the lowest priority
1025  */
1026  do
1027  {
1028  Coma = wcschr(Providers, L',');
1029  if (Coma != NULL)
1030  {
1031  *Coma = UNICODE_NULL;
1032  }
1033  else
1034  {
1035  End = TRUE;
1036  }
1037 
1038  InitializeProvider(Providers, ProviderCount);
1039  ++ProviderCount;
1040 
1041  Providers = Coma + 1;
1042  } while (!End);
1043  }
1044 
1045  if (Info != NULL)
1046  {
1048  }
1049 }
1050 
1051 PMUP_UNC
1053 {
1055  PMUP_UNC UncProvider;
1056 
1057  /* Browse the list of all the providers nodes we have */
1059  for (Entry = MupProviderList.Flink; Entry != &MupProviderList; Entry = Entry->Flink)
1060  {
1061  UncProvider = CONTAINING_RECORD(Entry, MUP_UNC, ProviderListEntry);
1062 
1063  /* If one matches the device and is not registered, that's ours! */
1064  if (!UncProvider->Registered && RtlEqualUnicodeString(RedirectorDeviceName, &UncProvider->DeviceName, TRUE))
1065  {
1066  UncProvider->NodeStatus = NODE_STATUS_HEALTHY;
1067  break;
1068  }
1069  }
1070 
1071  if (Entry == &MupProviderList)
1072  {
1073  UncProvider = NULL;
1074  }
1076 
1077  return UncProvider;
1078 }
1079 
1080 NTSTATUS
1082  PIRP Irp)
1083 
1084 {
1085  BOOLEAN New;
1086  PMUP_FCB Fcb;
1087  PMUP_CCB Ccb;
1088  NTSTATUS Status;
1092  PMUP_UNC UncProvider, ListEntry;
1095  OBJECT_HANDLE_INFORMATION HandleInfo;
1097 
1098  DPRINT1("RegisterUncProvider(%p, %p)\n", DeviceObject, Irp);
1099  New = FALSE;
1100 
1101  /* Check whether providers order was already initialized */
1103  if (MupOrderInitialized)
1104  {
1106  }
1107  else
1108  {
1109  /* They weren't, so do it */
1113  }
1114 
1116 
1117  /* This can only happen with a volume open */
1118  if (MupDecodeFileObject(Stack->FileObject, &Fcb, &Ccb) != NODE_TYPE_VCB)
1119  {
1120  Irp->IoStatus.Status = STATUS_INVALID_HANDLE;
1122 
1123  return STATUS_INVALID_HANDLE;
1124  }
1125 
1126  /* Get the registration information */
1127  RegInfo = (PMUP_PROVIDER_REGISTRATION_INFO)Irp->AssociatedIrp.SystemBuffer;
1128  _SEH2_TRY
1129  {
1133 
1134  /* Have we got already a node for it? (Like from previous init) */
1136  if (UncProvider == NULL)
1137  {
1138  /* If we don't, allocate a new one */
1139  New = TRUE;
1140  UncProvider = MupAllocateUncProvider(RegInfo->RedirectorDeviceNameLength);
1141  if (UncProvider == NULL)
1142  {
1144  _SEH2_LEAVE;
1145  }
1146 
1147  /* Set it up */
1150  UncProvider->DeviceName.Buffer = (PWSTR)((ULONG_PTR)UncProvider + sizeof(MUP_UNC));
1151 
1152  /* As it wasn't in registry for order, give the lowest priority possible */
1153  UncProvider->ProviderOrder = MAXLONG;
1155  }
1156 
1157  /* Continue registration */
1158  UncProvider->MailslotsSupported = RegInfo->MailslotsSupported;
1159  ++UncProvider->NodeReferences;
1160 
1161  /* Open a handle to the device */
1163  &UncProvider->DeviceName,
1165  NULL,
1166  NULL);
1167  Status = NtOpenFile(&UncProvider->DeviceHandle,
1168  FILE_TRAVERSE,
1170  &IoStatusBlock,
1173  if (NT_SUCCESS(Status))
1174  {
1176  }
1177 
1178  /* And return the provider (as CCB) */
1179  if (NT_SUCCESS(Status))
1180  {
1181  Stack->FileObject->FsContext2 = UncProvider;
1182  Status = ObReferenceObjectByHandle(UncProvider->DeviceHandle, 0, NULL, KernelMode, (PVOID *)&UncProvider->FileObject, &HandleInfo);
1183  if (!NT_SUCCESS(Status))
1184  {
1185  NtClose(UncProvider->DeviceHandle);
1186  }
1187  }
1188 
1189  if (!NT_SUCCESS(Status))
1190  {
1191  MupDereferenceUncProvider(UncProvider);
1192  }
1193  else
1194  {
1195  UncProvider->DeviceObject = IoGetRelatedDeviceObject(UncProvider->FileObject);
1196 
1197  /* Now, insert the provider in our global list
1198  * They are sorted by order
1199  */
1201  ++MupProviderCount;
1202  if (New)
1203  {
1204  for (Entry = MupProviderList.Flink; Entry != &MupProviderList; Entry = Entry->Flink)
1205  {
1206  ListEntry = CONTAINING_RECORD(Entry, MUP_UNC, ProviderListEntry);
1207 
1208  if (UncProvider->ProviderOrder < ListEntry->ProviderOrder)
1209  {
1210  break;
1211  }
1212  }
1213 
1214  InsertTailList(Entry, &UncProvider->ProviderListEntry);
1215  }
1216  UncProvider->Registered = TRUE;
1219 
1220  DPRINT1("UNC provider %wZ registered\n", &UncProvider->DeviceName);
1221  }
1222  }
1224  {
1226  {
1228  }
1229 
1231 
1232  Irp->IoStatus.Status = Status;
1234  }
1235  _SEH2_END;
1236 
1237  return Status;
1238 }
1239 
1240 NTSTATUS
1241 NTAPI
1243  PIRP Irp)
1244 {
1245  NTSTATUS Status;
1247 
1249 
1250  _SEH2_TRY
1251  {
1252  /* MUP only understands a single FSCTL code: registering UNC provider */
1253  if (Stack->Parameters.FileSystemControl.FsControlCode == FSCTL_MUP_REGISTER_PROVIDER)
1254  {
1255  /* It obviously has to come from a driver/kernelmode thread */
1256  if (Irp->RequestorMode == UserMode)
1257  {
1259 
1260  Irp->IoStatus.Status = Status;
1262 
1263  _SEH2_LEAVE;
1264  }
1265 
1267  }
1268  else
1269  {
1270  /* If that's an unknown FSCTL code, maybe it's for DFS, pass it */
1271  if (!MupEnableDfs)
1272  {
1274 
1275  Irp->IoStatus.Status = Status;
1277 
1278  _SEH2_LEAVE;
1279  }
1280 
1282  }
1283  }
1285  {
1287  }
1288  _SEH2_END;
1289 
1290  return Status;
1291 }
1292 
1293 VOID
1295  PMUP_FCB Fcb,
1296  PMUP_CCB Ccb)
1297 {
1298  FileObject->FsContext = Fcb;
1299  FileObject->FsContext2 = Ccb;
1300 }
1301 
1302 NTSTATUS
1304  PMUP_UNC UncProvider)
1305 {
1306  PWSTR FullPath;
1308 
1309  DPRINT1("Rerouting %wZ with %wZ\n", &FileObject->FileName, &UncProvider->DeviceName);
1310 
1311  /* Get the full path name (device name first, and requested file name appended) */
1312  TotalLength = UncProvider->DeviceName.Length + FileObject->FileName.Length;
1313  if (TotalLength > MAXUSHORT)
1314  {
1315  return STATUS_NAME_TOO_LONG;
1316  }
1317 
1318  /* Allocate a buffer big enough */
1320  if (FullPath == NULL)
1321  {
1323  }
1324 
1325  /* Create the full path */
1326  RtlMoveMemory(FullPath, UncProvider->DeviceName.Buffer, UncProvider->DeviceName.Length);
1327  RtlMoveMemory((PWSTR)((ULONG_PTR)FullPath + UncProvider->DeviceName.Length), FileObject->FileName.Buffer, FileObject->FileName.Length);
1328 
1329  /* And redo the path in the file object */
1330  ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1331  FileObject->FileName.Buffer = FullPath;
1332  FileObject->FileName.MaximumLength = TotalLength;
1333  FileObject->FileName.Length = FileObject->FileName.MaximumLength;
1334 
1335  /* Ob, please reparse to open the correct file at the right place, thanks! :-) */
1336  return STATUS_REPARSE;
1337 }
1338 
1339 NTSTATUS
1341 {
1342  PMUP_FCB Fcb;
1343  HANDLE Handle;
1345  PMUP_CCB Ccb = NULL;
1346  PMUP_UNC UncProvider;
1347  UNICODE_STRING FullPath;
1350  NTSTATUS Status, LastFailed;
1351  ULONG TotalLength, LastOrder;
1354  OBJECT_HANDLE_INFORMATION HandleInfo;
1355  BOOLEAN Locked, Referenced, CcbInitialized;
1356 
1357  Fcb = MupCreateFcb();
1358  if (Fcb == NULL)
1359  {
1361  }
1362 
1364  FileObject = Stack->FileObject;
1365  Locked = FALSE;
1366  Referenced = FALSE;
1367  CcbInitialized = FALSE;
1368  LastFailed = STATUS_NO_SUCH_FILE;
1369  LastOrder = (ULONG)-1;
1370 
1371  _SEH2_TRY
1372  {
1374  Locked = TRUE;
1375 
1376  /* Associate our FCB with the FO */
1379 
1380  /* Now, broadcast the open to any UNC provider that supports mailslots */
1381  for (Entry = MupProviderList.Flink; Entry != &MupProviderList; Entry = Entry->Flink)
1382  {
1383  UncProvider = CONTAINING_RECORD(Entry, MUP_UNC, ProviderListEntry);
1384  ++UncProvider->NodeReferences;
1385  Referenced = TRUE;
1386 
1388  Locked = FALSE;
1389 
1390  TotalLength = UncProvider->DeviceName.Length + FileObject->FileName.Length;
1391  if (UncProvider->MailslotsSupported && TotalLength <= MAXUSHORT)
1392  {
1393  /* Provide the correct name for the mailslot (ie, happened the device name of the provider) */
1395  if (FullPath.Buffer == NULL)
1396  {
1398  }
1399 
1400  FullPath.Length = TotalLength;
1401  FullPath.MaximumLength = TotalLength;
1402  RtlMoveMemory(FullPath.Buffer, UncProvider->DeviceName.Buffer, UncProvider->DeviceName.Length);
1403  RtlMoveMemory((PWSTR)((ULONG_PTR)FullPath.Buffer + UncProvider->DeviceName.Length),
1404  FileObject->FileName.Buffer,
1405  FileObject->FileName.Length);
1406 
1407  /* And just forward the creation request */
1409  &FullPath,
1411  NULL,
1412  NULL);
1414  Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_SIMPLE_RIGHTS_MASK,
1416  &IoStatusBlock,
1417  NULL,
1418  Stack->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS,
1419  Stack->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS,
1420  FILE_OPEN,
1421  Stack->Parameters.Create.Options & FILE_VALID_SET_FLAGS,
1422  NULL,
1423  0,
1425  NULL,
1427 
1428  ExFreePoolWithTag(FullPath.Buffer, TAG_MUP);
1429 
1430  /* If opening succeed */
1431  if (NT_SUCCESS(Status))
1432  {
1434 
1435  /* Create a CCB */
1436  Ccb = MupCreateCcb();
1437  if (Ccb == NULL)
1438  {
1440  }
1441 
1442  /* And associated a FO to it */
1443  if (NT_SUCCESS(Status))
1444  {
1445  Status = ObReferenceObjectByHandle(Handle, 0, 0, 0, (PVOID *)&Ccb->FileObject, &HandleInfo);
1446  ZwClose(Handle);
1447  }
1448  }
1449 
1450  /* If we failed, remember the last failed status of the higher priority provider */
1451  if (!NT_SUCCESS(Status))
1452  {
1453  if (UncProvider->ProviderOrder <= LastOrder)
1454  {
1455  LastOrder = UncProvider->ProviderOrder;
1456  LastFailed = Status;
1457  }
1458  }
1459  /* Otherwise, properly attach our CCB to the mailslot */
1460  else
1461  {
1462  Ccb->DeviceObject = IoGetRelatedDeviceObject(Ccb->FileObject);
1463  Ccb->Fcb = Fcb;
1464 
1466  Locked = TRUE;
1467  ++Fcb->NodeReferences;
1469  Locked = FALSE;
1470  CcbInitialized = TRUE;
1471 
1472  InsertTailList(&Fcb->CcbList, &Ccb->CcbListEntry);
1473  }
1474  }
1475 
1477  Locked = TRUE;
1478  MupDereferenceUncProvider(UncProvider);
1479  Referenced = FALSE;
1480  }
1481 
1483  Locked = FALSE;
1484  }
1486  {
1488  }
1489  _SEH2_END;
1490 
1491  /* If we at least opened one mailslot, return success */
1492  Status = (CcbInitialized ? STATUS_SUCCESS : LastFailed);
1493 
1494  if (Referenced)
1495  {
1496  MupDereferenceUncProvider(UncProvider);
1497  }
1498 
1499  if (Locked)
1500  {
1502  }
1503 
1504  /* In case of failure, don't leak CCB */
1505  if (!NT_SUCCESS(Status) && Ccb != NULL)
1506  {
1507  MupFreeNode(Ccb);
1508  }
1509 
1510  return Status;
1511 }
1512 
1513 PIRP
1515  PVOID Context,
1517  ULONG IoctlCode,
1519  ULONG InputBufferSize,
1521  ULONG OutputBufferSize,
1523 {
1524  PIRP Irp;
1527 
1528  if (InputBuffer == NULL)
1529  {
1530  return NULL;
1531  }
1532 
1533  /* Get the device object */
1535  /* Allocate the IRP (with one more location for us */
1536  Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);
1537  if (Irp == NULL)
1538  {
1539  return NULL;
1540  }
1541 
1542  /* Skip our location */
1544  /* Setup the IRP */
1545  Irp->Tail.Overlay.OriginalFileObject = FileObject;
1546  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1548 
1549  /* Setup the stack */
1551  Stack->MajorFunction = MajorFunction;
1552  Stack->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferSize;
1553  Stack->Parameters.DeviceIoControl.InputBufferLength = InputBufferSize;
1554  Stack->Parameters.DeviceIoControl.IoControlCode = IoctlCode;
1555  Stack->MinorFunction = 0;
1556  Stack->FileObject = FileObject;
1557  Stack->DeviceObject = DeviceObject;
1558 
1560  {
1561  case METHOD_BUFFERED:
1562  /* If it's buffered, just pass the buffers we got */
1563  Irp->MdlAddress = NULL;
1564  Irp->AssociatedIrp.SystemBuffer = InputBuffer;
1565  Irp->UserBuffer = OutputBuffer;
1566  Irp->Flags = IRP_BUFFERED_IO;
1567 
1568  if (OutputBuffer != NULL)
1569  {
1570  Irp->Flags |= IRP_INPUT_OPERATION;
1571  }
1572  break;
1573 
1574  case METHOD_IN_DIRECT:
1575  case METHOD_OUT_DIRECT:
1576  /* Otherwise, allocate an MDL */
1577  if (IoAllocateMdl(InputBuffer, InputBufferSize, FALSE, FALSE, Irp) == NULL)
1578  {
1579  IoFreeIrp(Irp);
1580  return NULL;
1581  }
1582 
1583  Irp->AssociatedIrp.SystemBuffer = InputBuffer;
1584  Irp->Flags = IRP_BUFFERED_IO;
1586  break;
1587 
1588  case METHOD_NEITHER:
1589  /* Or pass the buffers */
1590  Irp->UserBuffer = OutputBuffer;
1591  Irp->MdlAddress = NULL;
1592  Irp->AssociatedIrp.SystemBuffer = NULL;
1593  Stack->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
1594  break;
1595  }
1596 
1597  return Irp;
1598 }
1599 
1600 VOID
1602 {
1603  ExDeleteResourceLite(&MasterQueryContext->QueryPathListLock);
1604  ExFreePoolWithTag(MasterQueryContext, TAG_MUP);
1605 }
1606 
1607 NTSTATUS
1609 {
1610  LONG References;
1611  NTSTATUS Status;
1612  BOOLEAN KeepExtraRef;
1613 
1615  --MasterQueryContext->NodeReferences;
1616  References = MasterQueryContext->NodeReferences;
1618 
1619  if (References != 0)
1620  {
1621  DPRINT("Still having refs (%ld)\n", References);
1622  return STATUS_PENDING;
1623  }
1624 
1625  /* We HAVE an IRP to complete. It cannot be NULL
1626  * Please, help preserving kittens, don't provide NULL IRPs.
1627  */
1628  if (MasterQueryContext->Irp == NULL)
1629  {
1631  }
1632 
1634  RemoveEntryList(&MasterQueryContext->MQCListEntry);
1636 
1638  KeepExtraRef = MasterQueryContext->Prefix->KeepExtraRef;
1639  MupDereferenceKnownPrefix(MasterQueryContext->Prefix);
1640 
1641  /* We found a provider? */
1642  if (MasterQueryContext->LatestProvider != NULL)
1643  {
1644  /* With a successful status? */
1645  if (MasterQueryContext->LatestStatus == STATUS_SUCCESS)
1646  {
1647  /* Then, it's time to reroute, someone accepted to handle the file creation request! */
1648  if (!KeepExtraRef)
1649  {
1650  MupDereferenceKnownPrefix(MasterQueryContext->Prefix);
1651  }
1652 
1654  /* Reroute & complete :-) */
1655  Status = MupRerouteOpen(MasterQueryContext->FileObject, MasterQueryContext->LatestProvider);
1656  goto Complete;
1657  }
1658  else
1659  {
1660  MupDereferenceUncProvider(MasterQueryContext->LatestProvider);
1661  }
1662  }
1663 
1664  MupDereferenceKnownPrefix(MasterQueryContext->Prefix);
1666 
1667  /* Return the highest failed status we had */
1668  Status = MasterQueryContext->LatestStatus;
1669 
1670 Complete:
1671  /* In finally, complete the IRP for real! */
1672  MasterQueryContext->Irp->IoStatus.Status = Status;
1673  IoCompleteRequest(MasterQueryContext->Irp, IO_DISK_INCREMENT);
1674 
1675  MasterQueryContext->Irp = NULL;
1676  MupFreeMasterQueryContext(MasterQueryContext);
1677 
1678  return Status;
1679 }
1680 
1681 NTSTATUS
1682 NTAPI
1684  PIRP Irp,
1685  PVOID Context)
1686 {
1687  PMUP_PFX Prefix;
1688  ULONG LatestPos, Pos;
1689  PWSTR AcceptedPrefix;
1690  PMUP_MQC MasterQueryContext;
1691  NTSTATUS Status, TableStatus;
1692  PQUERY_PATH_CONTEXT QueryContext;
1693  PQUERY_PATH_RESPONSE QueryResponse;
1694 
1695  /* Get all the data from our query to the provider */
1696  QueryContext = (PQUERY_PATH_CONTEXT)Context;
1697  QueryResponse = (PQUERY_PATH_RESPONSE)QueryContext->QueryPathRequest;
1698  MasterQueryContext = QueryContext->MasterQueryContext;
1699  Status = Irp->IoStatus.Status;
1700 
1701  DPRINT("Reply from %wZ: %u (Status: %lx)\n", &QueryContext->UncProvider->DeviceName, QueryResponse->LengthAccepted, Status);
1702 
1703  ExAcquireResourceExclusiveLite(&MasterQueryContext->QueryPathListLock, TRUE);
1704  RemoveEntryList(&QueryContext->QueryPathListEntry);
1705 
1706  /* If the driver returned a success, and an acceptance length */
1707  if (NT_SUCCESS(Status) && QueryResponse->LengthAccepted > 0)
1708  {
1709  Prefix = MasterQueryContext->Prefix;
1710 
1711  /* Check if we already found a provider from a previous iteration */
1712  if (MasterQueryContext->LatestProvider != NULL)
1713  {
1714  /* If the current provider has a lower priority (ie, a greater order), then, bailout and keep previous one */
1715  if (QueryContext->UncProvider->ProviderOrder >= MasterQueryContext->LatestProvider->ProviderOrder)
1716  {
1717  MupDereferenceUncProvider(QueryContext->UncProvider);
1718  goto Cleanup;
1719  }
1720 
1721  /* Otherwise, if the prefix was in the prefix table, just drop it:
1722  * we have a provider which supersedes the accepted prefix, so leave
1723  * room for the new prefix/provider
1724  */
1726  if (Prefix->InTable)
1727  {
1728  RtlRemoveUnicodePrefix(&MupPrefixTable, &Prefix->PrefixTableEntry);
1729  RemoveEntryList(&Prefix->PrefixListEntry);
1730  Prefix->InTable = FALSE;
1731  }
1733 
1734  Prefix->KeepExtraRef = FALSE;
1735 
1736  /* Release data associated with the current prefix, if any
1737  * We'll renew them with the new accepted prefix
1738  */
1739  if (Prefix->AcceptedPrefix.Length != 0 && Prefix->AcceptedPrefix.Buffer != NULL)
1740  {
1741  ExFreePoolWithTag(Prefix->AcceptedPrefix.Buffer, TAG_MUP);
1742  Prefix->AcceptedPrefix.MaximumLength = 0;
1743  Prefix->AcceptedPrefix.Length = 0;
1744  Prefix->AcceptedPrefix.Buffer = NULL;
1745  Prefix->ExternalAlloc = FALSE;
1746  }
1747 
1748  /* If there was also a provider, drop it, the new one
1749  * is different
1750  */
1751  if (Prefix->UncProvider != NULL)
1752  {
1753  MupDereferenceUncProvider(Prefix->UncProvider);
1754  Prefix->UncProvider = NULL;
1755  }
1756  }
1757 
1758  /* Now, set our information about the provider that accepted the prefix */
1759  MasterQueryContext->LatestProvider = QueryContext->UncProvider;
1760  MasterQueryContext->LatestStatus = Status;
1761 
1762  if (MasterQueryContext->FileObject->FsContext2 != (PVOID)DFS_DOWNLEVEL_OPEN_CONTEXT)
1763  {
1764  /* Allocate a buffer for the prefix */
1765  AcceptedPrefix = ExAllocatePoolWithTag(PagedPool, QueryResponse->LengthAccepted, TAG_MUP);
1766  if (AcceptedPrefix == NULL)
1767  {
1768  Prefix->InTable = FALSE;
1769  }
1770  else
1771  {
1772  /* Set it up to the accepted length */
1773  RtlMoveMemory(AcceptedPrefix, MasterQueryContext->FileObject->FileName.Buffer, QueryResponse->LengthAccepted);
1774  Prefix->UncProvider = MasterQueryContext->LatestProvider;
1775  Prefix->AcceptedPrefix.Buffer = AcceptedPrefix;
1776  Prefix->AcceptedPrefix.Length = QueryResponse->LengthAccepted;
1777  Prefix->AcceptedPrefix.MaximumLength = QueryResponse->LengthAccepted;
1778  Prefix->ExternalAlloc = TRUE;
1779 
1780  /* Insert the accepted prefix in the table of known prefixes */
1781  DPRINT1("%wZ accepted %wZ\n", &Prefix->UncProvider->DeviceName, &Prefix->AcceptedPrefix);
1783  if (RtlInsertUnicodePrefix(&MupPrefixTable, &Prefix->AcceptedPrefix, &Prefix->PrefixTableEntry))
1784  {
1785  InsertHeadList(&MupPrefixList, &Prefix->PrefixListEntry);
1786  Prefix->InTable = TRUE;
1787  Prefix->KeepExtraRef = TRUE;
1788  }
1789  else
1790  {
1791  Prefix->InTable = FALSE;
1792  }
1794  }
1795  }
1796  }
1797  else
1798  {
1799  MupDereferenceUncProvider(QueryContext->UncProvider);
1800 
1801  /* We failed and didn't find any provider over the latest iterations */
1802  if (MasterQueryContext->LatestProvider == NULL)
1803  {
1804  /* If we had a success though (broken provider?) set our failed status */
1805  if (NT_SUCCESS(MasterQueryContext->LatestStatus))
1806  {
1807  MasterQueryContext->LatestStatus = Status;
1808  }
1809  else
1810  {
1811  TableStatus = MupOrderedErrorList[0];
1812  LatestPos = 0;
1813 
1814  /* Otherwise, time to compare statuses, between the latest failed
1815  * and the current failure.
1816  * We have an order table of failed status: the deeper you go in the
1817  * table, the more the error is critical.
1818  * Our goal is to return the most critical status that was returned by
1819  * any of the providers
1820  */
1821 
1822  /* Look for latest status position */
1823  while (TableStatus != 0 && TableStatus != MasterQueryContext->LatestStatus)
1824  {
1825  ++LatestPos;
1826  TableStatus = MupOrderedErrorList[LatestPos];
1827  }
1828 
1829  /* If at pos 0, the new status is likely more critical */
1830  if (LatestPos == 0)
1831  {
1832  MasterQueryContext->LatestStatus = Status;
1833  }
1834  else
1835  {
1836  /* Otherwise, find position of the new status in the table */
1837  Pos = 0;
1838  do
1839  {
1840  if (Status == MupOrderedErrorList[Pos])
1841  {
1842  break;
1843  }
1844 
1845  ++Pos;
1846  }
1847  while (Pos < LatestPos);
1848 
1849  /* If it has a higher position (more critical), return it */
1850  if (Pos >= LatestPos)
1851  {
1852  MasterQueryContext->LatestStatus = Status;
1853  }
1854  }
1855  }
1856  }
1857  }
1858 
1859 Cleanup:
1860  ExFreePoolWithTag(QueryResponse, TAG_MUP);
1861  ExFreePoolWithTag(QueryContext, TAG_MUP);
1862  IoFreeIrp(Irp);
1863 
1864  ExReleaseResourceLite(&MasterQueryContext->QueryPathListLock);
1865  MupDereferenceMasterQueryContext(MasterQueryContext);
1866 
1868 }
1869 
1870 NTSTATUS
1873  PIO_SECURITY_CONTEXT SecurityContext)
1874 {
1875  LONG Len;
1876  WCHAR Cur;
1877  PWSTR Name;
1878  PIRP QueryIrp;
1879  NTSTATUS Status;
1880  PMUP_PFX Prefix;
1882  PMUP_UNC UncProvider;
1884  LARGE_INTEGER CurrentTime;
1885  PMUP_MQC MasterQueryContext;
1886  PQUERY_PATH_CONTEXT QueryContext;
1887  PQUERY_PATH_REQUEST QueryPathRequest;
1889  BOOLEAN Locked, Referenced, BreakOnFirst;
1890 
1891  /* We cannot open a file without a name */
1892  if (FileObject->FileName.Length == 0)
1893  {
1894  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1896 
1898  }
1899 
1900  DPRINT1("Request for opening: %wZ\n", &FileObject->FileName);
1901 
1902  Referenced = FALSE;
1903  BreakOnFirst = TRUE;
1905 
1907  /* First, try to see if that's a prefix we already know */
1909  if (TableEntry != NULL)
1910  {
1912 
1913  DPRINT("Matching prefix found: %wZ\n", &Prefix->AcceptedPrefix);
1914 
1915  /* If so, check whether the prefix is still valid */
1916  KeQuerySystemTime(&CurrentTime);
1917  if (Prefix->ValidityTimeout.QuadPart < CurrentTime.QuadPart)
1918  {
1919  /* It is: so, update its validity period and reroute file opening */
1920  MupCalculateTimeout(&Prefix->ValidityTimeout);
1921  Status = MupRerouteOpen(FileObject, Prefix->UncProvider);
1923 
1924  if (Status == STATUS_REPARSE)
1925  {
1926  Irp->IoStatus.Information = FILE_SUPERSEDED;
1927  }
1928 
1929  Irp->IoStatus.Status = Status;
1931 
1932  return Status;
1933  }
1934 
1935  /* When here, we found a matching prefix, but expired, remove it from the table
1936  * We'll redo a full search
1937  */
1938  if (Prefix->InTable)
1939  {
1941  }
1942  }
1944 
1946  /* First of all, start looking for a mailslot */
1947  if (FileObject->FileName.Buffer[0] == L'\\' && Stack->MajorFunction != IRP_MJ_CREATE)
1948  {
1949  Name = &FileObject->FileName.Buffer[1];
1950  Len = FileObject->FileName.Length;
1951 
1952  /* Skip the remote destination name */
1953  do
1954  {
1955  Len -= sizeof(WCHAR);
1956  if (Len <= 0)
1957  {
1958  break;
1959  }
1960 
1961  Cur = *Name;
1962  ++Name;
1963  } while (Cur != L'\\');
1964  Len -= sizeof(WCHAR);
1965 
1966  /* If we still have room for "Mailslot" to fit */
1967  if (Len >= (sizeof(L"Mailslot") - sizeof(UNICODE_NULL)))
1968  {
1969  /* Get the len in terms of chars count */
1970  Len /= sizeof(WCHAR);
1971  if (Len > ((sizeof(L"Mailslot") - sizeof(UNICODE_NULL)) / sizeof(WCHAR)))
1972  {
1973  Len = (sizeof(L"Mailslot") - sizeof(UNICODE_NULL)) / sizeof(WCHAR);
1974  }
1975 
1976  /* It's indeed a mailslot opening! */
1977  if (_wcsnicmp(Name, L"Mailslot", Len) == 0)
1978  {
1979  /* Broadcast open */
1981  if (Status == STATUS_REPARSE)
1982  {
1983  Irp->IoStatus.Information = FILE_SUPERSEDED;
1984  }
1985 
1986  Irp->IoStatus.Status = Status;
1988 
1989  return Status;
1990  }
1991  }
1992  }
1993 
1994  /* Ok, at that point, that's a regular MUP opening (if no DFS) */
1995  if (!MupEnableDfs || FileObject->FsContext2 == (PVOID)DFS_DOWNLEVEL_OPEN_CONTEXT)
1996  {
1997  /* We won't complete immediately */
1999 
2000  /* Allocate a new prefix for our search */
2002  if (Prefix == NULL)
2003  {
2004  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2006 
2007  return STATUS_PENDING;
2008  }
2009 
2010  /* Allocate a context for our search */
2011  MasterQueryContext = MupAllocateMasterQueryContext();
2012  if (MasterQueryContext == NULL)
2013  {
2015 
2016  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2018 
2019  return STATUS_PENDING;
2020  }
2021 
2022  MasterQueryContext->Irp = Irp;
2023  MasterQueryContext->FileObject = FileObject;
2024  MasterQueryContext->LatestProvider = NULL;
2025  MasterQueryContext->Prefix = Prefix;
2026  MasterQueryContext->LatestStatus = STATUS_BAD_NETWORK_PATH;
2028  InsertTailList(&MupMasterQueryList, &MasterQueryContext->MQCListEntry);
2029  ++Prefix->NodeReferences;
2031 
2032  _SEH2_TRY
2033  {
2035  Locked = TRUE;
2036 
2037  /* Now, we will browse all the providers we know, to ask for their accepted prefix regarding the path */
2038  for (Entry = MupProviderList.Flink; Entry != &MupProviderList; Entry = Entry->Flink)
2039  {
2040  UncProvider = CONTAINING_RECORD(Entry, MUP_UNC, ProviderListEntry);
2041 
2042  ++UncProvider->NodeReferences;
2043  Referenced = TRUE;
2044 
2046  Locked = FALSE;
2047 
2048  /* We will obviously only query registered providers */
2049  if (UncProvider->Registered)
2050  {
2051  /* We will issue an IOCTL_REDIR_QUERY_PATH, so allocate input buffer */
2052  QueryPathRequest = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.Length + sizeof(QUERY_PATH_REQUEST), TAG_MUP);
2053  if (QueryPathRequest == NULL)
2054  {
2056  }
2057 
2058  /* Allocate a context for IRP completion routine
2059  * In case a prefix matches the path, the reroute will happen
2060  * in the completion routine, when we have return from the provider
2061  */
2062  QueryContext = ExAllocatePoolWithTag(PagedPool, sizeof(QUERY_PATH_CONTEXT), TAG_MUP);
2063  if (QueryContext == NULL)
2064  {
2065  ExFreePoolWithTag(QueryPathRequest, TAG_MUP);
2067  }
2068 
2069  InitializeListHead(&QueryContext->QueryPathListEntry);
2070  QueryContext->MasterQueryContext = MasterQueryContext;
2071  QueryContext->QueryPathRequest = QueryPathRequest;
2072  QueryPathRequest->PathNameLength = FileObject->FileName.Length;
2073  QueryPathRequest->SecurityContext = SecurityContext;
2074  RtlMoveMemory(QueryPathRequest->FilePathName, FileObject->FileName.Buffer, FileObject->FileName.Length);
2075 
2076  /* Build our IRP for the query */
2077  QueryIrp = MupBuildIoControlRequest(UncProvider->FileObject,
2078  QueryContext,
2081  QueryPathRequest,
2082  FileObject->FileName.Length + sizeof(QUERY_PATH_REQUEST),
2083  QueryPathRequest,
2084  sizeof(QUERY_PATH_RESPONSE),
2086  if (QueryIrp == NULL)
2087  {
2088  ExFreePoolWithTag(QueryContext, TAG_MUP);
2089  ExFreePoolWithTag(QueryPathRequest, TAG_MUP);
2091  }
2092 
2093  QueryIrp->RequestorMode = KernelMode;
2094  QueryContext->UncProvider = UncProvider;
2095  QueryContext->Irp = QueryIrp;
2096 
2098  ++UncProvider->NodeReferences;
2099  ++MasterQueryContext->NodeReferences;
2101 
2102  ExAcquireResourceExclusiveLite(&MasterQueryContext->QueryPathListLock, TRUE);
2103  InsertTailList(&MasterQueryContext->QueryPathList, &QueryContext->QueryPathListEntry);
2104  ExReleaseResourceLite(&MasterQueryContext->QueryPathListLock);
2105 
2106  /* Query the provider !*/
2107  DPRINT1("Requesting UNC provider: %wZ\n", &UncProvider->DeviceName);
2108  DPRINT("Calling: %wZ\n", &UncProvider->DeviceObject->DriverObject->DriverName);
2109  Status = IoCallDriver(UncProvider->DeviceObject, QueryIrp);
2110  }
2111 
2113  Locked = TRUE;
2114 
2115  /* We're done with that provider */
2116  MupDereferenceUncProvider(UncProvider);
2117  Referenced = FALSE;
2118 
2119  /* If query went fine on the first request, just break and leave */
2120  if (BreakOnFirst && Status == STATUS_SUCCESS)
2121  {
2122  break;
2123  }
2124 
2125  BreakOnFirst = FALSE;
2126  }
2127  }
2129  {
2131  {
2132  MasterQueryContext->LatestStatus = STATUS_INSUFFICIENT_RESOURCES;
2133  }
2134 
2135  if (Referenced)
2136  {
2137  MupDereferenceUncProvider(UncProvider);
2138  }
2139 
2140  if (Locked)
2141  {
2143  }
2144 
2145  MupDereferenceMasterQueryContext(MasterQueryContext);
2146 
2148  }
2149  _SEH2_END;
2150  }
2151  else
2152  {
2153  UNIMPLEMENTED;
2155  }
2156 
2157  return Status;
2158 }
2159 
2160 NTSTATUS
2165 {
2166  NTSTATUS Status;
2167 
2168  DPRINT1("Opening MUP\n");
2169 
2171  _SEH2_TRY
2172  {
2173  /* Update share access, increase reference count, and associated VCB to the FO, that's it! */
2175  if (NT_SUCCESS(Status))
2176  {
2177  ++Vcb->NodeReferences;
2180  }
2181  }
2183  {
2185  }
2186  _SEH2_END;
2187 
2188  return Status;
2189 }
2190 
2191 NTSTATUS
2192 NTAPI
2194  PIRP Irp)
2195 {
2196  NTSTATUS Status;
2198  PFILE_OBJECT FileObject, RelatedFileObject;
2199 
2201 
2202  _SEH2_TRY
2203  {
2204  /* If DFS is enabled, check if that's for DFS and is so relay */
2205  if (MupEnableDfs && (DeviceObject->DeviceType == FILE_DEVICE_DFS || DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM))
2206  {
2208  }
2209  else
2210  {
2212  FileObject = Stack->FileObject;
2213  RelatedFileObject = FileObject->RelatedFileObject;
2214 
2215  /* 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 */
2216  if (FileObject->FileName.Length != 0 || (RelatedFileObject != NULL && ((PMUP_FCB)(RelatedFileObject->FsContext))->NodeType != NODE_TYPE_VCB))
2217  {
2218  Status = CreateRedirectedFile(Irp, FileObject, Stack->Parameters.Create.SecurityContext);
2219  }
2220  /* Otherwise, it's just a volume open */
2221  else
2222  {
2223  Status = OpenMupFileSystem(DeviceObject->DeviceExtension,
2224  FileObject,
2225  Stack->Parameters.Create.SecurityContext->DesiredAccess,
2226  Stack->Parameters.Create.ShareAccess);
2227 
2228  Irp->IoStatus.Information = FILE_OPENED;
2229  Irp->IoStatus.Status = Status;
2231  }
2232  }
2233  }
2235  {
2237 
2238  Irp->IoStatus.Status = Status;
2240  }
2241  _SEH2_END;
2242 
2244 
2245  return Status;
2246 }
2247 
2248 VOID
2250 {
2252 
2253  /* If the node was still valid, reregister the UNC provider */
2254  if (UncProvider->NodeStatus == NODE_STATUS_HEALTHY)
2255  {
2256  UncProvider->NodeStatus = NODE_STATUS_CLEANUP;
2257  UncProvider->Registered = FALSE;
2259 
2260  if (UncProvider->FileObject != NULL)
2261  {
2262  ZwClose(UncProvider->DeviceHandle);
2263  ObDereferenceObject(UncProvider->FileObject);
2264  }
2265  }
2266  else
2267  {
2269  }
2270 }
2271 
2272 NTSTATUS
2273 NTAPI
2275  PIRP Irp)
2276 {
2277  ULONG Type;
2278  PMUP_FCB Fcb;
2279  PMUP_CCB Ccb;
2280  NTSTATUS Status;
2282 
2283  /* If DFS is enabled, check if that's for DFS and is so relay */
2284  if (MupEnableDfs)
2285  {
2286  if (DeviceObject->DeviceType == FILE_DEVICE_DFS || DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM)
2287  {
2288  return DfsFsdCleanup(DeviceObject, Irp);
2289  }
2290  }
2291 
2293 
2294  _SEH2_TRY
2295  {
2297  Type = MupDecodeFileObject(Stack->FileObject, &Fcb, &Ccb);
2298  switch (Type)
2299  {
2300  case NODE_TYPE_VCB:
2301  /* If we got a VCB, clean it up */
2303 
2304  Irp->IoStatus.Status = STATUS_SUCCESS;
2306 
2308 
2309  /* If Ccb is not null, then, it's a UNC provider node */
2310  if (Ccb)
2311  {
2312  /* Close it, and dereference */
2316  --MupProviderCount;
2318  }
2319 
2321  break;
2322 
2323  case NODE_TYPE_FCB:
2324  /* If the node wasn't already cleaned, do it */
2325  if (Fcb->NodeStatus == NODE_STATUS_HEALTHY)
2326  {
2329  }
2330  else
2331  {
2333  }
2334 
2335  Irp->IoStatus.Status = STATUS_SUCCESS;
2337 
2339  break;
2340 
2341  default:
2343 
2344  Irp->IoStatus.Status = Status;
2346 
2347  break;
2348  }
2349  }
2351  {
2353  }
2354  _SEH2_END;
2355 
2357 
2358  return Status;
2359 }
2360 
2361 NTSTATUS
2363  PIRP Irp,
2364  PMUP_VCB Vcb,
2366 {
2368 
2369  /* Remove FCB, UNC from FO */
2372 
2374 
2375  return STATUS_SUCCESS;
2376 }
2377 
2378 NTSTATUS
2380  PIRP Irp,
2381  PMUP_FCB Fcb,
2383 {
2385 
2386  /* Remove FCB, CCB from FO */
2389 
2391 
2392  return STATUS_SUCCESS;
2393 }
2394 
2395 NTSTATUS
2396 NTAPI
2398  PIRP Irp)
2399 {
2400  PMUP_FCB Fcb;
2401  PMUP_CCB Ccb;
2402  NTSTATUS Status;
2404 
2405  /* If DFS is enabled, check if that's for DFS and is so relay */
2406  if (MupEnableDfs)
2407  {
2408  if (DeviceObject->DeviceType == FILE_DEVICE_DFS || DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM)
2409  {
2410  return DfsFsdClose(DeviceObject, Irp);
2411  }
2412  }
2413 
2415 
2416  _SEH2_TRY
2417  {
2418  /* Get our internal structures from FO */
2420  MupDecodeFileObject(Stack->FileObject, &Fcb, &Ccb);
2421  if (Fcb == NULL)
2422  {
2424 
2425  Irp->IoStatus.Status = Status;
2427 
2428  _SEH2_LEAVE;
2429  }
2430 
2431  /* If we got the VCB, that's a volume close */
2432  if (Fcb->NodeType == NODE_TYPE_VCB)
2433  {
2435  }
2436  /* Otherwise close the FCB */
2437  else if (Fcb->NodeType == NODE_TYPE_FCB)
2438  {
2441  }
2442  else
2443  {
2445 
2446  Irp->IoStatus.Status = Status;
2448 
2449  _SEH2_LEAVE;
2450  }
2451 
2452  Irp->IoStatus.Status = STATUS_SUCCESS;
2454  }
2456  {
2458  }
2459  _SEH2_END;
2460 
2462 
2463  return Status;
2464 }
2465 
2466 VOID
2467 NTAPI
2469 {
2471 
2472  if (MupEnableDfs)
2473  {
2475  }
2476 
2478 }
2479 
2480 /*
2481  * FUNCTION: Called by the system to initialize the driver
2482  * ARGUMENTS:
2483  * DriverObject = object describing this driver
2484  * RegistryPath = path to our configuration entries
2485  * RETURNS: Success or failure
2486  */
2487 CODE_SEG("INIT")
2488 NTSTATUS
2489 NTAPI
2492 {
2493  NTSTATUS Status;
2494  UNICODE_STRING MupString;
2496 
2497  /* Only initialize global state of the driver
2498  * Other inits will happen when required
2499  */
2501 
2502  /* Check if DFS is disabled */
2504  /* If it's not disabled but when cannot init, disable it */
2506  {
2507  MupEnableDfs = FALSE;
2508  }
2509 
2510  /* Create the MUP device */
2511  RtlInitUnicodeString(&MupString, L"\\Device\\Mup");
2513  if (!NT_SUCCESS(Status))
2514  {
2515  if (MupEnableDfs)
2516  {
2518  }
2519 
2521 
2522  return Status;
2523  }
2524 
2525  /* Set our MJ */
2526  DriverObject->DriverUnload = MupUnload;
2527  DriverObject->MajorFunction[IRP_MJ_CREATE] = MupCreate;
2529  DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = MupCreate;
2530  DriverObject->MajorFunction[IRP_MJ_WRITE] = MupForwardIoRequest;
2532  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = MupCleanup;
2533  DriverObject->MajorFunction[IRP_MJ_CLOSE] = MupClose;
2534 
2535  /* And finish init */
2537  MupInitializeVcb(DeviceObject->DeviceExtension);
2538 
2539  return STATUS_SUCCESS;
2540 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
LONG NodeReferences
Definition: mup.h:109
* PNTSTATUS
Definition: strlen.c:14
BOOLEAN MuppIsDfsEnabled(VOID)
Definition: mup.c:94
NTSTATUS NTAPI DfsVolumePassThrough(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:38
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
VOID MupInitializeVcb(PMUP_VCB Vcb)
Definition: mup.c:84
const uint16_t * PCWSTR
Definition: typedefs.h:57
NTSTATUS MupCloseFcb(PDEVICE_OBJECT DeviceObject, PIRP Irp, PMUP_FCB Fcb, PFILE_OBJECT FileObject)
Definition: mup.c:2379
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
VOID MupSetFileObject(PFILE_OBJECT FileObject, PMUP_FCB Fcb, PMUP_CCB Ccb)
Definition: mup.c:1294
ULONG ProviderOrder
Definition: mup.h:82
NTSTATUS BuildAndSubmitIrp(PIRP Irp, PMUP_CCB Ccb, PMUP_MIC MasterIoContext)
Definition: mup.c:597
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1630
BOOLEAN MupEnableDfs
Definition: mup.c:46
ULONG NodeSize
Definition: mup.h:110
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define LL
Definition: tui.h:84
#define STATUS_REDIRECTOR_NOT_STARTED
Definition: ntstatus.h:487
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
WORK_QUEUE_ITEM WorkQueueItem
Definition: mup.h:125
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define FsRtlEnterFileSystem
#define IRP_MJ_CREATE_MAILSLOT
PVOID NTAPI ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: expool.c:2984
struct _QUERY_PATH_RESPONSE * PQUERY_PATH_RESPONSE
VOID MupDereferenceKnownPrefix(PMUP_PFX Prefix)
Definition: mup.c:422
ERESOURCE MupGlobalLock
Definition: mup.c:35
struct _Entry Entry
Definition: kefuncs.h:627
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
UNICODE_PREFIX_TABLE MupPrefixTable
Definition: mup.c:42
#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
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:520
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: mup.h:59
NTSTATUS DfsFsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:52
struct _MUP_UNC MUP_UNC
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define FILE_DEVICE_DFS_FILE_SYSTEM
Definition: winioctl.h:159
#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:56
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:2468
#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:1630
struct _QUERY_PATH_CONTEXT * PQUERY_PATH_CONTEXT
#define NODE_STATUS_CLEANUP
Definition: mup.h:26
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
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
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:104
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:74
unsigned short Length
Definition: sprintf.c:451
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1426
ERESOURCE MupCcbListLock
Definition: mup.c:37
VOID MupInitializeData(VOID)
Definition: mup.c:58
VOID MupDereferenceVcb(PMUP_VCB Vcb)
Definition: mup.c:353
LIST_ENTRY QueryPathListEntry
Definition: mup.h:135
VOID NTAPI RtlInitializeUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable)
NTSTATUS DfsFsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:68
PDEVICE_OBJECT DeviceObject
Definition: mup.h:80
IO_STATUS_BLOCK IoStatus
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
LIST_ENTRY MupMasterQueryList
Definition: mup.c:41
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG IoctlCode
Definition: wdfiotarget.h:1039
HANDLE DeviceHandle
Definition: mup.h:79
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778
#define InsertTailList(ListHead, Entry)
_In_ ULONG TotalLength
Definition: usbdlib.h:158
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSTATUS OpenMupFileSystem(PMUP_VCB Vcb, PFILE_OBJECT FileObject, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: mup.c:2161
PMUP_MIC MupAllocateMasterIoContext(VOID)
Definition: mup.c:191
_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:4137
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:2362
ULONG MupProviderCount
Definition: mup.c:44
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
NTSTATUS MupDereferenceMasterIoContext(PMUP_MIC MasterIoContext, PNTSTATUS NewStatus)
Definition: mup.c:363
#define FILE_SHARE_READ
Definition: compat.h:136
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
BOOLEAN Registered
Definition: mup.h:84
LONG NodeReferences
Definition: mup.h:63
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4226
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
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
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define FILE_TRAVERSE
Definition: nt_native.h:643
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
ERESOURCE MupPrefixTableLock
Definition: mup.c:36
return STATUS_NOT_IMPLEMENTED
NTSTATUS DfsFsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:45
PMUP_PFX Prefix
Definition: mup.h:115
void * Buffer
Definition: sprintf.c:453
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
struct _FCB::@703::@706 Fcb
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:494
#define METHOD_NEITHER
Definition: nt_native.h:597
UNICODE_STRING DeviceName
Definition: mup.h:78
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
PMUP_PFX MupAllocatePrefixEntry(ULONG PrefixLength)
Definition: mup.c:230
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
pRequest Complete(RequestStatus)
long LONG
Definition: pedump.c:60
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:541
NTSTATUS MupOrderedErrorList[]
Definition: mup.c:48
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:207
NTSTATUS NTAPI MupCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:2274
struct _MUP_PFX MUP_PFX
Definition: rtltypes.h:621
PQUERY_PATH_REQUEST QueryPathRequest
Definition: mup.h:134
LARGE_INTEGER MupKnownPrefixTimeout
Definition: mup.c:43
ULONG NodeType
Definition: mup.h:61
struct NameRec_ * Name
Definition: cdprocs.h:459
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_BAD_NETWORK_PATH
Definition: ntstatus.h:426
PDEVICE_OBJECT DeviceObject
Definition: mup.h:126
unsigned char BOOLEAN
NTSTATUS CreateRedirectedFile(PIRP Irp, PFILE_OBJECT FileObject, PIO_SECURITY_CONTEXT SecurityContext)
Definition: mup.c:1871
VOID MupCloseUncProvider(PMUP_UNC UncProvider)
Definition: mup.c:2249
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:166
#define IoCompleteRequest
Definition: irp.c:1240
LIST_ENTRY QueryPathList
Definition: mup.h:117
PMUP_UNC UncProvider
Definition: mup.h:133
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFKEY * Key
Definition: wdfdevice.h:2654
VOID MupCalculateTimeout(PLARGE_INTEGER EntryTime)
Definition: mup.c:142
PIRP Irp
Definition: mup.h:111
Definition: mup.h:37
ERESOURCE MupVcbLock
Definition: mup.c:38
void * PVOID
Definition: retypes.h:9
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
PMUP_FCB MupCreateFcb(VOID)
Definition: mup.c:171
NTSTATUS DfsFsdCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dfs.c:60
#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
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
PMUP_UNC MupAllocateUncProvider(ULONG RedirectorDeviceNameLength)
Definition: mup.c:210
ULONG NodeSize
Definition: mup.h:64
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:859
NTSTATUS MupDereferenceMasterQueryContext(PMUP_MQC MasterQueryContext)
Definition: mup.c:1608
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
NTSTATUS CommonForwardedIoCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFORWARDED_IO_CONTEXT FwdCtxt)
Definition: mup.c:530
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:121
#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
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:949
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:440
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: mup.c:2490
VOID MupDereferenceUncProvider(PMUP_UNC UncProvider)
Definition: mup.c:416
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
PFILE_OBJECT FileObject
Definition: mup.h:112
#define ASSERT(a)
Definition: mode.c:44
VOID MupFreeMasterQueryContext(PMUP_MQC MasterQueryContext)
Definition: mup.c:1601
NTSTATUS NTAPI MupFsControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:1242
__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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define NODE_TYPE_FCB
Definition: vfat.h:445
ULONG MupDecodeFileObject(PFILE_OBJECT FileObject, PMUP_FCB *pFcb, PMUP_CCB *pCcb)
Definition: mup.c:291
#define FILE_DEVICE_DFS
Definition: winioctl.h:112
#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:1415
PMUP_MIC MasterIoContext
Definition: mup.h:124
#define ObDereferenceObject
Definition: obfuncs.h:203
#define TAG_MUP
Definition: mup.h:13
NTSTATUS DfsDriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: dfs.c:83
Type
Definition: Type.h:6
NTSTATUS LastFailed
Definition: mup.h:67
VOID MupRemoveKnownPrefixEntry(PMUP_PFX Prefix)
Definition: mup.c:448
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
Definition: mup.h:71
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1998
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
Definition: mup.h:87
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
NTSTATUS LatestStatus
Definition: mup.h:116
#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:322
PMUP_MQC MupAllocateMasterQueryContext(VOID)
Definition: mup.c:269
VOID MupDereferenceCcb(PMUP_CCB Ccb)
Definition: mup.c:338
#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:480
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:761
#define FILE_SIMPLE_RIGHTS_MASK
Definition: mup.h:15
VOID MupDereferenceFcb(PMUP_FCB Fcb)
Definition: mup.c:328
NTSTATUS NTAPI MupCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:2193
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:588
LIST_ENTRY MupProviderList
Definition: mup.c:39
BOOLEAN NTAPI RtlInsertUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable, PUNICODE_STRING Prefix, PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry)
Definition: typedefs.h:119
static const WCHAR Cleanup[]
Definition: register.c:80
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
ULONG NodeStatus
Definition: mup.h:108
PMUP_UNC AddUnregisteredProvider(PCWSTR DeviceName, ULONG ProviderOrder)
Definition: mup.c:860
#define FILE_SHARE_VALID_FLAGS
Definition: nt_native.h:683
PMUP_UNC LatestProvider
Definition: mup.h:113
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:1303
LIST_ENTRY MupPrefixList
Definition: mup.c:40
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
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PIO_SECURITY_CONTEXT SecurityContext
#define IOCTL_REDIR_QUERY_PATH
_SEH2_END
Definition: create.c:4400
#define IRP_INPUT_OPERATION
#define IRP_BUFFERED_IO
VOID NTAPI DeferredForwardedIoCompletionRoutine(PVOID Context)
Definition: mup.c:565
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:922
unsigned short USHORT
Definition: pedump.c:61
#define IO_METHOD_FROM_CTL_CODE(C)
Definition: mup.h:11
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
#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:457
#define METHOD_BUFFERED
Definition: nt_native.h:594
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:893
_SEH2_FINALLY
Definition: create.c:4371
#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:1052
#define NODE_TYPE_MQC
Definition: mup.h:23
#define NULL
Definition: types.h:112
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:2835
PDEVICE_OBJECT mupDeviceObject
Definition: mup.c:47
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
#define MAXUSHORT
Definition: typedefs.h:83
#define SL_WRITE_THROUGH
Definition: iotypes.h:1824
#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:4303
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:1340
NTSTATUS NTAPI QueryPathCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: mup.c:1683
struct _MUP_MIC MUP_MIC
_In_ HANDLE Handle
Definition: extypes.h:390
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#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:499
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:2397
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
VOID InitializeProvider(PCWSTR ProviderName, ULONG ProviderOrder)
Definition: mup.c:895
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
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:1514
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define IRP_WRITE_OPERATION
#define _SEH2_LEAVE
Definition: filesup.c:20
#define DPRINT
Definition: sndvol32.h:71
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define NODE_STATUS_HEALTHY
Definition: mup.h:25
BOOLEAN KeepExtraRef
Definition: mup.h:100
unsigned short MaximumLength
Definition: sprintf.c:452
IoMarkIrpPending(Irp)
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PMUP_CCB MupCreateCcb(VOID)
Definition: mup.c:152
VOID MupGetProviderInformation(VOID)
Definition: mup.c:969
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
NTSTATUS NTAPI ForwardedIoCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: mup.c:574
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2680
#define FILE_DEVICE_MULTI_UNC_PROVIDER
Definition: winioctl.h:122
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:108
BOOLEAN MupOrderInitialized
Definition: mup.c:45
ULONG NodeType
Definition: mup.h:73
#define IRP_MJ_CREATE_NAMED_PIPE
NTSTATUS RegisterUncProvider(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: mup.c:1081
LONGLONG QuadPart
Definition: typedefs.h:114
PMUP_CCB Ccb
Definition: mup.h:123
UNICODE_STRING RedirectorDeviceName
Definition: unc.c:23
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
VOID DfsUnload(PDRIVER_OBJECT DriverObject)
Definition: dfs.c:76
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: dlist.c:348