• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            星綻紫輝(rawdata)的Blog

            快樂地學(xué)習(xí),快樂地工作!

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              16 Posts :: 0 Stories :: 37 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(5)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

                           
                         原創(chuàng): 星戰(zhàn)紫輝  http://www.shnenglu.com/rawdata 2009-2-23

                         關(guān)鍵字: 打印 SPL EMF 文件格式   

                         問題:

                         Windows的假脫機(jī)打印會(huì)在Windows\System32\spool\PRINERS目錄下生成.spl和.shd文件,其中的打印內(nèi)

            容存貯在.spl文件中,但是.spl文件格式似乎未公開,那么如何才能將未知的.spl文件剝離成.emf文件呢?

                          首先,讓我們了解一下Windows打印機(jī)制:

                          這是微軟的官網(wǎng)的一副打印流程圖片:

                          

                          其中ISV是應(yīng)用軟件接口,IHV是硬件接口,左邊是XP的打印模型,右邊是Vista最新的XPS打印模

            型,但兩者可以互相轉(zhuǎn)換,具有良好的兼容性。不過,這里暫時(shí)只關(guān)心XP系統(tǒng)的打印過程。

                         網(wǎng)絡(luò)打印過程圖:
                          
                         
                        

                         但是這些圖似乎還不夠詳細(xì),那么請(qǐng)看下面一副:(摘錄于論文:《基于關(guān)鍵字匹配的打印數(shù)據(jù)截獲

            系統(tǒng)》):

                         

                            基本的思路是: 打印過程發(fā)生時(shí),GDI模塊和打印驅(qū)動(dòng)(由打印機(jī)廠商提供)進(jìn)行基本的數(shù)據(jù)交換,在假

            脫機(jī)設(shè)置環(huán)境下,生成打印機(jī)命令文件:.spl或.emf文件,作為一個(gè)打印池的作業(yè),然后Windows后臺(tái)打印線

            程處理打印作業(yè),將數(shù)據(jù)文件送至打印機(jī)打印,打印完刪除該打印文件。


                            好,現(xiàn)在回到正題:.spl文件該如何剝離成.emf呢?看一個(gè)例子:

                            在WinHex中打開一個(gè).spl文件:

                           
                           參考:  http://www.undocprint.org/formats/winspool/spl 中一些打印結(jié)構(gòu)的定義。

                          首先,.spl文件都是以0x00010000簽名開頭,然后一個(gè)DWORD 是emf相關(guān)區(qū)的文件偏移,第3個(gè)

            DWORD是文檔描述字符串(UNICODE)的文件偏移,第4個(gè)DWORD 描述的是端口說明字符串(UNICODE)。大

            致結(jié)構(gòu)如下:

                          

                        文件尾就是這個(gè)樣子:
                
                       

                       當(dāng)定位到0x50的文件位置,讀取2個(gè)DWORD數(shù)據(jù)之后,就是.emf文件開始了。.emf文件格式是公開的,而

            且非常簡(jiǎn)單,是一系列EMR_XXX開口結(jié)構(gòu)的緊密排列,通常以EMR_HEADER(0x01)開頭,以EMR_EOF

            (0x0E)結(jié)尾。其實(shí)我們根本沒有必要去解析.emf文件格式,Windows  SDK有專門顯示.emf文件的API,3個(gè)函數(shù)就

            搞定:

                                  HENHMETAFILE hEMF = GetEnhMetaFile("EMF_DumpOK.emf");
                                  PlayEnhMetaFile (dc.m_hDC, hEMF, &rc) ;  
                                  DeleteEnhMetaFile (hEMF) ;


            然后.spl文件還有一些東西,我現(xiàn)在還沒有解析出來,但是.emf文件已經(jīng)剝離出來了,后面的可以先不理它。

                              然后,開始寫程序嘍,因?yàn)楸容^簡(jiǎn)單,所以代碼有點(diǎn)隨便哦~~:)
                            
                              http://www.shnenglu.com/rawdata/ 星綻紫輝

                              程序截圖如下:
              
                             





              1
              2
              3#include <windows.h>
              4#include <winspool.h>
              5#include <stdio.h>
              6#include   <locale.h>   
              7#include <tchar.h>
              8#include <iostream>
              9using namespace std;
             10
             11
             12BOOL AnalyseFile(const char* pszFileName);
             13
             14void PFT(const char* pszInfo,DWORD dwData)
             15{
             16    printf("%s: 0x%08X\n",pszInfo,dwData);
             17}

             18
             19void PFM(const char* pszInfo)
             20{
             21    printf("%s\n",pszInfo);
             22}

             23
             24void UPFM(const wchar_t pszInfo[])
             25{
             26    wprintf(L"%s\n",pszInfo);
             27}

             28
             29static char* ID_Func[] =
             30{
             31"EMR_HEADER",
             32"EMR_POLYBEZIER",
             33"EMR_POLYGON",
             34"EMR_POLYLINE",
             35"EMR_POLYBEZIERTO",
             36"EMR_POLYLINETO",
             37"EMR_POLYPOLYLINE",
             38"EMR_POLYPOLYGON",
             39"EMR_SETWINDOWEXTEX",         
             40"EMR_SETWINDOWORGEX",         
             41"EMR_SETVIEWPORTEXTEX",        
             42"EMR_SETVIEWPORTORGEX",        
             43"EMR_SETBRUSHORGEX",            
             44"EMR_EOF",                       
             45"EMR_SETPIXELV",                 
             46"EMR_SETMAPPERFLAGS",           
             47"EMR_SETMAPMODE",               
             48"EMR_SETBKMODE",                  
             49"EMR_SETPOLYFILLMODE",            
             50"EMR_SETROP2",                   
             51"EMR_SETSTRETCHBLTMODE",          
             52"EMR_SETTEXTALIGN",               
             53"EMR_SETCOLORADJUSTMENT",        
             54"EMR_SETTEXTCOLOR",              
             55"EMR_SETBKCOLOR",                
             56"EMR_OFFSETCLIPRGN",            
             57"EMR_MOVETOEX",                  
             58"EMR_SETMETARGN",                 
             59"EMR_EXCLUDECLIPRECT",          
             60"EMR_INTERSECTCLIPRECT",          
             61"EMR_SCALEVIEWPORTEXTEX",        
             62"EMR_SCALEWINDOWEXTEX",           
             63"EMR_SAVEDC",                     
             64"EMR_RESTOREDC",                  
             65"EMR_SETWORLDTRANSFORM",         
             66"EMR_MODIFYWORLDTRANSFORM",       
             67"EMR_SELECTOBJECT",               
             68"EMR_CREATEPEN",                   
             69"EMR_CREATEBRUSHINDIRECT",       
             70"EMR_DELETEOBJECT",               
             71"EMR_ANGLEARC",                    
             72"EMR_ELLIPSE",                   
             73"EMR_RECTANGLE",                  
             74"EMR_ROUNDRECT",                
             75"EMR_ARC",                        
             76"EMR_CHORD",                     
             77"EMR_PIE",                        
             78"EMR_SELECTPALETTE",            
             79"EMR_CREATEPALETTE",               
             80"EMR_SETPALETTEENTRIES",           
             81"EMR_RESIZEPALETTE",              
             82"EMR_REALIZEPALETTE",              
             83"EMR_EXTFLOODFILL",               
             84"EMR_LINETO",                     
             85"EMR_ARCTO",                      
             86"EMR_POLYDRAW",                  
             87"EMR_SETARCDIRECTION",          
             88"EMR_SETMITERLIMIT",              
             89"EMR_BEGINPATH",                
             90"EMR_ENDPATH",                  
             91"EMR_CLOSEFIGURE",               
             92"EMR_FILLPATH",                   
             93"EMR_STROKEANDFILLPATH",           
             94"EMR_STROKEPATH",               
             95"EMR_FLATTENPATH",               
             96"EMR_WIDENPATH",                  
             97"EMR_SELECTCLIPPATH",             
             98"EMR_ABORTPATH",
             99"69--Unknown",
            100
            101"EMR_GDICOMMENT",
            102"EMR_FILLRGN",
            103"EMR_FRAMERGN",
            104"EMR_INVERTRGN",
            105"EMR_PAINTRGN ",
            106"EMR_EXTSELECTCLIPRGN",
            107"EMR_BITBLT ",
            108"EMR_STRETCHBLT",
            109"EMR_MASKBLT",
            110"EMR_PLGBLT",
            111"EMR_SETDIBITSTODEVICE",
            112"EMR_STRETCHDIBITS",
            113"EMR_EXTCREATEFONTINDIRECTW",
            114"EMR_EXTTEXTOUTA ",
            115"EMR_EXTTEXTOUTW",
            116"EMR_POLYBEZIER16",
            117"EMR_POLYGON16 ",
            118"EMR_POLYLINE16 ",
            119"EMR_POLYBEZIERTO16",
            120"EMR_POLYLINETO16 ",
            121"EMR_POLYPOLYLINE16",
            122"EMR_POLYPOLYGON16",
            123"EMR_POLYDRAW16 ",
            124"EMR_CREATEMONOBRUSH ",
            125"EMR_CREATEDIBPATTERNBRUSHPT",
            126"EMR_EXTCREATEPEN",
            127"EMR_POLYTEXTOUTA ",
            128"EMR_POLYTEXTOUTW",
            129"EMR_SETICMMODE  ",
            130"EMR_CREATECOLORSPACE",
            131"EMR_SETCOLORSPACE ",
            132"EMR_DELETECOLORSPACE ",
            133"EMR_GLSRECORD ",
            134"EMR_GLSBOUNDEDRECORD",
            135"EMR_PIXELFORMAT",
            136"EMR_RESERVED_105 ",
            137"EMR_RESERVED_106 ",
            138"EMR_RESERVED_107",
            139"EMR_RESERVED_108 ",
            140"EMR_RESERVED_109",
            141"EMR_RESERVED_110 ",
            142"EMR_COLORCORRECTPALETTE",
            143"EMR_SETICMPROFILEA ",
            144"EMR_SETICMPROFILEW ",
            145"EMR_ALPHABLEND",
            146"EMR_SETLAYOUT ",
            147"EMR_TRANSPARENTBLT",
            148"EMR_RESERVED_117 ",
            149"EMR_GRADIENTFILL",
            150"EMR_RESERVED_119 ",
            151"EMR_RESERVED_120",
            152"EMR_COLORMATCHTOTARGETW",
            153"EMR_CREATECOLORSPACEW"
            154}
            ;
            155
            156int main()
            157{
            158    setlocale(LC_ALL,"");   
            159
            160    const char* pszFileName = "C:\\Documents and Settings\\joe\\桌面\\1\\00053.SPL";
            161
            162    if(!AnalyseFile(pszFileName))
            163        PFM("Analyse File Failed!");
            164    else
            165        PFM("Analyse File Successed Completed!");
            166
            167    return 0;
            168}

            169
            170
            171BOOL AnalyseFile(const char* pszFileName)
            172{
            173    BOOL bRet = FALSE;
            174
            175    DWORD dwStartPos = 0;
            176
            177    FILE* pFile = fopen(pszFileName,"rb");
            178
            179    if(!pFile)
            180    {
            181        PFM("Open File Failed!");
            182        return bRet;
            183    }

            184
            185    PFM("Begin Analyse");
            186
            187    PFM("[1] Begin to read SPL HeaderInfo:");
            188
            189    /* =======================Headers================================ */
            190    DWORD dwTmp = 0;
            191
            192    fseek(pFile,0,0);
            193
            194    fread(&dwTmp,sizeof(DWORD),1,pFile);
            195
            196    PFT("簽名",dwTmp);
            197
            198
            199    fread(&dwTmp,sizeof(DWORD),1,pFile);
            200
            201    dwStartPos = dwTmp;
            202
            203    PFT("正文信息偏移:",dwTmp);
            204
            205    fread(&dwTmp,sizeof(DWORD),1,pFile);
            206
            207    PFT("文檔信息偏移(UNICODE):",dwTmp);
            208
            209    long pos = ftell(pFile);
            210
            211    fseek(pFile,dwTmp,SEEK_SET);
            212
            213    wchar_t pszInfo[256= {0};
            214    pszInfo[0= L'(';
            215    
            216    WORD wTmp;
            217    for(int i = 1;;i++)
            218    {
            219        fread(&wTmp,sizeof(wTmp),1,pFile);
            220
            221        if(!wTmp)
            222            break;
            223
            224        memcpy((char*)&pszInfo[i],&wTmp,sizeof(wTmp));
            225    }

            226    pszInfo[i] = L')';
            227    UPFM(pszInfo);
            228
            229    fseek(pFile,pos,SEEK_SET);
            230
            231    fread(&dwTmp,sizeof(DWORD),1,pFile);
            232
            233    PFT("打印端口信息偏移(UNICODE):",dwTmp);
            234
            235    fseek(pFile,dwTmp,SEEK_SET);
            236
            237    memset(pszInfo,0,sizeof(wchar_t)*256);
            238    pszInfo[0= L'(';
            239    for(i = 1;;i++)
            240    {
            241        fread(&wTmp,sizeof(wTmp),1,pFile);
            242
            243        if(!wTmp)
            244            break;
            245
            246        memcpy((char*)&pszInfo[i],&wTmp,sizeof(wTmp));
            247    }

            248    pszInfo[i] = L')';
            249    UPFM(pszInfo);
            250
            251    /* ======================== Unknown datas ================================= */
            252    PFM("[2] Begin to read SPL Unknown Datas:");
            253
            254    fseek(pFile,dwStartPos,SEEK_SET);
            255
            256    fread(&dwTmp,sizeof(DWORD),1,pFile);
            257
            258    PFT("未知數(shù)據(jù)",dwTmp);
            259
            260    fread(&dwTmp,sizeof(DWORD),1,pFile);
            261
            262    PFT("未知數(shù)據(jù)",dwTmp);
            263
            264    /* ======================== Record datas ================================= */
            265    PFM("[3] Begin to read Record Datas:");
            266
            267    DWORD dwTmp2 = 0;
            268    for(int i=0;;i++)
            269    {
            270        pos = ftell(pFile);
            271
            272        fread(&dwTmp,sizeof(DWORD),1,pFile);
            273
            274        fread(&dwTmp2,sizeof(DWORD),1,pFile);
            275
            276        
            277        printf("index: (%04d)  type: 0x%04X  size: %04d  0x%08X (%s)\n",i,dwTmp,dwTmp2,pos,ID_Func[dwTmp-1]);
            278
            279//        printf("位置: %08X",pos);
            280
            281//        printf("(%s)\n",ID_Func[dwTmp]);
            282
            283        if(dwTmp == 0x0E)
            284        {
            285//            printf("index: (%04d)  type: 0x%04X  size: %04d  0x%08X  (End)\n",i,dwTmp,dwTmp2,pos,);
            286            PFM("End of Record Datas.");
            287            break;
            288        }

            289
            290        fseek(pFile,pos+dwTmp2,SEEK_SET);
            291    }

            292
            293    if(pFile) fclose(pFile);
            294    bRet = TRUE;
            295
            296    return bRet;
            297}

            298
            299
            300
            301
            302
            303
            304
            305
            306
            307
            308
            309
              
                          有了以上的分析,你應(yīng)該很容易寫一個(gè)spl To  EMF 文件格式的程序了。

                          如果代碼有什么謬誤或者Bug,請(qǐng)留言或者EmailToMe:  xiaolu69soft@yahoo.com.cn

                         祝你好運(yùn)~


                          rawdata
                           
                  

            posted on 2009-02-23 10:08 星綻紫輝 閱讀(8161) 評(píng)論(10)  編輯 收藏 引用

            Feedback

            # re: 如何將.spl剝離成.emf文件格式 2009-03-04 17:04
            好,頂一下  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 2009-03-04 19:26 星綻紫輝
            thx~  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 2010-05-26 10:21
            你好,你能將:《基于關(guān)鍵字匹配的打印數(shù)據(jù)截獲系統(tǒng)》這篇論文發(fā)給我嗎
            我的郵箱:fangyinyao@126.com  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 2010-07-23 16:30 wang li
            你好,很有內(nèi)容的文章,能將你的這篇論文也發(fā)給我嗎
            我的郵箱:iamalaa@126.com
            多謝~  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 2010-07-25 23:06 星綻紫輝
            @wang li
            我手頭上沒有完整的版本,是在網(wǎng)上搜到的,希望對(duì)你有幫助。  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 2010-07-25 23:06 星綻紫輝
            @方
            我手頭上沒有完整的版本,是在網(wǎng)上搜到的,希望對(duì)你有幫助。  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 [未登錄] 2014-01-03 09:37 dd
            想要這個(gè)程式,怎么聯(lián)系你,我的QQ號(hào)是1079436838  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 2014-12-02 16:31 申麗玲
            我在虛擬機(jī)上生成的SPL可以生成EMF文件, 但是安裝到我的電腦以后, 用國(guó)外的SPL Viewer 也說是invalid SPL File 是為什么呢?  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 2014-12-04 08:24 申麗玲
            我的電腦生成的SPL文件是raw格式的? 修改打印處理器為winprint emf格式也不好使。怎么才能導(dǎo)出emf的SPL格式呢?  回復(fù)  更多評(píng)論
              

            # re: 如何將.spl剝離成.emf文件格式 2015-07-22 16:57 dabao
            在嗎?樓主現(xiàn)在的新聯(lián)系方式有嗎?  回復(fù)  更多評(píng)論
              


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            日韩精品久久久肉伦网站| 精品少妇人妻av无码久久| 久久香蕉超碰97国产精品| 岛国搬运www久久| 麻豆成人久久精品二区三区免费 | 久久国产成人| 狠狠色婷婷久久一区二区三区| 免费一级做a爰片久久毛片潮| 久久91综合国产91久久精品| 久久亚洲sm情趣捆绑调教| 国产精品欧美亚洲韩国日本久久| 久久天天躁狠狠躁夜夜avapp| 久久99国产精品久久99小说| 韩国三级中文字幕hd久久精品| 国产麻豆精品久久一二三| 97精品依人久久久大香线蕉97| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 亚洲国产精品无码久久一区二区| 久久久久久国产精品无码下载| 精品亚洲综合久久中文字幕| 久久精品www人人爽人人| 久久国产欧美日韩精品| 亚洲人成网站999久久久综合| 久久久久久久国产免费看| 精品久久久无码中文字幕| 久久久中文字幕| 99久久人妻无码精品系列蜜桃| 久久久无码精品亚洲日韩蜜臀浪潮| 久久久久亚洲AV片无码下载蜜桃| 色综合合久久天天给综看| 久久亚洲国产成人影院网站| 久久无码一区二区三区少妇 | 久久青青草视频| 最新久久免费视频| 思思久久99热只有频精品66| 一级做a爰片久久毛片毛片| 亚洲欧美另类日本久久国产真实乱对白 | 久久精品无码一区二区日韩AV| 精品久久久久一区二区三区| 久久久久国产亚洲AV麻豆| 亚洲午夜无码久久久久小说|