user32/tests: Fix the listbox tests on Win9x and NT4.
[wine/multimedia.git] / dlls / dmloader / loaderstream.c
blobfb01cea3d8317942b259c4b321da03151e41b085
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
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 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
66 /* Custom : */
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) {
73 WARN(": failed\n");
74 return DMUS_E_LOADER_FAILEDOPEN;
76 /* create IDirectMusicGetLoader */
77 This->pLoader = pLoader;
78 lstrcpynW (This->wzFileName, wzFile, MAX_PATH);
79 TRACE(": succeeded\n");
80 return S_OK;
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);
102 return S_OK;
103 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
104 *ppobj = (LPVOID)&This->GetLoaderVtbl;
105 IDirectMusicLoaderFileStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
106 return S_OK;
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);
124 if (dwRef == 0) {
125 if (This->hFile)
126 IDirectMusicLoaderFileStream_Detach (iface);
127 HeapFree (GetProcessHeap(), 0, This);
130 return dwRef;
133 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Read (LPSTREAM iface, void* pv, ULONG cb, ULONG* pcbRead) {
134 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
135 ULONG cbRead;
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));
143 return S_OK;
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;
160 return S_OK;
163 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Clone (LPSTREAM iface, IStream** ppstm) {
164 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
165 LPSTREAM pOther = NULL;
166 HRESULT result;
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;
176 liZero.QuadPart = 0;
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)) {
185 TRACE(": failed\n");
186 IDirectMusicLoaderFileStream_IStream_Release (pOther);
187 return result;
190 TRACE(": succeeded\n");
191 *ppstm = pOther;
192 return S_OK;
195 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten) {
196 ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
197 ULONG cbWrite;
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));
205 return S_OK;
208 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) {
209 ERR(": should not be needed\n");
210 return E_NOTIMPL;
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");
215 return E_NOTIMPL;
218 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) {
219 ERR(": should not be needed\n");
220 return E_NOTIMPL;
223 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Revert (LPSTREAM iface) {
224 ERR(": should not be needed\n");
225 return E_NOTIMPL;
228 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
229 ERR(": should not be needed\n");
230 return E_NOTIMPL;
233 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
234 ERR(": should not be needed\n");
235 return E_NOTIMPL;
238 static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag) {
239 ERR(": should not be needed\n");
240 return E_NOTIMPL;
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);
283 return S_OK;
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));
298 if (NULL == obj) {
299 *ppobj = NULL;
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
313 /* Custom : */
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");
320 return E_FAIL;
322 IDirectMusicLoaderResourceStream_Detach (iface);
323 This->pbMemData = pbMemData;
324 This->llMemLength = llMemLength;
325 This->llPos = llPos;
326 This->pLoader = pLoader;
328 return S_OK;
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);
349 return S_OK;
350 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
351 *ppobj = (LPVOID)&This->GetLoaderVtbl;
352 IDirectMusicLoaderResourceStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
353 return S_OK;
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);
371 if (dwRef == 0) {
372 IDirectMusicLoaderResourceStream_Detach (iface);
373 HeapFree (GetProcessHeap(), 0, This);
376 return dwRef;
379 static 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%08X, %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%08X): %s\n", cb, debugstr_an(pv, cb));
396 return S_OK;
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);
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 static 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 = pOther;
456 return S_OK;
459 static 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 static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) {
465 ERR(": should not be needed\n");
466 return E_NOTIMPL;
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");
471 return E_NOTIMPL;
474 static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) {
475 ERR(": should not be needed\n");
476 return E_NOTIMPL;
479 static HRESULT WINAPI IDirectMusicLoaderResourceStream_IStream_Revert (LPSTREAM iface) {
480 ERR(": should not be needed\n");
481 return E_NOTIMPL;
484 static 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 static 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 static 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 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);
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);
566 /*****************************************************************************
567 * IDirectMusicLoaderGenericStream implementation
569 /* Custom : */
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);
574 if (!pStream) {
575 WARN(": invalid pStream\n");
576 return E_FAIL;
578 if (!pLoader) {
579 WARN(": invalid pLoader\n");
580 return E_FAIL;
583 IDirectMusicLoaderGenericStream_Detach (iface);
584 IStream_Clone (pStream, &This->pStream);
585 This->pLoader = pLoader;
587 return S_OK;
590 void WINAPI IDirectMusicLoaderGenericStream_Detach (LPSTREAM iface) {
591 ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
593 if (This->pStream)
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);
608 return S_OK;
609 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
610 *ppobj = (LPVOID)&This->GetLoaderVtbl;
611 IDirectMusicLoaderGenericStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER)&This->GetLoaderVtbl);
612 return S_OK;
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);
630 if (dwRef == 0) {
631 IDirectMusicLoaderGenericStream_Detach (iface);
632 HeapFree (GetProcessHeap(), 0, This);
635 return dwRef;
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);
642 if (!This->pStream)
643 return E_FAIL;
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);
651 if (!This->pStream)
652 return E_FAIL;
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;
661 HRESULT result;
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)))
668 return E_FAIL;
670 IDirectMusicLoaderGenericStream_Attach (pOther, pLowLevel, This->pLoader);
672 TRACE(": succeeded\n");
673 *ppstm = pOther;
674 return S_OK;
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);
680 if (!This->pStream)
681 return E_FAIL;
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));
689 if (!This->pStream)
690 return E_FAIL;
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);
698 if (!This->pStream)
699 return E_FAIL;
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);
707 if (!This->pStream)
708 return E_FAIL;
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);
716 if (!This->pStream)
717 return E_FAIL;
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);
725 if (!This->pStream)
726 return E_FAIL;
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);
734 if (!This->pStream)
735 return E_FAIL;
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);
743 if (!This->pStream)
744 return E_FAIL;
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);
789 return S_OK;
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));
804 if (NULL == obj) {
805 *ppobj = NULL;
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);