2017-02-24 95 views
0

好的,这让我发疯。我正在编写一个简单的程序,沿着目录树查看驱动器上所有文件的大小。漂亮的驯服的东西。FindFirstFile跳过一个目录

但我注意到我没有得到我预期的答案。原来我的代码是跳过的一些目录。首先,这里有一个(简体)版本我的代码:

#include <stdio.h> 
#include <Windows.h> 

int main() 
{ 
    WIN32_FIND_DATA fd; 
    HANDLE h = FindFirstFile(L"c:\\Windows\\System32\\wbem\\*.*", &fd); 

    if (h != INVALID_HANDLE_VALUE) 
    { 
    BOOL b; 
    do { 
     if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
      printf("d: %S\n", fd.cFileName); 
     //else 
     // printf("f: %S\n", fd.cFileName); 

     b = FindNextFile(h, &fd); 
    } while (b != FALSE); 
    FindClose(h); 
    } 
} 

我得到的输出是相当多的,你会想到什么:

d: . 
d: .. 
d: AutoRecover 
d: en-US 
d: Logs 
d: Repository 
d: tmf 
d: xml 

然而,在C命令提示符:\ WINDOWS \ SYSTEM32 \ WBEM,dir /ad给我:

06/15/2016 07:20 PM <DIR>   . 
06/15/2016 07:20 PM <DIR>   .. 
04/14/2016 05:40 PM <DIR>   AutoRecover 
03/24/2011 03:52 PM <DIR>   en-US 
07/13/2009 06:34 PM <DIR>   Logs 
07/13/2009 09:08 PM <DIR>   MOF 
02/20/2017 10:32 PM <DIR>   Performance 
02/23/2017 03:59 AM <DIR>   Repository 
07/13/2009 06:36 PM <DIR>   tmf 
07/13/2009 07:20 PM <DIR>   xml 
       0 File(s)    0 bytes 
       10 Dir(s) 171,203,104,768 bytes free 

仔细检查表明,PerformanceMOF目录不在我的输出中。咦?

显然这些目录有些不同。但是什么?

  • 看着dir输出,我们可以看到它们不是连接点。
  • 使用attrib,没有任何特殊的标志设置(如系统或隐藏)。
  • fsutil不显示任何硬链接。
  • 看着目录权限,管理员(我是)完全控制。

我很难过。我甚至跑到chkdsk /f去查看我的目录表是否被搞砸了。除了一些Cleaning up 472 unused index entries from index $SII of file 0x9. Cleaning up 472 unused index entries from index $SDH of file 0x9.它没有找到任何东西。

我试过使用FindFileEx与各种选项,但我仍然无法让这些目录出现。

我想不出还有什么可以尝试的。什么会导致这些目录出现dir但不是FindFile? (更重要的是)我如何让它们出现在FindFile中?

FWIW:

  • Windows 7专业版64位
  • 驱动器C是NTFS
  • 楼内有2010 MSVC

回答

3

你的代码试图访问64位System32文件夹。

我猜你的代码编译为32位,因此你实际上正在访问32位SysWOW64文件夹,而不是由于File System Redirector。在我的Win7 x64机器上,丢失的文件夹(MOFPerformance)仅存在于64位System32\wbem文件夹中,但不存在于32位SysWOW64\wbem文件夹中。

如果32位代码要访问64位System32文件夹,它必须使用WOW64的特殊Sysnative别名来避免重定向,如:

HANDLE h = FindFirstFile(L"c:\\Windows\\Sysnative\\wbem\\*.*", &fd); 

使用IsWow64Process()知道,如果你的代码中运行的WOW64模拟器或不。

就是说,你不应该硬编码c:\\Windows路径。并非所有用户都将Windows安装到该路径。使用GetWindowsDirectory(),SHGetFolderPath(CSIDL_WINDOWS)SHGetKnownFolderPath(FOLDERID_Windows)来代替实际路径。

尝试更多的东西是这样的:

bool IsRunningInWow64() 
{ 
    #ifndef _WIN64 
    BOOL bIsWow64 = FALSE; 
    if (IsWow64Process(GetCurrentProcess(), &bIsWow64) && bIsWow64) 
     return true; 
    #endif 

    return false; 
} 

... 

WCHAR szMask[MAX_PATH]; 

if (IsRunningInWow64()) 
{ 
    // Must be a 32-bit process running on a 64-bit system. 
    // Use the 'Sysnative' alias... 

    GetWindowsDirectory(szMask, MAX_PATH); 
    // or: SHGetFolderPath(..., CSIDL_WINDOWS, ...); 
    // or: SHGetKnownFolderPath(FOLDERID_Windows, ...); 
    PathAppend(szMask, L"Sysnative"); 
} 
else 
{ 
    // Must be either: 
    // - A 32-bit process running on a 32-bit system. 
    // - A 64-bit process running on a 64-bit system. 
    // Use the standard 'System32' path... 

    GetSystemDirectory(szMask, MAX_PATH); 
    // or: SHGetFolderPath(..., CSIDL_SYSTEM, ...); 
    // or: SHGetKnownFolderPath(FOLDERID_System, ...); 
} 

PathAppend(szMask, L"wbem"); 
PathAppend(szMask, L"*.*"); 

HANDLE h = FindFirstFile(szMask, &fd); 
+0

卫生署!是的,当然,我正在建设32位。它报告的目录来自syswow64。那里的wbem目录不包含这两个目录。 –