📄 dirctl.c
字号:
SetFlag(
Buffer->FileAttributes,
FILE_ATTRIBUTE_DIRECTORY
);
}
#ifndef FSD_RO
if (FlagOn(Vcb->Flags, VCB_READ_ONLY))
#endif
{
SetFlag(
Buffer->FileAttributes,
FILE_ATTRIBUTE_READONLY
);
}
Buffer->FileNameLength = InodeFileNameLength * 2;
Buffer->EaSize = 0;
Buffer->FileId = Fcb->IndexNumber;
RtlCopyMemory(
Buffer->FileName,
InodeFileName.Buffer,
InodeFileNameLength * 2
);
UsedLength += QueryBlockLength +
InodeFileNameLength * 2 - sizeof(WCHAR);
if (!ReturnSingleEntry)
{
Buffer->NextEntryOffset = QueryBlockLength +
InodeFileNameLength * 2 - sizeof(WCHAR) +
UsedLength % 8;
}
else
{
Buffer->NextEntryOffset = 0;
}
UsedLength += UsedLength % 8;
NextEntryOffset = &Buffer->NextEntryOffset;
}
break;
case FileIdBothDirectoryInformation:
{
PFILE_ID_BOTH_DIR_INFORMATION Buffer;
Buffer = (PFILE_ID_BOTH_DIR_INFORMATION)
(UserBuffer + UsedLength);
/*
typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
LARGE_INTEGER FileId;
WCHAR FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;
*/
Buffer->FileIndex = FileIndex;
Buffer->CreationTime.QuadPart = 0;
Buffer->LastAccessTime.QuadPart = 0;
Buffer->LastWriteTime.QuadPart = 0;
Buffer->ChangeTime.QuadPart = 0;
Buffer->EndOfFile.QuadPart =
be32_to_cpu(Inode->size);
Buffer->AllocationSize.QuadPart =
be32_to_cpu(Inode->size);
Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
if (FlagOn(be32_to_cpu(Inode->next), ROMFH_DIR))
{
SetFlag(
Buffer->FileAttributes,
FILE_ATTRIBUTE_DIRECTORY
);
}
#ifndef FSD_RO
if (FlagOn(Vcb->Flags, VCB_READ_ONLY))
#endif
{
SetFlag(
Buffer->FileAttributes,
FILE_ATTRIBUTE_READONLY
);
}
Buffer->FileNameLength = InodeFileNameLength * 2;
Buffer->EaSize = 0;
// TODO: Present a short alias
// Here we would like to use RtlGenerate8dot3Name but
// I don't know how to use the argument
// PGENERATE_NAME_CONTEXT
// Buffer->ShortNameLength
// Buffer->ShortName
Buffer->FileId = Fcb->IndexNumber;
RtlCopyMemory(
Buffer->FileName,
InodeFileName.Buffer,
InodeFileNameLength * 2
);
UsedLength += QueryBlockLength +
InodeFileNameLength * 2 - sizeof(WCHAR);
if (!ReturnSingleEntry)
{
Buffer->NextEntryOffset = QueryBlockLength +
InodeFileNameLength * 2 - sizeof(WCHAR) +
UsedLength % 8;
}
else
{
Buffer->NextEntryOffset = 0;
}
UsedLength += UsedLength % 8;
NextEntryOffset = &Buffer->NextEntryOffset;
}
break;
#endif // (VER_PRODUCTBUILD >= 2600)
}
}
if (InodeFileName.Buffer != NULL)
{
FsdFreePool(InodeFileName.Buffer);
InodeFileName.Buffer = NULL;
}
Ccb->CurrentByteOffset =
FileIndex =
Inode->next;
if (UsedLength && ReturnSingleEntry)
{
Status = STATUS_SUCCESS;
__leave;
}
}
if (!UsedLength)
{
if (FirstQuery)
{
Status = STATUS_NO_SUCH_FILE;
}
else
{
Status = STATUS_NO_MORE_FILES;
}
}
else
{
Status = STATUS_SUCCESS;
}
}
__finally
{
if (FcbResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->MainResource,
ExGetCurrentResourceThread()
);
}
if (UpcaseFileName.Buffer != NULL)
{
FsdFreePool(UpcaseFileName.Buffer);
}
if (Inode != NULL)
{
FsdFreePool(Inode);
}
if (InodeFileName.Buffer != NULL)
{
FsdFreePool(InodeFileName.Buffer);
}
if (NextEntryOffset != NULL)
{
*NextEntryOffset = 0;
}
if (!AbnormalTermination())
{
if (Status == STATUS_PENDING)
{
Status = FsdLockUserBuffer(
IrpContext->Irp,
Length,
IoWriteAccess
);
if (NT_SUCCESS(Status))
{
Status = FsdQueueRequest(IrpContext);
}
else
{
IrpContext->Irp->IoStatus.Status = Status;
FsdCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
FsdFreeIrpContext(IrpContext);
}
}
else
{
IrpContext->Irp->IoStatus.Information = UsedLength;
IrpContext->Irp->IoStatus.Status = Status;
FsdCompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
FsdFreeIrpContext(IrpContext);
}
}
}
return Status;
}
NTSTATUS
FsdNotifyChangeDirectory (
IN PFSD_IRP_CONTEXT IrpContext
)
{
PDEVICE_OBJECT DeviceObject;
BOOLEAN CompleteRequest;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PFSD_VCB Vcb;
PFILE_OBJECT FileObject;
PFSD_FCB Fcb;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
ULONG CompletionFilter;
BOOLEAN WatchTree;
__try
{
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == ICX) &&
(IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
if (DeviceObject == FsdGlobalData.DeviceObject)
{
CompleteRequest = TRUE;
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
Vcb = (PFSD_VCB) DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == VCB) &&
(Vcb->Identifier.Size == sizeof(FSD_VCB)));
FileObject = IrpContext->FileObject;
Fcb = (PFSD_FCB) FileObject->FsContext;
ASSERT(Fcb);
if (Fcb->Identifier.Type == VCB)
{
CompleteRequest = TRUE;
Status = STATUS_INVALID_PARAMETER;
__leave;
}
ASSERT((Fcb->Identifier.Type == FCB) &&
(Fcb->Identifier.Size == sizeof(FSD_FCB)));
if (!FlagOn(Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
{
CompleteRequest = TRUE;
Status = STATUS_INVALID_PARAMETER;
__leave;
}
Irp = IrpContext->Irp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
#ifndef _GNU_NTIFS_
CompletionFilter =
IrpSp->Parameters.NotifyDirectory.CompletionFilter;
#else
CompletionFilter = ((PEXTENDED_IO_STACK_LOCATION)
IrpSp)->Parameters.NotifyDirectory.CompletionFilter;
#endif
WatchTree = FlagOn(IrpSp->Flags, SL_WATCH_TREE);
CompleteRequest = FALSE;
Status = STATUS_PENDING;
FsRtlNotifyChangeDirectory(
Vcb->NotifySync,
FileObject->FsContext2,
(PSTRING)&Fcb->FileName,
&Vcb->NotifyList,
WatchTree,
CompletionFilter,
Irp
);
/*
Currently the driver is read-only but here is an example on how to use the
FsRtl-functions to report a change:
UNICODE_STRING TestString;
USHORT FileNamePartLength;
RtlInitUnicodeString(&TestString, L"\\ntifs.h");
FileNamePartLength = 7 * sizeof(WCHAR);
FsRtlNotifyReportChange(
Vcb->NotifySync, // PNOTIFY_SYNC NotifySync
&Vcb->NotifyList, // PLIST_ENTRY NotifyList
(PSTRING)&TestString, // PSTRING FullTargetName
&FileNamePartLength, // PUSHORT FileNamePartLength
FILE_NOTIFY_CHANGE_FILE_NAME // ULONG FilterMatch
);
or
UNICODE_STRING TestString;
RtlInitUnicodeString(&TestString, L"\\ntifs.h");
FsRtlNotifyFullReportChange(
Vcb->NotifySync, // PNOTIFY_SYNC NotifySync
&Vcb->NotifyList, // PLIST_ENTRY NotifyList
(PSTRING)&TestString, // PSTRING FullTargetName
2, // USHORT TargetNameOffset
NULL, // PSTRING StreamName OPTIONAL
NULL, // PSTRING NormalizedParentName OPTIONAL
FILE_NOTIFY_CHANGE_FILE_NAME, // ULONG FilterMatch
FILE_ACTION_ADDED, // ULONG Action
NULL // PVOID TargetContext
);
*/
}
__finally
{
if (!AbnormalTermination())
{
if (CompleteRequest)
{
IrpContext->Irp->IoStatus.Status = Status;
FsdCompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
}
FsdFreeIrpContext(IrpContext);
}
}
return Status;
}
#pragma code_seg() // end FSD_PAGED_CODE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -