Win32文件系统1-磁盘驱动器

来源:互联网 发布:ftp端口 编辑:程序博客网 时间:2024/06/05 07:33

[获取驱动器信息]

所用到的API函数:

GetLogicalDrivers:获取本机所有逻辑驱动器,以位标志的形式返回
GetLogicalDriverString:获取本机所有逻辑驱动器,以驱动器根路径字符串返回
FindFirstVolume:查找主机中的第一个驱动器,返回查找句柄.
FindNextVolume:根据FindFirstVolume返回句柄,查找主机中下一个逻辑驱动器
FindVolumeClose:关闭驱动器查找句柄
GetDriveType:获取驱动器类型
(值:RIVE_UNKNOWN,DRIVE_NO_ROOT_DIR,DRIVE_REMOVABLE,DRIVE_FIXED
DRIVE_REMOTE,DRIVE_CDROM,DRIVE_RAMDISK)
GetVolumeInformation:获取逻辑驱动器信息

#include <windows.h>#include <tchar.h>#include <stdio.h>#define BUFSIZE MAX_PATH//得到驱动器详细信息BOOL GetDriverInfo(TCHAR*);int main(void){TCHAR szVolumeName[BUFSIZE],szDriveName[BUFSIZE],*pTemp=szDriveName;HANDLE hVol;DWORD dwFlags;TCHAR szFlags[BUFSIZE];//UNICODE或ANSI都能正常输出中文_tsetlocale(0,_T("chs"));/*输出本机所有卷名*/hVol=FindFirstVolume(szVolumeName,BUFSIZE);if(hVol==INVALID_HANDLE_VALUE){return -1;}_tprintf(_T("所有卷信息\n"));do {_tprintf(_T("卷名:%s\n"),szVolumeName);} while(FindNextVolume(hVol,szVolumeName,BUFSIZE));FindVolumeClose(hVol);_tprintf(_T("\n"));/*得到本机所有磁盘驱动器信息-位标志形式*/dwFlags=GetLogicalDrives();//转成二进制存入szFlags//第0位是否为1对应是否有A盘//第1位是否为1对应是否有B盘...类推_itot(dwFlags,szFlags,2);_tprintf(_T("(标志位表示)所有磁盘驱动器信息:%s\n\n"),szFlags);/*得到本机所有磁盘驱动器信息-字符串形式*/GetLogicalDriveStrings(BUFSIZE,szDriveName);//得到的szDriveName大概是"C:\\ \0 D:\\ 0 E:\\ \0 F:\\ \0\0"//为了跳过\0,所以直到遇到2个连续的\0\0才算是显示完所有驱动器_tprintf(_T("所有驱动器信息\n"));while(*pTemp&&*(pTemp+1)){_tprintf(_T("%s\n"),pTemp);pTemp+=lstrlen(pTemp)+1;}//_tprintf(_T("\nC盘详细信息\n"));//GetDriverInfo(_T("c:\\"));system("pause");return 0;}BOOL GetDriverInfo(TCHAR *szDriveName){UINT uDriveType;DWORD dwVolumeSerialNumber;DWORD dwMaximumComponentLength;DWORD dwFileSystemFlags;TCHAR szFileSystemFlags[BUFSIZE];TCHAR szFileSystemNameBuffer[BUFSIZE];TCHAR szVolumeName[BUFSIZE];_tprintf(_T("盘符:%s\n"),szDriveName);uDriveType=GetDriveType(szDriveName);switch (uDriveType){case DRIVE_UNKNOWN:_tprintf(_T("%s\n"),_T("驱动器类型:不能确定."));break;case DRIVE_NO_ROOT_DIR:_tprintf(_T("%s\n"),_T("驱动器类型:无效的,例如没有卷安装在这个路径."));break;case DRIVE_REMOVABLE:_tprintf(_T("%s\n"),_T("驱动器类型:移动介质,例如,软盘或移动硬盘."));break;case DRIVE_FIXED:_tprintf(_T("%s\n"),_T("驱动器类型:硬盘."));break;case DRIVE_REMOTE:_tprintf(_T("%s\n"),_T("驱动器类型:网络驱动器."));break;case DRIVE_CDROM:_tprintf(_T("%s\n"),_T("驱动器类型:光驱."));break;default:break;}if(!GetVolumeInformation(szDriveName,//输入参数,驱动器名称(也可以用卷名代替)szVolumeName,//输出参数,驱动器卷标名BUFSIZE,//输入参数,存放[卷标名]的最大字符长度&dwVolumeSerialNumber,//输出参数,驱动器的序列号&dwMaximumComponentLength,//输出参数,驱动器文件系统允许的最大文件名长度&dwFileSystemFlags,//输出参数,驱动器文件系统的特性szFileSystemNameBuffer,//输出参数,驱动器文件系统的类型(NTFS,FAT,FAT32..)BUFSIZE//输入参数,存放[驱动器文件系统类型]的最大字符长度))return FALSE;_tprintf(_T("卷标名:%s\n"),lstrlen(szVolumeName)>0?szVolumeName:_T("没有卷标名"));_tprintf(_T("序列号:%04X-%04X\n"),HIWORD(dwVolumeSerialNumber),LOWORD(dwVolumeSerialNumber));_tprintf(_T("文件系统:%s\n"),lstrlen(szFileSystemNameBuffer)>0?szFileSystemNameBuffer:_T("无"));_tprintf(_T("允许的最大文件名长度:%d\n"),dwMaximumComponentLength);_itot(dwFileSystemFlags,szFileSystemFlags,2);_tprintf(_T("文件系统特性:%s\n"),szFileSystemFlags);/*dwFileSystemFlags这个输出参数可以是一个或多个下列标志。FS_FILE_COMPRESSION和FS_VOL_IS_COMPRESSED的是互斥的。值含义FILE_CASE_PRESERVED_NAMES指定的卷支持保存文件名的情况下,当它在磁盘上放置一个名称。FILE_CASE_SENSITIVE_SEARCH0X00000001指定的卷支持区分大小写的文件名。FILE_FILE_COMPRESSION0X00000010指定的卷支持基于文件的压缩。FILE_NAMED_STREAMS0x00040000指定的卷支持命名流。FILE_PERSISTENT_ACLS0x00000008的指定的卷保留和强制访问控制列表ACL。例如,NTFS文件系统保存和强制访问控制列表,FAT文件系统不支持。FILE_READ_ONLY_VOLUME0x00080000指定的卷是只读。FILE_SEQUENTIAL_WRITE_ONCE为0x00100000指定的卷支持一个单一的顺序写。FILE_SUPPORTS_ENCRYPTION0x00020000处指定的卷支持加密文件系统( EFS ) 。欲了解更多信息,请参阅文件加密。FILE_SUPPORTS_EXTENDED_ATTRIBUTES指定的卷支持扩展属性。扩展属性是一块特定于应用程序的元数据,应用程序可以与文件相关联的,不属于该文件的数据。FILE_SUPPORTS_HARD_LINKS指定的卷支持硬链接。欲了解更多信息,请参阅硬链接和路口。FILE_SUPPORTS_OBJECT_IDS指定的卷支持的对象标识符。FILE_SUPPORTS_OPEN_BY_FILE_ID文件系统支持从文件ID打开。请参阅FILE_ID_BOTH_DIR_INFO。FILE_SUPPORTS_REPARSE_POINTS指定的卷支持重解析点。但不为它们编制索引,所以FindFirstVolumeMountPoint和FindNextVolumeMountPoint不会如预期般运作。FILE_SUPPORTS_SPARSE_FILES指定的卷支持稀疏文件。FILE_SUPPORTS_TRANSACTIONS指定的卷支持交换。欲了解更多信息,请参阅关于KTM。FILE_SUPPORTS_USN_JOURNAL指定的卷支持更改序列号(USN )期刊。欲了解更多信息,请参阅更改日志记录。FILE_UNICODE_ON_DISK指定的卷支持Unicode文件名。FILE_VOLUME_IS_COMPRESSED指定的卷是一个压缩量,例如, DoubleSpace磁碟。FILE_VOLUME_QUOTAS指定的卷支持磁盘配额。*/return TRUE;}

