📄 main.cpp
字号:
/*
Name: main.cpp
Copyright:
Author: Gump Yang
Date: 16-01-06 21:52
Description: for cly
*/
#include <string>
#include <cstdlib>
#include <sstream>
#include <iostream>
using namespace std;
#include <windows.h>
#include <initguid.h>
#include <setupapi.h>
#include <ddk\scsi.h>
#include <ddk\ntddscsi.h>
#include <ddk\ntdddisk.h>
#include <ddk\ntddstor.h>
DEFINE_GUID(DiskClassGuid, 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
const int MAX_DEVICE = 16;
// SetupDiGetInterfaceDeviceDetail所需要的输出长度
#define INTERFACE_DETAIL_SIZE (1024)
// IOCTL_STORAGE_GET_MEDIA_TYPES_EX可能返回不止一条DEVICE_MEDIA_INFO,故定义足够的空间
#define MEDIA_INFO_SIZE (sizeof(GET_MEDIA_TYPES) + sizeof(DEVICE_MEDIA_INFO) * 15)
// 从GUID获得设备路径
// lpGuid: GUID指针
// pszDevicePath: 设备路径指针的指针
// 返回值: 成功得到的设备路径个数
int GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
{
HDEVINFO hDevInfoSet;
SP_DEVICE_INTERFACE_DATA ifdata;
PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
int nCount;
BOOL bResult;
// 取得一个该GUID相关的设备信息集句柄
hDevInfoSet = ::SetupDiGetClassDevs(lpGuid, // class GUID
NULL, // 无关键字
NULL, // 不指定父窗口句柄
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备
// 失败...
if(hDevInfoSet == INVALID_HANDLE_VALUE)
{
return 0;
}
// 申请设备接口数据空间
pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);
pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
nCount = 0;
bResult = TRUE;
// 设备序号=0,1,2... 逐一测试设备接口,到失败为止
while (bResult)
{
ifdata.cbSize=sizeof(ifdata);
// 枚举符合该GUID的设备接口
bResult = ::SetupDiEnumDeviceInterfaces(
hDevInfoSet, // 设备信息集句柄
NULL, // 不需额外的设备描述
lpGuid, // GUID
(ULONG)nCount, // 设备信息集里的设备序号
&ifdata); // 设备接口信息
if(bResult)
{
// 取得该设备接口的细节(设备路径)
bResult = ::SetupDiGetInterfaceDeviceDetail(
hDevInfoSet, // 设备信息集句柄
&ifdata, // 设备接口信息
pDetail, // 设备接口细节(设备路径)
INTERFACE_DETAIL_SIZE, // 输出缓冲区大小
NULL, // 不需计算输出缓冲区大小(直接用设定值)
NULL); // 不需额外的设备描述
if(bResult)
{
// 复制设备路径到输出缓冲区
::strcpy(pszDevicePath[nCount], pDetail->DevicePath);
// 调整计数值
nCount++;
}
}
}
// 释放设备接口数据空间
::GlobalFree(pDetail);
// 关闭设备信息集句柄
::SetupDiDestroyDeviceInfoList(hDevInfoSet);
return nCount;
}
// 打开设备
// pszDevicePath: 设备的路径
HANDLE OpenDevice(LPCTSTR pszDevicePath)
{
HANDLE hDevice;
// 打开设备
hDevice= ::CreateFile(pszDevicePath, // 设备路径
GENERIC_READ | GENERIC_WRITE, // 读写方式
FILE_SHARE_READ | FILE_SHARE_WRITE, // 共享方式
NULL, // 默认的安全描述符
OPEN_EXISTING, // 创建方式
0, // 不需设置文件属性
NULL); // 不需参照模板文件
return hDevice;
}
// 取设备属性信息
// hDevice -- 设备句柄
// pDevDesc -- 输出的设备描述和属性信息缓冲区指针(包含连接在一起的两部分)
BOOL GetDriveProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc)
{
STORAGE_PROPERTY_QUERY Query; // 查询输入参数
DWORD dwOutBytes; // IOCTL输出数据长度
BOOL bResult; // IOCTL返回值
// 指定查询方式
Query.PropertyId = StorageDeviceProperty;
Query.QueryType = PropertyStandardQuery;
// 用IOCTL_STORAGE_QUERY_PROPERTY取设备属性信息
bResult = ::DeviceIoControl(hDevice, // 设备句柄
IOCTL_STORAGE_QUERY_PROPERTY, // 取设备属性信息
&Query, sizeof(STORAGE_PROPERTY_QUERY), // 输入数据缓冲区
pDevDesc, pDevDesc->Size, // 输出数据缓冲区
&dwOutBytes, // 输出数据长度
(LPOVERLAPPED)NULL); // 用同步I/O
return bResult;
}
#define CDB10GENERIC_LENGTH 10
typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS {
SCSI_PASS_THROUGH spt;
ULONG Filler; // realign buffers to double word boundary
UCHAR ucSenseBuf[32];
UCHAR ucDataBuf[512];
} 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[32];
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
unsigned long ReadDrive(HANDLE hDevice)
{
cout << "读取数据" << endl;
SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH);
sptwb.spt.PathId = 0;
sptwb.spt.TargetId = 1;
sptwb.spt.Lun = 0;
sptwb.spt.CdbLength = CDB10GENERIC_LENGTH;
sptwb.spt.SenseInfoLength = 24;
sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
sptwb.spt.DataTransferLength = 1;
sptwb.spt.TimeOutValue = 2;
sptwb.spt.DataBufferOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);
sptwb.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
sptwb.spt.Cdb[0] = SCSIOP_READ;
sptwb.spt.Cdb[1] = 0x20;
sptwb.spt.Cdb[2] = 0xd0;
sptwb.spt.Cdb[3] = 0;
sptwb.spt.Cdb[4] = 0;
sptwb.spt.Cdb[5] = 0;
sptwb.spt.Cdb[6] = 0;
sptwb.spt.Cdb[7] = 0;
sptwb.spt.Cdb[8] = 0x01;
sptwb.spt.Cdb[9] = 0;
cout << "输出控制字: ";
for (int i = 0; i < sptwb.spt.CdbLength; i++) {
cout << hex << (int)sptwb.spt.Cdb[i] << " ";
}
cout << endl;
ULONG length = 0, returned = 0;
BOOL bResult; // IOCTL返回值
length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) +
sptwb.spt.DataTransferLength;
bResult = DeviceIoControl(hDevice,
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH),
&sptwb,
length,
&returned,
FALSE);
}
unsigned long GetDriveCapacity(HANDLE hDevice)
{
cout << "读取容量" << endl;
ULONG length = 0, returned = 0;
BOOL bResult; // IOCTL返回值
SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH);
sptwb.spt.PathId = 0;
sptwb.spt.TargetId = 1;
sptwb.spt.Lun = 0;
sptwb.spt.CdbLength = CDB10GENERIC_LENGTH;
sptwb.spt.SenseInfoLength = 24;
sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
sptwb.spt.DataTransferLength = 8;
sptwb.spt.TimeOutValue = 2;
sptwb.spt.DataBufferOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);
sptwb.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
sptwb.spt.Cdb[0] = SCSIOP_READ_CAPACITY;
sptwb.spt.Cdb[1] = 0;
sptwb.spt.Cdb[2] = 0;
sptwb.spt.Cdb[3] = 0;
sptwb.spt.Cdb[4] = 0;
sptwb.spt.Cdb[5] = 0;
sptwb.spt.Cdb[6] = 0;
sptwb.spt.Cdb[7] = 0;
sptwb.spt.Cdb[8] = 0x0;
sptwb.spt.Cdb[9] = 0x0;
cout << "输出控制字: ";
for (int i = 0; i < sptwb.spt.CdbLength; i++) {
cout << hex << (int)sptwb.spt.Cdb[i] << " ";
}
cout << endl;
length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) +
sptwb.spt.DataTransferLength;
bResult = DeviceIoControl(hDevice,
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH),
&sptwb,
length,
&returned,
FALSE);
READ_CAPACITY_DATA outdata;
ZeroMemory(&outdata, sizeof(READ_CAPACITY_DATA));
cout << "取得数据: ";
for (int i = 0; i < sptwb.spt.DataTransferLength; i++) {
cout << hex << (int)sptwb.ucDataBuf[i] << " ";
}
cout << endl;
outdata.LogicalBlockAddress = (int)(sptwb.ucDataBuf[0] << 24) +
(int)(sptwb.ucDataBuf[1] << 16) +
(int)(sptwb.ucDataBuf[2] << 8) +
(int)sptwb.ucDataBuf[3];
outdata.BytesPerBlock = (int)(sptwb.ucDataBuf[4] << 24) +
(int)(sptwb.ucDataBuf[5] << 16) +
(int)(sptwb.ucDataBuf[6] << 8) +
(int)sptwb.ucDataBuf[7];
return outdata.LogicalBlockAddress * outdata.BytesPerBlock;
}
int main(int argc, char *argv[])
{
HANDLE hDevice;
PSTORAGE_DEVICE_DESCRIPTOR pDevDesc;
string strInfo;
int nDevice;
int i, j, n;
char* szDevicePath[MAX_DEVICE]; // 设备路径
LPGUID lpGuid[] = {
(LPGUID)&DiskClassGuid,
}; // 一些存储设备的GUID
// 分配需要的空间
for(i=0;i<MAX_DEVICE;i++)
szDevicePath[i]=new char[256];
pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1;
// 对感兴趣的类型的存储设备,逐一获取设备信息
for(i=0; i<sizeof(lpGuid)/sizeof(LPGUID); i++)
{
// 取设备路径
nDevice = GetDevicePath(lpGuid[i], szDevicePath);
// 对同一类的存储设备,逐一获取设备信息
for(j=0; j<nDevice; j++)
{
// 打开设备
hDevice=OpenDevice(szDevicePath[j]);
if(hDevice != INVALID_HANDLE_VALUE)
{
// 取设备信息
GetDriveProperty(hDevice, pDevDesc);
if (pDevDesc->BusType == BusTypeUsb) {
// cout << "发现U盘" << endl;
// n = GetDriveCapacity(hDevice);
// cout << "容量为: " << dec << n << endl;
cout << "test" << endl;
ReadDrive(hDevice);
}
// 关闭设备
CloseHandle(hDevice);
}
}
}
// 释放空间
delete pDevDesc;
for(i=0;i<MAX_DEVICE;i++) delete []szDevicePath[i];
system("PAUSE");
return EXIT_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -