SetupAPI 结合注册表获取 USB优盘序列号

//---------------------------------------------------------------------------
// 获取优盘序列号的代码
// 参考: http://www.2ccc.com/article.asp?articleid=4167


#include <setupapi.h>
#include <stdio.h>
#include <objbase.h>


#ifndef __BORLANDC__
#pragma comment(lib, "setupapi.lib")
#endif

//---------------------------------------------------------------------------
char g_strCrnVerify[] =
{
    0xBB, 0xB6, 0xD3, 0xAD, 0xB9, 0xE2, 0xC1, 0xD9, 0x20, 0x43, 
    0x2B, 0x2B, 0x42, 0x75, 0x69, 0x6C, 0x64, 0x65, 0x72, 0xD1,
    0xD0, 0xBE, 0xBF, 0x20, 0x2D, 0x20, 0x68, 0x74, 0x74, 0x70,
    0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x63, 0x63, 0x72,
    0x75, 0x6E, 0x2E, 0x63, 0x6F, 0x6D
};
//---------------------------------------------------------------------------
void CrnReplaceString(LPSTR lpBuf,  char c1,  char c2)
{
    int nLen = strlen(lpBuf);
    LPSTR lpTemp =  new  char[nLen];
    memset(lpTemp, 0, nLen);
    int j=0;
    for( int i=0; i < nLen; i++)
    {
        if(lpBuf[i] == c1)
        {
            if(c2 != 0x00)
            {
                lpTemp[j] = c2;
                j++;
            }
        }
        else
        {
            lpTemp[j] = lpBuf[i];
            j++;
        }
    }
    //
    memset(lpBuf, 0, nLen);
    strncpy(lpBuf, lpTemp, nLen);
    delete []lpTemp;
}
//---------------------------------------------------------------------------
// 获取指定盘符的序列号(针对USB优盘有效)
// char cDiskID: 指定盘符,如 'L'
// LPSTR lpPID : 序列号存放的缓冲,如char szPID[32]
// by ccrun(老妖) info@ccrun.com
//---------------------------------------------------------------------------

