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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (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
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 /*****************************************************************************
56 * IDirectMusicLoaderFileStream implementation
59 HRESULT WINAPI
IDirectMusicLoaderFileStream_Attach (LPSTREAM iface
, LPCWSTR wzFile
, LPDIRECTMUSICLOADER8 pLoader
) {
60 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
61 TRACE("(%p, %s, %p)\n", This
, debugstr_w(wzFile
), pLoader
);
62 IDirectMusicLoaderFileStream_Detach (iface
);
63 This
->hFile
= CreateFileW (wzFile
, (GENERIC_READ
| GENERIC_WRITE
), (FILE_SHARE_READ
| FILE_SHARE_WRITE
), NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
64 if (This
->hFile
== INVALID_HANDLE_VALUE
) {
66 return DMUS_E_LOADER_FAILEDOPEN
;
68 /* create IDirectMusicGetLoader */
69 This
->pLoader
= pLoader
;
70 lstrcpynW (This
->wzFileName
, wzFile
, MAX_PATH
);
71 TRACE(": succeeded\n");
75 void WINAPI
IDirectMusicLoaderFileStream_Detach (LPSTREAM iface
) {
76 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
77 TRACE("(%p)\n", This
);
78 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
79 CloseHandle(This
->hFile
);
81 This
->wzFileName
[0] = (L
'\0');
85 /* IUnknown/IStream part: */
86 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
87 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
89 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
90 if (IsEqualIID (riid
, &IID_IUnknown
) ||
91 IsEqualIID (riid
, &IID_IStream
)) {
92 *ppobj
= (LPVOID
)&This
->StreamVtbl
;
93 IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
95 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
96 *ppobj
= (LPVOID
)&This
->GetLoaderVtbl
;
97 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
101 WARN(": not found\n");
102 return E_NOINTERFACE
;
105 ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface
) {
106 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
107 TRACE("(%p): AddRef from %ld\n", This
, This
->dwRef
);
108 return InterlockedIncrement (&This
->dwRef
);
111 ULONG WINAPI
IDirectMusicLoaderFileStream_IStream_Release (LPSTREAM iface
) {
112 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
114 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
115 TRACE("(%p): ReleaseRef to %ld\n", This
, dwRef
);
117 DMUSIC_DestroyDirectMusicLoaderFileStream (iface
);
123 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
124 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
127 TRACE_(dmfileraw
)("(%p, %p, 0x%08lX, %p)\n", This
, pv
, cb
, pcbRead
);
128 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
129 if (pcbRead
== NULL
) pcbRead
= &cbRead
;
130 if (!ReadFile (This
->hFile
, pv
, cb
, pcbRead
, NULL
) || *pcbRead
!= cb
) return E_FAIL
;
132 TRACE_(dmfileraw
)(": data (size = 0x%08lX): '%s'\n", *pcbRead
, debugstr_an(pv
, *pcbRead
));
136 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
137 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
138 LARGE_INTEGER liNewPos
;
140 TRACE_(dmfileraw
)("(%p, 0x%08llX, %s, %p)\n", This
, dlibMove
.QuadPart
, resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
142 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
144 liNewPos
.u
.HighPart
= dlibMove
.u
.HighPart
;
145 liNewPos
.u
.LowPart
= SetFilePointer (This
->hFile
, dlibMove
.u
.LowPart
, &liNewPos
.u
.HighPart
, dwOrigin
);
147 if (liNewPos
.u
.LowPart
== INVALID_SET_FILE_POINTER
&& GetLastError() != NO_ERROR
) return E_FAIL
;
148 if (plibNewPosition
) plibNewPosition
->QuadPart
= liNewPos
.QuadPart
;
153 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
154 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
155 LPSTREAM pOther
= NULL
;
158 TRACE("(%p, %p)\n", iface
, ppstm
);
159 result
= DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID
*)&pOther
);
160 if (FAILED(result
)) return result
;
161 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
162 ULARGE_INTEGER ullCurrentPosition
;
163 result
= IDirectMusicLoaderFileStream_Attach (pOther
, This
->wzFileName
, This
->pLoader
);
164 if (SUCCEEDED(result
)) {
165 LARGE_INTEGER liZero
;
167 result
= IDirectMusicLoaderFileStream_IStream_Seek (iface
, liZero
, STREAM_SEEK_CUR
, &ullCurrentPosition
); /* get current position in current stream */
169 if (SUCCEEDED(result
)) {
170 LARGE_INTEGER liNewPosition
;
171 liNewPosition
.QuadPart
= ullCurrentPosition
.QuadPart
;
172 result
= IDirectMusicLoaderFileStream_IStream_Seek ((LPSTREAM
)pOther
, liNewPosition
, STREAM_SEEK_SET
, &ullCurrentPosition
);
174 if (FAILED(result
)) {
176 IDirectMusicLoaderFileStream_IStream_Release ((LPSTREAM
)pOther
);
180 TRACE(": succeeded\n");
181 *ppstm
= (IStream
*)pOther
;
185 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
186 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
189 TRACE_(dmfileraw
)("(%p, %p, 0x%08lX, %p)\n", This
, pv
, cb
, pcbWritten
);
190 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
191 if (pcbWritten
== NULL
) pcbWritten
= &cbWrite
;
192 if (!WriteFile (This
->hFile
, pv
, cb
, pcbWritten
, NULL
) || *pcbWritten
!= cb
) return E_FAIL
;
194 TRACE_(dmfileraw
)(": data (size = 0x%08lX): '%s'\n", *pcbWritten
, debugstr_an(pv
, *pcbWritten
));
198 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
199 ERR(": should not be needed\n");
203 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
204 ERR(": should not be needed\n");
208 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
209 ERR(": should not be needed\n");
213 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Revert (LPSTREAM iface
) {
214 ERR(": should not be needed\n");
218 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
219 ERR(": should not be needed\n");
223 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
224 ERR(": should not be needed\n");
228 HRESULT WINAPI
IDirectMusicLoaderFileStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
229 ERR(": should not be needed\n");
233 static const IStreamVtbl DirectMusicLoaderFileStream_Stream_Vtbl
= {
234 IDirectMusicLoaderFileStream_IStream_QueryInterface
,
235 IDirectMusicLoaderFileStream_IStream_AddRef
,
236 IDirectMusicLoaderFileStream_IStream_Release
,
237 IDirectMusicLoaderFileStream_IStream_Read
,
238 IDirectMusicLoaderFileStream_IStream_Write
,
239 IDirectMusicLoaderFileStream_IStream_Seek
,
240 IDirectMusicLoaderFileStream_IStream_SetSize
,
241 IDirectMusicLoaderFileStream_IStream_CopyTo
,
242 IDirectMusicLoaderFileStream_IStream_Commit
,
243 IDirectMusicLoaderFileStream_IStream_Revert
,
244 IDirectMusicLoaderFileStream_IStream_LockRegion
,
245 IDirectMusicLoaderFileStream_IStream_UnlockRegion
,
246 IDirectMusicLoaderFileStream_IStream_Stat
,
247 IDirectMusicLoaderFileStream_IStream_Clone
250 /* IDirectMusicGetLoader part: */
251 HRESULT WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
252 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
253 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
256 ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
257 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
258 return IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
261 ULONG WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
262 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
263 return IDirectMusicLoaderFileStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
266 HRESULT WINAPI
IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
267 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, GetLoaderVtbl
, iface
);
269 TRACE("(%p, %p)\n", This
, ppLoader
);
270 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
271 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
276 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderFileStream_GetLoader_Vtbl
= {
277 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_QueryInterface
,
278 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef
,
279 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_Release
,
280 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_GetLoader
283 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderFileStream (LPVOID
* ppobj
) {
284 IDirectMusicLoaderFileStream
*obj
;
286 TRACE("(%p)\n", ppobj
);
287 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderFileStream
));
290 return E_OUTOFMEMORY
;
292 obj
->StreamVtbl
= &DirectMusicLoaderFileStream_Stream_Vtbl
;
293 obj
->GetLoaderVtbl
= &DirectMusicLoaderFileStream_GetLoader_Vtbl
;
294 obj
->dwRef
= 0; /* will be inited with QueryInterface */
296 return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);
299 HRESULT WINAPI
DMUSIC_DestroyDirectMusicLoaderFileStream (LPSTREAM iface
) {
300 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream
, StreamVtbl
, iface
);
302 TRACE("(%p)\n", iface
);
304 IDirectMusicLoaderFileStream_Detach (iface
);
305 HeapFree (GetProcessHeap(), 0, This
);
311 /*****************************************************************************
312 * IDirectMusicLoaderResourceStream implementation
315 HRESULT WINAPI
IDirectMusicLoaderResourceStream_Attach (LPSTREAM iface
, LPBYTE pbMemData
, LONGLONG llMemLength
, LONGLONG llPos
, LPDIRECTMUSICLOADER8 pLoader
) {
316 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
318 TRACE("(%p, %p, 0x%08llX, 0x%08llx, %p)\n", This
, pbMemData
, llMemLength
, llPos
, pLoader
);
319 if (!pbMemData
|| !llMemLength
) {
320 WARN(": invalid pbMemData or llMemLength\n");
323 IDirectMusicLoaderResourceStream_Detach (iface
);
324 This
->pbMemData
= pbMemData
;
325 This
->llMemLength
= llMemLength
;
327 This
->pLoader
= pLoader
;
332 void WINAPI
IDirectMusicLoaderResourceStream_Detach (LPSTREAM iface
) {
333 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
334 TRACE("(%p)\n", This
);
336 This
->pbMemData
= NULL
;
337 This
->llMemLength
= 0;
341 /* IUnknown/IStream part: */
342 HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
343 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
345 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
346 if (IsEqualIID (riid
, &IID_IUnknown
) ||
347 IsEqualIID (riid
, &IID_IStream
)) {
348 *ppobj
= (LPVOID
)&This
->StreamVtbl
;
349 IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
351 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
352 *ppobj
= (LPVOID
)&This
->GetLoaderVtbl
;
353 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
357 WARN(": not found\n");
358 return E_NOINTERFACE
;
361 ULONG WINAPI
IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface
) {
362 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
363 TRACE("(%p): AddRef from %ld\n", This
, This
->dwRef
);
364 return InterlockedIncrement (&This
->dwRef
);
367 ULONG WINAPI
IDirectMusicLoaderResourceStream_IStream_Release (LPSTREAM iface
) {
368 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
370 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
371 TRACE("(%p): ReleaseRef to %ld\n", This
, dwRef
);
373 DMUSIC_DestroyDirectMusicLoaderResourceStream (iface
);
379 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%08lX, %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%08lX): '%s'\n", cb
, debugstr_an(pv
, cb
));
399 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, 0x%08llX, %s, %p)\n", This
, 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 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");
455 *ppstm
= (IStream
*)pOther
;
459 HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
460 ERR(": should not be needed\n");
464 HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
465 ERR(": should not be needed\n");
469 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 HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
475 ERR(": should not be needed\n");
479 HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_Revert (LPSTREAM iface
) {
480 ERR(": should not be needed\n");
484 HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
485 ERR(": should not be needed\n");
489 HRESULT WINAPI
IDirectMusicLoaderResourceStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
490 ERR(": should not be needed\n");
494 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 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 ULONG WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
523 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
524 return IDirectMusicLoaderResourceStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
527 ULONG WINAPI
IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
528 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, GetLoaderVtbl
, iface
);
529 return IDirectMusicLoaderResourceStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
532 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
);
565 HRESULT WINAPI
DMUSIC_DestroyDirectMusicLoaderResourceStream (LPSTREAM iface
) {
566 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream
, StreamVtbl
, iface
);
568 TRACE("(%p)\n", iface
);
569 IDirectMusicLoaderResourceStream_Detach (iface
);
570 HeapFree (GetProcessHeap(), 0, This
);
575 /*****************************************************************************
576 * IDirectMusicLoaderGenericStream implementation
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
;
599 void WINAPI
IDirectMusicLoaderGenericStream_Detach (LPSTREAM iface
) {
600 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
603 IStream_Release (This
->pStream
);
604 This
->pStream
= NULL
;
608 /* IUnknown/IStream part: */
609 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
610 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
612 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
613 if (IsEqualIID (riid
, &IID_IUnknown
) ||
614 IsEqualIID (riid
, &IID_IStream
)) {
615 *ppobj
= (LPVOID
)&This
->StreamVtbl
;
616 IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
618 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
619 *ppobj
= (LPVOID
)&This
->GetLoaderVtbl
;
620 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
624 WARN(": not found\n");
625 return E_NOINTERFACE
;
628 ULONG WINAPI
IDirectMusicLoaderGenericStream_IStream_AddRef (LPSTREAM iface
) {
629 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
630 TRACE("(%p): AddRef from %ld\n", This
, This
->dwRef
);
631 return InterlockedIncrement (&This
->dwRef
);
634 ULONG WINAPI
IDirectMusicLoaderGenericStream_IStream_Release (LPSTREAM iface
) {
635 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
637 DWORD dwRef
= InterlockedDecrement (&This
->dwRef
);
638 TRACE("(%p): ReleaseRef to %ld\n", This
, dwRef
);
640 DMUSIC_DestroyDirectMusicLoaderGenericStream (iface
);
646 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
647 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
649 TRACE_(dmfileraw
)("(%p, %p, 0x%08lX, %p): redirecting to low-level stream\n", This
, pv
, cb
, pcbRead
);
653 return IStream_Read (This
->pStream
, pv
, cb
, pcbRead
);
656 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
657 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
658 TRACE_(dmfileraw
)("(%p, 0x%08llX, %s, %p): redirecting to low-level stream\n", This
, dlibMove
.QuadPart
, resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
662 return IStream_Seek (This
->pStream
, dlibMove
, dwOrigin
, plibNewPosition
);
665 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
666 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
667 LPSTREAM pOther
= NULL
;
668 LPSTREAM pLowLevel
= NULL
;
671 TRACE("(%p, %p)\n", iface
, ppstm
);
672 result
= DMUSIC_CreateDirectMusicLoaderGenericStream ((LPVOID
*)&pOther
);
673 if (FAILED(result
)) return result
;
675 if (FAILED(IStream_Clone (This
->pStream
, &pLowLevel
)))
678 IDirectMusicLoaderGenericStream_Attach (pOther
, pLowLevel
, This
->pLoader
);
680 TRACE(": succeeded\n");
681 *ppstm
= (IStream
*)pOther
;
685 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
686 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
687 TRACE_(dmfileraw
)("(%p, %p, 0x%08lX, %p): redirecting to low-level stream\n", This
, pv
, cb
, pcbWritten
);
691 return IStream_Write (This
->pStream
, pv
, cb
, pcbWritten
);
694 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
695 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
696 TRACE("(%p, 0x%08llX): redirecting to low-level stream\n", This
, libNewSize
.QuadPart
);
700 return IStream_SetSize (This
->pStream
, libNewSize
);
703 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
704 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
705 TRACE("(%p, %p, 0x%08llX, %p, %p): redirecting to low-level stream\n", This
, pstm
, cb
.QuadPart
, pcbRead
, pcbWritten
);
709 return IStream_CopyTo (This
->pStream
, pstm
, cb
, pcbRead
, pcbWritten
);
712 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
713 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
714 TRACE("(%p, 0x%08lX): redirecting to low-level stream\n", This
, grfCommitFlags
);
718 return IStream_Commit (This
->pStream
, grfCommitFlags
);
721 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Revert (LPSTREAM iface
) {
722 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
723 TRACE("(%p): redirecting to low-level stream\n", This
);
727 return IStream_Revert (This
->pStream
);
730 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
731 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
732 TRACE("(%p, 0x%08llX, 0x%08llX, 0x%08lX): redirecting to low-level stream\n", This
, libOffset
.QuadPart
, cb
.QuadPart
, dwLockType
);
736 return IStream_LockRegion (This
->pStream
, libOffset
, cb
, dwLockType
);
739 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
740 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
741 TRACE("(%p, 0x%08llX, 0x%08llX, 0x%08lX): redirecting to low-level stream\n", This
, libOffset
.QuadPart
, cb
.QuadPart
, dwLockType
);
745 return IStream_UnlockRegion (This
->pStream
, libOffset
, cb
, dwLockType
);
748 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
749 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
750 TRACE("(%p, %p, 0x%08lX): redirecting to low-level stream\n", This
, pstatstg
, grfStatFlag
);
754 return IStream_Stat (This
->pStream
, pstatstg
, grfStatFlag
);
757 static const IStreamVtbl DirectMusicLoaderGenericStream_Stream_Vtbl
= {
758 IDirectMusicLoaderGenericStream_IStream_QueryInterface
,
759 IDirectMusicLoaderGenericStream_IStream_AddRef
,
760 IDirectMusicLoaderGenericStream_IStream_Release
,
761 IDirectMusicLoaderGenericStream_IStream_Read
,
762 IDirectMusicLoaderGenericStream_IStream_Write
,
763 IDirectMusicLoaderGenericStream_IStream_Seek
,
764 IDirectMusicLoaderGenericStream_IStream_SetSize
,
765 IDirectMusicLoaderGenericStream_IStream_CopyTo
,
766 IDirectMusicLoaderGenericStream_IStream_Commit
,
767 IDirectMusicLoaderGenericStream_IStream_Revert
,
768 IDirectMusicLoaderGenericStream_IStream_LockRegion
,
769 IDirectMusicLoaderGenericStream_IStream_UnlockRegion
,
770 IDirectMusicLoaderGenericStream_IStream_Stat
,
771 IDirectMusicLoaderGenericStream_IStream_Clone
774 /* IDirectMusicGetLoader part: */
775 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
776 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
777 return IDirectMusicLoaderGenericStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
780 ULONG WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
781 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
782 return IDirectMusicLoaderGenericStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
785 ULONG WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
786 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
787 return IDirectMusicLoaderGenericStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
790 HRESULT WINAPI
IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
791 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, GetLoaderVtbl
, iface
);
793 TRACE("(%p, %p)\n", This
, ppLoader
);
794 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
795 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
800 static const IDirectMusicGetLoaderVtbl DirectMusicLoaderGenericStream_GetLoader_Vtbl
= {
801 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_QueryInterface
,
802 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef
,
803 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_Release
,
804 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_GetLoader
807 HRESULT WINAPI
DMUSIC_CreateDirectMusicLoaderGenericStream (LPVOID
* ppobj
) {
808 IDirectMusicLoaderGenericStream
*obj
;
810 TRACE("(%p)\n", ppobj
);
811 obj
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicLoaderGenericStream
));
814 return E_OUTOFMEMORY
;
816 obj
->StreamVtbl
= &DirectMusicLoaderGenericStream_Stream_Vtbl
;
817 obj
->GetLoaderVtbl
= &DirectMusicLoaderGenericStream_GetLoader_Vtbl
;
818 obj
->dwRef
= 0; /* will be inited with QueryInterface */
820 return IDirectMusicLoaderGenericStream_IStream_QueryInterface ((LPSTREAM
)&obj
->StreamVtbl
, &IID_IStream
, ppobj
);
823 HRESULT WINAPI
DMUSIC_DestroyDirectMusicLoaderGenericStream (LPSTREAM iface
) {
824 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream
, StreamVtbl
, iface
);
826 TRACE("(%p)\n", iface
);
827 IDirectMusicLoaderGenericStream_Detach (iface
);
828 HeapFree (GetProcessHeap(), 0, This
);