styletrack.c 19.4 KB
Newer Older
1 2
/* IDirectMusicStyleTrack Implementation
 *
3
 * Copyright (C) 2003-2004 Rok Mandeljc
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "dmstyle_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dmstyle);
WINE_DECLARE_DEBUG_CHANNEL(dmfile);

/*****************************************************************************
 * IDirectMusicStyleTrack implementation
 */
/* IDirectMusicStyleTrack IUnknown part: */
29 30
HRESULT WINAPI IDirectMusicStyleTrack_IUnknown_QueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID *ppobj) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, UnknownVtbl, iface);
31
	TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
32

33 34 35 36 37 38 39 40
	if (IsEqualIID (riid, &IID_IUnknown)) {
		*ppobj = (LPUNKNOWN)&This->UnknownVtbl;
		IDirectMusicStyleTrack_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
		return S_OK;
	} else if (IsEqualIID (riid, &IID_IDirectMusicTrack)
	  || IsEqualIID (riid, &IID_IDirectMusicTrack8)) {
		*ppobj = (LPDIRECTMUSICTRACK8)&This->TrackVtbl;
		IDirectMusicStyleTrack_IDirectMusicTrack_AddRef ((LPDIRECTMUSICTRACK8)&This->TrackVtbl);
41 42
		return S_OK;
	} else if (IsEqualIID (riid, &IID_IPersistStream)) {
43 44
		*ppobj = (LPPERSISTSTREAM)&This->PersistStreamVtbl;
		IDirectMusicStyleTrack_IPersistStream_AddRef ((LPPERSISTSTREAM)&This->PersistStreamVtbl);
45 46 47
		return S_OK;
	}
	
48
	WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
49 50 51
	return E_NOINTERFACE;
}

52 53
ULONG WINAPI IDirectMusicStyleTrack_IUnknown_AddRef (LPUNKNOWN iface) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, UnknownVtbl, iface);
54 55 56 57
        ULONG ref = InterlockedIncrement(&This->ref);

	TRACE("(%p): AddRef from %ld\n", This, ref - 1);

58 59
	DMSTYLE_LockModule();

60
	return ref;
61 62
}

63 64
ULONG WINAPI IDirectMusicStyleTrack_IUnknown_Release (LPUNKNOWN iface) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, UnknownVtbl, iface);
65 66 67 68
	ULONG ref = InterlockedDecrement(&This->ref);

	TRACE("(%p): ReleaseRef to %ld\n", This, ref);

69 70 71
	if (ref == 0) {
		HeapFree(GetProcessHeap(), 0, This);
	}
72 73 74
	
	DMSTYLE_UnlockModule();
	
75 76 77
	return ref;
}

78
static const IUnknownVtbl DirectMusicStyleTrack_Unknown_Vtbl = {
79 80 81 82
	IDirectMusicStyleTrack_IUnknown_QueryInterface,
	IDirectMusicStyleTrack_IUnknown_AddRef,
	IDirectMusicStyleTrack_IUnknown_Release
};
83

84 85 86 87 88
/* IDirectMusicStyleTrack IDirectMusicTrack8 part: */
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_QueryInterface (LPDIRECTMUSICTRACK8 iface, REFIID riid, LPVOID *ppobj) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
	return IDirectMusicStyleTrack_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
}
89

90 91 92
ULONG WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_AddRef (LPDIRECTMUSICTRACK8 iface) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
	return IDirectMusicStyleTrack_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
93 94
}

95 96 97 98 99 100
ULONG WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_Release (LPDIRECTMUSICTRACK8 iface) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
	return IDirectMusicStyleTrack_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
}

HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_Init (LPDIRECTMUSICTRACK8 iface, IDirectMusicSegment* pSegment)
101
{
102 103 104 105
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
	FIXME("(%p, %p): stub\n", This, pSegment);
	return S_OK;
}
106

107 108 109
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_InitPlay (LPDIRECTMUSICTRACK8 iface, IDirectMusicSegmentState* pSegmentState, IDirectMusicPerformance* pPerformance, void** ppStateData, DWORD dwVirtualTrack8ID, DWORD dwFlags)
{
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
110 111 112 113
	FIXME("(%p, %p, %p, %p, %ld, %ld): stub\n", This, pSegmentState, pPerformance, ppStateData, dwVirtualTrack8ID, dwFlags);
	return S_OK;
}

114
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_EndPlay (LPDIRECTMUSICTRACK8 iface, void* pStateData)
115
{
116
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
117 118 119 120
	FIXME("(%p, %p): stub\n", This, pStateData);
	return S_OK;
}

121
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_Play (LPDIRECTMUSICTRACK8 iface, void* pStateData, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, MUSIC_TIME mtOffset, DWORD dwFlags, IDirectMusicPerformance* pPerf, IDirectMusicSegmentState* pSegSt, DWORD dwVirtualID)
122
{
123
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
124 125 126 127
	FIXME("(%p, %p, %ld, %ld, %ld, %ld, %p, %p, %ld): stub\n", This, pStateData, mtStart, mtEnd, mtOffset, dwFlags, pPerf, pSegSt, dwVirtualID);
	return S_OK;
}

128 129
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_GetParam (LPDIRECTMUSICTRACK8 iface, REFGUID rguidType, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
130
	FIXME("(%p, %s, %ld, %p, %p): stub\n", This, debugstr_dmguid(rguidType), mtTime, pmtNext, pParam);
131 132 133
	return S_OK;
}

134 135
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_SetParam (LPDIRECTMUSICTRACK8 iface, REFGUID rguidType, MUSIC_TIME mtTime, void* pParam) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
136
	FIXME("(%p, %s, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), mtTime, pParam);
137 138 139
	return S_OK;
}

140 141
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_IsParamSupported (LPDIRECTMUSICTRACK8 iface, REFGUID rguidType) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
142

143
	TRACE("(%p, %s): ", This, debugstr_dmguid(rguidType));
144 145 146 147 148 149 150
	if (IsEqualGUID (rguidType, &GUID_DisableTimeSig)
		|| IsEqualGUID (rguidType, &GUID_EnableTimeSig)
		|| IsEqualGUID (rguidType, &GUID_IDirectMusicStyle)
		|| IsEqualGUID (rguidType, &GUID_SeedVariations)
		|| IsEqualGUID (rguidType, &GUID_TimeSignature)) {
		TRACE("param supported\n");
		return S_OK;
151
	}
152 153 154 155
	TRACE("param unsupported\n");
	return DMUS_E_TYPE_UNSUPPORTED;
}

156 157
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_AddNotificationType (LPDIRECTMUSICTRACK8 iface, REFGUID rguidNotificationType) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
158
	FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
159 160 161
	return S_OK;
}

162 163
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_RemoveNotificationType (LPDIRECTMUSICTRACK8 iface, REFGUID rguidNotificationType) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
164
	FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
165 166 167
	return S_OK;
}

168 169
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_Clone (LPDIRECTMUSICTRACK8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, IDirectMusicTrack** ppTrack) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
170 171 172 173
	FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppTrack);
	return S_OK;
}

174 175
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_PlayEx (LPDIRECTMUSICTRACK8 iface, void* pStateData, REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd, REFERENCE_TIME rtOffset, DWORD dwFlags, IDirectMusicPerformance* pPerf, IDirectMusicSegmentState* pSegSt, DWORD dwVirtualID) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
176 177 178 179
	FIXME("(%p, %p, %lli, %lli, %lli, %ld, %p, %p, %ld): stub\n", This, pStateData, rtStart, rtEnd, rtOffset, dwFlags, pPerf, pSegSt, dwVirtualID);
	return S_OK;
}

180 181
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_GetParamEx (LPDIRECTMUSICTRACK8 iface, REFGUID rguidType, REFERENCE_TIME rtTime, REFERENCE_TIME* prtNext, void* pParam, void* pStateData, DWORD dwFlags) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
182
	FIXME("(%p, %s, %lli, %p, %p, %p, %ld): stub\n", This, debugstr_dmguid(rguidType), rtTime, prtNext, pParam, pStateData, dwFlags);