[驱动器挂载点]

/*根据卷名输出卷上所有挂载点*/void GetVolumeMountPointToStrings(TCHAR *szDiskName){TCHAR lpszVolumeMountPoint[BUFSIZE]={0};HANDLE hVMP = FindFirstVolumeMountPoint(szDiskName,lpszVolumeMountPoint,BUFSIZE);if(hVol==INVALID_HANDLE_VALUE){_tprintf(_T("没有可用的卷"));return;}_tprintf(_T("在%s里有以下挂载点:\n"),szDiskName);do {_tprintf(_T("挂载点:%s\n"),lpszVolumeMountPoint);} while (FindNextVolumeMountPoint(hVMP,lpszVolumeMountPoint,BUFSIZE));FindVolumeMountPointClose(hVMP);}

/*根据挂载点名,根驱动器名进行挂载*///参数:lpszVolumeMountPoint 挂载点名称//参数:lpszDriveName 根驱动器名称bool DriveInfo::SetVolumeMountPoint2(TCHAR *lpszVolumeMountPoint,TCHAR *lpszDriveName){//返回值bool bRet;//错误代码int iErr;//卷名TCHAR szVolumeName[BUFSIZE]={0};//先测试是否已被挂GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint,szVolumeName,BUFSIZE);if(lstrlen(szVolumeName)>0){_tprintf(_T("挂载点%s已被使用\n"),lpszVolumeMountPoint);DeleteVolumeMountPoint(lpszVolumeMountPoint);_tprintf(_T("挂载点%s已被删除\n"),lpszVolumeMountPoint);}//将根驱动器lpszDriveName的卷名送入szVolumeNameGetVolumeNameForVolumeMountPoint(lpszDriveName,szVolumeName,BUFSIZE);//如果挂载成功if(SetVolumeMountPoint(lpszVolumeMountPoint,szVolumeName))_tprintf(_T("成功将 %s 挂载到 %s"),lpszVolumeMountPoint,lpszDriveName);else{iErr=GetLastError();if(iErr==123)_tprintf(_T("挂载点路径错误"),GetLastError());else if(iErr==87)_tprintf(_T("挂载失败,找不到文件夹:%s"),lpszVolumeMountPoint);else_tprintf(_T("挂载失败,错误代码:%d\n打开VS->工具->错误查找->找到具体错误提示\n"),iErr);bRet=false;}return bRet;}


