1 /* IDirectMusicLoaderFileStream
2 * IDirectMusicLoaderResourceStream
3 * IDirectMusicLoaderGenericStream
5 * Copyright (C) 2003-2004 Rok Mandeljc
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.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
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
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
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
44 * - Rok Mandeljc; 24. April, 2004
47 #define NONAMELESSUNION
49 #include "dmloader_private.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(dmloader
);
52 WINE_DECLARE_DEBUG_CHANNEL(dmfileraw
);
54 static ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface
);
55 static ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
);
56 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
);
57 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface
);
58 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IStream_AddRef (LPSTREAM iface
);
59 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
);
62 /*****************************************************************************
63 * IDirectMusicLoaderFileStream implementation
67 static void IDirectMusicLoaderFileStream_Detach (LPSTREAM iface
) {
68 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
69 TRACE("(%p)\n", This
);
70 if (This
->hFile
!= INVALID_HANDLE_VALUE
) CloseHandle(This
->hFile
);
71 This
->wzFileName
[0] = '\0';
74 HRESULT WINAPI
IDirectMusicLoaderFileStream_Attach (LPSTREAM iface
, LPCWSTR wzFile
, LPDIRECTMUSICLOADER8 pLoader
) {
75 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
76 TRACE("(%p, %s, %p)\n", This
, debugstr_w(wzFile
), pLoader
);
77 IDirectMusicLoaderFileStream_Detach (iface
);
78 This
->hFile
= CreateFileW (wzFile
, (GENERIC_READ
| GENERIC_WRITE
), (FILE_SHARE_READ
| FILE_SHARE_WRITE
), NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
79 if (This
->hFile
== INVALID_HANDLE_VALUE
) {
81 return DMUS_E_LOADER_FAILEDOPEN
;
83 /* create IDirectMusicGetLoader */
84 This
->pLoader
= pLoader
;
85 lstrcpynW (This
->wzFileName
, wzFile
, MAX_PATH
);
86 TRACE(": succeeded\n");
91 /* IUnknown/IStream part: */
92 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
93 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
95 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
96 if (IsEqualIID (riid
, &IID_IUnknown
) ||
97 IsEqualIID (riid
, &IID_IStream
)) {
98 *ppobj
= &This
->StreamVtbl
;
99 IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
101 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
102 *ppobj
= &This
->GetLoaderVtbl
;
103 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
107 WARN(": not found\n");
108 return E_NOINTERFACE
;
111 static ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface
) {
112 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
113 TRACE("(%p): AddRef from %d\n", This
, This
->dwRef
);
114 return InterlockedIncrement (&This
->dwRef
);
117 static ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_Release (LPSTREAM iface
) {
118 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
120 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
121 TRACE("(%p): ReleaseRef to %d\n", This
, dwRef
);
124 IDirectMusicLoaderFileStream_Detach (iface
);
125 HeapFree (GetProcessHeap(), 0, This
);
131 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
132 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
135 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p)\n", This
, pv
, cb
, pcbRead
);
136 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
137 if (pcbRead
== NULL
) pcbRead
= &cbRead
;
138 if (!ReadFile (This
->hFile
, pv
, cb
, pcbRead
, NULL
) || *pcbRead
!= cb
) return E_FAIL
;
140 TRACE_(dmfileraw
)(": data (size = 0x%08X): %s\n", *pcbRead
, debugstr_an(pv
, *pcbRead
));
144 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
145 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
146 LARGE_INTEGER liNewPos
;
148 TRACE_(dmfileraw
)("(%p, %s, %s, %p)\n", This
, wine_dbgstr_longlong(dlibMove
.QuadPart
), resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
150 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
152 liNewPos
.u
.HighPart
= dlibMove
.u
.HighPart
;
153 liNewPos
.u
.LowPart
= SetFilePointer (This
->hFile
, dlibMove
.u
.LowPart
, &liNewPos
.u
.HighPart
, dwOrigin
);
155 if (liNewPos
.u
.LowPart
== INVALID_SET_FILE_POINTER
&& GetLastError() != NO_ERROR
) return E_FAIL
;
156 if (plibNewPosition
) plibNewPosition
->QuadPart
= liNewPos
.QuadPart
;
161 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
162 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
163 LPSTREAM pOther
= NULL
;
166 TRACE("(%p, %p)\n", iface
, ppstm
);
167 result
= DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID
*)&pOther
);
168 if (FAILED(result
)) return result
;
169 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
170 ULARGE_INTEGER ullCurrentPosition
;
171 result
= IDirectMusicLoaderFileStream_Attach (pOther
, This
->wzFileName
, This
->pLoader
);
172 if (SUCCEEDED(result
)) {
173 LARGE_INTEGER liZero
;
175 result
= IDirectMusicLoaderFileStream_IStream_Seek (iface
, liZero
, STREAM_SEEK_CUR
, &ullCurrentPosition
); /* get current position in current stream */
177 if (SUCCEEDED(result
)) {
178 LARGE_INTEGER liNewPosition
;
179 liNewPosition
.QuadPart
= ullCurrentPosition
.QuadPart
;
180 result
= IDirectMusicLoaderFileStream_IStream_Seek (pOther
, liNewPosition
, STREAM_SEEK_SET
, &ullCurrentPosition
);
182 if (FAILED(result
)) {
184 IDirectMusicLoaderFileStream_IStream_Release (pOther
);
188 TRACE(": succeeded\n");
193 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
194 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
197 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p)\n", This
, pv
, cb
, pcbWritten
);
198 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
199 if (pcbWritten
== NULL
) pcbWritten
= &cbWrite
;
200 if (!WriteFile (This
->hFile
, pv
, cb
, pcbWritten
, NULL
) || *pcbWritten
!= cb
) return E_FAIL
;
202 TRACE_(dmfileraw
)(": data (size = 0x%08X): %s\n", *pcbWritten
, debugstr_an(pv
, *pcbWritten
));
206 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
207 ERR(": should not be needed\n");
211 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
212 ERR(": should not be needed\n");
216 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
217 ERR(": should not be needed\n");
221 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Revert (LPSTREAM iface
) {
222 ERR(": should not be needed\n");
226 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
227 ERR(": should not be needed\n");
231 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
232 ERR(": should not be needed\n");
236 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
237 ERR(": should not be needed\n");
241 static const IStreamVtbl DirectMusicLoaderFileStream_Stream_Vtbl
= {
242 IDirectMusicLoaderFileStream_IStream_QueryInterface
,
243 IDirectMusicLoaderFileStream_IStream_AddRef
,
244 IDirectMusicLoaderFileStream_IStream_Release
,
245 IDirectMusicLoaderFileStream_IStream_Read
,
246 IDirectMusicLoaderFileStream_IStream_Write
,
247 IDirectMusicLoaderFileStream_IStream_Seek
,
248 IDirectMusicLoaderFileStream_IStream_SetSize
,
249 IDirectMusicLoaderFileStream_IStream_CopyTo
,
250 IDirectMusicLoaderFileStream_IStream_Commit
,
251 IDirectMusicLoaderFileStream_IStream_Revert
,
252 IDirectMusicLoaderFileStream_IStream_LockRegion
,
253 IDirectMusicLoaderFileStream_IStream_UnlockRegion
,
254 IDirectMusicLoaderFileStream_IStream_Stat
,
255 IDirectMusicLoaderFileStream_IStream_Clone
258 /* IDirectMusicGetLoader part: */
259 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
260 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
261 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
264 static ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
265 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
266 return IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
269 static ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
270 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
271 return IDirectMusicLoaderFileStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
274 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
275 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
277 TRACE("(%p, %p)\n", This
, ppLoader
);
278 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
279 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
284 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderFileStream_GetLoader_Vtbl
= {
285 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface
,
286 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef
,
287 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release
,
288 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader
291 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderFileStream (LPVOID
* ppobj
) {
292 IDirectMusicLoaderFileStream
*obj
;
294 TRACE("(%p)\n", ppobj
);
295 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderFileStream
));
298 return E_OUTOFMEMORY
;
300 obj
->StreamVtbl
= &DirectMusicLoaderFileStream_Stream_Vtbl
;
301 obj
->GetLoaderVtbl
= &DirectMusicLoaderFileStream_GetLoader_Vtbl
;
302 obj
->dwRef
= 0; /* will be inited with QueryInterface */
304 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);
308 /*****************************************************************************
309 * IDirectMusicLoaderResourceStream implementation
313 static void IDirectMusicLoaderResourceStream_Detach (LPSTREAM iface
) {
314 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
315 TRACE("(%p)\n", This
);
317 This
->pbMemData
= NULL
;
318 This
->llMemLength
= 0;
321 HRESULT WINAPI
IDirectMusicLoaderResourceStream_Attach (LPSTREAM iface
, LPBYTE pbMemData
, LONGLONG llMemLength
, LONGLONG llPos
, LPDIRECTMUSICLOADER8 pLoader
) {
322 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
324 TRACE("(%p, %p, %s, %s, %p)\n", This
, pbMemData
, wine_dbgstr_longlong(llMemLength
), wine_dbgstr_longlong(llPos
), pLoader
);
325 if (!pbMemData
|| !llMemLength
) {
326 WARN(": invalid pbMemData or llMemLength\n");
329 IDirectMusicLoaderResourceStream_Detach (iface
);
330 This
->pbMemData
= pbMemData
;
331 This
->llMemLength
= llMemLength
;
333 This
->pLoader
= pLoader
;
339 /* IUnknown/IStream part: */
340 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
341 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
343 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
344 if (IsEqualIID (riid
, &IID_IUnknown
) ||
345 IsEqualIID (riid
, &IID_IStream
)) {
346 *ppobj
= &This
->StreamVtbl
;
347 IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
349 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
350 *ppobj
= &This
->GetLoaderVtbl
;
351 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
355 WARN(": not found\n");
356 return E_NOINTERFACE
;
359 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface
) {
360 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
361 TRACE("(%p): AddRef from %d\n", This
, This
->dwRef
);
362 return InterlockedIncrement (&This
->dwRef
);
365 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IStream_Release (LPSTREAM iface
) {
366 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
368 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
369 TRACE("(%p): ReleaseRef to %d\n", This
, dwRef
);
371 IDirectMusicLoaderResourceStream_Detach (iface
);
372 HeapFree (GetProcessHeap(), 0, This
);
378 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
380 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
382 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p)\n", This
, pv
, cb
, pcbRead
);
383 if ((This
->llPos
+ cb
) > This
->llMemLength
) {
384 WARN_(dmfileraw
)(": requested size out of range\n");
388 pByte
= &This
->pbMemData
[This
->llPos
];
389 memcpy (pv
, pByte
, cb
);
390 This
->llPos
+= cb
; /* move pointer */
391 /* FIXME: error checking would be nice */
392 if (pcbRead
) *pcbRead
= cb
;
394 TRACE_(dmfileraw
)(": data (size = 0x%08X): %s\n", cb
, debugstr_an(pv
, cb
));
398 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
399 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
400 TRACE_(dmfileraw
)("(%p, %s, %s, %p)\n", This
, wine_dbgstr_longlong(dlibMove
.QuadPart
), resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
403 case STREAM_SEEK_CUR
: {
404 if ((This
->llPos
+ dlibMove
.QuadPart
) > This
->llMemLength
) {
405 WARN_(dmfileraw
)(": requested offset out of range\n");
410 case STREAM_SEEK_SET
: {
411 if (dlibMove
.QuadPart
> This
->llMemLength
) {
412 WARN_(dmfileraw
)(": requested offset out of range\n");
415 /* set to the beginning of the stream */
419 case STREAM_SEEK_END
: {
420 /* TODO: check if this is true... I do think offset should be negative in this case */
421 if (dlibMove
.QuadPart
> 0) {
422 WARN_(dmfileraw
)(": requested offset out of range\n");
425 /* set to the end of the stream */
426 This
->llPos
= This
->llMemLength
;
430 ERR_(dmfileraw
)(": invalid dwOrigin\n");
435 This
->llPos
+= dlibMove
.QuadPart
;
437 if (plibNewPosition
) plibNewPosition
->QuadPart
= This
->llPos
;
442 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
443 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
444 LPSTREAM pOther
= NULL
;
447 TRACE("(%p, %p)\n", iface
, ppstm
);
448 result
= DMUSIC_CreateDirectMusicLoaderResourceStream ((LPVOID
*)&pOther
);
449 if (FAILED(result
)) return result
;
451 IDirectMusicLoaderResourceStream_Attach (pOther
, This
->pbMemData
, This
->llMemLength
, This
->llPos
, This
->pLoader
);
453 TRACE(": succeeded\n");
458 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
459 ERR(": should not be needed\n");
463 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
464 ERR(": should not be needed\n");
468 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
469 ERR(": should not be needed\n");
473 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
474 ERR(": should not be needed\n");
478 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Revert (LPSTREAM iface
) {
479 ERR(": should not be needed\n");
483 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
484 ERR(": should not be needed\n");
488 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
489 ERR(": should not be needed\n");
493 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
494 ERR(": should not be needed\n");
498 static const IStreamVtbl DirectMusicLoaderResourceStream_Stream_Vtbl
= {
499 IDirectMusicLoaderResourceStream_IStream_QueryInterface
,
500 IDirectMusicLoaderResourceStream_IStream_AddRef
,
501 IDirectMusicLoaderResourceStream_IStream_Release
,
502 IDirectMusicLoaderResourceStream_IStream_Read
,
503 IDirectMusicLoaderResourceStream_IStream_Write
,
504 IDirectMusicLoaderResourceStream_IStream_Seek
,
505 IDirectMusicLoaderResourceStream_IStream_SetSize
,
506 IDirectMusicLoaderResourceStream_IStream_CopyTo
,
507 IDirectMusicLoaderResourceStream_IStream_Commit
,
508 IDirectMusicLoaderResourceStream_IStream_Revert
,
509 IDirectMusicLoaderResourceStream_IStream_LockRegion
,
510 IDirectMusicLoaderResourceStream_IStream_UnlockRegion
,
511 IDirectMusicLoaderResourceStream_IStream_Stat
,
512 IDirectMusicLoaderResourceStream_IStream_Clone
515 /* IDirectMusicGetLoader part: */
516 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
517 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
518 return IDirectMusicLoaderResourceStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
521 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
522 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
523 return IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
526 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
527 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
528 return IDirectMusicLoaderResourceStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
531 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
532 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
534 TRACE("(%p, %p)\n", This
, ppLoader
);
535 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
536 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
541 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderResourceStream_GetLoader_Vtbl
= {
542 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_QueryInterface
,
543 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef
,
544 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_Release
,
545 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_GetLoader
548 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderResourceStream (LPVOID
* ppobj
) {
549 IDirectMusicLoaderResourceStream
*obj
;
551 TRACE("(%p)\n", ppobj
);
552 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderResourceStream
));
555 return E_OUTOFMEMORY
;
557 obj
->StreamVtbl
= &DirectMusicLoaderResourceStream_Stream_Vtbl
;
558 obj
->GetLoaderVtbl
= &DirectMusicLoaderResourceStream_GetLoader_Vtbl
;
559 obj
->dwRef
= 0; /* will be inited with QueryInterface */
561 return IDirectMusicLoaderResourceStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);
565 /*****************************************************************************
566 * IDirectMusicLoaderGenericStream implementation
570 static void IDirectMusicLoaderGenericStream_Detach (LPSTREAM iface
) {
571 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
574 IStream_Release (This
->pStream
);
575 This
->pStream
= NULL
;
578 HRESULT WINAPI
IDirectMusicLoaderGenericStream_Attach (LPSTREAM iface
, LPSTREAM pStream
, LPDIRECTMUSICLOADER8 pLoader
) {
579 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
581 TRACE("(%p, %p, %p)\n", This
, pStream
, pLoader
);
583 WARN(": invalid pStream\n");
587 WARN(": invalid pLoader\n");
591 IDirectMusicLoaderGenericStream_Detach (iface
);
592 IStream_Clone (pStream
, &This
->pStream
);
593 This
->pLoader
= pLoader
;
599 /* IUnknown/IStream part: */
600 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
601 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
603 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
604 if (IsEqualIID (riid
, &IID_IUnknown
) ||
605 IsEqualIID (riid
, &IID_IStream
)) {
606 *ppobj
= &This
->StreamVtbl
;
607 IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
609 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
610 *ppobj
= &This
->GetLoaderVtbl
;
611 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
615 WARN(": not found\n");
616 return E_NOINTERFACE
;
619 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IStream_AddRef (LPSTREAM iface
) {
620 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
621 TRACE("(%p): AddRef from %d\n", This
, This
->dwRef
);
622 return InterlockedIncrement (&This
->dwRef
);
625 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IStream_Release (LPSTREAM iface
) {
626 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
628 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
629 TRACE("(%p): ReleaseRef to %d\n", This
, dwRef
);
631 IDirectMusicLoaderGenericStream_Detach (iface
);
632 HeapFree (GetProcessHeap(), 0, This
);
638 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
639 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
641 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p): redirecting to low-level stream\n", This
, pv
, cb
, pcbRead
);
645 return IStream_Read (This
->pStream
, pv
, cb
, pcbRead
);
648 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
649 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
650 TRACE_(dmfileraw
)("(%p, %s, %s, %p): redirecting to low-level stream\n", This
, wine_dbgstr_longlong(dlibMove
.QuadPart
), resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
654 return IStream_Seek (This
->pStream
, dlibMove
, dwOrigin
, plibNewPosition
);
657 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
658 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
659 LPSTREAM pOther
= NULL
;
660 LPSTREAM pLowLevel
= NULL
;
663 TRACE("(%p, %p)\n", iface
, ppstm
);
664 result
= DMUSIC_CreateDirectMusicLoaderGenericStream ((LPVOID
*)&pOther
);
665 if (FAILED(result
)) return result
;
667 if (FAILED(IStream_Clone (This
->pStream
, &pLowLevel
)))
670 IDirectMusicLoaderGenericStream_Attach (pOther
, pLowLevel
, This
->pLoader
);
672 TRACE(": succeeded\n");
677 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
678 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
679 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p): redirecting to low-level stream\n", This
, pv
, cb
, pcbWritten
);
683 return IStream_Write (This
->pStream
, pv
, cb
, pcbWritten
);
686 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
687 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
688 TRACE("(%p, %s): redirecting to low-level stream\n", This
, wine_dbgstr_longlong(libNewSize
.QuadPart
));
692 return IStream_SetSize (This
->pStream
, libNewSize
);
695 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
696 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
697 TRACE("(%p, %p, %s, %p, %p): redirecting to low-level stream\n", This
, pstm
, wine_dbgstr_longlong(cb
.QuadPart
), pcbRead
, pcbWritten
);
701 return IStream_CopyTo (This
->pStream
, pstm
, cb
, pcbRead
, pcbWritten
);
704 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
705 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
706 TRACE("(%p, 0x%08X): redirecting to low-level stream\n", This
, grfCommitFlags
);
710 return IStream_Commit (This
->pStream
, grfCommitFlags
);
713 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Revert (LPSTREAM iface
) {
714 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
715 TRACE("(%p): redirecting to low-level stream\n", This
);
719 return IStream_Revert (This
->pStream
);
722 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
723 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
724 TRACE("(%p, %s, %s, 0x%08X): redirecting to low-level stream\n", This
, wine_dbgstr_longlong(libOffset
.QuadPart
), wine_dbgstr_longlong(cb
.QuadPart
), dwLockType
);
728 return IStream_LockRegion (This
->pStream
, libOffset
, cb
, dwLockType
);
731 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
732 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
733 TRACE("(%p, %s, %s, 0x%08X): redirecting to low-level stream\n", This
, wine_dbgstr_longlong(libOffset
.QuadPart
), wine_dbgstr_longlong(cb
.QuadPart
), dwLockType
);
737 return IStream_UnlockRegion (This
->pStream
, libOffset
, cb
, dwLockType
);
740 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
741 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
742 TRACE("(%p, %p, 0x%08X): redirecting to low-level stream\n", This
, pstatstg
, grfStatFlag
);
746 return IStream_Stat (This
->pStream
, pstatstg
, grfStatFlag
);
749 static const IStreamVtbl DirectMusicLoaderGenericStream_Stream_Vtbl
= {
750 IDirectMusicLoaderGenericStream_IStream_QueryInterface
,
751 IDirectMusicLoaderGenericStream_IStream_AddRef
,
752 IDirectMusicLoaderGenericStream_IStream_Release
,
753 IDirectMusicLoaderGenericStream_IStream_Read
,
754 IDirectMusicLoaderGenericStream_IStream_Write
,
755 IDirectMusicLoaderGenericStream_IStream_Seek
,
756 IDirectMusicLoaderGenericStream_IStream_SetSize
,
757 IDirectMusicLoaderGenericStream_IStream_CopyTo
,
758 IDirectMusicLoaderGenericStream_IStream_Commit
,
759 IDirectMusicLoaderGenericStream_IStream_Revert
,
760 IDirectMusicLoaderGenericStream_IStream_LockRegion
,
761 IDirectMusicLoaderGenericStream_IStream_UnlockRegion
,
762 IDirectMusicLoaderGenericStream_IStream_Stat
,
763 IDirectMusicLoaderGenericStream_IStream_Clone
766 /* IDirectMusicGetLoader part: */
767 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
768 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
769 return IDirectMusicLoaderGenericStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
772 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
773 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
774 return IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
777 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
778 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
779 return IDirectMusicLoaderGenericStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
782 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
783 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
785 TRACE("(%p, %p)\n", This
, ppLoader
);
786 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
787 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
792 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderGenericStream_GetLoader_Vtbl
= {
793 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_QueryInterface
,
794 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef
,
795 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_Release
,
796 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_GetLoader
799 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderGenericStream (LPVOID
* ppobj
) {
800 IDirectMusicLoaderGenericStream
*obj
;
802 TRACE("(%p)\n", ppobj
);
803 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderGenericStream
));
806 return E_OUTOFMEMORY
;
808 obj
->StreamVtbl
= &DirectMusicLoaderGenericStream_Stream_Vtbl
;
809 obj
->GetLoaderVtbl
= &DirectMusicLoaderGenericStream_GetLoader_Vtbl
;
810 obj
->dwRef
= 0; /* will be inited with QueryInterface */
812 return IDirectMusicLoaderGenericStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);