diff --git a/reactos/dll/directx/wine/CMakeLists.txt b/reactos/dll/directx/wine/CMakeLists.txt index f0e665bc097..64a2befba77 100644 --- a/reactos/dll/directx/wine/CMakeLists.txt +++ b/reactos/dll/directx/wine/CMakeLists.txt @@ -22,5 +22,6 @@ add_subdirectory(d3dx9_39) add_subdirectory(d3dx9_40) add_subdirectory(d3dx9_41) add_subdirectory(d3dx9_42) +add_subdirectory(d3dxof) add_subdirectory(ddraw) add_subdirectory(wined3d) diff --git a/reactos/dll/directx/wine/d3dxof/CMakeLists.txt b/reactos/dll/directx/wine/d3dxof/CMakeLists.txt new file mode 100644 index 00000000000..0cf261b1397 --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/CMakeLists.txt @@ -0,0 +1,18 @@ + +add_definitions(-D__WINESRC__) +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) + +spec2def(d3dxof.dll d3dxof.spec ADD_IMPORTLIB) + +list(APPEND SOURCE + d3dxof.c + main.c + mszip.c + parsing.c + ${CMAKE_CURRENT_BINARY_DIR}/d3dxof.def) + +add_library(d3dxof SHARED ${SOURCE} version.rc) +set_module_type(d3dxof win32dll) +target_link_libraries(d3dxof dxguid uuid wine) +add_importlibs(d3dxof msvcrt kernel32 ntdll) +add_cd_file(TARGET d3dxof DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/directx/wine/d3dxof/d3dxof.c b/reactos/dll/directx/wine/d3dxof/d3dxof.c new file mode 100644 index 00000000000..f72617068f4 --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/d3dxof.c @@ -0,0 +1,1222 @@ +/* + * Implementation of DirectX File Interfaces + * + * Copyright 2004, 2008, 2010 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/debug.h" + +#define COBJMACROS + +#include "winbase.h" +#include "wingdi.h" + +#include "d3dxof_private.h" +#include "dxfile.h" + +#include + +WINE_DEFAULT_DEBUG_CHANNEL(d3dxof); +WINE_DECLARE_DEBUG_CHANNEL(d3dxof_dump); + +static const struct IDirectXFileVtbl IDirectXFile_Vtbl; +static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl; +static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl; +static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl; +static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl; +static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl; +static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl; + +static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj); +static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj); +static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj); + +#define TOKEN_DWORD 41 +#define TOKEN_FLOAT 42 + +HRESULT IDirectXFileImpl_Create(IUnknown* pUnkOuter, LPVOID* ppObj) +{ + IDirectXFileImpl* object; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileImpl)); + if (!object) + { + ERR("Out of memory\n"); + return DXFILEERR_BADALLOC; + } + + object->IDirectXFile_iface.lpVtbl = &IDirectXFile_Vtbl; + object->ref = 1; + + /* Reserve first template to handle the case sensitive legacy type indexColor */ + object->nb_xtemplates = 1; + strcpy(object->xtemplates[0].name, "indexColor"); + object->xtemplates[0].nb_members = 2; + object->xtemplates[0].members[0].type = TOKEN_DWORD; + object->xtemplates[0].members[0].nb_dims = 0; + object->xtemplates[0].members[1].type = TOKEN_FLOAT; + object->xtemplates[0].members[1].nb_dims = 1; + object->xtemplates[0].members[1].dim_fixed[0] = TRUE; + object->xtemplates[0].members[1].dim_value[0] = 4; + + *ppObj = &object->IDirectXFile_iface; + + return S_OK; +} + +static inline IDirectXFileImpl *impl_from_IDirectXFile(IDirectXFile *iface) +{ + return CONTAINING_RECORD(iface, IDirectXFileImpl, IDirectXFile_iface); +} + +/*** IUnknown methods ***/ +static HRESULT WINAPI IDirectXFileImpl_QueryInterface(IDirectXFile* iface, REFIID riid, void** ppvObject) +{ + IDirectXFileImpl *This = impl_from_IDirectXFile(iface); + + TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirectXFile)) + { + IUnknown_AddRef(iface); + *ppvObject = &This->IDirectXFile_iface; + return S_OK; + } + + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + return E_NOINTERFACE; +} + +static ULONG WINAPI IDirectXFileImpl_AddRef(IDirectXFile* iface) +{ + IDirectXFileImpl *This = impl_from_IDirectXFile(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + return ref; +} + +static ULONG WINAPI IDirectXFileImpl_Release(IDirectXFile* iface) +{ + IDirectXFileImpl *This = impl_from_IDirectXFile(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +/*** IDirectXFile methods ***/ +static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPVOID pvSource, DXFILELOADOPTIONS dwLoadOptions, LPDIRECTXFILEENUMOBJECT* ppEnumObj) +{ + IDirectXFileImpl *This = impl_from_IDirectXFile(iface); + IDirectXFileEnumObjectImpl* object; + HRESULT hr; + LPBYTE file_buffer; + DWORD file_size; + + TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj); + + if (!ppEnumObj) + return DXFILEERR_BADVALUE; + + /* 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; + + TRACE("Open source file '%s'\n", (char*)pvSource); + + hFile = CreateFileA(pvSource, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + TRACE("File '%s' not found\n", (char*)pvSource); + return DXFILEERR_FILENOTFOUND; + } + + file_size = GetFileSize(hFile, NULL); + + file_mapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + CloseHandle(hFile); + if (!file_mapping) + { + hr = DXFILEERR_BADFILETYPE; + goto error; + } + + object->mapped_memory = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0); + CloseHandle(file_mapping); + if (!object->mapped_memory) + { + hr = DXFILEERR_BADFILETYPE; + goto error; + } + file_buffer = object->mapped_memory; + } + else if (dwLoadOptions == DXFILELOAD_FROMRESOURCE) + { + HRSRC resource_info; + HGLOBAL resource_data; + LPDXFILELOADRESOURCE lpdxflr = pvSource; + + TRACE("Source in resource (module = %p, name = %s, type = %s\n", lpdxflr->hModule, debugstr_a(lpdxflr->lpName), debugstr_a(lpdxflr->lpType)); + + resource_info = FindResourceA(lpdxflr->hModule, lpdxflr->lpName, lpdxflr->lpType); + if (!resource_info) + { + hr = DXFILEERR_RESOURCENOTFOUND; + goto error; + } + + file_size = SizeofResource(lpdxflr->hModule, resource_info); + + resource_data = LoadResource(lpdxflr->hModule, resource_info); + if (!resource_data) + { + hr = DXFILEERR_BADRESOURCE; + goto error; + } + + file_buffer = LockResource(resource_data); + if (!file_buffer) + { + hr = DXFILEERR_BADRESOURCE; + goto error; + } + } + else if (dwLoadOptions == DXFILELOAD_FROMMEMORY) + { + LPDXFILELOADMEMORY lpdxflm = pvSource; + + TRACE("Source in memory at %p with size %d\n", lpdxflm->lpMemory, lpdxflm->dSize); + + file_buffer = lpdxflm->lpMemory; + file_size = lpdxflm->dSize; + } + else + { + FIXME("Source type %d is not handled yet\n", dwLoadOptions); + hr = DXFILEERR_NOTDONEYET; + goto error; + } + + TRACE("File size is %d bytes\n", file_size); + + if (TRACE_ON(d3dxof_dump)) + { + static USHORT num; + char tmp[12]; + HANDLE file; + sprintf(tmp, "file%05u.x", num++); + + file = CreateFileA(tmp, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); + if (file != INVALID_HANDLE_VALUE) + { + WriteFile(file, file_buffer, file_size, NULL, NULL); + CloseHandle(file); + } + } + + object->pDirectXFile = This; + + object->buf.pdxf = This; + object->buf.token_present = FALSE; + object->buf.buffer = file_buffer; + object->buf.rem_bytes = file_size; + hr = parse_header(&object->buf, &object->decomp_buffer); + if (FAILED(hr)) + goto error; + + /* Check if there are templates defined before the object */ + if (!parse_templates(&object->buf, TRUE)) + { + hr = DXFILEERR_PARSEERROR; + goto error; + } + + if (TRACE_ON(d3dxof)) + { + ULONG i; + TRACE("Registered templates (%d):\n", This->nb_xtemplates); + for (i = 1; i < This->nb_xtemplates; i++) + DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id)); + } + + *ppEnumObj = &object->IDirectXFileEnumObject_iface; + + return DXFILE_OK; + +error: + IDirectXFileEnumObject_Release(&object->IDirectXFileEnumObject_iface); + *ppEnumObj = NULL; + + return hr; +} + +static HRESULT WINAPI IDirectXFileImpl_CreateSaveObject(IDirectXFile* iface, LPCSTR szFileName, DXFILEFORMAT dwFileFormat, LPDIRECTXFILESAVEOBJECT* ppSaveObj) +{ + IDirectXFileImpl *This = impl_from_IDirectXFile(iface); + IDirectXFileSaveObjectImpl *object; + HRESULT hr; + + FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This, iface, szFileName, dwFileFormat, ppSaveObj); + + if (!szFileName || !ppSaveObj) + return E_POINTER; + + hr = IDirectXFileSaveObjectImpl_Create(&object); + if (SUCCEEDED(hr)) + *ppSaveObj = &object->IDirectXFileSaveObject_iface; + return hr; +} + +static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize) +{ + IDirectXFileImpl *This = impl_from_IDirectXFile(iface); + parse_buffer buf; + HRESULT hr; + LPBYTE decomp_buffer = NULL; + + ZeroMemory(&buf, sizeof(buf)); + buf.buffer = pvData; + buf.rem_bytes = cbSize; + buf.pdxf = This; + + TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize); + + if (!pvData) + return DXFILEERR_BADVALUE; + + if (TRACE_ON(d3dxof_dump)) + { + static USHORT num; + char tmp[16]; + HANDLE file; + sprintf(tmp, "template%05u.x", num++); + + file = CreateFileA(tmp, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); + if (file != INVALID_HANDLE_VALUE) + { + WriteFile(file, pvData, cbSize, NULL, NULL); + CloseHandle(file); + } + } + + hr = parse_header(&buf, &decomp_buffer); + if (FAILED(hr)) + goto cleanup; + + if (!parse_templates(&buf, FALSE)) + { + hr = DXFILEERR_PARSEERROR; + goto cleanup; + } + + if (TRACE_ON(d3dxof)) + { + ULONG i; + TRACE("Registered templates (%d):\n", This->nb_xtemplates); + for (i = 1; i < This->nb_xtemplates; i++) + 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 hr; +} + +static const IDirectXFileVtbl IDirectXFile_Vtbl = +{ + IDirectXFileImpl_QueryInterface, + IDirectXFileImpl_AddRef, + IDirectXFileImpl_Release, + IDirectXFileImpl_CreateEnumObject, + IDirectXFileImpl_CreateSaveObject, + IDirectXFileImpl_RegisterTemplates +}; + +static HRESULT IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl** ppObj) +{ + IDirectXFileBinaryImpl* object; + + TRACE("(%p)\n", ppObj); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileBinaryImpl)); + if (!object) + { + ERR("Out of memory\n"); + return DXFILEERR_BADALLOC; + } + + object->IDirectXFileBinary_iface.lpVtbl = &IDirectXFileBinary_Vtbl; + object->ref = 1; + + *ppObj = object; + + return DXFILE_OK; +} + +static inline IDirectXFileBinaryImpl *impl_from_IDirectXFileBinary(IDirectXFileBinary *iface) +{ + return CONTAINING_RECORD(iface, IDirectXFileBinaryImpl, IDirectXFileBinary_iface); +} + +/*** IUnknown methods ***/ +static HRESULT WINAPI IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary* iface, REFIID riid, void** ppvObject) +{ + IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface); + + TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirectXFileObject) + || IsEqualGUID(riid, &IID_IDirectXFileBinary)) + { + IUnknown_AddRef(iface); + *ppvObject = &This->IDirectXFileBinary_iface; + return S_OK; + } + + /* Do not print an error for interfaces that can be queried to retrieve the type of the object */ + if (!IsEqualGUID(riid, &IID_IDirectXFileData) + && !IsEqualGUID(riid, &IID_IDirectXFileDataReference)) + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + + return E_NOINTERFACE; +} + +static ULONG WINAPI IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary* iface) +{ + IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + return ref; +} + +static ULONG WINAPI IDirectXFileBinaryImpl_Release(IDirectXFileBinary* iface) +{ + IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +/*** IDirectXFileObject methods ***/ +static HRESULT WINAPI IDirectXFileBinaryImpl_GetName(IDirectXFileBinary* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen) + +{ + IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface); + + FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, pstrNameBuf, pdwBufLen); + + return DXFILEERR_BADVALUE; +} + +static HRESULT WINAPI IDirectXFileBinaryImpl_GetId(IDirectXFileBinary* iface, LPGUID pGuid) +{ + IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface); + + FIXME("(%p/%p)->(%p) stub!\n", This, iface, pGuid); + + return DXFILEERR_BADVALUE; +} + +/*** IDirectXFileBinary methods ***/ +static HRESULT WINAPI IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary* iface, DWORD* pcbSize) +{ + IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface); + + FIXME("(%p/%p)->(%p) stub!\n", This, iface, pcbSize); + + return DXFILEERR_BADVALUE; +} + +static HRESULT WINAPI IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary* iface, LPCSTR* pszMimeType) +{ + IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface); + + FIXME("(%p/%p)->(%p) stub!\n", This, iface, pszMimeType); + + return DXFILEERR_BADVALUE; +} + +static HRESULT WINAPI IDirectXFileBinaryImpl_Read(IDirectXFileBinary* iface, LPVOID pvData, DWORD cbSize, LPDWORD pcbRead) +{ + IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface); + + FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This, iface, pvData, cbSize, pcbRead); + + return DXFILEERR_BADVALUE; +} + +static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl = +{ + IDirectXFileBinaryImpl_QueryInterface, + IDirectXFileBinaryImpl_AddRef, + IDirectXFileBinaryImpl_Release, + IDirectXFileBinaryImpl_GetName, + IDirectXFileBinaryImpl_GetId, + IDirectXFileBinaryImpl_GetSize, + IDirectXFileBinaryImpl_GetMimeType, + IDirectXFileBinaryImpl_Read +}; + +static HRESULT IDirectXFileDataImpl_Create(IDirectXFileDataImpl** ppObj) +{ + IDirectXFileDataImpl* object; + + TRACE("(%p)\n", ppObj); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataImpl)); + if (!object) + { + ERR("Out of memory\n"); + return DXFILEERR_BADALLOC; + } + + object->IDirectXFileData_iface.lpVtbl = &IDirectXFileData_Vtbl; + object->ref = 1; + + *ppObj = object; + + return S_OK; +} + +static inline IDirectXFileDataImpl *impl_from_IDirectXFileData(IDirectXFileData *iface) +{ + return CONTAINING_RECORD(iface, IDirectXFileDataImpl, IDirectXFileData_iface); +} + +/*** IUnknown methods ***/ +static HRESULT WINAPI IDirectXFileDataImpl_QueryInterface(IDirectXFileData* iface, REFIID riid, void** ppvObject) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + + TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirectXFileObject) + || IsEqualGUID(riid, &IID_IDirectXFileData)) + { + IUnknown_AddRef(iface); + *ppvObject = &This->IDirectXFileData_iface; + return S_OK; + } + + /* Do not print an error for interfaces that can be queried to retrieve the type of the object */ + if (!IsEqualGUID(riid, &IID_IDirectXFileBinary) + && !IsEqualGUID(riid, &IID_IDirectXFileDataReference)) + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + + return E_NOINTERFACE; +} + +static ULONG WINAPI IDirectXFileDataImpl_AddRef(IDirectXFileData* iface) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + return ref; +} + +static ULONG WINAPI IDirectXFileDataImpl_Release(IDirectXFileData* iface) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + if (!ref) + { + if (!This->level && !This->from_ref) + { + HeapFree(GetProcessHeap(), 0, This->pstrings); + if (This->pobj) + { + HeapFree(GetProcessHeap(), 0, This->pobj->pdata); + HeapFree(GetProcessHeap(), 0, This->pobj); + } + } + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +/*** IDirectXFileObject methods ***/ +static HRESULT WINAPI IDirectXFileDataImpl_GetName(IDirectXFileData* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + DWORD len; + + TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen); + + if (!pdwBufLen) + return DXFILEERR_BADVALUE; + + len = strlen(This->pobj->name); + if (len) + len++; + + if (pstrNameBuf) { + if (*pdwBufLen < len) + return DXFILEERR_BADVALUE; + CopyMemory(pstrNameBuf, This->pobj->name, len); + /* Even if we return a size of 0, an empty string with a null byte must be returned */ + if (*pdwBufLen && !len) + pstrNameBuf[0] = 0; + } + *pdwBufLen = len; + + return DXFILE_OK; +} + +static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pGuid); + + if (!pGuid) + return DXFILEERR_BADVALUE; + + memcpy(pGuid, &This->pobj->class_id, 16); + + return DXFILE_OK; +} + +/*** IDirectXFileData methods ***/ +static HRESULT WINAPI IDirectXFileDataImpl_GetData(IDirectXFileData* iface, LPCSTR szMember, DWORD* pcbSize, void** ppvData) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + + TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_a(szMember), pcbSize, ppvData); + + if (!pcbSize || !ppvData) + return DXFILEERR_BADVALUE; + + if (szMember) + { + ULONG i; + for (i = 0; i < This->pobj->nb_members; i++) + if (!strcmp(This->pobj->members[i].name, szMember)) + break; + if (i == This->pobj->nb_members) + { + WARN("Unknown member '%s'\n", szMember); + return DXFILEERR_BADDATAREFERENCE; + } + *pcbSize = This->pobj->members[i].size; + *ppvData = This->pobj->root->pdata + This->pobj->members[i].start; + } + else + { + *pcbSize = This->pobj->size; + *ppvData = This->pobj->root->pdata + This->pobj->pos_data; + } + + return DXFILE_OK; +} + +static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + static GUID guid; + + TRACE("(%p/%p)->(%p)\n", This, iface, pguid); + + if (!pguid) + return DXFILEERR_BADVALUE; + + memcpy(&guid, &This->pobj->type, 16); + *pguid = &guid; + + return DXFILE_OK; +} + +static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj) +{ + HRESULT hr; + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, ppChildObj); + + if (This->cur_enum_object >= This->pobj->nb_children) + { + *ppChildObj = NULL; + return DXFILEERR_NOMOREOBJECTS; + } + + if (This->from_ref && (This->level >= 1)) + { + /* Only 2 levels can be enumerated if the object is obtained from a reference */ + *ppChildObj = NULL; + return DXFILEERR_NOMOREOBJECTS; + } + + if (This->pobj->children[This->cur_enum_object]->binary) + { + IDirectXFileBinaryImpl *object; + + hr = IDirectXFileBinaryImpl_Create(&object); + if (FAILED(hr)) + return hr; + + *ppChildObj = (LPDIRECTXFILEOBJECT)&object->IDirectXFileBinary_iface; + } + else if (This->pobj->children[This->cur_enum_object]->ptarget) + { + IDirectXFileDataReferenceImpl *object; + + hr = IDirectXFileDataReferenceImpl_Create(&object); + if (FAILED(hr)) + return hr; + + object->ptarget = This->pobj->children[This->cur_enum_object++]->ptarget; + + *ppChildObj = (LPDIRECTXFILEOBJECT)&object->IDirectXFileDataReference_iface; + } + else + { + IDirectXFileDataImpl *object; + + hr = IDirectXFileDataImpl_Create(&object); + if (FAILED(hr)) + return hr; + + object->pobj = This->pobj->children[This->cur_enum_object++]; + object->cur_enum_object = 0; + object->from_ref = This->from_ref; + object->level = This->level + 1; + + *ppChildObj = (LPDIRECTXFILEOBJECT)&object->IDirectXFileData_iface; + } + + return DXFILE_OK; +} + +static HRESULT WINAPI IDirectXFileDataImpl_AddDataObject(IDirectXFileData* iface, LPDIRECTXFILEDATA pDataObj) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + + FIXME("(%p/%p)->(%p) stub!\n", This, iface, pDataObj); + + return DXFILEERR_BADVALUE; +} + +static HRESULT WINAPI IDirectXFileDataImpl_AddDataReference(IDirectXFileData* iface, LPCSTR szRef, const GUID* pguidRef) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + + FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szRef, pguidRef); + + return DXFILEERR_BADVALUE; +} + +static HRESULT WINAPI IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData* iface, LPCSTR szName, const GUID* pguid, LPCSTR szMimeType, LPVOID pvData, DWORD cbSize) +{ + IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface); + + FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This, iface, szName, pguid, szMimeType, pvData, cbSize); + + return DXFILEERR_BADVALUE; +} + +static const IDirectXFileDataVtbl IDirectXFileData_Vtbl = +{ + IDirectXFileDataImpl_QueryInterface, + IDirectXFileDataImpl_AddRef, + IDirectXFileDataImpl_Release, + IDirectXFileDataImpl_GetName, + IDirectXFileDataImpl_GetId, + IDirectXFileDataImpl_GetData, + IDirectXFileDataImpl_GetType, + IDirectXFileDataImpl_GetNextObject, + IDirectXFileDataImpl_AddDataObject, + IDirectXFileDataImpl_AddDataReference, + IDirectXFileDataImpl_AddBinaryObject +}; + +static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj) +{ + IDirectXFileDataReferenceImpl* object; + + TRACE("(%p)\n", ppObj); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataReferenceImpl)); + if (!object) + { + ERR("Out of memory\n"); + return DXFILEERR_BADALLOC; + } + + object->IDirectXFileDataReference_iface.lpVtbl = &IDirectXFileDataReference_Vtbl; + object->ref = 1; + + *ppObj = object; + + return S_OK; +} + +static inline IDirectXFileDataReferenceImpl *impl_from_IDirectXFileDataReference(IDirectXFileDataReference *iface) +{ + return CONTAINING_RECORD(iface, IDirectXFileDataReferenceImpl, IDirectXFileDataReference_iface); +} + +/*** IUnknown methods ***/ +static HRESULT WINAPI IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference* iface, REFIID riid, void** ppvObject) +{ + IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface); + + TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirectXFileObject) + || IsEqualGUID(riid, &IID_IDirectXFileDataReference)) + { + IUnknown_AddRef(iface); + *ppvObject = &This->IDirectXFileDataReference_iface; + return S_OK; + } + + /* Do not print an error for interfaces that can be queried to retrieve the type of the object */ + if (!IsEqualGUID(riid, &IID_IDirectXFileData) + && !IsEqualGUID(riid, &IID_IDirectXFileBinary)) + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + + return E_NOINTERFACE; +} + +static ULONG WINAPI IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference* iface) +{ + IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + return ref; +} + +static ULONG WINAPI IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference* iface) +{ + IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +/*** IDirectXFileObject methods ***/ +static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen) +{ + IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface); + DWORD len; + + TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen); + + if (!pdwBufLen) + return DXFILEERR_BADVALUE; + + len = strlen(This->ptarget->name); + if (len) + len++; + + if (pstrNameBuf) { + if (*pdwBufLen < len) + return DXFILEERR_BADVALUE; + CopyMemory(pstrNameBuf, This->ptarget->name, len); + /* Even if we return a size of 0, an empty string with a null byte must be returned */ + if (*pdwBufLen && !len) + pstrNameBuf[0] = 0; + } + *pdwBufLen = len; + + return DXFILE_OK; +} + +static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference* iface, LPGUID pGuid) +{ + IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pGuid); + + if (!pGuid) + return DXFILEERR_BADVALUE; + + memcpy(pGuid, &This->ptarget->class_id, 16); + + return DXFILE_OK; +} + +/*** IDirectXFileDataReference ***/ +static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj) +{ + IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface); + IDirectXFileDataImpl *object; + HRESULT hr; + + TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj); + + if (!ppDataObj) + return DXFILEERR_BADVALUE; + + hr = IDirectXFileDataImpl_Create(&object); + if (FAILED(hr)) + return hr; + + object->pobj = This->ptarget; + object->cur_enum_object = 0; + object->level = 0; + object->from_ref = TRUE; + + *ppDataObj = (LPDIRECTXFILEDATA)object; + + return DXFILE_OK; +} + +static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl = +{ + IDirectXFileDataReferenceImpl_QueryInterface, + IDirectXFileDataReferenceImpl_AddRef, + IDirectXFileDataReferenceImpl_Release, + IDirectXFileDataReferenceImpl_GetName, + IDirectXFileDataReferenceImpl_GetId, + IDirectXFileDataReferenceImpl_Resolve +}; + +static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj) +{ + IDirectXFileEnumObjectImpl* object; + + TRACE("(%p)\n", ppObj); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileEnumObjectImpl)); + if (!object) + { + ERR("Out of memory\n"); + return DXFILEERR_BADALLOC; + } + + object->IDirectXFileEnumObject_iface.lpVtbl = &IDirectXFileEnumObject_Vtbl; + object->ref = 1; + + *ppObj = object; + + return S_OK; +} + +static inline IDirectXFileEnumObjectImpl *impl_from_IDirectXFileEnumObject(IDirectXFileEnumObject *iface) +{ + return CONTAINING_RECORD(iface, IDirectXFileEnumObjectImpl, IDirectXFileEnumObject_iface); +} + +/*** IUnknown methods ***/ +static HRESULT WINAPI IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject* iface, REFIID riid, void** ppvObject) +{ + IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface); + + TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirectXFileEnumObject)) + { + IUnknown_AddRef(iface); + *ppvObject = &This->IDirectXFileEnumObject_iface; + return S_OK; + } + + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + return E_NOINTERFACE; +} + +static ULONG WINAPI IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject* iface) +{ + IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + return ref; +} + +static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* iface) +{ + IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + if (!ref) + { + ULONG i; + for (i = 0; i < This->nb_xobjects; i++) + IDirectXFileData_Release(This->pRefObjects[i]); + if (This->mapped_memory) + UnmapViewOfFile(This->mapped_memory); + HeapFree(GetProcessHeap(), 0, This->decomp_buffer); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +/*** IDirectXFileEnumObject methods ***/ +static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj) +{ + IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface); + IDirectXFileDataImpl* object; + HRESULT hr; + + if (!ppDataObj) + return E_POINTER; + + *ppDataObj = NULL; + + TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj); + + if (This->nb_xobjects >= MAX_OBJECTS) + { + ERR("Too many objects\n"); + return DXFILEERR_NOMOREOBJECTS; + } + + /* Check if there are templates defined before the object */ + if (!parse_templates(&This->buf, TRUE)) + return DXFILEERR_PARSEERROR; + + if (!This->buf.rem_bytes) + return DXFILEERR_NOMOREOBJECTS; + + hr = IDirectXFileDataImpl_Create(&object); + if (FAILED(hr)) + return hr; + + object->pobj = HeapAlloc(GetProcessHeap(), 0, sizeof(xobject)*MAX_SUBOBJECTS); + if (!object->pobj) + { + ERR("Out of memory\n"); + hr = DXFILEERR_BADALLOC; + goto error; + } + + object->pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER); + if (!object->pstrings) + { + ERR("Out of memory\n"); + hr = DXFILEERR_BADALLOC; + goto error; + } + + object->cur_enum_object = 0; + object->level = 0; + object->from_ref = FALSE; + + This->buf.pxo_globals = This->xobjects; + This->buf.nb_pxo_globals = This->nb_xobjects; + This->buf.level = 0; + This->buf.pdata = NULL; + This->buf.capacity = 0; + This->buf.cur_pos_data = 0; + This->buf.cur_pstrings = This->buf.pstrings = object->pstrings; + This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab = object->pobj; + This->buf.pxo->pdata = NULL; + This->buf.pxo->nb_subobjects = 1; + + if (!parse_object(&This->buf)) + { + WARN("Object is not correct\n"); + hr = DXFILEERR_PARSEERROR; + goto error; + } + + *ppDataObj = (LPDIRECTXFILEDATA)object; + + /* Get a reference to created object */ + This->pRefObjects[This->nb_xobjects] = (LPDIRECTXFILEDATA)object; + IDirectXFileData_AddRef(This->pRefObjects[This->nb_xobjects]); + + This->nb_xobjects++; + + return DXFILE_OK; + +error: + + IDirectXFileData_Release(&object->IDirectXFileData_iface); + + return hr; +} + +static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject* iface, REFGUID rguid, LPDIRECTXFILEDATA* ppDataObj) +{ + IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface); + + FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, rguid, ppDataObj); + + return DXFILEERR_BADVALUE; +} + +static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject* iface, LPCSTR szName, LPDIRECTXFILEDATA* ppDataObj) +{ + IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface); + + FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szName, ppDataObj); + + return DXFILEERR_BADVALUE; +} + +static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl = +{ + IDirectXFileEnumObjectImpl_QueryInterface, + IDirectXFileEnumObjectImpl_AddRef, + IDirectXFileEnumObjectImpl_Release, + IDirectXFileEnumObjectImpl_GetNextDataObject, + IDirectXFileEnumObjectImpl_GetDataObjectById, + IDirectXFileEnumObjectImpl_GetDataObjectByName +}; + +static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj) +{ + IDirectXFileSaveObjectImpl* object; + + TRACE("(%p)\n", ppObj); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileSaveObjectImpl)); + if (!object) + { + ERR("Out of memory\n"); + return DXFILEERR_BADALLOC; + } + + object->IDirectXFileSaveObject_iface.lpVtbl = &IDirectXFileSaveObject_Vtbl; + object->ref = 1; + + *ppObj = object; + + return S_OK; +} + +static inline IDirectXFileSaveObjectImpl *impl_from_IDirectXFileSaveObject(IDirectXFileSaveObject *iface) +{ + return CONTAINING_RECORD(iface, IDirectXFileSaveObjectImpl, IDirectXFileSaveObject_iface); +} + +/*** IUnknown methods ***/ +static HRESULT WINAPI IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject* iface, REFIID riid, void** ppvObject) +{ + IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface); + + TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirectXFileSaveObject)) + { + IUnknown_AddRef(iface); + *ppvObject = &This->IDirectXFileSaveObject_iface; + return S_OK; + } + + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + return E_NOINTERFACE; +} + +static ULONG WINAPI IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject* iface) +{ + IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + return ref; +} + +static ULONG WINAPI IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject* iface) +{ + IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject* iface, DWORD cTemplates, const GUID** ppguidTemplates) +{ + IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface); + + FIXME("(%p/%p)->(%d,%p) stub!\n", This, iface, cTemplates, ppguidTemplates); + + return DXFILE_OK; +} + +static HRESULT WINAPI IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject* iface, REFGUID rguidTemplate, LPCSTR szName, const GUID* pguid, DWORD cbSize, LPVOID pvData, LPDIRECTXFILEDATA* ppDataObj) +{ + IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface); + + FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This, iface, rguidTemplate, szName, pguid, cbSize, pvData, ppDataObj); + + return DXFILEERR_BADVALUE; +} + +static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject* iface, LPDIRECTXFILEDATA ppDataObj) +{ + IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface); + + FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppDataObj); + + return DXFILEERR_BADVALUE; +} + +static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl = +{ + IDirectXFileSaveObjectImpl_QueryInterface, + IDirectXFileSaveObjectImpl_AddRef, + IDirectXFileSaveObjectImpl_Release, + IDirectXFileSaveObjectImpl_SaveTemplates, + IDirectXFileSaveObjectImpl_CreateDataObject, + IDirectXFileSaveObjectImpl_SaveData +}; diff --git a/reactos/dll/directx/wine/d3dxof/d3dxof.idl b/reactos/dll/directx/wine/d3dxof/d3dxof.idl new file mode 100644 index 00000000000..ea72a6e36e0 --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/d3dxof.idl @@ -0,0 +1,26 @@ +/* + * COM Classes for d3dxof + * + * Copyright 2010 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +[ + helpstring("DirectX File"), + threading(both), + uuid(4516ec43-8f20-11d0-9b6d-0000c0781bc3) +] +coclass CDirectXFile { interface IDirectXFile; } diff --git a/reactos/dll/directx/wine/d3dxof/d3dxof.spec b/reactos/dll/directx/wine/d3dxof/d3dxof.spec new file mode 100644 index 00000000000..2eee2fd9728 --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/d3dxof.spec @@ -0,0 +1,5 @@ +@ stdcall DirectXFileCreate(ptr) +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/directx/wine/d3dxof/d3dxof_private.h b/reactos/dll/directx/wine/d3dxof/d3dxof_private.h new file mode 100644 index 00000000000..cf33ed21cea --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/d3dxof_private.h @@ -0,0 +1,171 @@ +/* + * DirectX File private interfaces (D3DXOF.DLL) + * + * Copyright 2004, 2008 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __D3DXOF_PRIVATE_INCLUDED__ +#define __D3DXOF_PRIVATE_INCLUDED__ + +#include + +#include "windef.h" +#include "winbase.h" +#include "wtypes.h" +#include "wingdi.h" +#include "winuser.h" +#include "dxfile.h" + +#define MAX_NAME_LEN 40 +#define MAX_ARRAY_DIM 4 +#define MAX_MEMBERS 50 +#define MAX_CHILDREN 200 +#define MAX_TEMPLATES 200 +#define MAX_OBJECTS 500 +#define MAX_SUBOBJECTS 2000 +#define MAX_STRINGS_BUFFER 10000 + +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; + BOOL binary; + ULONG nb_children; + char children[MAX_CHILDREN][MAX_NAME_LEN]; + ULONG nb_members; + member members[MAX_MEMBERS]; +} xtemplate; + +typedef struct { + char* name; + ULONG start; + ULONG size; +} xobject_member; + +struct _xobject { + BOOL binary; + struct _xobject* ptarget; + char name[MAX_NAME_LEN]; + GUID class_id; + GUID type; + LPBYTE pdata; + ULONG pos_data; + DWORD size; + ULONG nb_members; + xobject_member members[MAX_MEMBERS]; + ULONG nb_children; + ULONG nb_subobjects; + struct _xobject * children[MAX_CHILDREN]; + struct _xobject * root; +}; + +typedef struct _xobject xobject; + +typedef struct { + IDirectXFile IDirectXFile_iface; + LONG ref; + ULONG nb_xtemplates; + xtemplate xtemplates[MAX_TEMPLATES]; +} IDirectXFileImpl; + +typedef struct { + IDirectXFileBinary IDirectXFileBinary_iface; + LONG ref; +} IDirectXFileBinaryImpl; + +typedef struct { + IDirectXFileData IDirectXFileData_iface; + LONG ref; + xobject* pobj; + int cur_enum_object; + BOOL from_ref; + ULONG level; + LPBYTE pstrings; +} IDirectXFileDataImpl; + +typedef struct { + IDirectXFileDataReference IDirectXFileDataReference_iface; + LONG ref; + xobject* ptarget; +} IDirectXFileDataReferenceImpl; + +typedef struct { + IDirectXFileObject IDirectXFileObject_iface; + LONG ref; +} IDirectXFileObjectImpl; + +typedef struct { + /* Buffer to parse */ + LPBYTE buffer; + DWORD rem_bytes; + /* Misc info */ + WORD current_token; + BOOL token_present; + BOOL txt; + DWORD list_nb_elements; + BOOL list_type_float; + BOOL list_separator; + ULONG cur_pos_data; + LPBYTE cur_pstrings; + BYTE value[100]; + xobject** pxo_globals; + ULONG nb_pxo_globals; + xobject* pxo_tab; + IDirectXFileImpl* pdxf; + xobject* pxo; + xtemplate* pxt[MAX_SUBOBJECTS]; + ULONG level; + LPBYTE pdata; + ULONG capacity; + LPBYTE pstrings; +} parse_buffer; + +typedef struct { + IDirectXFileEnumObject IDirectXFileEnumObject_iface; + LONG ref; + LPBYTE mapped_memory; + LPBYTE decomp_buffer; + parse_buffer buf; + IDirectXFileImpl* pDirectXFile; + ULONG nb_xobjects; + xobject* xobjects[MAX_OBJECTS]; + IDirectXFileData* pRefObjects[MAX_OBJECTS]; +} IDirectXFileEnumObjectImpl; + +typedef struct { + IDirectXFileSaveObject IDirectXFileSaveObject_iface; + LONG ref; +} IDirectXFileSaveObjectImpl; + +HRESULT IDirectXFileImpl_Create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; + +HRESULT parse_header(parse_buffer *buf, BYTE **decomp_buffer_ptr) DECLSPEC_HIDDEN; +BOOL parse_object(parse_buffer * buf) DECLSPEC_HIDDEN; +BOOL parse_templates(parse_buffer * buf, BOOL templates_only) DECLSPEC_HIDDEN; + +int mszip_decompress(int inlen, int outlen, char* inbuffer, char* outbuffer) DECLSPEC_HIDDEN; + +#endif /* __D3DXOF_PRIVATE_INCLUDED__ */ diff --git a/reactos/dll/directx/wine/d3dxof/main.c b/reactos/dll/directx/wine/d3dxof/main.c new file mode 100644 index 00000000000..48ee22bb60f --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/main.c @@ -0,0 +1,245 @@ +/* + * DirectX Files Functions (D3DXOF.DLL) + * + * Copyright 2004 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "winerror.h" + +#include "ole2.h" +#include "rpcproxy.h" +#include "uuids.h" + +#include "d3dxof_private.h" +#include "dxfile.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dxof); + +static HINSTANCE instance; +static LONG dll_ref = 0; + +/* For the moment, do nothing here. */ +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +{ + switch(fdwReason) { + case DLL_PROCESS_ATTACH: + instance = hInstDLL; + DisableThreadLibraryCalls(hInstDLL); + break; + } + return TRUE; +} + +/****************************************************************************** + * DirectX File ClassFactory + */ +typedef struct { + IClassFactory IClassFactory_iface; + + LONG ref; + HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); +} IClassFactoryImpl; + +static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); +} + +struct object_creation_info +{ + const CLSID *clsid; + HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); +}; + +static const struct object_creation_info object_creation[] = +{ + { &CLSID_CDirectXFile, IDirectXFileImpl_Create }, +}; + +static HRESULT WINAPI XFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppobj) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef(iface); + *ppobj = &This->IClassFactory_iface; + return S_OK; + } + + WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI XFCF_AddRef(LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI XFCF_Release(LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + + ULONG ref = InterlockedDecrement(&This->ref); + + if (ref == 0) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI XFCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + HRESULT hres; + LPUNKNOWN punk; + + TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); + + *ppobj = NULL; + hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); + if (SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(punk, riid, ppobj); + IUnknown_Release(punk); + } + return hres; +} + +static HRESULT WINAPI XFCF_LockServer(LPCLASSFACTORY iface, BOOL dolock) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + FIXME("(%p)->(%d),stub!\n",This,dolock); + return S_OK; +} + +static const IClassFactoryVtbl XFCF_Vtbl = +{ + XFCF_QueryInterface, + XFCF_AddRef, + XFCF_Release, + XFCF_CreateInstance, + XFCF_LockServer +}; + +/*********************************************************************** + * DirectXFileCreate (D3DXOF.@) + */ +HRESULT WINAPI DirectXFileCreate(LPDIRECTXFILE* lplpDirectXFile) +{ + HRESULT hr; + + TRACE("(%p)\n", lplpDirectXFile); + + if (!lplpDirectXFile) + return DXFILEERR_BADVALUE; + + hr = IDirectXFileImpl_Create(NULL, (LPVOID)lplpDirectXFile); + + if (FAILED(hr)) + return DXFILEERR_BADALLOC; + + return S_OK; +} + +/******************************************************************************* + * DllGetClassObject [D3DXOF.@] + * Retrieves class object from a DLL object + * + * NOTES + * Docs say returns STDAPI + * + * PARAMS + * rclsid [I] CLSID for the class object + * riid [I] Reference to identifier of interface for class object + * ppv [O] Address of variable to receive interface pointer for riid + * + * RETURNS + * Success: S_OK + * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG, + * E_UNEXPECTED + */ +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + unsigned int i; + IClassFactoryImpl *factory; + + TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + + if ( !IsEqualGUID( &IID_IClassFactory, riid ) + && ! IsEqualGUID( &IID_IUnknown, riid) ) + return E_NOINTERFACE; + + for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) + { + if (IsEqualGUID(object_creation[i].clsid, rclsid)) + break; + } + + if (i == sizeof(object_creation)/sizeof(object_creation[0])) + { + FIXME("%s: no class found.\n", debugstr_guid(rclsid)); + return CLASS_E_CLASSNOTAVAILABLE; + } + + factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory)); + if (factory == NULL) return E_OUTOFMEMORY; + + factory->IClassFactory_iface.lpVtbl = &XFCF_Vtbl; + factory->ref = 1; + + factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; + + *ppv = &(factory->IClassFactory_iface); + return S_OK; +} + +/*********************************************************************** + * DllCanUnloadNow (D3DXOF.@) + */ +HRESULT WINAPI DllCanUnloadNow(void) +{ + return dll_ref != 0 ? S_FALSE : S_OK; +} + +/*********************************************************************** + * DllRegisterServer (D3DXOF.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( instance ); +} + +/*********************************************************************** + * DllUnregisterServer (D3DXOF.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources( instance ); +} diff --git a/reactos/dll/directx/wine/d3dxof/mszip.c b/reactos/dll/directx/wine/d3dxof/mszip.c new file mode 100644 index 00000000000..179661634f7 --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/mszip.c @@ -0,0 +1,645 @@ +/* + * MSZIP decompression (taken from fdi.c of cabinet dll) + * + * Copyright 2000-2002 Stuart Caie + * Copyright 2002 Patrik Stridvall + * Copyright 2003 Greg Turner + * Copyright 2010 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "windef.h" +#include "winbase.h" + +#include "wine/debug.h" + +#include "mszip.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dxof); + +THOSE_ZIP_CONSTS; + +/******************************************************** + * Ziphuft_free (internal) + */ +static void fdi_Ziphuft_free(HFDI hfdi, struct Ziphuft *t) +{ + register struct Ziphuft *p, *q; + + /* Go through linked list, freeing from the allocated (t[-1]) address. */ + p = t; + while (p != NULL) + { + q = (--p)->v.t; + PFDI_FREE(hfdi, p); + p = q; + } +} + +/********************************************************* + * fdi_Ziphuft_build (internal) + */ +static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e, +struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state) +{ + cab_ULONG a; /* counter for codes of length k */ + cab_ULONG el; /* length of EOB code (value 256) */ + cab_ULONG f; /* i repeats in table every f entries */ + cab_LONG g; /* maximum code length */ + cab_LONG h; /* table level */ + register cab_ULONG i; /* counter, current code */ + register cab_ULONG j; /* counter */ + register cab_LONG k; /* number of bits in current code */ + cab_LONG *l; /* stack of bits per table */ + register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */ + register struct Ziphuft *q; /* points to current table */ + struct Ziphuft r; /* table entry for structure assignment */ + register cab_LONG w; /* bits before this table == (l * h) */ + cab_ULONG *xp; /* pointer into x */ + cab_LONG y; /* number of dummy codes added */ + cab_ULONG z; /* number of entries in current table */ + + l = ZIP(lx)+1; + + /* Generate counts for each bit length */ + el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */ + + for(i = 0; i < ZIPBMAX+1; ++i) + ZIP(c)[i] = 0; + p = b; i = n; + do + { + ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */ + } while (--i); + if (ZIP(c)[0] == n) /* null input--all zero length codes */ + { + *t = NULL; + *m = 0; + return 0; + } + + /* Find minimum and maximum length, bound *m by those */ + for (j = 1; j <= ZIPBMAX; j++) + if (ZIP(c)[j]) + break; + k = j; /* minimum code length */ + if ((cab_ULONG)*m < j) + *m = j; + for (i = ZIPBMAX; i; i--) + if (ZIP(c)[i]) + break; + g = i; /* maximum code length */ + if ((cab_ULONG)*m > i) + *m = i; + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= ZIP(c)[j]) < 0) + return 2; /* bad input: more codes than bits */ + if ((y -= ZIP(c)[i]) < 0) + return 2; + ZIP(c)[i] += y; + + /* Generate starting offsets LONGo the value table for each length */ + ZIP(x)[1] = j = 0; + p = ZIP(c) + 1; xp = ZIP(x) + 2; + while (--i) + { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do{ + if ((j = *p++) != 0) + ZIP(v)[ZIP(x)[j]++] = i; + } while (++i < n); + + + /* Generate the Huffman codes and for each, make the table entries */ + ZIP(x)[0] = i = 0; /* first Huffman code is zero */ + p = ZIP(v); /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = l[-1] = 0; /* no bits decoded yet */ + ZIP(u)[0] = NULL; /* just to keep compilers happy */ + q = NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = ZIP(c)[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l[h]) + { + w += l[h++]; /* add bits already decoded */ + + /* compute minimum size table less than or equal to *m bits */ + if ((z = g - w) > (cab_ULONG)*m) /* upper limit */ + z = *m; + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = ZIP(c) + k; + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + if ((cab_ULONG)w + j > el && (cab_ULONG)w < el) + j = el - w; /* make EOB code end at table */ + z = 1 << j; /* table entries for j-bit table */ + l[h] = j; /* set table size in stack */ + + /* allocate and link in new table */ + if (!(q = PFDI_ALLOC(CAB(hfdi), (z + 1)*sizeof(struct Ziphuft)))) + { + if(h) + fdi_Ziphuft_free(CAB(hfdi), ZIP(u)[0]); + return 3; /* not enough memory */ + } + *t = q + 1; /* link to list for Ziphuft_free() */ + *(t = &(q->v.t)) = NULL; + ZIP(u)[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + ZIP(x)[h] = i; /* save pattern for backing up */ + r.b = (cab_UBYTE)l[h-1]; /* bits to dump before this table */ + r.e = (cab_UBYTE)(16 + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = (i & ((1 << w) - 1)) >> (w - l[h-1]); + ZIP(u)[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.b = (cab_UBYTE)(k - w); + if (p >= ZIP(v) + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) + { + r.e = (cab_UBYTE)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ + r.v.n = *p++; /* simple code is just the value */ + } + else + { + r.e = (cab_UBYTE)e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != ZIP(x)[h]) + w -= l[--h]; /* don't need to update q */ + } + } + + /* return actual size of base table */ + *m = l[0]; + + /* Return true (1) if we were given an incomplete table */ + return y != 0 && g != 1; +} + +/********************************************************* + * fdi_Zipinflate_codes (internal) + */ +static cab_LONG fdi_Zipinflate_codes(const struct Ziphuft *tl, const struct Ziphuft *td, + cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state) +{ + register cab_ULONG e; /* table entry flag/number of extra bits */ + cab_ULONG n, d; /* length and index for copy */ + cab_ULONG w; /* current window position */ + const struct Ziphuft *t; /* pointer to table entry */ + cab_ULONG ml, md; /* masks for bl and bd bits */ + register cab_ULONG b; /* bit buffer */ + register cab_ULONG k; /* number of bits in bit buffer */ + + /* make local copies of globals */ + b = ZIP(bb); /* initialize bit buffer */ + k = ZIP(bk); + w = ZIP(window_posn); /* initialize window position */ + + /* inflate the coded data */ + ml = Zipmask[bl]; /* precompute masks for speed */ + md = Zipmask[bd]; + + for(;;) + { + ZIPNEEDBITS((cab_ULONG)bl) + if((e = (t = tl + (b & ml))->e) > 16) + do + { + if (e == 99) + return 1; + ZIPDUMPBITS(t->b) + e -= 16; + ZIPNEEDBITS(e) + } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16); + ZIPDUMPBITS(t->b) + if (e == 16) /* then it's a literal */ + CAB(outbuf)[w++] = (cab_UBYTE)t->v.n; + else /* it's an EOB or a length */ + { + /* exit if end of block */ + if(e == 15) + break; + + /* get length of block to copy */ + ZIPNEEDBITS(e) + n = t->v.n + (b & Zipmask[e]); + ZIPDUMPBITS(e); + + /* decode distance of block to copy */ + ZIPNEEDBITS((cab_ULONG)bd) + if ((e = (t = td + (b & md))->e) > 16) + do { + if (e == 99) + return 1; + ZIPDUMPBITS(t->b) + e -= 16; + ZIPNEEDBITS(e) + } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16); + ZIPDUMPBITS(t->b) + ZIPNEEDBITS(e) + d = w - t->v.n - (b & Zipmask[e]); + ZIPDUMPBITS(e) + do + { + d &= ZIPWSIZE - 1; + e = ZIPWSIZE - max(d, w); + e = min(e, n); + n -= e; + do + { + CAB(outbuf)[w++] = CAB(outbuf)[d++]; + } while (--e); + } while (n); + } + } + + /* restore the globals from the locals */ + ZIP(window_posn) = w; /* restore global window pointer */ + ZIP(bb) = b; /* restore global bit buffer */ + ZIP(bk) = k; + + /* done */ + return 0; +} + +/*********************************************************** + * Zipinflate_stored (internal) + */ +static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state) +/* "decompress" an inflated type 0 (stored) block. */ +{ + cab_ULONG n; /* number of bytes in block */ + cab_ULONG w; /* current window position */ + register cab_ULONG b; /* bit buffer */ + register cab_ULONG k; /* number of bits in bit buffer */ + + /* make local copies of globals */ + b = ZIP(bb); /* initialize bit buffer */ + k = ZIP(bk); + w = ZIP(window_posn); /* initialize window position */ + + /* go to byte boundary */ + n = k & 7; + ZIPDUMPBITS(n); + + /* get the length and its complement */ + ZIPNEEDBITS(16) + n = (b & 0xffff); + ZIPDUMPBITS(16) + ZIPNEEDBITS(16) + if (n != ((~b) & 0xffff)) + return 1; /* error in compressed data */ + ZIPDUMPBITS(16) + + /* read and output the compressed data */ + while(n--) + { + ZIPNEEDBITS(8) + CAB(outbuf)[w++] = (cab_UBYTE)b; + ZIPDUMPBITS(8) + } + + /* restore the globals from the locals */ + ZIP(window_posn) = w; /* restore global window pointer */ + ZIP(bb) = b; /* restore global bit buffer */ + ZIP(bk) = k; + return 0; +} + +/****************************************************** + * fdi_Zipinflate_fixed (internal) + */ +static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state) +{ + struct Ziphuft *fixed_tl; + struct Ziphuft *fixed_td; + cab_LONG fixed_bl, fixed_bd; + cab_LONG i; /* temporary variable */ + cab_ULONG *l; + + l = ZIP(ll); + + /* literal table */ + for(i = 0; i < 144; i++) + l[i] = 8; + for(; i < 256; i++) + l[i] = 9; + for(; i < 280; i++) + l[i] = 7; + for(; i < 288; i++) /* make a complete, but wrong code set */ + l[i] = 8; + fixed_bl = 7; + if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state))) + return i; + + /* distance table */ + for(i = 0; i < 30; i++) /* make an incomplete code set */ + l[i] = 5; + fixed_bd = 5; + if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1) + { + fdi_Ziphuft_free(CAB(hfdi), fixed_tl); + return i; + } + + /* decompress until an end-of-block code */ + i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state); + + fdi_Ziphuft_free(CAB(hfdi), fixed_td); + fdi_Ziphuft_free(CAB(hfdi), fixed_tl); + return i; +} + +/************************************************************** + * fdi_Zipinflate_dynamic (internal) + */ +static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state) + /* decompress an inflated type 2 (dynamic Huffman codes) block. */ +{ + cab_LONG i; /* temporary variables */ + cab_ULONG j; + cab_ULONG *ll; + cab_ULONG l; /* last length */ + cab_ULONG m; /* mask for bit lengths table */ + cab_ULONG n; /* number of lengths to get */ + struct Ziphuft *tl; /* literal/length code table */ + struct Ziphuft *td; /* distance code table */ + cab_LONG bl; /* lookup bits for tl */ + cab_LONG bd; /* lookup bits for td */ + cab_ULONG nb; /* number of bit length codes */ + cab_ULONG nl; /* number of literal/length codes */ + cab_ULONG nd; /* number of distance codes */ + register cab_ULONG b; /* bit buffer */ + register cab_ULONG k; /* number of bits in bit buffer */ + + /* make local bit buffer */ + b = ZIP(bb); + k = ZIP(bk); + ll = ZIP(ll); + + /* read in table lengths */ + ZIPNEEDBITS(5) + nl = 257 + (b & 0x1f); /* number of literal/length codes */ + ZIPDUMPBITS(5) + ZIPNEEDBITS(5) + nd = 1 + (b & 0x1f); /* number of distance codes */ + ZIPDUMPBITS(5) + ZIPNEEDBITS(4) + nb = 4 + (b & 0xf); /* number of bit length codes */ + ZIPDUMPBITS(4) + if(nl > 288 || nd > 32) + return 1; /* bad lengths */ + + /* read in bit-length-code lengths */ + for(j = 0; j < nb; j++) + { + ZIPNEEDBITS(3) + ll[Zipborder[j]] = b & 7; + ZIPDUMPBITS(3) + } + for(; j < 19; j++) + ll[Zipborder[j]] = 0; + + /* build decoding table for trees--single level, 7 bit lookup */ + bl = 7; + if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0) + { + if(i == 1) + fdi_Ziphuft_free(CAB(hfdi), tl); + return i; /* incomplete code set */ + } + + /* read in literal and distance code lengths */ + n = nl + nd; + m = Zipmask[bl]; + i = l = 0; + while((cab_ULONG)i < n) + { + ZIPNEEDBITS((cab_ULONG)bl) + j = (td = tl + (b & m))->b; + ZIPDUMPBITS(j) + j = td->v.n; + if (j < 16) /* length of code in bits (0..15) */ + ll[i++] = l = j; /* save last length in l */ + else if (j == 16) /* repeat last length 3 to 6 times */ + { + ZIPNEEDBITS(2) + j = 3 + (b & 3); + ZIPDUMPBITS(2) + if((cab_ULONG)i + j > n) + return 1; + while (j--) + ll[i++] = l; + } + else if (j == 17) /* 3 to 10 zero length codes */ + { + ZIPNEEDBITS(3) + j = 3 + (b & 7); + ZIPDUMPBITS(3) + if ((cab_ULONG)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + else /* j == 18: 11 to 138 zero length codes */ + { + ZIPNEEDBITS(7) + j = 11 + (b & 0x7f); + ZIPDUMPBITS(7) + if ((cab_ULONG)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + } + + /* free decoding table for trees */ + fdi_Ziphuft_free(CAB(hfdi), tl); + + /* restore the global bit buffer */ + ZIP(bb) = b; + ZIP(bk) = k; + + /* build the decoding tables for literal/length and distance codes */ + bl = ZIPLBITS; + if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0) + { + if(i == 1) + fdi_Ziphuft_free(CAB(hfdi), tl); + return i; /* incomplete code set */ + } + bd = ZIPDBITS; + fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state); + + /* decompress until an end-of-block code */ + if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state)) + return 1; + + /* free the decoding tables, return */ + fdi_Ziphuft_free(CAB(hfdi), tl); + fdi_Ziphuft_free(CAB(hfdi), td); + return 0; +} + +/***************************************************** + * fdi_Zipinflate_block (internal) + */ +static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state) /* e == last block flag */ +{ /* decompress an inflated block */ + cab_ULONG t; /* block type */ + register cab_ULONG b; /* bit buffer */ + register cab_ULONG k; /* number of bits in bit buffer */ + + /* make local bit buffer */ + b = ZIP(bb); + k = ZIP(bk); + + /* read in last block bit */ + ZIPNEEDBITS(1) + *e = (cab_LONG)b & 1; + ZIPDUMPBITS(1) + + /* read in block type */ + ZIPNEEDBITS(2) + t = b & 3; + ZIPDUMPBITS(2) + + /* restore the global bit buffer */ + ZIP(bb) = b; + ZIP(bk) = k; + + /* inflate that block type */ + if(t == 2) + return fdi_Zipinflate_dynamic(decomp_state); + if(t == 0) + return fdi_Zipinflate_stored(decomp_state); + if(t == 1) + return fdi_Zipinflate_fixed(decomp_state); + /* bad block type */ + return 2; +} + +/**************************************************** + * ZIPfdi_decomp(internal) + */ +static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) +{ + cab_LONG e; /* last block flag */ + + TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen); + + ZIP(inpos) = CAB(inbuf); + ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0; + + if(outlen > ZIPWSIZE) + return DECR_DATAFORMAT; + + /* CK = Chris Kirmse, official Microsoft purloiner */ + if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B) + return DECR_ILLEGALDATA; + + ZIP(inpos) += 2; + + do { + if(fdi_Zipinflate_block(&e, decomp_state)) + return DECR_ILLEGALDATA; + } while(!e); + + /* return success */ + return DECR_OK; +} + +static void * __cdecl fdi_alloc(ULONG cb) +{ + return HeapAlloc(GetProcessHeap(), 0, cb); +} + +static void __cdecl fdi_free(void *pv) +{ + HeapFree(GetProcessHeap(), 0, pv); +} + +int mszip_decompress(unsigned int inlen, unsigned int outlen, char* inbuffer, char* outbuffer) +{ + int ret; + fdi_decomp_state decomp_state; + FDI_Int fdi; + + TRACE("(%u, %u, %p, %p)\n", inlen, outlen, inbuffer, outbuffer); + + if ((inlen > CAB_INPUTMAX) || (outlen > CAB_BLOCKMAX)) + { + FIXME("Big file not supported yet (inlen = %u, outlen = %u)\n", inlen, outlen); + return DECR_DATAFORMAT; + } + + fdi.pfnalloc = fdi_alloc; + fdi.pfnfree = fdi_free; + decomp_state.hfdi = (void*)&fdi; + + memcpy(decomp_state.inbuf, inbuffer, inlen); + + ret = ZIPfdi_decomp(inlen, outlen, &decomp_state); + + memcpy(outbuffer, decomp_state.outbuf, outlen); + + return ret; +} diff --git a/reactos/dll/directx/wine/d3dxof/mszip.h b/reactos/dll/directx/wine/d3dxof/mszip.h new file mode 100644 index 00000000000..23ff677caa2 --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/mszip.h @@ -0,0 +1,130 @@ +/* + * MSZIP decompression header (taken from cabinet.h of cabinet dll) + * + * Copyright 2002 Greg Turner + * Copyright 2005 Gerold Jens Wucherpfennig + * Copyright 2010 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "fdi.h" + +typedef unsigned char cab_UBYTE; /* 8 bits */ +typedef UINT16 cab_UWORD; /* 16 bits */ +typedef UINT32 cab_ULONG; /* 32 bits */ +typedef INT32 cab_LONG; /* 32 bits */ + +typedef struct { + unsigned int FDI_Intmagic; + PFNALLOC pfnalloc; + PFNFREE pfnfree; + PFNOPEN pfnopen; + PFNREAD pfnread; + PFNWRITE pfnwrite; + PFNCLOSE pfnclose; + PFNSEEK pfnseek; + PERF perf; +} FDI_Int, *PFDI_Int; + +/* cast an HFDI into a PFDI_Int */ +#define PFDI_INT(hfdi) ((PFDI_Int)(hfdi)) + +#define PFDI_ALLOC(hfdi, size) ((*PFDI_INT(hfdi)->pfnalloc) (size)) +#define PFDI_FREE(hfdi, ptr) ((*PFDI_INT(hfdi)->pfnfree) (ptr)) + +/* MSZIP stuff */ +#define ZIPWSIZE 0x8000 /* window size */ +#define ZIPLBITS 9 /* bits in base literal/length lookup table */ +#define ZIPDBITS 6 /* bits in base distance lookup table */ +#define ZIPBMAX 16 /* maximum bit length of any code */ +#define ZIPN_MAX 288 /* maximum number of codes in any set */ + +struct Ziphuft { + cab_UBYTE e; /* number of extra bits or operation */ + cab_UBYTE b; /* number of bits in this code or subcode */ + union { + cab_UWORD n; /* literal, length base, or distance base */ + struct Ziphuft *t; /* pointer to next level of table */ + } v; +}; + +struct ZIPstate { + cab_ULONG window_posn; /* current offset within the window */ + cab_ULONG bb; /* bit buffer */ + cab_ULONG bk; /* bits in bit buffer */ + cab_ULONG ll[288+32]; /* literal/length and distance code lengths */ + cab_ULONG c[ZIPBMAX+1]; /* bit length count table */ + cab_LONG lx[ZIPBMAX+1]; /* memory for l[-1..ZIPBMAX-1] */ + struct Ziphuft *u[ZIPBMAX]; /* table stack */ + cab_ULONG v[ZIPN_MAX]; /* values in order of bit length */ + cab_ULONG x[ZIPBMAX+1]; /* bit offsets, then code stack */ + cab_UBYTE *inpos; +}; + +#define CAB(x) (decomp_state->x) +#define ZIP(x) (decomp_state->methods.zip.x) +#define DECR_OK (0) +#define DECR_DATAFORMAT (1) +#define DECR_ILLEGALDATA (2) +#define DECR_NOMEMORY (3) +#define DECR_CHECKSUM (4) +#define DECR_INPUT (5) +#define DECR_OUTPUT (6) +#define DECR_USERABORT (7) + +#define ZIPNEEDBITS(n) {while(k<(n)){cab_LONG c=*(ZIP(inpos)++);\ + b|=((cab_ULONG)c)<>=(n);k-=(n);} + +/* CAB data blocks are <= 32768 bytes in uncompressed form. Uncompressed + * blocks have zero growth. MSZIP guarantees that it won't grow above + * uncompressed size by more than 12 bytes. LZX guarantees it won't grow + * more than 6144 bytes. + */ +#define CAB_BLOCKMAX (32768) +#define CAB_INPUTMAX (CAB_BLOCKMAX+6144) + +typedef struct fdi_cds_fwd { + void *hfdi; /* the hfdi we are using */ + cab_UBYTE inbuf[CAB_INPUTMAX+2]; /* +2 for lzx bitbuffer overflows! */ + cab_UBYTE outbuf[CAB_BLOCKMAX]; + union { + struct ZIPstate zip; + } methods; +} fdi_decomp_state; + +/* Tables for deflate from PKZIP's appnote.txt. */ + +#define THOSE_ZIP_CONSTS \ +static const cab_UBYTE Zipborder[] = /* Order of the bit length code lengths */ \ +{ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; \ +static const cab_UWORD Zipcplens[] = /* Copy lengths for literal codes 257..285 */ \ +{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, \ + 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; \ +static const cab_UWORD Zipcplext[] = /* Extra bits for literal codes 257..285 */ \ +{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, \ + 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ \ +static const cab_UWORD Zipcpdist[] = /* Copy offsets for distance codes 0..29 */ \ +{ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, \ +513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; \ +static const cab_UWORD Zipcpdext[] = /* Extra bits for distance codes */ \ +{ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, \ +10, 11, 11, 12, 12, 13, 13}; \ +/* And'ing with Zipmask[n] masks the lower n bits */ \ +static const cab_UWORD Zipmask[17] = { \ + 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, \ + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff \ +} diff --git a/reactos/dll/directx/wine/d3dxof/parsing.c b/reactos/dll/directx/wine/d3dxof/parsing.c new file mode 100644 index 00000000000..fa992ced71e --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/parsing.c @@ -0,0 +1,1433 @@ +/* + * X Files parsing + * + * Copyright 2008 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/debug.h" + +#define COBJMACROS + +#include "winbase.h" +#include "wingdi.h" + +#include "d3dxof_private.h" +#include "dxfile.h" + +#include + +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_ERROR 0xffff +#define TOKEN_NONE 0 +#define TOKEN_NAME 1 +#define TOKEN_STRING 2 +#define TOKEN_INTEGER 3 +#define TOKEN_GUID 5 +#define TOKEN_INTEGER_LIST 6 +#define TOKEN_FLOAT_LIST 7 +#define TOKEN_OBRACE 10 +#define TOKEN_CBRACE 11 +#define TOKEN_OPAREN 12 +#define TOKEN_CPAREN 13 +#define TOKEN_OBRACKET 14 +#define TOKEN_CBRACKET 15 +#define TOKEN_OANGLE 16 +#define TOKEN_CANGLE 17 +#define TOKEN_DOT 18 +#define TOKEN_COMMA 19 +#define TOKEN_SEMICOLON 20 +#define TOKEN_TEMPLATE 31 +#define TOKEN_WORD 40 +#define TOKEN_DWORD 41 +#define TOKEN_FLOAT 42 +#define TOKEN_DOUBLE 43 +#define TOKEN_CHAR 44 +#define TOKEN_UCHAR 45 +#define TOKEN_SWORD 46 +#define TOKEN_SDWORD 47 +#define TOKEN_VOID 48 +#define TOKEN_LPSTR 49 +#define TOKEN_UNICODE 50 +#define TOKEN_CSTRING 51 +#define TOKEN_ARRAY 52 + +#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) + { + 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 "STRING"; + case TOKEN_UNICODE: + return "UNICODE"; + case TOKEN_CSTRING: + return "CSTRING "; + default: + break; + } + return NULL; +} + +static void dump_template(xtemplate* templates_array, xtemplate* ptemplate) +{ + ULONG j, k; + GUID* clsid; + + clsid = &ptemplate->class_id; + + DPRINTF("template %s\n", ptemplate->name); + DPRINTF("{\n"); + 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 < ptemplate->nb_members; j++) + { + if (ptemplate->members[j].nb_dims) + DPRINTF("array "); + if (ptemplate->members[j].type == TOKEN_NAME) + DPRINTF("%s ", templates_array[ptemplate->members[j].idx_template].name); + else + DPRINTF("%s ", get_primitive_string(ptemplate->members[j].type)); + DPRINTF("%s", ptemplate->members[j].name); + for (k = 0; k < ptemplate->members[j].nb_dims; k++) + { + if (ptemplate->members[j].dim_fixed[k]) + DPRINTF("[%d]", ptemplate->members[j].dim_value[k]); + else + DPRINTF("[%s]", ptemplate->members[ptemplate->members[j].dim_value[k]].name); + } + DPRINTF(";\n"); + } + if (ptemplate->open) + DPRINTF("[...]\n"); + else if (ptemplate->nb_children) + { + DPRINTF("[%s", ptemplate->children[0]); + for (j = 1; j < ptemplate->nb_children; j++) + DPRINTF(",%s", ptemplate->children[j]); + DPRINTF("]\n"); + } + DPRINTF("}\n"); +} + +static BOOL read_bytes(parse_buffer * buf, LPVOID data, DWORD size) +{ + if (buf->rem_bytes < size) + return FALSE; + memcpy(data, buf->buffer, size); + buf->buffer += size; + buf->rem_bytes -= size; + return TRUE; +} + +static void rewind_bytes(parse_buffer * buf, DWORD size) +{ + buf->buffer -= 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-19 -> size of decompressed file including xof header, + * 20-21 -> size of first decompressed MSZIP chunk, 22-23 -> size of first compressed MSZIP chunk + * 24-xx -> compressed MSZIP data chunk + * xx-xx -> size of next decompressed MSZIP chunk, xx-xx -> size of next compressed MSZIP chunk + * xx-xx -> compressed MSZIP data chunk + * .............................................................................................. */ + int err; + DWORD decomp_file_size; + WORD decomp_chunk_size; + WORD comp_chunk_size; + LPBYTE decomp_buffer; + + if (!read_bytes(buf, &decomp_file_size, sizeof(decomp_file_size))) + return DXFILEERR_BADFILETYPE; + + TRACE("Compressed format %s detected: decompressed file size with xof header = %d\n", + debugstr_fourcc(header[2]), decomp_file_size); + + /* Does not take xof header into account */ + decomp_file_size -= 16; + + decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_file_size); + if (!decomp_buffer) + { + ERR("Out of memory\n"); + return DXFILEERR_BADALLOC; + } + *decomp_buffer_ptr = decomp_buffer; + + while (buf->rem_bytes) + { + if (!read_bytes(buf, &decomp_chunk_size, sizeof(decomp_chunk_size))) + return DXFILEERR_BADFILETYPE; + if (!read_bytes(buf, &comp_chunk_size, sizeof(comp_chunk_size))) + return DXFILEERR_BADFILETYPE; + + TRACE("Process chunk: compressed_size = %d, decompressed_size = %d\n", + comp_chunk_size, decomp_chunk_size); + + err = mszip_decompress(comp_chunk_size, decomp_chunk_size, (char*)buf->buffer, (char*)decomp_buffer); + if (err) + { + WARN("Error while decompressing MSZIP chunk %d\n", err); + HeapFree(GetProcessHeap(), 0, decomp_buffer); + return DXFILEERR_BADALLOC; + } + buf->rem_bytes -= comp_chunk_size; + buf->buffer += comp_chunk_size; + decomp_buffer += decomp_chunk_size; + } + + if ((decomp_buffer - *decomp_buffer_ptr) != decomp_file_size) + ERR("Size of all decompressed chunks (%u) does not match decompressed file size (%u)\n", + (DWORD)(decomp_buffer - *decomp_buffer_ptr), decomp_file_size); + + /* Use decompressed data */ + buf->buffer = *decomp_buffer_ptr; + buf->rem_bytes = decomp_file_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 + switch(token) + { + DUMP_TOKEN(TOKEN_NAME); + DUMP_TOKEN(TOKEN_STRING); + DUMP_TOKEN(TOKEN_INTEGER); + DUMP_TOKEN(TOKEN_GUID); + DUMP_TOKEN(TOKEN_INTEGER_LIST); + DUMP_TOKEN(TOKEN_FLOAT_LIST); + DUMP_TOKEN(TOKEN_OBRACE); + DUMP_TOKEN(TOKEN_CBRACE); + DUMP_TOKEN(TOKEN_OPAREN); + DUMP_TOKEN(TOKEN_CPAREN); + DUMP_TOKEN(TOKEN_OBRACKET); + DUMP_TOKEN(TOKEN_CBRACKET); + DUMP_TOKEN(TOKEN_OANGLE); + DUMP_TOKEN(TOKEN_CANGLE); + DUMP_TOKEN(TOKEN_DOT); + DUMP_TOKEN(TOKEN_COMMA); + DUMP_TOKEN(TOKEN_SEMICOLON); + DUMP_TOKEN(TOKEN_TEMPLATE); + DUMP_TOKEN(TOKEN_WORD); + DUMP_TOKEN(TOKEN_DWORD); + DUMP_TOKEN(TOKEN_FLOAT); + DUMP_TOKEN(TOKEN_DOUBLE); + DUMP_TOKEN(TOKEN_CHAR); + DUMP_TOKEN(TOKEN_UCHAR); + DUMP_TOKEN(TOKEN_SWORD); + DUMP_TOKEN(TOKEN_SDWORD); + DUMP_TOKEN(TOKEN_VOID); + DUMP_TOKEN(TOKEN_LPSTR); + DUMP_TOKEN(TOKEN_UNICODE); + DUMP_TOKEN(TOKEN_CSTRING); + DUMP_TOKEN(TOKEN_ARRAY); + default: + if (0) + TRACE("Unknown token %d\n", token); + break; + } +#undef DUMP_TOKEN +} + +static BOOL is_space(char c) +{ + switch (c) + { + case 0x00: + case 0x0D: + case 0x0A: + case ' ': + case '\t': + return TRUE; + } + return FALSE; +} + +static BOOL is_operator(char c) +{ + switch(c) + { + case '{': + case '}': + case '[': + case ']': + case '(': + case ')': + case '<': + case '>': + case ',': + case ';': + return TRUE; + } + return FALSE; +} + +static inline BOOL is_separator(char c) +{ + return is_space(c) || is_operator(c); +} + +static WORD get_operator_token(char c) +{ + switch(c) + { + case '{': + return TOKEN_OBRACE; + case '}': + return TOKEN_CBRACE; + case '[': + return TOKEN_OBRACKET; + case ']': + return TOKEN_CBRACKET; + case '(': + return TOKEN_OPAREN; + case ')': + return TOKEN_CPAREN; + case '<': + return TOKEN_OANGLE; + case '>': + return TOKEN_CANGLE; + case ',': + return TOKEN_COMMA; + case ';': + return TOKEN_SEMICOLON; + } + return 0; +} + +static BOOL is_keyword(parse_buffer* buf, const char* keyword) +{ + char tmp[8]; /* longest keyword size (template) */ + DWORD len = strlen(keyword); + + if (!read_bytes(buf, tmp, len)) + return FALSE; + if (strncasecmp(tmp, keyword, len)) + { + rewind_bytes(buf, len); + return FALSE; + } + + if (!read_bytes(buf, tmp, 1)) + return TRUE; + if (is_separator(tmp[0])) + { + rewind_bytes(buf, 1); + return TRUE; + } + rewind_bytes(buf, len+1); + return FALSE; +} + +static WORD get_keyword_token(parse_buffer* buf) +{ + if (is_keyword(buf, "template")) + return TOKEN_TEMPLATE; + if (is_keyword(buf, "WORD")) + return TOKEN_WORD; + if (is_keyword(buf, "DWORD")) + return TOKEN_DWORD; + if (is_keyword(buf, "FLOAT")) + return TOKEN_FLOAT; + if (is_keyword(buf, "DOUBLE")) + return TOKEN_DOUBLE; + if (is_keyword(buf, "CHAR")) + return TOKEN_CHAR; + if (is_keyword(buf, "UCHAR")) + return TOKEN_UCHAR; + if (is_keyword(buf, "SWORD")) + return TOKEN_SWORD; + if (is_keyword(buf, "SDWORD")) + return TOKEN_SDWORD; + if (is_keyword(buf, "VOID")) + return TOKEN_VOID; + if (is_keyword(buf, "STRING")) + return TOKEN_LPSTR; + if (is_keyword(buf, "UNICODE")) + return TOKEN_UNICODE; + if (is_keyword(buf, "CSTRING")) + return TOKEN_CSTRING; + if (is_keyword(buf, "array")) + return TOKEN_ARRAY; + + return 0; +} + +static BOOL is_guid(parse_buffer* buf) +{ + char tmp[50]; + DWORD pos = 1; + GUID class_id; + DWORD tab[10]; + int ret; + + if (buf->rem_bytes < 38 || *buf->buffer != '<') + return FALSE; + tmp[0] = '<'; + while (pos < sizeof(tmp) - 2 && *(buf->buffer+pos) != '>') + { + tmp[pos] = *(buf->buffer+pos); + pos++; + } + tmp[pos++] = '>'; + tmp[pos] = 0; + if (pos != 38 /* <+36+> */) + { + TRACE("Wrong guid %s (%d)\n", tmp, pos); + return FALSE; + } + buf->buffer += 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; +} + +static BOOL is_name(parse_buffer* buf) +{ + char tmp[512]; + DWORD pos = 0; + char c; + BOOL error = 0; + while (pos < buf->rem_bytes && !is_separator(c = *(buf->buffer+pos))) + { + if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || (c == '_') || (c == '-'))) + error = 1; + if (pos < sizeof(tmp)) + tmp[pos] = c; + pos++; + } + tmp[min(pos, sizeof(tmp) - 1)] = 0; + + if (error) + { + TRACE("Wrong name %s\n", tmp); + return FALSE; + } + + buf->buffer += pos; + buf->rem_bytes -= pos; + + TRACE("Found name %s\n", tmp); + strcpy((char*)buf->value, tmp); + + return TRUE; +} + +static BOOL is_float(parse_buffer* buf) +{ + char tmp[512]; + DWORD pos = 0; + char c; + float decimal; + BOOL dot = 0; + + while (pos < buf->rem_bytes && !is_separator(c = *(buf->buffer+pos))) + { + if (!((!pos && (c == '-')) || ((c >= '0') && (c <= '9')) || (!dot && (c == '.')))) + return FALSE; + if (c == '.') + dot = TRUE; + if (pos < sizeof(tmp)) + tmp[pos] = c; + pos++; + } + tmp[min(pos, sizeof(tmp) - 1)] = 0; + + buf->buffer += pos; + buf->rem_bytes -= pos; + + sscanf(tmp, "%f", &decimal); + + TRACE("Found float %s - %f\n", tmp, decimal); + + *(float*)buf->value = decimal; + + return TRUE; +} + +static BOOL is_integer(parse_buffer* buf) +{ + char tmp[512]; + DWORD pos = 0; + char c; + DWORD integer; + + while (pos < buf->rem_bytes && !is_separator(c = *(buf->buffer+pos))) + { + if (!((c >= '0') && (c <= '9'))) + return FALSE; + if (pos < sizeof(tmp)) + tmp[pos] = c; + pos++; + } + tmp[min(pos, sizeof(tmp) - 1)] = 0; + + buf->buffer += pos; + buf->rem_bytes -= pos; + + sscanf(tmp, "%d", &integer); + + TRACE("Found integer %s - %d\n", tmp, integer); + + *(DWORD*)buf->value = integer; + + return TRUE; +} + +static BOOL is_string(parse_buffer* buf) +{ + char tmp[512]; + DWORD pos = 0; + char c; + BOOL ok = 0; + + if (*buf->buffer != '"') + return FALSE; + + while ((pos+1) < buf->rem_bytes) + { + c = *(buf->buffer+pos+1); + if (c == '"') + { + ok = 1; + break; + } + if (pos < sizeof(tmp)) + tmp[pos] = c; + pos++; + } + tmp[min(pos, sizeof(tmp) - 1)] = 0; + + if (!ok) + { + TRACE("Wrong string %s\n", tmp); + return FALSE; + } + + buf->buffer += pos + 2; + buf->rem_bytes -= pos + 2; + + TRACE("Found string %s\n", tmp); + strcpy((char*)buf->value, tmp); + + return TRUE; +} + +static WORD parse_TOKEN(parse_buffer * buf) +{ + WORD token; + + if (buf->txt) + { + while(1) + { + char c; + if (!read_bytes(buf, &c, 1)) + return TOKEN_NONE; + if ((c == '#') || (c == '/')) + { + /* Handle comment (# or //) */ + if (c == '/') + { + if (!read_bytes(buf, &c, 1)) + return TOKEN_ERROR; + if (c != '/') + return TOKEN_ERROR; + } + c = 0; + while (c != 0x0A) + { + if (!read_bytes(buf, &c, 1)) + return TOKEN_NONE; + } + continue; + } + if (is_space(c)) + continue; + if (is_operator(c) && (c != '<')) + { + token = get_operator_token(c); + break; + } + else if (c == '.') + { + token = TOKEN_DOT; + break; + } + else + { + rewind_bytes(buf, 1); + + if ((token = get_keyword_token(buf))) + break; + + if (is_guid(buf)) + { + token = TOKEN_GUID; + break; + } + if (is_integer(buf)) + { + token = TOKEN_INTEGER; + break; + } + if (is_float(buf)) + { + token = TOKEN_FLOAT; + break; + } + if (is_string(buf)) + { + token = TOKEN_LPSTR; + break; + } + if (is_name(buf)) + { + token = TOKEN_NAME; + break; + } + + FIXME("Unrecognize element\n"); + return TOKEN_ERROR; + } + } + } + else + { + if (!buf->list_nb_elements) + { + if (!read_bytes(buf, &token, 2)) + return TOKEN_NONE; + + /* Convert integer and float list into separate elements */ + if (token == TOKEN_INTEGER_LIST) + { + if (!read_bytes(buf, &buf->list_nb_elements, 4)) + return TOKEN_ERROR; + token = TOKEN_INTEGER; + buf->list_type_float = FALSE; + TRACE("Integer list (TOKEN_INTEGER_LIST) of size %d\n", buf->list_nb_elements); + } + else if (token == TOKEN_FLOAT_LIST) + { + if (!read_bytes(buf, &buf->list_nb_elements, 4)) + return TOKEN_ERROR; + token = TOKEN_FLOAT; + buf->list_type_float = TRUE; + TRACE("Float list (TOKEN_FLOAT_LIST) of size %d\n", buf->list_nb_elements); + } + } + + if (buf->list_nb_elements) + { + if (buf->list_separator) + { + buf->list_nb_elements--; + buf->list_separator = FALSE; + /* Insert separarator between each values and since list does not accept separator at the end + use a comma so any extra separator will generate an error */ + token = TOKEN_COMMA; + } + else + { + DWORD value; + + if (!read_bytes(buf, &value, 4)) + return TOKEN_ERROR; + *(DWORD*)buf->value = value; + + buf->list_separator = TRUE; + /* Convert list into a serie of their basic type counterpart */ + token = buf->list_type_float ? TOKEN_FLOAT : TOKEN_INTEGER; + } + dump_TOKEN(token); + return token; + } + + switch (token) + { + case TOKEN_NAME: + { + DWORD count; + char *name = (char*)buf->value; + + if (!read_bytes(buf, &count, 4)) + return TOKEN_ERROR; + if (!read_bytes(buf, name, count)) + return TOKEN_ERROR; + name[count] = 0; + TRACE("name = %s\n", name); + } + break; + case TOKEN_INTEGER: + { + DWORD integer; + + if (!read_bytes(buf, &integer, 4)) + return TOKEN_ERROR; + TRACE("integer = %u\n", integer); + + *(DWORD*)buf->value = integer; + } + break; + case TOKEN_GUID: + { + char strguid[39]; + GUID class_id; + + if (!read_bytes(buf, &class_id, 16)) + return TOKEN_ERROR; + 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]); + TRACE("guid = %s\n", strguid); + + *(GUID*)buf->value = class_id; + } + break; + case TOKEN_STRING: + { + DWORD count; + char *string = (char*)buf->value; + + if (!read_bytes(buf, &count, 4)) + return TOKEN_ERROR; + if (!read_bytes(buf, string, count)) + return TOKEN_ERROR; + string[count] = 0; + TRACE("string = %s\n", string); + + token = TOKEN_LPSTR; + } + break; + case TOKEN_OBRACE: + case TOKEN_CBRACE: + case TOKEN_OPAREN: + case TOKEN_CPAREN: + case TOKEN_OBRACKET: + case TOKEN_CBRACKET: + case TOKEN_OANGLE: + case TOKEN_CANGLE: + case TOKEN_DOT: + case TOKEN_COMMA: + case TOKEN_SEMICOLON: + case TOKEN_TEMPLATE: + case TOKEN_WORD: + case TOKEN_DWORD: + case TOKEN_FLOAT: + case TOKEN_DOUBLE: + case TOKEN_CHAR: + case TOKEN_UCHAR: + case TOKEN_SWORD: + case TOKEN_SDWORD: + case TOKEN_VOID: + case TOKEN_LPSTR: + case TOKEN_UNICODE: + case TOKEN_CSTRING: + case TOKEN_ARRAY: + break; + default: + return TOKEN_ERROR; + } + } + + dump_TOKEN(token); + + return token; +} + +static WORD get_TOKEN(parse_buffer * buf) +{ + if (buf->token_present) + { + buf->token_present = FALSE; + return buf->current_token; + } + + buf->current_token = parse_TOKEN(buf); + + return buf->current_token; +} + +static WORD check_TOKEN(parse_buffer * buf) +{ + if (buf->token_present) + return buf->current_token; + + buf->current_token = parse_TOKEN(buf); + buf->token_present = TRUE; + + return buf->current_token; +} + +static inline BOOL is_primitive_type(WORD token) +{ + BOOL ret; + switch(token) + { + case TOKEN_WORD: + case TOKEN_DWORD: + case TOKEN_FLOAT: + case TOKEN_DOUBLE: + case TOKEN_CHAR: + case TOKEN_UCHAR: + case TOKEN_SWORD: + case TOKEN_SDWORD: + case TOKEN_LPSTR: + case TOKEN_UNICODE: + case TOKEN_CSTRING: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +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) + { + get_TOKEN(buf); + if (get_TOKEN(buf) != TOKEN_DOT) + return FALSE; + if (get_TOKEN(buf) != TOKEN_DOT) + return FALSE; + cur_template->open = TRUE; + } + else + { + while (1) + { + if (get_TOKEN(buf) != TOKEN_NAME) + return FALSE; + strcpy(cur_template->children[cur_template->nb_children], (char*)buf->value); + if (check_TOKEN(buf) == TOKEN_GUID) + get_TOKEN(buf); + cur_template->nb_children++; + if (check_TOKEN(buf) != TOKEN_COMMA) + break; + get_TOKEN(buf); + } + cur_template->open = FALSE; + } + + return TRUE; +} + +static BOOL parse_template_members_list(parse_buffer * buf) +{ + int idx_member = 0; + member* cur_member; + + while (1) + { + BOOL array = 0; + int nb_dims = 0; + cur_member = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[idx_member]; + + if (check_TOKEN(buf) == TOKEN_ARRAY) + { + get_TOKEN(buf); + array = 1; + } + + if (check_TOKEN(buf) == TOKEN_NAME) + { + cur_member->type = get_TOKEN(buf); + if (!strcmp((char*)buf->value, "indexColor")) + { + /* Case sensitive legacy type indexColor is described in the first template */ + cur_member->idx_template = 0; + } + else + { + cur_member->idx_template = 1; + while (cur_member->idx_template < buf->pdxf->nb_xtemplates) + { + if (!strcasecmp((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) + { + WARN("Reference to a nonexistent template '%s'\n", (char*)buf->value); + return FALSE; + } + } + } + else if (is_primitive_type(check_TOKEN(buf))) + cur_member->type = get_TOKEN(buf); + else + break; + + if (get_TOKEN(buf) != TOKEN_NAME) + return FALSE; + strcpy(cur_member->name, (char*)buf->value); + + if (array) + { + while (check_TOKEN(buf) == TOKEN_OBRACKET) + { + if (nb_dims >= MAX_ARRAY_DIM) + { + FIXME("Too many dimensions (%d) for multi-dimensional array\n", nb_dims + 1); + return FALSE; + } + get_TOKEN(buf); + if (check_TOKEN(buf) == TOKEN_INTEGER) + { + get_TOKEN(buf); + cur_member->dim_fixed[nb_dims] = TRUE; + cur_member->dim_value[nb_dims] = *(DWORD*)buf->value; + } + else + { + int i; + if (get_TOKEN(buf) != TOKEN_NAME) + return FALSE; + for (i = 0; i < idx_member; i++) + { + if (!strcmp((char*)buf->value, buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[i].name)) + { + if (buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[i].nb_dims) + { + ERR("Array cannot be used to specify variable array size\n"); + return FALSE; + } + if (buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[i].type != TOKEN_DWORD) + { + FIXME("Only DWORD supported to specify variable array size\n"); + return FALSE; + } + break; + } + } + if (i == idx_member) + { + ERR("Reference to unknown member %s\n", (char*)buf->value); + return FALSE; + } + cur_member->dim_fixed[nb_dims] = FALSE; + cur_member->dim_value[nb_dims] = i; + } + if (get_TOKEN(buf) != TOKEN_CBRACKET) + return FALSE; + nb_dims++; + } + if (!nb_dims) + return FALSE; + cur_member->nb_dims = nb_dims; + } + if (get_TOKEN(buf) != TOKEN_SEMICOLON) + return FALSE; + + idx_member++; + } + + buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].nb_members = idx_member; + + return TRUE; +} + +static BOOL parse_template_parts(parse_buffer * buf) +{ + if (!parse_template_members_list(buf)) + return FALSE; + if (check_TOKEN(buf) == TOKEN_OBRACKET) + { + get_TOKEN(buf); + if (!parse_template_option_info(buf)) + return FALSE; + if (get_TOKEN(buf) != TOKEN_CBRACKET) + return FALSE; + } + + return TRUE; +} + +static BOOL parse_template(parse_buffer * buf) +{ + if (get_TOKEN(buf) != TOKEN_TEMPLATE) + return FALSE; + if (get_TOKEN(buf) != TOKEN_NAME) + return FALSE; + strcpy(buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, (char*)buf->value); + if (get_TOKEN(buf) != TOKEN_OBRACE) + return FALSE; + if (get_TOKEN(buf) != TOKEN_GUID) + return FALSE; + buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id = *(GUID*)buf->value; + if (!parse_template_parts(buf)) + return FALSE; + if (get_TOKEN(buf) != TOKEN_CBRACE) + return FALSE; + + 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; +} + +BOOL parse_templates(parse_buffer * buf, BOOL templates_only) +{ + while (check_TOKEN(buf) != TOKEN_NONE) + { + if (templates_only && (check_TOKEN(buf) != TOKEN_TEMPLATE)) + return TRUE; + if (!parse_template(buf)) + { + WARN("Template is not correct\n"); + return FALSE; + } + else + { + TRACE("Template successfully parsed:\n"); + if (TRACE_ON(d3dxof_parsing)) + dump_template(buf->pdxf->xtemplates, &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates - 1]); + } + } + return TRUE; +} + +static BOOL check_buffer(parse_buffer * buf, ULONG size) +{ + if ((buf->cur_pos_data + size) > buf->capacity) + { + LPBYTE pdata; + ULONG new_capacity = buf->capacity ? 2 * buf->capacity : 100000; + + pdata = HeapAlloc(GetProcessHeap(), 0, new_capacity); + if (!pdata) + return FALSE; + memcpy(pdata, buf->pdata, buf->cur_pos_data); + HeapFree(GetProcessHeap(), 0, buf->pdata); + buf->capacity = new_capacity; + buf->pdata = pdata; + buf->pxo->root->pdata = pdata; + } + return TRUE; +} + +static BOOL parse_object_parts(parse_buffer * buf, BOOL allow_optional); +static BOOL parse_object_members_list(parse_buffer * buf) +{ + DWORD token; + ULONG i; + xtemplate* pt = buf->pxt[buf->level]; + + buf->pxo->nb_members = pt->nb_members; + + for (i = 0; i < pt->nb_members; i++) + { + ULONG k; + ULONG nb_elems = 1; + BOOL basic_type = TRUE; + + buf->pxo->members[i].name = pt->members[i].name; + buf->pxo->members[i].start = buf->cur_pos_data; + + for (k = 0; k < pt->members[i].nb_dims; k++) + { + if (pt->members[i].dim_fixed[k]) + nb_elems *= pt->members[i].dim_value[k]; + else + nb_elems *= *(DWORD*)(buf->pxo->root->pdata + buf->pxo->members[pt->members[i].dim_value[k]].start); + } + + TRACE("Elements to consider: %u\n", nb_elems); + + for (k = 0; k < nb_elems; k++) + { + if (pt->members[i].type == TOKEN_NAME) + { + ULONG j; + + TRACE("Found sub-object %s\n", buf->pdxf->xtemplates[pt->members[i].idx_template].name); + basic_type = FALSE; + buf->level++; + /* To do template lookup */ + for (j = 0; j < buf->pdxf->nb_xtemplates; j++) + { + if (!strcasecmp(buf->pdxf->xtemplates[pt->members[i].idx_template].name, buf->pdxf->xtemplates[j].name)) + { + buf->pxt[buf->level] = &buf->pdxf->xtemplates[j]; + break; + } + } + if (j == buf->pdxf->nb_xtemplates) + { + ERR("Unknown template %s\n", (char*)buf->value); + buf->level--; + return FALSE; + } + TRACE("Enter %s\n", buf->pdxf->xtemplates[pt->members[i].idx_template].name); + if (!parse_object_parts(buf, FALSE)) + { + buf->level--; + return FALSE; + } + buf->level--; + } + else + { + token = check_TOKEN(buf); + if (token == TOKEN_INTEGER) + { + get_TOKEN(buf); + TRACE("%s = %d\n", pt->members[i].name, *(DWORD*)buf->value); + /* Assume larger size */ + if (!check_buffer(buf, 4)) + return FALSE; + if (pt->members[i].type == TOKEN_WORD) + { + *(((WORD*)(buf->pdata + buf->cur_pos_data))) = (WORD)(*(DWORD*)buf->value); + buf->cur_pos_data += 2; + } + else if (pt->members[i].type == TOKEN_DWORD) + { + *(((DWORD*)(buf->pdata + buf->cur_pos_data))) = (DWORD)(*(DWORD*)buf->value); + buf->cur_pos_data += 4; + } + else + { + FIXME("Token %d not supported\n", pt->members[i].type); + return FALSE; + } + } + else if (token == TOKEN_FLOAT) + { + get_TOKEN(buf); + TRACE("%s = %f\n", pt->members[i].name, *(float*)buf->value); + if (!check_buffer(buf, 4)) + return FALSE; + if (pt->members[i].type == TOKEN_FLOAT) + { + *(((float*)(buf->pdata + buf->cur_pos_data))) = (float)(*(float*)buf->value); + buf->cur_pos_data += 4; + } + else + { + FIXME("Token %d not supported\n", pt->members[i].type); + return FALSE; + } + } + else if (token == TOKEN_LPSTR) + { + get_TOKEN(buf); + TRACE("%s = %s\n", pt->members[i].name, (char*)buf->value); + if (!check_buffer(buf, sizeof(LPSTR))) + return FALSE; + if (pt->members[i].type == TOKEN_LPSTR) + { + int len = strlen((char*)buf->value) + 1; + if ((buf->cur_pstrings - buf->pstrings + len) > MAX_STRINGS_BUFFER) + { + FIXME("Buffer too small %p %p %d\n", buf->cur_pstrings, buf->pstrings, len); + return FALSE; + } + strcpy((char*)buf->cur_pstrings, (char*)buf->value); + *(((LPCSTR*)(buf->pdata + buf->cur_pos_data))) = (char*)buf->cur_pstrings; + buf->cur_pstrings += len; + buf->cur_pos_data += sizeof(LPSTR); + } + else + { + FIXME("Token %d not supported\n", pt->members[i].type); + return FALSE; + } + } + else + { + WARN("Unexpected token %d\n", token); + return FALSE; + } + } + + if (basic_type) + { + /* Handle separator only for basic types */ + token = check_TOKEN(buf); + if ((token != TOKEN_COMMA) && (token != TOKEN_SEMICOLON)) + return FALSE; + /* Allow multi-semicolons + single comma separator */ + while (check_TOKEN(buf) == TOKEN_SEMICOLON) + get_TOKEN(buf); + if (check_TOKEN(buf) == TOKEN_COMMA) + get_TOKEN(buf); + } + } + + buf->pxo->members[i].size = buf->cur_pos_data - buf->pxo->members[i].start; + } + + return TRUE; +} + +static BOOL parse_object_parts(parse_buffer * buf, BOOL allow_optional) +{ + buf->pxo->nb_children = 0; + + if (!parse_object_members_list(buf)) + return FALSE; + + if (allow_optional) + { + buf->pxo->size = buf->cur_pos_data - buf->pxo->pos_data; + + while (1) + { + if (check_TOKEN(buf) == TOKEN_OBRACE) + { + ULONG i, j; + get_TOKEN(buf); + if (get_TOKEN(buf) != TOKEN_NAME) + return FALSE; + if (get_TOKEN(buf) != TOKEN_CBRACE) + return FALSE; + TRACE("Found optional reference %s\n", (char*)buf->value); + for (i = 0; i < (buf->nb_pxo_globals+1); i++) + { + for (j = 0; j < (buf->pxo_globals[i])[0].nb_subobjects; j++) + { + if (!strcmp((buf->pxo_globals[i])[j].name, (char*)buf->value)) + goto _exit; + } + } +_exit: + if (i == (buf->nb_pxo_globals+1)) + { + ERR("Reference to unknown object %s\n", (char*)buf->value); + return FALSE; + } + + if (buf->pxo->root->nb_subobjects >= MAX_SUBOBJECTS) + { + FIXME("Too many sub-objects\n"); + return FALSE; + } + + buf->pxo->children[buf->pxo->nb_children] = &buf->pxo_tab[buf->pxo->root->nb_subobjects++]; + buf->pxo->children[buf->pxo->nb_children]->ptarget = &(buf->pxo_globals[i])[j]; + buf->pxo->children[buf->pxo->nb_children]->binary = FALSE; + buf->pxo->nb_children++; + } + else if (check_TOKEN(buf) == TOKEN_NAME) + { + xobject* pxo = buf->pxo; + + if (buf->pxo->root->nb_subobjects >= MAX_SUBOBJECTS) + { + FIXME("Too many sub-objects\n"); + return FALSE; + } + + buf->pxo = buf->pxo->children[buf->pxo->nb_children] = &buf->pxo_tab[buf->pxo->root->nb_subobjects++]; + + TRACE("Enter optional %s\n", (char*)buf->value); + buf->level++; + if (!parse_object(buf)) + { + buf->level--; + return FALSE; + } + buf->level--; + buf->pxo = pxo; + buf->pxo->nb_children++; + } + else + break; + } + } + + if (buf->pxo->nb_children > MAX_CHILDREN) + { + FIXME("Too many children %d\n", buf->pxo->nb_children); + return FALSE; + } + + return TRUE; +} + +BOOL parse_object(parse_buffer * buf) +{ + ULONG i; + + buf->pxo->pos_data = buf->cur_pos_data; + buf->pxo->ptarget = NULL; + buf->pxo->binary = FALSE; + buf->pxo->root = buf->pxo_tab; + + if (get_TOKEN(buf) != TOKEN_NAME) + return FALSE; + + /* To do template lookup */ + for (i = 0; i < buf->pdxf->nb_xtemplates; i++) + { + if (!strcasecmp((char*)buf->value, buf->pdxf->xtemplates[i].name)) + { + buf->pxt[buf->level] = &buf->pdxf->xtemplates[i]; + memcpy(&buf->pxo->type, &buf->pdxf->xtemplates[i].class_id, 16); + break; + } + } + if (i == buf->pdxf->nb_xtemplates) + { + ERR("Unknown template %s\n", (char*)buf->value); + return FALSE; + } + + if (check_TOKEN(buf) == TOKEN_NAME) + { + get_TOKEN(buf); + strcpy(buf->pxo->name, (char*)buf->value); + } + else + buf->pxo->name[0] = 0; + + if (get_TOKEN(buf) != TOKEN_OBRACE) + return FALSE; + if (check_TOKEN(buf) == TOKEN_GUID) + { + get_TOKEN(buf); + memcpy(&buf->pxo->class_id, buf->value, 16); + } + else + memset(&buf->pxo->class_id, 0, 16); + + if (!parse_object_parts(buf, TRUE)) + return FALSE; + if (get_TOKEN(buf) != TOKEN_CBRACE) + return FALSE; + + /* For seeking to a possibly eof to avoid parsing another object next time */ + check_TOKEN(buf); + + return TRUE; +} diff --git a/reactos/dll/directx/wine/d3dxof/version.rc b/reactos/dll/directx/wine/d3dxof/version.rc new file mode 100644 index 00000000000..93c1371c7c0 --- /dev/null +++ b/reactos/dll/directx/wine/d3dxof/version.rc @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2004 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WINE_FILEDESCRIPTION_STR "DirectX Files dll" +#define WINE_FILENAME_STR "d3dxof.dll" +#define WINE_FILEVERSION 5,0,2135,1 +#define WINE_FILEVERSION_STR "5.0.2135.1" +#define WINE_PRODUCTVERSION 5,0,2135,1 +#define WINE_PRODUCTVERSION_STR "5.0.2135.1" + +#include "wine/wine_common_ver.rc" diff --git a/reactos/include/dxsdk/dxfile.h b/reactos/include/dxsdk/dxfile.h index fe30daf0de9..9eab71a1f4a 100644 --- a/reactos/include/dxsdk/dxfile.h +++ b/reactos/include/dxsdk/dxfile.h @@ -1,180 +1,299 @@ -#ifndef __DXFILE_H__ -#define __DXFILE_H__ +/* + * Copyright 2004 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_DXFILE_H +#define __WINE_DXFILE_H + +#include +#include #ifdef __cplusplus extern "C" { -#endif +#endif /* defined(__cplusplus) */ typedef DWORD DXFILEFORMAT; + +#define DXFILEFORMAT_BINARY 0 +#define DXFILEFORMAT_TEXT 1 +#define DXFILEFORMAT_COMPRESSED 2 + typedef DWORD DXFILELOADOPTIONS; -DEFINE_GUID(IID_IDirectXFile, 0x3D82AB40, 0x62DA, 0x11CF, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33); -DEFINE_GUID(IID_IDirectXFileEnumObject, 0x3D82AB41, 0x62DA, 0x11CF, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33); -DEFINE_GUID(IID_IDirectXFileSaveObject, 0x3D82AB42, 0x62DA, 0x11CF, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33); -DEFINE_GUID(IID_IDirectXFileObject, 0x3D82AB43, 0x62DA, 0x11CF, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33); -DEFINE_GUID(IID_IDirectXFileData, 0x3D82AB44, 0x62DA, 0x11CF, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33); -DEFINE_GUID(IID_IDirectXFileDataReference, 0x3D82AB45, 0x62DA, 0x11CF, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33); -DEFINE_GUID(IID_IDirectXFileBinary, 0x3D82AB46, 0x62DA, 0x11CF, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33); -DEFINE_GUID(TID_DXFILEHeader, 0x3D82AB43, 0x62DA, 0x11CF, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33); -DEFINE_GUID(CLSID_CDirectXFile, 0x4516EC43, 0x8F20, 0x11D0, 0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3); +#define DXFILELOAD_FROMFILE 0x00L +#define DXFILELOAD_FROMRESOURCE 0x01L +#define DXFILELOAD_FROMMEMORY 0x02L +#define DXFILELOAD_FROMSTREAM 0x04L +#define DXFILELOAD_FROMURL 0x08L -#ifndef WIN_TYPES - #define WIN_TYPES(itype, ptype) typedef interface itype *LP##ptype, **LPLP##ptype -#endif +typedef struct _DXFILELOADRESOURCE { + HMODULE hModule; + LPCSTR /*LPCTSTR*/ lpName; + LPCSTR /*LPCTSTR*/ lpType; +} DXFILELOADRESOURCE, *LPDXFILELOADRESOURCE; -#define DXFILEFORMAT_BINARY 0 -#define DXFILEFORMAT_TEXT 1 -#define DXFILEFORMAT_COMPRESSED 2 -#define DXFILELOAD_FROMFILE 0x00L -#define DXFILELOAD_FROMRESOURCE 0x01L -#define DXFILELOAD_FROMMEMORY 0x02L -#define DXFILELOAD_FROMSTREAM 0x04L -#define DXFILELOAD_FROMURL 0x08L +typedef struct _DXFILELOADMEMORY { + LPVOID lpMemory; + DWORD dSize; +} DXFILELOADMEMORY, *LPDXFILELOADMEMORY; -#define _FACDD 0x876 -#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) -#define DXFILE_OK 0 -#define DXFILEERR_BADOBJECT MAKE_DDHRESULT(850) -#define DXFILEERR_BADVALUE MAKE_DDHRESULT(851) -#define DXFILEERR_BADTYPE MAKE_DDHRESULT(852) -#define DXFILEERR_BADSTREAMHANDLE MAKE_DDHRESULT(853) -#define DXFILEERR_BADALLOC MAKE_DDHRESULT(854) -#define DXFILEERR_NOTFOUND MAKE_DDHRESULT(855) -#define DXFILEERR_NOTDONEYET MAKE_DDHRESULT(856) -#define DXFILEERR_FILENOTFOUND MAKE_DDHRESULT(857) -#define DXFILEERR_RESOURCENOTFOUND MAKE_DDHRESULT(858) -#define DXFILEERR_URLNOTFOUND MAKE_DDHRESULT(859) -#define DXFILEERR_BADRESOURCE MAKE_DDHRESULT(860) -#define DXFILEERR_BADFILETYPE MAKE_DDHRESULT(861) -#define DXFILEERR_BADFILEVERSION MAKE_DDHRESULT(862) -#define DXFILEERR_BADFILEFLOATSIZE MAKE_DDHRESULT(863) -#define DXFILEERR_BADFILECOMPRESSIONTYPE MAKE_DDHRESULT(864) -#define DXFILEERR_BADFILE MAKE_DDHRESULT(865) -#define DXFILEERR_PARSEERROR MAKE_DDHRESULT(866) -#define DXFILEERR_NOTEMPLATE MAKE_DDHRESULT(867) -#define DXFILEERR_BADARRAYSIZE MAKE_DDHRESULT(868) -#define DXFILEERR_BADDATAREFERENCE MAKE_DDHRESULT(869) -#define DXFILEERR_INTERNALERROR MAKE_DDHRESULT(870) -#define DXFILEERR_NOMOREOBJECTS MAKE_DDHRESULT(871) -#define DXFILEERR_BADINTRINSICS MAKE_DDHRESULT(872) -#define DXFILEERR_NOMORESTREAMHANDLES MAKE_DDHRESULT(873) -#define DXFILEERR_NOMOREDATA MAKE_DDHRESULT(874) -#define DXFILEERR_BADCACHEFILE MAKE_DDHRESULT(875) -#define DXFILEERR_NOINTERNET MAKE_DDHRESULT(876) - -WIN_TYPES(IDirectXFile, DIRECTXFILE); -WIN_TYPES(IDirectXFileEnumObject, DIRECTXFILEENUMOBJECT); -WIN_TYPES(IDirectXFileSaveObject, DIRECTXFILESAVEOBJECT); -WIN_TYPES(IDirectXFileObject, DIRECTXFILEOBJECT); -WIN_TYPES(IDirectXFileData, DIRECTXFILEDATA); -WIN_TYPES(IDirectXFileDataReference, DIRECTXFILEDATAREFERENCE); -WIN_TYPES(IDirectXFileBinary, DIRECTXFILEBINARY); - -typedef struct _DXFILELOADRESOURCE -{ - HMODULE hModule; - LPCTSTR lpName; - LPCTSTR lpType; -}DXFILELOADRESOURCE, *LPDXFILELOADRESOURCE; - -typedef struct _DXFILELOADMEMORY -{ - LPVOID lpMemory; - DWORD dSize; -}DXFILELOADMEMORY, *LPDXFILELOADMEMORY; +typedef struct IDirectXFile *LPDIRECTXFILE; +typedef struct IDirectXFileEnumObject *LPDIRECTXFILEENUMOBJECT; +typedef struct IDirectXFileSaveObject *LPDIRECTXFILESAVEOBJECT; +typedef struct IDirectXFileObject *LPDIRECTXFILEOBJECT; +typedef struct IDirectXFileData *LPDIRECTXFILEDATA; +typedef struct IDirectXFileDataReference *LPDIRECTXFILEDATAREFERENCE; +typedef struct IDirectXFileBinary *LPDIRECTXFILEBINARY; STDAPI DirectXFileCreate(LPDIRECTXFILE *lplpDirectXFile); + +#define INTERFACE IDirectXFile +DECLARE_INTERFACE_(IDirectXFile,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IDirectXFile methods ***/ + STDMETHOD(CreateEnumObject) (THIS_ LPVOID, DXFILELOADOPTIONS, LPDIRECTXFILEENUMOBJECT *) PURE; + STDMETHOD(CreateSaveObject) (THIS_ LPCSTR, DXFILEFORMAT, LPDIRECTXFILESAVEOBJECT *) PURE; + STDMETHOD(RegisterTemplates) (THIS_ LPVOID, DWORD) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) + /*** IUnknown methods ***/ +#define IDirectXFile_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectXFile_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectXFile_Release(p) (p)->lpVtbl->Release(p) + /*** IDirectXFile methods ***/ +#define IDirectXFile_CreateEnumObject(p,a,b,c) (p)->lpVtbl->CreateEnumObject(p,a,b,c) +#define IDirectXFile_CreateSaveObject(p,a,b,c) (p)->lpVtbl->CreateSaveObject(p,a,b,c) +#define IDirectXFile_RegisterTemplates(p,a,b) (p)->lpVtbl->RegisterTemplates(p,a,b) +#endif + +#define INTERFACE IDirectXFileEnumObject +DECLARE_INTERFACE_(IDirectXFileEnumObject,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IDirectXFileEnumObject methods ***/ + STDMETHOD(GetNextDataObject) (THIS_ LPDIRECTXFILEDATA *) PURE; + STDMETHOD(GetDataObjectById) (THIS_ REFGUID, LPDIRECTXFILEDATA *) PURE; + STDMETHOD(GetDataObjectByName) (THIS_ LPCSTR, LPDIRECTXFILEDATA *) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) + /*** IUnknown methods ***/ +#define IDirectXFileEnumObject_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectXFileEnumObject_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectXFileEnumObject_Release(p) (p)->lpVtbl->Release(p) + /*** IDirectXFileEnumObject methods ***/ +#define IDirectXFileEnumObject_GetNextDataObject(p,a) (p)->lpVtbl->GetNextDataObject(p,a) +#define IDirectXFileEnumObject_GetDataObjectById(p,a,b) (p)->lpVtbl->GetDataObjectById(p,a,b) +#define IDirectXFileEnumObject_GetDataObjectByName(p,a,b) (p)->lpVtbl->GetDataObjectByName(p,a,b) +#endif + +#define INTERFACE IDirectXFileSaveObject +DECLARE_INTERFACE_(IDirectXFileSaveObject,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IDirectXFileSaveObject methods ***/ + STDMETHOD(SaveTemplates) (THIS_ DWORD, const GUID **) PURE; + STDMETHOD(CreateDataObject) (THIS_ REFGUID, LPCSTR, const GUID *, DWORD, LPVOID, LPDIRECTXFILEDATA *) PURE; + STDMETHOD(SaveData) (THIS_ LPDIRECTXFILEDATA) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) + /*** IUnknown methods ***/ +#define IDirectXFileSaveObject_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectXFileSaveObject_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectXFileSaveObject_Release(p) (p)->lpVtbl->Release(p) + /*** IDirectXFileSaveObject methods ***/ +#define IDirectXFileSaveObject_SaveTemplates(p,a,b) (p)->lpVtbl->SaveTemplates(p,a,b) +#define IDirectXFileSaveObject_CreateDataObject(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDataObject(p,a,b,c,d,e,f) +#define IDirectXFileSaveObject_SaveData(p,a) (p)->lpVtbl->SaveData(p,a) +#endif + +#define IUNKNOWN_METHODS(kind) \ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) kind; \ + STDMETHOD_(ULONG,AddRef)(THIS) kind; \ + STDMETHOD_(ULONG,Release)(THIS) kind + #define IDIRECTXFILEOBJECT_METHODS(kind) \ STDMETHOD(GetName) (THIS_ LPSTR, LPDWORD) kind; \ STDMETHOD(GetId) (THIS_ LPGUID) kind -#define IUNKNOWN_METHODS(kind) \ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) kind; \ - STDMETHOD_(ULONG, AddRef) (THIS) kind; \ - STDMETHOD_(ULONG, Release) (THIS) kind -#undef INTERFACE -#define INTERFACE IDirectXFile - -DECLARE_INTERFACE_(IDirectXFile, IUnknown) -{ - IUNKNOWN_METHODS(PURE); - STDMETHOD(CreateEnumObject) (THIS_ LPVOID, DXFILELOADOPTIONS, LPDIRECTXFILEENUMOBJECT *) PURE; - STDMETHOD(CreateSaveObject) (THIS_ LPCSTR, DXFILEFORMAT, LPDIRECTXFILESAVEOBJECT *) PURE; - STDMETHOD(RegisterTemplates) (THIS_ LPVOID, DWORD) PURE; -}; - -#undef INTERFACE -#define INTERFACE IDirectXFileEnumObject - -DECLARE_INTERFACE_(IDirectXFileEnumObject, IUnknown) -{ - IUNKNOWN_METHODS(PURE); - STDMETHOD(GetNextDataObject) (THIS_ LPDIRECTXFILEDATA *) PURE; - STDMETHOD(GetDataObjectById) (THIS_ REFGUID, LPDIRECTXFILEDATA *) PURE; - STDMETHOD(GetDataObjectByName) (THIS_ LPCSTR, LPDIRECTXFILEDATA *) PURE; -}; - -#undef INTERFACE -#define INTERFACE IDirectXFileSaveObject - -DECLARE_INTERFACE_(IDirectXFileSaveObject, IUnknown) +#define INTERFACE IDirectXFileObject +DECLARE_INTERFACE_(IDirectXFileObject,IUnknown) { IUNKNOWN_METHODS(PURE); - STDMETHOD(SaveTemplates) (THIS_ DWORD, const GUID **) PURE; - STDMETHOD(CreateDataObject) (THIS_ REFGUID, LPCSTR, const GUID *, - DWORD, LPVOID, LPDIRECTXFILEDATA *) PURE; - STDMETHOD(SaveData) (THIS_ LPDIRECTXFILEDATA) PURE; + IDIRECTXFILEOBJECT_METHODS(PURE); }; - #undef INTERFACE -#define INTERFACE IDirectXFileObject -DECLARE_INTERFACE_(IDirectXFileObject, IUnknown) -{ - IUNKNOWN_METHODS(PURE); - IDIRECTXFILEOBJECT_METHODS(PURE); -}; +#if !defined(__cplusplus) || defined(CINTERFACE) + /*** IUnknown methods ***/ +#define IDirectXFileObject_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectXFileObject_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectXFileObject_Release(p) (p)->lpVtbl->Release(p) + /*** IDirectXFileObject methods ***/ +#define IDirectXFileObject_GetName(p,a,b) (p)->lpVtbl->GetName(p,a,b) +#define IDirectXFileObject_GetId(p,a) (p)->lpVtbl->GetId(p,a) +#endif -#undef INTERFACE #define INTERFACE IDirectXFileData - -DECLARE_INTERFACE_(IDirectXFileData, IDirectXFileObject) +DECLARE_INTERFACE_(IDirectXFileData,IDirectXFileObject) { - IUNKNOWN_METHODS(PURE); - IDIRECTXFILEOBJECT_METHODS(PURE); - STDMETHOD(GetData) (THIS_ LPCSTR, DWORD *, void **) PURE; - STDMETHOD(GetType) (THIS_ const GUID **) PURE; - STDMETHOD(GetNextObject) (THIS_ LPDIRECTXFILEOBJECT *) PURE; - STDMETHOD(AddDataObject) (THIS_ LPDIRECTXFILEDATA) PURE; - STDMETHOD(AddDataReference) (THIS_ LPCSTR, const GUID *) PURE; - STDMETHOD(AddBinaryObject) (THIS_ LPCSTR, const GUID *, LPCSTR, LPVOID, DWORD) PURE; + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + /*** IDirectXFileData methods ***/ + STDMETHOD(GetData) (THIS_ LPCSTR, DWORD *, void **) PURE; + STDMETHOD(GetType) (THIS_ const GUID **) PURE; + STDMETHOD(GetNextObject) (THIS_ LPDIRECTXFILEOBJECT *) PURE; + STDMETHOD(AddDataObject) (THIS_ LPDIRECTXFILEDATA) PURE; + STDMETHOD(AddDataReference) (THIS_ LPCSTR, const GUID *) PURE; + STDMETHOD(AddBinaryObject) (THIS_ LPCSTR, const GUID *, LPCSTR, LPVOID, DWORD) PURE; }; - #undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) + /*** IUnknown methods ***/ +#define IDirectXFileData_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectXFileData_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectXFileData_Release(p) (p)->lpVtbl->Release(p) + /*** IDirectXFileObject methods ***/ +#define IDirectXFileData_GetName(p,a,b) (p)->lpVtbl->GetName(p,a,b) +#define IDirectXFileData_GetId(p,a) (p)->lpVtbl->GetId(p,a) + /*** IDirectXFileData methods ***/ +#define IDirectXFileData_GetData(p,a,b,c) (p)->lpVtbl->GetData(p,a,b,c) +#define IDirectXFileData_GetType(p,a) (p)->lpVtbl->GetType(p,a) +#define IDirectXFileData_GetNextObject(p,a) (p)->lpVtbl->GetNextObject(p,a) +#define IDirectXFileData_AddDataObject(p,a) (p)->lpVtbl->AddDataObject(p,a) +#define IDirectXFileData_AddDataReference(p,a,b) (p)->lpVtbl->AddDataReference(p,a,b) +#define IDirectXFileData_AddBinaryObject(p,a,b,c,d,e) (p)->lpVtbl->AddBinaryObject(p,a,b,c,d,e) +#endif + #define INTERFACE IDirectXFileDataReference - -DECLARE_INTERFACE_(IDirectXFileDataReference, IDirectXFileObject) +DECLARE_INTERFACE_(IDirectXFileDataReference,IDirectXFileObject) { - IUNKNOWN_METHODS(PURE); - IDIRECTXFILEOBJECT_METHODS(PURE); - STDMETHOD(Resolve) (THIS_ LPDIRECTXFILEDATA *) PURE; + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + /*** IDirectXFileDataReference methods ***/ + STDMETHOD(Resolve) (THIS_ LPDIRECTXFILEDATA *) PURE; }; - #undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) + /*** IUnknown methods ***/ +#define IDirectXFileDataReference_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectXFileDataReference_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectXFileDataReference_Release(p) (p)->lpVtbl->Release(p) + /*** IDirectXFileObject methods ***/ +#define IDirectXFileDataReference_GetName(p,a,b) (p)->lpVtbl->GetName(p,a,b) +#define IDirectXFileDataReference_GetId(p,a) (p)->lpVtbl->GetId(p,a) + /*** IDirectXFileDataReference methods ***/ +#define IDirectXFileDataReference_Resolve(p,a) (p)->lpVtbl->Resolve(p,a) +#endif + #define INTERFACE IDirectXFileBinary - -DECLARE_INTERFACE_(IDirectXFileBinary, IDirectXFileObject) +DECLARE_INTERFACE_(IDirectXFileBinary,IDirectXFileObject) { - IUNKNOWN_METHODS(PURE); - IDIRECTXFILEOBJECT_METHODS(PURE); - - STDMETHOD(GetSize) (THIS_ DWORD *) PURE; - STDMETHOD(GetMimeType) (THIS_ LPCSTR *) PURE; - STDMETHOD(Read) (THIS_ LPVOID, DWORD, LPDWORD) PURE; + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + /*** IDirectXFileBinary methods ***/ + STDMETHOD(GetSize) (THIS_ DWORD *) PURE; + STDMETHOD(GetMimeType) (THIS_ LPCSTR *) PURE; + STDMETHOD(Read) (THIS_ LPVOID, DWORD, LPDWORD) PURE; }; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) + /*** IUnknown methods ***/ +#define IDirectXFileBinary_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectXFileBinary_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectXFileBinary_Release(p) (p)->lpVtbl->Release(p) + /*** IDirectXFileObject methods ***/ +#define IDirectXFileBinary_GetName(p,a,b) (p)->lpVtbl->GetName(p,a,b) +#define IDirectXFileBinary_GetId(p,a) (p)->lpVtbl->GetId(p,a) + /*** IDirectXFileBinary methods ***/ +#define IDirectXFileBinary_GetSize(p,a) (p)->lpVtbl->GetSize(p,a) +#define IDirectXFileBinary_GetMimeType(p,a) (p)->lpVtbl->GetMimeType(p,a) +#define IDirectXFileBinary_Read(p,a,b,c) (p)->lpVtbl->Read(p,a,b,c) +#endif + +/* DirectXFile Object CLSID */ +DEFINE_GUID(CLSID_CDirectXFile, 0x4516ec43, 0x8f20, 0x11d0, 0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3); + +/* DirectX File Interface GUIDs */ +DEFINE_GUID(IID_IDirectXFile, 0x3d82ab40, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileEnumObject, 0x3d82ab41, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileSaveObject, 0x3d82ab42, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileObject, 0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileData, 0x3d82ab44, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileDataReference, 0x3d82ab45, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileBinary, 0x3d82ab46, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* DirectX File Header template's GUID */ +DEFINE_GUID(TID_DXFILEHeader, 0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* DirectX File errors */ +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +#define DXFILE_OK 0 + +#define DXFILEERR_BADOBJECT MAKE_DDHRESULT(850) +#define DXFILEERR_BADVALUE MAKE_DDHRESULT(851) +#define DXFILEERR_BADTYPE MAKE_DDHRESULT(852) +#define DXFILEERR_BADSTREAMHANDLE MAKE_DDHRESULT(853) +#define DXFILEERR_BADALLOC MAKE_DDHRESULT(854) +#define DXFILEERR_NOTFOUND MAKE_DDHRESULT(855) +#define DXFILEERR_NOTDONEYET MAKE_DDHRESULT(856) +#define DXFILEERR_FILENOTFOUND MAKE_DDHRESULT(857) +#define DXFILEERR_RESOURCENOTFOUND MAKE_DDHRESULT(858) +#define DXFILEERR_URLNOTFOUND MAKE_DDHRESULT(859) +#define DXFILEERR_BADRESOURCE MAKE_DDHRESULT(860) +#define DXFILEERR_BADFILETYPE MAKE_DDHRESULT(861) +#define DXFILEERR_BADFILEVERSION MAKE_DDHRESULT(862) +#define DXFILEERR_BADFILEFLOATSIZE MAKE_DDHRESULT(863) +#define DXFILEERR_BADFILECOMPRESSIONTYPE MAKE_DDHRESULT(864) +#define DXFILEERR_BADFILE MAKE_DDHRESULT(865) +#define DXFILEERR_PARSEERROR MAKE_DDHRESULT(866) +#define DXFILEERR_NOTEMPLATE MAKE_DDHRESULT(867) +#define DXFILEERR_BADARRAYSIZE MAKE_DDHRESULT(868) +#define DXFILEERR_BADDATAREFERENCE MAKE_DDHRESULT(869) +#define DXFILEERR_INTERNALERROR MAKE_DDHRESULT(870) +#define DXFILEERR_NOMOREOBJECTS MAKE_DDHRESULT(871) +#define DXFILEERR_BADINTRINSICS MAKE_DDHRESULT(872) +#define DXFILEERR_NOMORESTREAMHANDLES MAKE_DDHRESULT(873) +#define DXFILEERR_NOMOREDATA MAKE_DDHRESULT(874) +#define DXFILEERR_BADCACHEFILE MAKE_DDHRESULT(875) +#define DXFILEERR_NOINTERNET MAKE_DDHRESULT(876) #ifdef __cplusplus -}; -#endif +} /* extern "C" */ +#endif /* defined(__cplusplus) */ -#endif +#endif /* __WINE_DXFILE_H */ diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 0489ff6f38b..20b423dba2c 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -41,6 +41,7 @@ reactos/dll/directx/qedit # Autosync reactos/dll/directx/quartz # Synced to Wine-1.5.26 reactos/dll/directx/wine/d3d8 # Synced to Wine-1.7.1 reactos/dll/directx/wine/d3d9 # Synced to Wine-1.7.1 +reactos/dll/directx/wine/d3dxof # Synced to Wine-1.7.1 reactos/dll/directx/wine/ddraw # Synced to Wine-1.7.1 reactos/dll/directx/wine/wined3d # Synced to Wine-1.7.1 reactos/dll/win32/activeds # Synced to Wine-1.1.43?