/* IDirectMusicLoaderImpl
 *
 * Copyright (C) 2003-2004 Rok Mandeljc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 Library General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "dmloader_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dmloader);

/*****************************************************************************
 * IDirectMusicLoaderImpl implementation
 */
/* IUnknown/IDirectMusicLoader(8) part: */
HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_QueryInterface (LPDIRECTMUSICLOADER8 iface, REFIID riid, LPVOID *ppobj) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);

	TRACE("(%p, %s, %p)\n",This, debugstr_dmguid(riid), ppobj);
	if (IsEqualIID (riid, &IID_IUnknown) || 
	    IsEqualIID (riid, &IID_IDirectMusicLoader) ||
	    IsEqualIID (riid, &IID_IDirectMusicLoader8)) {
		IDirectMusicLoaderImpl_IDirectMusicLoader_AddRef (iface);
		*ppobj = This;
		return S_OK;
	}
	
	WARN(": not found\n");
	return E_NOINTERFACE;
}

ULONG WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_AddRef (LPDIRECTMUSICLOADER8 iface) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	TRACE("(%p): AddRef from %ld\n", This, This->dwRef);
	return InterlockedIncrement (&This->dwRef);
}

ULONG WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_Release (LPDIRECTMUSICLOADER8 iface) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	
	DWORD dwRef = InterlockedDecrement (&This->dwRef);
	TRACE("(%p): ReleaseRef to %ld\n", This, This->dwRef);
	if (dwRef == 0) {
		DMUSIC_DestroyDirectMusicLoaderImpl (iface);
		HeapFree (GetProcessHeap(), 0, This);
	}
	
	return dwRef;
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_GetObject (LPDIRECTMUSICLOADER8 iface, LPDMUS_OBJECTDESC pDesc, REFIID riid, LPVOID* ppv) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	HRESULT result = S_OK;
	HRESULT ret = S_OK; /* used at the end of function, to determine whether everything went OK */
	
	struct list *pEntry;
	LPWINE_LOADER_ENTRY pObjectEntry = NULL;
	LPSTREAM pStream;
	IPersistStream* pPersistStream = NULL;

	LPDIRECTMUSICOBJECT pObject;
	DMUS_OBJECTDESC GotDesc;
	BOOL bCache;

	TRACE("(%p, %p, %s, %p): pDesc:\n%s", This, pDesc, debugstr_dmguid(riid), ppv, debugstr_DMUS_OBJECTDESC(pDesc));
	
	/* sometimes it happens that guidClass is missing... which is a BadThingTM */
	if (!(pDesc->dwValidData & DMUS_OBJ_CLASS)) {
	  ERR(": guidClass not valid but needed\n");
	  *ppv = NULL;
	  return DMUS_E_LOADER_NOCLASSID;
	}
	
	/* OK, first we iterate thru the list of objects we know about; these are either loaded (GetObject, LoadObjectFromFile)
	   or set via SetObject; */
	TRACE(": looking if we have object in the cache or if it can be found via alias\n");
	LIST_FOR_EACH(pEntry, This->pObjects) {
		LPWINE_LOADER_ENTRY pExistingEntry = LIST_ENTRY(pEntry, WINE_LOADER_ENTRY, entry);
		if ((pDesc->dwValidData & DMUS_OBJ_OBJECT) &&
			(pExistingEntry->Desc.dwValidData & DMUS_OBJ_OBJECT) &&
			IsEqualGUID (&pDesc->guidObject, &pExistingEntry->Desc.guidObject)) {
			TRACE(": found it by object GUID\n");
			/* I suppose such stuff can happen only when GUID for object is given (GUID_DefaultGMCollection) */
			if (pExistingEntry->bInvalidDefaultDLS) {
				TRACE(": found faulty default DLS collection... enabling M$ compliant behaviour\n");
				return DMUS_E_LOADER_NOFILENAME;	
			}
			if (pExistingEntry->Desc.dwValidData & DMUS_OBJ_LOADED) {
				TRACE(": already loaded\n");
				return IDirectMusicObject_QueryInterface (pExistingEntry->pObject, riid, ppv);
			} else {
				TRACE(": not loaded yet\n");
				pObjectEntry = pExistingEntry;
			}
		}
		else if ((pDesc->dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH)) &&
				(pExistingEntry->Desc.dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH)) &&
				!strncmpW (pDesc->wszFileName, pExistingEntry->Desc.wszFileName, DMUS_MAX_FILENAME)) {
			TRACE(": found it by fullpath filename\n");
			if (pExistingEntry->Desc.dwValidData & DMUS_OBJ_LOADED) {
				TRACE(": already loaded\n");
				return IDirectMusicObject_QueryInterface (pExistingEntry->pObject, riid, ppv);
			} else {
				TRACE(": not loaded yet\n");
				pObjectEntry = pExistingEntry;
			}
		}
		else if ((pDesc->dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY)) &&
				(pExistingEntry->Desc.dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY)) &&
				!strncmpW (pDesc->wszName, pExistingEntry->Desc.wszName, DMUS_MAX_NAME) &&
				!strncmpW (pDesc->wszCategory, pExistingEntry->Desc.wszCategory, DMUS_MAX_CATEGORY)) {
			TRACE(": found it by name and category\n");
			if (pExistingEntry->Desc.dwValidData & DMUS_OBJ_LOADED) {
				TRACE(": already loaded\n");
				return IDirectMusicObject_QueryInterface (pExistingEntry->pObject, riid, ppv);
			} else {
				TRACE(": not loaded yet\n");
				pObjectEntry = pExistingEntry;
			}
		}
		else if ((pDesc->dwValidData & DMUS_OBJ_NAME) &&
				(pExistingEntry->Desc.dwValidData & DMUS_OBJ_NAME) &&
				!strncmpW (pDesc->wszName, pExistingEntry->Desc.wszName, DMUS_MAX_NAME)) {
			TRACE(": found it by name\n");
			if (pExistingEntry->Desc.dwValidData & DMUS_OBJ_LOADED) {
				TRACE(": already loaded\n");
				return IDirectMusicObject_QueryInterface (pExistingEntry->pObject, riid, ppv);
			} else {
				TRACE(": not loaded yet\n");
				pObjectEntry = pExistingEntry;
			}
		}
		else if ((pDesc->dwValidData & DMUS_OBJ_FILENAME) &&
				(pExistingEntry->Desc.dwValidData & DMUS_OBJ_FILENAME) &&
				!strncmpW (pDesc->wszFileName, pExistingEntry->Desc.wszFileName, DMUS_MAX_FILENAME)) {
			TRACE(": found it by filename\n");				
			if (pExistingEntry->Desc.dwValidData & DMUS_OBJ_LOADED) {
				TRACE(": already loaded\n");
				return IDirectMusicObject_QueryInterface (pExistingEntry->pObject, riid, ppv);
			} else {
				TRACE(": not loaded yet\n");
				pObjectEntry = pExistingEntry;
			}
		}
	}
	
	/* basically, if we found alias, we use its descriptor to load...
	   else we use info we were given */
	if (pObjectEntry) {
		TRACE(": found alias entry for requested object... using stored info\n");
		/* I think in certain cases it can happen that entry's descriptor lacks info
		   where to load from (e.g.: if we loaded from stream and then released object
		   from cache; then only it's CLSID, GUID and perhaps name are left); so just
		   overwrite info entry has (since it ought to be 100% correct) */
		DMUSIC_CopyDescriptor (pDesc, &pObjectEntry->Desc);
		/*pDesc = &pObjectEntry->Desc; */ /* FIXME: is this OK? */
	} else {
		TRACE(": no cache/alias entry found for requested object\n");
	}
	
	if (pDesc->dwValidData & DMUS_OBJ_URL) {
		TRACE(": loading from URLs not supported yet\n");
		return DMUS_E_LOADER_FORMATNOTSUPPORTED;
	}
	else if (pDesc->dwValidData & DMUS_OBJ_FILENAME) {
		/* load object from file */
		/* generate filename; if it's full path, don't add search 
		   directory path, otherwise do */
		WCHAR wszFileName[MAX_PATH];

		if (pDesc->dwValidData & DMUS_OBJ_FULLPATH) {
			lstrcpyW(wszFileName, pDesc->wszFileName);
		} else {
			WCHAR *p, wszSearchPath[MAX_PATH];
			DMUSIC_GetLoaderSettings (iface, &pDesc->guidClass, wszSearchPath, NULL);
			lstrcpyW(wszFileName, wszSearchPath);
			p = wszFileName + lstrlenW(wszFileName);
			if (p > wszFileName && p[-1] != '\\') *p++ = '\\';
			strcpyW(p, pDesc->wszFileName);
		}
		TRACE(": loading from file (%s)\n", debugstr_w(wszFileName));
		/* create stream and associate it with file */			
		result = DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID*)&pStream);
		if (FAILED(result)) {
			ERR(": could not create loader stream\n");
			return result;
		}
		result = IDirectMusicLoaderFileStream_Attach (pStream, wszFileName, iface);
		if (FAILED(result)) {
			ERR(": could not attach stream to file\n");			
			return result;
		}

	}
	else if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
		/* load object from resource */
		TRACE(": loading from resource\n");
		/* create stream and associate it with given resource */			
		result = DMUSIC_CreateDirectMusicLoaderResourceStream ((LPVOID*)&pStream);
		if (FAILED(result)) {
			ERR(": could not create resource stream\n");
			return result;
		}
		result = IDirectMusicLoaderResourceStream_Attach (pStream, pDesc->pbMemData, pDesc->llMemLength, 0, iface);
		if (FAILED(result)) {
			ERR(": could not attach stream to resource\n");			
			return result;
		}
	}
	else if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
		/* load object from stream */
		TRACE(": loading from stream\n");
		/* create universal stream and associate it with given one */			
		result = DMUSIC_CreateDirectMusicLoaderGenericStream ((LPVOID*)&pStream);
		if (FAILED(result)) {
			ERR(": could not create generic stream\n");
			return result;
		}
		result = IDirectMusicLoaderGenericStream_Attach (pStream, pDesc->pStream, iface);
		if (FAILED(result)) {
			ERR(": failed to attach stream\n");
			return result;
		}
	} else {
		/* nowhere to load from */
		FIXME(": unknown/unsupported way of loading\n");
		return DMUS_E_LOADER_NOFILENAME; /* test shows this is returned */
	}

	/* create object */
	result = CoCreateInstance (&pDesc->guidClass, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicObject, (LPVOID*)&pObject);
	if (FAILED(result)) {
		ERR(": could not create object\n");
		return result;
	}
	/* acquire PersistStream interface */
	result = IDirectMusicObject_QueryInterface (pObject, &IID_IPersistStream, (LPVOID*)&pPersistStream);
	if (FAILED(result)) {
		ERR("failed to Query\n");
		return result;
	}
	/* load */
	result = IPersistStream_Load (pPersistStream, pStream);
	if (result != S_OK) {
		WARN(": failed to (completely) load object (%s)\n", debugstr_dmreturn(result));
		ret = DMUS_S_PARTIALLOAD /*result*/;
	}
	/* get descriptor */
	DM_STRUCT_INIT(&GotDesc);
	result = IDirectMusicObject_GetDescriptor (pObject, &GotDesc);
	/* set filename (if we loaded via filename) */
	if (pDesc->dwValidData & DMUS_OBJ_FILENAME) {
		GotDesc.dwValidData |= (pDesc->dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH));
		strcpyW (GotDesc.wszFileName, pDesc->wszFileName);
	}
	if (FAILED(result)) {
		ERR(": failed to get descriptor\n");
		return result;
	}
	/* release all loading related stuff */
	IStream_Release (pStream);
	IPersistStream_Release (pPersistStream);	
		
	/* add object to cache/overwrite existing info (if cache is enabled) */
	DMUSIC_GetLoaderSettings (iface, &pDesc->guidClass, NULL, &bCache);
	if (bCache) {
		if (!pObjectEntry) {
			pObjectEntry = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(WINE_LOADER_ENTRY));
			DM_STRUCT_INIT(&pObjectEntry->Desc);
			if (pObject) {
				DMUSIC_CopyDescriptor (&pObjectEntry->Desc, &GotDesc);
				pObjectEntry->pObject = pObject;
				pObjectEntry->bInvalidDefaultDLS = FALSE;
			}
			list_add_head (This->pObjects, &pObjectEntry->entry);
		} else {
			if (pObject) {
				DMUSIC_CopyDescriptor (&pObjectEntry->Desc, &GotDesc);
				pObjectEntry->pObject = pObject;
				pObjectEntry->bInvalidDefaultDLS = FALSE;
			}		
		}
		TRACE(": filled in cache entry\n");
	} else TRACE(": caching disabled\n");

