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
48 #define NONAMELESSSTRUCT
50 #include "dmloader_private.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(dmloader
);
53 WINE_DECLARE_DEBUG_CHANNEL(dmfileraw
);
55 static ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface
);
56 static ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
);
57 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
);
58 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface
);
59 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IStream_AddRef (LPSTREAM iface
);
60 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
);
63 /*****************************************************************************
64 * IDirectMusicLoaderFileStream implementation
68 static 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';
75 HRESULT WINAPI
IDirectMusicLoaderFileStream_Attach (LPSTREAM iface
, LPCWSTR wzFile
, LPDIRECTMUSICLOADER8 pLoader
) {
76 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
77 TRACE("(%p, %s, %p)\n", This
, debugstr_w(wzFile
), pLoader
);
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
);
80 if (This
->hFile
== INVALID_HANDLE_VALUE
) {
82 return DMUS_E_LOADER_FAILEDOPEN
;
84 /* create IDirectMusicGetLoader */
85 This
->pLoader
= pLoader
;
86 lstrcpynW (This
->wzFileName
, wzFile
, MAX_PATH
);
87 TRACE(": succeeded\n");
92 /* IUnknown/IStream part: */
93 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
94 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
96 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
97 if (IsEqualIID (riid
, &IID_IUnknown
) ||
98 IsEqualIID (riid
, &IID_IStream
)) {
99 *ppobj
= &This
->StreamVtbl
;
100 IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
102 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
103 *ppobj
= &This
->GetLoaderVtbl
;
104 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
108 WARN(": not found\n");
109 return E_NOINTERFACE
;
112 static ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface
) {
113 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
114 TRACE("(%p): AddRef from %d\n", This
, This
->dwRef
);
115 return InterlockedIncrement (&This
->dwRef
);
118 static ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_Release (LPSTREAM iface
) {
119 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
121 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
122 TRACE("(%p): ReleaseRef to %d\n", This
, dwRef
);
125 IDirectMusicLoaderFileStream_Detach (iface
);
126 HeapFree (GetProcessHeap(), 0, This
);
132 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
133 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
136 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p)\n", This
, pv
, cb
, pcbRead
);
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
;
141 TRACE_(dmfileraw
)(": data (size = 0x%08X): %s\n", *pcbRead
, debugstr_an(pv
, *pcbRead
));
145 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
146 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
147 LARGE_INTEGER liNewPos
;
149 TRACE_(dmfileraw
)("(%p, %s, %s, %p)\n", This
, wine_dbgstr_longlong(dlibMove
.QuadPart
), resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
151 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
153 liNewPos
.u
.HighPart
= dlibMove
.u
.HighPart
;
154 liNewPos
.u
.LowPart
= SetFilePointer (This
->hFile
, dlibMove
.u
.LowPart
, &liNewPos
.u
.HighPart
, dwOrigin
);
156 if (liNewPos
.u
.LowPart
== INVALID_SET_FILE_POINTER
&& GetLastError() != NO_ERROR
) return E_FAIL
;
157 if (plibNewPosition
) plibNewPosition
->QuadPart
= liNewPos
.QuadPart
;
162 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
163 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
164 LPSTREAM pOther
= NULL
;
167 TRACE("(%p, %p)\n", iface
, ppstm
);
168 result
= DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID
*)&pOther
);
169 if (FAILED(result
)) return result
;
170 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
171 ULARGE_INTEGER ullCurrentPosition
;
172 result
= IDirectMusicLoaderFileStream_Attach (pOther
, This
->wzFileName
, This
->pLoader
);
173 if (SUCCEEDED(result
)) {
174 LARGE_INTEGER liZero
;
176 result
= IDirectMusicLoaderFileStream_IStream_Seek (iface
, liZero
, STREAM_SEEK_CUR
, &ullCurrentPosition
); /* get current position in current stream */
178 if (SUCCEEDED(result
)) {
179 LARGE_INTEGER liNewPosition
;
180 liNewPosition
.QuadPart
= ullCurrentPosition
.QuadPart
;
181 result
= IDirectMusicLoaderFileStream_IStream_Seek (pOther
, liNewPosition
, STREAM_SEEK_SET
, &ullCurrentPosition
);
183 if (FAILED(result
)) {
185 IDirectMusicLoaderFileStream_IStream_Release (pOther
);
189 TRACE(": succeeded\n");
194 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
195 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
198 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p)\n", This
, pv
, cb
, pcbWritten
);
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
;
203 TRACE_(dmfileraw
)(": data (size = 0x%08X): %s\n", *pcbWritten
, debugstr_an(pv
, *pcbWritten
));
207 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
208 ERR(": should not be needed\n");
212 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
213 ERR(": should not be needed\n");
217 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
218 ERR(": should not be needed\n");
222 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Revert (LPSTREAM iface
) {
223 ERR(": should not be needed\n");
227 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
228 ERR(": should not be needed\n");
232 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
233 ERR(": should not be needed\n");
237 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
238 ERR(": should not be needed\n");
242 static const IStreamVtbl DirectMusicLoaderFileStream_Stream_Vtbl
= {
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
259 /* IDirectMusicGetLoader part: */
260 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
261 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
262 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
265 static ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
266 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
267 return IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
270 static ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
271 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
272 return IDirectMusicLoaderFileStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
275 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
276 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
278 TRACE("(%p, %p)\n", This
, ppLoader
);
279 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
280 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
285 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderFileStream_GetLoader_Vtbl
= {
286 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface
,
287 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef
,
288 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release
,
289 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader
292 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderFileStream (LPVOID
* ppobj
) {
293 IDirectMusicLoaderFileStream
*obj
;
295 TRACE("(%p)\n", ppobj
);
296 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderFileStream
));
299 return E_OUTOFMEMORY
;
301 obj
->StreamVtbl
= &DirectMusicLoaderFileStream_Stream_Vtbl
;
302 obj
->GetLoaderVtbl
= &DirectMusicLoaderFileStream_GetLoader_Vtbl
;
303 obj
->dwRef
= 0; /* will be inited with QueryInterface */
305 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);
309 /*****************************************************************************
310 * IDirectMusicLoaderResourceStream implementation
314 static void IDirectMusicLoaderResourceStream_Detach (LPSTREAM iface
) {
315 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
316 TRACE("(%p)\n", This
);
318 This
->pbMemData
= NULL
;
319 This
->llMemLength
= 0;
322 HRESULT WINAPI
IDirectMusicLoaderResourceStream_Attach (LPSTREAM iface
, LPBYTE pbMemData
, LONGLONG llMemLength
, LONGLONG llPos
, LPDIRECTMUSICLOADER8 pLoader
) {
323 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
325 TRACE("(%p, %p, %s, %s, %p)\n", This
, pbMemData
, wine_dbgstr_longlong(llMemLength
), wine_dbgstr_longlong(llPos
), pLoader
);
326 if (!pbMemData
|| !llMemLength
) {
327 WARN(": invalid pbMemData or llMemLength\n");
330 IDirectMusicLoaderResourceStream_Detach (iface
);
331 This
->pbMemData
= pbMemData
;
332 This
->llMemLength
= llMemLength
;
334 This
->pLoader
= pLoader
;
340 /* IUnknown/IStream part: */
341 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
342 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
344 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
345 if (IsEqualIID (riid
, &IID_IUnknown
) ||
346 IsEqualIID (riid
, &IID_IStream
)) {
347 *ppobj
= &This
->StreamVtbl
;
348 IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
350 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
351 *ppobj
= &This
->GetLoaderVtbl
;
352 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
356 WARN(": not found\n");
357 return E_NOINTERFACE
;
360 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface
) {
361 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
362 TRACE("(%p): AddRef from %d\n", This
, This
->dwRef
);
363 return InterlockedIncrement (&This
->dwRef
);
366 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IStream_Release (LPSTREAM iface
) {
367 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
369 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
370 TRACE("(%p): ReleaseRef to %d\n", This
, dwRef
);
372 IDirectMusicLoaderResourceStream_Detach (iface
);
373 HeapFree (GetProcessHeap(), 0, This
);
379 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
381 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
383 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p)\n", This
, pv
, cb
, pcbRead
);
384 if ((This
->llPos
+ cb
) > This
->llMemLength
) {
385 WARN_(dmfileraw
)(": requested size out of range\n");
389 pByte
= &This
->pbMemData
[This
->llPos
];
390 memcpy (pv
, pByte
, cb
);
391 This
->llPos
+= cb
; /* move pointer */
392 /* FIXME: error checking would be nice */
393 if (pcbRead
) *pcbRead
= cb
;
395 TRACE_(dmfileraw
)(": data (size = 0x%08X): %s\n", cb
, debugstr_an(pv
, cb
));
399 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
400 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
401 TRACE_(dmfileraw
)("(%p, %s, %s, %p)\n", This
, wine_dbgstr_longlong(dlibMove
.QuadPart
), resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
404 case STREAM_SEEK_CUR
: {
405 if ((This
->llPos
+ dlibMove
.QuadPart
) > This
->llMemLength
) {
406 WARN_(dmfileraw
)(": requested offset out of range\n");
411 case STREAM_SEEK_SET
: {
412 if (dlibMove
.QuadPart
> This
->llMemLength
) {
413 WARN_(dmfileraw
)(": requested offset out of range\n");
416 /* set to the beginning of the stream */
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");
426 /* set to the end of the stream */
427 This
->llPos
= This
->llMemLength
;
431 ERR_(dmfileraw
)(": invalid dwOrigin\n");
436 This
->llPos
+= dlibMove
.QuadPart
;
438 if (plibNewPosition
) plibNewPosition
->QuadPart
= This
->llPos
;
443 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
444 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
445 LPSTREAM pOther
= NULL
;
448 TRACE("(%p, %p)\n", iface
, ppstm
);
449 result
= DMUSIC_CreateDirectMusicLoaderResourceStream ((LPVOID
*)&pOther
);
450 if (FAILED(result
)) return result
;
452 IDirectMusicLoaderResourceStream_Attach (pOther
, This
->pbMemData
, This
->llMemLength
, This
->llPos
, This
->pLoader
);
454 TRACE(": succeeded\n");
459 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
460 ERR(": should not be needed\n");
464 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
465 ERR(": should not be needed\n");
469 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
470 ERR(": should not be needed\n");
474 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
475 ERR(": should not be needed\n");
479 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Revert (LPSTREAM iface
) {
480 ERR(": should not be needed\n");
484 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
485 ERR(": should not be needed\n");
489 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
490 ERR(": should not be needed\n");
494 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
495 ERR(": should not be needed\n");
499 static const IStreamVtbl DirectMusicLoaderResourceStream_Stream_Vtbl
= {
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
516 /* IDirectMusicGetLoader part: */
517 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
518 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
519 return IDirectMusicLoaderResourceStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
522 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
523 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
524 return IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
527 static ULONG WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
528 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
529 return IDirectMusicLoaderResourceStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
532 static HRESULT WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
533 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
535 TRACE("(%p, %p)\n", This
, ppLoader
);
536 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
537 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
542 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderResourceStream_GetLoader_Vtbl
= {
543 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_QueryInterface
,
544 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef
,
545 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_Release
,
546 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_GetLoader
549 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderResourceStream (LPVOID
* ppobj
) {
550 IDirectMusicLoaderResourceStream
*obj
;
552 TRACE("(%p)\n", ppobj
);
553 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderResourceStream
));
556 return E_OUTOFMEMORY
;
558 obj
->StreamVtbl
= &DirectMusicLoaderResourceStream_Stream_Vtbl
;
559 obj
->GetLoaderVtbl
= &DirectMusicLoaderResourceStream_GetLoader_Vtbl
;
560 obj
->dwRef
= 0; /* will be inited with QueryInterface */
562 return IDirectMusicLoaderResourceStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);
566 /*****************************************************************************
567 * IDirectMusicLoaderGenericStream implementation
571 static void IDirectMusicLoaderGenericStream_Detach (LPSTREAM iface
) {
572 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
575 IStream_Release (This
->pStream
);
576 This
->pStream
= NULL
;
579 HRESULT WINAPI
IDirectMusicLoaderGenericStream_Attach (LPSTREAM iface
, LPSTREAM pStream
, LPDIRECTMUSICLOADER8 pLoader
) {
580 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
582 TRACE("(%p, %p, %p)\n", This
, pStream
, pLoader
);
584 WARN(": invalid pStream\n");
588 WARN(": invalid pLoader\n");
592 IDirectMusicLoaderGenericStream_Detach (iface
);
593 IStream_Clone (pStream
, &This
->pStream
);
594 This
->pLoader
= pLoader
;
600 /* IUnknown/IStream part: */
601 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
602 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
604 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
605 if (IsEqualIID (riid
, &IID_IUnknown
) ||
606 IsEqualIID (riid
, &IID_IStream
)) {
607 *ppobj
= &This
->StreamVtbl
;
608 IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
610 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
611 *ppobj
= &This
->GetLoaderVtbl
;
612 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
616 WARN(": not found\n");
617 return E_NOINTERFACE
;
620 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IStream_AddRef (LPSTREAM iface
) {
621 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
622 TRACE("(%p): AddRef from %d\n", This
, This
->dwRef
);
623 return InterlockedIncrement (&This
->dwRef
);
626 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IStream_Release (LPSTREAM iface
) {
627 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
629 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
630 TRACE("(%p): ReleaseRef to %d\n", This
, dwRef
);
632 IDirectMusicLoaderGenericStream_Detach (iface
);
633 HeapFree (GetProcessHeap(), 0, This
);
639 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
640 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
642 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p): redirecting to low-level stream\n", This
, pv
, cb
, pcbRead
);
646 return IStream_Read (This
->pStream
, pv
, cb
, pcbRead
);
649 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
650 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
651 TRACE_(dmfileraw
)("(%p, %s, %s, %p): redirecting to low-level stream\n", This
, wine_dbgstr_longlong(dlibMove
.QuadPart
), resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
655 return IStream_Seek (This
->pStream
, dlibMove
, dwOrigin
, plibNewPosition
);
658 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
659 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
660 LPSTREAM pOther
= NULL
;
661 LPSTREAM pLowLevel
= NULL
;
664 TRACE("(%p, %p)\n", iface
, ppstm
);
665 result
= DMUSIC_CreateDirectMusicLoaderGenericStream ((LPVOID
*)&pOther
);
666 if (FAILED(result
)) return result
;
668 if (FAILED(IStream_Clone (This
->pStream
, &pLowLevel
)))
671 IDirectMusicLoaderGenericStream_Attach (pOther
, pLowLevel
, This
->pLoader
);
673 TRACE(": succeeded\n");
678 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
679 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
680 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p): redirecting to low-level stream\n", This
, pv
, cb
, pcbWritten
);
684 return IStream_Write (This
->pStream
, pv
, cb
, pcbWritten
);
687 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
688 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
689 TRACE("(%p, %s): redirecting to low-level stream\n", This
, wine_dbgstr_longlong(libNewSize
.QuadPart
));
693 return IStream_SetSize (This
->pStream
, libNewSize
);
696 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
697 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
698 TRACE("(%p, %p, %s, %p, %p): redirecting to low-level stream\n", This
, pstm
, wine_dbgstr_longlong(cb
.QuadPart
), pcbRead
, pcbWritten
);
702 return IStream_CopyTo (This
->pStream
, pstm
, cb
, pcbRead
, pcbWritten
);
705 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
706 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
707 TRACE("(%p, 0x%08X): redirecting to low-level stream\n", This
, grfCommitFlags
);
711 return IStream_Commit (This
->pStream
, grfCommitFlags
);
714 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Revert (LPSTREAM iface
) {
715 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
716 TRACE("(%p): redirecting to low-level stream\n", This
);
720 return IStream_Revert (This
->pStream
);
723 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
724 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
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
);
729 return IStream_LockRegion (This
->pStream
, libOffset
, cb
, dwLockType
);
732 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
733 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
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
);
738 return IStream_UnlockRegion (This
->pStream
, libOffset
, cb
, dwLockType
);
741 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
742 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
743 TRACE("(%p, %p, 0x%08X): redirecting to low-level stream\n", This
, pstatstg
, grfStatFlag
);
747 return IStream_Stat (This
->pStream
, pstatstg
, grfStatFlag
);
750 static const IStreamVtbl DirectMusicLoaderGenericStream_Stream_Vtbl
= {
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
767 /* IDirectMusicGetLoader part: */
768 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
769 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
770 return IDirectMusicLoaderGenericStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
773 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
774 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
775 return IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
778 static ULONG WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
779 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
780 return IDirectMusicLoaderGenericStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
783 static HRESULT WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
784 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
786 TRACE("(%p, %p)\n", This
, ppLoader
);
787 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
788 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
793 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderGenericStream_GetLoader_Vtbl
= {
794 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_QueryInterface
,
795 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef
,
796 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_Release
,
797 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_GetLoader
800 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderGenericStream (LPVOID
* ppobj
) {
801 IDirectMusicLoaderGenericStream
*obj
;
803 TRACE("(%p)\n", ppobj
);
804 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderGenericStream
));
807 return E_OUTOFMEMORY
;
809 obj
->StreamVtbl
= &DirectMusicLoaderGenericStream_Stream_Vtbl
;
810 obj
->GetLoaderVtbl
= &DirectMusicLoaderGenericStream_GetLoader_Vtbl
;
811 obj
->dwRef
= 0; /* will be inited with QueryInterface */
813 return IDirectMusicLoaderGenericStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);