// usb.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h" /************************************************************* Win32控制台应用程序 ***********************************************************/ #include <windows.h> #pragma comment(lib,"setupapi.lib") wchar_t USBSerial[5][100] = {TEXT("")}; // SetupDiGetInterfaceDeviceDetail所需要的输出长度,定义足够大 // 查询存储设备属性的类型 // 根据GUID获得设备路径 int main(int argc, char *argv[]) // printf("%d\n", nDevice); ////////////////// 文件操作 //////////////////////////////////////// // printf("1111111111111111111111111111\n"); if (hFile == INVALID_HANDLE_VALUE) } else } return gTag; }
编译环境:Visual Studio 2005
主要功能:
1). 读取U盘序列号,保存在USBSerial数组里。
2). 验证
第一次运行程序读取U盘序列号存放在
C:\Windows\system32\USBSerial.dat文件中
以后运行检验读取到的U盘序列号与保存在文件中的是否一致,
若相同,置 gTag 为1; 若不一致,置 gTag 为0;
#include <winioctl.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#include <string.h>
int gTag = 0;
#define MAX_DEVICE 256
//#define USBSERIAL_PATH C:\\Windows\\system32\\USBSerial.dat
DEFINE_GUID(UsbClassGuid, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed);
#define INTERFACE_DETAIL_SIZE (1024)
// IOCTL控制码
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
/*typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0, // 读取描述
PropertyExistsQuery, // 测试是否支持
PropertyMaskQuery, // 读取指定的描述
PropertyQueryMaxDefined // 验证数据
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
*/
// 查询存储设备还是适配器属性
//typedef enum _STORAGE_PROPERTY_ID {
// StorageDeviceProperty = 0, // 查询设备属性
// StorageAdapterProperty // 查询适配器属性
//} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
//
// 查询属性输入的数据结构
//typedef struct _STORAGE_PROPERTY_QUERY {
// STORAGE_PROPERTY_ID PropertyId; // 设备/适配器
// STORAGE_QUERY_TYPE QueryType; // 查询类型
// UCHAR AdditionalParameters[1]; // 额外的数据(仅定义了象征性的1个字节)
//} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
//
//// 查询属性输出的数据结构
//typedef struct _STORAGE_DEVICE_DESCRIPTOR {
// ULONG Version; // 版本
// ULONG Size; // 结构大小
// UCHAR DeviceType; // 设备类型
// UCHAR DeviceTypeModifier; // SCSI-2额外的设备类型
// BOOLEAN RemovableMedia; // 是否可移动
// BOOLEAN CommandQueueing; // 是否支持命令队列
// ULONG VendorIdOffset; // 厂家设定值的偏移
// ULONG ProductIdOffset; // 产品ID的偏移
// ULONG ProductRevisionOffset; // 产品版本的偏移
// ULONG SerialNumberOffset; // 序列号的偏移
// STORAGE_BUS_TYPE BusType; // 总线类型
// ULONG RawPropertiesLength; // 额外的属性数据长度
// UCHAR RawDeviceProperties[1]; // 额外的属性数据(仅定义了象征性的1个字节)
//} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
// lpGuid: GUID指针
// pszDevicePath: 设备路径指针的指针
// 返回: 成功得到的设备路径个数,可能不止1个
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)&UsbClassGuid, // class GUID
NULL, // 无关键字
NULL, // 不指定父窗口句柄
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备
// 失败...
if (hDevInfoSet == INVALID_HANDLE_VALUE)
{
printf("Error!\n");
// break;
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)
{
// 复制设备路径到输出缓冲区
wcscpy_s(pszDevicePath[nCount],wcslen(pDetail->DevicePath)+1, pDetail->DevicePath);
// 调整计数值
nCount++;
}
}
}
// printf("%d\n", nCount);
// printf("%s\n",pszDevicePath[1]);
// 释放设备接口数据空间
::GlobalFree(pDetail);
// 关闭设备信息集句柄
::SetupDiDestroyDeviceInfoList(hDevInfoSet);
return nCount;
}
// OpenDevice(char* DevicePath)
// 返回句柄 hDevice
HANDLE OpenDevice(wchar_t* DevicePath)
{
HANDLE hDevice;
hDevice = CreateFileW(DevicePath,
GENERIC_READ && GENERIC_WRITE,
FILE_SHARE_READ && FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
return hDevice;
}
{
int i, nDevice; // nDevice 表示有多少个USB设备
int ndevice = 0; // 表示多少个U盘设备(可进行读写的设备)
wchar_t* szDevicePath[MAX_DEVICE]; // 设备路径
char pdg[1024] ;
DWORD junk;
HANDLE hDevice;
BOOL bResult;
// DWORD dwOutBytes; // IOCTL输出数据长度
// 定义一个 PSTORAGE_DEVICE_DESCRIPTOR 变量,存放设备属性
PSTORAGE_DEVICE_DESCRIPTOR DeviceDesc;
// 变量初始化
DeviceDesc=(PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
DeviceDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1;
// 分配需要的空间
for (i = 0; i < MAX_DEVICE; i++)
{
szDevicePath[i] = new wchar_t[256];
}
// 取设备路径
nDevice = ::GetDevicePath((LPGUID)&UsbClassGuid, szDevicePath);
// for(i = 0; i< nDevice; i++)
// printf("%s\n",szDevicePath[i]);
// 逐一获取设备信息
for (i = 0; i < nDevice; i++)
{
// 打开设备
hDevice = OpenDevice(szDevicePath[i]);
if (hDevice != INVALID_HANDLE_VALUE)
{
bResult = ::DeviceIoControl(hDevice, // device to be queried
IOCTL_STORAGE_GET_MEDIA_TYPES, // operation to perform
NULL, 0, // no input buffer
pdg, 1024, // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
for(int j = 0; j < 4; j++)
{
USBSerial[ndevice][j] = szDevicePath[i][j+12];
}
for(int j = 4; j < 28; j++)
{
USBSerial[ndevice][j] = szDevicePath[i][j+22];
}
printf("U盘序列号为:");
wprintf(L"%ws\n", USBSerial[ndevice]);
ndevice ++;
::CloseHandle(hDevice);
}
}
// 释放空间
for (i = 0; i < MAX_DEVICE; i++)
{
delete []szDevicePath[i];
}
HANDLE hFile;
DWORD nBytesRead = 0, dwBytesWritten = 0;
// 打开文件
hFile = CreateFile(TEXT("C:\\USBSerial.txt"), // file to open
GENERIC_READ | GENERIC_WRITE, // open for reading
FILE_SHARE_READ | FILE_SHARE_WRITE, // share for reading
NULL, // default security
OPEN_EXISTING , // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
// printf("Could not open file!\n");
hFile = CreateFile(TEXT("C:\\USBSerial.txt"), // file to create
GENERIC_READ | GENERIC_WRITE, // open for writing
FILE_SHARE_READ | FILE_SHARE_WRITE, // do not share
NULL, // default security
CREATE_ALWAYS, // overwrite existing
FILE_ATTRIBUTE_NORMAL | // normal file
FILE_ATTRIBUTE_NORMAL, // asynchronous I/O
NULL);
// printf("Could not open file (error %d)\n", GetLastError());
}
long nFileSize = GetFileSize(hFile, NULL);
// printf("first:%d\n",nFileSize);
wchar_t *tempbuf = new wchar_t[nFileSize] ;
// 读文件内容
if (nFileSize == 0)
{
// 创建文件,并把序列号写入文件中
printf("创建文件,并把序列号写入文件中!\n");
hFile = CreateFile(TEXT("C:\\USBSerial.txt"), // file to create
GENERIC_READ | GENERIC_WRITE, // open for writing
FILE_SHARE_READ | FILE_SHARE_WRITE, // do not share
NULL, // default security
CREATE_ALWAYS, // overwrite existing
FILE_ATTRIBUTE_NORMAL | // normal file
FILE_ATTRIBUTE_NORMAL, // asynchronous I/O
NULL); // no attr. template
{
printf("Could not open file (error %d)\n", GetLastError());
return 0;
}
// 把序列号写入文件中
WriteFile(hFile,
USBSerial,
2*wcslen(* USBSerial),
&dwBytesWritten,
NULL);
nFileSize = GetFileSize(hFile, NULL);
// printf("second: %d\n", nFileSize);
{
// printf("third :%d\n",nFileSize);
printf("进入比较序列号\n");
ReadFile(hFile,
tempbuf,
nFileSize,
&nBytesRead,
NULL);
// printf("实际读取到的字节数目:%d\n", &nBytesRead);
// for (int i = 0; i< nFileSize/2; i ++)
// printf("%c", tempbuf[i]);
// printf("\n");
// wprintf(L"%ws\n", tempbuf);
// 比较已经有的序列号与新读的是否相等
for(int i = 0; i< ndevice; i ++)
{
for(int j = 0; j < nFileSize/2; j++)
{
// if( wcscmp( tempbuf, USBSerial[i] ) == 0)
// printf("%c,%c; ",tempbuf[j], USBSerial[i][j] );
if(tempbuf[j] == USBSerial[i][j])
gTag = 1;
else
gTag = 0;
}
if(gTag == 1)
break;
delete tempbuf;
}
printf("gTag is :%d\n", gTag);
if(gTag == 1)
printf("匹配成功!\n");
// 返回值 gTag,如果 gTag 为1,表示U盘序列号与保存在文件中的序列号相同,
// 若 gTag 为0,表示U盘序列号与保存在文件中的不同。
读取U盘物理序列号(转载的先放到这里研究下)
精选 转载上一篇:C/C+语言struct深层探索
下一篇:strcpy函数
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Qt 获取 MacBook 设备序列号
前言用 Qt 获取 Mac 电脑序列号有两种方式,一种是在 Qt 中调用 Mac 原生接口 object-c 代码去获取,一种是在 Qt 中使用QP
Mac-序列号 Qt bash 终端命令 序列号