#if 0
	/* for debug purposes (e.g. to check if all files are cached) */
	TRACE("*** Loader's cache ***\n");
	int i = 0;
	LIST_FOR_EACH (pEntry, This->pObjects) {
		i++;
		pObjectEntry = LIST_ENTRY(pEntry, WINE_LOADER_ENTRY, entry);
		TRACE(": entry nr. %i:\n%s  - bInvalidDefaultDLS = %i\n  - pObject = %p\n", i, debugstr_DMUS_OBJECTDESC(&pObjectEntry->Desc), pObjectEntry->bInvalidDefaultDLS, pObjectEntry->pObject);
	}
#endif
	
	result = IDirectMusicObject_QueryInterface (pObject, riid, ppv);
	if (!bCache) IDirectMusicObject_Release (pObject); /* since loader's reference is not needed */
	/* if there was trouble with loading, and if no other error occurred,
	   we should return DMUS_S_PARTIALLOAD; else, error is returned */
	if (result == S_OK)
		return ret;
	else
		return result;
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_SetObject (LPDIRECTMUSICLOADER8 iface, LPDMUS_OBJECTDESC pDesc) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	LPSTREAM pStream;
	LPDIRECTMUSICOBJECT pObject;
	DMUS_OBJECTDESC Desc;
	struct list *pEntry;
	LPWINE_LOADER_ENTRY pObjectEntry, pNewEntry;

	TRACE("(%p, %p): pDesc:\n%s\n", This, pDesc, debugstr_DMUS_OBJECTDESC(pDesc));

	/* create stream and load additional info from it */
	if (pDesc->dwValidData & DMUS_OBJ_FILENAME) {
		/* generate filename; if it's full path, don't add search 
		   directory path, otherwise do */
		WCHAR wszFileName[MAX_PATH];

		if (pDesc->dwValidData & DMUS_OBJ_FULLPATH) {
			lstrcpyW(wszFileName, pDesc->wszFileName);
		} else {
			WCHAR *p;
			WCHAR wszSearchPath[MAX_PATH];
			DMUSIC_GetLoaderSettings (iface, &pDesc->guidClass, wszSearchPath, NULL);
			lstrcpyW(wszFileName, wszSearchPath);
			p = wszFileName + lstrlenW(wszFileName);
			if (p > wszFileName && p[-1] != '\\') *p++ = '\\';
			strcpyW(p, pDesc->wszFileName);
		}
		/* create stream */
		DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID*)&pStream);
		/* attach stream */
		IDirectMusicLoaderFileStream_Attach (pStream, wszFileName, iface);
	}
	else if (pDesc->dwValidData & DMUS_OBJ_STREAM) {	
		/* create stream */
		DMUSIC_CreateDirectMusicLoaderGenericStream ((LPVOID*)&pStream);
		/* attach stream */
		IDirectMusicLoaderGenericStream_Attach (pStream, pDesc->pStream, iface);
	}
	else if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
		/* create stream */
		DMUSIC_CreateDirectMusicLoaderResourceStream ((LPVOID*)&pStream);
		/* attach stream */
		IDirectMusicLoaderResourceStream_Attach (pStream, pDesc->pbMemData, pDesc->llMemLength, 0, iface);
	}
	else {
		ERR(": no way to get additional info\n");
		return DMUS_E_LOADER_FAILEDOPEN;
	}

	/* create object */
	CoCreateInstance (&pDesc->guidClass, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicObject, (LPVOID*)&pObject);

	/* *sigh*... some ms objects have lousy implementation of ParseDescriptor that clears input descriptor :( */
