稀疏提交的内存映射文件

前面提到CreateFileMapping创建映射文件
第三个参数主要有三个值PAGE_READONLY,PAGE_READWRITE,PAGE_WRITECOPY 这三个值得意思我就不在做描述了
其实还有SEC_COMMIT,SEC_IMAGE,SEC_NOCACHE,SEC_RESERVE
我想大家应该知道MEM_COMMIT和MEM_RESERVE标志的意思(VirtualAlloc函数,前面有讲),那么SEC_COMMIT和SEC_RESERVE也是差不多的意思,前者是保留进程空间的地址,后者是将地址提交到物理存储器
如果打个比方,使用SEC_RESRVE就是一个空的容器,容器之中并没有的实际的东西,SEC_COMMIT表示容器是满的
这两个标志,只有在创建由系统的页文件支持的内存映射文件时才有效(存储器来自于页文件中),使用起来颇为不便

那么有没有存储器来自于磁盘文件的类似的用法呢,有(要不然就白讲了)
NT文件系统(NTFS)提供了对稀疏文件的支持,看下什么是NTFS吧
这里写图片描述
如果是这种文件系统就支持稀疏文件
下面我们讲讲怎么用吧
1.我们要用系统函数检查是否支持稀疏文件

    memset(g_Volume, 0, MAX_PATH);
    GetCurrentDirectory(MAX_PATH,g_szPath);
    strncpy_s(g_Volume, g_szPath, 3);
    DWORD dwFileSystemFlags = 0;
    bool bOK=GetVolumeInformation(g_Volume, NULL, 0, NULL, NULL, &dwFileSystemFlags, NULL, 0);//获取磁盘信息
    bOK = bOK && (dwFileSystemFlags&FILE_SUPPORTS_SPARSE_FILES);//dwFileSystemFlags&FILE_SUPPORTS_SPARSE_FILES查看标志位判断对稀疏文件的支持

2.创建文件,这次使用CreateFile函数(过于简单我就不说了)
3.使用DeviceIoC

DWORD dw;
bool ret = DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dw, NULL);//FSCTL_SET_SPARSE设置接下来创建的内存映射文件为稀疏文件

4.CreateFileMapping
5.MapViewOfFile得到内存指针,对于稀疏文件,你读每个每个字节内存,它的填充都为0,若是想写入数据,用通常的方法直接对内存赋值即可

使用完了之后,进行一系列的清除操作

这次贴上完整的代码

#include <windows.h>
#include <iostream>
#include <string>
#include <winioctl.h>
using namespace std;
#define FL (1024*1024)
#define FH 0
char g_szPath[MAX_PATH];
char g_Volume[MAX_PATH];
//(3797960)
int main()
{
    //先检查当前磁盘是否支持稀疏文件
    memset(g_Volume, 0, MAX_PATH);
    GetCurrentDirectory(MAX_PATH,g_szPath);
    strncpy_s(g_Volume, g_szPath, 3);
    DWORD dwFileSystemFlags = 0;
    bool bOK=GetVolumeInformation(g_Volume, NULL, 0, NULL, NULL, &dwFileSystemFlags, NULL, 0);//获取磁盘信息
    bOK = bOK && (dwFileSystemFlags&FILE_SUPPORTS_SPARSE_FILES);//dwFileSystemFlags&FILE_SUPPORTS_SPARSE_FILES查看标志位判断对稀疏文件的支持
    if (!bOK)
    {
        //如果系统不支持稀疏文件,就直接关闭程序
        return 1;
    }
    DWORD dw;
    string FileName = "MMF";
    HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    int err = GetLastError();
    if (hFile == INVALID_HANDLE_VALUE)
    {
        cout << "打开文件失败" << endl;
        return 1;
    }
    //bool ret=DeviceIoControl(hFile,FSCTL_SET_SPARSE,NULL,0,NULL,0,&dw,NULL);
    bool ret = DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dw, NULL);//设置稀疏文件
    err = GetLastError();
    if (!ret)
    {
        //err=GetLastError();
        cout << "err no:" << err << endl;
        return 2;
    }
    HANDLE hFileMapping = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024 * 1024, NULL);
    if (!hFileMapping)
    {
        CloseHandle(hFileMapping);
        cout << "创建文件映像失败" << endl;
        return 2;
    }
    PBYTE pFile = (PBYTE)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    UnmapViewOfFile(pFile);
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
    system("pause");
    return 0;
}

