wine.inf: Add some dll stub dll to the system directory.
[wine/multimedia.git] / dlls / dmloader / loaderstream.c
blob957ec8be17ced9bc7d9d3366d624d1aa0c2dff87
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.
23 /* SIDE NOTES:
24 * After extensive testing and structure dumping I came to a conclusion that
25 * DirectMusic as in present state implements three types of streams:
26 * 1. IDirectMusicLoaderFileStream: stream that was most obvious, since
27 * it's used for loading from files; it is sort of wrapper around
28 * CreateFile, ReadFile, WriteFile and SetFilePointer and it supports
29 * both read and write
30 * 2. IDirectMusicLoaderResourceStream: a stream that had to exist, since
31 * according to MSDN, IDirectMusicLoader supports loading from resource
32 * as well; in this case, data is represented as a big chunk of bytes,
33 * from which we "read" (copy) data and keep the trace of our position;
34 * it supports read only
35 * 3. IDirectMusicLoaderGenericStream: this one was the most problematic,
36 * since I thought it was URL-related; besides, there's no obvious need
37 * for it, since input streams can simply be cloned, lest loading from
38 * stream is requested; but if one really thinks about it, input stream
39 * could be none of 1. or 2.; in this case, a wrapper that offers
40 * IDirectMusicGetLoader interface would be nice, and this is what this
41 * stream is; as such, all functions are supported, as long as underlying
42 * ("low-level") stream supports them
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
58 /* Custom : */
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) {
65 WARN(": failed\n");
66 return DMUS_E_LOADER_FAILEDOPEN;
68 /* create IDirectMusicGetLoader */
69 This->pLoader = pLoader;
70 lstrcpynW (This->wzFileName, wzFile, MAX_PATH);
71 TRACE(": succeeded\n");
72 return S_OK;
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);
94 return S_OK;
95 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
96 *ppobj = (LPVOID)&This->GetLoaderVtbl;
97 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
98 return S_OK;
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);
116 if (dwRef == 0) {
117 DMUSIC_DestroyDirectMusicLoaderFileStream (iface);
120 return dwRef;
123 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Read (LPSTREAM iface, void* pv, ULONG cb, ULONG* pcbRead) {
124 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
125 ULONG cbRead;
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));
133 return S_OK;
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;
150 return S_OK;
153 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Clone (LPSTREAM iface, IStream** ppstm) {
154 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
155 LPSTREAM pOther = NULL;
156 HRESULT result;
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;
166 liZero.QuadPart = 0;
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)) {
175 TRACE(": failed\n");
176 IDirectMusicLoaderFileStream_IStream_Release ((LPSTREAM)pOther);
177 return result;
180 TRACE(": succeeded\n");
181 *ppstm = (IStream*)pOther;
182 return S_OK;
185 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten) {
186 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
187 ULONG cbWrite;
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));
195 return S_OK;
198 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) {
199 ERR(": should not be needed\n");
200 return E_NOTIMPL;
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");
205 return E_NOTIMPL;
208 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) {
209 ERR(": should not be needed\n");
210 return E_NOTIMPL;
213 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Revert (LPSTREAM iface) {
214 ERR(": should not be needed\n");
215 return E_NOTIMPL;
218 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
219 ERR(": should not be needed\n");
220 return E_NOTIMPL;
223 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
224 ERR(": should not be needed\n");
225 return E_NOTIMPL;
228 HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag) {
229 ERR(": should not be needed\n");
230 return E_NOTIMPL;
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);
273 return S_OK;
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));
288 if (NULL == obj) {
289 *ppobj = NULL;
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);
303 if (This->hFile)
304 IDirectMusicLoaderFileStream_Detach (iface);
305 HeapFree (GetProcessHeap(), 0, This);
307 return S_OK;
311 /*****************************************************************************
312 * IDirectMusicLoaderResourceStream implementation
314 /* Custom : */
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");
321 return E_FAIL;
323 IDirectMusicLoaderResourceStream_Detach (iface);
324 This->pbMemData = pbMemData;
325 This->llMemLength = llMemLength;
326 This->llPos = llPos;
327 This->pLoader = pLoader;
329 return S_OK;
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);
350 return S_OK;
351 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
352 *ppobj = (LPVOID)&This->GetLoaderVtbl;
353 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
354 return S_OK;
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);
372 if (dwRef == 0) {
373 DMUSIC_DestroyDirectMusicLoaderResourceStream (iface);
376 return dwRef;
379 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Read (LPSTREAM iface, void* pv, ULONG cb, ULONG* pcbRead) {
380 LPBYTE pByte;
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");
386 return E_FAIL;
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));
396 return S_OK;
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);
403 switch (dwOrigin) {
404 case STREAM_SEEK_CUR: {
405 if ((This->llPos + dlibMove.QuadPart) > This->llMemLength) {
406 WARN_(dmfileraw)(": requested offset out of range\n");
407 return E_FAIL;
409 break;
411 case STREAM_SEEK_SET: {
412 if (dlibMove.QuadPart > This->llMemLength) {
413 WARN_(dmfileraw)(": requested offset out of range\n");
414 return E_FAIL;
416 /* set to the beginning of the stream */
417 This->llPos = 0;
418 break;
420 case STREAM_SEEK_END: {
421 /* TODO: check if this is true... I do think offset should be negative in this case */
422 if (dlibMove.QuadPart > 0) {
423 WARN_(dmfileraw)(": requested offset out of range\n");
424 return E_FAIL;
426 /* set to the end of the stream */
427 This->llPos = This->llMemLength;
428 break;
430 default: {
431 ERR_(dmfileraw)(": invalid dwOrigin\n");
432 return E_FAIL;
435 /* now simply add */
436 This->llPos += dlibMove.QuadPart;
438 if (plibNewPosition) plibNewPosition->QuadPart = This->llPos;
440 return S_OK;
443 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Clone (LPSTREAM iface, IStream** ppstm) {
444 ICOM_THIS_MULTI(IDirectMusicLoaderResourceStream, StreamVtbl, iface);
445 LPSTREAM pOther = NULL;
446 HRESULT result;
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;
456 return S_OK;
459 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten) {
460 ERR(": should not be needed\n");
461 return E_NOTIMPL;
464 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) {
465 ERR(": should not be needed\n");
466 return E_NOTIMPL;
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");
471 return E_NOTIMPL;
474 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) {
475 ERR(": should not be needed\n");
476 return E_NOTIMPL;
479 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Revert (LPSTREAM iface) {
480 ERR(": should not be needed\n");
481 return E_NOTIMPL;
484 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
485 ERR(": should not be needed\n");
486 return E_NOTIMPL;
489 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
490 ERR(": should not be needed\n");
491 return E_NOTIMPL;
494 HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag) {
495 ERR(": should not be needed\n");
496 return E_NOTIMPL;
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);
539 return S_OK;
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));
554 if (NULL == obj) {
555 *ppobj = NULL;
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);
572 return S_OK;
575 /*****************************************************************************
576 * IDirectMusicLoaderGenericStream implementation
578 /* Custom : */
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);
583 if (!pStream) {
584 WARN(": invalid pStream\n");
585 return E_FAIL;
587 if (!pLoader) {
588 WARN(": invalid pLoader\n");
589 return E_FAIL;
592 IDirectMusicLoaderGenericStream_Detach (iface);
593 IStream_Clone (pStream, &This->pStream);
594 This->pLoader = pLoader;
596 return S_OK;
599 void WINAPI IDirectMusicLoaderGenericStream_Detach (LPSTREAM iface) {
600 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
602 if (This->pStream)
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);
617 return S_OK;
618 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
619 *ppobj = (LPVOID)&This->GetLoaderVtbl;
620 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
621 return S_OK;
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);
639 if (dwRef == 0) {
640 DMUSIC_DestroyDirectMusicLoaderGenericStream (iface);
643 return dwRef;
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);
650 if (!This->pStream)
651 return E_FAIL;
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);
659 if (!This->pStream)
660 return E_FAIL;
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;
669 HRESULT result;
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)))
676 return E_FAIL;
678 IDirectMusicLoaderGenericStream_Attach (pOther, pLowLevel, This->pLoader);
680 TRACE(": succeeded\n");
681 *ppstm = (IStream*)pOther;
682 return S_OK;
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);
688 if (!This->pStream)
689 return E_FAIL;
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);
697 if (!This->pStream)
698 return E_FAIL;
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);
706 if (!This->pStream)
707 return E_FAIL;
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);
715 if (!This->pStream)
716 return E_FAIL;
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);
724 if (!This->pStream)
725 return E_FAIL;
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);
733 if (!This->pStream)
734 return E_FAIL;
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);
742 if (!This->pStream)
743 return E_FAIL;
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);
751 if (!This->pStream)
752 return E_FAIL;
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);
797 return S_OK;
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));
812 if (NULL == obj) {
813 *ppobj = NULL;
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);
830 return S_OK;