[判断光驱] 

/*根据根路径判断是否为光驱,以及光驱里是否有光盘*/void DriveInfo::IsCDROM(TCHAR *szRootName){if(GetDriveType(szRootName)&DRIVE_CDROM){_tprintf(_T("%s是光驱\n"),szRootName);if(GetVolumeInformation(szRootName,NULL,NULL,NULL,NULL,NULL,NULL,NULL)){_tprintf(_T("%s里有光盘\n"),szRootName);}else{_tprintf(_T("%s里没有光盘\n"),szRootName);}}else{_tprintf(_T("%s不是光驱\n"),szRootName);}}


[检测磁盘容量,簇,扇区信息]

/*根据盘符取磁盘空间*/void DriveInfo::GetDiskSizeEx(TCHAR *szRootName){ULARGE_INTEGER lpFreeBytesAvailable;ULARGE_INTEGER lpTotalNumberOfBytes;ULARGE_INTEGER lpTotalNumberOfFreeBytes;//GetDiskFreeSpaceEx(根路径,实际可用空间,总大小,可用空间)if(GetDiskFreeSpaceEx(szRootName,&lpFreeBytesAvailable,&lpTotalNumberOfBytes,&lpTotalNumberOfFreeBytes)){_tprintf(_T("驱动器:%s\n"),szRootName);_tprintf(_T("总大小(字节):%I64d\n"),lpTotalNumberOfBytes);_tprintf(_T("驱动器实际可用空间(字节):%I64d\n"),lpFreeBytesAvailable);_tprintf(_T("驱动器可用空间(字节):%I64d\n"),lpTotalNumberOfFreeBytes);}else{_tprintf(_T("错误:%d\n"),GetLastError());}}/*根据盘符取磁盘空间及簇、扇区信息*/void DriveInfo::GetDiskSize(TCHAR *szRootName){DWORD64 diskTotalSize,diskFreeSize,diskUsedSize;DWORD sectorsPerCluster,bytesPerSector,numberOfFreeClusters,totalNumberOfClusters;//GetDiskFreeSpace(根路径,每个簇的扇区数,每个扇区的字节数,空闲簇的个数,总簇数)if(GetDiskFreeSpace(szRootName,§orsPerCluster,&bytesPerSector,&numberOfFreeClusters,&totalNumberOfClusters)){//磁盘总容量=总簇数*每个簇的扇区数*每个扇区的字节数diskTotalSize=(DWORD64)totalNumberOfClusters*sectorsPerCluster*bytesPerSector;//磁盘可用量=空闲簇的个数*每个簇的扇区数*每个扇区的字节数diskFreeSize=(DWORD64)numberOfFreeClusters*sectorsPerCluster*bytesPerSector;//磁盘使用量=磁盘总容量-磁盘可用量diskUsedSize=diskTotalSize-diskFreeSize;_tprintf(_T("驱动器:%s\n"),szRootName);_tprintf(_T("总簇数:%d\n"),totalNumberOfClusters);_tprintf(_T("每簇的扇区数:%d\n"),sectorsPerCluster);_tprintf(_T("每扇区的字节数:%d\n"),bytesPerSector);_tprintf(_T("空闲簇数:%d\n"),numberOfFreeClusters);_tprintf(_T("----------------------------------------------------------------------------\n"));_tprintf(_T("总字节数:%I64d\t大约:%.2lfG\n"),diskTotalSize,diskTotalSize/1024.0/1024.0/1024.0);_tprintf(_T("已使用字节数:%I64d\t大约:%.2lfG\n"),diskUsedSize,diskUsedSize/1024.0/1024.0/1024.0);_tprintf(_T("空闲字节数:%I64d\t空闲空间大约:%.2lfG\n"),diskFreeSize,diskFreeSize/1024.0/1024.0/1024.0);}else{_tprintf(_T("错误:%d\n"),GetLastError());}}