shdoclc: Fix Italian translation.
[wine] / dlls / dmloader / loaderstream.c
CommitLineData
72c80375
RM
1/* IDirectMusicLoaderFileStream
2 * IDirectMusicLoaderResourceStream
3 * IDirectMusicLoaderGenericStream
df167d17 4 *
0382ea1d 5 * Copyright (C) 2003-2004 Rok Mandeljc
df167d17 6 *
7718d2bd
AJ
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
df167d17
RM
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7718d2bd
AJ
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
df167d17 16 *
7718d2bd
AJ
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
df167d17
RM
20 */
21
72c80375
RM
22
23/* SIDE NOTES:
24 * After extensive testing and structure dumping I came to a conclusion that
25 * DirectMusic as in present state implements three types of streams:
26 * 1. IDirectMusicLoaderFileStream: stream that was most obvious, since
27 * it's used for loading from files; it is sort of wrapper around
28 * CreateFile, ReadFile, WriteFile and SetFilePointer and it supports
29 * both read and write
30 * 2. IDirectMusicLoaderResourceStream: a stream that had to exist, since
31 * according to MSDN, IDirectMusicLoader supports loading from resource
32 * as well; in this case, data is represented as a big chunk of bytes,
33 * from which we "read" (copy) data and keep the trace of our position;
34 * it supports read only
35 * 3. IDirectMusicLoaderGenericStream: this one was the most problematic,
36 * since I thought it was URL-related; besides, there's no obvious need
37 * for it, since input streams can simply be cloned, lest loading from
38 * stream is requested; but if one really thinks about it, input stream
39 * could be none of 1. or 2.; in this case, a wrapper that offers
40 * IDirectMusicGetLoader interface would be nice, and this is what this
41 * stream is; as such, all functions are supported, as long as underlying
42 * ("low-level") stream supports them
43 *
44 * - Rok Mandeljc; 24. april, 2004
45*/
46
df167d17
RM
47#define NONAMELESSUNION
48#define NONAMELESSSTRUCT
df167d17
RM
49
50#include "dmloader_private.h"
51
52WINE_DEFAULT_DEBUG_CHANNEL(dmloader);
0382ea1d 53WINE_DECLARE_DEBUG_CHANNEL(dmfileraw);
df167d17 54
12179978
AJ
55static ULONG WINAPI IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface);
56static ULONG WINAPI IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface);
57static ULONG WINAPI IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface);
58static ULONG WINAPI IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface);
59static ULONG WINAPI IDirectMusicLoaderGenericStream_IStream_AddRef (LPSTREAM iface);
60static ULONG WINAPI IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface);
61
62
df167d17 63/*****************************************************************************
72c80375 64 * IDirectMusicLoaderFileStream implementation
df167d17 65 */
72c80375 66/* Custom : */
02bfacff
AJ
67
68static void IDirectMusicLoaderFileStream_Detach (LPSTREAM iface) {
69 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
70 TRACE("(%p)\n", This);
71 if (This->hFile != INVALID_HANDLE_VALUE) CloseHandle(This->hFile);
72 This->wzFileName[0] = '\0';
73}
74
b8d3075d 75HRESULT WINAPI IDirectMusicLoaderFileStream_Attach (LPSTREAM iface, LPCWSTR wzFile, LPDIRECTMUSICLOADER8 pLoader) {
72c80375 76 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
493660a5 77 TRACE("(%p, %s, %p)\n", This, debugstr_w(wzFile), pLoader);
72c80375
RM
78 IDirectMusicLoaderFileStream_Detach (iface);
79 This->hFile = CreateFileW (wzFile, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
df167d17 80 if (This->hFile == INVALID_HANDLE_VALUE) {
72c80375 81 WARN(": failed\n");
0382ea1d 82 return DMUS_E_LOADER_FAILEDOPEN;
df167d17 83 }
493660a5 84 /* create IDirectMusicGetLoader */
b8d3075d 85 This->pLoader = pLoader;
6e3bcb5a 86 lstrcpynW (This->wzFileName, wzFile, MAX_PATH);
493660a5 87 TRACE(": succeeded\n");
df167d17
RM
88 return S_OK;
89}
90
72c80375
RM
91
92/* IUnknown/IStream part: */
12179978 93static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_QueryInterface (LPSTREAM iface, REFIID riid, void** ppobj) {
72c80375 94 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
df167d17 95
b26d65bb 96 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
72c80375
RM
97 if (IsEqualIID (riid, &IID_IUnknown) ||
98 IsEqualIID (riid, &IID_IStream)) {
4b50a4c6 99 *ppobj = &This->StreamVtbl;
72c80375 100 IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM)&This->StreamVtbl);
df167d17
RM
101 return S_OK;
102 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
4b50a4c6 103 *ppobj = &This->GetLoaderVtbl;
72c80375 104 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
df167d17
RM
105 return S_OK;
106 }
107
72c80375 108 WARN(": not found\n");
df167d17
RM
109 return E_NOINTERFACE;
110}
111
12179978 112static ULONG WINAPI IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface) {
72c80375 113 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
187b6ed9 114 TRACE("(%p): AddRef from %d\n", This, This->dwRef);
72c80375 115 return InterlockedIncrement (&This->dwRef);
df167d17
RM
116}
117
12179978 118static ULONG WINAPI IDirectMusicLoaderFileStream_IStream_Release (LPSTREAM iface) {
72c80375
RM
119 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
120
121 DWORD dwRef = InterlockedDecrement (&This->dwRef);
187b6ed9 122 TRACE("(%p): ReleaseRef to %d\n", This, dwRef);
72c80375 123 if (dwRef == 0) {
12179978
AJ
124 if (This->hFile)
125 IDirectMusicLoaderFileStream_Detach (iface);
126 HeapFree (GetProcessHeap(), 0, This);
df167d17 127 }
72c80375
RM
128
129 return dwRef;
0382ea1d
RM
130}
131
12179978 132static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Read (LPSTREAM iface, void* pv, ULONG cb, ULONG* pcbRead) {
72c80375 133 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
0382ea1d 134 ULONG cbRead;
72c80375 135
187b6ed9 136 TRACE_(dmfileraw)("(%p, %p, 0x%08X, %p)\n", This, pv, cb, pcbRead);
df167d17
RM
137 if (This->hFile == INVALID_HANDLE_VALUE) return E_FAIL;
138 if (pcbRead == NULL) pcbRead = &cbRead;
139 if (!ReadFile (This->hFile, pv, cb, pcbRead, NULL) || *pcbRead != cb) return E_FAIL;
72c80375 140
aab5e585 141 TRACE_(dmfileraw)(": data (size = 0x%08X): %s\n", *pcbRead, debugstr_an(pv, *pcbRead));
df167d17
RM
142 return S_OK;
143}
144
12179978 145static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Seek (LPSTREAM iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) {
72c80375 146 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
df167d17 147 LARGE_INTEGER liNewPos;
0382ea1d 148
aa68258b 149 TRACE_(dmfileraw)("(%p, %s, %s, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), resolve_STREAM_SEEK(dwOrigin), plibNewPosition);
df167d17 150
aa68258b 151 if (This->hFile == INVALID_HANDLE_VALUE) return E_FAIL;
df167d17 152
399901e0
GG
153 liNewPos.u.HighPart = dlibMove.u.HighPart;
154 liNewPos.u.LowPart = SetFilePointer (This->hFile, dlibMove.u.LowPart, &liNewPos.u.HighPart, dwOrigin);
df167d17 155
399901e0 156 if (liNewPos.u.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) return E_FAIL;
df167d17
RM
157 if (plibNewPosition) plibNewPosition->QuadPart = liNewPos.QuadPart;
158
159 return S_OK;
160}
161
12179978 162static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Clone (LPSTREAM iface, IStream** ppstm) {
72c80375 163 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
0382ea1d 164 LPSTREAM pOther = NULL;
df167d17
RM
165 HRESULT result;
166
167 TRACE("(%p, %p)\n", iface, ppstm);
72c80375 168 result = DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID*)&pOther);
df167d17
RM
169 if (FAILED(result)) return result;
170 if (This->hFile != INVALID_HANDLE_VALUE) {
171 ULARGE_INTEGER ullCurrentPosition;
b8d3075d 172 result = IDirectMusicLoaderFileStream_Attach (pOther, This->wzFileName, This->pLoader);
df167d17
RM
173 if (SUCCEEDED(result)) {
174 LARGE_INTEGER liZero;
175 liZero.QuadPart = 0;
72c80375 176 result = IDirectMusicLoaderFileStream_IStream_Seek (iface, liZero, STREAM_SEEK_CUR, &ullCurrentPosition); /* get current position in current stream */
df167d17
RM
177 }
178 if (SUCCEEDED(result)) {
179 LARGE_INTEGER liNewPosition;
180 liNewPosition.QuadPart = ullCurrentPosition.QuadPart;
9e55f92b 181 result = IDirectMusicLoaderFileStream_IStream_Seek (pOther, liNewPosition, STREAM_SEEK_SET, &ullCurrentPosition);
df167d17
RM
182 }
183 if (FAILED(result)) {
184 TRACE(": failed\n");
9e55f92b 185 IDirectMusicLoaderFileStream_IStream_Release (pOther);
df167d17
RM
186 return result;
187 }
188 }
189 TRACE(": succeeded\n");
9e55f92b 190 *ppstm = pOther;
df167d17
RM
191 return S_OK;
192}
193
12179978 194static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten) {
72c80375
RM
195 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
196 ULONG cbWrite;
197
187b6ed9 198 TRACE_(dmfileraw)("(%p, %p, 0x%08X, %p)\n", This, pv, cb, pcbWritten);
72c80375
RM
199 if (This->hFile == INVALID_HANDLE_VALUE) return E_FAIL;
200 if (pcbWritten == NULL) pcbWritten = &cbWrite;
201 if (!WriteFile (This->hFile, pv, cb, pcbWritten, NULL) || *pcbWritten != cb) return E_FAIL;
202
aab5e585 203 TRACE_(dmfileraw)(": data (size = 0x%08X): %s\n", *pcbWritten, debugstr_an(pv, *pcbWritten));
72c80375
RM
204 return S_OK;
205}
206
12179978 207static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) {
72c80375
RM
208 ERR(": should not be needed\n");
209 return E_NOTIMPL;
210}
211
12179978 212static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_CopyTo (LPSTREAM iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) {
72c80375
RM
213 ERR(": should not be needed\n");
214 return E_NOTIMPL;
215}
216
12179978 217static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) {
72c80375
RM
218 ERR(": should not be needed\n");
219 return E_NOTIMPL;
220}
221
12179978 222static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Revert (LPSTREAM iface) {
72c80375
RM
223 ERR(": should not be needed\n");
224 return E_NOTIMPL;
225}
226
12179978 227static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
72c80375
RM
228 ERR(": should not be needed\n");
229 return E_NOTIMPL;
230}
231
12179978 232static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
72c80375
RM
233 ERR(": should not be needed\n");
234 return E_NOTIMPL;
235}
236
12179978 237static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag) {
72c80375
RM
238 ERR(": should not be needed\n");
239 return E_NOTIMPL;
240}
241
247246ed 242static const IStreamVtbl DirectMusicLoaderFileStream_Stream_Vtbl = {
72c80375
RM
243 IDirectMusicLoaderFileStream_IStream_QueryInterface,
244 IDirectMusicLoaderFileStream_IStream_AddRef,
245 IDirectMusicLoaderFileStream_IStream_Release,
246 IDirectMusicLoaderFileStream_IStream_Read,
247 IDirectMusicLoaderFileStream_IStream_Write,
248 IDirectMusicLoaderFileStream_IStream_Seek,
249 IDirectMusicLoaderFileStream_IStream_SetSize,
250 IDirectMusicLoaderFileStream_IStream_CopyTo,
251 IDirectMusicLoaderFileStream_IStream_Commit,
252 IDirectMusicLoaderFileStream_IStream_Revert,
253 IDirectMusicLoaderFileStream_IStream_LockRegion,
254 IDirectMusicLoaderFileStream_IStream_UnlockRegion,
255 IDirectMusicLoaderFileStream_IStream_Stat,
256 IDirectMusicLoaderFileStream_IStream_Clone
257};
258
259/* IDirectMusicGetLoader part: */
12179978 260static HRESULT WINAPI IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface, REFIID riid, void** ppobj) {
72c80375
RM
261 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, GetLoaderVtbl, iface);
262 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM)&This->StreamVtbl, riid, ppobj);
263}
264
12179978 265static ULONG WINAPI IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface) {
72c80375
RM
266 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, GetLoaderVtbl, iface);
267 return IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM)&This->StreamVtbl);
268}
269
12179978 270static ULONG WINAPI IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface) {
72c80375
RM
271 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, GetLoaderVtbl, iface);
272 return IDirectMusicLoaderFileStream_IStream_Release ((LPSTREAM)&This->StreamVtbl);
273}
274
12179978 275static HRESULT WINAPI IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface, IDirectMusicLoader **ppLoader) {
72c80375
RM
276 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, GetLoaderVtbl, iface);
277
278 TRACE("(%p, %p)\n", This, ppLoader);
279 *ppLoader = (LPDIRECTMUSICLOADER)This->pLoader;
280 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8)*ppLoader);
281
282 return S_OK;
283}
284
247246ed 285static const IDirectMusicGetLoaderVtbl DirectMusicLoaderFileStream_GetLoader_Vtbl = {
72c80375
RM
286 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface,
287 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef,
288 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release,
289 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader
290};
291
292HRESULT WINAPI DMUSIC_CreateDirectMusicLoaderFileStream (LPVOID* ppobj) {
293 IDirectMusicLoaderFileStream *obj;
294
295 TRACE("(%p)\n", ppobj);
296 obj = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(IDirectMusicLoaderFileStream));
297 if (NULL == obj) {
ee0344a4 298 *ppobj = NULL;
72c80375
RM
299 return E_OUTOFMEMORY;
300 }
301 obj->StreamVtbl = &DirectMusicLoaderFileStream_Stream_Vtbl;
302 obj->GetLoaderVtbl = &DirectMusicLoaderFileStream_GetLoader_Vtbl;
303 obj->dwRef = 0; /* will be inited with QueryInterface */
304
305 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM)&obj->StreamVtbl, &IID_IStream, ppobj);
306}
307
72c80375
RM
308
309/*****************************************************************************
310 * IDirectMusicLoaderResourceStream implementation
311 */
312/* Custom : */
02bfacff
AJ
313
314static void IDirectMusicLoaderResourceStream_Detach (LPSTREAM iface) {
315 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
316 TRACE("(%p)\n", This);
317
318 This->pbMemData = NULL;
319 This->llMemLength = 0;
320}
321
b8d3075d 322HRESULT WINAPI IDirectMusicLoaderResourceStream_Attach (LPSTREAM iface, LPBYTE pbMemData, LONGLONG llMemLength, LONGLONG llPos, LPDIRECTMUSICLOADER8 pLoader) {
72c80375
RM
323 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
324
aa68258b 325 TRACE("(%p, %p, %s, %s, %p)\n", This, pbMemData, wine_dbgstr_longlong(llMemLength), wine_dbgstr_longlong(llPos), pLoader);
72c80375
RM
326 if (!pbMemData || !llMemLength) {
327 WARN(": invalid pbMemData or llMemLength\n");
328 return E_FAIL;
329 }
330 IDirectMusicLoaderResourceStream_Detach (iface);
331 This->pbMemData = pbMemData;
332 This->llMemLength = llMemLength;
333 This->llPos = llPos;
334 This->pLoader = pLoader;
335
336 return S_OK;
337}
338
72c80375
RM
339
340/* IUnknown/IStream part: */
12179978 341static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_QueryInterface (LPSTREAM iface, REFIID riid, void** ppobj) {
72c80375
RM
342 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
343
344 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
345 if (IsEqualIID (riid, &IID_IUnknown) ||
346 IsEqualIID (riid, &IID_IStream)) {
4b50a4c6 347 *ppobj = &This->StreamVtbl;
72c80375
RM
348 IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM)&This->StreamVtbl);
349 return S_OK;
350 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
4b50a4c6 351 *ppobj = &This->GetLoaderVtbl;
72c80375
RM
352 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
353 return S_OK;
354 }
355
356 WARN(": not found\n");
357 return E_NOINTERFACE;
358}
359
12179978 360static ULONG WINAPI IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface) {
72c80375 361 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
187b6ed9 362 TRACE("(%p): AddRef from %d\n", This, This->dwRef);
72c80375
RM
363 return InterlockedIncrement (&This->dwRef);
364}
365
12179978 366static ULONG WINAPI IDirectMusicLoaderResourceStream_IStream_Release (LPSTREAM iface) {
72c80375
RM
367 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
368
369 DWORD dwRef = InterlockedDecrement (&This->dwRef);
187b6ed9 370 TRACE("(%p): ReleaseRef to %d\n", This, dwRef);
72c80375 371 if (dwRef == 0) {
12179978
AJ
372 IDirectMusicLoaderResourceStream_Detach (iface);
373 HeapFree (GetProcessHeap(), 0, This);
72c80375
RM
374 }
375
376 return dwRef;
377}
378
12179978 379static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Read (LPSTREAM iface, void* pv, ULONG cb, ULONG* pcbRead) {
72c80375
RM
380 LPBYTE pByte;
381 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
382
187b6ed9 383 TRACE_(dmfileraw)("(%p, %p, 0x%08X, %p)\n", This, pv, cb, pcbRead);
72c80375
RM
384 if ((This->llPos + cb) > This->llMemLength) {
385 WARN_(dmfileraw)(": requested size out of range\n");
386 return E_FAIL;
387 }
388
389 pByte = &This->pbMemData[This->llPos];
390 memcpy (pv, pByte, cb);
391 This->llPos += cb; /* move pointer */
392 /* FIXME: error checking would be nice */
4a109c78 393 if (pcbRead) *pcbRead = cb;
72c80375 394
aab5e585 395 TRACE_(dmfileraw)(": data (size = 0x%08X): %s\n", cb, debugstr_an(pv, cb));
72c80375
RM
396 return S_OK;
397}
398
12179978 399static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Seek (LPSTREAM iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) {
72c80375 400 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
aa68258b 401 TRACE_(dmfileraw)("(%p, %s, %s, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), resolve_STREAM_SEEK(dwOrigin), plibNewPosition);
72c80375
RM
402
403 switch (dwOrigin) {
404 case STREAM_SEEK_CUR: {
405 if ((This->llPos + dlibMove.QuadPart) > This->llMemLength) {
406 WARN_(dmfileraw)(": requested offset out of range\n");
407 return E_FAIL;
408 }
409 break;
410 }
411 case STREAM_SEEK_SET: {
412 if (dlibMove.QuadPart > This->llMemLength) {
413 WARN_(dmfileraw)(": requested offset out of range\n");
414 return E_FAIL;
415 }
416 /* set to the beginning of the stream */
417 This->llPos = 0;
418 break;
419 }
420 case STREAM_SEEK_END: {
421 /* TODO: check if this is true... I do think offset should be negative in this case */
422 if (dlibMove.QuadPart > 0) {
423 WARN_(dmfileraw)(": requested offset out of range\n");
424 return E_FAIL;
425 }
426 /* set to the end of the stream */
427 This->llPos = This->llMemLength;
428 break;
429 }
430 default: {
431 ERR_(dmfileraw)(": invalid dwOrigin\n");
432 return E_FAIL;
433 }
434 }
435 /* now simply add */
436 This->llPos += dlibMove.QuadPart;
437
438 if (plibNewPosition) plibNewPosition->QuadPart = This->llPos;
439
440 return S_OK;
441}
442
12179978 443static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Clone (LPSTREAM iface, IStream** ppstm) {
72c80375
RM
444 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
445 LPSTREAM pOther = NULL;
446 HRESULT result;
447
448 TRACE("(%p, %p)\n", iface, ppstm);
449 result = DMUSIC_CreateDirectMusicLoaderResourceStream ((LPVOID*)&pOther);
450 if (FAILED(result)) return result;
451
452 IDirectMusicLoaderResourceStream_Attach (pOther, This->pbMemData, This->llMemLength, This->llPos, This->pLoader);
453
454 TRACE(": succeeded\n");
9e55f92b 455 *ppstm = pOther;
72c80375
RM
456 return S_OK;
457}
458
12179978 459static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten) {
1d0585c4 460 ERR(": should not be needed\n");
72c80375 461 return E_NOTIMPL;
df167d17
RM
462}
463
12179978 464static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) {
1d0585c4 465 ERR(": should not be needed\n");
df167d17
RM
466 return E_NOTIMPL;
467}
468
12179978 469static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_CopyTo (LPSTREAM iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) {
1d0585c4 470 ERR(": should not be needed\n");
df167d17
RM
471 return E_NOTIMPL;
472}
473
12179978 474static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) {
1d0585c4 475 ERR(": should not be needed\n");
df167d17
RM
476 return E_NOTIMPL;
477}
478
12179978 479static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Revert (LPSTREAM iface) {
1d0585c4 480 ERR(": should not be needed\n");
df167d17
RM
481 return E_NOTIMPL;
482}
483
12179978 484static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
1d0585c4 485 ERR(": should not be needed\n");
df167d17
RM
486 return E_NOTIMPL;
487}
488
12179978 489static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
1d0585c4 490 ERR(": should not be needed\n");
df167d17
RM
491 return E_NOTIMPL;
492}
493
12179978 494static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag) {
1d0585c4 495 ERR(": should not be needed\n");
df167d17
RM
496 return E_NOTIMPL;
497}
498
247246ed 499static const IStreamVtbl DirectMusicLoaderResourceStream_Stream_Vtbl = {
72c80375
RM
500 IDirectMusicLoaderResourceStream_IStream_QueryInterface,
501 IDirectMusicLoaderResourceStream_IStream_AddRef,
502 IDirectMusicLoaderResourceStream_IStream_Release,
503 IDirectMusicLoaderResourceStream_IStream_Read,
504 IDirectMusicLoaderResourceStream_IStream_Write,
505 IDirectMusicLoaderResourceStream_IStream_Seek,
506 IDirectMusicLoaderResourceStream_IStream_SetSize,
507 IDirectMusicLoaderResourceStream_IStream_CopyTo,
508 IDirectMusicLoaderResourceStream_IStream_Commit,
509 IDirectMusicLoaderResourceStream_IStream_Revert,
510 IDirectMusicLoaderResourceStream_IStream_LockRegion,
511 IDirectMusicLoaderResourceStream_IStream_UnlockRegion,
512 IDirectMusicLoaderResourceStream_IStream_Stat,
513 IDirectMusicLoaderResourceStream_IStream_Clone
df167d17
RM
514};
515
72c80375 516/* IDirectMusicGetLoader part: */
12179978 517static HRESULT WINAPI IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface, REFIID riid, void** ppobj) {
72c80375
RM
518 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, GetLoaderVtbl, iface);
519 return IDirectMusicLoaderResourceStream_IStream_QueryInterface ((LPSTREAM)&This->StreamVtbl, riid, ppobj);
520}
521
12179978 522static ULONG WINAPI IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface) {
72c80375
RM
523 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, GetLoaderVtbl, iface);
524 return IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM)&This->StreamVtbl);
525}
526
12179978 527static ULONG WINAPI IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface) {
72c80375
RM
528 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, GetLoaderVtbl, iface);
529 return IDirectMusicLoaderResourceStream_IStream_Release ((LPSTREAM)&This->StreamVtbl);
530}
531
12179978 532static HRESULT WINAPI IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface, IDirectMusicLoader **ppLoader) {
72c80375
RM
533 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, GetLoaderVtbl, iface);
534
535 TRACE("(%p, %p)\n", This, ppLoader);
536 *ppLoader = (LPDIRECTMUSICLOADER)This->pLoader;
537 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8)*ppLoader);
538
539 return S_OK;
540}
541
247246ed 542static const IDirectMusicGetLoaderVtbl DirectMusicLoaderResourceStream_GetLoader_Vtbl = {
72c80375
RM
543 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_QueryInterface,
544 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef,
545 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_Release,
546 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_GetLoader
547};
548
549HRESULT WINAPI DMUSIC_CreateDirectMusicLoaderResourceStream (LPVOID* ppobj) {
550 IDirectMusicLoaderResourceStream *obj;
551
552 TRACE("(%p)\n", ppobj);
553 obj = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(IDirectMusicLoaderResourceStream));
554 if (NULL == obj) {
ee0344a4 555 *ppobj = NULL;
72c80375
RM
556 return E_OUTOFMEMORY;
557 }
558 obj->StreamVtbl = &DirectMusicLoaderResourceStream_Stream_Vtbl;
559 obj->GetLoaderVtbl = &DirectMusicLoaderResourceStream_GetLoader_Vtbl;
560 obj->dwRef = 0; /* will be inited with QueryInterface */
561
562 return IDirectMusicLoaderResourceStream_IStream_QueryInterface ((LPSTREAM)&obj->StreamVtbl, &IID_IStream, ppobj);
563}
564
72c80375 565
df167d17 566/*****************************************************************************
72c80375 567 * IDirectMusicLoaderGenericStream implementation
df167d17 568 */
72c80375 569/* Custom : */
02bfacff
AJ
570
571static void IDirectMusicLoaderGenericStream_Detach (LPSTREAM iface) {
572 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
573
574 if (This->pStream)
575 IStream_Release (This->pStream);
576 This->pStream = NULL;
577}
578
b8d3075d 579HRESULT WINAPI IDirectMusicLoaderGenericStream_Attach (LPSTREAM iface, LPSTREAM pStream, LPDIRECTMUSICLOADER8 pLoader) {
72c80375
RM
580 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
581
582 TRACE("(%p, %p, %p)\n", This, pStream, pLoader);
583 if (!pStream) {
584 WARN(": invalid pStream\n");
585 return E_FAIL;
586 }
587 if (!pLoader) {
588 WARN(": invalid pLoader\n");
589 return E_FAIL;
590 }
591
592 IDirectMusicLoaderGenericStream_Detach (iface);
593 IStream_Clone (pStream, &This->pStream);
594 This->pLoader = pLoader;
595
596 return S_OK;
df167d17
RM
597}
598
72c80375
RM
599
600/* IUnknown/IStream part: */
12179978 601static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_QueryInterface (LPSTREAM iface, REFIID riid, void** ppobj) {
72c80375
RM
602 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
603
604 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
605 if (IsEqualIID (riid, &IID_IUnknown) ||
606 IsEqualIID (riid, &IID_IStream)) {
4b50a4c6 607 *ppobj = &This->StreamVtbl;
72c80375
RM
608 IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM)&This->StreamVtbl);
609 return S_OK;
610 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
4b50a4c6 611 *ppobj = &This->GetLoaderVtbl;
72c80375
RM
612 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
613 return S_OK;
614 }
615
616 WARN(": not found\n");
617 return E_NOINTERFACE;
df167d17
RM
618}
619
12179978 620static ULONG WINAPI IDirectMusicLoaderGenericStream_IStream_AddRef (LPSTREAM iface) {
72c80375 621 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
187b6ed9 622 TRACE("(%p): AddRef from %d\n", This, This->dwRef);
72c80375
RM
623 return InterlockedIncrement (&This->dwRef);
624}
625
12179978 626static ULONG WINAPI IDirectMusicLoaderGenericStream_IStream_Release (LPSTREAM iface) {
72c80375
RM
627 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
628
629 DWORD dwRef = InterlockedDecrement (&This->dwRef);
187b6ed9 630 TRACE("(%p): ReleaseRef to %d\n", This, dwRef);
72c80375 631 if (dwRef == 0) {
12179978
AJ
632 IDirectMusicLoaderGenericStream_Detach (iface);
633 HeapFree (GetProcessHeap(), 0, This);
72c80375
RM
634 }
635
636 return dwRef;
637}
638
12179978 639static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_Read (LPSTREAM iface, void* pv, ULONG cb, ULONG* pcbRead) {
72c80375
RM
640 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
641
187b6ed9 642 TRACE_(dmfileraw)("(%p, %p, 0x%08X, %p): redirecting to low-level stream\n", This, pv, cb, pcbRead);
72c80375
RM
643 if (!This->pStream)
644 return E_FAIL;
645
646 return IStream_Read (This->pStream, pv, cb, pcbRead);
647}
648
12179978 649static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_Seek (LPSTREAM iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) {
72c80375 650 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
aa68258b 651 TRACE_(dmfileraw)("(%p, %s, %s, %p): redirecting to low-level stream\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), resolve_STREAM_SEEK(dwOrigin), plibNewPosition);
72c80375
RM
652 if (!This->pStream)
653 return E_FAIL;
654
655 return IStream_Seek (This->pStream, dlibMove, dwOrigin, plibNewPosition);
656}
657
12179978 658static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_Clone (LPSTREAM iface, IStream** ppstm) {
72c80375
RM
659 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
660 LPSTREAM pOther = NULL;
661 LPSTREAM pLowLevel = NULL;
662 HRESULT result;
663
664 TRACE("(%p, %p)\n", iface, ppstm);
665 result = DMUSIC_CreateDirectMusicLoaderGenericStream ((LPVOID*)&pOther);
666 if (FAILED(result)) return result;
667
668 if (FAILED(IStream_Clone (This->pStream, &pLowLevel)))
669 return E_FAIL;
670
671 IDirectMusicLoaderGenericStream_Attach (pOther, pLowLevel, This->pLoader);
672
673 TRACE(": succeeded\n");
9e55f92b 674 *ppstm = pOther;
72c80375
RM
675 return S_OK;
676}
677
12179978 678static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten) {
72c80375 679 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
187b6ed9 680 TRACE_(dmfileraw)("(%p, %p, 0x%08X, %p): redirecting to low-level stream\n", This, pv, cb, pcbWritten);
72c80375
RM
681 if (!This->pStream)
682 return E_FAIL;
683
684 return IStream_Write (This->pStream, pv, cb, pcbWritten);
685}
686
12179978 687static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) {
72c80375 688 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
aa68258b 689 TRACE("(%p, %s): redirecting to low-level stream\n", This, wine_dbgstr_longlong(libNewSize.QuadPart));
72c80375
RM
690 if (!This->pStream)
691 return E_FAIL;
692
693 return IStream_SetSize (This->pStream, libNewSize);
694}
695
12179978 696static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_CopyTo (LPSTREAM iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) {
72c80375 697 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
aa68258b 698 TRACE("(%p, %p, %s, %p, %p): redirecting to low-level stream\n", This, pstm, wine_dbgstr_longlong(cb.QuadPart), pcbRead, pcbWritten);
72c80375
RM
699 if (!This->pStream)
700 return E_FAIL;
701
702 return IStream_CopyTo (This->pStream, pstm, cb, pcbRead, pcbWritten);
703}
704
12179978 705static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) {
72c80375 706 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
187b6ed9 707 TRACE("(%p, 0x%08X): redirecting to low-level stream\n", This, grfCommitFlags);
72c80375
RM
708 if (!This->pStream)
709 return E_FAIL;
710
711 return IStream_Commit (This->pStream, grfCommitFlags);
712}
713
12179978 714static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_Revert (LPSTREAM iface) {
72c80375
RM
715 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
716 TRACE("(%p): redirecting to low-level stream\n", This);
717 if (!This->pStream)
718 return E_FAIL;
719
720 return IStream_Revert (This->pStream);
721}
722
12179978 723static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
72c80375 724 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
aa68258b 725 TRACE("(%p, %s, %s, 0x%08X): redirecting to low-level stream\n", This, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType);
72c80375
RM
726 if (!This->pStream)
727 return E_FAIL;
728
729 return IStream_LockRegion (This->pStream, libOffset, cb, dwLockType);
730}
731
12179978 732static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
72c80375 733 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
aa68258b 734 TRACE("(%p, %s, %s, 0x%08X): redirecting to low-level stream\n", This, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType);
72c80375
RM
735 if (!This->pStream)
736 return E_FAIL;
737
738 return IStream_UnlockRegion (This->pStream, libOffset, cb, dwLockType);
739}
740
12179978 741static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag) {
72c80375 742 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
187b6ed9 743 TRACE("(%p, %p, 0x%08X): redirecting to low-level stream\n", This, pstatstg, grfStatFlag);
72c80375
RM
744 if (!This->pStream)
745 return E_FAIL;
746
747 return IStream_Stat (This->pStream, pstatstg, grfStatFlag);
748}
749
247246ed 750static const IStreamVtbl DirectMusicLoaderGenericStream_Stream_Vtbl = {
72c80375
RM
751 IDirectMusicLoaderGenericStream_IStream_QueryInterface,
752 IDirectMusicLoaderGenericStream_IStream_AddRef,
753 IDirectMusicLoaderGenericStream_IStream_Release,
754 IDirectMusicLoaderGenericStream_IStream_Read,
755 IDirectMusicLoaderGenericStream_IStream_Write,
756 IDirectMusicLoaderGenericStream_IStream_Seek,
757 IDirectMusicLoaderGenericStream_IStream_SetSize,
758 IDirectMusicLoaderGenericStream_IStream_CopyTo,
759 IDirectMusicLoaderGenericStream_IStream_Commit,
760 IDirectMusicLoaderGenericStream_IStream_Revert,
761 IDirectMusicLoaderGenericStream_IStream_LockRegion,
762 IDirectMusicLoaderGenericStream_IStream_UnlockRegion,
763 IDirectMusicLoaderGenericStream_IStream_Stat,
764 IDirectMusicLoaderGenericStream_IStream_Clone
765};
766
767/* IDirectMusicGetLoader part: */
12179978 768static HRESULT WINAPI IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface, REFIID riid, void** ppobj) {
72c80375
RM
769 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, GetLoaderVtbl, iface);
770 return IDirectMusicLoaderGenericStream_IStream_QueryInterface ((LPSTREAM)&This->StreamVtbl, riid, ppobj);
771}
772
12179978 773static ULONG WINAPI IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface) {
72c80375
RM
774 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, GetLoaderVtbl, iface);
775 return IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM)&This->StreamVtbl);
776}
777
12179978 778static ULONG WINAPI IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface) {
72c80375
RM
779 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, GetLoaderVtbl, iface);
780 return IDirectMusicLoaderGenericStream_IStream_Release ((LPSTREAM)&This->StreamVtbl);
781}
782
12179978 783static HRESULT WINAPI IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface, IDirectMusicLoader **ppLoader) {
72c80375 784 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, GetLoaderVtbl, iface);
df167d17
RM
785
786 TRACE("(%p, %p)\n", This, ppLoader);
787 *ppLoader = (LPDIRECTMUSICLOADER)This->pLoader;
1d0585c4
RM
788 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8)*ppLoader);
789
df167d17
RM
790 return S_OK;
791}
792
247246ed 793static const IDirectMusicGetLoaderVtbl DirectMusicLoaderGenericStream_GetLoader_Vtbl = {
72c80375
RM
794 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_QueryInterface,
795 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef,
796 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_Release,
797 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_GetLoader
df167d17
RM
798};
799
72c80375
RM
800HRESULT WINAPI DMUSIC_CreateDirectMusicLoaderGenericStream (LPVOID* ppobj) {
801 IDirectMusicLoaderGenericStream *obj;
df167d17 802
0382ea1d 803 TRACE("(%p)\n", ppobj);
72c80375
RM
804 obj = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(IDirectMusicLoaderGenericStream));
805 if (NULL == obj) {
ee0344a4 806 *ppobj = NULL;
df167d17
RM
807 return E_OUTOFMEMORY;
808 }
72c80375
RM
809 obj->StreamVtbl = &DirectMusicLoaderGenericStream_Stream_Vtbl;
810 obj->GetLoaderVtbl = &DirectMusicLoaderGenericStream_GetLoader_Vtbl;
811 obj->dwRef = 0; /* will be inited with QueryInterface */
812
813 return IDirectMusicLoaderGenericStream_IStream_QueryInterface ((LPSTREAM)&obj->StreamVtbl, &IID_IStream, ppobj);
814}