VC++实现Windows下直接读写磁盘扇区
WIN32和Kernel直接读写硬盘扇区

WIN32和Kernel直接读写硬盘扇区这里是摘自文章里的一个表:硬盘的总体结构***********************************************************************编号名称备注1 主引导扇区(含硬盘分区表) 占用一个扇区空间(一个扇区空间为512字节)2 保留扇区(操作系统不使用的扇区) 占用62个扇区空间3 第一个分区 C:盘4 扩展主引导扇区(含扩展分区表) 一个扇区空间(只有存在扩展分区是才存在)5 保留扇区占用62个扇区空间6 第2个分区 D:盘7 下一个扩展主引导扇区只有分区链没结束才存在8 ...... ......***********************************************************************通常的软件保护都会向编号为2的保留扇区写一些软件注册信息呀,等等的东西.而要读写这个没被操作系统利用的部分作者已经给出了代码(幸福呀,不用自己找).//以下是已经做好的一个函数BOOL ReadPhysicalSector(unsignedlong SectorStart, unsignedlong SectorCount, unsignedchar *p){unsignedlong BytesPerSector = 512;unsignedlong nBytes;char Drive[] = "////.//PHYSICALDRIVE0";BOOL result = FALSE;HANDLE hDeviceHandle = CreateFile(Drive,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,0);if(hDeviceHandle){long pointer;long phigh;pointer = SectorStart;pointer = pointer*BytesPerSector;phigh = pointer>>32;SetFilePointer(hDeviceHandle,(unsignedlong)pointer,&phigh,FILE_BEGIN);if(ReadFile(hDeviceHandle,p,SectorCount*BytesPerSector,&nBytes,NULL))result = TRUE;CloseHandle(hDeviceHandle);}return result;}//调用就这样int main(int argc, char* argv[]){unsignedlong SectorStart = 0;//比如我要读的是编号为的那个扇区开始的数据,这里写//如果读的是从第扇区开始后的数据这里就写unsignedlong SectorCount = 1;//读多少个扇区,这里是个unsignedchar p[512];//一个扇区数据量是字节呀ReadPhysicalSector(SectorStart, SectorCount, p);for(int i=0;i<512;i++)//输出的{printf("%02X ",p[i]);if(i%26==0)printf(" ");}return 0;}以上的代码都是读的,那如果要写就把ReadFile改成WriteFile呀.要注意的是别乱写了分区表了,很难恢复的.小心用WriteFile呀.以上的我就实现了,其实也是抄人家的代码,5555555没意思,突然间想把这些功能用驱动来实现.想就快呀,第一时间上网找ZwWriteFile,ZwReadFile的使用啦,想不到在baidu搜的都是怎么hook ZwWriteFile,ZwReadFile他们的文章,555555那个简单啦,不就改改SSDT然后自己定义函数嘛.但是......ZwWriteFile,ZwReadFile怎么用的文章几乎没有的.天呀!好惨!接着我看好久的DDK文档,看了很久ZwWriteFile,ZwReadFile的函数原型,就一步步写出以下的代码出来,经过了n的n次方次的失败后终于......成功读取了第一个扇区的数据了.#include<ntddk.h>//--------------------------------------------------------------------VOID ReadPhysicalSector(unsignedlong SectorCount, unsignedchar *p){unsignedlong BytesPerSector = 512;WCHAR* name = L"//??//PHYSICALDRIVE0";//这个找了好久呀,原来要这样写的NTSTATUS ntStatus;HANDLE hDeviceHandle;IO_STATUS_BLOCK IoStatusBlock;IO_STATUS_BLOCK IoStatusBlockR;OBJECT_ATTRIBUTES ObjectAttributesL;UNICODE_STRING UniFileNameL;LARGE_INTEGER ByteOffset;RtlInitUnicodeString(&UniFileNameL,name);InitializeObjectAttributes(&ObjectAttributesL,&UniFileNameL,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL);ntStatus = ZwCreateFile(&hDeviceHandle,GENERIC_READ,&ObjectAttributesL,&IoStatusBlock,NULL,0,FILE_SHARE_READ,FILE_OPEN,FILE_SYNCHRONOUS_IO_ALERT,NULL,0);if( NT_SUCCESS(ntStatus) ){DbgPrint("Open Success");ByteOffset.LowPart = FILE_USE_FILE_POINTER_POSITION;ByteOffset.HighPart = -1;ntStatus = ZwReadFile( hDeviceHandle,NULL,NULL,NULL,&IoStatusBlockR,p,SectorCount*BytesPerSector,&ByteOffset,NULL);if( NT_SUCCESS(ntStatus) ){DbgPrint("Read Success");}}ZwClose(hDeviceHandle);}//--------------------------------------------------------------------VOID OnUnload(IN PDRIVER_OBJECT DriverObject){DbgPrint(" 88 ");}NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRINGRegistryPath){unsignedlong SectorCount = 1;unsignedchar p[512];int i;DriverObject->DriverUnload = OnUnload;DbgPrint("Hi");ReadPhysicalSector(SectorCount, p);for(i=0;i<512;i++)DbgPrint("%02X ",p[i]);return STATUS_SUCCESS;}终于读取成功了,写就Read改成Write呀,哎....其实我都是刚刚学什么都不会,看了好久DDK文档才挤出上面几行代码.....但是现在我最不明白的就是ZwReadFile中怎么定位指针的位置呢,比如我想在第2个扇区开始读应该怎么写呢?55555555不想啦,很烦啊.....有高手路过就批一下啦,最好教一下我.好啦今天一起床,想了想,又看了看DDK终于将以上的问题解决了,可以任意读取某一个扇区了~~~~~~~~~~~心情当然非常激动啦~~~啦~~~啦~原来错误就在这两句里面,DDK误导人的,还是我的英文差呢~~~~~~好啦~~~其实DDK是这么说的:ByteOffsetPointer to a variable that specifies the starting byte offset in the file where the read operation will begin. If an attempt is made to read beyond the end of thefile, ZwReadFile returns an error.If the call to ZwCreateFile set either of the CreateOptions flags FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT, the I/O Manager maintains the current file position. If so, the caller of ZwReadFile can specify that the current file position offset be used instead of an explicit ByteOffset value. This specification can be made by using one of the following methods:● Specify a pointer to a LARGE_INTEGER value with the HighPart member set to -1 and the LowPart member set to the system-defined valueFILE_USE_FILE_POINTER_POSITION.● Pass a NULL pointer for ByteOffset.ZwReadFile updates the current file position by adding the number of bytes read when it completes the read operation, if it is using the current file position maintained by the I/O Manager.Even when the I/O Manager is maintaining the current file position, the caller can reset this position by passing an explicit ByteOffset value to ZwReadFile. Doing this automatically changes the current file position to that ByteOffset value, performs the read operation, and then updates the position according to the number of bytes actually read. This technique gives the caller atomic seek-and-read service.//今天不按照它说的来做,ByteOffset.LowPart = FILE_USE_FILE_POINTER_POSITION;ByteOffset.HighPart = -1;//改成:ByteOffset.QuadPart = //第几个字节;//终于成功了:代码如下:#include<ntddk.h>//--------------------------------------------------------------------VOID ReadPhysicalSector(unsignedlong SectorStart,unsignedlong SectorCount,unsignedchar *p){unsignedlong BytesPerSector = 512;WCHAR* name = L"//??//PHYSICALDRIVE0";//这个找了好久呀,原来要这样写的NTSTATUS ntStatus;HANDLE hDeviceHandle;IO_STATUS_BLOCK IoStatusBlock;IO_STATUS_BLOCK IoStatusBlockR;OBJECT_ATTRIBUTES ObjectAttributesL;UNICODE_STRING UniFileNameL;LARGE_INTEGER ByteOffset;RtlInitUnicodeString(&UniFileNameL,name);InitializeObjectAttributes(&ObjectAttributesL,&UniFileNameL,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL);ntStatus = ZwCreateFile(&hDeviceHandle,GENERIC_READ,&ObjectAttributesL,&IoStatusBlock,NULL,0,FILE_SHARE_READ,FILE_OPEN,FILE_SYNCHRONOUS_IO_ALERT,NULL,0);if( NT_SUCCESS(ntStatus) ){DbgPrint("Open Success");// ByteOffset.LowPart = FILE_USE_FILE_POINTER_POSITION;// ByteOffset.HighPart = -1;不要用这两句换成下面一句,DDK误导人啊~~~~~ByteOffset.QuadPart = SectorStart*BytesPerSector;//是这句了ntStatus = ZwReadFile( hDeviceHandle,NULL,NULL,NULL,&IoStatusBlockR,p,SectorCount*BytesPerSector,&ByteOffset,NULL);if( NT_SUCCESS(ntStatus) ){DbgPrint("Read Success");}}ZwClose(hDeviceHandle);}//--------------------------------------------------------------------VOID OnUnload(IN PDRIVER_OBJECT DriverObject){DbgPrint(" 88 ");}NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRINGRegistryPath) {unsignedlong SectorStart = 63;//现在是读扇区啦unsignedlong SectorCount = 1;unsignedchar p[512];int i;DriverObject->DriverUnload = OnUnload;DbgPrint("Hi");ReadPhysicalSector(SectorStart ,SectorCount, p);for(i=0;i<512;i++)DbgPrint("%02X ",p[i]);return STATUS_SUCCESS;}。
wince内存直接读写