#ifdef NOW_WE_ARE_FREE
	/* parse descriptor: we actually use input descriptor; fields that aren't available from stream remain,
	   otherwise real info is set */
	 IDirectMusicObject_ParseDescriptor (pObject, pStream, pDesc);
#endif
	/* hmph... due to some trouble I had with certain tests, we store current position and then set it back */
	DM_STRUCT_INIT(&Desc);
	if (FAILED(IDirectMusicObject_ParseDescriptor (pObject, pStream, &Desc))) {
		ERR(": couldn't parse descriptor\n");
		return DMUS_E_LOADER_FORMATNOTSUPPORTED;
	}

	/* copy elements from parsed descriptor into input descriptor; this sets new info, overwriting if necessary,
	   but leaves info that's provided by input and not available from stream */	
	DMUSIC_CopyDescriptor (pDesc, &Desc);
	
	/* release everything */
	IDirectMusicObject_Release (pObject);
	IStream_Release (pStream);	
	
	/* sometimes it happens that twisted programs call SetObject for same object twice...
	   in such cases, native loader returns S_OK and does nothing... a sound plan */
	LIST_FOR_EACH (pEntry, This->pObjects) {
		pObjectEntry = LIST_ENTRY (pEntry, WINE_LOADER_ENTRY, entry);
		if (!memcmp (&pObjectEntry->Desc, pDesc, sizeof(DMUS_OBJECTDESC))) {
			TRACE(": exacly same entry already exists\n");
			return S_OK;
		}
	}		
	
	/* add new entry */
	TRACE(": adding alias entry with following info: \n%s\n", debugstr_DMUS_OBJECTDESC(pDesc));
	pNewEntry = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(WINE_LOADER_ENTRY));
	/* use this function instead of pure memcpy due to streams (memcpy just copies pointer), 
	   which is basically used further by app that called SetDescriptor... better safety than exception */
	DMUSIC_CopyDescriptor (&pNewEntry->Desc, pDesc);
	list_add_head (This->pObjects, &pNewEntry->entry);

	return S_OK;
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_SetSearchDirectory (LPDIRECTMUSICLOADER8 iface, REFGUID rguidClass, WCHAR* pwzPath, BOOL fClear) {
	WCHAR wszCurrentPath[MAX_PATH];
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	TRACE("(%p, %s, %s, %d)\n", This, debugstr_dmguid(rguidClass), debugstr_w(pwzPath), fClear);
	FIXME(": fClear ignored\n");
	DMUSIC_GetLoaderSettings (iface, rguidClass, wszCurrentPath, NULL);
	if (!strncmpW(wszCurrentPath, pwzPath, MAX_PATH)) {
	  return S_FALSE;
	}
	/* FIXME: check if path is valid; else return DMUS_E_LOADER_BADPATH */
	return DMUSIC_SetLoaderSettings (iface, rguidClass, pwzPath, NULL);
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_ScanDirectory (LPDIRECTMUSICLOADER8 iface, REFGUID rguidClass, WCHAR* pwzFileExtension, WCHAR* pwzScanFileName) {
	static const WCHAR wszAny[] = {'*',0};
	WIN32_FIND_DATAW FileData;
	HANDLE hSearch;
	WCHAR wszSearchString[MAX_PATH];
	WCHAR *p;
	HRESULT result;
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	TRACE("(%p, %s, %p, %p)\n", This, debugstr_dmguid(rguidClass), pwzFileExtension, pwzScanFileName);
	if (IsEqualGUID (rguidClass, &GUID_DirectMusicAllTypes) || !DMUSIC_IsValidLoadableClass(rguidClass)) {
		ERR(": rguidClass invalid CLSID\n");
		return REGDB_E_CLASSNOTREG;
	}
	
	/* get search path for given class */
	DMUSIC_GetLoaderSettings (iface, rguidClass, wszSearchString, NULL);
	
	p = wszSearchString + lstrlenW(wszSearchString);
	if (p > wszSearchString && p[-1] != '\\') *p++ = '\\';
	*p++ = '*'; /* any file */
	if (strcmpW (pwzFileExtension, wszAny)) *p++ = '.'; /* if we have actual extension, put a dot */
	strcpyW (p, pwzFileExtension);
	
	TRACE(": search string: %s\n", debugstr_w(wszSearchString));
	
	hSearch = FindFirstFileW (wszSearchString, &FileData);
	if (hSearch == INVALID_HANDLE_VALUE) {
		TRACE(": no files found\n");
		return S_FALSE;
	}
	
	do {
		DMUS_OBJECTDESC Desc;
		DM_STRUCT_INIT(&Desc);
		Desc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH | DMUS_OBJ_DATE;
		memcpy (&Desc.guidClass, rguidClass, sizeof(GUID));
		strcpyW (Desc.wszFileName, FileData.cFileName);
		FileTimeToLocalFileTime (&FileData.ftCreationTime, &Desc.ftDate);
		IDirectMusicLoader8_SetObject (iface, &Desc);
		
		if (!FindNextFileW (hSearch, &FileData)) {
			if (GetLastError () == ERROR_NO_MORE_FILES) {
				TRACE(": search completed\n");
				result = S_OK;
			} else {
				ERR(": could not get next file\n");
				result = E_FAIL;
			}
			FindClose (hSearch);
			return result;
		}
	} while (1);
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_CacheObject (LPDIRECTMUSICLOADER8 iface, IDirectMusicObject* pObject) {
	DMUS_OBJECTDESC Desc;
	HRESULT result = DMUS_E_LOADER_OBJECTNOTFOUND;
	struct list *pEntry;
	LPWINE_LOADER_ENTRY  pObjectEntry = NULL;

	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	TRACE("(%p, %p)\n", This, pObject);
	
	/* get descriptor */
	DM_STRUCT_INIT(&Desc);
	IDirectMusicObject_GetDescriptor (pObject, &Desc);
	
	/* now iterate thru list and check if we have alias (without object), corresponding
	   to descriptor of input object */
	LIST_FOR_EACH(pEntry, This->pObjects) {
		pObjectEntry = LIST_ENTRY(pEntry, WINE_LOADER_ENTRY, entry);
		if ((Desc.dwValidData & DMUS_OBJ_OBJECT) &&
			(pObjectEntry->Desc.dwValidData & DMUS_OBJ_OBJECT) &&
			IsEqualGUID (&Desc.guidObject, &pObjectEntry->Desc.guidObject)) {
			TRACE(": found it by object GUID\n");
			if ((pObjectEntry->Desc.dwValidData & DMUS_OBJ_LOADED) && pObjectEntry->pObject)
				result = S_FALSE;
			else
				result = S_OK;
			break;
		}
		else if ((Desc.dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH)) &&
				(pObjectEntry->Desc.dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH)) &&
				!strncmpW (Desc.wszFileName, pObjectEntry->Desc.wszFileName, DMUS_MAX_FILENAME)) {
			TRACE(": found it by fullpath filename\n");
			if ((pObjectEntry->Desc.dwValidData & DMUS_OBJ_LOADED) && pObjectEntry->pObject)
				result = S_FALSE;
			else
				result = S_OK;
			break;
		}
		else if ((Desc.dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY)) &&
				(pObjectEntry->Desc.dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY)) &&
				!strncmpW (Desc.wszName, pObjectEntry->Desc.wszName, DMUS_MAX_NAME) &&
				!strncmpW (Desc.wszCategory, pObjectEntry->Desc.wszCategory, DMUS_MAX_CATEGORY)) {
			TRACE(": found it by name and category\n");
			if ((pObjectEntry->Desc.dwValidData & DMUS_OBJ_LOADED) && pObjectEntry->pObject)
				result = S_FALSE;
			else
				result = S_OK;
			break;
		}
		else if ((Desc.dwValidData & DMUS_OBJ_NAME) &&
				(pObjectEntry->Desc.dwValidData & DMUS_OBJ_NAME) &&
				!strncmpW (Desc.wszName, pObjectEntry->Desc.wszName, DMUS_MAX_NAME)) {
			TRACE(": found it by name\n");
			if ((pObjectEntry->Desc.dwValidData & DMUS_OBJ_LOADED) && pObjectEntry->pObject)
				result = S_FALSE;
			else
				result = S_OK;
			break;
		}
		else if ((Desc.dwValidData & DMUS_OBJ_FILENAME) &&
				(pObjectEntry->Desc.dwValidData & DMUS_OBJ_FILENAME) &&
				!strncmpW (Desc.wszFileName, pObjectEntry->Desc.wszFileName, DMUS_MAX_FILENAME)) {
			TRACE(": found it by filename\n");				
			if ((pObjectEntry->Desc.dwValidData & DMUS_OBJ_LOADED) && pObjectEntry->pObject)
				result = S_FALSE;
			else
				result = S_OK;
			break;
		}
	}
	
	/* if we found such alias, then set everything */
	if (result == S_OK) {
		pObjectEntry->Desc.dwValidData &= DMUS_OBJ_LOADED;
		pObjectEntry->pObject = pObject;
		IDirectMusicObject_AddRef (pObjectEntry->pObject);
	}
	
	return result;
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_ReleaseObject (LPDIRECTMUSICLOADER8 iface, IDirectMusicObject* pObject) {
	DMUS_OBJECTDESC Desc;
	struct list *pEntry;
	LPWINE_LOADER_ENTRY pObjectEntry = NULL;
	HRESULT result = S_FALSE;

	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	TRACE("(%p, %p)\n", This, pObject);
	
	/* get descriptor */
	DM_STRUCT_INIT(&Desc);
	IDirectMusicObject_GetDescriptor (pObject, &Desc);
	
	/* iterate thru the list of objects we know about; check only those with DMUS_OBJ_LOADED */
	TRACE(": looking for the object in cache\n");
	LIST_FOR_EACH(pEntry, This->pObjects) {
		pObjectEntry = LIST_ENTRY(pEntry, WINE_LOADER_ENTRY, entry);
		if ((Desc.dwValidData & DMUS_OBJ_OBJECT) &&
			(pObjectEntry->Desc.dwValidData & (DMUS_OBJ_OBJECT | DMUS_OBJ_LOADED)) &&
			IsEqualGUID (&Desc.guidObject, &pObjectEntry->Desc.guidObject)) {
			TRACE(": found it by object GUID\n%s", debugstr_DMUS_OBJECTDESC(&pObjectEntry->Desc));
			result = S_OK;
			break;
		}
		else if ((Desc.dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH)) &&
				(pObjectEntry->Desc.dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH | DMUS_OBJ_LOADED)) &&
				!strncmpW (Desc.wszFileName, pObjectEntry->Desc.wszFileName, DMUS_MAX_FILENAME)) {
			TRACE(": found it by fullpath filename\n");
			result = S_OK;			
			break;
		}
		else if ((Desc.dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY)) &&
				(pObjectEntry->Desc.dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY | DMUS_OBJ_LOADED)) &&
				!strncmpW (Desc.wszName, pObjectEntry->Desc.wszName, DMUS_MAX_NAME) &&
				!strncmpW (Desc.wszCategory, pObjectEntry->Desc.wszCategory, DMUS_MAX_CATEGORY)) {
			TRACE(": found it by name and category\n");
			result = S_OK;			
			break;
		}
		else if ((Desc.dwValidData & DMUS_OBJ_NAME) &&
				(pObjectEntry->Desc.dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_LOADED)) &&
				!strncmpW (Desc.wszName, pObjectEntry->Desc.wszName, DMUS_MAX_NAME)) {
			TRACE(": found it by name\n");
			result = S_OK;
			break;
		}
		else if ((Desc.dwValidData & DMUS_OBJ_FILENAME) &&
				(pObjectEntry->Desc.dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_LOADED)) &&
				!strncmpW (Desc.wszFileName, pObjectEntry->Desc.wszFileName, DMUS_MAX_FILENAME)) {
			TRACE(": found it by filename\n");
			result = S_OK;			
			break;
		}
	}
	if (result == S_OK) {
		/*TRACE(": releasing: \n%s  - bInvalidDefaultDLS = %i\n  - pObject = %p\n", debugstr_DMUS_OBJECTDESC(&pObjectEntry->Desc), pObjectEntry->bInvalidDefaultDLS, pObjectEntry->pObject); */
		IDirectMusicObject_Release (pObjectEntry->pObject);
		pObjectEntry->pObject = NULL;
		pObjectEntry->Desc.dwValidData &= ~DMUS_OBJ_LOADED;
	} 
	return result;
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_ClearCache (LPDIRECTMUSICLOADER8 iface, REFGUID rguidClass) {
	struct list *pEntry;
	LPWINE_LOADER_ENTRY pObjectEntry;
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	TRACE("(%p, %s)\n", This, debugstr_dmguid(rguidClass));
	
	LIST_FOR_EACH (pEntry, This->pObjects) {
		pObjectEntry = LIST_ENTRY (pEntry, WINE_LOADER_ENTRY, entry);
		
		if ((IsEqualGUID (rguidClass, &GUID_DirectMusicAllTypes) || IsEqualGUID (rguidClass, &pObjectEntry->Desc.guidClass)) &&
			(pObjectEntry->Desc.dwValidData & DMUS_OBJ_LOADED)) {
			/* basically, wrap to ReleaseObject for each object found */
			IDirectMusicLoader8_ReleaseObject (iface, pObjectEntry->pObject);
		}
	}
	
	return S_OK;
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_EnableCache (LPDIRECTMUSICLOADER8 iface, REFGUID rguidClass, BOOL fEnable) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	BOOL bCurrent;
	TRACE("(%p, %s, %d)\n", This, debugstr_dmguid(rguidClass), fEnable);
	DMUSIC_GetLoaderSettings (iface, rguidClass, NULL, &bCurrent);
	if (bCurrent == fEnable)
		return S_FALSE;
	else
		return DMUSIC_SetLoaderSettings (iface, rguidClass, NULL, &fEnable);
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_EnumObject (LPDIRECTMUSICLOADER8 iface, REFGUID rguidClass, DWORD dwIndex, LPDMUS_OBJECTDESC pDesc) {
	DWORD dwCount = 0;
	struct list *pEntry;
	LPWINE_LOADER_ENTRY pObjectEntry;
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	TRACE("(%p, %s, %ld, %p)\n", This, debugstr_dmguid(rguidClass), dwIndex, pDesc);
	
	DM_STRUCT_INIT(pDesc);
	
	LIST_FOR_EACH (pEntry, This->pObjects) {
		pObjectEntry = LIST_ENTRY (pEntry, WINE_LOADER_ENTRY, entry);
			
		if (IsEqualGUID (rguidClass, &GUID_DirectMusicAllTypes) || IsEqualGUID (rguidClass, &pObjectEntry->Desc.guidClass)) {
			if (dwCount == dwIndex) {
				memcpy (pDesc, &pObjectEntry->Desc, sizeof(DMUS_OBJECTDESC));
				/* we aren't supposed to reveal this info */
				pDesc->dwValidData &= ~(DMUS_OBJ_MEMORY | DMUS_OBJ_STREAM);
				pDesc->pbMemData = NULL;
				pDesc->llMemLength = 0;
				pDesc->pStream = NULL;
				return S_OK;
			}
			dwCount++;
		}
	}
	
	TRACE(": not found\n");	
	return S_FALSE;
}

void WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_CollectGarbage (LPDIRECTMUSICLOADER8 iface) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	FIXME("(%p): stub\n", This);
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_ReleaseObjectByUnknown (LPDIRECTMUSICLOADER8 iface, IUnknown* pObject) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	HRESULT result;
	LPDIRECTMUSICOBJECT pObjectInterface;
	
	TRACE("(%p, %p)\n", This, pObject);
	
	if (IsBadReadPtr (pObject, sizeof(LPUNKNOWN))) {
		ERR(": pObject bad write pointer\n");
		return E_POINTER;
	}
	/* we simply get IDirectMusicObject interface */
	result = IUnknown_QueryInterface (pObject, &IID_IDirectMusicObject, (LPVOID*)&pObjectInterface);
	if (FAILED(result)) return result;
	/* and release it in old-fashioned way */
	result = IDirectMusicLoader8_ReleaseObject (iface, pObjectInterface);
	IDirectMusicObject_Release (pObjectInterface);
	
	return result;
}

HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_LoadObjectFromFile (LPDIRECTMUSICLOADER8 iface, REFGUID rguidClassID, REFIID iidInterfaceID, WCHAR* pwzFilePath, void** ppObject) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	DMUS_OBJECTDESC ObjDesc;
	WCHAR wszLoaderSearchPath[MAX_PATH];
	
	TRACE("(%p, %s, %s, %s, %p): wrapping to IDirectMusicLoaderImpl_GetObject\n", This, debugstr_dmguid(rguidClassID), debugstr_dmguid(iidInterfaceID), debugstr_w(pwzFilePath), ppObject);
	
	DM_STRUCT_INIT(&ObjDesc);	
	ObjDesc.dwValidData = DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH | DMUS_OBJ_CLASS; /* I believe I've read somewhere in MSDN that this function requires either full path or relative path */
	memcpy (&ObjDesc.guidClass, rguidClassID, sizeof(CLSID));
	/* OK, MSDN says that search order is the following:
	    - current directory (DONE)
	    - windows search path (FIXME: how do I get that?)
	    - loader's search path (DONE)
	*/
	DMUSIC_GetLoaderSettings (iface, rguidClassID, wszLoaderSearchPath, NULL);
    /* search in current directory */
	if (!SearchPathW (NULL, pwzFilePath, NULL, sizeof(ObjDesc.wszFileName)/sizeof(WCHAR), ObjDesc.wszFileName, NULL) &&
	/* search in loader's search path */
		!SearchPathW (wszLoaderSearchPath, pwzFilePath, NULL, sizeof(ObjDesc.wszFileName)/sizeof(WCHAR), ObjDesc.wszFileName, NULL)) {
		/* cannot find file */
		TRACE(": cannot find file\n");
		return DMUS_E_LOADER_FAILEDOPEN;
	}
	
	TRACE(": full file path = %s\n", debugstr_w (ObjDesc.wszFileName));
	
	return IDirectMusicLoaderImpl_IDirectMusicLoader_GetObject (iface, &ObjDesc, iidInterfaceID, ppObject);
}

