sys: IRP_MJ_LOCK_CONTROL

This commit is contained in:
Bill Zissimopoulos 2016-04-06 15:41:16 -07:00
parent b729500d7b
commit 218ad0be8c
3 changed files with 94 additions and 8 deletions

View File

@ -155,9 +155,9 @@ extern __declspec(selectany) int fsp_dt = 1;
} \ } \
fsp_device_deref = TRUE; \ fsp_device_deref = TRUE; \
} while (0,0) } while (0,0)
#define FSP_LEAVE_MJ(fmt, ...) \ #define FSP_LEAVE_MJ_COND(COND, fmt, ...)\
FSP_LEAVE_( \ FSP_LEAVE_( \
if (STATUS_PENDING != Result) \ if (COND) \
{ \ { \
ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\ ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\
FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);\ FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);\
@ -187,6 +187,8 @@ extern __declspec(selectany) int fsp_dt = 1;
IoSetTopLevelIrp(fsp_top_level_irp);\ IoSetTopLevelIrp(fsp_top_level_irp);\
); \ ); \
return Result return Result
#define FSP_LEAVE_MJ(fmt, ...) \
FSP_LEAVE_MJ_COND(STATUS_PENDING != Result, fmt, __VA_ARGS__)
#define FSP_ENTER_IOC(...) \ #define FSP_ENTER_IOC(...) \
NTSTATUS Result = STATUS_SUCCESS; \ NTSTATUS Result = STATUS_SUCCESS; \
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); (VOID)IrpSp;\ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); (VOID)IrpSp;\
@ -873,6 +875,7 @@ typedef struct
ULONG SecurityChangeNumber; ULONG SecurityChangeNumber;
ULONG DirInfoChangeNumber; ULONG DirInfoChangeNumber;
BOOLEAN TruncateOnClose; BOOLEAN TruncateOnClose;
FILE_LOCK FileLock;
union union
{ {
PVOID LazyWriteThread; PVOID LazyWriteThread;
@ -951,6 +954,8 @@ VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size, BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
ULONG DirInfoChangeNumber); ULONG DirInfoChangeNumber);
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action); VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action);
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp,
PBOOLEAN PIrpRelinquished);
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,

View File

