zoukankan      html  css  js  c++  java
  • 获取磁盘、光盘的柱面扇区相关信息

     

    参考: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 "));
            _tprintf(_T("%s [disk number] [sector] "), 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 "), GetLastError());            
                return;
            }

            //
            
    //
            DWORD dwSize = diskGeometry.BytesPerSector;    // 每sector字节数
            PVOID lpBuffer = new BYTE [dwSize];
            if (lpBuffer == NULL) 
            {
                _tprintf(_T("Unable to allocate resources, exiting "));
                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个扇区 "), 
                                    partitionInfo.PartitionLength.QuadPart/1024./1024./1024.    //  磁盘空间
                                    , diskGeometry.BytesPerSector                               //  每扇区字节数
                                    , partitionInfo.PartitionLength.QuadPart / diskGeometry.BytesPerSector);  // 总扇区数
                    break;

                case eDT_CDROM:
                    _tprintf ( _T("光盘空间为 %.2fMB 每扇区 %ld字节 共%ld个扇区 "), 
                        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 "), _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 "), _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数据: "), 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(" "));
                        }

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

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

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


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

        _tprintf(_T(" "));

        return;
    }


    #else


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


    *    2    _getdiskfree显示磁盘扇区信息

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

    // crt_getdiskfree.c

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

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

    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个 ", 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 

  • 相关阅读:
    Oracle学习笔记:在ubuntu 8.10 Sever上 安装oracle10g,真真正正简简单单的解决‘utilities ctx_on‘错误
    Oracle学习笔记:oracle服务在linux平台的启动问题
    非常酷的 Javascript 简单调试工具Blackbird
    【转】Smashing Magazine CSS3 设计赛获奖作品
    Windows7 IIS7下以FastCgi和ISAPI方法安装配置PHP5教程
    推荐60多个CSS GALLERY画廊网站
    【转】2010全球最值得模仿的230个网站
    Godaddy免费空间WordPress使用记录
    【转】浅谈大型网站动态应用系统架构
    你可能不知道的10个JavaScript小技巧
  • 原文地址:https://www.cnblogs.com/ant-wjf/p/3432865.html
Copyright © 2011-2022 走看看