// 获取类的头文件
// GetComputerDiskInfo.h : Defines the entry point for the GetComputerDiskInfo application.
//
#if !defined(GETCOMPUTERDISKINFO__H_)
#define GETCOMPUTERDISKINFO__H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <windows.h>
#include <Winioctl.h>
#include <stdlib.h>
typedef struct PartitionInfo{
char chDrive;
PARTITION_INFORMATION info;
} PartitionInfo, *LPPartitionInfo;
typedef struct DiskInfo{
int iPartitionSize;
PPARTITION_INFORMATION pPartitions;
} DiskInfo, *LPDiskInfo;
class CGetComputerDiskInfo
{
public:
CGetComputerDiskInfo();
virtual ~CGetComputerDiskInfo();
public:
bool IsPartitionEqual(PPARTITION_INFORMATION pPart1, PPARTITION_INFORMATION pPart2);
void PrintDiskDrives(char disk[255]);
int GetAllDiskPartitionInfo(LPDiskInfo* lpDisks);
int GetAllLogicalDriveInfo(LPPartitionInfo* lpPartions);
protected:
private:
};
#endif // !defined(GETCOMPUTERDISKINFO__H_)
// 获取类的实现文件
// GetComputerDiskInfo.h : Defines the entry point for the GetComputerDiskInfo application.
//
#include "stdafx.h"
#include "GetComputerDiskInfo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CGetComputerDiskInfo::CGetComputerDiskInfo()
{
}
CGetComputerDiskInfo::~CGetComputerDiskInfo()
{
}
void CGetComputerDiskInfo::PrintDiskDrives(char disk[255])
{
LPDiskInfo lpDisks = NULL;
LPPartitionInfo lpPartitions = NULL;
int iDisks = GetAllDiskPartitionInfo(&lpDisks);
int iDrives = GetAllLogicalDriveInfo(&lpPartitions);
for (int i = 0; i < iDisks; ++i)
{
printf("Disk%d:\n", i);
for (int k = 0; k < lpDisks[i].iPartitionSize; ++k)
{
for (int j = 0; j < iDrives; ++j)
{
if (IsPartitionEqual(&lpDisks[i].pPartitions[k], &lpPartitions[j].info))
{
printf("%c, ", lpPartitions[j].chDrive);
disk[j] = lpPartitions[j].chDrive;
break;
}
}
}
printf("\n");
}
// free memory
for (int j = 0; j < iDisks; ++j)
{
free (lpDisks[j].pPartitions);
}
free (lpDisks);
free (lpPartitions);
}
int CGetComputerDiskInfo::GetAllDiskPartitionInfo(LPDiskInfo* lpDisks)
{
// 访问注册表
HKEY hKEY;
long lRet;
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",
0,
KEY_READ,
&hKEY);
if (lRet != ERROR_SUCCESS)
{
return 0;
}
int iSize = 0;
DWORD dwType;
DWORD dwValue;
DWORD dwBufLen = sizeof(DWORD);
__try
{
lRet = ::RegQueryValueEx(hKEY, "Count", NULL, &dwType, (BYTE*)&dwValue, &dwBufLen);
if(lRet != ERROR_SUCCESS)
{
__leave;//失败
}
*lpDisks = (LPDiskInfo)malloc(dwValue*sizeof(DiskInfo));
for (UINT i = 0; i < dwValue; i++)
{
char szDiskPos [128] = {0};
sprintf(szDiskPos, "\\\\.\\PHYSICALDRIVE%u", i);
HANDLE hDevice = NULL;
DWORD nDiskBytesRead = 0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度
DWORD nDiskBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + sizeof(PARTITION_INFORMATION) * 104;//26*4
PDRIVE_LAYOUT_INFORMATION lpDiskPartInfo = (PDRIVE_LAYOUT_INFORMATION)malloc(nDiskBufferSize);
if(lpDiskPartInfo == NULL)
{
free (lpDiskPartInfo);
continue;
}
//将缓冲区lpDiskPartInfo的内容设为nDiskBufferSize个NULL
memset(lpDiskPartInfo, 0, nDiskBufferSize);
//获得所有分区的信息///
hDevice = CreateFile(szDiskPos,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if(hDevice == NULL)
{
free (lpDiskPartInfo);
continue;
}
/获得某磁盘上的所有分区信息/
BOOL fRet = DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
(LPVOID) lpDiskPartInfo,
(DWORD) nDiskBufferSize,
(LPDWORD) &nDiskBytesRead,
NULL
);
if (!fRet)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
LocalFree( lpMsgBuf );
free (lpDiskPartInfo);
CloseHandle(hDevice);
continue;
}
//导出分区信息///
DWORD dwPartitionCount = lpDiskPartInfo->PartitionCount;
int iPartitions = dwPartitionCount / 4;
(*lpDisks)[iSize].pPartitions = (PPARTITION_INFORMATION)malloc (iPartitions * sizeof (PARTITION_INFORMATION));
(*lpDisks)[iSize].iPartitionSize = 0;
//永远是实际的分区数的4倍,不能用的分区将会显示类型PARTITION_ENTRY_UNUSED,即分区类型为0
///依次获取导出某分区信息,并与目的驱动器进行比较///
for (UINT j = 0;j < dwPartitionCount; j += 4)//+4是因为只有下标为4的整数倍的值才是正确的引用
{
memcpy (&((*lpDisks)[iSize].pPartitions [(*lpDisks)[iSize].iPartitionSize++]), &lpDiskPartInfo->PartitionEntry [j], sizeof (PARTITION_INFORMATION));
}
free(lpDiskPartInfo);
CloseHandle(hDevice);
++iSize;
}
}
__finally
{
if (hKEY != NULL)
{
RegCloseKey(hKEY);
}
}
return iSize;
}
int CGetComputerDiskInfo::GetAllLogicalDriveInfo(LPPartitionInfo* lpPartions)
{
int iSize = 0;
char szBuf [1024];
GetLogicalDriveStrings (1024, szBuf);
*lpPartions = (LPPartitionInfo) malloc (sizeof (PartitionInfo) * 26); // 26 个英文字母
char szDrive [64] = {0};
for (char* pszDrive = (char*)szBuf; pszDrive != NULL && *pszDrive != 0; pszDrive += strlen (pszDrive) + 1)
{
(*lpPartions)[iSize].chDrive = *pszDrive;
wsprintf(szDrive, "\\\\.\\%c:", *pszDrive);
HANDLE hDevice = CreateFile(szDrive,
GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
continue;
DWORD dwNum;
DeviceIoControl(hDevice,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&(*lpPartions)[iSize++].info,
sizeof(PARTITION_INFORMATION),
&dwNum,
NULL);
CloseHandle(hDevice);
}
return iSize;
}
bool CGetComputerDiskInfo::IsPartitionEqual(PPARTITION_INFORMATION pPart1, PPARTITION_INFORMATION pPart2)
{
if (pPart1->BootIndicator == pPart2->BootIndicator &&
pPart1->HiddenSectors == pPart2->HiddenSectors &&
pPart1->PartitionLength.QuadPart == pPart2->PartitionLength.QuadPart &&
pPart1->PartitionNumber == pPart2->PartitionNumber &&
pPart1->PartitionType == pPart2->PartitionType &&
pPart1->RecognizedPartition == pPart2->RecognizedPartition &&
pPart1->RewritePartition == pPart2->RewritePartition &&
pPart1->StartingOffset.QuadPart == pPart2->StartingOffset.QuadPart)
{
return true;
}
return false;
}
// 创建一个控制台程序
// GetDiskInfo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "GetComputerDiskInfo.h"
int main(int argc, char* argv[])
{
char disk[26] = {0};
CGetComputerDiskInfo gf;
gf.PrintDiskDrives(disk);
for (int i=0; i<sizeof(disk); i++)
{
printf("%c, ", disk[i]);
}
char * a[4] = {"this", "is", "a", "test!"}; //a是一个大小为4的数组,数组的每一个成员是char类型的指针
char b[][4] = {"aaa", "bbb"};
char (*c)[4]; //c是一个指针,指向char[4]类型的指针
c = &b[0]; //取b[0]地址
printf("%s %s %s\n", a[0], b[0], c);
printf("%p %p %p\n", a[0], b[0], c);
printf("%p %p %p\n", &a[0], &b[0], &c);
getchar();
return 0;
}