最近打算开发一个工具,将我自制的os内核安装到物理磁盘中运行,毕竟在虚拟机上运行与在真实的物理机上运行还是有差别的,同时也方便后续在windows上进行开发试验。前期需要验证一下磁盘绝对扇区读写的可行性。本来尝试用C语言的fopen,fread,fwrite,fclose这一套函数来编写的,但是fwrite一直不成功,最后换成了win32的文件操作api: CreateFile, WriteFile,ReadFile竟然成功了。
实验步骤分三个部分,首先读取磁盘的第一个扇区并打印内容,然后从磁盘第一个扇区开始写入制作好包含系统内核镜像的img文件,最后再次读取磁盘的第一个扇区内容,对比是否写入成功,全部源码如下:

// DiskBuildTool.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>#define DISK      "\\\\.\\PhysicalDrive2"// 参数:输出的字符串指针,开始位置,长度
// 返回值:读取的大小
int ReadDisk(unsigned char* buffer,DWORD start,DWORD size)
{OVERLAPPED over = { 0 };over.Offset = start;HANDLE handle = CreateFile(TEXT(DISK), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);if (handle == INVALID_HANDLE_VALUE){return (-1);}DWORD readsize;if (ReadFile(handle, buffer, size, &readsize, &over) == 0){CloseHandle(handle);return (-1);}  CloseHandle(handle);return readsize;
}//参数:写入字符串指针,开始位置,长度
//返回值:写入的大小
int WriteDisk(unsigned char* buffer,DWORD start,DWORD size)
{OVERLAPPED over = { 0 };over.Offset = start;HANDLE handle = CreateFile(TEXT(DISK), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);if (handle == INVALID_HANDLE_VALUE){return (-1);}DWORD writeensize;if (WriteFile(handle, buffer, size, &writeensize, &over) == 0){CloseHandle(handle);return (-1);}CloseHandle(handle);return writeensize;
}int _tmain(int argc, _TCHAR* argv[])
{unsigned char mbr[512];FILE *f_img;int len = ReadDisk(mbr, 0, 512);   // 读取并打印一个扇区if ( len > 0 ){printf("Read MBR from %s:", DISK);for (int i = 0; i < len/16; i++){printf("\n");for ( int j = 0; j < 16; j++ ){printf("%02X ", mbr[i*16+j]);}}// 将img文件写入磁盘fopen_s(&f_img, "E:\\LoverOS\\arch\\c.img", "rb");if ( !f_img ){perror("fopen()");exit(-1);}unsigned long offset = 0;while( !feof(f_img )){if (fread(mbr,sizeof(mbr),1,f_img) != 1 ){break;}WriteDisk(mbr,offset, 512);offset += 512;}fclose(f_img);}else{perror("");exit(-1);}printf("\n");memset(mbr,0,sizeof(mbr));        len = ReadDisk(mbr, 0, 512);   // 再次读取一个扇区并打印if ( len > 0 ){printf("Read MBR from %s:\n", DISK);for (int i = 0; i < len/16; i++){printf("\n");for ( int j = 0; j < 16; j++ ){printf("%02X ", mbr[i*16+j]);}}printf("\n\nimg to disk done\n");}else{perror("");exit(-1);}return 0;
}

其中需要说明的是

#define DISK     "\\\\.\\PhysicalDrive2"

这个定义的物理磁盘号,编号格式为PhysicalDrivenn,其中最后的n代表物理盘序号,从0开始,第一块磁盘就是PhysicalDrive0,第二块磁盘就是PhysicalDrive1,以此类推,我的电脑系统上一共有3块磁盘,第一块是256G的固态硬盘,第二块是500G的机械盘,因为我的系统分区都是MBR类型, 不敢往这两个磁盘写入数据,万一废了启动不了系统就麻烦了。 因此我用工具制作了一个内存硬盘,效果与真实物理磁盘一样的效果,这里它就是PhysicalDrive2。
实验结果如下
1,读取的第一个扇区:

写入文件后再读取:

镜像文件的第一个扇区数据:

看起来写入后再读取的内容与原文件内容是一致的,实验成功!!!

注意:如果写入失败,可能是由于权限不足导致, 可以尝试把vs以管理员身份运行,或者在vs中按以下配置修改一下工程属性,使得应用获得管理员权限:

到这里,忍不住直接插入一块U盘来试试,直接把

#define DISK     "\\\\.\\PhysicalDrive2"

替换为

#define DISK     "\\\\.\\PhysicalDrive3"

一切顺利!

