d3dxof: Implement storage of parsed information.

This commit is contained in:
Christian Costa 2008-08-22 13:16:58 +02:00 committed by Alexandre Julliard
parent 05a2c56622
commit 2f98206111
2 changed files with 250 additions and 92 deletions

View File

@ -77,18 +77,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dxof);
#define TOKEN_CSTRING 51 #define TOKEN_CSTRING 51
#define TOKEN_ARRAY 52 #define TOKEN_ARRAY 52
#define CLSIDFMT "<%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X>"
typedef struct { typedef struct {
/* Buffer to parse */ /* Buffer to parse */
LPBYTE buffer; LPBYTE buffer;
DWORD rem_bytes; DWORD rem_bytes;
/* Dump template content */ /* Misc info */
char* dump;
DWORD pos;
DWORD size;
BOOL txt; BOOL txt;
BYTE value[100];
IDirectXFileImpl* pdxf;
} parse_buffer; } parse_buffer;
static const struct IDirectXFileVtbl IDirectXFile_Vtbl; static const struct IDirectXFileVtbl IDirectXFile_Vtbl;
static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl; static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl;
static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl; static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl;
@ -209,18 +209,6 @@ static BOOL read_bytes(parse_buffer * buf, LPVOID data, DWORD size)
return TRUE; return TRUE;
} }
static void add_string(parse_buffer * buf, const char * str)
{
DWORD len = strlen(str);
if ((buf->pos + len + 1) > buf->size)
{
FIXME("Dump buffer to small\n");
return;
}
sprintf(buf->dump + buf->pos, str);
buf->pos += len;
}
static void dump_TOKEN(WORD token) static void dump_TOKEN(WORD token)
{ {
#define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
@ -381,6 +369,9 @@ static BOOL is_guid(parse_buffer* buf)
{ {
static char tmp[50]; static char tmp[50];
DWORD pos = 1; DWORD pos = 1;
GUID class_id;
DWORD tab[10];
int ret;
if (*buf->buffer != '<') if (*buf->buffer != '<')
return FALSE; return FALSE;
@ -397,10 +388,30 @@ static BOOL is_guid(parse_buffer* buf)
TRACE("Wrong guid %s (%d) \n", tmp, pos); TRACE("Wrong guid %s (%d) \n", tmp, pos);
return FALSE; return FALSE;
} }
TRACE("Found guid %s (%d) \n", tmp, pos);
buf->buffer += pos; buf->buffer += pos;
buf->rem_bytes -= pos; buf->rem_bytes -= pos;
ret = sscanf(tmp, CLSIDFMT, &class_id.Data1, tab, tab+1, tab+2, tab+3, tab+4, tab+5, tab+6, tab+7, tab+8, tab+9);
if (ret != 11)
{
TRACE("Wrong guid %s (%d) \n", tmp, pos);
return FALSE;
}
TRACE("Found guid %s (%d) \n", tmp, pos);
class_id.Data2 = tab[0];
class_id.Data3 = tab[1];
class_id.Data4[0] = tab[2];
class_id.Data4[1] = tab[3];
class_id.Data4[2] = tab[4];
class_id.Data4[3] = tab[5];
class_id.Data4[4] = tab[6];
class_id.Data4[5] = tab[7];
class_id.Data4[6] = tab[8];
class_id.Data4[7] = tab[9];
*(GUID*)buf->value = class_id;
return TRUE; return TRUE;
} }
@ -428,6 +439,34 @@ static BOOL is_name(parse_buffer* buf)
buf->rem_bytes -= pos; buf->rem_bytes -= pos;
TRACE("Found name %s\n", tmp); TRACE("Found name %s\n", tmp);
strcpy((char*)buf->value, tmp);
return TRUE;
}
static BOOL is_integer(parse_buffer* buf)
{
static char tmp[50];
DWORD pos = 0;
char c;
DWORD integer;
while (!is_separator(c = *(buf->buffer+pos)))
{
if (!((c >= '0') && (c <= '9')))
return FALSE;
tmp[pos++] = c;
}
tmp[pos] = 0;
buf->buffer += pos;
buf->rem_bytes -= pos;
sscanf(tmp, "%d", &integer);
TRACE("Found integer %s - %d\n", tmp, integer);
*(WORD*)buf->value = integer;
return TRUE; return TRUE;
} }
@ -469,7 +508,11 @@ static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token)
token = TOKEN_GUID; token = TOKEN_GUID;
break; break;
} }
if (is_integer(buf))
{
token = TOKEN_INTEGER;
break;
}
if (is_name(buf)) if (is_name(buf))
{ {
token = TOKEN_NAME; token = TOKEN_NAME;
@ -495,81 +538,31 @@ static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token)
case TOKEN_GUID: case TOKEN_GUID:
case TOKEN_INTEGER_LIST: case TOKEN_INTEGER_LIST:
case TOKEN_FLOAT_LIST: case TOKEN_FLOAT_LIST:
break;
case TOKEN_OBRACE: case TOKEN_OBRACE:
add_string(buf, "{ ");
break;
case TOKEN_CBRACE: case TOKEN_CBRACE:
add_string(buf, "} ");
break;
case TOKEN_OPAREN: case TOKEN_OPAREN:
add_string(buf, "( ");
break;
case TOKEN_CPAREN: case TOKEN_CPAREN:
add_string(buf, ") ");
break;
case TOKEN_OBRACKET: case TOKEN_OBRACKET:
add_string(buf, "[ ");
break;
case TOKEN_CBRACKET: case TOKEN_CBRACKET:
add_string(buf, "] ");
break;
case TOKEN_OANGLE: case TOKEN_OANGLE:
add_string(buf, "< ");
break;
case TOKEN_CANGLE: case TOKEN_CANGLE:
add_string(buf, "> ");
break;
case TOKEN_DOT: case TOKEN_DOT:
add_string(buf, ".");
break;
case TOKEN_COMMA: case TOKEN_COMMA:
add_string(buf, ", ");
break;
case TOKEN_SEMICOLON: case TOKEN_SEMICOLON:
add_string(buf, "; ");
break;
case TOKEN_TEMPLATE: case TOKEN_TEMPLATE:
add_string(buf, "template ");
break;
case TOKEN_WORD: case TOKEN_WORD:
add_string(buf, "WORD ");
break;
case TOKEN_DWORD: case TOKEN_DWORD:
add_string(buf, "DWORD ");
break;
case TOKEN_FLOAT: case TOKEN_FLOAT:
add_string(buf, "FLOAT ");
break;
case TOKEN_DOUBLE: case TOKEN_DOUBLE:
add_string(buf, "DOUBLE ");
break;
case TOKEN_CHAR: case TOKEN_CHAR:
add_string(buf, "CHAR ");
break;
case TOKEN_UCHAR: case TOKEN_UCHAR:
add_string(buf, "UCHAR ");
break;
case TOKEN_SWORD: case TOKEN_SWORD:
add_string(buf, "SWORD ");
break;
case TOKEN_SDWORD: case TOKEN_SDWORD:
add_string(buf, "SDWORD ");
break;
case TOKEN_VOID: case TOKEN_VOID:
add_string(buf, "VOID ");
break;
case TOKEN_LPSTR: case TOKEN_LPSTR:
add_string(buf, "LPSTR ");
break;
case TOKEN_UNICODE: case TOKEN_UNICODE:
add_string(buf, "UNICODE ");
break;
case TOKEN_CSTRING: case TOKEN_CSTRING:
add_string(buf, "CSTRING ");
break;
case TOKEN_ARRAY: case TOKEN_ARRAY:
add_string(buf, "array ");
break; break;
default: default:
return 0; return 0;
@ -581,6 +574,40 @@ static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token)
return token; return token;
} }
static const char* get_primitive_string(WORD token)
{
switch(token)
{
case TOKEN_WORD:
return "WORD";
case TOKEN_DWORD:
return "DWORD";
case TOKEN_FLOAT:
return "FLOAT";
case TOKEN_DOUBLE:
return "DOUBLE";
case TOKEN_CHAR:
return "CHAR";
case TOKEN_UCHAR:
return "UCHAR";
case TOKEN_SWORD:
return "SWORD";
case TOKEN_SDWORD:
return "SDWORD";
case TOKEN_VOID:
return "VOID";
case TOKEN_LPSTR:
return "LPSTR";
case TOKEN_UNICODE:
return "UNICODE";
case TOKEN_CSTRING:
return "CSTRING ";
default:
break;
}
return NULL;
}
static inline WORD parse_TOKEN(parse_buffer * buf) static inline WORD parse_TOKEN(parse_buffer * buf)
{ {
return parse_TOKEN_dbg_opt(buf, TRUE); return parse_TOKEN_dbg_opt(buf, TRUE);
@ -651,8 +678,8 @@ static BOOL parse_name(parse_buffer * buf)
return FALSE; return FALSE;
strname[count] = 0; strname[count] = 0;
/*TRACE("name = %s\n", strname);*/ /*TRACE("name = %s\n", strname);*/
add_string(buf, strname);
add_string(buf, " "); strcpy((char*)buf->value, strname);
return TRUE; return TRUE;
} }
@ -668,10 +695,11 @@ static BOOL parse_class_id(parse_buffer * buf)
return TRUE; return TRUE;
if (!read_bytes(buf, &class_id, 16)) if (!read_bytes(buf, &class_id, 16))
return FALSE; return FALSE;
sprintf(strguid, "<%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X>", class_id.Data1, class_id.Data2, class_id.Data3, class_id.Data4[0], sprintf(strguid, CLSIDFMT, class_id.Data1, class_id.Data2, class_id.Data3, class_id.Data4[0],
class_id.Data4[1], class_id.Data4[2], class_id.Data4[3], class_id.Data4[4], class_id.Data4[5], class_id.Data4[6], class_id.Data4[7]); class_id.Data4[1], class_id.Data4[2], class_id.Data4[3], class_id.Data4[4], class_id.Data4[5], class_id.Data4[6], class_id.Data4[7]);
/*TRACE("guid = {%s}\n", strguid);*/ /*TRACE("guid = {%s}\n", strguid);*/
add_string(buf, strguid);
*(GUID*)buf->value = class_id;
return TRUE; return TRUE;
} }
@ -682,17 +710,21 @@ static BOOL parse_integer(parse_buffer * buf)
if (parse_TOKEN(buf) != TOKEN_INTEGER) if (parse_TOKEN(buf) != TOKEN_INTEGER)
return FALSE; return FALSE;
if (buf->txt)
return TRUE;
if (!read_bytes(buf, &integer, 4)) if (!read_bytes(buf, &integer, 4))
return FALSE; return FALSE;
/*TRACE("integer = %ld\n", integer);*/ /*TRACE("integer = %ld\n", integer);*/
sprintf(buf->dump+buf->pos, "%d ", integer);
buf->pos = strlen(buf->dump); *(DWORD*)buf->value = integer;
return TRUE; return TRUE;
} }
static BOOL parse_template_option_info(parse_buffer * buf) static BOOL parse_template_option_info(parse_buffer * buf)
{ {
xtemplate* cur_template = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates];
if (check_TOKEN(buf) == TOKEN_DOT) if (check_TOKEN(buf) == TOKEN_DOT)
{ {
parse_TOKEN(buf); parse_TOKEN(buf);
@ -700,8 +732,7 @@ static BOOL parse_template_option_info(parse_buffer * buf)
return FALSE; return FALSE;
if (parse_TOKEN(buf) != TOKEN_DOT) if (parse_TOKEN(buf) != TOKEN_DOT)
return FALSE; return FALSE;
sprintf(buf->dump+buf->pos, " "); cur_template->open = TRUE;
buf->pos = strlen(buf->dump);
} }
else else
{ {
@ -709,86 +740,144 @@ static BOOL parse_template_option_info(parse_buffer * buf)
{ {
if (!parse_name(buf)) if (!parse_name(buf))
return FALSE; return FALSE;
strcpy(cur_template->childs[cur_template->nb_childs], (char*)buf->value);
if (check_TOKEN(buf) == TOKEN_GUID) if (check_TOKEN(buf) == TOKEN_GUID)
if (!parse_class_id(buf)) if (!parse_class_id(buf))
return FALSE; return FALSE;
cur_template->nb_childs++;
if (check_TOKEN(buf) != TOKEN_COMMA) if (check_TOKEN(buf) != TOKEN_COMMA)
break; break;
parse_TOKEN(buf); parse_TOKEN(buf);
} }
cur_template->open = FALSE;
} }
return TRUE; return TRUE;
} }
static BOOL parse_template_members_list(parse_buffer * buf) static BOOL parse_template_members_list(parse_buffer * buf)
{ {
parse_buffer save1; parse_buffer save1;
int idx_member = 0;
member* cur_member;
while (1) while (1)
{ {
cur_member = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[idx_member];
save1 = *buf; save1 = *buf;
if (check_TOKEN(buf) == TOKEN_NAME) if (check_TOKEN(buf) == TOKEN_NAME)
{ {
if (!parse_name(buf)) if (!parse_name(buf))
break; break;
while (cur_member->idx_template < buf->pdxf->nb_xtemplates)
{
if (!strcmp((char*)buf->value, buf->pdxf->xtemplates[cur_member->idx_template].name))
break;
cur_member->idx_template++;
}
if (cur_member->idx_template == buf->pdxf->nb_xtemplates)
{
TRACE("Reference to non existing template '%s'\n", (char*)buf->value);
return FALSE;
}
if (check_TOKEN(buf) == TOKEN_NAME) if (check_TOKEN(buf) == TOKEN_NAME)
if (!parse_name(buf)) if (!parse_name(buf))
break; break;
if (parse_TOKEN(buf) != TOKEN_SEMICOLON) if (parse_TOKEN(buf) != TOKEN_SEMICOLON)
break; break;
cur_member->type = TOKEN_NAME;
strcpy(cur_member->name, (char*)buf->value);
idx_member++;
} }
else if (check_TOKEN(buf) == TOKEN_ARRAY) else if (check_TOKEN(buf) == TOKEN_ARRAY)
{ {
parse_buffer save2; parse_buffer save2;
WORD token; WORD token;
int nb_dims = 0;
parse_TOKEN(buf); parse_TOKEN(buf);
token = check_TOKEN(buf); token = check_TOKEN(buf);
if (is_primitive_type(token)) if (is_primitive_type(token))
{ {
parse_TOKEN(buf); parse_TOKEN(buf);
cur_member->type = token;
} }
else else
{ {
if (!parse_name(buf)) if (!parse_name(buf))
break; break;
cur_member->type = TOKEN_NAME;
cur_member->idx_template = 0;
while (cur_member->idx_template < buf->pdxf->nb_xtemplates)
{
if (!strcmp((char*)buf->value, buf->pdxf->xtemplates[cur_member->idx_template].name))
break;
cur_member->idx_template++;
}
if (cur_member->idx_template == buf->pdxf->nb_xtemplates)
{
TRACE("Reference to non existing template '%s'\n", (char*)buf->value);
return FALSE;
}
} }
if (!parse_name(buf)) if (!parse_name(buf))
break; break;
strcpy(cur_member->name, (char*)buf->value);
save2 = *buf; save2 = *buf;
while (check_TOKEN(buf) == TOKEN_OBRACKET) while (check_TOKEN(buf) == TOKEN_OBRACKET)
{ {
if (nb_dims)
{
FIXME("No support for multi-dimensional array yet\n");
return FALSE;
}
parse_TOKEN(buf); parse_TOKEN(buf);
if (check_TOKEN(buf) == TOKEN_INTEGER) if (check_TOKEN(buf) == TOKEN_INTEGER)
{ {
if (!parse_integer(buf)) if (!parse_integer(buf))
break; break;
cur_member->dim_fixed[nb_dims] = TRUE;
cur_member->dim_value[nb_dims] = *(DWORD*)buf->value;
} }
else else
{ {
if (!parse_name(buf)) if (!parse_name(buf))
break; break;
cur_member->dim_fixed[nb_dims] = FALSE;
/* Hack: Assume array size is specified in previous member */
cur_member->dim_value[nb_dims] = idx_member - 1;
} }
if (parse_TOKEN(buf) != TOKEN_CBRACKET) if (parse_TOKEN(buf) != TOKEN_CBRACKET)
break; break;
save2 = *buf; save2 = *buf;
nb_dims++;
} }
*buf = save2; *buf = save2;
if (parse_TOKEN(buf) != TOKEN_SEMICOLON) if (parse_TOKEN(buf) != TOKEN_SEMICOLON)
break; break;
cur_member->nb_dims = nb_dims;
idx_member++;
} }
else if (is_primitive_type(check_TOKEN(buf))) else if (is_primitive_type(check_TOKEN(buf)))
{ {
cur_member->type = check_TOKEN(buf);
parse_TOKEN(buf); parse_TOKEN(buf);
if (check_TOKEN(buf) == TOKEN_NAME) if (check_TOKEN(buf) == TOKEN_NAME)
if (!parse_name(buf)) if (!parse_name(buf))
break; break;
strcpy(cur_member->name, (char*)buf->value);
if (parse_TOKEN(buf) != TOKEN_SEMICOLON) if (parse_TOKEN(buf) != TOKEN_SEMICOLON)
break; break;
idx_member++;
} }
else else
break; break;
add_string(buf, "\n");
} }
*buf = save1; *buf = save1;
buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].nb_members = idx_member;
return TRUE; return TRUE;
} }
@ -801,7 +890,6 @@ static BOOL parse_template_parts(parse_buffer * buf)
return FALSE; return FALSE;
if (parse_TOKEN(buf) != TOKEN_CBRACKET) if (parse_TOKEN(buf) != TOKEN_CBRACKET)
return FALSE; return FALSE;
add_string(buf, "\n");
} }
else else
{ {
@ -814,7 +902,6 @@ static BOOL parse_template_parts(parse_buffer * buf)
return FALSE; return FALSE;
if (parse_TOKEN(buf) != TOKEN_CBRACKET) if (parse_TOKEN(buf) != TOKEN_CBRACKET)
return FALSE; return FALSE;
add_string(buf, "\n");
} }
} }
@ -827,18 +914,16 @@ static BOOL parse_template(parse_buffer * buf)
return FALSE; return FALSE;
if (!parse_name(buf)) if (!parse_name(buf))
return FALSE; return FALSE;
add_string(buf, "\n"); strcpy(buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, (char*)buf->value);
if (parse_TOKEN(buf) != TOKEN_OBRACE) if (parse_TOKEN(buf) != TOKEN_OBRACE)
return FALSE; return FALSE;
add_string(buf, "\n");
if (!parse_class_id(buf)) if (!parse_class_id(buf))
return FALSE; return FALSE;
add_string(buf, "\n"); buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id = *(GUID*)buf->value;
if (!parse_template_parts(buf)) if (!parse_template_parts(buf))
return FALSE; return FALSE;
if (parse_TOKEN(buf) != TOKEN_CBRACE) if (parse_TOKEN(buf) != TOKEN_CBRACE)
return FALSE; return FALSE;
add_string(buf, "\n\n");
if (buf->txt) if (buf->txt)
{ {
/* Go to the next template */ /* Go to the next template */
@ -851,6 +936,10 @@ static BOOL parse_template(parse_buffer * buf)
} }
} }
} }
TRACE("%d - %s - %s\n", buf->pdxf->nb_xtemplates, buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, debugstr_guid(&buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id));
buf->pdxf->nb_xtemplates++;
return TRUE; return TRUE;
} }
@ -862,9 +951,8 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
buf.buffer = (LPBYTE)pvData; buf.buffer = (LPBYTE)pvData;
buf.rem_bytes = cbSize; buf.rem_bytes = cbSize;
buf.dump = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
buf.size = 500;
buf.txt = FALSE; buf.txt = FALSE;
buf.pdxf = This;
FIXME("(%p/%p)->(%p,%d) partial stub!\n", This, iface, pvData, cbSize); FIXME("(%p/%p)->(%p,%d) partial stub!\n", This, iface, pvData, cbSize);
@ -917,21 +1005,64 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
while (buf.rem_bytes) while (buf.rem_bytes)
{ {
buf.pos = 0;
if (!parse_template(&buf)) if (!parse_template(&buf))
{ {
TRACE("Template is not correct\n"); TRACE("Template is not correct\n");
return DXFILEERR_BADVALUE; return DXFILEERR_BADVALUE;
} }
else else
{
TRACE("Template successfully parsed:\n"); TRACE("Template successfully parsed:\n");
if (TRACE_ON(d3dxof)) if (TRACE_ON(d3dxof))
/* Only dump in binary format */ {
if (!buf.txt) int i,j,k;
DPRINTF(buf.dump); GUID* clsid;
i = This->nb_xtemplates - 1;
clsid = &This->xtemplates[i].class_id;
DPRINTF("template %s {\n", This->xtemplates[i].name);
DPRINTF(CLSIDFMT "\n", clsid->Data1, clsid->Data2, clsid->Data3, clsid->Data4[0],
clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7]);
for (j = 0; j < This->xtemplates[i].nb_members; j++)
{
if (This->xtemplates[i].members[j].nb_dims)
DPRINTF("array ");
if (This->xtemplates[i].members[j].type == TOKEN_NAME)
DPRINTF("%s ", This->xtemplates[This->xtemplates[i].members[j].idx_template].name);
else
DPRINTF("%s ", get_primitive_string(This->xtemplates[i].members[j].type));
DPRINTF("%s", This->xtemplates[i].members[j].name);
for (k = 0; k < This->xtemplates[i].members[j].nb_dims; k++)
{
if (This->xtemplates[i].members[j].dim_fixed[k])
DPRINTF("[%d]", This->xtemplates[i].members[j].dim_value[k]);
else
DPRINTF("[%s]", This->xtemplates[i].members[This->xtemplates[i].members[j].dim_value[k]].name);
}
DPRINTF(";\n");
}
if (This->xtemplates[i].open)
DPRINTF("[...]\n");
else if (This->xtemplates[i].nb_childs)
{
DPRINTF("[%s", This->xtemplates[i].childs[0]);
for (j = 1; j < This->xtemplates[i].nb_childs; j++)
DPRINTF(",%s", This->xtemplates[i].childs[j]);
DPRINTF("]\n");
}
DPRINTF("}\n");
}
}
} }
HeapFree(GetProcessHeap(), 0, buf.dump); if (TRACE_ON(d3dxof))
{
int i;
TRACE("Registered templates (%d):\n", This->nb_xtemplates);
for (i = 0; i < This->nb_xtemplates; i++)
DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
}
return DXFILE_OK; return DXFILE_OK;
} }