static const IDirectMusicLoader8Vtbl DirectMusicLoader_Loader_Vtbl = {
	IDirectMusicLoaderImpl_IDirectMusicLoader_QueryInterface,
	IDirectMusicLoaderImpl_IDirectMusicLoader_AddRef,
	IDirectMusicLoaderImpl_IDirectMusicLoader_Release,
	IDirectMusicLoaderImpl_IDirectMusicLoader_GetObject,
	IDirectMusicLoaderImpl_IDirectMusicLoader_SetObject,
	IDirectMusicLoaderImpl_IDirectMusicLoader_SetSearchDirectory,
	IDirectMusicLoaderImpl_IDirectMusicLoader_ScanDirectory,
	IDirectMusicLoaderImpl_IDirectMusicLoader_CacheObject,
	IDirectMusicLoaderImpl_IDirectMusicLoader_ReleaseObject,
	IDirectMusicLoaderImpl_IDirectMusicLoader_ClearCache,
	IDirectMusicLoaderImpl_IDirectMusicLoader_EnableCache,
	IDirectMusicLoaderImpl_IDirectMusicLoader_EnumObject,
	IDirectMusicLoaderImpl_IDirectMusicLoader_CollectGarbage,
	IDirectMusicLoaderImpl_IDirectMusicLoader_ReleaseObjectByUnknown,
	IDirectMusicLoaderImpl_IDirectMusicLoader_LoadObjectFromFile
};

