C Winapi:获取具有文件特定句柄的进程
目前我有一个软件,它有一个文件过滤器驱动程序,在软件安装过程中,驱动程序以如下方式作为服务启动:C Winapi:获取具有文件特定句柄的进程,c,windows,winapi,cmd,cygwin,C,Windows,Winapi,Cmd,Cygwin,目前我有一个软件,它有一个文件过滤器驱动程序,在软件安装过程中,驱动程序以如下方式作为服务启动: CreateService(serviceManager, name, displayName, SERVICE_START | DELETE | SERVICE_QUERY_STATUS | SERVICE_STOP, SERVICE_FILE_SYSTEM_DRIVER, SERVIC
CreateService(serviceManager, name, displayName,
SERVICE_START | DELETE | SERVICE_QUERY_STATUS | SERVICE_STOP,
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
path, NULL, NULL, NULL, NULL, NULL);
其中路径是C:\ProgramFiles(x86)\TSU\driver\TSUfsd.sys
我遇到的问题是在卸载软件的过程中。当软件试图删除TSUfsd.sys
文件时,它允许我拒绝访问
我检查了软件是如何删除驱动程序的,结果显示它使用DeleteService
功能删除驱动程序,并等待服务将其状态从service\u STOP\u PENDING
更改为service\u STOPPED
,如果一段时间后没有发生,它获取服务PID
并使用ProcessTerminate
终止它,然后尝试使用rmdir/S/Q C:\Program Files(x86)\TSU\
删除文件
我试图找到可以处理文件的进程(使用process Explorer),但找不到任何进程。然后我想可能该服务还活着,所以我键入了sc query TSUfsd
,但该服务也消失了
我还尝试更改权限并向我的用户授予完全权限,但仍然发生相同的错误
因此,我的问题是:
rm TSUfsd.sys
)删除文件时,它都会毫无问题地删除文件。使用cmd(del/f
)和cygwin删除文件有什么区别对于此任务,请从Windows Vista特殊存在开始
fileprocessidusingfileinformation
因此,我们需要使用文件读取属性打开文件(即使有人以0共享模式打开文件,这也是可能的。当然,如果我们无法访问文件(通过它DACL),但可以读取父目录)。并使用fileprocessidusingfileinformation
调用。返回时,我们使用文件信息
结构(在wdm.h
中定义)获得了FILE\u进程ID\u,其中包含保存此文件的ProcessId
列表(打开文件句柄或映射节。假设此文件是exe/dll-我们在加载的位置获得了进程ID)。同样适用于每个id的打印过程名称:
volatile UCHAR guz = 0;
NTSTATUS PrintProcessesUsingFile(HANDLE hFile)
{
NTSTATUS status;
IO_STATUS_BLOCK iosb;
ULONG cb = 0, rcb = FIELD_OFFSET(FILE_PROCESS_IDS_USING_FILE_INFORMATION, ProcessIdList[64]);
union {
PVOID buf;
PFILE_PROCESS_IDS_USING_FILE_INFORMATION ppiufi;
};
PVOID stack = alloca(guz);
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (0 <= (status = NtQueryInformationFile(hFile, &iosb, ppiufi, cb, FileProcessIdsUsingFileInformation)))
{
if (ppiufi->NumberOfProcessIdsInList)
{
PrintProcessesUsingFile(ppiufi);
}
}
rcb = (ULONG)iosb.Information;
} while (status == STATUS_INFO_LENGTH_MISMATCH);
return status;
}
NTSTATUS PrintProcessesUsingFile(POBJECT_ATTRIBUTES poa)
{
IO_STATUS_BLOCK iosb;
HANDLE hFile;
NTSTATUS status;
if (0 <= (status = NtOpenFile(&hFile, FILE_READ_ATTRIBUTES, poa, &iosb, FILE_SHARE_VALID_FLAGS, 0)))
{
status = PrintProcessesUsingFile(hFile);
NtClose(hFile);
}
return status;
}
NTSTATUS PrintProcessesUsingFile(PCWSTR FileName)
{
UNICODE_STRING ObjectName;
NTSTATUS status = RtlDosPathNameToNtPathName_U_WithStatus(FileName, &ObjectName, 0, 0);
if (0 <= status)
{
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
status = PrintProcessesUsingFile(&oa);
RtlFreeUnicodeString(&ObjectName);
}
return status;
}
NTSTATUS PrintProcessesUsingFile(PFILE_PROCESS_IDS_USING_FILE_INFORMATION ppiufi)
{
NTSTATUS status;
ULONG cb = 0x8000;
do
{
status = STATUS_INSUFFICIENT_RESOURCES;
if (PVOID buf = new BYTE[cb])
{
if (0 <= (status = NtQuerySystemInformation(SystemProcessInformation, buf, cb, &cb)))
{
union {
PVOID pv;
PBYTE pb;
PSYSTEM_PROCESS_INFORMATION pspi;
};
pv = buf;
ULONG NextEntryOffset = 0;
do
{
pb += NextEntryOffset;
ULONG NumberOfProcessIdsInList = ppiufi->NumberOfProcessIdsInList;
PULONG_PTR ProcessIdList = ppiufi->ProcessIdList;
do
{
if (*ProcessIdList++ == (ULONG_PTR)pspi->UniqueProcessId)
{
DbgPrint("%p %wZ\n", pspi->UniqueProcessId, &pspi->ImageName);
break;
}
} while (--NumberOfProcessIdsInList);
} while (NextEntryOffset = pspi->NextEntryOffset);
}
delete [] buf;
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
return status;
}
volatile-UCHAR-guz=0;
NTSTATUS打印进程使用文件(句柄hFile)
{
非关税国家地位;
IO_状态_块iosb;
ULONG cb=0,rcb=FIELD_OFFSET(使用文件信息的文件进程ID,ProcessIdList[64]);
联合{
pvoidbuf;
使用文件信息ppiufi的文件处理ID;
};
PVOID stack=alloca(guz);
做
{
如果(cbUniqueProcessId,&pspi->ImageName);
打破
}
}而(--NumberOfProcessIdsInList);
}而(NexteryOffset=pspi->NexteryOffset);
}
删除[]buf;
}
}而(状态==状态信息长度不匹配);
返回状态;
}
有一个很好的实用程序,名为Mark Russinovich。除非你想自己用代码来做,然后您可以枚举所有进程并检查它们的句柄?在windows 10中-系统保留已加载的驱动程序,在驱动程序将被卸载之前不允许删除。非常感谢您的回答:)因为生成代码时会出现错误:#windows DDK不支持错误编译器版本#windows DDK不支持错误编译器版本
我无法真正更新我的编译器,因为它安装在我的大学计算机上,更新它需要许可和大量时间@建议使用handle.exe来解决此问题,您的代码是否与handle.exe执行相同的操作?@user3503143-是。相同-fileprocessidusingfileinformation
-您的编译器版本是什么?您只需将粘贴wdk定义(NtQueryInformationFile
)复制到自己的src(GCC)4.9.2
,我们正在使用Cygwin。我尝试了handle.exe
,但没有找到匹配的句柄
。还有什么别的原因呢?用户配置文件和文件本身没有损坏。@user3503143您完全可以通过复制/粘贴一些定义来编译此代码。我只是简单地粘贴自己的就绪状态。但是,此处仅强制要求NtQueryInformationFile
,文件信息类
和文件处理ID使用文件信息
。对于可以使用CreateFileW
的打开文件,将进程id转换为不能使用的名称。@user3503143-按用户模式应用程序的方式包括wdm.h(windows.h也是如此)是很困难的。需要在名称空间中包含它+一些技巧。不要尝试将wdm.h包含到项目中。只需使用文件信息和NtQueryInformationFile复制/粘贴文件信息类和文件进程ID即可。使用CreateFileW打开文件(文件读取属性
和文件标志
备份语义)–真正的任务是绝对可行的