mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -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\fastio.c" />
|
||||
<ClCompile Include="..\..\src\sys\fileinfo.c" />
|
||||
<ClCompile Include="..\..\src\sys\fileobj.c" />
|
||||
<ClCompile Include="..\..\src\sys\flush.c" />
|
||||
<ClCompile Include="..\..\src\sys\fsctl.c" />
|
||||
<ClCompile Include="..\..\src\sys\iop.c" />
|
||||
|
@ -83,6 +83,9 @@
|
||||
<ClCompile Include="..\..\src\sys\device.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\sys\fileobj.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\sys\driver.h">
|
||||
|
@ -62,7 +62,11 @@ typedef struct
|
||||
UINT8 Kind;
|
||||
union
|
||||
{
|
||||
UINT8 Placeholder; // !!!: REMOVE
|
||||
struct
|
||||
{
|
||||
UINT8 Placeholder;
|
||||
WCHAR FileName[];
|
||||
} Create;
|
||||
} Req;
|
||||
} FSP_FSCTL_TRANSACT_REQ;
|
||||
typedef struct
|
||||
|
@ -48,6 +48,7 @@ static NTSTATUS FspFsvolCreate(
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result;
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
||||
FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject);
|
||||
@ -67,12 +68,14 @@ static NTSTATUS FspFsvolCreate(
|
||||
PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
ULONG EaLength = IrpSp->Parameters.Create.EaLength;
|
||||
BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE);
|
||||
BOOLEAN HasTrailingBackslash = FALSE;
|
||||
FSP_FILE_CONTEXT *FsContext = 0;
|
||||
|
||||
/* cannot open the volume object */
|
||||
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))
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
@ -97,6 +100,66 @@ static NTSTATUS FspFsvolCreate(
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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_WRITE) FSP_DRIVER_DISPATCH FspWrite;
|
||||
|
||||
/* I/O process functions */
|
||||
/* I/O processing functions */
|
||||
_IRQL_requires_max_(APC_LEVEL)
|
||||
_IRQL_requires_same_
|
||||
typedef VOID FSP_IOCMPL_DISPATCH(
|
||||
@ -245,6 +245,10 @@ PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis);
|
||||
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
||||
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 */
|
||||
enum
|
||||
{
|
||||
@ -321,9 +325,21 @@ VOID FspDeviceDeleteList(
|
||||
PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount);
|
||||
VOID FspDeviceDeleteAll(VOID);
|
||||
|
||||
/* I/O processing */
|
||||
VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result);
|
||||
VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||
/* file objects */
|
||||
typedef struct
|
||||
{
|
||||
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 */
|
||||
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