/* for ClassFactory */
HRESULT WINAPI DMUSIC_CreateDirectMusicLoaderImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter) {
	IDirectMusicLoaderImpl *obj;
	DMUS_OBJECTDESC Desc;
	LPWINE_LOADER_ENTRY pDefaultDLSEntry;
	struct list *pEntry;

	TRACE("(%s, %p, %p)\n", debugstr_dmguid(lpcGUID), ppobj, pUnkOuter);
	obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicLoaderImpl));
	if (NULL == obj) {
		*ppobj = (LPDIRECTMUSICLOADER8)NULL;
		return E_OUTOFMEMORY;
	}
	obj->LoaderVtbl = &DirectMusicLoader_Loader_Vtbl;
	obj->dwRef = 0; /* will be inited with QueryInterface */
	/* init critical section */
	/* init cache/alias list */
	/*InitializeCriticalSection (&obj->CritSect); */
	obj->pObjects = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(struct list));
	list_init (obj->pObjects);
	/* init settings */
	obj->pClassSettings = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(struct list));
	list_init (obj->pClassSettings);
	DMUSIC_InitLoaderSettings ((LPDIRECTMUSICLOADER8)obj);

	/* set default DLS collection (via SetObject... so that loading via DMUS_OBJ_OBJECT is possible) */
	DM_STRUCT_INIT(&Desc);
	Desc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH | DMUS_OBJ_OBJECT;
	memcpy (&Desc.guidClass, &CLSID_DirectMusicCollection, sizeof(CLSID));
	memcpy (&Desc.guidObject, &GUID_DefaultGMCollection, sizeof(GUID));
	DMUSIC_GetDefaultGMPath (Desc.wszFileName);
	IDirectMusicLoader_SetObject ((LPDIRECTMUSICLOADER8)obj, &Desc);
	/* and now the workaroundTM for "invalid" default DLS; basically, 
	   my tests showed that if GUID chunk is present in default DLS 
	   collection, loader treats it as "invalid" and returns 
	   DMUS_E_LOADER_NOFILENAME for all requests for it; basically, we check 
	   if out input guidObject was overwritten */
	pEntry = list_head (obj->pObjects);
	pDefaultDLSEntry = LIST_ENTRY (pEntry, WINE_LOADER_ENTRY, entry);
	if (!IsEqualGUID(&Desc.guidObject, &GUID_DefaultGMCollection)) {
		pDefaultDLSEntry->bInvalidDefaultDLS = TRUE;
	}

	/* increase number of instances */
	InterlockedIncrement (&dwDirectMusicLoader);
	
	return IDirectMusicLoaderImpl_IDirectMusicLoader_QueryInterface ((LPDIRECTMUSICLOADER8)obj, lpcGUID, ppobj);
}

