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. Shell编程学习1--基础了解

    "#!path"告诉系统path所指的程序为用来解释此脚本文件的Shell程序: 如#!/bin/sh, #!/bin/bash Shell Script的后缀名为.sh; ech ...

  2. Java线程:新特征-有返回值的线程《转》

      原始文章   在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.   现在Java终于有可返回值的任务(也可以叫做线程)了. ...

  3. 使用Netty4实现基本的消息分发

    示例工程代码 可从附件下载 具体的说明和用法在后面介绍 需求与目的 一个游戏服务端需要处理各种业务逻辑,每一种业务逻辑都对应着一个请求消息和一个响应消息.那么服务端需要把这些不同的消息自动分发到对应的 ...

  4. Centos之链接命令

    链接命令:ln  (link) ln -s [源文件] [目标文件] 功能描述:生成链接文件 选项: -s 创建软链接 硬链接特征: 1,拥有相同的i节点和存储block块,可以看作是同一个文件: 2 ...

  5. SCTF 2014 PWN400 分析

    之前没有分析PWN400,现在再开一篇文章分析一下. 这个日志是我做题的一个笔记,就是说我做一步题就记录一下是实时的.所以说可能会有错误之类的. 首先程序是经典的笔记本程序,基本上一看到这种笔记本就知 ...

  6. java.lang.NoClassDefFoundError: ognl/PropertyAccessor

    本篇对 Web 开发中,项目部署后.开启 Tomcat 服务器 Console 控制台报错 java.lang.NoClassDefFoundError: ognl/PropertyAccessor ...

  7. 004 爬虫(最初的爬虫方式,以及urllib2)

    一:最初的爬取方式 1.代码示例 # coding=utf-8 import urllib2 request=urllib2.Request("http://www.baidu.com&qu ...

  8. 一步一步写数据结构(BST-二叉排序树)

    二叉排序树的重要性不用多说,下面用c++实现二叉排序树的建立,插入,查找,修改,和删除.难点在于删除,其他几个相对比较简单. 以下是代码: #include<iostream> using ...

  9. 关于Python Profilers性能分析器

    1. 介绍性能分析器 作者:btchenguang profiler是一个程序,用来描述运行时的程序性能,并且从不同方面提供统计数据加以表述.Python中含有3个模块提供这样的功能,分别是cProf ...

  10. POJ 3678 Katu Puzzle 2-SAT 强连通分量 tarjan

    http://poj.org/problem?id=3678 给m条连接两个点的边,每条边有一个权值0或1,有一个运算方式and.or或xor,要求和这条边相连的两个点经过边上的运算后的结果是边的权值 ...