http://www.ezblog.idv.tw/Download/USBStorage.rar

這是一個不透過檔案系統,去讀寫USB Mass Storage 任何位置(包含FAT)的方式

首先需安裝微軟的DDK並include "usbioctl.h" , "usbdi.h" , "ntddscsi.h"

有幾個資料結構要定義

typedef struct _SCSI_Device_Info_
{
SCSI_PASS_THROUGH Spt;
BYTE Sense[ ];
BYTE Data[ ];
} SCSI_Device_Info, *pSCSI_Device_Info;
typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS
{
SCSI_PASS_THROUGH Spt;
ULONG Filler; // realign buffers to double word boundary
UCHAR ucSenseBuf[ SPT_SENSE_LENGTH ];
UCHAR ucDataBuf[ SPTWB_DATA_LENGTH ];
} SCSI_PASS_THROUGH_WITH_BUFFERS, *pSCSI_PASS_THROUGH_WITH_BUFFERS;
typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
{
SCSI_PASS_THROUGH_DIRECT sptd;
ULONG Filler; // realign buffer to double word boundary
UCHAR ucSenseBuf[ SPT_SENSE_LENGTH ];
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *pSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; /*
* Required UFI Commands
*/
#define UFI_FORMAT_UNIT 0x04 // output
#define UFI_INQUIRY 0x12 // input
#define UFI_MODE_SELECT 0x55 // output
#define UFI_MODE_SENSE_6 0x1A // input
#define UFI_MODE_SENSE_10 0x5A // input
#define UFI_PREVENT_MEDIUM_REMOVAL 0x1E
#define UFI_READ_10 0x28 // input
#define UFI_READ_12 0xA8 // input
#define UFI_READ_CAPACITY 0x25 // input
#define UFI_READ_FORMAT_CAPACITY 0x23 // input
#define UFI_REQUEST_SENSE 0x03 // input
#define UFI_REZERO_UNIT 0x01
#define UFI_SEEK_10 0x2B
#define UFI_SEND_DIAGNOSTIC 0x1D
#define UFI_START_UNIT 0x1B
#define UFI_TEST_UNIT_READY 0x00
#define UFI_VERIFY 0x2F
#define UFI_WRITE_10 0x2A // output
#define UFI_WRITE_12 0xAA // output
#define UFI_WRITE_AND_VERIFY 0x2E // output
#define UFI_ALLOW_MEDIUM_REMOVAL UFI_PREVENT_MEDIUM_REMOVAL
#define UFI_STOP_UNIT UFI_START_UNIT bool CUSBStorDrive::m_OpenDrive()
{
char DriveStr[]; m_CloseDrive();
memset(DriveStr,0x00,); sprintf(DriveStr, "\\\\?\\%c:", m_cDrive);
m_hDrive = CreateFile(
DriveStr, // device interface name
GENERIC_READ | GENERIC_WRITE,// dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE,// dwShareMode
NULL,// lpSecurityAttributes
OPEN_EXISTING,// dwCreationDistribution
,// dwFlagsAndAttributes
NULL// hTemplateFile
);
if (m_hDrive == INVALID_HANDLE_VALUE)
{
m_LastErrCode = GetLastError();
return false;
}
return m_SendInquiry(m_hDrive);
} bool CUSBStorDrive::m_CloseDrive()
{
if (m_hDrive != NULL)
{
CloseHandle(m_hDrive);
}
m_hDrive = NULL;
return true;
} bool CUSBStorDrive::m_SendInquiry(HANDLE hDrive)
{
SCSI_Device_Info SCSIInfo =
{ };
DWORD ReturnLen;
BOOL bResult; if (hDrive == NULL) return false; SCSIInfo.Spt.Length = sizeof(SCSIInfo.Spt);
SCSIInfo.Spt.SenseInfoLength = sizeof(SCSIInfo.Sense);
SCSIInfo.Spt.DataTransferLength = sizeof(SCSIInfo.Data);
SCSIInfo.Spt.SenseInfoOffset = offsetof(SCSI_Device_Info, Sense);
SCSIInfo.Spt.DataBufferOffset = offsetof(SCSI_Device_Info, Data);
SCSIInfo.Spt.TimeOutValue = ;
SCSIInfo.Spt.DataIn = SCSI_IOCTL_DATA_IN;
SCSIInfo.Spt.CdbLength = ;
SCSIInfo.Spt.Cdb[] = UFI_INQUIRY; // inquiry opcode
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = sizeof(SCSIInfo.Data);
SCSIInfo.Spt.Cdb[] = 0x00; bResult = DeviceIoControl(
hDrive,
IOCTL_SCSI_PASS_THROUGH,
&SCSIInfo,
sizeof(SCSIInfo),
&SCSIInfo,
sizeof(SCSIInfo),
&ReturnLen,
FALSE);
if (bResult)
{
return true;
}
else
{
m_LastErrCode = GetLastError();
return false;
}
} bool CUSBStorDrive::m_ReadCapacity(HANDLE hDrive)
{
SCSI_Device_Info SCSIInfo =
{ };
DWORD ReturnLen;
BOOL bResult;
if (hDrive == NULL) return false; SCSIInfo.Spt.Length = sizeof(SCSIInfo.Spt);
SCSIInfo.Spt.SenseInfoLength = sizeof(SCSIInfo.Sense);
SCSIInfo.Spt.DataTransferLength = sizeof(SCSIInfo.Data);
SCSIInfo.Spt.SenseInfoOffset = offsetof(SCSI_Device_Info, Sense);
SCSIInfo.Spt.DataBufferOffset = offsetof(SCSI_Device_Info, Data);
SCSIInfo.Spt.TimeOutValue = ;
SCSIInfo.Spt.DataIn = SCSI_IOCTL_DATA_IN;
SCSIInfo.Spt.CdbLength = ;
SCSIInfo.Spt.Cdb[] = UFI_READ_CAPACITY; // Read Capacity opcode
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00; bResult = DeviceIoControl(
hDrive,
IOCTL_SCSI_PASS_THROUGH,
&SCSIInfo,
sizeof(SCSIInfo),
&SCSIInfo,
sizeof(SCSIInfo),
&ReturnLen,
FALSE);
if (bResult)
{
return true;
}
else
{
m_LastErrCode = GetLastError();
return false;
}
} bool CUSBStorDrive::m_ReadFormatCapacity(HANDLE hDrive)
{
SCSI_Device_Info SCSIInfo =
{ };
DWORD ReturnLen = ;
BOOL bResult = false;
if (hDrive == NULL) return false; WORD wAllocLeng = 0x0000; SCSIInfo.Spt.Length = sizeof(SCSIInfo.Spt);
SCSIInfo.Spt.SenseInfoLength = sizeof(SCSIInfo.Sense);
SCSIInfo.Spt.DataTransferLength = sizeof(SCSIInfo.Data);
SCSIInfo.Spt.SenseInfoOffset = offsetof(SCSI_Device_Info, Sense);
SCSIInfo.Spt.DataBufferOffset = offsetof(SCSI_Device_Info, Data);
SCSIInfo.Spt.TimeOutValue = ;
SCSIInfo.Spt.DataIn = SCSI_IOCTL_DATA_IN;
SCSIInfo.Spt.CdbLength = ;
SCSIInfo.Spt.Cdb[] = UFI_READ_FORMAT_CAPACITY; // Read format Capacity opcode
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = wAllocLeng >> ;//Allocation Length (MSB)
SCSIInfo.Spt.Cdb[] = wAllocLeng & 0x00FF;//Allocation Length (LSB)
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00;
SCSIInfo.Spt.Cdb[] = 0x00; bResult = DeviceIoControl(
hDrive,
IOCTL_SCSI_PASS_THROUGH,
&SCSIInfo,
sizeof(SCSIInfo),
&SCSIInfo,
sizeof(SCSIInfo),
&ReturnLen,
FALSE);
if (bResult)
{
//SCSIInfo.Data[];
return true;
}
else
{
m_LastErrCode = GetLastError();
return false;
}
} bool CUSBStorDrive::m_Read10WithBuffer(HANDLE hDrive,DWORD dwStartBlock,BYTE *pBuf,DWORD dwlength)
{
SCSI_PASS_THROUGH_WITH_BUFFERS SCSIDataWithBuf =
{ };
DWORD ReturnLen = ;
BOOL bResult = false;
WORD wBlocks = 0x0001;
BYTE *ptr = NULL;
int iCount = ; if (hDrive == NULL) return false;
if (pBuf == NULL) return false; SCSIDataWithBuf.Spt.Length = sizeof(SCSI_PASS_THROUGH);
SCSIDataWithBuf.Spt.SenseInfoLength = SPT_SENSE_LENGTH;
SCSIDataWithBuf.Spt.DataTransferLength = SPTWB_DATA_LENGTH;
SCSIDataWithBuf.Spt.PathId = ;
SCSIDataWithBuf.Spt.TargetId = ;
SCSIDataWithBuf.Spt.Lun = ;
SCSIDataWithBuf.Spt.TimeOutValue = TIME_OUT;
SCSIDataWithBuf.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
SCSIDataWithBuf.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);
SCSIDataWithBuf.Spt.DataIn = SCSI_IOCTL_DATA_IN;
SCSIDataWithBuf.Spt.CdbLength = ;
SCSIDataWithBuf.Spt.Cdb[] = UFI_READ_10;
SCSIDataWithBuf.Spt.Cdb[] = 0x00;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0xFF000000) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x00FF0000) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x0000FF00) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x000000FF);
SCSIDataWithBuf.Spt.Cdb[] = 0x00;
SCSIDataWithBuf.Spt.Cdb[] = (wBlocks & 0xFF00) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (wBlocks & 0x00FF);
SCSIDataWithBuf.Spt.Cdb[] = 0x00;
SCSIDataWithBuf.Spt.Cdb[] = 0x00;
SCSIDataWithBuf.Spt.Cdb[] = 0x00; ptr = pBuf;
iCount = dwlength / SPTWB_DATA_LENGTH;
if ((dwlength % SPTWB_DATA_LENGTH) > ) iCount++;
int iPos = ;
for (int i=; i < iCount; i++)
{
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0xFF000000) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x00FF0000) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x0000FF00) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x000000FF); bResult = DeviceIoControl(
hDrive,
IOCTL_SCSI_PASS_THROUGH,
&SCSIDataWithBuf,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&SCSIDataWithBuf,
//length,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&ReturnLen,
FALSE);
if (bResult)
{
iPos = (i * )/iCount;
if (m_pWaitUISetPosProc != NULL)
{
(m_pWaitUISetPosProc)(,iPos);
}
if ((i+) == iCount) //last
{
memcpy(ptr,SCSIDataWithBuf.ucDataBuf,dwlength);
dwlength = ;
}
else
{
memcpy(ptr,SCSIDataWithBuf.ucDataBuf,SPTWB_DATA_LENGTH);
dwlength -= SPTWB_DATA_LENGTH;
}
ptr += SPTWB_DATA_LENGTH;
dwStartBlock ++;
}
else
{
m_LastErrCode = GetLastError();
break;
}
}
return bResult;
} bool CUSBStorDrive::m_Write10WithBuffer(HANDLE hDrive,DWORD dwStartBlock,BYTE *pBuf,DWORD dwlength)
{
SCSI_PASS_THROUGH_WITH_BUFFERS SCSIDataWithBuf =
{ };
DWORD ReturnLen = ;
WORD wBlocks = 0x0001;
BYTE *ptr = NULL;
BOOL bResult = false;
int iCount = ; if (hDrive == NULL) return false;
if (pBuf == NULL) return false; SCSIDataWithBuf.Spt.Length = sizeof(SCSI_PASS_THROUGH);
SCSIDataWithBuf.Spt.SenseInfoLength = SPT_SENSE_LENGTH;
SCSIDataWithBuf.Spt.DataTransferLength = SPTWB_DATA_LENGTH;
SCSIDataWithBuf.Spt.PathId = ;
SCSIDataWithBuf.Spt.TargetId = ;
SCSIDataWithBuf.Spt.Lun = ;
SCSIDataWithBuf.Spt.TimeOutValue = TIME_OUT;
SCSIDataWithBuf.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
SCSIDataWithBuf.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);
SCSIDataWithBuf.Spt.DataIn = SCSI_IOCTL_DATA_OUT;
SCSIDataWithBuf.Spt.CdbLength = ;
SCSIDataWithBuf.Spt.Cdb[] = UFI_WRITE_10;
SCSIDataWithBuf.Spt.Cdb[] = 0x00;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0xFF000000) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x00FF0000) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x0000FF00) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x000000FF);
SCSIDataWithBuf.Spt.Cdb[] = 0x00;
SCSIDataWithBuf.Spt.Cdb[] = (wBlocks & 0xFF00) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (wBlocks & 0x00FF);
SCSIDataWithBuf.Spt.Cdb[] = 0x00;
SCSIDataWithBuf.Spt.Cdb[] = 0x00;
SCSIDataWithBuf.Spt.Cdb[] = 0x00; ptr = pBuf;
iCount = dwlength / SPTWB_DATA_LENGTH;
if ((dwlength % SPTWB_DATA_LENGTH) > ) iCount++;
int iPos = ; for (int i=; i < iCount; i++)
{
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0xFF000000) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x00FF0000) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x0000FF00) >> ;
SCSIDataWithBuf.Spt.Cdb[] = (dwStartBlock & 0x000000FF);
memset(SCSIDataWithBuf.ucDataBuf,0x00,SPTWB_DATA_LENGTH);
if (dwlength >= SPTWB_DATA_LENGTH)
{
memcpy(SCSIDataWithBuf.ucDataBuf,ptr,SPTWB_DATA_LENGTH);
}
else
{
memcpy(SCSIDataWithBuf.ucDataBuf,ptr,dwlength);
}
bResult = DeviceIoControl(
hDrive,
IOCTL_SCSI_PASS_THROUGH,
SCSIDataWithBuf,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
SCSIDataWithBuf,
//length,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
ReturnLen,
FALSE);
if (bResult)
{
iPos = (i * )/iCount;
if (m_pWaitUISetPosProc != NULL)
{
(m_pWaitUISetPosProc)(,iPos);
}
ptr += SPTWB_DATA_LENGTH;
dwStartBlock ++;
dwlength -= SPTWB_DATA_LENGTH;
}
else
{
m_LastErrCode = GetLastError();
break;
}
}
return bResult;
}

