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
67 HRESULT WINAPI
IDirectMusicLoaderFileStream_Attach (LPSTREAM iface
, LPCWSTR wzFile
, LPDIRECTMUSICLOADER8 pLoader
) {
68 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
69 TRACE("(%p, %s, %p)\n", This
, debugstr_w(wzFile
), pLoader
);
70 IDirectMusicLoaderFileStream_Detach (iface
);
71 This
->hFile
= CreateFileW (wzFile
, (GENERIC_READ
| GENERIC_WRITE
), (FILE_SHARE_READ
| FILE_SHARE_WRITE
), NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
72 if (This
->hFile
== INVALID_HANDLE_VALUE
) {
74 return DMUS_E_LOADER_FAILEDOPEN
;
76 /* create IDirectMusicGetLoader */
77 This
->pLoader
= pLoader
;
78 lstrcpynW (This
->wzFileName
, wzFile
, MAX_PATH
);
79 TRACE(": succeeded\n");
83 void WINAPI
IDirectMusicLoaderFileStream_Detach (LPSTREAM iface
) {
84 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
85 TRACE("(%p)\n", This
);
86 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
87 CloseHandle(This
->hFile
);
89 This
->wzFileName
[0] = '\0';
93 /* IUnknown/IStream part: */
94 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
95 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
97 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
98 if (IsEqualIID (riid
, &IID_IUnknown
) ||
99 IsEqualIID (riid
, &IID_IStream
)) {
100 *ppobj
= (LPVOID
)&This
->StreamVtbl
;
101 IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
103 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
104 *ppobj
= (LPVOID
)&This
->GetLoaderVtbl
;
105 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
109 WARN(": not found\n");
110 return E_NOINTERFACE
;
113 static ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface
) {
114 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
115 TRACE("(%p): AddRef from %d\n", This
, This
->dwRef
);
116 return InterlockedIncrement (&This
->dwRef
);
119 static ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_Release (LPSTREAM iface
) {
120 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
122 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
123 TRACE("(%p): ReleaseRef to %d\n", This
, dwRef
);
126 IDirectMusicLoaderFileStream_Detach (iface
);
127 HeapFree (GetProcessHeap(), 0, This
);
133 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
134 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
137 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p)\n", This
, pv
, cb
, pcbRead
);
138 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
139 if (pcbRead
== NULL
) pcbRead
= &cbRead
;
140 if (!ReadFile (This
->hFile
, pv
, cb
, pcbRead
, NULL
) || *pcbRead
!= cb
) return E_FAIL
;
142 TRACE_(dmfileraw
)(": data (size = 0x%08X): %s\n", *pcbRead
, debugstr_an(pv
, *pcbRead
));
146 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
147 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
148 LARGE_INTEGER liNewPos
;
150 TRACE_(dmfileraw
)("(%p, %s, %s, %p)\n", This
, wine_dbgstr_longlong(dlibMove
.QuadPart
), resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
152 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
154 liNewPos
.u
.HighPart
= dlibMove
.u
.HighPart
;
155 liNewPos
.u
.LowPart
= SetFilePointer (This
->hFile
, dlibMove
.u
.LowPart
, &liNewPos
.u
.HighPart
, dwOrigin
);
157 if (liNewPos
.u
.LowPart
== INVALID_SET_FILE_POINTER
&& GetLastError() != NO_ERROR
) return E_FAIL
;
158 if (plibNewPosition
) plibNewPosition
->QuadPart
= liNewPos
.QuadPart
;
163 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
164 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
165 LPSTREAM pOther
= NULL
;
168 TRACE("(%p, %p)\n", iface
, ppstm
);
169 result
= DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID
*)&pOther
);
170 if (FAILED(result
)) return result
;
171 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
172 ULARGE_INTEGER ullCurrentPosition
;
173 result
= IDirectMusicLoaderFileStream_Attach (pOther
, This
->wzFileName
, This
->pLoader
);
174 if (SUCCEEDED(result
)) {
175 LARGE_INTEGER liZero
;
177 result
= IDirectMusicLoaderFileStream_IStream_Seek (iface
, liZero
, STREAM_SEEK_CUR
, &ullCurrentPosition
); /* get current position in current stream */
179 if (SUCCEEDED(result
)) {
180 LARGE_INTEGER liNewPosition
;
181 liNewPosition
.QuadPart
= ullCurrentPosition
.QuadPart
;
182 result
= IDirectMusicLoaderFileStream_IStream_Seek (pOther
, liNewPosition
, STREAM_SEEK_SET
, &ullCurrentPosition
);
184 if (FAILED(result
)) {
186 IDirectMusicLoaderFileStream_IStream_Release (pOther
);
190 TRACE(": succeeded\n");
195 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
196 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
199 TRACE_(dmfileraw
)("(%p, %p, 0x%08X, %p)\n", This
, pv
, cb
, pcbWritten
);
200 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
201 if (pcbWritten
== NULL
) pcbWritten
= &cbWrite
;
202 if (!WriteFile (This
->hFile
, pv
, cb
, pcbWritten
, NULL
) || *pcbWritten
!= cb
) return E_FAIL
;
204 TRACE_(dmfileraw
)(": data (size = 0x%08X): %s\n", *pcbWritten
, debugstr_an(pv
, *pcbWritten
));
208 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
209 ERR(": should not be needed\n");
213 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
214 ERR(": should not be needed\n");
218 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
219 ERR(": should not be needed\n");
223 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Revert (LPSTREAM iface
) {
224 ERR(": should not be needed\n");
228 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
229 ERR(": should not be needed\n");
233 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
234 ERR(": should not be needed\n");
238 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
239 ERR(": should not be needed\n");
243 static const IStreamVtbl DirectMusicLoaderFileStream_Stream_Vtbl
= {
244 IDirectMusicLoaderFileStream_IStream_QueryInterface
,
245 IDirectMusicLoaderFileStream_IStream_AddRef
,
246 IDirectMusicLoaderFileStream_IStream_Release
,
247 IDirectMusicLoaderFileStream_IStream_Read
,
248 IDirectMusicLoaderFileStream_IStream_Write
,
249 IDirectMusicLoaderFileStream_IStream_Seek
,
250 IDirectMusicLoaderFileStream_IStream_SetSize
,
251 IDirectMusicLoaderFileStream_IStream_CopyTo
,
252 IDirectMusicLoaderFileStream_IStream_Commit
,
253 IDirectMusicLoaderFileStream_IStream_Revert
,
254 IDirectMusicLoaderFileStream_IStream_LockRegion
,
255 IDirectMusicLoaderFileStream_IStream_UnlockRegion
,
256 IDirectMusicLoaderFileStream_IStream_Stat
,
257 IDirectMusicLoaderFileStream_IStream_Clone
260 /* IDirectMusicGetLoader part: */
261 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
262 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
263 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
266 static ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
267 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
268 return IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
271 static ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
272 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
273 return IDirectMusicLoaderFileStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
276 static HRESULT WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
277 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
279 TRACE("(%p, %p)\n", This
, ppLoader
);
280 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
281 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
286 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderFileStream_GetLoader_Vtbl
= {
287 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface
,
288 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef
,
289 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release
,
290 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader
293 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderFileStream (LPVOID
* ppobj
) {
294 IDirectMusicLoaderFileStream
*obj
;
296 TRACE("(%p)\n", ppobj
);
297 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderFileStream
));
300 return E_OUTOFMEMORY
;
302 obj
->StreamVtbl
= &DirectMusicLoaderFileStream_Stream_Vtbl
;
303 obj
->GetLoaderVtbl
= &DirectMusicLoaderFileStream_GetLoader_Vtbl
;
304 obj
->dwRef
= 0; /* will be inited with QueryInterface */
306 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);
310 /*****************************************************************************
311 * IDirectMusicLoaderResourceStream implementation
314 HRESULT WINAPI
IDirectMusicLoaderResourceStream_Attach (LPSTREAM iface
, LPBYTE pbMemData
, LONGLONG llMemLength
, LONGLONG llPos
, LPDIRECTMUSICLOADER8 pLoader
) {
315 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
317 TRACE("(%p, %p, %s, %s, %p)\n", This
, pbMemData
, wine_dbgstr_longlong(llMemLength
), wine_dbgstr_longlong(llPos
), pLoader
);
318 if (!pbMemData
|| !llMemLength
) {
319 WARN(": invalid pbMemData or llMemLength\n");
322 IDirectMusicLoaderResourceStream_Detach (iface
);
323 This
->pbMemData
= pbMemData
;
324 This
->llMemLength
= llMemLength
;
326 This
->pLoader
= pLoader
;
331 void WINAPI
IDirectMusicLoaderResourceStream_Detach (LPSTREAM iface
) {
332 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
333 TRACE("(%p)\n", This
);
335 This
->pbMemData
= NULL
;
336 This
->llMemLength
= 0;
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
= (LPVOID
)&This
->StreamVtbl
;
348 IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
350 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
351 *ppobj
= (LPVOID
)&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
570 HRESULT WINAPI
IDirectMusicLoaderGenericStream_Attach (LPSTREAM iface
, LPSTREAM pStream
, LPDIRECTMUSICLOADER8 pLoader
) {
571 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
573 TRACE("(%p, %p, %p)\n", This
, pStream
, pLoader
);
575 WARN(": invalid pStream\n");
579 WARN(": invalid pLoader\n");
583 IDirectMusicLoaderGenericStream_Detach (iface
);
584 IStream_Clone (pStream
, &This
->pStream
);
585 This
->pLoader
= pLoader
;
590 void WINAPI
IDirectMusicLoaderGenericStream_Detach (LPSTREAM iface
) {
591 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
594 IStream_Release (This
->pStream
);
595 This
->pStream
= NULL
;
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
= (LPVOID
)&This
->StreamVtbl
;
607 IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
609 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
610 *ppobj
= (LPVOID
)&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
);