Ice*_*Van 1 c# windows winapi interop
我试图DeviceIoControl用代码在C#中调用WinAPI函数IOCTL_DISK_SET_DISK_ATTRIBUTES并传递struct SET_DISK_ATTRIBUTES。我正在尝试使用以下代码:
const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;
const uint IOCTL_DISK_SET_DISK_ATTRIBUTES = 0x0007c0f4;
const ulong DISK_ATTRIBUTE_READ_ONLY = 0x0000000000000002;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr SecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped
);
struct SET_DISK_ATTRIBUTES
{
public uint Version;
public bool Persist;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved1;
public ulong Attributes;
public ulong AttributesMask;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] Reserved2;
};
private bool SetReadonly(IntPtr handle)
{
var sda = new SET_DISK_ATTRIBUTES();
sda.AttributesMask = DISK_ATTRIBUTE_READ_ONLY;
sda.Attributes = DISK_ATTRIBUTE_READ_ONLY;
int nPtrQryBytes = Marshal.SizeOf(sda);
sda.Version = (uint)nPtrQryBytes;
IntPtr ptrQuery = Marshal.AllocHGlobal(nPtrQryBytes);
Marshal.StructureToPtr(sda, ptrQuery, false);
uint byteReturned;
var res = DeviceIoControl(handle, IOCTL_DISK_SET_DISK_ATTRIBUTES, ptrQuery, (uint)nPtrQryBytes, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
var ex = new Win32Exception(Marshal.GetLastWin32Error());
MessageBox.Show(ex.Message);
return res;
}
Run Code Online (Sandbox Code Playgroud)
我收到错误“参数不正确”。调用DeviceIoControl函数传递结构的正确方法是什么SET_DISK_ATTRIBUTES?
的原始定义SET_DISK_ATTRIBUTES:
typedef struct _SET_DISK_ATTRIBUTES {
DWORD Version;
BOOLEAN Persist;
BYTE Reserved1[3];
DWORDLONG Attributes;
DWORDLONG AttributesMask;
DWORD Reserved2[4];
} SET_DISK_ATTRIBUTES, *PSET_DISK_ATTRIBUTES;
Run Code Online (Sandbox Code Playgroud)
使用BOOLEAN数据类型,数据类型定义为unsigned char(1字节)BOOL的同义词,与之相反的是int(4字节)的同义词。
默认情况下,bool将封送C#BOOL。
您需要将其强制为一个字节:
{
...
[MarshalAs(UnmanagedType.I1)]
public bool Persist;
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
241 次 |
| 最近记录: |