32-битные или 64-битные файлы SHD? - PullRequest
0 голосов
/ 11 октября 2018

Так что это сводит меня с ума.Я не могу получить правильные данные для файла .SHD.

Это с 64-битной машины, и библиотека, которую я использую, я думаю, кажется, работает только для 32-битной (хотя неповерьте мне на слово).

Код записи заголовка выглядит следующим образом:

[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
}

Затем в классе теневых файлов, который у меня есть, происходит следующее:

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

        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;
    }

Затем выполняется анализ всего этого:

        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;

Где функция ReadString:

    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;
        }
    }

и функция ExtractDevMode:

    public static unsafe DEVMODE ExtractDevMode(BinaryReader binaryReader, int offset) {
        binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin);
        var buffer = new byte[sizeof(DEVMODE)];
        binaryReader.BaseStream.Read(buffer, 0, buffer.Length);

        return new DEVMODE(buffer);
    }

(для этой функции также есть большое переопределение).

Теперь имя пользователя, имя документа идругие вещи получаются правильно, но либо повторяются в других полях, либо в других полях, а не в их собственных.Он также прерывается в части времени и даты.

Кто-нибудь знает об этом?Я читал, что, очевидно, смещения будут другими, т.е. не int32, а int64.Я попытался изменить их на int64 (только смещения), но он лопнул на части имени пользователя.Я серьезно застрял / не знаю, как это исправить и получить правильные детали.Когда установлено значение чтения заголовка в int32, оно получается как 224 байта ..... если это вообще что-то значит ...

...