@ -48,6 +48,9 @@ BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG S
static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode); static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode);
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
ULONG Filter, ULONG Action); ULONG Filter, ULONG Action);
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp,
PBOOLEAN PIrpRelinquished);
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
@ -85,6 +88,7 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
// !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo) // !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo)
// !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo) // !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo)
#pragma alloc_text(PAGE, FspFileNodeNotifyChange) #pragma alloc_text(PAGE, FspFileNodeNotifyChange)
#pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp)
#pragma alloc_text(PAGE, FspFileDescCreate) #pragma alloc_text(PAGE, FspFileDescCreate)
#pragma alloc_text(PAGE, FspFileDescDelete) #pragma alloc_text(PAGE, FspFileDescDelete)
#pragma alloc_text(PAGE, FspFileDescResetDirectoryPattern) #pragma alloc_text(PAGE, FspFileDescResetDirectoryPattern)
@ -178,6 +182,8 @@ NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
FspDeviceReference(FileNode->FsvolDeviceObject); FspDeviceReference(FileNode->FsvolDeviceObject);
RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize); RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize);
FsRtlInitializeFileLock(&FileNode->FileLock, FspFileNodeCompleteLockIrp, 0);
*PFileNode = FileNode; *PFileNode = FileNode;
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -190,6 +196,8 @@ VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode)
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
FsRtlUninitializeFileLock(&FileNode->FileLock);
FsRtlTeardownPerStreamContexts(&FileNode->Header); FsRtlTeardownPerStreamContexts(&FileNode->Header);
FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, FileNode->NonPaged->DirInfo); FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, FileNode->NonPaged->DirInfo);
@ -932,6 +940,47 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
0, Filter, Action); 0, Filter, Action);
} }
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp,
PBOOLEAN PIrpRelinquished)
{
PAGED_CODE();
NTSTATUS Result;
FspFileNodeAcquireShared(FileNode, Main);
FspFileNodeSetOwner(FileNode, Main, Irp);
try
{
Result = FsRtlProcessFileLock(&FileNode->FileLock, Irp, FileNode);
*PIrpRelinquished = TRUE;
}
except (EXCEPTION_EXECUTE_HANDLER)
{
FspFileNodeReleaseOwner(FileNode, Main, Irp);
Result = GetExceptionCode();
*PIrpRelinquished = FALSE;
}
return Result;
}
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp)
{
PAGED_CODE();
FSP_FILE_NODE *FileNode = Context;
NTSTATUS Result = Irp->IoStatus.Status;
FspFileNodeReleaseOwner(FileNode, Main, Irp);
DEBUGLOGIRP(Irp, Result);
FspIopCompleteIrp(Irp, Result);
return Result;
}
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc) NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc)
{ {
PAGED_CODE(); PAGED_CODE();

View File

@ -7,7 +7,8 @@
#include <sys/driver.h> #include <sys/driver.h>
static NTSTATUS FspFsvolLockControl( static NTSTATUS FspFsvolLockControl(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
PBOOLEAN PIrpRelinquished);
FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete; FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete;
FSP_DRIVER_DISPATCH FspLockControl; FSP_DRIVER_DISPATCH FspLockControl;
@ -18,11 +19,27 @@ FSP_DRIVER_DISPATCH FspLockControl;
#endif #endif
static NTSTATUS FspFsvolLockControl( static NTSTATUS FspFsvolLockControl(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
PBOOLEAN PIrpRelinquished)
{ {
PAGED_CODE(); PAGED_CODE();
return STATUS_INVALID_DEVICE_REQUEST; /* is this a valid FileObject? */
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
return STATUS_INVALID_DEVICE_REQUEST;
NTSTATUS Result;
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
/* only regular files can be locked */
if (FileNode->IsDirectory)
return STATUS_INVALID_PARAMETER;
/* let the FSRTL package handle this one! */
Result = FspFileNodeProcessLockIrp(FileNode, Irp, PIrpRelinquished);
return Result;
} }
NTSTATUS FspFsvolLockControlComplete( NTSTATUS FspFsvolLockControlComplete(
@ -30,21 +47,36 @@ NTSTATUS FspFsvolLockControlComplete(
{ {
FSP_ENTER_IOC(PAGED_CODE()); FSP_ENTER_IOC(PAGED_CODE());
FSP_LEAVE_IOC("%s", ""); FSP_LEAVE_IOC("FileObject=%p, "
"Key=%#lx, ByteOffset=%#lx:%#lx, Length=%ld",
IrpSp->FileObject,
IrpSp->Parameters.LockControl.Key,
IrpSp->Parameters.LockControl.ByteOffset.HighPart,
IrpSp->Parameters.LockControl.ByteOffset.LowPart,
IrpSp->Parameters.LockControl.Length);
} }
NTSTATUS FspLockControl( NTSTATUS FspLockControl(
PDEVICE_OBJECT DeviceObject, PIRP Irp) PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ {
BOOLEAN IrpRelinquished = FALSE;
FSP_ENTER_MJ(PAGED_CODE()); FSP_ENTER_MJ(PAGED_CODE());
switch (FspDeviceExtension(DeviceObject)->Kind) switch (FspDeviceExtension(DeviceObject)->Kind)
{ {
case FspFsvolDeviceExtensionKind: case FspFsvolDeviceExtensionKind:
FSP_RETURN(Result = FspFsvolLockControl(DeviceObject, Irp, IrpSp)); FSP_RETURN(Result = FspFsvolLockControl(DeviceObject, Irp, IrpSp, &IrpRelinquished));
default: default:
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
} }
FSP_LEAVE_MJ("%s", ""); FSP_LEAVE_MJ_COND(!IrpRelinquished && STATUS_PENDING != Result,
"FileObject=%p, "
"Key=%#lx, ByteOffset=%#lx:%#lx, Length=%ld",
IrpSp->FileObject,
IrpSp->Parameters.LockControl.Key,
IrpSp->Parameters.LockControl.ByteOffset.HighPart,
IrpSp->Parameters.LockControl.ByteOffset.LowPart,
IrpSp->Parameters.LockControl.Length);
} }