获取磁盘、光盘的柱面扇区相关信息

 

参考:http://bbs.csdn.net/topics/390011646

        http://blog.163.com/maple_zh@126/blog/static/107129598200921072150858/

 

在VC6 XP.sp3中的运行正常的代码:


//
//   两种方式:
//     1   DeviceIoControl读取磁盘扇区
//     2    _getdiskfree显示磁盘扇区信息
//
//  方式切换开关
#define WITH_IOCTL_DISK_GET_DRIVE_GEOMETRY



#ifdef WITH_IOCTL_DISK_GET_DRIVE_GEOMETRY

/*  -------------------------------------------------------------------------- *


*    1   DeviceIoControl读取磁盘扇区

*
* -------------------------------------------------------------------------- 
*/

#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <tchar.h>
#include <winioctl.h>

enum E_DISK_TYPE
{
    eDT_Physicaldrive,
    eDT_CDROM
};

VOID __cdecl _tmain (INT Argc, PTCHAR Argv[])
{
     // E_DISK_TYPE eDiskType = eDT_Physicaldrive;   //   读取磁盘信息
    E_DISK_TYPE eDiskType = eDT_CDROM;           //   读取光盘信息时

    TCHAR szName[MAX_PATH] = {  0 };
    HANDLE hDisk = NULL;
 
     //
    
//  命令行参数可在Project Settings->Debug->Program arguments下指定 如:0 1
    
//
     if (Argc !=  3
    {
        _tprintf(_T( " Reads a sector on the disk\n\n "));
        _tprintf(_T( " %s [disk number] [sector]\n "), Argv[ 0]);
         return;
    }
 
     switch (eDT_CDROM)
    {
     case eDT_Physicaldrive:
        _sntprintf(szName,  sizeof(szName) /  sizeof(szName[ 0]) -  1, _T( " \\\\.\\Physicaldrive%d "), _ttoi(Argv[ 1]));   //   读取磁盘信息时
         break;

     case eDT_CDROM:
        _sntprintf(szName,  sizeof(szName) /  sizeof(szName[ 0]) -  1, _T( " \\\\.\\CDROM%d "), _ttoi(Argv[ 1]));   //   读取光盘信息时
         break;
    }

     //
    
//  打开磁盘
    
//
    hDisk = CreateFile(szName,
                        GENERIC_READ,
                        FILE_SHARE_READ,
                        NULL,
                        OPEN_EXISTING,
                        NULL,
                         0);
     if (hDisk != INVALID_HANDLE_VALUE) 
    {
         //
        
//  磁盘的结构信息存在此结束中。
         /*
        typedef struct _DISK_GEOMETRY 
        {
            LARGE_INTEGER Cylinders;    // 柱面数
            MEDIA_TYPE MediaType;       // 磁盘类型,见MSDN
            DWORD TracksPerCylinder;    // 每道柱面数
            DWORD SectorsPerTrack;      // 每道扇区数
            DWORD BytesPerSector;       // 每扇区字节数
        } DISK_GEOMETRY;
        
*/
        DISK_GEOMETRY diskGeometry;
        DWORD dwBytes =  0;
         //
        
//  获得磁盘结构信息
         if (!DeviceIoControl(hDisk,
                            IOCTL_DISK_GET_DRIVE_GEOMETRY,     //  调用了CTL_CODE macro宏
                            NULL,
                             0,
                            &diskGeometry,
                             sizeof(DISK_GEOMETRY),
                            &dwBytes,
                            NULL))
        {
            _tprintf(_T( " IOCTL_DISK_GET_DRIVE_GEOMETRY failed with error code %d\n "), GetLastError());            
             return;
        }

         //
        
//
        DWORD dwSize = diskGeometry.BytesPerSector;     //  每sector字节数
        PVOID lpBuffer =  new BYTE [dwSize];
         if (lpBuffer == NULL) 
        {
            _tprintf(_T( " Unable to allocate resources, exiting\n "));
             return;
        } 

         //
        
//   关于磁盘分区的信息
        
//
         /*
        typedef struct _PARTITION_INFORMATION
        {
            LARGE_INTEGER StartingOffset;     // 启动分区偏移
            LARGE_INTEGER PartitionLength;    // 分区长度(字节)
            DWORD HiddenSectors;              // 分区中隐藏扇区数
            DWORD PartitionNumber;            // 分区数
            BYTE PartitionType;               // 分区类型
            BOOLEAN BootIndicator;            // 是否为引导分区,TRUE是
            BOOLEAN RecognizedPartition;      // 验证过的分区。TRUE是
            BOOLEAN RewritePartition;         // 分区是否可改变。TRUE
        } PARTITION_INFORMATION, *PPARTITION_INFORMATION;
        
*/
        PARTITION_INFORMATION partitionInfo;
         //
        
//  获得磁盘磁盘分区的信息
         if (DeviceIoControl(hDisk,
                            IOCTL_DISK_GET_PARTITION_INFO,
                            NULL,
                             0,
                            &partitionInfo,
                             sizeof(PARTITION_INFORMATION),
                            &dwBytes,
                            NULL)) 
        {
             switch (eDT_CDROM)
            {
             case eDT_Physicaldrive:
                _tprintf ( _T( " 磁盘空间为 %.2fGB 每扇区 %ld字节 共%ld个扇区\r\n "), 
                                partitionInfo.PartitionLength.QuadPart/ 1024./ 1024./ 1024.     //   磁盘空间
                                , diskGeometry.BytesPerSector                                //   每扇区字节数
                                , partitionInfo.PartitionLength.QuadPart / diskGeometry.BytesPerSector);   //  总扇区数
                 break;

             case eDT_CDROM:
                _tprintf ( _T( " 光盘空间为 %.2fMB 每扇区 %ld字节 共%ld个扇区\r\n "), 
                    partitionInfo.PartitionLength.QuadPart/ 1024./ 1024.           //   光盘空间
                    , diskGeometry.BytesPerSector                                //   每扇区字节数
                    , partitionInfo.PartitionLength.QuadPart / diskGeometry.BytesPerSector);   //  总扇区数

                 break;
            }

             //  获取总扇区数
            LONGLONG sectorCount = partitionInfo.PartitionLength.QuadPart / diskGeometry.BytesPerSector;
             //  以16进制输出
             switch (eDT_CDROM)
            {
             case eDT_Physicaldrive:
                _tprintf(_T( " PhysicalDisk %d has 0x%I64x sectors with 0x%x bytes in every sector\n "), _ttoi(Argv[ 1]), sectorCount, diskGeometry.BytesPerSector);
                 break;
             case eDT_CDROM:
                _tprintf(_T( " CDROM %d has 0x%I64x sectors with 0x%x bytes in every sector\n "), _ttoi(Argv[ 1]), sectorCount, diskGeometry.BytesPerSector);
                 break;
            }
            
             //
            LONGLONG nIndex = _ttoi64(Argv[ 2]);

             //
            
//  读取被请求的sector
            
//
             if (nIndex < sectorCount) 
            {
                 //  有符号的64位整型表示
                LARGE_INTEGER offset;

                 //  sector数所占字节
                offset.QuadPart = (nIndex) * diskGeometry.BytesPerSector;

                 //  从打开的文件(磁盘)中移动文件指针。offset.LowPart低32位为移动字节数
                SetFilePointer(hDisk, offset.LowPart, &offset.HighPart, FILE_BEGIN);

                 //  读取扇区的数据
                 if (ReadFile(hDisk, lpBuffer, dwSize, &dwBytes, NULL)) 
                {
                     //   扇区的数据
                    _tprintf(_T( " 扇区%d数据:\n "), nIndex);

                     //
                    
//  The dwBytes field holds the number of bytes that were actually read [ <= dwSize ]
                    
//
                     for (ULONG nOffset =  0; nOffset < dwBytes; nOffset +=  0x10
                    {
                        ULONG nBytes, nIdx;

                         //
                        
//  显示地址
                        
//
                        _tprintf(_T( " %011I64x  "), (offset.QuadPart) + nOffset);

                         //
                        
//  显示16进制数据
                        
//
                        nBytes = min( 0x10, dwBytes - nOffset);

                         for (nIdx =  0; nIdx < nBytes; nIdx++) 
                        {
                            _tprintf(_T( " %02x %s "), ((PUCHAR)lpBuffer)[nOffset + nIdx], ((nIdx +  1) %  0x8) ? _T( "") : _T( "   "));
                        }

                         for ( ; nIdx <  0x10; nIdx++) 
                        {
                            _tprintf(_T( "  %s "), ((nIdx +  1) %  0x8) ? _T( "") : _T( "   "));
                        }

                         //
                        
//  显示ascii格式数据
                        
//
                         for (nIdx =  0; nIdx < nBytes; nIdx++) 
                        {
                            _tprintf(_T( " %c "), isprint(((PUCHAR)lpBuffer)[nOffset + nIdx]) ? ((PUCHAR)lpBuffer)[nOffset + nIdx] : _T( ' . '));
                        }

                        _tprintf(_T( " \n "));
                    }

                }  //  end ReadFile
                 else
                {
                    _tprintf(_T( " ReadFile() on sector 0x%I64x failed with error code: %d\n "), nIndex, GetLastError());
                }

            }  //  end if (nIndex < sectorCount) 
             else
            {
                _tprintf(_T( " The requested sector is out-of-bounds\n "));
            }

        }  //  end 1 if (DeviceIoControl   
         else
        {
            _tprintf(_T( " IOCTL_DISK_GET_PARTITION_INFO failed with error code %d\n "), GetLastError());
        }


        delete [] lpBuffer;
        CloseHandle(hDisk);
  
    }  //  if (hDisk != INVALID_HANDLE_VALUE) 
     else
    {
        _tprintf(_T( " CreateFile() on %s failed with error code %d\n "), szName, GetLastError());
    }

    _tprintf(_T( " \n "));

     return;
}


#else


/*  -------------------------------------------------------------------------- *


*    2    _getdiskfree显示磁盘扇区信息

*
* -------------------------------------------------------------------------- 
*/

//  crt_getdiskfree.c

#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <tchar.h>

TCHAR   g_szBorder[] = _T( " ======================================================================\n ");
TCHAR   g_szTitle1[] = _T( " |DRIVE|TOTAL CLUSTERS|AVAIL CLUSTERS|SECTORS / CLUSTER|BYTES / SECTOR|\n ");
TCHAR   g_szTitle2[] = _T( " |=====|==============|==============|=================|==============|\n ");
TCHAR   g_szLine[]   = _T( " |  A: |              |              |                 |              |\n ");

void utoiRightJustified(TCHAR* szLeft, TCHAR* szRight, unsigned uVal);

int main( int argc,  char* argv[]) 
{
    TCHAR szMsg[ 4200];
     struct _diskfree_t df = { 0};
    ULONG uDriveMask = _getdrives();    //  表示当前可用的磁盘
    unsigned uErr, uLen, uDrive;
 
    printf(g_szBorder);
    printf(g_szTitle1);
    printf(g_szTitle2);
 
     int ifor =  0;
     for (uDrive= 1; uDrive<= 26; ++uDrive) 
    {
         if (uDriveMask &  1
        {
            uErr = _getdiskfree(uDrive, &df);
            memcpy(szMsg, g_szLine,  sizeof(g_szLine));
            szMsg[ 3] = uDrive +  ' A ' -  1;
             char lp[ 5] =  " C:\\ ";
            lp[ 0] = uDrive +  ' A ' -  1;
  
             if (uErr ==  0
            {
                utoiRightJustified(szMsg+ 8,  szMsg+ 19, df.total_clusters);
                utoiRightJustified(szMsg+ 23, szMsg+ 34, df.avail_clusters);
                utoiRightJustified(szMsg+ 38, szMsg+ 52, df.sectors_per_cluster);
                utoiRightJustified(szMsg+ 56, szMsg+ 67, df.bytes_per_sector);

                ifor ++;
            }
             else 
            {
                uLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, uErr,  0, szMsg+ 84100, NULL);
                szMsg[uLen+ 6] =  '   ';
                szMsg[uLen+ 7] =  '   ';
                szMsg[uLen+ 8] =  '   ';
                ifor ++;
            }
   
            printf(szMsg);
        }
  
         uDriveMask >>=  1;

          if (!uDriveMask)   break;
    }
 
    printf(g_szBorder);
    printf ( " 共%d个\n ", ifor);
     return  0;
}

void utoiRightJustified(TCHAR* szLeft, TCHAR* szRight, unsigned uVal) 
{
    TCHAR* szCur = szRight;
     int nComma =  0;
 
     if (uVal) 
    {
         while (uVal && (szCur >= szLeft)) 
        {
             if (nComma ==  3
            {
                *szCur =  ' , ';
                nComma =  0;
            }
             else 
            {
                *szCur = (uVal %  10) |  0x30;
                uVal /=  10;
                ++nComma;
            }
   
            --szCur;
        }
    }
     else 
    {
        *szCur =  ' 0 ';
        --szCur;
    }
 
     if (uVal) 
    {
        szCur = szLeft;
  
         while (szCur <= szRight) 
        {
            *szCur =  ' * ';
            ++szCur;
        }
    }
}

#endif 

 

 

你可能感兴趣的:(获取)