?? 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 + -