push 378fe7a60681a28e8b22f62dcfe122d585b92570
[wine/hacks.git] / dlls / d3dxof / d3dxof.c
blob6aa0032d73eb389844e42ef99b866c2415d35d49
1 /*
2 * Implementation of DirectX File Interfaces
4 * Copyright 2004, 2008 Christian Costa
6 * This file contains the (internal) driver registration functions,
7 * driver enumeration APIs and DirectDraw creation functions.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "config.h"
25 #include "wine/debug.h"
27 #define COBJMACROS
29 #include "winbase.h"
30 #include "wingdi.h"
32 #include "d3dxof_private.h"
33 #include "dxfile.h"
35 #include <stdio.h>
37 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof);
39 #define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
40 #define XOFFILE_FORMAT_MAGIC MAKEFOUR('x','o','f',' ')
41 #define XOFFILE_FORMAT_VERSION_302 MAKEFOUR('0','3','0','2')
42 #define XOFFILE_FORMAT_VERSION_303 MAKEFOUR('0','3','0','3')
43 #define XOFFILE_FORMAT_BINARY MAKEFOUR('b','i','n',' ')
44 #define XOFFILE_FORMAT_TEXT MAKEFOUR('t','x','t',' ')
45 #define XOFFILE_FORMAT_COMPRESSED MAKEFOUR('c','m','p',' ')
46 #define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
47 #define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
49 #define MAX_INPUT_SIZE 2000000
51 static const struct IDirectXFileVtbl IDirectXFile_Vtbl;
52 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl;
53 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl;
54 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl;
55 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl;
56 static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl;
57 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl;
59 static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj);
60 static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj);
61 static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj);
63 HRESULT IDirectXFileImpl_Create(IUnknown* pUnkOuter, LPVOID* ppObj)
65 IDirectXFileImpl* object;
67 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
69 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileImpl));
70 if (!object)
72 ERR("Out of memory\n");
73 return DXFILEERR_BADALLOC;
76 object->lpVtbl.lpVtbl = &IDirectXFile_Vtbl;
77 object->ref = 1;
79 *ppObj = object;
81 return S_OK;
84 /*** IUnknown methods ***/
85 static HRESULT WINAPI IDirectXFileImpl_QueryInterface(IDirectXFile* iface, REFIID riid, void** ppvObject)
87 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
89 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
91 if (IsEqualGUID(riid, &IID_IUnknown)
92 || IsEqualGUID(riid, &IID_IDirectXFile))
94 IClassFactory_AddRef(iface);
95 *ppvObject = This;
96 return S_OK;
99 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
100 return E_NOINTERFACE;
103 static ULONG WINAPI IDirectXFileImpl_AddRef(IDirectXFile* iface)
105 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
106 ULONG ref = InterlockedIncrement(&This->ref);
108 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
110 return ref;
113 static ULONG WINAPI IDirectXFileImpl_Release(IDirectXFile* iface)
115 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
116 ULONG ref = InterlockedDecrement(&This->ref);
118 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
120 if (!ref)
121 HeapFree(GetProcessHeap(), 0, This);
123 return ref;
126 /*** IDirectXFile methods ***/
127 static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPVOID pvSource, DXFILELOADOPTIONS dwLoadOptions, LPDIRECTXFILEENUMOBJECT* ppEnumObj)
129 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
130 IDirectXFileEnumObjectImpl* object;
131 HRESULT hr;
132 DWORD header[4];
133 DWORD size;
134 HANDLE hFile = INVALID_HANDLE_VALUE;
135 LPDXFILELOADMEMORY lpdxflm = NULL;
137 TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj);
139 if (!ppEnumObj)
140 return DXFILEERR_BADVALUE;
142 if (dwLoadOptions == DXFILELOAD_FROMFILE)
144 TRACE("Open source file '%s'\n", (char*)pvSource);
146 hFile = CreateFileA(pvSource, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
147 if (hFile == INVALID_HANDLE_VALUE)
149 TRACE("File '%s' not found\n", (char*)pvSource);
150 return DXFILEERR_FILENOTFOUND;
153 if (!ReadFile(hFile, header, 16, &size, NULL))
155 hr = DXFILEERR_BADVALUE;
156 goto error;
159 if (size < 16)
161 hr = DXFILEERR_BADFILETYPE;
162 goto error;
165 else if (dwLoadOptions == DXFILELOAD_FROMMEMORY)
167 lpdxflm = pvSource;
169 TRACE("Source in memory at %p with size %d\n", lpdxflm->lpMemory, lpdxflm->dSize);
171 memcpy(header, lpdxflm->lpMemory, 16);
173 else
175 FIXME("Source type %d is not handled yet\n", dwLoadOptions);
176 hr = DXFILEERR_NOTDONEYET;
177 goto error;
180 if (TRACE_ON(d3dxof))
182 char string[17];
183 memcpy(string, header, 16);
184 string[16] = 0;
185 TRACE("header = '%s'\n", string);
188 if (header[0] != XOFFILE_FORMAT_MAGIC)
190 hr = DXFILEERR_BADFILETYPE;
191 goto error;
194 if ((header[1] != XOFFILE_FORMAT_VERSION_302) && (header[1] != XOFFILE_FORMAT_VERSION_303))
196 hr = DXFILEERR_BADFILEVERSION;
197 goto error;
200 if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) && (header[2] != XOFFILE_FORMAT_COMPRESSED))
202 hr = DXFILEERR_BADFILETYPE;
203 goto error;
206 if (header[2] == XOFFILE_FORMAT_COMPRESSED)
208 FIXME("Compressed formats not supported yet\n");
209 hr = DXFILEERR_BADVALUE;
210 goto error;
213 if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
215 hr = DXFILEERR_BADFILEFLOATSIZE;
216 goto error;
219 TRACE("Header is correct\n");
221 hr = IDirectXFileEnumObjectImpl_Create(&object);
222 if (FAILED(hr))
223 goto error;
225 object->source = dwLoadOptions;
226 object->hFile = hFile;
227 object->pDirectXFile = This;
228 object->buf.pdxf = This;
229 object->buf.txt = (header[2] == XOFFILE_FORMAT_TEXT);
230 object->buf.token_present = FALSE;
231 object->buf.cur_subobject = 0;
233 if (dwLoadOptions == DXFILELOAD_FROMFILE)
235 object->buf.buffer = HeapAlloc(GetProcessHeap(), 0, MAX_INPUT_SIZE+1);
236 if (!object->buf.buffer)
238 ERR("Out of memory\n");
239 hr = DXFILEERR_BADALLOC;
240 goto error;
243 ReadFile(hFile, object->buf.buffer, MAX_INPUT_SIZE+1, &object->buf.rem_bytes, NULL);
244 if (object->buf.rem_bytes > MAX_INPUT_SIZE)
246 FIXME("File size > %d not supported yet\n", MAX_INPUT_SIZE);
247 HeapFree(GetProcessHeap(), 0, object->buf.buffer);
248 hr = DXFILEERR_PARSEERROR;
249 goto error;
252 else
254 object->buf.buffer = ((LPBYTE)lpdxflm->lpMemory) + 16;
255 object->buf.rem_bytes = lpdxflm->dSize;
258 TRACE("Read %d bytes\n", object->buf.rem_bytes);
260 *ppEnumObj = (LPDIRECTXFILEENUMOBJECT)object;
262 while (object->buf.rem_bytes && is_template_available(&object->buf))
264 if (!parse_template(&object->buf))
266 TRACE("Template is not correct\n");
267 hr = DXFILEERR_BADVALUE;
268 goto error;
270 else
272 TRACE("Template successfully parsed:\n");
273 if (TRACE_ON(d3dxof))
274 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
278 if (TRACE_ON(d3dxof))
280 int i;
281 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
282 for (i = 0; i < This->nb_xtemplates; i++)
283 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
286 return DXFILE_OK;
288 error:
289 if (hFile != INVALID_HANDLE_VALUE)
290 CloseHandle(hFile);
291 *ppEnumObj = NULL;
293 return hr;
296 static HRESULT WINAPI IDirectXFileImpl_CreateSaveObject(IDirectXFile* iface, LPCSTR szFileName, DXFILEFORMAT dwFileFormat, LPDIRECTXFILESAVEOBJECT* ppSaveObj)
298 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
300 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This, iface, szFileName, dwFileFormat, ppSaveObj);
302 if (!szFileName || !ppSaveObj)
303 return E_POINTER;
305 return IDirectXFileSaveObjectImpl_Create((IDirectXFileSaveObjectImpl**)ppSaveObj);
308 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
310 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
311 DWORD token_header;
312 parse_buffer buf;
314 buf.buffer = pvData;
315 buf.rem_bytes = cbSize;
316 buf.txt = FALSE;
317 buf.token_present = FALSE;
318 buf.pdxf = This;
320 TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize);
322 if (!pvData)
323 return DXFILEERR_BADVALUE;
325 if (cbSize < 16)
326 return DXFILEERR_BADFILETYPE;
328 if (TRACE_ON(d3dxof))
330 char string[17];
331 memcpy(string, pvData, 16);
332 string[16] = 0;
333 TRACE("header = '%s'\n", string);
336 read_bytes(&buf, &token_header, 4);
338 if (token_header != XOFFILE_FORMAT_MAGIC)
339 return DXFILEERR_BADFILETYPE;
341 read_bytes(&buf, &token_header, 4);
343 if ((token_header != XOFFILE_FORMAT_VERSION_302) && (token_header != XOFFILE_FORMAT_VERSION_303))
344 return DXFILEERR_BADFILEVERSION;
346 read_bytes(&buf, &token_header, 4);
348 if ((token_header != XOFFILE_FORMAT_BINARY) && (token_header != XOFFILE_FORMAT_TEXT) && (token_header != XOFFILE_FORMAT_COMPRESSED))
349 return DXFILEERR_BADFILETYPE;
351 if (token_header == XOFFILE_FORMAT_TEXT)
353 buf.txt = TRUE;
356 if (token_header == XOFFILE_FORMAT_COMPRESSED)
358 FIXME("Compressed formats not supported yet\n");
359 return DXFILEERR_BADVALUE;
362 read_bytes(&buf, &token_header, 4);
364 if ((token_header != XOFFILE_FORMAT_FLOAT_BITS_32) && (token_header != XOFFILE_FORMAT_FLOAT_BITS_64))
365 return DXFILEERR_BADFILEFLOATSIZE;
367 TRACE("Header is correct\n");
369 while (buf.rem_bytes)
371 if (!parse_template(&buf))
373 TRACE("Template is not correct\n");
374 return DXFILEERR_BADVALUE;
376 else
378 TRACE("Template successfully parsed:\n");
379 if (TRACE_ON(d3dxof))
380 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
384 if (TRACE_ON(d3dxof))
386 int i;
387 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
388 for (i = 0; i < This->nb_xtemplates; i++)
389 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
392 return DXFILE_OK;
395 static const IDirectXFileVtbl IDirectXFile_Vtbl =
397 IDirectXFileImpl_QueryInterface,
398 IDirectXFileImpl_AddRef,
399 IDirectXFileImpl_Release,
400 IDirectXFileImpl_CreateEnumObject,
401 IDirectXFileImpl_CreateSaveObject,
402 IDirectXFileImpl_RegisterTemplates
405 static HRESULT IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl** ppObj)
407 IDirectXFileBinaryImpl* object;
409 TRACE("(%p)\n", ppObj);
411 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileBinaryImpl));
412 if (!object)
414 ERR("Out of memory\n");
415 return DXFILEERR_BADALLOC;
418 object->lpVtbl.lpVtbl = &IDirectXFileBinary_Vtbl;
419 object->ref = 1;
421 *ppObj = object;
423 return DXFILE_OK;
426 /*** IUnknown methods ***/
427 static HRESULT WINAPI IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary* iface, REFIID riid, void** ppvObject)
429 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
431 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
433 if (IsEqualGUID(riid, &IID_IUnknown)
434 || IsEqualGUID(riid, &IID_IDirectXFileObject)
435 || IsEqualGUID(riid, &IID_IDirectXFileBinary))
437 IClassFactory_AddRef(iface);
438 *ppvObject = This;
439 return S_OK;
442 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
443 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
444 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
445 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
447 return E_NOINTERFACE;
450 static ULONG WINAPI IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary* iface)
452 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
453 ULONG ref = InterlockedIncrement(&This->ref);
455 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
457 return ref;
460 static ULONG WINAPI IDirectXFileBinaryImpl_Release(IDirectXFileBinary* iface)
462 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
463 ULONG ref = InterlockedDecrement(&This->ref);
465 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
467 if (!ref)
468 HeapFree(GetProcessHeap(), 0, This);
470 return ref;
473 /*** IDirectXFileObject methods ***/
474 static HRESULT WINAPI IDirectXFileBinaryImpl_GetName(IDirectXFileBinary* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
477 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
479 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, pstrNameBuf, pdwBufLen);
481 return DXFILEERR_BADVALUE;
484 static HRESULT WINAPI IDirectXFileBinaryImpl_GetId(IDirectXFileBinary* iface, LPGUID pGuid)
486 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
488 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pGuid);
490 return DXFILEERR_BADVALUE;
493 /*** IDirectXFileBinary methods ***/
494 static HRESULT WINAPI IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary* iface, DWORD* pcbSize)
496 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
498 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pcbSize);
500 return DXFILEERR_BADVALUE;
503 static HRESULT WINAPI IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary* iface, LPCSTR* pszMimeType)
505 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
507 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pszMimeType);
509 return DXFILEERR_BADVALUE;
512 static HRESULT WINAPI IDirectXFileBinaryImpl_Read(IDirectXFileBinary* iface, LPVOID pvData, DWORD cbSize, LPDWORD pcbRead)
514 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
516 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This, iface, pvData, cbSize, pcbRead);
518 return DXFILEERR_BADVALUE;
521 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl =
523 IDirectXFileBinaryImpl_QueryInterface,
524 IDirectXFileBinaryImpl_AddRef,
525 IDirectXFileBinaryImpl_Release,
526 IDirectXFileBinaryImpl_GetName,
527 IDirectXFileBinaryImpl_GetId,
528 IDirectXFileBinaryImpl_GetSize,
529 IDirectXFileBinaryImpl_GetMimeType,
530 IDirectXFileBinaryImpl_Read
533 static HRESULT IDirectXFileDataImpl_Create(IDirectXFileDataImpl** ppObj)
535 IDirectXFileDataImpl* object;
537 TRACE("(%p)\n", ppObj);
539 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataImpl));
540 if (!object)
542 ERR("Out of memory\n");
543 return DXFILEERR_BADALLOC;
546 object->lpVtbl.lpVtbl = &IDirectXFileData_Vtbl;
547 object->ref = 1;
549 *ppObj = object;
551 return S_OK;
554 /*** IUnknown methods ***/
555 static HRESULT WINAPI IDirectXFileDataImpl_QueryInterface(IDirectXFileData* iface, REFIID riid, void** ppvObject)
557 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
559 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
561 if (IsEqualGUID(riid, &IID_IUnknown)
562 || IsEqualGUID(riid, &IID_IDirectXFileObject)
563 || IsEqualGUID(riid, &IID_IDirectXFileData))
565 IClassFactory_AddRef(iface);
566 *ppvObject = This;
567 return S_OK;
570 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
571 if (!IsEqualGUID(riid, &IID_IDirectXFileBinary)
572 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
573 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
575 return E_NOINTERFACE;
578 static ULONG WINAPI IDirectXFileDataImpl_AddRef(IDirectXFileData* iface)
580 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
581 ULONG ref = InterlockedIncrement(&This->ref);
583 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
585 return ref;
588 static ULONG WINAPI IDirectXFileDataImpl_Release(IDirectXFileData* iface)
590 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
591 ULONG ref = InterlockedDecrement(&This->ref);
593 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
595 if (!ref)
597 if (!This->level)
599 HeapFree(GetProcessHeap(), 0, This->pdata);
600 HeapFree(GetProcessHeap(), 0, This->pstrings);
602 HeapFree(GetProcessHeap(), 0, This);
605 return ref;
608 /*** IDirectXFileObject methods ***/
609 static HRESULT WINAPI IDirectXFileDataImpl_GetName(IDirectXFileData* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
612 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
614 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
616 if (!pstrNameBuf)
617 return DXFILEERR_BADVALUE;
619 strcpy(pstrNameBuf, This->pobj->name);
621 return DXFILE_OK;
624 static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid)
626 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
628 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
630 if (!pGuid)
631 return DXFILEERR_BADVALUE;
633 memcpy(pGuid, &This->pobj->class_id, 16);
635 return DXFILE_OK;
638 /*** IDirectXFileData methods ***/
639 static HRESULT WINAPI IDirectXFileDataImpl_GetData(IDirectXFileData* iface, LPCSTR szMember, DWORD* pcbSize, void** ppvData)
641 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
643 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, szMember, pcbSize, ppvData);
645 if (!pcbSize || !ppvData)
646 return DXFILEERR_BADVALUE;
648 if (szMember)
650 FIXME("Specifying a member is not supported yet!\n");
651 return DXFILEERR_BADVALUE;
654 *pcbSize = This->pobj->size;
655 *ppvData = This->pobj->pdata;
657 return DXFILE_OK;
660 static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid)
662 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
663 static GUID guid;
665 TRACE("(%p/%p)->(%p)\n", This, iface, pguid);
667 if (!pguid)
668 return DXFILEERR_BADVALUE;
670 memcpy(&guid, &This->pobj->type, 16);
671 *pguid = &guid;
673 return DXFILE_OK;
676 static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj)
678 HRESULT hr;
679 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
681 TRACE("(%p/%p)->(%p)\n", This, iface, ppChildObj);
683 if (This->cur_enum_object >= This->pobj->nb_childs)
684 return DXFILEERR_NOMOREOBJECTS;
686 if (This->from_ref && (This->level >= 1))
688 /* Only 2 levels can enumerated if the object is obtained from a reference */
689 return DXFILEERR_NOMOREOBJECTS;
692 if (This->pobj->childs[This->cur_enum_object]->binary)
694 IDirectXFileBinaryImpl *object;
696 hr = IDirectXFileBinaryImpl_Create(&object);
697 if (FAILED(hr))
698 return hr;
700 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
702 else if (This->pobj->childs[This->cur_enum_object]->ptarget)
704 IDirectXFileDataReferenceImpl *object;
706 hr = IDirectXFileDataReferenceImpl_Create(&object);
707 if (FAILED(hr))
708 return hr;
710 object->ptarget = This->pobj->childs[This->cur_enum_object++]->ptarget;
712 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
714 else
716 IDirectXFileDataImpl *object;
718 hr = IDirectXFileDataImpl_Create(&object);
719 if (FAILED(hr))
720 return hr;
722 object->pobj = This->pobj->childs[This->cur_enum_object++];
723 object->cur_enum_object = 0;
724 object->from_ref = This->from_ref;
725 object->level = This->level + 1;
727 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
730 return DXFILE_OK;
733 static HRESULT WINAPI IDirectXFileDataImpl_AddDataObject(IDirectXFileData* iface, LPDIRECTXFILEDATA pDataObj)
735 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
737 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pDataObj);
739 return DXFILEERR_BADVALUE;
742 static HRESULT WINAPI IDirectXFileDataImpl_AddDataReference(IDirectXFileData* iface, LPCSTR szRef, const GUID* pguidRef)
744 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
746 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szRef, pguidRef);
748 return DXFILEERR_BADVALUE;
751 static HRESULT WINAPI IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData* iface, LPCSTR szName, const GUID* pguid, LPCSTR szMimeType, LPVOID pvData, DWORD cbSize)
753 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
755 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This, iface, szName, pguid, szMimeType, pvData, cbSize);
757 return DXFILEERR_BADVALUE;
760 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl =
762 IDirectXFileDataImpl_QueryInterface,
763 IDirectXFileDataImpl_AddRef,
764 IDirectXFileDataImpl_Release,
765 IDirectXFileDataImpl_GetName,
766 IDirectXFileDataImpl_GetId,
767 IDirectXFileDataImpl_GetData,
768 IDirectXFileDataImpl_GetType,
769 IDirectXFileDataImpl_GetNextObject,
770 IDirectXFileDataImpl_AddDataObject,
771 IDirectXFileDataImpl_AddDataReference,
772 IDirectXFileDataImpl_AddBinaryObject
775 static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj)
777 IDirectXFileDataReferenceImpl* object;
779 TRACE("(%p)\n", ppObj);
781 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataReferenceImpl));
782 if (!object)
784 ERR("Out of memory\n");
785 return DXFILEERR_BADALLOC;
788 object->lpVtbl.lpVtbl = &IDirectXFileDataReference_Vtbl;
789 object->ref = 1;
791 *ppObj = object;
793 return S_OK;
796 /*** IUnknown methods ***/
797 static HRESULT WINAPI IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference* iface, REFIID riid, void** ppvObject)
799 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
801 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
803 if (IsEqualGUID(riid, &IID_IUnknown)
804 || IsEqualGUID(riid, &IID_IDirectXFileObject)
805 || IsEqualGUID(riid, &IID_IDirectXFileDataReference))
807 IClassFactory_AddRef(iface);
808 *ppvObject = This;
809 return S_OK;
812 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
813 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
814 && !IsEqualGUID(riid, &IID_IDirectXFileBinary))
815 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
817 return E_NOINTERFACE;
820 static ULONG WINAPI IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference* iface)
822 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
823 ULONG ref = InterlockedIncrement(&This->ref);
825 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
827 return ref;
830 static ULONG WINAPI IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference* iface)
832 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
833 ULONG ref = InterlockedDecrement(&This->ref);
835 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
837 if (!ref)
838 HeapFree(GetProcessHeap(), 0, This);
840 return ref;
843 /*** IDirectXFileObject methods ***/
844 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
846 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
848 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
850 if (!pstrNameBuf)
851 return DXFILEERR_BADVALUE;
853 strcpy(pstrNameBuf, This->ptarget->name);
855 return DXFILEERR_BADVALUE;
858 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference* iface, LPGUID pGuid)
860 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
862 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
864 if (!pGuid)
865 return DXFILEERR_BADVALUE;
867 memcpy(pGuid, &This->ptarget->class_id, 16);
869 return DXFILE_OK;
872 /*** IDirectXFileDataReference ***/
873 static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj)
875 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
876 IDirectXFileDataImpl *object;
877 HRESULT hr;
879 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
881 if (!ppDataObj)
882 return DXFILEERR_BADVALUE;
884 hr = IDirectXFileDataImpl_Create(&object);
885 if (FAILED(hr))
886 return hr;
888 object->pobj = This->ptarget;
889 object->cur_enum_object = 0;
890 object->level = 0;
891 object->from_ref = TRUE;
893 *ppDataObj = (LPDIRECTXFILEDATA)object;
895 return DXFILE_OK;
898 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl =
900 IDirectXFileDataReferenceImpl_QueryInterface,
901 IDirectXFileDataReferenceImpl_AddRef,
902 IDirectXFileDataReferenceImpl_Release,
903 IDirectXFileDataReferenceImpl_GetName,
904 IDirectXFileDataReferenceImpl_GetId,
905 IDirectXFileDataReferenceImpl_Resolve
908 static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj)
910 IDirectXFileEnumObjectImpl* object;
912 TRACE("(%p)\n", ppObj);
914 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileEnumObjectImpl));
915 if (!object)
917 ERR("Out of memory\n");
918 return DXFILEERR_BADALLOC;
921 object->lpVtbl.lpVtbl = &IDirectXFileEnumObject_Vtbl;
922 object->ref = 1;
924 *ppObj = object;
926 return S_OK;
929 /*** IUnknown methods ***/
930 static HRESULT WINAPI IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject* iface, REFIID riid, void** ppvObject)
932 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
934 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
936 if (IsEqualGUID(riid, &IID_IUnknown)
937 || IsEqualGUID(riid, &IID_IDirectXFileEnumObject))
939 IClassFactory_AddRef(iface);
940 *ppvObject = This;
941 return S_OK;
944 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
945 return E_NOINTERFACE;
948 static ULONG WINAPI IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject* iface)
950 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
951 ULONG ref = InterlockedIncrement(&This->ref);
953 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
955 return ref;
958 static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* iface)
960 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
961 ULONG ref = InterlockedDecrement(&This->ref);
963 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
965 if (!ref)
967 int i;
968 for (i = 0; i < This->nb_xobjects; i++)
970 IDirectXFileData_Release(This->pRefObjects[i]);
971 HeapFree(GetProcessHeap(), 0, This->xobjects[i]);
973 if (This->source == DXFILELOAD_FROMFILE)
975 HeapFree(GetProcessHeap(), 0, This->buf.buffer);
976 CloseHandle(This->hFile);
978 HeapFree(GetProcessHeap(), 0, This);
981 return ref;
984 /*** IDirectXFileEnumObject methods ***/
985 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj)
987 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
988 IDirectXFileDataImpl* object;
989 HRESULT hr;
990 LPBYTE pdata = NULL;
991 LPBYTE pstrings = NULL;
993 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
995 if (This->nb_xobjects >= MAX_OBJECTS)
997 ERR("Too many objects\n");
998 return DXFILEERR_NOMOREOBJECTS;
1001 if (!This->buf.rem_bytes)
1002 return DXFILEERR_NOMOREOBJECTS;
1004 hr = IDirectXFileDataImpl_Create(&object);
1005 if (FAILED(hr))
1006 return hr;
1008 This->buf.pxo_globals = This->xobjects;
1009 This->buf.nb_pxo_globals = This->nb_xobjects;
1010 This->buf.cur_subobject = 1;
1011 This->buf.level = 0;
1013 This->buf.pxo_tab = HeapAlloc(GetProcessHeap(), 0, sizeof(xobject)*MAX_SUBOBJECTS);
1014 if (!This->buf.pxo_tab)
1016 ERR("Out of memory\n");
1017 hr = DXFILEERR_BADALLOC;
1018 goto error;
1020 This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab;
1022 pdata = HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE);
1023 if (!pdata)
1025 ERR("Out of memory\n");
1026 hr = DXFILEERR_BADALLOC;
1027 goto error;
1029 This->buf.cur_pdata = This->buf.pdata = object->pdata = pdata;
1031 pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER);
1032 if (!pstrings)
1034 ERR("Out of memory\n");
1035 hr = DXFILEERR_BADALLOC;
1036 goto error;
1038 This->buf.cur_pstrings = This->buf.pstrings = object->pstrings = pstrings;
1040 if (!parse_object(&This->buf))
1042 TRACE("Object is not correct\n");
1043 hr = DXFILEERR_PARSEERROR;
1044 goto error;
1047 This->buf.pxo->nb_subobjects = This->buf.cur_subobject;
1048 if (This->buf.cur_subobject > MAX_SUBOBJECTS)
1050 FIXME("Too many suobjects %d\n", This->buf.cur_subobject);
1051 hr = DXFILEERR_BADALLOC;
1052 goto error;
1055 object->pstrings = pstrings;
1056 object->pobj = This->buf.pxo;
1057 object->cur_enum_object = 0;
1058 object->level = 0;
1059 object->from_ref = FALSE;
1061 *ppDataObj = (LPDIRECTXFILEDATA)object;
1063 /* Get a reference to created object */
1064 This->pRefObjects[This->nb_xobjects] = (LPDIRECTXFILEDATA)object;
1065 IDirectXFileData_AddRef(This->pRefObjects[This->nb_xobjects]);
1067 This->nb_xobjects++;
1069 return DXFILE_OK;
1071 error:
1073 HeapFree(GetProcessHeap(), 0, This->buf.pxo_tab);
1074 HeapFree(GetProcessHeap(), 0, pdata);
1075 HeapFree(GetProcessHeap(), 0, pstrings);
1077 return hr;
1080 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject* iface, REFGUID rguid, LPDIRECTXFILEDATA* ppDataObj)
1082 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1084 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, rguid, ppDataObj);
1086 return DXFILEERR_BADVALUE;
1089 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject* iface, LPCSTR szName, LPDIRECTXFILEDATA* ppDataObj)
1091 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1093 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szName, ppDataObj);
1095 return DXFILEERR_BADVALUE;
1098 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl =
1100 IDirectXFileEnumObjectImpl_QueryInterface,
1101 IDirectXFileEnumObjectImpl_AddRef,
1102 IDirectXFileEnumObjectImpl_Release,
1103 IDirectXFileEnumObjectImpl_GetNextDataObject,
1104 IDirectXFileEnumObjectImpl_GetDataObjectById,
1105 IDirectXFileEnumObjectImpl_GetDataObjectByName
1108 static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj)
1110 IDirectXFileSaveObjectImpl* object;
1112 TRACE("(%p)\n", ppObj);
1114 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileSaveObjectImpl));
1115 if (!object)
1117 ERR("Out of memory\n");
1118 return DXFILEERR_BADALLOC;
1121 object->lpVtbl.lpVtbl = &IDirectXFileSaveObject_Vtbl;
1122 object->ref = 1;
1124 *ppObj = object;
1126 return S_OK;
1129 /*** IUnknown methods ***/
1130 static HRESULT WINAPI IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject* iface, REFIID riid, void** ppvObject)
1132 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1134 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1136 if (IsEqualGUID(riid, &IID_IUnknown)
1137 || IsEqualGUID(riid, &IID_IDirectXFileSaveObject))
1139 IClassFactory_AddRef(iface);
1140 *ppvObject = This;
1141 return S_OK;
1144 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1145 return E_NOINTERFACE;
1148 static ULONG WINAPI IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject* iface)
1150 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1151 ULONG ref = InterlockedIncrement(&This->ref);
1153 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1155 return ref;
1158 static ULONG WINAPI IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject* iface)
1160 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1161 ULONG ref = InterlockedDecrement(&This->ref);
1163 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1165 if (!ref)
1166 HeapFree(GetProcessHeap(), 0, This);
1168 return ref;
1171 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject* iface, DWORD cTemplates, const GUID** ppguidTemplates)
1173 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1175 FIXME("(%p/%p)->(%d,%p) stub!\n", This, iface, cTemplates, ppguidTemplates);
1177 return DXFILEERR_BADVALUE;
1180 static HRESULT WINAPI IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject* iface, REFGUID rguidTemplate, LPCSTR szName, const GUID* pguid, DWORD cbSize, LPVOID pvData, LPDIRECTXFILEDATA* ppDataObj)
1182 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1184 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This, iface, rguidTemplate, szName, pguid, cbSize, pvData, ppDataObj);
1186 return DXFILEERR_BADVALUE;
1189 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject* iface, LPDIRECTXFILEDATA ppDataObj)
1191 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1193 FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppDataObj);
1195 return DXFILEERR_BADVALUE;
1198 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl =
1200 IDirectXFileSaveObjectImpl_QueryInterface,
1201 IDirectXFileSaveObjectImpl_AddRef,
1202 IDirectXFileSaveObjectImpl_Release,
1203 IDirectXFileSaveObjectImpl_SaveTemplates,
1204 IDirectXFileSaveObjectImpl_CreateDataObject,
1205 IDirectXFileSaveObjectImpl_SaveData