2015-12-21 39 views
2

我有一個函數WINAPI C++獲取當前物理驅動器號

DWORD GetPhysicalDriveSerialNumber(UINT nDriveNumber, CString& strSerialNumber) 
{ 
    DWORD dwResult = NO_ERROR; 
    strSerialNumber.Empty(); 

    // Format physical drive path (may be '\\.\PhysicalDrive0', '\\.\PhysicalDrive1' and so on). 
    CString strDrivePath; 
    strDrivePath.Format(_T("\\\\.\\PhysicalDrive%u"), nDriveNumber); 

    // call CreateFile to get a handle to physical drive 
    HANDLE hDevice = ::CreateFile(strDrivePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 
     NULL, OPEN_EXISTING, 0, NULL); 

    if (INVALID_HANDLE_VALUE == hDevice) 
     return ::GetLastError(); 

    // set the input STORAGE_PROPERTY_QUERY data structure 
    STORAGE_PROPERTY_QUERY storagePropertyQuery; 
    ZeroMemory(&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY)); 
    storagePropertyQuery.PropertyId = StorageDeviceProperty; 
    storagePropertyQuery.QueryType = PropertyStandardQuery; 

    // get the necessary output buffer size 
    STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = { 0 }; 
    DWORD dwBytesReturned = 0; 
    if (!::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, 
     &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), 
     &storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), 
     &dwBytesReturned, NULL)) 
    { 
     dwResult = ::GetLastError(); 
     ::CloseHandle(hDevice); 
     return dwResult; 
    } 

    // allocate the necessary memory for the output buffer 
    const DWORD dwOutBufferSize = storageDescriptorHeader.Size; 
    BYTE* pOutBuffer = new BYTE[dwOutBufferSize]; 
    ZeroMemory(pOutBuffer, dwOutBufferSize); 

    // get the storage device descriptor 
    if (!::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, 
     &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), 
     pOutBuffer, dwOutBufferSize, 
     &dwBytesReturned, NULL)) 
    { 
     dwResult = ::GetLastError(); 
     delete[]pOutBuffer; 
     ::CloseHandle(hDevice); 
     return dwResult; 
    } 

    // Now, the output buffer points to a STORAGE_DEVICE_DESCRIPTOR structure 
    // followed by additional info like vendor ID, product ID, serial number, and so on. 
    STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR*)pOutBuffer; 
    const DWORD dwSerialNumberOffset = pDeviceDescriptor->SerialNumberOffset; 
    if (dwSerialNumberOffset != 0) 
    { 
     // finally, get the serial number 
     strSerialNumber = CString(pOutBuffer + dwSerialNumberOffset); 
    } 

    // perform cleanup and return 
    delete[]pOutBuffer; 
    ::CloseHandle(hDevice); 
    return dwResult; 
} 

我想目前的驅動器號 示例(位於程序的驅動器號)(我的系統): 如果我將運行porgram在磁盤c它必須返回0(hdd 0) 如果我將在磁盤d或e上運行progrman它必須返回1(hdd 1) 閃存驅動器2等 我該怎麼做?

+0

這是相當多的代碼...你能更具體問題出在哪裏?這將增加的機率會有人能夠提供一個有用的答案(不像這一個) – Jaap

+0

我剛纔的情況下添加該代碼爲人們理解我爲什麼要發在功能驅動器號(要獲取驅動器ID序列號)理想我願做這樣的事情GetPhysicalDriveSerialNumber(驅動器號GETED前FUNCCCALLED,Str_to_save_hhd_serial_numb) –

+0

如果你的程序在運行位置與此類似'\\服務器\ sharename'? – milevyo

回答

0

運行計算機管理應用程序,然後選擇磁盤管理器。檢查驅動器列表中的驅動器號是否與您想要的相符。我有一個多啓動系統,XP,XP X64和Win 7.在Win 7的情況下,當我運行操作系統時,驅動器重新編號。啓動過程中,XP和XP X64將使用與BIOS驅動器號碼對應的驅動器號碼,但Win 7有時會在驅動器啓動並運行後重新編號。

我想知道,如果你從你的代碼獲得了「物理」驅動器號對應的驅動器或驅動器的視窗排序的BIOS排序。

如果安裝在BIOS驅動器0以外的主分區0,Win 7的默認行爲是將其分區字母更改爲C,並從驅動器0主分區0中刪除驅動器號。如果Win 7是從XP X64或Win 7的另一個實例,那麼它將不會更改它的分區字母。

到目前爲止,我不知道一種方法來防止Windows 10在安裝過程中將其分區信號更改爲C.它不會從XP X64安裝,嘗試從Win 7安裝似乎默認升級安裝在Win 7分區之上。乾淨的安裝允許你選擇要安裝的驅動器/分區,但是它會將分區字母更改爲C.如果是多啓動,其他操作系統將會看到未改變的分區字母。