本文转载自 星战紫辉 http://www.cppblog.com/rawdata/archive/2009/02/23/74653.html

但C#代码实现为本人原创。https://github.com/SnailDev/SnailDev.EmfParser 欢迎star或fork

关键字: 打印 SPL EMF 文件格式

Windows的假脱机打印会在Windows\System32\spool\PRINERS目录下生成.spl和.shd文件,其中的打印内容存贮在.spl文件中,但是.spl文件格式似乎未公开,那么如何才能将未知的.spl文件剥离成.emf文件呢?

首先,让我们了解一下Windows打印机制,这是微软的官网的一副打印流程图片:

其中ISV是应用软件接口,IHV是硬件接口,左边是XP的打印模型,右边是Vista最新的XPS打印模型,但两者可以互相转换,具有良好的兼容性。不过,这里暂时只关心XP系统的打印过程。

网络打印过程图:

但是这些图似乎还不够详细,那么请看下面一副:(摘录于论文:《基于关键字匹配的打印数据截获系统》):

基本的思路是: 打印过程发生时,GDI模块和打印驱动(由打印机厂商提供)进行基本的数据交换,在假脱机设置环境下,生成打印机命令文件:.spl或.emf文件,作为一个打印池的作业,然后Windows后台打印线程处理打印作业,将数据文件送至打印机打印,打印完删除该打印文件。
好,现在回到正题:.spl文件该如何剥离成.emf呢?看一个例子:
在WinHex中打开一个.spl文件:

参考:  http://www.undocprint.org/formats/winspool/spl 中一些打印结构的定义。
首先,.spl文件都是以0x00010000签名开头,然后一个DWORD 是emf相关区的文件偏移,第3个DWORD是文档描述字符串(UNICODE)的文件偏移,第4个DWORD 描述的是端口说明字符串(UNICODE)。大致结构如下:

文件尾就是这个样子:

当定位到0x50的文件位置,读取2个DWORD数据之后,就是.emf文件开始了。.emf文件格式是公开的,而且非常简单,是一系列EMR_XXX开口结构的紧密排列,通常以EMR_HEADER(0x01)开头,以EMR_EOF(0x0E)结尾。其实我们根本没有必要去解析.emf文件格式,Windows  SDK有专门显示.emf文件的API,3个函数就搞定:
                      HENHMETAFILE hEMF = GetEnhMetaFile("EMF_DumpOK.emf");
                      PlayEnhMetaFile (dc.m_hDC, hEMF, &rc) ; 
                      DeleteEnhMetaFile (hEMF) ;
然后.spl文件还有一些东西,现在还没有解析出来,但是.emf文件已经剥离出来了,后面的可以先不理它。

代码见本人github仓库 https://github.com/SnailDev/SnailDev.EmfParser

C#将.spl剥离成.emf文件格式的更多相关文章

  1. DOS文件转换成UNIX文件格式详解

    转:DOS文件转换成UNIX文件格式详解 由windows平台迁移到unix系统下容易引发的问题:Linux执行脚本却提示No such file or directory dos格式文件传输到uni ...

  2. lucene学习笔记:三,Lucene的索引文件格式

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的一把钥匙. 当我们真正进入到Lucene源代码之中的时候,我们会发现: Lucene的索引过程, ...

  3. Lucene学习总结之三:Lucene的索引文件格式(1)

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的一把钥匙. 当我们真正进入到Lucene源代码之中的时候,我们会发现: Lucene的索引过程, ...

  4. matplotlib画的图保存为emf格式

    在用matplotlib保存图片时,发现不能直接保存为emf格式.百度有人说要先另存为svg格式,再使用INKSCAPE软件转换成emf格式.我试了一下,发现还是不行,后来,发现先用matplotli ...

  5. Lucene学习之四:Lucene的索引文件格式(1)

    本文转载自:http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623597.html Lucene的索引里面存了些什么,如何存放的,也即 ...

  6. dos与unix文件格式之间的转换

    1. VI编辑器中转换 在VI中使用命令 set ff?(fileformat)可以查看文件的格式,使用set ff=dos(unix)可以设置文件的格式 2.使用sed处理(来至http://www ...

  7. Lucene学习总结之三:Lucene的索引文件格式(1) 2014-06-25 14:15 1124人阅读 评论(0) 收藏

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的一把钥匙. 当我们真正进入到Lucene源代码之中的时候,我们会发现: Lucene的索引过程, ...

  8. Python: 把txt文件转换成csv

    最近在项目上需要批量把txt文件转成成csv文件格式,以前是手动打开excel文件,然后导入txt来生产csv文件,由于这已经变成每周需要做的事情,决定用python自动化脚本来实现,思路: 读取文件 ...

  9. dos2unix 将DOS格式转换成NUIX格式

    1.命令功能 dos2unix将windows文件格式转换成unix文件格式. 2.语法格式 dos2unix  file 3.使用范例 [root@localhost ~]# dos2unix wi ...

随机推荐

  1. Mac下VirtualBox共享文件夹设置

    环境:CentOS7.2最小化安装 步骤: 先安装必要软件包 yum install -y gcc gcc-devel gcc-c++ gcc-c++-devel make kernel kernel ...

  2. Frequent Pattern (FP Growth算法)

    FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达 到这样的效果,它采用了一种简洁的数据 ...

  3. OJ的初步了解

    注意源文件的注释可能跟题目不一样. 注意工程文件已有主函数. 注意输出结果还是返回值. 注意带参数的方法不用手动输入. 注意提交的次数的正确率会计入编程能力.

  4. APICloud常用模块

    常用模块 基础 fs db 支付 wxPay aliPay unionPay 消息 ajpush rongCloud2

  5. 多线程编程学习笔记——异步调用WCF服务

    接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...

  6. Emacs编辑器配置

    以前总是用的vim编辑器,今天突然想换emacs 用下.折腾了很久终于搞定.使用的是windows测试环境 emacs下载地址http://ftp.gnu.org/gnu/emacs/windows/ ...

  7. Java Web项目(Extjs)报错七

    1.Java Web项目(Extjs)报错七 具体报错如下:

  8. java.lang.IllegalArgumentException: Document base E:\Eclipse\workspace\.metadata\.plugins\org.eclips

    1.错误描述 四月 13, 2015 5:56:55 下午 org.apache.catalina.core.AprLifecycleListener init 信息: The APR based A ...

  9. directX根据设备类GUID查询所属的filter

    hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0);    ASSERT(SUCCEEDED(hr));    ...

  10. 提取DirectShow中视频采集的数据

    DirectShow中,数据流(Data Flow)都是依次流过各个Filter的.它对数据的管理也有自己的方法,而且并没有向用户提供一个统一的接口,供用户操作数据流.这里以提取视频采集在的每帧为位图 ...