183 184 185
	return S_OK;
}

186 187
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_SetParamEx (LPDIRECTMUSICTRACK8 iface, REFGUID rguidType, REFERENCE_TIME rtTime, void* pParam, void* pStateData, DWORD dwFlags) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
188
	FIXME("(%p, %s, %lli, %p, %p, %ld): stub\n", This, debugstr_dmguid(rguidType), rtTime, pParam, pStateData, dwFlags);
189 190 191
	return S_OK;
}

192 193
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_Compose (LPDIRECTMUSICTRACK8 iface, IUnknown* pContext, DWORD dwTrackGroup, IDirectMusicTrack** ppResultTrack) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
194 195 196 197
	FIXME("(%p, %p, %ld, %p): stub\n", This, pContext, dwTrackGroup, ppResultTrack);
	return S_OK;
}

198 199
HRESULT WINAPI IDirectMusicStyleTrack_IDirectMusicTrack_Join (LPDIRECTMUSICTRACK8 iface, IDirectMusicTrack* pNewTrack, MUSIC_TIME mtJoin, IUnknown* pContext, DWORD dwTrackGroup, IDirectMusicTrack** ppResultTrack) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, TrackVtbl, iface);
200 201 202 203
	FIXME("(%p, %p, %ld, %p, %ld, %p): stub\n", This, pNewTrack, mtJoin, pContext, dwTrackGroup, ppResultTrack);
	return S_OK;
}

204
static const IDirectMusicTrack8Vtbl DirectMusicStyleTrack_Track_Vtbl = {
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
	IDirectMusicStyleTrack_IDirectMusicTrack_QueryInterface,
	IDirectMusicStyleTrack_IDirectMusicTrack_AddRef,
	IDirectMusicStyleTrack_IDirectMusicTrack_Release,
	IDirectMusicStyleTrack_IDirectMusicTrack_Init,
	IDirectMusicStyleTrack_IDirectMusicTrack_InitPlay,
	IDirectMusicStyleTrack_IDirectMusicTrack_EndPlay,
	IDirectMusicStyleTrack_IDirectMusicTrack_Play,
	IDirectMusicStyleTrack_IDirectMusicTrack_GetParam,
	IDirectMusicStyleTrack_IDirectMusicTrack_SetParam,
	IDirectMusicStyleTrack_IDirectMusicTrack_IsParamSupported,
	IDirectMusicStyleTrack_IDirectMusicTrack_AddNotificationType,
	IDirectMusicStyleTrack_IDirectMusicTrack_RemoveNotificationType,
	IDirectMusicStyleTrack_IDirectMusicTrack_Clone,
	IDirectMusicStyleTrack_IDirectMusicTrack_PlayEx,
	IDirectMusicStyleTrack_IDirectMusicTrack_GetParamEx,
	IDirectMusicStyleTrack_IDirectMusicTrack_SetParamEx,
	IDirectMusicStyleTrack_IDirectMusicTrack_Compose,
	IDirectMusicStyleTrack_IDirectMusicTrack_Join
223 224
};

225 226 227 228
/* IDirectMusicStyleTrack IPersistStream part: */
HRESULT WINAPI IDirectMusicStyleTrack_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);
	return IDirectMusicStyleTrack_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
229 230
}

231 232 233
ULONG WINAPI IDirectMusicStyleTrack_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
	ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);
	return IDirectMusicStyleTrack_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
234 235
}

236
ULONG WINAPI IDirectMusicStyleTrack_IPersistStream_Release (LPPERSISTSTREAM iface) {
237 238
  ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);
  return IDirectMusicStyleTrack_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
239 240
}

241
HRESULT WINAPI IDirectMusicStyleTrack_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
242 243 244 245
  ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);
  TRACE("(%p, %p)\n", This, pClassID);
  memcpy(pClassID, &CLSID_DirectMusicStyleTrack, sizeof(CLSID));
  return S_OK;
246 247
}

248
HRESULT WINAPI IDirectMusicStyleTrack_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
249 250 251 252 253 254
  ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);
  FIXME("(%p): stub, always S_FALSE\n", This);
  return S_FALSE;
}

