Code::Blocks Forums

User forums => Using Code::Blocks => Topic started by: minke_wang on September 25, 2018, 05:02:57 pm

Title: Execution of the write command using DeviceIoControl failed
Post by: minke_wang on September 25, 2018, 05:02:57 pm
#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?
Title: Re: Execution of the write command using DeviceIoControl failed
Post by: BlueHazzard on September 25, 2018, 11:19:21 pm
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...