3 * Copyright (C) 2017 ReactOS Team
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.
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.
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.
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)
27 /* INCLUDES *****************************************************************/
30 #include <pseh/pseh2.h>
37 #define RX_TOPLEVELCTX_FLAG_FROM_POOL 1
41 (NTAPI
*PRX_FSD_DISPATCH
) (
44 typedef struct _RX_FSD_DISPATCH_VECTOR
46 PRX_FSD_DISPATCH CommonRoutine
;
47 } RX_FSD_DISPATCH_VECTOR
, *PRX_FSD_DISPATCH_VECTOR
;
51 RxAcquireFileForNtCreateSection(
52 PFILE_OBJECT FileObject
);
57 PFILE_OBJECT FileObject
,
58 PDEVICE_OBJECT DeviceObject
);
61 RxAddToTopLevelIrpAllocatedContextsList(
62 PRX_TOPLEVELIRP_CONTEXT TopLevelContext
);
88 RxCommonDevFCBCleanup(
104 PRX_CONTEXT Context
);
108 RxCommonDevFCBQueryVolInfo(
109 PRX_CONTEXT Context
);
113 RxCommonDeviceControl(
114 PRX_CONTEXT Context
);
118 RxCommonDirectoryControl(
119 PRX_CONTEXT Context
);
123 RxCommonDispatchProblem(
124 PRX_CONTEXT Context
);
128 RxCommonFileSystemControl(
129 PRX_CONTEXT Context
);
133 RxCommonFlushBuffers(
134 PRX_CONTEXT Context
);
139 PRX_CONTEXT Context
);
144 PRX_CONTEXT Context
);
148 RxCommonQueryInformation(
149 PRX_CONTEXT Context
);
153 RxCommonQueryQuotaInformation(
154 PRX_CONTEXT Context
);
158 RxCommonQuerySecurity(
159 PRX_CONTEXT Context
);
163 RxCommonQueryVolumeInformation(
164 PRX_CONTEXT Context
);
169 PRX_CONTEXT Context
);
174 PRX_CONTEXT Context
);
178 RxCommonSetInformation(
179 PRX_CONTEXT Context
);
183 RxCommonSetQuotaInformation(
184 PRX_CONTEXT Context
);
189 PRX_CONTEXT Context
);
193 RxCommonSetVolumeInformation(
194 PRX_CONTEXT Context
);
198 RxCommonUnimplemented(
199 PRX_CONTEXT Context
);
204 PRX_CONTEXT Context
);
207 RxCopyCreateParameters(
208 IN PRX_CONTEXT RxContext
);
213 PUNICODE_STRING NetRootName
);
217 IN PRX_CONTEXT RxContext
);
221 RxFastIoCheckIfPossible(
222 PFILE_OBJECT FileObject
,
223 PLARGE_INTEGER FileOffset
,
224 ULONG Length
, BOOLEAN Wait
,
225 ULONG LockKey
, BOOLEAN CheckForReadOperation
,
226 PIO_STATUS_BLOCK IoStatus
,
227 PDEVICE_OBJECT DeviceObject
);
231 RxFastIoDeviceControl(
232 PFILE_OBJECT FileObject
,
234 PVOID InputBuffer OPTIONAL
,
235 ULONG InputBufferLength
,
236 PVOID OutputBuffer OPTIONAL
,
237 ULONG OutputBufferLength
,
239 PIO_STATUS_BLOCK IoStatus
,
240 PDEVICE_OBJECT DeviceObject
);
245 PFILE_OBJECT FileObject
,
246 PLARGE_INTEGER FileOffset
,
251 PIO_STATUS_BLOCK IoStatus
,
252 PDEVICE_OBJECT DeviceObject
);
257 PFILE_OBJECT FileObject
,
258 PLARGE_INTEGER FileOffset
,
263 PIO_STATUS_BLOCK IoStatus
,
264 PDEVICE_OBJECT DeviceObject
);
268 PRX_CONTEXT RxContext
,
269 PUNICODE_STRING NetRootName
);
273 PRX_CONTEXT RxContext
,
274 PUNICODE_STRING FileName
,
275 PUNICODE_STRING CanonicalName
,
276 PNET_ROOT_TYPE NetRootType
);
279 RxFreeCanonicalNameBuffer(
280 PRX_CONTEXT Context
);
289 RxGetRegistryParameters(
290 IN PUNICODE_STRING RegistryPath
);
294 RxGetStringRegistryParameter(
297 OUT PUNICODE_STRING OutString
,
299 IN ULONG BufferLength
,
300 IN BOOLEAN LogFailure
);
304 RxInitializeDebugSupport(
309 RxInitializeDispatchVectors(
310 PDRIVER_OBJECT DriverObject
);
314 RxInitializeRegistrationStructures(
319 RxInitializeTopLevelIrpPackage(
325 PDRIVER_OBJECT DriverObject
,
329 RxIsThisAnRdbssTopLevelContext(
330 PRX_TOPLEVELIRP_CONTEXT TopLevelContext
);
334 RxLowIoIoCtlShellCompletion(
335 PRX_CONTEXT RxContext
);
339 PRX_CONTEXT RxContext
);
343 RxLowIoReadShellCompletion(
344 PRX_CONTEXT RxContext
);
348 PRX_CONTEXT RxContext
);
351 RxNotifyChangeDirectory(
352 PRX_CONTEXT RxContext
);
356 PRX_CONTEXT RxContext
,
357 FILE_INFORMATION_CLASS FileInfoClass
,
361 RxQueryAlternateNameInfo(
362 PRX_CONTEXT RxContext
,
363 PFILE_NAME_INFORMATION AltNameInfo
);
367 PRX_CONTEXT RxContext
,
368 PFILE_BASIC_INFORMATION BasicInfo
);
371 RxQueryCompressedInfo(
372 PRX_CONTEXT RxContext
,
373 PFILE_COMPRESSION_INFORMATION CompressionInfo
);
377 PRX_CONTEXT RxContext
);
381 PRX_CONTEXT RxContext
,
382 PFILE_EA_INFORMATION EaInfo
);
386 PRX_CONTEXT RxContext
,
387 PFILE_INTERNAL_INFORMATION InternalInfo
);
391 PRX_CONTEXT RxContext
,
392 PFILE_NAME_INFORMATION NameInfo
);
396 PRX_CONTEXT RxContext
,
397 PFILE_PIPE_INFORMATION PipeInfo
);
401 PRX_CONTEXT RxContext
,
402 PFILE_POSITION_INFORMATION PositionInfo
);
406 PRX_CONTEXT RxContext
,
407 PFILE_STANDARD_INFORMATION StandardInfo
);
411 RxReadRegistryParameters(
416 RxReleaseFileForNtCreateSection(
417 PFILE_OBJECT FileObject
);
422 PFILE_OBJECT FileObject
,
423 PDEVICE_OBJECT DeviceObject
);
426 RxRemoveOverflowEntry(
427 PRDBSS_DEVICE_OBJECT DeviceObject
,
428 WORK_QUEUE_TYPE Queue
);
431 RxSearchForCollapsibleOpen(
432 PRX_CONTEXT RxContext
,
433 ACCESS_MASK DesiredAccess
,
437 RxSetupNetFileObject(
438 PRX_CONTEXT RxContext
);
442 IN PRDBSS_DEVICE_OBJECT RxDeviceObject
,
446 RxUninitializeCacheMap(
447 PRX_CONTEXT RxContext
,
448 PFILE_OBJECT FileObject
,
449 PLARGE_INTEGER TruncateSize
);
454 PRDBSS_DEVICE_OBJECT DeviceObject
);
457 RxXXXControlFileCallthru(
458 PRX_CONTEXT Context
);
462 _RxAllocatePoolWithTag(
463 _In_ POOL_TYPE PoolType
,
464 _In_ SIZE_T NumberOfBytes
,
478 WCHAR RxStarForTemplate
= '*';
479 WCHAR Rx8QMdot3QM
[] = L
">>>>>>>>.>>>*";
480 BOOLEAN DisableByteRangeLockingOnReadOnlyFiles
= FALSE
;
481 BOOLEAN DisableFlushOnCleanup
= FALSE
;
482 ULONG ReadAheadGranularity
= 1 << PAGE_SHIFT
;
483 LIST_ENTRY RxActiveContexts
;
484 NPAGED_LOOKASIDE_LIST RxContextLookasideList
;
485 FAST_MUTEX RxContextPerFileSerializationMutex
;
488 RX_FSD_DISPATCH_VECTOR RxDeviceFCBVector
[IRP_MJ_MAXIMUM_FUNCTION
+ 1] =
490 { RxCommonDispatchProblem
},
491 { RxCommonDispatchProblem
},
492 { RxCommonDevFCBClose
},
493 { RxCommonDispatchProblem
},
494 { RxCommonDispatchProblem
},
495 { RxCommonDispatchProblem
},
496 { RxCommonDispatchProblem
},
497 { RxCommonDispatchProblem
},
498 { RxCommonDispatchProblem
},
499 { RxCommonDispatchProblem
},
500 { RxCommonDevFCBQueryVolInfo
},
501 { RxCommonDispatchProblem
},
502 { RxCommonDispatchProblem
},
503 { RxCommonDevFCBFsCtl
},
504 { RxCommonDevFCBIoCtl
},
505 { RxCommonDevFCBIoCtl
},
506 { RxCommonDispatchProblem
},
507 { RxCommonDispatchProblem
},
508 { RxCommonDevFCBCleanup
},
509 { RxCommonDispatchProblem
},
510 { RxCommonDispatchProblem
},
511 { RxCommonDispatchProblem
},
512 { RxCommonUnimplemented
},
513 { RxCommonUnimplemented
},
514 { RxCommonUnimplemented
},
515 { RxCommonUnimplemented
},
516 { RxCommonUnimplemented
},
517 { RxCommonUnimplemented
},
519 RDBSS_EXPORTS RxExports
;
520 FAST_IO_DISPATCH RxFastIoDispatch
;
521 PRDBSS_DEVICE_OBJECT RxFileSystemDeviceObject
;
522 RX_FSD_DISPATCH_VECTOR RxFsdDispatchVector
[IRP_MJ_MAXIMUM_FUNCTION
+ 1] =
525 { RxCommonUnimplemented
},
529 { RxCommonQueryInformation
},
530 { RxCommonSetInformation
},
533 { RxCommonFlushBuffers
},
534 { RxCommonQueryVolumeInformation
},
535 { RxCommonSetVolumeInformation
},
536 { RxCommonDirectoryControl
},
537 { RxCommonFileSystemControl
},
538 { RxCommonDeviceControl
},
539 { RxCommonDeviceControl
},
540 { RxCommonUnimplemented
},
541 { RxCommonLockControl
},
543 { RxCommonUnimplemented
},
544 { RxCommonQuerySecurity
},
545 { RxCommonSetSecurity
},
546 { RxCommonUnimplemented
},
547 { RxCommonUnimplemented
},
548 { RxCommonUnimplemented
},
549 { RxCommonQueryQuotaInformation
},
550 { RxCommonSetQuotaInformation
},
551 { RxCommonUnimplemented
},
553 ULONG RxFsdEntryCount
;
554 LIST_ENTRY RxIrpsList
;
555 KSPIN_LOCK RxIrpsListSpinLock
;
556 KMUTEX RxScavengerMutex
;
557 KMUTEX RxSerializationMutex
;
558 UCHAR RxSpaceForTheWrappersDeviceObject
[sizeof(*RxFileSystemDeviceObject
)];
559 KSPIN_LOCK TopLevelIrpSpinLock
;
560 LIST_ENTRY TopLevelIrpAllocatedContextsList
;
561 BOOLEAN RxForceQFIPassThrough
= FALSE
;
563 DECLARE_CONST_UNICODE_STRING(unknownId
, L
"???");
570 #define ASSERT(exp) \
573 RxAssert(#exp, __FILE__, __LINE__, NULL); \
578 #undef RxAllocatePool
579 #undef RxAllocatePoolWithTag
582 #define RxAllocatePool(P, S) _RxAllocatePoolWithTag(P, S, 0)
583 #define RxAllocatePoolWithTag _RxAllocatePoolWithTag
584 #define RxFreePool _RxFreePool
585 #define RxFreePoolWithTag _RxFreePoolWithTag
588 /* FUNCTIONS ****************************************************************/
591 CheckForLoudOperations(
592 PRX_CONTEXT RxContext
)
601 __RxInitializeTopLevelIrpContext(
602 IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext
,
604 IN PRDBSS_DEVICE_OBJECT RxDeviceObject
,
607 DPRINT("__RxInitializeTopLevelIrpContext(%p, %p, %p, %u)\n", TopLevelContext
, Irp
, RxDeviceObject
, Flags
);
609 RtlZeroMemory(TopLevelContext
, sizeof(RX_TOPLEVELIRP_CONTEXT
));
610 TopLevelContext
->Irp
= Irp
;
611 TopLevelContext
->Flags
= (Flags
? RX_TOPLEVELCTX_FLAG_FROM_POOL
: 0);
612 TopLevelContext
->Signature
= RX_TOPLEVELIRP_CONTEXT_SIGNATURE
;
613 TopLevelContext
->RxDeviceObject
= RxDeviceObject
;
614 TopLevelContext
->Previous
= IoGetTopLevelIrp();
615 TopLevelContext
->Thread
= PsGetCurrentThread();
617 /* We cannot add to list something that'd come from stack */
618 if (BooleanFlagOn(TopLevelContext
->Flags
, RX_TOPLEVELCTX_FLAG_FROM_POOL
))
620 RxAddToTopLevelIrpAllocatedContextsList(TopLevelContext
);
626 RxAcquireExclusiveFcbResourceInMRx(
627 _Inout_ PMRX_FCB Fcb
)
630 return STATUS_NOT_IMPLEMENTED
;
635 RxAcquireFcbForLazyWrite(
645 RxAcquireFcbForReadAhead(
655 RxAcquireFileForNtCreateSection(
656 PFILE_OBJECT FileObject
)
664 PFILE_OBJECT FileObject
,
665 PDEVICE_OBJECT DeviceObject
)
668 return STATUS_NOT_IMPLEMENTED
;
675 RxAddToTopLevelIrpAllocatedContextsList(
676 PRX_TOPLEVELIRP_CONTEXT TopLevelContext
)
680 DPRINT("RxAddToTopLevelIrpAllocatedContextsList(%p)\n", TopLevelContext
);
682 ASSERT(TopLevelContext
->Signature
== RX_TOPLEVELIRP_CONTEXT_SIGNATURE
);
683 ASSERT(BooleanFlagOn(TopLevelContext
->Flags
, RX_TOPLEVELCTX_FLAG_FROM_POOL
));
685 KeAcquireSpinLock(&TopLevelIrpSpinLock
, &OldIrql
);
686 InsertTailList(&TopLevelIrpAllocatedContextsList
, &TopLevelContext
->ListEntry
);
687 KeReleaseSpinLock(&TopLevelIrpSpinLock
, OldIrql
);
695 IN PRX_CONTEXT RxContext
,
700 WORK_QUEUE_TYPE Queue
;
701 PIO_STACK_LOCATION Stack
;
703 Stack
= RxContext
->CurrentIrpSp
;
704 RxContext
->PostRequest
= FALSE
;
706 /* First of all, select the appropriate queue - delayed for prefix claim, critical for the rest */
707 if (RxContext
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
&&
708 Stack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_REDIR_QUERY_PATH
)
710 Queue
= DelayedWorkQueue
;
711 SetFlag(RxContext
->Flags
, RX_CONTEXT_FLAG_FSP_DELAYED_OVERFLOW_QUEUE
);
715 Queue
= CriticalWorkQueue
;
716 SetFlag(RxContext
->Flags
, RX_CONTEXT_FLAG_FSP_CRITICAL_OVERFLOW_QUEUE
);
719 /* Check for overflow */
720 if (Stack
->FileObject
!= NULL
)
722 KeAcquireSpinLock(&RxFileSystemDeviceObject
->OverflowQueueSpinLock
, &OldIrql
);
724 Queued
= InterlockedIncrement(&RxFileSystemDeviceObject
->PostedRequestCount
[Queue
]);
725 /* In case of an overflow, add the new queued call to the overflow list */
728 InterlockedDecrement(&RxFileSystemDeviceObject
->PostedRequestCount
[Queue
]);
729 InsertTailList(&RxFileSystemDeviceObject
->OverflowQueue
[Queue
], &RxContext
->OverflowListEntry
);
730 ++RxFileSystemDeviceObject
->OverflowQueueCount
[Queue
];
732 KeReleaseSpinLock(&RxFileSystemDeviceObject
->OverflowQueueSpinLock
, OldIrql
);
736 KeReleaseSpinLock(&RxFileSystemDeviceObject
->OverflowQueueSpinLock
, OldIrql
);
739 ExInitializeWorkItem(&RxContext
->WorkQueueItem
, RxFspDispatch
, RxContext
);
740 ExQueueWorkItem((PWORK_QUEUE_ITEM
)&RxContext
->WorkQueueItem
, Queue
);
747 RxAllocateCanonicalNameBuffer(
748 PRX_CONTEXT RxContext
,
749 PUNICODE_STRING CanonicalName
,
750 USHORT CanonicalLength
)
754 DPRINT("RxContext: %p - CanonicalNameBuffer: %p\n", RxContext
, RxContext
->Create
.CanonicalNameBuffer
);
756 /* Context must be free of any already allocated name */
757 ASSERT(RxContext
->Create
.CanonicalNameBuffer
== NULL
);
759 /* Validate string length */
760 if (CanonicalLength
> USHRT_MAX
- 1)
762 CanonicalName
->Buffer
= NULL
;
763 return STATUS_OBJECT_PATH_INVALID
;
766 CanonicalName
->Buffer
= RxAllocatePoolWithTag(PagedPool
| POOL_COLD_ALLOCATION
, CanonicalLength
, RX_MISC_POOLTAG
);
767 if (CanonicalName
->Buffer
== NULL
)
769 return STATUS_INSUFFICIENT_RESOURCES
;
772 CanonicalName
->Length
= 0;
773 CanonicalName
->MaximumLength
= CanonicalLength
;
775 /* Set the two places - they must always be identical */
776 RxContext
->Create
.CanonicalNameBuffer
= CanonicalName
->Buffer
;
777 RxContext
->AlsoCanonicalNameBuffer
= CanonicalName
->Buffer
;
779 return STATUS_SUCCESS
;
785 PDEVICE_OBJECT DeviceObject
,
795 RxCanonicalizeFileNameByServerSpecs(
796 PRX_CONTEXT RxContext
,
797 PUNICODE_STRING NetRootName
)
799 USHORT NextChar
, CurChar
;
804 /* Validate file name is not empty */
805 MaxChars
= NetRootName
->Length
/ sizeof(WCHAR
);
808 return STATUS_MORE_PROCESSING_REQUIRED
;
811 /* Validate name is correct */
812 for (NextChar
= 0, CurChar
= 0; CurChar
+ 1 < MaxChars
; NextChar
= CurChar
+ 1)
816 for (i
= NextChar
+ 1; i
< MaxChars
; ++i
)
818 if (NetRootName
->Buffer
[i
] == '\\' || NetRootName
->Buffer
[i
] == ':')
825 if (CurChar
== NextChar
)
827 if (((NetRootName
->Buffer
[NextChar
] != '\\' && NetRootName
->Buffer
[NextChar
] != ':') || NextChar
== (MaxChars
- 1)) && NetRootName
->Buffer
[NextChar
] != '.')
834 if (CurChar
>= MaxChars
- 1)
839 if (NetRootName
->Buffer
[CurChar
+ 1] != ':')
841 return STATUS_OBJECT_PATH_SYNTAX_BAD
;
846 if (NetRootName
->Buffer
[1] != ':')
848 return STATUS_OBJECT_PATH_SYNTAX_BAD
;
854 if ((CurChar
- NextChar
) == 1)
856 if (NetRootName
->Buffer
[NextChar
+ 2] != '.')
861 if (NetRootName
->Buffer
[NextChar
] == '\\' || NetRootName
->Buffer
[NextChar
] == ':' || NetRootName
->Buffer
[NextChar
] == '.')
863 return STATUS_OBJECT_PATH_SYNTAX_BAD
;
868 if ((CurChar
- NextChar
) != 2 || (NetRootName
->Buffer
[NextChar
] != '\\' && NetRootName
->Buffer
[NextChar
] != ':')
869 || NetRootName
->Buffer
[NextChar
+ 1] != '.')
874 if (NetRootName
->Buffer
[NextChar
+ 2] == '.')
876 return STATUS_OBJECT_PATH_SYNTAX_BAD
;
882 return STATUS_MORE_PROCESSING_REQUIRED
;
886 RxCanonicalizeNameAndObtainNetRoot(
887 PRX_CONTEXT RxContext
,
888 PUNICODE_STRING FileName
,
889 PUNICODE_STRING NetRootName
)
892 NET_ROOT_TYPE NetRootType
;
893 UNICODE_STRING CanonicalName
;
897 NetRootType
= NET_ROOT_WILD
;
899 RtlInitEmptyUnicodeString(NetRootName
, NULL
, 0);
900 RtlInitEmptyUnicodeString(&CanonicalName
, NULL
, 0);
902 /* if not relative opening, just handle the passed name */
903 if (RxContext
->CurrentIrpSp
->FileObject
->RelatedFileObject
== NULL
)
905 Status
= RxFirstCanonicalize(RxContext
, FileName
, &CanonicalName
, &NetRootType
);
906 if (!NT_SUCCESS(Status
))
915 /* Make sure we have a valid FCB and a FOBX */
916 Fcb
= RxContext
->CurrentIrpSp
->FileObject
->RelatedFileObject
->FsContext
;
918 RxContext
->CurrentIrpSp
->FileObject
->RelatedFileObject
->FsContext2
== NULL
)
920 return STATUS_INVALID_PARAMETER
;
923 if (!NodeTypeIsFcb(Fcb
))
925 return STATUS_INVALID_PARAMETER
;
931 /* Get/Create the associated VNetRoot for opening */
932 Status
= RxFindOrConstructVirtualNetRoot(RxContext
, &CanonicalName
, NetRootType
, NetRootName
);
933 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
&&
934 BooleanFlagOn(RxContext
->Flags
, RX_CONTEXT_FLAG_MAILSLOT_REPARSE
))
936 ASSERT(CanonicalName
.Buffer
== RxContext
->Create
.CanonicalNameBuffer
);
938 RxFreeCanonicalNameBuffer(RxContext
);
939 Status
= RxFirstCanonicalize(RxContext
, FileName
, &CanonicalName
, &NetRootType
);
940 if (NT_SUCCESS(Status
))
942 Status
= RxFindOrConstructVirtualNetRoot(RxContext
, &CanonicalName
, NetRootType
, NetRootName
);
946 /* Filename cannot contain wildcards */
947 if (FsRtlDoesNameContainWildCards(NetRootName
))
949 Status
= STATUS_OBJECT_NAME_INVALID
;
952 /* Make sure file name is correct */
953 if (NT_SUCCESS(Status
))
955 Status
= RxCanonicalizeFileNameByServerSpecs(RxContext
, NetRootName
);
958 /* Give the mini-redirector a chance to prepare the name */
959 if (NT_SUCCESS(Status
) || Status
== STATUS_MORE_PROCESSING_REQUIRED
)
961 if (RxContext
->Create
.pNetRoot
!= NULL
)
963 NTSTATUS IgnoredStatus
;
965 MINIRDR_CALL(IgnoredStatus
, RxContext
, RxContext
->Create
.pNetRoot
->pSrvCall
->RxDeviceObject
->Dispatch
,
966 MRxPreparseName
, (RxContext
, NetRootName
));
976 RxChangeBufferingState(
979 BOOLEAN ComputeNewState
)
982 return STATUS_NOT_IMPLEMENTED
;
987 RxCheckFcbStructuresForAlignment(
995 _In_ ACCESS_MASK DesiredAccess
,
996 _In_ ULONG DesiredShareAccess
,
997 _Inout_ PFILE_OBJECT FileObject
,
998 _Inout_ PSHARE_ACCESS ShareAccess
,
1001 _In_ PSZ wherelogtag
)
1005 RxDumpWantedAccess(where
, "", wherelogtag
, DesiredAccess
, DesiredShareAccess
);
1006 RxDumpCurrentAccess(where
, "", wherelogtag
, ShareAccess
);
1008 return IoCheckShareAccess(DesiredAccess
, DesiredShareAccess
, FileObject
, ShareAccess
, Update
);
1015 RxCheckShareAccessPerSrvOpens(
1017 IN ACCESS_MASK DesiredAccess
,
1018 IN ULONG DesiredShareAccess
)
1021 BOOLEAN WriteAccess
;
1022 BOOLEAN DeleteAccess
;
1023 PSHARE_ACCESS ShareAccess
;
1027 ShareAccess
= &Fcb
->ShareAccessPerSrvOpens
;
1029 RxDumpWantedAccess("RxCheckShareAccessPerSrvOpens", "", "RxCheckShareAccessPerSrvOpens", DesiredAccess
, DesiredShareAccess
);
1030 RxDumpCurrentAccess("RxCheckShareAccessPerSrvOpens", "", "RxCheckShareAccessPerSrvOpens", ShareAccess
);
1032 /* Check if any access wanted */
1033 ReadAccess
= (DesiredAccess
& (FILE_READ_DATA
| FILE_EXECUTE
)) != 0;
1034 WriteAccess
= (DesiredAccess
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) != 0;
1035 DeleteAccess
= (DesiredAccess
& DELETE
) != 0;
1037 if (ReadAccess
|| WriteAccess
|| DeleteAccess
)
1039 BOOLEAN SharedRead
= (DesiredShareAccess
& FILE_SHARE_READ
) != 0;
1040 BOOLEAN SharedWrite
= (DesiredShareAccess
& FILE_SHARE_WRITE
) != 0;
1041 BOOLEAN SharedDelete
= (DesiredShareAccess
& FILE_SHARE_DELETE
) != 0;
1043 /* Check whether there's a violation */
1045 (ShareAccess
->SharedRead
< ShareAccess
->OpenCount
)) ||
1047 (ShareAccess
->SharedWrite
< ShareAccess
->OpenCount
)) ||
1049 (ShareAccess
->SharedDelete
< ShareAccess
->OpenCount
)) ||
1050 ((ShareAccess
->Readers
!= 0) && !SharedRead
) ||
1051 ((ShareAccess
->Writers
!= 0) && !SharedWrite
) ||
1052 ((ShareAccess
->Deleters
!= 0) && !SharedDelete
))
1054 return STATUS_SHARING_VIOLATION
;
1058 return STATUS_SUCCESS
;
1062 RxCloseAssociatedSrvOpen(
1064 IN PRX_CONTEXT RxContext OPTIONAL
)
1067 return STATUS_NOT_IMPLEMENTED
;
1074 RxCollapseOrCreateSrvOpen(
1075 PRX_CONTEXT RxContext
)
1082 PIO_STACK_LOCATION Stack
;
1083 ACCESS_MASK DesiredAccess
;
1084 RX_BLOCK_CONDITION FcbCondition
;
1088 DPRINT("RxCollapseOrCreateSrvOpen(%p)\n", RxContext
);
1090 Fcb
= (PFCB
)RxContext
->pFcb
;
1091 ASSERT(RxIsFcbAcquiredExclusive(Fcb
));
1092 ++Fcb
->UncleanCount
;
1094 Stack
= RxContext
->CurrentIrpSp
;
1095 DesiredAccess
= Stack
->Parameters
.Create
.SecurityContext
->DesiredAccess
& FILE_ALL_ACCESS
;
1096 ShareAccess
= Stack
->Parameters
.Create
.ShareAccess
& FILE_SHARE_VALID_FLAGS
;
1098 Disposition
= RxContext
->Create
.NtCreateParameters
.Disposition
;
1100 /* Try to find a reusable SRV_OPEN */
1101 Status
= RxSearchForCollapsibleOpen(RxContext
, DesiredAccess
, ShareAccess
);
1102 if (Status
== STATUS_NOT_FOUND
)
1104 /* If none found, create one */
1105 SrvOpen
= RxCreateSrvOpen((PV_NET_ROOT
)RxContext
->Create
.pVNetRoot
, Fcb
);
1106 if (SrvOpen
== NULL
)
1108 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1112 SrvOpen
->DesiredAccess
= DesiredAccess
;
1113 SrvOpen
->ShareAccess
= ShareAccess
;
1114 Status
= STATUS_SUCCESS
;
1117 RxContext
->pRelevantSrvOpen
= (PMRX_SRV_OPEN
)SrvOpen
;
1119 if (Status
!= STATUS_SUCCESS
)
1121 FcbCondition
= Condition_Bad
;
1125 RxInitiateSrvOpenKeyAssociation(SrvOpen
);
1127 /* Cookie to check the mini-rdr doesn't mess with RX_CONTEXT */
1128 RxContext
->CurrentIrp
->IoStatus
.Information
= 0xABCDEF;
1129 /* Inform the mini-rdr we're handling a create */
1130 MINIRDR_CALL(Status
, RxContext
, Fcb
->MRxDispatch
, MRxCreate
, (RxContext
));
1131 ASSERT(RxContext
->CurrentIrp
->IoStatus
.Information
== 0xABCDEF);
1133 DPRINT("MRxCreate returned: %x\n", Status
);
1134 if (Status
== STATUS_SUCCESS
)
1136 /* In case of overwrite, reset file size */
1137 if (Disposition
== FILE_OVERWRITE
|| Disposition
== FILE_OVERWRITE_IF
)
1139 RxAcquirePagingIoResource(RxContext
, Fcb
);
1140 Fcb
->Header
.AllocationSize
.QuadPart
= 0LL;
1141 Fcb
->Header
.FileSize
.QuadPart
= 0LL;
1142 Fcb
->Header
.ValidDataLength
.QuadPart
= 0LL;
1143 RxContext
->CurrentIrpSp
->FileObject
->SectionObjectPointer
= &Fcb
->NonPaged
->SectionObjectPointers
;
1144 CcSetFileSizes(RxContext
->CurrentIrpSp
->FileObject
, (PCC_FILE_SIZES
)&Fcb
->Header
.AllocationSize
);
1145 RxReleasePagingIoResource(RxContext
, Fcb
);
1149 /* Otherwise, adjust sizes */
1150 RxContext
->CurrentIrpSp
->FileObject
->SectionObjectPointer
= &Fcb
->NonPaged
->SectionObjectPointers
;
1151 if (CcIsFileCached(RxContext
->CurrentIrpSp
->FileObject
))
1153 RxAdjustAllocationSizeforCC(Fcb
);
1155 CcSetFileSizes(RxContext
->CurrentIrpSp
->FileObject
, (PCC_FILE_SIZES
)&Fcb
->Header
.AllocationSize
);
1159 /* Set the IoStatus with information returned by mini-rdr */
1160 RxContext
->CurrentIrp
->IoStatus
.Information
= RxContext
->Create
.ReturnedCreateInformation
;
1162 SrvOpen
->OpenStatus
= Status
;
1163 /* Set SRV_OPEN state - good or bad - depending on whether create succeed */
1164 RxTransitionSrvOpen(SrvOpen
, (Status
== STATUS_SUCCESS
? Condition_Good
: Condition_Bad
));
1166 ASSERT(RxIsFcbAcquiredExclusive(Fcb
));
1168 RxCompleteSrvOpenKeyAssociation(SrvOpen
);
1170 if (Status
== STATUS_SUCCESS
)
1172 if (BooleanFlagOn(Stack
->Parameters
.Create
.Options
, FILE_DELETE_ON_CLOSE
))
1174 ClearFlag(Fcb
->FcbState
, FCB_STATE_COLLAPSING_ENABLED
);
1176 SrvOpen
->CreateOptions
= RxContext
->Create
.NtCreateParameters
.CreateOptions
;
1177 FcbCondition
= Condition_Good
;
1181 FcbCondition
= Condition_Bad
;
1182 RxDereferenceSrvOpen(SrvOpen
, LHS_ExclusiveLockHeld
);
1183 RxContext
->pRelevantSrvOpen
= NULL
;
1185 if (RxContext
->pFobx
!= NULL
)
1187 RxDereferenceNetFobx(RxContext
->pFobx
, LHS_ExclusiveLockHeld
);
1188 RxContext
->pFobx
= NULL
;
1193 /* Set FCB state - good or bad - depending on whether create succeed */
1194 DPRINT("Transitioning FCB %p to condition %lx\n", Fcb
, Fcb
->Condition
);
1195 RxTransitionNetFcb(Fcb
, FcbCondition
);
1197 else if (Status
== STATUS_SUCCESS
)
1199 BOOLEAN IsGood
, ExtraOpen
;
1201 /* A reusable SRV_OPEN was found */
1202 RxContext
->CurrentIrp
->IoStatus
.Information
= FILE_OPENED
;
1205 SrvOpen
= (PSRV_OPEN
)RxContext
->pRelevantSrvOpen
;
1207 IsGood
= (SrvOpen
->Condition
== Condition_Good
);
1208 /* If the SRV_OPEN isn't in a stable situation, wait for it to become stable */
1209 if (!StableCondition(SrvOpen
->Condition
))
1211 RxReferenceSrvOpen(SrvOpen
);
1212 ++SrvOpen
->OpenCount
;
1215 RxReleaseFcb(RxContext
, Fcb
);
1216 RxContext
->Create
.FcbAcquired
= FALSE
;
1218 RxWaitForStableSrvOpen(SrvOpen
, RxContext
);
1220 if (NT_SUCCESS(RxAcquireExclusiveFcb(RxContext
, Fcb
)))
1222 RxContext
->Create
.FcbAcquired
= TRUE
;
1225 IsGood
= (SrvOpen
->Condition
== Condition_Good
);
1228 /* Inform the mini-rdr we do an opening with a reused SRV_OPEN */
1231 MINIRDR_CALL(Status
, RxContext
, Fcb
->MRxDispatch
, MRxCollapseOpen
, (RxContext
));
1233 ASSERT(RxIsFcbAcquiredExclusive(Fcb
));
1237 Status
= SrvOpen
->OpenStatus
;
1242 --SrvOpen
->OpenCount
;
1243 RxDereferenceSrvOpen(SrvOpen
, LHS_ExclusiveLockHeld
);
1247 --Fcb
->UncleanCount
;
1249 DPRINT("Status: %x\n", Status
);
1256 PRX_CONTEXT Context
)
1258 #define BugCheckFileId RDBSS_BUG_CHECK_CLEANUP
1263 PFILE_OBJECT FileObject
;
1267 Fcb
= (PFCB
)Context
->pFcb
;
1268 Fobx
= (PFOBX
)Context
->pFobx
;
1269 DPRINT("RxCommonCleanup(%p); FOBX: %p, FCB: %p\n", Context
, Fobx
, Fcb
);
1271 /* File system closing, it's OK */
1274 if (Fcb
->UncleanCount
> 0)
1276 InterlockedDecrement((volatile long *)&Fcb
->UncleanCount
);
1279 return STATUS_SUCCESS
;
1282 /* Check we have a correct FCB type */
1283 if (NodeType(Fcb
) != RDBSS_NTC_STORAGE_TYPE_FILE
&&
1284 NodeType(Fcb
) != RDBSS_NTC_STORAGE_TYPE_DIRECTORY
&&
1285 NodeType(Fcb
) != RDBSS_NTC_STORAGE_TYPE_UNKNOWN
&&
1286 NodeType(Fcb
) != RDBSS_NTC_SPOOLFILE
)
1288 DPRINT1("Invalid Fcb type for %p\n", Fcb
);
1289 RxBugCheck(Fcb
->Header
.NodeTypeCode
, 0, 0);
1292 FileObject
= Context
->CurrentIrpSp
->FileObject
;
1293 ASSERT(!BooleanFlagOn(FileObject
->Flags
, FO_CLEANUP_COMPLETE
));
1295 RxMarkFobxOnCleanup(Fobx
, &NeedPurge
);
1297 Status
= RxAcquireExclusiveFcb(Context
, Fcb
);
1298 if (!NT_SUCCESS(Status
))
1303 Fobx
->AssociatedFileObject
= NULL
;
1305 /* In case SRV_OPEN used is part of FCB */
1306 if (BooleanFlagOn(Fcb
->FcbState
, FCB_STATE_SRVOPEN_USED
))
1308 ASSERT(Fcb
->UncleanCount
!= 0);
1309 InterlockedDecrement((volatile long *)&Fcb
->UncleanCount
);
1311 if (BooleanFlagOn(FileObject
->Flags
, FO_NO_INTERMEDIATE_BUFFERING
))
1313 --Fcb
->UncachedUncleanCount
;
1316 /* Inform mini-rdr */
1317 MINIRDR_CALL(Status
, Context
, Fcb
->MRxDispatch
, MRxCleanupFobx
, (Context
));
1319 ASSERT(Fobx
->SrvOpen
->UncleanFobxCount
!= 0);
1320 --Fobx
->SrvOpen
->UncleanFobxCount
;
1322 RxUninitializeCacheMap(Context
, FileObject
, NULL
);
1324 RxReleaseFcb(Context
, Fcb
);
1326 return STATUS_SUCCESS
;
1330 return STATUS_NOT_IMPLEMENTED
;
1331 #undef BugCheckFileId
1337 PRX_CONTEXT Context
)
1339 #define BugCheckFileId RDBSS_BUG_CHECK_CLOSE
1343 PFILE_OBJECT FileObject
;
1344 BOOLEAN DereferenceFobx
, AcquiredFcb
;
1348 Fcb
= (PFCB
)Context
->pFcb
;
1349 Fobx
= (PFOBX
)Context
->pFobx
;
1350 FileObject
= Context
->CurrentIrpSp
->FileObject
;
1351 DPRINT("RxCommonClose(%p); FOBX: %p, FCB: %p, FO: %p\n", Context
, Fobx
, Fcb
, FileObject
);
1353 Status
= RxAcquireExclusiveFcb(Context
, Fcb
);
1354 if (!NT_SUCCESS(Status
))
1364 /* Check our FCB type is expected */
1365 if (NodeType(Fcb
) != RDBSS_NTC_STORAGE_TYPE_UNKNOWN
&&
1366 (NodeType(Fcb
) < RDBSS_NTC_STORAGE_TYPE_DIRECTORY
|| (NodeType(Fcb
) > RDBSS_NTC_STORAGE_TYPE_FILE
&&
1367 (NodeType(Fcb
) < RDBSS_NTC_SPOOLFILE
|| NodeType(Fcb
) > RDBSS_NTC_OPENTARGETDIR_FCB
))))
1369 RxBugCheck(NodeType(Fcb
), 0, 0);
1372 RxReferenceNetFcb(Fcb
);
1374 DereferenceFobx
= FALSE
;
1375 /* If we're not closing FS */
1381 SrvOpen
= (PSRV_OPEN
)Fobx
->pSrvOpen
;
1382 SrvCall
= (PSRV_CALL
)Fcb
->pNetRoot
->pSrvCall
;
1383 /* Handle delayed close */
1384 if (NodeType(Fcb
) != RDBSS_NTC_STORAGE_TYPE_DIRECTORY
)
1386 if (!BooleanFlagOn(Fcb
->FcbState
, FCB_STATE_DELETE_ON_CLOSE
| FCB_STATE_ORPHANED
))
1388 if (BooleanFlagOn(Fcb
->FcbState
, FCB_STATE_COLLAPSING_ENABLED
))
1390 DPRINT("Delay close for FOBX: %p, SrvOpen %p\n", Fobx
, SrvOpen
);
1392 if (SrvOpen
->OpenCount
== 1 && !BooleanFlagOn(SrvOpen
->Flags
, SRVOPEN_FLAG_COLLAPSING_DISABLED
))
1394 if (InterlockedIncrement(&SrvCall
->NumberOfCloseDelayedFiles
) >= SrvCall
->MaximumNumberOfCloseDelayedFiles
)
1396 InterlockedDecrement(&SrvCall
->NumberOfCloseDelayedFiles
);
1400 DereferenceFobx
= TRUE
;
1401 SetFlag(SrvOpen
->Flags
, SRVOPEN_FLAG_CLOSE_DELAYED
);
1408 /* If we reach maximum of delayed close/or if there are no delayed close */
1409 if (!DereferenceFobx
)
1413 NetRoot
= (PNET_ROOT
)Fcb
->pNetRoot
;
1414 if (NetRoot
->Type
!= NET_ROOT_PRINT
)
1416 /* Delete if asked */
1417 if (BooleanFlagOn(Fobx
->Flags
, FOBX_FLAG_DELETE_ON_CLOSE
))
1419 RxScavengeRelatedFobxs(Fcb
);
1420 RxSynchronizeWithScavenger(Context
);
1422 RxReleaseFcb(Context
, Fcb
);
1424 RxAcquireFcbTableLockExclusive(&NetRoot
->FcbTable
, TRUE
);
1425 RxOrphanThisFcb(Fcb
);
1426 RxReleaseFcbTableLock(&NetRoot
->FcbTable
);
1428 Status
= RxAcquireExclusiveFcb(Context
, Fcb
);
1429 ASSERT(NT_SUCCESS(Status
));
1434 RxMarkFobxOnClose(Fobx
);
1437 if (DereferenceFobx
)
1439 ASSERT(Fobx
!= NULL
);
1440 RxDereferenceNetFobx(Fobx
, LHS_SharedLockHeld
);
1444 RxCloseAssociatedSrvOpen(Fobx
, Context
);
1447 RxDereferenceNetFobx(Fobx
, LHS_ExclusiveLockHeld
);
1451 Freed
= RxDereferenceAndFinalizeNetFcb(Fcb
, Context
, FALSE
, FALSE
);
1452 AcquiredFcb
= !Freed
;
1454 FileObject
->FsContext
= (PVOID
)-1;
1458 RxTrackerUpdateHistory(Context
, NULL
, TRACKER_FCB_FREE
, __LINE__
, __FILE__
, 0);
1462 RxReleaseFcb(Context
, Fcb
);
1463 AcquiredFcb
= FALSE
;
1468 if (_SEH2_AbnormalTermination())
1472 RxReleaseFcb(Context
, Fcb
);
1477 ASSERT(!AcquiredFcb
);
1482 DPRINT("Status: %x\n", Status
);
1484 #undef BugCheckFileId
1490 PRX_CONTEXT Context
)
1494 PFILE_OBJECT FileObject
;
1495 PIO_STACK_LOCATION Stack
;
1499 DPRINT("RxCommonCreate(%p)\n", Context
);
1501 Irp
= Context
->CurrentIrp
;
1502 Stack
= Context
->CurrentIrpSp
;
1503 FileObject
= Stack
->FileObject
;
1505 /* Check whether that's a device opening */
1506 if (FileObject
->FileName
.Length
== 0 && FileObject
->RelatedFileObject
== NULL
)
1508 FileObject
->FsContext
= &RxDeviceFCB
;
1509 FileObject
->FsContext2
= NULL
;
1511 ++RxDeviceFCB
.NodeReferenceCount
;
1512 ++RxDeviceFCB
.OpenCount
;
1514 Irp
->IoStatus
.Information
= FILE_OPENED
;
1515 DPRINT("Device opening FO: %p, DO: %p, Name: %wZ\n", FileObject
, Context
->RxDeviceObject
, &Context
->RxDeviceObject
->DeviceName
);
1517 Status
= STATUS_SUCCESS
;
1521 PFCB RelatedFcb
= NULL
;
1523 /* Make sure caller is consistent */
1524 if (FlagOn(Stack
->Parameters
.Create
.Options
, FILE_DIRECTORY_FILE
| FILE_NON_DIRECTORY_FILE
| FILE_OPEN_REMOTE_INSTANCE
) ==
1525 (FILE_DIRECTORY_FILE
| FILE_NON_DIRECTORY_FILE
| FILE_OPEN_REMOTE_INSTANCE
))
1527 DPRINT1("Create.Options: %x\n", Stack
->Parameters
.Create
.Options
);
1528 return STATUS_INVALID_PARAMETER
;
1531 DPRINT("Ctxt: %p, FO: %p, Options: %lx, Flags: %lx, Attr: %lx, ShareAccess: %lx, DesiredAccess: %lx\n",
1532 Context
, FileObject
, Stack
->Parameters
.Create
.Options
, Stack
->Flags
, Stack
->Parameters
.Create
.FileAttributes
,
1533 Stack
->Parameters
.Create
.ShareAccess
, Stack
->Parameters
.Create
.SecurityContext
->DesiredAccess
);
1534 DPRINT("FileName: %wZ\n", &FileObject
->FileName
);
1536 if (FileObject
->RelatedFileObject
!= NULL
)
1538 RelatedFcb
= FileObject
->RelatedFileObject
->FsContext
;
1539 DPRINT("Rel FO: %p, path: %wZ\n", FileObject
->RelatedFileObject
, RelatedFcb
->FcbTableEntry
.Path
);
1542 /* Going to rename? */
1543 if (BooleanFlagOn(Stack
->Flags
, SL_OPEN_TARGET_DIRECTORY
))
1545 DPRINT("TargetDir!\n");
1548 /* Copy create parameters to the context */
1549 RxCopyCreateParameters(Context
);
1551 /* If the caller wants to establish a connection, go ahead */
1552 if (BooleanFlagOn(Stack
->Parameters
.Create
.Options
, FILE_CREATE_TREE_CONNECTION
))
1554 Status
= RxCreateTreeConnect(Context
);
1558 /* Validate file name */
1559 if (FileObject
->FileName
.Length
> sizeof(WCHAR
) &&
1560 FileObject
->FileName
.Buffer
[1] == OBJ_NAME_PATH_SEPARATOR
&&
1561 FileObject
->FileName
.Buffer
[0] == OBJ_NAME_PATH_SEPARATOR
)
1563 FileObject
->FileName
.Length
-= sizeof(WCHAR
);
1564 RtlMoveMemory(&FileObject
->FileName
.Buffer
[0], &FileObject
->FileName
.Buffer
[1],
1565 FileObject
->FileName
.Length
);
1567 if (FileObject
->FileName
.Length
> sizeof(WCHAR
) &&
1568 FileObject
->FileName
.Buffer
[1] == OBJ_NAME_PATH_SEPARATOR
&&
1569 FileObject
->FileName
.Buffer
[0] == OBJ_NAME_PATH_SEPARATOR
)
1571 return STATUS_OBJECT_NAME_INVALID
;
1575 /* Attempt to open the file */
1578 UNICODE_STRING NetRootName
;
1580 /* Strip last \ if required */
1581 if (FileObject
->FileName
.Length
!= 0 &&
1582 FileObject
->FileName
.Buffer
[FileObject
->FileName
.Length
/ sizeof(WCHAR
) - 1] == OBJ_NAME_PATH_SEPARATOR
)
1584 if (BooleanFlagOn(Stack
->Parameters
.Create
.Options
, FILE_NON_DIRECTORY_FILE
))
1586 return STATUS_OBJECT_NAME_INVALID
;
1589 FileObject
->FileName
.Length
-= sizeof(WCHAR
);
1590 Context
->Create
.Flags
|= RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH
;
1593 if (BooleanFlagOn(Context
->Flags
, RX_CONTEXT_FLAG_WRITE_THROUGH
))
1595 FileObject
->Flags
|= FO_WRITE_THROUGH
;
1598 /* Get the associated net root to opening */
1599 Status
= RxCanonicalizeNameAndObtainNetRoot(Context
, &FileObject
->FileName
, &NetRootName
);
1600 if (Status
!= STATUS_MORE_PROCESSING_REQUIRED
)
1605 /* And attempt to open */
1606 Status
= RxCreateFromNetRoot(Context
, &NetRootName
);
1607 if (Status
== STATUS_SHARING_VIOLATION
)
1611 else if (Status
== STATUS_REPARSE
)
1613 Context
->CurrentIrp
->IoStatus
.Information
= 0;
1617 ASSERT(!BooleanFlagOn(Context
->Create
.Flags
, RX_CONTEXT_CREATE_FLAG_REPARSE
));
1620 while (Status
== STATUS_MORE_PROCESSING_REQUIRED
);
1623 if (Status
== STATUS_RETRY
)
1625 RxpPrepareCreateContextForReuse(Context
);
1627 ASSERT(Status
!= STATUS_PENDING
);
1630 DPRINT("Status: %lx\n", Status
);
1639 RxCommonDevFCBCleanup(
1640 PRX_CONTEXT Context
)
1647 DPRINT("RxCommonDevFCBCleanup(%p)\n", Context
);
1649 Fcb
= Context
->pFcb
;
1650 Status
= STATUS_SUCCESS
;
1651 ASSERT(NodeType(Fcb
) == RDBSS_NTC_DEVICE_FCB
);
1653 /* Our FOBX if set, has to be a VNetRoot */
1654 if (Context
->pFobx
!= NULL
)
1656 RxAcquirePrefixTableLockShared(Context
->RxDeviceObject
->pRxNetNameTable
, TRUE
);
1657 if (Context
->pFobx
->NodeTypeCode
!= RDBSS_NTC_V_NETROOT
)
1659 Status
= STATUS_INVALID_DEVICE_REQUEST
;
1661 RxReleasePrefixTableLock(Context
->RxDeviceObject
->pRxNetNameTable
);
1665 --Fcb
->UncleanCount
;
1676 RxCommonDevFCBClose(
1677 PRX_CONTEXT Context
)
1681 PMRX_V_NET_ROOT NetRoot
;
1685 DPRINT("RxCommonDevFCBClose(%p)\n", Context
);
1687 Fcb
= Context
->pFcb
;
1688 NetRoot
= (PMRX_V_NET_ROOT
)Context
->pFobx
;
1689 Status
= STATUS_SUCCESS
;
1690 ASSERT(NodeType(Fcb
) == RDBSS_NTC_DEVICE_FCB
);
1692 /* Our FOBX if set, has to be a VNetRoot */
1693 if (NetRoot
!= NULL
)
1695 RxAcquirePrefixTableLockShared(Context
->RxDeviceObject
->pRxNetNameTable
, TRUE
);
1696 if (NetRoot
->NodeTypeCode
== RDBSS_NTC_V_NETROOT
)
1698 --NetRoot
->NumberOfOpens
;
1699 RxDereferenceVNetRoot(NetRoot
, LHS_ExclusiveLockHeld
);
1703 Status
= STATUS_NOT_IMPLEMENTED
;
1705 RxReleasePrefixTableLock(Context
->RxDeviceObject
->pRxNetNameTable
);
1717 RxCommonDevFCBFsCtl(
1718 PRX_CONTEXT Context
)
1721 return STATUS_NOT_IMPLEMENTED
;
1729 RxCommonDevFCBIoCtl(
1730 PRX_CONTEXT Context
)
1736 DPRINT("RxCommonDevFCBIoCtl(%p)\n", Context
);
1738 if (Context
->pFobx
!= NULL
)
1740 return STATUS_INVALID_HANDLE
;
1743 /* Is that a prefix claim from MUP? */
1744 if (Context
->CurrentIrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_REDIR_QUERY_PATH
)
1746 return RxPrefixClaim(Context
);
1749 /* Otherwise, pass through the mini-rdr */
1750 Status
= RxXXXControlFileCallthru(Context
);
1751 if (Status
!= STATUS_PENDING
)
1753 if (Context
->PostRequest
)
1755 Context
->ResumeRoutine
= RxCommonDevFCBIoCtl
;
1756 Status
= RxFsdPostRequest(Context
);
1760 DPRINT("Status: %lx\n", Status
);
1766 RxCommonDevFCBQueryVolInfo(
1767 PRX_CONTEXT Context
)
1770 return STATUS_NOT_IMPLEMENTED
;
1778 RxCommonDeviceControl(
1779 PRX_CONTEXT Context
)
1785 /* Prefix claim is only allowed for device, not files */
1786 if (Context
->CurrentIrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_REDIR_QUERY_PATH
)
1788 return STATUS_INVALID_DEVICE_REQUEST
;
1791 /* Submit to mini-rdr */
1792 RxInitializeLowIoContext(&Context
->LowIoContext
, LOWIO_OP_IOCTL
);
1793 Status
= RxLowIoSubmit(Context
, RxLowIoIoCtlShellCompletion
);
1794 if (Status
== STATUS_PENDING
)
1796 RxDereferenceAndDeleteRxContext_Real(Context
);
1807 RxCommonDirectoryControl(
1808 PRX_CONTEXT Context
)
1813 PIO_STACK_LOCATION Stack
;
1817 Fcb
= (PFCB
)Context
->pFcb
;
1818 Fobx
= (PFOBX
)Context
->pFobx
;
1819 Stack
= Context
->CurrentIrpSp
;
1820 DPRINT("RxCommonDirectoryControl(%p) FOBX: %p, FCB: %p, Minor: %d\n", Context
, Fobx
, Fcb
, Stack
->MinorFunction
);
1822 /* Call the appropriate helper */
1823 if (Stack
->MinorFunction
== IRP_MN_QUERY_DIRECTORY
)
1825 Status
= RxQueryDirectory(Context
);
1827 else if (Stack
->MinorFunction
== IRP_MN_NOTIFY_CHANGE_DIRECTORY
)
1829 Status
= RxNotifyChangeDirectory(Context
);
1830 if (Status
== STATUS_PENDING
)
1832 RxDereferenceAndDeleteRxContext_Real(Context
);
1837 Status
= STATUS_INVALID_DEVICE_REQUEST
;
1845 RxCommonDispatchProblem(
1846 PRX_CONTEXT Context
)
1849 return STATUS_NOT_IMPLEMENTED
;
1854 RxCommonFileSystemControl(
1855 PRX_CONTEXT Context
)
1858 return STATUS_NOT_IMPLEMENTED
;
1863 RxCommonFlushBuffers(
1864 PRX_CONTEXT Context
)
1867 return STATUS_NOT_IMPLEMENTED
;
1872 RxCommonLockControl(
1873 PRX_CONTEXT Context
)
1876 return STATUS_NOT_IMPLEMENTED
;
1882 PRX_CONTEXT Context
)
1885 return STATUS_NOT_IMPLEMENTED
;
1893 RxCommonQueryInformation(
1894 PRX_CONTEXT Context
)
1896 #define SET_SIZE_AND_QUERY(AlreadyConsummed, Function) \
1897 Context->Info.Length = Stack->Parameters.QueryFile.Length - (AlreadyConsummed); \
1898 Status = Function(Context, Add2Ptr(Buffer, AlreadyConsummed))
1905 PIO_STACK_LOCATION Stack
;
1906 FILE_INFORMATION_CLASS FileInfoClass
;
1910 Fcb
= (PFCB
)Context
->pFcb
;
1911 Fobx
= (PFOBX
)Context
->pFobx
;
1912 DPRINT("RxCommonQueryInformation(%p) FCB: %p, FOBX: %p\n", Context
, Fcb
, Fobx
);
1914 Irp
= Context
->CurrentIrp
;
1915 Stack
= Context
->CurrentIrpSp
;
1916 DPRINT("Buffer: %p, Length: %lx, Class: %ld\n", Irp
->AssociatedIrp
.SystemBuffer
,
1917 Stack
->Parameters
.QueryFile
.Length
, Stack
->Parameters
.QueryFile
.FileInformationClass
);
1919 Context
->Info
.Length
= Stack
->Parameters
.QueryFile
.Length
;
1920 FileInfoClass
= Stack
->Parameters
.QueryFile
.FileInformationClass
;
1927 /* Get a writable buffer */
1928 Buffer
= RxMapSystemBuffer(Context
);
1931 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1935 RtlZeroMemory(Buffer
, Context
->Info
.Length
);
1937 /* Validate file type */
1938 if (NodeType(Fcb
) != RDBSS_NTC_STORAGE_TYPE_UNKNOWN
)
1940 if (NodeType(Fcb
) < RDBSS_NTC_STORAGE_TYPE_DIRECTORY
)
1942 Status
= STATUS_INVALID_PARAMETER
;
1945 else if (NodeType(Fcb
) > RDBSS_NTC_STORAGE_TYPE_FILE
)
1947 if (NodeType(Fcb
) == RDBSS_NTC_MAILSLOT
)
1949 Status
= STATUS_NOT_IMPLEMENTED
;
1953 Status
= STATUS_INVALID_PARAMETER
;
1960 /* Acquire the right lock */
1961 if (!BooleanFlagOn(Fcb
->FcbState
, FCB_STATE_PAGING_FILE
) &&
1962 FileInfoClass
!= FileNameInformation
)
1964 if (FileInfoClass
== FileCompressionInformation
)
1966 Status
= RxAcquireExclusiveFcb(Context
, Fcb
);
1970 Status
= RxAcquireSharedFcb(Context
, Fcb
);
1973 if (Status
== STATUS_LOCK_NOT_GRANTED
)
1975 Status
= STATUS_PENDING
;
1978 else if (!NT_SUCCESS(Status
))
1986 /* Dispatch to the right helper */
1987 switch (FileInfoClass
)
1989 case FileBasicInformation
:
1990 Status
= RxQueryBasicInfo(Context
, Buffer
);
1993 case FileStandardInformation
:
1994 Status
= RxQueryStandardInfo(Context
, Buffer
);
1997 case FileInternalInformation
:
1998 Status
= RxQueryInternalInfo(Context
, Buffer
);
2001 case FileEaInformation
:
2002 Status
= RxQueryEaInfo(Context
, Buffer
);
2005 case FileNameInformation
:
2006 Status
= RxQueryNameInfo(Context
, Buffer
);
2009 case FileAllInformation
:
2010 SET_SIZE_AND_QUERY(0, RxQueryBasicInfo
);
2011 if (!NT_SUCCESS(Status
))
2016 SET_SIZE_AND_QUERY(sizeof(FILE_BASIC_INFORMATION
), RxQueryStandardInfo
);
2017 if (!NT_SUCCESS(Status
))
2022 SET_SIZE_AND_QUERY(sizeof(FILE_BASIC_INFORMATION
) +
2023 sizeof(FILE_STANDARD_INFORMATION
), RxQueryInternalInfo
);
2024 if (!NT_SUCCESS(Status
))
2029 SET_SIZE_AND_QUERY(sizeof(FILE_BASIC_INFORMATION
) +
2030 sizeof(FILE_STANDARD_INFORMATION
) +
2031 sizeof(FILE_INTERNAL_INFORMATION
), RxQueryEaInfo
);
2032 if (!NT_SUCCESS(Status
))
2037 SET_SIZE_AND_QUERY(sizeof(FILE_BASIC_INFORMATION
) +
2038 sizeof(FILE_STANDARD_INFORMATION
) +
2039 sizeof(FILE_INTERNAL_INFORMATION
) +
2040 sizeof(FILE_EA_INFORMATION
), RxQueryPositionInfo
);
2041 if (!NT_SUCCESS(Status
))
2046 SET_SIZE_AND_QUERY(sizeof(FILE_BASIC_INFORMATION
) +
2047 sizeof(FILE_STANDARD_INFORMATION
) +
2048 sizeof(FILE_INTERNAL_INFORMATION
) +
2049 sizeof(FILE_EA_INFORMATION
) +
2050 sizeof(FILE_POSITION_INFORMATION
), RxQueryNameInfo
);
2053 case FileAlternateNameInformation
:
2054 Status
= RxQueryAlternateNameInfo(Context
, Buffer
);
2057 case FilePipeInformation
:
2058 case FilePipeLocalInformation
:
2059 case FilePipeRemoteInformation
:
2060 Status
= RxQueryPipeInfo(Context
, Buffer
);
2063 case FileCompressionInformation
:
2064 Status
= RxQueryCompressedInfo(Context
, Buffer
);
2068 Context
->IoStatusBlock
.Status
= RxpQueryInfoMiniRdr(Context
, FileInfoClass
, Buffer
);
2069 Status
= Context
->IoStatusBlock
.Status
;
2073 if (Context
->Info
.Length
< 0)
2075 Status
= STATUS_BUFFER_OVERFLOW
;
2076 Context
->Info
.Length
= Stack
->Parameters
.QueryFile
.Length
;
2079 Irp
->IoStatus
.Information
= Stack
->Parameters
.QueryFile
.Length
- Context
->Info
.Length
;
2085 RxReleaseFcb(Context
, Fcb
);
2090 DPRINT("Status: %x\n", Status
);
2093 #undef SET_SIZE_AND_QUERY
2098 RxCommonQueryQuotaInformation(
2099 PRX_CONTEXT Context
)
2102 return STATUS_NOT_IMPLEMENTED
;
2107 RxCommonQuerySecurity(
2108 PRX_CONTEXT Context
)
2111 return STATUS_NOT_IMPLEMENTED
;
2119 RxCommonQueryVolumeInformation(
2120 PRX_CONTEXT Context
)
2126 PIO_STACK_LOCATION Stack
;
2130 Fcb
= (PFCB
)Context
->pFcb
;
2131 Fobx
= (PFOBX
)Context
->pFobx
;
2133 DPRINT("RxCommonQueryVolumeInformation(%p) FCB: %p, FOBX: %p\n", Context
, Fcb
, Fobx
);
2135 Irp
= Context
->CurrentIrp
;
2136 Stack
= Context
->CurrentIrpSp
;
2137 DPRINT("Length: %lx, Class: %lx, Buffer %p\n", Stack
->Parameters
.QueryVolume
.Length
,
2138 Stack
->Parameters
.QueryVolume
.FsInformationClass
, Irp
->AssociatedIrp
.SystemBuffer
);
2140 Context
->Info
.FsInformationClass
= Stack
->Parameters
.QueryVolume
.FsInformationClass
;
2141 Context
->Info
.Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
2142 Context
->Info
.Length
= Stack
->Parameters
.QueryVolume
.Length
;
2144 /* Forward to mini-rdr */
2145 MINIRDR_CALL(Status
, Context
, Fcb
->MRxDispatch
, MRxQueryVolumeInfo
, (Context
));
2147 /* Post request if mini-rdr asked to */
2148 if (Context
->PostRequest
)
2150 Status
= RxFsdPostRequest(Context
);
2154 Irp
->IoStatus
.Information
= Stack
->Parameters
.QueryVolume
.Length
- Context
->Info
.Length
;
2157 DPRINT("Status: %x\n", Status
);
2164 PRX_CONTEXT RxContext
)
2172 PFILE_OBJECT FileObject
;
2173 LARGE_INTEGER ByteOffset
;
2174 PIO_STACK_LOCATION Stack
;
2175 PLOWIO_CONTEXT LowIoContext
;
2176 PRDBSS_DEVICE_OBJECT RxDeviceObject
;
2177 ULONG ReadLength
, CapturedRxContextSerialNumber
= RxContext
->SerialNumber
;
2178 BOOLEAN CanWait
, PagingIo
, NoCache
, Sync
, PostRequest
, IsPipe
, ReadCachingEnabled
, ReadCachingDisabled
, InFsp
, OwnerSet
;
2182 Fcb
= (PFCB
)RxContext
->pFcb
;
2183 Fobx
= (PFOBX
)RxContext
->pFobx
;
2184 DPRINT("RxCommonRead(%p) FOBX: %p, FCB: %p\n", RxContext
, Fobx
, Fcb
);
2186 /* Get some parameters */
2187 Irp
= RxContext
->CurrentIrp
;
2188 Stack
= RxContext
->CurrentIrpSp
;
2189 CanWait
= BooleanFlagOn(RxContext
->Flags
, RX_CONTEXT_FLAG_WAIT
);
2190 PagingIo
= BooleanFlagOn(Irp
->Flags
, IRP_PAGING_IO
);
2191 NoCache
= BooleanFlagOn(Irp
->Flags
, IRP_NOCACHE
);
2192 Sync
= !BooleanFlagOn(RxContext
->Flags
, RX_CONTEXT_FLAG_ASYNC_OPERATION
);
2193 InFsp
= BooleanFlagOn(RxContext
->Flags
, RX_CONTEXT_FLAG_IN_FSP
);
2194 ReadLength
= Stack
->Parameters
.Read
.Length
;
2195 ByteOffset
.QuadPart
= Stack
->Parameters
.Read
.ByteOffset
.QuadPart
;
2196 DPRINT("Reading: %lx@%I64x %s %s %s %s\n", ReadLength
, ByteOffset
.QuadPart
,
2197 (CanWait
? "CW" : "!CW"), (PagingIo
? "PI" : "!PI"), (NoCache
? "NC" : "!NC"), (Sync
? "S" : "!S"));
2199 RxItsTheSameContext();
2201 Irp
->IoStatus
.Information
= 0;
2203 /* Should the read be loud - so far, it's just ignored on ReactOS:
2204 * s/DPRINT/DPRINT1/g will make it loud
2206 LowIoContext
= &RxContext
->LowIoContext
;
2207 CheckForLoudOperations(RxContext
);
2208 if (BooleanFlagOn(LowIoContext
->Flags
, LOWIO_CONTEXT_FLAG_LOUDOPS
))
2210 DPRINT("LoudRead %I64x/%lx on %lx vdl/size/alloc %I64x/%I64x/%I64x\n",
2211 ByteOffset
, ReadLength
,
2212 Fcb
, Fcb
->Header
.ValidDataLength
, Fcb
->Header
.FileSize
, Fcb
->Header
.AllocationSize
);
2215 RxDeviceObject
= RxContext
->RxDeviceObject
;
2217 if (!BooleanFlagOn(RxContext
->Flags
, RX_CONTEXT_FLAG_IN_FSP
) && Fcb
->CachedNetRootType
== NET_ROOT_DISK
)
2219 InterlockedIncrement((volatile long *)&RxDeviceObject
->ReadOperations
);
2221 if (ByteOffset
.QuadPart
!= Fobx
->Specific
.DiskFile
.PredictedReadOffset
)
2223 InterlockedIncrement((volatile long *)&RxDeviceObject
->RandomReadOperations
);
2225 Fobx
->Specific
.DiskFile
.PredictedReadOffset
= ByteOffset
.QuadPart
+ ReadLength
;
2229 ExInterlockedAddLargeStatistic(&RxDeviceObject
->PagingReadBytesRequested
, ReadLength
);
2233 ExInterlockedAddLargeStatistic(&RxDeviceObject
->NonPagingReadBytesRequested
, ReadLength
);
2237 ExInterlockedAddLargeStatistic(&RxDeviceObject
->CacheReadBytesRequested
, ReadLength
);
2241 /* A pagefile cannot be a pipe */
2242 IsPipe
= Fcb
->NetRoot
->Type
== NET_ROOT_PIPE
;
2243 if (IsPipe
&& PagingIo
)
2245 return STATUS_INVALID_DEVICE_REQUEST
;
2248 /* Null-length read is no-op */
2249 if (ReadLength
== 0)
2251 return STATUS_SUCCESS
;
2254 /* Validate FCB type */
2255 if (NodeType(Fcb
) != RDBSS_NTC_STORAGE_TYPE_FILE
&& NodeType(Fcb
) != RDBSS_NTC_VOLUME_FCB
)
2257 return STATUS_INVALID_DEVICE_REQUEST
;
2260 /* Init the lowio context for possible forward */
2261 RxInitializeLowIoContext(LowIoContext
, LOWIO_OP_READ
);
2263 PostRequest
= FALSE
;
2264 ReadCachingDisabled
= FALSE
;
2266 ReadCachingEnabled
= BooleanFlagOn(Fcb
->FcbState
, FCB_STATE_READCACHING_ENABLED
);
2267 FileObject
= Stack
->FileObject
;
2268 NetRoot
= (PNET_ROOT
)Fcb
->pNetRoot
;
2273 /* If no caching, make sure current Cc data have been flushed */
2274 if (!PagingIo
&& NoCache
&& !ReadCachingEnabled
&& FileObject
->SectionObjectPointer
!= NULL
)
2276 Status
= RxAcquireExclusiveFcb(RxContext
, Fcb
);
2277 if (Status
== STATUS_LOCK_NOT_GRANTED
)
2282 else if (Status
!= STATUS_SUCCESS
)
2287 ExAcquireResourceSharedLite(Fcb
->Header
.PagingIoResource
, TRUE
);
2288 CcFlushCache(FileObject
->SectionObjectPointer
, &ByteOffset
, ReadLength
, &Irp
->IoStatus
);
2289 RxReleasePagingIoResource(RxContext
, Fcb
);
2291 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
2296 RxAcquirePagingIoResource(RxContext
, Fcb
);
2297 RxReleasePagingIoResource(RxContext
, Fcb
);
2300 /* Acquire the appropriate lock */
2301 if (PagingIo
&& !ReadCachingEnabled
)
2305 if (!ExAcquireResourceSharedLite(Fcb
->Header
.PagingIoResource
, CanWait
))
2313 LowIoContext
->Resource
= Fcb
->Header
.PagingIoResource
;
2318 if (!ReadCachingEnabled
)
2320 if (!CanWait
&& NoCache
)
2322 Status
= RxAcquireSharedFcbWaitForEx(RxContext
, Fcb
);
2323 if (Status
== STATUS_LOCK_NOT_GRANTED
)
2325 DPRINT1("RdAsyLNG %x\n", RxContext
);
2329 if (Status
!= STATUS_SUCCESS
)
2331 DPRINT1("RdAsyOthr %x\n", RxContext
);
2335 if (RxIsFcbAcquiredShared(Fcb
) <= 0xF000)
2337 LowIoContext
->Resource
= Fcb
->Header
.Resource
;
2347 Status
= RxAcquireSharedFcb(RxContext
, Fcb
);
2348 if (Status
== STATUS_LOCK_NOT_GRANTED
)
2353 else if (Status
!= STATUS_SUCCESS
)
2361 RxItsTheSameContext();
2363 ReadCachingDisabled
= (ReadCachingEnabled
== FALSE
);
2369 RxGetFileSizeWithLock(Fcb
, &FileSize
);
2371 /* Make sure FLOCK doesn't conflict */
2374 if (!FsRtlCheckLockForReadAccess(&Fcb
->Specific
.Fcb
.FileLock
, Irp
))
2376 Status
= STATUS_FILE_LOCK_CONFLICT
;
2381 /* Validate byteoffset vs length */
2382 if (BooleanFlagOn(Fcb
->FcbState
, FCB_STATE_READCACHING_ENABLED
))
2384 if (ByteOffset
.QuadPart
>= FileSize
)
2386 Status
= STATUS_END_OF_FILE
;
2390 if (ReadLength
> FileSize
- ByteOffset
.QuadPart
)
2392 ReadLength
= FileSize
- ByteOffset
.QuadPart
;
2397 if (!PagingIo
&& !NoCache
&& ReadCachingEnabled
&&
2398 !BooleanFlagOn(Fobx
->pSrvOpen
->Flags
, SRVOPEN_FLAG_DONTUSE_READ_CACHING
))
2400 /* File was not cached yet, do it */
2401 if (FileObject
->PrivateCacheMap
== NULL
)
2403 if (BooleanFlagOn(FileObject
->Flags
, FO_CLEANUP_COMPLETE
))
2405 Status
= STATUS_FILE_CLOSED
;
2409 RxAdjustAllocationSizeforCC(Fcb
);
2411 CcInitializeCacheMap(FileObject
, (PCC_FILE_SIZES
)&Fcb
->Header
.AllocationSize
,
2412 FALSE
, &RxData
.CacheManagerCallbacks
, Fcb
);
2414 if (BooleanFlagOn(Fcb
->MRxDispatch
->MRxFlags
, RDBSS_NO_DEFERRED_CACHE_READAHEAD
))
2416 CcSetAdditionalCacheAttributes(FileObject
, FALSE
, FALSE
);
2420 CcSetAdditionalCacheAttributes(FileObject
, TRUE
, FALSE
);
2421 SetFlag(Fcb
->FcbState
, FCB_STATE_READAHEAD_DEFERRED
);
2424 CcSetReadAheadGranularity(FileObject
, NetRoot
->DiskParameters
.ReadAheadGranularity
);
2427 /* This should never happen - fix your RDR */
2428 if (BooleanFlagOn(RxContext
->MinorFunction
, IRP_MN_MDL
))
2433 CcMdlRead(FileObject
, &ByteOffset
, ReadLength
, &Irp
->MdlAddress
, &Irp
->IoStatus
);
2434 Status
= Irp
->IoStatus
.Status
;
2435 ASSERT(NT_SUCCESS(Status
));
2440 SystemBuffer
= RxNewMapUserBuffer(RxContext
);
2441 if (SystemBuffer
== NULL
)
2443 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2447 SetFlag(Fcb
->FcbState
, FCB_STATE_READCACHING_ENABLED
);
2449 RxItsTheSameContext();
2451 /* Perform the read */
2452 if (!CcCopyRead(FileObject
, &ByteOffset
, ReadLength
, CanWait
, SystemBuffer
, &Irp
->IoStatus
))
2454 if (!ReadCachingEnabled
)
2456 ClearFlag(Fcb
->FcbState
, FCB_STATE_READCACHING_ENABLED
);
2459 RxItsTheSameContext();
2465 if (!ReadCachingEnabled
)
2467 ClearFlag(Fcb
->FcbState
, FCB_STATE_READCACHING_ENABLED
);
2470 Status
= Irp
->IoStatus
.Status
;
2471 ASSERT(NT_SUCCESS(Status
));
2476 /* Validate the reading */
2477 if (FileObject
->PrivateCacheMap
!= NULL
&& BooleanFlagOn(Fcb
->FcbState
, FCB_STATE_READAHEAD_DEFERRED
) &&
2478 ByteOffset
.QuadPart
>= 4096)
2480 CcSetAdditionalCacheAttributes(FileObject
, FALSE
, FALSE
);
2481 ClearFlag(Fcb
->FcbState
, FCB_STATE_READAHEAD_DEFERRED
);
2484 /* If it's consistent, forward to mini-rdr */
2485 if (Fcb
->CachedNetRootType
!= NET_ROOT_DISK
|| BooleanFlagOn(Fcb
->FcbState
, FCB_STATE_READAHEAD_DEFERRED
) ||
2486 ByteOffset
.QuadPart
< Fcb
->Header
.ValidDataLength
.QuadPart
)
2488 LowIoContext
->ParamsFor
.ReadWrite
.ByteCount
= ReadLength
;
2489 LowIoContext
->ParamsFor
.ReadWrite
.ByteOffset
= ByteOffset
.QuadPart
;
2491 RxItsTheSameContext();
2493 if (InFsp
&& ReadCachingDisabled
)
2495 ExSetResourceOwnerPointer((PagingIo
? Fcb
->Header
.PagingIoResource
: Fcb
->Header
.Resource
),
2496 (PVOID
)((ULONG_PTR
)RxContext
| 3));
2500 Status
= RxLowIoReadShell(RxContext
);
2502 RxItsTheSameContext();
2506 if (ByteOffset
.QuadPart
> FileSize
)
2509 Irp
->IoStatus
.Information
= ReadLength
;
2513 if (ByteOffset
.QuadPart
+ ReadLength
> FileSize
)
2515 ReadLength
= FileSize
- ByteOffset
.QuadPart
;
2518 SystemBuffer
= RxNewMapUserBuffer(RxContext
);
2519 RtlZeroMemory(SystemBuffer
, ReadLength
);
2520 Irp
->IoStatus
.Information
= ReadLength
;
2526 RxItsTheSameContext();
2528 /* Post if required */
2531 InterlockedIncrement((volatile long *)&RxContext
->ReferenceCount
);
2532 Status
= RxFsdPostRequest(RxContext
);
2536 /* Update FO in case of sync IO */
2537 if (!IsPipe
&& !PagingIo
)
2539 if (BooleanFlagOn(FileObject
->Flags
, FO_SYNCHRONOUS_IO
))
2541 FileObject
->CurrentByteOffset
.QuadPart
= ByteOffset
.QuadPart
+ Irp
->IoStatus
.Information
;
2546 /* Set FastIo if read was a success */
2547 if (NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
2549 if (!IsPipe
&& !PagingIo
)
2551 SetFlag(FileObject
->Flags
, FO_FILE_FAST_IO_READ
);
2555 /* In case we're done (not expected any further processing */
2556 if (_SEH2_AbnormalTermination() || Status
!= STATUS_PENDING
|| PostRequest
)
2558 /* Release everything that can be */
2559 if (ReadCachingDisabled
)
2565 RxReleasePagingIoResourceForThread(RxContext
, Fcb
, LowIoContext
->ResourceThreadId
);
2569 RxReleasePagingIoResource(RxContext
, Fcb
);
2576 RxReleaseFcbForThread(RxContext
, Fcb
, LowIoContext
->ResourceThreadId
);
2580 RxReleaseFcb(RxContext
, Fcb
);
2585 /* Dereference/Delete context */
2588 RxDereferenceAndDeleteRxContext(RxContext
);
2592 if (BooleanFlagOn(RxContext
->FlagsForLowIo
, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION
))
2594 RxResumeBlockedOperations_Serially(RxContext
, &Fobx
->Specific
.NamedPipe
.ReadSerializationQueue
);
2598 /* We cannot return more than asked */
2599 if (Status
== STATUS_SUCCESS
)
2601 ASSERT(Irp
->IoStatus
.Information
<= Stack
->Parameters
.Read
.Length
);
2608 RxDereferenceAndDeleteRxContext(RxContext
);
2619 PRX_CONTEXT Context
)
2622 return STATUS_NOT_IMPLEMENTED
;
2627 RxCommonSetInformation(
2628 PRX_CONTEXT Context
)
2631 return STATUS_NOT_IMPLEMENTED
;
2636 RxCommonSetQuotaInformation(
2637 PRX_CONTEXT Context
)
2640 return STATUS_NOT_IMPLEMENTED
;
2645 RxCommonSetSecurity(
2646 PRX_CONTEXT Context
)
2649 return STATUS_NOT_IMPLEMENTED
;
2654 RxCommonSetVolumeInformation(
2655 PRX_CONTEXT Context
)
2658 return STATUS_NOT_IMPLEMENTED
;
2663 RxCommonUnimplemented(
2664 PRX_CONTEXT Context
)
2667 return STATUS_NOT_IMPLEMENTED
;
2673 PRX_CONTEXT Context
)
2676 return STATUS_NOT_IMPLEMENTED
;
2682 IN PRX_CONTEXT RxContext
)
2687 return STATUS_NOT_IMPLEMENTED
;
2694 RxCopyCreateParameters(
2695 IN PRX_CONTEXT RxContext
)
2699 PFILE_OBJECT FileObject
;
2700 PIO_STACK_LOCATION Stack
;
2701 PDFS_NAME_CONTEXT DfsNameContext
;
2702 PIO_SECURITY_CONTEXT SecurityContext
;
2704 Irp
= RxContext
->CurrentIrp
;
2705 Stack
= RxContext
->CurrentIrpSp
;
2706 FileObject
= Stack
->FileObject
;
2707 SecurityContext
= Stack
->Parameters
.Create
.SecurityContext
;
2709 RxContext
->Create
.NtCreateParameters
.SecurityContext
= SecurityContext
;
2710 if (SecurityContext
->AccessState
!= NULL
&& SecurityContext
->AccessState
->SecurityDescriptor
!= NULL
)
2712 RxContext
->Create
.SdLength
= RtlLengthSecurityDescriptor(SecurityContext
->AccessState
->SecurityDescriptor
);
2713 DPRINT("SD Ctxt: %p, Length: %lx\n", RxContext
->Create
.NtCreateParameters
.SecurityContext
,
2714 RxContext
->Create
.SdLength
);
2716 if (SecurityContext
->SecurityQos
!= NULL
)
2718 RxContext
->Create
.NtCreateParameters
.ImpersonationLevel
= SecurityContext
->SecurityQos
->ImpersonationLevel
;
2722 RxContext
->Create
.NtCreateParameters
.ImpersonationLevel
= SecurityImpersonation
;
2724 RxContext
->Create
.NtCreateParameters
.DesiredAccess
= SecurityContext
->DesiredAccess
;
2726 RxContext
->Create
.NtCreateParameters
.AllocationSize
.QuadPart
= Irp
->Overlay
.AllocationSize
.QuadPart
;
2727 RxContext
->Create
.NtCreateParameters
.FileAttributes
= Stack
->Parameters
.Create
.FileAttributes
& FILE_ATTRIBUTE_VALID_FLAGS
;
2728 RxContext
->Create
.NtCreateParameters
.ShareAccess
= Stack
->Parameters
.Create
.ShareAccess
& FILE_SHARE_VALID_FLAGS
;
2729 RxContext
->Create
.NtCreateParameters
.Disposition
= (Stack
->Parameters
.Create
.Options
>> 24) & 0x000000FF;
2730 RxContext
->Create
.NtCreateParameters
.CreateOptions
= Stack
->Parameters
.Create
.Options
& 0xFFFFFF;
2732 DfsContext
= FileObject
->FsContext2
;
2733 DfsNameContext
= FileObject
->FsContext
;
2734 RxContext
->Create
.NtCreateParameters
.DfsContext
= DfsContext
;
2735 RxContext
->Create
.NtCreateParameters
.DfsNameContext
= DfsNameContext
;
2736 ASSERT(DfsContext
== NULL
|| DfsContext
== UIntToPtr(DFS_OPEN_CONTEXT
) ||
2737 DfsContext
== UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT
) ||
2738 DfsContext
== UIntToPtr(DFS_CSCAGENT_NAME_CONTEXT
) ||
2739 DfsContext
== UIntToPtr(DFS_USER_NAME_CONTEXT
));
2740 ASSERT(DfsNameContext
== NULL
|| DfsNameContext
->NameContextType
== DFS_OPEN_CONTEXT
||
2741 DfsNameContext
->NameContextType
== DFS_DOWNLEVEL_OPEN_CONTEXT
||
2742 DfsNameContext
->NameContextType
== DFS_CSCAGENT_NAME_CONTEXT
||
2743 DfsNameContext
->NameContextType
== DFS_USER_NAME_CONTEXT
);
2744 FileObject
->FsContext2
= NULL
;
2745 FileObject
->FsContext
= NULL
;
2747 RxContext
->pFcb
= NULL
;
2748 RxContext
->Create
.ReturnedCreateInformation
= 0;
2750 /* if we stripped last \, it has to be a directory! */
2751 if (BooleanFlagOn(RxContext
->Create
.Flags
, RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH
))
2753 SetFlag(RxContext
->Create
.NtCreateParameters
.CreateOptions
, FILE_DIRECTORY_FILE
);
2756 RxContext
->Create
.EaLength
= Stack
->Parameters
.Create
.EaLength
;
2757 if (RxContext
->Create
.EaLength
== 0)
2759 RxContext
->Create
.EaBuffer
= NULL
;
2763 RxContext
->Create
.EaBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
2764 DPRINT("EA Buffer: %p, Length: %lx\n", Irp
->AssociatedIrp
.SystemBuffer
, RxContext
->Create
.EaLength
);
2769 RxCreateFromNetRoot(
2770 PRX_CONTEXT Context
,
2771 PUNICODE_STRING NetRootName
)
2776 PFILE_OBJECT FileObject
;
2777 PIO_STACK_LOCATION Stack
;
2778 ACCESS_MASK DesiredAccess
;
2779 USHORT DesiredShareAccess
;
2783 /* Validate that the context is consistent */
2784 if (Context
->Create
.pNetRoot
== NULL
)
2786 return STATUS_BAD_NETWORK_PATH
;
2789 NetRoot
= (PNET_ROOT
)Context
->Create
.pNetRoot
;
2790 if (Context
->RxDeviceObject
!= NetRoot
->pSrvCall
->RxDeviceObject
)
2792 return STATUS_BAD_NETWORK_PATH
;
2795 if (Context
->Create
.NtCreateParameters
.DfsContext
== UIntToPtr(DFS_OPEN_CONTEXT
) &&
2796 !BooleanFlagOn(NetRoot
->pSrvCall
->Flags
, SRVCALL_FLAG_DFS_AWARE_SERVER
))
2798 return STATUS_DFS_UNAVAILABLE
;
2801 if (Context
->Create
.NtCreateParameters
.DfsContext
== UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT
) &&
2802 BooleanFlagOn(NetRoot
->Flags
, NETROOT_FLAG_DFS_AWARE_NETROOT
))
2804 return STATUS_OBJECT_TYPE_MISMATCH
;
2807 Stack
= Context
->CurrentIrpSp
;
2808 DesiredShareAccess
= Stack
->Parameters
.Create
.ShareAccess
& FILE_SHARE_VALID_FLAGS
;
2809 if (NetRoot
->Type
== NET_ROOT_PRINT
)
2811 DesiredShareAccess
= FILE_SHARE_VALID_FLAGS
;
2814 DesiredAccess
= Stack
->Parameters
.Create
.SecurityContext
->DesiredAccess
& FILE_ALL_ACCESS
;
2816 /* We don't support renaming yet */
2817 if (BooleanFlagOn(Stack
->Flags
, SL_OPEN_TARGET_DIRECTORY
))
2820 return STATUS_NOT_IMPLEMENTED
;
2823 /* Try to find (or create) the FCB for the file */
2824 Status
= RxFindOrCreateFcb(Context
, NetRootName
);
2825 Fcb
= (PFCB
)Context
->pFcb
;
2828 ASSERT(!NT_SUCCESS(Status
));
2830 if (!NT_SUCCESS(Status
) || Fcb
== NULL
)
2835 if (BooleanFlagOn(Context
->Flags
, RX_CONTEXT_FLAG_CREATE_MAILSLOT
))
2837 Fcb
->Header
.NodeTypeCode
= RDBSS_NTC_MAILSLOT
;
2841 Status
= STATUS_MORE_PROCESSING_REQUIRED
;
2844 /* If finding FCB worked (mailslot case), mark the FCB as good and quit */
2845 if (NT_SUCCESS(Status
))
2847 RxTransitionNetFcb(Fcb
, Condition_Good
);
2848 DPRINT("Transitioning FCB %lx Condition %lx\n", Fcb
, Fcb
->Condition
);
2850 RxSetupNetFileObject(Context
);
2851 return STATUS_SUCCESS
;
2855 FileObject
= Stack
->FileObject
;
2856 /* Check SA for conflict */
2857 if (Fcb
->OpenCount
> 0)
2859 Status
= RxCheckShareAccess(DesiredAccess
, DesiredShareAccess
, FileObject
,
2860 &Fcb
->ShareAccess
, FALSE
, "early check per useropens", "EarlyPerUO");
2861 if (!NT_SUCCESS(Status
))
2863 RxDereferenceNetFcb(Fcb
);
2868 if (BooleanFlagOn(Context
->Create
.NtCreateParameters
.CreateOptions
, FILE_DELETE_ON_CLOSE
) &&
2869 !BooleanFlagOn(Context
->Create
.NtCreateParameters
.DesiredAccess
, ~SYNCHRONIZE
))
2876 /* Find a SRV_OPEN that suits the opening */
2877 Status
= RxCollapseOrCreateSrvOpen(Context
);
2878 if (Status
== STATUS_SUCCESS
)
2883 SrvOpen
= (PSRV_OPEN
)Context
->pRelevantSrvOpen
;
2884 Fobx
= (PFOBX
)Context
->pFobx
;
2885 /* There are already opens, check for conflict */
2886 if (Fcb
->OpenCount
!= 0)
2888 if (!NT_SUCCESS(RxCheckShareAccess(DesiredAccess
, DesiredShareAccess
,
2889 FileObject
, &Fcb
->ShareAccess
,
2890 FALSE
, "second check per useropens",
2893 ++SrvOpen
->UncleanFobxCount
;
2894 RxDereferenceNetFobx(Fobx
, LHS_LockNotHeld
);
2901 if (NetRoot
->Type
!= NET_ROOT_PIPE
)
2903 RxSetShareAccess(DesiredAccess
, DesiredShareAccess
, FileObject
,
2904 &Fcb
->ShareAccess
, "initial shareaccess setup", "InitShrAcc");
2908 RxSetupNetFileObject(Context
);
2910 /* No conflict? Set up SA */
2911 if (Fcb
->OpenCount
!= 0 && NetRoot
->Type
!= NET_ROOT_PIPE
)
2913 RxUpdateShareAccess(FileObject
, &Fcb
->ShareAccess
, "update share access", "UpdShrAcc");
2916 ++Fcb
->UncleanCount
;
2917 if (BooleanFlagOn(FileObject
->Flags
, FO_NO_INTERMEDIATE_BUFFERING
))
2919 ++Fcb
->UncachedUncleanCount
;
2922 if (SrvOpen
->UncleanFobxCount
== 0 && Fcb
->UncleanCount
== 1 &&
2923 !BooleanFlagOn(SrvOpen
->Flags
, SRVOPEN_FLAG_NO_BUFFERING_STATE_CHANGE
))
2925 RxChangeBufferingState(SrvOpen
, NULL
, FALSE
);
2928 /* No pending close, we're active */
2929 ClearFlag(Fcb
->FcbState
, FCB_STATE_DELAY_CLOSE
);
2932 ++SrvOpen
->UncleanFobxCount
;
2933 ++SrvOpen
->OpenCount
;
2934 SrvOpen
->ulFileSizeVersion
= Fcb
->ulFileSizeVersion
;
2936 if (BooleanFlagOn(Stack
->Parameters
.Create
.Options
, FILE_NO_INTERMEDIATE_BUFFERING
))
2938 SetFlag(SrvOpen
->Flags
, SRVOPEN_FLAG_DONTUSE_READ_CACHING
);
2939 SetFlag(SrvOpen
->Flags
, SRVOPEN_FLAG_DONTUSE_WRITE_CACHING
);
2941 ClearFlag(Fcb
->FcbState
, FCB_STATE_WRITECACHING_ENABLED
);
2942 ClearFlag(Fcb
->FcbState
, FCB_STATE_READCACHING_ENABLED
);
2944 RxPurgeFcbInSystemCache(Fcb
, NULL
, 0, TRUE
, TRUE
);
2947 /* Now, update SA for the SRV_OPEN */
2948 RxUpdateShareAccessPerSrvOpens(SrvOpen
);
2950 if (BooleanFlagOn(Stack
->Parameters
.Create
.Options
, FILE_DELETE_ON_CLOSE
))
2952 SetFlag(Fobx
->Flags
, FOBX_FLAG_DELETE_ON_CLOSE
);
2955 /* Update the FOBX info */
2958 if (Context
->Create
.pNetRoot
->Type
== NET_ROOT_PIPE
)
2960 SetFlag(FileObject
->Flags
, FO_NAMED_PIPE
);
2963 if (Context
->Create
.pNetRoot
->Type
== NET_ROOT_PRINT
||
2964 Context
->Create
.pNetRoot
->Type
== NET_ROOT_PIPE
)
2966 Fobx
->PipeHandleInformation
= &Fobx
->Specific
.NamedPipe
.PipeHandleInformation
;
2968 Fobx
->Specific
.NamedPipe
.CollectDataTime
.QuadPart
= 0;
2969 Fobx
->Specific
.NamedPipe
.CollectDataSize
= Context
->Create
.pNetRoot
->NamedPipeParameters
.DataCollectionSize
;
2971 Fobx
->Specific
.NamedPipe
.PipeHandleInformation
.TypeOfPipe
= Context
->Create
.PipeType
;
2972 Fobx
->Specific
.NamedPipe
.PipeHandleInformation
.ReadMode
= Context
->Create
.PipeReadMode
;
2973 Fobx
->Specific
.NamedPipe
.PipeHandleInformation
.CompletionMode
= Context
->Create
.PipeCompletionMode
;
2975 InitializeListHead(&Fobx
->Specific
.NamedPipe
.ReadSerializationQueue
);
2976 InitializeListHead(&Fobx
->Specific
.NamedPipe
.WriteSerializationQueue
);
2980 Status
= STATUS_SUCCESS
;
2985 if (Fcb
->OpenCount
== 0)
2987 if (Context
->Create
.FcbAcquired
)
2989 Context
->Create
.FcbAcquired
= (RxDereferenceAndFinalizeNetFcb(Fcb
,
2993 if (!Context
->Create
.FcbAcquired
)
2995 RxTrackerUpdateHistory(Context
, NULL
, TRACKER_FCB_FREE
, __LINE__
, __FILE__
, 0);
3001 RxDereferenceNetFcb(Fcb
);
3013 RxCreateTreeConnect(
3014 IN PRX_CONTEXT RxContext
)
3017 PV_NET_ROOT VNetRoot
;
3018 PFILE_OBJECT FileObject
;
3019 PIO_STACK_LOCATION Stack
;
3020 NET_ROOT_TYPE NetRootType
;
3021 UNICODE_STRING CanonicalName
, RemainingName
;
3025 Stack
= RxContext
->CurrentIrpSp
;
3026 FileObject
= Stack
->FileObject
;
3028 RtlInitEmptyUnicodeString(&CanonicalName
, NULL
, 0);
3029 /* As long as we don't know connection type, mark it wild */
3030 NetRootType
= NET_ROOT_WILD
;
3031 /* Get the type by parsing the name */
3032 Status
= RxFirstCanonicalize(RxContext
, &FileObject
->FileName
, &CanonicalName
, &NetRootType
);
3033 if (!NT_SUCCESS(Status
))
3038 RxContext
->Create
.ThisIsATreeConnectOpen
= TRUE
;
3039 RxContext
->Create
.TreeConnectOpenDeferred
= FALSE
;
3040 RtlInitEmptyUnicodeString(&RxContext
->Create
.TransportName
, NULL
, 0);
3041 RtlInitEmptyUnicodeString(&RxContext
->Create
.UserName
, NULL
, 0);
3042 RtlInitEmptyUnicodeString(&RxContext
->Create
.Password
, NULL
, 0);
3043 RtlInitEmptyUnicodeString(&RxContext
->Create
.UserDomainName
, NULL
, 0);
3045 /* We don't handle EA - they come from DFS, don't care */
3046 if (Stack
->Parameters
.Create
.EaLength
> 0)
3051 /* Mount if required */
3052 Status
= RxFindOrConstructVirtualNetRoot(RxContext
, &CanonicalName
, NetRootType
, &RemainingName
);
3053 if (Status
== STATUS_NETWORK_CREDENTIAL_CONFLICT
)
3055 RxScavengeVNetRoots(RxContext
->RxDeviceObject
);
3056 Status
= RxFindOrConstructVirtualNetRoot(RxContext
, &CanonicalName
, NetRootType
, &RemainingName
);
3059 if (!NT_SUCCESS(Status
))
3064 /* Validate the rest of the name with mini-rdr */
3065 if (RemainingName
.Length
> 0)
3067 MINIRDR_CALL(Status
, RxContext
,
3068 RxContext
->Create
.pNetRoot
->pSrvCall
->RxDeviceObject
->Dispatch
,
3069 MRxIsValidDirectory
, (RxContext
, &RemainingName
));
3072 if (!NT_SUCCESS(Status
))
3077 VNetRoot
= (PV_NET_ROOT
)RxContext
->Create
.pVNetRoot
;
3078 RxReferenceVNetRoot(VNetRoot
);
3079 if (InterlockedCompareExchange(&VNetRoot
->AdditionalReferenceForDeleteFsctlTaken
, 1, 0) != 0)
3081 RxDereferenceVNetRoot(VNetRoot
, LHS_LockNotHeld
);
3084 FileObject
->FsContext
= &RxDeviceFCB
;
3085 FileObject
->FsContext2
= VNetRoot
;
3087 VNetRoot
->ConstructionStatus
= STATUS_SUCCESS
;
3088 ++VNetRoot
->NumberOfOpens
;
3090 /* Create is over - clear context */
3091 RxContext
->Create
.pSrvCall
= NULL
;
3092 RxContext
->Create
.pNetRoot
= NULL
;
3093 RxContext
->Create
.pVNetRoot
= NULL
;
3100 RxDebugControlCommand(
3101 _In_ PSTR ControlString
)
3109 IN PDRIVER_OBJECT DriverObject
,
3110 IN PUNICODE_STRING RegistryPath
)
3113 USHORT i
, State
= 0;
3115 DPRINT("RxDriverEntry(%p, %p)\n", DriverObject
, RegistryPath
);
3119 RxCheckFcbStructuresForAlignment();
3121 RtlZeroMemory(&RxData
, sizeof(RxData
));
3122 RxData
.NodeTypeCode
= RDBSS_NTC_DATA_HEADER
;
3123 RxData
.NodeByteSize
= sizeof(RxData
);
3124 RxData
.DriverObject
= DriverObject
;
3126 RtlZeroMemory(&RxDeviceFCB
, sizeof(RxDeviceFCB
));
3127 RxDeviceFCB
.spacer
.NodeTypeCode
= RDBSS_NTC_DEVICE_FCB
;
3128 RxDeviceFCB
.spacer
.NodeByteSize
= sizeof(RxDeviceFCB
);
3130 KeInitializeSpinLock(&RxStrucSupSpinLock
);
3131 RxExports
.pRxStrucSupSpinLock
= &RxStrucSupSpinLock
;
3133 RxInitializeDebugSupport();
3135 RxFileSystemDeviceObject
= (PRDBSS_DEVICE_OBJECT
)&RxSpaceForTheWrappersDeviceObject
;
3136 RtlZeroMemory(&RxSpaceForTheWrappersDeviceObject
, sizeof(RxSpaceForTheWrappersDeviceObject
));
3141 RxGetRegistryParameters(RegistryPath
);
3142 RxReadRegistryParameters();
3144 Status
= RxInitializeRegistrationStructures();
3145 if (!NT_SUCCESS(Status
))
3151 RxInitializeDispatcher();
3153 ExInitializeNPagedLookasideList(&RxContextLookasideList
, RxAllocatePoolWithTag
, RxFreePool
, 0, sizeof(RX_CONTEXT
), RX_IRPC_POOLTAG
, 4);
3155 InitializeListHead(&RxIrpsList
);
3156 KeInitializeSpinLock(&RxIrpsListSpinLock
);
3158 InitializeListHead(&RxActiveContexts
);
3159 InitializeListHead(&RxSrvCalldownList
);
3161 ExInitializeFastMutex(&RxContextPerFileSerializationMutex
);
3162 ExInitializeFastMutex(&RxLowIoPagingIoSyncMutex
);
3163 KeInitializeMutex(&RxScavengerMutex
, 1);
3164 KeInitializeMutex(&RxSerializationMutex
, 1);
3166 for (i
= 0; i
< RxMaximumWorkQueue
; ++i
)
3168 RxFileSystemDeviceObject
->PostedRequestCount
[i
] = 0;
3169 RxFileSystemDeviceObject
->OverflowQueueCount
[i
] = 0;
3170 InitializeListHead(&RxFileSystemDeviceObject
->OverflowQueue
[i
]);
3173 KeInitializeSpinLock(&RxFileSystemDeviceObject
->OverflowQueueSpinLock
);
3175 RxInitializeDispatchVectors(DriverObject
);
3177 ExInitializeResourceLite(&RxData
.Resource
);
3178 RxData
.OurProcess
= IoGetCurrentProcess();
3180 RxInitializeRxTimer();
3184 if (!NT_SUCCESS(Status
))
3186 RxLogFailure(RxFileSystemDeviceObject
, NULL
, 0x80000BC4, Status
);
3187 RxInitUnwind(DriverObject
, State
);
3191 /* There are still bits to init - be consider it's fine for now */
3194 return STATUS_NOT_IMPLEMENTED
;
3196 return STATUS_SUCCESS
;
3204 RxDumpCurrentAccess(
3207 _In_ PSZ wherelogtag
,
3208 _In_ PSHARE_ACCESS ShareAccess
)
3220 _In_ PSZ wherelogtag
,
3221 _In_ ACCESS_MASK DesiredAccess
,
3222 _In_ ULONG DesiredShareAccess
)
3229 RxFastIoCheckIfPossible(
3230 PFILE_OBJECT FileObject
,
3231 PLARGE_INTEGER FileOffset
,
3232 ULONG Length
, BOOLEAN Wait
,
3233 ULONG LockKey
, BOOLEAN CheckForReadOperation
,
3234 PIO_STATUS_BLOCK IoStatus
,
3235 PDEVICE_OBJECT DeviceObject
)
3243 RxFastIoDeviceControl(
3244 PFILE_OBJECT FileObject
,
3246 PVOID InputBuffer OPTIONAL
,
3247 ULONG InputBufferLength
,
3248 PVOID OutputBuffer OPTIONAL
,
3249 ULONG OutputBufferLength
,
3250 ULONG IoControlCode
,
3251 PIO_STATUS_BLOCK IoStatus
,
3252 PDEVICE_OBJECT DeviceObject
)
3254 /* Only supported IOCTL */
3255 if (IoControlCode
== IOCTL_LMR_ARE_FILE_OBJECTS_ON_SAME_SERVER
)
3269 PFILE_OBJECT FileObject
,
3270 PLARGE_INTEGER FileOffset
,
3275 PIO_STATUS_BLOCK IoStatus
,
3276 PDEVICE_OBJECT DeviceObject
)
3285 PFILE_OBJECT FileObject
,
3286 PLARGE_INTEGER FileOffset
,
3291 PIO_STATUS_BLOCK IoStatus
,
3292 PDEVICE_OBJECT DeviceObject
)
3300 RxFinalizeConnection(
3301 IN OUT PNET_ROOT NetRoot
,
3302 IN OUT PV_NET_ROOT VNetRoot OPTIONAL
,
3303 IN LOGICAL ForceFilesClosed
)
3306 return STATUS_NOT_IMPLEMENTED
;
3311 PRX_CONTEXT RxContext
,
3312 PUNICODE_STRING NetRootName
)
3318 PV_NET_ROOT VNetRoot
;
3319 BOOLEAN TableAcquired
, AcquiredExclusive
;
3323 NetRoot
= (PNET_ROOT
)RxContext
->Create
.pNetRoot
;
3324 VNetRoot
= (PV_NET_ROOT
)RxContext
->Create
.pVNetRoot
;
3325 ASSERT(NetRoot
== VNetRoot
->NetRoot
);
3327 Status
= STATUS_SUCCESS
;
3328 AcquiredExclusive
= FALSE
;
3330 RxAcquireFcbTableLockShared(&NetRoot
->FcbTable
, TRUE
);
3331 TableAcquired
= TRUE
;
3332 Version
= NetRoot
->FcbTable
.Version
;
3334 /* Look for a cached FCB */
3335 Fcb
= RxFcbTableLookupFcb(&NetRoot
->FcbTable
, NetRootName
);
3338 DPRINT("RxFcbTableLookupFcb returned NULL fcb for %wZ\n", NetRootName
);
3342 DPRINT("FCB found for %wZ\n", &Fcb
->FcbTableEntry
.Path
);
3343 /* If FCB was to be orphaned, consider it as not suitable */
3344 if (Fcb
->fShouldBeOrphaned
)
3346 RxDereferenceNetFcb(Fcb
);
3347 RxReleaseFcbTableLock(&NetRoot
->FcbTable
);
3349 RxAcquireFcbTableLockExclusive(&NetRoot
->FcbTable
, TRUE
);
3350 TableAcquired
= TRUE
;
3351 AcquiredExclusive
= TRUE
;
3353 Fcb
= RxFcbTableLookupFcb(&NetRoot
->FcbTable
, NetRootName
);
3354 if (Fcb
!= NULL
&& Fcb
->fShouldBeOrphaned
)
3356 RxOrphanThisFcb(Fcb
);
3357 RxDereferenceNetFcb(Fcb
);
3363 /* If FCB was not found or is not covering full path, prepare for more work */