如何从迷你筛选器驱动程序中的 PUNICODESTRING 中提取卷和父目录?



我正在为Windows编写一个微筛选器驱动程序。我可以通过我的GetProcessFileName函数获取进程映像名称,该函数使用ZwQueryInformationProcess获取进程映像文件名并返回具有如下值的 PUNICODESTRING :

DeviceHarddiskVolume2Program FilesCommon FilesACD SystemsPicaViewACDSeePicaView.exe

但我想从这个 PUNICODESTRING 中提取三个变量的音量和父目录。例如

PUNICODESTRING volume;
PUNICODESTRING parentdir;
PUNICODESTRING processname;

怎么能做到这一点,所以我的变量将是:

volume  ---> DeviceHarddiskVolume2
parentdir ---> Program FilesCommon FilesACD SystemsPicaView
processname ---> ACDSeePicaView.exe

使用FltParseFileName函数 https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/fltkernel/nf-fltkernel-fltparsefilename

FltParse文件名解析扩展名、流和最终组件 从文件名字符串。

NTSTATUS FLTAPI FltParseFileName(
[in]      PCUNICODE_STRING FileName,
[in, out] PUNICODE_STRING  Extension,
[in, out] PUNICODE_STRING  Stream,
[in, out] PUNICODE_STRING  FinalComponent
);

该函数采用UNICODE_STRING结构指针,并返回文件扩展名、流和最终组件。

\设备\硬盘卷2\程序文件\通用文件\ACD 系统\PicaView\ACDSeePicaView.exe

扩展名:"exe">

最终组件:"ACDSeePicaView">

您可以通过第三个反斜杠之前的 get 字符串和父目录来获取卷名,并通过从字符串中减去卷和最终组件 + 扩展名来获取父目录。

这是一个从文件路径字符串中提取卷名的函数

NTSTATUS GetVolumeNameFromFileName(PUNICODE_STRING FileName, PUNICODE_STRING VolumeName) {
NTSTATUS status = STATUS_UNSUCCESSFUL;
PWCHAR fileName = ExAllocatePool2(POOL_FLAG_PAGED, FileName->Length + sizeof(WCHAR), 100);
if (fileName == NULL) {
KdPrint(("GetVolumeNameFromFileName -> Not enough memory to allocate for the file name.rn"));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(fileName, FileName->Buffer, FileName->Length);
WCHAR* p;
//Search the third backslash in the file name string
int pos = 0;
int slashIndex = -1;
p = wcschr(fileName, L'\');
while (p != NULL && pos < 3) {
if (pos == 2) {
slashIndex = p - fileName;
}
else {
p = wcschr(p + 1, L'\');
}
pos += 1;
}
ExFreePoolWithTag(fileName, 100);
if (slashIndex == -1) {
KdPrint(("GetVolumeNameFromFileName -> Failed to get the directory separator index.rn"));
return STATUS_UNSUCCESSFUL;
}
UNICODE_STRING volumeName = { 0 };
volumeName.Length = 0;
volumeName.MaximumLength = (slashIndex + 1) * sizeof(WCHAR);
volumeName.Buffer = ExAllocatePool2(POOL_FLAG_PAGED, volumeName.MaximumLength, 101);
status = RtlUnicodeStringCchCopyN(&volumeName, FileName, slashIndex);
if (NT_SUCCESS(status)) {
*VolumeName = volumeName;
}
else {
KdPrint(("GetVolumeNameFromFileName -> RtlUnicodeStringCchCopyN function failed (%08x).rn", status));
}
return status;

}

相关内容

  • 没有找到相关文章

最新更新