View File

@ -1,7 +1,7 @@
/* /*
* DirectX File private interfaces (D3DXOF.DLL) * DirectX File private interfaces (D3DXOF.DLL)
* *
* Copyright 2004 Christian Costa * Copyright 2004, 2008 Christian Costa
* *
* This file contains the (internal) driver registration functions, * This file contains the (internal) driver registration functions,
* driver enumeration APIs and DirectDraw creation functions. * driver enumeration APIs and DirectDraw creation functions.
@ -33,9 +33,36 @@
#include "winuser.h" #include "winuser.h"
#include "dxfile.h" #include "dxfile.h"
#define MAX_NAME_LEN 32
#define MAX_ARRAY_DIM 1
#define MAX_MEMBERS 50
#define MAX_CHILDS 10
#define MAX_TEMPLATES 200
typedef struct {
DWORD type;
LONG idx_template;
char name[MAX_NAME_LEN];
ULONG nb_dims;
BOOL dim_fixed[MAX_ARRAY_DIM]; /* fixed or variable */
ULONG dim_value[MAX_ARRAY_DIM]; /* fixed value or member index */
} member;
typedef struct {
char name[MAX_NAME_LEN];
GUID class_id;
BOOL open;
ULONG nb_childs;
char childs[MAX_CHILDS][MAX_NAME_LEN];
ULONG nb_members;
member members[MAX_MEMBERS];
} xtemplate;
typedef struct { typedef struct {
IDirectXFile lpVtbl; IDirectXFile lpVtbl;
LONG ref; LONG ref;
ULONG nb_xtemplates;
xtemplate xtemplates[MAX_TEMPLATES];
} IDirectXFileImpl; } IDirectXFileImpl;
typedef struct { typedef struct {