mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 17:03:12 -05:00
sys: IRP_MJ_CREATE: FspFsvolCreateRequestFini
This commit is contained in:
parent
d21180cba0
commit
0c62199c73
103
src/sys/create.c
103
src/sys/create.c
@ -16,6 +16,7 @@ FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
|
||||
static VOID FspFsvolCreateCleanupClose(
|
||||
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||
FSP_IOP_REQUEST_FINI FspFsvolCreateRequestFini;
|
||||
FSP_DRIVER_DISPATCH FspCreate;
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
@ -25,9 +26,17 @@ FSP_DRIVER_DISPATCH FspCreate;
|
||||
#pragma alloc_text(PAGE, FspFsvolCreatePrepare)
|
||||
#pragma alloc_text(PAGE, FspFsvolCreateComplete)
|
||||
#pragma alloc_text(PAGE, FspFsvolCreateCleanupClose)
|
||||
#pragma alloc_text(PAGE, FspFsvolCreateRequestFini)
|
||||
#pragma alloc_text(PAGE, FspCreate)
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
ContextFileObject = 0,
|
||||
ContextFsContext,
|
||||
ContextAccessToken,
|
||||
};
|
||||
|
||||
static NTSTATUS FspFsctlCreate(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
@ -90,7 +99,7 @@ static NTSTATUS FspFsvolCreate(
|
||||
/* cannot open the volume object */
|
||||
if (0 == RelatedFileObject && 0 == FileName.Length)
|
||||
{
|
||||
Result = STATUS_ACCESS_DENIED; /* need error code like POSIX EPERM (STATUS_NOT_SUPPORTED?) */
|
||||
Result = STATUS_ACCESS_DENIED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -256,21 +265,21 @@ static NTSTATUS FspFsvolCreate(
|
||||
Result = RtlAppendUnicodeStringToString(&FsContext->FileName, &FileName);
|
||||
ASSERT(NT_SUCCESS(Result));
|
||||
|
||||
/*
|
||||
* From this point forward we MUST remember to delete the FsContext on error.
|
||||
*/
|
||||
|
||||
/* create the user-mode file system request */
|
||||
Result = FspIopCreateRequest(Irp, &FsContext->FileName, SecurityDescriptorSize, &Request);
|
||||
Result = FspIopCreateRequestEx(Irp, &FsContext->FileName, SecurityDescriptorSize,
|
||||
FspFsvolCreateRequestFini, &Request);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileContextDelete(FsContext);
|
||||
FspFileContextRelease(FsContext);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* The new request is associated with our IRP and will be deleted during its completion.
|
||||
* Go ahead and associate the FileObject and FsContext with the Request as well.
|
||||
*/
|
||||
FspIopRequestContext(Request, ContextFileObject) = FileObject;
|
||||
FspIopRequestContext(Request, ContextFsContext) = FsContext;
|
||||
|
||||
/* populate the Create request */
|
||||
Request->Kind = FspFsctlTransactCreateKind;
|
||||
@ -297,9 +306,8 @@ static NTSTATUS FspFsvolCreate(
|
||||
Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, &SecurityDescriptorSize);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileContextDelete(FsContext);
|
||||
if (STATUS_BAD_DESCRIPTOR_FORMAT == Result || STATUS_BUFFER_TOO_SMALL == Result)
|
||||
return STATUS_INVALID_PARAMETER; /* should not happen */
|
||||
Result = STATUS_INVALID_PARAMETER; /* should not happen */
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@ -307,19 +315,6 @@ static NTSTATUS FspFsvolCreate(
|
||||
RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
|
||||
SecurityDescriptor, SecurityDescriptorSize);
|
||||
|
||||
/*
|
||||
* Post the IRP to our Ioq; we do this here instead of at FSP_LEAVE_MJ time,
|
||||
* so that we can FspFileContextDelete() on failure.
|
||||
*/
|
||||
if (!FspIoqPostIrp(&FsvrtDeviceExtension->Ioq, Irp))
|
||||
{
|
||||
/* this can only happen if the Ioq was stopped */
|
||||
ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq));
|
||||
FspFileContextDelete(FsContext);
|
||||
Result = STATUS_CANCELLED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
FileObject->FsContext = FsContext;
|
||||
|
||||
Result = STATUS_PENDING;
|
||||
@ -357,15 +352,10 @@ NTSTATUS FspFsvolCreatePrepare(
|
||||
Result = ObOpenObjectByPointer(SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext),
|
||||
0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
FspFileContextDelete(FileObject->FsContext);
|
||||
FileObject->FsContext = 0;
|
||||
FSP_RETURN();
|
||||
}
|
||||
|
||||
/* send the user-mode handle to the user-mode file system */
|
||||
FspIrpContextHandle(Irp) = UserModeAccessToken;
|
||||
FspIopRequestContext(Request, ContextAccessToken) = UserModeAccessToken;
|
||||
Request->Req.Create.AccessToken = (UINT_PTR)UserModeAccessToken;
|
||||
|
||||
FSP_LEAVE_IOP();
|
||||
@ -394,6 +384,7 @@ VOID FspFsvolCreateComplete(
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
||||
FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject);
|
||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIopRequest(Irp);
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState;
|
||||
ULONG CreateOptions = IrpSp->Parameters.Create.Options;
|
||||
@ -415,9 +406,6 @@ VOID FspFsvolCreateComplete(
|
||||
/* did the user-mode file system sent us a failure code? */
|
||||
if (!NT_SUCCESS(Response->IoStatus.Status))
|
||||
{
|
||||
FspFileContextDelete(FileObject->FsContext);
|
||||
FileObject->FsContext = 0;
|
||||
|
||||
Irp->IoStatus.Information = Response->IoStatus.Information;
|
||||
Result = Response->IoStatus.Status;
|
||||
FSP_RETURN();
|
||||
@ -437,16 +425,13 @@ VOID FspFsvolCreateComplete(
|
||||
if (0 == ReparseFileName.Length ||
|
||||
(PUINT8)ReparseFileName.Buffer + ReparseFileName.Length >
|
||||
(PUINT8)Response + Response->Size)
|
||||
goto reparse_fail;
|
||||
FSP_RETURN();
|
||||
|
||||
if (ReparseFileName.Length > FileObject->FileName.MaximumLength)
|
||||
{
|
||||
PVOID Buffer = ExAllocatePoolWithTag(NonPagedPool, ReparseFileName.Length, FSP_TAG);
|
||||
if (0 == Buffer)
|
||||
{
|
||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto reparse_fail;
|
||||
}
|
||||
FSP_RETURN(Result = STATUS_INSUFFICIENT_RESOURCES);
|
||||
ExFreePool(FileObject->FileName.Buffer);
|
||||
FileObject->FileName.MaximumLength = ReparseFileName.Length;
|
||||
FileObject->FileName.Buffer = Buffer;
|
||||
@ -458,19 +443,14 @@ VOID FspFsvolCreateComplete(
|
||||
if (IO_REMOUNT == Response->IoStatus.Information)
|
||||
{
|
||||
if (0 != ReparseFileName.Length)
|
||||
goto reparse_fail;
|
||||
FSP_RETURN();
|
||||
}
|
||||
else
|
||||
goto reparse_fail;
|
||||
FSP_RETURN();
|
||||
|
||||
Irp->IoStatus.Information = Response->IoStatus.Information;
|
||||
Result = Response->IoStatus.Status;
|
||||
FSP_RETURN();
|
||||
|
||||
reparse_fail:
|
||||
FspFileContextDelete(FileObject->FsContext);
|
||||
FileObject->FsContext = 0;
|
||||
FSP_RETURN();
|
||||
}
|
||||
|
||||
/* record the user-mode file system contexts */
|
||||
@ -629,11 +609,17 @@ VOID FspFsvolCreateComplete(
|
||||
FSP_RETURN();
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks like SUCCESS! Disassociate our FileObject and FileObject->FsContext from the Request.
|
||||
*/
|
||||
FspIopRequestContext(Request, ContextFileObject) = 0;
|
||||
FspIopRequestContext(Request, ContextFsContext) = 0;
|
||||
|
||||
/* did an FsContext with the same UserContext already exist? */
|
||||
if (!Inserted)
|
||||
{
|
||||
/* delete the newly created FsContext and use the existing one */
|
||||
FspFileContextDelete(FileObject->FsContext);
|
||||
FspFileContextRelease(FileObject->FsContext);
|
||||
FileObject->FsContext = FsContext;
|
||||
}
|
||||
|
||||
@ -709,9 +695,32 @@ leak_exit:;
|
||||
UserContext, UserContext2);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
FspFileContextDelete(FsContext);
|
||||
FileObject->FsContext = 0;
|
||||
exit:;
|
||||
}
|
||||
|
||||
VOID FspFsvolCreateRequestFini(PVOID Context[3])
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if (0 != Context[ContextFsContext])
|
||||
{
|
||||
PFILE_OBJECT FileObject = Context[ContextFileObject];
|
||||
if (0 != FileObject && FileObject->FsContext == Context[ContextFsContext])
|
||||
FileObject->FsContext = 0;
|
||||
FspFileContextRelease(Context[ContextFsContext]);
|
||||
}
|
||||
|
||||
if (0 != Context[ContextAccessToken])
|
||||
{
|
||||
#if DBG
|
||||
NTSTATUS Result0;
|
||||
Result0 = ObCloseHandle(Context[ContextAccessToken], KernelMode);
|
||||
if (!NT_SUCCESS(Result0))
|
||||
DEBUGLOG("ObCloseHandle() = %s", NtStatusSym(Result0));
|
||||
#else
|
||||
ObCloseHandle(Context[ContextAccessToken], KernelMode);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS FspCreate(
|
||||
|
@ -267,8 +267,6 @@ PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
||||
(*(FSP_FSCTL_TRANSACT_REQ **)&(Irp)->Tail.Overlay.DriverContext[0])
|
||||
#define FspIopRequestContext(Request, I)\
|
||||
(*FspIopRequestContextAddress(Request, I))
|
||||
#define FspIrpContextHandle(Irp) \
|
||||
(*(HANDLE *)&(Irp)->Tail.Overlay.DriverContext[1])
|
||||
#define FspIopCreateRequest(I, F, E, P) FspIopCreateRequestEx(I, F, E, 0, P)
|
||||
typedef VOID FSP_IOP_REQUEST_FINI(PVOID Context[3]);
|
||||
NTSTATUS FspIopCreateRequestEx(
|
||||
|
@ -44,12 +44,16 @@ static NTSTATUS FspFsvolInternalDeviceControl(
|
||||
Request->Hint = (UINT_PTR)Irp;
|
||||
FspIopRequest(Irp) = Request;
|
||||
|
||||
/*
|
||||
* Post the IRP to our Ioq; we do this here instead of at IRP_LEAVE_MJ time,
|
||||
* so that we can disassociate the Request on failure and release ownership
|
||||
* back to the caller.
|
||||
*/
|
||||
if (!FspIoqPostIrp(&FsvrtDeviceExtension->Ioq, Irp))
|
||||
{
|
||||
/* this can only happen if the Ioq was stopped */
|
||||
ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq));
|
||||
|
||||
/* disocciate the Request from our Irp; release ownership back to caller */
|
||||
Request->Hint = 0;
|
||||
FspIopRequest(Irp) = 0;
|
||||
|
||||
|
@ -160,20 +160,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease)
|
||||
FspIopRequest(Irp) = 0;
|
||||
}
|
||||
|
||||
if (0 != FspIrpContextHandle(Irp))
|
||||
{
|
||||
#if DBG
|
||||
NTSTATUS Result0;
|
||||
Result0 = ObCloseHandle(FspIrpContextHandle(Irp), KernelMode);
|
||||
if (!NT_SUCCESS(Result0))
|
||||
DEBUGLOG("ObCloseHandle() = %s", NtStatusSym(Result0));
|
||||
#else
|
||||
ObCloseHandle(FspIrpContextHandle(Irp), KernelMode);
|
||||
#endif
|
||||
|
||||
FspIrpContextHandle(Irp) = 0;
|
||||
}
|
||||
|
||||
/* get the device object out of the IRP before completion */
|
||||
PDEVICE_OBJECT DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject;
|
||||
|
||||
if (!NT_SUCCESS(Result))
|
||||
|
Loading…
x
Reference in New Issue
Block a user