ReactOS 0.4.17-dev-923-g4c9a150
segment.c
Go to the documentation of this file.
1/* IDirectMusicSegment8 Implementation
2 *
3 * Copyright (C) 2003-2004 Rok Mandeljc
4 * Copyright (C) 2003-2004 Raphael Junqueira
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "dmime_private.h"
22
24
26{
27 struct list entry;
30 IDirectMusicTrack *pTrack;
31};
32
34{
35 HRESULT hr;
36
37 if (FAILED(hr = IDirectMusicTrack_Init(entry->pTrack, NULL)))
38 WARN("Failed to de-init track %p, hr %#lx\n", entry->pTrack, hr);
40
41 free(entry);
42}
43
44struct segment
45{
46 IDirectMusicSegment8 IDirectMusicSegment8_iface;
50 IDirectMusicGraph *pGraph;
51 struct list tracks;
52};
53
54static struct segment *segment_create(void);
55
56static inline struct segment *impl_from_IDirectMusicSegment8(IDirectMusicSegment8 *iface)
57{
59}
60
61static HRESULT WINAPI segment_QueryInterface(IDirectMusicSegment8 *iface, REFIID riid, void **ret_iface)
62{
64
65 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ret_iface);
66
67 *ret_iface = NULL;
68
69 if (IsEqualIID (riid, &IID_IUnknown) || IsEqualIID (riid, &IID_IDirectMusicSegment) ||
70 IsEqualIID(riid, &IID_IDirectMusicSegment2) ||
71 IsEqualIID (riid, &IID_IDirectMusicSegment8))
72 *ret_iface = iface;
73 else if (IsEqualIID (riid, &IID_IDirectMusicObject))
74 *ret_iface = &This->dmobj.IDirectMusicObject_iface;
76 *ret_iface = &This->dmobj.IPersistStream_iface;
77 else {
78 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
79 return E_NOINTERFACE;
80 }
81
82 IUnknown_AddRef((IUnknown*)*ret_iface);
83 return S_OK;
84}
85
86static ULONG WINAPI segment_AddRef(IDirectMusicSegment8 *iface)
87{
90
91 TRACE("(%p) ref=%ld\n", This, ref);
92
93 return ref;
94}
95
96static ULONG WINAPI segment_Release(IDirectMusicSegment8 *iface)
97{
100
101 TRACE("(%p) ref=%ld\n", This, ref);
102
103 if (!ref) {
104 struct track_entry *entry, *next;
105
107 {
108 list_remove(&entry->entry);
110 }
111 free(This);
112 }
113
114 return ref;
115}
116
117static HRESULT WINAPI segment_GetLength(IDirectMusicSegment8 *iface, MUSIC_TIME *length)
118{
120
121 TRACE("(%p, %p)\n", This, length);
122
123 if (!length) return E_POINTER;
124 *length = This->header.mtLength;
125
126 return S_OK;
127}
128
129static HRESULT WINAPI segment_SetLength(IDirectMusicSegment8 *iface, MUSIC_TIME length)
130{
132
133 TRACE("(%p, %ld)\n", This, length);
134
135 This->header.mtLength = length;
136
137 return S_OK;
138}
139
140static HRESULT WINAPI segment_GetRepeats(IDirectMusicSegment8 *iface, DWORD *repeats)
141{
143
144 TRACE("(%p, %p)\n", This, repeats);
145
146 if (!repeats) return E_POINTER;
147 *repeats = This->header.dwRepeats;
148
149 return S_OK;
150}
151
152static HRESULT WINAPI segment_SetRepeats(IDirectMusicSegment8 *iface, DWORD repeats)
153{
155
156 TRACE("(%p, %ld)\n", This, repeats);
157 This->header.dwRepeats = repeats;
158
159 return S_OK;
160}
161
162static HRESULT WINAPI segment_GetDefaultResolution(IDirectMusicSegment8 *iface, DWORD *resolution)
163{
165
166 TRACE("(%p, %p)\n", This, resolution);
167
168 if (!resolution) return E_POINTER;
169 *resolution = This->header.dwResolution;
170
171 return S_OK;
172}
173
174static HRESULT WINAPI segment_SetDefaultResolution(IDirectMusicSegment8 *iface, DWORD resolution)
175{
177
178 TRACE("(%p, %ld)\n", This, resolution);
179 This->header.dwResolution = resolution;
180
181 return S_OK;
182}
183
184static HRESULT WINAPI segment_GetTrack(IDirectMusicSegment8 *iface, REFGUID type, DWORD group,
185 DWORD index, IDirectMusicTrack **ret_track)
186{
188 struct track_entry *entry;
189 HRESULT hr = S_OK;
190
191 TRACE("(%p, %s, %#lx, %#lx, %p)\n", This, debugstr_dmguid(type), group, index, ret_track);
192
193 if (!ret_track) return E_POINTER;
194
196 {
197 if (group != -1 && !(entry->dwGroupBits & group)) continue;
198
199 if (!IsEqualGUID(&GUID_NULL, type))
200 {
201 CLSID entry_type = GUID_NULL;
202 IPersistStream *persist;
203
204 if (SUCCEEDED(hr = IDirectMusicTrack_QueryInterface(entry->pTrack, &IID_IPersistStream, (void **)&persist)))
205 {
206 hr = IPersistStream_GetClassID(persist, &entry_type);
207 if (SUCCEEDED(hr)) TRACE(" - %p -> %s\n", entry, debugstr_dmguid(&entry_type));
208 IPersistStream_Release(persist);
209 }
210
211 if (!IsEqualGUID(&entry_type, type)) continue;
212 }
213
214 if (!index--)
215 {
216 *ret_track = entry->pTrack;
218 return S_OK;
219 }
220 }
221
222 return DMUS_E_NOT_FOUND;
223}
224
225static HRESULT WINAPI segment_GetTrackGroup(IDirectMusicSegment8 *iface, IDirectMusicTrack *track, DWORD *ret_group)
226{
228 struct track_entry *entry;
229
230 TRACE("(%p, %p, %p)\n", This, track, ret_group);
231
232 if (!ret_group) return E_POINTER;
233
235 {
236 if (entry->pTrack == track)
237 {
238 *ret_group = entry->dwGroupBits;
239 return S_OK;
240 }
241 }
242
243 return DMUS_E_NOT_FOUND;
244}
245
246static HRESULT segment_append_track(struct segment *This, IDirectMusicTrack *track, DWORD group, DWORD flags)
247{
248 struct track_entry *entry;
249 HRESULT hr;
250
251 if (!(entry = calloc(1, sizeof(*entry)))) return E_OUTOFMEMORY;
252 entry->dwGroupBits = group;
253 entry->flags = flags;
254 entry->pTrack = track;
256
257 hr = IDirectMusicTrack_Init(track, (IDirectMusicSegment *)&This->IDirectMusicSegment8_iface);
259 else list_add_tail(&This->tracks, &entry->entry);
260
261 return hr;
262}
263
264static HRESULT WINAPI segment_InsertTrack(IDirectMusicSegment8 *iface, IDirectMusicTrack *track, DWORD group)
265{
267 struct track_entry *entry;
268
269 TRACE("(%p, %p, %#lx)\n", This, track, group);
270
271 if (!group) return E_INVALIDARG;
272
274 if (entry->pTrack == track) return E_FAIL;
275
277}
278
279static HRESULT WINAPI segment_RemoveTrack(IDirectMusicSegment8 *iface, IDirectMusicTrack *track)
280{
282 struct track_entry *entry;
283
284 TRACE("(%p, %p)\n", This, track);
285
287 {
288 if (entry->pTrack == track)
289 {
290 list_remove(&entry->entry);
292 return S_OK;
293 }
294 }
295
296 return S_FALSE;
297}
298
299static HRESULT WINAPI segment_InitPlay(IDirectMusicSegment8 *iface,
300 IDirectMusicSegmentState **state, IDirectMusicPerformance *performance, DWORD flags)
301{
303 HRESULT hr;
304
305 FIXME("(%p, %p, %p, %ld): semi-stub\n", This, state, performance, flags);
306
307 if (!state) return E_POINTER;
308 if (FAILED(hr = create_dmsegmentstate(&IID_IDirectMusicSegmentState, (void **)state))) return hr;
309
310 /* TODO: DMUS_SEGF_FLAGS */
311 return S_OK;
312}
313
314static HRESULT WINAPI segment_GetGraph(IDirectMusicSegment8 *iface, IDirectMusicGraph **graph)
315{
317
318 FIXME("(%p, %p): semi-stub\n", This, graph);
319
320 if (!graph) return E_POINTER;
321 if (!(*graph = This->pGraph)) return DMUS_E_NOT_FOUND;
323
324 return S_OK;
325}
326
327static HRESULT WINAPI segment_SetGraph(IDirectMusicSegment8 *iface, IDirectMusicGraph *graph)
328{
330
331 FIXME("(%p, %p): to complete\n", This, graph);
332
333 if (This->pGraph) IDirectMusicGraph_Release(This->pGraph);
334 if ((This->pGraph = graph)) IDirectMusicGraph_AddRef(This->pGraph);
335
336 return S_OK;
337}
338
339static HRESULT WINAPI segment_AddNotificationType(IDirectMusicSegment8 *iface, REFGUID rguidNotificationType)
340{
342 FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
343 return S_OK;
344}
345
346static HRESULT WINAPI segment_RemoveNotificationType(IDirectMusicSegment8 *iface, REFGUID rguidNotificationType)
347{
349 FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
350 return S_OK;
351}
352
353static HRESULT WINAPI segment_GetParam(IDirectMusicSegment8 *iface, REFGUID type, DWORD group,
355{
357 IDirectMusicTrack *track;
358 unsigned int i, count;
360
361 TRACE("(%p, %s, %#lx, %lu, %ld, %p, %p)\n", This, debugstr_dmguid(type), group, index, time,
362 next, param);
363
364 if (!type)
365 return E_POINTER;
366
367 /* Index is relative to the search pattern: group bits and supported param type */
368 for (i = 0, count = 0; i < DMUS_SEG_ANYTRACK && count <= index; i++) {
369 if (FAILED(segment_GetTrack(iface, &GUID_NULL, group, i, &track))) break;
371 {
373 continue;
374 }
375 if (index == count || index == DMUS_SEG_ANYTRACK)
378
379 if (SUCCEEDED(hr))
380 return hr;
381 count++;
382 }
383
384 TRACE("(%p): not found\n", This);
385
386 return hr;
387}
388
389static HRESULT WINAPI segment_SetParam(IDirectMusicSegment8 *iface, REFGUID type,
390 DWORD group, DWORD index, MUSIC_TIME music_time, void *param)
391{
393 struct track_entry *entry;
394 HRESULT hr;
395
396 TRACE("(%p, %s, %#lx, %ld, %ld, %p)\n", This, debugstr_dmguid(type), group,
397 index, music_time, param);
398
400 {
401 if (group != -1)
402 {
403 if (!(group & entry->dwGroupBits)) continue;
404 if (index != DMUS_SEG_ALLTRACKS && index--) continue;
405 }
406
408 && FAILED(hr = IDirectMusicTrack_SetParam(entry->pTrack, type, music_time, param)))
409 WARN("SetParam for track %p failed, hr %#lx\n", entry->pTrack, hr);
410 }
411
412 return S_OK;
413}
414
415static HRESULT WINAPI segment_Clone(IDirectMusicSegment8 *iface, MUSIC_TIME start, MUSIC_TIME end,
416 IDirectMusicSegment **segment)
417{
419 struct segment *clone;
420 IDirectMusicTrack *track;
421 struct track_entry *entry;
422 HRESULT hr = S_OK;
423
424 TRACE("(%p, %ld, %ld, %p)\n", This, start, end, segment);
425
426 if (!segment) return E_POINTER;
427
428 if (!(clone = segment_create()))
429 {
430 *segment = NULL;
431 return E_OUTOFMEMORY;
432 }
433
434 clone->header = This->header;
435 if ((clone->pGraph = This->pGraph)) IDirectMusicGraph_AddRef(clone->pGraph);
436
438 {
439 if (FAILED(hr = IDirectMusicTrack_Clone(entry->pTrack, start, end, &track))) break;
440 hr = segment_append_track(clone, track, entry->dwGroupBits, entry->flags);
442 if (FAILED(hr)) break;
443 }
444
445 *segment = (IDirectMusicSegment *)&clone->IDirectMusicSegment8_iface;
446 return FAILED(hr) ? S_FALSE : S_OK;
447}
448
449static HRESULT WINAPI segment_SetStartPoint(IDirectMusicSegment8 *iface, MUSIC_TIME start)
450{
452
453 TRACE("(%p, %ld)\n", This, start);
454
455 if (start >= This->header.mtLength) return DMUS_E_OUT_OF_RANGE;
456 This->header.mtPlayStart = start;
457
458 return S_OK;
459}
460
461static HRESULT WINAPI segment_GetStartPoint(IDirectMusicSegment8 *iface, MUSIC_TIME *start)
462{
464
465 TRACE("(%p, %p)\n", This, start);
466 if (!start) return E_POINTER;
467 *start = This->header.mtPlayStart;
468
469 return S_OK;
470}
471
472static HRESULT WINAPI segment_SetLoopPoints(IDirectMusicSegment8 *iface, MUSIC_TIME start, MUSIC_TIME end)
473{
475
476 TRACE("(%p, %ld, %ld)\n", This, start, end);
477
478 if ((end || start) && (start >= This->header.mtLength || end > This->header.mtLength || start > end))
479 return DMUS_E_OUT_OF_RANGE;
480 This->header.mtLoopStart = start;
481 This->header.mtLoopEnd = end;
482
483 return S_OK;
484}
485
486static HRESULT WINAPI segment_GetLoopPoints(IDirectMusicSegment8 *iface, MUSIC_TIME *start, MUSIC_TIME *end)
487{
489
490 TRACE("(%p, %p, %p)\n", This, start, end);
491
492 if (!start || !end) return E_POINTER;
493 *start = This->header.mtLoopStart;
494 *end = This->header.mtLoopEnd;
495
496 return S_OK;
497}
498
499static HRESULT WINAPI segment_SetPChannelsUsed(IDirectMusicSegment8 *iface, DWORD dwNumPChannels, DWORD *paPChannels)
500{
502 FIXME("(%p, %ld, %p): stub\n", This, dwNumPChannels, paPChannels);
503 return S_OK;
504}
505
506static HRESULT WINAPI segment_SetTrackConfig(IDirectMusicSegment8 *iface, REFGUID rguidTrackClassID,
507 DWORD dwGroupBits, DWORD dwIndex, DWORD dwFlagsOn, DWORD dwFlagsOff)
508{
510 FIXME("(%p, %s, %#lx, %ld, %ld, %ld): stub\n", This, debugstr_dmguid(rguidTrackClassID),
511 dwGroupBits, dwIndex, dwFlagsOn, dwFlagsOff);
512 return S_OK;
513}
514
515static HRESULT WINAPI segment_GetAudioPathConfig(IDirectMusicSegment8 *iface, IUnknown **ppAudioPathConfig)
516{
518 FIXME("(%p, %p): stub\n", This, ppAudioPathConfig);
519 return S_OK;
520}
521
522static HRESULT WINAPI segment_Compose(IDirectMusicSegment8 *iface, MUSIC_TIME mtTime,
523 IDirectMusicSegment *pFromSegment, IDirectMusicSegment *pToSegment, IDirectMusicSegment **ppComposedSegment)
524{
526 FIXME("(%p, %ld, %p, %p, %p): stub\n", This, mtTime, pFromSegment, pToSegment, ppComposedSegment);
527 return S_OK;
528}
529
530static HRESULT WINAPI segment_Download(IDirectMusicSegment8 *iface, IUnknown *audio_path)
531{
533 TRACE("(%p, %p)\n", This, audio_path);
534 return IDirectMusicSegment8_SetParam(iface, &GUID_DownloadToAudioPath, -1, DMUS_SEG_ALLTRACKS, 0, audio_path);
535}
536
537static HRESULT WINAPI segment_Unload(IDirectMusicSegment8 *iface, IUnknown *audio_path)
538{
540 TRACE("(%p, %p)\n", This, audio_path);
541 return IDirectMusicSegment8_SetParam(iface, &GUID_UnloadFromAudioPath, -1, DMUS_SEG_ALLTRACKS, 0, audio_path);
542}
543
544static const IDirectMusicSegment8Vtbl segment_vtbl =
545{
577};
578
580{
581 struct chunk_entry riff = {0};
583 HRESULT hr;
584
585 TRACE("(%p, %p, %p)\n", iface, stream, desc);
586
587 if (!stream || !desc)
588 return E_POINTER;
589
590 if ((hr = stream_get_chunk(stream, &riff)) != S_OK)
591 return hr;
592 if (riff.id != FOURCC_RIFF || !(riff.type == DMUS_FOURCC_SEGMENT_FORM ||
593 riff.type == mmioFOURCC('W','A','V','E'))) {
594 TRACE("loading failed: unexpected %s\n", debugstr_chunk(&riff));
596 return E_FAIL;
597 }
598
599 if (riff.type == DMUS_FOURCC_SEGMENT_FORM)
600 supported |= DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY;
601 else
602 supported |= DMUS_OBJ_NAME_INFO;
603 hr = dmobj_parsedescriptor(stream, &riff, desc, supported);
604 if (FAILED(hr))
605 return hr;
606
607 desc->guidClass = CLSID_DirectMusicSegment;
608 desc->dwValidData |= DMUS_OBJ_CLASS;
609
611 return S_OK;
612}
613
614static const IDirectMusicObjectVtbl segment_object_vtbl =
615{
622};
623
624static HRESULT parse_track_form(struct segment *This, IStream *stream, const struct chunk_entry *riff)
625{
626 struct chunk_entry chunk = {.parent = riff};
627 IDirectMusicTrack *track = NULL;
628 IPersistStream *ps = NULL;
629 IStream *clone;
631 DMUS_IO_TRACK_EXTRAS_HEADER txhdr = {0};
632 HRESULT hr;
633
634 TRACE("Parsing track form in %p: %s\n", stream, debugstr_chunk(riff));
635
636 /* First chunk must be the track header */
638 return hr;
641 if (FAILED(hr = stream_chunk_get_data(stream, &chunk, &thdr, sizeof(thdr))))
642 return hr;
643 TRACE("Found DMUS_IO_TRACK_HEADER\n");
644 TRACE("\tclass: %s\n", debugstr_guid (&thdr.guidClassID));
645 TRACE("\tdwGroup: %#lx\n", thdr.dwGroup);
646 TRACE("\tckid: %s\n", debugstr_fourcc (thdr.ckid));
647 TRACE("\tfccType: %s\n", debugstr_fourcc (thdr.fccType));
648
649 if (!!thdr.ckid == !!thdr.fccType) {
650 WARN("One and only one of the ckid (%s) and fccType (%s) need to be set\n",
653 }
654
655 /* Optional chunks */
656 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) {
657 if ((thdr.ckid && chunk.id == thdr.ckid) ||
658 (!thdr.ckid && (chunk.id == FOURCC_LIST || chunk.id == FOURCC_RIFF) &&
659 chunk.type == thdr.fccType))
660 break;
661
663 SUCCEEDED(stream_chunk_get_data(stream, &chunk, &txhdr, sizeof(txhdr)))) {
664 FIXME("DMUS_IO_TRACK_EXTRAS_HEADER chunk not fully handled\n");
665 TRACE("dwFlags: %#lx, dwPriority: %lu\n", txhdr.dwFlags, txhdr.dwPriority);
666 }
667 }
668 if (hr != S_OK)
669 return hr == S_FALSE ? DMUS_E_TRACK_NOT_FOUND : hr;
670
671 /* Some DirectMusicTrack implementation expect the stream to start with their data chunk */
672 if (FAILED(hr = IStream_Clone(stream, &clone)))
673 return hr;
675
676 /* Load the track */
677 hr = CoCreateInstance(&thdr.guidClassID, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicTrack,
678 (void **)&track);
679 if (FAILED(hr))
680 goto done;
682 if (FAILED(hr))
683 goto done;
684 hr = IPersistStream_Load(ps, clone);
685 if (FAILED(hr))
686 goto done;
687
688 hr = segment_append_track(This, track, thdr.dwGroup, txhdr.dwFlags);
689
690done:
691 if (ps)
692 IPersistStream_Release(ps);
693 if (track)
695 IStream_Release(clone);
696
697 return hr;
698}
699
700static HRESULT parse_track_list(struct segment *This, IStream *stream, const struct chunk_entry *trkl)
701{
702 struct chunk_entry chunk = {.parent = trkl};
703 HRESULT hr;
704
705 TRACE("Parsing track list in %p: %s\n", stream, debugstr_chunk(trkl));
706
707 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
708 if (chunk.id == FOURCC_RIFF && chunk.type == DMUS_FOURCC_TRACK_FORM)
710
711 return SUCCEEDED(hr) ? S_OK : hr;
712}
713
715{
716 unsigned int dx = 9;
717
718 if (size == offsetof(DMUS_IO_SEGMENT_HEADER, rtLength))
719 dx = 7;
720 else if (size == offsetof(DMUS_IO_SEGMENT_HEADER, rtLoopStart))
721 dx = 8;
722 TRACE("Found DirectX%d DMUS_IO_SEGMENT_HEADER\n", dx);
723 TRACE("\tdwRepeats: %lu\n", h->dwRepeats);
724 TRACE("\tmtLength: %lu\n", h->mtLength);
725 TRACE("\tmtPlayStart: %lu\n", h->mtPlayStart);
726 TRACE("\tmtLoopStart: %lu\n", h->mtLoopStart);
727 TRACE("\tmtLoopEnd: %lu\n", h->mtLoopEnd);
728 TRACE("\tdwResolution: %lu\n", h->dwResolution);
729 if (dx >= 8) {
730 TRACE("\trtLength: %s\n", wine_dbgstr_longlong(h->rtLength));
731 TRACE("\tdwFlags: %lu\n", h->dwFlags);
732 TRACE("\tdwReserved: %lu\n", h->dwReserved);
733 }
734 if (dx == 9) {
735 TRACE("\trtLoopStart: %s\n", wine_dbgstr_longlong(h->rtLoopStart));
736 TRACE("\trtLoopEnd: %s\n", wine_dbgstr_longlong(h->rtLoopEnd));
737 if (size > offsetof(DMUS_IO_SEGMENT_HEADER, rtPlayStart))
738 TRACE("\trtPlayStart: %s\n", wine_dbgstr_longlong(h->rtPlayStart));
739 }
740}
741
742static HRESULT parse_dmsg_chunk(struct segment *This, IStream *stream, const struct chunk_entry *riff)
743{
744 struct chunk_entry chunk = {.parent = riff};
745 HRESULT hr;
746
747 TRACE("Parsing segment form in %p: %s\n", stream, debugstr_chunk(riff));
748
751 return hr;
752
753 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) {
754 switch (chunk.id) {
756 /* DX9 without rtPlayStart field */
757 if (chunk.size == offsetof(DMUS_IO_SEGMENT_HEADER, rtPlayStart))
758 WARN("Missing rtPlayStart field in %s\n", debugstr_chunk(&chunk));
759 /* DX7, DX8 and DX9 structure sizes */
760 else if (chunk.size != offsetof(DMUS_IO_SEGMENT_HEADER, rtLength) &&
761 chunk.size != offsetof(DMUS_IO_SEGMENT_HEADER, rtLoopStart) &&
762 chunk.size != sizeof(DMUS_IO_SEGMENT_HEADER)) {
763 WARN("Invalid size of %s\n", debugstr_chunk(&chunk));
764 break;
765 }
766 if (FAILED(hr = stream_chunk_get_data(stream, &chunk, &This->header, chunk.size))) {
767 WARN("Failed to read data of %s\n", debugstr_chunk(&chunk));
768 return hr;
769 }
771 break;
772 case FOURCC_LIST:
773 if (chunk.type == DMUS_FOURCC_TRACK_LIST)
775 return hr;
776 break;
777 case FOURCC_RIFF:
778 FIXME("Loading of embedded RIFF form %s\n", debugstr_fourcc(chunk.type));
779 break;
780 }
781 }
782
783 return SUCCEEDED(hr) ? S_OK : hr;
784}
785
787{
788 return CONTAINING_RECORD(iface, struct segment, dmobj.IPersistStream_iface);
789}
790
792{
793 struct segment *This = impl_from_IPersistStream(iface);
794 struct chunk_entry chunk = {0};
795 HRESULT hr;
796
797 TRACE("(%p, %p): Loading\n", This, stream);
798
799 if (!stream) return E_POINTER;
800
801 if ((hr = stream_get_chunk(stream, &chunk)) == S_OK)
802 {
803 switch (MAKE_IDTYPE(chunk.id, chunk.type))
804 {
807 break;
808
809 case mmioFOURCC('M','T','h','d'):
810 hr = parse_midi(stream, &This->IDirectMusicSegment8_iface);
811 break;
812
813 case MAKE_IDTYPE(FOURCC_RIFF, mmioFOURCC('W','A','V','E')):
814 {
815 IDirectMusicTrack8 *track;
816
817 TRACE("Loading segment %p from wave file\n", This);
818
819 This->header.mtLength = 1;
820 if (FAILED(hr = wave_track_create_from_chunk(stream, &chunk, &track))) break;
821 hr = segment_append_track(This, (IDirectMusicTrack *)track, 1, 0);
823 break;
824 }
825
826 default:
827 WARN("Invalid segment chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
829 break;
830 }
831 }
832
833 if (chunk.id != mmioFOURCC('M', 'T', 'h', 'd'))
835
836 if (FAILED(hr))
837 {
838 WARN("Failed to load segment from stream %p, hr %#lx\n", stream, hr);
840 }
841
842 This->dmobj.desc.guidClass = CLSID_DirectMusicSegment;
843 This->dmobj.desc.dwValidData |= DMUS_OBJ_CLASS;
844
845 return S_OK;
846}
847
848static const IPersistStreamVtbl segment_persist_stream_vtbl =
849{
858};
859
860static struct segment *segment_create(void)
861{
862 struct segment *obj;
863
864 if (!(obj = calloc(1, sizeof(*obj)))) return NULL;
865 obj->IDirectMusicSegment8_iface.lpVtbl = &segment_vtbl;
866 obj->ref = 1;
867 dmobject_init(&obj->dmobj, &CLSID_DirectMusicSegment, (IUnknown *)&obj->IDirectMusicSegment8_iface);
868 obj->dmobj.IDirectMusicObject_iface.lpVtbl = &segment_object_vtbl;
869 obj->dmobj.IPersistStream_iface.lpVtbl = &segment_persist_stream_vtbl;
870 list_init(&obj->tracks);
871
872 return obj;
873}
874
875/* for ClassFactory */
877{
878 struct segment *obj;
879 HRESULT hr;
880
881 if (!(obj = segment_create()))
882 {
883 *ret_iface = NULL;
884 return E_OUTOFMEMORY;
885 }
886
887 hr = IDirectMusicSegment8_QueryInterface(&obj->IDirectMusicSegment8_iface, guid, ret_iface);
888 IDirectMusicSegment8_Release(&obj->IDirectMusicSegment8_iface);
889
890 return hr;
891}
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
Definition: list.h:39
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
GUID guid
Definition: version.c:147
#define DMUS_E_UNSUPPORTED_STREAM
Definition: dmerror.h:100
#define DMUS_E_TRACK_HDR_NOT_FIRST_CK
Definition: dmerror.h:103
#define DMUS_E_INVALID_TRACK_HDR
Definition: dmerror.h:105
#define DMUS_E_NOT_FOUND
Definition: dmerror.h:109
#define DMUS_E_TRACK_NOT_FOUND
Definition: dmerror.h:114
#define DMUS_E_OUT_OF_RANGE
Definition: dmerror.h:126
HRESULT parse_midi(IStream *stream, IDirectMusicSegment8 *segment)
Definition: midi.c:483
HRESULT wave_track_create_from_chunk(IStream *stream, struct chunk_entry *parent, IDirectMusicTrack8 **ret_iface)
Definition: wavetrack.c:605
HRESULT create_dmsegmentstate(REFIID riid, void **ret_iface)
Definition: segmentstate.c:293
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_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
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
HRESULT WINAPI unimpl_IPersistStream_GetSizeMax(IPersistStream *iface, ULARGE_INTEGER *size)
Definition: dmobject.c:742
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
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 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
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 WINAPI unimpl_IPersistStream_Save(IPersistStream *iface, IStream *stream, BOOL clear_dirty)
Definition: dmobject.c:735
static HRESULT stream_reset_chunk_data(IStream *stream, const struct chunk_entry *chunk)
Definition: dmobject.h:50
static HRESULT stream_reset_chunk_start(IStream *stream, const struct chunk_entry *chunk)
Definition: dmobject.h:61
#define DMUS_OBJ_NAME_INFO
Definition: dmobject.h:97
#define MAKE_IDTYPE(id, type)
Definition: dmobject.h:33
#define IDirectMusicTrack8_Release(p)
Definition: dmplugin.h:275
#define IDirectMusicTrack_SetParam(p, a, b, c)
Definition: dmplugin.h:233
#define IDirectMusicTrack_GetParam(p, a, b, c, d)
Definition: dmplugin.h:232
#define IDirectMusicTrack_Release(p)
Definition: dmplugin.h:226
LONG MUSIC_TIME
Definition: dmplugin.h:95
#define IDirectMusicTrack_Init(p, a)
Definition: dmplugin.h:228
#define IDirectMusicTrack_QueryInterface(p, a, b)
Definition: dmplugin.h:224
#define IDirectMusicTrack_IsParamSupported(p, a)
Definition: dmplugin.h:234
#define IDirectMusicTrack_AddRef(p)
Definition: dmplugin.h:225
#define IDirectMusicTrack_Clone(p, a, b, c)
Definition: dmplugin.h:237
#define DMUS_FOURCC_TRACK_FORM
Definition: dmusicf.h:141
#define DMUS_FOURCC_SEGMENT_FORM
Definition: dmusicf.h:114
#define DMUS_FOURCC_TRACK_EXTRAS_CHUNK
Definition: dmusicf.h:143
#define DMUS_FOURCC_SEGMENT_CHUNK
Definition: dmusicf.h:115
#define DMUS_FOURCC_TRACK_LIST
Definition: dmusicf.h:116
#define DMUS_FOURCC_TRACK_CHUNK
Definition: dmusicf.h:142
#define DMUS_SEG_ALLTRACKS
Definition: dmusici.h:317
#define IDirectMusicSegment8_Release(p)
Definition: dmusici.h:1083
#define DMUS_OBJ_NAME
Definition: dmusici.h:267
#define DMUS_SEG_ANYTRACK
Definition: dmusici.h:318
#define IDirectMusicSegment8_QueryInterface(p, a, b)
Definition: dmusici.h:1081
#define IDirectMusicSegment8_SetParam(p, a, b, c, d, e)
Definition: dmusici.h:1101
#define DMUS_OBJ_CLASS
Definition: dmusici.h:266
#define IDirectMusicGraph_Release(p)
Definition: dmusici.h:1472
#define DMUS_OBJ_VERSION
Definition: dmusici.h:272
#define IDirectMusicGraph_AddRef(p)
Definition: dmusici.h:1471
#define DMUS_OBJ_CATEGORY
Definition: dmusici.h:268
#define DMUS_OBJ_OBJECT
Definition: dmusici.h:265
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLboolean GLuint group
Definition: glext.h:11120
GLfloat param
Definition: glext.h:5796
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
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
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define GUID_NULL
Definition: ks.h:106
GLint dx
Definition: linetemp.h:97
__u16 time
Definition: mkdosfs.c:8
#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
long LONG
Definition: pedump.c:60
const GUID IID_IPersistStream
Definition: proxy.cpp:13
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static unsigned __int64 next
Definition: rand_nt.c:6
#define calloc
Definition: rosglue.h:14
#define offsetof(TYPE, MEMBER)
static __inline const char * debugstr_fourcc(unsigned int cc)
Definition: debug.h:397
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
static const IDirectMusicSegment8Vtbl segment_vtbl
Definition: segment.c:544
static HRESULT parse_track_form(struct segment *This, IStream *stream, const struct chunk_entry *riff)
Definition: segment.c:624
static ULONG WINAPI segment_AddRef(IDirectMusicSegment8 *iface)
Definition: segment.c:86
static HRESULT WINAPI segment_GetStartPoint(IDirectMusicSegment8 *iface, MUSIC_TIME *start)
Definition: segment.c:461
static HRESULT WINAPI segment_SetLoopPoints(IDirectMusicSegment8 *iface, MUSIC_TIME start, MUSIC_TIME end)
Definition: segment.c:472
static HRESULT WINAPI segment_InitPlay(IDirectMusicSegment8 *iface, IDirectMusicSegmentState **state, IDirectMusicPerformance *performance, DWORD flags)
Definition: segment.c:299
static struct segment * segment_create(void)
Definition: segment.c:860
static HRESULT WINAPI segment_SetStartPoint(IDirectMusicSegment8 *iface, MUSIC_TIME start)
Definition: segment.c:449
static HRESULT parse_dmsg_chunk(struct segment *This, IStream *stream, const struct chunk_entry *riff)
Definition: segment.c:742
static const IPersistStreamVtbl segment_persist_stream_vtbl
Definition: segment.c:848
static HRESULT WINAPI segment_SetRepeats(IDirectMusicSegment8 *iface, DWORD repeats)
Definition: segment.c:152
static ULONG WINAPI segment_Release(IDirectMusicSegment8 *iface)
Definition: segment.c:96
static HRESULT WINAPI segment_Download(IDirectMusicSegment8 *iface, IUnknown *audio_path)
Definition: segment.c:530
static HRESULT WINAPI segment_RemoveTrack(IDirectMusicSegment8 *iface, IDirectMusicTrack *track)
Definition: segment.c:279
static void track_entry_destroy(struct track_entry *entry)
Definition: segment.c:33
static struct segment * impl_from_IDirectMusicSegment8(IDirectMusicSegment8 *iface)
Definition: segment.c:56
static HRESULT WINAPI segment_SetTrackConfig(IDirectMusicSegment8 *iface, REFGUID rguidTrackClassID, DWORD dwGroupBits, DWORD dwIndex, DWORD dwFlagsOn, DWORD dwFlagsOff)
Definition: segment.c:506
static HRESULT WINAPI segment_GetGraph(IDirectMusicSegment8 *iface, IDirectMusicGraph **graph)
Definition: segment.c:314
static HRESULT WINAPI segment_GetDefaultResolution(IDirectMusicSegment8 *iface, DWORD *resolution)
Definition: segment.c:162
static HRESULT WINAPI segment_QueryInterface(IDirectMusicSegment8 *iface, REFIID riid, void **ret_iface)
Definition: segment.c:61
static HRESULT WINAPI segment_AddNotificationType(IDirectMusicSegment8 *iface, REFGUID rguidNotificationType)
Definition: segment.c:339
static HRESULT WINAPI segment_GetLength(IDirectMusicSegment8 *iface, MUSIC_TIME *length)
Definition: segment.c:117
static HRESULT WINAPI segment_GetParam(IDirectMusicSegment8 *iface, REFGUID type, DWORD group, DWORD index, MUSIC_TIME time, MUSIC_TIME *next, void *param)
Definition: segment.c:353
static HRESULT WINAPI segment_GetRepeats(IDirectMusicSegment8 *iface, DWORD *repeats)
Definition: segment.c:140
static HRESULT segment_append_track(struct segment *This, IDirectMusicTrack *track, DWORD group, DWORD flags)
Definition: segment.c:246
static HRESULT parse_track_list(struct segment *This, IStream *stream, const struct chunk_entry *trkl)
Definition: segment.c:700
static HRESULT WINAPI segment_SetDefaultResolution(IDirectMusicSegment8 *iface, DWORD resolution)
Definition: segment.c:174
static HRESULT WINAPI segment_Unload(IDirectMusicSegment8 *iface, IUnknown *audio_path)
Definition: segment.c:537
static HRESULT WINAPI segment_RemoveNotificationType(IDirectMusicSegment8 *iface, REFGUID rguidNotificationType)
Definition: segment.c:346
static HRESULT WINAPI segment_SetLength(IDirectMusicSegment8 *iface, MUSIC_TIME length)
Definition: segment.c:129
static HRESULT WINAPI segment_SetParam(IDirectMusicSegment8 *iface, REFGUID type, DWORD group, DWORD index, MUSIC_TIME music_time, void *param)
Definition: segment.c:389
static void dump_segment_header(DMUS_IO_SEGMENT_HEADER *h, DWORD size)
Definition: segment.c:714
static HRESULT WINAPI segment_GetLoopPoints(IDirectMusicSegment8 *iface, MUSIC_TIME *start, MUSIC_TIME *end)
Definition: segment.c:486
static HRESULT WINAPI segment_Clone(IDirectMusicSegment8 *iface, MUSIC_TIME start, MUSIC_TIME end, IDirectMusicSegment **segment)
Definition: segment.c:415
HRESULT create_dmsegment(REFIID guid, void **ret_iface)
Definition: segment.c:876
static const IDirectMusicObjectVtbl segment_object_vtbl
Definition: segment.c:614
static HRESULT WINAPI segment_persist_stream_Load(IPersistStream *iface, IStream *stream)
Definition: segment.c:791
static HRESULT WINAPI segment_InsertTrack(IDirectMusicSegment8 *iface, IDirectMusicTrack *track, DWORD group)
Definition: segment.c:264
static HRESULT WINAPI segment_GetTrack(IDirectMusicSegment8 *iface, REFGUID type, DWORD group, DWORD index, IDirectMusicTrack **ret_track)
Definition: segment.c:184
static HRESULT WINAPI segment_object_ParseDescriptor(IDirectMusicObject *iface, IStream *stream, DMUS_OBJECTDESC *desc)
Definition: segment.c:579
static HRESULT WINAPI segment_Compose(IDirectMusicSegment8 *iface, MUSIC_TIME mtTime, IDirectMusicSegment *pFromSegment, IDirectMusicSegment *pToSegment, IDirectMusicSegment **ppComposedSegment)
Definition: segment.c:522
static struct segment * impl_from_IPersistStream(IPersistStream *iface)
Definition: segment.c:786
static HRESULT WINAPI segment_GetAudioPathConfig(IDirectMusicSegment8 *iface, IUnknown **ppAudioPathConfig)
Definition: segment.c:515
static HRESULT WINAPI segment_SetPChannelsUsed(IDirectMusicSegment8 *iface, DWORD dwNumPChannels, DWORD *paPChannels)
Definition: segment.c:499
static HRESULT WINAPI segment_SetGraph(IDirectMusicSegment8 *iface, IDirectMusicGraph *graph)
Definition: segment.c:327
static HRESULT WINAPI segment_GetTrackGroup(IDirectMusicSegment8 *iface, IDirectMusicTrack *track, DWORD *ret_group)
Definition: segment.c:225
#define TRACE(s)
Definition: solgame.cpp:4
Definition: scsiwmi.h:51
Definition: dmobject.h:26
FOURCC id
Definition: dmobject.h:27
FOURCC type
Definition: dmobject.h:29
uint16_t size
Definition: btrfs_drv.h:563
Definition: graph.c:32
Definition: send.c:48
IDirectMusicSegment8 IDirectMusicSegment8_iface
Definition: segment.c:46
LONG ref
Definition: segment.c:48
DMUS_IO_SEGMENT_HEADER header
Definition: segment.c:49
struct list tracks
Definition: segment.c:51
IDirectMusicGraph * pGraph
Definition: segment.c:50
struct dmobject dmobj
Definition: segment.c:47
Definition: parse.h:23
Definition: segment.c:26
DWORD dwGroupBits
Definition: segment.c:28
IDirectMusicTrack * pTrack
Definition: segment.c:30
IDirectMusicTrack * track
Definition: segmentstate.c:29
DWORD flags
Definition: segment.c:29
struct list entry
Definition: segment.c:27
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480