获取 磁盘空间、文件夹等大小

// 获取的头文件
// 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;
}






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值