DeviceIoControl 在 C++ 和 C# 中工作,但在 C++/CLI 中调用时返回 ERROR_INVALID_FUNCTION

Posted

技术标签:

【中文标题】DeviceIoControl 在 C++ 和 C# 中工作,但在 C++/CLI 中调用时返回 ERROR_INVALID_FUNCTION【英文标题】:DeviceIoControl works in C++ and C# but return ERROR_INVALID_FUNCTION when called in C++/CLI 【发布时间】:2013-06-29 01:59:09 【问题描述】:

我正在尝试枚举 MFT 以获取文件名列表。

此代码在 Win32 项目中使用时有效:

MFT_ENUM_DATA med;
med.StartFileReferenceNumber = 0;
med.LowUsn = 0;
med.HighUsn = ujd.NextUsn;
BYTE pData[sizeof(DWORDLONG) + 0x10000];
DWORD cb;
while (DeviceIoControl(handleToVolume, FSCTL_ENUM_USN_DATA, &med, sizeof(med),
  pData, sizeof(pData), &cb, NULL) != FALSE) 
 //do the processing

但是当我在 C++/CLI 中使用相同的代码时,DeviceIoControl 给出 false,GetLastError 给出 ERROR_INVALID_FUNCTION。 当相同的代码被翻译成 C# 时,它可以工作。

知道发生了什么吗?

【问题讨论】:

您应该注意托管代码中的GetLastError。您应该在 DllImport 属性中放置正确的标志,并改用Marshal::GetLastWin32Error...此外,即使它不应该产生影响,您也应该在调用之前将cb 初始化为零。 我正在使用非托管 DeviceIoControl。我也试过Marshal::GetLastWin32Error,它给出的值1与GetLastError相同。也初始化了cb,但是不行。我现在想知道这是否是由某些项目设置或属性引起的...... 【参考方案1】:

检查你是否有这个定义:

#define FSCTL_ENUM_USN_DATA 
 CTL_CODE(FILE_DEVICE_FILE_SYSTEM,44,METHOD_NEITHER,FILE_READ_DATA)

并将FILE_READ_DATA 替换为FILE_ANY_ACCESS

【讨论】:

以上是关于DeviceIoControl 在 C++ 和 C# 中工作,但在 C++/CLI 中调用时返回 ERROR_INVALID_FUNCTION的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 VB.NET 中使用 DeviceIoControl 进行文件枚举比在 C++ 中更快?

如何通过 C#.net 中的 DeviceIoControl 使用 IOCTL_SCSI_MINIPORT?

使用 usbser.sys 冻结 SerialPort.Open / DeviceIoControl / GetcommState

使用 DeviceIoControl 都有哪些好的策略?

Winpcap 和 DeviceIoControl - Win7 上的错误代码 1

如何在 C# 中使用 DeviceIoControl 和 FSCTL_MAKE_MEDIA_COMPATIBLE 完成 Live File System (LiveUDF) 光盘?