用C++程式設計獲取驅動器碟符(一)
有關驅動器的函式有GetLogicalDrives,GetLogicalDriveStrings和GetDriveType。前兩個用來獲取邏輯驅動器碟符,GetLogicalDriveStrings返回路徑名字串,如:
"A:\<null>C:\<null>F:\<null><null>"
這裡每一個路徑名都由NULL(空或者零)字元分隔,最後結尾是兩個空字元--這是標準的C風格處理方法。對於喜歡操作位和位元組的組合語言使用者來說,GetLogicalDrives是個很好用的API函式。它以位掩碼的形式返回邏輯驅動器。即在一個DWORD型別的返回值中,位0(最小的一位)表示驅動器A,位1表示驅動器B,以此類推。每一個位的狀態如果是on,則表示對應的邏輯驅動器存在;否則狀態為off,表示對應的邏輯驅動器不存在。大家知道DWORD是一個32位的值,足以包括所有的英文字母,也就是說最多可有26個碟符。
為了確定某個邏輯驅動器的型別,必須呼叫GetDriveType函式。它以路徑名作為引數(如C:\),返回DRIVE_FIXED,DRIVE_REMOVABLE,或DRIVE_UNKNOWN。下面列出了所有可能返回的值:這些值在winbase.h定義
#define DRIVE_UNKNOWN 0 // 無效路徑名
#define DRIVE_NO_ROOT_DIR 1 // 無效路經,如無法找到的卷標
#define DRIVE_REMOVABLE 2 // 可移動驅動器(如磁碟驅動器,光碟機等)
#define DRIVE_FIXED 3 // 固定的驅動器 (如 通常的硬碟)
#define DRIVE_REMOTE 4 // 網路驅動器
#define DRIVE_CDROM 5 // CD-ROM
#define DRIVE_RAMDISK 6 // 隨機存取(RAM) 磁碟
為了更容易說明問題,我寫了一個小程式--ListDrives,它可以列出某臺機器上所有的邏輯驅動器。其實現程式碼如下:
ListDrives.cpp
#include "stdafx.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
using namespace std; // for string class
// 下面是一個GetDriveType返回碼與人可讀字串的迷你對照表
//
struct {
UINT type; // GetDriveType返回碼型別
LPCSTR name; // ascii 名稱
} DriveTypeFlags [] = {
{ DRIVE_UNKNOWN, "未知" },
{ DRIVE_NO_ROOT_DIR, "無效路經" },
{ DRIVE_REMOVABLE, "可移動" },
{ DRIVE_FIXED, "固定" },
{ DRIVE_REMOTE, "網路驅動器" },
{ DRIVE_CDROM, "CD-ROM" },
{ DRIVE_RAMDISK, "隨機存取磁碟" },
{ 0, NULL},
};
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) {
cerr << _T("Fatal Error: MFC initialization failed") << endl;
return -1;
}
// 獲取邏輯驅動器字串- a:\b:\c:\... 等.
// 還可以用GetLogicalDrives 以點陣圖形式代替字串形式獲取資訊
TCHAR buf[100];
DWORD len = GetLogicalDriveStrings(sizeof(buf)/sizeof(TCHAR),buf);
// 顯示每個驅動器的資訊
//
string msg = "Logical Drives:\n"; // STL string
for (TCHAR* s=buf; *s; s+=_tcslen(s)+1) {
LPCTSTR sDrivePath = s;
msg += sDrivePath;
msg += " ";
// GetDriveType 獲取列舉值,如DRIVE_UNKNOWN等.
//
UINT uDriveType = GetDriveType(sDrivePath);
// 查詢驅動器型別。在此我用了表(結構陣列)來進行查詢處理,過於繁瑣了一些,
// 但既然uDriveType 的值是連續的。
// 我可以用DriveTypeFlags[uDriveType]來代替線性查詢。在實際的程式設計中通常可以這麼做:
// if (uDriveType & DEVICE_CDROM) {
……
// }
//
for (int i=0; DriveTypeFlags[i].name; i++) {
if (uDriveType == DriveTypeFlags[i].type) {
msg += DriveTypeFlags[i].name;
break;
}
}
msg += ''''''''''''''''\n'''''''''''''''';
}
cout << msg.c_str();
return 0;
}
程式程式碼很簡單,它是一個MFC程式。用GetLogicalDriveStrings獲取所有邏輯驅動器的根路徑名,然後呼叫GetDriveType來確定每個驅動器的型別。如果你要找CD-ROM,則檢查uDriveType = DRIVE_CDROM就可以了。