⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 使用DDK来进行编程
💻 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 + -