大家好啊,向大家请教个问题,如何识别移动硬盘的盘符;
下面代码主要功能是:每有移动存储设备插入电脑,接受到一个消息,
通过API函数禁用移动存储设备;移动硬盘一直无法识别#include <Dbt.h>
#include <Winioctl.h>//查找可移动磁盘
CString CUSBMngDlg::FindFdisk()
{
CString strdir="";
for(char cc='A';cc<='Z';cc++)
{
strdir.Format("%c:",cc);
if(GetDriveType((LPCTSTR)strdir)==DRIVE_REMOVABLE) //只能识别U盘,无法识别移动硬盘
//if(GetDriveType((LPCTSTR)strdir)==DRIVE_FIXED)
return strdir;
}
return strdir="";
}//每当有优盘插入时,接收一次系统发给的消息
LRESULT CUSBMngDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_DEVICECHANGE)
{
switch(wParam)
{
case DBT_DEVICEARRIVAL: //设备插入消息
{
HANDLE hDevice;
DWORD dwOutBytes;
bool bResult;
CString logicalDisk; m_NewFdisk = FindFdisk();
//if(m_NewFdisk != m_OldFdisk && m_NewFdisk!= "")
//if(m_NewFdisk !=“”)
if (m_NewFdisk !="")
{
logicalDisk = "\\\\.\\"+m_NewFdisk;
hDevice = CreateFile(
logicalDisk, //要打开的驱动名称
GENERIC_READ|GENERIC_WRITE, //访问方式
FILE_SHARE_READ|FILE_SHARE_WRITE, //共享方式
NULL, //安全描述符指针
OPEN_EXISTING, //创建方式
0, //文件属性及标志
NULL //模板文件的句柄
);
bResult = DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&dwOutBytes,(LPOVERLAPPED)NULL);
} if(m_NewFdisk!="")
{
m_OldFdisk=m_NewFdisk;
}
else
{
m_OldFdisk="";
}
}
//break;
}
}
return CDialog::WindowProc(message, wParam, lParam);
}
下面代码主要功能是:每有移动存储设备插入电脑,接受到一个消息,
通过API函数禁用移动存储设备;移动硬盘一直无法识别#include <Dbt.h>
#include <Winioctl.h>//查找可移动磁盘
CString CUSBMngDlg::FindFdisk()
{
CString strdir="";
for(char cc='A';cc<='Z';cc++)
{
strdir.Format("%c:",cc);
if(GetDriveType((LPCTSTR)strdir)==DRIVE_REMOVABLE) //只能识别U盘,无法识别移动硬盘
//if(GetDriveType((LPCTSTR)strdir)==DRIVE_FIXED)
return strdir;
}
return strdir="";
}//每当有优盘插入时,接收一次系统发给的消息
LRESULT CUSBMngDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_DEVICECHANGE)
{
switch(wParam)
{
case DBT_DEVICEARRIVAL: //设备插入消息
{
HANDLE hDevice;
DWORD dwOutBytes;
bool bResult;
CString logicalDisk; m_NewFdisk = FindFdisk();
//if(m_NewFdisk != m_OldFdisk && m_NewFdisk!= "")
//if(m_NewFdisk !=“”)
if (m_NewFdisk !="")
{
logicalDisk = "\\\\.\\"+m_NewFdisk;
hDevice = CreateFile(
logicalDisk, //要打开的驱动名称
GENERIC_READ|GENERIC_WRITE, //访问方式
FILE_SHARE_READ|FILE_SHARE_WRITE, //共享方式
NULL, //安全描述符指针
OPEN_EXISTING, //创建方式
0, //文件属性及标志
NULL //模板文件的句柄
);
bResult = DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&dwOutBytes,(LPOVERLAPPED)NULL);
} if(m_NewFdisk!="")
{
m_OldFdisk=m_NewFdisk;
}
else
{
m_OldFdisk="";
}
}
//break;
}
}
return CDialog::WindowProc(message, wParam, lParam);
}
我用//if(GetDriveType((LPCTSTR)strdir)==DRIVE_FIXED)也不可以啊,
还有个问题就是,优盘是获取一个盘符,
移动硬盘获取多个盘符,但是只能接受系统的一个消息吧
GetDriveType(strdir)的参数strdir请用“X:\\”的形式,所以逻辑盘符都能得到属性,与是否移动硬盘没有关系另外给你个建议用GetLogicalDrives可以带到当前的所有逻辑盘符,不需要用for(char cc='A';cc <='Z';cc++) 全部循环
有优盘插入时,在下拉列表框内显示盘符,并且锁住优盘或者移动硬盘
请大家帮忙看下,谢谢CString GetDiskNumber(CString name)
{
HKEY hkey;
char sz[256];
DWORD dwtype,sl = 256;
int number=0;
// 确定选择的磁盘
for(int i=1;i<8;i++) //好像这边有问题 {
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",\
NULL,KEY_ALL_ACCESS,&hkey)==ERROR_SUCCESS)
{
CString id;
id.Format("%d",i);
if(RegQueryValueEx(hkey,id,NULL,&dwtype,(LPBYTE)sz,&sl)==ERROR_SUCCESS)
{
CString str=(CString)sz;
if(str.Compare(name)==0)
{
number=i;
break;
}
}
}
}
CString driver="\\\\.\\PHYSICALDRIVE";
CString num;
num.Format("%d",number);
driver+=num;
return driver;
}
LRESULT CMSSDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
CString name;
CString driver; //获取物理盘符
int id;
HANDLE hDevice; //打开设备的句柄
DWORD dwOutBytes;
bool bResult; //DeviceIOControl返回值
CString logicalDisk; //设备的盘符
if (WM_DEVICECHANGE == message)
{
m_select.ResetContent();
HKEY hkey;
char sz[256];
DWORD dwtype,sl = 256;
for(int i=1;i<8;i++)
{
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",\
NULL,KEY_ALL_ACCESS,&hkey)==ERROR_SUCCESS)
{
CString id;
id.Format("%d",i);
if(RegQueryValueEx(hkey,id,NULL,&dwtype,(LPBYTE)sz,&sl)==ERROR_SUCCESS)
{
CString str=(CString)sz;
m_select.AddString(sz);
}
}
}
m_select.SetCurSel(0); //默认选择为下拉列表框的第一项
id=m_select.GetCurSel(); //id=0 //感觉这几行代码有问题 //U盘返回值 name=USBSTOR\Disk&Ven_CBM&Prod_Flash_Disk&Rev_5.00
//移动硬盘返回值USBSTOR\Disk&Ven_Hitachi&Prod_HTS542516K9SA00&Rev_0002\000000000033&0
m_select.GetLBText(id,name); //driver=\\.\PHYSICALDRIVE1
driver=GetDiskNumber(name);
logicalDisk = driver; //hDevice有返回值
hDevice = CreateFile(
logicalDisk, //要打开的驱动名称
GENERIC_READ|GENERIC_WRITE, //访问方式
FILE_SHARE_READ|FILE_SHARE_WRITE, //共享方式
NULL, //安全描述符指针
OPEN_EXISTING, //创建方式
0, //文件属性及标志
NULL //模板文件的句柄
);
//bResult值为1
bResult = DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&dwOutBytes,(LPOVERLAPPED)NULL);
RegCloseKey(hkey);
}
return CDialog::WindowProc(message, wParam, lParam);
}
{
////本段程序的前提是DriveName是已经过GetDriveType的判断是本地磁盘,否则报错,作用是判断是否是真正的本地磁盘////////
//////////////////111111111111111111111111111111111111111/////////////////////////////////////////////
///////////////////////获得某分区(目的地址)的信息/////////////////////////
HANDLE hDeviceDest = NULL;
DWORD nBytesRead = 0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度
DWORD nBufferSize = sizeof(PARTITION_INFORMATION);
PPARTITION_INFORMATION lpPartInfo = (PPARTITION_INFORMATION)malloc(nBufferSize);
if(lpPartInfo == NULL)
{
//MessageBox("缓冲区分配出错!","失败!",MB_OK);
return FALSE;
}
memset(lpPartInfo, 0, nBufferSize);//将缓冲区lpPartInfo的内容设为nDiskBufferSize个NULL
//CString DriveName="J:";//为判断提供接口
DriveName="\\\\.\\"+DriveName;
hDeviceDest = CreateFile(LPCTSTR(DriveName),//注意一定要是\\\\.\\的形式,CreateFile的要求 ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL);
if(hDeviceDest == NULL)
{
//MessageBox("CreateFile出错!","失败!",MB_OK);
return FALSE;
}
/////////////获得该分区信息/////////////////////////
BOOL ret1=DeviceIoControl(
hDeviceDest,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
(LPVOID) lpPartInfo,
(DWORD) nBufferSize,
(LPDWORD) &nBytesRead,
NULL//指向一个异步的结构体
);
if (!ret1)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
//MessageBox( (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
//MessageBox("DeviceIoControl出错!","失败!",MB_OK);
return FALSE;
}
///////////////////导出该分区信息///////////////////////////////////
LARGE_INTEGER StartingOffset=lpPartInfo->StartingOffset;
LONGLONG QuadPart=StartingOffset.QuadPart;//取上面的值之一情形,支持64位整型
LARGE_INTEGER PartitionLength=lpPartInfo->PartitionLength;
LONGLONG QuadPart1=PartitionLength.QuadPart;//取上面的值之一情形,支持64位整型
DWORD HiddenSectors=lpPartInfo->HiddenSectors;
DWORD PartitionNumber=lpPartInfo->PartitionNumber;
BYTE PartitionType=lpPartInfo->PartitionType;
BOOLEAN BootIndicator=lpPartInfo->BootIndicator;
BOOLEAN RecognizedPartition=lpPartInfo->RecognizedPartition;
BOOLEAN RewritePartition=lpPartInfo->RewritePartition;
free(lpPartInfo);
CloseHandle(hDeviceDest);
/////////////////////查询注册表中COUNT(Disk)的值//////////////////////////////////////
UINT IDESeqNum;//IDE的序号
BOOL FindIDE=FALSE;
HKEY hKEY;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum", 0, KEY_READ, &hKEY);
///////////接收DWORD型/////////////
DWORD Type;//仅仅用于接收数据类型
DWORD dwValue;
DWORD dwBufLen = sizeof(DWORD);
long ret2=::RegQueryValueEx(hKEY, _T("Count"), NULL, &Type, (BYTE*)&dwValue, &dwBufLen);
if(ret2!=ERROR_SUCCESS)
{
//MessageBox("找不到磁盘的个数","提示",MB_OK);
return FALSE;//失败
}
for (UINT k=0; k<dwValue; k++)
{
///////////接收字符型/////////////
char str[256];
DWORD sl = 256;
CString nDisk;
nDisk.Format("%u",k);
RegQueryValueEx(hKEY, nDisk, NULL, NULL, (LPBYTE)str, &sl); //注意第三项必须设为NULL,否则接收到的字符数据出错
CString temp=str;
if (temp.Left(3)=="IDE")
{
IDESeqNum=k;//IDE的序号
FindIDE=TRUE;
}
}
if (!FindIDE)
return FALSE; // IDESeqNum=0;
RegCloseKey(hKEY);
CString temp;
temp.Format("%u",IDESeqNum);
temp="\\\\.\\PHYSICALDRIVE"+temp;//为下一步检测作准备
//////////////////22222222222222222222222222222222222222222 /////////////////////////////////////////
HANDLE hDevice = NULL;
DWORD nDiskBytesRead = 0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度
DWORD nDiskBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + sizeof(PARTITION_INFORMATION)*104;//26*4
PDRIVE_LAYOUT_INFORMATION lpDiskPartInfo = (PDRIVE_LAYOUT_INFORMATION)malloc(nDiskBufferSize);
if(lpDiskPartInfo == NULL)
{
//MessageBox("缓冲区分配出错!","失败!",MB_OK);
return FALSE;
}
memset(lpDiskPartInfo, 0, nDiskBufferSize);//将缓冲区lpDiskPartInfo的内容设为nDiskBufferSize个NULL
//////////////////////获得所有分区的信息///////////////////////////////////////
hDevice = CreateFile(LPCTSTR(temp),//注意一定要是\\\\.\\的形式,CreateFile的要求 ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL);
if(hDevice == NULL)
{
//MessageBox("CreateFile出错!","失败!",MB_OK);
return FALSE;
}
/////////////获得某磁盘上的所有分区信息/////////////////////////
BOOL ret=DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
(LPVOID) lpDiskPartInfo,
(DWORD) nDiskBufferSize,
(LPDWORD) &nDiskBytesRead,
NULL
);
if (!ret)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
//MessageBox( (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
//MessageBox("DeviceIoControl出错!","失败!",MB_OK);
return FALSE;
}
}
//////////////////////////////导出分区信息///////////////////////////////////////
DWORD PartitionCount=lpDiskPartInfo->PartitionCount; //永远是实际的分区数的4倍,不能用的分区将会显示类型PARTITION_ENTRY_UNUSED,即分区类型为0
///////////////////依次获取导出某分区信息,并与目的驱动器进行比较///////////////////////////////////
for (UINT i=0; i<PartitionCount; i=i+4)//+4是因为只有下标为4的整数倍的值才是正确的引用
{
PARTITION_INFORMATION DiskPartInfo=lpDiskPartInfo->PartitionEntry[i];//0为C:,4为D:,8为e:,12为F
LARGE_INTEGER DiskStartingOffset = DiskPartInfo.StartingOffset;
LONGLONG DiskQuadPart = DiskStartingOffset.QuadPart; //取上面的值之一情形,支持64位整型
LARGE_INTEGER DiskPartitionLength = DiskPartInfo.PartitionLength;
LONGLONG DiskQuadPart1 = DiskPartitionLength.QuadPart; //取上面的值之一情形,支持64位整型
DWORD DiskHiddenSectors = DiskPartInfo.HiddenSectors;
DWORD DiskPartitionNumber = DiskPartInfo.PartitionNumber;
BYTE DiskPartitionType = DiskPartInfo.PartitionType;
BOOLEAN DiskBootIndicator = DiskPartInfo.BootIndicator;
BOOLEAN DiskRecognizedPartition = DiskPartInfo.RecognizedPartition;
BOOLEAN DiskRewritePartition = DiskPartInfo.RewritePartition;
if ((DiskQuadPart==QuadPart) && (DiskQuadPart1==QuadPart1)
&& (DiskHiddenSectors==HiddenSectors) && (DiskPartitionNumber==PartitionNumber)
&& (DiskPartitionType==PartitionType ) && (DiskBootIndicator==BootIndicator)
&& (DiskRecognizedPartition==RecognizedPartition) && (DiskRewritePartition==RewritePartition))
{
free(lpDiskPartInfo);
CloseHandle(hDevice);
::MessageBox(NULL,"属于本地驱动器!","提示",MB_OK);
return TRUE;
}
}
free(lpDiskPartInfo);
CloseHandle(hDevice);
::MessageBox(NULL,"非本地驱动器!","提示",MB_OK);//改为return IDCANCEL;
return FALSE;
2.我用DDK的方法可以区分是否为移动盘符的.我写的USBLOCK程序就是这么区别分的,如果是U盘或移动硬盘就再读其GUID,如果是已注册的硬件就可以使用,否则如果管理员输入了密码也可以使用到指定的时间为止,否则自动弹出.但现在出差了,手头上没有代码.
/*************************************************************************
* Function Name : GetDeviceInfo(LPGUID, vector<DEVICE_DESCRIPTOR>&)
*
* Introduction : Get storage device description
*
* Input parameter : lpGuid, DeviceVect
*
* Output parameter :None
*
* Return : None
*************************************************************************/
DWORD GetDeviceInfo(LPGUID lpGuid, vector<DEVICE_DESCRIPTOR>& DeviceVector)
{
SP_INTERFACE_DEVICE_DATA InterfaceData = {0}; //存储设备接口信息的结构体
PSP_INTERFACE_DEVICE_DETAIL_DATA_W pDetail = NULL;
SP_DEVINFO_DATA DevInfoData = {0};
HDEVINFO hDevInfoSet = NULL;
DWORD dwErrorCount = 0;
DWORD dwDevIndex = 0;
DEVINST ParentInstance = 0;
BOOL bResult = FALSE;
DEVICE_DESCRIPTOR tmpDevInfo;
DWORD dwNeededSize = 0;
//SetupDiEnumDeviceInterfaces函数取得设备属性集中某个设备接口的上下文环境
//每次调用都返回一个设备接口的相关信息.此函数可以被再三调用以获取一或多个
//设备暴露的、数个接口的信息,这里我们用来枚举符合该GUID的设备接口,调用成功
//的话,ifdata中将得到一个完成的SP_DEVICE_INTERFACE_DATA结构,该结构体将指明
//和枚举参数对应的,设备的接口信息.在调用该参数之前,必须填写ifdata的cbSize域
hDevInfoSet = SetupDiGetClassDevsW(
lpGuid, // 设备类的GUID
NULL, // 不指定关键字
NULL, // 不指定父窗口句柄
DIGCF_PRESENT| // 只枚举目前存在的设备
DIGCF_INTERFACEDEVICE //取得接口信息
);
if(hDevInfoSet == INVALID_HANDLE_VALUE) //失败??
{
MessageBox(NULL,"Sorry,Failed to retrive information set!","Error",MB_OK|MB_ICONERROR);
return 0;
}
// 成功!填写InterfaceData的cbSize域,准备调用SetupDiEnumDeviceInterfaces
InterfaceData.cbSize = sizeof(InterfaceData);
dwDevIndex = 0;
do
{
bResult = SetupDiEnumDeviceInterfaces(
hDevInfoSet, // 设备信息集句柄
NULL, // 不需额外的设备描述
lpGuid, // GUID
dwDevIndex, // 设备信息集里的设备序号
&InterfaceData // 设备接口信息(出口buffer)
);
if(!bResult) //失败?
{
break;
}
//成功,继续进行下列操作
dwNeededSize = 0;
//如果在调用SetupDiGetDeviceInterfaceDetail函数时,指定DeviceInterfaceDetailData,
//DeviceInterfaceDetailDataSize为NULL,并且RequiredSize变量有效的话,将得到需要的
//出口缓冲区的大小
SetupDiGetDeviceInterfaceDetailW(
hDevInfoSet,
&InterfaceData,
NULL,
0,
&dwNeededSize,
NULL
);
//上一次调用,我们在dwNeededSize中得到了PSP_DEVICE_INTERFACE_DETAIL_DATA
//结构体需要的缓冲区的大小,现在我们分配并初始化之.
pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA_W)new char[dwNeededSize];
pDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA_W);
DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
//OK,分配完毕,再次调用SetupDiGetDeviceInterfaceDetail得到特定接口的详细信息
bResult = SetupDiGetDeviceInterfaceDetailW
(
hDevInfoSet, // 设备信息集句柄,包含接口和下层设备信息(入口)
&InterfaceData, // 设备接口信息,表明我们要获取哪个接口的信息(入口)
pDetail, // 存储要查询的设备接口的详细细节(设备路径,出口)
dwNeededSize, // 指定输出缓冲区大小(入口)
&dwNeededSize, // 不需计算输出缓冲区大小(直接用设定值,出口)
&DevInfoData // 不需额外的设备描述(出口)
);
if(!bResult) //失败,则清场
{
dwErrorCount++;
delete []pDetail;
pDetail = NULL;
dwNeededSize = 0;
continue;
}
//取出设备路径(3环的应用程序所看到的设备路径)
tmpDevInfo.wstrRing3Interface = pDetail->DevicePath;
delete [](char*)pDetail;
pDetail = NULL;
dwNeededSize = 0;
tmpDevInfo.wstrFriendlyName = GetRegistryPropertyW(hDevInfoSet,DevInfoData,SPDRP_FRIENDLYNAME);
tmpDevInfo.wstrDeviceDesc = GetRegistryPropertyW(hDevInfoSet,DevInfoData,SPDRP_DEVICEDESC);
tmpDevInfo.wstrPhysicalDeviceObjectName = GetRegistryPropertyW(hDevInfoSet,DevInfoData,SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
tmpDevInfo.wstrService = GetRegistryPropertyW(hDevInfoSet,DevInfoData,SPDRP_SERVICE);
//获取本地设备树中父节点的ID
GetParentID(
DevInfoData.DevInst,
ParentInstance,
tmpDevInfo.wstrParentInstanceID,
tmpDevInfo.wstrParentDeviceDesc
);
GetStorageInfo(
tmpDevInfo.wstrRing3Interface,
tmpDevInfo.dwStorageDeviceNumber,
tmpDevInfo.wstrStorageManagerName
);
dwDevIndex++; DeviceVector.push_back(tmpDevInfo);
}while(bResult);
SetupDiDestroyDeviceInfoList(hDevInfoSet);
return dwErrorCount;
}
typedef struct _DEVICE_DESCRIPTOR
{
wstring wstrRing3Interface;
wstring wstrFriendlyName;
wstring wstrDeviceDesc;
wstring wstrPhysicalDeviceObjectName;
wstring wstrService;
wstring wstrParentInstanceID;
wstring wstrParentDeviceDesc;
wstring wstrStorageManagerName;
DWORD dwStorageDeviceNumber;
DWORD dwSectors;
DWORD dwBytesPerSector;
DISK_PARAMETER DiskGeometry;
}DEVICE_DESCRIPTOR, *PDEVICE_DESCRIPTOR;
6年前写的代码,一下子拖出来我自己也没怎么细看,lz将就着看看吧。
{
HKEY hkey;
char sz[256];
DWORD dwtype,sl = 256;
int number=0;
// 确定选择的磁盘
for(int i=1;i<8;i++)
{
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",\
NULL,KEY_ALL_ACCESS,&hkey)==ERROR_SUCCESS)
{
CString id;
id.Format("%d",i);
if(RegQueryValueEx(hkey,id,NULL,&dwtype,(LPBYTE)sz,&sl)==ERROR_SUCCESS)
{
CString str=(CString)sz;
if(str.Compare(name)==0)
{
number=i;
break;
}
}
}
}
CString driver="\\\\.\\PHYSICALDRIVE";
CString num;
num.Format("%d",number);
driver+=num;
return driver;
}
// 确定选择的磁盘
driver=GetDiskNumber(name);
////////////////////////////////////////////////////////////////////////
U盘返回值
name = {"USBSTOR\Disk&Ven_CBM&Prod_Flash_Disk&Rev_5.00\0210010065721303&0"}
driver = {"\\.\PHYSICALDRIVE1"}移动硬盘返回值
name = {"USBSTOR\Disk&Ven_Hitachi&Prod_HTS542516K9SA00&Rev_0002\000000000033&0"}
driver = {"\\.\PHYSICALDRIVE1"}//////添加下面几行代码,来锁优盘和移动硬盘是否可行
logicalDisk = driver; //物理驱动,之前用的是逻辑驱动
hDevice = CreateFile(
logicalDisk, //要打开的驱动名称
GENERIC_READ|GENERIC_WRITE, //访问方式
FILE_SHARE_READ|FILE_SHARE_WRITE, //共享方式
NULL, //安全描述符指针
OPEN_EXISTING, //创建方式
0, //文件属性及标志
NULL //模板文件的句柄
);
bResult = DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&dwOutBytes,(LPOVERLAPPED)NULL);
cloResult= CloseHandle(hDevice);
////////////////////////////////////////////////////////////////////////
加上8楼朋友提供的判断是否本地硬盘的代码,
现在可以锁住移动硬盘的第一个盘符,第二个盘符锁不住。//获取移动磁盘的盘符
CString CusbmngDlg::FindFdisk()
{
CString strdir;
CString ret_mobiledir;
bool is_ide = true; for(char cc='A';cc<='Z';cc++)
{
strdir.Format(L"%c:",cc); if(GetDriveType((LPCTSTR)strdir)==DRIVE_REMOVABLE) //获取U盘的盘符
{
return strdir;
}
else if(GetDriveType((LPCTSTR)strdir)==DRIVE_FIXED) //获取移动硬盘的盘符
{
//判断该盘符是否为USB盘符
is_ide = IsIDE(strdir); if (is_ide == false)
{
return strdir;
}
}
} return strdir ="";
}//回调函数的实现
LRESULT CusbmngDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_DEVICECHANGE)
{
switch(wParam)
{
case DBT_DEVICEARRIVAL: //判断是否有设备插入的消息
{
HANDLE hDevice;
DWORD dwOutBytes;
bool bResult;
bool lock_flag = false;
CString logicalDisk; //有设备插入,则跳转到该行
//查注册表
HKEY hkey;
char sz[256];
DWORD dwtype,sl = 256; for(int i=1;i<8;i++)
{
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",\
NULL, KEY_ALL_ACCESS, &hkey)==ERROR_SUCCESS)
{
CString id;
id.Format(L"%d",i); if(RegQueryValueEx(hkey,id,NULL,&dwtype,(LPBYTE)sz,&sl)==ERROR_SUCCESS)
{
LPCTSTR str = (LPCTSTR)sz;
m_select.AddString(str);
}
}
}
RegCloseKey(hkey); if(m_select.GetCount()==0)
{
lock_flag = false;
SetDlgItemText(IDC_EDIT_DRIVERNAME,L"没有发现移动设备...."); } if(m_select.GetCount()>0)
{
lock_flag = true;
SetDlgItemText(IDC_EDIT_DRIVERNAME,L"发现移动设备....");
}
if (lock_flag == true)
{
m_NewFdisk = FindFdisk(); if (m_NewFdisk !="")
{
logicalDisk = L"\\\\.\\"+m_NewFdisk; hDevice = CreateFile(
logicalDisk, //驱动器名称
GENERIC_READ|GENERIC_WRITE, //打开方式(可读可写)
FILE_SHARE_READ|FILE_SHARE_WRITE, //共享方式
NULL, //安全描述符指针
OPEN_EXISTING, //创建方式
0, //文件属性及标志
NULL //模板文件的句柄
);
//锁移动设备卷标
bResult = DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&dwOutBytes,(LPOVERLAPPED)NULL);
} //end of if (m_NewFdisk !="") if(m_NewFdisk!="")
{
m_OldFdisk=m_NewFdisk;
}
else
{
m_OldFdisk="";
}
} //end of if (lock_flag == true)
} // end of case DBT_DEVICEARRIVAL:
//break;
} //end of switch(wParam)
} //end of if(message == WM_DEVICECHANGE)
return CDialog::WindowProc(message, wParam, lParam);
}
GetDriveType是针对逻辑盘符的。依靠我的记忆,DBT_DEVICEARRIVAL也是对应逻辑盘符的,有几个盘符就有几次消息。
GetDriveType(strdir)的参数strdir请用“X:\\”的形式,所以逻辑盘符都能得到属性,与是否移动硬盘没有关系 另外给你个建议用GetLogicalDrives可以带到当前的所有逻辑盘符,不需要用for(char cc='A';cc <='Z';cc++) 全部循环 [/b]使用For循环,只能获取移动硬盘的第一个盘符,两次接收的消息,都锁第一个盘符。
如何使用GetDriveType,获取移动硬盘的多个盘符?谢谢
该函数功能是返回一个代表当前变量磁盘驱动器的位掩码;
该函数原型为:DWORD GetLogicalDrives(VOID);
该函数如果调用成功,返回值为一个代表当前变量磁盘驱动器的位屏蔽掩码,位的位置0为驱动器A,1为驱动器B,2为驱动器C等。如果函数调用失败,返回值为0。
举例:如果某台电脑上驱动器为A、C、D、E,则函数调用成功后的返回值是00011101,其中最低位代表驱动器A,由A存在所以该位掩码为1,而由于B不存在,所以倒数第二位掩码为0。
但是在普通用户权限下不可以使用