|
很多情况下我们需要判断一个文件是否已经被打开,查阅资料发现网上说的很杂,算了,自己研究了一下,和大家交流一下!
<1>CreateFile
BOOL IsFileOpen(LPCWSTR lpfile)
{
HANDLE fileHandle=CreateFileW(L"C:\\Users\\Administrator\\Desktop\\123456789.txt",GENERIC_READ,NULL,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(fileHandle&&fileHandle!=INVALID_HANDLE_VALUE)
{
DWORD dw=GetLastError();
WCHAR szBuffer[MAX_PATH];
swprintf(szBuffer,L"The GetLaseerror is %d",dw);
OutputDebugStringW(szBuffer);
CloseHandle(fileHandle);
return TRUE;
}
else
{
return FALSE;
}
}
msdn查阅0这个参数是必须的,代表文件以独占的方式打开,想一下,一个美女现在有了老公了,你呢 ,还想单独拥有她,结果人家很恩爱,你呢,只能是伤心了,杀了他就好了,一下容不下二虎!沙占用文件发IRp去除相应的标记即可,有空代码奉上!
<2>ZwQueryObject
很不幸运,结果测试发现有的时候打开文件第一种方法失败了!郁闷!!!思索之下,原因未找到!只能另找新的途径!结果想了一个笨办法。这种方法不支持大家用,仅参考。
BOOL IsFileOpenByHandle(LPCWSTR lpPath)
{
ULONG cbBuffer = 0x4000;
LPVOID pBuffer = NULL;
NTSTATUS s;
do
{
pBuffer = malloc(cbBuffer);
if(pBuffer == NULL)
return FALSE;
memset(pBuffer,0,cbBuffer);
s = _ZwQuerySystemInforamtion(SystemHandleInformation,pBuffer,cbBuffer,NULL);
if(s == STATUS_INFO_LENGTH_MISMATCH)
{
free(pBuffer);
cbBuffer = cbBuffer * 2;
}
}while(s == STATUS_INFO_LENGTH_MISMATCH);//分配好了,早晚能够了 结构体的定义大家网上搜索
PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer;//PSYSTEM_HANDLE_INFORMATION_EX 自己定义 前四个节是handle 个数
for(DWORD i = 0;i<pInfo->NumberOfHandles;i++)
{
//if(pInfo->Information.ProcessId==PID)
{
WCHAR szBuffer[MAX_PATH];
BOOL zfTag=FALSE;
zfTag=GetPathByHandle((HANDLE)pInfo->Information.Handle,szBuffer,MAX_PATH);
if(zfTag)
{
if(_tcsnicmp(szBuffer,lpPath,_tcslen(lpPath))==0)
{
OutputDebugStringW(szBuffer);
OutputDebugStringW(L"\n");
free(pBuffer);
return TRUE;
}
}
}
}
free(pBuffer);
return FALSE;
}
BOOL GetPathByHandle(HANDLE hFile, LPWSTR lpBuf, DWORD nBuf) //这个方法是网上找的写的挺好
{
ULONG m, n;
WCHAR lpPath[MAX_PATH+4];
WCHAR lpDrive[MAX_PATH];
WCHAR lpDevName[MAX_PATH];
if (ZwQueryObject(hFile, 1, lpPath, MAX_PATH+4, &m) >= 0 && //如果大家不明白,参阅资料,好像ZwQueryObject,是个枚举体,1代表NameInfo,这个函数同样可以获得handle类型等等procexp.exe我感觉主要功能和这个函数密切相关,大家有兴趣可以一起探讨
(m = GetLogicalDriveStringsW(MAX_PATH, lpDrive)) && m < MAX_PATH)
{
WCHAR *p = lpDrive;
while (m = (ULONG)wcslen(p))
{
p[m-1] = L'\0';
n = QueryDosDeviceW(p, lpDevName, MAX_PATH);
if (n && n < MAX_PATH)
{
n = (ULONG)wcslen(lpDevName);
if (!wcsnicmp(lpPath+4, lpDevName, n))
{
wcsncpy(lpBuf, p, nBuf);
if (nBuf > 2) wcsncpy(lpBuf+2, lpPath+4+n, nBuf-2);
return TRUE;
}
}
p += m + 1;
}
}
return FALSE;
}
编译通过,运行结果不过,可是没有想到和第一种方法一样,还是存在问题,不过概率对于一般的使用几乎是零
其实nt函数,功能真的相当强大,大家如果学会使用这些函数,你可以做很多坏事的,哈哈哈 |
评分
-
查看全部评分
|