mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 09:22:57 -05:00
sys: FileStatLxInformation and friends
This commit is contained in:
@ -494,6 +494,9 @@ NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK Desir
|
||||
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
|
||||
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
||||
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
|
||||
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
||||
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
||||
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
|
||||
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
||||
NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
||||
NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags);
|
||||
@ -1636,4 +1639,24 @@ LOGICAL RtlEqualMemory(const VOID *Source1, const VOID *Source2, SIZE_T Length)
|
||||
return Length == RtlCompareMemory(Source1, Source2, Length);
|
||||
}
|
||||
|
||||
typedef struct _FILE_STAT_LX_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER FileId;
|
||||
LARGE_INTEGER CreationTime;
|
||||
LARGE_INTEGER LastAccessTime;
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
LARGE_INTEGER ChangeTime;
|
||||
LARGE_INTEGER AllocationSize;
|
||||
LARGE_INTEGER EndOfFile;
|
||||
ULONG FileAttributes;
|
||||
ULONG ReparseTag;
|
||||
ULONG NumberOfLinks;
|
||||
ACCESS_MASK EffectiveAccess;
|
||||
ULONG LxFlags;
|
||||
ULONG LxUid;
|
||||
ULONG LxGid;
|
||||
ULONG LxMode;
|
||||
ULONG LxDeviceIdMajor;
|
||||
ULONG LxDeviceIdMinor;
|
||||
} FILE_STAT_LX_INFORMATION, *PFILE_STAT_LX_INFORMATION;
|
||||
#endif
|
||||
|
@ -45,6 +45,15 @@ static NTSTATUS FspFsvolQueryPositionInformation(PFILE_OBJECT FileObject,
|
||||
static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
|
||||
PVOID *PBuffer, PVOID BufferEnd,
|
||||
const FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
static NTSTATUS FspFsvolQueryStatInformation(PFILE_OBJECT FileObject,
|
||||
PVOID *PBuffer, PVOID BufferEnd,
|
||||
const FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
static NTSTATUS FspFsvolQueryStatLxInformation(PFILE_OBJECT FileObject,
|
||||
PVOID *PBuffer, PVOID BufferEnd,
|
||||
const FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
static NTSTATUS FspFsvolQueryStatLxInformationEa(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
|
||||
PVOID *PBuffer, PVOID BufferEnd);
|
||||
static NTSTATUS FspFsvolQueryStreamInformationCopy(
|
||||
FSP_FSCTL_STREAM_INFO *StreamInfoBuffer, ULONG StreamInfoBufferSize,
|
||||
PVOID DestBuf, PULONG PDestLen);
|
||||
@ -97,6 +106,9 @@ FAST_IO_QUERY_OPEN FspFastIoQueryOpen;
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryNetworkOpenInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryPositionInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryStandardInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryStatInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryStatLxInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryStatLxInformationEa)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformationCopy)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformationSuccess)
|
||||
@ -417,6 +429,195 @@ static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolQueryStatInformation(PFILE_OBJECT FileObject,
|
||||
PVOID *PBuffer, PVOID BufferEnd,
|
||||
const FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
PFILE_STAT_INFORMATION Info = (PFILE_STAT_INFORMATION)*PBuffer;
|
||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||
|
||||
ASSERT(FileNode == FileDesc->FileNode);
|
||||
|
||||
if (0 == FileInfo)
|
||||
{
|
||||
if ((PVOID)(Info + 1) > BufferEnd)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Info->FileId.QuadPart = FileNode->IndexNumber;
|
||||
Info->CreationTime.QuadPart = FileInfo->CreationTime;
|
||||
Info->LastAccessTime.QuadPart = FileInfo->LastAccessTime;
|
||||
Info->LastWriteTime.QuadPart = FileInfo->LastWriteTime;
|
||||
Info->ChangeTime.QuadPart = FileInfo->ChangeTime;
|
||||
Info->AllocationSize.QuadPart = FileInfo->AllocationSize;
|
||||
Info->EndOfFile.QuadPart = FileInfo->FileSize;
|
||||
Info->FileAttributes = 0 != FileInfo->FileAttributes ?
|
||||
FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL;
|
||||
Info->ReparseTag = FileInfo->ReparseTag;
|
||||
Info->NumberOfLinks = 1;
|
||||
Info->EffectiveAccess = FileDesc->GrantedAccess;
|
||||
|
||||
*PBuffer = (PVOID)(Info + 1);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolQueryStatLxInformation(PFILE_OBJECT FileObject,
|
||||
PVOID *PBuffer, PVOID BufferEnd,
|
||||
const FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
PFILE_STAT_LX_INFORMATION Info = (PFILE_STAT_LX_INFORMATION)*PBuffer;
|
||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||
|
||||
ASSERT(FileNode == FileDesc->FileNode);
|
||||
|
||||
if (0 == FileInfo)
|
||||
{
|
||||
if ((PVOID)(Info + 1) > BufferEnd)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Info->FileId.QuadPart = FileNode->IndexNumber;
|
||||
Info->CreationTime.QuadPart = FileInfo->CreationTime;
|
||||
Info->LastAccessTime.QuadPart = FileInfo->LastAccessTime;
|
||||
Info->LastWriteTime.QuadPart = FileInfo->LastWriteTime;
|
||||
Info->ChangeTime.QuadPart = FileInfo->ChangeTime;
|
||||
Info->AllocationSize.QuadPart = FileInfo->AllocationSize;
|
||||
Info->EndOfFile.QuadPart = FileInfo->FileSize;
|
||||
Info->FileAttributes = 0 != FileInfo->FileAttributes ?
|
||||
FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL;
|
||||
Info->ReparseTag = FileInfo->ReparseTag;
|
||||
Info->NumberOfLinks = 1;
|
||||
Info->EffectiveAccess = FileDesc->GrantedAccess;
|
||||
|
||||
*PBuffer = (PVOID)(Info + 1);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolQueryStatLxInformationEa(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
|
||||
PVOID *PBuffer, PVOID BufferEnd)
|
||||
{
|
||||
#define ADD_GET_EA(Name, End) \
|
||||
GetEa->NextEntryOffset = (ULONG)(End ? 0 :\
|
||||
FSP_FSCTL_ALIGN_UP( \
|
||||
FIELD_OFFSET(FILE_GET_EA_INFORMATION, EaName) + sizeof("" Name),\
|
||||
sizeof(ULONG))); \
|
||||
GetEa->EaNameLength = (UCHAR)(sizeof("" Name) - 1);\
|
||||
RtlCopyMemory(GetEa->EaName, "" Name, sizeof("" Name));\
|
||||
GetEaLength = (ULONG)((PUINT8)GetEa - (PUINT8)&GetEaBuf.V +\
|
||||
FIELD_OFFSET(FILE_GET_EA_INFORMATION, EaName) + sizeof("" Name));\
|
||||
GetEa = (PVOID)((PUINT8)GetEa + GetEa->NextEntryOffset);
|
||||
#define EQUAL_EA_NAME(Name) \
|
||||
CmpName.Length = \
|
||||
CmpName.MaximumLength = sizeof("" Name) - 1,\
|
||||
CmpName.Buffer = "" Name, \
|
||||
RtlEqualString(&CmpName, &EaName, TRUE/* always case-insensitive */)
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
PFILE_STAT_LX_INFORMATION Info = (PFILE_STAT_LX_INFORMATION)*PBuffer;
|
||||
union
|
||||
{
|
||||
FILE_GET_EA_INFORMATION V;
|
||||
UINT8 B[256];
|
||||
} GetEaBuf;
|
||||
PFILE_GET_EA_INFORMATION GetEa = &GetEaBuf.V;
|
||||
ULONG GetEaLength = 0;
|
||||
union
|
||||
{
|
||||
FILE_FULL_EA_INFORMATION V;
|
||||
UINT8 B[256];
|
||||
} EaBuf;
|
||||
ULONG EaLength = sizeof EaBuf;
|
||||
STRING EaName, CmpName;
|
||||
NTSTATUS Result;
|
||||
|
||||
Info->LxFlags = 0;
|
||||
Info->LxUid = 0;
|
||||
Info->LxGid = 0;
|
||||
Info->LxMode = 0;
|
||||
Info->LxDeviceIdMajor = 0;
|
||||
Info->LxDeviceIdMinor = 0;
|
||||
|
||||
if (!FsvolDeviceExtension->VolumeParams.ExtendedAttributes)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
ADD_GET_EA("$LXUID", 0);
|
||||
ADD_GET_EA("$LXGID", 0);
|
||||
ADD_GET_EA("$LXMOD", 0);
|
||||
ADD_GET_EA("$LXDEV", 1);
|
||||
|
||||
Result = FspSendQueryEaIrp(FsvolDeviceObject/* bypass filters */, FileObject,
|
||||
&GetEaBuf.V, GetEaLength,
|
||||
&EaBuf.V, &EaLength);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
for (PFILE_FULL_EA_INFORMATION Ea = &EaBuf.V, EaEnd = (PVOID)((PUINT8)Ea + EaLength);
|
||||
EaEnd > Ea; Ea = FSP_NEXT_EA(Ea, EaEnd))
|
||||
{
|
||||
EaName.Length =
|
||||
EaName.MaximumLength = Ea->EaNameLength,
|
||||
EaName.Buffer = Ea->EaName;
|
||||
|
||||
if (EQUAL_EA_NAME("$LXUID"))
|
||||
{
|
||||
if (sizeof(ULONG) == Ea->EaValueLength)
|
||||
{
|
||||
Info->LxFlags |= 0x1/*LX_FILE_METADATA_HAS_UID*/;
|
||||
Info->LxUid = *(PULONG)(Ea->EaName + sizeof "$LXUID");
|
||||
}
|
||||
}
|
||||
else
|
||||
if (EQUAL_EA_NAME("$LXGID"))
|
||||
{
|
||||
if (sizeof(ULONG) == Ea->EaValueLength)
|
||||
{
|
||||
Info->LxFlags |= 0x2/*LX_FILE_METADATA_HAS_GID*/;
|
||||
Info->LxGid = *(PULONG)(Ea->EaName + sizeof "$LXGID");
|
||||
}
|
||||
}
|
||||
else
|
||||
if (EQUAL_EA_NAME("$LXMOD"))
|
||||
{
|
||||
if (sizeof(ULONG) == Ea->EaValueLength)
|
||||
{
|
||||
Info->LxFlags |= 0x4/*LX_FILE_METADATA_HAS_MODE*/;
|
||||
Info->LxMode = *(PULONG)(Ea->EaName + sizeof "$LXMOD");
|
||||
}
|
||||
}
|
||||
else
|
||||
if (EQUAL_EA_NAME("$LXDEV"))
|
||||
{
|
||||
if (sizeof(UINT64) == Ea->EaValueLength)
|
||||
{
|
||||
Info->LxFlags |= 0x8/*LX_FILE_METADATA_HAS_DEVICE_ID*/;
|
||||
UINT64 Dev = *(PUINT64)(Ea->EaName + sizeof "$LXDEV");
|
||||
Info->LxDeviceIdMajor = (Dev >> 32) & 0xffffffff;
|
||||
Info->LxDeviceIdMinor = Dev & 0xffffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
#undef EQUAL_EA_NAME
|
||||
#undef ADD_GET_EA
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolQueryStreamInformationCopy(
|
||||
FSP_FSCTL_STREAM_INFO *StreamInfo, ULONG StreamInfoSize,
|
||||
PVOID DestBuf, PULONG PDestLen)
|
||||
@ -720,6 +921,12 @@ static NTSTATUS FspFsvolQueryInformation(
|
||||
case FileStandardInformation:
|
||||
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, 0);
|
||||
break;
|
||||
case FileStatInformation:
|
||||
Result = FspFsvolQueryStatInformation(FileObject, &Buffer, BufferEnd, 0);
|
||||
break;
|
||||
case 70/*FileStatLxInformation*/:
|
||||
Result = FspFsvolQueryStatLxInformation(FileObject, &Buffer, BufferEnd, 0);
|
||||
break;
|
||||
default:
|
||||
Result = STATUS_INVALID_PARAMETER;
|
||||
return Result;
|
||||
@ -729,6 +936,18 @@ static NTSTATUS FspFsvolQueryInformation(
|
||||
return Result;
|
||||
|
||||
FspFileNodeAcquireShared(FileNode, Main);
|
||||
|
||||
if (70/*FileStatLxInformation*/ == FileInformationClass)
|
||||
{
|
||||
Result = FspFsvolQueryStatLxInformationEa(
|
||||
FsvolDeviceObject, FileObject, &Buffer, BufferEnd);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Main);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
if (FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf))
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Main);
|
||||
@ -755,6 +974,12 @@ static NTSTATUS FspFsvolQueryInformation(
|
||||
case FileStandardInformation:
|
||||
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
|
||||
break;
|
||||
case FileStatInformation:
|
||||
Result = FspFsvolQueryStatInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
|
||||
break;
|
||||
case 70/*FileStatLxInformation*/:
|
||||
Result = FspFsvolQueryStatLxInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
Result = STATUS_INVALID_PARAMETER;
|
||||
@ -865,6 +1090,12 @@ NTSTATUS FspFsvolQueryInformationComplete(
|
||||
case FileStandardInformation:
|
||||
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, FileInfo);
|
||||
break;
|
||||
case FileStatInformation:
|
||||
Result = FspFsvolQueryStatInformation(FileObject, &Buffer, BufferEnd, FileInfo);
|
||||
break;
|
||||
case 70/*FileStatLxInformation*/:
|
||||
Result = FspFsvolQueryStatLxInformation(FileObject, &Buffer, BufferEnd, FileInfo);
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
Result = STATUS_INVALID_PARAMETER;
|
||||
|
@ -26,7 +26,10 @@ NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK Desir
|
||||
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
|
||||
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
||||
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
|
||||
static NTSTATUS FspSendSetInformationIrpCompletion(
|
||||
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
||||
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
||||
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
|
||||
static NTSTATUS FspSendIrpCompletion(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0);
|
||||
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
||||
NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
||||
@ -124,6 +127,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
||||
#pragma alloc_text(PAGE, FspCreateGuid)
|
||||
#pragma alloc_text(PAGE, FspGetDeviceObjectPointer)
|
||||
#pragma alloc_text(PAGE, FspSendSetInformationIrp)
|
||||
#pragma alloc_text(PAGE, FspSendQueryEaIrp)
|
||||
#pragma alloc_text(PAGE, FspBufferUserBuffer)
|
||||
#pragma alloc_text(PAGE, FspLockUserBuffer)
|
||||
#pragma alloc_text(PAGE, FspMapLockedPagesInUserMode)
|
||||
@ -275,7 +279,7 @@ typedef struct
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
KEVENT Event;
|
||||
} FSP_SEND_SET_INFORMATION_IRP_CONTEXT;
|
||||
} FSP_SEND_IRP_CONTEXT;
|
||||
|
||||
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
||||
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length)
|
||||
@ -289,7 +293,7 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File
|
||||
NTSTATUS Result;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
FSP_SEND_SET_INFORMATION_IRP_CONTEXT Context;
|
||||
FSP_SEND_IRP_CONTEXT Context;
|
||||
|
||||
if (0 == DeviceObject)
|
||||
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
@ -304,9 +308,9 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File
|
||||
IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
|
||||
IrpSp->FileObject = FileObject;
|
||||
IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
|
||||
IrpSp->Parameters.SetFile.Length = FileInformationClass;
|
||||
IrpSp->Parameters.SetFile.Length = Length;
|
||||
|
||||
IoSetCompletionRoutine(Irp, FspSendSetInformationIrpCompletion, &Context, TRUE, TRUE, TRUE);
|
||||
IoSetCompletionRoutine(Irp, FspSendIrpCompletion, &Context, TRUE, TRUE, TRUE);
|
||||
|
||||
KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
|
||||
Result = IoCallDriver(DeviceObject, Irp);
|
||||
@ -316,12 +320,58 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File
|
||||
return NT_SUCCESS(Result) ? Context.IoStatus.Status : Result;
|
||||
}
|
||||
|
||||
static NTSTATUS FspSendSetInformationIrpCompletion(
|
||||
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
||||
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
||||
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
FSP_SEND_IRP_CONTEXT Context;
|
||||
ULONG EaLength = *PEaLength;
|
||||
|
||||
*PEaLength = 0;
|
||||
|
||||
if (0 == DeviceObject)
|
||||
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
|
||||
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||
if (0 == Irp)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
IrpSp = IoGetNextIrpStackLocation(Irp);
|
||||
Irp->RequestorMode = KernelMode;
|
||||
Irp->AssociatedIrp.SystemBuffer = Ea;
|
||||
IrpSp->MajorFunction = IRP_MJ_QUERY_EA;
|
||||
IrpSp->FileObject = FileObject;
|
||||
IrpSp->Parameters.QueryEa.Length = EaLength;
|
||||
IrpSp->Parameters.QueryEa.EaList = GetEa;
|
||||
IrpSp->Parameters.QueryEa.EaListLength = GetEaLength;
|
||||
|
||||
IoSetCompletionRoutine(Irp, FspSendIrpCompletion, &Context, TRUE, TRUE, TRUE);
|
||||
|
||||
KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
|
||||
Result = IoCallDriver(DeviceObject, Irp);
|
||||
if (STATUS_PENDING == Result)
|
||||
KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0);
|
||||
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
if (NT_SUCCESS(Context.IoStatus.Status))
|
||||
*PEaLength = (ULONG)Context.IoStatus.Information;
|
||||
|
||||
return Context.IoStatus.Status;
|
||||
}
|
||||
|
||||
static NTSTATUS FspSendIrpCompletion(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0)
|
||||
{
|
||||
// !PAGED_CODE();
|
||||
|
||||
FSP_SEND_SET_INFORMATION_IRP_CONTEXT *Context = Context0;
|
||||
FSP_SEND_IRP_CONTEXT *Context = Context0;
|
||||
|
||||
Context->IoStatus = Irp->IoStatus;
|
||||
KeSetEvent(&Context->Event, 1, FALSE);
|
||||
|
Reference in New Issue
Block a user