32位和64位SHD文件?

时间:2018-10-11 10:54:16

标签: c# windows spooler

所以这让我完全发疯了。我似乎无法获得.SHD文件的正确数据。

它来自一台64位计算机,而我正在使用的库似乎只能在32位上运行(尽管我不敢相信)。

标头记录代码如下:

net use

然后在我拥有的影子文件类中,发生以下情况:

private HeaderRecord ParseHeaderRecord(){             var headerRecord = new HeaderRecord {stSubmitTime = new SYSTEMTIME()};

[StructLayout(LayoutKind.Sequential)]
internal struct HeaderRecord {
    public int dwHeaderSize;
    public int dwJobID;
    public int dwPageCount;
    public int dwPriority;
    public int dwSignature;
    public int dwSizeSecurityInfo;
    public int dwSizeSPL;
    public int dwSPLSize2;
    public int dwStartTime;
    public int dwUnknown2;
    public int dwUnknown3;
    public int dwUnknown4;
    public int dwUnknown5;
    public int dwUntilTime;
    public int offComputername;
    public int offDataFormat;
    public int offDevMode;
    public int offDocumentName;
    public int offDriverName;
    public int offNotifyName;
    public int offPort;
    public int offPrinterName;
    public int offPrintProcessor;
    public int offSecurityInfo;
    public int offUserName;
    public SYSTEMTIME stSubmitTime;
    public short wStatus;
    public short wUnknown1;
}

public enum ShadowSignature {
    SHD_SIGNATURE_WIN2000 = 0x4967,
    SHD_SIGNATURE_WIN2003 = 0x4968,
    SHD_SIGNATURE_WIN98 = 0x494b,
    SHD_SIGNATURE_WINNT = 0x4966
}

然后,这就是全部解析:

        binaryReader.BaseStream.Position = 0L;
        headerRecord.dwSignature = binaryReader.ReadInt32();
        var dwSignature = (ShadowSignature)headerRecord.dwSignature;
        if (dwSignature >= ShadowSignature.SHD_SIGNATURE_WIN2000) {
            headerRecord.dwHeaderSize = binaryReader.ReadInt32();
        }
        headerRecord.wStatus = binaryReader.ReadInt16();
        headerRecord.wUnknown1 = binaryReader.ReadInt16();
        headerRecord.dwJobID = binaryReader.ReadInt32();
        headerRecord.dwPriority = binaryReader.ReadInt32();
        headerRecord.offUserName = binaryReader.ReadInt32();
        headerRecord.offNotifyName = binaryReader.ReadInt32();
        headerRecord.offDocumentName = binaryReader.ReadInt32();
        headerRecord.offPort = binaryReader.ReadInt32();
        headerRecord.offPrinterName = binaryReader.ReadInt32();
        headerRecord.offDriverName = binaryReader.ReadInt32();
        headerRecord.offDevMode = binaryReader.ReadInt32();
        headerRecord.offPrintProcessor = binaryReader.ReadInt32();
        headerRecord.offDataFormat = binaryReader.ReadInt32();
        headerRecord.dwUnknown2 = binaryReader.ReadInt32();
        headerRecord.stSubmitTime.wYear = binaryReader.ReadUInt16();
        headerRecord.stSubmitTime.wMonth = binaryReader.ReadUInt16();
        headerRecord.stSubmitTime.wDayOfWeek = binaryReader.ReadUInt16();
        headerRecord.stSubmitTime.wDay = binaryReader.ReadUInt16();
        headerRecord.stSubmitTime.wHour = binaryReader.ReadUInt16();
        headerRecord.stSubmitTime.wMinute = binaryReader.ReadUInt16();
        headerRecord.stSubmitTime.wSecond = binaryReader.ReadUInt16();
        headerRecord.stSubmitTime.wMilliseconds = binaryReader.ReadUInt16();
        headerRecord.dwStartTime = binaryReader.ReadInt32();
        headerRecord.dwUntilTime = binaryReader.ReadInt32();
        headerRecord.dwSizeSPL = binaryReader.ReadInt32();
        headerRecord.dwPageCount = binaryReader.ReadInt32();
        headerRecord.dwSizeSecurityInfo = binaryReader.ReadInt32();
        headerRecord.offSecurityInfo = binaryReader.ReadInt32();
        headerRecord.dwUnknown3 = binaryReader.ReadInt32();
        if (dwSignature >= ShadowSignature.SHD_SIGNATURE_WINNT) {
            headerRecord.dwUnknown4 = binaryReader.ReadInt32();
            headerRecord.dwUnknown5 = binaryReader.ReadInt32();
        }
        if (dwSignature >= ShadowSignature.SHD_SIGNATURE_WIN2000) {
            headerRecord.offComputername = binaryReader.ReadInt32();
            headerRecord.dwSPLSize2 = binaryReader.ReadInt32();
        }


        return headerRecord;
    }