2.对物理内存的直接读写在PC环境下,Windows是不允许用户态进程直接访问内存的,任何对内存的访问都会引起程序的异常。
而在嵌入式设备中,需要直接对内存进行读写,以此来提高处理速度,此外,在ARM体系中,I/O被映射到高端的地址进行访问,只有读写物理地址,I/O的驱动才能高效地运行。
Windows CE中有一些API提供了对物理内存的“直接”访问。
不过,在访问之前,必须把物理内存映射到虚拟地址中,通过虚拟地址才能读写物理内存。
PHYSICAL_ADDRESS描述了Windows CE的物理内存结构体,Windows CE在ceddk.h中定义了PHYSICAL_ADDRESS,其定义如下:n 在ceddk.h中typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;n 在winnt.h中typedef union _LARGE_INTEGER{struct{DWORD LowPart;LONG HighPart;};LONGLONG QuadPart;} LARGE_INTEGER;可见,Windows CE中用64位来代表物理地址,对于大多数32位的CPU而言,只需要把它的HighPart设置为0就可以了。
VirtualAlloc()函数是Windows CE中分配连续虚拟地址的API,VirtualCopy()函数将一段物理内存映射到虚拟地址。
因此,在进程中访问物理地址,就像访问虚拟地址一样方便,当然,如何选择虚拟地址是需要研究的。
// 申请虚拟内存LPVOID VirtualAlloc(LPVOID lpAddress, // 希望的虚拟内存起始地址DWORD dwSize, // 以字节为单位的大小DWORD flAllocationType, // 申请类型,分为Reserve和Commit DWORD flProtect // 访问权限);// 把物理内存绑定到虚拟地址空间BOOL VirtualCopy(LPVOID lpvDest, // 虚拟内存的目标地址LPVOID lpvSrc, // 物理内存地址DWORD cbSize, // 要绑定的大小DWORD fdwProtect // 访问权限);VirtualAlloc对虚拟内存的申请分为两步,保留MEM_RESERVE和提交MEM_COMMIT。
Windows下直接读取软盘扇区

Windows下直接读取软盘扇区作者:汪虹来源:《电脑知识与技术》2009年第24期摘要:随着计算机的普及和互联网的发展,病毒、系统故障、误操作等因素所带来的数据丢失正在迅速增加,由此造成的损失也越来越严重,因此掌握数据恢复技术的变的越来越重要,而对磁盘、文件系统了解是进行数据恢复的必备知识。
本文对Windows下如何直接读取磁盘扇区进行了分析与研究,并结合Delphi实现了系统。
关键词:磁盘;扇区;Delphi ;CreateFile;DeviceIoControl;SetFilePointer中图分类号:TP393文献标识码:A文章编号:1009-3044(2009)24-6791-03Read Floppy Disk Sector for WindowsWANG Hong(Traditional Chinese Hospital of Luan, Luan 237006,China)Abstract: With the popularization of computers and the development of the internet,the data missing because of the virus,system malfunction,misoperation and so on is increasing rapidly,the corresponding loss is also more and more severely,so it is very important to master the technology of resuming the data.understanding the disk and the file system is the necessary knowledge.this text analyze and study how to read the sector directly based on windows system,and realize the demo system by Delphi.Key words: disk; sector; Delphi; CreateFile; DeviceIoControl; SetFilePointer信息化时代,都越来越依赖于计算机进行工作。
CC++关于文件的读写操作以及文件的打开和保存