HRESULT WINAPI DMUSIC_DestroyDirectMusicLoaderImpl (LPDIRECTMUSICLOADER8 iface) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);

	TRACE("(%p)\n", This);
	
	/* firstly, release the cache */
	IDirectMusicLoader8_ClearCache (iface, &GUID_DirectMusicAllTypes);
	/* FIXME: release all allocated entries */
	/* destroy critical section */
	/*DeleteCriticalSection (&This->CritSect); */
	
	/* decrease number of instances */
	InterlockedDecrement (&dwDirectMusicLoader);
	
	return S_OK;
}

/* help function for DMUSIC_SetDefaultDLS */
HRESULT WINAPI DMUSIC_GetDefaultGMPath (WCHAR wszPath[MAX_PATH]) {
	HKEY hkDM;
	DWORD returnType, sizeOfReturnBuffer = MAX_PATH;
	char szPath[MAX_PATH];

	if ((RegOpenKeyExA (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\DirectMusic" , 0, KEY_READ, &hkDM) != ERROR_SUCCESS) || 
	    (RegQueryValueExA (hkDM, "GMFilePath", NULL, &returnType, (LPBYTE) szPath, &sizeOfReturnBuffer) != ERROR_SUCCESS)) {
		WARN(": registry entry missing\n" );
		return E_FAIL;
	}
	/* FIXME: Check return types to ensure we're interpreting data right */
	MultiByteToWideChar (CP_ACP, 0, szPath, -1, wszPath, MAX_PATH);
	
	return S_OK;
}

/* help function for retrieval of search path and caching option for certain class */
HRESULT WINAPI DMUSIC_GetLoaderSettings (LPDIRECTMUSICLOADER8 iface, REFGUID pClassID, WCHAR* wszSearchPath, LPBOOL pbCache) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	struct list *pEntry;
	TRACE(": (%p, %s, %p, %p)\n", This, debugstr_dmguid(pClassID), wszSearchPath, pbCache);
	
	LIST_FOR_EACH(pEntry, This->pClassSettings) {
		LPWINE_LOADER_OPTION pOptionEntry = LIST_ENTRY(pEntry, WINE_LOADER_OPTION, entry);
		if (IsEqualCLSID (pClassID, &pOptionEntry->guidClass)) {
			if (wszSearchPath)
				strcpyW(wszSearchPath, pOptionEntry->wszSearchPath);
			if (pbCache)
				*pbCache = pOptionEntry->bCache;
			return S_OK;
		}
	}
	return S_FALSE;
}

/* help function for setting search path and caching option for certain class */
HRESULT WINAPI DMUSIC_SetLoaderSettings (LPDIRECTMUSICLOADER8 iface, REFGUID pClassID, WCHAR* wszSearchPath, LPBOOL pbCache) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	struct list *pEntry;
	HRESULT result = S_FALSE; /* in case pClassID != GUID_DirectMusicAllTypes and not a valid CLSID */
	TRACE(": (%p, %s, %p, %p)\n", This, debugstr_dmguid(pClassID), wszSearchPath, pbCache);
	
	LIST_FOR_EACH(pEntry, This->pClassSettings) {
		LPWINE_LOADER_OPTION pOptionEntry = LIST_ENTRY(pEntry, WINE_LOADER_OPTION, entry);
		/* well, either we have GUID_DirectMusicAllTypes and need to set it to all,
		   or specific CLSID is given and we set it only to it */
		if (IsEqualGUID (pClassID, &GUID_DirectMusicAllTypes) ||
			IsEqualCLSID (pClassID, &pOptionEntry->guidClass)) {
			if (wszSearchPath)
				strcpyW(pOptionEntry->wszSearchPath, wszSearchPath);
			if (pbCache)
				pOptionEntry->bCache = *pbCache;
			result = S_OK;
		}
	}

	return result;
}

