1 /* ILoaderStream Implementation
3 * Copyright (C) 2003 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
28 #include "wine/debug.h"
29 #include "wine/unicode.h"
31 #include "dmloader_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(dmloader
);
35 /*****************************************************************************
38 HRESULT WINAPI
ILoaderStream_Attach (ILoaderStream
* This
, LPCWSTR wzFile
, IDirectMusicLoader
*pLoader
)
40 TRACE("(%p, %s, %p)\n", This
, debugstr_w(wzFile
), pLoader
);
41 ILoaderStream_Detach (This
);
42 This
->hFile
= CreateFileW (wzFile
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
43 if (This
->hFile
== INVALID_HANDLE_VALUE
) {
47 /* create IDirectMusicGetLoader */
48 (LPDIRECTMUSICLOADER
) This
->pLoader
= pLoader
;
49 strncpyW (This
->wzFileName
, wzFile
, MAX_PATH
);
50 TRACE(": succeeded\n");
54 void WINAPI
ILoaderStream_Detach (ILoaderStream
* This
)
56 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
57 CloseHandle(This
->hFile
);
59 This
->wzFileName
[0] = (L
'\0');
62 /*****************************************************************************
63 * ILoaderStream IStream:
65 HRESULT WINAPI
ILoaderStream_IStream_QueryInterface (LPSTREAM iface
, REFIID riid
, void** ppobj
)
67 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
69 if (IsEqualIID (riid
, &IID_IUnknown
)
70 || IsEqualIID (riid
, &IID_IStream
)) {
71 *ppobj
= (LPVOID
)&This
->StreamVtbl
;
72 ILoaderStream_IStream_AddRef (iface
);
74 } else if (IsEqualIID (riid
, &IID_IDirectMusicGetLoader
)) {
75 *ppobj
= (LPVOID
)&This
->GetLoaderVtbl
;
76 ILoaderStream_IStream_AddRef (iface
);
80 WARN("(%p)->(%s,%p),not found\n", This
, debugstr_guid(riid
), ppobj
);
84 ULONG WINAPI
ILoaderStream_IStream_AddRef (LPSTREAM iface
)
86 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
87 TRACE("(%p) : AddRef from %ld\n", This
, This
->ref
);
91 ULONG WINAPI
ILoaderStream_IStream_Release (LPSTREAM iface
)
93 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
94 ULONG ref
= --This
->ref
;
95 TRACE("(%p) : ReleaseRef to %ld\n", This
, This
->ref
);
97 HeapFree(GetProcessHeap(), 0, This
);
102 HRESULT WINAPI
ILoaderStream_IStream_Read (LPSTREAM iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
)
104 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
107 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
108 if (pcbRead
== NULL
) pcbRead
= &cbRead
;
109 if (!ReadFile (This
->hFile
, pv
, cb
, pcbRead
, NULL
) || *pcbRead
!= cb
) return E_FAIL
;
114 HRESULT WINAPI
ILoaderStream_IStream_Seek (LPSTREAM iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
)
116 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
117 LARGE_INTEGER liNewPos
;
119 if (This
->hFile
== INVALID_HANDLE_VALUE
) return E_FAIL
;
121 liNewPos
.s
.HighPart
= dlibMove
.s
.HighPart
;
122 liNewPos
.s
.LowPart
= SetFilePointer (This
->hFile
, dlibMove
.s
.LowPart
, &liNewPos
.s
.HighPart
, dwOrigin
);
124 if (liNewPos
.s
.LowPart
== INVALID_SET_FILE_POINTER
&& GetLastError() != NO_ERROR
) return E_FAIL
;
125 if (plibNewPosition
) plibNewPosition
->QuadPart
= liNewPos
.QuadPart
;
130 HRESULT WINAPI
ILoaderStream_IStream_Clone (LPSTREAM iface
, IStream
** ppstm
)
132 ICOM_THIS_MULTI(ILoaderStream
, StreamVtbl
, iface
);
133 ILoaderStream
* pOther
= NULL
;
136 TRACE("(%p, %p)\n", iface
, ppstm
);
137 result
= DMUSIC_CreateLoaderStream ((LPSTREAM
*)&pOther
);
138 if (FAILED(result
)) return result
;
139 if (This
->hFile
!= INVALID_HANDLE_VALUE
) {
140 ULARGE_INTEGER ullCurrentPosition
;
141 result
= ILoaderStream_Attach (pOther
, This
->wzFileName
, (LPDIRECTMUSICLOADER
)This
->pLoader
);
142 if (SUCCEEDED(result
)) {
143 LARGE_INTEGER liZero
;
145 result
= ILoaderStream_IStream_Seek (iface
, liZero
, STREAM_SEEK_CUR
, &ullCurrentPosition
); /* get current position in current stream */
147 if (SUCCEEDED(result
)) {
148 LARGE_INTEGER liNewPosition
;
149 liNewPosition
.QuadPart
= ullCurrentPosition
.QuadPart
;
150 result
= ILoaderStream_IStream_Seek ((LPSTREAM
)pOther
, liNewPosition
, STREAM_SEEK_SET
, &ullCurrentPosition
);
152 if (FAILED(result
)) {
154 ILoaderStream_IStream_Release ((LPSTREAM
)pOther
);
158 TRACE(": succeeded\n");
159 *ppstm
= (IStream
*)pOther
;
164 HRESULT WINAPI
ILoaderStream_IStream_Write (LPSTREAM iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
)
166 ERR(": should not be needed\n");
170 HRESULT WINAPI
ILoaderStream_IStream_SetSize (LPSTREAM iface
, ULARGE_INTEGER libNewSize
)
172 ERR(": should not be needed\n");
176 HRESULT WINAPI
ILoaderStream_IStream_CopyTo (LPSTREAM iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
)
178 ERR(": should not be needed\n");
182 HRESULT WINAPI
ILoaderStream_IStream_Commit (LPSTREAM iface
, DWORD grfCommitFlags
)
184 ERR(": should not be needed\n");
188 HRESULT WINAPI
ILoaderStream_IStream_Revert (LPSTREAM iface
)
190 ERR(": should not be needed\n");
194 HRESULT WINAPI
ILoaderStream_IStream_LockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
)
196 ERR(": should not be needed\n");
200 HRESULT WINAPI
ILoaderStream_IStream_UnlockRegion (LPSTREAM iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
)
202 ERR(": should not be needed\n");
206 HRESULT WINAPI
ILoaderStream_IStream_Stat (LPSTREAM iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
)
208 ERR(": should not be needed\n");
212 ICOM_VTABLE(IStream
) LoaderStream_Stream_Vtbl
=
214 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
215 ILoaderStream_IStream_QueryInterface
,
216 ILoaderStream_IStream_AddRef
,
217 ILoaderStream_IStream_Release
,
218 ILoaderStream_IStream_Read
,
219 ILoaderStream_IStream_Write
,
220 ILoaderStream_IStream_Seek
,
221 ILoaderStream_IStream_SetSize
,
222 ILoaderStream_IStream_CopyTo
,
223 ILoaderStream_IStream_Commit
,
224 ILoaderStream_IStream_Revert
,
225 ILoaderStream_IStream_LockRegion
,
226 ILoaderStream_IStream_UnlockRegion
,
227 ILoaderStream_IStream_Stat
,
228 ILoaderStream_IStream_Clone
231 /*****************************************************************************
232 * ILoaderStream IDirectMusicGetLoader:
234 HRESULT WINAPI
ILoaderStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface
, REFIID riid
, void** ppobj
)
236 ICOM_THIS_MULTI(ILoaderStream
, GetLoaderVtbl
, iface
);
237 return ILoaderStream_IStream_QueryInterface ((LPSTREAM
)&This
->StreamVtbl
, riid
, ppobj
);
240 ULONG WINAPI
ILoaderStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface
)
242 ICOM_THIS_MULTI(ILoaderStream
, GetLoaderVtbl
, iface
);
243 return ILoaderStream_IStream_AddRef ((LPSTREAM
)&This
->StreamVtbl
);
246 ULONG WINAPI
ILoaderStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface
)
248 ICOM_THIS_MULTI(ILoaderStream
, GetLoaderVtbl
, iface
);
249 return ILoaderStream_IStream_Release ((LPSTREAM
)&This
->StreamVtbl
);
252 HRESULT WINAPI
ILoaderStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface
, IDirectMusicLoader
**ppLoader
)
254 ICOM_THIS_MULTI(ILoaderStream
, GetLoaderVtbl
, iface
);
256 TRACE("(%p, %p)\n", This
, ppLoader
);
257 *ppLoader
= (LPDIRECTMUSICLOADER
)This
->pLoader
;
258 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8
)*ppLoader
);
263 ICOM_VTABLE(IDirectMusicGetLoader
) LoaderStream_GetLoader_Vtbl
=
265 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
266 ILoaderStream_IDirectMusicGetLoader_QueryInterface
,
267 ILoaderStream_IDirectMusicGetLoader_AddRef
,
268 ILoaderStream_IDirectMusicGetLoader_Release
,
269 ILoaderStream_IDirectMusicGetLoader_GetLoader
273 HRESULT WINAPI
DMUSIC_CreateLoaderStream (LPSTREAM
* ppStream
)
275 ILoaderStream
*pStream
;
277 TRACE("(%p)\n", ppStream
);
279 pStream
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(ILoaderStream
));
280 if (NULL
== pStream
) {
281 *ppStream
= (LPSTREAM
)NULL
;
282 return E_OUTOFMEMORY
;
284 pStream
->StreamVtbl
= &LoaderStream_Stream_Vtbl
;
285 pStream
->GetLoaderVtbl
= &LoaderStream_GetLoader_Vtbl
;
288 *ppStream
= (LPSTREAM
)pStream
;