使用Device IO Control 讀寫 USB Mass Storage的更多相关文章

  1. usb mass storage device

    Problem adding USB host device to KVM Windows guest machine. Status: CLOSED CURRENTRELEASE   Aliases ...

  2. USB Mass Storage协议分析

    目录 简介 指令数据和状态协议 CBW指令格式 CSWCommand Status Wrapper状态格式 SCSI命令集 Format Unit Inquiry MODE SELECT 简介 USB ...

  3. USB Mass Storage大容量存储的基本知识

    http://www.crifan.com/files/doc/docbook/usb_disk_driver/release/htmls/ch02_msc_basic.html 目录 2.1. US ...

  4. USB Mass Storage communication with PassThrough / more than 64K data length

    http://social.msdn.microsoft.com/Forums/windowsdesktop/zh-CN/35620a05-43be-46a8-8cbe-846bc8295d85/us ...

  5. Android USB Connections Explained: MTP, PTP, and USB Mass Storage

    Android USB Connections Explained: MTP, PTP, and USB Mass Storage Older Android devices support USB ...

  6. USB Mass Storage学习笔记-STM32+FLASH实现U盘

    一.内容概述  采用STM32内部自带USB控制器外加大页NAND FLASH K9F1G08U0A实现一个128M的U盘. 1.STM32的USB控制器 STM32F103的MCU自带USB从控制器 ...

  7. usb mass storage之旅

    前面总结了usb hid keyboard,现在总结usb mass storage,在枚举阶段没什么好总结的,hid和mass storage差不多,都是同样的枚举过程,但是在他们的配置描述符.接口 ...

  8. USB mass storage协议

    这一节主要把在实现“linux模拟U盘功能”过程中的一些调试过程记录下来,并加以解析. 一.背景知识     1.USB Mass Storage类规范概述        USB 组织在univers ...

  9. 实现Linux下的U盘(USB Mass Storage)驱动

    如何实现Linux下的U盘(USB Mass Storage)驱动 版本:v0.7 How to Write Linux USB MSC (Mass Storage Class) Driver Cri ...

