C#將.spl剝離成.emf文件格式


本文轉載自 星戰紫輝 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM