對於在linux下,我們可以讀取/proc/partitions來獲得系統中所有的硬碟和分區的各個裝置名稱,但對於windows下,我們又如何獲得系統下的各個裝置呢,這裡用了windows下的API --- FindFirstVolume、
FindNextVolume
和
FindVolumeClose。
這些API可以枚舉windows系統下的各個裝置。
以下的程式摘自微軟的msdn上的例子程式,用於顯示系統中的所有裝置和卷的路徑名。對於每個卷,例子中的程式將會尋找系統中的每個卷,程式將獲得卷的裝置名稱和卷的路徑名,並顯示出了。
#include <windows.h><br />#include <stdio.h><br />void DisplayVolumePaths(<br /> __in PWCHAR VolumeName<br /> )<br />{<br /> DWORD CharCount = MAX_PATH + 1;<br /> PWCHAR Names = NULL;<br /> PWCHAR NameIdx = NULL;<br /> BOOL Success = FALSE;<br /> for (;;)<br /> {<br /> //<br /> // Allocate a buffer to hold the paths.<br /> Names = (PWCHAR) new BYTE [CharCount * sizeof(WCHAR)];<br /> if ( !Names )<br /> {<br /> //<br /> // If memory can't be allocated, return.<br /> return;<br /> }<br /> //<br /> // Obtain all of the paths<br /> // for this volume.<br /> Success = GetVolumePathNamesForVolumeNameW(<br /> VolumeName, Names, CharCount, &CharCount<br /> );<br /> if ( Success )<br /> {<br /> break;<br /> }<br /> if ( GetLastError() != ERROR_MORE_DATA )<br /> {<br /> break;<br /> }<br /> //<br /> // Try again with the<br /> // new suggested size.<br /> delete [] Names;<br /> Names = NULL;<br /> }<br /> if ( Success )<br /> {<br /> //<br /> // Display the various paths.<br /> for ( NameIdx = Names;<br /> NameIdx[0] != L'/0';<br /> NameIdx += wcslen(NameIdx) + 1 )<br /> {<br /> wprintf(L" %s", NameIdx);<br /> }<br /> wprintf(L"/n");<br /> }<br /> if ( Names != NULL )<br /> {<br /> delete [] Names;<br /> Names = NULL;<br /> }<br /> return;<br />}<br />void __cdecl wmain(void)<br />{<br /> DWORD CharCount = 0;<br /> WCHAR DeviceName[MAX_PATH] = L"";<br /> DWORD Error = ERROR_SUCCESS;<br /> HANDLE FindHandle = INVALID_HANDLE_VALUE;<br /> BOOL Found = FALSE;<br /> size_t Index = 0;<br /> BOOL Success = FALSE;<br /> WCHAR VolumeName[MAX_PATH] = L"";<br /> //<br /> // Enumerate all volumes in the system.<br /> FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));<br /> if (FindHandle == INVALID_HANDLE_VALUE)<br /> {<br /> Error = GetLastError();<br /> wprintf(L"FindFirstVolumeW failed with error code %d/n", Error);<br /> return;<br /> }<br /> for (;;)<br /> {<br /> //<br /> // Skip the //?/ prefix and remove the trailing backslash.<br /> Index = wcslen(VolumeName) - 1;<br /> if (VolumeName[0] != L'//' ||<br /> VolumeName[1] != L'//' ||<br /> VolumeName[2] != L'?' ||<br /> VolumeName[3] != L'//' ||<br /> VolumeName[Index] != L'//')<br /> {<br /> Error = ERROR_BAD_PATHNAME;<br /> wprintf(L"FindFirstVolumeW/FindNextVolumeW returned a bad path: %s/n", VolumeName);<br /> break;<br /> }<br /> //<br /> // QueryDosDeviceW doesn't allow a trailing backslash,<br /> // so temporarily remove it.<br /> VolumeName[Index] = L'/0';<br /> CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName));<br /> VolumeName[Index] = L'//';<br /> if ( CharCount == 0 )<br /> {<br /> Error = GetLastError();<br /> wprintf(L"QueryDosDeviceW failed with error code %d/n", Error);<br /> break;<br /> }<br /> wprintf(L"/nFound a device:/n %s", DeviceName);<br /> wprintf(L"/nVolume name: %s", VolumeName);<br /> wprintf(L"/nPaths:");<br /> DisplayVolumePaths(VolumeName);<br /> //<br /> // Move on to the next volume.<br /> Success = FindNextVolumeW(FindHandle, VolumeName, ARRAYSIZE(VolumeName));<br /> if ( !Success )<br /> {<br /> Error = GetLastError();<br /> if (Error != ERROR_NO_MORE_FILES)<br /> {<br /> wprintf(L"FindNextVolumeW failed with error code %d/n", Error);<br /> break;<br /> }<br /> //<br /> // Finished iterating<br /> // through all the volumes.<br /> Error = ERROR_SUCCESS;<br /> break;<br /> }<br /> }<br /> FindVolumeClose(FindHandle);<br /> FindHandle = INVALID_HANDLE_VALUE;<br /> return;<br />}<br />
下面是程式輸出中的一個例子,對於每個卷,輸出它的卷裝置路徑,卷GUID路徑和裝置字元。
Found a device:
/Device/HarddiskVolume2
Volume name: //?/Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}/
Paths: C:/
Found a device:
/Device/CdRom0
Volume name: //?/Volume{4c1b02c4-d990-11dc-99ae-806e6f6e6963}/
Paths: D:/