目前共有8篇帖子。 內容轉換:不轉換▼
 
點擊 回復
428 7
【API】获取驱动器列表及其详细信息
一派護法 十九級
1樓 發表于:2016-3-3 22:09
#include <iostream>
#include <tchar.h>
#include <Windows.h>

using namespace std;

int main(void)
{
    DWORD drives = GetLogicalDrives();
    cout << "Drives Mask: " << drives << endl;

    TCHAR str[100];
    LPTSTR pStr = str;
    HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    GetLogicalDriveStrings(sizeof(str), str);
    while (*pStr != '\0')
    {
        size_t len = _tcslen(pStr);
        WriteConsole(hConsoleOutput, pStr, len, NULL, NULL);
        cout << ": ";

        UINT uType = GetDriveType(pStr);
        switch (uType)
        {
        case DRIVE_NO_ROOT_DIR:
            cout << "空驱动器";
            break;
        case DRIVE_REMOVABLE:
            cout << "可移动磁盘";
            break;
        case DRIVE_FIXED:
            cout << "硬盘";
            break;
        case DRIVE_REMOTE:
            cout << "网络驱动器";
            break;
        case DRIVE_CDROM:
            cout << "光驱";
            break;
        case DRIVE_RAMDISK:
            cout << "只读存储器";
            break;
        case DRIVE_UNKNOWN:
        default:
            cout << "未知";
            break;
        }

        cout << endl;
        pStr += len + 1;
    }

    HANDLE hFindVolume = FindFirstVolume(str, sizeof(str));
    do
    {
        WriteConsole(hConsoleOutput, str, _tcslen(str), NULL, NULL);
        cout << endl;
    } while (FindNextVolume(hFindVolume, str, sizeof(str)));
    FindVolumeClose(hFindVolume);

    DWORD dwSerialNumber, dwMaxCompLen, dwFlags;
    TCHAR szType[10];
    cout << endl;
    GetVolumeInformation(TEXT("C:\\"), str, sizeof(str), &dwSerialNumber, &dwMaxCompLen, &dwFlags, szType, sizeof(szType));
    cout << "dwSerialNumber: " << dwSerialNumber << endl;
    cout << "dwMaxCompLen: " << dwMaxCompLen << endl;
    cout << "dwFlags: " << dwFlags << endl;
    cout << "szType: ";
    WriteConsole(hConsoleOutput, szType, _tcslen(szType), NULL, NULL);
    cout << endl;

    system("pause");
    return 0;
}
一派護法 十九級
2樓 發表于:2016-3-3 22:09
【输出】
Drives Mask: 124
C:\: 硬盘
D:\: 硬盘
E:\: 硬盘
F:\: 硬盘
G:\: 光驱
\\?\Volume{5e889bb2-6c1b-11e5-8413-806e6f6e6963}\
\\?\Volume{5e889bb4-6c1b-11e5-8413-806e6f6e6963}\
\\?\Volume{5e889bb5-6c1b-11e5-8413-806e6f6e6963}\
\\?\Volume{5e889bb6-6c1b-11e5-8413-806e6f6e6963}\
\\?\Volume{5e889bb3-6c1b-11e5-8413-806e6f6e6963}\
\\?\Volume{5e889bb7-6c1b-11e5-8413-806e6f6e6963}\
\\?\Volume{5e889bba-6c1b-11e5-8413-806e6f6e6963}\

dwSerialNumber: 3500692001
dwMaxCompLen: 255
dwFlags: 65470719
szType: NTFS
Press any key to continue . . .
一派護法 十九級
4樓 發表于:2016-7-17 18:35
GetLogicalDriveStrings(sizeof(str), str)
这句代码中第一个参数没有写对
应该是
GetLogicalDriveStrings(_countof(str), str);
才对。
第一个参数是缓冲区最大可容纳的字符数,包括\0和\0\0在内。
一派護法 十九級
5樓 發表于:2016-7-17 18:40

【循环输出驱动器列表的示例】

#include <iostream>
#include <Windows.h>
using namespace std;
#ifdef _UNICODE
ostream &operator << (ostream &os, const wchar_t *wstr)
{
 if (os == cout)
  WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wstr, wcslen(wstr), NULL, NULL);
 return os;
}
#endif
int main(void)
{
 int i = 0;
 TCHAR szDrives[100];
 GetLogicalDriveStrings(_countof(szDrives), szDrives);
 while (szDrives[i] != '\0')
 {
  cout << szDrives + i << endl;
  i += lstrlen(szDrives + i) + 1;
 }
 return 0;
}
【输出】

C:\
D:\
E:\
F:\
G:\

一派護法 十九級
6樓 發表于:2016-7-17 19:44

1楼的程序中所有的sizeof都要改成_countof,因为API要求的单位都是字符个数。

另外,对于FindFirstVolume和FindNextVolume函数,如果缓冲区大小不够,那么直接操作失败。

一派護法 十九級
7樓 發表于:2016-7-17 19:49

【获取磁盘卷标的方法】

TCHAR szBuffer[MAX_PATH + 1];
GetVolumeInformation(TEXT("F:\\"), szBuffer, _countof(szBuffer), NULL, NULL, NULL, NULL, NULL);

如果缓冲区不够大,那么函数会执行失败。

获得的卷标可能会是空字符串。(依磁盘属性里面的文本框里显示的为准。注意空字符串和“本地磁盘”是有区别的,尽管在“我的电脑”里显示都是“本地磁盘”)

一派護法 十九級
8樓 發表于:2016-7-17 19:52

【设置磁盘卷标】

SetVolumeLabel(TEXT("F:\\"), TEXT("新卷标"));

【清空磁盘卷标】
SetVolumeLabel(TEXT("F:\\"), NULL);

 

这两个函数在Win7下必须要以管理员方式运行程序才能执行成功。

一派護法 十九級
9樓 發表于:2016-7-17 20:07

【获取驱动器全部非根目录挂载点】

TCHAR szBuffer[MAX_PATH + 1];
HANDLE hFind = FindFirstVolumeMountPoint(TEXT("C:\\"), szBuffer, _countof(szBuffer));
if (hFind == INVALID_HANDLE_VALUE)
{
 DWORD dwErr = GetLastError();
 cout << L"操作失败, 错误码: " << GetLastError() << endl;
 if (dwErr == ERROR_ACCESS_DENIED)
  cout << L"无权限" << endl;
 else if (dwErr == ERROR_NO_MORE_FILES)
  cout << L"无非根目录的挂载点" << endl;
}
else
{
 do
 {
  cout << szBuffer << endl;
 } while (FindNextVolumeMountPoint(TEXT("C:\\"), szBuffer, _countof(szBuffer)));
 FindVolumeMountPointClose(hFind);
}

【运行结果一般为】

操作失败, 错误码: 18
无挂载点

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:428 回複數:7
評論數: ?
作者:巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2016-7-17 20:07
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。