操作系统 实验十一:读/写磁盘指定位置信息(只需完成读取)

实验十一:读/写磁盘指定位置信息(只需完成读取)

一、实验目的

(1)了解磁盘的物理知识。

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

(3)根据输入的扇区号读/写指定扇区。

二、实验准备知识:相关API函数介绍

1.设置读/写操作的位置

函数SetFilePointer()用于移动一个打开文件中的读/写指针,这里磁盘设备被当作文件处理,因此用于移动文件读/写指针在磁盘上的位置。

原型:

DWORD SetFilePointer(

HANDLE hFile,

LONG lpdistanceToMove,

PLONG lpDistanceToMoveHigh,

DWORD dwMoveMethod

);

参数说明:

hFile:打开的文件句柄,创建的文件必须具有GENERIC_READ或GENERIC_WRITE的存取权限。

lpDistanceToMove:指针要移动的偏移量的低32位,用于指定移动文件指针的字节大小。如果参数lpDistanceToMoveHigh不为空,lpDistanceToMoveHigh和lpDistanceToMove两个参数形成一个64位的值来指定移动的位置。如果参数lpDistanceToMoveHigh为空,lpDistanceToMove是一个32位带符号值,当lpDistanceToMove为正值时,文件指针向前移动,否则向后移动。

lpDistanceToMoveHigh:指针要移动的偏移量的高32位。如果不需要该参数,可以将其设置为空。当该参数不为空时,该参数为文件指针的高32位的DWORD类型值。

dwMoveMethod:文件指针移动的初始位置,其值如表5—2所示。

dwMoveMethod的值

描述
FILE_BEGIN开始点为0或者为文件的开始位置
FILE_CURRENT开始点为文件指针的当前位置
FILE_END开始点为文件的结尾位置

返回值:

如果函数调用成功,而且参数lpDistanceToMoveHigh为空,返回值为文件指针的低32位DWORD类型值。如果参数lpdistanceToMoveHigh不为空,返回值为文件指针的低32位DWORD类型值,并且高32位DWORD类型值输出到一个long类型的参数中。

如果函数调用失败,而且参数lpdistanceToMoveHigh不为空,返回值为0XFFFFFFFF,若要得到错误信息,请调用函数GetLastError()。如果函数调用失败,而且参数lpdistanceToMoveHigh不为空,返回值为0XFFFFFFFF,但由于0XFFFFFFFF不是一个有效的低32位DWORD类型值,必须通过调用函数GetLastError()才能判断是否有错误发生。若发生错误,则函数GetLastError()返回错误值,NO_ERROR否则返回。

如果新的文件指针位置是一个负值,则表明函数调用失败,文件指针将不移动,通过调用函数GetLastError()返回的值是ERROR_NEGATIVE_SEEK。

2.读文件

读取磁盘指定区域的内容。

原型:

BOOL ReadFile(

    HANDLE hFile,                //要读的文件的句柄

    LPVOID lpBuffer,              //指向文件缓冲区的指针

    DWORD nNumberOfBytesToRead,       //从文件中要读取的字节数

    LPDWORD lpNumberOfBytesRead,      //指向从文件中要读取的字节数的指针

    LPOVERLAPPED lpOverlapped	//指向OVERLAPPED结构的指针;

3.写文件

该函数将数据写入磁盘指定区域。

原型:

BOOL ReadFile(

    HANDLE hFile,                //要读的文件的句柄

    LPVOID lpBuffer,              //指向文件缓冲区的指针

    DWORD nNumberOfBytesToWrite,      //从文件中要读取的字节数

    LPDWORD lpNumberOfBytesWritten,     //指向从文件中要读取的字节数的指针

    LPOVERLAPPED lpOverlapped	//指向OVERLAPPED结构的指针

);

三、实验内容

(一) 实验内容

编写两个函数,分别完成如下功能。

1.对给定的扇区号读取该扇区的内容。

2.将用户输入的数据写入指定的扇区。

在主程序中让用户选择:R、W或Q,若用户选择R,则调用函数BOOL SectorRead(HANDLE Handle),完成读给定扇区的功能;若用户选择W则调用函数BOOL SectorWrite(HANDLE Handle)完成对给定扇区号写入信息的功能;若用户选择Q,则程序退出。

(二) 主要代码
//Disk_Inforamtion_Read and Write.cpp:Defines the entry ponit for the console application.
//
#include “stdafx.h”
#include “Disk_Inforamtion_Get.h”
#include “winioctl.h”

#ifdef_DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
#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;
	char Choise;
	Handle=GetDiskInformation('A');

	While(TRUE)
	{
		printf("please Select Read or Write! Input ‘R’ to read ,’W’ to write,’Q’ to quit!\n");
		Choice=getchar();
		printf("\n");
		switch(Choice)
		{
			case 'W'
			{
				if (!SectorWrite(Handle))
                    printf("Write Sector Fail!\n");
				Getchar();
				Break;
			}
            case 'R'
            {
                if(!SectorRead(Hadle))   
                    printf("Read Sector Fail!\n");
                getchar();
                break;
            }
            case 'Q'
            {
                exit(0);
                break;
            }
            default:
            {
                printf("Input Error!,Try again please!\n");
                getchar();
            }

	}
	return nRetCode;
}
HANNDLE GetDiskInformation(char drivername)
{
  char device[]="\\\\.\\:";
  device[4]=drivername;
  HANDLE FloopyDisk;
  DWORD ReturnSize;
  DWIRD 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_VALUE!");
  if(GetLastError()==ERROR_ALREADY_ETISTS)
   printf("Cannot Open Disk! %d\n",GetLastError());
  if(!DeviceIoControl(FloopyDisk,IOCTL_DISK_GET_DRIVE_CEOMETRY,NULL,0,&disk_info,50,&ReturnSize,(LPOVERLAPPED)NULL))
      printf("Open Disk Error! %d\n",GetLastError());
      printf("Disk Information: \n");
      printf("\t  BytesPerSector:  %d\n",disk_info.BytesPerSector);
      printf("\t  SectorPerTrack:  %d\n",disk_info.SectorPerTrack);
      printf("\t  TracksPerCylinder:  %d\n",disk_info.TracksPerCylinder);
      printf("\t  Cylinder:  %d\n",disk_info.Cylinders);
Sector=disk_ionfo.Cylinders.QuadPart *disk_info.TrackPerCylinder *disk_info.SectorPerTrack;
  printf("\t There is %d Sectors! \n",Sector);
  DiskSize=Sector *disk_info.BytesPerSector;
  printf("\t Size of Disk: %4.2f KB\n",(DiskSize)/(1024*1024));
  return FloopyDisk;

}
BOOL SectorRead(HANDLE Handle)
{
  char ReadBuffer[1024*16];
  DWORD SectorNumber;
  DWORD BytestoRead;
  DWORD Sector;
  DWORD rc;
  int i;
  if (Handle==NULL)
    {
      printf ("there is No disk!\n");
      return FALSE;
     }

  printf ("Please Input the Sector Number to Read From:\n");
  Scanf("%d",&SectorNumber);
  printf ("\n");
  Sector =disk_info.Cylinder.QuadPart* Disk_info.TacksCylinder* Disk-info.SectorPerTrack;
  if(SectorNumber>Sector) 
      printf("there is not this Sector!");
  printf ("Content:\n");
  BytestoRead=SectorNumber*(disk_info.BytesPerSector);
  rc=SetFilePointer(Handle,BytestoRead,NULL,FILE_BEGIN);
  if (!ReadFile(Handle,ReadBuffer,BytestoRead,&BytestoRead,NULL))
    {
      printf("Read File Error:%d\n",GetLastError());
      return FALSE;
    }
  printf(“\t Text Content:\n”);
  for (i=0;i<512;i++)
    { 
      printf("%c",ReadBuffer[i]);
    }
   printf("\n");
   printf("\t  Hex Text Content: \n");
   for (i=0;i<512;i++)
     {
       printf("%x",ReadBuffer[i]);
       printf(" ");
	}
    printf("\n");
    return TRUE;
}
// 11.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "11.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;
	char Choice;
	Handle=GetDiskInformation('C');
	while(TRUE)
	{
		printf("please select Read or Write!Input 'R' to read,'Q' to quit!\n");
		Choice=getchar();
		printf("\n");
		switch(Choice)
		{
			
			case 'R':
			{
				if(!SectorRead(Handle))
					printf("Read Sector Fail!\n");
				getchar();
				break;
			}
			case 'Q':
			{
				exit(0);
				break;
			}
			default:
			{
				printf("Input Error!Try again please!\n");
				getchar();
			}
		}
	}

	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;
}

BOOL SectorRead(HANDLE Handle)
{
	char ReadBuffer[1024*16];
	DWORD SectorNumber;
	DWORD BytestoRead;
	DWORD Sector;
	DWORD rc;
	int i;
	if (Handle==NULL)
	{
	  printf ("There is No disk!\n");
	  return FALSE;
	}

	printf ("Please Input the Sector Number to Read From:\n");
	scanf("%d",&SectorNumber);
	printf ("\n");
	Sector =disk_info.Cylinders.QuadPart*
		disk_info.TracksPerCylinder*
		disk_info.SectorsPerTrack;
	if (SectorNumber>Sector) 
		printf("There is not this Sector !");
	printf("Content:\n");
	BytestoRead=SectorNumber*(disk_info.BytesPerSector);
	rc=SetFilePointer(Handle,BytestoRead,NULL,FILE_BEGIN);
	if (!ReadFile(Handle,ReadBuffer,BytestoRead,&BytestoRead,NULL))
	{
	  printf("Read File Error:%d\n",GetLastError());
	  return FALSE;
	}
	printf("\t Text Content:\n");
	for (i=0;i<512;i++)
	{ 
	  printf("%c",ReadBuffer[i]);
	}
	printf("\n");
	printf("\t  Hex Text Content: \n");
	for (i=0;i<512;i++)
	{
	  printf("%x",ReadBuffer[i]);
	  printf(" ");
	}
	printf("\n");
	return TRUE;
}

四、实验结果与总结

image

image

在实验中,应用程序首先显示软盘的信息。

Disk Information:

BytestPerSector:512

SectorPerTrack:18

TrackPerCylinder:2

Cylinder:80

There is 2880 Sectors!

Size of Disk:1.41 KB

然后提示用户进行选择“Please Select Read Or Write! Input ‘R’ to read,’W’ to Write,’Q’ to quit!”当用户输入W表示要写软盘后,应用程序提示用户“Please Input the Select Number to Write to :”输入要写的磁道号,当用户输入4表示要写第4道后,应用程序提示用户“Please Input the Content to Write to Disk A::”输入要写入的第4道的内容,当用户输入要写入的内容后,应用程序提示“Write Complete!”表示写操作完成。

接着,应用程序继续提示用户进行选择“Please Select Read or Write ! Input ‘R’ to read ,’W’ to Write,’Q’ to quit!”当用户输入R表示要读软盘后,应用程序提示用户“Please input the Sector Number to Read to:”输入要读的磁盘号,当用户输入4表示要读第4个道的内容,应用程序显示“Content:”后分别以字符形式和十六进制形式显示软盘上第4道的内容。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值