bool CrnGetUSBDiskID( char cDiskID, LPSTR lpPID)
{
    char szDrv[4];
    sprintf(szDrv, "%c:\\", cDiskID);
    if(GetDriveType(szDrv) != DRIVE_REMOVABLE)
    {
        MessageBox(0,  "指定的盘不是有效的优盘.",
                "错误", MB_OK | MB_ICONWARNING);
        return  false;
    }

    char lpRegPath[512] = { 0 };
    char lpRegValue[256] = { 0 };
    sprintf(lpRegPath,  "SYSTEM\\MountedDevices");
    sprintf(lpRegValue,  "\\DosDevices\\%c:", cDiskID);
    //
    DWORD dwDataSize(0);
    DWORD dwRegType(REG_BINARY);
    LPBYTE lpRegBinData(NULL);
    LPSTR lpUSBKeyData(NULL);

    // 查询注册表中映射驱动器的设备信息
    HKEY hKey;
    long lRet = ::RegOpenKeyEx(
            HKEY_LOCAL_MACHINE,  // root key
            lpRegPath,  // 要访问的键的位置
            0,          //
            KEY_READ,  // 以查询的方式访问注册表
            &hKey);    // hKEY保存此函数所打开的键的句柄
    if(lRet != ERROR_SUCCESS)
        return  false;
    else
    {
        lRet = ::RegQueryValueEx(hKey,  // 所打开的键的句柄
                lpRegValue,    // 要查询的键值名
                NULL,
                &dwRegType,    // 查询数据的类型
                lpRegBinData,  // 保存所查询的数据
                &dwDataSize);  // 预设置的数据长度
        if(lRet != ERROR_SUCCESS)
        {
            ::RegCloseKey(hKey);
            return  false;
        }
        else
        {
            lpRegBinData =  new BYTE[dwDataSize];
            lpUSBKeyData =  new  char[dwDataSize];
            memset(lpUSBKeyData, 0, dwDataSize);
            lRet = ::RegQueryValueEx(hKey,
                    lpRegValue,
                    NULL,
                    &dwRegType,
                    lpRegBinData,
                    &dwDataSize);
            if(lRet != ERROR_SUCCESS)
            {
                delete []lpRegBinData;
                delete []lpUSBKeyData;
                ::RegCloseKey(hKey);
                return  false;
            }
        }
    }
    ::RegCloseKey(hKey);
    // 过滤二进制串中的无用信息(将0x0字符去除)
    int j = 0;
    for(DWORD i=0; i<dwDataSize; i++)
    {
        if(lpRegBinData[i] != 0x0)
        {
            lpUSBKeyData[j] = lpRegBinData[i];
            j++;
        }
    }
    delete []lpRegBinData;

    // I'm sorry: You can remove under line in your Code.
    MessageBox(0, g_strCrnVerify,  "CrnGetUSBDiskID", 0);
    // I'm sorry: Only for [Zhuan Tie Bu Liu Ming]. - -#

    // 截取lpUSBKeyData中的有用信息, 例: 7&100a16f&0
    // \??\STORAGE#RemovableMedia#7&100a16f&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
    // 63 63 72 75 6E 2E 63 6F 6D
    LPSTR lpPos1 = strstr(lpUSBKeyData,  "#RemovableMedia#") + 16;
    LPSTR lpPos2 = strstr(lpUSBKeyData,  "RM");
    strncpy(lpUSBKeyData, lpPos1,  int(lpPos2) -  int(lpPos1));
    lpUSBKeyData[ int(lpPos2) -  int(lpPos1) - 1] = 0x0;
    strcpy(lpUSBKeyData, strupr(lpUSBKeyData));

    // Disk Device(磁盘设备)的GUID
    GUID guidUSB;
    CLSIDFromString(L "{53f56307-b6bf-11d0-94f2-00a0c91efb8b}", &guidUSB);

    //
    HDEVINFO hUSB = SetupDiGetClassDevs(
            &guidUSB, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if(hUSB == INVALID_HANDLE_VALUE)
    {
        delete []lpUSBKeyData;
        return  false;
    }
    //
    int nDevIndex = 0;
    bool bSuccess;
    SP_DEVINFO_DATA DevData;
    SP_DEVICE_INTERFACE_DATA DevIntData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA lpDevIntDetailData;
    DWORD dwBytesReturned;

    // 遍历磁盘设备
    do
    {
        DevIntData.cbSize =  sizeof(SP_DEVICE_INTERFACE_DATA);
        bSuccess = SetupDiEnumDeviceInterfaces(hUSB, NULL, &guidUSB,
                nDevIndex, &DevIntData) > 0;
// 本文转自 C++Builder研究 - http://www.ccrun.com/article.asp?i=1021&d=fgp83l
        if(bSuccess)
        {
            // 获取接口详细信息
            DevData.cbSize =  sizeof(SP_DEVINFO_DATA);
            dwBytesReturned = 0;
            SetupDiGetDeviceInterfaceDetailA(hUSB, &DevIntData,
                    NULL, 0, &dwBytesReturned, &DevData);
            if(dwBytesReturned != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                lpDevIntDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)
                        GlobalAlloc(GMEM_FIXED, dwBytesReturned);
                lpDevIntDetailData->cbSize =
                        sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
                if(SetupDiGetDeviceInterfaceDetailA(hUSB, &DevIntData,
                        lpDevIntDetailData, dwBytesReturned, &dwBytesReturned, &DevData))
                {
                    // 取得设备接口详细信息并根据转化后的路径在注册表中查询
                    LPSTR lpPathTemp =  new  char[strlen(lpDevIntDetailData->DevicePath) + 256];
                    strcpy(lpRegPath, "SYSTEM\\CurrentControlSet\\Enum\\");
                    strcpy(lpPathTemp, lpDevIntDetailData->DevicePath);
                    lpPos1 = LPSTR( int(lpPathTemp) + 4);
                    lpPos2 = LPSTR( int(strstr(lpPathTemp,  "{")) - 1);
                    strncpy(lpPathTemp, lpPos1,  int(lpPos2) -  int(lpPos1));
                    lpPathTemp[ int(lpPos2) -  int(lpPos1)] = 0x0;
                    CrnReplaceString(lpPathTemp, ' #', '\\');

                    strcat(lpRegPath, lpPathTemp);
                    //
                    if(RegOpenKeyEx(
                            HKEY_LOCAL_MACHINE,
                            lpRegPath,
                            0,
                            KEY_READ,
                            &hKey) == ERROR_SUCCESS)
                    {
                        dwRegType = REG_SZ;
                        LPSTR lpRegSzData = NULL;
                        dwDataSize = 0;
                        lRet = ::RegQueryValueEx(hKey,
                                "ParentIdPrefix",
                                NULL,
                                &dwRegType,
                                (LPBYTE)lpRegSzData,
                                &dwDataSize);
                        if(lRet == ERROR_SUCCESS)
                        {
                            lpRegSzData =  new  char[dwDataSize];
                            lRet = ::RegQueryValueEx(hKey,
                                    "ParentIdPrefix",
                                    NULL,
                                    &dwRegType,
                                    (LPBYTE)lpRegSzData,
                                    &dwDataSize);
                            if(lRet == ERROR_SUCCESS)
                            {
                                strcpy(lpRegSzData, strupr(lpRegSzData));
                                if(!strcmp(lpUSBKeyData, lpRegSzData))
                                {
                                    // 经比对,找到要查询的磁盘设备
                                    strcpy(lpPathTemp, LPSTR( int(strstr(
                                        lpDevIntDetailData->DevicePath,  "#")) + 1));
                                    lpPos1 = LPSTR( int(strstr(lpPathTemp,  "#")) + 1);
                                    lpPos2 = LPSTR( int(strstr(lpPathTemp,  "#{")));
                                    strncpy(lpPathTemp, lpPos1,  int(lpPos2) -  int(lpPos1));
                                    lpPathTemp[ int(lpPos2) -  int(lpPos1)] = 0x0;

                                    // 获取最终的磁盘序列号
                                    CrnReplaceString(lpPathTemp, '&', 0x00);
                                    if(lpPID)
                                        strncpy(lpPID, strupr(lpPathTemp), 32);
                                    //
                                    delete []lpRegSzData;
                                    delete []lpPathTemp;
                                    GlobalFree(lpDevIntDetailData);
                                    ::RegCloseKey(hKey);
                                    break;
                                }
                            }
                            delete []lpRegSzData;
                        }
                        ::RegCloseKey(hKey);
                    }
                    delete []lpPathTemp;
                    nDevIndex++;
                }
                GlobalFree(lpDevIntDetailData);
            }
        }
    } while(bSuccess);

    SetupDiDestroyDeviceInfoList(hUSB);

    delete []lpUSBKeyData;

    return  true;
}
//---------------------------------------------------------------------------
void  __fastcall TForm1::Button1Click(TObject *Sender)
{
    char lpPID[32];
    if(CrnGetUSBDiskID('L', lpPID))
        ShowMessage(lpPID);
}
获取U盘ID序列号 VS2005编译通过,源码源自CSDN。已经测试好用。 可以获得U盘名称,制造商ID号 版本号 U盘序列号及容量 Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System.Management; namespace UDiskTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button2_Click(object sender, EventArgs e) { DriveInfo[] s = DriveInfo.GetDrives(); foreach (DriveInfo drive in s) { if (drive.DriveType == DriveType.Removable) { pf.Text = drive.Name.ToString(); break; } } ManagementClass cimobject = new ManagementClass("Win32_DiskDrive"); ManagementObjectCollection moc = cimobject.GetInstances(); foreach (ManagementObject mo in moc) { if (mo.Properties["InterfaceType"].Value.ToString() == "USB") { try { //产品名称 Caption.Text = mo.Properties["Caption"].Value.ToString(); //总容量 Size.Text = mo.Properties["Size"].Value.ToString(); string[] info = mo.Properties["PNPDeviceID"].Value.ToString().Split('&'); string[] xx = info[3].Split('\\'); //序列号 MessageBox.Show("U盘序列号:" + xx[1]); PNPDeviceID.Text = xx[1]; xx = xx[0].Split('_'); //版本号 REV.Text = xx[1]; //制造商ID xx = info[1].Split('_'); VID.Text = xx[1]; } catch (Exception ex) { MessageBox.Show(ex.Message); } } } } } } 如果编译遇到问题是using System.Management;无法找到引用找到, 项目(p)->添加引用(R)->找到.NET标签页 列表中下部位找到System.Management 双击点确定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值