Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DeviceIoControl返回带有IOCTL\u SCSI\u PASS\u的1306_C#_Deviceiocontrol - Fatal编程技术网

C# DeviceIoControl返回带有IOCTL\u SCSI\u PASS\u的1306

C# DeviceIoControl返回带有IOCTL\u SCSI\u PASS\u的1306,c#,deviceiocontrol,C#,Deviceiocontrol,我正在尝试将DeviceIoControl与C中的IOCTL_SCSI_PASS_THROUGH控制代码一起使用。 但是DeviceIoControl返回错误代码1306 我想做的是获得INTEL NVMe SSD的S.M.A.R.T 我试着参考一下Crystal Disk Info的源代码 它在C或C++中成功运行。 以下源代码的问题在哪里 [DllImport("kernel32.dll", SetLastError = true, CallingConvention

我正在尝试将DeviceIoControl与C中的IOCTL_SCSI_PASS_THROUGH控制代码一起使用。 但是DeviceIoControl返回错误代码1306

我想做的是获得INTEL NVMe SSD的S.M.A.R.T

我试着参考一下Crystal Disk Info的源代码

它在C或C++中成功运行。 以下源代码的问题在哪里

[DllImport("kernel32.dll", SetLastError = true,
            CallingConvention = CallingConvention.StdCall,
            CharSet = CharSet.Auto)]
public static extern IntPtr CreateFile(
            [MarshalAs(UnmanagedType.LPTStr)] string filename,
            [MarshalAs(UnmanagedType.U4)] FileAccess access,
            [MarshalAs(UnmanagedType.U4)] FileShare share,
            IntPtr securityAttributes,
            [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
            UInt32 flagsAndAttributes,
            IntPtr templateFile);

[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeviceIoControl(
            IntPtr hDevice,
            UInt32 dwIoControlCode,
            IntPtr lpInBuffer,
            UInt32 nInBufferSize,
            IntPtr lpOutBuffer,
            UInt32 nOutBufferSize,
            [Out]out UInt32 lpBytesReturned,
            IntPtr lpOverlapped);

[StructLayout(LayoutKind.Sequential)]
struct SCSI_PASS_THROUGH
{
    public ushort length;
    public byte scsiStatus;
    public byte pathId;
    public byte targetId;
    public byte lun;
    public byte cdbLength;
    public byte senseInfoLength;
    public byte dataIn;
    public uint dataTransferLength;
    public uint timeOutValue;
    public ulong dataBufferOffset;
    public uint senseInfoOffset;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public byte[] cdb;
};

[StructLayout(LayoutKind.Sequential)]
struct SCSI_PASS_THROUGH_WITH_BUFFERS24
{
    public SCSI_PASS_THROUGH spt;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
    public byte[] senseBuf;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)]
    public byte[] dataBuf;
};

private static void VolumeDeviceIoControl(string physicalDriveId)
{
    IntPtr handle = CreateFile(physicalDriveId, FileAccess.ReadWrite,
                FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);

    if (handle != System.IntPtr.Zero && (uint)handle.ToInt32() != (uint)0xffffffff)
    {
        Console.WriteLine("hadle success open");
    }
    else
    {
        throw new Exception("handle failed open", new Win32Exception());
    }

    uint returned = 0;
    SCSI_PASS_THROUGH_WITH_BUFFERS24 sptwb = new SCSI_PASS_THROUGH_WITH_BUFFERS24();

    // initialize
    sptwb.spt.length = 0;
    sptwb.spt.scsiStatus = 0;
    sptwb.spt.pathId = 0;
    sptwb.spt.targetId = 0;
    sptwb.spt.lun = 0;
    sptwb.spt.cdbLength = 0;
    sptwb.spt.senseInfoLength = 0;
    sptwb.spt.dataIn = 0;
    sptwb.spt.dataTransferLength = 0;
    sptwb.spt.timeOutValue = 0;
    sptwb.spt.dataBufferOffset = 0;
    sptwb.spt.senseInfoOffset = 0;
    sptwb.spt.cdb = new byte[16];
    sptwb.senseBuf = new byte[24];
    sptwb.dataBuf = new byte[4096];

    // set input parameter
    sptwb.spt.length = 56;
    sptwb.spt.pathId = 0;
    sptwb.spt.targetId = 0;
    sptwb.spt.lun = 0;
    sptwb.spt.senseInfoLength = 24;
    sptwb.spt.dataIn = 0;
    sptwb.spt.dataTransferLength = 512;
    sptwb.spt.timeOutValue = 2;
    sptwb.spt.dataBufferOffset = 80;
    sptwb.spt.senseInfoOffset = 56;
    sptwb.spt.cdbLength = 12;
    sptwb.spt.cdb[0] = 0xA1;
    sptwb.spt.cdb[1] = 0x80;
    sptwb.spt.cdb[2] = 0;
    sptwb.spt.cdb[3] = 0;
    sptwb.spt.cdb[4] = 2;
    sptwb.spt.cdb[5] = 0;
    sptwb.spt.cdb[6] = 0;
    sptwb.spt.cdb[7] = 0;
    sptwb.spt.cdb[8] = 0;
    sptwb.spt.cdb[9] = 0;
    sptwb.spt.cdb[10] = 0;
    sptwb.spt.cdb[11] = 0;
    sptwb.dataBuf[0] = 0x4e;
    sptwb.dataBuf[1] = 0x56;
    sptwb.dataBuf[2] = 0x4d;
    sptwb.dataBuf[3] = 0x45;
    sptwb.dataBuf[8] = 0x02;
    sptwb.dataBuf[10] = 0x56;
    sptwb.dataBuf[12] = 0xFF;
    sptwb.dataBuf[13] = 0xFF;
    sptwb.dataBuf[14] = 0xFF;
    sptwb.dataBuf[15] = 0xFF;
    sptwb.dataBuf[0x21] = 0x40;
    sptwb.dataBuf[0x22] = 0x7A;
    sptwb.dataBuf[0x30] = 0x02;
    sptwb.dataBuf[0x32] = 0x7F;

    // sptwbPtr
    IntPtr sptwbPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(SCSI_PASS_THROUGH_WITH_BUFFERS24)));
    Marshal.StructureToPtr(sptwb, sptwbPtr, false);

    // DeviceIoControl
    bool isSuccess = false;
    isSuccess = DeviceIoControl(handle, 0x4d004 /* IOCTL_SCSI_PASS_THROUGH */, sptwbPtr, 592, sptwbPtr, 592, out returned, IntPtr.Zero);
    Console.Write("DeviceIoControl=" + isSuccess);
    if (!isSuccess)
    {
        // return 1306
        Console.WriteLine("DeviceIoControl ErrorCd=" + Marshal.GetLastWin32Error() + " returned=" + returned);
        try { throw new Win32Exception(); } catch (Exception e) { Console.WriteLine("Msg=" + e.Message); }
        Marshal.FreeCoTaskMem(sptwbPtr);
        return;
     } else if (isSuccess)
     {
         return;
     }
}

模糊的错误代码,但谷歌搜索效果很好。告诉您Length属性是错误的。它在32位模式下为44,在64位模式下为56。项目>属性>生成选项卡,“首选32位”复选框。喜欢Marshal.SizeOf()。您是否查看了pinvoke示例代码:@HansPassant我根据您的评论进行了尝试,结果成功了。请回答这个问题。谢谢:)@anonymq你能解决这个问题吗?我目前面临着一个挑战:通过Powershell读取NVMe设备的智能数据,并寻找一些好的C#模板将其嵌入PS脚本。