From 483e39f1963f7e93be16ae550d87b4b690e7e41a Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 4 Jan 2016 22:34:54 -0800 Subject: [PATCH] remove obsolete directory src0 --- src0/dll/fsctl.c | 268 ---------------- src0/sys/cleanup.c | 176 ----------- src0/sys/close.c | 148 --------- src0/sys/create.c | 767 --------------------------------------------- src0/sys/misc.c | 109 ------- 5 files changed, 1468 deletions(-) delete mode 100644 src0/dll/fsctl.c delete mode 100644 src0/sys/cleanup.c delete mode 100644 src0/sys/close.c delete mode 100644 src0/sys/create.c delete mode 100644 src0/sys/misc.c diff --git a/src0/dll/fsctl.c b/src0/dll/fsctl.c deleted file mode 100644 index 96fca459..00000000 --- a/src0/dll/fsctl.c +++ /dev/null @@ -1,268 +0,0 @@ -/** - * @file dll/fsctl.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include -#if !defined(NDEBUG) -#include -#endif - -#define GLOBALROOT L"\\\\?\\GLOBALROOT" - -static inline VOID GlobalDevicePath(PWCHAR DevicePathBuf, SIZE_T DevicePathSize, PWSTR DevicePath) -{ - PWSTR DeviceRoot = L'\\' == DevicePath[0] ? GLOBALROOT : GLOBALROOT "\\Device\\"; - SIZE_T RootSize = lstrlenW(DeviceRoot) * sizeof(WCHAR); - SIZE_T PathSize = lstrlenW(DevicePath) * sizeof(WCHAR) + sizeof(WCHAR); - - if (RootSize + PathSize <= DevicePathSize) - { - memcpy(DevicePathBuf, DeviceRoot, RootSize); - memcpy((PUINT8)DevicePathBuf + RootSize, DevicePath, PathSize); - } - else - /* we should be doing assert(sizeof(WCHAR) <= DevicePathSize), but we don't have assert! */ - DevicePathBuf[0] = L'\0'; -} - -static NTSTATUS CreateSelfRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, - PSECURITY_DESCRIPTOR *PSelfRelativeSecurityDescriptor, PDWORD PSelfRelativeSecurityDescriptorSize) -{ - NTSTATUS Result; - BOOLEAN Success; - PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor = 0; - DWORD SelfRelativeSecurityDescriptorSize; - SECURITY_DESCRIPTOR_CONTROL SecurityDescriptorControl; - DWORD SecurityDescriptorRevision; - SECURITY_DESCRIPTOR SecurityDescriptorStruct; - PTOKEN_USER User = 0; - PACL Acl = 0; - DWORD UserSize = 0; - DWORD AclSize = 0; - HANDLE Token = 0; - - *PSelfRelativeSecurityDescriptor = 0; - *PSelfRelativeSecurityDescriptorSize = 0; - - if (0 == SecurityDescriptor) - { - Success = - OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token) && - (GetTokenInformation(Token, TokenUser, 0, 0, &UserSize) || - ERROR_INSUFFICIENT_BUFFER == GetLastError()) && - (User = MemAllocSLE(UserSize)) && - GetTokenInformation(Token, TokenUser, User, UserSize, &UserSize) && - (AclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(User->User.Sid) - sizeof(DWORD)) && - (Acl = MemAllocSLE(AclSize)) && - InitializeAcl(Acl, AclSize, ACL_REVISION) && - AddAccessAllowedAce(Acl, ACL_REVISION, FILE_ALL_ACCESS, User->User.Sid) && - InitializeSecurityDescriptor(&SecurityDescriptorStruct, SECURITY_DESCRIPTOR_REVISION) && - SetSecurityDescriptorDacl(&SecurityDescriptorStruct, TRUE, Acl, FALSE) && - SetSecurityDescriptorControl(&SecurityDescriptorStruct, SE_DACL_PROTECTED, SE_DACL_PROTECTED); - if (!Success) - { - Result = FspNtStatusFromWin32(GetLastError()); - goto exit; - } - SecurityDescriptor = &SecurityDescriptorStruct; - } - - if (!GetSecurityDescriptorControl(SecurityDescriptor, - &SecurityDescriptorControl, &SecurityDescriptorRevision)) - { - Result = FspNtStatusFromWin32(GetLastError()); - goto exit; - } - - if (SecurityDescriptorControl & SE_SELF_RELATIVE) - { - SelfRelativeSecurityDescriptorSize = GetSecurityDescriptorLength(SecurityDescriptor); - Success = - (SelfRelativeSecurityDescriptor = MemAllocSLE(SelfRelativeSecurityDescriptorSize)) && - memcpy(SelfRelativeSecurityDescriptor, SecurityDescriptor, SelfRelativeSecurityDescriptorSize); - } - else - { - SelfRelativeSecurityDescriptorSize = 0; - Success = - (MakeSelfRelativeSD(SecurityDescriptor, 0, &SelfRelativeSecurityDescriptorSize) || - ERROR_INSUFFICIENT_BUFFER == GetLastError()) && - (SelfRelativeSecurityDescriptor = MemAllocSLE(SelfRelativeSecurityDescriptorSize)) && - (MakeSelfRelativeSD(SecurityDescriptor, SelfRelativeSecurityDescriptor, &SelfRelativeSecurityDescriptorSize)); - } - if (!Success) - { - Result = FspNtStatusFromWin32(GetLastError()); - goto exit; - } - - *PSelfRelativeSecurityDescriptor = SelfRelativeSecurityDescriptor; - *PSelfRelativeSecurityDescriptorSize = SelfRelativeSecurityDescriptorSize; - Result = STATUS_SUCCESS; - -exit: - if (0 != Token) - CloseHandle(Token); - - MemFree(Acl); - MemFree(User); - - if (STATUS_SUCCESS != Result) - MemFree(SelfRelativeSecurityDescriptor); - - return Result; -} - -FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, - const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor, - PWCHAR VolumePathBuf, SIZE_T VolumePathSize) -{ - NTSTATUS Result = STATUS_SUCCESS; - PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor = 0; - DWORD SelfRelativeSecurityDescriptorSize; - FSP_FSCTL_VOLUME_PARAMS *ParamsBuf = 0; - WCHAR DevicePathBuf[MAX_PATH]; - HANDLE DeviceHandle = INVALID_HANDLE_VALUE; - DWORD Bytes; - - if (sizeof(WCHAR) <= VolumePathSize) - VolumePathBuf[0] = L'\0'; - - Result = CreateSelfRelativeSecurityDescriptor(SecurityDescriptor, - &SelfRelativeSecurityDescriptor, &SelfRelativeSecurityDescriptorSize); - if (!NT_SUCCESS(Result)) - goto exit; - - ParamsBuf = MemAlloc(FSP_FSCTL_VOLUME_PARAMS_SIZE + SelfRelativeSecurityDescriptorSize); - if (0 == ParamsBuf) - { - Result = STATUS_INSUFFICIENT_RESOURCES; - goto exit; - } - memset(ParamsBuf, 0, FSP_FSCTL_VOLUME_PARAMS_SIZE); - *ParamsBuf = *Params; - memcpy((PUINT8)ParamsBuf + FSP_FSCTL_VOLUME_PARAMS_SIZE, - SelfRelativeSecurityDescriptor, SelfRelativeSecurityDescriptorSize); - - GlobalDevicePath(DevicePathBuf, sizeof DevicePathBuf, DevicePath); - -#if !defined(NDEBUG) - { - PSTR Sddl; - if (ConvertSecurityDescriptorToStringSecurityDescriptorA(SelfRelativeSecurityDescriptor, - SDDL_REVISION_1, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - &Sddl, 0)) - { - DEBUGLOG("Device=\"%S\", Sddl=\"%s\", SdSize=%lu", - DevicePathBuf, Sddl, SelfRelativeSecurityDescriptorSize); - LocalFree(Sddl); - } - } -#endif - - DeviceHandle = CreateFileW(DevicePathBuf, - 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (INVALID_HANDLE_VALUE == DeviceHandle) - { - Result = FspNtStatusFromWin32(GetLastError()); - if (STATUS_OBJECT_NAME_NOT_FOUND == Result) - Result = STATUS_NO_SUCH_DEVICE; - goto exit; - } - - if (!DeviceIoControl(DeviceHandle, FSP_FSCTL_CREATE, - ParamsBuf, FSP_FSCTL_VOLUME_PARAMS_SIZE + SelfRelativeSecurityDescriptorSize, - VolumePathBuf, (DWORD)VolumePathSize, - &Bytes, 0)) - { - Result = FspNtStatusFromWin32(GetLastError()); - goto exit; - } - -exit: - - if (INVALID_HANDLE_VALUE != DeviceHandle) - CloseHandle(DeviceHandle); - - MemFree(ParamsBuf); - MemFree(SelfRelativeSecurityDescriptor); - - return Result; -} - -FSP_API NTSTATUS FspFsctlOpenVolume(PWSTR VolumePath, - PHANDLE PVolumeHandle) -{ - NTSTATUS Result = STATUS_SUCCESS; - WCHAR DevicePathBuf[MAX_PATH]; - HANDLE VolumeHandle; - - *PVolumeHandle = 0; - - GlobalDevicePath(DevicePathBuf, sizeof DevicePathBuf, VolumePath); - - DEBUGLOG("Device=\"%S\"", DevicePathBuf); - - VolumeHandle = CreateFileW(DevicePathBuf, - 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (INVALID_HANDLE_VALUE == VolumeHandle) - { - Result = FspNtStatusFromWin32(GetLastError()); - if (STATUS_OBJECT_NAME_NOT_FOUND == Result) - Result = STATUS_NO_SUCH_DEVICE; - goto exit; - } - - *PVolumeHandle = VolumeHandle; - -exit: - return Result; -} - -FSP_API NTSTATUS FspFsctlDeleteVolume(HANDLE VolumeHandle) -{ - NTSTATUS Result = STATUS_SUCCESS; - DWORD Bytes; - - if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_DELETE, - 0, 0, 0, 0, - &Bytes, 0)) - { - Result = FspNtStatusFromWin32(GetLastError()); - goto exit; - } - -exit: - return Result; -} - -FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, - PVOID ResponseBuf, SIZE_T ResponseBufSize, - PVOID RequestBuf, SIZE_T *PRequestBufSize) -{ - NTSTATUS Result = STATUS_SUCCESS; - DWORD Bytes = 0; - - if (0 != PRequestBufSize) - { - Bytes = (DWORD)*PRequestBufSize; - *PRequestBufSize = 0; - } - - if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_TRANSACT, - ResponseBuf, (DWORD)ResponseBufSize, RequestBuf, Bytes, - &Bytes, 0)) - { - Result = FspNtStatusFromWin32(GetLastError()); - goto exit; - } - - if (0 != PRequestBufSize) - *PRequestBufSize = Bytes; - -exit: - return Result; -} diff --git a/src0/sys/cleanup.c b/src0/sys/cleanup.c deleted file mode 100644 index 4aea9e75..00000000 --- a/src0/sys/cleanup.c +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file sys/cleanup.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -static NTSTATUS FspFsctlCleanup( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -static NTSTATUS FspFsvrtCleanup( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -static NTSTATUS FspFsvolCleanup( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -FSP_IOCMPL_DISPATCH FspFsvolCleanupComplete; -FSP_DRIVER_DISPATCH FspCleanup; - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, FspFsctlCleanup) -#pragma alloc_text(PAGE, FspFsvrtCleanup) -#pragma alloc_text(PAGE, FspFsvolCleanup) -#pragma alloc_text(PAGE, FspFsvolCleanupComplete) -#pragma alloc_text(PAGE, FspCleanup) -#endif - -static NTSTATUS FspFsctlCleanup( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - NTSTATUS Result = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - return Result; -} - -static NTSTATUS FspFsvrtCleanup( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - NTSTATUS Result = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - return Result; -} - -static NTSTATUS FspFsvolCleanup( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - /* is this a valid FileObject? */ - if (!FspFileContextIsValid(IrpSp->FileObject->FsContext)) - return STATUS_SUCCESS; - - NTSTATUS Result; - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - PFILE_OBJECT FileObject = IrpSp->FileObject; - FSP_FILE_CONTEXT *FsContext = FileObject->FsContext; - UINT64 UserContext = FsContext->UserContext; - UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2; - BOOLEAN DeletePending; - LONG OpenCount; - - /* lock the FsContext */ - ExAcquireResourceExclusiveLite(FsContext->Header.Resource, TRUE); - - /* propagate the FsContext DeleteOnClose to DeletePending */ - if (FsContext->DeleteOnClose) - FsContext->DeletePending = TRUE; - DeletePending = FsContext->DeletePending; - - /* all handles on this FileObject are gone; decrement its FsContext->OpenCount */ - OpenCount = FspFileContextClose(FsContext); - - /* unlock the FsContext */ - ExReleaseResourceLite(FsContext->Header.Resource); - - /* is the FsContext going away as well? */ - if (0 == OpenCount) - { - /* - * The following must be done under the file system volume device Resource, - * because we are manipulating its GenericTable. - */ - ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->Base.Resource, TRUE); - try - { - /* remove the FsContext from the file system volume device generic table */ - FspFsvolDeviceDeleteContext(DeviceObject, FsContext->UserContext, 0); - } - finally - { - ExReleaseResourceLite(&FsvolDeviceExtension->Base.Resource); - } - } - - PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; - if (!FspDeviceRetain(FsvrtDeviceObject)) - /* IRP_MJ_CLEANUP cannot really fail :-\ */ - return STATUS_SUCCESS; - - try - { - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); - BOOLEAN FileNameRequired = 0 != FsvrtDeviceExtension->VolumeParams.FileNameRequired; - FSP_FSCTL_TRANSACT_REQ *Request; - - /* create the user-mode file system request */ - Result = FspIopCreateRequest(Irp, FileNameRequired ? &FsContext->FileName : 0, 0, &Request); - if (!NT_SUCCESS(Result)) - goto leak_exit; - - /* - * The new request is associated with our IRP and will be deleted during its completion. - */ - - /* populate the Cleanup request */ - Request->Kind = FspFsctlTransactCleanupKind; - Request->Req.Cleanup.UserContext = UserContext; - Request->Req.Cleanup.UserContext2 = UserContext2; - Request->Req.Cleanup.Delete = DeletePending && 0 == OpenCount; - - Result = STATUS_PENDING; - - goto exit; - - leak_exit:; -#if DBG - DEBUGLOG("FileObject=%p[%p:\"%wZ\"], UserContext=%llx, UserContext2=%llx: " - "error: the user-mode file system handle will be leaked!", - IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName, - UserContext, UserContext2); -#endif - - /* IRP_MJ_CLEANUP cannot really fail :-\ */ - Result = STATUS_SUCCESS; - - exit:; - } - finally - { - FspDeviceRelease(FsvrtDeviceObject); - } - - return Result; -} - -VOID FspFsvolCleanupComplete( - PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) -{ - FSP_ENTER_IOC(PAGED_CODE()); - - FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject); -} - -NTSTATUS FspCleanup( - PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - FSP_ENTER_MJ(PAGED_CODE()); - - ASSERT(IRP_MJ_CLEANUP == IrpSp->MajorFunction); - - switch (FspDeviceExtension(DeviceObject)->Kind) - { - case FspFsvolDeviceExtensionKind: - FSP_RETURN(Result = FspFsvolCleanup(DeviceObject, Irp, IrpSp)); - case FspFsvrtDeviceExtensionKind: - FSP_RETURN(Result = FspFsvrtCleanup(DeviceObject, Irp, IrpSp)); - case FspFsctlDeviceExtensionKind: - FSP_RETURN(Result = FspFsctlCleanup(DeviceObject, Irp, IrpSp)); - default: - FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); - } - - FSP_LEAVE_MJ("FileObject=%p", IrpSp->FileObject); -} diff --git a/src0/sys/close.c b/src0/sys/close.c deleted file mode 100644 index 1b912117..00000000 --- a/src0/sys/close.c +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file sys/close.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -static NTSTATUS FspFsctlClose( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -static NTSTATUS FspFsvrtClose( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -static NTSTATUS FspFsvolClose( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -FSP_IOCMPL_DISPATCH FspFsvolCloseComplete; -FSP_DRIVER_DISPATCH FspClose; - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, FspFsctlClose) -#pragma alloc_text(PAGE, FspFsvrtClose) -#pragma alloc_text(PAGE, FspFsvolClose) -#pragma alloc_text(PAGE, FspFsvolCloseComplete) -#pragma alloc_text(PAGE, FspClose) -#endif - -static NTSTATUS FspFsctlClose( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - NTSTATUS Result = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - return Result; -} - -static NTSTATUS FspFsvrtClose( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - NTSTATUS Result = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - return Result; -} - -static NTSTATUS FspFsvolClose( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - /* is this a valid FileObject? */ - if (!FspFileContextIsValid(IrpSp->FileObject->FsContext)) - return STATUS_SUCCESS; - - NTSTATUS Result; - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - PFILE_OBJECT FileObject = IrpSp->FileObject; - FSP_FILE_CONTEXT *FsContext = FileObject->FsContext; - UINT64 UserContext = FsContext->UserContext; - UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2; - - /* dereference the FsContext (and delete if no more references) */ - FspFileContextRelease(FsContext); - - PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; - if (!FspDeviceRetain(FsvrtDeviceObject)) - /* IRP_MJ_CLOSE cannot really fail :-\ */ - return STATUS_SUCCESS; - - try - { - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); - BOOLEAN FileNameRequired = 0 != FsvrtDeviceExtension->VolumeParams.FileNameRequired; - FSP_FSCTL_TRANSACT_REQ *Request; - - /* create the user-mode file system request */ - Result = FspIopCreateRequest(0, FileNameRequired ? &FsContext->FileName : 0, 0, &Request); - if (!NT_SUCCESS(Result)) - goto leak_exit; - - /* - * The new request is associated with our IRP and will be deleted during its completion. - */ - - /* populate the Close request */ - Request->Kind = FspFsctlTransactCloseKind; - Request->Req.Close.UserContext = UserContext; - Request->Req.Close.UserContext2 = UserContext2; - - /* post as a work request; this allows us to complete our own IRP and return immediately! */ - if (!FspIopPostWorkRequest(DeviceObject, Request)) - /* no need to delete the request here as FspIopPostWorkRequest() will do so in all cases */ - goto leak_exit; - - Result = STATUS_SUCCESS; - - goto exit; - - leak_exit:; -#if DBG - DEBUGLOG("FileObject=%p[%p:\"%wZ\"], UserContext=%llx, UserContext2=%llx: " - "error: the user-mode file system handle will be leaked!", - IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName, - UserContext, UserContext2); -#endif - - /* IRP_MJ_CLOSE cannot really fail :-\ */ - Result = STATUS_SUCCESS; - - exit:; - } - finally - { - FspDeviceRelease(FsvrtDeviceObject); - } - - return Result; -} - -VOID FspFsvolCloseComplete( - PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) -{ - FSP_ENTER_IOC(PAGED_CODE()); - - FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject); -} - -NTSTATUS FspClose( - PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - FSP_ENTER_MJ(PAGED_CODE()); - - ASSERT(IRP_MJ_CLOSE == IrpSp->MajorFunction); - - switch (FspDeviceExtension(DeviceObject)->Kind) - { - case FspFsvolDeviceExtensionKind: - FSP_RETURN(Result = FspFsvolClose(DeviceObject, Irp, IrpSp)); - case FspFsvrtDeviceExtensionKind: - FSP_RETURN(Result = FspFsvrtClose(DeviceObject, Irp, IrpSp)); - case FspFsctlDeviceExtensionKind: - FSP_RETURN(Result = FspFsctlClose(DeviceObject, Irp, IrpSp)); - default: - FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); - } - - FSP_LEAVE_MJ("FileObject=%p", IrpSp->FileObject); -} diff --git a/src0/sys/create.c b/src0/sys/create.c deleted file mode 100644 index 052558fe..00000000 --- a/src0/sys/create.c +++ /dev/null @@ -1,767 +0,0 @@ -/** - * @file sys/create.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -static NTSTATUS FspFsctlCreate( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -static NTSTATUS FspFsvrtCreate( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -static NTSTATUS FspFsvolCreate( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; -FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; -static VOID FspFsvolCreateCleanupClose( - PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); -FSP_IOP_REQUEST_FINI FspFsvolCreateRequestFini; -FSP_DRIVER_DISPATCH FspCreate; - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, FspFsctlCreate) -#pragma alloc_text(PAGE, FspFsvrtCreate) -#pragma alloc_text(PAGE, FspFsvolCreate) -#pragma alloc_text(PAGE, FspFsvolCreatePrepare) -#pragma alloc_text(PAGE, FspFsvolCreateComplete) -#pragma alloc_text(PAGE, FspFsvolCreateCleanupClose) -#pragma alloc_text(PAGE, FspFsvolCreateRequestFini) -#pragma alloc_text(PAGE, FspCreate) -#endif - -enum -{ - RequestFsContext = 0, - RequestAccessToken, -}; - -static NTSTATUS FspFsctlCreate( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - NTSTATUS Result = STATUS_SUCCESS; - Irp->IoStatus.Information = FILE_OPENED; - return Result; -} - -static NTSTATUS FspFsvrtCreate( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - NTSTATUS Result = STATUS_SUCCESS; - Irp->IoStatus.Information = FILE_OPENED; - return Result; -} - -static NTSTATUS FspFsvolCreate( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) -{ - PAGED_CODE(); - - /* open the volume object? */ - if (0 == IrpSp->FileObject->FileName.Length && - (0 == IrpSp->FileObject->RelatedFileObject || - 0 == IrpSp->FileObject->RelatedFileObject->FsContext)) - { - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; - - IrpSp->FileObject->Vpb = FsvrtDeviceObject->Vpb; - Irp->IoStatus.Information = FILE_OPENED; - return STATUS_SUCCESS; - } - - NTSTATUS Result; - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - - PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; - if (!FspDeviceRetain(FsvrtDeviceObject)) - return STATUS_CANCELLED; - - try - { - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); - PFILE_OBJECT FileObject = IrpSp->FileObject; - PFILE_OBJECT RelatedFileObject = FileObject->RelatedFileObject; - UNICODE_STRING FileName = FileObject->FileName; - PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; - ULONG CreateOptions = IrpSp->Parameters.Create.Options; - USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes; - PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor; - ULONG SecurityDescriptorSize = 0; - LARGE_INTEGER AllocationSize = Irp->Overlay.AllocationSize; - ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; - USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; - PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; - //ULONG EaLength = IrpSp->Parameters.Create.EaLength; - ULONG Flags = IrpSp->Flags; - KPROCESSOR_MODE RequestorMode = - FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; - BOOLEAN HasTraversePrivilege = - BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); - BOOLEAN IsAbsoluteSecurityDescriptor = FALSE; - BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE; - BOOLEAN HasTrailingBackslash = FALSE; - FSP_FILE_CONTEXT *FsContext = 0; - FSP_FSCTL_TRANSACT_REQ *Request; - - /* cannot open a paging file */ - if (FlagOn(Flags, SL_OPEN_PAGING_FILE)) - { - Result = STATUS_ACCESS_DENIED; - goto exit; - } - - /* cannot open files by fileid */ - if (FlagOn(CreateOptions, FILE_OPEN_BY_FILE_ID)) - { - Result = STATUS_NOT_IMPLEMENTED; - goto exit; - } - - /* do we support EA? */ - if (0 != EaBuffer && !FsvrtDeviceExtension->VolumeParams.EaSupported) - { - Result = STATUS_EAS_NOT_SUPPORTED; - goto exit; - } - - /* check create options */ - if (FlagOn(CreateOptions, FILE_NON_DIRECTORY_FILE) && - FlagOn(CreateOptions, FILE_DIRECTORY_FILE)) - { - Result = STATUS_INVALID_PARAMETER; - goto exit; - } - - /* check security descriptor validity */ - if (0 != SecurityDescriptor) - { - IsAbsoluteSecurityDescriptor = RtlValidSecurityDescriptor(SecurityDescriptor); - if (IsAbsoluteSecurityDescriptor) - { - Result = RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize); - if (STATUS_BUFFER_TOO_SMALL != Result) - { - Result = STATUS_INVALID_PARAMETER; - goto exit; - } - } - else - { - SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); - IsSelfRelativeSecurityDescriptor = RtlValidRelativeSecurityDescriptor( - SecurityDescriptor, SecurityDescriptorSize, 0); - if (!IsSelfRelativeSecurityDescriptor) - { - Result = STATUS_INVALID_PARAMETER; - goto exit; - } - } - } - - /* according to fastfat, filenames that begin with two backslashes are ok */ - if (sizeof(WCHAR) * 2 <= FileName.Length && - L'\\' == FileName.Buffer[1] && L'\\' == FileName.Buffer[0]) - { - FileName.Length -= sizeof(WCHAR); - FileName.MaximumLength -= sizeof(WCHAR); - FileName.Buffer++; - - if (sizeof(WCHAR) * 2 <= FileName.Length && - L'\\' == FileName.Buffer[1] && L'\\' == FileName.Buffer[0]) - { - Result = STATUS_OBJECT_NAME_INVALID; - goto exit; - } - } - - /* check for trailing backslash */ - if (sizeof(WCHAR) * 2/* not empty or root */ <= 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]) - { - Result = STATUS_OBJECT_NAME_INVALID; - goto exit; - } - } - if (HasTrailingBackslash && !FlagOn(CreateOptions, FILE_DIRECTORY_FILE)) - { - Result = STATUS_OBJECT_NAME_INVALID; - goto exit; - } - - /* is this a relative or absolute open? */ - if (0 != RelatedFileObject) - { - FSP_FILE_CONTEXT *RelatedFsContext = RelatedFileObject->FsContext; - - /* is this a valid RelatedFileObject? */ - if (!FspFileContextIsValid(RelatedFsContext)) - { - Result = STATUS_OBJECT_PATH_NOT_FOUND; - goto exit; - } - - /* must be a relative path */ - if (sizeof(WCHAR) <= FileName.Length && L'\\' == FileName.Buffer[0]) - { - Result = STATUS_OBJECT_NAME_INVALID; - goto exit; - } - - /* cannot FILE_DELETE_ON_CLOSE on the root directory */ - if (sizeof(WCHAR) == RelatedFsContext->FileName.Length && - 0 == FileName.Length && - FlagOn(CreateOptions, FILE_DELETE_ON_CLOSE)) - { - Result = STATUS_CANNOT_DELETE; - goto exit; - } - - /* - * 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. - */ - BOOLEAN AppendBackslash = - sizeof(WCHAR) * 2/* not empty or root */ <= RelatedFsContext->FileName.Length && - sizeof(WCHAR) <= FileName.Length && L':' != FileName.Buffer[0]; - Result = FspFileContextCreate(DeviceObject, - RelatedFsContext->FileName.Length + AppendBackslash * sizeof(WCHAR) + FileName.Length, - &FsContext); - if (!NT_SUCCESS(Result)) - goto exit; - - Result = RtlAppendUnicodeStringToString(&FsContext->FileName, &RelatedFsContext->FileName); - ASSERT(NT_SUCCESS(Result)); - if (AppendBackslash) - { - Result = RtlAppendUnicodeToString(&FsContext->FileName, L"\\"); - ASSERT(NT_SUCCESS(Result)); - } - } - else - { - /* must be an absolute path */ - if (sizeof(WCHAR) <= FileName.Length && L'\\' != FileName.Buffer[0]) - { - Result = STATUS_OBJECT_NAME_INVALID; - goto exit; - } - - /* cannot FILE_DELETE_ON_CLOSE on the root directory */ - if (sizeof(WCHAR) == FileName.Length && - FlagOn(CreateOptions, FILE_DELETE_ON_CLOSE)) - { - Result = STATUS_CANNOT_DELETE; - goto exit; - } - - Result = FspFileContextCreate(DeviceObject, - FileName.Length, - &FsContext); - if (!NT_SUCCESS(Result)) - goto exit; - } - - Result = RtlAppendUnicodeStringToString(&FsContext->FileName, &FileName); - ASSERT(NT_SUCCESS(Result)); - - /* create the user-mode file system request */ - Result = FspIopCreateRequestEx(Irp, &FsContext->FileName, SecurityDescriptorSize, - FspFsvolCreateRequestFini, &Request); - if (!NT_SUCCESS(Result)) - { - FspFileContextRelease(FsContext); - goto exit; - } - - /* - * The new request is associated with our IRP and will be deleted during its completion. - * Go ahead and associate our FsContext with the Request as well. - */ - FspIopRequestContext(Request, RequestFsContext) = FsContext; - - /* populate the Create request */ - Request->Kind = FspFsctlTransactCreateKind; - Request->Req.Create.CreateOptions = CreateOptions; - Request->Req.Create.FileAttributes = FileAttributes; - Request->Req.Create.SecurityDescriptor.Offset = 0 == SecurityDescriptorSize ? 0 : - FSP_FSCTL_DEFAULT_ALIGN_UP(Request->FileName.Size); - Request->Req.Create.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize; - Request->Req.Create.AllocationSize = AllocationSize.QuadPart; - Request->Req.Create.AccessToken = 0; - Request->Req.Create.DesiredAccess = DesiredAccess; - Request->Req.Create.ShareAccess = ShareAccess; - Request->Req.Create.Ea.Offset = 0; - Request->Req.Create.Ea.Size = 0; - Request->Req.Create.UserMode = UserMode == RequestorMode; - Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege; - Request->Req.Create.OpenTargetDirectory = BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY); - Request->Req.Create.CaseSensitive = BooleanFlagOn(Flags, SL_CASE_SENSITIVE); - - /* copy the security descriptor into the request */ - if (IsAbsoluteSecurityDescriptor) - { - Result = RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, - Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, &SecurityDescriptorSize); - if (!NT_SUCCESS(Result)) - { - if (STATUS_BAD_DESCRIPTOR_FORMAT == Result || STATUS_BUFFER_TOO_SMALL == Result) - Result = STATUS_INVALID_PARAMETER; /* should not happen */ - goto exit; - } - } - else if (IsSelfRelativeSecurityDescriptor) - RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, - SecurityDescriptor, SecurityDescriptorSize); - - Result = STATUS_PENDING; - - exit:; - } - finally - { - FspDeviceRelease(FsvrtDeviceObject); - } - - return Result; -} - -NTSTATUS FspFsvolCreatePrepare( - PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request) -{ - FSP_ENTER_IOP(PAGED_CODE()); - - PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = - FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject); - - /* is the user-mode file system doing access checks? */ - if (!FsvrtDeviceExtension->VolumeParams.NoSystemAccessCheck) - { - ASSERT(0 == Request->Req.Create.AccessToken); - FSP_RETURN(Result = STATUS_SUCCESS); - } - - /* get a user-mode handle to the access token */ - PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; - HANDLE UserModeAccessToken; - Result = ObOpenObjectByPointer(SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext), - 0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken); - if (!NT_SUCCESS(Result)) - FSP_RETURN(); - - /* send the user-mode handle to the user-mode file system */ - FspIopRequestContext(Request, RequestAccessToken) = UserModeAccessToken; - Request->Req.Create.AccessToken = (UINT_PTR)UserModeAccessToken; - - FSP_LEAVE_IOP(); -} - -VOID FspFsvolCreateComplete( - PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) -{ - FSP_ENTER_IOC(PAGED_CODE()); - - /* - * NOTE: - * In the following we may have to close the just opened file object. But we must - * never close a file we just created, because this will leave an orphan file on - * the disk. - * - * Files may have to be closed if a security access or share access check fails. In - * both those cases we were opening an existing file and so it is safe to close it. - * - * Because of how IRP_MJ_CREATE works in Windows, it is difficult to improve on this - * scheme without introducing a 2-phase Create protocol, which is undesirable as it - * means two trips into user-mode for a single Create request. - */ - - PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); - FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); - PFILE_OBJECT FileObject = IrpSp->FileObject; - PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; - ULONG CreateOptions = IrpSp->Parameters.Create.Options; - BOOLEAN FileCreated = FILE_CREATED == Response->IoStatus.Information; - UINT32 ResponseFileAttributes = Response->Rsp.Create.Opened.FileAttributes; - PSECURITY_DESCRIPTOR SecurityDescriptor; - ULONG SecurityDescriptorSize; - UNICODE_STRING ReparseFileName; - ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; - PPRIVILEGE_SET Privileges = 0; - USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; - ULONG Flags = IrpSp->Flags; - KPROCESSOR_MODE RequestorMode = - FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; - FSP_FILE_CONTEXT *FsContext = FspIopRequestContext(Request, RequestFsContext); - ACCESS_MASK GrantedAccess; - BOOLEAN Inserted = FALSE; - - /* did the user-mode file system sent us a failure code? */ - if (!NT_SUCCESS(Response->IoStatus.Status)) - { - Irp->IoStatus.Information = Response->IoStatus.Information; - Result = Response->IoStatus.Status; - FSP_RETURN(); - } - - /* special case STATUS_REPARSE */ - if (STATUS_REPARSE == Result) - { - ReparseFileName.Buffer = - (PVOID)(Response->Buffer + Response->Rsp.Create.Reparse.FileName.Offset); - ReparseFileName.Length = ReparseFileName.MaximumLength = - Response->Rsp.Create.Reparse.FileName.Size; - - Result = STATUS_ACCESS_DENIED; - if (IO_REPARSE == Response->IoStatus.Information) - { - if (0 == ReparseFileName.Length || - (PUINT8)ReparseFileName.Buffer + ReparseFileName.Length > - (PUINT8)Response + Response->Size) - FSP_RETURN(); - - if (ReparseFileName.Length > FileObject->FileName.MaximumLength) - { - PVOID Buffer = FspAllocExternal(ReparseFileName.Length); - if (0 == Buffer) - FSP_RETURN(Result = STATUS_INSUFFICIENT_RESOURCES); - FspFreeExternal(FileObject->FileName.Buffer); - FileObject->FileName.MaximumLength = ReparseFileName.Length; - FileObject->FileName.Buffer = Buffer; - } - FileObject->FileName.Length = 0; - RtlCopyUnicodeString(&FileObject->FileName, &ReparseFileName); - } - else - if (IO_REMOUNT == Response->IoStatus.Information) - { - if (0 != ReparseFileName.Length) - FSP_RETURN(); - } - else - FSP_RETURN(); - - Irp->IoStatus.Information = Response->IoStatus.Information; - Result = Response->IoStatus.Status; - FSP_RETURN(); - } - - /* are we doing access checks? */ - if (!FsvrtDeviceExtension->VolumeParams.NoSystemAccessCheck) - { - /* read-only attribute check */ - if (!FileCreated && FlagOn(ResponseFileAttributes, FILE_ATTRIBUTE_READONLY)) - { - /* from fastfat: allowed accesses when read-only */ - ACCESS_MASK Allowed = - DELETE | READ_CONTROL | WRITE_OWNER | WRITE_DAC | - SYNCHRONIZE | ACCESS_SYSTEM_SECURITY | - FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA | - FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | - FILE_EXECUTE | FILE_TRAVERSE | FILE_LIST_DIRECTORY | - FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE | FILE_DELETE_CHILD; - - if (FlagOn(DesiredAccess, ~Allowed)) - { - FspFsvolCreateCleanupClose(Irp, Response); - FSP_RETURN(Result = STATUS_ACCESS_DENIED); - } - else - if (!FlagOn(ResponseFileAttributes, FILE_ATTRIBUTE_DIRECTORY) && - FlagOn(CreateOptions, FILE_DELETE_ON_CLOSE)) - { - FspFsvolCreateCleanupClose(Irp, Response); - FSP_RETURN(Result = STATUS_CANNOT_DELETE); - } - } - - /* security descriptor check */ - SecurityDescriptor = - (PVOID)(Response->Buffer + Response->Rsp.Create.Opened.SecurityDescriptor.Offset); - SecurityDescriptorSize = Response->Rsp.Create.Opened.SecurityDescriptor.Size; - if (0 != SecurityDescriptorSize) - { - if ((PUINT8)SecurityDescriptor + SecurityDescriptorSize > - (PUINT8)Response + Response->Size || - !FspValidRelativeSecurityDescriptor(SecurityDescriptor, SecurityDescriptorSize, 0)) - { - FspFsvolCreateCleanupClose(Irp, Response); - FSP_RETURN(Result = STATUS_ACCESS_DENIED); - } - - /* access check */ - if (!SeAccessCheck(SecurityDescriptor, - &AccessState->SubjectSecurityContext, - FALSE, - DesiredAccess, - AccessState->PreviouslyGrantedAccess, - &Privileges, - IoGetFileObjectGenericMapping(), - RequestorMode, - &GrantedAccess, - &Result)) - { - FspFsvolCreateCleanupClose(Irp, Response); - FSP_RETURN(); - } - - if (0 != Privileges) - { - Result = SeAppendPrivileges(AccessState, Privileges); - SeFreePrivileges(Privileges); - if (!NT_SUCCESS(Result)) - { - FspFsvolCreateCleanupClose(Irp, Response); - FSP_RETURN(); - } - } - - SetFlag(AccessState->PreviouslyGrantedAccess, GrantedAccess); - ClearFlag(AccessState->RemainingDesiredAccess, GrantedAccess); - } - } - - /* were we asked to open a directory or non-directory? */ - if (FlagOn(CreateOptions, FILE_DIRECTORY_FILE) && - !FileCreated && !FlagOn(ResponseFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) - { - FspFsvolCreateCleanupClose(Irp, Response); - FSP_RETURN(Result = STATUS_NOT_A_DIRECTORY); - } - if (FlagOn(CreateOptions, FILE_NON_DIRECTORY_FILE) && - !FileCreated && FlagOn(ResponseFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) - { - FspFsvolCreateCleanupClose(Irp, Response); - FSP_RETURN(Result = STATUS_FILE_IS_A_DIRECTORY); - } - - /* - * The following must be done under the file system volume device Resource, - * because we are manipulating its GenericTable and accessing foreign FsContext's. - */ - ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->Base.Resource, TRUE); - try - { - /* insert the newly created FsContext into our generic table */ - FsContext = FspFsvolDeviceInsertContext(DeviceObject, - FsContext->UserContext, FsContext, &FsContext->ElementStorage, &Inserted); - ASSERT(0 != FsContext); - - /* share access check */ - if (Inserted) - { - /* - * This is a newly created FsContext. Set its share access and - * increment its open count. There is no need to acquire the - * FsContext's Resource (because it is newly created). - */ - IoSetShareAccess(AccessState->PreviouslyGrantedAccess, - ShareAccess, FileObject, &FsContext->ShareAccess); - FspFileContextOpen(FsContext); - if (FlagOn(CreateOptions, FILE_DELETE_ON_CLOSE)) - FsContext->DeleteOnClose = TRUE; - Result = STATUS_SUCCESS; - } - else - { - /* - * This is an existing FsContext. We must acquire its Resource and - * check if there is a delete pending and the share access. Only if - * both tests succeed we increment the open count and report success. - */ - ExAcquireResourceExclusiveLite(FsContext->Header.Resource, TRUE); - if (FsContext->DeletePending) - Result = STATUS_DELETE_PENDING; - else - Result = IoCheckShareAccess(AccessState->PreviouslyGrantedAccess, - ShareAccess, FileObject, &FsContext->ShareAccess, TRUE); - if (NT_SUCCESS(Result)) - { - FspFileContextRetain(FsContext); - FspFileContextOpen(FsContext); - if (FlagOn(CreateOptions, FILE_DELETE_ON_CLOSE)) - FsContext->DeleteOnClose = TRUE; - } - ExReleaseResourceLite(FsContext->Header.Resource); - } - } - finally - { - ExReleaseResourceLite(&FsvolDeviceExtension->Base.Resource); - } - - /* did we fail our share access checks? */ - if (!NT_SUCCESS(Result)) - { - ASSERT(!Inserted); - FspFsvolCreateCleanupClose(Irp, Response); - FSP_RETURN(); - } - - /* - * Looks like SUCCESS! - */ - - /* did an FsContext with the same UserContext already exist? */ - if (!Inserted) - /* delete the newly created FsContext as it is not being used */ - FspFileContextRelease(FspIopRequestContext(Request, RequestFsContext)); - - /* disassociate our FsContext from the Request */ - FspIopRequestContext(Request, RequestFsContext) = 0; - - /* record the user-mode file system contexts */ - FsContext->UserContext = Response->Rsp.Create.Opened.UserContext; - FileObject->FsContext = FsContext; - FileObject->FsContext2 = (PVOID)(UINT_PTR)Response->Rsp.Create.Opened.UserContext2; - - /* finish seting up the FileObject */ - FileObject->Vpb = FsvrtDeviceObject->Vpb; - - /* SUCCESS! */ - Irp->IoStatus.Information = Response->IoStatus.Information; - Result = Response->IoStatus.Status; - - FSP_LEAVE_IOC( - "FileObject=%p[%p:\"%wZ\"]", - IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName); -} - -static VOID FspFsvolCreateCleanupClose( - PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) -{ - PAGED_CODE(); - - /* - * This routine handles the case where we must close an open file, - * because of a failure during Create completion. We simply create - * a CreateClose request and we post it as a work item. - * - * Ideally there would be no failure modes for this routine. Reality is - * different. - * - * The more serious (but perhaps non-existent in practice) failure is a - * memory allocation failure. In this case we will leak the user-mode - * file system handle! - * - * This routine may also fail if we cannot post a work item, which means that - * the virtual volume device and the file system volume device are being - * deleted. Because it is assumed that only the user-mode file system would - * initiate a device deletion, this case is more benign (presumably the file - * system knows to close off all its handles when tearing down its devices). - */ - - NTSTATUS Result; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = - FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject); - FSP_FSCTL_TRANSACT_REQ *OriginalRequest = FspIrpRequest(Irp); - FSP_FILE_CONTEXT *FsContext = FspIopRequestContext(OriginalRequest, RequestFsContext); - UINT64 UserContext = Response->Rsp.Create.Opened.UserContext; - UINT64 UserContext2 = Response->Rsp.Create.Opened.UserContext2; - BOOLEAN FileNameRequired = 0 != FsvrtDeviceExtension->VolumeParams.FileNameRequired; - FSP_FSCTL_TRANSACT_REQ *Request; - - /* create the user-mode file system request */ - Result = FspIopCreateRequest(0, FileNameRequired ? &FsContext->FileName : 0, 0, &Request); - if (!NT_SUCCESS(Result)) - goto leak_exit; - - /* populate the CreateCleanupClose request */ - Request->Kind = FspFsctlTransactCreateCleanupCloseKind; - Request->Req.Cleanup.UserContext = UserContext; - Request->Req.Cleanup.UserContext2 = UserContext2; - Request->Req.Cleanup.Delete = FILE_CREATED == Response->IoStatus.Information; - - /* post as a work request */ - if (!FspIopPostWorkRequest(DeviceObject, Request)) - /* no need to delete the request here as FspIopPostWorkRequest() will do so in all cases */ - goto leak_exit; - - goto exit; - -leak_exit:; -#if DBG - DEBUGLOG("FileObject=%p[%p:\"%wZ\"], UserContext=%llx, UserContext2=%llx: " - "error: the user-mode file system handle will be leaked!", - IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName, - UserContext, UserContext2); -#endif - -exit:; -} - -VOID FspFsvolCreateRequestFini(PVOID Context[3]) -{ - PAGED_CODE(); - - if (0 != Context[RequestFsContext]) - FspFileContextRelease(Context[RequestFsContext]); - - if (0 != Context[RequestAccessToken]) - { -#if DBG - NTSTATUS Result0; - Result0 = ObCloseHandle(Context[RequestAccessToken], KernelMode); - if (!NT_SUCCESS(Result0)) - DEBUGLOG("ObCloseHandle() = %s", NtStatusSym(Result0)); -#else - ObCloseHandle(Context[RequestAccessToken], KernelMode); -#endif - } -} - -NTSTATUS FspCreate( - PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - FSP_ENTER_MJ(PAGED_CODE()); - - ASSERT(IRP_MJ_CREATE == IrpSp->MajorFunction); - - switch (FspDeviceExtension(DeviceObject)->Kind) - { - case FspFsvolDeviceExtensionKind: - FSP_RETURN(Result = FspFsvolCreate(DeviceObject, Irp, IrpSp)); - case FspFsvrtDeviceExtensionKind: - FSP_RETURN(Result = FspFsvrtCreate(DeviceObject, Irp, IrpSp)); - case FspFsctlDeviceExtensionKind: - FSP_RETURN(Result = FspFsctlCreate(DeviceObject, Irp, IrpSp)); - default: - FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); - } - - FSP_LEAVE_MJ( - "FileObject=%p[%p:\"%wZ\"], " - "Flags=%x, " - "DesiredAccess=%#lx, " - "ShareAccess=%#x, " - "Options=%#lx, " - "FileAttributes=%#x, " - "AllocationSize=%#lx:%#lx, " - "Ea=%p, EaLength=%ld", - IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName, - IrpSp->Flags, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess, - IrpSp->Parameters.Create.ShareAccess, - IrpSp->Parameters.Create.Options, - IrpSp->Parameters.Create.FileAttributes, - Irp->Overlay.AllocationSize.HighPart, Irp->Overlay.AllocationSize.LowPart, - Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength); -} diff --git a/src0/sys/misc.c b/src0/sys/misc.c deleted file mode 100644 index c4cd398a..00000000 --- a/src0/sys/misc.c +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file sys/misc.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -NTSTATUS FspCreateGuid(GUID *Guid); -BOOLEAN FspValidRelativeSecurityDescriptor( - PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG SecurityDescriptorLength, - SECURITY_INFORMATION RequiredInformation); -NTSTATUS FspSecuritySubjectContextAccessCheck( - PSECURITY_DESCRIPTOR SecurityDescriptor, ACCESS_MASK DesiredAccess, KPROCESSOR_MODE AccessMode); -VOID FspInitializeWorkItemWithDelay(FSP_WORK_ITEM_WITH_DELAY *WorkItem, - PWORKER_THREAD_ROUTINE Routine, PVOID Context); -VOID FspQueueWorkItemWithDelay(FSP_WORK_ITEM_WITH_DELAY *WorkItem, LARGE_INTEGER Timeout); -static KDEFERRED_ROUTINE FspQueueWorkItemWithDelayDPC; - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, FspCreateGuid) -#pragma alloc_text(PAGE, FspValidRelativeSecurityDescriptor) -#pragma alloc_text(PAGE, FspSecuritySubjectContextAccessCheck) -#pragma alloc_text(PAGE, FspInitializeWorkItemWithDelay) -#pragma alloc_text(PAGE, FspQueueWorkItemWithDelay) -#endif - -NTSTATUS FspCreateGuid(GUID *Guid) -{ - PAGED_CODE(); - - NTSTATUS Result; - - int Retries = 3; - do - { - Result = ExUuidCreate(Guid); - } while (!NT_SUCCESS(Result) && 0 < --Retries); - - return Result; -} - -BOOLEAN FspValidRelativeSecurityDescriptor( - PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG SecurityDescriptorLength, - SECURITY_INFORMATION RequiredInformation) -{ - PAGED_CODE(); - - BOOLEAN Result; - - try - { - Result = RtlValidRelativeSecurityDescriptor(SecurityDescriptor, SecurityDescriptorLength, - RequiredInformation); - } - except (EXCEPTION_EXECUTE_HANDLER) - { - Result = FALSE; - } - - return Result; -} - -NTSTATUS FspSecuritySubjectContextAccessCheck( - PSECURITY_DESCRIPTOR SecurityDescriptor, ACCESS_MASK DesiredAccess, KPROCESSOR_MODE AccessMode) -{ - PAGED_CODE(); - - NTSTATUS Result = STATUS_ACCESS_DENIED; - SECURITY_SUBJECT_CONTEXT SecuritySubjectContext; - ACCESS_MASK GrantedAccess; - - SeCaptureSubjectContext(&SecuritySubjectContext); - if (SeAccessCheck(SecurityDescriptor, - &SecuritySubjectContext, FALSE, - DesiredAccess, 0, 0, IoGetFileObjectGenericMapping(), AccessMode, - &GrantedAccess, &Result)) - Result = STATUS_SUCCESS; - SeReleaseSubjectContext(&SecuritySubjectContext); - - return Result; -} - -VOID FspInitializeWorkItemWithDelay(FSP_WORK_ITEM_WITH_DELAY *WorkItem, - PWORKER_THREAD_ROUTINE Routine, PVOID Context) -{ - PAGED_CODE(); - - KeInitializeTimer(&WorkItem->Timer); - KeInitializeDpc(&WorkItem->Dpc, FspQueueWorkItemWithDelayDPC, WorkItem); - ExInitializeWorkItem(&WorkItem->WorkQueueItem, Routine, Context); -} - -VOID FspQueueWorkItemWithDelay(FSP_WORK_ITEM_WITH_DELAY *WorkItem, LARGE_INTEGER Timeout) -{ - PAGED_CODE(); - - KeSetTimer(&WorkItem->Timer, Timeout, &WorkItem->Dpc); -} - -static VOID FspQueueWorkItemWithDelayDPC(PKDPC Dpc, - PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) -{ - // !PAGED_CODE(); - - FSP_WORK_ITEM_WITH_DELAY *WorkItem = DeferredContext; - - ExQueueWorkItem(&WorkItem->WorkQueueItem, DelayedWorkQueue); -}