由于專案要用到移動硬碟。所以做了一個判斷是本地硬碟還是移動硬碟的程式,請教各位大神,下面這段程式錯在哪里了,為什么在不同的機器上運行的結果不一樣,我就郁悶了,程式是判斷是不是ide硬碟,如果是就是本地硬碟。否則是移動硬碟.
BOOL IsIDE(CString DriveName)
{
///////////////////////獲得某磁區(目的地址)的資訊/////////////////////////
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=_T("\\\\.\\")+DriveName;
hDeviceDest = CreateFile(LPCTSTR(DriveName),
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( NULL,(LPCTSTR)lpMsgBuf, _T("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,_T("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++)
{
///////////接收字符型/////////////
TCHAR str[256];
DWORD sl = 256;
CString nDisk;
nDisk.Format(_T("%u"),k);
RegQueryValueEx(hKEY, nDisk, NULL, NULL, (LPBYTE)str, &sl);
CString temp=str;
if (temp.Left(3)== _T("IDE") )
{
IDESeqNum=k;//IDE的序號
FindIDE=TRUE;
}
}
if (!FindIDE)
return FALSE; // IDESeqNum=0;
RegCloseKey(hKEY);
CString temp;
temp.Format(_T("%u"),IDESeqNum);
temp=_T("\\\\.\\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),
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,_T("屬于本地驅動器!"),_T("提示"),MB_OK);
return TRUE;
}
}
free(lpDiskPartInfo);
CloseHandle(hDevice);
//::MessageBox(NULL,_T("非本地驅動器!"),_T("提示"),MB_OK);//改為return IDCANCEL;
return FALSE;
}
uj5u.com熱心網友回復:
http://bbs.csdn.net/topics/370252647uj5u.com熱心網友回復:
我是要得到移動硬碟的盤符啊。移動硬碟和本地硬碟的型別都是driver_fixed.你說的這個沒有用uj5u.com熱心網友回復:
試試這個
bool isUsbDrv(char *path)
{
//#include <winioctl.h>
//path: "\\\\?\\F:"
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _STORAGE_DEVICE_DESCRIPTOR
{
DWORD Version; DWORD Size;
BYTE DeviceType; BYTE DeviceTypeModifier;
BOOLEAN RemovableMedia; BOOLEAN CommandQueueing;
DWORD VendorIdOffset; DWORD ProductIdOffset;
DWORD ProductRevisionOffset; DWORD SerialNumberOffset;
STORAGE_BUS_TYPE BusType; DWORD RawPropertiesLength;
BYTE RawDeviceProperties[1];
} STORAGE_DEVICE_DESCRIPTOR;
HANDLE hDisk;
STORAGE_DEVICE_DESCRIPTOR devDesc;
DWORD query[3]={0,0,1588180};
DWORD cbBytesReturned;
hDisk = CreateFile(path, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
if(hDisk == INVALID_HANDLE_VALUE)
return false;
if(DeviceIoControl(hDisk, IOCTL_STORAGE_QUERY_PROPERTY, &query,sizeof(query),
&devDesc, sizeof(devDesc), &cbBytesReturned, NULL))
{
if(devDesc.BusType == BusTypeUsb)
{
CloseHandle(hDisk);
return true;
}
}
return false;
}
//呼叫
char fileName[32];
char len=0;
for(char z='C';z<'Z';z++)
{
len=wsprintf(fileName,"\\\\?\\%C:",z);
if(isUsbDrv(fileName))
{
len=0;
break;
}
}
if(len!=0)
{
//messBox("沒有偵測到USB存盤設定!\r\n\r\n所以無法匯出記錄影像。");
return;
}
uj5u.com熱心網友回復:
學習了,沒遇到這樣的需求轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/137509.html
上一篇:急求~C++實作Web網頁提取后再進行字數統計的代碼。各位大神幫幫忙~
下一篇:記憶體映射問題
