mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 17:03:12 -05:00
sys: FileRenameResource implementation
This commit is contained in:
parent
3ef9042071
commit
9c200f2a62
@ -12,6 +12,8 @@ static NTSTATUS FspFsvrtCreate(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static NTSTATUS FspFsvolCreate(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static NTSTATUS FspFsvolCreateNoLock(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
|
||||
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
|
||||
@ -27,6 +29,7 @@ FSP_DRIVER_DISPATCH FspCreate;
|
||||
#pragma alloc_text(PAGE, FspFsctlCreate)
|
||||
#pragma alloc_text(PAGE, FspFsvrtCreate)
|
||||
#pragma alloc_text(PAGE, FspFsvolCreate)
|
||||
#pragma alloc_text(PAGE, FspFsvolCreateNoLock)
|
||||
#pragma alloc_text(PAGE, FspFsvolCreatePrepare)
|
||||
#pragma alloc_text(PAGE, FspFsvolCreateComplete)
|
||||
#pragma alloc_text(PAGE, FspFsvolCreateTryOpen)
|
||||
@ -43,14 +46,16 @@ FSP_DRIVER_DISPATCH FspCreate;
|
||||
enum
|
||||
{
|
||||
/* Create */
|
||||
RequestFileDesc = 0,
|
||||
RequestAccessToken = 1,
|
||||
RequestProcess = 2,
|
||||
RequestDeviceObject = 0,
|
||||
RequestFileDesc = 1,
|
||||
RequestAccessToken = 2,
|
||||
RequestProcess = 3,
|
||||
|
||||
/* TryOpen/Overwrite */
|
||||
//RequestFileDesc = 0,
|
||||
RequestFileObject = 1,
|
||||
RequestState = 2,
|
||||
//RequestDeviceObject = 0,
|
||||
//RequestFileDesc = 1,
|
||||
RequestFileObject = 2,
|
||||
RequestState = 3,
|
||||
|
||||
/* RequestState */
|
||||
RequestPending = 0,
|
||||
@ -92,6 +97,27 @@ static NTSTATUS FspFsvolCreate(
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result = STATUS_SUCCESS;
|
||||
|
||||
FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject);
|
||||
try
|
||||
{
|
||||
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (FSP_STATUS_IOQ_POST != Result)
|
||||
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolCreateNoLock(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result;
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
@ -180,6 +206,11 @@ static NTSTATUS FspFsvolCreate(
|
||||
{
|
||||
RelatedFileNode = RelatedFileObject->FsContext;
|
||||
|
||||
/*
|
||||
* Accesses of RelatedFileNode->FileName are protected
|
||||
* by FSP_FSVOL_DEVICE_EXTENSION::FileRenameResource.
|
||||
*/
|
||||
|
||||
/* is this a valid RelatedFileObject? */
|
||||
if (!FspFileNodeIsValid(RelatedFileNode))
|
||||
return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
@ -202,12 +233,6 @@ static NTSTATUS FspFsvolCreate(
|
||||
sizeof(WCHAR) == RelatedFileNode->FileName.Length && 0 == FileName.Length)
|
||||
return STATUS_CANNOT_DELETE;
|
||||
|
||||
/*
|
||||
* There is no need to lock our accesses of RelatedFileObject->FileNode->FileName,
|
||||
* because RelatedFileObject->FileNode->Filename is read-only (after creation) and
|
||||
* because RelatedFileObject->FileNode is guaranteed to exist while RelatedFileObject
|
||||
* exists.
|
||||
*/
|
||||
BOOLEAN AppendBackslash =
|
||||
sizeof(WCHAR) * 2/* not empty or root */ <= RelatedFileNode->FileName.Length &&
|
||||
sizeof(WCHAR) <= FileName.Length && L':' != FileName.Buffer[0];
|
||||
@ -320,6 +345,8 @@ static NTSTATUS FspFsvolCreate(
|
||||
* delete the Request and any associated resources.
|
||||
*/
|
||||
FileDesc->FileNode = FileNode;
|
||||
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request);
|
||||
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
|
||||
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
|
||||
|
||||
/* populate the Create request */
|
||||
@ -589,25 +616,20 @@ NTSTATUS FspFsvolCreateComplete(
|
||||
if (FileNode->IsDirectory)
|
||||
SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
|
||||
|
||||
/* delete the old request */
|
||||
FspIrpRequest(Irp) = 0;
|
||||
/* disassociate the FileDesc momentarily from the Request */
|
||||
FspIopRequestContext(Request, RequestDeviceObject) = 0;
|
||||
FspIopRequestContext(Request, RequestFileDesc) = 0;
|
||||
/* disassociate the FileDesc from the old Request as we want to keep it around! */
|
||||
FspIopDeleteRequest(Request);
|
||||
|
||||
/* create the Overwrite request; MustSucceed because we must either overwrite or close */
|
||||
FspIopCreateRequestFunnel(Irp,
|
||||
FsvolDeviceExtension->VolumeParams.FileNameRequired ? &FileNode->FileName : 0, 0,
|
||||
FspFsvolCreateOverwriteRequestFini, TRUE,
|
||||
&Request);
|
||||
|
||||
/* associate the FileDesc and FileObject with the Overwrite request */
|
||||
/* reset the request */
|
||||
Request->Kind = FspFsctlTransactOverwriteKind;
|
||||
RtlZeroMemory(&Request->Req.Create, sizeof Request->Req.Create);
|
||||
FspIopResetRequest(Request, FspFsvolCreateOverwriteRequestFini);
|
||||
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
|
||||
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
|
||||
FspIopRequestContext(Request, RequestFileObject) = FileObject;
|
||||
FspIopRequestContext(Request, RequestState) = (PVOID)RequestPending;
|
||||
|
||||
/* populate the Overwrite request */
|
||||
Request->Kind = FspFsctlTransactOverwriteKind;
|
||||
Request->Req.Overwrite.UserContext = FileNode->UserContext;
|
||||
Request->Req.Overwrite.UserContext2 = FileDesc->UserContext2;
|
||||
Request->Req.Overwrite.FileAttributes = FileAttributes;
|
||||
@ -681,13 +703,17 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
|
||||
|
||||
if (FspFsctlTransactCreateKind == Request->Kind)
|
||||
{
|
||||
PDEVICE_OBJECT FsvolDeviceObject = FspIopRequestContext(Request, RequestDeviceObject);
|
||||
|
||||
/* disassociate the FileDesc momentarily from the Request */
|
||||
Request = FspIrpRequest(Irp);
|
||||
FspIopRequestContext(Request, RequestDeviceObject) = 0;
|
||||
FspIopRequestContext(Request, RequestFileDesc) = 0;
|
||||
|
||||
/* reset the Request and reassociate the FileDesc and FileObject with it */
|
||||
Request->Kind = FspFsctlTransactReservedKind;
|
||||
FspIopResetRequest(Request, FspFsvolCreateTryOpenRequestFini);
|
||||
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
|
||||
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
|
||||
FspIopRequestContext(Request, RequestFileObject) = FileObject;
|
||||
FspIopRequestContext(Request, RequestState) = (PVOID)(UINT_PTR)FlushImage;
|
||||
@ -761,10 +787,11 @@ static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc)
|
||||
*/
|
||||
}
|
||||
|
||||
static VOID FspFsvolCreateRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3])
|
||||
static VOID FspFsvolCreateRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
PDEVICE_OBJECT FsvolDeviceObject = Context[RequestDeviceObject];
|
||||
FSP_FILE_DESC *FileDesc = Context[RequestFileDesc];
|
||||
HANDLE AccessToken = Context[RequestAccessToken];
|
||||
PEPROCESS Process = Context[RequestProcess];
|
||||
@ -798,12 +825,16 @@ static VOID FspFsvolCreateRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Con
|
||||
|
||||
ObDereferenceObject(Process);
|
||||
}
|
||||
|
||||
if (0 != FsvolDeviceObject)
|
||||
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, Request);
|
||||
}
|
||||
|
||||
static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3])
|
||||
static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
PDEVICE_OBJECT FsvolDeviceObject = Context[RequestDeviceObject];
|
||||
FSP_FILE_DESC *FileDesc = Context[RequestFileDesc];
|
||||
PFILE_OBJECT FileObject = Context[RequestFileObject];
|
||||
|
||||
@ -816,12 +847,16 @@ static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PV
|
||||
FspFileNodeDereference(FileDesc->FileNode);
|
||||
FspFileDescDelete(FileDesc);
|
||||
}
|
||||
|
||||
if (0 != FsvolDeviceObject)
|
||||
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, Request);
|
||||
}
|
||||
|
||||
static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3])
|
||||
static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
PDEVICE_OBJECT FsvolDeviceObject = Context[RequestDeviceObject];
|
||||
FSP_FILE_DESC *FileDesc = Context[RequestFileDesc];
|
||||
PFILE_OBJECT FileObject = Context[RequestFileObject];
|
||||
ULONG State = (ULONG)(UINT_PTR)Context[RequestState];
|
||||
@ -839,6 +874,9 @@ static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
FspFileNodeDereference(FileDesc->FileNode);
|
||||
FspFileDescDelete(FileDesc);
|
||||
}
|
||||
|
||||
if (0 != FsvolDeviceObject)
|
||||
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, Request);
|
||||
}
|
||||
|
||||
NTSTATUS FspCreate(
|
||||
|
@ -25,6 +25,11 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject);
|
||||
static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject);
|
||||
static IO_TIMER_ROUTINE FspFsvolDeviceTimerRoutine;
|
||||
static WORKER_THREAD_ROUTINE FspFsvolDeviceExpirationRoutine;
|
||||
VOID FspFsvolDeviceFileRenameAcquireShared(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceFileRenameAcquireExclusive(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceFileRenameSetOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
|
||||
VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
|
||||
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject);
|
||||
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier);
|
||||
@ -60,6 +65,11 @@ VOID FspDeviceDeleteAll(VOID);
|
||||
#pragma alloc_text(PAGE, FspDeviceDelete)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceInit)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceFini)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameAcquireShared)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameAcquireExclusive)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameSetOwner)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameRelease)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameReleaseOwner)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceLockContextTable)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceUnlockContextTable)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceLookupContext)
|
||||
@ -437,6 +447,58 @@ static VOID FspFsvolDeviceExpirationRoutine(PVOID Context)
|
||||
FspDeviceDereference(DeviceObject);
|
||||
}
|
||||
|
||||
VOID FspFsvolDeviceFileRenameAcquireShared(PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
|
||||
ExAcquireResourceSharedLite(&FsvolDeviceExtension->FileRenameResource, TRUE);
|
||||
}
|
||||
|
||||
VOID FspFsvolDeviceFileRenameAcquireExclusive(PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
|
||||
ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->FileRenameResource, TRUE);
|
||||
}
|
||||
|
||||
VOID FspFsvolDeviceFileRenameSetOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
|
||||
Owner = (PVOID)((UINT_PTR)Owner | 3);
|
||||
|
||||
ExSetResourceOwnerPointer(&FsvolDeviceExtension->FileRenameResource, Owner);
|
||||
}
|
||||
|
||||
VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
|
||||
ExReleaseResourceLite(&FsvolDeviceExtension->FileRenameResource);
|
||||
}
|
||||
|
||||
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
|
||||
Owner = (PVOID)((UINT_PTR)Owner | 3);
|
||||
|
||||
if (ExIsResourceAcquiredLite(&FsvolDeviceExtension->FileRenameResource))
|
||||
ExReleaseResourceLite(&FsvolDeviceExtension->FileRenameResource);
|
||||
else
|
||||
ExReleaseResourceForThreadLite(&FsvolDeviceExtension->FileRenameResource, (ERESOURCE_THREAD)Owner);
|
||||
}
|
||||
|
||||
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
@ -419,7 +419,7 @@ PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp);
|
||||
#define FspIopPostWorkRequestBestEffort(D, R)\
|
||||
FspIopPostWorkRequestFunnel(D, R, TRUE)
|
||||
#define FspIopCompleteIrp(I, R) FspIopCompleteIrpEx(I, R, TRUE)
|
||||
typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3]);
|
||||
typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4]);
|
||||
NTSTATUS FspIopCreateRequestFunnel(
|
||||
PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini,
|
||||
BOOLEAN MustSucceed,
|
||||
@ -522,6 +522,11 @@ NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject);
|
||||
BOOLEAN FspDeviceReference(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspDeviceDereference(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceFileRenameAcquireShared(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceFileRenameAcquireExclusive(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceFileRenameSetOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
|
||||
VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
|
||||
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject);
|
||||
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier);
|
||||
|
@ -851,7 +851,7 @@ NTSTATUS FspFsvolSetInformationComplete(
|
||||
IrpSp->FileObject);
|
||||
}
|
||||
|
||||
static VOID FspFsvolInformationRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3])
|
||||
static VOID FspFsvolInformationRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
|
@ -84,7 +84,7 @@ static PVOID FspAllocateIrpMustSucceed(CCHAR StackSize)
|
||||
typedef struct
|
||||
{
|
||||
FSP_IOP_REQUEST_FINI *RequestFini;
|
||||
PVOID Context[3];
|
||||
PVOID Context[4];
|
||||
FSP_FSCTL_TRANSACT_RSP *Response;
|
||||
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 RequestBuf[];
|
||||
} FSP_FSCTL_TRANSACT_REQ_HEADER;
|
||||
|
Loading…
x
Reference in New Issue
Block a user