2

I'm working on a project that aims at monitoring print jobs. I'm copying spl and shd files from spool folder to a temporary folder and trying to parse the to get data I want such as number of printed pages, owner, date and time...

I'm using the following code to parse spooler spl files (get the emf file structure)

#include "stdafx.h"
#include <windows.h>
#include <winspool.h>
#include <stdio.h>
#include <locale.h>   
#include <tchar.h>
#include <iostream>
using namespace std;

BOOL AnalyseFile(const char* pszFileName);

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

 static char* ID_Func[] =
{ 
    "EMF_HEADER", "EMF_POLYBEZIER", /*....*/
};

int main()
{
    setlocale(LC_ALL,"");   

    const char* pszFileName = "~MyTempFolder\\00031.SPL";

    if(!AnalyseFile(pszFileName))
        printf("Analyse File Failed!");
    else
        printf("Analyse File Successed Completed!");

    return 0;
}


BOOL AnalyseFile(const char* pszFileName)
{
    BOOL bRet = FALSE;

    DWORD dwStartPos = 0;
    FILE * f ;
    f = fopen("log.txt", "w");
    FILE* pFile = fopen(pszFileName,"rb");

    if(!pFile)
    {
        fprintf(f,"Open File Failed!");
        return bRet;
    }

    /* =======================Headers================================ */
    DWORD dwTmp = 0;

    fseek(pFile,0,0);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    dwStartPos = dwTmp;

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    long pos = ftell(pFile);

    fseek(pFile,dwTmp,SEEK_SET);

    wchar_t pszInfo[256] = {0};
    pszInfo[0] = L'(';

    WORD wTmp;
    int i;
   for( i = 1;;i++)
    {
        fread(&wTmp,sizeof(wTmp),1,pFile);

        if(!wTmp)
            break;

        memcpy((char*)&pszInfo[i],&wTmp,sizeof(wTmp));
    }
    pszInfo[i] = L')';
    UPFM(pszInfo);

    fseek(pFile,pos,SEEK_SET);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    fseek(pFile,dwTmp,SEEK_SET);

    memset(pszInfo,0,sizeof(wchar_t)*256);
    pszInfo[0] = L'(';
    for(i = 1;;i++)
    {
        fread(&wTmp,sizeof(wTmp),1,pFile);

        if(!wTmp)
            break;

        memcpy((char*)&pszInfo[i],&wTmp,sizeof(wTmp));
    }
    pszInfo[i] = L')';
    UPFM(pszInfo);

    /* ======================== Unknown datas ================================= */
    fseek(pFile,dwStartPos,SEEK_SET);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    /* ======================== Record datas ================================= */
     DWORD dwTmp2 = 0;
    for(int i=0;;i++)
    {
        pos = ftell(pFile);

        fread(&dwTmp,sizeof(DWORD),1,pFile);

        fread(&dwTmp2,sizeof(DWORD),1,pFile);
        FILE *f;
        f = fopen("log.txt", "a");

        fprintf(f,"index: (%04d)  type: 0x%04X  size: %04d  0x%08X (%s)\n",i,dwTmp,dwTmp2,pos,ID_Func[dwTmp-1]);
        fclose (f);

        if(dwTmp == 0x0E)
        {
            break;
        }

        fseek(pFile,pos+dwTmp2,SEEK_SET);
    }
    fclose (f);
    if(pFile) fclose(pFile);
    bRet = TRUE;

    return bRet;
}

Is there a way to calculate page count of the spl file with this method?

2 Answers2

0

To calculate pages you have to count PAGE headers.

Here is a part of code which does it

 SpoolFilename = Path.ChangeExtension(SpoolFilename, ".SPL")

    '\\ Open a binary reader for the spool file
    Dim SpoolFileStream As New System.IO.FileStream(SpoolFilename, FileMode.Open, FileAccess.Read)
    Dim SpoolBinaryReader As New BinaryReader(SpoolFileStream, System.Text.Encoding.UTF8)

    'Read the spooler records and count the total pages
    Dim recNext As EMFMetaRecordHeader = NextHeader(SpoolBinaryReader)
    While recNext.iType <> SpoolerRecordTypes.SRT_EOF
        If recNext.iType = SpoolerRecordTypes.SRT_PAGE Then
            _Pages += 1
        End If
        'SpoolfileReaderPerformaceCounter.Increment()
        Call SkipAHeader(recNext, SpoolBinaryReader)
        recNext = NextHeader(SpoolBinaryReader)
    End While

Code gets filename, opens binary stream for it, and read header after header. If header code is SRT_PAGE, increment pages counter.

more details and source here

DevOvercome
  • 151
  • 1
  • 12
0

Here is how you do it in C++

struct EMFMetaRecordHeader {
    long Seek;
    SpoolerRecordTypes iType;
    int Size;
};  

if (splfile)
{
    EMFMetaRecordHeader recNext = NextHeader(splfile);
    while (recNext.iType != SpoolerRecordTypes::SRT_EOF)
    {
        if (recNext.iType == SpoolerRecordTypes::SRT_PAGE)
        {
            nPages++;
        }
        recNext = NextHeader(splfile);

    }

    nEmf_record_code = 0;
}

EMFMetaRecordHeader EMFSpoolfileReader::NextHeader(FILE* splfile){
EMFMetaRecordHeader recRet;
recRet.Seek = ftell(splfile);

fread(&recRet.iType, sizeof(int), 1, splfile);
if (feof(splfile))
{
    recRet.iType = SpoolerRecordTypes::SRT_EOF;
    return recRet;
}
fread(&recRet.Size, sizeof(int), 1, splfile);

return recRet;
}

splfile is a spool file pointer

more details and source here