【问题标题】:DeviceIoControl GetLastError 87 (ERROR_INVALID_PARAMETER)DeviceIoControl GetLastError 87 (ERROR_INVALID_PARAMETER)
【发布时间】:2018-01-07 15:59:52
【问题描述】:

这段代码在 Windows 7 上启动时非常好:

HANDLE hVol = CreateFile(L"\\\\.\\c:", GENERIC_WRITE | GENERIC_READ, 
                         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
// hVol is always successful (both of Win7 and 10), I double-checked
BYTE pData[sizeof(DWORDLONG) + 0x10000];
DWORD cb;
MFT_ENUM_DATA med;
med.StartFileReferenceNumber = 0;
med.LowUsn = 0;
med.HighUsn = MAXLONGLONG;
DeviceIoControl(hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL);
err = GetLastError();

但在 Windows 10 上运行时出现错误 87 (ERROR_INVALID_PARAMETER)。可能是什么原因?

【问题讨论】:

  • 为什么指定GENERIC_WRITE?你似乎只是在阅读。

标签: c++ windows winapi ntfs deviceiocontrol


【解决方案1】:

MFT_ENUM_DATA 这真的是 typedef 扩展为 MFT_ENUM_DATA_V0MFT_ENUM_DATA_V1 取决于 NTDDI_VERSION

#if (NTDDI_VERSION >= NTDDI_WIN8)
typedef MFT_ENUM_DATA_V1 MFT_ENUM_DATA, *PMFT_ENUM_DATA;
#else
typedef MFT_ENUM_DATA_V0 MFT_ENUM_DATA, *PMFT_ENUM_DATA;
#endif

显然在你的情况下NTDDI_VERSION >= NTDDI_WIN8 而你使用MFT_ENUM_DATA_V1

并且您没有初始化必须设置为 2 或 3 的 MaxMajorVersion

所以你需要或添加行med.MaxMajorVersion = 2;(或3)。或使用MFT_ENUM_DATA_V0 med={};

【讨论】:

  • #if (NTDDI_VERSION >= NTDDI_WIN8) 在编译时进行评估。 OP 在两个系统上都运行 same 二进制文件,因此与问题无关。
  • @IInspectable - 当然是在编译时评估的。那又怎样?
  • 我在 Win7 上编译,在 Win7 和 Win10 上测试了相同的 .exe。我同意你的观点@IInspectable:它是在编译时评估的。但奇怪的是,MFT_ENUM_DATA_V0 med; 解决了这个问题 :)(非常感谢 RbMm!)
  • @Basj - 哪里 你编译 - 绝对不重要。重要的是您使用什么版本的 sdk(我假设您没有直接定义 NTDDI_VERSION 自己)
  • @RbMm 没错。我检查了:在编译时(在Win7上,但这没关系),因为我有SDK,我看到NTDDI_VERSION >= NTDDI_WIN8是真的,所以这是应用的:typedef MFT_ENUM_DATA_V1 MFT_ENUM_DATA, *PMFT_ENUM_DATA;
猜你喜欢
  • 2020-11-10
  • 2020-07-06
  • 2015-04-04
  • 2014-03-02
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
相关资源
最近更新 更多