jiedengye 发表于 2010-7-17 17:11:10

判别文件是否被占用的方法

很多情况下我们需要判断一个文件是否已经被打开,查阅资料发现网上说的很杂,算了,自己研究了一下,和大家交流一下!
<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();
WCHARszBuffer;
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;
   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;
WCHAR lpDrive;
WCHAR lpDevName;

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 = 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函数,功能真的相当强大,大家如果学会使用这些函数,你可以做很多坏事的,哈哈哈

Tesla.Angela 发表于 2010-7-17 20:39:23

是原创吗?支持楼主。

阿杰 发表于 2010-7-18 10:59:06

感谢分享

jiedengye 发表于 2010-7-18 11:13:41

第一种方法网上有介绍,不过第二种是俺自己想出来的,嘿嘿
页: [1]
查看完整版本: 判别文件是否被占用的方法