描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302489108丛书名: 21世纪高等学校计算机专业核心课程规划教材
操作系统课程的实验环节一直是操作系统教学的难点,本书设计了Windows和Linux两个操作系统、C和Java两种计算机语言的实验供读者选择和参考,提供一些编程实例,以此加深学生对操作系统原理的领会和对操作系统方法的理解,并且使学生在程序设计方面得到基本训练。
课程指导方面,本书对操作系统课程所涉及的基本概念、基本理论等知识点进行学习指导,对重点知识点配有典型例题分析,并设计了一些自测题供学生进行自我学习测试。
本书的使用对象是开设操作系统课程的相关专业的本科生、具有一些操作系统基本知识并想进一步了解操作系统内部编程的读者。本书可作为普通高等院校操作系统实验指导书和复习参考资料。
目录
篇Windows系统下C实验指导
第1章Visual C 开发环境介绍
1.1Visual C 概述
1.1.1Visual C 简介
1.1.2Visual C 6.0的主要特性
1.1.3Visual C 6.0的窗口
1.2Visual C 6.0控制台程序
1.2.1Visual C 6.0控制台程序的建立
1.2.2Visual C 6.0工程的文件组成
1.3MSDN概述
1.3.1MSDN简介
1.3.2MSDN使用
第2章Windows的进程管理
2.1实验一: 线程的创建与撤销
2.1.1实验目的
2.1.2实验准备知识: 相关API函数介绍
2.1.3实验内容
2.1.4实验要求
2.1.5实验指导
2.1.6实验总结
2.1.7源程序
2.1.8实验展望
2.2实验二: 线程的同步
2.2.1实验目的
2.2.2实验准备知识: 相关API函数介绍
2.2.3实验内容
2.2.4实验要求
2.2.5实验指导
2.2.6实验总结
2.2.7源程序
2.2.8实验展望
2.3实验三: 线程的互斥
2.3.1实验目的
2.3.2实验准备知识: 相关API函数介绍
2.3.3实验内容
2.3.4实验要求
2.3.5实验指导
2.3.6实验总结
2.3.7源程序
2.3.8实验展望
2.4实验四: 使用命名管道实现进程通信
2.4.1实验目的
2.4.2实验准备知识: 相关API函数介绍
2.4.3实验内容
2.4.4实验要求
2.4.5实验指导
2.4.6实验总结
2.4.7源程序
2.4.8实验展望
目录
计算机操作系统实验指导(第3版)
第3章Windows的内存管理
3.1实验一: 动态链接库的建立与调用
3.1.1实验目的
3.1.2实验准备知识: 动态链接库介绍
3.1.3实验内容
3.1.4实验要求
3.1.5实验指导
3.1.6实验总结
3.1.7源程序
3.1.8实验展望
3.2实验二: 系统内存使用统计
3.2.1实验目的
3.2.2实验准备知识: 相关数据结构及API函数介绍
3.2.3实验内容
3.2.4实验要求
3.2.5实验指导
3.2.6实验总结
3.2.7源程序
3.2.8实验展望
第4章Windows的文件管理
4.1实验一: 采用无缓冲方式实现文件读/写
4.1.1实验目的
4.1.2实验准备知识: 相关API函数介绍
4.1.3实验内容
4.1.4实验要求
4.1.5实验指导
4.1.6实验总结
4.1.7源程序
4.2实验二: 采用高速缓存实现文件读/写
4.2.1实验目的
4.2.2实验准备知识: 高速缓存
4.2.3实验内容
4.2.4实验要求
4.2.5实验指导
4.2.6实验总结
4.2.7源程序
4.3实验三: 采用异步方式实现文件读/写
4.3.1实验目的
4.3.2实验准备知识: 文件异步传输及相关API函数介绍
4.3.3实验内容
4.3.4实验要求
4.3.5实验指导
4.3.6实验总结
4.3.7源程序
4.4实验四: 实现文件读/写的3种方式比较
4.4.1实验目的
4.4.2实验准备知识: 相关API函数介绍
4.4.3实验内容
4.4.4实验要求
4.4.5实验指导
4.4.6实验总结
4.4.7源程序
4.4.8实验展望
第5章Windows的设备管理
5.1实验一: 获取磁盘基本信息
5.1.1实验目的
5.1.2实验准备知识: 相关数据结构及API函数介绍
5.1.3实验内容
5.1.4实验要求
5.1.5实验指导
5.1.6实验总结
5.1.7源程序
5.2实验二: 读/写磁盘指定位置信息
5.2.1实验目的
5.2.2实验准备知识: 相关API函数介绍
5.2.3实验内容
5.2.4实验要求
5.2.5实验指导
5.2.6实验总结
5.2.7源程序
5.2.8实验展望
第二篇Windows系统下Java实验指导
第6章Java语言概述
6.1Java的产生
6.2Java的特点
6.3Java的现状与前景
6.4Java的体系结构
6.5Java的运行环境及配置
第7章进程管理
7.1实验一: 线程的创建与撤销(Java)
7.1.1实验目的
7.1.2实验准备知识
7.1.3实验内容
7.1.4实验要求
7.1.5实验指导
7.1.6实验总结
7.1.7源程序
7.2实验二: 线程的同步(Java)
7.2.1实验目的
7.2.2实验准备知识
7.2.3实验内容
7.2.4实验要求
7.2.5实验指导
7.2.6实验总结
7.2.7源程序
7.3实验三: 线程的互斥(Java)
7.3.1实验目的
7.3.2实验准备知识
7.3.3实验内容
7.3.4实验要求
7.3.5实验指导
7.3.6实验总结
7.3.7源程序
第8章内存管理
8.1实验一: 动态链接库的建立与调用(Java)
8.1.1实验目的
8.1.2实验准备知识
8.1.3实验内容
8.1.4实验要求
8.1.5实验指导
8.1.6实验总结
8.1.7源程序
8.2实验二: 系统内存使用统计(Java)
8.2.1实验目的
8.2.2实验准备知识: 相关数据结构以及类和接口
8.2.3实验内容
8.2.4实验要求
8.2.5实验指导
8.2.6实验总结
8.2.7源程序
第9章文件管理(Java)
9.1实验: 文件管理与IO流(Java)
9.1.1实验目的
9.1.2实验准备知识
9.1.3实验内容
9.1.4实验要求
9.1.5实验指导
9.1.6实验总结
9.1.7源程序
第三篇Linux系统实验指导
第10章Linux系统的安装和使用
10.1安装CentOS 7
10.1.1实验目的
10.1.2实验内容和步骤
10.2Linux系统的基本操作
10.2.1实验目的
10.2.2实验内容和步骤
10.3常用的Linux命令
10.3.1实验目的
10.3.2实验准备知识: 常用的Linux命令
10.3.3实验内容和步骤
10.4vi的使用
10.4.1实验目的
10.4.2实验准备知识
10.4.3实验内容和步骤
10.5Linux的编辑器gcc
10.5.1实验目的
10.5.2实验准备知识
10.5.3实验内容和步骤
10.6Shell程序设计
10.6.1实验目的
10.6.2实验准备知识
10.6.3实验内容和步骤
第11章Linux的进程管理
11.1实验目的
11.2实验准备知识
11.2.1进程控制的API
11.2.2进程之间通信的API
11.3实验内容
11.3.1编制实现软中断通信的程序
11.3.2编制实现管道通信的程序
11.4实验指导
11.4.1软中断通信算法流程图
11.4.2管道通信算法流程图
11.5实验总结
11.5.1软中断通信的运行
11.5.2管道通信的运行
11.6源程序
11.6.1软中断通信的源程序
11.6.2管道通信的源程序
第12章Linux的存储器管理
12.1实验目的
12.2实验准备知识
12.2.1实时监控内存使用情况
12.2.2使用Linux命令回收内存
12.2.3虚拟内存实现的机制
12.3实验内容
12.3.1内存的监控、检查和回收
12.3.2模拟FIFO、LRU和OPT页面置换算法
12.4实验指导
12.4.1FIFO
12.4.2LRU
12.4.3OPT
12.5实验总结
12.6源程序
第13章Linux的设备管理
13.1实验目的
13.2实验准备知识
13.2.1设备驱动程序简介
13.2.2设备驱动程序与外部接口
13.2.3设备驱动程序的组织结构
13.3实验内容
13.3.1字符类型设备的驱动程序
13.3.2块类型设备的驱动程序
13.4实验指导
13.4.1字符类型设备的驱动程序
13.4.2块类型设备的驱动程序
13.5实验总结
13.6源程序
13.6.1字符设备驱动程序
13.6.2块设备驱动程序
第14章Linux的文件管理
14.1实验目的
14.2实验准备知识
14.2.1文件结构
14.2.2目录管理
14.2.3Linux的EXT4文件系统
14.2.4相关函数
14.3实验内容
14.3.1设计并实现一个文件执行程序
14.3.2设计并实现一个一级文件系统程序
14.4实验指导
14.5实验总结
14.6源程序
14.6.1设计并实现一个文件执行程序
14.6.2设计并实现一个一级文件系统程序
第15章Linux内核编译
15.1实验目的
15.2实验准备知识
15.2.1内核简介
15.2.2内核编译涉及的相关命令和术语
15.3实验内容
15.4实验指导
15.5实验总结
第四篇操作系统学习指导和习题解析
第16章操作系统概述
16.1知识点学习指导
16.1.1操作系统的定义
16.1.2操作系统的产生和发展
16.1.3操作系统的特征
16.1.4操作系统的功能
16.1.5操作系统的类型
16.2典型例题分析
16.3自测题
16.4自测题答案
16.5作业
第17章进程与线程
17.1知识点学习指导
17.1.1进程的引入
17.1.2进程的状态及其组成
17.1.3进程控制
17.1.4线程
17.2典型例题分析
17.3自测题
17.4自测题答案
17.5作业
第18章进程同步与通信
18.1知识点学习指导
18.1.1进程同步与互斥
18.1.2经典进程同步问题
18.1.3AND信号量
18.1.4管程
18.1.5进程通信
18.2典型例题分析
18.3自测题
18.4自测题答案
18.5作业
第19章调度与死锁
19.1知识点学习指导
19.1.1调度类型与准则
19.1.2调度算法
19.1.3死锁的基本概念
19.1.4死锁的预防与避免
19.1.5死锁的检测与解除
19.2典型例题分析
19.3自测题
19.4自测题答案
19.5作业
第20章存储管理
20.1知识点学习指导
20.1.1程序的装入与链接
20.1.2连续分配存储管理
20.1.3页式存储管理
20.1.4段式存储管理
20.1.5段页式存储管理
20.2典型例题分析
20.3自测题
20.4自测题答案
20.5作业
第21章虚拟存储管理
21.1知识点学习指导
21.1.1虚拟存储器的引入
21.1.2请求页式存储管理
21.1.3请求段式存储管理
21.1.4段式存储管理与页式存储管理的比较
21.2典型例题分析
21.3自测题
21.4自测题答案
21.5作业
第22章设备管理
22.1知识点学习指导
22.1.1I/O管理概述
22.1.2I/O控制方式
22.1.3I/O系统
22.1.4磁盘管理
22.1.5缓冲管理
22.2典型例题分析
22.3自测题
22.4自测题答案
22.5作业
第23章文件管理
23.1知识点学习指导
23.1.1文件和文件系统
23.1.2文件的结构
23.1.3目录
23.1.4文件存储空间的管理
23.1.5文件存取控制
23.2典型例题分析
23.3自测题
23.4自测题答案
23.5作业
附录A试卷样例
附录A.1试卷A
附录A.2试卷A答案
附录A.3试卷B
附录A.4试卷B答案
参考文献
随着互联网技术的不断发展,Java的市场需求不断增加,Java的面向对象及跨平台特性,使得Java成为互联网应用程序开发的主要程序语言,目前Java在编程语言中占据主导地位。本书第3版主要根据计算机的发展和读者要求增加了Java语言实验; 对Linux实验部分进行了升级,增加了Linux 发行版介绍,将Red Hat Linux 9.0改为目前更流行的发行版CentOS 7,补充了一些Shell常用命令介绍; 另外还增加了一些习题,附录中有两份试卷及答案,供教师和学生参考使用。本书篇由郁红英编写,第二篇由王宁宁编写,第三篇由李春强、赵晓永、武磊、郁红英编写,第四篇由郁红英、刘亚辉编写,郁红英负责全书的统稿。另外,冯庚豹、冯琎参加了本书部分程序的编写和调试工作,在此表示感谢。作者深知水平有限,书中难免有错误和不足之处,恳请同行和广大读者,特别是使用本书的教师和学生多提宝贵意见。
作者2017年10月
Windows的设备管理
5.1实验一: 获取磁盘基本信息5.1.1实验目的
(1) 了解磁盘的物理组织。(2) 熟悉Windows系统如何查看磁盘相关参数。(3) 掌握Windows系统提供的有关对磁盘操作API函数。5.1.2实验准备知识: 相关数据结构及API函数介绍1. 相关系统数据结构说明磁盘基本物理结构原型:
typedef struct_DISK_GEOMETRY {
LARGE_INTEGERCylinders;
MEDIA_TYPEMediaType;
DWORDTracksPerCylinder;
DWORDSectorsPerTrack;
DWORDBytesPerSector;
} DISK_GEOMETRY;
成员说明: (1) Cylinders: 磁盘的柱面数。(2) MediaType: 介质类型,如3.5英寸、1.44MB软盘。(3) TracksPerCylinder: 每个柱面的磁道数。 (4) SectorsPerTrack: 每个磁道的扇区数。 (5) BytesPerSector: 每个扇区的字节数。 2. 相关API函数介绍(1) 文件创建。函数CreateFile()用于打开磁盘驱动器并返回一个文件句柄,这里驱动器被当作文件来处理。有关文件操作函数的详细说明参见4.1.2节。原型:
HANDLE CreateFile(
LPCTSTR lpFileName,//指向文件名的指针
DWORD dwDesiredAccess, //读/写访问模式
DWORD dwShareMode, //共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针
DWORD dwCreationDisposition,//文件存在标志
DWORD dwFlagsAndAttributes,//文件属性
HANDLE hTemplateFile //指向访问模板文件的句柄
);
(2) 获取磁盘的基本信息。函数DeviceIoControl ()用于获取磁盘的基本信息。原型:
BOOL DeviceIoControl(
HANDLE hDevice, //设备句柄
DWORD dwIoControlCode, //操作控制代码
LPVOID lpInBuffer,//输入数据缓冲区
DWORD nInBufferSize,//输入数据缓冲区大小
LPVOID lpOutBuffer, //输出数据缓冲区
DWORD nOutBufferSize,//输出数据缓冲区大小
LPDWORD lpBytesReturned,//可获取的字节计数
LPOVERLAPPED lpOverlapped//指向OVERLAPPED结构的指针
);
参数说明: ① hDevice: 目标设备的句柄,由CreateFile()函数获得。② dwIoControlCode: 指定操作的控制信息,用该值可以辨别将要执行的操作,以及对哪类设备进行操作。该参数取值如表51所示。
表51dwIoControlCode的值
值描述
IOCTL_DISK_GET_DRIVE_GEOMETRY 得到磁盘物理结构信息IOCTL_DISK_GET_PARTITION_INFO 得到磁盘分区信息FSCTL_QUERY_FAT_BPB返回FAT16或FAT12卷的前36字节FSCTL_GET_COMPRESSION获取文件或目录的压缩信息
③ lpInBuffer: 指向一个缓冲区,该缓冲区存放指定操作所输入的数据。④ nInBufferSize: 由lpInBuffer所指缓冲区的大小。⑤ lpOutBuffer: 指向一个缓冲区,该缓冲区存放指定操作所输出的数据。⑥ nOutBufferSize: 由lpOutBuffer所指缓冲区的大小。⑦ lpBytesReturned: 实际输出结果所占字节数。⑧ lpOverlapped: 指向OVERLAPPED结构的指针。返回值: 如果函数调用成功,则返回值为非0值。如果函数调用失败,则返回值为0。若要得到更多的错误信息,可调用函数GetLastError()。5.1.3实验内容编写一个函数,根据给出的驱动器号读取磁盘基本信息,包括磁盘的大小、该磁盘包括多少个扇区、该磁盘有多少个柱面,以及每个柱面的磁道数、每个磁道的扇区数、每个扇区包含的字节数。5.1.4实验要求了解MSDN Library Visual Studio 6.0中提供的磁盘主要数据结构DISK_GEOMETRY中每个成员的的含义,深入理解操作系统将设备当作文件处理的特性,理解函数CreateFile()及DeviceloControl()中每个参数的实际意义并能在本实验中正确使用。5.1.5实验指导在Microsoft Visual C 6.0环境下选择Win32 Console Application选项建立一个控制台工程文件,由于有关设备及文件操作的函数均是Microsoft Windows操作系统的系统调用,因此在图51中选中An application that supports MFC单选按钮。
图51建立一个MFC支持的应用程序
本实验要使用的主要数据结构DISK_GEOMETRY是由系统提供的,其声明在“#include “winioctl.h””中,因此要将其加入到实验程序的头文件说明中,否则程序编译时系统将无法识别DISK_GEOMETRY结构。5.1.6实验总结本实验程序的运行结果如图52所示。
图52软盘的基本物理组成信息
从实验结果可以看出,对给定的磁盘驱动器中的软盘A,本实验能正确识别出它每个扇区有512字节,每个磁道有18个扇区,每个柱面有2个磁道,共有80个柱面,该磁盘共有2880个磁道,磁盘的大小为1.41MB。应当注意,磁盘上有一部分空间是存储磁盘的物理信息的,这部分空间系统是不能够直接存取的,因此没有编入逻辑扇区,也就是说逻辑扇区比磁盘的实际扇区数要小,因此计算出的磁盘大小是磁盘可用空间的大小,比磁盘的物理大小要小。5.1.7源程序
//Disk_Inforamtion_Get.cpp: Defines the entry point for the console application.
#include “stdafx.h”
#include “Disk_Inforamtion_Get.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);
/////////////////////////////////////////////////////////////////////////////
//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(‘A’);
return nRetCode;
}
HANDLE GetDiskInformation(char drivername)
{
char device[]=”\\\\.\\: “;
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_VALUE!\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(“\t BytesPerSector: %d\n”,disk_info.BytesPerSector);
printf(“\t SectorPerTrack: %d\n”,disk_info.SectorsPerTrack);
printf(“\t TracksPerCylinder: %d\n”,disk_info.TracksPerCylinder);
printf(“\t Cylinder: %d\n”,disk_info.Cylinders);
Sector=disk_info.Cylinders.QuadPart*
disk_info.TracksPerCylinder*
disk_info.SectorsPerTrack;
printf(“\t There is %d Sectors!\n”,Sector);
DiskSize=Sector*disk_info.BytesPerSector;
printf(“\t Size of Disk: %4.2f MB\n”,(DiskSize)/(1024*1024));
return FloopyDisk;
}
5.2实验二: 读/写磁盘指定位置信息5.2.1实验目的
(1) 了解磁盘的物理组织。(2) 掌握Windows系统提供的有关对磁盘操作API函数。(3) 根据输入的扇区号读/写指定扇区。5.2.2实验准备知识: 相关API函数介绍1. 设置读/写操作的位置函数SetFilePointer()用于移动一个打开文件中的读/写指针,这里磁盘设备被当作文件处理,因此用于移动文件读/写指针在磁盘上的位置。原型:
DWORD SetFilePointer(
HANDLE hFile,//文件句柄
LONG lpDistanceToMove,//文件指针要移动的偏移量的低32位
PLONG lpDistanceToMoveHigh,//文件指针要移动的偏移量的高32位
DWORD dwMoveMethod //移动起点
);
参数说明: (1) hFile: 打开的文件句柄,创建的文件必须具有GENERIC_ READ或GENERIC_ WRITE的存取权限。(2) lpDistanceToMove: 指针要移动的偏移量的低32位,用于指定移动文件指针的字节大小。如果参数lpDistanceToMoveHigh不为空,那么lpDistanceToMoveHigh 和lpDistanceToMove两个参数形成一个64位的值来指定移动的位置。如果参数lpDistanceToMoveHigh为空,且lpDistanceToMove是一个32位带符号值,那么当lpDistanceToMove为正值时,文件指针向前移动,否则向后移动。(3) lpDistanceToMoveHigh: 指针要移动的偏移量的高32位。如果不需要该参数,可将其设置为空。当该参数不为空时,该参数为文件指针的高32位的DWORD类型值。(4) dwMoveMethod: 文件指针移动的初始位置,其值如表52所示。
表52dwMoveMethod的值
值描述
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. 读文件读取磁盘指定区域的内容,函数详细说明参见4.1.2节。原型:
BOOL ReadFile(
HANDLE hFile,//要读的文件的句柄
LPVOID lpBuffer, //指向文件缓冲区的指针
DWORD nNumberOfBytesToRead,//从文件中要读取的字节数
LPDWORD lpNumberOfBytesRead, //指向从文件中要读取的字节数的指针
LPOVERLAPPED lpOverlapped//指向OVERLAPPED结构的指针
);
3. 写文件该函数将数据写入磁盘指定区域,函数详细说明参见4.1.2节。原型:
BOOL WriteFile(
HANDLE hFile, //要读的文件的句柄
LPVOID lpBuffer, //指向文件缓冲区的指针
DWORD nNumberOfBytesToWrite,//从文件中要读取的字节数
LPDWORD lpNumberOfBytesWritten, //指向从文件中要读取的字节数的指针
LPOVERLAPPED lpOverlapped//指向OVERLAPPED结构的指针
);
5.2.3实验内容在本章实验一的基础上,继续完成该实验。编写两个函数,分别完成如下功能。(1) 对给定的扇区号读取该扇区的内容。(2) 将用户输入的数据写入指定的扇区。5.2.4实验要求深入理解操作系统将设备当作文件处理的特性,理解函数SetFilePointer()、ReadFile()及WriteFile()中每个参数的实际意义并能在本实验中正确使用。5.2.5实验指导在主程序中让用户选择: R、W或Q,若用户选择R选项,则调用函数BOOL SectorRead(HANDLE Handle),完成读给定扇区信息的功能; 若用户选择W选项,则调用函数BOOL SectorWrite(HANDLE Handle) 完成对给定扇区号写入信息的功能; 若用户选择Q选项,则程序退出。5.2.6实验总结用户读/写扇区的情况如图53所示。
图53用户读/写扇区的情况
在上面的实验中,应用程序首先显示软盘的信息。
Disk Information:
BytesPerSector: 512
SectorPerTrack: 18
TracksPerCylinder: 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 Sector 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 From: ”输入要读的磁道号,当用户输入4表示要读第4道的内容后,应用程序显示“Content: ”后分别以字符形式和十六进制形式显示软盘上第4道的内容。5.2.7源程序
//Disk_Inforamtion_Read and Write.cpp: Defines the entry point for the console application.
#include “stdafx.h”
#include “Disk_Inforamtion_Get.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(‘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(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[]=”\\\\.\\: “;
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_VALUE!\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(“\t BytesPerSector: %d\n”,disk_info.BytesPerSector);
printf(“\t SectorPerTrack: %d\n”,disk_info.SectorsPerTrack);
printf(“\t TracksPerCylinder: %d\n”,disk_info.TracksPerCylinder);
printf(“\t Cylinder: %d\n”,disk_info.Cylinders);
Sector=disk_info.Cylinders.QuadPart*
disk_info.TracksPerCylinder*
disk_info.SectorsPerTrack;
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.Cylinders.QuadPart*
disk_info.TracksPerCylinder*
disk_info.SectorsPerTrack;
if (SectorNumber>Sector) printf(“There is not this Sector!\n”);
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;
}
BOOL SectorWrite(HANDLE Handle)
{
char WriteBuffer[1024];
DWORD SectorNumber,SecterMove;
DWORD BytestoWrite;
DWORD Sector;
DWORD rc;
if (Handle==NULL)
{
printf(“There is No disk!\n”);
return FALSE;
}
printf(“Please Input the Sector Number to Write to: \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!\n”);
printf(“Please Input the Content to Write to Disk A: \n”);
scanf(“%s”,&WriteBuffer);
SecterMove=SectorNumber*(disk_info.BytesPerSector);
rc=SetFilePointer(Handle,SecterMove,NULL,FILE_BEGIN);
if (!WriteFile(Handle,WriteBuffer,512,&BytestoWrite,NULL))
{
printf(“Read File Error: %d\n”, GetLastError());
return FALSE;
}
printf(“Write Complete!\n”);
return TRUE;
}
5.2.8实验展望在上述实验的基础上,读者可以尝试实现下述功能: 读取软盘上的文件目录,并查看指定文件信息。
评论
还没有评论。