static HRESULT IDirectMusicStyleTrack_IPersistStream_ParseStyleRef (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
255
  ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);
256 257 258
  DMUS_PRIVATE_CHUNK Chunk;
  DWORD ListSize[3], ListCount[3];
  LARGE_INTEGER liMove; /* used when skipping chunks */
259
  HRESULT hr;
260

261 262
  IDirectMusicObject* pObject = NULL;
  LPDMUS_PRIVATE_STYLE_ITEM pNewItem = NULL;
263 264

  if (pChunk->fccID != DMUS_FOURCC_STYLE_REF_LIST) {
265
    ERR_(dmfile)(": %s chunk should be a STYLE list\n", debugstr_fourcc (pChunk->fccID));
266 267 268 269 270 271 272 273 274 275 276 277 278
    return E_FAIL;
  }

  ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
  ListCount[0] = 0;

  do {
    IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
    ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
    TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
    switch (Chunk.fccID) { 
    case DMUS_FOURCC_TIME_STAMP_CHUNK: {
      TRACE_(dmfile)(": Time Stamp chunck \n");
279 280 281 282 283 284 285 286
      pNewItem = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_STYLE_ITEM));
      if (NULL == pNewItem) {
	ERR(": no more memory\n");
	return  E_OUTOFMEMORY;
      }
      IStream_Read (pStm, &pNewItem->dwTimeStamp, sizeof(DWORD), NULL);
      TRACE_(dmfile)(" - dwTimeStamp: %lu\n", pNewItem->dwTimeStamp);
      list_add_tail (&This->Items, &pNewItem->entry);      
287 288 289 290 291 292 293 294 295 296 297 298 299
      break;
    }
    case FOURCC_LIST: {
      IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
      TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
      ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
      ListCount[1] = 0;
      switch (Chunk.fccID) { 
	/**
	 * should be a DMRF (DirectMusic Reference) list @TODO
	 */
      case DMUS_FOURCC_REF_LIST: {
	FIXME_(dmfile)(": DMRF (DM References) list, not yet handled\n");
300 301 302 303 304 305 306
	hr = IDirectMusicUtils_IPersistStream_ParseReference (iface,  &Chunk, pStm, &pObject);
	if (FAILED(hr)) {
	  ERR(": could not load Reference\n");
	  return hr;
	}
	hr = IDirectMusicObject_QueryInterface(pObject, &IID_IDirectMusicStyle8, (LPVOID*)&pNewItem->pObject);
	if (FAILED(hr)) {
307
	  ERR(": Reference not an IDirectMusicStyle, exiting\n");
308 309 310 311
	  exit(-1);
	  return hr;
	}
	IDirectMusicObject_Release(pObject);
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
	break;						
      }
      default: {
	TRACE_(dmfile)(": unknown (skipping)\n");
	liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
	IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	break;						
      }
      }	
      break;
    }
    default: {
      TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
      liMove.QuadPart = Chunk.dwSize;
      IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
      break;						
    }
    }
    TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
  } while (ListCount[0] < ListSize[0]);

  return S_OK;
}

static HRESULT IDirectMusicStyleTrack_IPersistStream_ParseStyleTrackList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {

  /*ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);*/
  DMUS_PRIVATE_CHUNK Chunk;
  DWORD ListSize[3], ListCount[3];
  LARGE_INTEGER liMove; /* used when skipping chunks */
  HRESULT hr;

  if (pChunk->fccID != DMUS_FOURCC_STYLE_TRACK_LIST) {
    ERR_(dmfile)(": %s chunk should be a STYLETRACK list\n", debugstr_fourcc (pChunk->fccID));
    return E_FAIL;
  }  

  ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
  ListCount[0] = 0;

  do {
    IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
    ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
    TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
    switch (Chunk.fccID) { 
    case FOURCC_LIST: { 
      IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
      TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
      ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
      ListCount[1] = 0;
      switch (Chunk.fccID) { 
      case DMUS_FOURCC_STYLE_REF_LIST: {
	TRACE_(dmfile)(": STYLE_REF list\n"); 
	hr = IDirectMusicStyleTrack_IPersistStream_ParseStyleRef (iface, &Chunk, pStm);
	if (FAILED(hr)) return hr;	
	break;
      }
      default: {
	TRACE_(dmfile)(": unknown (skipping)\n");
	liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
	IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	break;						
      }
      }
      break;
    }
    default: {
      TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
      liMove.QuadPart = Chunk.dwSize;
      IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
      break;		
    }
    }
    TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
  } while (ListCount[0] < ListSize[0]);

  return S_OK;
389 390
}

