C++ 目录名为空的GetDiskFreeSpaceEx失败

C++ 目录名为空的GetDiskFreeSpaceEx失败,c++,windows,winapi,C++,Windows,Winapi,我试图在我的C++ Win32应用程序中使用GETDISKFRESPEACEX来获得当前驱动器上的可用字节总数。我在Windows7上 我正在使用以下示例代码: 而且它有效!嗯,差不多了。如果我提供一个驱动器,它就会工作,例如: ... szDrive[0] = 'C'; // <-- specifying drive szDrive[1] = ':'; szDrive[2] = '\\'; szDrive[3] = '\0'; pszDrive = szDrive; ... fR

我试图在我的C++ Win32应用程序中使用GETDISKFRESPEACEX来获得当前驱动器上的可用字节总数。我在Windows7上

我正在使用以下示例代码:

而且它有效!嗯,差不多了。如果我提供一个驱动器,它就会工作,例如:

...

szDrive[0] = 'C'; // <-- specifying drive
szDrive[1] = ':';
szDrive[2] = '\\';
szDrive[3] = '\0';

pszDrive = szDrive;

...

fResult = pGetDiskFreeSpaceEx ((LPCTSTR)pszDrive,
                             (PULARGE_INTEGER)&i64FreeBytesToCaller,
                             (PULARGE_INTEGER)&i64TotalBytes,
                               (PULARGE_INTEGER)&i64FreeBytes);
这奇怪吗?我肯定错过了什么?感谢您的帮助

编辑

根据Joseph的评论,我做了一个GetLastError()调用。它返回DWORD,用于:

错误\u无效\u名称123(0x7B)

第二次编辑

在我提到的评论中:

我尝试了GetCurrentDirectory,它返回了正确的绝对路径,只是在前面加了
\\?\


我非常确定您必须检索当前驱动器和目录,并将其传递给函数。我记得我曾试图使用目录名为
”的
GetDiskFreeSpaceEx()
,但没有成功

它返回正确的绝对路径,只是在前面加了
\\?\

这是解开这个谜的钥匙。返回的是带有本机api路径名的目录名。Windows是一个内部看起来与您熟悉的winapi编程非常不同的操作系统。Windows内核有一个完全不同的api,它非常类似于DEC VMS操作系统。大卫·卡特勒(David Cutler)曾为DEC工作,这并非巧合。除此之外,本机操作系统最初有三个api层:Win32、POSIX和OS/2。他们使得将程序从其他操作系统移植到WindowsNT变得很容易。没有人关心POSIX和OS/2层,它们在XP时代就被删除了

Win32中一个臭名昭著的限制是MAX_PATH 260的值。它设置存储文件路径名的C字符串的最大允许大小。本机api允许更大的名称,32000个字符。通过使用本机api格式的路径名,可以绕过Win32限制。它与您熟悉的路径名完全相同,但前缀为
\\?\

因此,从GetCurrentDirectory()返回这样一个字符串的原因肯定是因为当前目录名超过259个字符。进一步推断,GetDiskFreeSpaceEx()失败,因为它有一个bug,它拒绝传递NULL时看到的长名称。有些可以理解,它通常不需要处理长名字。每个人都只是传递驱动器名

这是创建具有如此长名称的目录时发生的典型情况。东西开始随机掉落。一般来说,有很多C代码使用MAX_路径,当它必须处理比MAX_路径长的路径名时,这些代码会失败得很惨。这也是一个很容易被利用的问题,因为它能够在C程序中创建堆栈缓冲区溢出,从技术上讲,精心编制的文件名可以用来操纵程序和注入恶意软件


对于这个问题没有真正的解决方法,GetDiskFreeSpaceEx()中的bug不会很快被修复。删除该目录,可能会造成更多的麻烦,并将其作为一种学习体验来记录。

调用
GetLastError()
以获取错误的详细信息。嗨,约瑟夫,我已经更新了我的答案,以包含
GetLastError()
的详细信息,不确定问题出在哪里
GetDiskFreeSpaceEx(NULL,&FreeByTestOcaler,&TotalBytes,&FreeBytes)
在我的机器(Windows 7)上运行良好。我没有使用
GetProcAddress
,因为我不希望现在有人运行Windows 95。奇怪。。。我还为实际的GetDiskFreeSpaceEx()函数调用关闭了pGetDiskFreeSpaceEx指针-即,没有GetProcAddress内容-仍然无法工作…还要注意,传递
NULL
将检索当前目录的可用磁盘空间。该目录的报告内容是什么?它是一个有效的目录吗?当您将
GetCurrentDirectory
的结果传递给
GetDiskFreeSpaceEx
时会发生什么?来自世界的另一端(UNIX),我真想知道。。。后者有一个API,
fpathconf()
-see-可用于查询给定目录中允许的最大路径名长度(mountpoint/junction/…)。这是对
sysconf()
路径\u MAX的全局查询的补充。Windows API是否有类似的功能?我不知道,请单击“提问”按钮。Hans,我非常感谢您的介绍,毫无疑问其他人也会这样做。因此,从这里我将尽我所能提取驱动器名并使用它。再次感谢!
fResult = pGetDiskFreeSpaceEx (NULL,
                             (PULARGE_INTEGER)&i64FreeBytesToCaller,
                             (PULARGE_INTEGER)&i64TotalBytes,
                               (PULARGE_INTEGER)&i64FreeBytes);

//fResult == false 
  The filename, directory name, or volume label syntax is incorrect.