ReactOS 0.4.15-dev-7788-g1ad9096
rdbss.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2017 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: sdk/lib/drivers/rdbsslib/rdbss.c
23 * PURPOSE: RDBSS library
24 * PROGRAMMER: Pierre Schweitzer (pierre@reactos.org)
25 */
26
27/* INCLUDES *****************************************************************/
28
29#include <rx.h>
30#include <pseh/pseh2.h>
31#include <limits.h>
32#include <dfs.h>
33#include <copysup.h>
34
35#define NDEBUG
36#include <debug.h>
37
38#define RX_TOPLEVELCTX_FLAG_FROM_POOL 1
39
40typedef
44
46{
49
50VOID
54
60
61VOID
63 PRX_TOPLEVELIRP_CONTEXT TopLevelContext);
64
65VOID
68 PVOID File,
69 ULONG Line,
71
76
81
86
91
96
101
103NTAPI
106
108NTAPI
111
113NTAPI
116
118NTAPI
121
123NTAPI
126
128NTAPI
131
133NTAPI
136
138NTAPI
141
143NTAPI
146
148NTAPI
151
153NTAPI
156
158NTAPI
161
163NTAPI
166
168NTAPI
171
173NTAPI
176
178NTAPI
181
183NTAPI
186
188NTAPI
191
193NTAPI
196
198NTAPI
201
203NTAPI
206
207VOID
209 IN PRX_CONTEXT RxContext);
210
214 PUNICODE_STRING NetRootName);
215
218 IN PRX_CONTEXT RxContext);
219
221NTAPI
229
231NTAPI
242
244NTAPI
254
256NTAPI
266
269 PRX_CONTEXT RxContext,
270 PUNICODE_STRING NetRootName);
271
274 PRX_CONTEXT RxContext,
276 PUNICODE_STRING CanonicalName,
277 PNET_ROOT_TYPE NetRootType);
278
279VOID
282
283VOID
284NTAPI
287
288VOID
289NTAPI
292
294NTAPI
298 OUT PUNICODE_STRING OutString,
301 IN BOOLEAN LogFailure);
302
303VOID
304NTAPI
306 VOID);
307
308VOID
309NTAPI
312
314NTAPI
316 VOID);
317
318VOID
319NTAPI
321 VOID);
322
323VOID
324NTAPI
327 USHORT State);
328
331 PRX_TOPLEVELIRP_CONTEXT TopLevelContext);
332
334NTAPI
336 PRX_CONTEXT RxContext);
337
340 PRX_CONTEXT RxContext);
341
343NTAPI
345 PRX_CONTEXT RxContext);
346
349 IN PRX_CONTEXT RxContext);
350
352NTAPI
354 PRX_CONTEXT RxContext);
355
356PVOID
358 PRX_CONTEXT RxContext);
359
362 PRX_CONTEXT RxContext);
363
364VOID
365NTAPI
367 PVOID Context);
368
371 PRX_CONTEXT RxContext,
372 FILE_INFORMATION_CLASS FileInfoClass,
373 PVOID Buffer);
374
375VOID
377 PFCB Fcb,
378 PRX_CONTEXT LocalContext);
379
382 PRX_CONTEXT RxContext,
383 PFILE_NAME_INFORMATION AltNameInfo);
384
387 PRX_CONTEXT RxContext,
388 PFILE_BASIC_INFORMATION BasicInfo);
389
392 PRX_CONTEXT RxContext,
393 PFILE_COMPRESSION_INFORMATION CompressionInfo);
394
397 PRX_CONTEXT RxContext);
398
401 PRX_CONTEXT RxContext,
402 PFILE_EA_INFORMATION EaInfo);
403
406 PRX_CONTEXT RxContext,
407 PFILE_INTERNAL_INFORMATION InternalInfo);
408
411 PRX_CONTEXT RxContext,
412 PFILE_NAME_INFORMATION NameInfo);
413
416 PRX_CONTEXT RxContext,
418
421 PRX_CONTEXT RxContext,
422 PFILE_POSITION_INFORMATION PositionInfo);
423
426 PRX_CONTEXT RxContext,
427 PFILE_STANDARD_INFORMATION StandardInfo);
428
429VOID
430NTAPI
432 VOID);
433
434VOID
435NTAPI
438
440NTAPI
444
449
452 PRX_CONTEXT RxContext,
455
458 PRX_CONTEXT RxContext);
459
462 PRX_CONTEXT RxContext);
463
466 PRX_CONTEXT RxContext);
467
470 PRX_CONTEXT RxContext);
471
474 PRX_CONTEXT RxContext);
475
478 PRX_CONTEXT RxContext);
479
482 PRX_CONTEXT RxContext);
483
486 PRX_CONTEXT RxContext);
487
488VOID
490 PRX_CONTEXT RxContext);
491
494 IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
495 IN PIRP Irp);
496
497VOID
499 PRX_CONTEXT RxContext,
501 PLARGE_INTEGER TruncateSize);
502
503VOID
507
511
512PVOID
513NTAPI
517 _In_ ULONG Tag);
518
519VOID
520NTAPI
523
524VOID
525NTAPI
528 _In_ ULONG Tag);
529
531WCHAR Rx8QMdot3QM[] = L">>>>>>>>.>>>*";
541{
570};
575{
576 { RxCommonCreate },
578 { RxCommonClose },
579 { RxCommonRead },
580 { RxCommonWrite },
583 { RxCommonQueryEa },
584 { RxCommonSetEa },
594 { RxCommonCleanup },
604};
610UCHAR RxSpaceForTheWrappersDeviceObject[sizeof(*RxFileSystemDeviceObject)];
615
617
618#if RDBSS_ASSERTS
619#ifdef ASSERT
620#undef ASSERT
621#endif
622
623#define ASSERT(exp) \
624 if (!(exp)) \
625 { \
626 RxAssert(#exp, __FILE__, __LINE__, NULL); \
627 }
628#endif
629
630#if RX_POOL_WRAPPER
631#undef RxAllocatePool
632#undef RxAllocatePoolWithTag
633#undef RxFreePool
634
635#define RxAllocatePool(P, S) _RxAllocatePoolWithTag(P, S, 0)
636#define RxAllocatePoolWithTag _RxAllocatePoolWithTag
637#define RxFreePool _RxFreePool
638#define RxFreePoolWithTag _RxFreePoolWithTag
639#endif
640
641/* FUNCTIONS ****************************************************************/
642
643/*
644 * @implemented
645 */
646VOID
648 PRX_CONTEXT RxContext)
649{
651
652 PAGED_CODE();
653
654#define ALLSCR_LENGTH (sizeof(L"all.scr") - sizeof(UNICODE_NULL))
655
656 /* Are loud operations enabled? */
658 {
659 /* If so, the operation will be loud only if filename ends with all.scr */
660 if (RtlCompareMemory(Add2Ptr(capFcb->PrivateAlreadyPrefixedName.Buffer,
661 (capFcb->PrivateAlreadyPrefixedName.Length - ALLSCR_LENGTH)),
662 L"all.scr", ALLSCR_LENGTH) == ALLSCR_LENGTH)
663 {
665 }
666 }
667#undef ALLSCR_LENGTH
668}
669
670/*
671 * @implemented
672 */
673VOID
675 IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext,
676 IN PIRP Irp,
677 IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
678 IN ULONG Flags)
679{
680 DPRINT("__RxInitializeTopLevelIrpContext(%p, %p, %p, %u)\n", TopLevelContext, Irp, RxDeviceObject, Flags);
681
682 RtlZeroMemory(TopLevelContext, sizeof(RX_TOPLEVELIRP_CONTEXT));
683 TopLevelContext->Irp = Irp;
684 TopLevelContext->Flags = (Flags ? RX_TOPLEVELCTX_FLAG_FROM_POOL : 0);
685 TopLevelContext->Signature = RX_TOPLEVELIRP_CONTEXT_SIGNATURE;
686 TopLevelContext->RxDeviceObject = RxDeviceObject;
687 TopLevelContext->Previous = IoGetTopLevelIrp();
688 TopLevelContext->Thread = PsGetCurrentThread();
689
690 /* We cannot add to list something that'd come from stack */
691 if (BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL))
692 {
694 }
695}
696
697/*
698 * @implemented
699 */
700VOID
702 PRX_CONTEXT RxContext,
703 BOOLEAN ResourceOwnerSet,
707{
709
710 PAGED_CODE();
711
712 ASSERT(RxContext != NULL);
713 ASSERT(capFcb != NULL);
714
715 /* If FCB resource was acquired, release it */
716 if (RxContext->FcbResourceAcquired)
717 {
718 /* Taking care of owner */
719 if (ResourceOwnerSet)
720 {
722 }
723 else
724 {
725 RxReleaseFcb(RxContext, capFcb);
726 }
727
728 RxContext->FcbResourceAcquired = FALSE;
729 }
730
731 /* If FCB paging resource was acquired, release it */
732 if (RxContext->FcbPagingIoResourceAcquired)
733 {
734 /* Taking care of owner */
735 if (ResourceOwnerSet)
736 {
738 }
739 else
740 {
742 }
743
744 /* No need to release boolean here, RxReleasePagingIoResource() takes care of it */
745 }
746}
747
748/*
749 * @implemented
750 */
751VOID
753 PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
754{
756
757 DPRINT("RxAddToTopLevelIrpAllocatedContextsList(%p)\n", TopLevelContext);
758
761
765}
766
767/*
768 * @implemented
769 */
770VOID
771NTAPI
773 IN PRX_CONTEXT RxContext,
774 IN PIRP Irp)
775{
776 ULONG Queued;
779
781
782 RxContext->PostRequest = FALSE;
783
784 /* First of all, select the appropriate queue - delayed for prefix claim, critical for the rest */
785 if (RxContext->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
786 capPARAMS->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH)
787 {
790 }
791 else
792 {
795 }
796
797 /* Check for overflow */
798 if (capPARAMS->FileObject != NULL)
799 {
801
803 /* In case of an overflow, add the new queued call to the overflow list */
804 if (Queued > 1)
805 {
807 InsertTailList(&RxFileSystemDeviceObject->OverflowQueue[Queue], &RxContext->OverflowListEntry);
809
811 return;
812 }
813
815 }
816
817 ExInitializeWorkItem(&RxContext->WorkQueueItem, RxFspDispatch, RxContext);
818 ExQueueWorkItem((PWORK_QUEUE_ITEM)&RxContext->WorkQueueItem, Queue);
819}
820
821/*
822 * @implemented
823 */
824VOID
826 PRX_CONTEXT RxContext)
827{
829 LARGE_INTEGER CurrentTime;
830 FILE_BASIC_INFORMATION FileBasicInfo;
832 BOOLEAN FileModified, SetLastChange, SetLastAccess, SetLastWrite, NeedUpdate;
833
838
839 PAGED_CODE();
840
841 /* If Cc isn't initialized, the file was not read nor written, nothing to do */
842 if (capFileObject->PrivateCacheMap == NULL)
843 {
844 return;
845 }
846
847 /* Get now */
848 KeQuerySystemTime(&CurrentTime);
849
850 /* Was the file modified? */
851 FileModified = BooleanFlagOn(capFileObject->Flags, FO_FILE_MODIFIED);
852 /* We'll set last write if it was modified and user didn't update yet */
853 SetLastWrite = FileModified && !BooleanFlagOn(capFobx->Flags, FOBX_FLAG_USER_SET_LAST_WRITE);
854 /* File was accessed if: written or read (fastio), we'll update last access if user didn't */
855 SetLastAccess = SetLastWrite ||
858 /* We'll set last change if it was modified and user didn't update yet */
859 SetLastChange = FileModified && !BooleanFlagOn(capFobx->Flags, FOBX_FLAG_USER_SET_LAST_CHANGE);
860
861 /* Nothing to update? Job done */
862 if (!FileModified && !SetLastWrite && !SetLastAccess && !SetLastChange)
863 {
864 return;
865 }
866
867 /* By default, we won't issue any MRxSetFileInfoAtCleanup call */
868 NeedUpdate = FALSE;
869 RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
870
871 /* Update lastwrite time if required */
872 if (SetLastWrite)
873 {
874 NeedUpdate = TRUE;
875 capFcb->LastWriteTime.QuadPart = CurrentTime.QuadPart;
876 FileBasicInfo.LastWriteTime.QuadPart = CurrentTime.QuadPart;
877 }
878
879 /* Update lastaccess time if required */
880 if (SetLastAccess)
881 {
882 NeedUpdate = TRUE;
883 capFcb->LastAccessTime.QuadPart = CurrentTime.QuadPart;
884 FileBasicInfo.LastAccessTime.QuadPart = CurrentTime.QuadPart;
885 }
886
887 /* Update lastchange time if required */
888 if (SetLastChange)
889 {
890 NeedUpdate = TRUE;
891 capFcb->LastChangeTime.QuadPart = CurrentTime.QuadPart;
892 FileBasicInfo.ChangeTime.QuadPart = CurrentTime.QuadPart;
893 }
894
895 /* If one of the date was modified, issue a call to mini-rdr */
896 if (NeedUpdate)
897 {
898 RxContext->Info.FileInformationClass = FileBasicInformation;
899 RxContext->Info.Buffer = &FileBasicInfo;
900 RxContext->Info.Length = sizeof(FileBasicInfo);
901
902 MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxSetFileInfoAtCleanup, (RxContext));
903 (void)Status;
904 }
905
906 /* If the file was modified, update its EOF */
907 if (FileModified)
908 {
909 FileEOFInfo.EndOfFile.QuadPart = capFcb->Header.FileSize.QuadPart;
910
911 RxContext->Info.FileInformationClass = FileEndOfFileInformation;
912 RxContext->Info.Buffer = &FileEOFInfo;
913 RxContext->Info.Length = sizeof(FileEOFInfo);
914
915 MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxSetFileInfoAtCleanup, (RxContext));
916 (void)Status;
917 }
918}
919
920/*
921 * @implemented
922 */
925 PRX_CONTEXT RxContext,
926 PUNICODE_STRING CanonicalName,
927 USHORT CanonicalLength)
928{
929 PAGED_CODE();
930
931 DPRINT("RxContext: %p - CanonicalNameBuffer: %p\n", RxContext, RxContext->Create.CanonicalNameBuffer);
932
933 /* Context must be free of any already allocated name */
934 ASSERT(RxContext->Create.CanonicalNameBuffer == NULL);
935
936 /* Validate string length */
937 if (CanonicalLength > USHRT_MAX - 1)
938 {
939 CanonicalName->Buffer = NULL;
941 }
942
943 CanonicalName->Buffer = RxAllocatePoolWithTag(PagedPool | POOL_COLD_ALLOCATION, CanonicalLength, RX_MISC_POOLTAG);
944 if (CanonicalName->Buffer == NULL)
945 {
947 }
948
949 CanonicalName->Length = 0;
950 CanonicalName->MaximumLength = CanonicalLength;
951
952 /* Set the two places - they must always be identical */
953 RxContext->Create.CanonicalNameBuffer = CanonicalName->Buffer;
954 RxContext->AlsoCanonicalNameBuffer = CanonicalName->Buffer;
955
956 return STATUS_SUCCESS;
957}
958
959/*
960 * @implemented
961 */
962VOID
964 PFOBX Fobx)
965{
969 LIST_ENTRY ContextsToCancel;
970
971 /* Init a list for the contexts to cancel */
972 InitializeListHead(&ContextsToCancel);
973
974 /* Lock our list lock */
976
977 /* Now, browse all the active contexts, to find the associated ones */
979 while (Entry != &RxActiveContexts)
980 {
981 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
982 Entry = Entry->Flink;
983
984 /* Not the IRP we're looking for, ignore */
985 if (Context->MajorFunction != IRP_MJ_DIRECTORY_CONTROL ||
986 Context->MinorFunction != IRP_MN_NOTIFY_CHANGE_DIRECTORY)
987 {
988 continue;
989 }
990
991 /* Not the FOBX we're looking for, ignore */
992 if ((PFOBX)Context->pFobx != Fobx)
993 {
994 continue;
995 }
996
997 /* No cancel routine (can't be cancel, then), ignore */
998 if (Context->MRxCancelRoutine == NULL)
999 {
1000 continue;
1001 }
1002
1003 /* Mark our context as cancelled */
1005
1006 /* Move it to our list */
1007 RemoveEntryList(&Context->ContextListEntry);
1008 InsertTailList(&ContextsToCancel, &Context->ContextListEntry);
1009
1010 InterlockedIncrement((volatile long *)&Context->ReferenceCount);
1011 }
1012
1013 /* Done with the contexts */
1015
1016 /* Now, handle all our "extracted" contexts */
1017 while (!IsListEmpty(&ContextsToCancel))
1018 {
1019 Entry = RemoveHeadList(&ContextsToCancel);
1020 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
1021
1022 /* If they had an associated IRP (should be always true) */
1023 if (Context->CurrentIrp != NULL)
1024 {
1025 /* Then, call cancel routine */
1026 ASSERT(Context->MRxCancelRoutine != NULL);
1027 DPRINT1("Canceling %p with %p\n", Context, Context->MRxCancelRoutine);
1028 Context->MRxCancelRoutine(Context);
1029 }
1030
1031 /* And delete the context */
1033 }
1034}
1035
1036/*
1037 * @implemented
1038 */
1041 PV_NET_ROOT VNetRoot,
1042 BOOLEAN ForceFilesClosed)
1043{
1044 KIRQL OldIrql;
1048 LIST_ENTRY ContextsToCancel;
1049
1050 /* Init a list for the contexts to cancel */
1051 InitializeListHead(&ContextsToCancel);
1052
1053 /* Lock our list lock */
1055
1056 /* Assume success */
1058
1059 /* Now, browse all the active contexts, to find the associated ones */
1061 while (Entry != &RxActiveContexts)
1062 {
1063 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
1064 Entry = Entry->Flink;
1065
1066 /* Not the IRP we're looking for, ignore */
1067 if (Context->MajorFunction != IRP_MJ_DIRECTORY_CONTROL ||
1068 Context->MinorFunction != IRP_MN_NOTIFY_CHANGE_DIRECTORY)
1069 {
1070 continue;
1071 }
1072
1073 /* Not the VNetRoot we're looking for, ignore */
1074 if (Context->pFcb == NULL ||
1075 (PV_NET_ROOT)Context->NotifyChangeDirectory.pVNetRoot != VNetRoot)
1076 {
1077 continue;
1078 }
1079
1080 /* No cancel routine (can't be cancel, then), ignore */
1081 if (Context->MRxCancelRoutine == NULL)
1082 {
1083 continue;
1084 }
1085
1086 /* At that point, we found a matching context
1087 * If we're not asked to force close, then fail - it's still open
1088 */
1089 if (!ForceFilesClosed)
1090 {
1092 break;
1093 }
1094
1095 /* Mark our context as cancelled */
1097
1098 /* Move it to our list */
1099 RemoveEntryList(&Context->ContextListEntry);
1100 InsertTailList(&ContextsToCancel, &Context->ContextListEntry);
1101
1102 InterlockedIncrement((volatile long *)&Context->ReferenceCount);
1103 }
1104
1105 /* Done with the contexts */
1107
1108 if (Status != STATUS_SUCCESS)
1109 {
1110 return Status;
1111 }
1112
1113 /* Now, handle all our "extracted" contexts */
1114 while (!IsListEmpty(&ContextsToCancel))
1115 {
1116 Entry = RemoveHeadList(&ContextsToCancel);
1117 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
1118
1119 /* If they had an associated IRP (should be always true) */
1120 if (Context->CurrentIrp != NULL)
1121 {
1122 /* Then, call cancel routine */
1123 ASSERT(Context->MRxCancelRoutine != NULL);
1124 DPRINT1("Canceling %p with %p\n", Context, Context->MRxCancelRoutine);
1125 Context->MRxCancelRoutine(Context);
1126 }
1127
1128 /* And delete the context */
1130 }
1131
1132 return Status;
1133}
1134
1135/*
1136 * @implemented
1137 */
1138BOOLEAN
1140 PRX_CONTEXT RxContext)
1141{
1142 KIRQL OldIrql;
1143 BOOLEAN OperationToCancel;
1144
1145 /* By default, nothing cancelled */
1146 OperationToCancel = FALSE;
1147
1148 /* Acquire the overflow spinlock */
1150
1151 /* Is our context in any queue? */
1153 {
1154 /* Make sure flag is consistent with facts... */
1155 if (RxContext->OverflowListEntry.Flink != NULL)
1156 {
1157 /* Remove it from the list */
1159 RxContext->OverflowListEntry.Flink = NULL;
1160
1161 /* Decrement appropriate count */
1163 {
1165 }
1166 else
1167 {
1169 }
1170
1171 /* Clear the flag */
1173
1174 /* Time to cancel! */
1175 OperationToCancel = TRUE;
1176 }
1177 }
1178
1180
1181 /* We have something to cancel & complete */
1182 if (OperationToCancel)
1183 {
1186 }
1187
1188 return OperationToCancel;
1189}
1190
1191/*
1192 * @implemented
1193 */
1194VOID
1195NTAPI
1198 PIRP Irp)
1199{
1200 KIRQL OldIrql;
1202 PRX_CONTEXT RxContext;
1203
1204 /* Lock our contexts list */
1206
1207 /* Now, find a context that matches the cancelled IRP */
1209 while (Entry != &RxActiveContexts)
1210 {
1211 RxContext = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
1212 Entry = Entry->Flink;
1213
1214 /* Found! */
1215 if (RxContext->CurrentIrp == Irp)
1216 {
1217 break;
1218 }
1219 }
1220
1221 /* If we reached the end of the list, we didn't find any context, so zero the buffer
1222 * If the context is already under cancellation, forget about it too
1223 */
1225 {
1226 RxContext = NULL;
1227 }
1228 else
1229 {
1230 /* Otherwise, reference it and mark it cancelled */
1232 InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
1233 }
1234
1235 /* Done with the contexts list */
1237
1238 /* And done with the cancellation, we'll do it now */
1239 IoReleaseCancelSpinLock(Irp->CancelIrql);
1240
1241 /* If we have a context to cancel */
1242 if (RxContext != NULL)
1243 {
1244 /* We cannot executed at dispatch, so queue a deferred cancel */
1246 {
1248 }
1249 /* Cancel now! */
1250 else
1251 {
1252 RxpCancelRoutine(RxContext);
1253 }
1254 }
1255}
1256
1257/*
1258 * @implemented
1259 */
1262 PRX_CONTEXT RxContext,
1263 PUNICODE_STRING NetRootName)
1264{
1265 USHORT NextChar, CurChar;
1266 USHORT MaxChars;
1267
1268 PAGED_CODE();
1269
1270 /* Validate file name is not empty */
1271 MaxChars = NetRootName->Length / sizeof(WCHAR);
1272 if (MaxChars == 0)
1273 {
1275 }
1276
1277 /* Validate name is correct */
1278 for (NextChar = 0, CurChar = 0; CurChar + 1 < MaxChars; NextChar = CurChar + 1)
1279 {
1280 USHORT i;
1281
1282 for (i = NextChar + 1; i < MaxChars; ++i)
1283 {
1284 if (NetRootName->Buffer[i] == '\\' || NetRootName->Buffer[i] == ':')
1285 {
1286 break;
1287 }
1288 }
1289
1290 CurChar = i - 1;
1291 if (CurChar == NextChar)
1292 {
1293 if (((NetRootName->Buffer[NextChar] != '\\' && NetRootName->Buffer[NextChar] != ':') || NextChar == (MaxChars - 1)) && NetRootName->Buffer[NextChar] != '.')
1294 {
1295 continue;
1296 }
1297
1298 if (CurChar != 0)
1299 {
1300 if (CurChar >= MaxChars - 1)
1301 {
1302 continue;
1303 }
1304
1305 if (NetRootName->Buffer[CurChar + 1] != ':')
1306 {
1308 }
1309 }
1310 else
1311 {
1312 if (NetRootName->Buffer[1] != ':')
1313 {
1315 }
1316 }
1317 }
1318 else
1319 {
1320 if ((CurChar - NextChar) == 1)
1321 {
1322 if (NetRootName->Buffer[NextChar + 2] != '.')
1323 {
1324 continue;
1325 }
1326
1327 if (NetRootName->Buffer[NextChar] == '\\' || NetRootName->Buffer[NextChar] == ':' || NetRootName->Buffer[NextChar] == '.')
1328 {
1330 }
1331 }
1332 else
1333 {
1334 if ((CurChar - NextChar) != 2 || (NetRootName->Buffer[NextChar] != '\\' && NetRootName->Buffer[NextChar] != ':')
1335 || NetRootName->Buffer[NextChar + 1] != '.')
1336 {
1337 continue;
1338 }
1339
1340 if (NetRootName->Buffer[NextChar + 2] == '.')
1341 {
1343 }
1344 }
1345 }
1346 }
1347
1349}
1350
1353 PRX_CONTEXT RxContext,
1355 PUNICODE_STRING NetRootName)
1356{
1358 NET_ROOT_TYPE NetRootType;
1359 UNICODE_STRING CanonicalName;
1360
1363
1364 PAGED_CODE();
1365
1366 NetRootType = NET_ROOT_WILD;
1367
1368 RtlInitEmptyUnicodeString(NetRootName, NULL, 0);
1369 RtlInitEmptyUnicodeString(&CanonicalName, NULL, 0);
1370
1371 /* if not relative opening, just handle the passed name */
1372 if (capFileObject->RelatedFileObject == NULL)
1373 {
1374 Status = RxFirstCanonicalize(RxContext, FileName, &CanonicalName, &NetRootType);
1375 if (!NT_SUCCESS(Status))
1376 {
1377 return Status;
1378 }
1379 }
1380 else
1381 {
1382 PFCB Fcb;
1383
1384 /* Make sure we have a valid FCB and a FOBX */
1385 Fcb = capFileObject->RelatedFileObject->FsContext;
1386 if (Fcb == NULL || capFileObject->RelatedFileObject->FsContext2 == NULL)
1387 {
1389 }
1390
1391 if (!NodeTypeIsFcb(Fcb))
1392 {
1394 }
1395
1397 }
1398
1399 /* Get/Create the associated VNetRoot for opening */
1400 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, NetRootName);
1401 if (!NT_SUCCESS(Status) && Status != STATUS_PENDING &&
1403 {
1404 ASSERT(CanonicalName.Buffer == RxContext->Create.CanonicalNameBuffer);
1405
1406 RxFreeCanonicalNameBuffer(RxContext);
1407 Status = RxFirstCanonicalize(RxContext, FileName, &CanonicalName, &NetRootType);
1408 if (NT_SUCCESS(Status))
1409 {
1410 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, NetRootName);
1411 }
1412 }
1413
1414 /* Filename cannot contain wildcards */
1415 if (FsRtlDoesNameContainWildCards(NetRootName))
1416 {
1418 }
1419
1420 /* Make sure file name is correct */
1421 if (NT_SUCCESS(Status))
1422 {
1423 Status = RxCanonicalizeFileNameByServerSpecs(RxContext, NetRootName);
1424 }
1425
1426 /* Give the mini-redirector a chance to prepare the name */
1428 {
1429 if (RxContext->Create.pNetRoot != NULL)
1430 {
1431 NTSTATUS IgnoredStatus;
1432
1433 MINIRDR_CALL(IgnoredStatus, RxContext, RxContext->Create.pNetRoot->pSrvCall->RxDeviceObject->Dispatch,
1434 MRxPreparseName, (RxContext, NetRootName));
1435 (void)IgnoredStatus;
1436 }
1437 }
1438
1439 return Status;
1440}
1441
1442/*
1443 * @implemented
1444 */
1445VOID
1446NTAPI
1448 VOID)
1449{
1450 PAGED_CODE();
1451}
1452
1453#if DBG
1461 _In_ PSZ where,
1462 _In_ PSZ wherelogtag)
1463{
1464 PAGED_CODE();
1465
1466 RxDumpWantedAccess(where, "", wherelogtag, DesiredAccess, DesiredShareAccess);
1467 RxDumpCurrentAccess(where, "", wherelogtag, ShareAccess);
1468
1470}
1471#endif
1472
1473/*
1474 * @implemented
1475 */
1478 IN PFCB Fcb,
1481{
1484 BOOLEAN DeleteAccess;
1486
1487 PAGED_CODE();
1488
1490
1491 RxDumpWantedAccess("RxCheckShareAccessPerSrvOpens", "", "RxCheckShareAccessPerSrvOpens", DesiredAccess, DesiredShareAccess);
1492 RxDumpCurrentAccess("RxCheckShareAccessPerSrvOpens", "", "RxCheckShareAccessPerSrvOpens", ShareAccess);
1493
1494 /* Check if any access wanted */
1497 DeleteAccess = (DesiredAccess & DELETE) != 0;
1498
1499 if (ReadAccess || WriteAccess || DeleteAccess)
1500 {
1501 BOOLEAN SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
1502 BOOLEAN SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
1503 BOOLEAN SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
1504
1505 /* Check whether there's a violation */
1506 if ((ReadAccess &&
1507 (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
1508 (WriteAccess &&
1509 (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
1510 (DeleteAccess &&
1511 (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
1512 ((ShareAccess->Readers != 0) && !SharedRead) ||
1513 ((ShareAccess->Writers != 0) && !SharedWrite) ||
1514 ((ShareAccess->Deleters != 0) && !SharedDelete))
1515 {
1517 }
1518 }
1519
1520 return STATUS_SUCCESS;
1521}
1522
1523VOID
1526{
1528}
1529
1530/*
1531 * @implemented
1532 */
1535 IN PFOBX Fobx,
1536 IN PRX_CONTEXT RxContext OPTIONAL)
1537{
1538 PFCB Fcb;
1540 PSRV_OPEN SrvOpen;
1541 BOOLEAN CloseSrvOpen;
1542 PRX_CONTEXT LocalContext;
1543
1544 PAGED_CODE();
1545
1546 /* Assume SRV_OPEN is already closed */
1547 CloseSrvOpen = FALSE;
1548 /* If we have a FOBX, we'll have to close it */
1549 if (Fobx != NULL)
1550 {
1551 /* If the FOBX isn't closed yet */
1552 if (!BooleanFlagOn(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED))
1553 {
1554 SrvOpen = Fobx->SrvOpen;
1555 Fcb = (PFCB)SrvOpen->pFcb;
1556 /* Check whether we've to close SRV_OPEN first */
1557 if (!BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
1558 {
1559 CloseSrvOpen = TRUE;
1560 }
1561 else
1562 {
1564
1565 /* Not much to do */
1566 SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
1567
1568 if (SrvOpen->OpenCount > 0)
1569 {
1570 --SrvOpen->OpenCount;
1571 }
1572 }
1573 }
1574
1575 /* No need to close SRV_OPEN, so close FOBX */
1576 if (!CloseSrvOpen)
1577 {
1578 RxMarkFobxOnClose(Fobx);
1579
1580 return STATUS_SUCCESS;
1581 }
1582 }
1583 else
1584 {
1585 /* No FOBX? No RX_CONTEXT, ok, job done! */
1586 if (RxContext == NULL)
1587 {
1588 return STATUS_SUCCESS;
1589 }
1590
1591 /* Get the FCB from RX_CONTEXT */
1592 Fcb = (PFCB)RxContext->pFcb;
1593 SrvOpen = NULL;
1594 }
1595
1596 /* If we don't have RX_CONTEXT, allocte one, we'll need it */
1597 if (RxContext == NULL)
1598 {
1599 ASSERT(Fobx != NULL);
1600
1602 if (LocalContext == NULL)
1603 {
1605 }
1606
1607 LocalContext->MajorFunction = 2;
1608 LocalContext->pFcb = RX_GET_MRX_FCB(Fcb);
1609 LocalContext->pFobx = (PMRX_FOBX)Fobx;
1610 LocalContext->pRelevantSrvOpen = (PMRX_SRV_OPEN)Fobx->SrvOpen;
1611 }
1612 else
1613 {
1614 LocalContext = RxContext;
1615 }
1616
1618
1619 /* Now, close the FOBX */
1620 if (Fobx != NULL)
1621 {
1622 RxMarkFobxOnClose(Fobx);
1623 }
1624 else
1625 {
1626 InterlockedDecrement((volatile long *)&Fcb->OpenCount);
1627 }
1628
1629 /* If not a "standard" file, SRV_OPEN can be null */
1630 if (SrvOpen == NULL)
1631 {
1634
1635 if (LocalContext != RxContext)
1636 {
1637 RxDereferenceAndDeleteRxContext(LocalContext);
1638 }
1639
1640 return STATUS_SUCCESS;
1641 }
1642
1643 /* If SRV_OPEN isn't in a good condition, nothing to close */
1644 if (SrvOpen->Condition != Condition_Good)
1645 {
1646 if (LocalContext != RxContext)
1647 {
1648 RxDereferenceAndDeleteRxContext(LocalContext);
1649 }
1650
1651 return STATUS_SUCCESS;
1652 }
1653
1654 /* Decrease open count */
1655 if (SrvOpen->OpenCount > 0)
1656 {
1657 --SrvOpen->OpenCount;
1658 }
1659
1660 /* If we're the only one left, is there a FOBX handled by Scavenger? */
1661 if (SrvOpen->OpenCount == 1)
1662 {
1663 if (!IsListEmpty(&SrvOpen->FobxList))
1664 {
1665 if (!IsListEmpty(&CONTAINING_RECORD(SrvOpen->FobxList.Flink, FOBX, FobxQLinks)->ScavengerFinalizationList))
1666 {
1667 SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
1668 }
1669 }
1670 }
1671
1672 /* Nothing left, purge FCB */
1673 if (SrvOpen->OpenCount == 0 && RxContext == NULL)
1674 {
1675 RxPurgeNetFcb(Fcb, LocalContext);
1676 }
1677
1678 /* Already closed? Job done! */
1679 SrvOpen = Fobx->SrvOpen;
1680 if (SrvOpen == NULL ||
1681 (SrvOpen->OpenCount != 0 && !BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING)) ||
1682 BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
1683 {
1684 SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
1685 if (LocalContext != RxContext)
1686 {
1687 RxDereferenceAndDeleteRxContext(LocalContext);
1688 }
1689
1690 return STATUS_SUCCESS;
1691 }
1692
1694
1695 /* Inform mini-rdr about closing */
1696 MINIRDR_CALL(Status, LocalContext, Fcb->MRxDispatch, MRxCloseSrvOpen, (LocalContext));
1697 DPRINT("MRxCloseSrvOpen returned: %lx, called with RX_CONTEXT %p for FOBX %p (FCB %p, SRV_OPEN %p)\n ",
1698 Status, RxContext, Fobx, Fcb, SrvOpen);
1699
1700 /* And mark as such */
1701 SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED);
1702 SrvOpen->Key = (PVOID)-1;
1703
1704 /* If we were delayed, we're not! */
1705 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED))
1706 {
1707 InterlockedDecrement(&((PSRV_CALL)Fcb->pNetRoot->pSrvCall)->NumberOfCloseDelayedFiles);
1708 }
1709
1710 /* Clear access */
1713
1714 /* Dereference */
1716
1717 /* Mark the FOBX closed as well */
1718 SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
1719
1720 if (LocalContext != RxContext)
1721 {
1722 RxDereferenceAndDeleteRxContext(LocalContext);
1723 }
1724
1725 return Status;
1726}
1727
1728/*
1729 * @implemented
1730 */
1733 PRX_CONTEXT RxContext)
1734{
1737 PSRV_OPEN SrvOpen;
1740 RX_BLOCK_CONDITION FcbCondition;
1741
1744
1745 PAGED_CODE();
1746
1747 DPRINT("RxCollapseOrCreateSrvOpen(%p)\n", RxContext);
1748
1750 ++capFcb->UncleanCount;
1751
1752 DesiredAccess = capPARAMS->Parameters.Create.SecurityContext->DesiredAccess & FILE_ALL_ACCESS;
1753 ShareAccess = capPARAMS->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS;
1754
1755 Disposition = RxContext->Create.NtCreateParameters.Disposition;
1756
1757 /* Try to find a reusable SRV_OPEN */
1759 if (Status == STATUS_NOT_FOUND)
1760 {
1761 /* If none found, create one */
1762 SrvOpen = RxCreateSrvOpen((PV_NET_ROOT)RxContext->Create.pVNetRoot, capFcb);
1763 if (SrvOpen == NULL)
1764 {
1766 }
1767 else
1768 {
1769 SrvOpen->DesiredAccess = DesiredAccess;
1770 SrvOpen->ShareAccess = ShareAccess;
1772 }
1773
1774 RxContext->pRelevantSrvOpen = (PMRX_SRV_OPEN)SrvOpen;
1775
1776 if (Status != STATUS_SUCCESS)
1777 {
1778 FcbCondition = Condition_Bad;
1779 }
1780 else
1781 {
1783
1784 /* Cookie to check the mini-rdr doesn't mess with RX_CONTEXT */
1785 RxContext->CurrentIrp->IoStatus.Information = 0xABCDEF;
1786 /* Inform the mini-rdr we're handling a create */
1787 MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxCreate, (RxContext));
1788 ASSERT(RxContext->CurrentIrp->IoStatus.Information == 0xABCDEF);
1789
1790 DPRINT("MRxCreate returned: %x\n", Status);
1791 if (Status == STATUS_SUCCESS)
1792 {
1793 /* In case of overwrite, reset file size */
1795 {
1797 capFcb->Header.AllocationSize.QuadPart = 0LL;
1798 capFcb->Header.FileSize.QuadPart = 0LL;
1799 capFcb->Header.ValidDataLength.QuadPart = 0LL;
1800 RxContext->CurrentIrpSp->FileObject->SectionObjectPointer = &capFcb->NonPaged->SectionObjectPointers;
1801 CcSetFileSizes(RxContext->CurrentIrpSp->FileObject, (PCC_FILE_SIZES)&capFcb->Header.AllocationSize);
1803 }
1804 else
1805 {
1806 /* Otherwise, adjust sizes */
1807 RxContext->CurrentIrpSp->FileObject->SectionObjectPointer = &capFcb->NonPaged->SectionObjectPointers;
1808 if (CcIsFileCached(RxContext->CurrentIrpSp->FileObject))
1809 {
1811 }
1812 CcSetFileSizes(RxContext->CurrentIrpSp->FileObject, (PCC_FILE_SIZES)&capFcb->Header.AllocationSize);
1813 }
1814 }
1815
1816 /* Set the IoStatus with information returned by mini-rdr */
1817 RxContext->CurrentIrp->IoStatus.Information = RxContext->Create.ReturnedCreateInformation;
1818
1819 SrvOpen->OpenStatus = Status;
1820 /* Set SRV_OPEN state - good or bad - depending on whether create succeed */
1822
1824
1826
1827 if (Status == STATUS_SUCCESS)
1828 {
1829 if (BooleanFlagOn(capPARAMS->Parameters.Create.Options, FILE_DELETE_ON_CLOSE))
1830 {
1832 }
1833 SrvOpen->CreateOptions = RxContext->Create.NtCreateParameters.CreateOptions;
1834 FcbCondition = Condition_Good;
1835 }
1836 else
1837 {
1838 FcbCondition = Condition_Bad;
1840 RxContext->pRelevantSrvOpen = NULL;
1841
1842 if (RxContext->pFobx != NULL)
1843 {
1845 RxContext->pFobx = NULL;
1846 }
1847 }
1848 }
1849
1850 /* Set FCB state - good or bad - depending on whether create succeed */
1851 DPRINT("Transitioning FCB %p to condition %lx\n", capFcb, capFcb->Condition);
1852 RxTransitionNetFcb(capFcb, FcbCondition);
1853 }
1854 else if (Status == STATUS_SUCCESS)
1855 {
1856 BOOLEAN IsGood, ExtraOpen;
1857
1858 /* A reusable SRV_OPEN was found */
1860 ExtraOpen = FALSE;
1861
1862 SrvOpen = (PSRV_OPEN)RxContext->pRelevantSrvOpen;
1863
1864 IsGood = (SrvOpen->Condition == Condition_Good);
1865 /* If the SRV_OPEN isn't in a stable situation, wait for it to become stable */
1866 if (!StableCondition(SrvOpen->Condition))
1867 {
1868 RxReferenceSrvOpen(SrvOpen);
1869 ++SrvOpen->OpenCount;
1870 ExtraOpen = TRUE;
1871
1872 RxReleaseFcb(RxContext, capFcb);
1873 RxContext->Create.FcbAcquired = FALSE;
1874
1875 RxWaitForStableSrvOpen(SrvOpen, RxContext);
1876
1877 if (NT_SUCCESS(RxAcquireExclusiveFcb(RxContext, capFcb)))
1878 {
1879 RxContext->Create.FcbAcquired = TRUE;
1880 }
1881
1882 IsGood = (SrvOpen->Condition == Condition_Good);
1883 }
1884
1885 /* Inform the mini-rdr we do an opening with a reused SRV_OPEN */
1886 if (IsGood)
1887 {
1888 MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxCollapseOpen, (RxContext));
1889
1891 }
1892 else
1893 {
1894 Status = SrvOpen->OpenStatus;
1895 }
1896
1897 if (ExtraOpen)
1898 {
1899 --SrvOpen->OpenCount;
1901 }
1902 }
1903
1904 --capFcb->UncleanCount;
1905
1906 DPRINT("Status: %x\n", Status);
1907 return Status;
1908}
1909
1910/*
1911 * @implemented
1912 */
1914NTAPI
1917{
1918#define BugCheckFileId RDBSS_BUG_CHECK_CLEANUP
1919 PFCB Fcb;
1920 PFOBX Fobx;
1923 PNET_ROOT NetRoot;
1925 LARGE_INTEGER TruncateSize;
1926 PLARGE_INTEGER TruncateSizePtr;
1927 BOOLEAN NeedPurge, FcbTableAcquired, OneLeft, IsFile, FcbAcquired, LeftForDelete;
1928
1929 PAGED_CODE();
1930
1931 Fcb = (PFCB)Context->pFcb;
1932 Fobx = (PFOBX)Context->pFobx;
1933 DPRINT("RxCommonCleanup(%p); FOBX: %p, FCB: %p\n", Context, Fobx, Fcb);
1934
1935 /* File system closing, it's OK */
1936 if (Fobx == NULL)
1937 {
1938 if (Fcb->UncleanCount > 0)
1939 {
1940 InterlockedDecrement((volatile long *)&Fcb->UncleanCount);
1941 }
1942
1943 return STATUS_SUCCESS;
1944 }
1945
1946 /* Check we have a correct FCB type */
1951 {
1952 DPRINT1("Invalid Fcb type for %p\n", Fcb);
1953 RxBugCheck(Fcb->Header.NodeTypeCode, 0, 0);
1954 }
1955
1956 FileObject = Context->CurrentIrpSp->FileObject;
1958
1959 RxMarkFobxOnCleanup(Fobx, &NeedPurge);
1960
1962 if (!NT_SUCCESS(Status))
1963 {
1964 return Status;
1965 }
1966
1967 FcbAcquired = TRUE;
1968
1969 Fobx->AssociatedFileObject = NULL;
1970
1971 /* In case it was already orphaned */
1973 {
1974 ASSERT(Fcb->UncleanCount != 0);
1975 InterlockedDecrement((volatile long *)&Fcb->UncleanCount);
1976
1978 {
1979 --Fcb->UncachedUncleanCount;
1980 }
1981
1982 /* Inform mini-rdr */
1983 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxCleanupFobx, (Context));
1984
1985 ASSERT(Fobx->SrvOpen->UncleanFobxCount != 0);
1986 --Fobx->SrvOpen->UncleanFobxCount;
1987
1989
1991
1992 return STATUS_SUCCESS;
1993 }
1994
1995 /* Report the fact that file could be set as delete on close */
1996 if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE))
1997 {
1999 }
2000
2001 /* Cancel any pending notification */
2003
2004 /* Backup open count before we start playing with it */
2006
2007 NetRoot = (PNET_ROOT)Fcb->pNetRoot;
2008 FcbTableAcquired = FALSE;
2009 LeftForDelete = FALSE;
2010 OneLeft = (Fcb->UncleanCount == 1);
2011
2012 _SEH2_TRY
2013 {
2014 /* Unclean count and delete on close? Verify whether we're the one */
2016 {
2018 {
2019 FcbTableAcquired = TRUE;
2020 }
2021 else
2022 {
2024
2026
2028 if (Status != STATUS_SUCCESS)
2029 {
2031 return Status;
2032 }
2033
2034 FcbTableAcquired = TRUE;
2035 }
2036
2037 /* That means we'll perform the delete on close! */
2038 if (Fcb->UncleanCount == 1)
2039 {
2040 LeftForDelete = TRUE;
2041 }
2042 else
2043 {
2045 FcbTableAcquired = FALSE;
2046 }
2047 }
2048
2049 IsFile = FALSE;
2050 TruncateSizePtr = NULL;
2051 /* Handle cleanup for pipes and printers */
2052 if (NetRoot->Type == NET_ROOT_PIPE || NetRoot->Type == NET_ROOT_PRINT)
2053 {
2055 }
2056 /* Handle cleanup for files */
2057 else if (NetRoot->Type == NET_ROOT_DISK || NetRoot->Type == NET_ROOT_WILD)
2058 {
2059 Context->LowIoContext.Flags |= LOWIO_CONTEXT_FLAG_SAVEUNLOCKS;
2061 {
2062 /* First, unlock */
2064
2065 /* If there are still locks to release, proceed */
2066 if (Context->LowIoContext.ParamsFor.Locks.LockList != NULL)
2067 {
2069 Context->LowIoContext.ParamsFor.Locks.Flags = 0;
2071 }
2072
2073 /* Fix times and size */
2075
2076 /* If we're the only one left... */
2077 if (OneLeft)
2078 {
2079 /* And if we're supposed to delete on close */
2080 if (LeftForDelete)
2081 {
2082 /* Update the sizes */
2084 Fcb->Header.FileSize.QuadPart = 0;
2085 Fcb->Header.ValidDataLength.QuadPart = 0;
2087 }
2088 /* Otherwise, call the mini-rdr to adjust sizes */
2089 else
2090 {
2091 /* File got grown up, fill with zeroes */
2093 (Fcb->Header.ValidDataLength.QuadPart < Fcb->Header.FileSize.QuadPart))
2094 {
2095 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxZeroExtend, (Context));
2096 Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
2097 }
2098
2099 /* File was truncated, let mini-rdr proceed */
2101 {
2102 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxTruncate, (Context));
2104
2105 /* Keep track of file change for Cc uninit */
2106 TruncateSize.QuadPart = Fcb->Header.FileSize.QuadPart;
2107 TruncateSizePtr = &TruncateSize;
2108 }
2109 }
2110 }
2111
2112 /* If RxMarkFobxOnCleanup() asked for purge, make sure we're the only one left first */
2113 if (NeedPurge)
2114 {
2115 if (!OneLeft)
2116 {
2117 NeedPurge = FALSE;
2118 }
2119 }
2120 /* Otherwise, try to see whether we can purge */
2121 else
2122 {
2123 NeedPurge = (OneLeft && (LeftForDelete || !BooleanFlagOn(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED)));
2124 }
2125
2126 IsFile = TRUE;
2127 }
2128 }
2129
2130 /* We have to still be there! */
2131 ASSERT(Fcb->UncleanCount != 0);
2132 InterlockedDecrement((volatile long *)&Fcb->UncleanCount);
2133
2135 {
2136 --Fcb->UncachedUncleanCount;
2137 }
2138
2139 /* Inform mini-rdr about ongoing cleanup */
2140 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxCleanupFobx, (Context));
2141
2142 ASSERT(Fobx->SrvOpen->UncleanFobxCount != 0);
2143 --Fobx->SrvOpen->UncleanFobxCount;
2144
2145 /* Flush cache */
2147 {
2148 /* Only if we're the last standing */
2150 Fcb->UncleanCount == Fcb->UncachedUncleanCount)
2151 {
2152 DPRINT("Flushing %p due to last cached handle cleanup\n", Context);
2154 }
2155 }
2156 else
2157 {
2158 /* Always */
2160 {
2161 DPRINT("Flushing %p on cleanup\n", Context);
2163 }
2164 }
2165
2166 /* If only remaining uncached & unclean, then flush and purge */
2168 {
2169 if (Fcb->UncachedUncleanCount != 0)
2170 {
2171 if (Fcb->UncachedUncleanCount == Fcb->UncleanCount &&
2173 {
2174 DPRINT("Flushing FCB in system cache for %p\n", Context);
2176 }
2177 }
2178 }
2179
2180 /* If purge required, and not about to delete, flush */
2181 if (!LeftForDelete && NeedPurge)
2182 {
2183 DPRINT("Flushing FCB in system cache for %p\n", Context);
2185 }
2186
2187 /* If it was a file, drop cache */
2188 if (IsFile)
2189 {
2190 DPRINT("Uninit cache map for file\n");
2191 RxUninitializeCacheMap(Context, FileObject, TruncateSizePtr);
2192 }
2193
2194 /* If that's the one left for deletion, or if it needs purge, flush */
2195 if (LeftForDelete || NeedPurge)
2196 {
2197 RxPurgeFcbInSystemCache(Fcb, NULL, 0, FALSE, !LeftForDelete);
2198 /* If that's for deletion, also remove from FCB table */
2199 if (LeftForDelete)
2200 {
2203 FcbTableAcquired = FALSE;
2204 }
2205 }
2206
2207 /* Remove any share access */
2208 if (OpenCount != 0 && NetRoot->Type == NET_ROOT_DISK)
2209 {
2210 RxRemoveShareAccess(FileObject, &Fcb->ShareAccess, "Cleanup the share access", "ClnUpShr");
2211 }
2212
2213 /* In case there's caching, on a file, and we were asked to drop collapsing, handle it */
2214 if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_FILE && BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING) &&
2215 RxWriteCacheingAllowed(Fcb, Fobx->pSrvOpen))
2216 {
2217 NTSTATUS InternalStatus;
2218 PRX_CONTEXT InternalContext;
2219
2220 /* If we can properly set EOF, there's no need to drop collapsing, try to do it */
2221 InternalStatus = STATUS_UNSUCCESSFUL;
2222 InternalContext = RxCreateRxContext(Context->CurrentIrp,
2225 if (InternalContext != NULL)
2226 {
2228
2229 InternalStatus = STATUS_SUCCESS;
2230
2231 /* Initialize the context for file information set */
2232 InternalContext->pFcb = RX_GET_MRX_FCB(Fcb);
2233 InternalContext->pFobx = (PMRX_FOBX)Fobx;
2234 InternalContext->pRelevantSrvOpen = Fobx->pSrvOpen;
2235
2236 /* Get EOF from the FCB */
2237 FileEOF.EndOfFile.QuadPart = Fcb->Header.FileSize.QuadPart;
2238 InternalContext->Info.FileInformationClass = FileEndOfFileInformation;
2239 InternalContext->Info.Buffer = &FileEOF;
2240 InternalContext->Info.Length = sizeof(FileEOF);
2241
2242 /* Call the mini-rdr */
2243 MINIRDR_CALL_THROUGH(InternalStatus, Fcb->MRxDispatch, MRxSetFileInfo, (InternalContext));
2244
2245 /* We're done */
2246 RxDereferenceAndDeleteRxContext(InternalContext);
2247 }
2248
2249 /* We tried, so, clean the FOBX flag */
2250 ClearFlag(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING);
2251 /* If it failed, then, disable collapsing on the FCB */
2252 if (!NT_SUCCESS(InternalStatus))
2253 {
2255 }
2256 }
2257
2258 /* We're clean! */
2260
2261 FcbAcquired = FALSE;
2263 }
2265 {
2266 if (FcbAcquired)
2267 {
2269 }
2270
2271 if (FcbTableAcquired)
2272 {
2274 }
2275 }
2276 _SEH2_END;
2277
2278 return Status;
2279#undef BugCheckFileId
2280}
2281
2283NTAPI
2286{
2287#define BugCheckFileId RDBSS_BUG_CHECK_CLOSE
2288 PFCB Fcb;
2289 PFOBX Fobx;
2292 BOOLEAN DereferenceFobx, AcquiredFcb;
2293
2294 PAGED_CODE();
2295
2296 Fcb = (PFCB)Context->pFcb;
2297 Fobx = (PFOBX)Context->pFobx;
2298 FileObject = Context->CurrentIrpSp->FileObject;
2299 DPRINT("RxCommonClose(%p); FOBX: %p, FCB: %p, FO: %p\n", Context, Fobx, Fcb, FileObject);
2300
2302 if (!NT_SUCCESS(Status))
2303 {
2304 return Status;
2305 }
2306
2307 AcquiredFcb = TRUE;
2308 _SEH2_TRY
2309 {
2310 BOOLEAN Freed;
2311
2312 /* Check our FCB type is expected */
2316 {
2317 RxBugCheck(NodeType(Fcb), 0, 0);
2318 }
2319
2321
2322 DereferenceFobx = FALSE;
2323 /* If we're not closing FS */
2324 if (Fobx != NULL)
2325 {
2326 PSRV_OPEN SrvOpen;
2327 PSRV_CALL SrvCall;
2328
2329 SrvOpen = (PSRV_OPEN)Fobx->pSrvOpen;
2330 SrvCall = (PSRV_CALL)Fcb->pNetRoot->pSrvCall;
2331 /* Handle delayed close */
2333 {
2335 {
2337 {
2338 DPRINT("Delay close for FOBX: %p, SrvOpen %p\n", Fobx, SrvOpen);
2339
2340 if (SrvOpen->OpenCount == 1 && !BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_COLLAPSING_DISABLED))
2341 {
2342 if (InterlockedIncrement(&SrvCall->NumberOfCloseDelayedFiles) >= SrvCall->MaximumNumberOfCloseDelayedFiles)
2343 {
2345 }
2346 else
2347 {
2348 DereferenceFobx = TRUE;
2349 SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
2350 }
2351 }
2352 }
2353 }
2354 }
2355
2356 /* If we reach maximum of delayed close/or if there are no delayed close */
2357 if (!DereferenceFobx)
2358 {
2359 PNET_ROOT NetRoot;
2360
2361 NetRoot = (PNET_ROOT)Fcb->pNetRoot;
2362 if (NetRoot->Type != NET_ROOT_PRINT)
2363 {
2364 /* Delete if asked */
2365 if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE))
2366 {
2369
2371
2375
2378 }
2379 }
2380 }
2381
2382 RxMarkFobxOnClose(Fobx);
2383 }
2384
2385 if (DereferenceFobx)
2386 {
2387 ASSERT(Fobx != NULL);
2389 }
2390 else
2391 {
2393 if (Fobx != NULL)
2394 {
2396 }
2397 }
2398
2400 AcquiredFcb = !Freed;
2401
2402 FileObject->FsContext = (PVOID)-1;
2403
2404 if (Freed)
2405 {
2406 RxTrackerUpdateHistory(Context, NULL, TRACKER_FCB_FREE, __LINE__, __FILE__, 0);
2407 }
2408 else
2409 {
2411 AcquiredFcb = FALSE;
2412 }
2413 }
2415 {
2417 {
2418 if (AcquiredFcb)
2419 {
2421 }
2422 }
2423 else
2424 {
2425 ASSERT(!AcquiredFcb);
2426 }
2427 }
2428 _SEH2_END;
2429
2430 DPRINT("Status: %x\n", Status);
2431 return Status;
2432#undef BugCheckFileId
2433}
2434
2435/*
2436 * @implemented
2437 */
2439NTAPI
2442{
2443 PIRP Irp;
2447
2448 PAGED_CODE();
2449
2450 DPRINT("RxCommonCreate(%p)\n", Context);
2451
2452 Irp = Context->CurrentIrp;
2453 Stack = Context->CurrentIrpSp;
2454 FileObject = Stack->FileObject;
2455
2456 /* Check whether that's a device opening */
2457 if (FileObject->FileName.Length == 0 && FileObject->RelatedFileObject == NULL)
2458 {
2459 FileObject->FsContext = &RxDeviceFCB;
2460 FileObject->FsContext2 = NULL;
2461
2462 ++RxDeviceFCB.NodeReferenceCount;
2464
2465 Irp->IoStatus.Information = FILE_OPENED;
2466 DPRINT("Device opening FO: %p, DO: %p, Name: %wZ\n", FileObject, Context->RxDeviceObject, &Context->RxDeviceObject->DeviceName);
2467
2469 }
2470 else
2471 {
2472 PFCB RelatedFcb = NULL;
2473
2474 /* Make sure caller is consistent */
2477 {
2478 DPRINT1("Create.Options: %x\n", Stack->Parameters.Create.Options);
2480 }
2481
2482 DPRINT("Ctxt: %p, FO: %p, Options: %lx, Flags: %lx, Attr: %lx, ShareAccess: %lx, DesiredAccess: %lx\n",
2483 Context, FileObject, Stack->Parameters.Create.Options, Stack->Flags, Stack->Parameters.Create.FileAttributes,
2484 Stack->Parameters.Create.ShareAccess, Stack->Parameters.Create.SecurityContext->DesiredAccess);
2485 DPRINT("FileName: %wZ\n", &FileObject->FileName);
2486
2487 if (FileObject->RelatedFileObject != NULL)
2488 {
2489 RelatedFcb = FileObject->RelatedFileObject->FsContext;
2490 DPRINT("Rel FO: %p, path: %wZ\n", FileObject->RelatedFileObject, RelatedFcb->FcbTableEntry.Path);
2491 }
2492
2493 /* Going to rename? */
2495 {
2496 DPRINT("TargetDir!\n");
2497 }
2498
2499 /* Copy create parameters to the context */
2501
2502 /* If the caller wants to establish a connection, go ahead */
2503 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_CREATE_TREE_CONNECTION))
2504 {
2506 }
2507 else
2508 {
2509 /* Validate file name */
2510 if (FileObject->FileName.Length > sizeof(WCHAR) &&
2511 FileObject->FileName.Buffer[1] == OBJ_NAME_PATH_SEPARATOR &&
2512 FileObject->FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2513 {
2514 FileObject->FileName.Length -= sizeof(WCHAR);
2515 RtlMoveMemory(&FileObject->FileName.Buffer[0], &FileObject->FileName.Buffer[1],
2516 FileObject->FileName.Length);
2517
2518 if (FileObject->FileName.Length > sizeof(WCHAR) &&
2519 FileObject->FileName.Buffer[1] == OBJ_NAME_PATH_SEPARATOR &&
2520 FileObject->FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2521 {
2523 }
2524 }
2525
2526 /* Attempt to open the file */
2527 do
2528 {
2529 UNICODE_STRING NetRootName;
2530
2531 /* Strip last \ if required */
2532 if (FileObject->FileName.Length != 0 &&
2533 FileObject->FileName.Buffer[FileObject->FileName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
2534 {
2535 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE))
2536 {
2538 }
2539
2540 FileObject->FileName.Length -= sizeof(WCHAR);
2542 }
2543
2545 {
2546 FileObject->Flags |= FO_WRITE_THROUGH;
2547 }
2548
2549 /* Get the associated net root to opening */
2550 Status = RxCanonicalizeNameAndObtainNetRoot(Context, &FileObject->FileName, &NetRootName);
2552 {
2553 break;
2554 }
2555
2556 /* And attempt to open */
2557 Status = RxCreateFromNetRoot(Context, &NetRootName);
2559 {
2561
2562 /* If that happens for file creation, fail for real */
2563 if (Context->Create.NtCreateParameters.Disposition == FILE_CREATE)
2564 {
2566 }
2567 else
2568 {
2569 /* Otherwise, if possible, attempt to scavenger current FOBX
2570 * to check whether a dormant FOBX is the reason for sharing violation
2571 */
2572 if (Context->Create.TryForScavengingOnSharingViolation &&
2573 !Context->Create.ScavengingAlreadyTried)
2574 {
2575 /* Only doable with a VNetRoot */
2576 if (Context->Create.pVNetRoot != NULL)
2577 {
2578 PV_NET_ROOT VNetRoot;
2579 NT_CREATE_PARAMETERS SavedParameters;
2580
2581 /* Save create parameters */
2582 RtlCopyMemory(&SavedParameters, &Context->Create.NtCreateParameters, sizeof(NT_CREATE_PARAMETERS));
2583
2584 /* Reference the VNetRoot for the scavenging time */
2585 VNetRoot = (PV_NET_ROOT)Context->Create.pVNetRoot;
2586 RxReferenceVNetRoot(VNetRoot);
2587
2588 /* Prepare the RX_CONTEXT for reuse */
2591
2592 /* Copy what we saved */
2593 RtlCopyMemory(&Context->Create.NtCreateParameters, &SavedParameters, sizeof(NT_CREATE_PARAMETERS));
2594
2595 /* And recopy what can be */
2597
2598 /* And start purging, then scavenging FOBX */
2599 RxPurgeRelatedFobxs((PNET_ROOT)VNetRoot->pNetRoot, Context,
2601 RxScavengeFobxsForNetRoot((PNET_ROOT)VNetRoot->pNetRoot,
2602 NULL, TRUE);
2603
2604 /* Ask for a second round */
2606
2607 /* Keep track we already scavenged */
2608 Context->Create.ScavengingAlreadyTried = TRUE;
2609
2610 /* Reference our SRV_CALL for CBS handling */
2611 RxReferenceSrvCall(VNetRoot->pNetRoot->pSrvCall);
2612 RxpProcessChangeBufferingStateRequests((PSRV_CALL)VNetRoot->pNetRoot->pSrvCall, FALSE);
2613
2614 /* Drop our extra reference */
2616 }
2617 }
2618 }
2619 }
2620 else if (Status == STATUS_REPARSE)
2621 {
2622 Context->CurrentIrp->IoStatus.Information = 0;
2623 }
2624 else
2625 {
2627 }
2628 }
2630 }
2631
2632 if (Status == STATUS_RETRY)
2633 {
2635 }
2637 }
2638
2639 DPRINT("Status: %lx\n", Status);
2640 return Status;
2641}
2642
2643/*
2644 * @implemented
2645 */
2647NTAPI
2650{
2651 PMRX_FCB Fcb;
2653
2654 PAGED_CODE();
2655
2656 DPRINT("RxCommonDevFCBCleanup(%p)\n", Context);
2657
2658 Fcb = Context->pFcb;
2661
2662 /* Our FOBX if set, has to be a VNetRoot */
2663 if (Context->pFobx != NULL)
2664 {
2665 RxAcquirePrefixTableLockShared(Context->RxDeviceObject->pRxNetNameTable, TRUE);
2666 if (Context->pFobx->NodeTypeCode != RDBSS_NTC_V_NETROOT)
2667 {
2669 }
2670 RxReleasePrefixTableLock(Context->RxDeviceObject->pRxNetNameTable);
2671 }
2672 else
2673 {
2674 --Fcb->UncleanCount;
2675 }
2676
2677 return Status;
2678}
2679
2680/*
2681 * @implemented
2682 */
2684NTAPI
2687{
2688 PMRX_FCB Fcb;
2690 PMRX_V_NET_ROOT NetRoot;
2691
2692 PAGED_CODE();
2693
2694 DPRINT("RxCommonDevFCBClose(%p)\n", Context);
2695
2696 Fcb = Context->pFcb;
2697 NetRoot = (PMRX_V_NET_ROOT)Context->pFobx;
2700
2701 /* Our FOBX if set, has to be a VNetRoot */
2702 if (NetRoot != NULL)
2703 {
2704 RxAcquirePrefixTableLockExclusive(Context->RxDeviceObject->pRxNetNameTable, TRUE);
2705 if (NetRoot->NodeTypeCode == RDBSS_NTC_V_NETROOT)
2706 {
2707 --NetRoot->NumberOfOpens;
2709 }
2710 else
2711 {
2713 }
2714 RxReleasePrefixTableLock(Context->RxDeviceObject->pRxNetNameTable);
2715 }
2716 else
2717 {
2718 --Fcb->OpenCount;
2719 }
2720
2721 return Status;
2722}
2723
2725NTAPI
2728{
2731}
2732
2733/*
2734 * @implemented
2735 */
2737NTAPI
2740{
2742
2743 PAGED_CODE();
2744
2745 DPRINT("RxCommonDevFCBIoCtl(%p)\n", Context);
2746
2747 if (Context->pFobx != NULL)
2748 {
2749 return STATUS_INVALID_HANDLE;
2750 }
2751
2752 /* Is that a prefix claim from MUP? */
2753 if (Context->CurrentIrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH)
2754 {
2755 return RxPrefixClaim(Context);
2756 }
2757
2758 /* Otherwise, pass through the mini-rdr */
2760 if (Status != STATUS_PENDING)
2761 {
2762 if (Context->PostRequest)
2763 {
2764 Context->ResumeRoutine = RxCommonDevFCBIoCtl;
2766 }
2767 }
2768
2769 DPRINT("Status: %lx\n", Status);
2770 return Status;
2771}
2772
2774NTAPI
2777{
2780}
2781
2782/*
2783 * @implemented
2784 */
2786NTAPI
2789{
2791
2792 PAGED_CODE();
2793
2794 /* Prefix claim is only allowed for device, not files */
2795 if (Context->CurrentIrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH)
2796 {
2798 }
2799
2800 /* Submit to mini-rdr */
2803 if (Status == STATUS_PENDING)
2804 {
2806 }
2807
2808 return Status;
2809}
2810
2811/*
2812 * @implemented
2813 */
2815NTAPI
2818{
2819 PFCB Fcb;
2820 PFOBX Fobx;
2823
2824 PAGED_CODE();
2825
2826 Fcb = (PFCB)Context->pFcb;
2827 Fobx = (PFOBX)Context->pFobx;
2828 Stack = Context->CurrentIrpSp;
2829 DPRINT("RxCommonDirectoryControl(%p) FOBX: %p, FCB: %p, Minor: %d\n", Context, Fobx, Fcb, Stack->MinorFunction);
2830
2831 /* Call the appropriate helper */
2832 if (Stack->MinorFunction == IRP_MN_QUERY_DIRECTORY)
2833 {
2835 }
2836 else if (Stack->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY)
2837 {
2839 if (Status == STATUS_PENDING)
2840 {
2842 }
2843 }
2844 else
2845 {
2847 }
2848
2849 return Status;
2850}
2851
2853NTAPI
2856{
2859}
2860
2862NTAPI
2865{
2866 PIRP Irp;
2869
2870 PAGED_CODE();
2871
2872 Irp = Context->CurrentIrp;
2873 Stack = Context->CurrentIrpSp;
2874 ControlCode = Stack->Parameters.FileSystemControl.FsControlCode;
2875
2876 DPRINT1("RxCommonFileSystemControl: %p, %p, %d, %lx\n", Context, Irp, Stack->MinorFunction, ControlCode);
2877
2880}
2881
2883NTAPI
2886{
2889}
2890
2892NTAPI
2895{
2898}
2899
2901NTAPI
2904{
2907}
2908
2909/*
2910 * @implemented
2911 */
2913NTAPI
2916{
2917#define SET_SIZE_AND_QUERY(AlreadyConsummed, Function) \
2918 Context->Info.Length = Stack->Parameters.QueryFile.Length - (AlreadyConsummed); \
2919 Status = Function(Context, Add2Ptr(Buffer, AlreadyConsummed))
2920
2921 PFCB Fcb;
2922 PIRP Irp;
2923 PFOBX Fobx;
2927 FILE_INFORMATION_CLASS FileInfoClass;
2928
2929 PAGED_CODE();
2930
2931 Fcb = (PFCB)Context->pFcb;
2932 Fobx = (PFOBX)Context->pFobx;
2933 DPRINT("RxCommonQueryInformation(%p) FCB: %p, FOBX: %p\n", Context, Fcb, Fobx);
2934
2935 Irp = Context->CurrentIrp;
2936 Stack = Context->CurrentIrpSp;
2937 DPRINT("Buffer: %p, Length: %lx, Class: %ld\n", Irp->AssociatedIrp.SystemBuffer,
2938 Stack->Parameters.QueryFile.Length, Stack->Parameters.QueryFile.FileInformationClass);
2939
2940 Context->Info.Length = Stack->Parameters.QueryFile.Length;
2941 FileInfoClass = Stack->Parameters.QueryFile.FileInformationClass;
2942
2943 Locked = FALSE;
2944 _SEH2_TRY
2945 {
2946 PVOID Buffer;
2947
2948 /* Get a writable buffer */
2950 if (Buffer == NULL)
2951 {
2954 }
2955 /* Zero it */
2956 RtlZeroMemory(Buffer, Context->Info.Length);
2957
2958 /* Validate file type */
2960 {
2962 {
2965 }
2967 {
2969 {
2971 }
2972 else
2973 {
2975 }
2976
2978 }
2979 }
2980
2981 /* Acquire the right lock */
2983 FileInfoClass != FileNameInformation)
2984 {
2985 if (FileInfoClass == FileCompressionInformation)
2986 {
2988 }
2989 else
2990 {
2992 }
2993
2995 {
2998 }
2999 else if (!NT_SUCCESS(Status))
3000 {
3002 }
3003
3004 Locked = TRUE;
3005 }
3006
3007 /* Dispatch to the right helper */
3008 switch (FileInfoClass)
3009 {
3012 break;
3013
3016 break;
3017
3020 break;
3021
3022 case FileEaInformation:
3024 break;
3025
3028 break;
3029
3030 case FileAllInformation:
3032 if (!NT_SUCCESS(Status))
3033 {
3034 break;
3035 }
3036
3038 if (!NT_SUCCESS(Status))
3039 {
3040 break;
3041 }
3042
3045 if (!NT_SUCCESS(Status))
3046 {
3047 break;
3048 }
3049
3053 if (!NT_SUCCESS(Status))
3054 {
3055 break;
3056 }
3057
3062 if (!NT_SUCCESS(Status))
3063 {
3064 break;
3065 }
3066
3070 sizeof(FILE_EA_INFORMATION) +
3072 break;
3073
3076 break;
3077
3082 break;
3083
3086 break;
3087
3088 default:
3089 Context->IoStatusBlock.Status = RxpQueryInfoMiniRdr(Context, FileInfoClass, Buffer);
3090 Status = Context->IoStatusBlock.Status;
3091 break;
3092 }
3093
3094 if (Context->Info.Length < 0)
3095 {
3097 Context->Info.Length = Stack->Parameters.QueryFile.Length;
3098 }
3099
3100 Irp->IoStatus.Information = Stack->Parameters.QueryFile.Length - Context->Info.Length;
3101 }
3103 {
3104 if (Locked)
3105 {
3107 }
3108 }
3109 _SEH2_END;
3110
3111 DPRINT("Status: %x\n", Status);
3112 return Status;
3113
3114#undef SET_SIZE_AND_QUERY
3115}
3116
3118NTAPI
3121{
3124}
3125
3127NTAPI
3130{
3133}
3134
3135/*
3136 * @implemented
3137 */
3139NTAPI
3142{
3143 PIRP Irp;
3144 PFCB Fcb;
3145 PFOBX Fobx;
3148
3149 PAGED_CODE();
3150
3151 Fcb = (PFCB)Context->pFcb;
3152 Fobx = (PFOBX)Context->pFobx;
3153
3154 DPRINT("RxCommonQueryVolumeInformation(%p) FCB: %p, FOBX: %p\n", Context, Fcb, Fobx);
3155
3156 Irp = Context->CurrentIrp;
3157 Stack = Context->CurrentIrpSp;
3158 DPRINT("Length: %lx, Class: %lx, Buffer %p\n", Stack->Parameters.QueryVolume.Length,
3159 Stack->Parameters.QueryVolume.FsInformationClass, Irp->AssociatedIrp.SystemBuffer);
3160
3161 Context->Info.FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
3162 Context->Info.Buffer = Irp->AssociatedIrp.SystemBuffer;
3163 Context->Info.Length = Stack->Parameters.QueryVolume.Length;
3164
3165 /* Forward to mini-rdr */
3166 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxQueryVolumeInfo, (Context));
3167
3168 /* Post request if mini-rdr asked to */
3169 if (Context->PostRequest)
3170 {
3172 }
3173 else
3174 {
3175 Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - Context->Info.Length;
3176 }
3177
3178 DPRINT("Status: %x\n", Status);
3179 return Status;
3180}
3181
3183NTAPI
3185 PRX_CONTEXT RxContext)
3186{
3187 PFCB Fcb;
3188 PIRP Irp;
3189 PFOBX Fobx;
3191 PNET_ROOT NetRoot;
3192 PVOID SystemBuffer;
3196 PLOWIO_CONTEXT LowIoContext;
3197 PRDBSS_DEVICE_OBJECT RxDeviceObject;
3198 ULONG ReadLength, CapturedRxContextSerialNumber = RxContext->SerialNumber;
3199 BOOLEAN CanWait, PagingIo, NoCache, Sync, PostRequest, IsPipe, ReadCachingEnabled, ReadCachingDisabled, InFsp, OwnerSet;
3200
3201 PAGED_CODE();
3202
3203 Fcb = (PFCB)RxContext->pFcb;
3204 Fobx = (PFOBX)RxContext->pFobx;
3205 DPRINT("RxCommonRead(%p) FOBX: %p, FCB: %p\n", RxContext, Fobx, Fcb);
3206
3207 /* Get some parameters */
3208 Irp = RxContext->CurrentIrp;
3209 Stack = RxContext->CurrentIrpSp;
3210 CanWait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
3211 PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
3212 NoCache = BooleanFlagOn(Irp->Flags, IRP_NOCACHE);
3214 InFsp = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
3215 ReadLength = Stack->Parameters.Read.Length;
3216 ByteOffset.QuadPart = Stack->Parameters.Read.ByteOffset.QuadPart;
3217 DPRINT("Reading: %lx@%I64x %s %s %s %s\n", ReadLength, ByteOffset.QuadPart,
3218 (CanWait ? "CW" : "!CW"), (PagingIo ? "PI" : "!PI"), (NoCache ? "NC" : "!NC"), (Sync ? "S" : "!S"));
3219
3221
3222 Irp->IoStatus.Information = 0;
3223
3224 /* Should the read be loud - so far, it's just ignored on ReactOS:
3225 * s/DPRINT/DPRINT1/g will make it loud
3226 */
3227 LowIoContext = &RxContext->LowIoContext;
3228 CheckForLoudOperations(RxContext);
3230 {
3231 DPRINT("LoudRead %I64x/%lx on %lx vdl/size/alloc %I64x/%I64x/%I64x\n",
3233 Fcb, Fcb->Header.ValidDataLength, Fcb->Header.FileSize, Fcb->Header.AllocationSize);
3234 }
3235
3236 RxDeviceObject = RxContext->RxDeviceObject;
3237 /* Update stats */
3238 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP) && Fcb->CachedNetRootType == NET_ROOT_DISK)
3239 {
3240 InterlockedIncrement((volatile long *)&RxDeviceObject->ReadOperations);
3241
3242 if (ByteOffset.QuadPart != Fobx->Specific.DiskFile.PredictedReadOffset)
3243 {
3244 InterlockedIncrement((volatile long *)&RxDeviceObject->RandomReadOperations);
3245 }
3246 Fobx->Specific.DiskFile.PredictedReadOffset = ByteOffset.QuadPart + ReadLength;
3247
3248 if (PagingIo)
3249 {
3251 }
3252 else if (NoCache)
3253 {
3255 }
3256 else
3257 {
3259 }
3260 }
3261
3262 /* A pagefile cannot be a pipe */
3263 IsPipe = Fcb->NetRoot->Type == NET_ROOT_PIPE;
3264 if (IsPipe && PagingIo)
3265 {
3267 }
3268
3269 /* Null-length read is no-op */
3270 if (ReadLength == 0)
3271 {
3272 return STATUS_SUCCESS;
3273 }
3274
3275 /* Validate FCB type */
3277 {
3279 }
3280
3281 /* Init the lowio context for possible forward */
3283
3284 PostRequest = FALSE;
3285 ReadCachingDisabled = FALSE;
3286 OwnerSet = FALSE;
3288 FileObject = Stack->FileObject;
3289 NetRoot = (PNET_ROOT)Fcb->pNetRoot;
3290 _SEH2_TRY
3291 {
3293
3294 /* If no caching, make sure current Cc data have been flushed */
3295 if (!PagingIo && NoCache && !ReadCachingEnabled && FileObject->SectionObjectPointer != NULL)
3296 {
3297 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
3299 {
3300 PostRequest = TRUE;
3302 }
3303 else if (Status != STATUS_SUCCESS)
3304 {
3306 }
3307
3308 ExAcquireResourceSharedLite(Fcb->Header.PagingIoResource, TRUE);
3309 CcFlushCache(FileObject->SectionObjectPointer, &ByteOffset, ReadLength, &Irp->IoStatus);
3310 RxReleasePagingIoResource(RxContext, Fcb);
3311
3312 if (!NT_SUCCESS(Irp->IoStatus.Status))
3313 {
3314 Status = Irp->IoStatus.Status;
3316 }
3317
3318 RxAcquirePagingIoResource(RxContext, Fcb);
3319 RxReleasePagingIoResource(RxContext, Fcb);
3320 }
3321
3322 /* Acquire the appropriate lock */
3323 if (PagingIo && !ReadCachingEnabled)
3324 {
3325 ASSERT(!IsPipe);
3326
3327 if (!ExAcquireResourceSharedLite(Fcb->Header.PagingIoResource, CanWait))
3328 {
3329 PostRequest = TRUE;
3331 }
3332
3333 if (!CanWait)
3334 {
3335 LowIoContext->Resource = Fcb->Header.PagingIoResource;
3336 }
3337 }
3338 else
3339 {
3340 if (!ReadCachingEnabled)
3341 {
3342 if (!CanWait && NoCache)
3343 {
3346 {
3347 DPRINT1("RdAsyLNG %x\n", RxContext);
3348 PostRequest = TRUE;
3350 }
3351 if (Status != STATUS_SUCCESS)
3352 {
3353 DPRINT1("RdAsyOthr %x\n", RxContext);
3355 }
3356
3357 if (RxIsFcbAcquiredShared(Fcb) <= 0xF000)
3358 {
3359 LowIoContext->Resource = Fcb->Header.Resource;
3360 }
3361 else
3362 {
3363 PostRequest = TRUE;
3365 }
3366 }
3367 else
3368 {
3369 Status = RxAcquireSharedFcb(RxContext, Fcb);
3371 {
3372 PostRequest = TRUE;
3374 }
3375 else if (Status != STATUS_SUCCESS)
3376 {
3378 }
3379 }
3380 }
3381 }
3382
3384
3385 ReadCachingDisabled = (ReadCachingEnabled == FALSE);
3386 if (IsPipe)
3387 {
3389 }
3390
3392
3393 /* Make sure FLOCK doesn't conflict */
3394 if (!PagingIo)
3395 {
3397 {
3400 }
3401 }
3402
3403 /* Validate byteoffset vs length */
3405 {
3406 if (ByteOffset.QuadPart >= FileSize)
3407 {
3410 }
3411
3412 if (ReadLength > FileSize - ByteOffset.QuadPart)
3413 {
3414 ReadLength = FileSize - ByteOffset.QuadPart;
3415 }
3416 }
3417
3418 /* Read with Cc! */
3419 if (!PagingIo && !NoCache && ReadCachingEnabled &&
3420 !BooleanFlagOn(Fobx->pSrvOpen->Flags, SRVOPEN_FLAG_DONTUSE_READ_CACHING))
3421 {
3422 /* File was not cached yet, do it */
3423 if (FileObject->PrivateCacheMap == NULL)
3424 {
3426 {
3429 }
3430
3432
3435
3437 {
3439 }
3440 else
3441 {
3444 }
3445
3446 CcSetReadAheadGranularity(FileObject, NetRoot->DiskParameters.ReadAheadGranularity);
3447 }
3448
3449 /* This should never happen - fix your RDR */
3450 if (BooleanFlagOn(RxContext->MinorFunction, IRP_MN_MDL))
3451 {
3452 ASSERT(FALSE);
3453 ASSERT(CanWait);
3454
3455 CcMdlRead(FileObject, &ByteOffset, ReadLength, &Irp->MdlAddress, &Irp->IoStatus);
3456 Status = Irp->IoStatus.Status;
3458 }
3459 else
3460 {
3461 /* Map buffer */
3462 SystemBuffer = RxNewMapUserBuffer(RxContext);
3463 if (SystemBuffer == NULL)
3464 {
3467 }
3468
3470
3472
3473 /* Perform the read */
3474 if (!CcCopyRead(FileObject, &ByteOffset, ReadLength, CanWait, SystemBuffer, &Irp->IoStatus))
3475 {
3476 if (!ReadCachingEnabled)
3477 {
3479 }
3480
3482
3483 PostRequest = TRUE;
3485 }
3486
3487 if (!ReadCachingEnabled)
3488 {
3490 }
3491
3492 Status = Irp->IoStatus.Status;
3494 }
3495 }
3496 else
3497 {
3498 /* Validate the reading */
3499 if (FileObject->PrivateCacheMap != NULL && BooleanFlagOn(Fcb->FcbState, FCB_STATE_READAHEAD_DEFERRED) &&
3500 ByteOffset.QuadPart >= 4096)
3501 {
3504 }
3505
3506 /* If it's consistent, forward to mini-rdr */
3507 if (Fcb->CachedNetRootType != NET_ROOT_DISK || BooleanFlagOn(Fcb->FcbState, FCB_STATE_READAHEAD_DEFERRED) ||
3508 ByteOffset.QuadPart < Fcb->Header.ValidDataLength.QuadPart)
3509 {
3510 LowIoContext->ParamsFor.ReadWrite.ByteCount = ReadLength;
3511 LowIoContext->ParamsFor.ReadWrite.ByteOffset = ByteOffset.QuadPart;
3512
3514
3515 if (InFsp && ReadCachingDisabled)
3516 {
3517 ExSetResourceOwnerPointer((PagingIo ? Fcb->Header.PagingIoResource : Fcb->Header.Resource),
3518 (PVOID)((ULONG_PTR)RxContext | 3));
3519 OwnerSet = TRUE;
3520 }
3521
3522 Status = RxLowIoReadShell(RxContext);
3523
3525 }
3526 else
3527 {
3528 if (ByteOffset.QuadPart > FileSize)
3529 {
3530 ReadLength = 0;
3531 Irp->IoStatus.Information = ReadLength;
3533 }
3534
3535 if (ByteOffset.QuadPart + ReadLength > FileSize)
3536 {
3537 ReadLength = FileSize - ByteOffset.QuadPart;
3538 }
3539
3540 SystemBuffer = RxNewMapUserBuffer(RxContext);
3541 RtlZeroMemory(SystemBuffer, ReadLength);
3542 Irp->IoStatus.Information = ReadLength;
3543 }
3544 }
3545 }
3547 {
3549
3550 /* Post if required */
3551 if (PostRequest)
3552 {
3553 InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
3554 Status = RxFsdPostRequest(RxContext);
3555 }
3556 else
3557 {
3558 /* Update FO in case of sync IO */
3559 if (!IsPipe && !PagingIo)
3560 {
3562 {
3563 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information;
3564 }
3565 }
3566 }
3567
3568 /* Set FastIo if read was a success */
3570 {
3571 if (!IsPipe && !PagingIo)
3572 {
3574 }
3575 }
3576
3577 /* In case we're done (not expected any further processing */
3578 if (_SEH2_AbnormalTermination() || Status != STATUS_PENDING || PostRequest)
3579 {
3580 /* Release everything that can be */
3581 if (ReadCachingDisabled)
3582 {
3583 if (PagingIo)
3584 {
3585 if (OwnerSet)
3586 {
3587 RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
3588 }
3589 else
3590 {
3591 RxReleasePagingIoResource(RxContext, Fcb);
3592 }
3593 }
3594 else
3595 {
3596 if (OwnerSet)
3597 {
3598 RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
3599 }
3600 else
3601 {
3602 RxReleaseFcb(RxContext, Fcb);
3603 }
3604 }
3605 }
3606
3607 /* Dereference/Delete context */
3608 if (PostRequest)
3609 {
3611 }
3612 else
3613 {
3614 if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
3615 {
3616 RxResumeBlockedOperations_Serially(RxContext, &Fobx->Specific.NamedPipe.ReadSerializationQueue);
3617 }
3618 }
3619
3620 /* We cannot return more than asked */
3621 if (Status == STATUS_SUCCESS)
3622 {
3623 ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Read.Length);
3624 }
3625 }
3626 else
3627 {
3628 ASSERT(!Sync);
3629
3631 }
3632 }
3633 _SEH2_END;
3634
3635 return Status;
3636}
3637
3639NTAPI
3642{
3645}
3646
3647/*
3648 * @implemented
3649 */
3651NTAPI
3654{
3655 PIRP Irp;
3656 PFCB Fcb;
3657 PFOBX Fobx;
3659 PNET_ROOT NetRoot;
3662 BOOLEAN CanWait, FcbTableAcquired, FcbAcquired;
3663
3664 PAGED_CODE();
3665
3666 Fcb = (PFCB)Context->pFcb;
3667 Fobx = (PFOBX)Context->pFobx;
3668 DPRINT("RxCommonSetInformation(%p), FCB: %p, FOBX: %p\n", Context, Fcb, Fobx);
3669
3670 Irp = Context->CurrentIrp;
3671 Stack = Context->CurrentIrpSp;
3672 Class = Stack->Parameters.SetFile.FileInformationClass;
3673 DPRINT("Buffer: %p, Length: %lx, Class: %ld, ReplaceIfExists: %d\n",
3674 Irp->AssociatedIrp.SystemBuffer, Stack->Parameters.SetFile.Length,
3675 Class, Stack->Parameters.SetFile.ReplaceIfExists);
3676
3678 CanWait = BooleanFlagOn(Context->Flags, RX_CONTEXT_FLAG_WAIT);
3679 FcbTableAcquired = FALSE;
3680 FcbAcquired = FALSE;
3681 NetRoot = (PNET_ROOT)Fcb->pNetRoot;
3682
3683#define _SEH2_TRY_RETURN(S) S; goto try_exit
3684
3685 _SEH2_TRY
3686 {
3687 /* Valide the node type first */
3690 {
3692 {
3694 {
3696 }
3697 }
3698 else if (NodeType(Fcb) != RDBSS_NTC_SPOOLFILE)
3699 {
3701 {
3703 }
3704 else
3705 {
3706 DPRINT1("Illegal type of file provided: %x\n", NodeType(Fcb));
3708 }
3709 }
3710 }
3711
3712 /* We don't autorize advance operation */
3713 if (Class == FileEndOfFileInformation && Stack->Parameters.SetFile.AdvanceOnly)
3714 {
3715 DPRINT1("Not allowed\n");
3716
3718 }
3719
3720 /* For these to classes, we'll have to deal with the FCB table (removal)
3721 * We thus need the exclusive FCB table lock
3722 */
3724 {
3725 RxPurgeRelatedFobxs(NetRoot, Context, TRUE, Fcb);
3727
3728 if (!RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, CanWait))
3729 {
3730 Context->PostRequest = TRUE;
3732 }
3733
3734 FcbTableAcquired = TRUE;
3735 }
3736
3737 /* Finally, if not paging file, we need exclusive FCB lock */
3739 {
3742 {
3743 Context->PostRequest = TRUE;
3745 }
3746 else if (Status != STATUS_SUCCESS)
3747 {
3749 }
3750
3751 FcbAcquired = TRUE;
3752 }
3753
3755
3756 /* And now, perform the job! */
3757 switch (Class)
3758 {
3761 break;
3762
3764 {
3766
3767 /* Check whether user wants deletion */
3768 FDI = Irp->AssociatedIrp.SystemBuffer;
3769 if (FDI->DeleteFile)
3770 {
3771 /* If so, check whether it's doable */
3772 if (!MmFlushImageSection(&Fcb->NonPaged->SectionObjectPointers, MmFlushForDelete))
3773 {
3775 }
3776
3777 /* And if doable, already remove from FCB table */
3778 if (Status == STATUS_SUCCESS)
3779 {
3780 ASSERT(FcbAcquired && FcbTableAcquired);
3782
3784 FcbTableAcquired = FALSE;
3785 }
3786 }
3787
3788 /* If it succeed, perform the operation */
3789 if (Status == STATUS_SUCCESS)
3790 {
3792 }
3793
3794 break;
3795 }
3796
3799 break;
3800
3803 break;
3804
3807 break;
3808
3813 break;
3814
3818 /* If we can wait, try to perform the operation right now */
3819 if (CanWait)
3820 {
3821 /* Of course, collapsing is not doable anymore, file is
3822 * in an inbetween state
3823 */
3825
3826 /* Set the information */
3828 /* If it succeed, drop the current entry from FCB table */
3830 {
3831 ASSERT(FcbAcquired && FcbTableAcquired);
3833 }
3835 }
3836 /* Can't wait? Post for async retry */
3837 else
3838 {
3841 }
3842 break;
3843
3846 {
3848 }
3849 break;
3850
3853 break;
3854
3855 default:
3856 DPRINT1("Insupported class: %x\n", Class);
3858
3859 break;
3860 }
3861
3862try_exit: NOTHING;
3863 /* If mini-rdr was OK and wants a re-post on this, do it */
3864 if (Status == STATUS_SUCCESS)
3865 {
3866 if (Context->PostRequest)
3867 {
3869 }
3870 }
3871 }
3873 {
3874 /* Release any acquired lock */
3875 if (FcbAcquired)
3876 {
3878 }
3879
3880 if (FcbTableAcquired)
3881 {
3883 }
3884 }
3885 _SEH2_END;
3886
3887#undef _SEH2_TRY_RETURN
3888
3889 return Status;
3890}
3891
3893NTAPI
3896{
3899}
3900
3902NTAPI
3905{
3908}
3909
3911NTAPI
3914{
3917}
3918
3920NTAPI
3923{
3926}
3927
3929NTAPI
3931 PRX_CONTEXT RxContext)
3932{
3933 PIRP Irp;
3934 PFCB Fcb;
3935 PFOBX Fobx;
3937 PNET_ROOT NetRoot;
3938 PSRV_OPEN SrvOpen;
3942 NODE_TYPE_CODE NodeTypeCode;
3943 PLOWIO_CONTEXT LowIoContext;
3944 PRDBSS_DEVICE_OBJECT RxDeviceObject;
3945 ULONG WriteLength, CapturedRxContextSerialNumber = RxContext->SerialNumber;
3946 LONGLONG FileSize, ValidDataLength, InitialFileSize, InitialValidDataLength;
3947 BOOLEAN CanWait, PagingIo, NoCache, Sync, NormalFile, WriteToEof, IsPipe, NoPreposting, InFsp, RecursiveWriteThrough, CalledByLazyWriter, SwitchBackToAsync, ExtendingFile, ExtendingValidData, UnwindOutstandingAsync, ResourceOwnerSet, PostIrp, ContextReferenced;
3948
3949 PAGED_CODE();
3950
3951 Fcb = (PFCB)RxContext->pFcb;
3952 NodeTypeCode = NodeType(Fcb);
3953 /* Validate FCB type */
3954 if (NodeTypeCode != RDBSS_NTC_STORAGE_TYPE_FILE && NodeTypeCode != RDBSS_NTC_VOLUME_FCB &&
3955 NodeTypeCode != RDBSS_NTC_SPOOLFILE && NodeTypeCode != RDBSS_NTC_MAILSLOT)
3956 {
3958 }
3959
3960 /* We'll write to file, keep track of it */
3961 Fcb->IsFileWritten = TRUE;
3962
3963 Stack = RxContext->CurrentIrpSp;
3964 /* Set write through if asked */
3966 {
3968 }
3969
3970 Fobx = (PFOBX)RxContext->pFobx;
3971 DPRINT("RxCommonWrite(%p) FOBX: %p, FCB: %p\n", RxContext, Fobx, Fcb);
3972
3973 /* Get some parameters */
3974 Irp = RxContext->CurrentIrp;
3975 NoPreposting = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED);
3976 InFsp = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
3977 CanWait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
3978 PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
3979 NoCache = BooleanFlagOn(Irp->Flags, IRP_NOCACHE);
3981 WriteLength = Stack->Parameters.Write.Length;
3982 ByteOffset.QuadPart = Stack->Parameters.Write.ByteOffset.QuadPart;
3983 DPRINT("Writing: %lx@%I64x %s %s %s %s\n", WriteLength, ByteOffset.QuadPart,
3984 (CanWait ? "CW" : "!CW"), (PagingIo ? "PI" : "!PI"), (NoCache ? "NC" : "!NC"), (Sync ? "S" : "!S"));
3985
3987
3988 RxContext->FcbResourceAcquired = FALSE;
3990
3991 LowIoContext = &RxContext->LowIoContext;
3992 CheckForLoudOperations(RxContext);
3994 {
3995 DPRINT("LoudWrite %I64x/%lx on %lx vdl/size/alloc %I64x/%I64x/%I64x\n",
3997 Fcb, Fcb->Header.ValidDataLength, Fcb->Header.FileSize, Fcb->Header.AllocationSize);
3998 }
3999
4000 RxDeviceObject = RxContext->RxDeviceObject;
4001 /* Update stats */
4002 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP) && Fcb->CachedNetRootType == NET_ROOT_DISK)
4003 {
4004 InterlockedIncrement((volatile long *)&RxDeviceObject->WriteOperations);
4005
4006 if (ByteOffset.QuadPart != Fobx->Specific.DiskFile.PredictedWriteOffset)
4007 {
4008 InterlockedIncrement((volatile long *)&RxDeviceObject->RandomWriteOperations);
4009 }
4010 Fobx->Specific.DiskFile.PredictedWriteOffset = ByteOffset.QuadPart + WriteLength;
4011
4012 if (PagingIo)
4013 {
4015 }
4016 else if (NoCache)
4017 {
4019 }
4020 else
4021 {
4023 }
4024 }
4025
4026 NetRoot = (PNET_ROOT)Fcb->NetRoot;
4027 IsPipe = (NetRoot->Type == NET_ROOT_PIPE);
4028 /* Keep track for normal writes */
4029 if (NetRoot->Type == NET_ROOT_DISK || NetRoot->Type == NET_ROOT_WILD)
4030 {
4031 NormalFile = TRUE;
4032 }
4033 else
4034 {
4035 NormalFile = FALSE;
4036 }
4037
4038 /* Zero-length write is immediate success */
4039 if (NormalFile && WriteLength == 0)
4040 {
4041 return STATUS_SUCCESS;
4042 }
4043
4044 /* Check whether we have input data */
4045 if (Irp->UserBuffer == NULL && Irp->MdlAddress == NULL)
4046 {
4048 }
4049
4050 /* Are we writting to EOF? */
4051 WriteToEof = ((ByteOffset.LowPart == FILE_WRITE_TO_END_OF_FILE) && (ByteOffset.HighPart == -1));
4052 /* FIXME: validate length/offset */
4053
4054 /* Get our SRV_OPEN in case of normal write */
4055 if (Fobx != NULL)
4056 {
4057 SrvOpen = (PSRV_OPEN)Fobx->pSrvOpen;
4058 }
4059 else
4060 {
4061 SrvOpen = NULL;
4062 }
4063
4064 FileObject = Stack->FileObject;
4065
4066 /* If we have caching enabled, check whether we have to defer write */
4067 if (!NoCache)
4068 {
4069 if (RxWriteCacheingAllowed(Fcb, SrvOpen))
4070 {
4072 (CanWait && !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP)),
4074 {
4075 BOOLEAN Retrying;
4076
4077 Retrying = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_DEFERRED_WRITE);
4078
4079 RxPrePostIrp(RxContext, Irp);
4080
4082
4084
4085 return STATUS_PENDING;
4086 }
4087 }
4088 }
4089
4090 /* Initialize the low IO context for write */
4092
4093 /* Initialize our (many) booleans */
4094 RecursiveWriteThrough = FALSE;
4095 CalledByLazyWriter = FALSE;
4096 SwitchBackToAsync = FALSE;
4097 ExtendingFile = FALSE;
4098 ExtendingValidData = FALSE;
4099 UnwindOutstandingAsync = FALSE;
4100 ResourceOwnerSet = FALSE;
4101 PostIrp = FALSE;
4102 ContextReferenced = FALSE;
4103
4104#define _SEH2_TRY_RETURN(S) S; goto try_exit
4105
4106 _SEH2_TRY
4107 {
4108 /* No volume FCB here! */
4109 ASSERT((NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE) ||
4110 (NodeTypeCode == RDBSS_NTC_SPOOLFILE) ||
4111 (NodeTypeCode == RDBSS_NTC_MAILSLOT));
4112
4113 /* Writing to EOF on a paging file is non sense */
4114 ASSERT(!(WriteToEof && PagingIo));
4115
4117
4118 /* Start locking stuff */
4119 if (!PagingIo && !NoPreposting)
4120 {
4121 /* If it's already acquired, all fine */
4122 if (RxContext->FcbResourceAcquired)
4123 {
4124 ASSERT(!IsPipe);
4125 }
4126 else
4127 {
4128 /* Otherwise, try to acquire shared (excepted for pipes) */
4129 if (IsPipe)
4130 {
4131 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
4132 }
4133 else if (CanWait ||
4134 (!NoCache && RxWriteCacheingAllowed(Fcb, SrvOpen)))
4135 {
4136 Status = RxAcquireSharedFcb(RxContext, Fcb);
4137 }
4138 else
4139 {
4141 }
4142
4143 /* We'll post IRP to retry */
4145 {
4146 PostIrp = TRUE;
4147 DPRINT1("Failed to acquire lock!\n");
4149 }
4150
4151 /* We'll just fail */
4152 if (Status != STATUS_SUCCESS)
4153 {
4155 }
4156
4157 /* Resource acquired */
4158 RxContext->FcbResourceAcquired = TRUE;
4159 }
4160
4161 /* At that point, resource is acquired */
4162 if (IsPipe)
4163 {
4164 ASSERT(RxContext->FcbResourceAcquired);
4165 }
4166 else
4167 {
4168 BOOLEAN IsDormant;
4169
4170 /* Now, check whether we have to promote shared lock */
4171 if (NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE && Fobx != NULL)
4172 {
4173 IsDormant = BooleanFlagOn(Fobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT);
4174 }
4175 else
4176 {
4177 IsDormant = FALSE;
4178 }
4179
4180 /* We're writing beyond VDL, we'll need an exclusive lock if not dormant */
4182 ByteOffset.QuadPart + WriteLength > Fcb->Header.ValidDataLength.QuadPart)
4183 {
4184 if (!IsDormant)
4185 {
4186 RxReleaseFcb(RxContext, Fcb);
4187 RxContext->FcbResourceAcquired = FALSE;
4188
4189 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
4191 {
4192 PostIrp = TRUE;
4193 DPRINT1("Failed to acquire lock!\n");
4195 }
4196
4197 if (Status != STATUS_SUCCESS)
4198 {
4200 }
4201
4202 RxContext->FcbResourceAcquired = TRUE;
4203 }
4204 }
4205
4206 /* If we're writing in VDL, or if we're dormant, shared lock is enough */
4207 if (ByteOffset.QuadPart + WriteLength <= Fcb->Header.ValidDataLength.QuadPart ||
4208 IsDormant)
4209 {
4211 {
4212 RxConvertToSharedFcb(RxContext, Fcb);
4213 }
4214 }
4215 else
4216 {
4217 /* We're extending file, disable collapsing */
4219
4220 DPRINT("Disabling collapsing\n");
4221
4222 if (NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE && Fobx != NULL)
4223 {
4224 SetFlag(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING);
4225 }
4226 }
4227
4228 ASSERT(RxContext->FcbResourceAcquired);
4229 }
4230
4231 /* Keep track of the acquired resource */
4232 LowIoContext->Resource = Fcb->Header.Resource;
4233 }
4234 else
4235 {
4236 /* Paging IO */
4237 ASSERT(!IsPipe);
4238
4239 /* Lock the paging resource */
4241
4242 /* Keep track of the acquired resource */
4243 LowIoContext->Resource = Fcb->Header.PagingIoResource;
4244 }
4245
4246 if (IsPipe)
4247 {
4250 }
4251
4252 /* If it's a non cached write, or if caching is disallowed */
4253 if (NoCache || !RxWriteCacheingAllowed(Fcb, SrvOpen))
4254 {
4255 /* If cache was previously enabled, we'll have to flush before writing */
4257 {
4258 LARGE_INTEGER FlushOffset;
4259
4260 /* FCB is lock */
4262
4263 /* If shared, we'll have to relock exclusive */
4265 {
4266 /* Release and retry exclusive */
4267 RxReleaseFcb(RxContext, Fcb);
4268 RxContext->FcbResourceAcquired = FALSE;
4269
4270 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
4272 {
4273 PostIrp = TRUE;
4274 DPRINT1("Failed to acquire lock for flush!\n");
4276 }
4277
4278 if (Status != STATUS_SUCCESS)
4279 {
4281 }
4282
4283 RxContext->FcbResourceAcquired = TRUE;
4284 }
4285
4286 /* Get the length to flush */
4287 if (WriteToEof)
4288 {
4289 RxGetFileSizeWithLock(Fcb, &FlushOffset.QuadPart);
4290 }
4291 else
4292 {
4293 FlushOffset.QuadPart = ByteOffset.QuadPart;
4294 }
4295
4296 /* Perform the flushing */
4297 RxAcquirePagingIoResource(RxContext, Fcb);
4299 WriteLength, &Irp->IoStatus);
4300 RxReleasePagingIoResource(RxContext, Fcb);
4301
4302 /* Cannot continue if flushing failed */
4303 if (!NT_SUCCESS(Irp->IoStatus.Status))
4304 {
4305 _SEH2_TRY_RETURN(Status = Irp->IoStatus.Status);
4306 }
4307
4308 /* Synchronize */
4309 RxAcquirePagingIoResource(RxContext, Fcb);
4310 RxReleasePagingIoResource(RxContext, Fcb);
4311
4312 /* And purge */
4314 &FlushOffset, WriteLength, FALSE);
4315 }
4316 }
4317
4318 /* If not paging IO, check if write is allowed */
4319 if (!PagingIo)
4320 {
4322 {
4324 }
4325 }
4326
4327 /* Get file sizes */
4328 ValidDataLength = Fcb->Header.ValidDataLength.QuadPart;
4330 ASSERT(ValidDataLength <= FileSize);
4331
4332 /* If paging IO, we cannot write past file size
4333 * so fix write length if needed
4334 */
4335 if (PagingIo)
4336 {
4337 if (ByteOffset.QuadPart >= FileSize)
4338 {
4340 }
4341
4342 if (WriteLength > FileSize - ByteOffset.QuadPart)
4343 {
4344 WriteLength = FileSize - ByteOffset.QuadPart;
4345 }
4346 }
4347
4348 /* If we're being called by the lazywrite */
4349 if (Fcb->Specific.Fcb.LazyWriteThread == PsGetCurrentThread())
4350 {
4351 CalledByLazyWriter = TRUE;
4352
4353 /* Fail if we're beyong VDL */
4355 {
4356 if ((ByteOffset.QuadPart + WriteLength > ValidDataLength) &&
4357 (ByteOffset.QuadPart < FileSize))
4358 {
4359 if (ByteOffset.QuadPart + WriteLength > ((ValidDataLength + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
4360 {
4362 }
4363 }
4364 }
4365 }
4366
4367 /* If that's a recursive synchronous page write */
4370 {
4371 PIRP TopIrp;
4372
4373 /* Check the top level IRP on the FastIO path */
4374 TopIrp = RxGetTopIrpIfRdbssIrp();
4375 if (TopIrp != NULL && (ULONG_PTR)TopIrp > FSRTL_FAST_IO_TOP_LEVEL_IRP)
4376 {
4377 PIO_STACK_LOCATION IrpStack;
4378
4379 ASSERT(NodeType(TopIrp) == IO_TYPE_IRP);
4380
4381 /* If the top level IRP was a cached write for this file, keep track */
4382 IrpStack = IoGetCurrentIrpStackLocation(TopIrp);
4383 if (IrpStack->MajorFunction == IRP_MJ_WRITE &&
4384 IrpStack->FileObject->FsContext == FileObject->FsContext)
4385 {
4386 RecursiveWriteThrough = TRUE;
4388 }
4389 }
4390 }
4391
4392 /* Now, deal with file size and VDL */
4393 if (!CalledByLazyWriter && !RecursiveWriteThrough &&
4394 (WriteToEof || ByteOffset.QuadPart + WriteLength > ValidDataLength))
4395 {
4396 /* Not sync? Let's make it sync, just the time we extended */
4397 if (!Sync)
4398 {
4399 CanWait = TRUE;
4400 SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
4402 Sync = TRUE;
4403
4404 /* Keep track we'll have to switch back to async */
4405 if (NoCache)
4406 {
4407 SwitchBackToAsync = TRUE;
4408 }
4409 }
4410
4411 /* Release all the locks */
4412 RxWriteReleaseResources(RxContext, 0);
4413
4414 /* Acquire exclusive */
4415 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
4417 {
4418 PostIrp = TRUE;
4419 DPRINT1("Failed to acquire lock for extension!\n");
4421 }
4422
4423 if (Status != STATUS_SUCCESS)
4424 {
4426 }
4427
4428 RxContext->FcbResourceAcquired = TRUE;
4429
4431
4432 /* Get the sizes again, to be sure they didn't change in the meantime */
4433 ValidDataLength = Fcb->Header.ValidDataLength.QuadPart;
4435 ASSERT(ValidDataLength <= FileSize);
4436
4437 /* Check we can switch back to async? */
4438 if ((SwitchBackToAsync && Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL) ||
4439 (ByteOffset.QuadPart + WriteLength > FileSize) || RxNoAsync)
4440 {
4441 SwitchBackToAsync = FALSE;
4442 }
4443
4444 /* If paging IO, check we don't try to extend the file */
4445 if (PagingIo)
4446 {
4447 if (ByteOffset.QuadPart >= FileSize)
4448 {
4450 }
4451
4452 if (WriteLength > FileSize - ByteOffset.QuadPart)
4453 {
4454 WriteLength = FileSize - ByteOffset.QuadPart;
4455 }
4456 }
4457 }
4458
4459 /* Save our initial sizes for potential rollback */
4460 InitialFileSize = FileSize;
4461 InitialValidDataLength = ValidDataLength;
4462 /* If writing to EOF, update byte offset with file size */
4463 if (WriteToEof)
4464 {
4465 ByteOffset.QuadPart = FileSize;
4466 }
4467
4468 /* Check again whether we're allowed to write */
4469 if (!PagingIo)
4470 {
4471 if (!FsRtlCheckLockForWriteAccess(&Fcb->Specific.Fcb.FileLock, Irp ))
4472 {
4474 }
4475
4476 /* Do we have to extend? */
4477 if (NormalFile && (ByteOffset.QuadPart + WriteLength > FileSize))
4478 {
4479 DPRINT("Need to extend file\n");
4480 ExtendingFile = TRUE;
4482 }
4483 }
4484
4485 /* Let's start to extend */
4486 if (ExtendingFile)
4487 {
4488 /* If we're past allocating, inform mini-rdr */
4489 FileSize = ByteOffset.QuadPart + WriteLength;
4490 if (FileSize > Fcb->Header.AllocationSize.QuadPart)
4491 {
4492 LARGE_INTEGER NewAllocationSize;
4493
4494 DPRINT("Extending %p\n", RxContext);
4495
4496 if (NoCache)
4497 {
4498 C_ASSERT(sizeof(LONGLONG) == sizeof(LARGE_INTEGER));
4499 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxExtendForNonCache,
4500 (RxContext, (PLARGE_INTEGER)&FileSize, &NewAllocationSize));
4501 }
4502 else
4503 {
4504 C_ASSERT(sizeof(LONGLONG) == sizeof(LARGE_INTEGER));
4505 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxExtendForCache,
4506 (RxContext, (PLARGE_INTEGER)&FileSize, &NewAllocationSize));
4507 }
4508
4509 if (!NT_SUCCESS(Status))
4510 {
4512 }
4513
4514 if (FileSize > NewAllocationSize.QuadPart)
4515 {
4516 NewAllocationSize.QuadPart = FileSize;
4517 }
4518
4519 /* And update FCB */
4520 Fcb->Header.AllocationSize.QuadPart = NewAllocationSize.QuadPart;
4521 }
4522
4523 /* Set the new sizes */
4526
4527 /* And inform Cc */
4529 {
4531 }
4532 }
4533
4534 /* Do we have to extend VDL? */
4535 if (!CalledByLazyWriter && !RecursiveWriteThrough)
4536 {
4537 if (WriteToEof || ByteOffset.QuadPart + WriteLength > ValidDataLength)
4538 {
4539 ExtendingValidData = TRUE;
4541 }
4542 }
4543
4544 /* If none cached write */
4545 if (PagingIo || NoCache || !RxWriteCacheingAllowed(Fcb, SrvOpen))
4546 {
4547 /* Switch back to async, if asked to */
4548 if (SwitchBackToAsync)
4549 {
4550 CanWait = FALSE;
4551 Sync = FALSE;
4552
4555 }
4556
4557 /* If not synchronous, keep track of writes to be finished */
4558 if (!Sync)
4559 {
4561 {
4565 }
4566
4568 1,
4569 &RxStrucSupSpinLock) == 0)
4570 {
4572 }
4573
4574 UnwindOutstandingAsync = TRUE;
4575 LowIoContext->ParamsFor.ReadWrite.NonPagedFcb = Fcb->NonPaged;
4576 }
4577
4578 /* Set our LOWIO_CONTEXT information */
4579 LowIoContext->ParamsFor.ReadWrite.ByteOffset = ByteOffset.QuadPart;
4580 LowIoContext->ParamsFor.ReadWrite.ByteCount = WriteLength;
4581
4583
4584 /* We have to be locked */
4585 ASSERT(RxContext->FcbResourceAcquired || RxContext->FcbPagingIoResourceAcquired);
4586
4587 /* Update thread ID if we're in FSP */
4588 if (InFsp)
4589 {
4590 LowIoContext->ResourceThreadId = (ULONG_PTR)RxContext | 3;
4591
4592 if (RxContext->FcbResourceAcquired)
4593 {
4594 ExSetResourceOwnerPointer(Fcb->Header.Resource, (PVOID)((ULONG_PTR)RxContext | 3));
4595 }
4596
4597 if (RxContext->FcbPagingIoResourceAcquired)
4598 {
4599 ExSetResourceOwnerPointer(Fcb->Header.PagingIoResource, (PVOID)((ULONG_PTR)RxContext | 3));
4600 }
4601
4602 ResourceOwnerSet = TRUE;
4603 }
4604
4605 /* And perform the write */
4606 Status = RxLowIoWriteShell(RxContext);
4607
4609
4610 /* Not outstanding write anymore */
4611 if (UnwindOutstandingAsync && Status == STATUS_PENDING)
4612 {
4613 UnwindOutstandingAsync = FALSE;
4614 }
4615 }
4616 /* Cached write */
4617 else
4618 {
4619 /* If cache wasn't enabled yet, do it */
4620 if (FileObject->PrivateCacheMap == NULL)
4621 {
4623 {
4625 }
4626
4628
4631
4632 CcSetReadAheadGranularity(FileObject, NetRoot->DiskParameters.ReadAheadGranularity);
4633 }
4634
4635 /* If that's a MDL backed write */
4636 if (BooleanFlagOn(RxContext->MinorFunction, IRP_MN_MDL))
4637 {
4638 /* Shouldn't happen */
4639 ASSERT(FALSE);
4640 ASSERT(CanWait);
4641
4642 /* Perform it, though */
4644 &Irp->MdlAddress, &Irp->IoStatus);
4645
4646 Status = Irp->IoStatus.Status;
4647 }
4648 else
4649 {
4650 PVOID SystemBuffer;
4651 ULONG BreakpointsSave;
4652
4653 /* Map the user buffer */
4654 SystemBuffer = RxNewMapUserBuffer(RxContext);
4655 if (SystemBuffer == NULL)
4656 {
4658 }
4659
4660 RxSaveAndSetExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
4661
4663
4664 /* And deal with Cc */
4666 SystemBuffer))
4667 {
4668 RxRestoreExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
4669
4671
4672 DPRINT1("CcCopyWrite failed for: %p %I64d %d %lx\n",
4673 FileObject, Fcb->Header.FileSize.QuadPart, WriteLength, Status);
4674
4675 PostIrp = TRUE;
4676 }
4677 else
4678 {
4679 Irp->IoStatus.Status = STATUS_SUCCESS;
4680 Irp->IoStatus.Information = WriteLength;
4681
4682 RxRestoreExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
4683
4685
4686 DPRINT("CcCopyWrite succeed for: %p %I64d %d %lx\n",
4687 FileObject, Fcb->Header.FileSize.QuadPart, WriteLength, Status);
4688 }
4689 }
4690 }
4691
4692try_exit: NOTHING;
4693
4694 /* If we've to post the IRP */
4695 if (PostIrp)
4696 {
4697 /* Reset the file size if required */
4698 if (ExtendingFile && !IsPipe)
4699 {
4700 ASSERT(RxWriteCacheingAllowed(Fcb, SrvOpen));
4701 ASSERT(Fcb->Header.PagingIoResource != NULL);
4702
4703 RxAcquirePagingIoResource(RxContext, Fcb);
4704 RxSetFileSizeWithLock(Fcb, &InitialFileSize);
4705 RxReleasePagingIoResource(RxContext, Fcb);
4706
4707 if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
4708 {
4710 }
4711 }
4712
4713 InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
4714 ContextReferenced = TRUE;
4715
4716 /* Release locks */
4717 ASSERT(!ResourceOwnerSet);
4718 RxWriteReleaseResources(RxContext, ResourceOwnerSet);
4719
4720#ifdef RDBSS_TRACKER
4721 ASSERT(RxContext->AcquireReleaseFcbTrackerX == 0);
4722#endif
4723
4724 /* And post the request */
4725 Status = RxFsdPostRequest(RxContext);
4726 }
4727 else
4728 {
4729 if (!IsPipe)
4730 {
4731 /* Update FILE_OBJECT if synchronous write succeed */
4732 if (!PagingIo)
4733 {
4735 {
4736 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information;
4737 }
4738 }
4739
4740 /* If write succeed, ,also update FILE_OBJECT flags */
4742 {
4743 /* File was modified */
4744 if (!PagingIo)
4745 {
4747 }
4748
4749 /* If was even extended */
4750 if (ExtendingFile)
4751 {
4753 }
4754
4755 /* If VDL was extended, update FCB and inform Cc */
4756 if (ExtendingValidData)
4757 {
4758 LONGLONG LastOffset;
4759
4760 LastOffset = ByteOffset.QuadPart + Irp->IoStatus.Information;
4761 if (FileSize < LastOffset)
4762 {
4763 LastOffset = FileSize;
4764 }
4765
4766 Fcb->Header.ValidDataLength.QuadPart = LastOffset;
4767
4768 if (NoCache && CcIsFileCached(FileObject))
4769 {
4771 }
4772 }
4773 }
4774 }
4775 }
4776 }
4778 {
4779 /* Finally, if we failed while extension was required */
4780 if (_SEH2_AbnormalTermination() && (ExtendingFile || ExtendingValidData))
4781 {
4782 /* Rollback! */
4783 if (!IsPipe)
4784 {
4785 ASSERT(Fcb->Header.PagingIoResource != NULL);
4786
4787 RxAcquirePagingIoResource(RxContext, Fcb);
4788 RxSetFileSizeWithLock(Fcb, &InitialFileSize);
4789 Fcb->Header.ValidDataLength.QuadPart = InitialValidDataLength;
4790 RxReleasePagingIoResource(RxContext, Fcb);
4791
4792 if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
4793 {
4795 }
4796 }
4797 }
4798
4799 /* One async write less */
4800 if (UnwindOutstandingAsync)
4801 {
4802 ASSERT(!IsPipe);
4803
4806 }
4807
4808 /* And now, cleanup everything */
4809 if (_SEH2_AbnormalTermination() || Status != STATUS_PENDING || PostIrp)
4810 {
4811 /* If we didn't post, release every lock (for posting, it's already done) */
4812 if (!PostIrp)
4813 {
4814 RxWriteReleaseResources(RxContext, ResourceOwnerSet);
4815 }
4816
4817 /* If the context was referenced - posting, dereference it */
4818 if (ContextReferenced)
4819 {
4821 }
4822
4823 /* If that's a pipe operation, resume any blocked one */
4824 if (!PostIrp)
4825 {
4827 {
4828 RxResumeBlockedOperations_Serially(RxContext, &Fobx->Specific.NamedPipe.ReadSerializationQueue);
4829 }
4830 }
4831
4832 /* Sanity check for write */
4833 if (Status == STATUS_SUCCESS)
4834 {
4835 ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Write.Length);
4836 }
4837 }
4838 /* Just dereference our context */
4839 else
4840 {
4841 ASSERT(!Sync);
4843 }
4844 }
4845 _SEH2_END;
4846
4847#undef _SEH2_TRY_RETURN
4848
4849 return Status;
4850}
4851
4852/*
4853 * @implemented
4854 */
4856NTAPI
4858 IN PRX_CONTEXT RxContext)
4859{
4860 PIRP Irp;
4863
4864#define BugCheckFileId RDBSS_BUG_CHECK_CACHESUP
4865
4866 PAGED_CODE();
4867
4868 Irp = RxContext->CurrentIrp;
4869 Stack = RxContext->CurrentIrpSp;
4870 FileObject = Stack->FileObject;
4871
4872 /* We can only complete for IRP_MJ_READ and IRP_MJ_WRITE */
4873 switch (RxContext->MajorFunction)
4874 {
4875 /* Call the Cc function */
4876 case IRP_MJ_READ:
4877 CcMdlReadComplete(FileObject, Irp->MdlAddress);
4878 break;
4879
4880 case IRP_MJ_WRITE:
4881 /* If here, we can wait */
4882 ASSERT(BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT));
4883
4884 /* Call the Cc function */
4885 CcMdlWriteComplete(FileObject, &Stack->Parameters.Write.ByteOffset, Irp->MdlAddress);
4886
4887 Irp->IoStatus.Status = STATUS_SUCCESS;
4888 break;
4889
4890 default:
4891 DPRINT1("Invalid major for RxCompleteMdl: %d\n", RxContext->MajorFunction);
4892 RxBugCheck(RxContext->MajorFunction, 0, 0);
4893 break;
4894 }
4895
4896 /* MDL was freed */
4897 Irp->MdlAddress = NULL;
4898
4899 /* And complete the IRP */
4901
4902#undef BugCheckFileId
4903
4904 return STATUS_SUCCESS;
4905}
4906
4907/*
4908 * @implemented
4909 */
4910VOID
4912 PFCB Fcb,
4913 PFOBX Fobx,
4914 PULONG ActualNameLength,
4915 PWCHAR OriginalName,
4916 PLONG LengthRemaining,
4917 RX_NAME_CONJURING_METHODS NameConjuringMethod)
4918{
4919 PWSTR Prefix, Name;
4920 PV_NET_ROOT VNetRoot;
4921 USHORT PrefixLength, NameLength, ToCopy;
4922
4923 PAGED_CODE();
4924
4925 VNetRoot = Fcb->VNetRoot;
4926 /* We will use the prefix contained in NET_ROOT, if we don't have
4927 * a V_NET_ROOT, or if it wasn't null deviced or if we already have
4928 * a UNC path */
4929 if (VNetRoot == NULL || VNetRoot->PrefixEntry.Prefix.Buffer[1] != L';' ||
4930 BooleanFlagOn(Fobx->Flags, FOBX_FLAG_UNC_NAME))
4931 {
4932 Prefix = ((PNET_ROOT)Fcb->pNetRoot)->PrefixEntry.Prefix.Buffer;
4933 PrefixLength = ((PNET_ROOT)Fcb->pNetRoot)->PrefixEntry.Prefix.Length;
4934 NameLength = 0;
4935
4936 /* In that case, keep track that we will have a prefix as buffer */
4937 NameConjuringMethod = VNetRoot_As_Prefix;
4938 }
4939 else
4940 {
4941 ASSERT(NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT);
4942
4943 /* Otherwise, return the prefix from our V_NET_ROOT */
4944 Prefix = VNetRoot->PrefixEntry.Prefix.Buffer;
4945 PrefixLength = VNetRoot->PrefixEntry.Prefix.Length;
4946 NameLength = VNetRoot->NamePrefix.Length;
4947
4948 /* If we want a UNC path, skip potential device */
4949 if (NameConjuringMethod == VNetRoot_As_UNC_Name)
4950 {
4951 do
4952 {
4953 ++Prefix;
4954 PrefixLength -= sizeof(WCHAR);
4955 } while (PrefixLength > 0 && Prefix[0] != L'\\');
4956 }
4957 }
4958
4959 /* If we added an extra backslash, skip it */
4961 {
4962 NameLength += sizeof(WCHAR);
4963 }
4964
4965 /* If we're asked for a drive letter, skip the prefix */
4966 if (NameConjuringMethod == VNetRoot_As_DriveLetter)
4967 {
4968 PrefixLength = 0;
4969
4970 /* And make sure we arrive at a backslash */
4971 if (Fcb->FcbTableEntry.Path.Length > NameLength &&
4972 Fcb->FcbTableEntry.Path.Buffer[NameLength / sizeof(WCHAR)] != L'\\')
4973 {
4974 NameLength -= sizeof(WCHAR);
4975 }
4976 }
4977 else
4978 {
4979 /* Prepare to copy the prefix, make sure not to overflow */
4980 if (*LengthRemaining >= PrefixLength)
4981 {
4982 /* Copy everything */
4983 ToCopy = PrefixLength;
4984 *LengthRemaining = *LengthRemaining - PrefixLength;
4985 }
4986 else
4987 {
4988 /* Copy as much as we can */
4989 ToCopy = *LengthRemaining;
4990 /* And return failure */
4991 *LengthRemaining = -1;
4992 }
4993
4994 /* Copy the prefix */
4995 RtlCopyMemory(OriginalName, Prefix, ToCopy);
4996 }
4997
4998 /* Do we have a name to copy now? */
4999 if (Fcb->FcbTableEntry.Path.Length > NameLength)
5000 {
5001 ToCopy = Fcb->FcbTableEntry.Path.Length - NameLength;
5003 }
5004 else
5005 {
5006 /* Just use slash for now */
5007 ToCopy = sizeof(WCHAR);
5008 NameLength = 0;
5009 Name = L"\\";
5010 }
5011
5012 /* Total length we will have in the output buffer (if everything is alright) */
5013 *ActualNameLength = ToCopy + PrefixLength;
5014 /* If we still have room to write data */
5015 if (*LengthRemaining != -1)
5016 {
5017 /* If we can copy everything, it's fine! */
5018 if (*LengthRemaining > ToCopy)
5019 {
5020 *LengthRemaining = *LengthRemaining - ToCopy;
5021 }
5022 /* Otherwise, copy as much as possible, and return failure */
5023 else
5024 {
5025 ToCopy = *LengthRemaining;
5026 *LengthRemaining = -1;
5027 }
5028
5029 /* Copy name after the prefix */
5030 RtlCopyMemory(Add2Ptr(OriginalName, PrefixLength),
5031 Add2Ptr(Name, NameLength), ToCopy);
5032 }
5033}
5034
5035/*
5036 * @implemented
5037 */
5038VOID
5040 IN PRX_CONTEXT RxContext)
5041{
5042 PIRP Irp;
5043 PVOID DfsContext;
5046 PDFS_NAME_CONTEXT DfsNameContext;
5047 PIO_SECURITY_CONTEXT SecurityContext;
5048
5049 Irp = RxContext->CurrentIrp;
5050 Stack = RxContext->CurrentIrpSp;
5051 FileObject = Stack->FileObject;
5052 SecurityContext = Stack->Parameters.Create.SecurityContext;
5053
5054 RxContext->Create.NtCreateParameters.SecurityContext = SecurityContext;
5055 if (SecurityContext->AccessState != NULL && SecurityContext->AccessState->SecurityDescriptor != NULL)
5056 {
5057 RxContext->Create.SdLength = RtlLengthSecurityDescriptor(SecurityContext->AccessState->SecurityDescriptor);
5058 DPRINT("SD Ctxt: %p, Length: %lx\n", RxContext->Create.NtCreateParameters.SecurityContext,
5059 RxContext->Create.SdLength);
5060 }
5061 if (SecurityContext->SecurityQos != NULL)
5062 {
5063 RxContext->Create.NtCreateParameters.ImpersonationLevel = SecurityContext->SecurityQos->ImpersonationLevel;
5064 }
5065 else
5066 {
5067 RxContext->Create.NtCreateParameters.ImpersonationLevel = SecurityImpersonation;
5068 }
5069 RxContext->Create.NtCreateParameters.DesiredAccess = SecurityContext->DesiredAccess;
5070
5071 RxContext->Create.NtCreateParameters.AllocationSize.QuadPart = Irp->Overlay.AllocationSize.QuadPart;
5072 RxContext->Create.NtCreateParameters.FileAttributes = Stack->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS;
5073 RxContext->Create.NtCreateParameters.ShareAccess = Stack->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS;
5074 RxContext->Create.NtCreateParameters.Disposition = (Stack->Parameters.Create.Options >> 24) & 0x000000FF;
5075 RxContext->Create.NtCreateParameters.CreateOptions = Stack->Parameters.Create.Options & 0xFFFFFF;
5076
5077 DfsContext = FileObject->FsContext2;
5078 DfsNameContext = FileObject->FsContext;
5079 RxContext->Create.NtCreateParameters.DfsContext = DfsContext;
5080 RxContext->Create.NtCreateParameters.DfsNameContext = DfsNameContext;
5081 ASSERT(DfsContext == NULL || DfsContext == UIntToPtr(DFS_OPEN_CONTEXT) ||
5082 DfsContext == UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT) ||
5083 DfsContext == UIntToPtr(DFS_CSCAGENT_NAME_CONTEXT) ||
5084 DfsContext == UIntToPtr(DFS_USER_NAME_CONTEXT));
5085 ASSERT(DfsNameContext == NULL || DfsNameContext->NameContextType == DFS_OPEN_CONTEXT ||
5086 DfsNameContext->NameContextType == DFS_DOWNLEVEL_OPEN_CONTEXT ||
5087 DfsNameContext->NameContextType == DFS_CSCAGENT_NAME_CONTEXT ||
5088 DfsNameContext->NameContextType == DFS_USER_NAME_CONTEXT);
5089 FileObject->FsContext2 = NULL;
5090 FileObject->FsContext = NULL;
5091
5092 RxContext->pFcb = NULL;
5093 RxContext->Create.ReturnedCreateInformation = 0;
5094
5095 /* if we stripped last \, it has to be a directory! */
5097 {
5098 SetFlag(RxContext->Create.NtCreateParameters.CreateOptions, FILE_DIRECTORY_FILE);
5099 }
5100
5101 RxContext->Create.EaLength = Stack->Parameters.Create.EaLength;
5102 if (RxContext->Create.EaLength == 0)
5103 {
5104 RxContext->Create.EaBuffer = NULL;
5105 }
5106 else
5107 {
5108 RxContext->Create.EaBuffer = Irp->AssociatedIrp.SystemBuffer;
5109 DPRINT("EA Buffer: %p, Length: %lx\n", Irp->AssociatedIrp.SystemBuffer, RxContext->Create.EaLength);
5110 }
5111}
5112
5116 PUNICODE_STRING NetRootName)
5117{
5118 PFCB Fcb;
5120 PNET_ROOT NetRoot;
5125
5126 PAGED_CODE();
5127
5128 /* Validate that the context is consistent */
5129 if (Context->Create.pNetRoot == NULL)
5130 {
5132 }
5133
5134 NetRoot = (PNET_ROOT)Context->Create.pNetRoot;
5135 if (Context->RxDeviceObject != NetRoot->pSrvCall->RxDeviceObject)
5136 {
5138 }
5139
5140 if (Context->Create.NtCreateParameters.DfsContext == UIntToPtr(DFS_OPEN_CONTEXT) &&
5141 !BooleanFlagOn(NetRoot->pSrvCall->Flags, SRVCALL_FLAG_DFS_AWARE_SERVER))
5142 {
5144 }
5145
5146 if (Context->Create.NtCreateParameters.DfsContext == UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT) &&
5148 {
5150 }
5151
5152 Stack = Context->CurrentIrpSp;
5153 DesiredShareAccess = Stack->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS;
5154 if (NetRoot->Type == NET_ROOT_PRINT)
5155 {
5157 }
5158
5159 DesiredAccess = Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_ALL_ACCESS;
5160
5161 /* Get file object */
5162 FileObject = Stack->FileObject;
5163
5164 /* Do we have to open target directory for renaming? */
5166 {
5167 DPRINT("Opening target directory\n");
5168
5169 /* If we have been asked for delete, try to purge first */
5170 if (BooleanFlagOn(Context->Create.NtCreateParameters.DesiredAccess, DELETE))
5171 {
5172 RxPurgeRelatedFobxs((PNET_ROOT)Context->Create.pVNetRoot->pNetRoot, Context,
5174 }
5175
5176 /* Create the FCB */
5177 Fcb = RxCreateNetFcb(Context, (PV_NET_ROOT)Context->Create.pVNetRoot, NetRootName);
5178 if (Fcb == NULL)
5179 {
5181 }
5182
5183 /* Fake it: it will be used only renaming */
5185 Context->Create.FcbAcquired = FALSE;
5186 Context->Create.NetNamePrefixEntry = NULL;
5187
5188 /* Assign it to the FO */
5189 FileObject->FsContext = Fcb;
5190
5191 /* If we have a FOBX already, check whether it's for DFS opening */
5192 if (Context->pFobx != NULL)
5193 {
5194 /* If so, reflect this in the FOBX */
5195 if (FileObject->FsContext2 == UIntToPtr(DFS_OPEN_CONTEXT))
5196 {
5197 SetFlag(Context->pFobx->Flags, FOBX_FLAG_DFS_OPEN);
5198 }
5199 else
5200 {
5201 ClearFlag(Context->pFobx->Flags, FOBX_FLAG_DFS_OPEN);
5202 }
5203 }
5204
5205 /* Acquire the FCB */
5207 if (Status != STATUS_SUCCESS)
5208 {
5209 return Status;
5210 }
5211
5212 /* Reference the FCB and release */
5215
5216 /* We're done! */
5217 return STATUS_SUCCESS;
5218 }
5219
5220 /* Try to find (or create) the FCB for the file */
5221 Status = RxFindOrCreateFcb(Context, NetRootName);
5222 Fcb = (PFCB)Context->pFcb;
5223 if (Fcb == NULL)
5224 {
5226 }
5227 if (!NT_SUCCESS(Status) || Fcb == NULL)
5228 {
5229 return Status;
5230 }
5231
5233 {
5234 Fcb->Header.NodeTypeCode = RDBSS_NTC_MAILSLOT;
5235 }
5236 else
5237 {
5239 }
5240
5241 /* If finding FCB worked (mailslot case), mark the FCB as good and quit */
5242 if (NT_SUCCESS(Status))
5243 {
5245 DPRINT("Transitioning FCB %lx Condition %lx\n", Fcb, Fcb->Condition);
5246 ++Fcb->OpenCount;
5248 return STATUS_SUCCESS;
5249 }
5250
5251 /* Not mailslot! */
5252 /* Check SA for conflict */
5253 if (Fcb->OpenCount > 0)
5254 {
5256 &Fcb->ShareAccess, FALSE, "early check per useropens", "EarlyPerUO");
5257 if (!NT_SUCCESS(Status))
5258 {
5260 return Status;
5261 }
5262 }
5263
5264 if (BooleanFlagOn(Context->Create.NtCreateParameters.CreateOptions, FILE_DELETE_ON_CLOSE) &&
5265 !BooleanFlagOn(Context->Create.NtCreateParameters.DesiredAccess, ~SYNCHRONIZE))
5266 {
5268 }
5269
5270 _SEH2_TRY
5271 {
5272 /* Find a SRV_OPEN that suits the opening */
5274 if (Status == STATUS_SUCCESS)
5275 {
5276 PFOBX Fobx;
5277 PSRV_OPEN SrvOpen;
5278
5279 SrvOpen = (PSRV_OPEN)Context->pRelevantSrvOpen;
5280 Fobx = (PFOBX)Context->pFobx;
5281 /* There are already opens, check for conflict */
5282 if (Fcb->OpenCount != 0)
5283 {
5286 FALSE, "second check per useropens",
5287 "2ndAccPerUO")))
5288 {
5289 ++SrvOpen->UncleanFobxCount;
5291
5293 }
5294 }
5295 else
5296 {
5297 if (NetRoot->Type != NET_ROOT_PIPE)
5298 {
5300 &Fcb->ShareAccess, "initial shareaccess setup", "InitShrAcc");
5301 }
5302 }
5303
5305
5306 /* No conflict? Set up SA */
5307 if (Fcb->OpenCount != 0 && NetRoot->Type != NET_ROOT_PIPE)
5308 {
5309 RxUpdateShareAccess(FileObject, &Fcb->ShareAccess, "update share access", "UpdShrAcc");
5310 }
5311
5312 ++Fcb->UncleanCount;
5314 {
5315 ++Fcb->UncachedUncleanCount;
5316 }
5317
5318 if (SrvOpen->UncleanFobxCount == 0 && Fcb->UncleanCount == 1 &&
5320 {
5322 }
5323
5324 /* No pending close, we're active */
5326
5327 ++Fcb->OpenCount;
5328 ++SrvOpen->UncleanFobxCount;
5329 ++SrvOpen->OpenCount;
5330 SrvOpen->ulFileSizeVersion = Fcb->ulFileSizeVersion;
5331
5332 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_NO_INTERMEDIATE_BUFFERING))
5333 {
5336
5339
5341 }
5342
5343 /* Now, update SA for the SRV_OPEN */
5345
5346 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_DELETE_ON_CLOSE))
5347 {
5348 SetFlag(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE);
5349 }
5350
5351 /* Update the FOBX info */
5352 if (Fobx != NULL)
5353 {
5354 if (Context->Create.pNetRoot->Type == NET_ROOT_PIPE)
5355 {
5357 }
5358
5359 if (Context->Create.pNetRoot->Type == NET_ROOT_PRINT ||
5360 Context->Create.pNetRoot->Type == NET_ROOT_PIPE)
5361 {
5362 Fobx->PipeHandleInformation = &Fobx->Specific.NamedPipe.PipeHandleInformation;
5363
5364 Fobx->Specific.NamedPipe.CollectDataTime.QuadPart = 0;
5365 Fobx->Specific.NamedPipe.CollectDataSize = Context->Create.pNetRoot->NamedPipeParameters.DataCollectionSize;
5366
5367 Fobx->Specific.NamedPipe.PipeHandleInformation.TypeOfPipe = Context->Create.PipeType;
5368 Fobx->Specific.NamedPipe.PipeHandleInformation.ReadMode = Context->Create.PipeReadMode;
5369 Fobx->Specific.NamedPipe.PipeHandleInformation.CompletionMode = Context->Create.PipeCompletionMode;
5370
5371 InitializeListHead(&Fobx->Specific.NamedPipe.ReadSerializationQueue);
5372 InitializeListHead(&Fobx->Specific.NamedPipe.WriteSerializationQueue);
5373 }
5374 }
5375
5377 }
5378 }
5380 {
5381 if (Fcb->OpenCount == 0)
5382 {
5383 if (Context->Create.FcbAcquired)
5384 {
5385 Context->Create.FcbAcquired = (RxDereferenceAndFinalizeNetFcb(Fcb,
5386 Context,
5387 FALSE,
5388 FALSE) == 0);
5389 if (!Context->Create.FcbAcquired)
5390 {
5391 RxTrackerUpdateHistory(Context, NULL, TRACKER_FCB_FREE, __LINE__, __FILE__, 0);
5392 }
5393 }
5394 }
5395 else
5396 {
5398 }
5399 }
5400 _SEH2_END;
5401
5402 return Status;
5403}
5404
5405/*
5406 * @implemented
5407 */
5410 IN PRX_CONTEXT RxContext)
5411{
5413 PV_NET_ROOT VNetRoot;
5416 NET_ROOT_TYPE NetRootType;
5417 UNICODE_STRING CanonicalName, RemainingName;
5418
5419 PAGED_CODE();
5420
5421 Stack = RxContext->CurrentIrpSp;
5422 FileObject = Stack->FileObject;
5423
5424 RtlInitEmptyUnicodeString(&CanonicalName, NULL, 0);
5425 /* As long as we don't know connection type, mark it wild */
5426 NetRootType = NET_ROOT_WILD;
5427 /* Get the type by parsing the name */
5428 Status = RxFirstCanonicalize(RxContext, &FileObject->FileName, &CanonicalName, &NetRootType);
5429 if (!NT_SUCCESS(Status))
5430 {
5431 return Status;
5432 }
5433
5434 RxContext->Create.ThisIsATreeConnectOpen = TRUE;
5435 RxContext->Create.TreeConnectOpenDeferred = FALSE;
5436 RtlInitEmptyUnicodeString(&RxContext->Create.TransportName, NULL, 0);
5437 RtlInitEmptyUnicodeString(&RxContext->Create.UserName, NULL, 0);
5438 RtlInitEmptyUnicodeString(&RxContext->Create.Password, NULL, 0);
5439 RtlInitEmptyUnicodeString(&RxContext->Create.UserDomainName, NULL, 0);
5440
5441 /* We don't handle EA - they come from DFS, don't care */
5442 if (Stack->Parameters.Create.EaLength > 0)
5443 {
5445 }
5446
5447 /* Mount if required */
5448 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, &RemainingName);
5450 {
5451 RxScavengeVNetRoots(RxContext->RxDeviceObject);
5452 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, &RemainingName);
5453 }
5454
5455 if (!NT_SUCCESS(Status))
5456 {
5457 return Status;
5458 }
5459
5460 /* Validate the rest of the name with mini-rdr */
5461 if (RemainingName.Length > 0)
5462 {
5463 MINIRDR_CALL(Status, RxContext,
5464 RxContext->Create.pNetRoot->pSrvCall->RxDeviceObject->Dispatch,
5465 MRxIsValidDirectory, (RxContext, &RemainingName));
5466 }
5467
5468 if (!NT_SUCCESS(Status))
5469 {
5470 return Status;
5471 }
5472
5473 VNetRoot = (PV_NET_ROOT)RxContext->Create.pVNetRoot;
5474 RxReferenceVNetRoot(VNetRoot);
5476 {
5478 }
5479
5480 FileObject->FsContext = &RxDeviceFCB;
5481 FileObject->FsContext2 = VNetRoot;
5482
5483 VNetRoot->ConstructionStatus = STATUS_SUCCESS;
5484 ++VNetRoot->NumberOfOpens;
5485
5486 /* Create is over - clear context */
5487 RxContext->Create.pSrvCall = NULL;
5488 RxContext->Create.pNetRoot = NULL;
5489 RxContext->Create.pVNetRoot = NULL;
5490
5491 return Status;
5492}
5493
5494VOID
5495NTAPI
5497 _In_ PSTR ControlString)
5498{
5500}
5501
5503NTAPI
5507{
5509 USHORT i, State = 0;
5510
5511 DPRINT("RxDriverEntry(%p, %p)\n", DriverObject, RegistryPath);
5512
5513 _SEH2_TRY
5514 {
5516
5517 RtlZeroMemory(&RxData, sizeof(RxData));
5519 RxData.NodeByteSize = sizeof(RxData);
5521
5524 RxDeviceFCB.spacer.NodeByteSize = sizeof(RxDeviceFCB);
5525
5528
5530
5533
5535 State = 2;
5536
5539
5541 if (!NT_SUCCESS(Status))
5542 {
5544 }
5545 State = 1;
5546
5548
5550
5553
5556
5561
5562 for (i = 0; i < RxMaximumWorkQueue; ++i)
5563 {
5567 }
5568
5570
5572
5575
5577 }
5579 {
5580 if (!NT_SUCCESS(Status))
5581 {
5584 }
5585 } _SEH2_END;
5586
5587 /* There are still bits to init - be consider it's fine for now */
5588#if 0
5591#else
5592 return STATUS_SUCCESS;
5593#endif
5594}
5595
5596#if DBG
5597/*
5598 * @implemented
5599 */
5600VOID
5602 _In_ PSZ where1,
5603 _In_ PSZ where2,
5604 _In_ PSZ wherelogtag,
5606{
5607 PAGED_CODE();
5608}
5609
5610/*
5611 * @implemented
5612 */
5613VOID
5615 _In_ PSZ where1,
5616 _In_ PSZ where2,
5617 _In_ PSZ wherelogtag,
5620{
5621 PAGED_CODE();
5622}
5623#endif
5624
5625/*
5626 * @implemented
5627 */
5628BOOLEAN
5629NTAPI
5637{
5638 PFCB Fcb;
5639 PSRV_OPEN SrvOpen;
5640 LARGE_INTEGER LargeLength;
5641
5642 PAGED_CODE();
5643
5644 /* Get the FCB to validate it */
5645 Fcb = FileObject->FsContext;
5647 {
5648 DPRINT1("Not a file, FastIO not possible!\n");
5649 return FALSE;
5650 }
5651
5652 if (FileObject->DeletePending)
5653 {
5654 DPRINT1("File delete pending\n");
5655 return FALSE;
5656 }
5657
5658 /* If there's a pending write operation, deny fast operation */
5660 {
5661 DPRINT1("Write operations to be completed\n");
5662 return FALSE;
5663 }
5664
5665 /* Deny read on orphaned node */
5666 SrvOpen = (PSRV_OPEN)((PFOBX)FileObject->FsContext2)->pSrvOpen;
5667 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_ORPHANED))
5668 {
5669 DPRINT1("SRV_OPEN orphaned\n");
5670 return FALSE;
5671 }
5672
5674 {
5675 DPRINT1("FCB orphaned\n");
5676 return FALSE;
5677 }
5678
5679 /* If there's a buffering state change pending, deny fast operation (it might change
5680 * cache status)
5681 */
5683 {
5684 DPRINT1("Buffering change pending\n");
5685 return FALSE;
5686 }
5687
5688 /* File got renamed/deleted, deny operation */
5689 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_DELETED) ||
5691 {
5692 DPRINT1("File renamed/deleted\n");
5693 return FALSE;
5694 }
5695
5696 /* Process pending change buffering state operations */
5700
5701 LargeLength.QuadPart = Length;
5702
5703 /* If operation to come is a read operation */
5705 {
5706 /* Check that read cache is enabled */
5708 {
5709 DPRINT1("Read caching disabled\n");
5710 return FALSE;
5711 }
5712
5713 /* Check whether there's a lock conflict */
5714 if (!FsRtlFastCheckLockForRead(&Fcb->Specific.Fcb.FileLock,
5715 FileOffset,
5716 &LargeLength,
5717 LockKey,
5718 FileObject,
5720 {
5721 DPRINT1("FsRtlFastCheckLockForRead failed\n");
5722 return FALSE;
5723 }
5724
5725 return TRUE;
5726 }
5727
5728 /* Check that write cache is enabled */
5730 {
5731 DPRINT1("Write caching disabled\n");
5732 return FALSE;
5733 }
5734
5735 /* Check whether there's a lock conflict */
5737 FileOffset,
5738 &LargeLength,
5739 LockKey,
5740 FileObject,
5742 {
5743 DPRINT1("FsRtlFastCheckLockForWrite failed\n");
5744 return FALSE;
5745 }
5746
5747 return TRUE;
5748}
5749
5750BOOLEAN
5751NTAPI
5754 BOOLEAN Wait,
5762{
5763 /* Only supported IOCTL */
5765 {
5767 return FALSE;
5768 }
5769 else
5770 {
5771 return FALSE;
5772 }
5773}
5774
5775/*
5776 * @implemented
5777 */
5778BOOLEAN
5779NTAPI
5783 ULONG Length,
5784 BOOLEAN Wait,
5785 ULONG LockKey,
5786 PVOID Buffer,
5789{
5790 BOOLEAN Ret;
5791 RX_TOPLEVELIRP_CONTEXT TopLevelContext;
5792
5793 PAGED_CODE();
5794
5795 DPRINT("RxFastIoRead: %p (%p, %p)\n", FileObject, FileObject->FsContext,
5796 FileObject->FsContext2);
5797 DPRINT("Reading %ld at %I64x\n", Length, FileOffset->QuadPart);
5798
5799 /* Prepare a TLI context */
5803
5805 IoStatus, DeviceObject, &TopLevelContext);
5806 if (Ret)
5807 {
5808 DPRINT("Read OK\n");
5809 }
5810 else
5811 {
5812 DPRINT1("Read failed!\n");
5813 }
5814
5815 return Ret;
5816}
5817
5818/*
5819 * @implemented
5820 */
5821BOOLEAN
5822NTAPI
5826 ULONG Length,
5827 BOOLEAN Wait,
5828 ULONG LockKey,
5829 PVOID Buffer,
5832{
5833 PFOBX Fobx;
5834 BOOLEAN Ret;
5835 RX_TOPLEVELIRP_CONTEXT TopLevelContext;
5836
5837 PAGED_CODE();
5838
5839 Fobx = (PFOBX)FileObject->FsContext2;
5840 if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_BAD_HANDLE))
5841 {
5842 return FALSE;
5843 }
5844
5845 DPRINT("RxFastIoWrite: %p (%p, %p)\n", FileObject, FileObject->FsContext,
5846 FileObject->FsContext2);
5847 DPRINT("Writing %ld at %I64x\n", Length, FileOffset->QuadPart);
5848
5849 /* Prepare a TLI context */
5853
5855 IoStatus, DeviceObject, &TopLevelContext);
5856 if (Ret)
5857 {
5858 DPRINT("Write OK\n");
5859 }
5860 else
5861 {
5862 DPRINT1("Write failed!\n");
5863 }
5864
5865 return Ret;
5866}
5867
5870 PRX_CONTEXT RxContext,
5871 PUNICODE_STRING NetRootName)
5872{
5873 PFCB Fcb;
5874 ULONG Version;
5876 PNET_ROOT NetRoot;
5877 PV_NET_ROOT VNetRoot;
5878 BOOLEAN TableAcquired, AcquiredExclusive;
5879
5880 PAGED_CODE();
5881
5882 NetRoot = (PNET_ROOT)RxContext->Create.pNetRoot;
5883 VNetRoot = (PV_NET_ROOT)RxContext->Create.pVNetRoot;
5884 ASSERT(NetRoot == VNetRoot->NetRoot);
5885
5887 AcquiredExclusive = FALSE;
5888
5890 TableAcquired = TRUE;
5891 Version = NetRoot->FcbTable.Version;
5892
5893 /* Look for a cached FCB */
5894 Fcb = RxFcbTableLookupFcb(&NetRoot->FcbTable, NetRootName);
5895 if (Fcb == NULL)
5896 {
5897 DPRINT("RxFcbTableLookupFcb returned NULL fcb for %wZ\n", NetRootName);
5898 }
5899 else
5900 {
5901 DPRINT("FCB found for %wZ\n", &Fcb->FcbTableEntry.Path);
5902 /* If FCB was to be orphaned, consider it as not suitable */
5903 if (Fcb->fShouldBeOrphaned)
5904 {
5907
5909 TableAcquired = TRUE;
5910 AcquiredExclusive = TRUE;
5911
5912 Fcb = RxFcbTableLookupFcb(&NetRoot->FcbTable, NetRootName);
5913 if (Fcb != NULL && Fcb->fShouldBeOrphaned)
5914 {
5917 Fcb = NULL;
5918 }
5919 }
5920 }
5921
5922 /* If FCB was not found or is not covering full path, prepare for more work */
5923 if (Fcb == NULL || Fcb->FcbTableEntry.Path.Length != NetRootName->Length)
5924 {
5925 if (Fcb != NULL)
5926 {
5927 DPRINT1("FCB was found and it's not covering the whole path: %wZ - %wZ\n", &Fcb->FcbTableEntry.Path, NetRootName);
5928 }
5929
5930 if (!AcquiredExclusive)
5931 {
5934 TableAcquired = TRUE;
5935 }
5936
5937 /* If FCB table was updated in between, re-attempt a lookup */
5938 if (NetRoot->FcbTable.Version != Version)
5939 {
5940 Fcb = RxFcbTableLookupFcb(&NetRoot->FcbTable, NetRootName);
5941 if (Fcb != NULL && Fcb->FcbTableEntry.Path.Length != NetRootName->Length)
5942 {
5943 Fcb = NULL;
5944 }
5945 }
5946 }
5947
5948 /* Allocate the FCB */
5949 _SEH2_TRY
5950 {
5951 if (Fcb == NULL)
5952 {
5953 Fcb = RxCreateNetFcb(RxContext, VNetRoot, NetRootName);
5954 if (Fcb == NULL)
5955 {
5957 }
5958 else
5959 {
5960 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
5961 RxContext->Create.FcbAcquired = NT_SUCCESS(Status);
5962 }
5963 }
5964 }
5966 {
5968 {
5970 TableAcquired = FALSE;
5971
5972 if (Fcb != NULL)
5973 {
5975
5978 {
5979 ExReleaseResourceLite(Fcb->Header.Resource);
5980 }
5981 }
5982 }
5983 }
5984 _SEH2_END;
5985
5986 if (TableAcquired)
5987 {
5989 }
5990
5991 if (!NT_SUCCESS(Status))
5992 {
5993 return Status;
5994 }
5995
5996 RxContext->pFcb = RX_GET_MRX_FCB(Fcb);
5997 DPRINT("FCB %p is in condition %lx\n", Fcb, Fcb->Condition);
5998
5999 if (!RxContext->Create.FcbAcquired)
6000 {
6001 RxWaitForStableNetFcb(Fcb, RxContext);
6002 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
6003 RxContext->Create.FcbAcquired = NT_SUCCESS(Status);
6004 }
6005
6006 return Status;
6007}
6008
6011 PRX_CONTEXT RxContext,
6013 PUNICODE_STRING CanonicalName,
6014 PNET_ROOT_TYPE NetRootType)
6015{
6018 BOOLEAN UncName, PrependString, IsSpecial;
6019 USHORT CanonicalLength;
6020 UNICODE_STRING SessionIdString;
6021 WCHAR SessionIdBuffer[16];
6022
6023 PAGED_CODE();
6024
6026 PrependString = FALSE;
6027 IsSpecial = FALSE;
6028 UncName = FALSE;
6030
6031 /* Name has to contain at least \\ */
6032 if (FileName->Length < 2 * sizeof(WCHAR))
6033 {
6035 }
6036
6037 /* First easy check, is that a path with a name? */
6038 CanonicalLength = FileName->Length;
6039 if (FileName->Length > 5 * sizeof(WCHAR))
6040 {
6041 if (FileName->Buffer[0] == '\\' && FileName->Buffer[1] == ';')
6042 {
6043 if (FileName->Buffer[3] == ':')
6044 {
6046 }
6047 else
6048 {
6050 }
6051 }
6052 }
6053
6054 /* Nope, attempt deeper parsing */
6055 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR && FileName->Buffer[1] != ';')
6056 {
6058 PWSTR FirstSlash, EndOfString;
6059
6061 UncName = TRUE;
6062
6063 /* The lack of drive letter will be replaced by session ID */
6065 RtlInitEmptyUnicodeString(&SessionIdString, SessionIdBuffer, sizeof(SessionIdBuffer));
6066 RtlIntegerToUnicodeString(SessionId, 10, &SessionIdString);
6067
6068 EndOfString = Add2Ptr(FileName->Buffer, FileName->Length);
6069 for (FirstSlash = &FileName->Buffer[1]; FirstSlash != EndOfString; ++FirstSlash)
6070 {
6071 if (*FirstSlash == OBJ_NAME_PATH_SEPARATOR)
6072 {
6073 break;
6074 }
6075 }
6076
6077 if (EndOfString - FirstSlash <= 1)
6078 {
6080 }
6081 else
6082 {
6084 DPRINT1("WARNING: Assuming not special + disk!\n");
6087 //Status = STATUS_NOT_IMPLEMENTED;
6088 /* Should be check against IPC, mailslot, and so on */
6089 }
6090 }
6091
6092 /* Update net root type with our deduced one */
6093 *NetRootType = Type;
6094 DPRINT("Returning type: %x\n", Type);
6095
6096 if (!NT_SUCCESS(Status))
6097 {
6098 return Status;
6099 }
6100
6101 /* Do we have to prepend session ID? */
6102 if (UncName)
6103 {
6104 if (!IsSpecial)
6105 {
6106 PrependString = TRUE;
6107 CanonicalLength += SessionIdString.Length + 3 * sizeof(WCHAR);
6108 }
6109 }
6110
6111 /* If not UNC path, we should preprend stuff */
6112 if (!PrependString && !IsSpecial && FileName->Buffer[0] != '\\')
6113 {
6115 }
6116
6117 /* Allocate the buffer */
6118 Status = RxAllocateCanonicalNameBuffer(RxContext, CanonicalName, CanonicalLength);
6119 if (!NT_SUCCESS(Status))
6120 {
6121 return Status;
6122 }
6123
6124 /* We don't support that case, we always return disk */
6125 if (IsSpecial)
6126 {
6127 ASSERT(CanonicalName->Length == CanonicalLength);
6130 }
6131 else
6132 {
6133 /* If we have to prepend, go ahead */
6134 if (PrependString)
6135 {
6136 CanonicalName->Buffer[0] = '\\';
6137 CanonicalName->Buffer[1] = ';';
6138 CanonicalName->Buffer[2] = ':';
6139 CanonicalName->Length = 3 * sizeof(WCHAR);
6140 RtlAppendUnicodeStringToString(CanonicalName, &SessionIdString);
6142
6143 DPRINT1("CanonicalName: %wZ\n", CanonicalName);
6144 }
6145 /* Otherwise, that's a simple copy */
6146 else
6147 {
6148 RtlCopyUnicodeString(CanonicalName, FileName);
6149 }
6150 }
6151
6152 return Status;
6153}
6154
6155/*
6156 * @implemented
6157 */
6158VOID
6161{
6162 /* These two buffers are always the same */
6163 ASSERT(Context->Create.CanonicalNameBuffer == Context->AlsoCanonicalNameBuffer);
6164
6165 if (Context->Create.CanonicalNameBuffer != NULL)
6166 {
6167 RxFreePoolWithTag(Context->Create.CanonicalNameBuffer, RX_MISC_POOLTAG);
6168 Context->Create.CanonicalNameBuffer = NULL;
6169 Context->AlsoCanonicalNameBuffer = NULL;
6170 }
6171
6172 ASSERT(Context->AlsoCanonicalNameBuffer == NULL);
6173}
6174
6177 PRX_FSD_DISPATCH_VECTOR DispatchVector,
6181 PIRP Irp,
6182 PRDBSS_DEVICE_OBJECT RxDeviceObject)
6183{
6184 KIRQL OldIrql;
6188 PFILE_OBJECT StackFileObject;
6189 PRX_FSD_DISPATCH DispatchFunc;
6190 RX_TOPLEVELIRP_CONTEXT TopLevelContext;
6191 BOOLEAN TopLevel, Closing, PassToDriver, SetCancelRoutine, PostRequest, CanWait;
6192
6194
6195 DPRINT("RxFsdCommonDispatch(%p, %d, %p, %p, %p, %p)\n", DispatchVector, MajorFunction, Stack, FileObject, Irp, RxDeviceObject);
6196
6198
6199 TopLevel = RxTryToBecomeTheTopLevelIrp(&TopLevelContext, Irp, RxDeviceObject, FALSE);
6200
6201 _SEH2_TRY
6202 {
6203 CanWait = TRUE;
6204 Closing = FALSE;
6205 PostRequest = FALSE;
6206 SetCancelRoutine = TRUE;
6207 MinorFunction = Stack->MinorFunction;
6208 /* Can we wait? */
6209 switch (MajorFunction)
6210 {
6212 if (FileObject != NULL)
6213 {
6214 CanWait = IoIsOperationSynchronous(Irp);
6215 }
6216 else
6217 {
6218 CanWait = TRUE;
6219 }
6220 break;
6221
6222 case IRP_MJ_READ:
6223 case IRP_MJ_WRITE:
6226 case IRP_MJ_QUERY_EA:
6227 case IRP_MJ_SET_EA:
6236 CanWait = IoIsOperationSynchronous(Irp);
6237 break;
6238
6239 case IRP_MJ_CLOSE:
6240 case IRP_MJ_CLEANUP:
6241 Closing = TRUE;
6242 SetCancelRoutine = FALSE;
6243 break;
6244
6245 default:
6246 break;
6247 }
6248
6250 /* Should we stop it right now, or mini-rdr deserves to know? */
6251 PassToDriver = TRUE;
6252 if (RxGetRdbssState(RxDeviceObject) != RDBSS_STARTABLE)
6253 {
6254 if (RxGetRdbssState(RxDeviceObject) == RDBSS_STOP_IN_PROGRESS && !Closing)
6255 {
6256 PassToDriver = FALSE;
6258 DPRINT1("Not started!\n");
6259 }
6260 }
6261 else
6262 {
6263 if (DispatchVector != RxDeviceFCBVector && (FileObject->FileName.Length != 0 || FileObject->RelatedFileObject != NULL))
6264 {
6265 PassToDriver = FALSE;
6267 DPRINT1("Not started!\n");
6268 }
6269 }
6271
6272 StackFileObject = Stack->FileObject;
6273 /* Make sure we don't deal with orphaned stuff */
6274 if (StackFileObject != NULL && StackFileObject->FsContext != NULL)
6275 {
6276 if (StackFileObject->FsContext2 != UIntToPtr(DFS_OPEN_CONTEXT) &&
6277 StackFileObject->FsContext2 != UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT) &&
6278 StackFileObject->FsContext != &RxDeviceFCB)
6279 {
6280 PFCB Fcb;
6281 PFOBX Fobx;
6282
6283 Fcb = StackFileObject->FsContext;
6284 Fobx = StackFileObject->FsContext2;
6285
6287 ((Fobx != NULL) && BooleanFlagOn(Fobx->pSrvOpen->Flags, SRVOPEN_FLAG_ORPHANED)))
6288 {
6289 if (Closing)
6290 {
6291 PassToDriver = TRUE;
6292 }
6293 else
6294 {
6295 PassToDriver = FALSE;
6297 DPRINT1("Operation on orphaned FCB: %p\n", Fcb);
6298 }
6299 }
6300 }
6301 }
6302
6303 /* Did we receive a close request whereas we're stopping? */
6304 if (RxGetRdbssState(RxDeviceObject) == RDBSS_STOP_IN_PROGRESS && Closing)
6305 {
6306 PFCB Fcb;
6307
6308 Fcb = StackFileObject->FsContext;
6309
6310 DPRINT1("Close received after stop\n");
6311 DPRINT1("Irp: %p %d:%d FO: %p FCB: %p\n",
6312 Irp, Stack->MajorFunction, Stack->MinorFunction, StackFileObject, Fcb);
6313
6314 if (Fcb != NULL && Fcb != &RxDeviceFCB &&
6316 {
6317 DPRINT1("OpenCount: %ld, UncleanCount: %ld, Name: %wZ\n",
6319 }
6320 }
6321
6322 /* Should we stop the whole thing now? */
6323 if (!PassToDriver)
6324 {
6326 {
6328 Irp->IoStatus.Status = Status;
6329 Irp->IoStatus.Information = 0;
6332 }
6333 else
6334 {
6335 Irp->IoStatus.Status = Status;
6336 Irp->IoStatus.Information = 0;
6338 }
6339
6341 }
6342
6343 /* No? Allocate a context to deal with the mini-rdr */
6344 Context = RxCreateRxContext(Irp, RxDeviceObject, (CanWait ? RX_CONTEXT_FLAG_WAIT : 0));
6345 if (Context == NULL)
6346 {
6350 }
6351
6352 /* Set cancel routine if required */
6353 if (SetCancelRoutine)
6354 {
6357 }
6358 else
6359 {
6362 }
6364
6366
6367 Irp->IoStatus.Status = STATUS_SUCCESS;
6368 Irp->IoStatus.Information = 0;
6369 /* Get the dispatch routine */
6370 DispatchFunc = DispatchVector[MajorFunction].CommonRoutine;
6371
6373 {
6374 /* Handle the complete MDL case */
6376 {
6377 DispatchFunc = RxCompleteMdl;
6378 }
6379 else
6380 {
6381 /* Do we have to post request? */
6383 {
6384 PostRequest = TRUE;
6385 }
6386 else
6387 {
6388 /* Our read function needs stack, make sure we won't overflow,
6389 * otherwise, post the request
6390 */
6392 {
6393 if (IoGetRemainingStackSize() < 0xE00)
6394 {
6395 Context->PendingReturned = TRUE;
6397 if (Status != STATUS_PENDING)
6398 {
6399 Context->PendingReturned = FALSE;
6401 }
6402
6404 }
6405 }
6406 }
6407 }
6408 }
6409
6410 Context->ResumeRoutine = DispatchFunc;
6411 /* There's a dispatch routine? Time to dispatch! */
6412 if (DispatchFunc != NULL)
6413 {
6414 Context->PendingReturned = TRUE;
6415 if (PostRequest)
6416 {
6418 }
6419 else
6420 {
6421 /* Retry as long as we have */
6422 do
6423 {
6424 Status = DispatchFunc(Context);
6425 }
6426 while (Status == STATUS_RETRY);
6427
6428 if (Status == STATUS_PENDING)
6429 {
6431 }
6432
6433 /* Sanity check: did someone mess with our context? */
6434 if (Context->CurrentIrp != Irp || Context->CurrentIrpSp != Stack ||
6435 Context->MajorFunction != MajorFunction || Stack->MinorFunction != MinorFunction)
6436 {
6437 DPRINT1("RX_CONTEXT %p has been contaminated!\n", Context);
6438 DPRINT1("->CurrentIrp %p %p\n", Context->CurrentIrp, Irp);
6439 DPRINT1("->CurrentIrpSp %p %p\n", Context->CurrentIrpSp, Stack);
6440 DPRINT1("->MajorFunction %d %d\n", Context->MajorFunction, MajorFunction);
6441 DPRINT1("->MinorFunction %d %d\n", Context->MinorFunction, MinorFunction);
6442 }
6443 Context->PendingReturned = FALSE;
6445 }
6446 }
6447 else
6448 {
6450 }
6451 }
6453 {
6454 if (TopLevel)
6455 {
6456 RxUnwindTopLevelIrp(&TopLevelContext);
6457 }
6458
6460 }
6461 _SEH2_END;
6462
6463 DPRINT("RxFsdDispatch, Status: %lx\n", Status);
6464 return Status;
6465}
6466
6467/*
6468 * @implemented
6469 */
6471NTAPI
6473 IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
6474 IN PIRP Irp)
6475{
6476 PFCB Fcb;
6478 PRX_FSD_DISPATCH_VECTOR DispatchVector;
6479
6480 PAGED_CODE();
6481
6482 DPRINT("RxFsdDispatch(%p, %p)\n", RxDeviceObject, Irp);
6483
6485
6486 /* Dispatch easy case */
6487 if (Stack->MajorFunction == IRP_MJ_SYSTEM_CONTROL)
6488 {
6489 return RxSystemControl(RxDeviceObject, Irp);
6490 }
6491
6492 /* Bail out broken cases */
6493 if (Stack->MajorFunction == IRP_MJ_CREATE_MAILSLOT ||
6494 Stack->MajorFunction == IRP_MJ_CREATE_NAMED_PIPE)
6495 {
6497 Irp->IoStatus.Information = 0;
6498 Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
6500 return STATUS_PENDING;
6501 }
6502
6503 /* Immediately handle create */
6504 if (Stack->MajorFunction == IRP_MJ_CREATE)
6505 {
6506 return RxFsdCommonDispatch(&RxFsdDispatchVector[0], Stack->MajorFunction, Stack, Stack->FileObject, Irp, RxDeviceObject);
6507 }
6508
6509 /* If not a creation, we must have at least a FO with a FCB */
6510 if (Stack->FileObject == NULL || Stack->FileObject->FsContext == NULL)
6511 {
6513 Irp->IoStatus.Information = 0;
6514 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
6516 return STATUS_PENDING;
6517 }
6518
6519 /* Set the dispatch vector if required */
6520 Fcb = Stack->FileObject->FsContext;
6522 {
6523 DispatchVector = &RxFsdDispatchVector[0];
6524 }
6525 else
6526 {
6527 DispatchVector = Fcb->PrivateDispatchVector;
6528 }
6529
6530 /* Device cannot accept such requests */
6531 if (RxDeviceObject == RxFileSystemDeviceObject)
6532 {
6534 Irp->IoStatus.Information = 0;
6535 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
6537 return STATUS_PENDING;
6538 }
6539
6540 /* Dispatch for real! */
6541 return RxFsdCommonDispatch(DispatchVector, Stack->MajorFunction, Stack, Stack->FileObject, Irp, RxDeviceObject);
6542}
6543
6544/*
6545 * @implemented
6546 */
6549 IN PRX_CONTEXT RxContext)
6550{
6551 /* Initialize posting if required */
6553 {
6554 RxPrePostIrp(RxContext, RxContext->CurrentIrp);
6555 }
6556
6557 DPRINT("Posting MN: %d, Ctxt: %p, IRP: %p, Thrd: %lx #%lx\n",
6558 RxContext->MinorFunction, RxContext,
6559 RxContext->CurrentIrp, RxContext->LastExecutionThread,
6560 RxContext->SerialNumber);
6561
6562 RxAddToWorkque(RxContext, RxContext->CurrentIrp);
6563 return STATUS_PENDING;
6564}
6565
6566/*
6567 * @implemented
6568 */
6569VOID
6570NTAPI
6573{
6574 KIRQL EntryIrql;
6576 PRDBSS_DEVICE_OBJECT VolumeDO;
6577 PRX_CONTEXT RxContext, EntryContext;
6578
6579 PAGED_CODE();
6580
6581 RxContext = Context;
6583 /* Save IRQL at entry for later checking */
6584 EntryIrql = KeGetCurrentIrql();
6585
6586 /* No FO, deal with device */
6587 if (RxContext->CurrentIrpSp->FileObject != NULL)
6588 {
6589 VolumeDO = RxFileSystemDeviceObject;
6590 }
6591 else
6592 {
6593 VolumeDO = NULL;
6594 }
6595
6596 /* Which queue to used for delayed? */
6598 {
6600 }
6601 else
6602 {
6605 }
6606
6607 do
6608 {
6609 PIRP Irp;
6611 BOOLEAN RecursiveCall;
6612 RX_TOPLEVELIRP_CONTEXT TopLevelContext;
6613
6615 ASSERT(!RxContext->PostRequest);
6616
6619
6620 DPRINT("Dispatch: MN: %d, Ctxt: %p, IRP: %p, THRD: %lx #%lx\n", RxContext->MinorFunction,
6621 RxContext, RxContext->CurrentIrp, RxContext->LastExecutionThread,
6622 RxContext->SerialNumber);
6623
6624 Irp = RxContext->CurrentIrp;
6625
6627
6628 RecursiveCall = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_RECURSIVE_CALL);
6629 RxTryToBecomeTheTopLevelIrp(&TopLevelContext,
6630 (RecursiveCall ? (PIRP)FSRTL_FSP_TOP_LEVEL_IRP : RxContext->CurrentIrp),
6631 RxContext->RxDeviceObject, TRUE);
6632
6633 ASSERT(RxContext->ResumeRoutine != NULL);
6634
6635 if (BooleanFlagOn(RxContext->MinorFunction, IRP_MN_DPC) && Irp->Tail.Overlay.Thread == NULL)
6636 {
6637 ASSERT((RxContext->MajorFunction == IRP_MJ_WRITE) || (RxContext->MajorFunction == IRP_MJ_READ));
6638 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
6639 }
6640
6641 /* Call the resume routine */
6642 do
6643 {
6644 BOOLEAN NoComplete;
6645
6647
6648 Status = RxContext->ResumeRoutine(RxContext);
6649 if (!NoComplete && Status != STATUS_PENDING)
6650 {
6651 if (Status != STATUS_RETRY)
6652 {
6653 Status = RxCompleteRequest(RxContext, Status);
6654 }
6655 }
6656 }
6657 while (Status == STATUS_RETRY);
6658
6659 RxUnwindTopLevelIrp(&TopLevelContext);
6661
6662 if (VolumeDO != NULL)
6663 {
6664 RxContext = RxRemoveOverflowEntry(VolumeDO, Queue);
6665 }
6666 else
6667 {
6668 RxContext = NULL;
6669 }
6670 } while (RxContext != NULL);
6671
6672 /* Did we mess with IRQL? */
6673 if (KeGetCurrentIrql() >= APC_LEVEL)
6674 {
6675 DPRINT1("High IRQL for Ctxt %p, on entry: %x\n", EntryContext, EntryIrql);
6676 }
6677}
6678
6679/*
6680 * @implemented
6681 */
6682ULONG
6685{
6686 PAGED_CODE();
6687 return 1;
6688}
6689
6690/*
6691 * @implemented
6692 */
6693VOID
6694NTAPI
6697{
6698 USHORT i;
6700 UCHAR Buffer[0x400];
6702 UNICODE_STRING KeyName, OutString;
6704
6705 PAGED_CODE();
6706
6709 if (!NT_SUCCESS(Status))
6710 {
6711 return;
6712 }
6713
6714 RtlInitUnicodeString(&KeyName, L"Parameters");
6717 if (NT_SUCCESS(Status))
6718 {
6719 /* The only parameter we deal with is InitialDebugString */
6720 RxGetStringRegistryParameter(KeyHandle, L"InitialDebugString", &OutString, Buffer, sizeof(Buffer), 0);
6721 if (OutString.Length != 0 && OutString.Length < 0x140)
6722 {
6723 PWSTR Read;
6724 PSTR Write;
6725
6726 Read = OutString.Buffer;
6727 Write = (PSTR)OutString.Buffer;
6728 for (i = 0; i < OutString.Length; ++i)
6729 {
6730 *Read = *Write;
6731 ++Write;
6732 *Write = ANSI_NULL;
6733 ++Read;
6734 }
6735
6736 /* Which is a string we'll just write out */
6737 DPRINT("InitialDebugString read from registry: '%s'\n", OutString.Buffer);
6738 RxDebugControlCommand((PSTR)OutString.Buffer);
6739 }
6740
6742 }
6743
6745}
6746
6747/*
6748 * @implemented
6749 */
6750ULONG
6753{
6756 PIO_SECURITY_CONTEXT SecurityContext;
6757
6758 PAGED_CODE();
6759
6760 /* If that's not a prefix claim, not an open request, session id will be 0 */
6761 if (IrpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL || IrpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_REDIR_QUERY_PATH)
6762 {
6763 if (IrpSp->MajorFunction != IRP_MJ_CREATE || IrpSp->Parameters.Create.SecurityContext == NULL)
6764 {
6765 return 0;
6766 }
6767
6768 SecurityContext = IrpSp->Parameters.Create.SecurityContext;
6769 }
6770 else
6771 {
6772 SecurityContext = ((PQUERY_PATH_REQUEST)IrpSp->Parameters.DeviceIoControl.Type3InputBuffer)->SecurityContext;
6773 }
6774
6775 /* Query the session id */
6778
6779 return SessionId;
6780}
6781
6782/*
6783 * @implemented
6784 */
6786NTAPI
6790 OUT PUNICODE_STRING OutString,
6793 IN BOOLEAN LogFailure)
6794{
6797 UNICODE_STRING KeyString;
6798
6799 PAGED_CODE();
6800
6801 RtlInitUnicodeString(&KeyString, KeyName);
6802 Status = ZwQueryValueKey(KeyHandle, &KeyString, KeyValuePartialInformation, Buffer, BufferLength, &ResultLength);
6803 OutString->Length = 0;
6804 OutString->Buffer = 0;
6805 if (!NT_SUCCESS(Status))
6806 {
6807 if (LogFailure)
6808 {
6810 }
6811
6812 return Status;
6813 }
6814
6815 OutString->Buffer = (PWSTR)(((PKEY_VALUE_PARTIAL_INFORMATION)Buffer)->Data);
6816 OutString->Length = ((PKEY_VALUE_PARTIAL_INFORMATION)Buffer)->DataLength - sizeof(UNICODE_NULL);
6817 OutString->MaximumLength = OutString->Length;
6818
6819 return STATUS_SUCCESS;
6820}
6821
6822/*
6823 * @implemented
6824 */
6827 VOID)
6828{
6829 PIRP TopLevelIrp;
6830 PRDBSS_DEVICE_OBJECT TopDevice = NULL;
6831
6832 TopLevelIrp = IoGetTopLevelIrp();
6834 {
6835 TopDevice = ((PRX_TOPLEVELIRP_CONTEXT)TopLevelIrp)->RxDeviceObject;
6836 }
6837
6838 return TopDevice;
6839}
6840
6841/*
6842 * @implemented
6843 */
6844PIRP
6846 VOID)
6847{
6848 PIRP Irp = NULL;
6850
6853 {
6854 Irp = TopLevel->Irp;
6855 }
6856
6857 return Irp;
6858}
6859
6860/*
6861 * @implemented
6862 */
6863LUID
6866{
6867 LUID Luid;
6869
6870 PAGED_CODE();
6871
6874
6875 return Luid;
6876}
6877
6878VOID
6879NTAPI
6881 PMRX_SRV_CALL SrvCall,
6882 PMRX_SRV_OPEN SrvOpen,
6883 PVOID SrvOpenKey,
6884 PVOID Context)
6885{
6887}
6888
6889/*
6890 * @implemented
6891 */
6892VOID
6893NTAPI
6896{
6897 USHORT i;
6898
6899 PAGED_CODE();
6900
6901 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
6902 {
6903 DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)RxFsdDispatch;
6904 }
6905
6909
6910 DriverObject->FastIoDispatch = &RxFastIoDispatch;
6926
6928
6933
6938}
6939
6941NTAPI
6943 VOID)
6944{
6947}
6948
6949/*
6950 * @implemented
6951 */
6952VOID
6955{
6956 PAGED_CODE();
6957}
6958
6959/*
6960 * @implemented
6961 */
6963NTAPI
6965 VOID)
6966{
6967 PAGED_CODE();
6968
6973
6974 return STATUS_SUCCESS;
6975}
6976
6977/*
6978 * @implemented
6979 */
6980VOID
6981NTAPI
6983 VOID)
6984{
6987}
6988
6989VOID
6990NTAPI
6993 USHORT State)
6994{
6996}
6997
6998/*
6999 * @implemented
7000 */
7001BOOLEAN
7003 PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
7004{
7005 KIRQL OldIrql;
7006 PLIST_ENTRY NextEntry;
7008 PRX_TOPLEVELIRP_CONTEXT ListContext;
7009
7010 /* Browse all the allocated TLC to find ours */
7012 for (NextEntry = TopLevelIrpAllocatedContextsList.Flink;
7014 NextEntry = NextEntry->Flink)
7015 {
7016 ListContext = CONTAINING_RECORD(NextEntry, RX_TOPLEVELIRP_CONTEXT, ListEntry);
7019
7020 /* Found! */
7021 if (ListContext == TopLevelContext)
7022 {
7023 Found = TRUE;
7024 break;
7025 }
7026 }
7028
7029 return Found;
7030}
7031
7032/*
7033 * @implemented
7034 */
7035BOOLEAN
7037 PFCB Fcb)
7038{
7040
7041 /* No associated SRV_OPEN, it's OK to purge */
7042 if (IsListEmpty(&Fcb->SrvOpenList))
7043 {
7044 return TRUE;
7045 }
7046
7047 /* Only allow to purge if all the associated SRV_OPEN
7048 * - have no outstanding opens ongoing
7049 * - have only read attribute set
7050 */
7051 for (Entry = Fcb->SrvOpenList.Flink;
7052 Entry != &Fcb->SrvOpenList;
7053 Entry = Entry->Flink)
7054 {
7055 PSRV_OPEN SrvOpen;
7056
7057 SrvOpen = CONTAINING_RECORD(Entry, SRV_OPEN, SrvOpenQLinks);
7058
7059 /* Failing previous needs, don't allow purge */
7060 if (SrvOpen->UncleanFobxCount != 0 ||
7061 (SrvOpen->DesiredAccess & 0xFFEFFFFF) != FILE_READ_ATTRIBUTES)
7062 {
7063 return FALSE;
7064 }
7065 }
7066
7067 /* All correct, allow purge */
7068 return TRUE;
7069}
7070
7071/*
7072 * @implemented
7073 */
7074BOOLEAN
7076 PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
7077{
7078 ULONG_PTR StackTop, StackBottom;
7079
7080 /* Bail out for flags */
7081 if ((ULONG_PTR)TopLevelContext <= FSRTL_FAST_IO_TOP_LEVEL_IRP)
7082 {
7083 return FALSE;
7084 }
7085
7086 /* Is our provided TLC allocated on stack? */
7087 IoGetStackLimits(&StackTop, &StackBottom);
7088 if ((ULONG_PTR)TopLevelContext <= StackBottom - sizeof(RX_TOPLEVELIRP_CONTEXT) &&
7089 (ULONG_PTR)TopLevelContext >= StackTop)
7090 {
7091 /* Yes, so check whether it's really a TLC by checking alignement & signature */
7092 if (!BooleanFlagOn((ULONG_PTR)TopLevelContext, 0x3) && TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE)
7093 {
7094 return TRUE;
7095 }
7096
7097 return FALSE;
7098 }
7099
7100 /* No, use the helper function */
7101 return RxIsMemberOfTopLevelIrpAllocatedContextsList(TopLevelContext);
7102}
7103
7104/*
7105 * @implemented
7106 */
7107BOOLEAN
7109 IN PIRP Irp)
7110{
7111 PIRP TopLevelIrp;
7112
7113 /* When we put oursleves as top level, we set TLC as 'IRP', so look for it */
7114 TopLevelIrp = IoGetTopLevelIrp();
7116 {
7117 TopLevelIrp = ((PRX_TOPLEVELIRP_CONTEXT)TopLevelIrp)->Irp;
7118 }
7119
7120 return (TopLevelIrp == Irp);
7121}
7122
7124NTAPI
7127 IN PIRP Irp)
7128{
7131}
7132
7133/*
7134 * @implemented
7135 */
7136VOID
7137NTAPI
7140 IN PUNICODE_STRING OriginatorId,
7141 IN ULONG EventId,
7143 IN ULONG Line)
7144{
7145 PUNICODE_STRING Originator = OriginatorId;
7146 LARGE_INTEGER LargeLine;
7147
7148 /* Set optional parameters */
7149 LargeLine.QuadPart = Line;
7150 if (OriginatorId == NULL || OriginatorId->Length == 0)
7151 {
7152 Originator = (PUNICODE_STRING)&unknownId;
7153 }
7154
7155 /* And log */
7156 RxLogEventWithAnnotation(DeviceObject, EventId, Status, &LargeLine, sizeof(LargeLine), Originator, 1);
7157}
7158
7159VOID
7160NTAPI
7163 IN ULONG EventId,
7165 IN PVOID DataBuffer,
7167 IN PUNICODE_STRING Annotation,
7168 IN ULONG AnnotationCount)
7169{
7171}
7172
7174NTAPI
7176 PRX_CONTEXT RxContext)
7177{
7180}
7181
7182/*
7183 * @implemented
7184 */
7186NTAPI
7188 PRX_CONTEXT RxContext)
7189{
7190 PIRP Irp;
7192
7193 PAGED_CODE();
7194
7195 DPRINT("RxLowIoIoCtlShellCompletion(%p)\n", RxContext);
7196
7197 Irp = RxContext->CurrentIrp;
7198 Status = RxContext->IoStatusBlock.Status;
7199
7200 /* Set information and status */
7202 {
7203 Irp->IoStatus.Information = RxContext->IoStatusBlock.Information;
7204 }
7205
7206 Irp->IoStatus.Status = Status;
7207
7208 return Status;
7209}
7210
7213 IN PRX_CONTEXT RxContext)
7214{
7217}
7218
7219/*
7220 * @implemented
7221 */
7223NTAPI
7225 PRX_CONTEXT RxContext)
7226{
7227 PAGED_CODE();
7228
7229 DPRINT("Completing NCD with: %lx, %lx\n", RxContext->IoStatusBlock.Status, RxContext->IoStatusBlock.Information);
7230
7231 /* Just copy back the IO_STATUS to the IRP */
7232 RxSetIoStatusStatus(RxContext, RxContext->IoStatusBlock.Status);
7233 RxSetIoStatusInfo(RxContext, RxContext->IoStatusBlock.Information);
7234
7235 return RxContext->IoStatusBlock.Status;
7236}
7237
7238/*
7239 * @implemented
7240 */
7243 PRX_CONTEXT RxContext)
7244{
7245 PFCB Fcb;
7247
7248 PAGED_CODE();
7249
7250 DPRINT("RxLowIoReadShell(%p)\n", RxContext);
7251
7252 Fcb = (PFCB)RxContext->pFcb;
7254 {
7256 }
7257
7258 /* Always update stats for disks */
7259 if (Fcb->CachedNetRootType == NET_ROOT_DISK)
7260 {
7262 }
7263
7264 /* And forward the read to the mini-rdr */
7266 DPRINT("RxLowIoReadShell(%p), Status: %lx\n", RxContext, Status);
7267
7268 return Status;
7269}
7270
7272NTAPI
7274 PRX_CONTEXT RxContext)
7275{
7276 PIRP Irp;
7277 PFCB Fcb;
7279 BOOLEAN PagingIo, IsPipe;
7281 PLOWIO_CONTEXT LowIoContext;
7282
7283 PAGED_CODE();
7284
7285 DPRINT("RxLowIoReadShellCompletion(%p)\n", RxContext);
7286
7287 Status = RxContext->IoStatusBlock.Status;
7288 DPRINT("In %p, Status: %lx, Information: %lx\n", RxContext, Status, RxContext->IoStatusBlock.Information);
7289
7290 Irp = RxContext->CurrentIrp;
7291 PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
7292
7293 /* Set IRP information from the RX_CONTEXT status block */
7294 Irp->IoStatus.Information = RxContext->IoStatusBlock.Information;
7295
7296 /* Fixup status for paging file if nothing was read */
7297 if (PagingIo)
7298 {
7299 if (NT_SUCCESS(Status) && RxContext->IoStatusBlock.Information == 0)
7300 {
7302 }
7303 }
7304
7305 LowIoContext = &RxContext->LowIoContext;
7306 ASSERT(RxLowIoIsBufferLocked(LowIoContext));
7307
7308 /* Check broken cases that should never happen */
7309 Fcb = (PFCB)RxContext->pFcb;
7311 {
7313 {
7314 ASSERT(FALSE);
7315 return STATUS_RETRY;
7316 }
7317 }
7318 else if (Status == STATUS_SUCCESS)
7319 {
7321 {
7324 {
7325 ASSERT(FALSE);
7326 }
7327 }
7328
7330 {
7331 ASSERT(FALSE);
7332 }
7333 }
7334
7335 /* Readahead should go through Cc and not finish here */
7337
7338 /* If it's sync, RxCommonRead will finish the work - nothing to do here */
7340 {
7341 return Status;
7342 }
7343
7344 Stack = RxContext->CurrentIrpSp;
7346 /* Release lock if required */
7347 if (PagingIo)
7348 {
7349 RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
7350 }
7351 else
7352 {
7353 /* Set FastIo if read was a success */
7354 if (NT_SUCCESS(Status) && !IsPipe)
7355 {
7356 SetFlag(Stack->FileObject->Flags, FO_FILE_FAST_IO_READ);
7357 }
7358
7360 {
7361 RxResumeBlockedOperations_Serially(RxContext, &((PFOBX)RxContext->pFobx)->Specific.NamedPipe.ReadSerializationQueue);
7362 }
7363 else
7364 {
7365 RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
7366 }
7367 }
7368
7369 if (IsPipe)
7370 {
7372 }
7373
7374 /* Final sanity checks */
7376 ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Read.Length);
7377 ASSERT(RxContext->MajorFunction == IRP_MJ_READ);
7378
7379 return Status;
7380}
7381
7382/*
7383 * @implemented
7384 */
7387 IN PRX_CONTEXT RxContext)
7388{
7389 PFCB Fcb;
7391
7392 PAGED_CODE();
7393
7394 DPRINT("RxLowIoWriteShell(%p)\n", RxContext);
7395
7396 Fcb = (PFCB)RxContext->pFcb;
7397
7400
7401 /* Always update stats for disks */
7402 if (Fcb->CachedNetRootType == NET_ROOT_DISK)
7403 {
7404 ExInterlockedAddLargeStatistic(&RxContext->RxDeviceObject->NetworkWriteBytesRequested, RxContext->LowIoContext.ParamsFor.ReadWrite.ByteCount);
7405 }
7406
7407 /* And forward the write to the mini-rdr */
7409 DPRINT("RxLowIoWriteShell(%p), Status: %lx\n", RxContext, Status);
7410
7411 return Status;
7412}
7413
7415NTAPI
7417 PRX_CONTEXT RxContext)
7418{
7419 PIRP Irp;
7420 PFCB Fcb;
7422 BOOLEAN PagingIo;
7423 PLOWIO_CONTEXT LowIoContext;
7424
7425 PAGED_CODE();
7426
7427 DPRINT("RxLowIoWriteShellCompletion(%p)\n", RxContext);
7428
7429 Status = RxContext->IoStatusBlock.Status;
7430 DPRINT("In %p, Status: %lx, Information: %lx\n", RxContext, Status, RxContext->IoStatusBlock.Information);
7431
7432 Irp = RxContext->CurrentIrp;
7433
7434 /* Set IRP information from the RX_CONTEXT status block */
7436
7437 LowIoContext = &RxContext->LowIoContext;
7438 ASSERT(RxLowIoIsBufferLocked(LowIoContext));
7439
7440 /* Perform a few sanity checks */
7441 Fcb = (PFCB)RxContext->pFcb;
7443 {
7445 {
7448 }
7449
7451 }
7452
7453 PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
7454 if (Status != STATUS_SUCCESS && PagingIo)
7455 {
7456 DPRINT1("Paging IO failed %p (%p) %lx\n", Fcb, Fcb->NetRoot, Status);
7457 }
7458
7459 /* In case of async call, perform last bits not done in RxCommonWrite */
7460 if (!BooleanFlagOn(LowIoContext->Flags, LOWIO_CONTEXT_FLAG_SYNCCALL))
7461 {
7464
7465 /* We only succeed if we wrote what was asked for */
7467 {
7468 ASSERT(Irp->IoStatus.Information == LowIoContext->ParamsFor.ReadWrite.ByteCount);
7469 }
7470
7471 /* If write succeed, ,also update FILE_OBJECT flags */
7472 Stack = RxContext->CurrentIrpSp;
7474 if (!PagingIo)
7475 {
7477 }
7478
7480 {
7482 }
7483
7484 /* If VDL was extended, fix attributes */
7486 {
7487 LONGLONG LastOffset, FileSize;
7488
7489 LastOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset +
7490 Irp->IoStatus.Information;
7492
7493 if (FileSize < LastOffset)
7494 {
7495 LastOffset = FileSize;
7496 }
7497
7498 Fcb->Header.ValidDataLength.QuadPart = LastOffset;
7499 }
7500
7501 /* One less outstanding write */
7503 {
7504 PNON_PAGED_FCB NonPagedFcb;
7505
7506 NonPagedFcb = LowIoContext->ParamsFor.ReadWrite.NonPagedFcb;
7507 if (NonPagedFcb != NULL)
7508 {
7510 -1, &RxStrucSupSpinLock) == 1)
7511 {
7513 }
7514 }
7515 }
7516
7517 /* Release paging resource if acquired */
7518 if (RxContext->FcbPagingIoResourceAcquired)
7519 {
7520 RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
7521 }
7522
7523 /* Resume blocked operations for pipes */
7525 {
7527 &((PFOBX)RxContext->pFobx)->Specific.NamedPipe.WriteSerializationQueue);
7528 }
7529 else
7530 {
7531 /* And release FCB only for files */
7532 if (RxContext->FcbResourceAcquired)
7533 {
7534 RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
7535 }
7536 }
7537
7538 /* Final sanity checks */
7540 ASSERT((Status != STATUS_SUCCESS) || (Irp->IoStatus.Information <= Stack->Parameters.Write.Length));
7541 ASSERT(RxContext->MajorFunction == IRP_MJ_WRITE);
7542
7544 {
7546 }
7547 }
7548
7549 return Status;
7550}
7551
7552/*
7553 * @implemented
7554 */
7557 PRX_CONTEXT RxContext)
7558{
7559 PIRP Irp;
7562
7563 PAGED_CODE();
7564
7565 /* The IRP can abviously wait */
7566 SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
7567
7568 /* Initialize its lowio */
7570
7571 _SEH2_TRY
7572 {
7573 /* Lock user buffer */
7574 Stack = RxContext->CurrentIrpSp;
7575 RxLockUserBuffer(RxContext, IoWriteAccess, Stack->Parameters.NotifyDirectory.Length);
7576
7577 /* Copy parameters from IO_STACK */
7579 RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.CompletionFilter = Stack->Parameters.NotifyDirectory.CompletionFilter;
7580 RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.NotificationBufferLength = Stack->Parameters.NotifyDirectory.Length;
7581
7582 /* If we have an associated MDL */
7583 Irp = RxContext->CurrentIrp;
7584 if (Irp->MdlAddress != NULL)
7585 {
7586 /* Then, call mini-rdr */
7588 if (RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.pNotificationBuffer != NULL)
7589 {
7591 }
7592 else
7593 {
7595 }
7596 }
7597 else
7598 {
7600 }
7601 }
7603 {
7604 /* All correct */
7605 }
7606 _SEH2_END;
7607
7608 return Status;
7609}
7610
7611/*
7612 * @implemented
7613 */
7614VOID
7615NTAPI
7617 PVOID Context)
7618{
7619 PRX_CONTEXT RxContext;
7620
7621 PAGED_CODE();
7622
7623 RxContext = Context;
7624
7625 /* First, notify mini-rdr about cancellation */
7626 if (RxContext->MRxCancelRoutine != NULL)
7627 {
7628 RxContext->MRxCancelRoutine(RxContext);
7629 }
7630 /* If we didn't find in overflow queue, try in blocking operations */
7631 else if (!RxCancelOperationInOverflowQueue(RxContext))
7632 {
7633 RxCancelBlockingOperation(RxContext);
7634 }
7635
7636 /* And delete the context */
7638}
7639
7642 IN PRX_CONTEXT RxContext)
7643{
7644 PAGED_CODE();
7645
7648}
7649
7650/*
7651 * @implemented
7652 */
7653VOID
7655 PRX_CONTEXT RxContext)
7656{
7657 /* Reuse can only happen for open operations (STATUS_RETRY) */
7658 ASSERT(RxContext->MajorFunction == IRP_MJ_CREATE);
7659
7660 /* Release the FCB if it was acquired */
7661 if (RxContext->Create.FcbAcquired)
7662 {
7663 RxReleaseFcb(RxContext, RxContext->pFcb);
7664 RxContext->Create.FcbAcquired = FALSE;
7665 }
7666
7667 /* Free the canonical name */
7668 RxFreeCanonicalNameBuffer(RxContext);
7669
7670 /* If we have a VNetRoot associated */
7671 if (RxContext->Create.pVNetRoot != NULL || RxContext->Create.NetNamePrefixEntry != NULL)
7672 {
7673 /* Remove our link and thus, dereference the VNetRoot */
7675 if (RxContext->Create.pVNetRoot != NULL)
7676 {
7677 RxDereferenceVNetRoot(RxContext->Create.pVNetRoot, TRUE);
7678 RxContext->Create.pVNetRoot = NULL;
7679 }
7681 }
7682
7683 DPRINT("RxContext: %p prepared for reuse\n", RxContext);
7684}
7685
7686/*
7687 * @implemented
7688 */
7691 PRX_CONTEXT RxContext,
7692 FILE_INFORMATION_CLASS FileInfoClass,
7693 PVOID Buffer)
7694{
7695 PFCB Fcb;
7697
7698 Fcb = (PFCB)RxContext->pFcb;
7699
7700 /* Set the RX_CONTEXT */
7701 RxContext->Info.FileInformationClass = FileInfoClass;
7702 RxContext->Info.Buffer = Buffer;
7703
7704 /* Pass down */
7705 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxQueryFileInfo, (RxContext));
7706
7707 return Status;
7708}
7709
7710/*
7711 * @implemented
7712 */
7715 IN PRX_CONTEXT RxContext)
7716{
7717 PIRP Irp;
7719 NET_ROOT_TYPE NetRootType;
7720 UNICODE_STRING CanonicalName, FileName, NetRootName;
7721
7722 PAGED_CODE();
7723
7724 Irp = RxContext->CurrentIrp;
7725
7726 /* This has to come from MUP */
7727 if (Irp->RequestorMode == UserMode)
7728 {
7730 }
7731
7732 if (RxContext->MajorFunction == IRP_MJ_DEVICE_CONTROL)
7733 {
7734 PQUERY_PATH_REQUEST QueryRequest;
7735
7736 /* Get parameters */
7737 QueryRequest = RxContext->CurrentIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
7738
7739 /* Don't overflow allocation */
7740 if (QueryRequest->PathNameLength >= MAXUSHORT - 1)
7741 {
7743 }
7744
7745 /* Forcefully rewrite IRP MJ */
7746 RxContext->MajorFunction = IRP_MJ_CREATE;
7747
7748 /* Fake canon name */
7749 RxContext->PrefixClaim.SuppliedPathName.Buffer = RxAllocatePoolWithTag(NonPagedPool, QueryRequest->PathNameLength, RX_MISC_POOLTAG);
7750 if (RxContext->PrefixClaim.SuppliedPathName.Buffer == NULL)
7751 {
7753 goto Leave;
7754 }
7755
7756 /* Copy the prefix to look for */
7757 RtlCopyMemory(RxContext->PrefixClaim.SuppliedPathName.Buffer, &QueryRequest->FilePathName[0], QueryRequest->PathNameLength);
7758 RxContext->PrefixClaim.SuppliedPathName.Length = QueryRequest->PathNameLength;
7759 RxContext->PrefixClaim.SuppliedPathName.MaximumLength = QueryRequest->PathNameLength;
7760
7761 /* Zero the create parameters */
7762 RtlZeroMemory(&RxContext->Create,
7763 FIELD_OFFSET(RX_CONTEXT, AlsoCanonicalNameBuffer) - FIELD_OFFSET(RX_CONTEXT, Create.NtCreateParameters));
7764 RxContext->Create.ThisIsATreeConnectOpen = TRUE;
7765 RxContext->Create.NtCreateParameters.SecurityContext = QueryRequest->SecurityContext;
7766 }
7767 else
7768 {
7769 /* If not devcontrol, it comes from open, name was already copied */
7770 ASSERT(RxContext->MajorFunction == IRP_MJ_CREATE);
7771 ASSERT(RxContext->PrefixClaim.SuppliedPathName.Buffer != NULL);
7772 }
7773
7774 /* Canonilize name */
7775 NetRootType = NET_ROOT_WILD;
7776 RtlInitEmptyUnicodeString(&CanonicalName, NULL, 0);
7777 FileName.Length = RxContext->PrefixClaim.SuppliedPathName.Length;
7778 FileName.MaximumLength = RxContext->PrefixClaim.SuppliedPathName.MaximumLength;
7779 FileName.Buffer = RxContext->PrefixClaim.SuppliedPathName.Buffer;
7780 NetRootName.Length = RxContext->PrefixClaim.SuppliedPathName.Length;
7781 NetRootName.MaximumLength = RxContext->PrefixClaim.SuppliedPathName.MaximumLength;
7782 NetRootName.Buffer = RxContext->PrefixClaim.SuppliedPathName.Buffer;
7783 Status = RxFirstCanonicalize(RxContext, &FileName, &CanonicalName, &NetRootType);
7784 /* It went fine, attempt to establish a connection (that way we know whether the prefix is accepted) */
7785 if (NT_SUCCESS(Status))
7786 {
7787 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, &NetRootName);
7788 }
7789 if (Status == STATUS_PENDING)
7790 {
7791 return Status;
7792 }
7793 /* Reply to MUP */
7794 if (NT_SUCCESS(Status))
7795 {
7796 PQUERY_PATH_RESPONSE QueryResponse;
7797
7798 /* We accept the length that was canon (minus netroot) */
7799 QueryResponse = RxContext->CurrentIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
7800 QueryResponse->LengthAccepted = RxContext->PrefixClaim.SuppliedPathName.Length - NetRootName.Length;
7801 }
7802
7803Leave:
7804 /* If we reach that point with MJ, reset everything and make IRP being a device control */
7805 if (RxContext->MajorFunction == IRP_MJ_CREATE)
7806 {
7807 if (RxContext->PrefixClaim.SuppliedPathName.Buffer != NULL)
7808 {
7809 RxFreePoolWithTag(RxContext->PrefixClaim.SuppliedPathName.Buffer, RX_MISC_POOLTAG);
7810 }
7811
7813
7814 RxContext->MajorFunction = IRP_MJ_DEVICE_CONTROL;
7815 }
7816
7817 return Status;
7818}
7819
7820/*
7821 * @implemented
7822 */
7824NTAPI
7826 PRX_CONTEXT RxContext,
7827 BOOLEAN SymbolicLinkEmbeddedInOldPath,
7828 PUNICODE_STRING NewPath,
7829 BOOLEAN NewPathIsAbsolute,
7830 PBOOLEAN ReparseRequired)
7831{
7832 PWSTR NewBuffer;
7835
7836 /* Assume no reparse is required first */
7837 *ReparseRequired = FALSE;
7838
7839 /* Only supported for IRP_MJ_CREATE */
7840 if (RxContext->MajorFunction != IRP_MJ_CREATE)
7841 {
7843 }
7844
7845 /* If symbolic link is not embedded, and DELETE is specified, fail */
7846 if (!SymbolicLinkEmbeddedInOldPath)
7847 {
7848 /* Excepted if DELETE is the only flag specified, then, open has to succeed
7849 * See: https://msdn.microsoft.com/en-us/library/windows/hardware/ff554649(v=vs.85).aspx (remarks)
7850 */
7851 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, DELETE) &&
7852 BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, ~DELETE))
7853 {
7854 return STATUS_ACCESS_DENIED;
7855 }
7856 }
7857
7858 /* At that point, assume reparse will be required */
7859 *ReparseRequired = TRUE;
7860
7861 /* If new path isn't absolute, it's up to us to make it absolute */
7862 if (!NewPathIsAbsolute)
7863 {
7864 /* The prefix will be \Device\Mup */
7865 NewLength = NewPath->Length + (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL));
7868 if (NewBuffer == NULL)
7869 {
7871 }
7872
7873 /* Copy data for the new path */
7874 RtlMoveMemory(NewBuffer, L"\\Device\\Mup", (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL)));
7875 RtlMoveMemory(Add2Ptr(NewBuffer, (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL))),
7876 NewPath->Buffer, NewPath->Length);
7877 }
7878 /* Otherwise, use caller path as it */
7879 else
7880 {
7881 NewLength = NewPath->Length;
7882 NewBuffer = NewPath->Buffer;
7883 }
7884
7885 /* Get the FILE_OBJECT we'll modify */
7886 FileObject = RxContext->CurrentIrpSp->FileObject;
7887
7888 /* Free old path first */
7889 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
7890 /* And setup new one */
7891 FileObject->FileName.Length = NewLength;
7892 FileObject->FileName.MaximumLength = NewLength;
7893 FileObject->FileName.Buffer = NewBuffer;
7894
7895 /* And set reparse flag */
7897
7898 /* Done! */
7899 return STATUS_SUCCESS;
7900}
7901
7902/*
7903 * @implemented
7904 */
7905VOID
7908 IN PIRP Irp)
7909{
7912 PRX_CONTEXT RxContext = Context;
7913
7914 /* NULL IRP is no option */
7915 if (Irp == NULL)
7916 {
7917 return;
7918 }
7919
7920 /* Check whether preparation was really needed */
7922 {
7923 return;
7924 }
7925 /* Mark the context as prepared */
7927
7928 /* Just lock the user buffer, with the correct length, depending on the MJ */
7930 Stack = RxContext->CurrentIrpSp;
7931 if (RxContext->MajorFunction == IRP_MJ_READ || RxContext->MajorFunction == IRP_MJ_WRITE)
7932 {
7933 if (!BooleanFlagOn(RxContext->MinorFunction, IRP_MN_MDL))
7934 {
7935 if (RxContext->MajorFunction == IRP_MJ_READ)
7936 {
7938 }
7939 RxLockUserBuffer(RxContext, Lock, Stack->Parameters.Read.Length);
7940 }
7941 }
7942 else
7943 {
7944 if ((RxContext->MajorFunction == IRP_MJ_DIRECTORY_CONTROL && RxContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) ||
7945 RxContext->MajorFunction == IRP_MJ_QUERY_EA)
7946 {
7948 RxLockUserBuffer(RxContext, Lock, Stack->Parameters.QueryDirectory.Length);
7949 }
7950 else if (RxContext->MajorFunction == IRP_MJ_SET_EA)
7951 {
7952 RxLockUserBuffer(RxContext, Lock, Stack->Parameters.SetEa.Length);
7953 }
7954 }
7955
7956 /* As it will be posted (async), mark the IRP pending */
7958}
7959
7960/*
7961 * @implemented
7962 */
7965 PRX_CONTEXT RxContext,
7967{
7968 PFCB Fcb;
7970
7971 /* Initialize parameters in RX_CONTEXT */
7972 RxContext->Info.FileInformationClass = Class;
7973 RxContext->Info.Buffer = RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
7974 RxContext->Info.Length = RxContext->CurrentIrpSp->Parameters.SetFile.Length;
7975
7976 /* And call mini-rdr */
7977 Fcb = (PFCB)RxContext->pFcb;
7978 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxSetFileInfo, (RxContext));
7979
7980 return Status;
7981}
7982
7983VOID
7984NTAPI
7986 IN PRDBSS_DEVICE_OBJECT RxDeviceObject)
7987{
7989}
7990
7991/*
7992 * @implemented
7993 */
7994VOID
7996 PFCB Fcb,
7997 PRX_CONTEXT LocalContext)
7998{
8000
8001 PAGED_CODE();
8002
8003 /* First, flush */
8005
8006 /* And force close */
8011}
8012
8015 PRX_CONTEXT RxContext,
8016 PFILE_NAME_INFORMATION AltNameInfo)
8017{
8020}
8021
8022/*
8023 * @implemented
8024 */
8027 PRX_CONTEXT RxContext,
8028 PFILE_BASIC_INFORMATION BasicInfo)
8029{
8030 PAGED_CODE();
8031
8032 DPRINT("RxQueryBasicInfo(%p, %p)\n", RxContext, BasicInfo);
8033
8034 /* Simply zero and forward to mini-rdr */
8035 RtlZeroMemory(BasicInfo, sizeof(FILE_BASIC_INFORMATION));
8036 return RxpQueryInfoMiniRdr(RxContext, FileBasicInformation, BasicInfo);
8037}
8038
8041 PRX_CONTEXT RxContext,
8042 PFILE_COMPRESSION_INFORMATION CompressionInfo)
8043{
8046}
8047
8048/*
8049 * @implemented
8050 */
8053 PRX_CONTEXT RxContext)
8054{
8055 PIRP Irp;
8056 PFCB Fcb;
8057 PFOBX Fobx;
8058 UCHAR Flags;
8060 BOOLEAN LockNotGranted;
8061 ULONG Length, FileIndex;
8064 FILE_INFORMATION_CLASS FileInfoClass;
8065
8066 PAGED_CODE();
8067
8068 DPRINT("RxQueryDirectory(%p)\n", RxContext);
8069
8070 /* Get parameters */
8071 Stack = RxContext->CurrentIrpSp;
8072 Length = Stack->Parameters.QueryDirectory.Length;
8073 FileName = Stack->Parameters.QueryDirectory.FileName;
8074 FileInfoClass = Stack->Parameters.QueryDirectory.FileInformationClass;
8075 DPRINT("Wait: %d, Length: %ld, FileName: %p, Class: %d\n",
8077 FileName, FileInfoClass);
8078
8079 Irp = RxContext->CurrentIrp;
8080 Flags = Stack->Flags;
8081 FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
8082 DPRINT("Index: %d, Buffer: %p, Flags: %x\n", FileIndex, Irp->UserBuffer, Flags);
8083
8084 if (FileName != NULL)
8085 {
8086 DPRINT("FileName: %wZ\n", FileName);
8087 }
8088
8089 /* No FOBX: not a standard file/directory */
8090 Fobx = (PFOBX)RxContext->pFobx;
8091 if (Fobx == NULL)
8092 {
8094 }
8095
8096 /* We can only deal with a disk */
8097 Fcb = (PFCB)RxContext->pFcb;
8098 if (Fcb->pNetRoot->Type != NET_ROOT_DISK)
8099 {
8100 DPRINT1("Not a disk! %x\n", Fcb->pNetRoot->Type);
8102 }
8103
8104 /* Setup RX_CONTEXT related fields */
8105 RxContext->QueryDirectory.FileIndex = FileIndex;
8106 RxContext->QueryDirectory.RestartScan = BooleanFlagOn(Flags, SL_RESTART_SCAN);
8107 RxContext->QueryDirectory.ReturnSingleEntry = BooleanFlagOn(Flags, SL_RETURN_SINGLE_ENTRY);
8108 RxContext->QueryDirectory.IndexSpecified = BooleanFlagOn(Flags, SL_INDEX_SPECIFIED);
8109 RxContext->QueryDirectory.InitialQuery = (Fobx->UnicodeQueryTemplate.Buffer == NULL) && !BooleanFlagOn(Fobx->Flags, FOBX_FLAG_MATCH_ALL);
8110
8111 /* We don't support (yet?) a specific index being set */
8112 if (RxContext->QueryDirectory.IndexSpecified)
8113 {
8115 }
8116
8117 /* Try to lock FCB */
8118 LockNotGranted = TRUE;
8119 if (RxContext->QueryDirectory.InitialQuery)
8120 {
8121 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
8123 {
8124 if (!NT_SUCCESS(Status))
8125 {
8126 return Status;
8127 }
8128
8129 if (Fobx->UnicodeQueryTemplate.Buffer != NULL)
8130 {
8131 RxContext->QueryDirectory.InitialQuery = FALSE;
8132 RxConvertToSharedFcb(RxContext, Fcb);
8133 }
8134
8135 LockNotGranted = FALSE;
8136 }
8137 }
8138 else
8139 {
8140 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
8142 {
8143 if (!NT_SUCCESS(Status))
8144 {
8145 return Status;
8146 }
8147
8148 LockNotGranted = FALSE;
8149 }
8150 }
8151
8152 /* If it failed, post request */
8153 if (LockNotGranted)
8154 {
8155 return RxFsdPostRequest(RxContext);
8156 }
8157
8158 /* This cannot be done on a orphaned directory */
8160 {
8161 RxReleaseFcb(RxContext, Fcb);
8162 return STATUS_FILE_CLOSED;
8163 }
8164
8165 _SEH2_TRY
8166 {
8167 /* Set index */
8168 if (!RxContext->QueryDirectory.IndexSpecified && RxContext->QueryDirectory.RestartScan)
8169 {
8170 RxContext->QueryDirectory.FileIndex = 0;
8171 }
8172
8173 /* Assume success */
8175 /* If initial query, prepare FOBX */
8176 if (RxContext->QueryDirectory.InitialQuery)
8177 {
8178 /* We cannot have a template already! */
8180
8181 /* If we have a file name and a correct one, duplicate it in the FOBX */
8182 if (FileName != NULL && FileName->Length != 0 && FileName->Buffer != NULL &&
8183 (FileName->Length != sizeof(WCHAR) || FileName->Buffer[0] != '*') &&
8184 (FileName->Length != 12 * sizeof(WCHAR) ||
8185 RtlCompareMemory(FileName->Buffer, Rx8QMdot3QM, 12 * sizeof(WCHAR)) != 12 * sizeof(WCHAR)))
8186 {
8188
8189 Fobx->UnicodeQueryTemplate.Buffer = RxAllocatePoolWithTag(PagedPool, FileName->Length, RX_DIRCTL_POOLTAG);
8190 if (Fobx->UnicodeQueryTemplate.Buffer != NULL)
8191 {
8192 /* UNICODE_STRING; length has to be even */
8193 if ((FileName->Length & 1) != 0)
8194 {
8196 RxFreePoolWithTag(Fobx->UnicodeQueryTemplate.Buffer, RX_DIRCTL_POOLTAG);
8197 }
8198 else
8199 {
8200 Fobx->UnicodeQueryTemplate.Length = FileName->Length;
8201 Fobx->UnicodeQueryTemplate.MaximumLength = FileName->Length;
8202 RtlMoveMemory(Fobx->UnicodeQueryTemplate.Buffer, FileName->Buffer, FileName->Length);
8203
8204 SetFlag(Fobx->Flags, FOBX_FLAG_FREE_UNICODE);
8205 }
8206 }
8207 else
8208 {
8210 }
8211 }
8212 /* No name specified, or a match all wildcard? Match everything */
8213 else
8214 {
8215 Fobx->ContainsWildCards = TRUE;
8216
8217 Fobx->UnicodeQueryTemplate.Buffer = &RxStarForTemplate;
8218 Fobx->UnicodeQueryTemplate.Length = sizeof(WCHAR);
8219 Fobx->UnicodeQueryTemplate.MaximumLength = sizeof(WCHAR);
8220
8221 SetFlag(Fobx->Flags, FOBX_FLAG_MATCH_ALL);
8222 }
8223
8224 /* No need for exclusive any longer */
8225 if (NT_SUCCESS(Status))
8226 {
8227 RxConvertToSharedFcb(RxContext, Fcb);
8228 }
8229 }
8230
8231 /* Lock user buffer and forward to mini-rdr */
8232 if (NT_SUCCESS(Status))
8233 {
8235 RxContext->Info.FileInformationClass = FileInfoClass;
8236 RxContext->Info.Buffer = RxNewMapUserBuffer(RxContext);
8237 RxContext->Info.Length = Length;
8238
8239 if (RxContext->Info.Buffer != NULL)
8240 {
8241 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxQueryDirectory, (RxContext));
8242 }
8243
8244 /* Post if mini-rdr asks to */
8245 if (RxContext->PostRequest)
8246 {
8247 RxFsdPostRequest(RxContext);
8248 }
8249 else
8250 {
8251 Irp->IoStatus.Information = Length - RxContext->Info.LengthRemaining;
8252 }
8253 }
8254 }
8256 {
8257 RxReleaseFcb(RxContext, Fcb);
8258 }
8259 _SEH2_END;
8260
8261 return Status;
8262}
8263
8266 PRX_CONTEXT RxContext,
8267 PFILE_EA_INFORMATION EaInfo)
8268{
8271}
8272
8275 PRX_CONTEXT RxContext,
8276 PFILE_INTERNAL_INFORMATION InternalInfo)
8277{
8280}
8281
8282/*
8283 * @implemented
8284 */
8287 PRX_CONTEXT RxContext,
8288 PFILE_NAME_INFORMATION NameInfo)
8289{
8290 PFCB Fcb;
8291 PFOBX Fobx;
8292 PAGED_CODE();
8293
8294 DPRINT("RxQueryNameInfo(%p, %p)\n", RxContext, NameInfo);
8295
8296 /* Check we can at least copy name size */
8297 if (RxContext->Info.LengthRemaining < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
8298 {
8299 DPRINT1("Buffer too small: %d\n", RxContext->Info.LengthRemaining);
8300 RxContext->Info.Length = 0;
8302 }
8303
8304 RxContext->Info.LengthRemaining -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
8305
8306 Fcb = (PFCB)RxContext->pFcb;
8307 Fobx = (PFOBX)RxContext->pFobx;
8308 /* Get the UNC name */
8309 RxConjureOriginalName(Fcb, Fobx, &NameInfo->FileNameLength, &NameInfo->FileName[0],
8310 &RxContext->Info.Length, VNetRoot_As_UNC_Name);
8311
8312 /* If RxConjureOriginalName returned a negative len (-1) then output buffer
8313 * was too small, return the appropriate length & status.
8314 */
8315 if (RxContext->Info.LengthRemaining < 0)
8316 {
8317 DPRINT1("Buffer too small!\n");
8318 RxContext->Info.Length = 0;
8320 }
8321
8322#if 1 // CORE-13938, rfb: please note I replaced 0 with 1 here
8324 RxContext->Info.LengthRemaining >= sizeof(WCHAR))
8325 {
8326 NameInfo->FileName[NameInfo->FileNameLength / sizeof(WCHAR)] = L'\\';
8327 NameInfo->FileNameLength += sizeof(WCHAR);
8328 RxContext->Info.LengthRemaining -= sizeof(WCHAR);
8329 }
8330#endif
8331
8332 /* All correct */
8333 return STATUS_SUCCESS;
8334}
8335
8338 PRX_CONTEXT RxContext,
8340{
8343}
8344
8347 PRX_CONTEXT RxContext,
8348 PFILE_POSITION_INFORMATION PositionInfo)
8349{
8352}
8353
8354/*
8355 * @implemented
8356 */
8359 PRX_CONTEXT RxContext,
8360 PFILE_STANDARD_INFORMATION StandardInfo)
8361{
8362 PFCB Fcb;
8363 PFOBX Fobx;
8365
8366 PAGED_CODE();
8367
8368 DPRINT("RxQueryStandardInfo(%p, %p)\n", RxContext, StandardInfo);
8369
8370 /* Zero output buffer */
8371 RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
8372
8373 Fcb = (PFCB)RxContext->pFcb;
8374 Fobx = (PFOBX)RxContext->pFobx;
8375 /* If not a standard file type, or opened for backup, immediately forward to mini-rdr */
8377 BooleanFlagOn(Fobx->pSrvOpen->CreateOptions, FILE_OPEN_FOR_BACKUP_INTENT))
8378 {
8379 return RxpQueryInfoMiniRdr(RxContext, FileStandardInformation, StandardInfo);
8380 }
8381
8382 /* Otherwise, fill what we can already */
8384 StandardInfo->NumberOfLinks = Fcb->NumberOfLinks;
8387 if (StandardInfo->NumberOfLinks == 0)
8388 {
8389 StandardInfo->NumberOfLinks = 1;
8390 }
8391
8393 {
8394 StandardInfo->AllocationSize.QuadPart = Fcb->Header.AllocationSize.QuadPart;
8396 }
8397
8398 /* If we are asked to forcefully forward to mini-rdr or if size isn't cached, do it */
8400 {
8401 Status = RxpQueryInfoMiniRdr(RxContext, FileStandardInformation, StandardInfo);
8402 }
8403 else
8404 {
8406 }
8407
8408 return Status;
8409}
8410
8411/*
8412 * @implemented
8413 */
8414VOID
8415NTAPI
8417 VOID)
8418{
8422 UCHAR Buffer[0x40];
8423 UNICODE_STRING KeyName, ParamName;
8426
8427 PAGED_CODE();
8428
8429 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\LanmanWorkStation\\Parameters");
8432 if (!NT_SUCCESS(Status))
8433 {
8434 return;
8435 }
8436
8438 RtlInitUnicodeString(&ParamName, L"DisableByteRangeLockingOnReadOnlyFiles");
8439 Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
8440 if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
8441 {
8442 DisableByteRangeLockingOnReadOnlyFiles = (*(PULONG)PartialInfo->Data != 0);
8443 }
8444
8445 RtlInitUnicodeString(&ParamName, L"ReadAheadGranularity");
8446 Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
8447 if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
8448 {
8449 ULONG Granularity = *(PULONG)PartialInfo->Data;
8450
8451 if (Granularity > 16)
8452 {
8453 Granularity = 16;
8454 }
8455
8456 ReadAheadGranularity = Granularity << PAGE_SHIFT;
8457 }
8458
8459 RtlInitUnicodeString(&ParamName, L"DisableFlushOnCleanup");
8460 Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
8461 if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
8462 {
8463 DisableFlushOnCleanup = (*(PULONG)PartialInfo->Data != 0);
8464 }
8465
8467}
8468
8469/*
8470 * @implemented
8471 */
8473NTAPI
8477 IN PMINIRDR_DISPATCH MrdrDispatch,
8478 IN ULONG Controls,
8480 IN ULONG DeviceExtensionSize,
8483{
8485 PRDBSS_DEVICE_OBJECT RDBSSDevice;
8486
8487 PAGED_CODE();
8488
8489 if (!DeviceObject)
8490 {
8492 }
8493
8494 /* Create device object with provided parameters */
8496 DeviceExtensionSize + sizeof(RDBSS_DEVICE_OBJECT),
8497 DeviceName,
8498 DeviceType,
8500 FALSE,
8501 (PDEVICE_OBJECT *)&RDBSSDevice);
8502 if (!NT_SUCCESS(Status))
8503 {
8504 return Status;
8505 }
8506
8507 if (!RxData.DriverObject)
8508 {
8509 return STATUS_UNSUCCESSFUL;
8510 }
8511
8512 /* Initialize our DO extension */
8513 RDBSSDevice->RDBSSDeviceObject = NULL;
8514 ++RxFileSystemDeviceObject->ReferenceCount;
8515 *DeviceObject = RDBSSDevice;
8516 RDBSSDevice->RdbssExports = &RxExports;
8517 RDBSSDevice->Dispatch = MrdrDispatch;
8518 RDBSSDevice->RegistrationControls = Controls;
8519 RDBSSDevice->DeviceName = *DeviceName;
8522 InitializeListHead(&RDBSSDevice->OverflowQueue[0]);
8523 InitializeListHead(&RDBSSDevice->OverflowQueue[1]);
8524 InitializeListHead(&RDBSSDevice->OverflowQueue[2]);
8527
8528 DPRINT("Registered MiniRdr %wZ (prio: %x)\n", DeviceName, RDBSSDevice->NetworkProviderPriority);
8529
8533
8534 /* Unless mini-rdr explicitly asked not to, initialize dispatch table */
8536 {
8538 }
8539
8540 /* Unless mini-rdr explicitly asked not to, initialize prefix scavenger */
8542 {
8543 LARGE_INTEGER ScavengerTimeLimit;
8544
8545 RDBSSDevice->pRxNetNameTable = &RDBSSDevice->RxNetNameTableInDeviceObject;
8548 ScavengerTimeLimit.QuadPart = MrdrDispatch->ScavengerTimeout * 10000000LL;
8549 RDBSSDevice->pRdbssScavenger = &RDBSSDevice->RdbssScavengerInDeviceObject;
8550 RxInitializeRdbssScavenger(RDBSSDevice->pRdbssScavenger, ScavengerTimeLimit);
8551 }
8552
8554
8555 return STATUS_SUCCESS;
8556}
8557
8558/*
8559 * @implemented
8560 */
8561VOID
8563 PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
8564{
8565 KIRQL OldIrql;
8566
8567 /* Make sure this is a TLC and that it was allocated (otherwise, it is not in the list */
8570
8572 RemoveEntryList(&TopLevelContext->ListEntry);
8574}
8575
8576/*
8577 * @implemented
8578 */
8583{
8584 KIRQL OldIrql;
8586
8587 KeAcquireSpinLock(&DeviceObject->OverflowQueueSpinLock, &OldIrql);
8588 if (DeviceObject->OverflowQueueCount[Queue] <= 0)
8589 {
8590 /* No entries left, nothing to return */
8591 InterlockedDecrement(&DeviceObject->PostedRequestCount[Queue]);
8592 Context = NULL;
8593 }
8594 else
8595 {
8597
8598 /* Decrement count */
8599 --DeviceObject->OverflowQueueCount[Queue];
8600
8601 /* Return head */
8602 Entry = RemoveHeadList(&DeviceObject->OverflowQueue[Queue]);
8603 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, OverflowListEntry);
8605 Context->OverflowListEntry.Flink = NULL;
8606 }
8607 KeReleaseSpinLock(&DeviceObject->OverflowQueueSpinLock, OldIrql);
8608
8609 return Context;
8610}
8611
8612#if DBG
8613/*
8614 * @implemented
8615 */
8616VOID
8620 _In_ PSZ where,
8621 _In_ PSZ wherelogtag)
8622{
8623 PAGED_CODE();
8624
8625 RxDumpCurrentAccess(where, "before", wherelogtag, ShareAccess);
8627 RxDumpCurrentAccess(where, "after", wherelogtag, ShareAccess);
8628}
8629#endif
8630
8631/*
8632 * @implemented
8633 */
8634VOID
8636 IN OUT PSRV_OPEN SrvOpen)
8637{
8641 BOOLEAN DeleteAccess;
8642
8643 PAGED_CODE();
8644
8645 /* Get access that were granted to SRV_OPEN */
8646 DesiredAccess = SrvOpen->DesiredAccess;
8649 DeleteAccess = (DesiredAccess & DELETE) != 0;
8650
8651 /* If any, drop them */
8652 if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
8653 {
8654 BOOLEAN SharedRead;
8655 BOOLEAN SharedWrite;
8656 BOOLEAN SharedDelete;
8659
8660 ShareAccess = &((PFCB)SrvOpen->pFcb)->ShareAccessPerSrvOpens;
8661 DesiredShareAccess = SrvOpen->ShareAccess;
8662
8663 ShareAccess->Readers -= ReadAccess;
8664 ShareAccess->Writers -= WriteAccess;
8665 ShareAccess->Deleters -= DeleteAccess;
8666
8667 ShareAccess->OpenCount--;
8668
8669 SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
8670 SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
8671 SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
8672 ShareAccess->SharedRead -= SharedRead;
8673 ShareAccess->SharedWrite -= SharedWrite;
8674 ShareAccess->SharedDelete -= SharedDelete;
8675 }
8676}
8677
8680 PRX_CONTEXT RxContext,
8683{
8684 PFCB Fcb;
8686 PLIST_ENTRY ListEntry;
8687 BOOLEAN ShouldTry, Purged, Scavenged;
8688
8689 PAGED_CODE();
8690
8691 DPRINT("RxSearchForCollapsibleOpen(%p, %x, %x)\n", RxContext, DesiredAccess, ShareAccess);
8692
8693 Fcb = (PFCB)RxContext->pFcb;
8694
8695 /* If we're asked to open for backup, don't allow SRV_OPEN reuse */
8696 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.CreateOptions, FILE_OPEN_FOR_BACKUP_INTENT))
8697 {
8699
8702
8703 return STATUS_NOT_FOUND;
8704 }
8705
8706 /* If basic open, ask the mini-rdr if we should try to collapse */
8707 if (RxContext->Create.NtCreateParameters.Disposition == FILE_OPEN ||
8708 RxContext->Create.NtCreateParameters.Disposition == FILE_OPEN_IF)
8709 {
8710 ShouldTry = TRUE;
8711
8712 if (Fcb->MRxDispatch != NULL)
8713 {
8714 ASSERT(RxContext->pRelevantSrvOpen == NULL);
8716
8717 ShouldTry = NT_SUCCESS(Fcb->MRxDispatch->MRxShouldTryToCollapseThisOpen(RxContext));
8718 }
8719 }
8720 else
8721 {
8722 ShouldTry = FALSE;
8723 }
8724
8725 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.CreateOptions, FILE_DELETE_ON_CLOSE))
8726 {
8727 ShouldTry = FALSE;
8728 }
8729
8730 /* If we shouldn't try, ask the caller to allocate a new SRV_OPEN */
8731 if (!ShouldTry)
8732 {
8734 {
8735 return STATUS_NOT_FOUND;
8736 }
8737
8739
8742
8743 return STATUS_NOT_FOUND;
8744 }
8745
8746 /* Only collapse for matching NET_ROOT & disks */
8747 if (Fcb->pNetRoot != RxContext->Create.pNetRoot ||
8748 Fcb->pNetRoot->Type != NET_ROOT_DISK)
8749 {
8750 return STATUS_NOT_FOUND;
8751 }
8752
8753 Purged = FALSE;
8754 Scavenged = FALSE;
8756TryAgain:
8757 /* Browse all our SRV_OPEN to find the matching one */
8758 for (ListEntry = Fcb->SrvOpenList.Flink;
8759 ListEntry != &Fcb->SrvOpenList;
8760 ListEntry = ListEntry->Flink)
8761 {
8762 PSRV_OPEN SrvOpen;
8763
8764 SrvOpen = CONTAINING_RECORD(ListEntry, SRV_OPEN, SrvOpenQLinks);
8765 /* Not the same VNET_ROOT, move to the next one */
8766 if (SrvOpen->pVNetRoot != RxContext->Create.pVNetRoot)
8767 {
8768 RxContext->Create.TryForScavengingOnSharingViolation = TRUE;
8769 continue;
8770 }
8771
8772 /* Is there a sharing violation? */
8773 if (SrvOpen->DesiredAccess != DesiredAccess || SrvOpen->ShareAccess != ShareAccess ||
8775 {
8776 if (SrvOpen->pVNetRoot != RxContext->Create.pVNetRoot)
8777 {
8778 RxContext->Create.TryForScavengingOnSharingViolation = TRUE;
8779 continue;
8780 }
8781
8782 /* Check against the SRV_OPEN */
8784 if (!NT_SUCCESS(Status))
8785 {
8786 break;
8787 }
8788 }
8789 else
8790 {
8791 /* Don't allow collaspse for reparse point opening */
8792 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.CreateOptions ^ SrvOpen->CreateOptions, FILE_OPEN_REPARSE_POINT))
8793 {
8794 Purged = TRUE;
8795 Scavenged = TRUE;
8797 break;
8798 }
8799
8800 /* Not readonly? Or bytereange lock disabled? Try to collapse! */
8802 {
8803 RxContext->pRelevantSrvOpen = (PMRX_SRV_OPEN)SrvOpen;
8804
8807 {
8808 /* Is close delayed - great reuse*/
8809 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED))
8810 {
8811 DPRINT("Delayed close successfull, reusing %p\n", SrvOpen);
8812 InterlockedDecrement(&((PSRV_CALL)Fcb->pNetRoot->pSrvCall)->NumberOfCloseDelayedFiles);
8813 ClearFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
8814 }
8815
8816 return STATUS_SUCCESS;
8817 }
8818
8820 break;
8821 }
8822 }
8823 }
8824 /* We browse the whole list and didn't find any matching? NOT_FOUND */
8825 if (ListEntry == &Fcb->SrvOpenList)
8826 {
8828 }
8829
8830 /* Only required access: read attributes? Don't reuse */
8831 if ((DesiredAccess & 0xFFEFFFFF) == FILE_READ_ATTRIBUTES)
8832 {
8833 return STATUS_NOT_FOUND;
8834 }
8835
8836 /* Not found? Scavenge and retry to look for collaspile SRV_OPEN */
8837 if (!Scavenged)
8838 {
8840 Scavenged = TRUE;
8842 goto TryAgain;
8843 }
8844
8845 /* Not found? Purgeable? Purge and retry to look for collaspile SRV_OPEN */
8846 if (!Purged && RxIsOkToPurgeFcb(Fcb))
8847 {
8849 Purged = TRUE;
8850 goto TryAgain;
8851 }
8852
8853 /* If sharing violation, keep track of it */
8855 {
8856 RxContext->Create.TryForScavengingOnSharingViolation = TRUE;
8857 }
8858
8859 DPRINT("Status: %x\n", Status);
8860 return Status;
8861}
8862
8865 PRX_CONTEXT RxContext)
8866{
8869}
8870
8871/*
8872 * @implemented
8873 */
8876 PRX_CONTEXT RxContext)
8877{
8879
8880 PAGED_CODE();
8881
8882#define FILE_ATTRIBUTE_VOLUME 0x8
8883#define VALID_FILE_ATTRIBUTES ( \
8884 FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
8885 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_VOLUME | \
8886 FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DEVICE | \
8887 FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_SPARSE_FILE | \
8888 FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED | \
8889 FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | \
8890 FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_INTEGRITY_STREAM)
8891#define VALID_DIR_ATTRIBUTES (VALID_FILE_ATTRIBUTES | FILE_ATTRIBUTE_DIRECTORY)
8892
8893 /* First of all, call the mini-rdr */
8895 /* If it succeed, perform last bits */
8896 if (NT_SUCCESS(Status))
8897 {
8898 PIRP Irp;
8899 PFCB Fcb;
8900 PFOBX Fobx;
8902 ULONG Attributes, CleanAttr;
8903 PFILE_BASIC_INFORMATION BasicInfo;
8904
8905 Fcb = (PFCB)RxContext->pFcb;
8906 Fobx = (PFOBX)RxContext->pFobx;
8907 Irp = RxContext->CurrentIrp;
8908 BasicInfo = Irp->AssociatedIrp.SystemBuffer;
8909 FileObject = RxContext->CurrentIrpSp->FileObject;
8910
8911 /* If caller provided flags, handle the change */
8912 Attributes = BasicInfo->FileAttributes;
8913 if (Attributes != 0)
8914 {
8915 /* Clean our flags first, with only stuff we support */
8917 {
8919 }
8920 else
8921 {
8922 CleanAttr = Attributes & VALID_FILE_ATTRIBUTES;
8923 }
8924
8925 /* Handle the temporary mark (set/unset depending on caller) */
8927 {
8930 }
8931 else
8932 {
8935 }
8936
8937 /* And set new attributes */
8938 Fcb->Attributes = CleanAttr;
8939 }
8940
8941 /* If caller provided a creation time, set it */
8942 if (BasicInfo->CreationTime.QuadPart != 0LL)
8943 {
8944 Fcb->CreationTime.QuadPart = BasicInfo->CreationTime.QuadPart;
8946 }
8947
8948 /* If caller provided a last access time, set it */
8949 if (BasicInfo->LastAccessTime.QuadPart != 0LL)
8950 {
8953 }
8954
8955 /* If caller provided a last write time, set it */
8956 if (BasicInfo->LastWriteTime.QuadPart != 0LL)
8957 {
8960 }
8961
8962 /* If caller provided a last change time, set it */
8963 if (BasicInfo->ChangeTime.QuadPart != 0LL)
8964 {
8967 }
8968 }
8969
8970 /* Done */
8971 return Status;
8972}
8973
8974/*
8975 * @implemented
8976 */
8979 PRX_CONTEXT RxContext)
8980{
8982
8983 PAGED_CODE();
8984
8985 /* First, make the mini-rdr work! */
8987 /* If it succeed, we'll keep track of the change */
8988 if (NT_SUCCESS(Status))
8989 {
8990 PFCB Fcb;
8993
8994 Fcb = (PFCB)RxContext->pFcb;
8995 FileObject = RxContext->CurrentIrpSp->FileObject;
8996 FileDispo = RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
8997 /* Caller asks for deletion: mark as delete on close */
8998 if (FileDispo->DeleteFile)
8999 {
9001 FileObject->DeletePending = TRUE;
9002 }
9003 /* Otherwise, clear it */
9004 else
9005 {
9007 FileObject->DeletePending = FALSE;
9008 }
9009
9010 /* Sanitize output */
9012 }
9013
9014 return Status;
9015}
9016
9019 PRX_CONTEXT RxContext)
9020{
9023}
9024
9027 PRX_CONTEXT RxContext)
9028{
9031}
9032
9035 PRX_CONTEXT RxContext)
9036{
9039}
9040
9041/*
9042 * @implemented
9043 */
9046 PRX_CONTEXT RxContext)
9047{
9048 ULONG Length;
9050 PFCB RenameFcb, Fcb;
9052 PFILE_RENAME_INFORMATION RenameInfo, UserInfo;
9053
9054 PAGED_CODE();
9055
9056 DPRINT("RxSetRenameInfo(%p)\n", RxContext);
9057
9058 Stack = RxContext->CurrentIrpSp;
9059 DPRINT("FO: %p, Replace: %d\n", Stack->Parameters.SetFile.FileObject, Stack->Parameters.SetFile.ReplaceIfExists);
9060
9061 /* If there's no FO, we won't do extra operation, so directly pass to mini-rdr and quit */
9062 RxContext->Info.ReplaceIfExists = Stack->Parameters.SetFile.ReplaceIfExists;
9063 if (Stack->Parameters.SetFile.FileObject == NULL)
9064 {
9065 return RxpSetInfoMiniRdr(RxContext, Stack->Parameters.SetFile.FileInformationClass);
9066 }
9067
9068 Fcb = (PFCB)RxContext->pFcb;
9069 RenameFcb = Stack->Parameters.SetFile.FileObject->FsContext;
9070 /* First, validate the received file object */
9072 if (Fcb->pNetRoot != RenameFcb->pNetRoot)
9073 {
9074 DPRINT1("Not the same device: %p:%p (%wZ) - %p:%p (%wZ)\n", Fcb, Fcb->pNetRoot, Fcb->pNetRoot->pNetRootName, RenameFcb, RenameFcb->pNetRoot, RenameFcb->pNetRoot->pNetRootName);
9076 }
9077
9078 /* We'll reallocate a safe buffer */
9079 Length = Fcb->pNetRoot->DiskParameters.RenameInfoOverallocationSize + RenameFcb->FcbTableEntry.Path.Length + FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName);
9080 RenameInfo = RxAllocatePoolWithTag(PagedPool, Length, '??xR');
9081 if (RenameInfo == NULL)
9082 {
9084 }
9085
9086 _SEH2_TRY
9087 {
9088 /* Copy the data */
9089 UserInfo = RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
9090 RenameInfo->ReplaceIfExists = UserInfo->ReplaceIfExists;
9091 RenameInfo->RootDirectory = UserInfo->RootDirectory;
9092 RenameInfo->FileNameLength = RenameFcb->FcbTableEntry.Path.Length;
9093 RtlMoveMemory(&RenameInfo->FileName[0], RenameFcb->FcbTableEntry.Path.Buffer, RenameFcb->FcbTableEntry.Path.Length);
9094
9095 /* Set them in the RX_CONTEXT */
9096 RxContext->Info.FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
9097 RxContext->Info.Buffer = RenameInfo;
9098 RxContext->Info.Length = Length;
9099
9100 /* And call the mini-rdr */
9101 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxSetFileInfo, (RxContext));
9102 }
9104 {
9105 /* Free */
9106 RxFreePoolWithTag(RenameInfo, '??xR');
9107 }
9108 _SEH2_END;
9109
9110 /* Done! */
9111 return Status;
9112}
9113
9114#if DBG
9115/*
9116 * @implemented
9117 */
9118VOID
9124 _In_ PSZ where,
9125 _In_ PSZ wherelogtag)
9126{
9127 PAGED_CODE();
9128
9129 RxDumpCurrentAccess(where, "before", wherelogtag, ShareAccess);
9131 RxDumpCurrentAccess(where, "after", wherelogtag, ShareAccess);
9132}
9133#endif
9134
9137 PRX_CONTEXT RxContext)
9138{
9141}
9142
9143/*
9144 * @implemented
9145 */
9146VOID
9148 PRX_CONTEXT RxContext)
9149{
9150 PFCB Fcb;
9151 PFOBX Fobx;
9154
9155 PAGED_CODE();
9156
9157 /* Assert FOBX is FOBX or NULL */
9158 Fobx = (PFOBX)RxContext->pFobx;
9159 ASSERT((Fobx == NULL) || (NodeType(Fobx) == RDBSS_NTC_FOBX));
9160
9161 Fcb = (PFCB)RxContext->pFcb;
9162 Stack = RxContext->CurrentIrpSp;
9164 /* If it's temporary mark FO as such */
9165 if (Fcb != NULL && NodeType(Fcb) != RDBSS_NTC_VCB &&
9167 {
9168 if (FileObject == NULL)
9169 {
9170 return;
9171 }
9172
9173 FileObject->Flags |= FO_TEMPORARY_FILE;
9174 }
9175
9176 /* No FO, nothing to setup */
9177 if (FileObject == NULL)
9178 {
9179 return;
9180 }
9181
9182 /* Assign FCB & CCB (FOBX) to FO */
9183 FileObject->FsContext = Fcb;
9184 FileObject->FsContext2 = Fobx;
9185 if (Fobx != NULL)
9186 {
9187 ULONG_PTR StackTop, StackBottom;
9188
9189 /* If FO is allocated on pool, keep track of it */
9190 IoGetStackLimits(&StackTop, &StackBottom);
9191 if ((ULONG_PTR)FileObject <= StackBottom || (ULONG_PTR)FileObject >= StackTop)
9192 {
9193 Fobx->AssociatedFileObject = FileObject;
9194 }
9195 else
9196 {
9197 Fobx->AssociatedFileObject = NULL;
9198 }
9199
9200 /* Make sure to mark FOBX if it's a DFS open */
9201 if (RxContext->Create.NtCreateParameters.DfsContext == UIntToPtr(DFS_OPEN_CONTEXT))
9202 {
9203 SetFlag(Fobx->Flags, FOBX_FLAG_DFS_OPEN);
9204 }
9205 else
9206 {
9207 ClearFlag(Fobx->Flags, FOBX_FLAG_DFS_OPEN);
9208 }
9209 }
9210
9211 /* Set Cc pointers */
9212 FileObject->SectionObjectPointer = &Fcb->NonPaged->SectionObjectPointers;
9213
9214 /* Update access state */
9215 if (Stack->Parameters.Create.SecurityContext != NULL)
9216 {
9218
9219 AccessState = Stack->Parameters.Create.SecurityContext->AccessState;
9220 AccessState->PreviouslyGrantedAccess |= AccessState->RemainingDesiredAccess;
9221 AccessState->RemainingDesiredAccess = 0;
9222 }
9223}
9224
9225/*
9226 * @implemented
9227 */
9229NTAPI
9231 IN PRX_CONTEXT RxContext,
9232 OUT PBOOLEAN PostToFsp)
9233{
9235 BOOLEAN Wait, AlreadyStarted;
9237
9238 /* If we've not been post, then, do it */
9239 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP))
9240 {
9242
9244 RxContext->FsdUid = RxGetUid(&SubjectContext);
9246
9247 *PostToFsp = TRUE;
9248 return STATUS_PENDING;
9249 }
9250
9251 /* Acquire all the required locks */
9252 Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
9254 {
9255 *PostToFsp = TRUE;
9256 return STATUS_PENDING;
9257 }
9258
9259 if (!RxAcquirePrefixTableLockExclusive(RxContext->RxDeviceObject->pRxNetNameTable, Wait))
9260 {
9262 *PostToFsp = TRUE;
9263 return STATUS_PENDING;
9264 }
9265
9266 AlreadyStarted = FALSE;
9267 DeviceObject = RxContext->RxDeviceObject;
9268 _SEH2_TRY
9269 {
9270 /* MUP handle set, means already registered */
9271 if (DeviceObject->MupHandle != NULL)
9272 {
9273 AlreadyStarted = TRUE;
9276 }
9277
9278 /* If we're asked to register to MUP, then do it */
9280 if (DeviceObject->RegisterUncProvider)
9281 {
9283 &DeviceObject->DeviceName,
9284 DeviceObject->RegisterMailSlotProvider);
9285 }
9286 if (!NT_SUCCESS(Status))
9287 {
9288 DeviceObject->MupHandle = NULL;
9290 }
9291
9292 /* Register as file system */
9293 IoRegisterFileSystem(&DeviceObject->DeviceObject);
9294 DeviceObject->RegisteredAsFileSystem = TRUE;
9295
9296 /* Inform mini-rdr it has to start */
9297 MINIRDR_CALL(Status, RxContext, DeviceObject->Dispatch, MRxStart, (RxContext, DeviceObject));
9298 if (NT_SUCCESS(Status))
9299 {
9300 ++DeviceObject->StartStopContext.Version;
9303
9305 }
9306 }
9308 {
9310 {
9311 if (!AlreadyStarted)
9312 {
9313 RxUnstart(RxContext, DeviceObject);
9314 }
9315 }
9316
9317 RxReleasePrefixTableLock(RxContext->RxDeviceObject->pRxNetNameTable);
9319 }
9320 _SEH2_END;
9321
9322 return Status;
9323}
9324
9326NTAPI
9328 IN PRX_CONTEXT RxContext,
9329 OUT PBOOLEAN PostToFsp)
9330{
9333}
9334
9337 IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
9338 IN PIRP Irp)
9339{
9342}
9343
9344/*
9345 * @implemented
9346 */
9347BOOLEAN
9349 IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext,
9350 IN PIRP Irp,
9351 IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
9352 IN BOOLEAN ForceTopLevel
9353 )
9354{
9355 BOOLEAN FromPool = FALSE;
9356
9357 PAGED_CODE();
9358
9359 /* If not top level, and not have to be, quit */
9360 if (IoGetTopLevelIrp() && !ForceTopLevel)
9361 {
9362 return FALSE;
9363 }
9364
9365 /* If not TLC provider, allocate one */
9366 if (TopLevelContext == NULL)
9367 {
9368 TopLevelContext = RxAllocatePoolWithTag(NonPagedPool, sizeof(RX_TOPLEVELIRP_CONTEXT), RX_TLC_POOLTAG);
9369 if (TopLevelContext == NULL)
9370 {
9371 return FALSE;
9372 }
9373
9374 FromPool = TRUE;
9375 }
9376
9377 /* Init it */
9378 __RxInitializeTopLevelIrpContext(TopLevelContext, Irp, RxDeviceObject, FromPool);
9379
9380 ASSERT(TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
9381 if (FromPool)
9382 {
9383 ASSERT(BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL));
9384 }
9385
9386 /* Make it top level IRP */
9387 IoSetTopLevelIrp((PIRP)TopLevelContext);
9388 return TRUE;
9389}
9390
9391#if DBG
9392/*
9393 * @implemented
9394 */
9395VOID
9399 _In_ PSZ where,
9400 _In_ PSZ wherelogtag)
9401{
9402 PAGED_CODE();
9403
9404 RxDumpCurrentAccess(where, "before", wherelogtag, ShareAccess);
9406 RxDumpCurrentAccess(where, "after", wherelogtag, ShareAccess);
9407}
9408#endif
9409
9410/*
9411 * @implemented
9412 */
9413VOID
9415 PRX_CONTEXT RxContext,
9417 PLARGE_INTEGER TruncateSize)
9418{
9419 PFCB Fcb;
9421 CACHE_UNINITIALIZE_EVENT UninitEvent;
9422
9423 PAGED_CODE();
9424
9425 Fcb = FileObject->FsContext;
9428
9430 CcUninitializeCacheMap(FileObject, TruncateSize, &UninitEvent);
9431
9432 /* Always release the FCB before waiting for the uninit event */
9433 RxReleaseFcb(RxContext, Fcb);
9434
9436
9437 /* Re-acquire it afterwards */
9438 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
9440}
9441
9442VOID
9443NTAPI
9446{
9448}
9449
9450VOID
9451NTAPI
9454 IN PFILE_LOCK_INFO LockInfo)
9455{
9457}
9458
9459VOID
9463{
9465}
9466
9467/*
9468 * @implemented
9469 */
9470VOID
9472 IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
9473{
9474 DPRINT("RxUnwindTopLevelIrp(%p)\n", TopLevelContext);
9475
9476 /* No TLC provided? Ask the system for ours! */
9477 if (TopLevelContext == NULL)
9478 {
9479 TopLevelContext = (PRX_TOPLEVELIRP_CONTEXT)IoGetTopLevelIrp();
9480 if (TopLevelContext == NULL)
9481 {
9482 return;
9483 }
9484
9485 /* In that case, just assert it's really ours */
9486 ASSERT(RxIsThisAnRdbssTopLevelContext(TopLevelContext));
9487 ASSERT(BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL));
9488 }
9489
9490 ASSERT(TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
9491 ASSERT(TopLevelContext->Thread == PsGetCurrentThread());
9492 /* Restore the previous top level IRP */
9493 IoSetTopLevelIrp(TopLevelContext->Previous);
9494 /* If TLC was allocated from pool, remove it from list and release it */
9495 if (BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL))
9496 {
9498 RxFreePoolWithTag(TopLevelContext, RX_TLC_POOLTAG);
9499 }
9500}
9501
9502/*
9503 * @implemented
9504 */
9505VOID
9507 IN PSRV_OPEN SrvOpen)
9508{
9512 BOOLEAN DeleteAccess;
9513
9514 PAGED_CODE();
9515
9516 /* If already updated, no need to continue */
9518 {
9519 return;
9520 }
9521
9522 /* Check if any access wanted */
9523 DesiredAccess = SrvOpen->DesiredAccess;
9526 DeleteAccess = (DesiredAccess & DELETE) != 0;
9527
9528 /* In that case, update it */
9529 if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
9530 {
9531 BOOLEAN SharedRead;
9532 BOOLEAN SharedWrite;
9533 BOOLEAN SharedDelete;
9536
9537 ShareAccess = &((PFCB)SrvOpen->pFcb)->ShareAccessPerSrvOpens;
9538 DesiredShareAccess = SrvOpen->ShareAccess;
9539
9540 SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
9541 SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
9542 SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
9543
9544 ShareAccess->OpenCount++;
9545
9546 ShareAccess->Readers += ReadAccess;
9547 ShareAccess->Writers += WriteAccess;
9548 ShareAccess->Deleters += DeleteAccess;
9549 ShareAccess->SharedRead += SharedRead;
9550 ShareAccess->SharedWrite += SharedWrite;
9551 ShareAccess->SharedDelete += SharedDelete;
9552 }
9553
9555}
9556
9557/*
9558 * @implemented
9559 */
9563{
9565
9566 PAGED_CODE();
9567
9568 DPRINT("RxXXXControlFileCallthru(%p)\n", Context);
9569
9570 /* No dispatch table? Nothing to dispatch */
9571 if (Context->RxDeviceObject->Dispatch == NULL)
9572 {
9573 Context->pFobx = NULL;
9575 }
9576
9577 /* Init the lowio context */
9579 if (!NT_SUCCESS(Status))
9580 {
9581 return Status;
9582 }
9583
9584 /* Check whether we're consistent: a length means a buffer */
9585 if ((Context->LowIoContext.ParamsFor.FsCtl.InputBufferLength > 0 && Context->LowIoContext.ParamsFor.FsCtl.pInputBuffer == NULL) ||
9586 (Context->LowIoContext.ParamsFor.FsCtl.OutputBufferLength > 0 && Context->LowIoContext.ParamsFor.FsCtl.pOutputBuffer == NULL))
9587 {
9589 }
9590
9591 /* Forward the call to the mini-rdr */
9592 DPRINT("Calling: %p\n", Context->RxDeviceObject->Dispatch->MRxDevFcbXXXControlFile);
9593 Status = Context->RxDeviceObject->Dispatch->MRxDevFcbXXXControlFile(Context);
9594 if (Status != STATUS_PENDING)
9595 {
9596 Context->CurrentIrp->IoStatus.Information = Context->InformationToReturn;
9597 }
9598
9599 DPRINT("RxXXXControlFileCallthru: %x, %ld\n", Context->CurrentIrp->IoStatus.Status, Context->CurrentIrp->IoStatus.Information);
9600 return Status;
9601}
BOOLEAN NTAPI MmForceSectionClosed(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
Definition: section.c:3042
#define PAGED_CODE()
ULONG ReadLength
ULONG WriteLength
Definition: CcPinRead_drv.c:40
static USHORT USHORT * NewLength
NodeType
Definition: Node.h:6
static NDIS_HANDLE DriverHandle
unsigned char BOOLEAN
Type
Definition: Type.h:7
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 LineNumber
Definition: acpixf.h:1220
struct NameRec_ * Name
Definition: cdprocs.h:460
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define DPRINT1
Definition: precomp.h:8
@ Create
Definition: registry.c:563
@ Update
Definition: registry.c:565
#define UIntToPtr(ui)
Definition: basetsd.h:90
@ TryAgain
Definition: bl.h:896
#define UNIMPLEMENTED
Definition: debug.h:115
VOID RxPurgeChangeBufferingStateRequestsForSrvOpen(_In_ PSRV_OPEN SrvOpen)
VOID RxCompleteSrvOpenKeyAssociation(_Inout_ PSRV_OPEN SrvOpen)
NTSTATUS RxPurgeFcbInSystemCache(_In_ PFCB Fcb, _In_ PLARGE_INTEGER FileOffset OPTIONAL, _In_ ULONG Length, _In_ BOOLEAN UninitializeCacheMaps, _In_ BOOLEAN FlushFile)
NTSTATUS RxFlushFcbInSystemCache(_In_ PFCB Fcb, _In_ BOOLEAN SynchronizeWithLazyWriter)
VOID RxpProcessChangeBufferingStateRequests(PSRV_CALL SrvCall, BOOLEAN UpdateHandlerState)
Definition: rxce.c:6417
VOID RxInitiateSrvOpenKeyAssociation(_Inout_ PSRV_OPEN SrvOpen)
VOID NTAPI CcPrepareMdlWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:91
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
VOID NTAPI CcMdlRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:64
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
#define CcGetFileSizePointer(FO)
Definition: ccfuncs.h:389
#define CcIsFileCached(FO)
return Found
Definition: dirsup.c:1270
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
_In_ PFCB Fcb
Definition: cdprocs.h:159
FCB * PFCB
Definition: cdstruc.h:1040
Definition: bufpool.h:45
Definition: File.h:16
Definition: Header.h:9
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define DFS_DOWNLEVEL_OPEN_CONTEXT
Definition: dfs.h:7
#define DFS_USER_NAME_CONTEXT
Definition: dfs.h:9
#define DFS_CSCAGENT_NAME_CONTEXT
Definition: dfs.h:8
#define DFS_OPEN_CONTEXT
Definition: dfs.h:6
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DEVICE_TYPE
Definition: guid.c:10
#define NTSTATUS
Definition: precomp.h:21
#define FILE_SHARE_READ
Definition: compat.h:136
#define Assert(cond, msg)
Definition: inflate.c:41
ULONG SessionId
Definition: dllmain.c:28
DWORD OpenCount
Definition: legacy.c:25
static const WCHAR Message[]
Definition: register.c:74
USHORT NODE_TYPE_CODE
Definition: nodetype.h:22
#define NodeType(P)
Definition: nodetype.h:51
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_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:4147
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define FILE_WRITE_TO_END_OF_FILE
Definition: ext2fs.h:278
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2665
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN CheckForReadOperation
Definition: fatprocs.h:2666
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
#define FCB_STATE_TEMPORARY
Definition: fatstruc.h:1198
#define FCB_STATE_DELETE_ON_CLOSE
Definition: fatstruc.h:1193
#define FCB_STATE_TRUNCATE_ON_CLOSE
Definition: fatstruc.h:1194
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
#define FCB_STATE_DELAY_CLOSE
Definition: fatstruc.h:1203
#define FCB_STATE_WRITECACHING_ENABLED
Definition: fcb.h:226
VOID RxGetFileSizeWithLock(_In_ PFCB Fcb, _Out_ PLONGLONG FileSize)
#define FCB_STATE_FILE_IS_BUF_COMPRESSED
Definition: fcb.h:212
VOID RxSetFileSizeWithLock(_Inout_ PFCB Fcb, _In_ PLONGLONG FileSize)
#define RxDereferenceSrvOpen(SrvOpen, LockHoldingState)
Definition: fcb.h:427
#define FCB_STATE_FILESIZECACHEING_ENABLED
Definition: fcb.h:219
#define RxWaitForStableNetFcb(F, R)
Definition: fcb.h:542
#define RxReferenceVNetRoot(VNetRoot)
Definition: fcb.h:407
#define RxDereferenceNetFcb(Fcb)
Definition: fcb.h:435
struct _FOBX * PFOBX
#define RxTransitionNetFcb(F, C)
Definition: fcb.h:543
#define FCB_STATE_FILE_IS_DISK_COMPRESSED
Definition: fcb.h:213
#define RxTransitionSrvOpen(S, C)
Definition: fcb.h:578
#define FOBX_FLAG_MARKED_AS_DORMANT
Definition: fcb.h:299
#define FOBX_FLAG_USER_SET_LAST_CHANGE
Definition: fcb.h:294
#define SRVOPEN_FLAG_SHAREACCESS_UPDATED
Definition: fcb.h:258
#define FCB_STATE_READCACHING_ENABLED
Definition: fcb.h:224
#define FCB_STATE_ORPHANED
Definition: fcb.h:208
struct _V_NET_ROOT * PV_NET_ROOT
#define FOBX_FLAG_DELETE_ON_CLOSE
Definition: fcb.h:295
PSRV_OPEN RxCreateSrvOpen(_In_ PV_NET_ROOT VNetRoot, _In_ OUT PFCB Fcb)
#define FOBX_FLAG_USER_SET_LAST_WRITE
Definition: fcb.h:291
#define FOBX_FLAG_MATCH_ALL
Definition: fcb.h:289
#define RxReferenceNetFcb(Fcb)
Definition: fcb.h:431
struct _SRV_OPEN * PSRV_OPEN
#define FOBX_FLAG_UNC_NAME
Definition: fcb.h:297
#define RxDereferenceAndFinalizeNetFcb(Fcb, RxContext, RecursiveFinalize, ForceFinalize)
Definition: fcb.h:439
PFCB RxCreateNetFcb(_In_ PRX_CONTEXT RxContext, _In_ PV_NET_ROOT VNetRoot, _In_ PUNICODE_STRING Name)
#define FOBX_FLAG_USER_SET_LAST_ACCESS
Definition: fcb.h:292
struct _NET_ROOT * PNET_ROOT
#define RxReferenceSrvOpen(SrvOpen)
Definition: fcb.h:423
#define FOBX_FLAG_FREE_UNICODE
Definition: fcb.h:290
#define FOBX_FLAG_USER_SET_CREATION
Definition: fcb.h:293
#define FCB_STATE_ADDEDBACKSLASH
Definition: fcb.h:228
VOID RxRemoveNameNetFcb(_Out_ PFCB ThisFcb)
#define FCB_STATE_COLLAPSING_ENABLED
Definition: fcb.h:221
#define FOBX_FLAG_SRVOPEN_CLOSED
Definition: fcb.h:296
#define FCB_STATE_FILE_IS_SHADOWED
Definition: fcb.h:214
#define RxWaitForStableSrvOpen(S, R)
Definition: fcb.h:577
#define RxReferenceSrvCall(SrvCall)
Definition: fcb.h:391
#define RxDereferenceNetFobx(Fobx, LockHoldingState)
Definition: fcb.h:419
#define RxDereferenceVNetRoot(VNetRoot, LockHoldingState)
Definition: fcb.h:411
#define FCB_STATE_READAHEAD_DEFERRED
Definition: fcb.h:209
#define RxAcquireFcbTableLockShared(T, W)
Definition: fcbtable.h:54
#define RxAcquireFcbTableLockExclusive(T, W)
Definition: fcbtable.h:55
PFCB RxFcbTableLookupFcb(_In_ PRX_FCB_TABLE FcbTable, _In_ PUNICODE_STRING Path)
#define RxReleaseFcbTableLock(T)
Definition: fcbtable.h:56
struct _FileName FileName
Definition: fatprocs.h:896
BOOLEAN NTAPI FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:782
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:710
NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL)
Definition: filelock.c:1025
BOOLEAN NTAPI FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:748
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:672
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2246
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_opt_ GUID _In_ USHORT DataBufferLength
Definition: fltkernel.h:1270
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileMoveClusterInformation
Definition: from_kernel.h:92
@ FilePipeLocalInformation
Definition: from_kernel.h:85
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileCompressionInformation
Definition: from_kernel.h:89
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileAllInformation
Definition: from_kernel.h:79
@ FilePipeRemoteInformation
Definition: from_kernel.h:86
@ FileLinkInformation
Definition: from_kernel.h:72
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileEaInformation
Definition: from_kernel.h:68
@ FilePipeInformation
Definition: from_kernel.h:84
@ FileAlternateNameInformation
Definition: from_kernel.h:82
@ FileValidDataLengthInformation
Definition: from_kernel.h:100
@ FileNameInformation
Definition: from_kernel.h:70
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
@ FileShortNameInformation
Definition: from_kernel.h:101
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_CREATE
Definition: from_kernel.h:55
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_OPEN_REMOTE_INSTANCE
Definition: from_kernel.h:37
#define FILE_CREATE_TREE_CONNECTION
Definition: from_kernel.h:33
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
#define FSRTL_FLAG_USER_MAPPED_FILE
Definition: fsrtltypes.h:50
#define FSRTL_FAST_IO_TOP_LEVEL_IRP
Definition: fsrtltypes.h:62
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define USHRT_MAX
Definition: limits.h:38
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR)
#define NOTHING
Definition: input_list.c:10
HRESULT Create([out]ITransactionReceiver **ppReceiver)
ULONG NTAPI ExInterlockedAddUlong(IN OUT PULONG Addend, IN ULONG Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:88
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define C_ASSERT(e)
Definition: intsafe.h:73
#define Add2Ptr(PTR, INC)
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
if(dx< 0)
Definition: linetemp.h:194
VOID NTAPI CcSetAdditionalCacheAttributes(IN PFILE_OBJECT FileObject, IN BOOLEAN DisableReadAhead, IN BOOLEAN DisableWriteBehind)
Definition: logsup.c:22
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
NTSTATUS NTAPI RxLowIoPopulateFsctlInfo(_In_ PRX_CONTEXT RxContext)
FAST_MUTEX RxLowIoPagingIoSyncMutex
Definition: rxce.c:136
NTSTATUS NTAPI RxLowIoSubmit(_In_ PRX_CONTEXT RxContext, _In_ PLOWIO_COMPLETION_ROUTINE CompletionRoutine)
VOID NTAPI RxInitializeLowIoContext(_Out_ PLOWIO_CONTEXT LowIoContext, _In_ ULONG Operation)
#define RxLowIoIsBufferLocked(LowIoContext)
Definition: lowio.h:10
@ SecurityImpersonation
Definition: lsa.idl:57
DeviceType
Definition: mmdrv.h:42
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define for
Definition: utility.h:88
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
@ NormalPagePriority
Definition: imports.h:56
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
enum _RX_BLOCK_CONDITION RX_BLOCK_CONDITION
#define LOWIO_CONTEXT_FLAG_SAVEUNLOCKS
Definition: mrx.h:321
#define LOWIO_READWRITEFLAG_EXTENDING_VDL
Definition: mrx.h:327
@ Condition_Good
Definition: mrx.h:76
@ Condition_Bad
Definition: mrx.h:77
#define LOWIO_READWRITEFLAG_EXTENDING_FILESIZE
Definition: mrx.h:326
@ LOWIO_OP_WRITE
Definition: mrx.h:235
@ LOWIO_OP_READ
Definition: mrx.h:234
@ LOWIO_OP_NOTIFY_CHANGE_DIRECTORY
Definition: mrx.h:242
@ LOWIO_OP_UNLOCK_MULTIPLE
Definition: mrx.h:239
@ LOWIO_OP_IOCTL
Definition: mrx.h:241
#define RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS
Definition: mrx.h:10
#define RxSetIoStatusStatus(R, S)
Definition: mrx.h:4
#define LOWIO_CONTEXT_FLAG_SYNCCALL
Definition: mrx.h:320
#define RDBSS_NO_DEFERRED_CACHE_READAHEAD
Definition: mrx.h:335
#define RX_REGISTERMINI_FLAG_DONT_INIT_DRIVER_DISPATCH
Definition: mrx.h:11
#define StableCondition(X)
Definition: mrx.h:81
#define RX_REGISTERMINI_FLAG_DONT_PROVIDE_UNCS
Definition: mrx.h:9
#define LOWIO_CONTEXT_FLAG_LOUDOPS
Definition: mrx.h:322
#define RX_REGISTERMINI_FLAG_DONT_INIT_PREFIX_N_SCAVENGER
Definition: mrx.h:12
#define RxSetIoStatusInfo(R, I)
Definition: mrx.h:5
#define NET_ROOT_WILD
Definition: mrxfcb.h:33
#define FOBX_FLAG_DFS_OPEN
Definition: mrxfcb.h:181
struct _MRX_SRV_OPEN_ * PMRX_SRV_OPEN
#define SRVOPEN_FLAG_NO_BUFFERING_STATE_CHANGE
Definition: mrxfcb.h:139
struct _MRX_FOBX_ * PMRX_FOBX
#define SRVOPEN_FLAG_COLLAPSING_DISABLED
Definition: mrxfcb.h:137
#define SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING
Definition: mrxfcb.h:136
#define SRVOPEN_FLAG_DONTUSE_WRITE_CACHING
Definition: mrxfcb.h:131
#define NET_ROOT_PIPE
Definition: mrxfcb.h:31
#define SRVOPEN_FLAG_FILE_DELETED
Definition: mrxfcb.h:135
#define FOBX_FLAG_BAD_HANDLE
Definition: mrxfcb.h:182
#define NET_ROOT_DISK
Definition: mrxfcb.h:30
UCHAR * PNET_ROOT_TYPE
Definition: mrxfcb.h:36
struct _MRX_V_NET_ROOT_ * PMRX_V_NET_ROOT
#define SRVOPEN_FLAG_DONTUSE_READ_CACHING
Definition: mrxfcb.h:130
#define SRVOPEN_FLAG_CLOSED
Definition: mrxfcb.h:132
#define NET_ROOT_PRINT
Definition: mrxfcb.h:32
#define NETROOT_FLAG_DFS_AWARE_NETROOT
Definition: mrxfcb.h:45
#define SRVCALL_FLAG_DFS_AWARE_SERVER
Definition: mrxfcb.h:13
#define SRVOPEN_FLAG_CLOSE_DELAYED
Definition: mrxfcb.h:133
UCHAR NET_ROOT_TYPE
Definition: mrxfcb.h:36
#define SRVOPEN_FLAG_ORPHANED
Definition: mrxfcb.h:140
#define SRVOPEN_FLAG_FILE_RENAMED
Definition: mrxfcb.h:134
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4207
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_ATTRIBUTE_VALID_FLAGS
Definition: nt_native.h:714
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
@ KeyValuePartialInformation
Definition: nt_native.h:1182
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define FILE_SHARE_VALID_FLAGS
Definition: nt_native.h:683
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
#define FILE_OPENED
Definition: nt_native.h:769
#define KEY_NOTIFY
Definition: nt_native.h:1020
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
#define UNICODE_NULL
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
@ SynchronizationEvent
#define IOCTL_REDIR_QUERY_PATH
struct _QUERY_PATH_REQUEST * PQUERY_PATH_REQUEST
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:43
VOID NTAPI CcDeferWrite(IN PFILE_OBJECT FileObject, IN PCC_POST_DEFERRED_WRITE PostRoutine, IN PVOID Context1, IN PVOID Context2, IN ULONG BytesToWrite, IN BOOLEAN Retrying)
Definition: copysup.c:225
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
Definition: resource.c:2050
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
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
VOID NTAPI IoSetShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3517
NTSTATUS NTAPI IoCheckShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess, IN BOOLEAN Update)
Definition: file.c:3390
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3478
VOID NTAPI IoUpdateShareAccess(IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3351
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI IoGetStackLimits(OUT PULONG_PTR LowLimit, OUT PULONG_PTR HighLimit)
Definition: util.c:78
PEPROCESS NTAPI IoGetCurrentProcess(VOID)
Definition: util.c:139
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
VOID NTAPI IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:987
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
NTSTATUS NTAPI SeQueryAuthenticationIdToken(_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
Queries the authentication ID of an access token.
Definition: token.c:2036
NTSTATUS NTAPI SeQuerySessionIdToken(_In_ PACCESS_TOKEN Token, _Out_ PULONG pSessionId)
Queries the session ID of an access token.
Definition: token.c:2004
#define RxGetRequestorProcess(RxContext)
Definition: ntrxdef.h:33
#define capFileObject
Definition: ntrxdef.h:23
#define capFcb
Definition: ntrxdef.h:20
#define capPARAMS
Definition: ntrxdef.h:22
#define RxAdjustAllocationSizeforCC(Fcb)
Definition: ntrxdef.h:35
#define RxAllocatePoolWithTag
Definition: ntrxdef.h:25
#define capFobx
Definition: ntrxdef.h:21
#define RxFreePool
Definition: ntrxdef.h:26
#define RxCaptureFileObject
Definition: ntrxdef.h:18
#define RxCaptureFobx
Definition: ntrxdef.h:11
#define RxCaptureParamBlock
Definition: ntrxdef.h:17
#define RxCaptureFcb
Definition: ntrxdef.h:10
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:711
#define STATUS_BAD_NETWORK_PATH
Definition: ntstatus.h:426
#define STATUS_REDIRECTOR_NOT_STARTED
Definition: ntstatus.h:487
#define STATUS_REDIRECTOR_STARTED
Definition: ntstatus.h:488
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_LOCK_NOT_GRANTED
Definition: ntstatus.h:321
#define STATUS_NETWORK_CREDENTIAL_CONFLICT
Definition: ntstatus.h:638
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
#define STATUS_DFS_UNAVAILABLE
Definition: ntstatus.h:746
#define STATUS_UNEXPECTED_NETWORK_ERROR
Definition: ntstatus.h:432
#define STATUS_FILES_OPEN
Definition: ntstatus.h:499
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define RxAcquirePrefixTableLockShared(T, W)
Definition: prefix.h:82
VOID RxpReleasePrefixTableLock(_In_ PRX_PREFIX_TABLE pTable, _In_ BOOLEAN ProcessBufferingStateChangeRequests)
BOOLEAN RxpAcquirePrefixTableLockShared(_In_ PRX_PREFIX_TABLE pTable, _In_ BOOLEAN Wait, _In_ BOOLEAN ProcessBufferingStateChangeRequests)
#define RxAcquirePrefixTableLockExclusive(T, W)
Definition: prefix.h:83
VOID RxInitializePrefixTable(_Inout_ PRX_PREFIX_TABLE ThisTable, _In_opt_ ULONG TableSize, _In_ BOOLEAN CaseInsensitiveMatch)
#define RxReleasePrefixTableLock(T)
Definition: prefix.h:84
#define FileStandardInformation
Definition: propsheet.cpp:61
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
VOID RxUnwindTopLevelIrp(IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:9471
BOOLEAN RxIsOkToPurgeFcb(PFCB Fcb)
Definition: rdbss.c:7036
NTSTATUS NTAPI RxCommonQuerySecurity(PRX_CONTEXT Context)
Definition: rdbss.c:3128
KMUTEX RxSerializationMutex
Definition: rdbss.c:609
FCB RxDeviceFCB
Definition: rdbss.c:538
#define VALID_FILE_ATTRIBUTES
VOID RxUpdateShareAccessPerSrvOpens(IN PSRV_OPEN SrvOpen)
Definition: rdbss.c:9506
VOID NTAPI RxIndicateChangeOfBufferingStateForSrvOpen(PMRX_SRV_CALL SrvCall, PMRX_SRV_OPEN SrvOpen, PVOID SrvOpenKey, PVOID Context)
Definition: rdbss.c:6880
VOID RxAddToTopLevelIrpAllocatedContextsList(PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:752
NTSTATUS NTAPI RxLowIoReadShellCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7273
NTSTATUS RxQueryDirectory(PRX_CONTEXT RxContext)
Definition: rdbss.c:8052
LUID RxGetUid(IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext)
Definition: rdbss.c:6864
NTSTATUS NTAPI RxCommonUnimplemented(PRX_CONTEXT Context)
Definition: rdbss.c:3921
VOID NTAPI RxGetRegistryParameters(IN PUNICODE_STRING RegistryPath)
Definition: rdbss.c:6695
VOID NTAPI RxFspDispatch(IN PVOID Context)
Definition: rdbss.c:6571
#define VALID_DIR_ATTRIBUTES
struct _RX_FSD_DISPATCH_VECTOR RX_FSD_DISPATCH_VECTOR
NTSTATUS NTAPI RxCommonDevFCBClose(PRX_CONTEXT Context)
Definition: rdbss.c:2685
NTSTATUS RxFsdPostRequest(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:6548
NTSTATUS NTAPI RxCommonLockControl(PRX_CONTEXT Context)
Definition: rdbss.c:2893
NPAGED_LOOKASIDE_LIST RxContextLookasideList
Definition: rdbss.c:536
NTSTATUS RxSystemControl(IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN PIRP Irp)
Definition: rdbss.c:9336
NTSTATUS NTAPI RxCommonClose(PRX_CONTEXT Context)
Definition: rdbss.c:2284
NTSTATUS NTAPI RxCommonDevFCBCleanup(PRX_CONTEXT Context)
Definition: rdbss.c:2648
VOID __RxWriteReleaseResources(PRX_CONTEXT RxContext, BOOLEAN ResourceOwnerSet, ULONG LineNumber, PCSTR FileName, ULONG SerialNumber)
Definition: rdbss.c:701
NTSTATUS NTAPI RxCommonRead(PRX_CONTEXT Context)
Definition: rdbss.c:3184
NTSTATUS RxQueryInternalInfo(PRX_CONTEXT RxContext, PFILE_INTERNAL_INFORMATION InternalInfo)
Definition: rdbss.c:8274
VOID RxpPrepareCreateContextForReuse(PRX_CONTEXT RxContext)
Definition: rdbss.c:7654
NTSTATUS RxCheckShareAccessPerSrvOpens(IN PFCB Fcb, IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess)
Definition: rdbss.c:1477
PRDBSS_DEVICE_OBJECT RxFileSystemDeviceObject
Definition: rdbss.c:573
BOOLEAN DisableByteRangeLockingOnReadOnlyFiles
Definition: rdbss.c:532
VOID RxCopyCreateParameters(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:5039
VOID RxSetupNetFileObject(PRX_CONTEXT RxContext)
Definition: rdbss.c:9147
NTSTATUS RxCreateFromNetRoot(PRX_CONTEXT Context, PUNICODE_STRING NetRootName)
Definition: rdbss.c:5114
VOID RxConjureOriginalName(PFCB Fcb, PFOBX Fobx, PULONG ActualNameLength, PWCHAR OriginalName, PLONG LengthRemaining, RX_NAME_CONJURING_METHODS NameConjuringMethod)
Definition: rdbss.c:4911
NTSTATUS RxCreateTreeConnect(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:5409
VOID RxFreeCanonicalNameBuffer(PRX_CONTEXT Context)
Definition: rdbss.c:6159
VOID RxAssert(PVOID Assert, PVOID File, ULONG Line, PVOID Message)
Definition: rxce.c:645
NTSTATUS RxPostStackOverflowRead(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:7641
LIST_ENTRY RxActiveContexts
Definition: rdbss.c:535
NTSTATUS RxQueryBasicInfo(PRX_CONTEXT RxContext, PFILE_BASIC_INFORMATION BasicInfo)
Definition: rdbss.c:8026
NTSTATUS NTAPI RxCommonFlushBuffers(PRX_CONTEXT Context)
Definition: rdbss.c:2884
NTSTATUS RxQueryCompressedInfo(PRX_CONTEXT RxContext, PFILE_COMPRESSION_INFORMATION CompressionInfo)
Definition: rdbss.c:8040
ULONG ReadAheadGranularity
Definition: rdbss.c:534
#define SET_SIZE_AND_QUERY(AlreadyConsummed, Function)
NTSTATUS NTAPI RxCommonCreate(PRX_CONTEXT Context)
Definition: rdbss.c:2440
NTSTATUS RxQueryNameInfo(PRX_CONTEXT RxContext, PFILE_NAME_INFORMATION NameInfo)
Definition: rdbss.c:8286
NTSTATUS NTAPI RxCommonDispatchProblem(PRX_CONTEXT Context)
Definition: rdbss.c:2854
NTSTATUS NTAPI RxCommonSetEa(PRX_CONTEXT Context)
Definition: rdbss.c:3640
#define ALLSCR_LENGTH
RDBSS_DATA RxData
Definition: rdbss.c:537
KMUTEX RxScavengerMutex
Definition: rdbss.c:608
PRX_CONTEXT RxRemoveOverflowEntry(PRDBSS_DEVICE_OBJECT DeviceObject, WORK_QUEUE_TYPE Queue)
Definition: rdbss.c:8580
FAST_IO_DISPATCH RxFastIoDispatch
Definition: rdbss.c:572
VOID NTAPI RxReleaseFileForNtCreateSection(PFILE_OBJECT FileObject)
Definition: rxce.c:7578
PVOID RxNewMapUserBuffer(PRX_CONTEXT RxContext)
Definition: rxce.c:5775
RX_FSD_DISPATCH_VECTOR RxFsdDispatchVector[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: rdbss.c:574
NTSTATUS(NTAPI * PRX_FSD_DISPATCH)(PRX_CONTEXT Context)
Definition: rdbss.c:42
NTSTATUS RxpSetInfoMiniRdr(PRX_CONTEXT RxContext, FILE_INFORMATION_CLASS Class)
Definition: rdbss.c:7964
BOOLEAN DisableFlushOnCleanup
Definition: rdbss.c:533
NTSTATUS RxQueryStandardInfo(PRX_CONTEXT RxContext, PFILE_STANDARD_INFORMATION StandardInfo)
Definition: rdbss.c:8358
NTSTATUS NTAPI RxLowIoCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7175
NTSTATUS RxCanonicalizeFileNameByServerSpecs(PRX_CONTEXT RxContext, PUNICODE_STRING NetRootName)
Definition: rdbss.c:1261
VOID NTAPI RxCancelRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: rdbss.c:1196
NTSTATUS NTAPI RxReleaseForCcFlush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
Definition: rxce.c:7586
BOOLEAN RxIsMemberOfTopLevelIrpAllocatedContextsList(PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:7002
NTSTATUS NTAPI RxLowIoIoCtlShellCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7187
VOID RxAdjustFileTimesAndSize(PRX_CONTEXT RxContext)
Definition: rdbss.c:825
NTSTATUS RxSetEndOfFileInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9018
NTSTATUS NTAPI RxCommonQueryEa(PRX_CONTEXT Context)
Definition: rdbss.c:2902
VOID RxPrePostIrp(IN PVOID Context, IN PIRP Irp)
Definition: rdbss.c:7906
NTSTATUS RxSetAllocationInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:8864
VOID NTAPI RxInitUnwind(PDRIVER_OBJECT DriverObject, USHORT State)
Definition: rdbss.c:6991
VOID NTAPI RxLogEventWithAnnotation(IN PRDBSS_DEVICE_OBJECT DeviceObject, IN ULONG EventId, IN NTSTATUS Status, IN PVOID DataBuffer, IN USHORT DataBufferLength, IN PUNICODE_STRING Annotation, IN ULONG AnnotationCount)
Definition: rdbss.c:7161
NTSTATUS NTAPI RxLockOperationCompletion(IN PVOID Context, IN PIRP Irp)
Definition: rdbss.c:7125
VOID NTAPI RxDebugControlCommand(_In_ PSTR ControlString)
Definition: rdbss.c:5496
NTSTATUS RxCanonicalizeNameAndObtainNetRoot(PRX_CONTEXT RxContext, PUNICODE_STRING FileName, PUNICODE_STRING NetRootName)
Definition: rdbss.c:1352
NTSTATUS RxSetDispositionInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:8978
NTSTATUS NTAPI RxCommonDirectoryControl(PRX_CONTEXT Context)
Definition: rdbss.c:2816
VOID RxRemoveShareAccessPerSrvOpens(IN OUT PSRV_OPEN SrvOpen)
Definition: rdbss.c:8635
BOOLEAN NTAPI RxFastIoCheckIfPossible(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, BOOLEAN CheckForReadOperation, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
Definition: rdbss.c:5630
NTSTATUS NTAPI RxCommonSetQuotaInformation(PRX_CONTEXT Context)
Definition: rdbss.c:3894
NTSTATUS RxCollapseOrCreateSrvOpen(PRX_CONTEXT RxContext)
Definition: rdbss.c:1732
NTSTATUS NTAPI RxGetStringRegistryParameter(IN HANDLE KeyHandle, IN PCWSTR KeyName, OUT PUNICODE_STRING OutString, IN PUCHAR Buffer, IN ULONG BufferLength, IN BOOLEAN LogFailure)
Definition: rdbss.c:6787
VOID RxUnstart(PRX_CONTEXT Context, PRDBSS_DEVICE_OBJECT DeviceObject)
Definition: rdbss.c:9460
NTSTATUS RxQueryEaInfo(PRX_CONTEXT RxContext, PFILE_EA_INFORMATION EaInfo)
Definition: rdbss.c:8265
NTSTATUS RxPrefixClaim(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:7714
LIST_ENTRY TopLevelIrpAllocatedContextsList
Definition: rdbss.c:612
UCHAR RxSpaceForTheWrappersDeviceObject[sizeof(*RxFileSystemDeviceObject)]
Definition: rdbss.c:610
PIRP RxGetTopIrpIfRdbssIrp(VOID)
Definition: rdbss.c:6845
NTSTATUS RxQueryAlternateNameInfo(PRX_CONTEXT RxContext, PFILE_NAME_INFORMATION AltNameInfo)
Definition: rdbss.c:8014
VOID NTAPI RxLogEventDirect(IN PRDBSS_DEVICE_OBJECT DeviceObject, IN PUNICODE_STRING OriginatorId, IN ULONG EventId, IN NTSTATUS Status, IN ULONG Line)
Definition: rdbss.c:7138
ULONG RxGetNetworkProviderPriority(PUNICODE_STRING DeviceName)
Definition: rdbss.c:6683
VOID __RxInitializeTopLevelIrpContext(IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext, IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN ULONG Flags)
Definition: rdbss.c:674
NTSTATUS NTAPI RxInitializeRegistrationStructures(VOID)
Definition: rdbss.c:6964
NTSTATUS RxQueryPipeInfo(PRX_CONTEXT RxContext, PFILE_PIPE_INFORMATION PipeInfo)
Definition: rdbss.c:8337
VOID RxUninitializeCacheMap(PRX_CONTEXT RxContext, PFILE_OBJECT FileObject, PLARGE_INTEGER TruncateSize)
Definition: rdbss.c:9414
NTSTATUS NTAPI RxFsdDispatch(IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN PIRP Irp)
Definition: rdbss.c:6472
NTSTATUS RxFirstCanonicalize(PRX_CONTEXT RxContext, PUNICODE_STRING FileName, PUNICODE_STRING CanonicalName, PNET_ROOT_TYPE NetRootType)
Definition: rdbss.c:6010
BOOLEAN RxLoudLowIoOpsEnabled
Definition: rdbss.c:539
NTSTATUS NTAPI RxCommonSetInformation(PRX_CONTEXT Context)
Definition: rdbss.c:3652
VOID CheckForLoudOperations(PRX_CONTEXT RxContext)
Definition: rdbss.c:647
NTSTATUS NTAPI RxCommonDevFCBQueryVolInfo(PRX_CONTEXT Context)
Definition: rdbss.c:2775
BOOLEAN RxTryToBecomeTheTopLevelIrp(IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext, IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN BOOLEAN ForceTopLevel)
Definition: rdbss.c:9348
NTSTATUS RxSetRenameInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9045
NTSTATUS NTAPI RxCommonDevFCBFsCtl(PRX_CONTEXT Context)
Definition: rdbss.c:2726
VOID RxRemoveFromTopLevelIrpAllocatedContextsList(PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:8562
NTSTATUS RxSearchForCollapsibleOpen(PRX_CONTEXT RxContext, ACCESS_MASK DesiredAccess, ULONG ShareAccess)
Definition: rdbss.c:8679
NTSTATUS NTAPI RxCommonSetVolumeInformation(PRX_CONTEXT Context)
Definition: rdbss.c:3912
VOID NTAPI RxpUnregisterMinirdr(IN PRDBSS_DEVICE_OBJECT RxDeviceObject)
Definition: rdbss.c:7985
NTSTATUS NTAPI RxCommonWrite(PRX_CONTEXT Context)
Definition: rdbss.c:3930
WCHAR Rx8QMdot3QM[]
Definition: rdbss.c:531
RX_FSD_DISPATCH_VECTOR RxDeviceFCBVector[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: rdbss.c:540
BOOLEAN NTAPI RxFastIoWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
Definition: rdbss.c:5823
ULONG RxGetSessionId(IN PIO_STACK_LOCATION IrpSp)
Definition: rdbss.c:6751
NTSTATUS NTAPI RxStartMinirdr(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
Definition: rdbss.c:9230
#define _SEH2_TRY_RETURN(S)
#define RX_TOPLEVELCTX_FLAG_FROM_POOL
Definition: rdbss.c:38
PVOID NTAPI _RxAllocatePoolWithTag(_In_ POOL_TYPE PoolType, _In_ SIZE_T NumberOfBytes, _In_ ULONG Tag)
Definition: rxce.c:8941
NTSTATUS RxCloseAssociatedSrvOpen(IN PFOBX Fobx, IN PRX_CONTEXT RxContext OPTIONAL)
Definition: rdbss.c:1534
NTSTATUS RxLowIoLockControlShell(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:7212
VOID NTAPI RxAcquireFileForNtCreateSection(PFILE_OBJECT FileObject)
Definition: rxce.c:276
BOOLEAN NTAPI RxFastIoDeviceControl(PFILE_OBJECT FileObject, BOOLEAN Wait, PVOID InputBuffer OPTIONAL, ULONG InputBufferLength, PVOID OutputBuffer OPTIONAL, ULONG OutputBufferLength, ULONG IoControlCode, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
Definition: rdbss.c:5752
VOID NTAPI RxpCancelRoutine(PVOID Context)
Definition: rdbss.c:7616
NTSTATUS NTAPI RxCommonQueryVolumeInformation(PRX_CONTEXT Context)
Definition: rdbss.c:3140
NTSTATUS NTAPI RxInitializeLog(VOID)
Definition: rdbss.c:6942
NTSTATUS NTAPI RxCommonDeviceControl(PRX_CONTEXT Context)
Definition: rdbss.c:2787
BOOLEAN RxCancelOperationInOverflowQueue(PRX_CONTEXT RxContext)
Definition: rdbss.c:1139
NTSTATUS RxAllocateCanonicalNameBuffer(PRX_CONTEXT RxContext, PUNICODE_STRING CanonicalName, USHORT CanonicalLength)
Definition: rdbss.c:924
KSPIN_LOCK TopLevelIrpSpinLock
Definition: rdbss.c:611
VOID NTAPI RxUnlockOperation(IN PVOID Context, IN PFILE_LOCK_INFO LockInfo)
Definition: rdbss.c:9452
VOID NTAPI RxInitializeTopLevelIrpPackage(VOID)
Definition: rdbss.c:6982
NTSTATUS RxSetBasicInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:8875
VOID NTAPI RxInitializeDebugSupport(VOID)
Definition: rxce.c:4677
NTSTATUS RxFsdCommonDispatch(PRX_FSD_DISPATCH_VECTOR DispatchVector, UCHAR MajorFunction, PIO_STACK_LOCATION Stack, PFILE_OBJECT FileObject, PIRP Irp, PRDBSS_DEVICE_OBJECT RxDeviceObject)
Definition: rdbss.c:6176
VOID NTAPI _RxFreePool(_In_ PVOID Buffer)
Definition: rxce.c:8954
LIST_ENTRY RxIrpsList
Definition: rdbss.c:606
NTSTATUS RxFindOrCreateFcb(PRX_CONTEXT RxContext, PUNICODE_STRING NetRootName)
Definition: rdbss.c:5869
BOOLEAN NTAPI RxFastIoRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
Definition: rdbss.c:5780
NTSTATUS NTAPI RxCommonFileSystemControl(PRX_CONTEXT Context)
Definition: rdbss.c:2863
NTSTATUS RxNotifyChangeDirectory(PRX_CONTEXT RxContext)
Definition: rdbss.c:7556
BOOLEAN RxIsThisTheTopLevelIrp(IN PIRP Irp)
Definition: rdbss.c:7108
NTSTATUS NTAPI RxCommonSetSecurity(PRX_CONTEXT Context)
Definition: rdbss.c:3903
VOID NTAPI RxCheckFcbStructuresForAlignment(VOID)
Definition: rdbss.c:1447
VOID NTAPI RxReadRegistryParameters(VOID)
Definition: rdbss.c:8416
VOID NTAPI RxAddToWorkque(IN PRX_CONTEXT RxContext, IN PIRP Irp)
Definition: rdbss.c:772
NTSTATUS RxXXXControlFileCallthru(PRX_CONTEXT Context)
Definition: rdbss.c:9561
NTSTATUS RxCancelNotifyChangeDirectoryRequestsForVNetRoot(PV_NET_ROOT VNetRoot, BOOLEAN ForceFilesClosed)
Definition: rdbss.c:1040
struct _RX_FSD_DISPATCH_VECTOR * PRX_FSD_DISPATCH_VECTOR
RDBSS_EXPORTS RxExports
Definition: rdbss.c:571
NTSTATUS NTAPI RxLowIoWriteShellCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7416
ULONG RxFsdEntryCount
Definition: rdbss.c:605
NTSTATUS NTAPI RxCommonDevFCBIoCtl(PRX_CONTEXT Context)
Definition: rdbss.c:2738
VOID RxCleanupPipeQueues(PRX_CONTEXT Context)
Definition: rdbss.c:1524
NTSTATUS RxSetPositionInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9034
NTSTATUS NTAPI RxStopMinirdr(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
Definition: rdbss.c:9327
NTSTATUS NTAPI RxCommonQueryInformation(PRX_CONTEXT Context)
Definition: rdbss.c:2914
BOOLEAN RxNoAsync
Definition: rdbss.c:614
KSPIN_LOCK RxIrpsListSpinLock
Definition: rdbss.c:607
NTSTATUS RxLowIoReadShell(PRX_CONTEXT RxContext)
Definition: rdbss.c:7242
WCHAR RxStarForTemplate
Definition: rdbss.c:530
VOID NTAPI RxInitializeDispatchVectors(PDRIVER_OBJECT DriverObject)
Definition: rdbss.c:6894
NTSTATUS NTAPI RxCompleteMdl(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:4857
NTSTATUS NTAPI RxLowIoNotifyChangeDirectoryCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7224
VOID RxCancelNotifyChangeDirectoryRequestsForFobx(PFOBX Fobx)
Definition: rdbss.c:963
NTSTATUS RxpQueryInfoMiniRdr(PRX_CONTEXT RxContext, FILE_INFORMATION_CLASS FileInfoClass, PVOID Buffer)
Definition: rdbss.c:7690
VOID NTAPI RxUnload(IN PDRIVER_OBJECT DriverObject)
Definition: rdbss.c:9444
NTSTATUS NTAPI RxCommonQueryQuotaInformation(PRX_CONTEXT Context)
Definition: rdbss.c:3119
NTSTATUS RxQueryPositionInfo(PRX_CONTEXT RxContext, PFILE_POSITION_INFORMATION PositionInfo)
Definition: rdbss.c:8346
PRDBSS_DEVICE_OBJECT RxGetTopDeviceObjectIfRdbssIrp(VOID)
Definition: rdbss.c:6826
NTSTATUS RxLowIoWriteShell(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:7386
NTSTATUS NTAPI RxRegisterMinirdr(OUT PRDBSS_DEVICE_OBJECT *DeviceObject, IN OUT PDRIVER_OBJECT DriverObject, IN PMINIRDR_DISPATCH MrdrDispatch, IN ULONG Controls, IN PUNICODE_STRING DeviceName, IN ULONG DeviceExtensionSize, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics)
Definition: rdbss.c:8474
NTSTATUS NTAPI RxDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: rdbss.c:5504
NTSTATUS RxSetSimpleInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9136
VOID NTAPI _RxFreePoolWithTag(_In_ PVOID Buffer, _In_ ULONG Tag)
Definition: rxce.c:8965
NTSTATUS NTAPI RxCommonCleanup(PRX_CONTEXT Context)
Definition: rdbss.c:1915
BOOLEAN RxIsThisAnRdbssTopLevelContext(PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:7075
VOID RxInitializeMinirdrDispatchTable(IN PDRIVER_OBJECT DriverObject)
Definition: rdbss.c:6953
NTSTATUS NTAPI RxPrepareToReparseSymbolicLink(PRX_CONTEXT RxContext, BOOLEAN SymbolicLinkEmbeddedInOldPath, PUNICODE_STRING NewPath, BOOLEAN NewPathIsAbsolute, PBOOLEAN ReparseRequired)
Definition: rdbss.c:7825
BOOLEAN RxForceQFIPassThrough
Definition: rdbss.c:613
VOID RxPurgeNetFcb(PFCB Fcb, PRX_CONTEXT LocalContext)
Definition: rdbss.c:7995
NTSTATUS NTAPI RxAcquireForCcFlush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
Definition: rxce.c:284
NTSTATUS RxSetPipeInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9026
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
ULONG SerialNumber
Definition: rxce.c:117
#define RxRestoreExceptionNoBreakpointFlag(R, F)
Definition: rxcontx.h:358
#define RX_TOPLEVELIRP_CONTEXT_SIGNATURE
Definition: rxcontx.h:4
@ RX_CONTEXT_FLAG_RECURSIVE_CALL
Definition: rxcontx.h:285
@ RX_CONTEXT_FLAG_CREATE_MAILSLOT
Definition: rxcontx.h:291
@ RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED
Definition: rxcontx.h:302
@ RX_CONTEXT_FLAG_CANCELLED
Definition: rxcontx.h:300
@ RX_CONTEXT_FLAG_FSP_DELAYED_OVERFLOW_QUEUE
Definition: rxcontx.h:296
@ RX_CONTEXT_FLAG_WRITE_THROUGH
Definition: rxcontx.h:283
@ RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING
Definition: rxcontx.h:309
@ RX_CONTEXT_FLAG_IN_FSP
Definition: rxcontx.h:290
@ RX_CONTEXT_FLAG_NO_COMPLETE_FROM_FSP
Definition: rxcontx.h:294
@ RX_CONTEXT_FLAG_WAIT
Definition: rxcontx.h:282
@ RX_CONTEXT_FLAG_DEFERRED_WRITE
Definition: rxcontx.h:287
@ RX_CONTEXT_FLAG_ASYNC_OPERATION
Definition: rxcontx.h:293
@ RX_CONTEXT_FLAG_MAILSLOT_REPARSE
Definition: rxcontx.h:292
@ RX_CONTEXT_FLAG_FSP_CRITICAL_OVERFLOW_QUEUE
Definition: rxcontx.h:297
@ RXCONTEXT_FLAG4LOWIO_THIS_READ_ENLARGED
Definition: rxcontx.h:335
@ RXCONTEXT_FLAG4LOWIO_READAHEAD
Definition: rxcontx.h:334
@ RXCONTEXT_FLAG4LOWIO_PIPE_OPERATION
Definition: rxcontx.h:332
@ RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION
Definition: rxcontx.h:333
@ RXCONTEXT_FLAG4LOWIO_THIS_IO_BUFFERED
Definition: rxcontx.h:336
FAST_MUTEX RxContextPerFileSerializationMutex
Definition: rxce.c:146
VOID NTAPI RxResumeBlockedOperations_Serially(_Inout_ PRX_CONTEXT RxContext, _Inout_ PLIST_ENTRY BlockingIoQ)
struct _RX_TOPLEVELIRP_CONTEXT * PRX_TOPLEVELIRP_CONTEXT
VOID NTAPI RxReinitializeContext(_Inout_ PRX_CONTEXT RxContext)
VOID RxRemoveOperationFromBlockingQueue(_Inout_ PRX_CONTEXT RxContext)
VOID NTAPI RxDereferenceAndDeleteRxContext_Real(_In_ PRX_CONTEXT RxContext)
#define MINIRDR_CALL_THROUGH(STATUS, DISPATCH, FUNC, ARGLIST)
Definition: rxcontx.h:375
#define MINIRDR_CALL(STATUS, CONTEXT, DISPATCH, FUNC, ARGLIST)
Definition: rxcontx.h:389
#define RxSaveAndSetExceptionNoBreakpointFlag(R, F)
Definition: rxcontx.h:357
#define RxItsTheSameContext()
Definition: rxcontx.h:370
VOID RxCancelBlockingOperation(_Inout_ PRX_CONTEXT RxContext)
#define RxInitializeTopLevelIrpContext(a, b, c)
Definition: rxcontx.h:38
#define RxDereferenceAndDeleteRxContext(RXCONTEXT)
Definition: rxcontx.h:514
@ RX_CONTEXT_CREATE_FLAG_UNC_NAME
Definition: rxcontx.h:324
@ RX_CONTEXT_CREATE_FLAG_REPARSE
Definition: rxcontx.h:327
@ RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH
Definition: rxcontx.h:325
PRX_CONTEXT NTAPI RxCreateRxContext(_In_ PIRP Irp, _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, _In_ ULONG InitialContextFlags)
LIST_ENTRY RxSrvCalldownList
Definition: rxce.c:122
#define RX_DIRCTL_POOLTAG
Definition: rxpooltg.h:20
#define RX_IRPC_POOLTAG
Definition: rxpooltg.h:11
#define RX_MISC_POOLTAG
Definition: rxpooltg.h:10
#define RxDumpWantedAccess(w1, w2, wlt, DA, DSA)
Definition: rxprocs.h:526
#define RxDumpCurrentAccess(w1, w2, wlt, SA)
Definition: rxprocs.h:527
#define RxIsFcbAcquiredExclusive(Fcb)
Definition: rxprocs.h:229
PVOID RxMapSystemBuffer(_In_ PRX_CONTEXT RxContext)
VOID NTAPI RxNoOpRelease(_In_ PVOID Fcb)
#define RxAcquireSharedFcb(R, F)
Definition: rxprocs.h:162
#define RxIsFcbAcquiredShared(Fcb)
Definition: rxprocs.h:228
VOID RxProcessChangeBufferingStateRequestsForSrvOpen(PSRV_OPEN SrvOpen)
Definition: rxce.c:6655
#define RxAcquireExclusiveFcb(R, F)
Definition: rxprocs.h:154
#define RxAcquirePagingIoResourceShared(RxContext, Fcb, Flag)
Definition: rxprocs.h:242
VOID RxCompleteRequest_Real(_In_ PRX_CONTEXT RxContext, _In_ PIRP Irp, _In_ NTSTATUS Status)
#define RxSetShareAccess(a1, a2, a3, a4, a5, a6)
Definition: rxprocs.h:580
enum _RX_NAME_CONJURING_METHODS RX_NAME_CONJURING_METHODS
@ VNetRoot_As_DriveLetter
Definition: rxprocs.h:82
@ VNetRoot_As_Prefix
Definition: rxprocs.h:80
@ VNetRoot_As_UNC_Name
Definition: rxprocs.h:81
VOID NTAPI RxReleaseFcbFromReadAhead(_In_ PVOID Null)
NTSTATUS RxFindOrConstructVirtualNetRoot(_In_ PRX_CONTEXT RxContext, _In_ PUNICODE_STRING CanonicalName, _In_ NET_ROOT_TYPE NetRootType, _In_ PUNICODE_STRING RemainingName)
#define RxReleasePagingIoResource(RxContext, Fcb)
Definition: rxprocs.h:268
NTSTATUS NTAPI RxChangeBufferingState(PSRV_OPEN SrvOpen, PVOID Context, BOOLEAN ComputeNewState)
Definition: rxce.c:783
#define RxReleaseFcb(R, F)
Definition: rxprocs.h:186
BOOLEAN NTAPI RxAcquireFcbForReadAhead(_In_ PVOID Null, _In_ BOOLEAN Wait)
#define RxCheckShareAccess(a1, a2, a3, a4, a5, a6, a7)
Definition: rxprocs.h:578
#define RxCompleteAsynchronousRequest(C, S)
Definition: rxprocs.h:386
#define RxUpdateShareAccess(a1, a2, a3, a4)
Definition: rxprocs.h:581
#define RX_GET_MRX_FCB(F)
Definition: rxprocs.h:157
VOID RxOrphanThisFcb(_In_ PFCB Fcb)
#define RxTrackerUpdateHistory(R, F, O, L, F, S)
Definition: rxprocs.h:218
BOOLEAN NTAPI RxNoOpAcquire(_In_ PVOID Fcb, _In_ BOOLEAN Wait)
BOOLEAN NTAPI RxAcquireFcbForLazyWrite(_In_ PVOID Null, _In_ BOOLEAN Wait)
#define RxReleasePagingIoResourceForThread(RxContext, Fcb, Thread)
Definition: rxprocs.h:276
#define RxAcquirePagingIoResource(RxContext, Fcb)
Definition: rxprocs.h:233
NTSTATUS RxCompleteRequest(_In_ PRX_CONTEXT pContext, _In_ NTSTATUS Status)
PVOID RxNull
Definition: rxce.c:118
#define RxReleaseFcbForThread(R, F, T)
Definition: rxprocs.h:205
#define RxLogFailure(DO, Originator, Event, Status)
Definition: rxprocs.h:11
#define RxConvertToSharedFcb(R, F)
Definition: rxprocs.h:337
#define RxAcquireSharedFcbWaitForEx(R, F)
Definition: rxprocs.h:168
VOID RxLockUserBuffer(_In_ PRX_CONTEXT RxContext, _In_ LOCK_OPERATION Operation, _In_ ULONG BufferLength)
#define RxRemoveShareAccess(a1, a2, a3, a4)
Definition: rxprocs.h:579
VOID NTAPI RxReleaseFcbFromLazyWrite(_In_ PVOID Null)
RX_SPIN_LOCK RxStrucSupSpinLock
Definition: rxce.c:123
struct _RDBSS_DEVICE_OBJECT * PRDBSS_DEVICE_OBJECT
#define RxGetRdbssState(RxDeviceObject)
Definition: rxstruc.h:78
@ LHS_LockNotHeld
Definition: rxstruc.h:20
@ LHS_SharedLockHeld
Definition: rxstruc.h:21
@ LHS_ExclusiveLockHeld
Definition: rxstruc.h:22
@ RDBSS_STARTABLE
Definition: rxstruc.h:52
@ RDBSS_STARTED
Definition: rxstruc.h:53
@ RDBSS_STOP_IN_PROGRESS
Definition: rxstruc.h:54
#define RxSetRdbssState(RxDeviceObject, NewState)
Definition: rxstruc.h:70
NTSTATUS NTAPI RxInitializeRxTimer(VOID)
Definition: rxce.c:4946
#define RxMaximumWorkQueue
Definition: rxtypes.h:6
NTSTATUS RxInitializeMRxDispatcher(_Inout_ PRDBSS_DEVICE_OBJECT pMRxDeviceObject)
NTSTATUS NTAPI RxDispatchToWorkerThread(_In_ PRDBSS_DEVICE_OBJECT pMRxDeviceObject, _In_ WORK_QUEUE_TYPE WorkQueueType, _In_ PRX_WORKERTHREAD_ROUTINE Routine, _In_ PVOID pContext)
NTSTATUS NTAPI RxInitializeDispatcher(VOID)
Definition: rxce.c:4688
VOID RxSynchronizeWithScavenger(_In_ PRX_CONTEXT RxContext)
BOOLEAN RxScavengeRelatedFobxs(_In_ PFCB Fcb)
#define ATTEMPT_FINALIZE_ON_PURGE
Definition: scavengr.h:46
VOID RxMarkFobxOnClose(_In_ PFOBX Fobx)
VOID RxMarkFobxOnCleanup(_In_ PFOBX pFobx, _Out_ PBOOLEAN NeedPurge)
VOID RxScavengeFobxsForNetRoot(PNET_ROOT NetRoot, PFCB PurgingFcb, BOOLEAN SynchronizeWithScavenger)
Definition: rxce.c:7798
#define RxInitializeRdbssScavenger(Scavenger, ScavengerTimeLimit)
Definition: scavengr.h:84
NTSTATUS RxPurgeRelatedFobxs(PNET_ROOT NetRoot, PRX_CONTEXT RxContext, BOOLEAN AttemptFinalization, PFCB PurgingFcb)
Definition: rxce.c:7133
BOOLEAN RxScavengeVNetRoots(_In_ PRDBSS_DEVICE_OBJECT RxDeviceObject)
#define DONT_ATTEMPT_FINALIZE_ON_PURGE
Definition: scavengr.h:45
#define REG_DWORD
Definition: sdbapi.c:596
#define RDBSS_NTC_STORAGE_TYPE_UNKNOWN
Definition: nodetype.h:41
#define RDBSS_NTC_VOLUME_FCB
Definition: nodetype.h:51
#define RDBSS_NTC_STORAGE_TYPE_DIRECTORY
Definition: nodetype.h:42
#define RDBSS_NTC_OPENTARGETDIR_FCB
Definition: nodetype.h:44
#define RDBSS_NTC_DATA_HEADER
Definition: nodetype.h:55
#define RDBSS_NTC_FOBX
Definition: nodetype.h:57
#define RDBSS_NTC_STORAGE_TYPE_FILE
Definition: nodetype.h:43
#define RDBSS_NTC_DEVICE_FCB
Definition: nodetype.h:54
#define RDBSS_NTC_VCB
Definition: nodetype.h:56
#define RDBSS_NTC_MAILSLOT
Definition: nodetype.h:46
#define RDBSS_NTC_SPOOLFILE
Definition: nodetype.h:47
#define RDBSS_NTC_V_NETROOT
Definition: nodetype.h:50
#define NodeTypeIsFcb(FCB)
Definition: nodetype.h:68
#define RxBugCheck(A, B, C)
Definition: nodetype.h:86
#define RDBSS_NTC_IPC_SHARE
Definition: nodetype.h:45
#define S(x)
Definition: test.h:217
BOOLEAN FsRtlCopyRead2(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject, IN PVOID TopLevelContext)
Definition: copysup.c:40
BOOLEAN FsRtlCopyWrite2(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject, IN PVOID TopLevelContext)
Definition: copysup.c:190
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
Definition: section.c:4255
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4356
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ BOOLEAN Read
Definition: strmini.h:479
base of all file and directory entries
Definition: entries.h:83
Definition: ncftp.h:79
Definition: movable.cpp:9
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: setypes.h:235
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: setypes.h:234
PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite
Definition: cctypes.h:39
PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite
Definition: cctypes.h:40
PACQUIRE_FOR_READ_AHEAD AcquireForReadAhead
Definition: cctypes.h:41
PRELEASE_FROM_READ_AHEAD ReleaseFromReadAhead
Definition: cctypes.h:42
LONG NameContextType
Definition: dfs.h:14
PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo
Definition: iotypes.h:1738
PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey
Definition: iotypes.h:1742
PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush
Definition: iotypes.h:1760
PFAST_IO_WRITE FastIoWrite
Definition: iotypes.h:1736
PFAST_IO_UNLOCK_ALL FastIoUnlockAll
Definition: iotypes.h:1741
PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush
Definition: iotypes.h:1759
ULONG SizeOfFastIoDispatch
Definition: iotypes.h:1733
PFAST_IO_DEVICE_CONTROL FastIoDeviceControl
Definition: iotypes.h:1743
PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection
Definition: iotypes.h:1744
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1735
PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo
Definition: iotypes.h:1737
PFAST_IO_LOCK FastIoLock
Definition: iotypes.h:1739
PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle
Definition: iotypes.h:1740
PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection
Definition: iotypes.h:1745
PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible
Definition: iotypes.h:1734
Definition: cdstruc.h:902
LONGLONG CreationTime
Definition: cdstruc.h:1030
RX_BLOCK_CONDITION Condition
Definition: fcb.h:147
union _FCB::@719 Specific
ULONG NumberOfLinks
Definition: fcb.h:156
SHARE_ACCESS ShareAccess
Definition: cdstruc.h:1009
PRX_FSD_DISPATCH_VECTOR PrivateDispatchVector
Definition: fcb.h:148
ULONG ulFileSizeVersion
Definition: fcb.h:164
PMINIRDR_DISPATCH MRxDispatch
Definition: fcb.h:150
struct _FCB::@719::@722 Fcb
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:922
CLONG OpenCount
Definition: fatstruc.h:881
PV_NET_ROOT VNetRoot
Definition: fcb.h:139
CLONG UncleanCount
Definition: fatstruc.h:873
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG FcbState
Definition: cdstruc.h:971
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:921
PRDBSS_DEVICE_OBJECT RxDeviceObject
Definition: fcb.h:149
LARGE_INTEGER LastChangeTime
Definition: fcb.h:160
RX_FCB_TABLE_ENTRY FcbTableEntry
Definition: fcb.h:144
PNON_PAGED_FCB NonPaged
Definition: fatstruc.h:811
FSRTL_ADVANCED_FCB_HEADER spacer
Definition: fcb.h:135
SHARE_ACCESS ShareAccessPerSrvOpens
Definition: fcb.h:155
PNET_ROOT NetRoot
Definition: fcb.h:136
PFILE_OBJECT FileObject
Definition: ntfs.h:520
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
LARGE_INTEGER CreationTime
Definition: nt_native.h:939
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
Definition: fcb.h:305
MRX_PIPE_HANDLE_INFORMATION PipeHandleInformation
Definition: fcb.h:330
struct _FOBX::@1953::@1956 NamedPipe
BOOLEAN ContainsWildCards
Definition: fcb.h:321
PSRV_OPEN SrvOpen
Definition: fcb.h:312
union _FOBX::@1953 Specific
struct _FOBX::@1953::@1957 DiskFile
PACCESS_STATE AccessState
Definition: iotypes.h:2867
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: iotypes.h:2866
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2868
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
union _LOWIO_CONTEXT::@2060 ParamsFor
struct _LOWIO_CONTEXT::@2060::@2061 ReadWrite
ERESOURCE_THREAD ResourceThreadId
Definition: mrx.h:285
PERESOURCE Resource
Definition: mrx.h:284
USHORT Flags
Definition: mrx.h:282
struct _LOWIO_CONTEXT::@2060::@2063 NotifyChangeDirectory
ULONG MRxFlags
Definition: mrx.h:341
PMRX_CALLDOWN MRxShouldTryToCollapseThisOpen
Definition: mrx.h:353
ULONG NumberOfOpens
Definition: mrxfcb.h:97
Definition: fcb.h:34
RX_FCB_TABLE FcbTable
Definition: fcb.h:54
KEVENT TheActualEvent
Definition: fcb.h:94
PKEVENT OutstandingAsyncEvent
Definition: fatstruc.h:743
ULONG OutstandingAsyncWrites
Definition: fatstruc.h:737
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: fatstruc.h:729
PIO_SECURITY_CONTEXT SecurityContext
LONG NumberOfMinirdrsRegistered
Definition: rxstruc.h:33
ERESOURCE Resource
Definition: rxstruc.h:39
PDRIVER_OBJECT DriverObject
Definition: rxstruc.h:29
PEPROCESS OurProcess
Definition: rxstruc.h:34
NODE_BYTE_SIZE NodeByteSize
Definition: rxstruc.h:28
NODE_TYPE_CODE NodeTypeCode
Definition: rxstruc.h:27
FAST_MUTEX MinirdrRegistrationMutex
Definition: rxstruc.h:31
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: rxstruc.h:35
volatile LONG NumberOfMinirdrsStarted
Definition: rxstruc.h:30
CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks
Definition: rxstruc.h:37
LIST_ENTRY RegisteredMiniRdrs
Definition: rxstruc.h:32
LONG OverflowQueueCount[RxMaximumWorkQueue]
Definition: rxstruc.h:120
volatile ULONG RandomReadOperations
Definition: rxstruc.h:109
ULONG NetworkProviderPriority
Definition: rxstruc.h:91
volatile ULONG WriteOperations
Definition: rxstruc.h:115
PMINIRDR_DISPATCH Dispatch
Definition: rxstruc.h:89
LIST_ENTRY OverflowQueue[RxMaximumWorkQueue]
Definition: rxstruc.h:121
BOOLEAN RegisterMailSlotProvider
Definition: rxstruc.h:94
volatile ULONG ReadOperations
Definition: rxstruc.h:107
volatile ULONG RandomWriteOperations
Definition: rxstruc.h:117
RDBSS_SCAVENGER RdbssScavengerInDeviceObject
Definition: rxstruc.h:130
PRDBSS_SCAVENGER pRdbssScavenger
Definition: rxstruc.h:129
LARGE_INTEGER NonPagingWriteBytesRequested
Definition: rxstruc.h:111
PRDBSS_EXPORTS RdbssExports
Definition: rxstruc.h:87
RX_PREFIX_TABLE RxNetNameTableInDeviceObject
Definition: rxstruc.h:128
LARGE_INTEGER PagingWriteBytesRequested
Definition: rxstruc.h:110
LARGE_INTEGER CacheReadBytesRequested
Definition: rxstruc.h:104
PDEVICE_OBJECT RDBSSDeviceObject
Definition: rxstruc.h:88
RX_SPIN_LOCK OverflowQueueSpinLock
Definition: rxstruc.h:122
volatile LONG PostedRequestCount[RxMaximumWorkQueue]
Definition: rxstruc.h:119
PRX_PREFIX_TABLE pRxNetNameTable
Definition: rxstruc.h:127
LARGE_INTEGER PagingReadBytesRequested
Definition: rxstruc.h:102
PKEVENT pAsynchronousRequestsCompletionEvent
Definition: rxstruc.h:124
LARGE_INTEGER NonPagingReadBytesRequested
Definition: rxstruc.h:103
ULONG RegistrationControls
Definition: rxstruc.h:86
BOOLEAN RegisterUncProvider
Definition: rxstruc.h:93
LARGE_INTEGER NetworkReadBytesRequested
Definition: rxstruc.h:106
LARGE_INTEGER CacheWriteBytesRequested
Definition: rxstruc.h:112
UNICODE_STRING DeviceName
Definition: rxstruc.h:90
LIST_ENTRY MiniRdrListLinks
Definition: rxstruc.h:97
PRX_SPIN_LOCK pRxStrucSupSpinLock
Definition: rxstruc.h:14
LIST_ENTRY OverflowListEntry
Definition: rxcontx.h:150
ULONG Flags
Definition: rxcontx.h:124
BOOLEAN FcbResourceAcquired
Definition: rxcontx.h:125
PWCH AlsoCanonicalNameBuffer
Definition: rxcontx.h:267
PIRP CurrentIrp
Definition: rxcontx.h:110
PMRX_CALLDOWN MRxCancelRoutine
Definition: rxcontx.h:147
BOOLEAN PostRequest
Definition: rxcontx.h:108
LOWIO_CONTEXT LowIoContext
Definition: rxcontx.h:263
struct _RX_CONTEXT::@2143::@2156 QueryDirectory
PRX_DISPATCH ResumeRoutine
Definition: rxcontx.h:148
PETHREAD LastExecutionThread
Definition: rxcontx.h:118
PMRX_FOBX pFobx
Definition: rxcontx.h:113
volatile ULONG ReferenceCount
Definition: rxcontx.h:103
UCHAR MajorFunction
Definition: rxcontx.h:105
FILE_INFORMATION_CLASS FileInformationClass
Definition: rxcontx.h:162
IO_STATUS_BLOCK IoStatusBlock
Definition: rxcontx.h:139
PIO_STACK_LOCATION CurrentIrpSp
Definition: rxcontx.h:111
ULONG SerialNumber
Definition: rxcontx.h:122
ULONG FlagsForLowIo
Definition: rxcontx.h:262
UCHAR MinorFunction
Definition: rxcontx.h:106
struct _RX_CONTEXT::@2143::@2155 Create
PRDBSS_DEVICE_OBJECT RxDeviceObject
Definition: rxcontx.h:116
PMRX_SRV_OPEN pRelevantSrvOpen
Definition: rxcontx.h:114
struct _RX_CONTEXT::@2141::@2149 Info
LONG Length
Definition: rxcontx.h:167
PMRX_FCB pFcb
Definition: rxcontx.h:112
BOOLEAN FcbPagingIoResourceAcquired
Definition: rxcontx.h:126
UNICODE_STRING Path
Definition: fcbtable.h:8
volatile ULONG Version
Definition: fcbtable.h:19
PRX_FSD_DISPATCH CommonRoutine
Definition: rdbss.c:47
UNICODE_STRING Prefix
Definition: prefix.h:53
BOOLEAN IsNetNameTable
Definition: prefix.h:70
LIST_ENTRY ListEntry
Definition: rxcontx.h:13
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
ULONG OpenCount
Definition: iotypes.h:525
Definition: fcb.h:10
volatile LONG NumberOfCloseDelayedFiles
Definition: fcb.h:23
Definition: fcb.h:261
NTSTATUS OpenStatus
Definition: fcb.h:286
LIST_ENTRY FobxList
Definition: fcb.h:279
RX_BLOCK_CONDITION Condition
Definition: fcb.h:275
void * Buffer
Definition: sprintf.c:453
USHORT MaximumLength
Definition: env_spec_w32.h:370
PNET_ROOT NetRoot
Definition: fcb.h:65
UNICODE_STRING NamePrefix
Definition: fcb.h:73
RX_PREFIX_ENTRY PrefixEntry
Definition: fcb.h:72
volatile LONG AdditionalReferenceForDeleteFsctlTaken
Definition: fcb.h:71
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: subject.c:85
#define LL
Definition: tui.h:167
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
INT POOL_TYPE
Definition: typedefs.h:78
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
static const unsigned short IsPipe
Definition: typegen.c:75
#define STATUS_RETRY
Definition: udferr_usr.h:182
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
NTSTATUS NTAPI FsRtlRegisterUncProvider(OUT PHANDLE Handle, IN PCUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported)
Definition: unc.c:280
LONGLONG QuadPart
Definition: typedefs.h:114
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
Definition: vmhorizon.c:15
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
_In_ WDFDEVICE _In_ ULONG DeviceCharacteristics
Definition: wdfdevice.h:2775
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_opt_ PWDF_USB_PIPE_INFORMATION PipeInfo
Definition: wdfusb.h:2543
char * PSZ
Definition: windef.h:57
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
VOID(NTAPI * PCC_POST_DEFERRED_WRITE)(_In_ PVOID Context1, _In_ PVOID Context2)
Definition: cctypes.h:66
#define ExInterlockedAddLargeStatistic(Addend, Increment)
Definition: exfuncs.h:850
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
enum _WORK_QUEUE_TYPE WORK_QUEUE_TYPE
@ DelayedWorkQueue
Definition: extypes.h:190
@ CriticalWorkQueue
Definition: extypes.h:189
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST NPAGED_LOOKASIDE_LIST
_In_ ULONG DesiredShareAccess
Definition: iofuncs.h:781
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define FO_NAMED_PIPE
Definition: iotypes.h:1782
#define IO_TYPE_IRP
#define IRP_MJ_QUERY_EA
#define SL_WATCH_TREE
Definition: iotypes.h:1839
@ ReadAccess
Definition: iotypes.h:424
@ WriteAccess
Definition: iotypes.h:425
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1837
#define IRP_MJ_CREATE_NAMED_PIPE
#define IRP_MJ_CREATE_MAILSLOT
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1791
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_PAGING_IO
#define IRP_MJ_SET_VOLUME_INFORMATION
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1795
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define IRP_MN_REMOVE_DEVICE
#define POOL_COLD_ALLOCATION
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1836
DRIVER_DISPATCH * PDRIVER_DISPATCH
Definition: iotypes.h:2262
#define IRP_MJ_QUERY_SECURITY
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
#define IRP_MJ_SET_EA
#define IRP_MJ_SYSTEM_CONTROL
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MN_MDL
Definition: iotypes.h:4419
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1789
#define IRP_MJ_FLUSH_BUFFERS
#define IOCTL_LMR_ARE_FILE_OBJECTS_ON_SAME_SERVER
Definition: iotypes.h:7253
#define IRP_MN_DPC
Definition: iotypes.h:4418
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define SL_WRITE_THROUGH
Definition: iotypes.h:1824
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_MJ_SET_SECURITY
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1818
#define SL_RESTART_SCAN
Definition: iotypes.h:1835
#define IRP_NOCACHE
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
#define IRP_MJ_CLEANUP
#define IRP_MJ_MAXIMUM_FUNCTION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Executive
Definition: ketypes.h:415
enum _LOCK_OPERATION LOCK_OPERATION
@ IoReadAccess
Definition: ketypes.h:863
@ IoWriteAccess
Definition: ketypes.h:864
@ IoModifyAccess
Definition: ketypes.h:865
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1630
#define SeQuerySubjectContextToken(SubjectContext)
Definition: sefuncs.h:583
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180