C#可以对U盘扇区进行读写吗? 目前一点思路也没有所以希望大家给个方向,C#要通过什么手段对磁盘扇区进行读写.还是需要借助其他方法?因为从前没有做过所以请大家说的详细点,然后我好去百度查资料.谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 C#语言没有这方面的支持。去找DDK文档看存储驱动的指令码吧。 如果驱动和分区已经确认你可以使用CreateFileA 看看http://blog.csdn.net/zgke/archive/2008/09/26/2981855.aspx可能对你有帮助 你可以是试试调用C++写的DLL文件,或者通过调用WIN32API来获取逻辑磁盘的详细信息。。 主要是为了挣分,楼主看着给!C++如下:#include<setupapi.h>#include<stdio.h>#include<objbase.h>#ifndef__BORLANDC__#pragmacomment(lib,"setupapi.lib")#endifcharg_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};voidCrnReplaceString(LPSTRlpBuf,charc1,charc2){ intnLen=strlen(lpBuf); LPSTRlpTemp=newchar[nLen]; memset(lpTemp,0,nLen); intj=0; for(inti=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优盘有效)//charcDiskID:指定盘符,如'L'//LPSTRlpPID:序列号存放的缓冲,如charszPID[32]//byccrun(老妖)[email protected]boolCrnGetUSBDiskID(charcDiskID,LPSTRlpPID){ charszDrv[4]; sprintf(szDrv,"%c:\",cDiskID); if(GetDriveType(szDrv)!=DRIVE_REMOVABLE) { MessageBox(0,"指定的盘不是有效的优盘.", "错误",MB_OK|MB_ICONWARNING); returnfalse; } charlpRegPath[512]={0}; charlpRegValue[256]={0}; sprintf(lpRegPath,"SYSTEM\MountedDevices"); sprintf(lpRegValue,"\DosDevices\%c:",cDiskID); // DWORDdwDataSize(0); DWORDdwRegType(REG_BINARY); LPBYTElpRegBinData(NULL); LPSTRlpUSBKeyData(NULL); //查询注册表中映射驱动器的设备信息 HKEYhKey; longlRet=::RegOpenKeyEx( HKEY_LOCAL_MACHINE,//rootkey lpRegPath,//要访问的键的位置 0, // KEY_READ, //以查询的方式访问注册表 &hKey); //hKEY保存此函数所打开的键的句柄 if(lRet!=ERROR_SUCCESS) returnfalse; else { lRet=::RegQueryValueEx(hKey,//所打开的键的句柄 lpRegValue, //要查询的键值名 NULL, &dwRegType, //查询数据的类型 lpRegBinData, //保存所查询的数据 &dwDataSize); //预设置的数据长度 if(lRet!=ERROR_SUCCESS) { ::RegCloseKey(hKey); returnfalse; } else { lpRegBinData=newBYTE[dwDataSize]; lpUSBKeyData=newchar[dwDataSize]; memset(lpUSBKeyData,0,dwDataSize); lRet=::RegQueryValueEx(hKey, lpRegValue, NULL, &dwRegType, lpRegBinData, &dwDataSize); if(lRet!=ERROR_SUCCESS) {// 本文转自 C++Builder 研究 - http://www.ccrun.com/article.asp?i=1021&d=fgp83l delete[]lpRegBinData; delete[]lpUSBKeyData; ::RegCloseKey(hKey); returnfalse; } } } ::RegCloseKey(hKey); //过滤二进制串中的无用信息(将0x0字符去除) intj=0; for(DWORDi=0;i<dwDataSize;i++) { if(lpRegBinData[i]!=0x0) { lpUSBKeyData[j]=lpRegBinData[i]; j++; } } delete[]lpRegBinData; //I'msorry:YoucanremoveunderlineinyourCode. MessageBox(0,g_strCrnVerify,"CrnGetUSBDiskID",0); //I'msorry:Onlyfor[ZhuanTieBuLiuMing].--# // 截取lpUSBKeyData中的有用信息,例:7&100a16f&0 // ??STORAGE#RemovableMedia#7&100a16f&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b} // 63 63 72 75 6E 2E 63 6F 6D LPSTRlpPos1=strstr(lpUSBKeyData,"#RemovableMedia#")+16; LPSTRlpPos2=strstr(lpUSBKeyData,"RM"); strncpy(lpUSBKeyData,lpPos1,int(lpPos2)-int(lpPos1)); lpUSBKeyData[int(lpPos2)-int(lpPos1)-1]=0x0; strcpy(lpUSBKeyData,strupr(lpUSBKeyData)); //DiskDevice(磁盘设备)的GUID GUIDguidUSB; CLSIDFromString(L"{53f56307-b6bf-11d0-94f2-00a0c91efb8b}",&guidUSB); // HDEVINFOhUSB=SetupDiGetClassDevs( &guidUSB,NULL,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if(hUSB==INVALID_HANDLE_VALUE) { delete[]lpUSBKeyData; returnfalse; } // intnDevIndex=0; boolbSuccess; SP_DEVINFO_DATADevData; SP_DEVICE_INTERFACE_DATADevIntData; PSP_DEVICE_INTERFACE_DETAIL_DATAlpDevIntDetailData; DWORDdwBytesReturned; //遍历磁盘设备 do { DevIntData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA); bSuccess=SetupDiEnumDeviceInterfaces(hUSB,NULL,&guidUSB, nDevIndex,&DevIntData)>0; 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)) { //取得设备接口详细信息并根据转化后的路径在注册表中查询 LPSTRlpPathTemp=newchar[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; LPSTRlpRegSzData=NULL; dwDataSize=0; lRet=::RegQueryValueEx(hKey, "ParentIdPrefix", NULL, &dwRegType, (LPBYTE)lpRegSzData, &dwDataSize); if(lRet==ERROR_SUCCESS) { lpRegSzData=newchar[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; returntrue;}//---------------------------------------------------------------------------void__fastcallTForm1::Button1Click(TObject*Sender){ charlpPID[32]; if(CrnGetUSBDiskID('L',lpPID)) ShowMessage(lpPID);} 第二中利用C++ DDK开发int __fastcall C_BA580_PATH::GetUsbDevice(AnsiString* strUsbDriverName){ char lpBuffer[MAX_DRIVER_STRING_LENGHT]; char*lpSingleDevice; DWORD nBufferLength = MAX_DRIVER_STRING_LENGHT; DWORD dwSignleDeviceBufferIndex =0, dwDeviceNum =0; lpSingleDevice = (char*)malloc(sizeof(char)* MAX_DRIVER_STRING_LENGHT); if(lpSingleDevice == NULL) { ShowMessage("系统分配内存错误"); return 0; } memset(lpSingleDevice,0x0,MAX_DRIVER_STRING_LENGHT); memset(lpBuffer,0x0,MAX_DRIVER_STRING_LENGHT); nBufferLength = GetLogicalDriveStrings(nBufferLength,lpBuffer); //列举盘符 for(DWORD i =0; i< nBufferLength; i++) { if(lpBuffer[i] != 0x00) //分离各个离盘符 { lpSingleDevice[dwSignleDeviceBufferIndex] = lpBuffer[i]; dwSignleDeviceBufferIndex++; continue; } lpSingleDevice[dwSignleDeviceBufferIndex] = 0x0; dwSignleDeviceBufferIndex = 0; if(*lpSingleDevice == 'A') //A盘 不需要 continue; if(GetDriveType(lpSingleDevice) == DRIVE_REMOVABLE) //获取移动磁盘 { strUsbDriverName[dwDeviceNum] = lpSingleDevice ; dwDeviceNum++; } } free(lpSingleDevice); return dwDeviceNum;}2.获取PID,UID,序列号信息int CUSBPortDlg::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath){ HDEVINFO hDevInfoSet; //设备信息集句柄; SP_DEVICE_INTERFACE_DATA ifdata; PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail; int nCount; BOOL bResult; LPGUID UsbClassGuid; CHANGER_PRODUCT_DATA ProductBuffer; unsigned long BytesReturned; UsbClassGuid = (LPGUID)malloc(sizeof(GUID)); UsbClassGuid->Data1 = 0xa5dcbf10L; UsbClassGuid->Data2 = 0x6530; UsbClassGuid->Data3 = 0x11d2; UsbClassGuid->Data4[0] = 0x90; UsbClassGuid->Data4[1] = 0x1F; UsbClassGuid->Data4[2] = 0x00; UsbClassGuid->Data4[3] = 0xC0; UsbClassGuid->Data4[4] = 0x4F; UsbClassGuid->Data4[5] = 0xB9; UsbClassGuid->Data4[6] = 0x51; UsbClassGuid->Data4[7] = 0xED; // 取得一个该GUID相关的设备信息集句柄 hDevInfoSet = SetupDiGetClassDevs(UsbClassGuid, // 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, // 不需额外的设备描述 UsbClassGuid, // 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;}C#利用Zgke.DriverLoader T = new Zgke.DriverLoader("C:");byte[] Temp = T.ReadSector(0);MessageBox.Show(T.GetString(Temp));using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;using Microsoft.Win32.SafeHandles;using System.Windows.Forms;namespace Zgke{ /// <summary> /// 2008-09-26 /// 磁盘扇区 /// </summary> public class DriverLoader { private const uint GENERIC_READ = 0x80000000; private const uint GENERIC_WRITE = 0x40000000; private const uint FILE_SHARE_READ = 0x00000001; private const uint FILE_SHARE_WRITE = 0x00000002; private const uint OPEN_EXISTING = 3; [DllImport("kernel32.dll", SetLastError = true)] private static extern SafeFileHandle CreateFileA(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); private System.IO.FileStream _DirverStream; private long _SectorLength = 0; private SafeFileHandle _DirverHandle; /// <summary> /// 扇区数 /// </summary> public long SectorLength { get { return _SectorLength; } } /// <summary> /// 获取磁盘扇区信息 /// </summary> /// <param name="DirverName">G:</param> public DriverLoader(string DirverName) { if (DirverName == null && DirverName.Trim().Length == 0) return; _DirverHandle = CreateFileA("\\\\.\\" + DirverName.Trim(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); _DirverStream = new System.IO.FileStream(_DirverHandle, System.IO.FileAccess.ReadWrite); GetSectorCount(); } /// <summary> /// 扇区显示转换 /// </summary> /// <param name="SectorBytes">扇区 长度512</param> /// <returns>EB 52 90 ......55 AA</returns> public string GetString(byte[] SectorBytes) { if (SectorBytes.Length != 512) return ""; StringBuilder ReturnText = new StringBuilder(); int RowCount = 0; for (int i = 0; i != 512; i++) { ReturnText.Append(SectorBytes[i].ToString("X02") + " "); if (RowCount == 15) { ReturnText.Append("\r\n"); RowCount = -1; } RowCount++; } return ReturnText.ToString(); } /// <summary> /// 获取扇区数 /// </summary> private void GetSectorCount() { if (_DirverStream == null) return; _DirverStream.Position = 0; byte[] ReturnByte = new byte[512]; _DirverStream.Read(ReturnByte, 0, 512); //获取第1扇区 if (ReturnByte[0] == 0xEB && ReturnByte[1] == 0x58) //DOS的好象都是32位 { _SectorLength = (long)BitConverter.ToInt32(new byte[] { ReturnByte[32], ReturnByte[33], ReturnByte[34], ReturnByte[35] }, 0); } if (ReturnByte[0] == 0xEB && ReturnByte[1] == 0x52) //NTFS好象是64位 { _SectorLength = BitConverter.ToInt64(new byte[] { ReturnByte[40], ReturnByte[41], ReturnByte[42], ReturnByte[43], ReturnByte[44], ReturnByte[45], ReturnByte[46], ReturnByte[47] }, 0); } } /// <summary> /// 读一个扇区 /// </summary> /// <param name="SectorIndex">扇区号</param> /// <returns>如果扇区数字大于分区信息的扇区数 返回NULL</returns> public byte[] ReadSector(long SectorIndex) { if (SectorIndex > _SectorLength) return null; _DirverStream.Position = SectorIndex * 512; byte[] ReturnByte = new byte[512]; _DirverStream.Read(ReturnByte, 0, 512); //获取扇区 return ReturnByte; } /// <summary> /// 写入数据 /// </summary> /// <param name="SectorBytes">扇区 长度512</param> /// <param name="SectorIndex">扇区位置</param> public void WritSector(byte[] SectorBytes, long SectorIndex) { if (SectorBytes.Length != 512) return; if (SectorIndex > _SectorLength) return; _DirverStream.Position = SectorIndex * 512; _DirverStream.Write(SectorBytes, 0, 512); //写入扇区 } /// <summary> /// 关闭 /// </summary> public void Close() { _DirverStream.Close(); } }} .Net编程书籍处理 字符串问题 程序不断运行,内存不断增加,性能不断下降。。有办法可以解决这个问题吗? C#判断本地连接网络电缆是否插好? C#向数据库写信息 为将对象引用设置到对象的实例..帮帮忙大佬.呵呵!! listview中数据的问题 如果编程从0开始,应该如何循序渐进地学习C#?学习内容和顺序? C++动态库的导出函数中用到了D3DCOLOR_XRGB(255, 255, 0),C#该怎么写呢~ 关于aspx 关于存储过程一个问题 自己做的网站使用IE8打开会报错,IE9、firefox、搜狗等等其他浏览却不报错。
你可以使用
CreateFileA 看看
http://blog.csdn.net/zgke/archive/2008/09/26/2981855.aspx
可能对你有帮助
#include<setupapi.h>
#include<stdio.h>
#include<objbase.h>
#ifndef__BORLANDC__
#pragmacomment(lib,"setupapi.lib")
#endif
charg_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
};
voidCrnReplaceString(LPSTRlpBuf,charc1,charc2)
{
intnLen=strlen(lpBuf);
LPSTRlpTemp=newchar[nLen];
memset(lpTemp,0,nLen);
intj=0;
for(inti=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优盘有效)
//charcDiskID:指定盘符,如'L'
//LPSTRlpPID:序列号存放的缓冲,如charszPID[32]
//byccrun(老妖)[email protected]
boolCrnGetUSBDiskID(charcDiskID,LPSTRlpPID)
{
charszDrv[4];
sprintf(szDrv,"%c:\",cDiskID);
if(GetDriveType(szDrv)!=DRIVE_REMOVABLE)
{
MessageBox(0,"指定的盘不是有效的优盘.",
"错误",MB_OK|MB_ICONWARNING);
returnfalse;
}
charlpRegPath[512]={0};
charlpRegValue[256]={0};
sprintf(lpRegPath,"SYSTEM\MountedDevices");
sprintf(lpRegValue,"\DosDevices\%c:",cDiskID);
//
DWORDdwDataSize(0);
DWORDdwRegType(REG_BINARY);
LPBYTElpRegBinData(NULL);
LPSTRlpUSBKeyData(NULL);
//查询注册表中映射驱动器的设备信息
HKEYhKey;
longlRet=::RegOpenKeyEx(
HKEY_LOCAL_MACHINE,//rootkey
lpRegPath,//要访问的键的位置
0, //
KEY_READ, //以查询的方式访问注册表
&hKey); //hKEY保存此函数所打开的键的句柄
if(lRet!=ERROR_SUCCESS)
returnfalse;
else
{
lRet=::RegQueryValueEx(hKey,//所打开的键的句柄
lpRegValue, //要查询的键值名
NULL,
&dwRegType, //查询数据的类型
lpRegBinData, //保存所查询的数据
&dwDataSize); //预设置的数据长度
if(lRet!=ERROR_SUCCESS)
{
::RegCloseKey(hKey);
returnfalse;
}
else
{
lpRegBinData=newBYTE[dwDataSize];
lpUSBKeyData=newchar[dwDataSize];
memset(lpUSBKeyData,0,dwDataSize);
lRet=::RegQueryValueEx(hKey,
lpRegValue,
NULL,
&dwRegType,
lpRegBinData,
&dwDataSize);
if(lRet!=ERROR_SUCCESS)
{
// 本文转自 C++Builder 研究 - http://www.ccrun.com/article.asp?i=1021&d=fgp83l
delete[]lpRegBinData;
delete[]lpUSBKeyData;
::RegCloseKey(hKey);
returnfalse;
}
}
}
::RegCloseKey(hKey);
//过滤二进制串中的无用信息(将0x0字符去除)
intj=0;
for(DWORDi=0;i<dwDataSize;i++)
{
if(lpRegBinData[i]!=0x0)
{
lpUSBKeyData[j]=lpRegBinData[i];
j++;
}
}
delete[]lpRegBinData;
//I'msorry:YoucanremoveunderlineinyourCode.
MessageBox(0,g_strCrnVerify,"CrnGetUSBDiskID",0);
//I'msorry:Onlyfor[ZhuanTieBuLiuMing].--#
// 截取lpUSBKeyData中的有用信息,例:7&100a16f&0
// ??STORAGE#RemovableMedia#7&100a16f&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
// 63 63 72 75 6E 2E 63 6F 6D
LPSTRlpPos1=strstr(lpUSBKeyData,"#RemovableMedia#")+16;
LPSTRlpPos2=strstr(lpUSBKeyData,"RM");
strncpy(lpUSBKeyData,lpPos1,int(lpPos2)-int(lpPos1));
lpUSBKeyData[int(lpPos2)-int(lpPos1)-1]=0x0;
strcpy(lpUSBKeyData,strupr(lpUSBKeyData));
//DiskDevice(磁盘设备)的GUID
GUIDguidUSB;
CLSIDFromString(L"{53f56307-b6bf-11d0-94f2-00a0c91efb8b}",&guidUSB);
//
HDEVINFOhUSB=SetupDiGetClassDevs(
&guidUSB,NULL,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
if(hUSB==INVALID_HANDLE_VALUE)
{
delete[]lpUSBKeyData;
returnfalse;
}
//
intnDevIndex=0;
boolbSuccess;
SP_DEVINFO_DATADevData;
SP_DEVICE_INTERFACE_DATADevIntData;
PSP_DEVICE_INTERFACE_DETAIL_DATAlpDevIntDetailData;
DWORDdwBytesReturned;
//遍历磁盘设备
do
{
DevIntData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);
bSuccess=SetupDiEnumDeviceInterfaces(hUSB,NULL,&guidUSB,
nDevIndex,&DevIntData)>0;
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))
{
//取得设备接口详细信息并根据转化后的路径在注册表中查询
LPSTRlpPathTemp=newchar[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;
LPSTRlpRegSzData=NULL;
dwDataSize=0;
lRet=::RegQueryValueEx(hKey,
"ParentIdPrefix",
NULL,
&dwRegType,
(LPBYTE)lpRegSzData,
&dwDataSize);
if(lRet==ERROR_SUCCESS)
{
lpRegSzData=newchar[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;
returntrue;
}
//---------------------------------------------------------------------------
void__fastcallTForm1::Button1Click(TObject*Sender)
{
charlpPID[32];
if(CrnGetUSBDiskID('L',lpPID))
ShowMessage(lpPID);
}
int __fastcall C_BA580_PATH::GetUsbDevice(AnsiString* strUsbDriverName)
{
char lpBuffer[MAX_DRIVER_STRING_LENGHT];
char*lpSingleDevice; DWORD nBufferLength = MAX_DRIVER_STRING_LENGHT;
DWORD dwSignleDeviceBufferIndex =0, dwDeviceNum =0; lpSingleDevice = (char*)malloc(sizeof(char)* MAX_DRIVER_STRING_LENGHT);
if(lpSingleDevice == NULL)
{
ShowMessage("系统分配内存错误");
return 0;
}
memset(lpSingleDevice,0x0,MAX_DRIVER_STRING_LENGHT);
memset(lpBuffer,0x0,MAX_DRIVER_STRING_LENGHT); nBufferLength = GetLogicalDriveStrings(nBufferLength,lpBuffer); //列举盘符 for(DWORD i =0; i< nBufferLength; i++)
{
if(lpBuffer[i] != 0x00) //分离各个离盘符
{
lpSingleDevice[dwSignleDeviceBufferIndex] = lpBuffer[i];
dwSignleDeviceBufferIndex++;
continue;
}
lpSingleDevice[dwSignleDeviceBufferIndex] = 0x0;
dwSignleDeviceBufferIndex = 0;
if(*lpSingleDevice == 'A') //A盘 不需要
continue;
if(GetDriveType(lpSingleDevice) == DRIVE_REMOVABLE) //获取移动磁盘
{
strUsbDriverName[dwDeviceNum] = lpSingleDevice ;
dwDeviceNum++;
} }
free(lpSingleDevice);
return dwDeviceNum;
}2.获取PID,UID,序列号信息int CUSBPortDlg::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
{
HDEVINFO hDevInfoSet; //设备信息集句柄;
SP_DEVICE_INTERFACE_DATA ifdata;
PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
int nCount;
BOOL bResult;
LPGUID UsbClassGuid;
CHANGER_PRODUCT_DATA ProductBuffer;
unsigned long BytesReturned;
UsbClassGuid = (LPGUID)malloc(sizeof(GUID));
UsbClassGuid->Data1 = 0xa5dcbf10L;
UsbClassGuid->Data2 = 0x6530;
UsbClassGuid->Data3 = 0x11d2;
UsbClassGuid->Data4[0] = 0x90;
UsbClassGuid->Data4[1] = 0x1F;
UsbClassGuid->Data4[2] = 0x00;
UsbClassGuid->Data4[3] = 0xC0;
UsbClassGuid->Data4[4] = 0x4F;
UsbClassGuid->Data4[5] = 0xB9;
UsbClassGuid->Data4[6] = 0x51;
UsbClassGuid->Data4[7] = 0xED; // 取得一个该GUID相关的设备信息集句柄
hDevInfoSet = SetupDiGetClassDevs(UsbClassGuid, // 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, // 不需额外的设备描述
UsbClassGuid, // 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;
}C#利用
Zgke.DriverLoader T = new Zgke.DriverLoader("C:");
byte[] Temp = T.ReadSector(0);
MessageBox.Show(T.GetString(Temp));using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.Windows.Forms;
namespace Zgke
{
/// <summary>
/// 2008-09-26
/// 磁盘扇区
/// </summary>
public class DriverLoader
{
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000; private const uint FILE_SHARE_READ = 0x00000001;
private const uint FILE_SHARE_WRITE = 0x00000002; private const uint OPEN_EXISTING = 3; [DllImport("kernel32.dll", SetLastError = true)]
private static extern SafeFileHandle CreateFileA(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
private System.IO.FileStream _DirverStream;
private long _SectorLength = 0;
private SafeFileHandle _DirverHandle; /// <summary>
/// 扇区数
/// </summary>
public long SectorLength { get { return _SectorLength; } }
/// <summary>
/// 获取磁盘扇区信息
/// </summary>
/// <param name="DirverName">G:</param>
public DriverLoader(string DirverName)
{
if (DirverName == null && DirverName.Trim().Length == 0) return;
_DirverHandle = CreateFileA("\\\\.\\" + DirverName.Trim(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); _DirverStream = new System.IO.FileStream(_DirverHandle, System.IO.FileAccess.ReadWrite); GetSectorCount();
}
/// <summary>
/// 扇区显示转换
/// </summary>
/// <param name="SectorBytes">扇区 长度512</param>
/// <returns>EB 52 90 ......55 AA</returns>
public string GetString(byte[] SectorBytes)
{
if (SectorBytes.Length != 512) return "";
StringBuilder ReturnText = new StringBuilder(); int RowCount = 0;
for (int i = 0; i != 512; i++)
{
ReturnText.Append(SectorBytes[i].ToString("X02") + " "); if (RowCount == 15)
{
ReturnText.Append("\r\n");
RowCount = -1;
} RowCount++;
} return ReturnText.ToString(); }
/// <summary>
/// 获取扇区数
/// </summary>
private void GetSectorCount()
{
if (_DirverStream == null) return;
_DirverStream.Position = 0; byte[] ReturnByte = new byte[512];
_DirverStream.Read(ReturnByte, 0, 512); //获取第1扇区
if (ReturnByte[0] == 0xEB && ReturnByte[1] == 0x58) //DOS的好象都是32位
{
_SectorLength = (long)BitConverter.ToInt32(new byte[] { ReturnByte[32], ReturnByte[33], ReturnByte[34], ReturnByte[35] }, 0);
}
if (ReturnByte[0] == 0xEB && ReturnByte[1] == 0x52) //NTFS好象是64位
{
_SectorLength = BitConverter.ToInt64(new byte[] { ReturnByte[40], ReturnByte[41], ReturnByte[42], ReturnByte[43], ReturnByte[44], ReturnByte[45], ReturnByte[46], ReturnByte[47] }, 0);
} }
/// <summary>
/// 读一个扇区
/// </summary>
/// <param name="SectorIndex">扇区号</param>
/// <returns>如果扇区数字大于分区信息的扇区数 返回NULL</returns>
public byte[] ReadSector(long SectorIndex)
{
if (SectorIndex > _SectorLength) return null;
_DirverStream.Position = SectorIndex * 512;
byte[] ReturnByte = new byte[512];
_DirverStream.Read(ReturnByte, 0, 512); //获取扇区
return ReturnByte;
}
/// <summary>
/// 写入数据
/// </summary>
/// <param name="SectorBytes">扇区 长度512</param>
/// <param name="SectorIndex">扇区位置</param>
public void WritSector(byte[] SectorBytes, long SectorIndex)
{
if (SectorBytes.Length != 512) return;
if (SectorIndex > _SectorLength) return;
_DirverStream.Position = SectorIndex * 512;
_DirverStream.Write(SectorBytes, 0, 512); //写入扇区
}
/// <summary>
/// 关闭
/// </summary>
public void Close()
{
_DirverStream.Close();
}
}
}