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

View File

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

View File

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

View File

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

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_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
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);
}