CheckForLoudOperations(
PRX_CONTEXT RxContext)
{
+ RxCaptureFcb;
+
PAGED_CODE();
#define ALLSCR_LENGTH (sizeof(L"all.scr") - sizeof(UNICODE_NULL))
/* Are loud operations enabled? */
if (RxLoudLowIoOpsEnabled)
{
- PFCB Fcb;
-
/* If so, the operation will be loud only if filename ends with all.scr */
- Fcb = (PFCB)RxContext->pFcb;
- if (RtlCompareMemory(Add2Ptr(Fcb->PrivateAlreadyPrefixedName.Buffer, (Fcb->PrivateAlreadyPrefixedName.Length - ALLSCR_LENGTH)),
+ if (RtlCompareMemory(Add2Ptr(capFcb->PrivateAlreadyPrefixedName.Buffer,
+ (capFcb->PrivateAlreadyPrefixedName.Length - ALLSCR_LENGTH)),
L"all.scr", ALLSCR_LENGTH) == ALLSCR_LENGTH)
{
SetFlag(RxContext->LowIoContext.Flags, LOWIO_CONTEXT_FLAG_LOUDOPS);
PCSTR FileName,
ULONG SerialNumber)
{
- PFCB Fcb;
+ RxCaptureFcb;
PAGED_CODE();
ASSERT(RxContext != NULL);
-
- Fcb = (PFCB)RxContext->pFcb;
- ASSERT(Fcb != NULL);
+ ASSERT(capFcb != NULL);
/* If FCB resource was acquired, release it */
if (RxContext->FcbResourceAcquired)
/* Taking care of owner */
if (ResourceOwnerSet)
{
- RxReleaseFcbForThread(RxContext, Fcb, RxContext->LowIoContext.ResourceThreadId);
+ RxReleaseFcbForThread(RxContext, capFcb, RxContext->LowIoContext.ResourceThreadId);
}
else
{
- RxReleaseFcb(RxContext, Fcb);
+ RxReleaseFcb(RxContext, capFcb);
}
RxContext->FcbResourceAcquired = FALSE;
/* Taking care of owner */
if (ResourceOwnerSet)
{
- RxReleasePagingIoResourceForThread(RxContext, Fcb, RxContext->LowIoContext.ResourceThreadId);
+ RxReleasePagingIoResourceForThread(RxContext, capFcb, RxContext->LowIoContext.ResourceThreadId);
}
else
{
- RxReleasePagingIoResource(RxContext, Fcb);
+ RxReleasePagingIoResource(RxContext, capFcb);
}
/* No need to release boolean here, RxReleasePagingIoResource() takes care of it */
ULONG Queued;
KIRQL OldIrql;
WORK_QUEUE_TYPE Queue;
- PIO_STACK_LOCATION Stack;
- Stack = RxContext->CurrentIrpSp;
+ RxCaptureParamBlock;
+
RxContext->PostRequest = FALSE;
/* First of all, select the appropriate queue - delayed for prefix claim, critical for the rest */
if (RxContext->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
- Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH)
+ capPARAMS->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH)
{
Queue = DelayedWorkQueue;
SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_FSP_DELAYED_OVERFLOW_QUEUE);
}
/* Check for overflow */
- if (Stack->FileObject != NULL)
+ if (capPARAMS->FileObject != NULL)
{
KeAcquireSpinLock(&RxFileSystemDeviceObject->OverflowQueueSpinLock, &OldIrql);
*/
VOID
RxAdjustFileTimesAndSize(
- PRX_CONTEXT Context)
+ PRX_CONTEXT RxContext)
{
- PFCB Fcb;
- PFOBX Fobx;
NTSTATUS Status;
- PFILE_OBJECT FileObject;
LARGE_INTEGER CurrentTime;
FILE_BASIC_INFORMATION FileBasicInfo;
FILE_END_OF_FILE_INFORMATION FileEOFInfo;
BOOLEAN FileModified, SetLastChange, SetLastAccess, SetLastWrite, NeedUpdate;
+ RxCaptureFcb;
+ RxCaptureFobx;
+ RxCaptureParamBlock;
+ RxCaptureFileObject;
+
PAGED_CODE();
- FileObject = Context->CurrentIrpSp->FileObject;
/* If Cc isn't initialized, the file was not read nor written, nothing to do */
- if (FileObject->PrivateCacheMap == NULL)
+ if (capFileObject->PrivateCacheMap == NULL)
{
return;
}
/* Get now */
KeQuerySystemTime(&CurrentTime);
- Fobx = (PFOBX)Context->pFobx;
/* Was the file modified? */
- FileModified = BooleanFlagOn(FileObject->Flags, FO_FILE_MODIFIED);
+ FileModified = BooleanFlagOn(capFileObject->Flags, FO_FILE_MODIFIED);
/* We'll set last write if it was modified and user didn't update yet */
- SetLastWrite = FileModified && !BooleanFlagOn(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_WRITE);
+ SetLastWrite = FileModified && !BooleanFlagOn(capFobx->Flags, FOBX_FLAG_USER_SET_LAST_WRITE);
/* File was accessed if: written or read (fastio), we'll update last access if user didn't */
SetLastAccess = SetLastWrite ||
- (BooleanFlagOn(FileObject->Flags, FO_FILE_FAST_IO_READ) &&
- !BooleanFlagOn(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_ACCESS));
+ (BooleanFlagOn(capFileObject->Flags, FO_FILE_FAST_IO_READ) &&
+ !BooleanFlagOn(capFobx->Flags, FOBX_FLAG_USER_SET_LAST_ACCESS));
/* We'll set last change if it was modified and user didn't update yet */
- SetLastChange = FileModified && !BooleanFlagOn(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_CHANGE);
+ SetLastChange = FileModified && !BooleanFlagOn(capFobx->Flags, FOBX_FLAG_USER_SET_LAST_CHANGE);
/* Nothing to update? Job done */
if (!FileModified && !SetLastWrite && !SetLastAccess && !SetLastChange)
return;
}
- Fcb = (PFCB)Context->pFcb;
/* By default, we won't issue any MRxSetFileInfoAtCleanup call */
NeedUpdate = FALSE;
RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
if (SetLastWrite)
{
NeedUpdate = TRUE;
- Fcb->LastWriteTime.QuadPart = CurrentTime.QuadPart;
+ capFcb->LastWriteTime.QuadPart = CurrentTime.QuadPart;
FileBasicInfo.LastWriteTime.QuadPart = CurrentTime.QuadPart;
}
if (SetLastAccess)
{
NeedUpdate = TRUE;
- Fcb->LastAccessTime.QuadPart = CurrentTime.QuadPart;
+ capFcb->LastAccessTime.QuadPart = CurrentTime.QuadPart;
FileBasicInfo.LastAccessTime.QuadPart = CurrentTime.QuadPart;
}
if (SetLastChange)
{
NeedUpdate = TRUE;
- Fcb->LastChangeTime.QuadPart = CurrentTime.QuadPart;
+ capFcb->LastChangeTime.QuadPart = CurrentTime.QuadPart;
FileBasicInfo.ChangeTime.QuadPart = CurrentTime.QuadPart;
}
/* If one of the date was modified, issue a call to mini-rdr */
if (NeedUpdate)
{
- Context->Info.FileInformationClass = FileBasicInformation;
- Context->Info.Buffer = &FileBasicInfo;
- Context->Info.Length = sizeof(FileBasicInfo);
+ RxContext->Info.FileInformationClass = FileBasicInformation;
+ RxContext->Info.Buffer = &FileBasicInfo;
+ RxContext->Info.Length = sizeof(FileBasicInfo);
- MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxSetFileInfoAtCleanup, (Context));
+ MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxSetFileInfoAtCleanup, (RxContext));
(void)Status;
}
/* If the file was modified, update its EOF */
if (FileModified)
{
- FileEOFInfo.EndOfFile.QuadPart = Fcb->Header.FileSize.QuadPart;
+ FileEOFInfo.EndOfFile.QuadPart = capFcb->Header.FileSize.QuadPart;
- Context->Info.FileInformationClass = FileEndOfFileInformation;
- Context->Info.Buffer = &FileEOFInfo;
- Context->Info.Length = sizeof(FileEOFInfo);
+ RxContext->Info.FileInformationClass = FileEndOfFileInformation;
+ RxContext->Info.Buffer = &FileEOFInfo;
+ RxContext->Info.Length = sizeof(FileEOFInfo);
- MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxSetFileInfoAtCleanup, (Context));
+ MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxSetFileInfoAtCleanup, (RxContext));
(void)Status;
}
}
NET_ROOT_TYPE NetRootType;
UNICODE_STRING CanonicalName;
+ RxCaptureParamBlock;
+ RxCaptureFileObject;
+
PAGED_CODE();
NetRootType = NET_ROOT_WILD;
RtlInitEmptyUnicodeString(&CanonicalName, NULL, 0);
/* if not relative opening, just handle the passed name */
- if (RxContext->CurrentIrpSp->FileObject->RelatedFileObject == NULL)
+ if (capFileObject->RelatedFileObject == NULL)
{
Status = RxFirstCanonicalize(RxContext, FileName, &CanonicalName, &NetRootType);
if (!NT_SUCCESS(Status))
PFCB Fcb;
/* Make sure we have a valid FCB and a FOBX */
- Fcb = RxContext->CurrentIrpSp->FileObject->RelatedFileObject->FsContext;
- if (Fcb == NULL ||
- RxContext->CurrentIrpSp->FileObject->RelatedFileObject->FsContext2 == NULL)
+ Fcb = capFileObject->RelatedFileObject->FsContext;
+ if (Fcb == NULL || capFileObject->RelatedFileObject->FsContext2 == NULL)
{
return STATUS_INVALID_PARAMETER;
}
return Status;
}
+/*
+ * @implemented
+ */
VOID
NTAPI
RxCheckFcbStructuresForAlignment(
VOID)
{
- UNIMPLEMENTED;
+ PAGED_CODE();
}
#if DBG
RxCollapseOrCreateSrvOpen(
PRX_CONTEXT RxContext)
{
- PFCB Fcb;
NTSTATUS Status;
ULONG Disposition;
PSRV_OPEN SrvOpen;
USHORT ShareAccess;
- PIO_STACK_LOCATION Stack;
ACCESS_MASK DesiredAccess;
RX_BLOCK_CONDITION FcbCondition;
+ RxCaptureFcb;
+ RxCaptureParamBlock;
+
PAGED_CODE();
DPRINT("RxCollapseOrCreateSrvOpen(%p)\n", RxContext);
- Fcb = (PFCB)RxContext->pFcb;
- ASSERT(RxIsFcbAcquiredExclusive(Fcb));
- ++Fcb->UncleanCount;
+ ASSERT(RxIsFcbAcquiredExclusive(capFcb));
+ ++capFcb->UncleanCount;
- Stack = RxContext->CurrentIrpSp;
- DesiredAccess = Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_ALL_ACCESS;
- ShareAccess = Stack->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS;
+ DesiredAccess = capPARAMS->Parameters.Create.SecurityContext->DesiredAccess & FILE_ALL_ACCESS;
+ ShareAccess = capPARAMS->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS;
Disposition = RxContext->Create.NtCreateParameters.Disposition;
if (Status == STATUS_NOT_FOUND)
{
/* If none found, create one */
- SrvOpen = RxCreateSrvOpen((PV_NET_ROOT)RxContext->Create.pVNetRoot, Fcb);
+ SrvOpen = RxCreateSrvOpen((PV_NET_ROOT)RxContext->Create.pVNetRoot, capFcb);
if (SrvOpen == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
/* Cookie to check the mini-rdr doesn't mess with RX_CONTEXT */
RxContext->CurrentIrp->IoStatus.Information = 0xABCDEF;
/* Inform the mini-rdr we're handling a create */
- MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxCreate, (RxContext));
+ MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxCreate, (RxContext));
ASSERT(RxContext->CurrentIrp->IoStatus.Information == 0xABCDEF);
DPRINT("MRxCreate returned: %x\n", Status);
/* In case of overwrite, reset file size */
if (Disposition == FILE_OVERWRITE || Disposition == FILE_OVERWRITE_IF)
{
- RxAcquirePagingIoResource(RxContext, Fcb);
- Fcb->Header.AllocationSize.QuadPart = 0LL;
- Fcb->Header.FileSize.QuadPart = 0LL;
- Fcb->Header.ValidDataLength.QuadPart = 0LL;
- RxContext->CurrentIrpSp->FileObject->SectionObjectPointer = &Fcb->NonPaged->SectionObjectPointers;
- CcSetFileSizes(RxContext->CurrentIrpSp->FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
- RxReleasePagingIoResource(RxContext, Fcb);
+ RxAcquirePagingIoResource(RxContext, capFcb);
+ capFcb->Header.AllocationSize.QuadPart = 0LL;
+ capFcb->Header.FileSize.QuadPart = 0LL;
+ capFcb->Header.ValidDataLength.QuadPart = 0LL;
+ RxContext->CurrentIrpSp->FileObject->SectionObjectPointer = &capFcb->NonPaged->SectionObjectPointers;
+ CcSetFileSizes(RxContext->CurrentIrpSp->FileObject, (PCC_FILE_SIZES)&capFcb->Header.AllocationSize);
+ RxReleasePagingIoResource(RxContext, capFcb);
}
else
{
/* Otherwise, adjust sizes */
- RxContext->CurrentIrpSp->FileObject->SectionObjectPointer = &Fcb->NonPaged->SectionObjectPointers;
+ RxContext->CurrentIrpSp->FileObject->SectionObjectPointer = &capFcb->NonPaged->SectionObjectPointers;
if (CcIsFileCached(RxContext->CurrentIrpSp->FileObject))
{
- RxAdjustAllocationSizeforCC(Fcb);
+ RxAdjustAllocationSizeforCC(capFcb);
}
- CcSetFileSizes(RxContext->CurrentIrpSp->FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
+ CcSetFileSizes(RxContext->CurrentIrpSp->FileObject, (PCC_FILE_SIZES)&capFcb->Header.AllocationSize);
}
}
/* Set SRV_OPEN state - good or bad - depending on whether create succeed */
RxTransitionSrvOpen(SrvOpen, (Status == STATUS_SUCCESS ? Condition_Good : Condition_Bad));
- ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+ ASSERT(RxIsFcbAcquiredExclusive(capFcb));
RxCompleteSrvOpenKeyAssociation(SrvOpen);
if (Status == STATUS_SUCCESS)
{
- if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_DELETE_ON_CLOSE))
+ if (BooleanFlagOn(capPARAMS->Parameters.Create.Options, FILE_DELETE_ON_CLOSE))
{
- ClearFlag(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED);
+ ClearFlag(capFcb->FcbState, FCB_STATE_COLLAPSING_ENABLED);
}
SrvOpen->CreateOptions = RxContext->Create.NtCreateParameters.CreateOptions;
FcbCondition = Condition_Good;
}
/* Set FCB state - good or bad - depending on whether create succeed */
- DPRINT("Transitioning FCB %p to condition %lx\n", Fcb, Fcb->Condition);
- RxTransitionNetFcb(Fcb, FcbCondition);
+ DPRINT("Transitioning FCB %p to condition %lx\n", capFcb, capFcb->Condition);
+ RxTransitionNetFcb(capFcb, FcbCondition);
}
else if (Status == STATUS_SUCCESS)
{
++SrvOpen->OpenCount;
ExtraOpen = TRUE;
- RxReleaseFcb(RxContext, Fcb);
+ RxReleaseFcb(RxContext, capFcb);
RxContext->Create.FcbAcquired = FALSE;
RxWaitForStableSrvOpen(SrvOpen, RxContext);
- if (NT_SUCCESS(RxAcquireExclusiveFcb(RxContext, Fcb)))
+ if (NT_SUCCESS(RxAcquireExclusiveFcb(RxContext, capFcb)))
{
RxContext->Create.FcbAcquired = TRUE;
}
/* Inform the mini-rdr we do an opening with a reused SRV_OPEN */
if (IsGood)
{
- MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxCollapseOpen, (RxContext));
+ MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxCollapseOpen, (RxContext));
- ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+ ASSERT(RxIsFcbAcquiredExclusive(capFcb));
}
else
{
}
}
- --Fcb->UncleanCount;
+ --capFcb->UncleanCount;
DPRINT("Status: %x\n", Status);
return Status;
return STATUS_SUCCESS;
}
+/*
+ * @implemented
+ */
+VOID
+RxConjureOriginalName(
+ PFCB Fcb,
+ PFOBX Fobx,
+ PULONG ActualNameLength,
+ PWCHAR OriginalName,
+ PLONG LengthRemaining,
+ RX_NAME_CONJURING_METHODS NameConjuringMethod)
+{
+ PWSTR Prefix, Name;
+ PV_NET_ROOT VNetRoot;
+ USHORT PrefixLength, NameLength, ToCopy;
+
+ PAGED_CODE();
+
+ VNetRoot = Fcb->VNetRoot;
+ /* We will use the prefix contained in NET_ROOT, if we don't have
+ * a V_NET_ROOT, or if it wasn't null deviced or if we already have
+ * a UNC path */
+ if (VNetRoot == NULL || VNetRoot->PrefixEntry.Prefix.Buffer[1] != L';' ||
+ BooleanFlagOn(Fobx->Flags, FOBX_FLAG_UNC_NAME))
+ {
+ Prefix = ((PNET_ROOT)Fcb->pNetRoot)->PrefixEntry.Prefix.Buffer;
+ PrefixLength = ((PNET_ROOT)Fcb->pNetRoot)->PrefixEntry.Prefix.Length;
+ NameLength = 0;
+
+ /* In that case, keep track that we will have a prefix as buffer */
+ NameConjuringMethod = VNetRoot_As_Prefix;
+ }
+ else
+ {
+ ASSERT(NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT);
+
+ /* Otherwise, return the prefix from our V_NET_ROOT */
+ Prefix = VNetRoot->PrefixEntry.Prefix.Buffer;
+ PrefixLength = VNetRoot->PrefixEntry.Prefix.Length;
+ NameLength = VNetRoot->NamePrefix.Length;
+
+ /* If we want a UNC path, skip potential device */
+ if (NameConjuringMethod == VNetRoot_As_UNC_Name)
+ {
+ do
+ {
+ ++Prefix;
+ PrefixLength -= sizeof(WCHAR);
+ } while (PrefixLength > 0 && Prefix[0] != L'\\');
+ }
+ }
+
+ /* If we added an extra backslash, skip it */
+ if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_ADDEDBACKSLASH))
+ {
+ NameLength += sizeof(WCHAR);
+ }
+
+ /* If we're asked for a drive letter, skip the prefix */
+ if (NameConjuringMethod == VNetRoot_As_DriveLetter)
+ {
+ PrefixLength = 0;
+
+ /* And make sure we arrive at a backslash */
+ if (Fcb->FcbTableEntry.Path.Length > NameLength &&
+ Fcb->FcbTableEntry.Path.Buffer[NameLength / sizeof(WCHAR)] != L'\\')
+ {
+ NameLength -= sizeof(WCHAR);
+ }
+ }
+ else
+ {
+ /* Prepare to copy the prefix, make sure not to overflow */
+ if (*LengthRemaining >= PrefixLength)
+ {
+ /* Copy everything */
+ ToCopy = PrefixLength;
+ *LengthRemaining = *LengthRemaining - PrefixLength;
+ }
+ else
+ {
+ /* Copy as much as we can */
+ ToCopy = *LengthRemaining;
+ /* And return failure */
+ *LengthRemaining = -1;
+ }
+
+ /* Copy the prefix */
+ RtlCopyMemory(OriginalName, Prefix, ToCopy);
+ }
+
+ /* Do we have a name to copy now? */
+ if (Fcb->FcbTableEntry.Path.Length > NameLength)
+ {
+ ToCopy = Fcb->FcbTableEntry.Path.Length - NameLength;
+ Name = Fcb->FcbTableEntry.Path.Buffer;
+ }
+ else
+ {
+ /* Just use slash for now */
+ ToCopy = sizeof(WCHAR);
+ NameLength = 0;
+ Name = L"\\";
+ }
+
+ /* Total length we will have in the output buffer (if everything is alright) */
+ *ActualNameLength = ToCopy + PrefixLength;
+ /* If we still have room to write data */
+ if (*LengthRemaining != -1)
+ {
+ /* If we can copy everything, it's fine! */
+ if (*LengthRemaining > ToCopy)
+ {
+ *LengthRemaining = *LengthRemaining - ToCopy;
+ }
+ /* Otherwise, copy as much as possible, and return failure */
+ else
+ {
+ ToCopy = *LengthRemaining;
+ *LengthRemaining = -1;
+ }
+
+ /* Copy name after the prefix */
+ RtlCopyMemory(Add2Ptr(OriginalName, PrefixLength),
+ Add2Ptr(Name, NameLength), ToCopy);
+ }
+}
+
/*
* @implemented
*/
UNIMPLEMENTED;
}
-VOID
-NTAPI
-RxInitializeDebugSupport(
- VOID)
-{
- UNIMPLEMENTED;
-}
-
/*
* @implemented
*/
return STATUS_NOT_IMPLEMENTED;
}
+/*
+ * @implemented
+ */
NTSTATUS
RxQueryNameInfo(
PRX_CONTEXT RxContext,
PFILE_NAME_INFORMATION NameInfo)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PFCB Fcb;
+ PFOBX Fobx;
+ PAGED_CODE();
+
+ DPRINT("RxQueryNameInfo(%p, %p)\n", RxContext, NameInfo);
+
+ /* Check we can at least copy name size */
+ if (RxContext->Info.LengthRemaining < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
+ {
+ DPRINT1("Buffer too small: %d\n", RxContext->Info.LengthRemaining);
+ RxContext->Info.Length = 0;
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ Fcb = (PFCB)RxContext->pFcb;
+ Fobx = (PFOBX)RxContext->pFobx;
+ /* Get the UNC name */
+ RxConjureOriginalName(Fcb, Fobx, &NameInfo->FileNameLength, &NameInfo->FileName[0],
+ &RxContext->Info.Length, VNetRoot_As_UNC_Name);
+
+ /* If RxConjureOriginalName returned a negative len (-1) then output buffer
+ * was too small, return the appropriate length & status.
+ */
+ if (RxContext->Info.LengthRemaining < 0)
+ {
+ DPRINT1("Buffer too small!\n");
+ RxContext->Info.Length = 0;
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ /* All correct */
+ return STATUS_SUCCESS;
}
NTSTATUS