1. 程式人生 > >用C++程式設計獲取驅動器碟符(一)

用C++程式設計獲取驅動器碟符(一)

首先,一臺機器可能有不止一個CD-ROM驅動器。現在CD-ROM已經是PC機的標準配置,此外再裝個可擦寫的光碟驅動,甚至是DVD都是很常見的事情。不管一臺機器上裝多少個不同的驅動器,如何找到它們呢?

  有關驅動器的函式有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就可以了。