[2/3] d3dxof: Factor out duplicated code for parsing X file header.
Dylan Smith
dylan.ah.smith at gmail.com
Wed Jun 8 14:38:58 CDT 2011
---
dlls/d3dxof/d3dxof.c | 233 +++++-------------------------------------
dlls/d3dxof/d3dxof_private.h | 1 +
dlls/d3dxof/parsing.c | 101 ++++++++++++++++++
3 files changed, 128 insertions(+), 207 deletions(-)
diff --git a/dlls/d3dxof/d3dxof.c b/dlls/d3dxof/d3dxof.c
index 8392c31..213f3e1 100644
--- a/dlls/d3dxof/d3dxof.c
+++ b/dlls/d3dxof/d3dxof.c
@@ -33,18 +33,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3dxof);
-#define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
-#define XOFFILE_FORMAT_MAGIC MAKEFOUR('x','o','f',' ')
-#define XOFFILE_FORMAT_VERSION_302 MAKEFOUR('0','3','0','2')
-#define XOFFILE_FORMAT_VERSION_303 MAKEFOUR('0','3','0','3')
-#define XOFFILE_FORMAT_BINARY MAKEFOUR('b','i','n',' ')
-#define XOFFILE_FORMAT_TEXT MAKEFOUR('t','x','t',' ')
-#define XOFFILE_FORMAT_BINARY_MSZIP MAKEFOUR('b','z','i','p')
-#define XOFFILE_FORMAT_TEXT_MSZIP MAKEFOUR('t','z','i','p')
-#define XOFFILE_FORMAT_COMPRESSED MAKEFOUR('c','m','p',' ')
-#define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
-#define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
-
static const struct IDirectXFileVtbl IDirectXFile_Vtbl;
static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl;
static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl;
@@ -57,15 +45,6 @@ static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImp
static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj);
static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj);
-/* FOURCC to string conversion for debug messages */
-static const char *debugstr_fourcc(DWORD fourcc)
-{
- if (!fourcc) return "'null'";
- return wine_dbg_sprintf ("\'%c%c%c%c\'",
- (char)(fourcc), (char)(fourcc >> 8),
- (char)(fourcc >> 16), (char)(fourcc >> 24));
-}
-
HRESULT IDirectXFileImpl_Create(IUnknown* pUnkOuter, LPVOID* ppObj)
{
IDirectXFileImpl* object;
@@ -140,10 +119,6 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
IDirectXFileEnumObjectImpl* object;
HRESULT hr;
- DWORD* header;
- LPBYTE mapped_memory = NULL;
- LPBYTE decomp_buffer = NULL;
- DWORD decomp_size = 0;
LPBYTE file_buffer;
DWORD file_size;
@@ -155,6 +130,10 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
/* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
dwLoadOptions &= 0xF;
+ hr = IDirectXFileEnumObjectImpl_Create(&object);
+ if (FAILED(hr))
+ return hr;
+
if (dwLoadOptions == DXFILELOAD_FROMFILE)
{
HANDLE hFile, file_mapping;
@@ -178,15 +157,15 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
goto error;
}
- mapped_memory = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
+ object->mapped_memory = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
CloseHandle(file_mapping);
CloseHandle(hFile);
- if (!mapped_memory)
+ if (!object->mapped_memory)
{
hr = DXFILEERR_BADFILETYPE;
goto error;
}
- file_buffer = mapped_memory;
+ file_buffer = object->mapped_memory;
}
else if (dwLoadOptions == DXFILELOAD_FROMRESOURCE)
{
@@ -235,107 +214,17 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
goto error;
}
- header = (DWORD*)file_buffer;
-
- if (TRACE_ON(d3dxof))
- {
- char string[17];
- memcpy(string, header, 16);
- string[16] = 0;
- TRACE("header = '%s'\n", string);
- }
-
- if (file_size < 16)
- {
- hr = DXFILEERR_BADFILETYPE;
- goto error;
- }
-
- if (header[0] != XOFFILE_FORMAT_MAGIC)
- {
- hr = DXFILEERR_BADFILETYPE;
- goto error;
- }
-
- if ((header[1] != XOFFILE_FORMAT_VERSION_302) && (header[1] != XOFFILE_FORMAT_VERSION_303))
- {
- hr = DXFILEERR_BADFILEVERSION;
- goto error;
- }
-
- if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) &&
- (header[2] != XOFFILE_FORMAT_BINARY_MSZIP) && (header[2] != XOFFILE_FORMAT_TEXT_MSZIP))
- {
- WARN("File type %s unknown\n", debugstr_fourcc(header[2]));
- hr = DXFILEERR_BADFILETYPE;
- goto error;
- }
-
- if ((header[2] == XOFFILE_FORMAT_BINARY_MSZIP) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP))
- {
- int err;
- DWORD comp_size;
-
- /* 0-15 -> xfile header, 16-17 -> decompressed size w/ header, 18-19 -> null,
- 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
- 24-xx -> compressed MSZIP data */
- decomp_size = ((WORD*)file_buffer)[10];
- comp_size = ((WORD*)file_buffer)[11];
-
- TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
- debugstr_fourcc(header[2]), comp_size, decomp_size);
-
- decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
- if (!decomp_buffer)
- {
- ERR("Out of memory\n");
- hr = DXFILEERR_BADALLOC;
- goto error;
- }
- err = mszip_decompress(comp_size, decomp_size, (char*)file_buffer + 24, (char*)decomp_buffer);
- if (err)
- {
- WARN("Error while decomrpessing mszip archive %d\n", err);
- hr = DXFILEERR_BADALLOC;
- goto error;
- }
- }
-
- if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
- {
- hr = DXFILEERR_BADFILEFLOATSIZE;
- goto error;
- }
-
- TRACE("Header is correct\n");
-
- hr = IDirectXFileEnumObjectImpl_Create(&object);
- if (FAILED(hr))
- goto error;
+ TRACE("File size is %d bytes\n", file_size);
- object->mapped_memory = mapped_memory;
- object->decomp_buffer = decomp_buffer;
object->pDirectXFile = This;
+
object->buf.pdxf = This;
- object->buf.txt = (header[2] == XOFFILE_FORMAT_TEXT) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP);
object->buf.token_present = FALSE;
-
- TRACE("File size is %d bytes\n", file_size);
-
- if (decomp_size)
- {
- /* Use decompressed data */
- object->buf.buffer = decomp_buffer;
- object->buf.rem_bytes = decomp_size;
- }
- else
- {
- /* Go to data after header */
- object->buf.buffer = file_buffer + 16;
- object->buf.rem_bytes = file_size - 16;
- }
-
- *ppEnumObj = &object->IDirectXFileEnumObject_iface;
+ object->buf.buffer = file_buffer;
+ object->buf.rem_bytes = file_size;
+ hr = parse_header(&object->buf, &object->decomp_buffer);
+ if (FAILED(hr))
+ goto error;
while (object->buf.rem_bytes && is_template_available(&object->buf))
{
@@ -361,12 +250,12 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
}
+ *ppEnumObj = &object->IDirectXFileEnumObject_iface;
+
return DXFILE_OK;
error:
- if (mapped_memory)
- UnmapViewOfFile(mapped_memory);
- HeapFree(GetProcessHeap(), 0, decomp_buffer);
+ IDirectXFileEnumObject_Release(&object->IDirectXFileEnumObject_iface);
*ppEnumObj = NULL;
return hr;
@@ -392,10 +281,9 @@ static HRESULT WINAPI IDirectXFileImpl_CreateSaveObject(IDirectXFile* iface, LPC
static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
{
IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
- DWORD token_header;
parse_buffer buf;
+ HRESULT hr;
LPBYTE decomp_buffer = NULL;
- DWORD decomp_size = 0;
buf.buffer = pvData;
buf.rem_bytes = cbSize;
@@ -408,87 +296,17 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
if (!pvData)
return DXFILEERR_BADVALUE;
- if (cbSize < 16)
- return DXFILEERR_BADFILETYPE;
-
- if (TRACE_ON(d3dxof))
- {
- char string[17];
- memcpy(string, pvData, 16);
- string[16] = 0;
- TRACE("header = '%s'\n", string);
- }
-
- read_bytes(&buf, &token_header, 4);
-
- if (token_header != XOFFILE_FORMAT_MAGIC)
- return DXFILEERR_BADFILETYPE;
-
- read_bytes(&buf, &token_header, 4);
-
- if ((token_header != XOFFILE_FORMAT_VERSION_302) && (token_header != XOFFILE_FORMAT_VERSION_303))
- return DXFILEERR_BADFILEVERSION;
-
- read_bytes(&buf, &token_header, 4);
-
- if ((token_header != XOFFILE_FORMAT_BINARY) && (token_header != XOFFILE_FORMAT_TEXT) &&
- (token_header != XOFFILE_FORMAT_BINARY_MSZIP) && (token_header != XOFFILE_FORMAT_TEXT_MSZIP))
- {
- WARN("File type %s unknown\n", debugstr_fourcc(token_header));
- return DXFILEERR_BADFILETYPE;
- }
-
- if ((token_header == XOFFILE_FORMAT_BINARY_MSZIP) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
- {
- int err;
- DWORD comp_size;
-
- /* 0-15 -> xfile header, 16-17 -> decompressed size w/ header, 18-19 -> null,
- 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
- 24-xx -> compressed MSZIP data */
- decomp_size = ((WORD*)pvData)[10];
- comp_size = ((WORD*)pvData)[11];
-
- TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
- debugstr_fourcc(token_header), comp_size, decomp_size);
-
- decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
- if (!decomp_buffer)
- {
- ERR("Out of memory\n");
- return DXFILEERR_BADALLOC;
- }
- err = mszip_decompress(comp_size, decomp_size, (char*)pvData + 24, (char*)decomp_buffer);
- if (err)
- {
- WARN("Error while decomrpessing mszip archive %d\n", err);
- HeapFree(GetProcessHeap(), 0, decomp_buffer);
- return DXFILEERR_BADALLOC;
- }
- }
-
- if ((token_header == XOFFILE_FORMAT_TEXT) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
- buf.txt = TRUE;
-
- read_bytes(&buf, &token_header, 4);
-
- if ((token_header != XOFFILE_FORMAT_FLOAT_BITS_32) && (token_header != XOFFILE_FORMAT_FLOAT_BITS_64))
- return DXFILEERR_BADFILEFLOATSIZE;
-
- TRACE("Header is correct\n");
-
- if (decomp_size)
- {
- buf.buffer = decomp_buffer;
- buf.rem_bytes = decomp_size;
- }
+ hr = parse_header(&buf, &decomp_buffer);
+ if (FAILED(hr))
+ goto cleanup;
while (buf.rem_bytes && is_template_available(&buf))
{
if (!parse_template(&buf))
{
WARN("Template is not correct\n");
- return DXFILEERR_BADVALUE;
+ hr = DXFILEERR_BADVALUE;
+ goto cleanup;
}
else
{
@@ -506,9 +324,10 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
}
+ hr = DXFILE_OK;
+cleanup:
HeapFree(GetProcessHeap(), 0, decomp_buffer);
-
- return DXFILE_OK;
+ return hr;
}
static const IDirectXFileVtbl IDirectXFile_Vtbl =
diff --git a/dlls/d3dxof/d3dxof_private.h b/dlls/d3dxof/d3dxof_private.h
index 5e61d65..15dca52 100644
--- a/dlls/d3dxof/d3dxof_private.h
+++ b/dlls/d3dxof/d3dxof_private.h
@@ -163,6 +163,7 @@ typedef struct {
HRESULT IDirectXFileImpl_Create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN;
BOOL read_bytes(parse_buffer * buf, LPVOID data, DWORD size) DECLSPEC_HIDDEN;
+HRESULT parse_header(parse_buffer *buf, BYTE **decomp_buffer_ptr) DECLSPEC_HIDDEN;
BOOL parse_template(parse_buffer * buf) DECLSPEC_HIDDEN;
void dump_template(xtemplate* templates_array, xtemplate* ptemplate) DECLSPEC_HIDDEN;
BOOL is_template_available(parse_buffer * buf) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dxof/parsing.c b/dlls/d3dxof/parsing.c
index 417194b..7682dfe 100644
--- a/dlls/d3dxof/parsing.c
+++ b/dlls/d3dxof/parsing.c
@@ -36,6 +36,18 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3dxof_parsing);
+#define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
+#define XOFFILE_FORMAT_MAGIC MAKEFOUR('x','o','f',' ')
+#define XOFFILE_FORMAT_VERSION_302 MAKEFOUR('0','3','0','2')
+#define XOFFILE_FORMAT_VERSION_303 MAKEFOUR('0','3','0','3')
+#define XOFFILE_FORMAT_BINARY MAKEFOUR('b','i','n',' ')
+#define XOFFILE_FORMAT_TEXT MAKEFOUR('t','x','t',' ')
+#define XOFFILE_FORMAT_BINARY_MSZIP MAKEFOUR('b','z','i','p')
+#define XOFFILE_FORMAT_TEXT_MSZIP MAKEFOUR('t','z','i','p')
+#define XOFFILE_FORMAT_COMPRESSED MAKEFOUR('c','m','p',' ')
+#define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
+#define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
+
#define TOKEN_NAME 1
#define TOKEN_STRING 2
#define TOKEN_INTEGER 3
@@ -70,6 +82,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dxof_parsing);
#define CLSIDFMT "<%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X>"
+/* FOURCC to string conversion for debug messages */
+static const char *debugstr_fourcc(DWORD fourcc)
+{
+ if (!fourcc) return "'null'";
+ return wine_dbg_sprintf ("\'%c%c%c%c\'",
+ (char)(fourcc), (char)(fourcc >> 8),
+ (char)(fourcc >> 16), (char)(fourcc >> 24));
+}
+
static const char* get_primitive_string(WORD token)
{
switch(token)
@@ -161,6 +182,86 @@ static void rewind_bytes(parse_buffer * buf, DWORD size)
buf->rem_bytes += size;
}
+HRESULT parse_header(parse_buffer * buf, BYTE ** decomp_buffer_ptr)
+{
+ /* X File common header:
+ * 0-3 -> Magic Number (format identifier)
+ * 4-7 -> Format Version
+ * 8-11 -> Format Type (text or binary, decompressed or compressed)
+ * 12-15 -> Float Size (32 or 64 bits) */
+ DWORD header[4];
+
+ if (!read_bytes(buf, header, sizeof(header)))
+ return DXFILEERR_BADFILETYPE;
+
+ if (TRACE_ON(d3dxof_parsing))
+ {
+ char string[17];
+ memcpy(string, header, 16);
+ string[16] = 0;
+ TRACE("header = '%s'\n", string);
+ }
+
+ if (header[0] != XOFFILE_FORMAT_MAGIC)
+ return DXFILEERR_BADFILETYPE;
+
+ if (header[1] != XOFFILE_FORMAT_VERSION_302 && header[1] != XOFFILE_FORMAT_VERSION_303)
+ return DXFILEERR_BADFILEVERSION;
+
+ if (header[2] != XOFFILE_FORMAT_BINARY && header[2] != XOFFILE_FORMAT_TEXT &&
+ header[2] != XOFFILE_FORMAT_BINARY_MSZIP && header[2] != XOFFILE_FORMAT_TEXT_MSZIP)
+ {
+ WARN("File type %s unknown\n", debugstr_fourcc(header[2]));
+ return DXFILEERR_BADFILETYPE;
+ }
+
+ if (header[3] != XOFFILE_FORMAT_FLOAT_BITS_32 && header[3] != XOFFILE_FORMAT_FLOAT_BITS_64)
+ return DXFILEERR_BADFILEFLOATSIZE;
+
+ buf->txt = header[2] == XOFFILE_FORMAT_TEXT || header[2] == XOFFILE_FORMAT_TEXT_MSZIP;
+
+ if (header[2] == XOFFILE_FORMAT_BINARY_MSZIP || header[2] == XOFFILE_FORMAT_TEXT_MSZIP)
+ {
+ /* Extended header for compressed data:
+ * 16-17 -> decompressed size w/ header, 18-19 -> null,
+ * 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
+ * 24-xx -> compressed MSZIP data */
+ int err;
+ WORD decomp_size;
+ WORD comp_size;
+ LPBYTE decomp_buffer;
+
+ buf->rem_bytes -= sizeof(WORD) * 2;
+ buf->buffer += sizeof(WORD) * 2;
+ read_bytes(buf, &decomp_size, sizeof(decomp_size));
+ read_bytes(buf, &comp_size, sizeof(comp_size));
+
+ TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
+ debugstr_fourcc(header[2]), comp_size, decomp_size);
+
+ decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
+ if (!decomp_buffer)
+ {
+ ERR("Out of memory\n");
+ return DXFILEERR_BADALLOC;
+ }
+ err = mszip_decompress(comp_size, decomp_size, (char*)buf->buffer, (char*)decomp_buffer);
+ if (err)
+ {
+ WARN("Error while decompressing mszip archive %d\n", err);
+ HeapFree(GetProcessHeap(), 0, decomp_buffer);
+ return DXFILEERR_BADALLOC;
+ }
+ /* Use decompressed data */
+ buf->buffer = *decomp_buffer_ptr = decomp_buffer;
+ buf->rem_bytes = decomp_size;
+ }
+
+ TRACE("Header is correct\n");
+
+ return S_OK;
+}
+
static void dump_TOKEN(WORD token)
{
#define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
--
1.7.4.1
More information about the wine-patches
mailing list