Operating system experiment 11: read / write the specified location information of the disk (just complete the reading)

Experiment 11: read / write the specified location information of the disk (just complete the reading)

1, Experimental purpose

(1) Knowledge of Disk Physics.

(2) Master the API for disk operation provided by Windows system.

(3) Read / write the specified sector according to the entered sector number.

2, Experimental preparation knowledge: introduction to relevant API functions

1. Set the position of read / write operation

The function SetFilePointer() is used to move the read / write pointer in an open file. Here, the disk device is treated as a file, so it is used to move the position of the file read / write pointer on the disk.

Prototype:

DWORD SetFilePointer(

HANDLE hFile,

LONG lpdistanceToMove,

PLONG lpDistanceToMoveHigh,

DWORD dwMoveMethod

);

Parameter Description:

hFile: open file handle. The created file must have GENERIC_READ or generic_ Access to write.

lpDistanceToMove: the lower 32 bits of the offset of the pointer to be moved. It is used to specify the byte size of the file pointer to be moved. If the parameter lpDistanceToMoveHigh is not empty, the two parameters lpDistanceToMoveHigh and lpDistanceToMove form a 64 bit value to specify the location of the move. If the parameter lpDistanceToMoveHigh is null, lpDistanceToMove is a 32-bit signed value. When lpDistanceToMove is positive, the file pointer moves forward, otherwise it moves backward.

lpDistanceToMoveHigh: 32 bits high of the offset to be moved by the pointer. If you do not need this parameter, you can set it to null. When the parameter is not null, the parameter is the DWORD type value of the upper 32 bits of the file pointer.

dwMoveMethod: the initial position where the file pointer moves, and its value is shown in table 5-2.

Value of dwMoveMethod

value describe
FILE_BEGIN The starting point is 0 or the starting position of the file
FILE_CURRENT The starting point is the current position of the file pointer
FILE_END The starting point is the end of the file

Return value:

If the function call succeeds and the parameter lpdistancetomovehigh is null, the return value is the low 32-bit DWORD type value of the file pointer. If the parameter lpdistancetomovehigh is not null, the return value is the low 32-bit DWORD type value of the file pointer, and the high 32-bit DWORD type value is output to a long type parameter.

If the function call fails, and the parameter lpdistanceToMoveHigh is not empty, the return value is 0xfffffff. To get the error information, call the function GetLastError(). If the function call fails and the parameter lpdistanceToMoveHigh is not empty, the return value is 0xfffffff. However, since 0xfffffff is not a valid low 32-bit DWORD type value, you must call the function GetLastError() to determine whether an error has occurred. If an error occurs, the function GetLastError() returns the error value, NO_ERROR, otherwise return.

If the new file pointer position is a negative value, it indicates that the function call fails and the file pointer will not move. The value returned by calling the function GetLastError() is ERROR_NEGATIVE_SEEK.

2. Reading documents

Read the contents of the specified area of the disk.

Prototype:

BOOL ReadFile(

    HANDLE hFile,                //Handle to the file to be read

    LPVOID lpBuffer,              //Pointer to file buffer

    DWORD nNumberOfBytesToRead,       //The number of bytes to read from the file

    LPDWORD lpNumberOfBytesRead,      //Pointer to the number of bytes to read from the file

    LPOVERLAPPED lpOverlapped	//Pointer to OVERLAPPED structure
);

3. Write documents

This function writes data to the specified area of the disk.

Prototype:

BOOL ReadFile(

    HANDLE hFile,                //Handle to the file to be read

    LPVOID lpBuffer,              //Pointer to file buffer

    DWORD nNumberOfBytesToWrite,      //The number of bytes to read from the file

    LPDWORD lpNumberOfBytesWritten,     //Pointer to the number of bytes to read from the file

    LPOVERLAPPED lpOverlapped	//Pointer to OVERLAPPED structure

);

3, Experimental content

(1) Experimental content

Write two functions to complete the following functions respectively.

1. Read the content of the given sector pair.

2. Write the data entered by the user into the specified sector.

In the main program, let the user select R, w or Q. if the user selects R, call the function bool sectorread (handle) to complete the function of reading the given sector; If the user selects W, call the function bool sectorwrite (handle) to complete the function of writing information to the given sector number; If the user selects Q, the program exits.

(2) Main code

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

4, Experimental results and summary

In the experiment, the application first displays the information of the floppy disk.

Disk Information:

BytestPerSector:512

SectorPerTrack:18

TrackPerCylinder:2

Cylinder:80

There is 2880 Sectors!

Size of Disk:1.41 KB

Then prompt the user to select "Please Select Read Or Write! Input 'R' to read, 'W' to Write, 'Q' to quit!" When the user enters w to Write the floppy disk, the application prompts the user "Please Input the Select Number to Write to:" to input the track number to Write. When the user enters 4 to Write the fourth track, the application prompts the user "Please Input the Content to Write to Disk A::" to input the content of the fourth track to Write. When the user enters the content to Write, the application prompts "Write Complete!" Indicates that the write operation is complete.

Next, the application continues to prompt the user to select "please select read or write! Input 'R' to read, 'W' to Write, 'Q' to quit!" When the user enters r to read the floppy disk, the application prompts the user "Please input the Sector Number to Read to:" to enter the disk number to read. When the user enters 4 to read the Content of the fourth track, the application displays "Content:" and displays the Content of the fourth track on the floppy disk in character form and hexadecimal form respectively.

Tags: C++ Operating System

Posted by floR on Wed, 25 May 2022 06:36:39 +0300