391
HRESULT WINAPI IDirectMusicStyleTrack_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
  ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);

  DMUS_PRIVATE_CHUNK Chunk;
  LARGE_INTEGER liMove;
  HRESULT hr;
 
  FIXME("(%p, %p): Loading not fully implemented yet\n", This, pStm);

  IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
  TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
  switch (Chunk.fccID) {	
  case FOURCC_LIST: {
    IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
    TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
    switch (Chunk.fccID) { 
    case DMUS_FOURCC_STYLE_TRACK_LIST: {
      TRACE_(dmfile)(": Chord track list\n");
      hr = IDirectMusicStyleTrack_IPersistStream_ParseStyleTrackList (iface, &Chunk, pStm);
      if (FAILED(hr)) return hr;
      break;    
    }
    default: {
      TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
      liMove.QuadPart = Chunk.dwSize;
      IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
      return E_FAIL;
    }
    }
    TRACE_(dmfile)(": reading finished\n");
    break;
  }
  default: {
    TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
    liMove.QuadPart = Chunk.dwSize;
    IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
    return E_FAIL;
  }
  }

  return S_OK;
432 433
}

434
HRESULT WINAPI IDirectMusicStyleTrack_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
435 436 437
  ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);
  FIXME("(%p): Saving not implemented yet\n", This);
  return E_NOTIMPL;
438 439
}

440
HRESULT WINAPI IDirectMusicStyleTrack_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
441 442 443
  ICOM_THIS_MULTI(IDirectMusicStyleTrack, PersistStreamVtbl, iface);
  FIXME("(%p, %p): stub\n", This, pcbSize);
  return E_NOTIMPL;
444 445
}

446
static const IPersistStreamVtbl DirectMusicStyleTrack_PersistStream_Vtbl = {
447 448 449 450 451 452 453 454
  IDirectMusicStyleTrack_IPersistStream_QueryInterface,
  IDirectMusicStyleTrack_IPersistStream_AddRef,
  IDirectMusicStyleTrack_IPersistStream_Release,
  IDirectMusicStyleTrack_IPersistStream_GetClassID,
  IDirectMusicStyleTrack_IPersistStream_IsDirty,
  IDirectMusicStyleTrack_IPersistStream_Load,
  IDirectMusicStyleTrack_IPersistStream_Save,
  IDirectMusicStyleTrack_IPersistStream_GetSizeMax
455
};
456 457 458

/* for ClassFactory */
HRESULT WINAPI DMUSIC_CreateDirectMusicStyleTrack (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter) {
459 460 461 462
  IDirectMusicStyleTrack* track;
  
  track = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicStyleTrack));
  if (NULL == track) {
463
    *ppobj = NULL;
464 465 466 467 468 469 470 471 472 473
    return E_OUTOFMEMORY;
  }
  track->UnknownVtbl = &DirectMusicStyleTrack_Unknown_Vtbl;
  track->TrackVtbl = &DirectMusicStyleTrack_Track_Vtbl;
  track->PersistStreamVtbl = &DirectMusicStyleTrack_PersistStream_Vtbl;
  track->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
  DM_STRUCT_INIT(track->pDesc);
  track->pDesc->dwValidData |= DMUS_OBJ_CLASS;
  memcpy (&track->pDesc->guidClass, &CLSID_DirectMusicStyleTrack, sizeof (CLSID));
  track->ref = 0; /* will be inited by QueryInterface */
474
  list_init (&track->Items);
475 476
  
  return IDirectMusicStyleTrack_IUnknown_QueryInterface ((LPUNKNOWN)&track->UnknownVtbl, lpcGUID, ppobj);
477
}