Read and write binary files in binary mode on Windows.
[wine/multimedia.git] / dlls / dmloader / loaderstream.c
blobac2041431448d985cf5b7f244caee28a63f8ab4a
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
22 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "wingdi.h"
28 #include "wine/debug.h"
29 #include "wine/unicode.h"
31 #include "dmloader_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(dmloader);
35 /*****************************************************************************
36 * Custom functions:
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) {
44 TRACE(": failed\n");
45 return E_FAIL;
47 /* create IDirectMusicGetLoader */
48 (LPDIRECTMUSICLOADER)This->pLoader = pLoader;
49 strncpyW (This->wzFileName, wzFile, MAX_PATH);
50 TRACE(": succeeded\n");
52 return S_OK;
55 void WINAPI ILoaderStream_Detach (ILoaderStream* This)
57 if (This->hFile != INVALID_HANDLE_VALUE) {
58 CloseHandle(This->hFile);
60 This->wzFileName[0] = (L'\0');
63 /*****************************************************************************
64 * ILoaderStream IStream:
66 HRESULT WINAPI ILoaderStream_IStream_QueryInterface (LPSTREAM iface, REFIID riid, void** ppobj)
68 ICOM_THIS_MULTI(ILoaderStream, StreamVtbl, iface);
70 if (IsEqualIID (riid, &IID_IUnknown)
71 || IsEqualIID (riid, &IID_IStream)) {
72 *ppobj = (LPVOID)&This->StreamVtbl;
73 ILoaderStream_IStream_AddRef (iface);
74 return S_OK;
75 } else if (IsEqualIID (riid, &IID_IDirectMusicGetLoader)) {
76 *ppobj = (LPVOID)&This->GetLoaderVtbl;
77 ILoaderStream_IStream_AddRef (iface);
78 return S_OK;
81 WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
82 return E_NOINTERFACE;
85 ULONG WINAPI ILoaderStream_IStream_AddRef (LPSTREAM iface)
87 ICOM_THIS_MULTI(ILoaderStream, StreamVtbl, iface);
88 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
89 return ++(This->ref);
92 ULONG WINAPI ILoaderStream_IStream_Release (LPSTREAM iface)
94 ICOM_THIS_MULTI(ILoaderStream, StreamVtbl, iface);
95 ULONG ref = --This->ref;
96 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
97 if (ref == 0) {
98 HeapFree(GetProcessHeap(), 0, This);
100 return ref;
103 HRESULT WINAPI ILoaderStream_IStream_Read (LPSTREAM iface, void* pv, ULONG cb, ULONG* pcbRead)
105 ICOM_THIS_MULTI(ILoaderStream, StreamVtbl, iface);
106 ULONG cbRead;
108 if (This->hFile == INVALID_HANDLE_VALUE) return E_FAIL;
109 if (pcbRead == NULL) pcbRead = &cbRead;
110 if (!ReadFile (This->hFile, pv, cb, pcbRead, NULL) || *pcbRead != cb) return E_FAIL;
112 return S_OK;
115 HRESULT WINAPI ILoaderStream_IStream_Seek (LPSTREAM iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
117 ICOM_THIS_MULTI(ILoaderStream, StreamVtbl, iface);
118 LARGE_INTEGER liNewPos;
120 if (This->hFile == INVALID_HANDLE_VALUE) return E_FAIL;
122 liNewPos.s.HighPart = dlibMove.s.HighPart;
123 liNewPos.s.LowPart = SetFilePointer (This->hFile, dlibMove.s.LowPart, &liNewPos.s.HighPart, dwOrigin);
125 if (liNewPos.s.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) return E_FAIL;
126 if (plibNewPosition) plibNewPosition->QuadPart = liNewPos.QuadPart;
128 return S_OK;
131 HRESULT WINAPI ILoaderStream_IStream_Clone (LPSTREAM iface, IStream** ppstm)
133 ICOM_THIS_MULTI(ILoaderStream, StreamVtbl, iface);
134 ILoaderStream* pOther = NULL;
135 HRESULT result;
137 TRACE("(%p, %p)\n", iface, ppstm);
138 result = DMUSIC_CreateLoaderStream ((LPSTREAM*)&pOther);
139 if (FAILED(result)) return result;
140 if (This->hFile != INVALID_HANDLE_VALUE) {
141 ULARGE_INTEGER ullCurrentPosition;
142 result = ILoaderStream_Attach (pOther, This->wzFileName, (LPDIRECTMUSICLOADER)This->pLoader);
143 if (SUCCEEDED(result)) {
144 LARGE_INTEGER liZero;
145 liZero.QuadPart = 0;
146 result = ILoaderStream_IStream_Seek (iface, liZero, STREAM_SEEK_CUR, &ullCurrentPosition); /* get current position in current stream */
148 if (SUCCEEDED(result)) {
149 LARGE_INTEGER liNewPosition;
150 liNewPosition.QuadPart = ullCurrentPosition.QuadPart;
151 result = ILoaderStream_IStream_Seek ((LPSTREAM)pOther, liNewPosition, STREAM_SEEK_SET, &ullCurrentPosition);
153 if (FAILED(result)) {
154 TRACE(": failed\n");
155 ILoaderStream_IStream_Release ((LPSTREAM)pOther);
156 return result;
159 TRACE(": succeeded\n");
160 *ppstm = (IStream*)pOther;
161 return S_OK;
164 /* not needed*/
165 HRESULT WINAPI ILoaderStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten)
167 ERR(": should not be needed\n");
168 return E_NOTIMPL;
171 HRESULT WINAPI ILoaderStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize)
173 ERR(": should not be needed\n");
174 return E_NOTIMPL;
177 HRESULT WINAPI ILoaderStream_IStream_CopyTo (LPSTREAM iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
179 ERR(": should not be needed\n");
180 return E_NOTIMPL;
183 HRESULT WINAPI ILoaderStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags)
185 ERR(": should not be needed\n");
186 return E_NOTIMPL;
189 HRESULT WINAPI ILoaderStream_IStream_Revert (LPSTREAM iface)
191 ERR(": should not be needed\n");
192 return E_NOTIMPL;
195 HRESULT WINAPI ILoaderStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
197 ERR(": should not be needed\n");
198 return E_NOTIMPL;
201 HRESULT WINAPI ILoaderStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
203 ERR(": should not be needed\n");
204 return E_NOTIMPL;
207 HRESULT WINAPI ILoaderStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag)
209 ERR(": should not be needed\n");
210 return E_NOTIMPL;
213 ICOM_VTABLE(IStream) LoaderStream_Stream_Vtbl =
215 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
216 ILoaderStream_IStream_QueryInterface,
217 ILoaderStream_IStream_AddRef,
218 ILoaderStream_IStream_Release,
219 ILoaderStream_IStream_Read,
220 ILoaderStream_IStream_Write,
221 ILoaderStream_IStream_Seek,
222 ILoaderStream_IStream_SetSize,
223 ILoaderStream_IStream_CopyTo,
224 ILoaderStream_IStream_Commit,
225 ILoaderStream_IStream_Revert,
226 ILoaderStream_IStream_LockRegion,
227 ILoaderStream_IStream_UnlockRegion,
228 ILoaderStream_IStream_Stat,
229 ILoaderStream_IStream_Clone
232 /*****************************************************************************
233 * ILoaderStream IDirectMusicGetLoader:
235 HRESULT WINAPI ILoaderStream_IDirectMusicGetLoader_QueryInterface (LPDIRECTMUSICGETLOADER iface, REFIID riid, void** ppobj)
237 ICOM_THIS_MULTI(ILoaderStream, GetLoaderVtbl, iface);
238 return ILoaderStream_IStream_QueryInterface ((LPSTREAM)&This->StreamVtbl, riid, ppobj);
241 ULONG WINAPI ILoaderStream_IDirectMusicGetLoader_AddRef (LPDIRECTMUSICGETLOADER iface)
243 ICOM_THIS_MULTI(ILoaderStream, GetLoaderVtbl, iface);
244 return ILoaderStream_IStream_AddRef ((LPSTREAM)&This->StreamVtbl);
247 ULONG WINAPI ILoaderStream_IDirectMusicGetLoader_Release (LPDIRECTMUSICGETLOADER iface)
249 ICOM_THIS_MULTI(ILoaderStream, GetLoaderVtbl, iface);
250 return ILoaderStream_IStream_Release ((LPSTREAM)&This->StreamVtbl);
253 HRESULT WINAPI ILoaderStream_IDirectMusicGetLoader_GetLoader (LPDIRECTMUSICGETLOADER iface, IDirectMusicLoader **ppLoader)
255 ICOM_THIS_MULTI(ILoaderStream, GetLoaderVtbl, iface);
257 TRACE("(%p, %p)\n", This, ppLoader);
258 *ppLoader = (LPDIRECTMUSICLOADER)This->pLoader;
259 IDirectMusicLoader8_AddRef ((LPDIRECTMUSICLOADER8)*ppLoader);
261 return S_OK;
264 ICOM_VTABLE(IDirectMusicGetLoader) LoaderStream_GetLoader_Vtbl =
266 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
267 ILoaderStream_IDirectMusicGetLoader_QueryInterface,
268 ILoaderStream_IDirectMusicGetLoader_AddRef,
269 ILoaderStream_IDirectMusicGetLoader_Release,
270 ILoaderStream_IDirectMusicGetLoader_GetLoader
274 HRESULT WINAPI DMUSIC_CreateLoaderStream (LPSTREAM* ppStream)
276 ILoaderStream *pStream;
278 TRACE("(%p)\n", ppStream);
280 pStream = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(ILoaderStream));
281 if (NULL == pStream) {
282 *ppStream = (LPSTREAM)NULL;
283 return E_OUTOFMEMORY;
285 pStream->StreamVtbl = &LoaderStream_Stream_Vtbl;
286 pStream->GetLoaderVtbl = &LoaderStream_GetLoader_Vtbl;
287 pStream->ref = 1;
289 *ppStream = (LPSTREAM)pStream;
290 return S_OK;