其中的ReadString函数为:

        HeaderRecord headerRecord = this.ParseHeaderRecord();

        this.devMode = ParsingHelper.ExtractDevMode(binaryReader, headerRecord.offDevMode);

        this.jobID = headerRecord.dwJobID;
        this.priority = headerRecord.dwPriority;
        this.userName = ParsingHelper.ReadString(binaryReader, headerRecord.offUserName);
        this.notifyName = ParsingHelper.ReadString(binaryReader, headerRecord.offNotifyName);
        this.documentName = ParsingHelper.ReadString(binaryReader, headerRecord.offDocumentName);
        this.port = ParsingHelper.ReadString(binaryReader, headerRecord.offPort);
        this.printerName = ParsingHelper.ReadString(binaryReader, headerRecord.offPrinterName);
        this.driverName = ParsingHelper.ReadString(binaryReader, headerRecord.offDriverName);
        this.printProcessor = ParsingHelper.ReadString(binaryReader, headerRecord.offPrintProcessor);
        this.dataFormat = ParsingHelper.ReadString(binaryReader, headerRecord.offDataFormat);
        this.submitted = new DateTime(headerRecord.stSubmitTime.wYear, headerRecord.stSubmitTime.wMonth, headerRecord.stSubmitTime.wDay, headerRecord.stSubmitTime.wHour, headerRecord.stSubmitTime.wMinute, headerRecord.stSubmitTime.wSecond, headerRecord.stSubmitTime.wMilliseconds);
        this.startTime = (headerRecord.dwStartTime > 0) ? new DateTime(headerRecord.dwStartTime) : DateTime.MinValue;
        this.untilTime = (headerRecord.dwUntilTime > 0) ? new DateTime(headerRecord.dwUntilTime) : DateTime.MaxValue;
        this.size = headerRecord.dwSizeSPL;
        this.pageCount = headerRecord.dwPageCount;
        this.computername = ParsingHelper.ReadString(binaryReader, headerRecord.offComputername);
        this.size2 = headerRecord.dwSPLSize2;

        this.deviceMode = new DeviceMode(this.devMode);

        return true;

,ExtractDevMode函数为:

    public static string ReadString(BinaryReader binaryReader, int offset) {
        binaryReader.BaseStream.Seek((long)offset, SeekOrigin.Begin);
        var str = string.Empty;
        while (true) {
            var ch = binaryReader.ReadChar();
            if (ch == '\0') {
                return str;
            }
            str = str + ch;
        }
    }

(该功能也有很长的覆盖)。

现在,用户名,文档名称和其他内容正确显示出来,但在其他字段中重复出现,或者在其他字段中重复出现,而不是它们本身。它还在日期时间部分中断。

有人对此有任何线索吗?我读到的偏移量显然是不同的,即不是int32而是int64。我尝试将它们更改为int64(仅偏移量),但在用户名部分出现了问题。我严重卡住/不知道如何解决此问题并获得正确的零件。设置为读取int32的标头大小时,它的大小为224个字节。

0 个答案:

没有答案