【问题标题】:CreateFileMapping for Directory为目录创建文件映射
【发布时间】:2011-11-23 19:41:06
【问题描述】:

我有这个函数,它从文件句柄中给出完整的文件名(路径)。唯一的问题是目录句柄的 CreateFileMapping 失败。有解决办法吗?

我使用 NtCreateFile() 获取句柄

   ULONG status = NtCreatefile(&f, GENERIC_ALL, &oa, iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_OPEN_BY_FILE_ID , NULL, 0);
    printf("status: %X, handle: %x\n", status, f);

   BOOL CHouseKeeper::GetFileNameFromHandle(HANDLE hFile) 
{
  BOOL bSuccess = FALSE;
  TCHAR pszFilename[MAX_PATH+1];
  HANDLE hFileMap;

  // Get the file size.
  DWORD dwFileSizeHi = 0;
  DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi); 

  if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
  {
     _tprintf(TEXT("Cannot map a file with a length of zero.\n"));
     return FALSE;
  }

  // Create a file mapping object.
  //It fails here if a directory handle is passed, it returns 0
  hFileMap = CreateFileMapping(hFile, 
                NULL, 
                PAGE_READONLY,
                0, 
                1,
                NULL);

  if (hFileMap) 
  {
    // Create a file mapping to get the file name.
    void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);

    if (pMem) 
    {
      if (GetMappedFileName (GetCurrentProcess(), 
                         pMem, 
                         pszFilename,
                         MAX_PATH)) 
      {

        // Translate path with device name to drive letters.
        TCHAR szTemp[BUFSIZE];
        szTemp[0] = '\0';

        if (GetLogicalDriveStrings(BUFSIZE-1, szTemp)) 
        {
      TCHAR szName[MAX_PATH];
      TCHAR szDrive[3] = TEXT(" :");
      BOOL bFound = FALSE;
      TCHAR* p = szTemp;

      do 
      {
        // Copy the drive letter to the template string
        *szDrive = *p;

        // Look up each device name
        if (QueryDosDevice(szDrive, szName, MAX_PATH))
        {
          size_t uNameLen = _tcslen(szName);

          if (uNameLen < MAX_PATH) 
          {
            bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0
                     && *(pszFilename + uNameLen) == _T('\\');

            if (bFound) 
            {
              // Reconstruct pszFilename using szTempFile
              // Replace device path with DOS path
              TCHAR szTempFile[MAX_PATH];
              StringCchPrintf(szTempFile,
                        MAX_PATH,
                        TEXT("%s%s"),
                        szDrive,
                        pszFilename+uNameLen);
              StringCchCopyN(pszFilename, MAX_PATH+1, szTempFile, _tcslen(szTempFile));
            }
          }
        }

        // Go to the next NULL character.
        while (*p++);
      } while (!bFound && *p); // end of string
    }
  }
  bSuccess = TRUE;
  UnmapViewOfFile(pMem);
} 

CloseHandle(hFileMap);
  }else {

  wcout<<GetLastError()<<endl;
  }
  _tprintf(TEXT("File name is %s\n"), pszFilename);
  return(bSuccess);
}

【问题讨论】:

  • 内存映射文件需要一个文件,它不能对目录做任何有意义的事情。使用 GetFinalPathNameByHandle()。
  • 既然你创建了这个文件,你肯定知道它叫什么名字吧?
  • @HansPassant:你救了我的命。那一个功能足以取代我发布的所有废话。只需将其发布为答案。非常感谢。
  • @DavidHeffernan:不,我正在使用 NtCreatefile() 获取文件句柄,它基本上给了我一个文件名,查看文件参考号。
  • @roymustang86 好的,我看不到,因为我看不到您传递给 NtCreateFile 的内容。无论如何,avakar 的答案似乎更合适,因为它适用于 Win2k 而不是 Vista。

标签: c++ windows backup wdk


【解决方案1】:

您可以使用 NtQueryInformationFile 和 FileNameInformation 来检索与文件句柄关联的名称。

【讨论】:

    猜你喜欢
    • 2021-08-25
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多