From: Pierre Schweitzer Date: Sat, 5 Aug 2017 08:12:23 +0000 (+0000) Subject: [RDBSS] X-Git-Tag: backups/GSoC_2017/rapps@75905~4^2~193 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=98d7d08cbf2aec929ef392f750e86ed52f07c5e4 [RDBSS] - Implement RxSetRenameInfo() - Implement the SL_OPEN_TARGET_DIRECTORY case in RxCreateFromNetRoot() This implements renaming in RDBSS, and thus in NFS. So far, renaming fails due to different NET_ROOT, I need to check why. So far, files are properly copied on rename failure. CORE-8204 CORE-11327 CORE-13632 svn path=/trunk/; revision=75487 --- diff --git a/reactos/sdk/lib/drivers/rdbsslib/rdbss.c b/reactos/sdk/lib/drivers/rdbsslib/rdbss.c index 904befe1094..84b172e7353 100644 --- a/reactos/sdk/lib/drivers/rdbsslib/rdbss.c +++ b/reactos/sdk/lib/drivers/rdbsslib/rdbss.c @@ -4909,11 +4909,63 @@ RxCreateFromNetRoot( DesiredAccess = Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_ALL_ACCESS; - /* We don't support renaming yet */ + /* Get file object */ + FileObject = Stack->FileObject; + + /* Do we have to open target directory for renaming? */ if (BooleanFlagOn(Stack->Flags, SL_OPEN_TARGET_DIRECTORY)) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + DPRINT("Opening target directory\n"); + + /* If we have been asked for delete, try to purge first */ + if (BooleanFlagOn(Context->Create.NtCreateParameters.DesiredAccess, DELETE)) + { + RxPurgeRelatedFobxs((PNET_ROOT)Context->Create.pVNetRoot->pNetRoot, Context, + ATTEMPT_FINALIZE_ON_PURGE, NULL); + } + + /* Create the FCB */ + Fcb = RxCreateNetFcb(Context, (PV_NET_ROOT)Context->Create.pVNetRoot, NetRootName); + if (Fcb == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Fake it: it will be used only renaming */ + NodeType(Fcb) = RDBSS_NTC_OPENTARGETDIR_FCB; + Context->Create.FcbAcquired = FALSE; + Context->Create.NetNamePrefixEntry = NULL; + + /* Assign it to the FO */ + FileObject->FsContext = Fcb; + + /* If we have a FOBX already, check whether it's for DFS opening */ + if (Context->pFobx != NULL) + { + /* If so, reflect this in the FOBX */ + if (NodeType(FileObject->FsContext2) == DFS_OPEN_CONTEXT) + { + SetFlag(Context->pFobx->Flags, FOBX_FLAG_DFS_OPEN); + } + else + { + ClearFlag(Context->pFobx->Flags, FOBX_FLAG_DFS_OPEN); + } + } + + /* Acquire the FCB */ + Status = RxAcquireExclusiveFcb(Context, Fcb); + if (Status != STATUS_SUCCESS) + { + return Status; + } + + /* Reference the FCB and release */ + RxReferenceNetFcb(Fcb); + RxReleaseFcb(Context, Fcb); + + /* We're done! */ + return STATUS_SUCCESS; } /* Try to find (or create) the FCB for the file */ @@ -4948,7 +5000,6 @@ RxCreateFromNetRoot( } /* Not mailslot! */ - FileObject = Stack->FileObject; /* Check SA for conflict */ if (Fcb->OpenCount > 0) { @@ -8672,12 +8723,77 @@ RxSetPositionInfo( return STATUS_NOT_IMPLEMENTED; } +/* + * @implemented + */ NTSTATUS RxSetRenameInfo( PRX_CONTEXT RxContext) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + ULONG Length; + NTSTATUS Status; + PFCB RenameFcb, Fcb; + PIO_STACK_LOCATION Stack; + PFILE_RENAME_INFORMATION RenameInfo, UserInfo; + + PAGED_CODE(); + + DPRINT("RxSetRenameInfo(%p)\n", RxContext); + + Stack = RxContext->CurrentIrpSp; + DPRINT("FO: %p, Replace: %d\n", Stack->Parameters.SetFile.FileObject, Stack->Parameters.SetFile.ReplaceIfExists); + + /* If there's no FO, we won't do extra operation, so directly pass to mini-rdr and quit */ + RxContext->Info.ReplaceIfExists = Stack->Parameters.SetFile.ReplaceIfExists; + if (Stack->Parameters.SetFile.FileObject == NULL) + { + return RxpSetInfoMiniRdr(RxContext, Stack->Parameters.SetFile.FileInformationClass); + } + + Fcb = (PFCB)RxContext->pFcb; + RenameFcb = Stack->Parameters.SetFile.FileObject->FsContext; + /* First, validate the received file object */ + ASSERT(NodeType(RenameFcb) == RDBSS_NTC_OPENTARGETDIR_FCB); + if (Fcb->pNetRoot != RenameFcb->pNetRoot) + { + DPRINT1("Not the same device: %p:%p (%wZ) - %p:%p (%wZ)\n", Fcb, Fcb->pNetRoot, Fcb->pNetRoot->pNetRootName, RenameFcb, RenameFcb->pNetRoot, RenameFcb->pNetRoot->pNetRootName); + return STATUS_NOT_SAME_DEVICE; + } + + /* We'll reallocate a safe buffer */ + Length = Fcb->pNetRoot->DiskParameters.RenameInfoOverallocationSize + RenameFcb->FcbTableEntry.Path.Length + FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName); + RenameInfo = RxAllocatePoolWithTag(PagedPool, Length, '??xR'); + if (RenameInfo == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + _SEH2_TRY + { + /* Copy the data */ + UserInfo = RxContext->CurrentIrp->AssociatedIrp.SystemBuffer; + RenameInfo->ReplaceIfExists = UserInfo->ReplaceIfExists; + RenameInfo->RootDirectory = UserInfo->RootDirectory; + RenameInfo->FileNameLength = RenameFcb->FcbTableEntry.Path.Length; + RtlMoveMemory(&RenameInfo->FileName[0], RenameFcb->FcbTableEntry.Path.Buffer, RenameFcb->FcbTableEntry.Path.Length); + + /* Set them in the RX_CONTEXT */ + RxContext->Info.FileInformationClass = Stack->Parameters.SetFile.FileInformationClass; + RxContext->Info.Buffer = RenameInfo; + RxContext->Info.Length = Length; + + /* And call the mini-rdr */ + MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxSetFileInfo, (RxContext)); + } + _SEH2_FINALLY + { + /* Free */ + RxFreePoolWithTag(RenameInfo, '??xR'); + } + _SEH2_END; + + /* Done! */ + return Status; } #if DBG