aboutsummaryrefslogtreecommitdiff
path: root/src/FileStream.h
blob: 44beeed91fd1dc8f67b32e2448205151292ece67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*****************************************************************************/
/* FileStream.h                           Copyright (c) Ladislav Zezula 2012 */
/*---------------------------------------------------------------------------*/
/* Description: Definitions for FileStream object                            */
/*---------------------------------------------------------------------------*/
/*   Date    Ver   Who  Comment                                              */
/* --------  ----  ---  -------                                              */
/* 14.04.12  1.00  Lad  The first version of FileStream.h                    */
/*****************************************************************************/

#ifndef __FILESTREAM_H__
#define __FILESTREAM_H__

//-----------------------------------------------------------------------------
// Function prototypes

typedef void (*STREAM_INIT)(
    struct TFileStream * pStream        // Pointer to an unopened stream
);

typedef bool (*STREAM_CREATE)(
    struct TFileStream * pStream        // Pointer to an unopened stream
    );

typedef bool (*STREAM_OPEN)(
    struct TFileStream * pStream,       // Pointer to an unopened stream
    const TCHAR * szFileName,           // Pointer to file name to be open
    DWORD dwStreamFlags                 // Stream flags
    );

typedef bool (*STREAM_READ)(
    struct TFileStream * pStream,       // Pointer to an open stream
    ULONGLONG * pByteOffset,            // Pointer to file byte offset. If NULL, it reads from the current position
    void * pvBuffer,                    // Pointer to data to be read
    DWORD dwBytesToRead                 // Number of bytes to read from the file
    );

typedef bool (*STREAM_WRITE)(
    struct TFileStream * pStream,       // Pointer to an open stream
    ULONGLONG * pByteOffset,            // Pointer to file byte offset. If NULL, it writes to the current position
    const void * pvBuffer,              // Pointer to data to be written
    DWORD dwBytesToWrite                // Number of bytes to read from the file
    );

typedef bool (*STREAM_RESIZE)(
    struct TFileStream * pStream,       // Pointer to an open stream
    ULONGLONG FileSize                  // New size for the file, in bytes
    );

typedef bool (*STREAM_GETSIZE)(
    struct TFileStream * pStream,       // Pointer to an open stream
    ULONGLONG * pFileSize               // Receives the file size, in bytes
    );

typedef bool (*STREAM_GETPOS)(
    struct TFileStream * pStream,       // Pointer to an open stream
    ULONGLONG * pByteOffset             // Pointer to store current file position
    );

typedef void (*STREAM_CLOSE)(
    struct TFileStream * pStream        // Pointer to an open stream
    );

typedef bool (*BLOCK_READ)(
    struct TFileStream * pStream,       // Pointer to a block-oriented stream
    ULONGLONG StartOffset,              // Byte offset of start of the block array
    ULONGLONG EndOffset,                // End offset (either end of the block or end of the file)
    LPBYTE BlockBuffer,                 // Pointer to block-aligned buffer
    DWORD BytesNeeded,                  // Number of bytes that are really needed
    bool bAvailable                     // true if the block is available
    );

typedef bool (*BLOCK_CHECK)(
    struct TFileStream * pStream,       // Pointer to a block-oriented stream
    ULONGLONG BlockOffset               // Offset of the file to check
    );

typedef void (*BLOCK_SAVEMAP)(
    struct TFileStream * pStream        // Pointer to a block-oriented stream
    );

//-----------------------------------------------------------------------------
// Local structures - partial file structure and bitmap footer

#define ID_FILE_BITMAP_FOOTER   0x33767470  // Signature of the file bitmap footer ('ptv3')
#define DEFAULT_BLOCK_SIZE      0x00004000  // Default size of the stream block
#define DEFAULT_BUILD_NUMBER         10958  // Build number for newly created partial MPQs

typedef struct _PART_FILE_HEADER
{
    DWORD PartialVersion;                   // Always set to 2
    char  GameBuildNumber[0x20];            // Minimum build number of the game that can use this MPQ
    DWORD Flags;                            // Flags (details unknown)
    DWORD FileSizeLo;                       // Low 32 bits of the contained file size
    DWORD FileSizeHi;                       // High 32 bits of the contained file size
    DWORD BlockSize;                        // Size of one file block, in bytes

} PART_FILE_HEADER, *PPART_FILE_HEADER;

// Structure describing the block-to-file map entry
typedef struct _PART_FILE_MAP_ENTRY
{
    DWORD Flags;                            // 3 = the block is present in the file
    DWORD BlockOffsLo;                      // Low 32 bits of the block position in the file
    DWORD BlockOffsHi;                      // High 32 bits of the block position in the file
    DWORD LargeValueLo;                     // 64-bit value, meaning is unknown
    DWORD LargeValueHi;

} PART_FILE_MAP_ENTRY, *PPART_FILE_MAP_ENTRY;

