1 /* ILoaderStream Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
23 #include "dmloader_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(dmloader
);
26 WINE_DECLARE_DEBUG_CHANNEL(dmfileraw
);
28 /*****************************************************************************
31 HRESULT WINAPI
ILoaderStream_Attach (LPSTREAM iface
, LPCWSTR wzFile
, IDirectMusicLoader
*pLoader
) {
32 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
33 TRACE("(%p, %s, %p)\n", This
, debugstr_w(wzFile
), pLoader
);
34 ILoaderStream_Detach (iface
);
35 This
->hFile
= CreateFileW (wzFile
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
36 if (This
->hFile
== INVALID_HANDLE_VALUE
) {
38 return DMUS_E_LOADER_FAILEDOPEN
;
40 /* create IDirectMusicGetLoader */
41 (LPDIRECTMUSICLOADER
) This
->pLoader
= pLoader
;
42 strncpyW (This
->wzFileName
, wzFile
, MAX_PATH
);
43 TRACE(": succeeded\n");
47 void WINAPI
ILoaderStream_Detach (LPSTREAM iface
) {
48 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
49 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
50 CloseHandle(This
->hFile
);
52 This
->wzFileName
[0] = (L
'\0');
55 /*****************************************************************************
56 * ILoaderStream implementation
58 /* ILoaderStream IUnknown part: */
59 HRESULT WINAPI
ILoaderStream_IUnknown_QueryInterface (LPUNKNOWN iface
, REFIID riid
, void** ppobj
) {
60 ICOM_THIS_MULTI(ILoaderStream
, UnknownVtbl
, iface
);
62 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
63 if (IsEqualIID (riid
, &IID_IUnknown
)) {
64 *ppobj
= (LPVOID
)&This
->UnknownVtbl
;
65 ILoaderStream_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
67 } else if (IsEqualIID (riid
, &IID_IStream
)) {
68 *ppobj
= (LPVOID
)&This
->StreamVtbl
;
69 ILoaderStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
71 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
72 *ppobj
= (LPVOID
)&This
->GetLoaderVtbl
;
73 ILoaderStream_IDirectMusicGetLoader_AddRef ((LPDIRECTMUSICGETLOADER
)&This
->GetLoaderVtbl
);
77 WARN("(%p, %s,%p): not found\n", This
, debugstr_dmguid(riid
), ppobj
);
81 ULONG WINAPI
ILoaderStream_IUnknown_AddRef (LPUNKNOWN iface
) {
82 ICOM_THIS_MULTI(ILoaderStream
, UnknownVtbl
, iface
);
83 TRACE("(%p): AddRef from %ld\n", This
, This
->ref
);
87 ULONG WINAPI
ILoaderStream_IUnknown_Release (LPUNKNOWN iface
) {
88 ICOM_THIS_MULTI(ILoaderStream
, UnknownVtbl
, iface
);
89 ULONG ref
= --This
->ref
;
90 TRACE("(%p): ReleaseRef to %ld\n", This
, This
->ref
);
92 HeapFree(GetProcessHeap(), 0, This
);
97 ICOM_VTABLE(IUnknown
) LoaderStream_Unknown_Vtbl
= {
98 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
99 ILoaderStream_IUnknown_QueryInterface
,
100 ILoaderStream_IUnknown_AddRef
,
101 ILoaderStream_IUnknown_Release
104 /* ILoaderStream IStream part: */
105 HRESULT WINAPI
ILoaderStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
) {
106 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
107 return ILoaderStream_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
110 ULONG WINAPI
ILoaderStream_IStream_AddRef (LPSTREAM iface
) {
111 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
112 return ILoaderStream_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
115 ULONG WINAPI
ILoaderStream_IStream_Release (LPSTREAM iface
) {
116 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
117 return ILoaderStream_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
120 HRESULT WINAPI
ILoaderStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
) {
121 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
123 TRACE_(dmfileraw
)("(%p, %p, 0x%04lx, %p)\n", This
, pv
, cb
, pcbRead
);
124 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
125 if (pcbRead
== NULL
) pcbRead
= &cbRead
;
126 if (!ReadFile (This
->hFile
, pv
, cb
, pcbRead
, NULL
) || *pcbRead
!= cb
) return E_FAIL
;
127 TRACE_(dmfileraw
)(": data (size = 0x%04lx): '%s'\n", *pcbRead
, debugstr_an(pv
, *pcbRead
));
131 HRESULT WINAPI
ILoaderStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
) {
132 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
133 LARGE_INTEGER liNewPos
;
135 TRACE_(dmfileraw
)("(%p, 0x%04llx, %s, %p)\n", This
, dlibMove
.QuadPart
, resolve_STREAM_SEEK(dwOrigin
), plibNewPosition
);
137 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
139 liNewPos
.u
.HighPart
= dlibMove
.u
.HighPart
;
140 liNewPos
.u
.LowPart
= SetFilePointer (This
->hFile
, dlibMove
.u
.LowPart
, &liNewPos
.u
.HighPart
, dwOrigin
);
142 if (liNewPos
.u
.LowPart
== INVALID_SET_FILE_POINTER
&& GetLastError() != NO_ERROR
) return E_FAIL
;
143 if (plibNewPosition
) plibNewPosition
->QuadPart
= liNewPos
.QuadPart
;
148 HRESULT WINAPI
ILoaderStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
) {
149 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
150 LPSTREAM pOther
= NULL
;
153 TRACE("(%p, %p)\n", iface
, ppstm
);
154 result
= DMUSIC_CreateLoaderStream ((LPVOID
*)&pOther
);
155 if (FAILED(result
)) return result
;
156 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
157 ULARGE_INTEGER ullCurrentPosition
;
158 result
= ILoaderStream_Attach (pOther
, This
->wzFileName
, (LPDIRECTMUSICLOADER
)This
->pLoader
);
159 if (SUCCEEDED(result
)) {
160 LARGE_INTEGER liZero
;
162 result
= ILoaderStream_IStream_Seek (iface
, liZero
, STREAM_SEEK_CUR
, &ullCurrentPosition
); /* get current position in current stream */
164 if (SUCCEEDED(result
)) {
165 LARGE_INTEGER liNewPosition
;
166 liNewPosition
.QuadPart
= ullCurrentPosition
.QuadPart
;
167 result
= ILoaderStream_IStream_Seek ((LPSTREAM
)pOther
, liNewPosition
, STREAM_SEEK_SET
, &ullCurrentPosition
);
169 if (FAILED(result
)) {
171 ILoaderStream_IStream_Release ((LPSTREAM
)pOther
);
175 TRACE(": succeeded\n");
176 *ppstm
= (IStream
*)pOther
;
180 HRESULT WINAPI
ILoaderStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
) {
181 ERR(": should not be needed\n");
185 HRESULT WINAPI
ILoaderStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
) {
186 ERR(": should not be needed\n");
190 HRESULT WINAPI
ILoaderStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {
191 ERR(": should not be needed\n");
195 HRESULT WINAPI
ILoaderStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
) {
196 ERR(": should not be needed\n");
200 HRESULT WINAPI
ILoaderStream_IStream_Revert (LPSTREAM iface
) {
201 ERR(": should not be needed\n");
205 HRESULT WINAPI
ILoaderStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
206 ERR(": should not be needed\n");
210 HRESULT WINAPI
ILoaderStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {
211 ERR(": should not be needed\n");
215 HRESULT WINAPI
ILoaderStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
) {
216 ERR(": should not be needed\n");
220 ICOM_VTABLE(IStream
) LoaderStream_Stream_Vtbl
= {
221 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
222 ILoaderStream_IStream_QueryInterface
,
223 ILoaderStream_IStream_AddRef
,
224 ILoaderStream_IStream_Release
,
225 ILoaderStream_IStream_Read
,
226 ILoaderStream_IStream_Write
,
227 ILoaderStream_IStream_Seek
,
228 ILoaderStream_IStream_SetSize
,
229 ILoaderStream_IStream_CopyTo
,
230 ILoaderStream_IStream_Commit
,
231 ILoaderStream_IStream_Revert
,
232 ILoaderStream_IStream_LockRegion
,
233 ILoaderStream_IStream_UnlockRegion
,
234 ILoaderStream_IStream_Stat
,
235 ILoaderStream_IStream_Clone
238 /*****************************************************************************
239 * ILoaderStream IDirectMusicGetLoader part:
241 HRESULT WINAPI
ILoaderStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
) {
242 ICOM_THIS_MULTI(ILoaderStream
, GetLoaderVtbl
, iface
);
243 return ILoaderStream_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
246 ULONG WINAPI
ILoaderStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
) {
247 ICOM_THIS_MULTI(ILoaderStream
, GetLoaderVtbl
, iface
);
248 return ILoaderStream_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
251 ULONG WINAPI
ILoaderStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
) {
252 ICOM_THIS_MULTI(ILoaderStream
, GetLoaderVtbl
, iface
);
253 return ILoaderStream_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
256 HRESULT WINAPI
ILoaderStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
) {
257 ICOM_THIS_MULTI(ILoaderStream
, GetLoaderVtbl
, iface
);
259 TRACE("(%p, %p)\n", This
, ppLoader
);
260 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
261 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
266 ICOM_VTABLE(IDirectMusicGetLoader
) LoaderStream_GetLoader_Vtbl
= {
267 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
268 ILoaderStream_IDirectMusicGetLoader_QueryInterface
,
269 ILoaderStream_IDirectMusicGetLoader_AddRef
,
270 ILoaderStream_IDirectMusicGetLoader_Release
,
271 ILoaderStream_IDirectMusicGetLoader_GetLoader
274 HRESULT WINAPI
DMUSIC_CreateLoaderStream (LPVOID
* ppobj
) {
275 ILoaderStream
*pStream
;
277 TRACE("(%p)\n", ppobj
);
278 pStream
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(ILoaderStream
));
279 if (NULL
== pStream
) {
280 *ppobj
= (LPVOID
) NULL
;
281 return E_OUTOFMEMORY
;
283 pStream
->UnknownVtbl
= &LoaderStream_Unknown_Vtbl
;
284 pStream
->StreamVtbl
= &LoaderStream_Stream_Vtbl
;
285 pStream
->GetLoaderVtbl
= &LoaderStream_GetLoader_Vtbl
;
286 pStream
->ref
= 0; /* will be inited with QueryInterface */
288 return ILoaderStream_IUnknown_QueryInterface ((LPUNKNOWN
)&pStream
->UnknownVtbl
, &IID_IStream
, ppobj
);