创建好的文件时这样子的
这里写图片描述
虽然可以容纳的字节数为1MB,但是由于并没有分配内存,所以,实际大小只有4KB
我们来看看为什么大小为4KB,而不是0KB
文件在磁盘上所占的空间不是已Byte来衡量 的,而是以簇来衡量的
扇区是磁盘最小的物理存储单元,但由于操作系统无法对数目众多的扇区进行寻址,所以操作系统就将相邻的扇区组合在一起,形成一个簇,然后再对簇进行管理
操作系统规定一个簇中只能放置一个文件的内容,因此文件实际所占用的物理空间大小,只能是簇的整数倍;而如果文件实际大小小于一簇,它也要占一簇的空间
也就是说簇是文件存放的基本单位,那么一簇是多少字节呢
这里写图片描述
可以看出,这就是占用4KB的原因

另外对于稀疏文件,哪怕你只对其中的一个字节赋值,系统就会提交分配粒度(64KB)大小的区域到存储器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
http://wangfaqiang.download.csdn.net/ 上面这个网址就可以看到所有7个的下载链接 内容简介   本书从Windows内核编程出发,全面系统地介绍了串口、键盘、磁盘、文件系统、网络等相关的Windows内核模块的编程技术,以及基于这些技术实现的密码保护、防毒引擎、文件加密、网络嗅探、网络防火墙等信息安全软件的核心组件的具体编程。主要知识重点包括:Windows串口与键盘过滤驱动、Windows虚拟存储设备与存储设备过滤驱动、Windows文件系统过滤驱动、文件系统透明加密/解密驱动、Windows各类网络驱动(包括TDI过滤驱动及三类NDIS驱动),以及最新的WDF驱动开发模型。有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000 一直到目前最新的Windows 7 Beta 版。   本书适合大专院校计算机系的学生、普通Windows程序员、Windows内核程序员、信息安全行业的程序员,以及希望了解Windows系统底层知识的计算机编程爱好者使用。阅读本书,需要读者有C语言、数据结构、操作系统和计算机网络的基础知识。 目录: 封面 -25 扉页 -24 内容简介 -23 序 -22 关于本书作者和贡献者 -20 前言 -18 阅读注意 -16 目录 -12 正文 1 第1章 内核上机指导 1 1.1 下载和使用WDK 2 1.1.1 下载安装WDK 2 1.1.2 编写第一个C文件 3 1.1.3 编译一个工程 5 1.2 安装与运行 6 1.2.1 下载一个安装工具 6 1.2.2 运行与查看输出信息 7 1.2.3 在虚拟机中运行 9 1.3 调试内核模块 9 1.3.1 下载和安装WinDbg 9 1.3.2 设置Windows XP 调试执行 10 1.3.3 设置Vista调试执行 11 1.3.4 设置VMWare的管道虚拟串口 11 1.3.5 设置Windows内核符号表 13 1.3.6 实战调试first 14 练习题 16 第2章 内核编程环境及其特殊性 17 2.1 内核编程的环境 18 2.1.1 隔离的应用程序 18 2.1.2 共享的内核空间 19 2.1.3 无处不在的内核模块 20 2.2 数据类型 21 2.2.1 基本数据类型 21 2.2.2 返回状态 22 2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发模型 32 2.6 WDK编程中的特殊点 33 2.6.1 内核编程的主要调用源 33 2.6.2 函数的多线程安全性 34 2.6.3 代码的中断级 36 2.6.4 WDK中出现的特殊代码 37 练习题 38 第3章 串口的过滤 40 3.1 过滤的概念 41 3.1.1 设备绑定的内核API之一 41 3.1.2 设备绑定的内核API之二 43 3.1.3 生成过滤设备并绑定 43 3.1.4 从名字获得设备对象 45 3.1.5 绑定所有串口 46 3.2 获得实际数据 47 3.2.1 请求的区分 47 3.2.2 请求的结局 48 3.2.3 写请求的数据 49 3.3 完整的代码 50 3.3.1 完整的分发函数 50 3.3.2 如何动态卸载 52 3.3.3 完整的代码 53 本章的示例代码 53 练习题 54 第4章 键盘的过滤 56 4.1 技术原理 57 4.1.1 预备知识 57 4.1.2 Windows中从击键到内核 58 4.1.3 键盘硬件原理 60 4.2 键盘过滤的框架 61 4.2.1 找到所有的键盘设备 61 4.2.2 应用设备扩展 64 4.2.3 键盘过滤模块的DriverEntry 65 4.2.4 键盘过滤模块的动态加载 66 4.3 键盘过滤的请求处理 68 4.3.1 通常的处理 68 4.3.2 PNP的处理 69 4.3.3 读的处理 70 4.3.4 读完成的处理 71 4.4 从请求中打印出按键信息 72 4.4.1 从缓冲区中获得KEYBOARD_INPUT_DATA 72 4.4.2 从KEYBOARD_INPUT_DATA中得到键 73 4.4.3 从MakeCode到实际字符 74 4.5 Hook分发函数 75 4.5.1 获得类驱动对象 76 4.5.2 修改类驱动的分发函数指针 77 4.5.3 类驱动之下的端口驱动 78 4.5
本书以详尽资料和大量的范例深入讨论了有关32位Windows编程的高级问题,包括进程和线程的管理、Win32的内存管理、消息处理、动态链接库、文件系统和设备输入输出、结构化异常处理、Unicode等,并重点讨论了Windows 95和Windows NT在实现上的不同之处,其中包含了大量的编程技巧。 本书可供高等院校计算机专业的师生和广大的计算机编程人员使用。----------《Windows高级编程指南(第三版)》 原书: Advanced Windows (3rd Ed) 作者: Jeffrey Richter 译者: 王书洪 刘光明---------- 抽空将书中的C程序用PASCAL写了一遍, 由于水平所限, 可能存在错误, 仅供参考! 感谢网友chinesexing提供PDF电子书! 感谢老朋友savetime兄提供附书代码! 刘麻子 于 05年7月7号----------附上代码列表: CopyData -- 利用WM_COPYDATA跨进程传递数据 VMStat -- 显示虚拟内存状态 VMAlloc -- 使用虚拟内存 (保留、提交、回收、释放) VMMap -- 遍历VMMap.exe进程的虚拟内存空间 DIPS & -- 进入Explorer.exe进程以操作桌面项目 DIPSLib SysInfo -- 显示系统相关信息 MMFShare -- 利用内存映射共享数据 FileRev -- 利用内存映射处理文件 Counter -- 纤程例子 (后台纤程以低优先级作运算) DiskInfo -- 显示本地逻辑驱动器信息 MultInst -- 使用EXE中带有共享属性的PE节存储数据 TInjLib & -- 远程线程装载指定DLL到指定进程空间 ImgWalk LISLab -- 实验"局部输入状态" (Local Input State) TLSStat -- 在EXE模块中使用静态TLS TLSDyn & -- 在DLL模块中使用动态TLS SomeLib ModUse & -- 使用DLL中带有共享属性的PE节存储数据 Module DocStats -- 利用事件对象使多个线程协同工作 (统计文档) Mutexes -- 利用互斥对象使(计算/显示)两个线程同步 DirWalk -- 遍历DirWalk.exe所在磁盘目录树 FileChng -- 监视目录变化 CritSecs -- 利用临界区对象使(计算/显示)两个线程同步 SprMrkt -- 利用互斥对象和信号量对象控制"超市"运转 SEHSum -- 利用SEH机制, 修复堆栈溢出 SEHTerm -- 演示SEH终止处理和异常抛出 SEHExcpt -- 利用SEH机制, 稀疏提交数组内存 SEHSoft -- 抛出自定义异常通知程序清零记录 Bucket -- SWMRG复合同步对象 (单写入/多读取) AlertIO -- 利用"回调通知"进行文件拷贝 (异步&分块) IOCmpPrt -- 利用"完成端口"进行文件拷贝 (异步&分块)
内容简介   本书从Windows内核编程出发,全面系统地介绍了串口、键盘、磁盘、文件系统、网络等相关的Windows内核模块的编程技术,以及基于这些技术实现的密码保护、防毒引擎、文件加密、网络嗅探、网络防火墙等信息安全软件的核心组件的具体编程。主要知识重点包括:Windows串口与键盘过滤驱动、Windows虚拟存储设备与存储设备过滤驱动、Windows文件系统过滤驱动、文件系统透明加密/解密驱动、Windows各类网络驱动(包括TDI过滤驱动及三类NDIS驱动),以及最新的WDF驱动开发模型。有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000 一直到目前最新的Windows 7 Beta 版。   本书适合大专院校计算机系的学生、普通Windows程序员、Windows内核程序员、信息安全行业的程序员,以及希望了解Windows系统底层知识的计算机编程爱好者使用。阅读本书,需要读者有C语言、数据结构、操作系统和计算机网络的基础知识。 目录: 封面 -25 扉页 -24 内容简介 -23 序 -22 关于本书作者和贡献者 -20 前言 -18 阅读注意 -16 目录 -12 正文 1 第1章 内核上机指导 1 1.1 下载和使用WDK 2 1.1.1 下载安装WDK 2 1.1.2 编写第一个C文件 3 1.1.3 编译一个工程 5 1.2 安装与运行 6 1.2.1 下载一个安装工具 6 1.2.2 运行与查看输出信息 7 1.2.3 在虚拟机中运行 9 1.3 调试内核模块 9 1.3.1 下载和安装WinDbg 9 1.3.2 设置Windows XP 调试执行 10 1.3.3 设置Vista调试执行 11 1.3.4 设置VMWare的管道虚拟串口 11 1.3.5 设置Windows内核符号表 13 1.3.6 实战调试first 14 练习题 16 第2章 内核编程环境及其特殊性 17 2.1 内核编程的环境 18 2.1.1 隔离的应用程序 18 2.1.2 共享的内核空间 19 2.1.3 无处不在的内核模块 20 2.2 数据类型 21 2.2.1 基本数据类型 21 2.2.2 返回状态 22 2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发模型 32 2.6 WDK编程中的特殊点 33 2.6.1 内核编程的主要调用源 33 2.6.2 函数的多线程安全性 34 2.6.3 代码的中断级 36 2.6.4 WDK中出现的特殊代码 37 练习题 38 第3章 串口的过滤 40 3.1 过滤的概念 41 3.1.1 设备绑定的内核API之一 41 3.1.2 设备绑定的内核API之二 43 3.1.3 生成过滤设备并绑定 43 3.1.4 从名字获得设备对象 45 3.1.5 绑定所有串口 46 3.2 获得实际数据 47 3.2.1 请求的区分 47 3.2.2 请求的结局 48 3.2.3 写请求的数据 49 3.3 完整的代码 50 3.3.1 完整的分发函数 50 3.3.2 如何动态卸载 52 3.3.3 完整的代码 53 本章的示例代码 53 练习题 54 第4章 键盘的过滤 56 4.1 技术原理 57 4.1.1 预备知识 57 4.1.2 Windows中从击键到内核 58 4.1.3 键盘硬件原理 60 4.2 键盘过滤的框架 61 4.2.1 找到所有的键盘设备 61 4.2.2 应用设备扩展 64 4.2.3 键盘过滤模块的DriverEntry 65 4.2.4 键盘过滤模块的动态加载 66 4.3 键盘过滤的请求处理 68 4.3.1 通常的处理 68 4.3.2 PNP的处理 69 4.3.3 读的处理 70 4.3.4 读完成的处理 71 4.4 从请求中打印出按键信息 72 4.4.1 从缓冲区中获得KEYBOARD_INPUT_DATA 72 4.4.2 从KEYBOARD_INPUT_DATA中得到键 73 4.4.3 从MakeCode到实际字符 74 4.5 Hook分发函数 75 4.5.1 获得类驱动对象 76 4.5.2 修改类驱动的分发函数指针 77 4.5.3 类驱动之下的端口驱动 78 4.5.4 端口驱动和驱动之间的协作机制 79 4.5.5 找到关键的回调函数的条件 80 4.5.6 定义常数和数据结构

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值