mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
Major refactoring: IRP_MJ_CREATE
This commit is contained in:
parent
1bd9c09d22
commit
e3c04e15ba
@ -123,7 +123,6 @@ typedef struct
|
|||||||
{
|
{
|
||||||
UINT64 UserContext;
|
UINT64 UserContext;
|
||||||
UINT64 UserContext2;
|
UINT64 UserContext2;
|
||||||
UINT32 Delete:1; /* if set, the file or directory must be deleted */
|
|
||||||
} Cleanup;
|
} Cleanup;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -154,6 +153,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
UINT64 UserContext; /* open file user context (unique file id) */
|
UINT64 UserContext; /* open file user context (unique file id) */
|
||||||
UINT64 UserContext2; /* kernel file object user context (only low 32 bits valid) */
|
UINT64 UserContext2; /* kernel file object user context (only low 32 bits valid) */
|
||||||
|
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
||||||
} Opened;
|
} Opened;
|
||||||
/* IoStatus.Status == STATUS_REPARSE */
|
/* IoStatus.Status == STATUS_REPARSE */
|
||||||
struct
|
struct
|
||||||
|
106
src/sys/create.c
106
src/sys/create.c
@ -105,7 +105,7 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
BOOLEAN IsAbsoluteSecurityDescriptor = FALSE;
|
BOOLEAN IsAbsoluteSecurityDescriptor = FALSE;
|
||||||
BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE;
|
BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE;
|
||||||
BOOLEAN HasTrailingBackslash = FALSE;
|
BOOLEAN HasTrailingBackslash = FALSE;
|
||||||
FSP_FILE_CONTEXT *FsContext = 0, *RelatedFsContext;
|
FSP_FILE_CONTEXT *FsContext, *RelatedFsContext;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
|
||||||
/* cannot open files by fileid */
|
/* cannot open files by fileid */
|
||||||
@ -313,6 +313,110 @@ VOID FspFsvolCreateComplete(
|
|||||||
{
|
{
|
||||||
FSP_ENTER_IOC(PAGED_CODE());
|
FSP_ENTER_IOC(PAGED_CODE());
|
||||||
|
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
|
SHARE_ACCESS TemporaryShareAccess;
|
||||||
|
UNICODE_STRING ReparseFileName;
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
FSP_FILE_CONTEXT *FsContext;
|
||||||
|
BOOLEAN Inserted;
|
||||||
|
|
||||||
|
/* did the user-mode file system sent us a failure code? */
|
||||||
|
if (!NT_SUCCESS(Response->IoStatus.Status))
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = Response->IoStatus.Information;
|
||||||
|
Result = Response->IoStatus.Status;
|
||||||
|
FSP_RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* special case STATUS_REPARSE */
|
||||||
|
if (STATUS_REPARSE == Result)
|
||||||
|
{
|
||||||
|
ReparseFileName.Buffer =
|
||||||
|
(PVOID)(Response->Buffer + Response->Rsp.Create.Reparse.FileName.Offset);
|
||||||
|
ReparseFileName.Length = ReparseFileName.MaximumLength =
|
||||||
|
Response->Rsp.Create.Reparse.FileName.Size;
|
||||||
|
|
||||||
|
Result = STATUS_ACCESS_DENIED;
|
||||||
|
if (IO_REPARSE == Response->IoStatus.Information)
|
||||||
|
{
|
||||||
|
if (0 == ReparseFileName.Length ||
|
||||||
|
(PUINT8)ReparseFileName.Buffer + ReparseFileName.Length >
|
||||||
|
(PUINT8)Response + Response->Size)
|
||||||
|
FSP_RETURN();
|
||||||
|
|
||||||
|
if (ReparseFileName.Length > FileObject->FileName.MaximumLength)
|
||||||
|
{
|
||||||
|
PVOID Buffer = FspAllocExternal(ReparseFileName.Length);
|
||||||
|
if (0 == Buffer)
|
||||||
|
FSP_RETURN(Result = STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
FspFreeExternal(FileObject->FileName.Buffer);
|
||||||
|
FileObject->FileName.MaximumLength = ReparseFileName.Length;
|
||||||
|
FileObject->FileName.Buffer = Buffer;
|
||||||
|
}
|
||||||
|
FileObject->FileName.Length = 0;
|
||||||
|
RtlCopyUnicodeString(&FileObject->FileName, &ReparseFileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (IO_REMOUNT == Response->IoStatus.Information)
|
||||||
|
{
|
||||||
|
if (0 != ReparseFileName.Length)
|
||||||
|
FSP_RETURN();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FSP_RETURN();
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = Response->IoStatus.Information;
|
||||||
|
Result = Response->IoStatus.Status;
|
||||||
|
FSP_RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the FsContext from our Request and associate it with the Response UserContext */
|
||||||
|
Request = FspIrpRequest(Irp);
|
||||||
|
FsContext = FspIopRequestContext(Request, RequestFsContext);
|
||||||
|
FsContext->UserContext = Response->Rsp.Create.Opened.UserContext;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt to insert our FsContext into the volume device's generic table.
|
||||||
|
* If an FsContext with the same UserContext already exists, then use that
|
||||||
|
* FsContext instead.
|
||||||
|
*/
|
||||||
|
FspFsvolDeviceLockContext(FsvolDeviceObject);
|
||||||
|
FsContext = FspFsvolDeviceInsertContext(FsvolDeviceObject,
|
||||||
|
FsContext->UserContext, FsContext, &FsContext->ElementStorage, &Inserted);
|
||||||
|
ASSERT(0 != FsContext);
|
||||||
|
if (Inserted)
|
||||||
|
/* Our FsContext was inserted into the volume device's generic table.
|
||||||
|
* Disassociate it from the Request.
|
||||||
|
*/
|
||||||
|
FspIopRequestContext(Request, RequestFsContext) = 0;
|
||||||
|
else
|
||||||
|
/*
|
||||||
|
* We are using a previously inserted FsContext. We must retain it.
|
||||||
|
* Our own FsContext is still associated with the Request and will be
|
||||||
|
* deleted during IRP completion.
|
||||||
|
*/
|
||||||
|
FspFileContextRetain(FsContext);
|
||||||
|
FspFileContextOpen(FsContext);
|
||||||
|
FspFsvolDeviceUnlockContext(FsvolDeviceObject);
|
||||||
|
|
||||||
|
/* set up share access on FileObject; user-mode file system assumed to have done share check */
|
||||||
|
IoSetShareAccess(Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess,
|
||||||
|
FileObject, &TemporaryShareAccess);
|
||||||
|
|
||||||
|
/* finish seting up the FileObject */
|
||||||
|
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
||||||
|
FileObject->Vpb = FsvolDeviceExtension->FsvrtDeviceObject->Vpb;
|
||||||
|
FileObject->SectionObjectPointer = &FsContext->NonPaged->SectionObjectPointers;
|
||||||
|
FileObject->PrivateCacheMap = 0;
|
||||||
|
FileObject->FsContext = FsContext;
|
||||||
|
FileObject->FsContext2 = (PVOID)(UINT_PTR)Response->Rsp.Create.Opened.UserContext2;
|
||||||
|
|
||||||
|
/* SUCCESS! */
|
||||||
|
Irp->IoStatus.Information = Response->IoStatus.Information;
|
||||||
|
Result = Response->IoStatus.Status;
|
||||||
|
|
||||||
FSP_LEAVE_IOC(
|
FSP_LEAVE_IOC(
|
||||||
"FileObject=%p[%p:\"%wZ\"]",
|
"FileObject=%p[%p:\"%wZ\"]",
|
||||||
IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName);
|
IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName);
|
||||||
|
@ -456,6 +456,7 @@ typedef struct
|
|||||||
ERESOURCE Resource;
|
ERESOURCE Resource;
|
||||||
ERESOURCE PagingIoResource;
|
ERESOURCE PagingIoResource;
|
||||||
FAST_MUTEX HeaderFastMutex;
|
FAST_MUTEX HeaderFastMutex;
|
||||||
|
SECTION_OBJECT_POINTERS SectionObjectPointers;
|
||||||
} FSP_FILE_CONTEXT_NONPAGED;
|
} FSP_FILE_CONTEXT_NONPAGED;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -463,34 +464,38 @@ typedef struct
|
|||||||
FSP_FILE_CONTEXT_NONPAGED *NonPaged;
|
FSP_FILE_CONTEXT_NONPAGED *NonPaged;
|
||||||
/* interlocked access */
|
/* interlocked access */
|
||||||
LONG RefCount;
|
LONG RefCount;
|
||||||
#if 0
|
|
||||||
/* protected by Header.Resource */
|
|
||||||
LONG OpenCount;
|
LONG OpenCount;
|
||||||
SHARE_ACCESS ShareAccess;
|
/* read-only after creation (and insertion in the GenericTable) */
|
||||||
BOOLEAN DeletePending; /* FileDispositionInformation */
|
|
||||||
BOOLEAN DeleteOnClose; /* FILE_DELETE_ON_CLOSE */
|
|
||||||
FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage;
|
|
||||||
UINT64 UserContext;
|
|
||||||
#endif
|
|
||||||
/* read-only after creation */
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject;
|
||||||
|
UINT64 UserContext;
|
||||||
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage;
|
||||||
UNICODE_STRING FileName;
|
UNICODE_STRING FileName;
|
||||||
WCHAR FileNameBuf[];
|
WCHAR FileNameBuf[];
|
||||||
} FSP_FILE_CONTEXT;
|
} FSP_FILE_CONTEXT;
|
||||||
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
|
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
|
||||||
VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context);
|
VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext);
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileContextRetain(FSP_FILE_CONTEXT *Context)
|
VOID FspFileContextRetain(FSP_FILE_CONTEXT *FsContext)
|
||||||
{
|
{
|
||||||
InterlockedIncrement(&Context->RefCount);
|
InterlockedIncrement(&FsContext->RefCount);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileContextRelease(FSP_FILE_CONTEXT *Context)
|
VOID FspFileContextRelease(FSP_FILE_CONTEXT *FsContext)
|
||||||
{
|
{
|
||||||
LONG RefCount = InterlockedDecrement(&Context->RefCount);
|
LONG RefCount = InterlockedDecrement(&FsContext->RefCount);
|
||||||
if (0 == RefCount)
|
if (0 == RefCount)
|
||||||
FspFileContextDelete(Context);
|
FspFileContextDelete(FsContext);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
|
VOID FspFileContextOpen(FSP_FILE_CONTEXT *FsContext)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&FsContext->OpenCount);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
|
LONG FspFileContextClose(FSP_FILE_CONTEXT *FsContext)
|
||||||
|
{
|
||||||
|
return InterlockedDecrement(&FsContext->OpenCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* debug */
|
/* debug */
|
||||||
@ -508,42 +513,4 @@ extern PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
|||||||
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
||||||
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
|
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
|
||||||
|
|
||||||
#if 0
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
FSRTL_ADVANCED_FCB_HEADER Header;
|
|
||||||
FSP_FILE_CONTEXT_NONPAGED *NonPaged;
|
|
||||||
/* interlocked access */
|
|
||||||
LONG RefCount;
|
|
||||||
/* protected by Header.Resource */
|
|
||||||
LONG OpenCount;
|
|
||||||
SHARE_ACCESS ShareAccess;
|
|
||||||
BOOLEAN DeletePending; /* FileDispositionInformation */
|
|
||||||
BOOLEAN DeleteOnClose; /* FILE_DELETE_ON_CLOSE */
|
|
||||||
/* read-only after creation */
|
|
||||||
FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage;
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject;
|
|
||||||
UINT64 UserContext;
|
|
||||||
UNICODE_STRING FileName;
|
|
||||||
WCHAR FileNameBuf[];
|
|
||||||
} FSP_FILE_CONTEXT;
|
|
||||||
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
|
|
||||||
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
|
|
||||||
VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context);
|
|
||||||
static inline
|
|
||||||
VOID FspFileContextOpen(FSP_FILE_CONTEXT *Context)
|
|
||||||
{
|
|
||||||
ASSERT(0 == Context->OpenCount || ExIsResourceAcquiredExclusiveLite(Context->Header.Resource));
|
|
||||||
Context->OpenCount++;
|
|
||||||
}
|
|
||||||
static inline
|
|
||||||
LONG FspFileContextClose(FSP_FILE_CONTEXT *Context)
|
|
||||||
{
|
|
||||||
ASSERT(ExIsResourceAcquiredExclusiveLite(Context->Header.Resource));
|
|
||||||
ASSERT(0 < Context->OpenCount);
|
|
||||||
return --Context->OpenCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user