News:

As usual while waiting for the next release - don't forget to check the nightly builds in the forum.

Main Menu

Execution of the write command using DeviceIoControl failed

Started by minke_wang, September 25, 2018, 05:02:57 PM

Previous topic - Next topic

minke_wang

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define ULONG_PTR ULONG
#include <ddk/ntddscsi.h> //SDK里面的头文件
#include <ddk/ntifs.h>

int main()
{
    HANDLE hUDisk;
    SCSI_PASS_THROUGH_DIRECT sptdwb;
    ULONG length = 0;
    DWORD bytesReturn;
    BYTE bufDataRead[64*1024+10];
    int iRet;

    //获得U盘句柄 ,假设U盘的盘符为I:盘
    hUDisk = CreateFile("\\\\.\\F:",GENERIC_READ | GENERIC_WRITE,
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING,0,NULL
                       );
    if (hUDisk ==INVALID_HANDLE_VALUE)
    {
        printf("Get Udisk hadnler error\n");
        return 0;
    }
    ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT));
    sptdwb.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
    sptdwb.PathId = 0;
    sptdwb.TargetId = 1;
    sptdwb.Lun = 0;
    sptdwb.CdbLength = 10;
    sptdwb.DataIn = SCSI_IOCTL_DATA_IN;
    sptdwb.SenseInfoLength = 0x0;//24;
    sptdwb.DataTransferLength = 8;
    sptdwb.TimeOutValue = 2;
    sptdwb.DataBuffer = bufDataRead; //存放数据的数组
    sptdwb.SenseInfoOffset = 0x0;//offsetof(SCSI_PASS_THROUGH_DIRECT,ucSenseBuf);
    sptdwb.Cdb[0] = 0x25 ;   //获取容量命令
    length = sizeof(SCSI_PASS_THROUGH_DIRECT);
    iRet = DeviceIoControl(hUDisk,
                           IOCTL_SCSI_PASS_THROUGH_DIRECT,
                           &sptdwb,
                           length,
                           &sptdwb,
                           length,
                           &bytesReturn,
                           NULL);
    if (0 == iRet)
    {
        iRet = GetLastError();
        printf("Get\n");
        return 0;
    }

    //扇区数
    int sectors = bufDataRead[0]*(1<<24) + bufDataRead[1]*(1<<16)
                  + bufDataRead[2]*(1<<8) + bufDataRead[3] + 1;
    //每个扇区的字节数
    int bytesPerSector = bufDataRead[4]*(1<<24) + bufDataRead[5]*(1<<16)
                         + bufDataRead[6]*(1<<8) + bufDataRead[7];
    printf("sectors=%d bytesPreSector=%d\n",sectors,bytesPerSector);


    int posSector = 10000;   //从第65个扇区开始读,扇区编号从0开始
    int readSectors = 1 ; //读2个扇区
#if 1
    //锁定卷
    iRet = DeviceIoControl(hUDisk,
                       FSCTL_LOCK_VOLUME,
                       NULL,
                       0,
                       NULL,
                       0,
                       &bytesReturn,
                       NULL);
    if (0 == iRet)
    {
        iRet = GetLastError();
        printf("lock error\n");
        return 0;
    }
#endif
    ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT));
    sptdwb.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
    sptdwb.PathId = 0;
    sptdwb.TargetId = 1;
    sptdwb.Lun = 0;
    sptdwb.CdbLength = 10; //SCSI命令长度
    sptdwb.DataIn = SCSI_IOCTL_DATA_IN;
    sptdwb.SenseInfoLength = 0x0;//24;
    sptdwb.DataTransferLength = bytesPerSector * readSectors; //写数据量
    sptdwb.TimeOutValue = 2000;
    sptdwb.DataBuffer = bufDataRead;
    sptdwb.SenseInfoOffset = 0x0;//offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf);
    sptdwb.Cdb[0] = 0x2A;          //command write(10)
    sptdwb.Cdb[2] = (posSector>>24)&0xff; //从第posSector开始读
    sptdwb.Cdb[3] = (posSector>>16)&0xff;
    sptdwb.Cdb[4] = (posSector>>8)&0xff;
    sptdwb.Cdb[5] = posSector&0xff;
    sptdwb.Cdb[7] = (readSectors>>8)&0xff;
    sptdwb.Cdb[8] = readSectors&0xff;   //write readSectors ,注意这个值一定要与DataTransferLength相对应
    length = sizeof(SCSI_PASS_THROUGH_DIRECT);
    iRet = DeviceIoControl(hUDisk,
                           IOCTL_SCSI_PASS_THROUGH_DIRECT,
                           &sptdwb,
                           length,
                           &sptdwb,
                           length,
                           &bytesReturn,
                           FALSE);
    if (0 == iRet)
    {
        iRet = GetLastError();    //Get Last Error code is 121, timeout, why?????????????????????????
        printf("write udisk data error\n");
        return 0;
    }

    //unlock volume
    iRet = DeviceIoControl(hUDisk,
                       FSCTL_UNLOCK_VOLUME,
                       NULL,
                       0,
                       NULL,
                       0,
                       &bytesReturn,
                       NULL);
    if (0 == iRet)
    {
        iRet = GetLastError();
        printf(" unlock error\n");
        return 0;
    }

    CloseHandle(hUDisk);
    return 0;
}


i dont know why write(10) command failed?

BlueHazzard

This is the wrong forum to ask this kind of question. We support only codeblocks question and not generic programming questions or microsoft API questions...