mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 17:03:12 -05:00
sys: IRP_MJ_CREATE
This commit is contained in:
parent
7d22bec54b
commit
25457b916d
@ -145,6 +145,7 @@
|
|||||||
<ClCompile Include="..\..\src\sys\ea.c" />
|
<ClCompile Include="..\..\src\sys\ea.c" />
|
||||||
<ClCompile Include="..\..\src\sys\fastio.c" />
|
<ClCompile Include="..\..\src\sys\fastio.c" />
|
||||||
<ClCompile Include="..\..\src\sys\fileinfo.c" />
|
<ClCompile Include="..\..\src\sys\fileinfo.c" />
|
||||||
|
<ClCompile Include="..\..\src\sys\fileobj.c" />
|
||||||
<ClCompile Include="..\..\src\sys\flush.c" />
|
<ClCompile Include="..\..\src\sys\flush.c" />
|
||||||
<ClCompile Include="..\..\src\sys\fsctl.c" />
|
<ClCompile Include="..\..\src\sys\fsctl.c" />
|
||||||
<ClCompile Include="..\..\src\sys\iop.c" />
|
<ClCompile Include="..\..\src\sys\iop.c" />
|
||||||
|
@ -83,6 +83,9 @@
|
|||||||
<ClCompile Include="..\..\src\sys\device.c">
|
<ClCompile Include="..\..\src\sys\device.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\sys\fileobj.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\sys\driver.h">
|
<ClInclude Include="..\..\src\sys\driver.h">
|
||||||
|
@ -62,7 +62,11 @@ typedef struct
|
|||||||
UINT8 Kind;
|
UINT8 Kind;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
UINT8 Placeholder; // !!!: REMOVE
|
struct
|
||||||
|
{
|
||||||
|
UINT8 Placeholder;
|
||||||
|
WCHAR FileName[];
|
||||||
|
} Create;
|
||||||
} Req;
|
} Req;
|
||||||
} FSP_FSCTL_TRANSACT_REQ;
|
} FSP_FSCTL_TRANSACT_REQ;
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -48,6 +48,7 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
||||||
FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject);
|
FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject);
|
||||||
@ -67,12 +68,14 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer;
|
PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
ULONG EaLength = IrpSp->Parameters.Create.EaLength;
|
ULONG EaLength = IrpSp->Parameters.Create.EaLength;
|
||||||
BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE);
|
BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE);
|
||||||
|
BOOLEAN HasTrailingBackslash = FALSE;
|
||||||
|
FSP_FILE_CONTEXT *FsContext = 0;
|
||||||
|
|
||||||
/* cannot open the volume object */
|
/* cannot open the volume object */
|
||||||
if (0 == RelatedFileObject && 0 == FileName.Length)
|
if (0 == RelatedFileObject && 0 == FileName.Length)
|
||||||
return STATUS_ACCESS_DENIED; // need error code like UNIX EPERM (STATUS_NOT_SUPPORTED?)
|
return STATUS_ACCESS_DENIED; /* need error code like UNIX EPERM (STATUS_NOT_SUPPORTED?) */
|
||||||
|
|
||||||
/* cannot open paging file */
|
/* cannot open a paging file */
|
||||||
if (FlagOn(Flags, SL_OPEN_PAGING_FILE))
|
if (FlagOn(Flags, SL_OPEN_PAGING_FILE))
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
@ -97,6 +100,66 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
return STATUS_OBJECT_NAME_INVALID;
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for trailing backslash */
|
||||||
|
if (sizeof(WCHAR) * 2/* root can have trailing backslash */ <= FileName.Length &&
|
||||||
|
L'\\' == FileName.Buffer[FileName.Length / 2 - 1])
|
||||||
|
{
|
||||||
|
FileName.Length -= sizeof(WCHAR);
|
||||||
|
HasTrailingBackslash = TRUE;
|
||||||
|
|
||||||
|
if (sizeof(WCHAR) * 2 <= FileName.Length && L'\\' == FileName.Buffer[FileName.Length / 2 - 1])
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is this a relative or absolute open? */
|
||||||
|
if (0 != RelatedFileObject)
|
||||||
|
{
|
||||||
|
/* must be a relative path */
|
||||||
|
if (sizeof(WCHAR) <= FileName.Length && L'\\' == FileName.Buffer[0])
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
|
||||||
|
FSP_FILE_CONTEXT *RelatedFsContext = RelatedFileObject->FsContext;
|
||||||
|
ASSERT(0 != RelatedFsContext);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is no need to lock our accesses of RelatedFileObject->FsContext->FileName,
|
||||||
|
* because RelatedFileObject->FsContext->Filename is read-only (after creation) and
|
||||||
|
* because RelatedFileObject->FsContext is guaranteed to exist while RelatedFileObject
|
||||||
|
* exists.
|
||||||
|
*/
|
||||||
|
Result = FspFileContextCreate(
|
||||||
|
RelatedFsContext->FileName.Length + sizeof(WCHAR)/* backslash */ + FileName.Length,
|
||||||
|
&FsContext);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
Result = RtlAppendUnicodeStringToString(&FsContext->FileName, &RelatedFsContext->FileName);
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
if (HasTrailingBackslash)
|
||||||
|
{
|
||||||
|
Result = RtlAppendUnicodeToString(&FsContext->FileName, L"\\");
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
}
|
||||||
|
Result = RtlAppendUnicodeStringToString(&FsContext->FileName, &FileName);
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* absolute open */
|
||||||
|
Result = FspFileContextCreate(
|
||||||
|
FileName.Length,
|
||||||
|
&FsContext);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
Result = RtlAppendUnicodeStringToString(&FsContext->FileName, &FileName);
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* From this point forward we MUST remember to delete the FsContext on error.
|
||||||
|
*/
|
||||||
|
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ _Dispatch_type_(IRP_MJ_SET_VOLUME_INFORMATION) FSP_DRIVER_DISPATCH FspSetVolumeI
|
|||||||
_Dispatch_type_(IRP_MJ_SHUTDOWN) FSP_DRIVER_DISPATCH FspShutdown;
|
_Dispatch_type_(IRP_MJ_SHUTDOWN) FSP_DRIVER_DISPATCH FspShutdown;
|
||||||
_Dispatch_type_(IRP_MJ_WRITE) FSP_DRIVER_DISPATCH FspWrite;
|
_Dispatch_type_(IRP_MJ_WRITE) FSP_DRIVER_DISPATCH FspWrite;
|
||||||
|
|
||||||
/* I/O process functions */
|
/* I/O processing functions */
|
||||||
_IRQL_requires_max_(APC_LEVEL)
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
_IRQL_requires_same_
|
_IRQL_requires_same_
|
||||||
typedef VOID FSP_IOCMPL_DISPATCH(
|
typedef VOID FSP_IOCMPL_DISPATCH(
|
||||||
@ -245,6 +245,10 @@ PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis);
|
|||||||
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
||||||
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
||||||
|
|
||||||
|
/* I/O processing */
|
||||||
|
VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result);
|
||||||
|
VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
|
||||||
/* device management */
|
/* device management */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -321,9 +325,21 @@ VOID FspDeviceDeleteList(
|
|||||||
PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount);
|
PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount);
|
||||||
VOID FspDeviceDeleteAll(VOID);
|
VOID FspDeviceDeleteAll(VOID);
|
||||||
|
|
||||||
/* I/O processing */
|
/* file objects */
|
||||||
VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result);
|
typedef struct
|
||||||
VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
{
|
||||||
|
FAST_MUTEX HeaderFastMutex;
|
||||||
|
} FSP_FILE_CONTEXT_NONPAGED;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FSRTL_ADVANCED_FCB_HEADER Header;
|
||||||
|
FSP_FILE_CONTEXT_NONPAGED *NonPaged;
|
||||||
|
BOOLEAN HasTrailingBackslash;
|
||||||
|
UNICODE_STRING FileName;
|
||||||
|
WCHAR FileNameBuf[];
|
||||||
|
} FSP_FILE_CONTEXT;
|
||||||
|
NTSTATUS FspFileContextCreate(SIZE_T ExtraSize, FSP_FILE_CONTEXT **PContext);
|
||||||
|
VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context);
|
||||||
|
|
||||||
/* misc */
|
/* misc */
|
||||||
NTSTATUS FspCreateGuid(GUID *Guid);
|
NTSTATUS FspCreateGuid(GUID *Guid);
|
||||||
|
56
src/sys/fileobj.c
Normal file
56
src/sys/fileobj.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* @file sys/fileobj.c
|
||||||
|
*
|
||||||
|
* @copyright 2015 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/driver.h>
|
||||||
|
|
||||||
|
NTSTATUS FspFileContextCreate(SIZE_T ExtraSize, FSP_FILE_CONTEXT **PContext);
|
||||||
|
VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context);
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, FspFileContextCreate)
|
||||||
|
#pragma alloc_text(PAGE, FspFileContextDelete)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NTSTATUS FspFileContextCreate(SIZE_T ExtraSize, FSP_FILE_CONTEXT **PFsContext)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
*PFsContext = 0;
|
||||||
|
|
||||||
|
FSP_FILE_CONTEXT_NONPAGED *NonPaged = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
sizeof *NonPaged, FSP_TAG);
|
||||||
|
if (0 == NonPaged)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
FSP_FILE_CONTEXT *FsContext = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
sizeof *FsContext + ExtraSize, FSP_TAG);
|
||||||
|
if (0 == FsContext)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(NonPaged, FSP_TAG);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(NonPaged, sizeof *NonPaged);
|
||||||
|
ExInitializeFastMutex(&NonPaged->HeaderFastMutex);
|
||||||
|
|
||||||
|
RtlZeroMemory(FsContext, sizeof *FsContext + ExtraSize);
|
||||||
|
FsRtlSetupAdvancedHeader(&FsContext->Header, &NonPaged->HeaderFastMutex);
|
||||||
|
FsContext->NonPaged = NonPaged;
|
||||||
|
RtlInitEmptyUnicodeString(&FsContext->FileName, FsContext->FileNameBuf, (USHORT)ExtraSize);
|
||||||
|
|
||||||
|
*PFsContext = FsContext;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FsRtlTeardownPerStreamContexts(&FsContext->Header);
|
||||||
|
ExFreePoolWithTag(FsContext->NonPaged, FSP_TAG);
|
||||||
|
ExFreePoolWithTag(FsContext, FSP_TAG);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user