Finally, I've found that damn bug that was molesting my loader's cache implementation. I have rewritten it using recently added wine/list.h (my original scheme with HeapReAllocs doesn't seem to be of any use, so I dropped it). Now it's possible to run dxdiag with native dm*.dlls and builtin loader, which works like charm :) Tom, you are free to declare it 50% (or even more) operational, since only stuff missing is some advanced cache management. ChangeLog: - rewritten cache code and fixed a bug that was in it -- Rok Mandeljc <rok.mandeljc@gimb.org> "Hold your position! Leave doubt for the dying!" -- Tahngarth of the Weatherlight
diff -Nru Original/wine/dlls/dmloader/dmloader_private.h wine/dlls/dmloader/dmloader_private.h --- Original/wine/dlls/dmloader/dmloader_private.h 2003-09-21 19:34:43.000000000 +0200 +++ wine/dlls/dmloader/dmloader_private.h 2003-09-21 19:57:48.000000000 +0200 @@ -33,23 +33,19 @@ #include "dmplugin.h" #include "dmusicf.h" #include "dsound.h" +#include "wine/list.h" -typedef struct _DMUS_PRIVATE_CACHE_ENTRY -{ +/***************************************************************************** + * Auxiliary definitions + */ +typedef struct _DMUS_PRIVATE_CACHE_ENTRY { + struct list entry; /* for listing elements */ GUID guidObject; - WCHAR pwzFileName[MAX_PATH]; + WCHAR wzFileName[MAX_PATH]; IDirectMusicObject* pObject; } DMUS_PRIVATE_CACHE_ENTRY, *LPDMUS_PRIVATE_CACHE_ENTRY; -typedef struct _DMUS_PRIVATE_OBJECT_REFERENCE DMUS_PRIVATE_OBJECT_REFERENCE; - -struct _DMUS_PRIVATE_OBJECT_REFERENCE { - DMUS_PRIVATE_OBJECT_REFERENCE* pNext; - WCHAR pwsFileName[MAX_PATH]; - GUID guidObject; - IDirectMusicObject* pObject; -}; /***************************************************************************** * Interfaces @@ -103,9 +99,8 @@ /* IDirectMusicLoaderImpl fields */ WCHAR wzSearchPath[MAX_PATH]; - /* simple cache */ - LPDMUS_PRIVATE_CACHE_ENTRY pCache; /* cache entries */ - DWORD dwCacheSize; /* nr. of entries */ + /* simple cache (linked list) */ + struct list* pCacheList; }; /* IUnknown: */ diff -Nru Original/wine/dlls/dmloader/loader.c wine/dlls/dmloader/loader.c --- Original/wine/dlls/dmloader/loader.c 2003-09-21 19:34:43.000000000 +0200 +++ wine/dlls/dmloader/loader.c 2003-09-21 19:36:14.000000000 +0200 @@ -72,32 +72,37 @@ HRESULT WINAPI IDirectMusicLoader8Impl_GetObject (LPDIRECTMUSICLOADER8 iface, LPDMUS_OBJECTDESC pDesc, REFIID riid, LPVOID* ppv) { IDirectMusicObject* pObject; - DMUS_OBJECTDESC desc; ICOM_THIS(IDirectMusicLoader8Impl,iface); - int i; HRESULT result; TRACE("(%p, %p, %s, %p)\n", This, pDesc, debugstr_guid(riid), ppv); - TRACE(": looking up cache"); - /* first, check if requested object is already in cache (check by name and GUID) */ - for (i = 0; i < This->dwCacheSize; i++) { - if (pDesc->dwValidData & DMUS_OBJ_OBJECT) { - if (IsEqualGUID (&pDesc->guidObject, &This->pCache[i].guidObject)) { - TRACE(": object already exist in cache (found by GUID)\n"); - if (This->pCache[i].pObject) { - return IDirectMusicObject_QueryInterface (This->pCache[i].pObject, riid, ppv); + + + TRACE("looking up cache...\n"); + struct list *listEntry; + DMUS_PRIVATE_CACHE_ENTRY *cacheEntry; + + LIST_FOR_EACH (listEntry, This->pCacheList) { + cacheEntry = LIST_ENTRY( listEntry, DMUS_PRIVATE_CACHE_ENTRY, entry ); + + if ((pDesc->dwValidData & DMUS_OBJ_OBJECT) || (pDesc->dwValidData & DMUS_OBJ_FILENAME)) { + if (pDesc->dwValidData & DMUS_OBJ_OBJECT) { + if (IsEqualGUID (&cacheEntry->guidObject, &pDesc->guidObject)) { + TRACE(": found it by GUID\n"); + if (cacheEntry->pObject) + return IDirectMusicObject_QueryInterface ((LPDIRECTMUSICOBJECT)cacheEntry->pObject, riid, ppv); } } - } else if (pDesc->dwValidData & DMUS_OBJ_FILENAME) { - if (This->pCache[i].pwzFileName && !strncmpW(pDesc->wszFileName, This->pCache[i].pwzFileName, MAX_PATH)) { - TRACE(": object already exist in cache (found by file name)\n"); - if (This->pCache[i].pObject) { - return IDirectMusicObject_QueryInterface (This->pCache[i].pObject, riid, ppv); + if (pDesc->dwValidData & DMUS_OBJ_FILENAME) { + if (cacheEntry->wzFileName && !strncmpW (pDesc->wszFileName, cacheEntry->wzFileName, MAX_PATH)) { + TRACE(": found it by FileName\n"); + if (cacheEntry->pObject) + return IDirectMusicObject_QueryInterface ((LPDIRECTMUSICOBJECT)cacheEntry->pObject, riid, ppv); } } } } - + /* object doesn't exist in cache... guess we'll have to load it */ TRACE(": object does not exist in cache\n"); result = CoCreateInstance (&pDesc->guidClass, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicObject, (LPVOID*)&pObject); @@ -109,13 +114,13 @@ IPersistStream *pPersistStream = NULL; /* if it's full path, don't add search directory path, otherwise do */ if (pDesc->dwValidData & DMUS_OBJ_FULLPATH) { - lstrcpyW( wzFileName, pDesc->wszFileName ); + lstrcpyW( wzFileName, pDesc->wszFileName ); } else { - WCHAR *p; - lstrcpyW( wzFileName, This->wzSearchPath ); - p = wzFileName + lstrlenW(wzFileName); - if (p > wzFileName && p[-1] != '\\') *p++ = '\\'; - lstrcpyW( p, pDesc->wszFileName ); + WCHAR *p; + lstrcpyW( wzFileName, This->wzSearchPath ); + p = wzFileName + lstrlenW(wzFileName); + if (p > wzFileName && p[-1] != '\\') *p++ = '\\'; + strcpyW( p, pDesc->wszFileName ); } TRACE(": loading from file (%s)\n", debugstr_w(wzFileName)); @@ -140,22 +145,13 @@ TRACE(": loading from stream\n"); result = IDirectMusicObject_QueryInterface (pObject, &IID_IPersistStream, (LPVOID*)&pPersistStream); - if (FAILED(result)) { - TRACE("couln\'t get IPersistStream\n"); - return result; - } + if (FAILED(result)) return result; result = IStream_Clone (pDesc->pStream, &pClonedStream); - if (FAILED(result)) { - TRACE("failed to clone\n"); - return result; - } + if (FAILED(result)) return result; result = IPersistStream_Load (pPersistStream, pClonedStream); - if (FAILED(result)) { - TRACE("failed to load\n"); - return result; - } + if (FAILED(result)) return result; IPersistStream_Release (pPersistStream); IStream_Release (pClonedStream); @@ -163,11 +159,27 @@ /* load object by GUID */ TRACE(": loading by GUID (only default DLS supported)\n"); if (IsEqualGUID (&pDesc->guidObject, &GUID_DefaultGMCollection)) { - /* great idea: let's just change dwValid and wszFileName fields and then call ourselves again :D */ - pDesc->dwValidData = DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH; - if (FAILED(DMUSIC_GetDefaultGMPath (pDesc->wszFileName))) + WCHAR wzFileName[MAX_PATH]; + if (FAILED(DMUSIC_GetDefaultGMPath (wzFileName))) return E_FAIL; - return IDirectMusicLoader8Impl_GetObject (iface, pDesc, riid, ppv); + /* load object from file */ + ILoaderStream* pStream; + IPersistStream *pPersistStream = NULL; + + result = DMUSIC_CreateLoaderStream ((LPSTREAM*)&pStream); + if (FAILED(result)) return result; + + result = ILoaderStream_Attach (pStream, wzFileName, (LPDIRECTMUSICLOADER)iface); + if (FAILED(result)) return result; + + result = IDirectMusicObject_QueryInterface (pObject, &IID_IPersistStream, (LPVOID*)&pPersistStream); + if (FAILED(result)) return result; + + result = IPersistStream_Load (pPersistStream, (LPSTREAM)pStream); + if (FAILED(result)) return result; + + ILoaderStream_IStream_Release ((LPSTREAM)pStream); + IPersistStream_Release (pPersistStream); } else { return E_FAIL; } @@ -176,32 +188,28 @@ FIXME(": unknown/unsupported way of loading\n"); return E_FAIL; } - - memset((LPVOID)&desc, 0, sizeof(desc)); - desc.dwSize = sizeof (DMUS_OBJECTDESC); - IDirectMusicObject_GetDescriptor (pObject, &desc); - - /* tests with native dlls show that descriptor, which is received by GetDescriptor doesn't contain filepath - therefore we must copy it from input description */ - if (pDesc->dwValidData & DMUS_OBJ_FILENAME || desc.dwValidData & DMUS_OBJ_OBJECT) { - DMUS_PRIVATE_CACHE_ENTRY CacheEntry; - This->dwCacheSize++; /* increase size of cache for one entry */ - This->pCache = HeapReAlloc (GetProcessHeap (), 0, This->pCache, sizeof(DMUS_PRIVATE_CACHE_ENTRY) * This->dwCacheSize); - if (desc.dwValidData & DMUS_OBJ_OBJECT) - CacheEntry.guidObject = desc.guidObject; - if (pDesc->dwValidData & DMUS_OBJ_FILENAME) - strncpyW (CacheEntry.pwzFileName, pDesc->wszFileName, MAX_PATH); - CacheEntry.pObject = pObject; - IDirectMusicObject_AddRef (pObject); /* MSDN says that we should */ - This->pCache[This->dwCacheSize - 1] = CacheEntry; /* fill in one backward, as list is zero based */ - TRACE(": filled in cache entry\n"); - } + /* add object to cache */ + LPDMUS_PRIVATE_CACHE_ENTRY newEntry; + newEntry = (LPDMUS_PRIVATE_CACHE_ENTRY) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_CACHE_ENTRY)); + if (pDesc->dwValidData & DMUS_OBJ_OBJECT) + memcpy (&newEntry->guidObject, &pDesc->guidObject, sizeof (pDesc->guidObject)); + if (pDesc->dwValidData & DMUS_OBJ_FILENAME) + strncpyW (newEntry->wzFileName, pDesc->wszFileName, MAX_PATH); + if (pObject) + newEntry->pObject = pObject; + list_add_tail (This->pCacheList, &newEntry->entry); + TRACE(": filled in cache entry\n"); - TRACE(": nr. of entries = %ld\n", This->dwCacheSize); - for (i = 0; i < This->dwCacheSize; i++) { - TRACE(": cache entry [%i]: GUID = %s, file name = %s, object = %p\n", i, debugstr_guid(&This->pCache[i].guidObject), debugstr_w(This->pCache[i].pwzFileName), This->pCache[i].pObject); + /* for debug purposes (e.g. to check if all files are cached) */ +#if 0 + int i = 0; + LIST_FOR_EACH (listEntry, This->pCacheList) { + i++; + cacheEntry = LIST_ENTRY( listEntry, DMUS_PRIVATE_CACHE_ENTRY, entry ); + TRACE("Entry nr. %i: GUID = %s, FileName = %s\n", i, debugstr_guid (&cacheEntry->guidObject), debugstr_w (cacheEntry->wzFileName)); } - +#endif + return IDirectMusicObject_QueryInterface (pObject, riid, ppv); } @@ -352,6 +360,8 @@ } dmloader->lpVtbl = &DirectMusicLoader8_Vtbl; dmloader->ref = 1; + dmloader->pCacheList = (struct list*) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof (struct list)); + list_init (dmloader->pCacheList); *ppDMLoad = (LPDIRECTMUSICLOADER8)dmloader; return S_OK; } diff -Nru Original/wine/dlls/dmloader/loaderstream.c wine/dlls/dmloader/loaderstream.c --- Original/wine/dlls/dmloader/loaderstream.c 2003-09-21 19:34:43.000000000 +0200 +++ wine/dlls/dmloader/loaderstream.c 2003-09-21 19:36:14.000000000 +0200 @@ -46,7 +46,6 @@ } /* create IDirectMusicGetLoader */ (LPDIRECTMUSICLOADER)This->pLoader = pLoader; - IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8)This->pLoader); strncpyW (This->wzFileName, wzFile, MAX_PATH); TRACE(": succeeded\n"); @@ -165,41 +164,49 @@ /* not needed*/ HRESULT WINAPI ILoaderStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten) { + ERR(": should not be needed\n"); return E_NOTIMPL; } HRESULT WINAPI ILoaderStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) { + ERR(": should not be needed\n"); return E_NOTIMPL; } HRESULT WINAPI ILoaderStream_IStream_CopyTo (LPSTREAM iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) { + ERR(": should not be needed\n"); return E_NOTIMPL; } HRESULT WINAPI ILoaderStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) { + ERR(": should not be needed\n"); return E_NOTIMPL; } HRESULT WINAPI ILoaderStream_IStream_Revert (LPSTREAM iface) { + ERR(": should not be needed\n"); return E_NOTIMPL; } HRESULT WINAPI ILoaderStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { + ERR(": should not be needed\n"); return E_NOTIMPL; } HRESULT WINAPI ILoaderStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { + ERR(": should not be needed\n"); return E_NOTIMPL; } HRESULT WINAPI ILoaderStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag) { + ERR(": should not be needed\n"); return E_NOTIMPL; } @@ -249,7 +256,8 @@ TRACE("(%p, %p)\n", This, ppLoader); *ppLoader = (LPDIRECTMUSICLOADER)This->pLoader; - + IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8)*ppLoader); + return S_OK; }
Attachment:
signature.asc
Description: To je digitalno podpisan del =?iso-8859-2?Q?sporo=E8ila?=