sys: IRP_MJ_CREATE

This commit is contained in:
Bill Zissimopoulos 2015-12-04 23:43:58 -08:00
parent 41fbb8cc58
commit 0187b77f8b
4 changed files with 64 additions and 8 deletions

View File

@ -133,6 +133,7 @@ typedef struct
{ {
UINT64 UserContext; /* user context attached to an open file (unique file id) */ UINT64 UserContext; /* user context attached to an open file (unique file id) */
UINT64 UserContext2; /* user context attached to a kernel file object */ UINT64 UserContext2; /* user context attached to a kernel file object */
/* (only low 32 bits valid in 32-bit mode) */
UINT16 SecurityDescriptor; /* security descriptor for existing files (offset within Buffer) */ UINT16 SecurityDescriptor; /* security descriptor for existing files (offset within Buffer) */
UINT16 SecurityDescriptorSize; /* security descriptor size */ UINT16 SecurityDescriptorSize; /* security descriptor size */
} Create; } Create;

View File

@ -309,11 +309,8 @@ NTSTATUS FspFsvolCreatePrepare(
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
ASSERT(FspFsvolDeviceExtensionKind == FsvolDeviceExtension->Base.Kind); FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject);
/* it is not necessary to retain the FsvrtDeviceObject; our callers have already done so */
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
/* if the user-mode file system is not doing access checks, there is nothing else to do */ /* if the user-mode file system is not doing access checks, there is nothing else to do */
if (!FsvrtDeviceExtension->VolumeParams.NoSystemAccessCheck) if (!FsvrtDeviceExtension->VolumeParams.NoSystemAccessCheck)
@ -322,14 +319,18 @@ NTSTATUS FspFsvolCreatePrepare(
FSP_RETURN(Result = STATUS_SUCCESS); FSP_RETURN(Result = STATUS_SUCCESS);
} }
/* get a user-mode handle to the access token */
PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState;
HANDLE UserModeAccessToken; HANDLE UserModeAccessToken;
/* get a user-mode handle to the access token */
Result = ObOpenObjectByPointer(SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext), Result = ObOpenObjectByPointer(SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext),
0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken); 0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
FspFileContextDelete(FileObject->FsContext);
FileObject->FsContext = 0;
FSP_RETURN(); FSP_RETURN();
}
/* send the user-mode handle to the user-mode file system */ /* send the user-mode handle to the user-mode file system */
Irp->Tail.Overlay.DriverContext[1] = UserModeAccessToken; Irp->Tail.Overlay.DriverContext[1] = UserModeAccessToken;
@ -343,6 +344,44 @@ VOID FspFsvolCreateComplete(
{ {
FSP_ENTER_IOC(PAGED_CODE()); FSP_ENTER_IOC(PAGED_CODE());
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
PFILE_OBJECT FileObject = IrpSp->FileObject;
/* if the user-mode file system sent us a failure code, fail the request now */
if (!NT_SUCCESS(Response->IoStatus.Status))
{
FspFileContextDelete(FileObject->FsContext);
FileObject->FsContext = 0;
goto exit;
}
/* record the user-mode file system contexts */
FSP_FILE_CONTEXT *FsContext = FileObject->FsContext;
BOOLEAN Inserted;
FsContext->UserContext = Response->Rsp.Create.UserContext;
FileObject->FsContext2 = (PVOID)(UINT_PTR)Response->Rsp.Create.UserContext2;
/* insert the new FsContext into our generic table */
FsContext = FspFsvolDeviceInsertContext(DeviceObject,
FsContext->UserContext, FsContext, &Inserted);
if (0 == FsContext)
{
FspFsvolCreateClose(Irp, Response);
FSP_RETURN(Result = STATUS_INSUFFICIENT_RESOURCES);
}
/* if it was not inserted, an FsContext with the same UserContext already exists; reuse it */
if (!Inserted)
{
FspFileContextDelete(FileObject->FsContext);
FspFileContextOpen(FsContext);
FileObject->FsContext = FsContext;
}
exit:
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);

View File

@ -262,7 +262,8 @@ PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
NTSTATUS FspIopCreateRequest( NTSTATUS FspIopCreateRequest(
PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest); PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest);
VOID FspIopCompleteRequestEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease); VOID FspIopCompleteRequestEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease);
static inline VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result) static inline
VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result)
{ {
FspIopCompleteRequestEx(Irp, Result, TRUE); FspIopCompleteRequestEx(Irp, Result, TRUE);
} }
@ -363,11 +364,25 @@ typedef struct
{ {
FSRTL_ADVANCED_FCB_HEADER Header; FSRTL_ADVANCED_FCB_HEADER Header;
FSP_FILE_CONTEXT_NONPAGED *NonPaged; FSP_FILE_CONTEXT_NONPAGED *NonPaged;
LONG OpenCount;
UINT64 UserContext;
UNICODE_STRING FileName; UNICODE_STRING FileName;
WCHAR FileNameBuf[]; WCHAR FileNameBuf[];
} FSP_FILE_CONTEXT; } FSP_FILE_CONTEXT;
NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PContext); NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PContext);
VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context);
static inline
VOID FspFileContextOpen(FSP_FILE_CONTEXT *Context)
{
InterlockedIncrement(&Context->OpenCount);
}
static inline
VOID FspFileContextClose(FSP_FILE_CONTEXT *Context)
{
LONG Result = InterlockedDecrement(&Context->OpenCount);
if (0 == Result)
FspFileContextDelete(Context);
}
/* misc */ /* misc */
NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspCreateGuid(GUID *Guid);

View File

@ -46,6 +46,7 @@ NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext)
FsContext->Header.PagingIoResource = &NonPaged->PagingIoResource; FsContext->Header.PagingIoResource = &NonPaged->PagingIoResource;
FsRtlSetupAdvancedHeader(&FsContext->Header, &NonPaged->HeaderFastMutex); FsRtlSetupAdvancedHeader(&FsContext->Header, &NonPaged->HeaderFastMutex);
FsContext->NonPaged = NonPaged; FsContext->NonPaged = NonPaged;
FsContext->OpenCount = 1;
RtlInitEmptyUnicodeString(&FsContext->FileName, FsContext->FileNameBuf, (USHORT)ExtraSize); RtlInitEmptyUnicodeString(&FsContext->FileName, FsContext->FileNameBuf, (USHORT)ExtraSize);
*PFsContext = FsContext; *PFsContext = FsContext;