CC++关于⽂件的读写操作以及⽂件的打开和保存通过近来的学习,总结⼀下关于⽂件的读写操作以及⽂件的打开和保存的⽅法。
⼀、⽂件的读写操作:(1)C语⾔对⽂件的读写操作在C语⾔中,对⽂件的读写操作是⽤FILE结构体和常⽤的对⽂件操作的函数实现的,下⾯总结⼀下C语⾔中对⽂件操作的常⽤函数:fopen() 打开以⽂件名指定的⽂件fwrite() 写⽂件fread() 读⽂件fseek() 移动⽂件的指针到新的位置通过该函数的参数设定的偏移量和初始位置rewind() 移动⽂件的指针到⽂件流的开始位置,在通常情况下可⽤fseek()实现相同的功能,但⼆者有区别ftell() 获得当前⽂件指针的位置,常⽤该函数获得⽂件的⽂件流的长度fflush() 刷新缓冲区中的内容,当⽂件写⼊时直接将⽂件流的内容从缓冲区写⼊磁盘,当读取⽂件时直接将磁盘⽂件写⼊缓冲区,⽽不必等程序运⾏结束或关闭程序。
fclose() 关闭⽂件memset() 在⼀段内存块中填充某个给定的值⽰例代码如下:/*********************************************************** C语⾔实现⽂件写操作 ************************************************************/FILE *pFile=fopen("CLanguage.txt","w");fwrite("CLanguage",1,strlen("CLanguage"),pFile);//fseek(pFile,0,SEEK_SET);//fwrite("实现⽂件写操作",1,strlen("实现⽂件写操作"),pFile);fclose(pFile);/*********************************************************** C语⾔实现⽂件读操作 ************************************************************/FILE *pFile=fopen("CLanguage.txt","r");//char ch[100];//memset(ch,0,100);//fread(ch,1,100,pFile);//MessageBox(ch);char* pBuf;int length;fseek(pFile,0,SEEK_END);length=ftell(pFile);pBuf=new char[length+1];//fseek(pFile,0,SEEK_SET);rewind(pFile);fread(pBuf,1,length,pFile);pBuf[length]=0;MessageBox(pBuf);fclose(pFile);注意:在⽤C语⾔实现⽂件的读操作时,要注意⽂件的指针位置。
读写硬盘扇区的C语言程序

