mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-31 12:08:41 -05:00 
			
		
		
		
	remove obsolete directory src0
This commit is contained in:
		
							
								
								
									
										268
									
								
								src0/dll/fsctl.c
									
									
									
									
									
								
							
							
						
						
									
										268
									
								
								src0/dll/fsctl.c
									
									
									
									
									
								
							| @@ -1,268 +0,0 @@ | ||||
| /** | ||||
|  * @file dll/fsctl.c | ||||
|  * | ||||
|  * @copyright 2015 Bill Zissimopoulos | ||||
|  */ | ||||
|  | ||||
| #include <dll/library.h> | ||||
| #if !defined(NDEBUG) | ||||
| #include <sddl.h> | ||||
| #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; | ||||
| } | ||||
| @@ -1,176 +0,0 @@ | ||||
| /** | ||||
|  * @file sys/cleanup.c | ||||
|  * | ||||
|  * @copyright 2015 Bill Zissimopoulos | ||||
|  */ | ||||
|  | ||||
| #include <sys/driver.h> | ||||
|  | ||||
| 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); | ||||
| } | ||||
							
								
								
									
										148
									
								
								src0/sys/close.c
									
									
									
									
									
								
							
							
						
						
									
										148
									
								
								src0/sys/close.c
									
									
									
									
									
								
							| @@ -1,148 +0,0 @@ | ||||
| /** | ||||
|  * @file sys/close.c | ||||
|  * | ||||
|  * @copyright 2015 Bill Zissimopoulos | ||||
|  */ | ||||
|  | ||||
| #include <sys/driver.h> | ||||
|  | ||||
| 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); | ||||
| } | ||||
| @@ -1,767 +0,0 @@ | ||||
| /** | ||||
|  * @file sys/create.c | ||||
|  * | ||||
|  * @copyright 2015 Bill Zissimopoulos | ||||
|  */ | ||||
|  | ||||
| #include <sys/driver.h> | ||||
|  | ||||
| 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); | ||||
| } | ||||
							
								
								
									
										109
									
								
								src0/sys/misc.c
									
									
									
									
									
								
							
							
						
						
									
										109
									
								
								src0/sys/misc.c
									
									
									
									
									
								
							| @@ -1,109 +0,0 @@ | ||||
| /** | ||||
|  * @file sys/misc.c | ||||
|  * | ||||
|  * @copyright 2015 Bill Zissimopoulos | ||||
|  */ | ||||
|  | ||||
| #include <sys/driver.h> | ||||
|  | ||||
| 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); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user