vcruntime140_1: Add __CxxFrameHandler4 stub.
[wine.git] / dlls / dmime / segtriggertrack.c
blobd36412cfc3d669a287a5fb9b9c9441887c0395bb
1 /* IDirectMusicSegTriggerTrack Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
4 * Copyright (C) 2003-2004 Raphael Junqueira
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.
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.
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
21 #include "dmime_private.h"
22 #include "dmobject.h"
24 #include "wine/heap.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dmime);
27 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
29 /*****************************************************************************
30 * IDirectMusicSegTriggerTrack implementation
32 typedef struct IDirectMusicSegTriggerTrack {
33 IDirectMusicTrack8 IDirectMusicTrack8_iface;
34 struct dmobject dmobj;/* IPersistStream only */
35 LONG ref;
36 struct list Items;
37 } IDirectMusicSegTriggerTrack;
39 /* IDirectMusicSegTriggerTrack IDirectMusicTrack8 part: */
40 static inline IDirectMusicSegTriggerTrack *impl_from_IDirectMusicTrack8(IDirectMusicTrack8 *iface)
42 return CONTAINING_RECORD(iface, IDirectMusicSegTriggerTrack, IDirectMusicTrack8_iface);
45 static HRESULT WINAPI segment_track_QueryInterface(IDirectMusicTrack8 *iface, REFIID riid,
46 void **ret_iface)
48 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
50 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ret_iface);
52 *ret_iface = NULL;
54 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicTrack) ||
55 IsEqualIID(riid, &IID_IDirectMusicTrack8))
56 *ret_iface = iface;
57 else if (IsEqualIID(riid, &IID_IPersistStream))
58 *ret_iface = &This->dmobj.IPersistStream_iface;
59 else {
60 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
61 return E_NOINTERFACE;
64 IUnknown_AddRef((IUnknown*)*ret_iface);
65 return S_OK;
68 static ULONG WINAPI segment_track_AddRef(IDirectMusicTrack8 *iface)
70 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
71 LONG ref = InterlockedIncrement(&This->ref);
73 TRACE("(%p) ref=%d\n", This, ref);
75 return ref;
78 static ULONG WINAPI segment_track_Release(IDirectMusicTrack8 *iface)
80 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
81 LONG ref = InterlockedDecrement(&This->ref);
83 TRACE("(%p) ref=%d\n", This, ref);
85 if (!ref) {
86 struct list *cursor, *cursor2;
87 DMUS_PRIVATE_SEGMENT_ITEM *item;
89 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->Items) {
90 item = LIST_ENTRY(cursor, DMUS_PRIVATE_SEGMENT_ITEM, entry);
91 list_remove(cursor);
93 if (item->pObject)
94 IDirectMusicObject_Release(item->pObject);
95 heap_free(item);
98 heap_free(This);
99 DMIME_UnlockModule();
102 return ref;
105 static HRESULT WINAPI segment_track_Init(IDirectMusicTrack8 *iface, IDirectMusicSegment *pSegment)
107 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
108 FIXME("(%p, %p): stub\n", This, pSegment);
109 return S_OK;
112 static HRESULT WINAPI segment_track_InitPlay(IDirectMusicTrack8 *iface,
113 IDirectMusicSegmentState *pSegmentState, IDirectMusicPerformance *pPerformance,
114 void **ppStateData, DWORD dwVirtualTrack8ID, DWORD dwFlags)
116 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
117 FIXME("(%p, %p, %p, %p, %d, %d): stub\n", This, pSegmentState, pPerformance, ppStateData, dwVirtualTrack8ID, dwFlags);
118 return S_OK;
121 static HRESULT WINAPI segment_track_EndPlay(IDirectMusicTrack8 *iface, void *pStateData)
123 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
124 FIXME("(%p, %p): stub\n", This, pStateData);
125 return S_OK;
128 static HRESULT WINAPI segment_track_Play(IDirectMusicTrack8 *iface, void *pStateData,
129 MUSIC_TIME mtStart, MUSIC_TIME mtEnd, MUSIC_TIME mtOffset, DWORD dwFlags,
130 IDirectMusicPerformance *pPerf, IDirectMusicSegmentState *pSegSt, DWORD dwVirtualID)
132 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
133 FIXME("(%p, %p, %d, %d, %d, %d, %p, %p, %d): stub\n", This, pStateData, mtStart, mtEnd, mtOffset, dwFlags, pPerf, pSegSt, dwVirtualID);
134 return S_OK;
137 static HRESULT WINAPI segment_track_GetParam(IDirectMusicTrack8 *iface, REFGUID type,
138 MUSIC_TIME time, MUSIC_TIME *next, void *param)
140 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
142 TRACE("(%p, %s, %d, %p, %p): not supported\n", This, debugstr_dmguid(type), time, next, param);
143 return DMUS_E_GET_UNSUPPORTED;
146 static HRESULT WINAPI segment_track_SetParam(IDirectMusicTrack8 *iface, REFGUID type,
147 MUSIC_TIME time, void *param)
149 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
151 TRACE("(%p, %s, %d, %p): not supported\n", This, debugstr_dmguid(type), time, param);
152 return S_OK;
155 static HRESULT WINAPI segment_track_IsParamSupported(IDirectMusicTrack8 *iface, REFGUID type)
157 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
159 TRACE("(%p, %s)\n", This, debugstr_dmguid(type));
160 return S_OK;
163 static HRESULT WINAPI segment_track_AddNotificationType(IDirectMusicTrack8 *iface,
164 REFGUID notiftype)
166 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
168 TRACE("(%p, %s): method not implemented\n", This, debugstr_dmguid(notiftype));
169 return E_NOTIMPL;
172 static HRESULT WINAPI segment_track_RemoveNotificationType(IDirectMusicTrack8 *iface,
173 REFGUID notiftype)
175 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
177 TRACE("(%p, %s): method not implemented\n", This, debugstr_dmguid(notiftype));
178 return E_NOTIMPL;
181 static HRESULT WINAPI segment_track_Clone(IDirectMusicTrack8 *iface, MUSIC_TIME mtStart,
182 MUSIC_TIME mtEnd, IDirectMusicTrack **ppTrack)
184 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
185 FIXME("(%p, %d, %d, %p): stub\n", This, mtStart, mtEnd, ppTrack);
186 return S_OK;
189 static HRESULT WINAPI segment_track_PlayEx(IDirectMusicTrack8 *iface, void *pStateData,
190 REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd, REFERENCE_TIME rtOffset, DWORD dwFlags,
191 IDirectMusicPerformance *pPerf, IDirectMusicSegmentState *pSegSt, DWORD dwVirtualID)
193 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
194 FIXME("(%p, %p, 0x%s, 0x%s, 0x%s, %d, %p, %p, %d): stub\n", This, pStateData, wine_dbgstr_longlong(rtStart),
195 wine_dbgstr_longlong(rtEnd), wine_dbgstr_longlong(rtOffset), dwFlags, pPerf, pSegSt, dwVirtualID);
196 return S_OK;
199 static HRESULT WINAPI segment_track_GetParamEx(IDirectMusicTrack8 *iface, REFGUID rguidType,
200 REFERENCE_TIME rtTime, REFERENCE_TIME *prtNext, void *pParam, void *pStateData,
201 DWORD dwFlags)
203 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
204 FIXME("(%p, %s, 0x%s, %p, %p, %p, %d): stub\n", This, debugstr_dmguid(rguidType),
205 wine_dbgstr_longlong(rtTime), prtNext, pParam, pStateData, dwFlags);
206 return S_OK;
209 static HRESULT WINAPI segment_track_SetParamEx(IDirectMusicTrack8 *iface, REFGUID rguidType,
210 REFERENCE_TIME rtTime, void *pParam, void *pStateData, DWORD dwFlags)
212 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
213 FIXME("(%p, %s, 0x%s, %p, %p, %d): stub\n", This, debugstr_dmguid(rguidType),
214 wine_dbgstr_longlong(rtTime), pParam, pStateData, dwFlags);
215 return S_OK;
218 static HRESULT WINAPI segment_track_Compose(IDirectMusicTrack8 *iface, IUnknown *context,
219 DWORD trackgroup, IDirectMusicTrack **track)
221 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
223 TRACE("(%p, %p, %d, %p): method not implemented\n", This, context, trackgroup, track);
224 return E_NOTIMPL;
227 static HRESULT WINAPI segment_track_Join(IDirectMusicTrack8 *iface, IDirectMusicTrack *newtrack,
228 MUSIC_TIME join, IUnknown *context, DWORD trackgroup, IDirectMusicTrack **resulttrack)
230 IDirectMusicSegTriggerTrack *This = impl_from_IDirectMusicTrack8(iface);
231 TRACE("(%p, %p, %d, %p, %d, %p): method not implemented\n", This, newtrack, join, context,
232 trackgroup, resulttrack);
233 return E_NOTIMPL;
236 static const IDirectMusicTrack8Vtbl dmtrack8_vtbl = {
237 segment_track_QueryInterface,
238 segment_track_AddRef,
239 segment_track_Release,
240 segment_track_Init,
241 segment_track_InitPlay,
242 segment_track_EndPlay,
243 segment_track_Play,
244 segment_track_GetParam,
245 segment_track_SetParam,
246 segment_track_IsParamSupported,
247 segment_track_AddNotificationType,
248 segment_track_RemoveNotificationType,
249 segment_track_Clone,
250 segment_track_PlayEx,
251 segment_track_GetParamEx,
252 segment_track_SetParamEx,
253 segment_track_Compose,
254 segment_track_Join
257 static HRESULT parse_segment(IDirectMusicSegTriggerTrack *This, DMUS_PRIVATE_CHUNK *pChunk,
258 IStream *pStm)
260 DMUS_PRIVATE_CHUNK Chunk;
261 DWORD ListSize[3], ListCount[3];
262 LARGE_INTEGER liMove; /* used when skipping chunks */
263 HRESULT hr;
265 IDirectMusicObject* pObject = NULL;
266 LPDMUS_PRIVATE_SEGMENT_ITEM pNewItem = NULL;
268 if (pChunk->fccID != DMUS_FOURCC_SEGMENT_LIST) {
269 ERR_(dmfile)(": %s chunk should be a SEGMENT list\n", debugstr_fourcc (pChunk->fccID));
270 return E_FAIL;
273 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
274 ListCount[0] = 0;
276 do {
277 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
278 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
279 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
280 switch (Chunk.fccID) {
281 case DMUS_FOURCC_SEGMENTITEM_CHUNK: {
282 TRACE_(dmfile)(": segment item chunk\n");
283 /** alloc new item entry */
284 pNewItem = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_SEGMENT_ITEM));
285 if (!pNewItem)
286 return E_OUTOFMEMORY;
288 IStream_Read (pStm, &pNewItem->header, sizeof(DMUS_IO_SEGMENT_ITEM_HEADER), NULL);
289 TRACE_(dmfile)(" - lTimePhysical: %u\n", pNewItem->header.lTimeLogical);
290 TRACE_(dmfile)(" - lTimePhysical: %u\n", pNewItem->header.lTimePhysical);
291 TRACE_(dmfile)(" - dwPlayFlags: 0x%08x\n", pNewItem->header.dwPlayFlags);
292 TRACE_(dmfile)(" - dwFlags: 0x%08x\n", pNewItem->header.dwFlags);
293 list_add_tail (&This->Items, &pNewItem->entry);
294 break;
296 case DMUS_FOURCC_SEGMENTITEMNAME_CHUNK: {
297 TRACE_(dmfile)(": segment item name chunk\n");
298 if (!pNewItem) {
299 ERR(": pNewItem not allocated, bad chunk order?\n");
300 return E_FAIL;
302 IStream_Read (pStm, pNewItem->wszName, Chunk.dwSize, NULL);
303 TRACE_(dmfile)(" - name: %s\n", debugstr_w(pNewItem->wszName));
304 break;
306 case FOURCC_LIST: {
307 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
308 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
309 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
310 ListCount[1] = 0;
311 switch (Chunk.fccID) {
312 case DMUS_FOURCC_REF_LIST: {
313 FIXME_(dmfile)(": DMRF (DM References) list\n");
314 hr = IDirectMusicUtils_IPersistStream_ParseReference(&This->dmobj.IPersistStream_iface,
315 &Chunk, pStm, &pObject);
316 if (FAILED(hr)) {
317 ERR(": could not load Reference\n");
318 return hr;
320 if (!pNewItem) {
321 ERR(": pNewItem not allocated, bad chunk order?\n");
322 return E_FAIL;
324 pNewItem->pObject = pObject;
325 break;
327 default: {
328 TRACE_(dmfile)(": unknown (skipping)\n");
329 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
330 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
331 break;
334 break;
336 default: {
337 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
338 liMove.QuadPart = Chunk.dwSize;
339 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
340 break;
343 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
344 } while (ListCount[0] < ListSize[0]);
346 return S_OK;
349 static HRESULT parse_segments_list(IDirectMusicSegTriggerTrack *This, DMUS_PRIVATE_CHUNK *pChunk,
350 IStream *pStm)
352 HRESULT hr = E_FAIL;
353 DMUS_PRIVATE_CHUNK Chunk;
354 DWORD ListSize[3], ListCount[3];
355 LARGE_INTEGER liMove; /* used when skipping chunks */
357 if (pChunk->fccID != DMUS_FOURCC_SEGMENTS_LIST) {
358 ERR_(dmfile)(": %s chunk should be a SEGMENTS list\n", debugstr_fourcc (pChunk->fccID));
359 return E_FAIL;
362 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
363 ListCount[0] = 0;
365 do {
366 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
367 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
368 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
369 switch (Chunk.fccID) {
370 case FOURCC_LIST: {
371 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
372 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
373 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
374 ListCount[1] = 0;
375 switch (Chunk.fccID) {
376 case DMUS_FOURCC_SEGMENT_LIST: {
377 TRACE_(dmfile)(": SEGMENT list\n");
378 hr = parse_segment(This, &Chunk, pStm);
379 if (FAILED(hr)) return hr;
380 break;
382 default: {
383 TRACE_(dmfile)(": unknown (skipping)\n");
384 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
385 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
386 break;
389 break;
391 default: {
392 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
393 liMove.QuadPart = Chunk.dwSize;
394 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
395 break;
398 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
399 } while (ListCount[0] < ListSize[0]);
401 return S_OK;
404 static HRESULT parse_seqtrack_list(IDirectMusicSegTriggerTrack *This, DMUS_PRIVATE_CHUNK *pChunk,
405 IStream *pStm)
407 HRESULT hr = E_FAIL;
408 DMUS_PRIVATE_CHUNK Chunk;
409 DWORD ListSize[3], ListCount[3];
410 LARGE_INTEGER liMove; /* used when skipping chunks */
412 if (pChunk->fccID != DMUS_FOURCC_SEGTRACK_LIST) {
413 ERR_(dmfile)(": %s chunk should be a SEGTRACK list\n", debugstr_fourcc (pChunk->fccID));
414 return E_FAIL;
417 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
418 ListCount[0] = 0;
420 do {
421 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
422 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
423 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
424 switch (Chunk.fccID) {
425 case DMUS_FOURCC_SEGTRACK_CHUNK: {
426 TRACE_(dmfile)(": segment trigger track chunk\n");
427 liMove.QuadPart = Chunk.dwSize;
428 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
429 break;
431 case FOURCC_LIST: {
432 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
433 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
434 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
435 ListCount[1] = 0;
436 switch (Chunk.fccID) {
437 case DMUS_FOURCC_SEGMENTS_LIST: {
438 TRACE_(dmfile)(": SEGMENTS list\n");
439 hr = parse_segments_list(This, &Chunk, pStm);
440 if (FAILED(hr)) return hr;
441 break;
443 default: {
444 TRACE_(dmfile)(": unknown (skipping)\n");
445 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
446 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
447 break;
450 break;
452 default: {
453 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
454 liMove.QuadPart = Chunk.dwSize;
455 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
456 break;
459 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
460 } while (ListCount[0] < ListSize[0]);
462 return S_OK;
465 static inline IDirectMusicSegTriggerTrack *impl_from_IPersistStream(IPersistStream *iface)
467 return CONTAINING_RECORD(iface, IDirectMusicSegTriggerTrack, dmobj.IPersistStream_iface);
470 static HRESULT WINAPI trigger_IPersistStream_Load(IPersistStream *iface, IStream *pStm)
472 IDirectMusicSegTriggerTrack *This = impl_from_IPersistStream(iface);
473 DMUS_PRIVATE_CHUNK Chunk;
474 LARGE_INTEGER liMove;
475 HRESULT hr;
477 TRACE("(%p, %p): Loading\n", This, pStm);
479 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
480 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
481 switch (Chunk.fccID) {
482 case FOURCC_LIST: {
483 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
484 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
485 switch (Chunk.fccID) {
486 case DMUS_FOURCC_SEGTRACK_LIST: {
487 TRACE_(dmfile)(": segment trigger track list\n");
488 hr = parse_seqtrack_list(This, &Chunk, pStm);
489 if (FAILED(hr)) return hr;
490 break;
492 default: {
493 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
494 liMove.QuadPart = Chunk.dwSize;
495 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
496 return E_FAIL;
499 TRACE_(dmfile)(": reading finished\n");
500 break;
502 default: {
503 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
504 liMove.QuadPart = Chunk.dwSize;
505 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
506 return E_FAIL;
510 return S_OK;
513 static const IPersistStreamVtbl persiststream_vtbl = {
514 dmobj_IPersistStream_QueryInterface,
515 dmobj_IPersistStream_AddRef,
516 dmobj_IPersistStream_Release,
517 dmobj_IPersistStream_GetClassID,
518 unimpl_IPersistStream_IsDirty,
519 trigger_IPersistStream_Load,
520 unimpl_IPersistStream_Save,
521 unimpl_IPersistStream_GetSizeMax
524 /* for ClassFactory */
525 HRESULT WINAPI create_dmsegtriggertrack(REFIID lpcGUID, void **ppobj)
527 IDirectMusicSegTriggerTrack *track;
528 HRESULT hr;
530 track = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*track));
531 if (!track) {
532 *ppobj = NULL;
533 return E_OUTOFMEMORY;
535 track->IDirectMusicTrack8_iface.lpVtbl = &dmtrack8_vtbl;
536 track->ref = 1;
537 dmobject_init(&track->dmobj, &CLSID_DirectMusicSegTriggerTrack,
538 (IUnknown *)&track->IDirectMusicTrack8_iface);
539 track->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
540 list_init(&track->Items);
542 DMIME_LockModule();
543 hr = IDirectMusicTrack8_QueryInterface(&track->IDirectMusicTrack8_iface, lpcGUID, ppobj);
544 IDirectMusicTrack8_Release(&track->IDirectMusicTrack8_iface);
546 return hr;