读写硬盘的MBR和DBR扇区的程序。
/******************************************** Master Boot Record Programme: ** Backup the Master Boot Sector ** Fix the Master Boot Sector ** Change the Partition Table ** -- by Crystal.Mouse 04/30/99 -- ** Turboc 2.0 ********************************************/#include <ctype.h>#include <stdlib.h>#include <stdio.h>#include <bios.h>#include <io.h>#include <dos.h>#include <fcntl.h>#include <sys\stat.h>#include <conio.h>/* define the */char buff[512]; /*buffer for master boot sector *//* buffer1 backup for master boot sector */char buff1[512];/* This is the dos boot programme data */char sector2[512]={0xEB,0x3C,0x90,0x4D,0x53,0x57,0x49,0x4E,0x34,0x2E,0x31,0x00, 0x02,0x20,0x01,0x00,0x02,0x00,0x02,0x00,0x00,0xF8,0xC9,0x00,0x3F,0x00,0x40,0x00,0x3F,0x00,0x00,0x00,0x01,0x0A,0x19,0x00,0x80,0x00,0x29,0xDC,0x12,0x6F,0x04,0x30,0x34,0x32,0x36,0x39,0x39,0x20,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x36,0x20,0x20,0x20,0xFA,0x33,0xC9,0x8E,0xD1,0xBC,0xFC,0x7B,0x16,0x07, 0xBD,0x78,0x00,0xC5,0x76,0x00,0x1E,0x56,0x16,0x55,0xBF,0x22, 0x05,0x89,0x7E,0x00,0x89,0x4E,0x02,0xB1,0x0B,0xFC,0xF3,0xA4, 0x06,0x1F,0xBD,0x00,0x7C,0xC6,0x45,0xFE,0x0F,0x8B,0x46,0x18, 0x88,0x45,0xF9,0x38,0x4E,0x24,0x7D,0x22,0x8B,0xC1,0x99,0xE8, 0x77,0x01,0x72,0x1A,0x83,0xEB,0x3A,0x66,0xA1,0x1C,0x7C,0x66, 0x3B,0x07,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA,0x02,0x88,0x56, 0x02,0x80,0xC3,0x10,0x73,0xED,0x33,0xC9,0x8A,0x46,0x10,0x98, 0xF7,0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E, 0x13,0xD1,0x8B,0x76,0x11,0x60,0x89,0x46,0xFC,0x89,0x56,0xFE, 0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03,0xC3,0x48,0xF7, 0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x07,0xE8, 0x23,0x01,0x72,0x39,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE, 0xD8,0x7D,0xF3,0xA6,0x61,0x74,0x39,0x4E,0x74,0x09,0x83,0xC7, 0x20,0x3B,0xFB,0x72,0xE7,0xEB,0xDD,0xBE,0x7F,0x7D,0xAC,0x98, 0x03,0xF0,0xAC,0x84,0xC0,0x74,0x17,0x3C,0xFF,0x74,0x09,0xB4, 0x0E,0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEE,0xBE,0x82,0x7D,0xEB, 0xE5,0xBE,0x80,0x7D,0xEB,0xE0,0x98,0xCD,0x16,0x5E,0x1F,0x66, 0x8F,0x04,0xCD,0x19,0xBE,0x81,0x7D,0x8B,0x7D,0x1A,0x8D,0x45, 0xFE,0x8A,0x4E,0x0D,0xF7,0xE1,0x03,0x46,0xFC,0x13,0x56,0xFE, 0xB1,0x04,0xE8,0xC1,0x00,0x72,0xD6,0xEA,0x00,0x02,0x70,0x00, 0xB4,0x42,0xEB,0x2D,0x60,0x66,0x6A,0x00,0x52,0x50,0x06,0x53, 0x6A,0x01,0x6A,0x10,0x8B,0xF4,0x74,0xEC,0x91,0x92,0x33,0xD2, 0xF7,0x76,0x18,0x91,0xF7,0x76,0x18,0x42,0x87,0xCA,0xF7,0x76, 0x1A,0x8A,0xF2,0x8A,0xE8,0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01, 0x02,0x8A,0x56,0x24,0xCD,0x13,0x8D,0x64,0x10,0x61,0x72,0x0A, 0x40,0x75,0x01,0x42,0x03,0x5E,0x0B,0x49,0x75,0x77,0xC3,0x03, 0x18,0x01,0x27,0x0D,0x0A,0x49,0x6E,0x76,0x61,0x6C,0x69,0x64, 0x20,0x73,0x79,0x73,0x74,0x65,0x6D,0x20,0x64,0x69,0x73,0x6B, 0xFF,0x0D,0x0A,0x44,0x69,0x73,0x6B,0x20,0x49,0x2F,0x4F,0x20,0x61,0x63,0x65,0x20,0x74,0x68,0x65,0x20,0x64,0x69,0x73,0x6B,0x2C,0x20,0x61,0x6E,0x64,0x20,0x74,0x68,0x65,0x6E,0x20,0x70,0x72,0x65,0x73,0x73,0x20,0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x0D,0x0A,0x00,0x00,0x49,0x4F,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x59,0x53,0x4D,0x53,0x44,0x4F,0x53,0x20,0x20,0x20,0x53,0x59,0x53,0x7F,0x01,0x00,0x41,0xBB,0x00,0x07,0x80,0x7E,0x02,0x0E,0xE9,0x40,0xFF,0x00,0x00,0x55,0xAA};/* sector1 is the Master boot program data */char sector1[512]={0xFA,0x33,0xC0,0x8E,0xD0,0xBC,0x00,0x7C,0x8B,0xF4,0x50,0x07, 0x50,0x1F,0xFB,0xFC,0xBF,0x00,0x06,0xB9,0x00,0x01,0xF2,0xA5,0xEA,0x1D,0x06,0x00,0x00,0xB8,0x01,0x02,0xBB,0x00,0x08,0xB9,0x01,0x00,0xBA,0x80,0x00,0xCD,0x13,0xBF,0x00,0x06,0xBE,0x00,0x08,0xB9,0x00,0x01,0xFC,0xF3,0xA7,0x74,0x14,0xBE,0x17,0x07,0xE8,0x2F,0x01,0xB8,0x01,0x03,0xBB,0x00,0x06,0xB9,0x01,0x00,0xBA,0x80,0x00,0xCD,0x13,0xBE,0xBE,0x07,0xB3,0x04,0x80,0x3C,0x80,0x74,0x0E,0x80,0x3C,0x00,0x75,0x1C,0x83,0xC6,0x10,0xFE,0xCB,0x75,0xEF,0xCD,0x18,0x8B,0x14,0x8B,0x4C,0x02,0x8B,0xEE,0x83,0xC6,0x10,0xFE,0xCB,0x74,0x0D,0x80,0x3C,0x00,0x74,0xF4,0xBE,0xAE,0x06,0xE8,0xF0,0x00,0xEB,0xFE,0xBF,0x05,0x00,0xBB,0x00,0x7C,0xB8,0x01,0x02,0x57,0xCD,0x13,0x5F,0x73,0x0C,0x33,0xC0,0xCD,0x13,0x4F,0x75,0xED,0xBE,0xD2,0x06,0xEB,0xE0,0xBE,0xF7,0x06,0xBF,0xFE,0x7D,0x81,0x3D,0x55,0xAA,0x75,0xD4,0x8B,0xF5,0xEA,0x00,0x7C,0x00,0x00,0x49,0x6E,0x76,0x61,0x6C,0x69,0x64,0x20,0x70,0x61,0x72,0x74,0x69,0x74,0x69,0x6F,0x6E,0x20,0x74,0x61,0x62,0x6C,0x65,0x2E,0x20,0x4F,0x68,0x2C,0x6D,0x79,0x20,0x67,0x6F,0x64,0x21,0x00,0x45,0x72,0x72,0x6F,0x72,0x20,0x6C,0x6F,0x61,0x64,0x69,0x6E,0x67,0x20,0x6F,0x70,0x65,0x72,0x61,0x74,0x69,0x6E,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6D,0x6E,0x67,0x20,0x6F,0x70,0x65,0x72,0x61,0x74,0x69,0x6E,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6D,0x2E,0x20,0x53,0x68,0x69,0x74,0x21,0x00,0x4D,0x61,0x73,0x74,0x65,0x72,0x20,0x42,0x6F,0x6F,0x74,0x20,0x53,0x65,0x63,0x74,0x6F,0x72,0x20,0x63,0x68,0x61,0x6E,0x67,0x65,0x64,0x2E,0x0A,0x0D,0x44,0x6F,0x6E,0x27,0x74,0x20,0x77,0x6F,0x72,0x72,0x79,0x2C,0x49,0x20,0x68,0x61,0x76,0x65,0x20,0x72,0x65,0x63,0x6F,0x76,0x65,0x72,0x65,0x64,0x20,0x69,0x74,0x21,0x20,0x43,0x6C,0x65,0x76,0x65,0x72,0x21,0x20,0x45,0x54,0x2D,0x4D,0x6F,0x75,0x73,0x65,0x20,0x59,0x65,0x61,0x68,0x21,0x0A,0x0D,0x00,0xAC,0x3C,0x00,0x74,0x0B,0x56,0xBB,0x07,0x00,0xB4,0x0E,0xCD,0x10,0x5E,0xEB,0xF0,0xC3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xAA};char fnwrite[20],fnread[20]; /* filename */FILE *fp; /* file pointer */int head,cylinder,sector,drive; /* harddisk head,cylinder sector drive */ /* define the key code */#define ESC 0x011b#define LEFT 0x4b00#define RIGHT 0x4d00#define UP 0x4800#define DOWN 0x5000#define HOME 0x4700#define END 0x4f00#define PGUP 0x4900#define PGDN 0x5100#define F2 0x3c00#define F1 0x3b00#define W 1#define R 0 /* flag for */#define D 0 /* flag for Dos Boot Sector */#define M 1 /* flag for Master Boot Sector *//* declare the function */int fileopen(int f,char *file); /*Read or Creat the backupfile */int writembr(char *file); /* write the buffer to master boot sector */ int writedbr(char *file); /* write the buffer to dos boot sector */int backupmbr(char *file); /* backup the Master Boot record data */ int backupdbr(char *file); /* backup the dos boot sector data */ int printmbr(); /* print the master boot sector */int init(int f); /* init the operating */void help(); /*help*/void title(); /* display the infomation */int copypart(char *src,char *dest);void infina(char *file); /* open or creat the backup file */void closecur(); /* close the cursor */void opencur(); /* open the cursor */int display(); /* display the data */void interrupt(*reset)(); /* interrupt reset the machine */void resetwin(); /* reset the screen */void search(); /* search the dos boot sector */int detect(int num,int driver,int f); /* detect the drive */int detect(int num,int driver,int f)/* detect the disk */{union REGS r;r.h.ah=num;r.h.dl=driver;int86(0x13,&r,&r);if(f)return r.h.al;elsereturn r.x.cflag;}/* backup the dos boot sector */int backupdbr(char *file){int flag=1; /* flag for success or not */if(!fileopen(W,file)){printf("\nBackup file write error!");flag=0;}return flag;}/* rewrite the dos boot record */int writedbr(char *file){int flag; /* flag for success or not */char key;search(); /* search the the dos boot sector: head , cylinder and sector */ init(D); /* initialize the dos boot sector data to the buffer */printf("\nWarning...");printf("\nIt might destory your harddisk!");printf("\nDo you want to a backup?(y/n)");key=getch();switch(key){case 'y':case 'Y':infina(fnwrite); /* input the backup filename */if(!backupdbr(fnwrite)){printf("\nBackup error!");flag=0;break;}case 'n':case 'N':if(!fileopen(R,file)) /* open the existed backup file data to buffer */ {printf("\nBackup file %s open error!",file);flag=0;return flag;}}/* rewrite the dos boot sector with the buffer data */if(biosdisk(0x03,0x80,head,cylinder,sector,1,buff1)) {printf("\nWrite Master Boot Sector error!");flag=0;}else{printf("\nWrite Dos Boot Sector OK!");flag=1;}}/* backup the Master Boot Sector data to file */int backupmbr(char *file){int flag=1;init(M); /* initialize the master boot sector to the buffer */ if(!fileopen(W,file)){printf("\nBackup file write error!");flag=0;}return flag;}int fileopen(int f,char *file)/* f for read or creat file */{int flag=1;if(f==0){if((fp=fopen(file,"rb"))!=NULL){fread(buff1,512,1,fp);fclose(fp);}else flag=0;}if(f==1){if((fp=fopen(file,"wb"))!=NULL){fwrite(buff,512,1,fp);fclose(fp);}else flag=0;}return flag;}int writembr(char *file){int flag=1;char key;printf("\nWarning...");printf("\nIt might destory your harddisk!");printf("\nDo you want to a backup?(y/n)");key=getch();switch(key){case 'y':case 'Y':infina(fnwrite);init(M); /* initialize the MBR to buffer */if(!backupmbr(fnwrite)) /* backup the MBR */{printf("\nBackup error!");flag=0;}printf("\nFile %s backup ok!",fnwrite);if(!biosdisk(0x03,0x80,0,0,3,1,buff))printf("\nThe old MBR write to head:0 , Cylinder:0 ,Sector:1 error!");if(!biosdisk(0x03,0x80,0,0,5,1,buff))printf("\nThe old MBR write to head:0 , Cylinder:0 ,Sector:1 error!");printf("\nThe old MBR also backup to the harddisk side 0 cylinder 0 sector 3 and 5.");flag=1;case 'n':case 'N':if(!fileopen(R,file)) /* open the existed backup file */{flag=0;return flag;}}if(biosdisk(0x03,0x80,0,0,1,1,buff1)) /* Rewrite the MBR with buffer1 */ {printf("\nWrite Master Boot Sector error!");flag=0;}else{printf("\nWrite Master Boot Sector OK!");flag=1;}return flag;}int init(int f){int i;int result=1;for(i=0;i<512;i++) /* initialize the buffer */buff[i]=0;if(f){if(biosdisk(0x02,0x80,0,0,1,1,buff)) /* read the Mbr to buffer */{result=0;}}else if(biosdisk(0x02,0x80,head,cylinder,sector,1,buff)) {printf("\nDos Boot Sector read error!");result=0;}return result;}main(){int far *res=(int far *)0x472; /* the data for reset */int i,j,k;char key;reset=MK_FP(0xffff,0x0000); /* reset interrupt address */clrscr();while(1){printf("\nSetMbr programme...('h' for help)");printf("\n.");key=getch();printf("%c",key);switch(key){case 'H':case 'h':help();break;/* rewrite the MBR sector */case 'w':case 'W':infina(fnread); /* input the existed file name */ if(!writembr(fnread)){printf("\nWrite HardDisk MBR error!");printf("\nPress 'v' to check it.");printf("\nPress 'm' to fix it.");}elseprintf("\nWrite HardDisk MBR OK!");break;/* backup the MBR sector */case 'b':case 'B':infina(fnwrite);if(!backupmbr(fnwrite))printf("\nBackup MBR error!");elseprintf("\nBackup MBR OK!");break;/* rewrite the dos boot sector */case 'd':case 'D':infina(fnread);{printf("\nWrite Dos Boot Sector error!");printf("\nPress 'v' to view the Dos Boot Sector!");break;}break;/* backup the dos boot sector */case 'o':case 'O':infina(fnwrite);search();init(D);if(!backupdbr(fnwrite))printf("\nBackup Dos Boot Sector error!");elseprintf("\nBackup Dos Boot Sector OK!");break;/* rewrite the dos boot sector with default data */ case 'i':case 'I':search();init(D);printf("\nIt would modify the Dos Boot secotr!");printf("\nDo you want to backup?(Y/N)");key=getch();if(key=='y' || key=='Y'){if(!backupmbr(fnwrite))printf("\nBackup Error!");elseprintf("\nBackup OK!");}elseif(key=='n' || key=='N')printf("\nWarning:it would modify the Dos Boot Sector!"); /* write the sector2 to the dos boot sector */if(biosdisk(0x03,0x80,head,cylinder,sector,1,sector2)!=0) printf("\nDos Boot Sector Write error!");elseprintf("\nDos Boot Sector Write OK!");break;/* reset the machine */case 'r':case 'R':*res=0x1234;(*reset)();/* view the harddisk sector data */case 'v':case 'V':search();printmbr();break;/* fixed the flappy boot sector */case 'f':case 'F':printf("\nWhich dekette? -> (A,B,...):");key=getch();printf("%1c:",key);if(key>=97)key=key-97;elsekey=key-65;/* if(detect(0x10,key,0)){printf("\nDriver %1c: not ready!",key+65);break;}elseif(detect(0x13,key,1)==0x03){printf("\nDriver %1c: write protect!",key+65);break;}else */if(biosdisk(0x03,key,0,0,1,1,sector2))printf("\nDriver %c: write error!",key+65);elseprintf("\nDrive %1c: write OK!",key+65);break;/* fixed the MBR with default data */case 'm':case 'M':printf("\nIt would modify the Master Boot Record.");printf("\nDo you want to backup?(Y/N)");key=getch();printf("%1c",key);if(key=='y' || key=='Y'){infina(fnwrite);if(!backupmbr(fnwrite)){printf("\nBackup Error!");break;}}elseif(key=='n' || key=='N')printf("\nWarning:it would modify the Master Boot Sector!");init(M);if((buff[0x1be]&0x00ff)==0x80 || (buff[0x1be+16]&0x00ff)==0x80|| (buff[0x1be+32]&0x00ff)==0x80 || (buff[0x1be+48]&0x00ff)==0x80) copypart(buff+0x1be,sector1+0x1be);if(biosdisk(0x03,0x80,0,0,1,1,sector1)){printf("\nHardDisk Write error!");break;}else{printf("\nHardDisk Write OK!");printf("\nPress 'v' to check it.");}break;/* dos shell */case 's':case 'S':printf("\nPress 'Exit' to return....");system("");break;/* exit */case 'q':case 'Q':title();return 1;/* print the undefine command */default:printf("%cBad command!",27);}}}/* display the information */void title(){printf("\nThank you for using the programme...");printf("\nProgrammer:Crystal.Mouse");printf("\nDate:05/01/1999");}/* change the destination partition table data with the source data */ int copypart(char *src,char *dest){char len=0x40;while(len>=0){*(dest+len)=*(src+len);len--;}}/* input the filename */void infina(char *file){printf("\nPlease input the file name:");scanf("%s",file);}void search(){int i,addr;init(M);for(i=0x1be;i<0x1fe;i++)if((buff[i]&0x00ff)==0x80){addr=i;break;}head=buff[addr+1];sector=(buff[addr+2]<<2)>>2;cylinder=(buff[addr+2]>>6)*256+buff[addr+3]; }/* close the cursor */void closecur(){union REGS r;r.h.ah=1;r.h.ch=0x20;int86(0x10,&r,&r);}/* open the cursor */void opencur(){union REGS r;r.h.ah=1;r.h.ch=12;r.h.cl=13;int86(0x10,&r,&r);}void help(){printf("\n\tMaster Boot sector backup programme...");printf("\n\tH: help.");printf("\n\tW: ReWrite the Master Boot Record from a file.");printf("\n\tB: Backup the Master Boot Record to a file.");printf("\n\tO: Save the Dos Boot Sector to a file.");printf("\n\tD: Rewrite the Dos Boot Sector from a file.");printf("\n\tI: Rewrite the Dos Boot Sector with a default.");printf("\n\tV: View the Master Boot Record.");printf("\n\tF: Fixed the floppy Boot Sector.");printf("\n\tM: The same with Command:'Fdisk /mbr'.");printf("\n\tS: Dos shell.");printf("\n\tQ: Exit the programme.");printf("\n Press any key to continue...");getch();sound(2000);delay(2000);nosound();}/* print the mbr */int printmbr(){int count=1;int key;int f=0;closecur();init(M);display(count,&f);while(bioskey(1)==0);key=bioskey(0);while(1){switch(key){case ESC:resetwin();return 1;case HOME:count=1;f=0; break;case END: count=63;f=0; break;case PGUP: case UP: case LEFT: if(count<=1) count=63; elsecount--;f=0; break;case PGDN: case DOWN: case RIGHT: if(count>=63) count=1; elsecount++;f=0; break;case F2:if(f==0){f=1; break;}{f=0;break;}case F1:resetwin();printf("\nIt would save the sector to a file...");if(f){ if(biosdisk(0x02,0x80,head,cylinder,sector,1,buff)!=0) {printf("\nharddisk Dos Boot Sector read error!");break;}}elseif(biosdisk(0x02,0x80,0,0,count,1,buff)){printf("\nHardDisk MBR read error!");break;}infina(fnwrite);if(!fileopen(W,fnwrite))printf("\nFile %s Write error!",fnwrite);else{printf("\nFile %s save OK.",fnwrite);printf("\nPress any key to return...");}break;default:break;}display(count,f);while(bioskey(1)==0);key=bioskey(0);}}/* reset the screen */void resetwin(){opencur();window(1,1,80,25);textcolor(WHITE);textbackground(BLACK);clrscr();}/* put the buffer data to the screen */ int display(int count,int f){int lines,i;resetwin();closecur();i=count;if(f)if(biosdisk(0x02,0x80,head,cylinder,sector,1,buff)){printf("\nHarddisk read error!");resetwin();return 0;}}elseif(biosdisk(0x02,0x80,0,0,count,1,buff)){printf("\nHarddisk read error!");resetwin();return 0;}window(1,25,80,25);textbackground(CYAN);textcolor(WHITE);clrscr();cprintf(" HELP:ESC PGUP PGDN HOME END %c %c %c %c %c ",24,26,25,27,179); textcolor(RED);cprintf("F1");textcolor(WHITE);cprintf(":Save this sector to a file.");cprintf(" 05/01/99");window(1,1,80,1);textbackground(LIGHTGRAY);textcolor(LIGHTGREEN);clrscr();cprintf(" HardDisk C:1 %c 63 Sector",196);cprintf(" ( DOS BOOT SECTOR ) By: Howard.Crystal ");elsecprintf(" (Hard Disk Partition Table) By: Howard.Crystal ");window(1,2,80,24);textbackground(BLUE);textcolor(WHITE);clrscr();gotoxy(1,1);if(!f){cprintf(" Head:%-d Cylinder:%-d Sector:%-d",0,0,i);cprintf(" F2: View Dos Boot Sector\n");}else{cprintf(" Head:%-d Cylinder:%-d Sector:%-d",head,cylinder,sector); cprintf(" F2: View Master Boot Sector\n");}lines=1;gotoxy(1,1);for(i=0;i<512;i++){if(i%24==0){lines++;gotoxy(1,lines);}if(i%4==0)cprintf(" ");if(f)if(buff[510]==0x55 && (buff[511]&0x00ff)==0xaa)if(i>=510){textattr(RED+(BLUE<<4)+BLINK); /* flash the special data */sound(1000);delay(1000);nosound();cprintf("%02x",buff[i]&0x00ff);textcolor(WHITE);}elsecprintf("%02x",buff[i]&0x00ff);elsecprintf("%02x",buff[i]&0x00ff);elseif(buff[510]==0x55 && (buff[511]&0x00ff)==0xaa)if(i>=0x1be && (((i-0x1be)%16==0 && (buff[i]&0x00ff)==0x80) || (buff[i]&0x00ff)==0x55 || (buff[i]&0x00ff)==0xaa)){textattr(RED+(BLUE<<4)+BLINK);cprintf("%02x",buff[i]&0x00ff);sound(1000);delay(1000);nosound();textcolor(WHITE);}elsecprintf("%02x",buff[i]&0x00ff);elsecprintf("%02x",buff[i]&0x00ff); }lines=1;for(i=0;i<512;i++){if(i%24==0)lines++;gotoxy(57+i%24,lines);if(isprint(buff[i]))cprintf("%1c",buff[i]);elsecprintf(".");}return 1;}。
windows sdk编程系列文章29 --- 直接从硬盘扇区读取文件内容.

