sys: IRP_MJ_CREATE

This commit is contained in:
Bill Zissimopoulos 2015-12-02 19:40:40 -08:00
parent 7d22bec54b
commit 25457b916d
6 changed files with 150 additions and 7 deletions

View File

@ -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" />

View File

@ -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">

View File

@ -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

View File

@ -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;
}

View File

@ -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
View 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);
}