随机推荐

  1. TF-图像的深度和通道的概念(转)

    图像的深度和通道概念 图像的深度: 图片是由一个个像素点构成的,所有不同颜色的像素点构成了一副完整的图像,计算机存储图片是以二进制来进行的. 1 bit : 用一位来存储,那么这个像素点的取值范围就是 ...

  2. java基础70 负责静态的网页制作语言XML(网页知识)

    HTML:负责网页结构的CSS:负责网页的样式(美观)JavaScript:负责客户(浏览器)端与用户进行交互 1.HTML语言的特点 1.由标签组成    2.语法结构松散     3.大小写不区分 ...

  3. JSP和Servlet那些事儿系列--HTTPS

    原文:http://qingkangxu.iteye.com/blog/1614053 <JSP和Servlet那些事儿 >系列文章旨在阐述Servlet(Struts和Spring的MV ...

  4. 关于django过滤器的使用

    最近项目中要做分类筛选,其实已经做了这个功能,但是有一个字段是MultiSelectField类型,包含多个值,用户提交的数据是单个值,无法查询出结果, 所以用到了自定义过滤 原代码 class In ...

  5. Linux下堆漏洞的利用机制

    1.保护机制 )) malloc_printerr (check_action, "corrupted double-linked list", P); 这个就是所谓的堆指针的ch ...

  6. 第一篇CodeIgniter框架的下载及安装

    初次学习Php,网上搜了很多php框架,最后选择了CodeIgniter. 安装环境:php5+mysql6.5+iis7 我的电脑是用来办公写文档用的,win7系统,不想换系统,所以就安装了win7 ...

  7. pytest的参数化测试

    感觉在单元测试当中可能有用, 但在django这种框架中,用途另一说. import pytest import tasks from tasks import Task def test_add_1 ...

  8. python 判断字符编码

    一般情况下,需要加这个: import sys reload(sys) sys.setdefaultencoding('utf-8') 打开其他文件编码用codecs.open 读 下面的代码读取了文 ...

  9. HDU - 4420 2013icpc长春A 函数离散化 + st表

    思路:我们定义F(x) 为以x点为起点,向后(a - b)个里面有多少个白球,虽然x的范围是LL范围内的,但是白球的 个数只有1e5, 那么我们可以把连续一段相同的离散化到一起, 对于一个确定的长度为 ...

  10. HDU 1028 HDU 1398 (母函数)

    题意:输入一个n  给出其所有组合数 如: 4 = 4;  4 = 3 + 1;  4 = 2 + 2;  4 = 2 + 1 + 1;  4 = 1 + 1 + 1 + 1; 重复不算 母函数入门题 ...