typedef struct _FILE_BITMAP_FOOTER
{
    DWORD Signature;                      // 'ptv3' (ID_FILE_BITMAP_FOOTER)
    DWORD Version;                        // Unknown, seems to always have value of 3 (version?)
    DWORD BuildNumber;                    // Game build number for that MPQ
    DWORD MapOffsetLo;                    // Low 32-bits of the offset of the bit map
    DWORD MapOffsetHi;                    // High 32-bits of the offset of the bit map
    DWORD BlockSize;                      // Size of one block (usually 0x4000 bytes)

} FILE_BITMAP_FOOTER, *PFILE_BITMAP_FOOTER;

//-----------------------------------------------------------------------------
// Structure for file stream

union TBaseProviderData
{
    struct
    {
        ULONGLONG FileSize;                 // Size of the file
        ULONGLONG FilePos;                  // Current file position
        ULONGLONG FileTime;                 // Last write time
        HANDLE hFile;                       // File handle
    } File;

    struct
    {
        ULONGLONG FileSize;                 // Size of the file
        ULONGLONG FilePos;                  // Current file position
        ULONGLONG FileTime;                 // Last write time
        LPBYTE pbFile;                      // Pointer to mapped view
    } Map;

    struct
    {
        ULONGLONG FileSize;                 // Size of the file
        ULONGLONG FilePos;                  // Current file position
        ULONGLONG FileTime;                 // Last write time
        HANDLE hInternet;                   // Internet handle
        HANDLE hConnect;                    // Connection to the internet server
    } Http;
};

struct TFileStream
{
    // Stream provider functions
    STREAM_READ    StreamRead;              // Pointer to stream read function for this archive. Do not use directly.
    STREAM_WRITE   StreamWrite;             // Pointer to stream write function for this archive. Do not use directly.
    STREAM_RESIZE  StreamResize;            // Pointer to function changing file size
    STREAM_GETSIZE StreamGetSize;           // Pointer to function returning file size
    STREAM_GETPOS  StreamGetPos;            // Pointer to function that returns current file position
    STREAM_CLOSE   StreamClose;             // Pointer to function closing the stream

    // Block-oriented functions
    BLOCK_READ     BlockRead;               // Pointer to function reading one or more blocks
    BLOCK_CHECK    BlockCheck;              // Pointer to function checking whether the block is present

    // Base provider functions
    STREAM_CREATE  BaseCreate;              // Pointer to base create function
    STREAM_OPEN    BaseOpen;                // Pointer to base open function
    STREAM_READ    BaseRead;                // Read from the stream
    STREAM_WRITE   BaseWrite;               // Write to the stream
    STREAM_RESIZE  BaseResize;              // Pointer to function changing file size
    STREAM_GETSIZE BaseGetSize;             // Pointer to function returning file size
    STREAM_GETPOS  BaseGetPos;              // Pointer to function that returns current file position
    STREAM_CLOSE   BaseClose;               // Pointer to function closing the stream

    // Base provider data (file size, file position)
    TBaseProviderData Base;

    // Stream provider data
    TFileStream * pMaster;                  // Master stream (e.g. MPQ on a web server)
    TCHAR * szFileName;                     // File name (self-relative pointer)

    ULONGLONG StreamSize;                   // Stream size (can be less than file size)
    ULONGLONG StreamPos;                    // Stream position
    DWORD BuildNumber;                      // Game build number
    DWORD dwFlags;                          // Stream flags

    // Followed by stream provider data, with variable length
};

//-----------------------------------------------------------------------------
// Structures for block-oriented stream

struct TBlockStream : public TFileStream
{
    SFILE_DOWNLOAD_CALLBACK pfnCallback;    // Callback for downloading
    void * FileBitmap;                      // Array of bits for file blocks
    void * UserData;                        // User data to be passed to the download callback
    DWORD BitmapSize;                       // Size of the file bitmap (in bytes)
    DWORD BlockSize;                        // Size of one block, in bytes
    DWORD BlockCount;                       // Number of data blocks in the file
    DWORD IsComplete;                       // If nonzero, no blocks are missing
    DWORD IsModified;                       // nonzero if the bitmap has been modified
};        

//-----------------------------------------------------------------------------
// Structure for encrypted stream

#define MPQE_CHUNK_SIZE 0x40                // Size of one chunk to be decrypted

struct TEncryptedStream : public TBlockStream
{
    BYTE Key[MPQE_CHUNK_SIZE];              // File key
};

#endif // __FILESTREAM_H__