win32 api读写磁盘物理扇区相关推荐

  1. python读写磁盘扇区数据_[Win32] 直接读写磁盘扇区(磁盘绝对读写)

    正讲着驱动开发呢,这里突然插一篇Win32的博文.事实上.还是做引子,上一篇博文"IRP与派遣函数"中,我们知道了驱动程序须要处理I/O请求.我们先来看看怎么发出一个I/O请求. ...

  2. [Win32] 直接读写磁盘扇区(磁盘绝对读写)

    本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article ...

  3. android手机扇区数据读写,磁盘、SD卡、移动磁盘物理扇区读写

    在Windows下把所有的设备都当作文件进行操作,对磁盘的某个扇区读写,可以使用CreateFile()函数.这里不是用"DISK1"."DISK2"等去标识某 ...

  4. linux磁盘第一个扇区分析,[转]Linux中如何读写硬盘上指定物理扇区

    读指定物理扇区: dd  if=  of=   skip=  bs=512 count=1 写指定物理扇区: dd   if=   of=   seek=  bs=512 count=1 实例: 我们 ...

  5. Linux中如何读写硬盘上指定物理扇区

    读指定物理扇区: dd  if=<源设备>  of=<输出设备或文件>   skip=<指定扇区值>  bs=512 count=1 写指定物理扇区: dd   i ...

  6. python读写磁盘扇区数据有什么用_磁盘存放数据原理 - osc_v8xs2czi的个人空间 - OSCHINA - 中文开源技术交流社区...

    磁盘结构作用数据原理 拓扑图 盘面(side) 模型: 1.磁盘圆形盘面,一个磁盘内含有多个盘面. 2.层叠关系,每个盘面之间不会贴着. 3.第一个盘的正面成为0面,反面为1面:第二个盘正面为2面,反 ...

  7. python读写磁盘扇区数据_linux 读写磁盘扇区

    广告关闭 云服务器1核2G首年99年,还有多款热门云产品满足您的上云需求 为何更改为 4096 字节扇区? 如果您熟悉磁盘结构,就知道磁盘是被分解成扇区 的,大小通常是 512 字节: 所有读写操作均 ...

  8. python读写磁盘扇区数据_C++-如何直接读取Windows磁盘扇区的数据?

    1.通过CreateFile系列来完成 读写扇区可以通过CreateFile打开磁盘逻辑分区,还要通过SetFilePointer以文件操作的方式把指针移到要操作的磁盘扇区开始处,在定位到要访问的扇区 ...

  9. WIN32:API串口通讯实例教程

    WIN32 API串口通讯实例教程   第一节   实现串口通讯的函数及串口编程简介   API函数不仅提供了打开和读写通讯端口的操作方法,还提供了名目繁多的函数以支持对串行通讯的各种操作.常用函数及 ...

最新文章

  1. oracle 触发器的实例(转)
  2. IDEA 2019.2版本下载安装与PJ教程
  3. Java5线程并发库之LOCK(锁)CONDITION(条件)实现线程同步通信
  4. 对话阿里云叔同:释放云价值,让容器成为“普适”技术
  5. ORA-01843 无效的月份的解决方法/NLS_DATE_FORMAT参数
  6. linux 之学习路线
  7. Oracle归档模式与非归档模式设置
  8. fscapture下载收费吗?_如今听歌要收费,下载也要付费,你能接受国内音乐App这种改变吗...
  9. 利用 0DAY 漏洞 CVE-2018-8174 获取windows系统 shell
  10. Navicat Premium 连接 MongoDB 失败: Cannot connect to MongoDB.No suitable servers found: ......
  11. 江苏计算机对口高考分数线,单招好还是高考好|江苏省对口单招 历年分数线是多少?...
  12. android如何增加北斗定位,安卓手机怎么设置北斗导航图文教程
  13. 解析ipa生成plist文件
  14. java apdu读取社保卡_使用javax.smartcardio的用于智能卡的ISO 7816 APDU
  15. 禅与摩托车维修艺术(4)
  16. 程序员后来都干啥去了
  17. 配置虚拟机(VMware Workstation)静态 IP 地址
  18. C++编程练习3--给出年、月、日,计算该日是该年的第几天
  19. Flex 布局 flex-grow 占用空间
  20. 传递函数和状态方程互转

热门文章

  1. 虚拟sntp服务器,配置NTP服务器
  2. 18、包含网关(Inclusive Gateway)
  3. 1011: 【顺序结构】勾股定理
  4. cellranger-atac 操作笔记-1:安装并构建绵羊单细胞ATAC参考基因组
  5. Word中替换回车的办法
  6. mysql的ini文件在哪里_mysql的ini文件在哪?
  7. NC用友 UAP开发问题
  8. Matplotlib库的使用
  9. 【视频】编码基础知识之I帧、P帧、B帧
  10. clickhouse分析:clickhouse jdbc返回failed to respond问题排查