user32: Remove side effect code out of asserts() (Coverity).
[wine] / dlls / dmcompos / dmcompos_main.c
1 /* DirectMusicComposer Main
2  *
3  * Copyright (C) 2003-2004 Rok Mandeljc
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include "config.h"
21 #include "wine/port.h"
22
23 #include "dmcompos_private.h"
24 #include "rpcproxy.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(dmcompos);
27
28 static HINSTANCE instance;
29 LONG DMCOMPOS_refCount = 0;
30
31 typedef struct {
32     const IClassFactoryVtbl *lpVtbl;
33 } IClassFactoryImpl;
34
35 /******************************************************************
36  *              DirectMusicChordMap ClassFactory
37  */
38 static HRESULT WINAPI ChordMapCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
39         FIXME("- no interface IID: %s\n", debugstr_guid(riid));
40
41         if (ppobj == NULL) return E_POINTER;
42         
43         return E_NOINTERFACE;
44 }
45
46 static ULONG WINAPI ChordMapCF_AddRef(LPCLASSFACTORY iface) {
47         DMCOMPOS_LockModule();
48         
49         return 2; /* non-heap based object */
50 }
51
52 static ULONG WINAPI ChordMapCF_Release(LPCLASSFACTORY iface) {
53         DMCOMPOS_UnlockModule();
54         
55         return 1; /* non-heap based object */
56 }
57
58 static HRESULT WINAPI ChordMapCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
59         TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
60         
61         return DMUSIC_CreateDirectMusicChordMapImpl (riid, ppobj, pOuter);
62 }
63
64 static HRESULT WINAPI ChordMapCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
65         TRACE("(%d)\n", dolock);
66         
67         if (dolock)
68                 DMCOMPOS_LockModule();
69         else
70                 DMCOMPOS_UnlockModule();
71
72         return S_OK;
73 }
74
75 static const IClassFactoryVtbl ChordMapCF_Vtbl = {
76         ChordMapCF_QueryInterface,
77         ChordMapCF_AddRef,
78         ChordMapCF_Release,
79         ChordMapCF_CreateInstance,
80         ChordMapCF_LockServer
81 };
82
83 static IClassFactoryImpl ChordMap_CF = {&ChordMapCF_Vtbl};
84
85 /******************************************************************
86  *              DirectMusicComposer ClassFactory
87  */
88 static HRESULT WINAPI ComposerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
89         FIXME("- no interface IID: %s\n", debugstr_guid(riid));
90
91         if (ppobj == NULL) return E_POINTER;
92         
93         return E_NOINTERFACE;
94 }
95
96 static ULONG WINAPI ComposerCF_AddRef(LPCLASSFACTORY iface) {
97         DMCOMPOS_LockModule();
98         
99         return 2; /* non-heap based object */
100 }
101
102 static ULONG WINAPI ComposerCF_Release(LPCLASSFACTORY iface) {
103         DMCOMPOS_UnlockModule();
104         
105         return 1; /* non-heap based object */
106 }
107
108 static HRESULT WINAPI ComposerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
109         TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
110         
111         return DMUSIC_CreateDirectMusicComposerImpl (riid, ppobj, pOuter);
112 }
113
114 static HRESULT WINAPI ComposerCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
115         TRACE("(%d)\n", dolock);
116         
117         if (dolock)
118                 DMCOMPOS_LockModule();
119         else
120                 DMCOMPOS_UnlockModule();
121
122         return S_OK;
123 }
124
125 static const IClassFactoryVtbl ComposerCF_Vtbl = {
126         ComposerCF_QueryInterface,
127         ComposerCF_AddRef,
128         ComposerCF_Release,
129         ComposerCF_CreateInstance,
130         ComposerCF_LockServer
131 };
132
133 static IClassFactoryImpl Composer_CF = {&ComposerCF_Vtbl};
134
135 /******************************************************************
136  *              DirectMusicChordMapTrack ClassFactory
137  */
138 static HRESULT WINAPI ChordMapTrackCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
139         FIXME("- no interface IID: %s\n", debugstr_guid(riid));
140
141         if (ppobj == NULL) return E_POINTER;
142         
143         return E_NOINTERFACE;
144 }
145
146 static ULONG WINAPI ChordMapTrackCF_AddRef(LPCLASSFACTORY iface) {
147         DMCOMPOS_LockModule();
148         
149         return 2; /* non-heap based object */
150 }
151
152 static ULONG WINAPI ChordMapTrackCF_Release(LPCLASSFACTORY iface) {
153         DMCOMPOS_UnlockModule();
154         
155         return 1; /* non-heap based object */
156 }
157
158 static HRESULT WINAPI ChordMapTrackCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
159         TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
160         
161         return DMUSIC_CreateDirectMusicChordMapTrack (riid, ppobj, pOuter);
162 }
163
164 static HRESULT WINAPI ChordMapTrackCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
165         TRACE("(%d)\n", dolock);
166         
167         if (dolock)
168                 DMCOMPOS_LockModule();
169         else
170                 DMCOMPOS_UnlockModule();
171
172         return S_OK;
173 }
174
175 static const IClassFactoryVtbl ChordMapTrackCF_Vtbl = {
176         ChordMapTrackCF_QueryInterface,
177         ChordMapTrackCF_AddRef,
178         ChordMapTrackCF_Release,
179         ChordMapTrackCF_CreateInstance,
180         ChordMapTrackCF_LockServer
181 };
182
183 static IClassFactoryImpl ChordMapTrack_CF = {&ChordMapTrackCF_Vtbl};
184
185 /******************************************************************
186  *              DirectMusicTemplate ClassFactory
187  */
188 static HRESULT WINAPI TemplateCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
189         FIXME("- no interface IID: %s\n", debugstr_guid(riid));
190
191         if (ppobj == NULL) return E_POINTER;
192         
193         return E_NOINTERFACE;
194 }
195
196 static ULONG WINAPI TemplateCF_AddRef(LPCLASSFACTORY iface) {
197         DMCOMPOS_LockModule();
198         
199         return 2; /* non-heap based object */
200 }
201
202 static ULONG WINAPI TemplateCF_Release(LPCLASSFACTORY iface) {
203         DMCOMPOS_UnlockModule();
204         
205         return 1; /* non-heap based object */
206 }
207
208 static HRESULT WINAPI TemplateCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
209         TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
210         /* nothing yet */
211         WARN("(%s,%p): not found\n", debugstr_dmguid(riid), ppobj);
212         
213         return E_NOINTERFACE;
214 }
215
216 static HRESULT WINAPI TemplateCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
217         TRACE("(%d)\n", dolock);
218         
219         if (dolock)
220                 DMCOMPOS_LockModule();
221         else
222                 DMCOMPOS_UnlockModule();
223
224         return S_OK;
225 }
226
227 static const IClassFactoryVtbl TemplateCF_Vtbl = {
228         TemplateCF_QueryInterface,
229         TemplateCF_AddRef,
230         TemplateCF_Release,
231         TemplateCF_CreateInstance,
232         TemplateCF_LockServer
233 };
234
235 static IClassFactoryImpl Template_CF = {&TemplateCF_Vtbl};
236
237 /******************************************************************
238  *              DirectMusicSignPostTrack ClassFactory
239  */
240 static HRESULT WINAPI SignPostTrackCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
241         FIXME("- no interface IID: %s\n", debugstr_guid(riid));
242
243         if (ppobj == NULL) return E_POINTER;
244         
245         return E_NOINTERFACE;
246 }
247
248 static ULONG WINAPI SignPostTrackCF_AddRef(LPCLASSFACTORY iface) {
249         DMCOMPOS_LockModule();
250         
251         return 2; /* non-heap based object */
252 }
253
254 static ULONG WINAPI SignPostTrackCF_Release(LPCLASSFACTORY iface) {
255         DMCOMPOS_UnlockModule();
256         
257         return 1; /* non-heap based object */
258 }
259
260 static HRESULT WINAPI SignPostTrackCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
261         TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
262         
263         return DMUSIC_CreateDirectMusicSignPostTrack (riid, ppobj, pOuter);
264 }
265
266 static HRESULT WINAPI SignPostTrackCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
267         TRACE("(%d)\n", dolock);
268         
269         if (dolock)
270                 DMCOMPOS_LockModule();
271         else
272                 DMCOMPOS_UnlockModule();
273
274         return S_OK;
275 }
276
277 static const IClassFactoryVtbl SignPostTrackCF_Vtbl = {
278         SignPostTrackCF_QueryInterface,
279         SignPostTrackCF_AddRef,
280         SignPostTrackCF_Release,
281         SignPostTrackCF_CreateInstance,
282         SignPostTrackCF_LockServer
283 };
284
285 static IClassFactoryImpl SignPostTrack_CF = {&SignPostTrackCF_Vtbl};
286
287 /******************************************************************
288  *              DllMain
289  *
290  *
291  */
292 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
293         if (fdwReason == DLL_PROCESS_ATTACH)    {
294             instance = hinstDLL;
295             DisableThreadLibraryCalls(hinstDLL);
296                 /* FIXME: Initialisation */
297         }
298         else if (fdwReason == DLL_PROCESS_DETACH)       {
299                 /* FIXME: Cleanup */
300         }
301
302         return TRUE;
303 }
304
305
306 /******************************************************************
307  *              DllCanUnloadNow (DMCOMPOS.@)
308  *
309  *
310  */
311 HRESULT WINAPI DllCanUnloadNow(void) {
312     return DMCOMPOS_refCount != 0 ? S_FALSE : S_OK;
313 }
314
315
316 /******************************************************************
317  *              DllGetClassObject (DMCOMPOS.@)
318  *
319  *
320  */
321 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) {
322     TRACE("(%s, %s, %p)\n", debugstr_dmguid(rclsid), debugstr_dmguid(riid), ppv);
323     if (IsEqualCLSID (rclsid, &CLSID_DirectMusicChordMap) && IsEqualIID (riid, &IID_IClassFactory)) {
324                 *ppv = &ChordMap_CF;
325                 IClassFactory_AddRef((IClassFactory*)*ppv);
326                 return S_OK;
327         } else if (IsEqualCLSID (rclsid, &CLSID_DirectMusicComposer) && IsEqualIID (riid, &IID_IClassFactory)) { 
328                 *ppv = &Composer_CF;
329                 IClassFactory_AddRef((IClassFactory*)*ppv);             
330                 return S_OK;
331         } else if (IsEqualCLSID (rclsid, &CLSID_DirectMusicChordMapTrack) && IsEqualIID (riid, &IID_IClassFactory)) {
332                 *ppv = &ChordMapTrack_CF;
333                 IClassFactory_AddRef((IClassFactory*)*ppv);             
334                 return S_OK;
335         } else if (IsEqualCLSID (rclsid, &CLSID_DirectMusicTemplate) && IsEqualIID (riid, &IID_IClassFactory)) {
336                 *ppv = &Template_CF;
337                 IClassFactory_AddRef((IClassFactory*)*ppv);             
338                 return S_OK;
339         } else if (IsEqualCLSID (rclsid, &CLSID_DirectMusicSignPostTrack) && IsEqualIID (riid, &IID_IClassFactory)) {
340                 *ppv = &SignPostTrack_CF;
341                 IClassFactory_AddRef((IClassFactory*)*ppv);             
342                 return S_OK;
343         }
344
345     WARN("(%s, %s, %p): no interface found.\n", debugstr_dmguid(rclsid), debugstr_dmguid(riid), ppv);
346     return CLASS_E_CLASSNOTAVAILABLE;
347 }
348
349 /***********************************************************************
350  *              DllRegisterServer (DMCOMPOS.@)
351  */
352 HRESULT WINAPI DllRegisterServer(void)
353 {
354     return __wine_register_resources( instance, NULL );
355 }
356
357 /***********************************************************************
358  *              DllUnregisterServer (DMCOMPOS.@)
359  */
360 HRESULT WINAPI DllUnregisterServer(void)
361 {
362     return __wine_unregister_resources( instance, NULL );
363 }
364
365 /******************************************************************
366  *              Helper functions
367  *
368  *
369  */
370 /* FOURCC to string conversion for debug messages */
371 const char *debugstr_fourcc (DWORD fourcc) {
372     if (!fourcc) return "'null'";
373     return wine_dbg_sprintf ("\'%c%c%c%c\'",
374                 (char)(fourcc), (char)(fourcc >> 8),
375         (char)(fourcc >> 16), (char)(fourcc >> 24));
376 }
377
378 /* DMUS_VERSION struct to string conversion for debug messages */
379 static const char *debugstr_dmversion (const DMUS_VERSION *version) {
380         if (!version) return "'null'";
381         return wine_dbg_sprintf ("\'%i,%i,%i,%i\'",
382                 (int)((version->dwVersionMS & 0xFFFF0000) >> 8), (int)(version->dwVersionMS & 0x0000FFFF), 
383                 (int)((version->dwVersionLS & 0xFFFF0000) >> 8), (int)(version->dwVersionLS & 0x0000FFFF));
384 }
385
386 /* returns name of given GUID */
387 const char *debugstr_dmguid (const GUID *id) {
388         static const guid_info guids[] = {
389                 /* CLSIDs */
390                 GE(CLSID_AudioVBScript),
391                 GE(CLSID_DirectMusic),
392                 GE(CLSID_DirectMusicAudioPath),
393                 GE(CLSID_DirectMusicAudioPathConfig),
394                 GE(CLSID_DirectMusicAuditionTrack),
395                 GE(CLSID_DirectMusicBand),
396                 GE(CLSID_DirectMusicBandTrack),
397                 GE(CLSID_DirectMusicChordMapTrack),
398                 GE(CLSID_DirectMusicChordMap),
399                 GE(CLSID_DirectMusicChordTrack),
400                 GE(CLSID_DirectMusicCollection),
401                 GE(CLSID_DirectMusicCommandTrack),
402                 GE(CLSID_DirectMusicComposer),
403                 GE(CLSID_DirectMusicContainer),
404                 GE(CLSID_DirectMusicGraph),
405                 GE(CLSID_DirectMusicLoader),
406                 GE(CLSID_DirectMusicLyricsTrack),
407                 GE(CLSID_DirectMusicMarkerTrack),
408                 GE(CLSID_DirectMusicMelodyFormulationTrack),
409                 GE(CLSID_DirectMusicMotifTrack),
410                 GE(CLSID_DirectMusicMuteTrack),
411                 GE(CLSID_DirectMusicParamControlTrack),
412                 GE(CLSID_DirectMusicPatternTrack),
413                 GE(CLSID_DirectMusicPerformance),
414                 GE(CLSID_DirectMusicScript),
415                 GE(CLSID_DirectMusicScriptAutoImpSegment),
416                 GE(CLSID_DirectMusicScriptAutoImpPerformance),
417                 GE(CLSID_DirectMusicScriptAutoImpSegmentState),
418                 GE(CLSID_DirectMusicScriptAutoImpAudioPathConfig),
419                 GE(CLSID_DirectMusicScriptAutoImpAudioPath),
420                 GE(CLSID_DirectMusicScriptAutoImpSong),
421                 GE(CLSID_DirectMusicScriptSourceCodeLoader),
422                 GE(CLSID_DirectMusicScriptTrack),
423                 GE(CLSID_DirectMusicSection),
424                 GE(CLSID_DirectMusicSegment),
425                 GE(CLSID_DirectMusicSegmentState),
426                 GE(CLSID_DirectMusicSegmentTriggerTrack),
427                 GE(CLSID_DirectMusicSegTriggerTrack),
428                 GE(CLSID_DirectMusicSeqTrack),
429                 GE(CLSID_DirectMusicSignPostTrack),
430                 GE(CLSID_DirectMusicSong),
431                 GE(CLSID_DirectMusicStyle),
432                 GE(CLSID_DirectMusicStyleTrack),
433                 GE(CLSID_DirectMusicSynth),
434                 GE(CLSID_DirectMusicSynthSink),
435                 GE(CLSID_DirectMusicSysExTrack),
436                 GE(CLSID_DirectMusicTemplate),
437                 GE(CLSID_DirectMusicTempoTrack),
438                 GE(CLSID_DirectMusicTimeSigTrack),
439                 GE(CLSID_DirectMusicWaveTrack),
440                 GE(CLSID_DirectSoundWave),
441                 /* IIDs */
442                 GE(IID_IDirectMusic),
443                 GE(IID_IDirectMusic2),
444                 GE(IID_IDirectMusic8),
445                 GE(IID_IDirectMusicAudioPath),
446                 GE(IID_IDirectMusicBand),
447                 GE(IID_IDirectMusicBuffer),
448                 GE(IID_IDirectMusicChordMap),
449                 GE(IID_IDirectMusicCollection),
450                 GE(IID_IDirectMusicComposer),
451                 GE(IID_IDirectMusicContainer),
452                 GE(IID_IDirectMusicDownload),
453                 GE(IID_IDirectMusicDownloadedInstrument),
454                 GE(IID_IDirectMusicGetLoader),
455                 GE(IID_IDirectMusicGraph),
456                 GE(IID_IDirectMusicInstrument),
457                 GE(IID_IDirectMusicLoader),
458                 GE(IID_IDirectMusicLoader8),
459                 GE(IID_IDirectMusicObject),
460                 GE(IID_IDirectMusicPatternTrack),
461                 GE(IID_IDirectMusicPerformance),
462                 GE(IID_IDirectMusicPerformance2),
463                 GE(IID_IDirectMusicPerformance8),
464                 GE(IID_IDirectMusicPort),
465                 GE(IID_IDirectMusicPortDownload),
466                 GE(IID_IDirectMusicScript),
467                 GE(IID_IDirectMusicSegment),
468                 GE(IID_IDirectMusicSegment2),
469                 GE(IID_IDirectMusicSegment8),
470                 GE(IID_IDirectMusicSegmentState),
471                 GE(IID_IDirectMusicSegmentState8),
472                 GE(IID_IDirectMusicStyle),
473                 GE(IID_IDirectMusicStyle8),
474                 GE(IID_IDirectMusicSynth),
475                 GE(IID_IDirectMusicSynth8),
476                 GE(IID_IDirectMusicSynthSink),
477                 GE(IID_IDirectMusicThru),
478                 GE(IID_IDirectMusicTool),
479                 GE(IID_IDirectMusicTool8),
480                 GE(IID_IDirectMusicTrack),
481                 GE(IID_IDirectMusicTrack8),
482                 GE(IID_IUnknown),
483                 GE(IID_IPersistStream),
484                 GE(IID_IStream),
485                 GE(IID_IClassFactory),
486                 /* GUIDs */
487                 GE(GUID_DirectMusicAllTypes),
488                 GE(GUID_NOTIFICATION_CHORD),
489                 GE(GUID_NOTIFICATION_COMMAND),
490                 GE(GUID_NOTIFICATION_MEASUREANDBEAT),
491                 GE(GUID_NOTIFICATION_PERFORMANCE),
492                 GE(GUID_NOTIFICATION_RECOMPOSE),
493                 GE(GUID_NOTIFICATION_SEGMENT),
494                 GE(GUID_BandParam),
495                 GE(GUID_ChordParam),
496                 GE(GUID_CommandParam),
497                 GE(GUID_CommandParam2),
498                 GE(GUID_CommandParamNext),
499                 GE(GUID_IDirectMusicBand),
500                 GE(GUID_IDirectMusicChordMap),
501                 GE(GUID_IDirectMusicStyle),
502                 GE(GUID_MuteParam),
503                 GE(GUID_Play_Marker),
504                 GE(GUID_RhythmParam),
505                 GE(GUID_TempoParam),
506                 GE(GUID_TimeSignature),
507                 GE(GUID_Valid_Start_Time),
508                 GE(GUID_Clear_All_Bands),
509                 GE(GUID_ConnectToDLSCollection),
510                 GE(GUID_Disable_Auto_Download),
511                 GE(GUID_DisableTempo),
512                 GE(GUID_DisableTimeSig),
513                 GE(GUID_Download),
514                 GE(GUID_DownloadToAudioPath),
515                 GE(GUID_Enable_Auto_Download),
516                 GE(GUID_EnableTempo),
517                 GE(GUID_EnableTimeSig),
518                 GE(GUID_IgnoreBankSelectForGM),
519                 GE(GUID_SeedVariations),
520                 GE(GUID_StandardMIDIFile),
521                 GE(GUID_Unload),
522                 GE(GUID_UnloadFromAudioPath),
523                 GE(GUID_Variations),
524                 GE(GUID_PerfMasterTempo),
525                 GE(GUID_PerfMasterVolume),
526                 GE(GUID_PerfMasterGrooveLevel),
527                 GE(GUID_PerfAutoDownload),
528                 GE(GUID_DefaultGMCollection),
529                 GE(GUID_Synth_Default),
530                 GE(GUID_Buffer_Reverb),
531                 GE(GUID_Buffer_EnvReverb),
532                 GE(GUID_Buffer_Stereo),
533                 GE(GUID_Buffer_3D_Dry),
534                 GE(GUID_Buffer_Mono),
535                 GE(GUID_DMUS_PROP_GM_Hardware),
536                 GE(GUID_DMUS_PROP_GS_Capable),
537                 GE(GUID_DMUS_PROP_GS_Hardware),
538                 GE(GUID_DMUS_PROP_DLS1),
539                 GE(GUID_DMUS_PROP_DLS2),
540                 GE(GUID_DMUS_PROP_Effects),
541                 GE(GUID_DMUS_PROP_INSTRUMENT2),
542                 GE(GUID_DMUS_PROP_LegacyCaps),
543                 GE(GUID_DMUS_PROP_MemorySize),
544                 GE(GUID_DMUS_PROP_SampleMemorySize),
545                 GE(GUID_DMUS_PROP_SamplePlaybackRate),
546                 GE(GUID_DMUS_PROP_SetSynthSink),
547                 GE(GUID_DMUS_PROP_SinkUsesDSound),
548                 GE(GUID_DMUS_PROP_SynthSink_DSOUND),
549                 GE(GUID_DMUS_PROP_SynthSink_WAVE),
550                 GE(GUID_DMUS_PROP_Volume),
551                 GE(GUID_DMUS_PROP_WavesReverb),
552                 GE(GUID_DMUS_PROP_WriteLatency),
553                 GE(GUID_DMUS_PROP_WritePeriod),
554                 GE(GUID_DMUS_PROP_XG_Capable),
555                 GE(GUID_DMUS_PROP_XG_Hardware)
556         };
557
558         unsigned int i;
559
560         if (!id) return "(null)";
561
562         for (i = 0; i < sizeof(guids)/sizeof(guids[0]); i++) {
563                 if (IsEqualGUID(id, guids[i].guid))
564                         return guids[i].name;
565         }
566         /* if we didn't find it, act like standard debugstr_guid */     
567         return debugstr_guid(id);
568 }       
569
570 /* generic flag-dumping function */
571 static const char* debugstr_flags (DWORD flags, const flag_info* names, size_t num_names){
572         char buffer[128] = "", *ptr = &buffer[0];
573         unsigned int i;
574         int size = sizeof(buffer);
575         
576         for (i=0; i < num_names; i++)
577         {
578                 if ((flags & names[i].val) ||   /* standard flag*/
579                         ((!flags) && (!names[i].val))) { /* zero value only */
580                                 int cnt = snprintf(ptr, size, "%s ", names[i].name);
581                                 if (cnt < 0 || cnt >= size) break;
582                                 size -= cnt;
583                                 ptr += cnt;
584                 }
585         }
586         
587         return wine_dbg_sprintf("%s", buffer);
588 }
589
590 /* dump DMUS_OBJ flags */
591 static const char *debugstr_DMUS_OBJ_FLAGS (DWORD flagmask) {
592     static const flag_info flags[] = {
593             FE(DMUS_OBJ_OBJECT),
594             FE(DMUS_OBJ_CLASS),
595             FE(DMUS_OBJ_NAME),
596             FE(DMUS_OBJ_CATEGORY),
597             FE(DMUS_OBJ_FILENAME),
598             FE(DMUS_OBJ_FULLPATH),
599             FE(DMUS_OBJ_URL),
600             FE(DMUS_OBJ_VERSION),
601             FE(DMUS_OBJ_DATE),
602             FE(DMUS_OBJ_LOADED),
603             FE(DMUS_OBJ_MEMORY),
604             FE(DMUS_OBJ_STREAM)
605         };
606     return debugstr_flags (flagmask, flags, sizeof(flags)/sizeof(flags[0]));
607 }
608
609 /* dump whole DMUS_OBJECTDESC struct */
610 const char *debugstr_DMUS_OBJECTDESC (LPDMUS_OBJECTDESC pDesc) {
611         if (pDesc) {
612                 char buffer[1024] = "", *ptr = &buffer[0];
613                 
614                 ptr += sprintf(ptr, "DMUS_OBJECTDESC (%p):\n", pDesc);
615                 ptr += sprintf(ptr, " - dwSize = %d\n", pDesc->dwSize);
616                 ptr += sprintf(ptr, " - dwValidData = %s\n", debugstr_DMUS_OBJ_FLAGS (pDesc->dwValidData));
617                 if (pDesc->dwValidData & DMUS_OBJ_CLASS) ptr += sprintf(ptr, " - guidClass = %s\n", debugstr_dmguid(&pDesc->guidClass));
618                 if (pDesc->dwValidData & DMUS_OBJ_OBJECT) ptr += sprintf(ptr, " - guidObject = %s\n", debugstr_guid(&pDesc->guidObject));
619                 if (pDesc->dwValidData & DMUS_OBJ_DATE) ptr += sprintf(ptr, " - ftDate = FIXME\n");
620                 if (pDesc->dwValidData & DMUS_OBJ_VERSION) ptr += sprintf(ptr, " - vVersion = %s\n", debugstr_dmversion(&pDesc->vVersion));
621                 if (pDesc->dwValidData & DMUS_OBJ_NAME) ptr += sprintf(ptr, " - wszName = %s\n", debugstr_w(pDesc->wszName));
622                 if (pDesc->dwValidData & DMUS_OBJ_CATEGORY) ptr += sprintf(ptr, " - wszCategory = %s\n", debugstr_w(pDesc->wszCategory));
623                 if (pDesc->dwValidData & DMUS_OBJ_FILENAME) ptr += sprintf(ptr, " - wszFileName = %s\n", debugstr_w(pDesc->wszFileName));
624                 if (pDesc->dwValidData & DMUS_OBJ_MEMORY) ptr += sprintf(ptr, " - llMemLength = 0x%s\n  - pbMemData = %p\n",
625                                                                      wine_dbgstr_longlong(pDesc->llMemLength), pDesc->pbMemData);
626                 if (pDesc->dwValidData & DMUS_OBJ_STREAM) ptr += sprintf(ptr, " - pStream = %p", pDesc->pStream);
627
628                 return wine_dbg_sprintf("%s", buffer);
629         } else {
630                 return wine_dbg_sprintf("(NULL)");
631         }
632 }