예제 #1
0
void WriteLog(PCWSTR Format, ...)
{
#if ENABLE_LOG

    NtFileDisk log;
    WCHAR Buffer[0xFF0];

    log.CreateIfNotExist(L"log.txt");
    if (log.GetSize32() == 0)
    {
        ULONG BOM = BOM_UTF16_LE;
        log.Write(&BOM, 2);
    }

    log.Seek(0, FILE_END);

    log.Write(Buffer, vswprintf(Buffer, Format, (va_list)(&Format + 1)) * 2);
    log.Write(L"\r\n", 4);

#endif
}
예제 #2
0
UPK_STATUS
NitroPlus::
Pack(
    PCWSTR          InputPath,
    PCWSTR          OutputFile  /* = NULL */,
    PLARGE_INTEGER  PackedFiles /* = NULL */,
    ULONG           Flags       /* = 0 */
)
{
    UNREFERENCED_PARAMETER(OutputFile);
    UNREFERENCED_PARAMETER(Flags);

    ULONG                   PathLength, Length, Hash, Offset;
    ULONG                   Size, CompressedSize, FileBufferSize, CompresseBufferSize;
    WCHAR                   FilePath[MAX_NTPATH];
    PVOID                   NpaEntryBase, FileBuffer, CompresseBuffer;
    PBYTE                   NpaEntryBuffer;
    PWSTR                   FileName;
    NTSTATUS                Status;
    LARGE_INTEGER           FileCount, PackedFileCount;
    NITRO_PLUS_ENTRY       *BaseEntry, *Entry;
    NITRO_PLUS_NPA_HEADER   Header;
    NITRO_PLUS_NPA_ETNRY   *Info;
    NtFileDisk              File;

    if (PackedFiles == NULL)
        PackedFiles = &PackedFileCount;

    PackedFiles->QuadPart = 0;

    if (!EnumDirectoryFiles(
            (PVOID *)&BaseEntry,
            L"*.*",
            sizeof(*BaseEntry),
            InputPath,
            &FileCount,
            (EnumDirectoryFilesCallBackRoutine)QueryFileList,
            0,
            EDF_SUBDIR)
       )
    {
        return STATUS_UNSUCCESSFUL;
    }

    FileBufferSize      = 0;
    CompresseBufferSize = 0;
    FileBuffer          = NULL;
    CompresseBuffer     = NULL;

    *(PULONG)&Header.Signature  = NPA_HEADER_MAGIC;
    Header.Version              = NPA_GCLX_VERSION;
    Header.EntryCount           = FileCount.LowPart;
    Header.FileCount            = FileCount.LowPart;
    Header.DirectoryCount       = 0;
    Header.IsCompressed         = TRUE;
    Header.IsEncrypted          = TRUE;

    RtlRandom(&Header.Hash[0]);
    RtlRandom(&Header.Hash[1]);

    PathLength = StrLengthW(InputPath);

    if (OutputFile != NULL)
    {
        Status = m_File.Create(OutputFile);
    }
    else
    {
        FileName = FilePath + PathLength;
        CopyMemory(FilePath, InputPath, PathLength * sizeof(*FilePath));
        if (FileName[-1] == '\\')
            --FileName;

        *(PULONG64)FileName = TAG4W('.npa');
        FileName[4] = 0;

        Status = m_File.Create(FilePath);
    }

    if (!NT_SUCCESS(Status))
        goto RETURN_POINT;

    PathLength += InputPath[PathLength - 1] != '\\';

    NpaEntryBase = AllocateMemory(sizeof(*BaseEntry) * FileCount.LowPart);
    if (NpaEntryBase == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto RETURN_POINT;
    }

    NpaEntryBuffer  = (PBYTE)NpaEntryBase;
    Entry           = BaseEntry;

    for (ULONG Index = 0, Count = FileCount.LowPart; Count; ++Index, --Count)
    {
        Length = StrLengthW(Entry->FileName) - PathLength;

        Length = WideCharToMultiByte(
                    CP_SHIFTJIS,
                    0,
                    Entry->FileName + PathLength,
                    Length,
                    (PSTR)NpaEntryBuffer + 4,
                    INT_MAX,
                    NULL,
                    NULL
                 );
//        Nt_UnicodeToAnsi((PSTR)NpaEntryBuffer + 4, INT_MAX, Entry->FileName + PathLength, Length, &Length);
        *(PULONG)NpaEntryBuffer = Length;

        NpaEntryBuffer += 4;

        Entry->DecryptLength    = Length;
        Entry->Seed             = HashBuffer(NpaEntryBuffer, Length);

        EncryptName(NpaEntryBuffer, Length, Index, &Header);

        NpaEntryBuffer += Length;
        NpaEntryBuffer += sizeof(*Info);

        ++Entry;
    }

    Header.EntrySize = PtrOffset(NpaEntryBuffer, NpaEntryBase);

    Hash            = Header.Hash[0] * Header.Hash[1];
    NpaEntryBuffer  = (PBYTE)NpaEntryBase;
    Entry           = BaseEntry;
    Offset          = 0;

    m_File.Seek(Header.EntrySize + sizeof(Header), FILE_BEGIN);

    for (ULONG Index = 0, Count = FileCount.LowPart; Count; ++Index, --Count)
    {
        Status = File.Open(Entry->FileName);
        if (!NT_SUCCESS(Status))
            break;

        Size = File.GetSize32();
        if (FileBufferSize < Size)
        {
            FileBufferSize = Size;
            FileBuffer = ReAllocateMemory(FileBuffer, FileBufferSize);
            if (FileBuffer == NULL)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }
        }

        Status = File.Read(FileBuffer, Size);
        if (!NT_SUCCESS(Status))
            break;

        CompressedSize = Size * 4;
        if (CompresseBufferSize < CompressedSize)
        {
            CompresseBufferSize = CompressedSize;
            CompresseBuffer = ReAllocateMemory(CompresseBuffer, CompresseBufferSize);
            if (CompresseBuffer == NULL)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }
        }

        CompressedSize = CompresseBufferSize;
        Status = compress2(CompresseBuffer, &CompressedSize, FileBuffer, Size, Z_BEST_COMPRESSION);
        if (Status != Z_OK)
        {
            Status = STATUS_UNSUCCESSFUL;
            break;
        }

        EncryptData(
            CompresseBuffer,
            MY_MIN(CompressedSize, Entry->DecryptLength + 0x1000),
            (Hash + Entry->Seed) * Size
        );

        NpaEntryBuffer += *(PULONG)NpaEntryBuffer + 4;
        Info            = (NITRO_PLUS_NPA_ETNRY *)NpaEntryBuffer;
        NpaEntryBuffer += sizeof(*Info);

        Info->FileType          = NP_FILE_TYPE_FILE;
        Info->CompressedSize    = CompressedSize;
        Info->Offset            = Offset;
        Info->OriginalSize      = Size;
        Info->DirectoryIndex    = 0;

        Status = m_File.Write(CompresseBuffer, CompressedSize);
        if (!NT_SUCCESS(Status))
            break;

        Offset += CompressedSize;
        ++Entry;
    }

    if (!NT_SUCCESS(Status))
        goto RETURN_POINT;

    m_File.Seek(0, FILE_BEGIN);
    Status = m_File.Write(&Header, sizeof(Header));
    if (!NT_SUCCESS(Status))
        goto RETURN_POINT;

    Status = m_File.Write(NpaEntryBase, Header.EntrySize);
    if (!NT_SUCCESS(Status))
        goto RETURN_POINT;

    PackedFiles->QuadPart = FileCount.QuadPart;

RETURN_POINT:

    FreeMemory(FileBuffer);
    EnumDirectoryFilesFree(BaseEntry);

    return Status;
}