HRESULT WINAPI DMUSIC_InitLoaderSettings (LPDIRECTMUSICLOADER8 iface) {
	ICOM_THIS_MULTI(IDirectMusicLoaderImpl, LoaderVtbl, iface);
	
	/* hard-coded list of classes */
	static REFCLSID classes[] = {
		&CLSID_DirectMusicAudioPathConfig,
		&CLSID_DirectMusicBand,
		&CLSID_DirectMusicContainer,
		&CLSID_DirectMusicCollection,
		&CLSID_DirectMusicChordMap,
		&CLSID_DirectMusicSegment,
		&CLSID_DirectMusicScript,
		&CLSID_DirectMusicSong,
		&CLSID_DirectMusicStyle,
		&CLSID_DirectMusicGraph,
		&CLSID_DirectSoundWave
	};
	
	unsigned int i;
	WCHAR wszCurrent[MAX_PATH];

	TRACE(": (%p)\n", This);
	GetCurrentDirectoryW (MAX_PATH, wszCurrent);
	
	for (i = 0; i < sizeof(classes)/sizeof(REFCLSID); i++) {
		LPWINE_LOADER_OPTION pNewSetting = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(WINE_LOADER_OPTION));
		memcpy (&pNewSetting->guidClass, classes[i], sizeof(CLSID));
		strcpyW (pNewSetting->wszSearchPath, wszCurrent);
		pNewSetting->bCache = TRUE;
		list_add_tail (This->pClassSettings, &pNewSetting->entry);
	}

	return S_OK;
}

HRESULT WINAPI DMUSIC_CopyDescriptor (LPDMUS_OBJECTDESC pDst, LPDMUS_OBJECTDESC pSrc) {
	TRACE(": copy \n%s", debugstr_DMUS_OBJECTDESC(pSrc));
	/* copy field by field */
	if (pSrc->dwValidData & DMUS_OBJ_CLASS) memcpy (&pDst->guidClass, &pSrc->guidClass, sizeof(CLSID));
	if (pSrc->dwValidData & DMUS_OBJ_OBJECT) memcpy (&pDst->guidObject, &pSrc->guidObject, sizeof(GUID));
	if (pSrc->dwValidData & DMUS_OBJ_DATE) memcpy (&pDst->ftDate, &pSrc->ftDate, sizeof(FILETIME));
	if (pSrc->dwValidData & DMUS_OBJ_VERSION) memcpy (&pDst->vVersion, &pSrc->vVersion, sizeof(DMUS_VERSION));
	if (pSrc->dwValidData & DMUS_OBJ_NAME) strcpyW (pDst->wszName, pSrc->wszName);
	if (pSrc->dwValidData & DMUS_OBJ_CATEGORY) strcpyW (pDst->wszCategory, pSrc->wszCategory);
	if (pSrc->dwValidData & DMUS_OBJ_FILENAME) strcpyW (pDst->wszFileName, pSrc->wszFileName);
	if (pSrc->dwValidData & DMUS_OBJ_STREAM) IStream_Clone (pSrc->pStream, &pDst->pStream);
	if (pSrc->dwValidData & DMUS_OBJ_MEMORY) {
		pDst->pbMemData = pSrc->pbMemData;
		pDst->llMemLength = pSrc->llMemLength;
	}
	/* set flags */
	pDst->dwValidData |= pSrc->dwValidData;
	return S_OK;
}

BOOL WINAPI DMUSIC_IsValidLoadableClass (REFCLSID pClassID) {
	if (IsEqualCLSID(pClassID, &CLSID_DirectMusicAudioPathConfig) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicBand) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicContainer) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicCollection) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicChordMap) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicSegment) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicScript) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicSong) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicStyle) ||
		IsEqualCLSID(pClassID, &CLSID_DirectMusicGraph) ||
		IsEqualCLSID(pClassID, &CLSID_DirectSoundWave) ||
		IsEqualCLSID(pClassID, &GUID_DirectMusicAllTypes))
		return TRUE;
	else
		return FALSE;
}
