ReactOS 0.4.17-dev-966-gf06eace
dmobject.c
Go to the documentation of this file.
1/*
2 * Base IDirectMusicObject Implementation
3 * Keep in sync with the master in dlls/dmusic/dmobject.c
4 *
5 * Copyright (C) 2003-2004 Rok Mandeljc
6 * Copyright (C) 2014 Michael Stefaniuc
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#define COBJMACROS
24#include <assert.h>
25#include "objbase.h"
26#include "dmusici.h"
27#include "dmusicf.h"
28#include "dmusics.h"
29#include "dmobject.h"
30#include "wine/debug.h"
31
34
35/* Debugging helpers */
36const char *debugstr_dmguid(const GUID *id) {
37 unsigned int i;
38#define X(guid) { &guid, #guid }
39 static const struct {
40 const GUID *guid;
41 const char *name;
42 } guids[] = {
43 /* CLSIDs */
44 X(CLSID_AudioVBScript),
45 X(CLSID_DirectMusic),
46 X(CLSID_DirectMusicAudioPathConfig),
47 X(CLSID_DirectMusicAuditionTrack),
48 X(CLSID_DirectMusicBand),
49 X(CLSID_DirectMusicBandTrack),
50 X(CLSID_DirectMusicChordMapTrack),
51 X(CLSID_DirectMusicChordMap),
52 X(CLSID_DirectMusicChordTrack),
53 X(CLSID_DirectMusicCollection),
54 X(CLSID_DirectMusicCommandTrack),
55 X(CLSID_DirectMusicComposer),
56 X(CLSID_DirectMusicContainer),
57 X(CLSID_DirectMusicGraph),
58 X(CLSID_DirectMusicLoader),
59 X(CLSID_DirectMusicLyricsTrack),
60 X(CLSID_DirectMusicMarkerTrack),
61 X(CLSID_DirectMusicMelodyFormulationTrack),
62 X(CLSID_DirectMusicMotifTrack),
63 X(CLSID_DirectMusicMuteTrack),
64 X(CLSID_DirectMusicParamControlTrack),
65 X(CLSID_DirectMusicPatternTrack),
66 X(CLSID_DirectMusicPerformance),
67 X(CLSID_DirectMusicScript),
68 X(CLSID_DirectMusicScriptAutoImpSegment),
69 X(CLSID_DirectMusicScriptAutoImpPerformance),
70 X(CLSID_DirectMusicScriptAutoImpSegmentState),
71 X(CLSID_DirectMusicScriptAutoImpAudioPathConfig),
72 X(CLSID_DirectMusicScriptAutoImpAudioPath),
73 X(CLSID_DirectMusicScriptAutoImpSong),
74 X(CLSID_DirectMusicScriptSourceCodeLoader),
75 X(CLSID_DirectMusicScriptTrack),
76 X(CLSID_DirectMusicSection),
77 X(CLSID_DirectMusicSegment),
78 X(CLSID_DirectMusicSegmentState),
79 X(CLSID_DirectMusicSegmentTriggerTrack),
80 X(CLSID_DirectMusicSegTriggerTrack),
81 X(CLSID_DirectMusicSeqTrack),
82 X(CLSID_DirectMusicSignPostTrack),
83 X(CLSID_DirectMusicSong),
84 X(CLSID_DirectMusicStyle),
85 X(CLSID_DirectMusicStyleTrack),
86 X(CLSID_DirectMusicSynth),
87 X(CLSID_DirectMusicSynthSink),
88 X(CLSID_DirectMusicSysExTrack),
89 X(CLSID_DirectMusicTemplate),
90 X(CLSID_DirectMusicTempoTrack),
91 X(CLSID_DirectMusicTimeSigTrack),
92 X(CLSID_DirectMusicWaveTrack),
93 X(CLSID_DirectSoundWave),
94 /* IIDs */
95 X(IID_IDirectMusic),
96 X(IID_IDirectMusic2),
97 X(IID_IDirectMusic8),
98 X(IID_IDirectMusicAudioPath),
99 X(IID_IDirectMusicBand),
100 X(IID_IDirectMusicBuffer),
101 X(IID_IDirectMusicChordMap),
102 X(IID_IDirectMusicCollection),
103 X(IID_IDirectMusicComposer),
104 X(IID_IDirectMusicContainer),
105 X(IID_IDirectMusicDownload),
106 X(IID_IDirectMusicDownloadedInstrument),
107 X(IID_IDirectMusicGetLoader),
108 X(IID_IDirectMusicGraph),
109 X(IID_IDirectMusicInstrument),
110 X(IID_IDirectMusicLoader),
111 X(IID_IDirectMusicLoader8),
112 X(IID_IDirectMusicObject),
113 X(IID_IDirectMusicPatternTrack),
114 X(IID_IDirectMusicPerformance),
115 X(IID_IDirectMusicPerformance2),
116 X(IID_IDirectMusicPerformance8),
117 X(IID_IDirectMusicPort),
118 X(IID_IDirectMusicPortDownload),
119 X(IID_IDirectMusicScript),
120 X(IID_IDirectMusicSegment),
121 X(IID_IDirectMusicSegment2),
122 X(IID_IDirectMusicSegment8),
123 X(IID_IDirectMusicSegmentState),
124 X(IID_IDirectMusicSegmentState8),
125 X(IID_IDirectMusicStyle),
126 X(IID_IDirectMusicStyle8),
127 X(IID_IDirectMusicSynth),
128 X(IID_IDirectMusicSynth8),
129 X(IID_IDirectMusicSynthSink),
130 X(IID_IDirectMusicThru),
131 X(IID_IDirectMusicTool),
132 X(IID_IDirectMusicTool8),
133 X(IID_IDirectMusicTrack),
134 X(IID_IDirectMusicTrack8),
137 X(IID_IStream),
139 /* GUIDs */
140 X(GUID_DirectMusicAllTypes),
141 X(GUID_NOTIFICATION_CHORD),
142 X(GUID_NOTIFICATION_COMMAND),
143 X(GUID_NOTIFICATION_MEASUREANDBEAT),
144 X(GUID_NOTIFICATION_PERFORMANCE),
145 X(GUID_NOTIFICATION_RECOMPOSE),
146 X(GUID_NOTIFICATION_SEGMENT),
147 X(GUID_BandParam),
148 X(GUID_ChordParam),
149 X(GUID_CommandParam),
150 X(GUID_CommandParam2),
151 X(GUID_CommandParamNext),
152 X(GUID_IDirectMusicBand),
153 X(GUID_IDirectMusicChordMap),
154 X(GUID_IDirectMusicStyle),
155 X(GUID_MuteParam),
156 X(GUID_Play_Marker),
157 X(GUID_RhythmParam),
158 X(GUID_TempoParam),
159 X(GUID_TimeSignature),
160 X(GUID_Valid_Start_Time),
161 X(GUID_Clear_All_Bands),
162 X(GUID_ConnectToDLSCollection),
163 X(GUID_Disable_Auto_Download),
164 X(GUID_DisableTempo),
165 X(GUID_DisableTimeSig),
166 X(GUID_Download),
167 X(GUID_DownloadToAudioPath),
168 X(GUID_Enable_Auto_Download),
169 X(GUID_EnableTempo),
170 X(GUID_EnableTimeSig),
172 X(GUID_SeedVariations),
173 X(GUID_StandardMIDIFile),
174 X(GUID_Unload),
175 X(GUID_UnloadFromAudioPath),
176 X(GUID_Variations),
177 X(GUID_PerfMasterTempo),
178 X(GUID_PerfMasterVolume),
179 X(GUID_PerfMasterGrooveLevel),
180 X(GUID_PerfAutoDownload),
181 X(GUID_DefaultGMCollection),
182 X(GUID_Synth_Default),
183 X(GUID_Buffer_Reverb),
184 X(GUID_Buffer_EnvReverb),
185 X(GUID_Buffer_Stereo),
186 X(GUID_Buffer_3D_Dry),
187 X(GUID_Buffer_Mono),
188 X(GUID_DMUS_PROP_GM_Hardware),
189 X(GUID_DMUS_PROP_GS_Capable),
190 X(GUID_DMUS_PROP_GS_Hardware),
191 X(GUID_DMUS_PROP_DLS1),
192 X(GUID_DMUS_PROP_DLS2),
193 X(GUID_DMUS_PROP_Effects),
194 X(GUID_DMUS_PROP_INSTRUMENT2),
195 X(GUID_DMUS_PROP_LegacyCaps),
196 X(GUID_DMUS_PROP_MemorySize),
197 X(GUID_DMUS_PROP_SampleMemorySize),
198 X(GUID_DMUS_PROP_SamplePlaybackRate),
199 X(GUID_DMUS_PROP_SetSynthSink),
200 X(GUID_DMUS_PROP_SinkUsesDSound),
201 X(GUID_DMUS_PROP_SynthSink_DSOUND),
202 X(GUID_DMUS_PROP_SynthSink_WAVE),
203 X(GUID_DMUS_PROP_Volume),
204 X(GUID_DMUS_PROP_WavesReverb),
205 X(GUID_DMUS_PROP_WriteLatency),
206 X(GUID_DMUS_PROP_WritePeriod),
207 X(GUID_DMUS_PROP_XG_Capable),
208 X(GUID_DMUS_PROP_XG_Hardware)
209 };
210#undef X
211
212 if (!id)
213 return "(null)";
214
215 for (i = 0; i < ARRAY_SIZE(guids); i++)
216 if (IsEqualGUID(id, guids[i].guid))
217 return guids[i].name;
218
219 return debugstr_guid(id);
220}
221
223{
224 if (!desc || !TRACE_ON(dmfile))
225 return;
226
227 TRACE_(dmfile)("DMUS_OBJECTDESC (%p):", desc);
228 TRACE_(dmfile)(" - dwSize = %lu\n", desc->dwSize);
229
230#define X(flag) if (desc->dwValidData & flag) TRACE_(dmfile)(#flag " ")
231 TRACE_(dmfile)(" - dwValidData = %#08lx ( ", desc->dwValidData);
244 TRACE_(dmfile)(")\n");
245#undef X
246
247 if (desc->dwValidData & DMUS_OBJ_CLASS)
248 TRACE_(dmfile)(" - guidClass = %s\n", debugstr_dmguid(&desc->guidClass));
249 if (desc->dwValidData & DMUS_OBJ_OBJECT)
250 TRACE_(dmfile)(" - guidObject = %s\n", debugstr_guid(&desc->guidObject));
251
252 if (desc->dwValidData & DMUS_OBJ_DATE) {
254 FileTimeToSystemTime(&desc->ftDate, &time);
255 TRACE_(dmfile)(" - ftDate = \'%04u-%02u-%02u %02u:%02u:%02u\'\n",
256 time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
257 }
258 if (desc->dwValidData & DMUS_OBJ_VERSION)
259 TRACE_(dmfile)(" - vVersion = \'%u,%u,%u,%u\'\n",
260 HIWORD(desc->vVersion.dwVersionMS), LOWORD(desc->vVersion.dwVersionMS),
261 HIWORD(desc->vVersion.dwVersionLS), LOWORD(desc->vVersion.dwVersionLS));
262 if (desc->dwValidData & DMUS_OBJ_NAME)
263 TRACE_(dmfile)(" - wszName = %s\n", debugstr_w(desc->wszName));
264 if (desc->dwValidData & DMUS_OBJ_CATEGORY)
265 TRACE_(dmfile)(" - wszCategory = %s\n", debugstr_w(desc->wszCategory));
266 if (desc->dwValidData & DMUS_OBJ_FILENAME)
267 TRACE_(dmfile)(" - wszFileName = %s\n", debugstr_w(desc->wszFileName));
268 if (desc->dwValidData & DMUS_OBJ_MEMORY)
269 TRACE_(dmfile)(" - llMemLength = 0x%s - pbMemData = %p\n",
270 wine_dbgstr_longlong(desc->llMemLength), desc->pbMemData);
271 if (desc->dwValidData & DMUS_OBJ_STREAM)
272 TRACE_(dmfile)(" - pStream = %p\n", desc->pStream);
273}
274
275
276/* RIFF format parsing */
277#define CHUNK_HDR_SIZE (sizeof(FOURCC) + sizeof(DWORD))
278
279const char *debugstr_chunk(const struct chunk_entry *chunk)
280{
281 const char *type = "";
282
283 if (!chunk)
284 return "(null)";
285 if (chunk->id == FOURCC_RIFF || chunk->id == FOURCC_LIST)
286 type = wine_dbg_sprintf("type %s, ", debugstr_fourcc(chunk->type));
287 return wine_dbg_sprintf("%s chunk, %ssize %lu", debugstr_fourcc(chunk->id), type, chunk->size);
288}
289
291{
292 ULONG read;
293 HRESULT hr;
294
295 hr = IStream_Read(stream, data, size, &read);
296 if (FAILED(hr))
297 TRACE_(dmfile)("IStream_Read failed: %#lx\n", hr);
298 else if (!read && read < size) {
299 /* All or nothing: Handle a partial read due to end of stream as an error */
300 TRACE_(dmfile)("Short read: %lu < %lu\n", read, size);
301 return E_FAIL;
302 }
303
304 return hr;
305}
306
308{
309 static const LARGE_INTEGER zero;
310 ULONGLONG ck_end = 0, p_end = 0;
311 HRESULT hr;
312
313 hr = IStream_Seek(stream, zero, STREAM_SEEK_CUR, &chunk->offset);
314 if (FAILED(hr))
315 return hr;
316 assert(!(chunk->offset.QuadPart & 1));
317 if (chunk->parent) {
318 p_end = chunk->parent->offset.QuadPart + CHUNK_HDR_SIZE + ((chunk->parent->size + 1) & ~1);
319 if (chunk->offset.QuadPart == p_end)
320 return S_FALSE;
321 ck_end = chunk->offset.QuadPart + CHUNK_HDR_SIZE;
322 if (ck_end > p_end) {
323 WARN_(dmfile)("No space for sub-chunk header in parent chunk: ends at offset %s > %s\n",
325 return E_FAIL;
326 }
327 }
328
330 if (hr != S_OK)
331 return hr;
332 if (chunk->parent) {
333 ck_end += (chunk->size + 1) & ~1;
334 if (ck_end > p_end) {
335 WARN_(dmfile)("No space for sub-chunk data in parent chunk: ends at offset %s > %s\n",
337 return E_FAIL;
338 }
339 }
340
341 if (chunk->id != FOURCC_LIST && chunk->id != FOURCC_RIFF)
342 chunk->type = 0;
343 else if ((hr = stream_read(stream, &chunk->type, sizeof(FOURCC))) != S_OK)
344 return hr != S_FALSE ? hr : E_FAIL;
345
346 TRACE_(dmfile)("Returning %s\n", debugstr_chunk(chunk));
347
348 return S_OK;
349}
350
352{
354
355 end.QuadPart = (chunk->offset.QuadPart + CHUNK_HDR_SIZE + chunk->size + 1) & ~(ULONGLONG)1;
356
357 return IStream_Seek(stream, end, STREAM_SEEK_SET, NULL);
358}
359
361{
362 HRESULT hr;
363
364 if (chunk->id) {
366 if (FAILED(hr))
367 return hr;
368 }
369
371}
372
373/* Reads chunk data of the form:
374 DWORD - size of array element
375 element[] - Array of elements
376 The caller needs to free() the array.
377*/
379 unsigned int *count, DWORD elem_size)
380{
381 DWORD size;
382 HRESULT hr;
383
384 *array = NULL;
385 *count = 0;
386
387 if (chunk->size < sizeof(DWORD)) {
388 WARN_(dmfile)("%s: Too short to read element size\n", debugstr_chunk(chunk));
389 return E_FAIL;
390 }
391 if (FAILED(hr = stream_read(stream, &size, sizeof(DWORD))))
392 return hr;
393 if (size != elem_size) {
394 WARN_(dmfile)("%s: Array element size mismatch: got %lu, expected %lu\n",
395 debugstr_chunk(chunk), size, elem_size);
397 }
398
399 *count = (chunk->size - sizeof(DWORD)) / elem_size;
400 size = *count * elem_size;
401 if (!(*array = malloc(size)))
402 return E_OUTOFMEMORY;
403 if (FAILED(hr = stream_read(stream, *array, size))) {
404 free(*array);
405 *array = NULL;
406 return hr;
407 }
408
409 if (chunk->size > size + sizeof(DWORD)) {
410 WARN_(dmfile)("%s: Extraneous data at end of array\n", debugstr_chunk(chunk));
412 return S_FALSE;
413 }
414 return S_OK;
415}
416
418 ULONG size)
419{
420 if (chunk->size != size) {
421 WARN_(dmfile)("Chunk %s (size %lu, offset %s) doesn't contains the expected data size %lu\n",
424 return E_FAIL;
425 }
426 return stream_read(stream, data, size);
427}
428
430 ULONG size)
431{
432 ULONG len;
433 HRESULT hr;
434
435 hr = IStream_Read(stream, str, min(chunk->size, size), &len);
436 if (FAILED(hr))
437 return hr;
438
439 /* Don't assume the string is properly zero terminated */
440 str[min(len, size - 1)] = 0;
441
442 if (len < chunk->size)
443 return S_FALSE;
444 return S_OK;
445}
446
447HRESULT stream_get_loader(IStream *stream, IDirectMusicLoader **ret_loader)
448{
449 IDirectMusicGetLoader *getter;
450 HRESULT hr;
451
452 if (SUCCEEDED(hr = IStream_QueryInterface(stream, &IID_IDirectMusicGetLoader, (void**)&getter)))
453 {
454 hr = IDirectMusicGetLoader_GetLoader(getter, ret_loader);
456 }
457
458 if (FAILED(hr)) *ret_loader = NULL;
459 return hr;
460}
461
463{
464 IDirectMusicLoader *loader;
465 HRESULT hr;
466
468 {
469 hr = IDirectMusicLoader_GetObject(loader, desc, iid, ret_iface);
471 }
472
473 if (FAILED(hr)) *ret_iface = NULL;
474 return hr;
475}
476
477
478/* Generic IDirectMusicObject methods */
479static inline struct dmobject *impl_from_IDirectMusicObject(IDirectMusicObject *iface)
480{
482}
483
485 void **ret_iface)
486{
488 return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface);
489}
490
492{
494 return IUnknown_AddRef(This->outer_unk);
495}
496
498{
500 return IUnknown_Release(This->outer_unk);
501}
502
505{
507
508 TRACE("(%p/%p)->(%p)\n", iface, This, desc);
509
510 if (!desc)
511 return E_POINTER;
512
513 memcpy(desc, &This->desc, This->desc.dwSize);
514
515 return S_OK;
516}
517
520{
522 HRESULT ret = S_OK;
523
524 TRACE("(%p, %p)\n", iface, desc);
525
526 if (!desc)
527 return E_POINTER;
528
529 /* Immutable property */
530 if (desc->dwValidData & DMUS_OBJ_CLASS)
531 {
532 desc->dwValidData &= ~DMUS_OBJ_CLASS;
533 ret = S_FALSE;
534 }
535 /* Set only valid fields */
536 if (desc->dwValidData & DMUS_OBJ_OBJECT)
537 This->desc.guidObject = desc->guidObject;
538 if (desc->dwValidData & DMUS_OBJ_NAME)
539 lstrcpynW(This->desc.wszName, desc->wszName, DMUS_MAX_NAME);
540 if (desc->dwValidData & DMUS_OBJ_CATEGORY)
541 lstrcpynW(This->desc.wszCategory, desc->wszCategory, DMUS_MAX_CATEGORY);
542 if (desc->dwValidData & DMUS_OBJ_FILENAME)
543 lstrcpynW(This->desc.wszFileName, desc->wszFileName, DMUS_MAX_FILENAME);
544 if (desc->dwValidData & DMUS_OBJ_VERSION)
545 This->desc.vVersion = desc->vVersion;
546 if (desc->dwValidData & DMUS_OBJ_DATE)
547 This->desc.ftDate = desc->ftDate;
548 if (desc->dwValidData & DMUS_OBJ_MEMORY) {
549 This->desc.llMemLength = desc->llMemLength;
550 memcpy(This->desc.pbMemData, desc->pbMemData, desc->llMemLength);
551 }
552 if (desc->dwValidData & DMUS_OBJ_STREAM)
553 IStream_Clone(desc->pStream, &This->desc.pStream);
554
555 This->desc.dwValidData |= desc->dwValidData;
556
557 return ret;
558}
559
560/* Helper for IDirectMusicObject::ParseDescriptor */
561static inline void info_get_name(IStream *stream, const struct chunk_entry *info,
563{
564 struct chunk_entry chunk = {.parent = info};
565 char name[DMUS_MAX_NAME];
566 ULONG len;
567 HRESULT hr = E_FAIL;
568
569 while (stream_next_chunk(stream, &chunk) == S_OK)
570 if (chunk.id == mmioFOURCC('I','N','A','M'))
571 hr = IStream_Read(stream, name, min(chunk.size, sizeof(name)), &len);
572
573 if (SUCCEEDED(hr)) {
574 len = MultiByteToWideChar(CP_ACP, 0, name, len, desc->wszName, sizeof(desc->wszName));
575 desc->wszName[min(len, sizeof(desc->wszName) - 1)] = 0;
576 desc->dwValidData |= DMUS_OBJ_NAME;
577 }
578}
579
580static inline void unfo_get_name(IStream *stream, const struct chunk_entry *unfo,
582{
583 struct chunk_entry chunk = {.parent = unfo};
584
585 while (stream_next_chunk(stream, &chunk) == S_OK)
586 if (chunk.id == DMUS_FOURCC_UNAM_CHUNK || (inam && chunk.id == mmioFOURCC('I','N','A','M')))
587 if (stream_chunk_get_wstr(stream, &chunk, desc->wszName, sizeof(desc->wszName)) == S_OK)
588 desc->dwValidData |= DMUS_OBJ_NAME;
589}
590
592 DMUS_OBJECTDESC *desc, DWORD supported)
593{
594 struct chunk_entry chunk = {.parent = riff};
595 HRESULT hr;
596
597 TRACE("Looking for %#lx in %p: %s\n", supported, stream, debugstr_chunk(riff));
598
599 desc->dwValidData = 0;
600 desc->dwSize = sizeof(*desc);
601
602 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) {
603 switch (chunk.id) {
606 desc->wszCategory, sizeof(desc->wszCategory)) == S_OK)
607 desc->dwValidData |= DMUS_OBJ_CATEGORY;
608 break;
610 if ((supported & DMUS_OBJ_DATE) && stream_chunk_get_data(stream, &chunk,
611 &desc->ftDate, sizeof(desc->ftDate)) == S_OK)
612 desc->dwValidData |= DMUS_OBJ_DATE;
613 break;
616 desc->wszFileName, sizeof(desc->wszFileName)) == S_OK)
617 desc->dwValidData |= DMUS_OBJ_FILENAME;
618 break;
619 case FOURCC_DLID:
620 if (!(supported & DMUS_OBJ_GUID_DLID)) break;
621 if ((supported & DMUS_OBJ_OBJECT) && stream_chunk_get_data(stream, &chunk,
622 &desc->guidObject, sizeof(desc->guidObject)) == S_OK)
623 desc->dwValidData |= DMUS_OBJ_OBJECT;
624 break;
626 if ((supported & DMUS_OBJ_GUID_DLID)) break;
627 if ((supported & DMUS_OBJ_OBJECT) && stream_chunk_get_data(stream, &chunk,
628 &desc->guidObject, sizeof(desc->guidObject)) == S_OK)
629 desc->dwValidData |= DMUS_OBJ_OBJECT;
630 break;
632 if ((supported & DMUS_OBJ_NAME) && stream_chunk_get_wstr(stream, &chunk,
633 desc->wszName, sizeof(desc->wszName)) == S_OK)
634 desc->dwValidData |= DMUS_OBJ_NAME;
635 break;
637 if ((supported & DMUS_OBJ_VERSION) && stream_chunk_get_data(stream, &chunk,
638 &desc->vVersion, sizeof(desc->vVersion)) == S_OK)
639 desc->dwValidData |= DMUS_OBJ_VERSION;
640 break;
641 case FOURCC_LIST:
642 if (chunk.type == DMUS_FOURCC_UNFO_LIST && (supported & DMUS_OBJ_NAME))
644 else if (chunk.type == DMUS_FOURCC_INFO_LIST && (supported & DMUS_OBJ_NAME_INFO))
646 break;
647 }
648 }
649 TRACE("Found %#lx\n", desc->dwValidData);
650
651 return hr;
652}
653
655 IDirectMusicObject **dmobj)
656{
657 struct chunk_entry chunk = {.parent = list};
660 HRESULT hr;
661
663 return hr;
666
668 WARN("Failed to read data of %s\n", debugstr_chunk(&chunk));
669 return hr;
670 }
671 TRACE("REFERENCE guidClassID %s, dwValidData %#lx\n", debugstr_dmguid(&reference.guidClassID),
672 reference.dwValidData);
673
674 if (FAILED(hr = dmobj_parsedescriptor(stream, list, &desc, reference.dwValidData)))
675 return hr;
676 desc.guidClass = reference.guidClassID;
677 desc.dwValidData |= DMUS_OBJ_CLASS;
679
680 return stream_get_object(stream, &desc, &IID_IDirectMusicObject, (void **)dmobj);
681}
682
683/* Generic IPersistStream methods */
685{
686 return CONTAINING_RECORD(iface, struct dmobject, IPersistStream_iface);
687}
688
690 void **ret_iface)
691{
692 struct dmobject *This = impl_from_IPersistStream(iface);
693 return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface);
694}
695
697{
698 struct dmobject *This = impl_from_IPersistStream(iface);
699 return IUnknown_AddRef(This->outer_unk);
700}
701
703{
704 struct dmobject *This = impl_from_IPersistStream(iface);
705 return IUnknown_Release(This->outer_unk);
706}
707
709{
710 struct dmobject *This = impl_from_IPersistStream(iface);
711
712 TRACE("(%p, %p)\n", This, class);
713
714 if (!class)
715 return E_POINTER;
716
717 *class = This->desc.guidClass;
718
719 return S_OK;
720}
721
722/* IPersistStream methods not implemented in native */
724{
725 TRACE("(%p, %p): method not implemented\n", iface, class);
726 return E_NOTIMPL;
727}
728
730{
731 TRACE("(%p): method not implemented, always returning S_FALSE\n", iface);
732 return S_FALSE;
733}
734
736 BOOL clear_dirty)
737{
738 TRACE("(%p, %p, %d): method not implemented\n", iface, stream, clear_dirty);
739 return E_NOTIMPL;
740}
741
743{
744 TRACE("(%p, %p): method not implemented\n", iface, size);
745 return E_NOTIMPL;
746}
747
748
749void dmobject_init(struct dmobject *dmobj, const GUID *class, IUnknown *outer_unk)
750{
751 dmobj->outer_unk = outer_unk;
752 dmobj->desc.dwSize = sizeof(dmobj->desc);
754 dmobj->desc.guidClass = *class;
755}
#define read
Definition: acwin.h:97
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
const GUID IID_IClassFactory
Definition: list.h:39
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
#define CP_ACP
Definition: compat.h:109
#define TRACE_(x)
Definition: compat.h:76
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define TRACE_ON(x)
Definition: compat.h:75
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrcpynW
Definition: compat.h:738
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:183
const struct sortguid * guids
Definition: locale.c:422
GUID guid
Definition: version.c:147
#define assert(_expr)
Definition: assert.h:32
#define FOURCC_DLID
Definition: dls1.h:34
DWORD FOURCC
Definition: dmdls.h:25
#define DMUS_E_UNSUPPORTED_STREAM
Definition: dmerror.h:100
static struct dmobject * impl_from_IPersistStream(IPersistStream *iface)
Definition: dmobject.c:684
HRESULT WINAPI dmobj_IDirectMusicObject_GetDescriptor(IDirectMusicObject *iface, DMUS_OBJECTDESC *desc)
Definition: dmobject.c:503
void dmobject_init(struct dmobject *dmobj, const GUID *class, IUnknown *outer_unk)
Definition: dmobject.c:749
HRESULT stream_get_loader(IStream *stream, IDirectMusicLoader **ret_loader)
Definition: dmobject.c:447
HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size)
Definition: dmobject.c:417
HRESULT stream_next_chunk(IStream *stream, struct chunk_entry *chunk)
Definition: dmobject.c:360
ULONG WINAPI dmobj_IPersistStream_Release(IPersistStream *iface)
Definition: dmobject.c:702
#define CHUNK_HDR_SIZE
Definition: dmobject.c:277
ULONG WINAPI dmobj_IDirectMusicObject_Release(IDirectMusicObject *iface)
Definition: dmobject.c:497
HRESULT dmobj_parsedescriptor(IStream *stream, const struct chunk_entry *riff, DMUS_OBJECTDESC *desc, DWORD supported)
Definition: dmobject.c:591
HRESULT WINAPI dmobj_IDirectMusicObject_QueryInterface(IDirectMusicObject *iface, REFIID riid, void **ret_iface)
Definition: dmobject.c:484
static void info_get_name(IStream *stream, const struct chunk_entry *info, DMUS_OBJECTDESC *desc)
Definition: dmobject.c:561
static void unfo_get_name(IStream *stream, const struct chunk_entry *unfo, DMUS_OBJECTDESC *desc, BOOL inam)
Definition: dmobject.c:580
HRESULT WINAPI unimpl_IPersistStream_GetClassID(IPersistStream *iface, CLSID *class)
Definition: dmobject.c:723
HRESULT WINAPI unimpl_IPersistStream_GetSizeMax(IPersistStream *iface, ULARGE_INTEGER *size)
Definition: dmobject.c:742
#define X(guid)
HRESULT WINAPI dmobj_IDirectMusicObject_SetDescriptor(IDirectMusicObject *iface, DMUS_OBJECTDESC *desc)
Definition: dmobject.c:518
void dump_DMUS_OBJECTDESC(DMUS_OBJECTDESC *desc)
Definition: dmobject.c:222
HRESULT stream_chunk_get_wstr(IStream *stream, const struct chunk_entry *chunk, WCHAR *str, ULONG size)
Definition: dmobject.c:429
const char * debugstr_chunk(const struct chunk_entry *chunk)
Definition: dmobject.c:279
HRESULT WINAPI dmobj_IPersistStream_GetClassID(IPersistStream *iface, CLSID *class)
Definition: dmobject.c:708
ULONG WINAPI dmobj_IPersistStream_AddRef(IPersistStream *iface)
Definition: dmobject.c:696
const char * debugstr_dmguid(const GUID *id)
Definition: dmobject.c:36
HRESULT dmobj_parsereference(IStream *stream, const struct chunk_entry *list, IDirectMusicObject **dmobj)
Definition: dmobject.c:654
HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, void **array, unsigned int *count, DWORD elem_size)
Definition: dmobject.c:378
HRESULT WINAPI dmobj_IPersistStream_QueryInterface(IPersistStream *iface, REFIID riid, void **ret_iface)
Definition: dmobject.c:689
ULONG WINAPI dmobj_IDirectMusicObject_AddRef(IDirectMusicObject *iface)
Definition: dmobject.c:491
static struct dmobject * impl_from_IDirectMusicObject(IDirectMusicObject *iface)
Definition: dmobject.c:479
HRESULT stream_skip_chunk(IStream *stream, const struct chunk_entry *chunk)
Definition: dmobject.c:351
HRESULT stream_get_chunk(IStream *stream, struct chunk_entry *chunk)
Definition: dmobject.c:307
HRESULT WINAPI unimpl_IPersistStream_IsDirty(IPersistStream *iface)
Definition: dmobject.c:729
HRESULT stream_get_object(IStream *stream, DMUS_OBJECTDESC *desc, REFIID iid, void **ret_iface)
Definition: dmobject.c:462
HRESULT WINAPI unimpl_IPersistStream_Save(IPersistStream *iface, IStream *stream, BOOL clear_dirty)
Definition: dmobject.c:735
#define DMUS_OBJ_NAME_INAM
Definition: dmobject.h:96
#define DMUS_OBJ_NAME_INFO
Definition: dmobject.h:97
#define DMUS_OBJ_GUID_DLID
Definition: dmobject.h:98
#define DMUS_FOURCC_GUID_CHUNK
Definition: dmusicf.h:42
#define DMUS_FOURCC_REF_CHUNK
Definition: dmusicf.h:103
#define DMUS_FOURCC_UNAM_CHUNK
Definition: dmusicf.h:45
#define DMUS_FOURCC_VERSION_CHUNK
Definition: dmusicf.h:51
#define DMUS_FOURCC_FILE_CHUNK
Definition: dmusicf.h:106
#define DMUS_FOURCC_INFO_LIST
Definition: dmusicf.h:43
#define DMUS_FOURCC_NAME_CHUNK
Definition: dmusicf.h:105
#define DMUS_FOURCC_DATE_CHUNK
Definition: dmusicf.h:104
#define DMUS_FOURCC_UNFO_LIST
Definition: dmusicf.h:44
#define DMUS_FOURCC_CATEGORY_CHUNK
Definition: dmusicf.h:50
#define DMUS_OBJ_DATE
Definition: dmusici.h:273
#define IDirectMusicGetLoader_GetLoader(p, a)
Definition: dmusici.h:963
#define DMUS_OBJ_FULLPATH
Definition: dmusici.h:270
#define IDirectMusicLoader_Release(p)
Definition: dmusici.h:879
#define DMUS_MAX_CATEGORY
Definition: dmusici.h:246
#define DMUS_OBJ_MEMORY
Definition: dmusici.h:275
#define DMUS_OBJ_NAME
Definition: dmusici.h:267
#define DMUS_OBJ_STREAM
Definition: dmusici.h:276
#define DMUS_OBJ_FILENAME
Definition: dmusici.h:269
#define DMUS_OBJ_CLASS
Definition: dmusici.h:266
#define DMUS_MAX_NAME
Definition: dmusici.h:245
#define DMUS_OBJ_URL
Definition: dmusici.h:271
#define IDirectMusicGetLoader_Release(p)
Definition: dmusici.h:961
#define DMUS_MAX_FILENAME
Definition: dmusici.h:247
#define DMUS_OBJ_VERSION
Definition: dmusici.h:272
#define IDirectMusicLoader_GetObject(p, a, b, c)
Definition: dmusici.h:881
#define DMUS_OBJ_CATEGORY
Definition: dmusici.h:268
#define DMUS_OBJ_OBJECT
Definition: dmusici.h:265
#define GUID_IgnoreBankSelectForGM
Definition: dmusici.h:181
#define DMUS_OBJ_LOADED
Definition: dmusici.h:274
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLint reference
Definition: glext.h:11729
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define FOURCC_LIST
Definition: mmsystem.h:565
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
static int stream_read
Definition: htmldoc.c:205
#define min(a, b)
Definition: monoChain.cc:55
#define DWORD
Definition: nt_native.h:44
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
const GUID IID_IPersistStream
Definition: proxy.cpp:13
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
const WCHAR * str
#define WARN_(ch,...)
Definition: debug.h:157
static __inline const char * debugstr_fourcc(unsigned int cc)
Definition: debug.h:397
int zero
Definition: sehframes.cpp:29
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwValidData
Definition: dmusici.h:743
Definition: undname.c:54
Definition: dmobject.h:26
uint16_t size
Definition: btrfs_drv.h:563
uint64_t offset
Definition: btrfs_drv.h:564
IPersistStream IPersistStream_iface
Definition: dmobject.h:74
DMUS_OBJECTDESC desc
Definition: dmobject.h:76
IUnknown * outer_unk
Definition: dmobject.h:75
IDirectMusicObject IDirectMusicObject_iface
Definition: dmobject.h:73
Definition: loader.c:72
Definition: name.c:39
Definition: parse.h:23
uint64_t ULONGLONG
Definition: typedefs.h:67
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_POINTER
Definition: winerror.h:3480