实验十

一、实验目的

(1) 了解磁盘的物理组织。

(2) 熟悉Windows 系统如何查看磁盘相关系数。

(3) 掌握Windows 系统提供的有关对磁盘操作 API。

二、实验准备

磁盘基本物理结构原型:
Typedef struct_DTSK_GEOMETRY {
	LARGE_INTEGER  Cylinders;  	//磁盘的柱面数
	MEDIA_TYPE MediaType;	    //介质类型,如3.5英寸,1.44MB软盘
	DWORD  TracksPerCylinder;  	//每个柱面的磁道数
	DWORD  SectorsPerTrack;	   //每个磁道的扇区数
	DWORD  BytesPerSector;		//每个扇区的字节数
} DISK_GEOMETRY;				
相关API函数:
1.文件创建:

函数CreateFile() 用于打开磁盘驱动器并返回一个文件句柄,这里驱动器被当做文件来处理。

原型:

HANDLE CreateFile(
	LPCTSTE lpFileName,            //指向文件名的指针
	DWORD dwDesiredAccess,         //读/写访问模式
	DWORD dwShareMode,             //共享模式
	LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针
	DWORD dwCreateionaDisposition,      //文件存在标志
	DWORD dwFlagsAndAttributes,        //文件属性
	HANDLE hTemplateFile           //指向访问模板文件的句柄
);
2.获取磁盘的基本信息:

函数DeviceIoControl() 用于获取磁盘的基本信息

原型:

BOOL DeviceIoControl(
	HANDLE hDevice,			//设备句柄,由CreateFile() 函数获得
	DWORD dwIoControlCode,    //操作控制代码
	LPVOID lpInBuffer,           //输入数据缓冲区
	DWORD  nInBufferSize,        //输入数据缓冲区大小
	LPVOID lpOutBuffer,           //输出数据缓冲区
	DWORD nOutBufferSize,         //输出数据缓冲区大小
	LPDWORD lpBytesReturned,      //可获取的字节计数
	LPOVERLAPPED lpOverlapped,     //指向OVERLAPPED结构的指针
); 

​ 表 1 dwIoControlCode 的值

描述
IOCTL_DISK_GET_DRIVE_GEOMETRY得到磁盘物理结构信息
IOCTL_DISK_GET_PARTITION_INFO得到磁盘分区信息
FSCTL_QUERY_FAT_BPB返回FAT16或FAT12卷的前36字节
FSCTL_GET_COMPRESSION获取文件或目录的压缩信息

返回值:

如果函数调用成功,则返回值为非0值。如果函数调用失败,则返回值为0。若要得到更多的错误信息,可调用函数GetLastError()。

三、实验内容

(一)实验内容

编写一个函数,根据给出的驱动器号读取磁盘基本信息,包括键盘的大小、该磁盘包括多少个扇区,该磁盘有多少个柱面,每个柱面的磁道数、每个磁道的扇区数、每个扇区包含的字节数。

(二)主要代码

// Disk_Information.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Disk_Information.h"
#include "winioctl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

DISK_GEOMETRY disk_info;
HANDLE GetDiskInformation(char drivername);
BOOL SectorRead(HANDLE Handle);
BOOL SectorWrite(HANDLE Handle);
/
// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode=0;
	HANDLE Handle;
	Handle=GetDiskInformation('C');
	return nRetCode;
}
HANDLE GetDiskInformation(char drivername)
{
	char device[]="\\\\.\\C:"; 
	device[4]=drivername;
	HANDLE FloopyDisk;
	DWORD ReturnSize;
	DWORD Sector;
	double DiskSize;
	FloopyDisk=CreateFile(device,
		GENERIC_READ|GENERIC_WRITE,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_NO_BUFFERING,
		NULL);
	if(FloopyDisk==INVALID_HANDLE_VALUE)
		printf("INVALID_HANDLE_VALVE!\n");
	if(GetLastError()==ERROR_ALREADY_EXISTS)
		printf("Can not Open Disk!%d\n",GetLastError());
	if (!DeviceIoControl(FloopyDisk,IOCTL_DISK_GET_DRIVE_GEOMETRY,
		NULL,
		0,
		&disk_info,
		50,
		&ReturnSize,
		(LPOVERLAPPED)NULL))
		printf("Open Disk Error!%d\n", GetLastError());
	printf("Disk Information:\n");
	printf("\tBytesPerSector:%d\n",disk_info.BytesPerSector);
	printf("\tSectorPerTrack:%d\n",disk_info.SectorsPerTrack);
	printf("\tTrackPerCylinder:%d\n",disk_info.TracksPerCylinder);
	printf("\tCylinder: %d\n", disk_info.Cylinders);
	Sector= disk_info. Cylinders.QuadPart* disk_info. TracksPerCylinder* disk_info. SectorsPerTrack;
	printf("\tThere is %d Sectors!\n", Sector);
	DiskSize=Sector*disk_info. BytesPerSector;
	printf("\tSize of Disk: %4.2fMB\n",(DiskSize)/(1024*1024));
	return FloopyDisk;
}

四、实验结果与总结

运行结果:
Disk Information:
        BytesPerSector:512
        SectorPerTrack:63
        TrackPerCylinder:255
        Cylinder: 62260
        There is 1000206900 Sectors!
        Size of Disk: 958.28MB
总结:

1.在代码实现过程中,Handle=GetDiskInformation(‘C’);

由于我的电脑只有一个C盘,没有其他盘,所以这里只能查看C盘,其他则会报错。

2.从实验结果可以看出,对给定的磁盘驱动器中的C,本实验能正确识别出它每个扇区有512字节,每个磁道有63个扇区,每个柱面有255个磁道,共有62260个柱面,该盘共有1000206900个磁道,磁盘的大小是958.28MB。

3.应当注意,磁道上有一部分空间是存储磁盘的物理信息的,这部分空间系统是不能够直接存取的,因此没有编入逻辑扇区,也就是说逻辑扇区比磁盘的实际扇区要小,因此计算出的磁盘大小是磁盘可用空间的大小,比磁盘的物理大小要小。

Logo

鸿蒙生态一站式服务平台。

更多推荐