windows sdk编程系列文章 --- 直接从硬盘扇区读取文件内容2008-09-05 15:43理论:基本概念就是通过文件句柄获取文件所在的簇列表。
然后直接打开硬盘,根据簇所在的位置,直接读取文件数据。
方法1:可以通过打开"\\\\.\\PHYSICALDRIVE0",读取MBR,然后根据MBR中的DPT,找到活动分区的偏移,定位到DBR。
然后将要定位簇的文件打开,获取文件句柄,将文件句柄传递给DeviceIoControl的FSCTL_GET_RETRIEVAL_POINTERS功能,就可以得到RETRIEVAL_POINTERS_BUFFER结构。
方法2:直接打开"\\\\.\\c:"就是定位到DBR了。
然后跟上面同样的操作。
对于一些基本概念,MBR, DPT,DBR,以及fat32和ntfs的文件结构,可以参考下面的链接了解。
/html/magnetism/200806/17-55.html代码:(vc6, ntfs 见光盘DirectAccessFile#define _WIN32_WINNT 0x0400#include#include#includeULONGLONG *GetFileClusters(PCHAR lpFileName,ULONG *ClusterSize,ULONG *ClCount,ULONG *FileSize{HANDLE hFile;ULONG OutSize;ULONG Bytes, Cls, CnCount, r;ULONGLONG *Clusters = NULL;BOOLEAN Result = FALSE;LARGE_INTEGER PrevVCN, Lcn;STARTING_VCN_INPUT_BUFFER InBuf;PRETRIEVAL_POINTERS_BUFFER OutBuf;CHAR Name[7];DWORD SecPerCl;DWORD BtPerSec;Name[0] = lpFileName[0];Name[1] = ':';Name[2] = 0;GetDiskFreeSpace(Name, &SecPerCl, &BtPerSec, NULL, NULL;*ClusterSize = SecPerCl * BtPerSec;hFile = CreateFile(lpFileName, FILE_READ_ATTRIBUTES,FILE_SHARE_READ |FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL, OPEN_EXISTING, 0, 0;if (hFile != INVALID_HANDLE_VALUE{*FileSize = GetFileSize(hFile, NULL;OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER + (*FileSize / *ClusterSize * sizeof(OutBuf->Extents;OutBuf = (RETRIEVAL_POINTERS_BUFFER *malloc(OutSize;InBuf.StartingVcn.QuadPart = 0;if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,sizeof(InBuf, OutBuf, OutSize, &Bytes, NULL{*ClCount = (*FileSize + *ClusterSize - 1 /*ClusterSize;Clusters = (ULONGLONG *malloc(*ClCount *sizeof(ULONGLONG;PrevVCN = OutBuf->StartingVcn;for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++{Lcn = OutBuf->Extents[r].Lcn;for (CnCount = (ULONG(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart;CnCount; CnCount--, Cls++, Lcn.QuadPart++Clusters[Cls] = Lcn.QuadPart;PrevVCN = OutBuf->Extents[r].NextVcn;}}free(OutBuf;CloseHandle(hFile;}return Clusters;}void Read(PCHAR lpSrcName{ULONG ClusterSize, BlockSize;ULONGLONG *Clusters;ULONG ClCount, FileSize, Bytes;HANDLE hDrive;ULONG r;PVOID Buff;LARGE_INTEGER Offset;CHAR Name[7];Clusters = GetFileClusters(lpSrcName, &ClusterSize, &ClCount, &FileSize;if (Clusters{Name[0] = '\\';Name[1] = '\\';Name[2] = '.';Name[3] = '\\';Name[4] = lpSrcName[0];Name[5] = ':';Name[6] = 0;hDrive = CreateFile(Name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0;if (hDrive != INVALID_HANDLE_VALUE{Buff = malloc(ClusterSize;for (r = 0; r < ClCount; r++, FileSize -= BlockSize{Offset.QuadPart = ClusterSize *Clusters[r];SetFilePointer(hDrive, Offset.LowPart,&Offset.HighPart, FILE_BEGIN;ReadFile(hDrive, Buff, ClusterSize,&Bytes, NULL;BlockSize = FileSize < ClusterSize ? FileSize : ClusterSize;}free(Buff;CloseHandle(hDrive;}free(Clusters;}}void main({Read("c:\\windows\\system32\\comctl32.dll";}分析:GetFileClusters 函数用于获取文件占用的簇列表,以及每个簇占用字节数,文件占用的簇数,文件大小等信息。
操作系统课设

函数功能选择:interwindow
Openfloyyp:如果目前为打开软盘, 测试者打开磁盘并记录磁盘参数
Choose=?
=1 =3
physicalDisk: 显 示磁盘相关数据
sectorDump: 读 取 特 定 的磁盘区域的内容
=4
结束程序
=2
sectorWrite: 将 输 入 的 数 据写到指定扇区中去
为了统一,在程序中将输入/输出缓冲区均设为一个扇区大小(512 字节),在读写操作 中以指定 512 字节为读出和写入的字节数。
2.3、函数调用关系图
程序的几个主要函数有: l Iterwindow:完成功能选择。 l openfloppy:打开磁盘并记录磁盘参数。 l physicalDisk:显示磁盘相关数据。 l sectordump:读取特定的磁盘区域的内容。 l sectorwrite:将键人的数据写到指定扇区中去。 l sectorRead:进行实际的读盘操作。 它们构成了程序的基本框架,如图 2.1 所示。
4、运行结果解释
PDF pdfFactory
当应用程序运行时,屏幕会出现一个选择控制界面,提供 3 种可供选择的功能
图 4.1 磁盘读写程序的运行接口
4.1、运行结果
4.1.1、打印出磁盘基本信息:包括磁盘的柱面数、每柱面的磁道数、每扇区的字节数等。 4.2.2、往指定的扇区中执行写入动作:程序会提示输入目标扇区的逻辑扇区号,随后会要 求输入要写入的内容:内容输入完毕后回车即可写入到该扇区;注意这会覆盖掉该扇区原 有的数据。扇区逻辑号范围是从 O 开始到磁盘的最大扇区号;因为每一扇区大小通过前一 功能可以获得,通过磁盘的容量可以大致估计出最大逻辑扇区号。同时应当注意磁盘上的 有些空间存储着磁盘物理信息等,是操作系统不能存取的,这部分空间没有编入逻辑扇区 空间中;也就是说逻辑扇区数比整个磁盘的实际扇区数目要小。对于任何一个逻辑扇区号 代表的磁盘扇区,都可以通过本程序进行读写。 4.3、读取指定逻辑扇区内的内容:该应用程序需要用户输入逻辑扇区号,并将对应扇区的 内容以 AscII 码和十六进制两种方式显示出来;该功能可用来验证功能(2)中的写入操作是 否正确,只需要指定同一个扇区号,看读出的内容是不是所输入的内容即可。由于输入的 内容一般不能装满一个扇区(例如小于 512 字节),所以在显示出来的扇区内容中,后半部 分是写入缓冲区中的初始值内容。
VC中的文件读写操作

VC中的文件读写操作各种关于文件的操作在程序设计中是十分常见,如果能对其各种操作都了如指掌,就可以根据实际情况找到最佳的解决方案,从而在较短的时间内编写出高效的代码,因而熟练的掌握文件操作是十分重要的。
本文将对Visual C++中有关文件操作进行全面的介绍,并对在文件操作中经常遇到的一些疑难问题进行详细的分析。
1.文件的查找当对一个文件操作时,如果不知道该文件是否存在,就要首先进行查找。
MFC中有一个专门用来进行文件查找的类CFileFind,使用它可以方便快捷地进行文件的查找。
下面这段代码演示了这个类的最基本使用方法。
CString strFileTitle;CFileFind finder;BOOL bWorking = finder.FindFile("C:\\windows\\sysbkup\\*.cab");while(bWorking){bWorking=finder.FindNextFile();strFileTitle=finder.GetFileTitle();}2.文件的打开/保存对话框让用户选择文件进行打开和存储操作时,就要用到文件打开/保存对话框。
MFC的类CFileDialog用于实现这种功能。
使用CFileDialog声明一个对象时,第一个BOOL型参数用于指定文件的打开或保存,当为TRUE时将构造一个文件打开对话框,为FALSE时构造一个文件保存对话框。
在构造CFileDialog对象时,如果在参数中指定了OFN_ALLOWMULTISELECT风格,则在此对话框中可以进行多选操作。
此时要重点注意为此CFileDialog对象的m_ofn.lpstrFile 分配一块内存,用于存储多选操作所返回的所有文件路径名,如果不进行分配或分配的内存过小就会导致操作失败。
下面这段程序演示了文件打开对话框的使用方法。
CFileDialog mFileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT, "All Files (*.*)|*.*||",AfxGetMainWnd());CString str(" ",10000);mFileDlg.m_ofn.lpstrFile=str.GetBuffer(10000);str.ReleaseBuffer();POSITION mPos=mFileDlg.GetStartPosition();CString pathName(" ",128);CFileStatus status;while(mPos!=NULL){pathName=mFileDlg.GetNextPathName(mPos);CFile::GetStatus( pathName, status );}3.文件的读写文件的读写非常重要,下面将重点进行介绍。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC++实现Windows下直接读写磁盘扇区
摘要:本文主要介绍了在Windows下对磁盘扇区数据的直接读写访问方法,并在此基础上实现了对磁盘扇区内容的查看、基于扇区的数据备份与恢复、对磁盘信息的彻底擦除等一些有着实际意义的应用。
关键字:磁盘访问;扇区;Windows;VC++
引言
由于Windows 操作系统在很大程度上采取了访问安全保护机制(例如,在Windows操作系统下不能直接访问物理内存、不能使用各种DOS、BIOS中断等等),使得广大程序设计人员在长时间的开发过程中不知不觉地逐渐养成了这样的潜意识——在Windows操作系统下直接操纵硬件设备是极端困难和非常烦琐的,并将其看作Windows编程的一个禁区。
尽管在大多数场合下这样的论断还算是贴切,但也并非对所有的硬件设备访问都那么困难。
其实Windows在采取“实保护”措施的同时也提供了另外的一种有别于在DOS下访问硬件设备的方法,即把所有的硬件设备全部看做“文件”,并允许按照对文件的读写方式来对其进行数据存取访问。
撰写本文的另外一个目的也就是帮助读者打消在Windows环境下对硬件编程的恐惧心理。
对磁盘扇区数据的访问
前面已经提过,在Windows 下把所有的设备当作文件进行操作。
如果对串口进行编程或许不少读者还比较熟悉:对于串行端口1、2,可以用”COM1”、”COM2”作为参数调用CreateFile()函数,这里
的”COM1”、”COM2”即以文件存放路径的方式指出了要操作的硬件设备。
但是如果需要对磁盘的某个扇区进行读写,可能不少读者不会想到使用CreateFile()函数或是不知如何使用。
其实,与对串行端口的访问类似,需要用与文件存放路径相类似的方式指出要操作的硬件设备(硬盘)。
但是这里并不是用“DISK1”、“DISK2”等去标识某一块物理存在的硬盘。
由于逻辑扇区是存在于逻辑分区上的,因此这里需要以某种特定的格式来指定需要访问的磁盘逻辑分区。
对于逻辑分区X,其格式为”\\.\X:”。
HANDLE CreateFile( LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile );
CreateFile()函数原型如上所示,由于访问的是事实上已经存在的磁盘扇区,因此只能以
OPEN_EXISTING标志设置dwCreationDisposition参数指出将要打开已经存在的文件(设备)。
至于其他参数的使用与操作普通文件时的用法相同。
通过CreateFile()打开的是整个磁盘逻辑分区,而要操作的是该分区的某些扇区,因此还要通过SetFilePointer()函数以文件操作的方式把指针移到要操作的磁盘扇区开始处。
SetFilePointer()函数原型为:
DWORD SetFilePointer(HANDLE hFile,
LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh,
DWORD dwMoveMethod);
参数hFile为CreateFile()返回的文件(设备)句柄;lDistanceToMove和lpDistanceToMoveHigh 指出了要设置偏移量的低端和高端部分;dwMoveMethod指出文件指针从何处开始移动,可能的选项有FILE_START(从文件开始)、FILE_END(从文件结尾)和FILE_CURRENT(从文件当前位置)。
在定位到要访问的扇区开始位置后就可以通过ReadFile()或WriteFile()函数实施相应的读写访问了,具体操作与文件读写并没有什么太大的差别。
最后,在完成访问操作后以CloseHandle()关闭文件句柄释放资源,从而完成一次完整的磁盘扇区数据访问操作。
下面给出具体的读、写处理过程:
BOOL CDirectAccessHDDlg::WriteSectors(BYTE bDrive, DWORD dwStartSector, WORD
wSectors, LPBYTE lpSectBuff)
// 对磁盘扇区数据的写入
{
if (bDrive == 0) return 0;
char devName[] = "\\\\.\\A:";
devName[4] ='A' + bDrive - 1;
HANDLE hDev = CreateFile(devName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hDev == INVALID_HANDLE_VALUE) return 0;
SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);
DWORD dwCB;
BOOL bRet = WriteFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);
CloseHandle(hDev);
return bRet;
}
BOOL CDirectAccessHDDlg::ReadSectors(BYTE bDrive, DWORD dwStartSector, WORD
wSectors, LPBYTE lpSectBuff)
// 对磁盘扇区数据的读取
{
if (bDrive == 0) return 0;
char devName[] = "\\\\.\\A:";
devName[4] ='A' + bDrive - 1;
HANDLE hDev = CreateFile(devName, GENERIC_READ, FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hDev == INVALID_HANDLE_VALUE) return 0;
SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);
DWORD dwCB;
BOOL bRet = ReadFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);
CloseHandle(hDev);
return bRet;
磁盘扇区数据直接读写技术的应用
上一步实现了对磁盘扇区数据进行读写访问的核心处理过程。
在此基础上可以完成一些有实用价值的应用,例如,可以实现对指定磁盘分区中指定起止扇区的内容查看:
为了方便数据的显示,可做如下处理以完成格式转换等工作:
显示结果如上图所示。
另外一种应用与之类似,即对磁盘扇区内容的备份与恢复处理。
不少防病毒软件都提供这样的功能:对硬盘引导区内容的备份,一旦硬盘引导扇区被病毒破坏后能够通过对备份数据的写入实现恢复。
备份操作与前面的数据显示操作类似,只是把读取的内容不经格式处理而直接保存到指定的文件中即可:
数据的恢复处理正好与之相反,首先打开备份文件并根据文件长度计算要写的扇区数,然后读取其内容到缓存,最后将其写入到指定扇区完成数据的恢复:
下面将要给出的最后一个应用是对磁盘数据的安全擦除。
众所周知,在操作系统下是通过文件管理系统实现对文件访问管理的。
当删除一个文件时,该文件的全部内容并没有发生任何损坏,如果没有外部数据的覆盖,完全可以通过各种数据恢复软件将先前删除的文件恢复出来。
但在军工、政府等特殊的涉密行业、部门中,要求的是数据的彻底删除,即经删除过的数据是不可进行再恢复处理的。
为了确保磁盘数据的可靠清空,可以对每一个扇区写入全1后再写入全0。
之所以多次写入数据,是因为一次写入只能防止数据恢复软件的恢复处理。
如果覆盖次数不多的化,通过一种被称做“磁盘放大镜”的特殊仪器仍能够以物理的方法将先前删除的数据恢复出来,因此这里需要对扇区多次重复写入数据,反复次数越多擦除效果越好。
下面是这部分的具体实现代码:
小结
本文仅对磁盘扇区内容的直接读写方法做了介绍并给出了扇区数据内容的显示、备份与恢复、磁盘数据的彻底擦除等几个主要的应用作了介绍。
读者可以根据需要实现其他的应用如利用磁盘扇区内容进行身份认证、数据隐藏、磁盘删除数据的恢复等。
本文所述程序代码在Windows Professional + SP4下由Microsoft Visual C++ 6.0编译通过。