这一系列文章是根据cutebunny 的BLOG “windows的磁盘操作” 写成的,主要是部分修改原作中的代码,使之兼容Unicode和Windows 7 64bit. 原文可以在下面的网址找到
http://cutebunny.blog.51cto.com 。 本文是参考 “windows的磁盘操作之五——获取物理磁盘上的所有逻辑分区号”写成。
程序实现了获得当前硬盘上全部盘符的功能(分区可能没有分配盘符,比如:win7一般都会隐藏起来最前面的分区)。
// emuPart.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
/******************************************************************************
* Function: get disk's physical number from its drive letter
* e.g. C-->0 (C: is on disk0)
* input: letter, drive letter
* output: N/A
* return: Succeed, disk number
* Fail, -1
******************************************************************************/
DWORD GetPhysicalDriveFromPartitionLetter(TCHAR letter)
{
HANDLE hDevice; // handle to the drive to be examined
BOOL result; // results flag
DWORD readed; // discard results
STORAGE_DEVICE_NUMBER number; //use this to get disk numbers
TCHAR path[MAX_PATH];
wsprintf(path, L"\\\\.\\%c:", letter);
hDevice = CreateFile(path, // drive to open
GENERIC_READ | GENERIC_WRITE, // access to the drive
FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attribute
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
return DWORD(-1);
}
result = DeviceIoControl(
hDevice, // handle to device
IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
&number, // output buffer
sizeof(number), // size of output buffer
&readed, // number of bytes returned
NULL // OVERLAPPED structure
);
if (!result) // fail
{
fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld\n", GetLastError());
(void)CloseHandle(hDevice);
return (DWORD)-1;
}
printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber);
(void)CloseHandle(hDevice);
return number.DeviceNumber;
}
/******************************************************************************
* Function: get disk's drive letters from physical number
* e.g. 0-->{C, D, E} (disk0 has 3 drives, C:, D: and E:)
* input: phyDriveNumber, disk's physical number
* output: letters, letters array
* return: Succeed, the amount of letters
* Fail, -1
******************************************************************************/
DWORD GetPartitionLetterFromPhysicalDrive(DWORD phyDriveNumber, TCHAR **letters)
{
DWORD mask;
DWORD driveType;
DWORD bmLetters;
DWORD diskNumber;
TCHAR path[MAX_PATH];
TCHAR letter;
DWORD letterNum;
WORD i;
TCHAR *p;
bmLetters = GetLogicalDrives();
if (0 == bmLetters)
{
return (DWORD)-1;
}
letterNum = 0;
for (i = 0; i < sizeof(DWORD) * 8; i++)
{
mask = 0x1u << i;
if ((mask & bmLetters) == 0) //get one letter
{
continue;
}
letter = (TCHAR)(0x41 + i); //ASCII change
wsprintf(path, L"%c:\\", letter);
driveType = GetDriveType(path);
if (driveType != DRIVE_FIXED)
{
bmLetters &= ~mask; //clear this bit
continue;
}
diskNumber = GetPhysicalDriveFromPartitionLetter(letter);
if (diskNumber != phyDriveNumber)
{
bmLetters &= ~mask; //clear this bit
continue;
}
letterNum++;
}
//build the result
*letters = (TCHAR *)malloc(letterNum);
if (NULL == *letters)
{
return (DWORD)-1;
}
p = *letters;
for (i = 0; i < sizeof(DWORD) * 8; i++)
{
mask = 0x1u << i;
if ((mask & bmLetters) == 0)
{
continue;
}
letter = (TCHAR)(0x41 + i); //ASCII change
*p = letter;
printf("%c",letter);
p++;
}
return letterNum;
}
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR *List;
GetPartitionLetterFromPhysicalDrive(0,&List);
getchar();
return 0;
}
最后一行给出了PhysicalDrive0 上的三个盘符
参考:
1.cutebunny 的BLOG “windows的磁盘操作” 可以在这里下载 WindowsDisk
