2 * Based on ../shell32/memorystream.c
4 * Copyright 1999 Juergen Schmied
5 * Copyright 2003 Mike McCormack for CodeWeavers
7 * This library 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 library 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 library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
38 #include "urlmon_main.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
42 static const IStreamVtbl stvt;
44 HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL,
48 IUMCacheStream **ppstr)
50 IUMCacheStream* ucstr;
53 LPWSTR url, c, ext = NULL;
56 size = (strlenW(pszURL)+1)*sizeof(WCHAR);
57 url = HeapAlloc(GetProcessHeap(), 0, size);
58 memcpy(url, pszURL, size);
60 for (c = url; *c && *c != '#' && *c != '?'; ++c)
70 if(!CreateUrlCacheEntryW(url, dwSize, ext, pszFileName, 0))
71 hr = HRESULT_FROM_WIN32(GetLastError());
75 HeapFree(GetProcessHeap(), 0, url);
80 TRACE("Opening %s\n", debugstr_w(pszFileName) );
82 handle = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL );
83 if( handle == INVALID_HANDLE_VALUE )
84 return HRESULT_FROM_WIN32(GetLastError());
88 /* Call CreateFileW again because we need a handle with its own file pointer, and DuplicateHandle will return
89 * a handle that shares its file pointer with the original.
91 *phfile = CreateFileW( pszFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
93 if (*phfile == (HANDLE) HFILE_ERROR)
95 DWORD dwError = GetLastError();
98 return HRESULT_FROM_WIN32(dwError);
102 ucstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(IUMCacheStream));
105 ucstr->pszURL = HeapAlloc(GetProcessHeap(),
107 sizeof(WCHAR) * (lstrlenW(pszURL) + 1));
110 ucstr->pszFileName = HeapAlloc(GetProcessHeap(),
112 sizeof(WCHAR) * (lstrlenW(pszFileName) + 1));
113 if (ucstr->pszFileName)
117 ucstr->handle = handle;
119 lstrcpyW(ucstr->pszURL, pszURL);
120 lstrcpyW(ucstr->pszFileName, pszFileName);
126 HeapFree(GetProcessHeap(), 0, ucstr->pszURL);
128 HeapFree(GetProcessHeap(), 0, ucstr);
132 CloseHandle(*phfile);
133 return E_OUTOFMEMORY;
136 void UMCloseCacheFileStream(IUMCacheStream *This)
142 ftZero.dwLowDateTime = ftZero.dwHighDateTime = 0;
145 CommitUrlCacheEntryW(This->pszURL,
157 /**************************************************************************
158 * IStream_fnQueryInterface
160 static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface,
164 IUMCacheStream *This = (IUMCacheStream *)iface;
166 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
170 if(IsEqualIID(riid, &IID_IUnknown) ||
171 IsEqualIID(riid, &IID_IStream))
178 IStream_AddRef((IStream*)*ppvObj);
179 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
182 TRACE("-- Interface: E_NOINTERFACE\n");
183 return E_NOINTERFACE;
186 /**************************************************************************
189 static ULONG WINAPI IStream_fnAddRef(IStream *iface)
191 IUMCacheStream *This = (IUMCacheStream *)iface;
192 ULONG refCount = InterlockedIncrement(&This->ref);
194 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
199 /**************************************************************************
202 static ULONG WINAPI IStream_fnRelease(IStream *iface)
204 IUMCacheStream *This = (IUMCacheStream *)iface;
205 ULONG refCount = InterlockedDecrement(&This->ref);
207 TRACE("(%p)->(count=%u)\n", This, refCount + 1);
211 TRACE(" destroying UMCacheStream (%p)\n",This);
212 UMCloseCacheFileStream(This);
213 CloseHandle(This->handle);
214 HeapFree(GetProcessHeap(), 0, This->pszFileName);
215 HeapFree(GetProcessHeap(), 0, This->pszURL);
216 HeapFree(GetProcessHeap(),0,This);
221 static HRESULT WINAPI IStream_fnRead (IStream * iface,
227 IUMCacheStream *This = (IUMCacheStream *)iface;
229 TRACE("(%p)->(%p,0x%08x,%p)\n",This, pv, cb, pcbRead);
232 return STG_E_INVALIDPOINTER;
235 pcbRead = &dwBytesRead;
237 if ( ! ReadFile( This->handle, pv, cb, (LPDWORD)pcbRead, NULL ) )
241 return This->closed ? S_FALSE : E_PENDING;
245 static HRESULT WINAPI IStream_fnWrite (IStream * iface,
253 static HRESULT WINAPI IStream_fnSeek (IStream * iface,
254 LARGE_INTEGER dlibMove,
256 ULARGE_INTEGER* plibNewPosition)
258 LARGE_INTEGER newpos;
259 IUMCacheStream *This = (IUMCacheStream *)iface;
261 TRACE("(%p)\n",This);
263 if (!SetFilePointerEx( This->handle, dlibMove, &newpos, dwOrigin ))
267 plibNewPosition->QuadPart = newpos.QuadPart;
272 static HRESULT WINAPI IStream_fnSetSize (IStream * iface,
273 ULARGE_INTEGER libNewSize)
275 LARGE_INTEGER newpos;
276 IUMCacheStream *This = (IUMCacheStream *)iface;
278 TRACE("(%p)\n",This);
280 newpos.QuadPart = libNewSize.QuadPart;
281 if( ! SetFilePointerEx( This->handle, newpos, NULL, FILE_BEGIN ) )
284 if( ! SetEndOfFile( This->handle ) )
290 static HRESULT WINAPI IStream_fnCopyTo (IStream * iface,
293 ULARGE_INTEGER* pcbRead,
294 ULARGE_INTEGER* pcbWritten)
296 IUMCacheStream *This = (IUMCacheStream *)iface;
298 TRACE("(%p)\n",This);
303 static HRESULT WINAPI IStream_fnCommit (IStream * iface,
304 DWORD grfCommitFlags)
306 IUMCacheStream *This = (IUMCacheStream *)iface;
308 TRACE("(%p)\n",This);
313 static HRESULT WINAPI IStream_fnRevert (IStream * iface)
315 IUMCacheStream *This = (IUMCacheStream *)iface;
317 TRACE("(%p)\n",This);
321 static HRESULT WINAPI IStream_fnLockRegion (IStream * iface,
322 ULARGE_INTEGER libOffset,
326 IUMCacheStream *This = (IUMCacheStream *)iface;
328 TRACE("(%p)\n",This);
332 static HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface,
333 ULARGE_INTEGER libOffset,
337 IUMCacheStream *This = (IUMCacheStream *)iface;
339 TRACE("(%p)\n",This);
343 static HRESULT WINAPI IStream_fnStat (IStream * iface,
347 IUMCacheStream *This = (IUMCacheStream *)iface;
349 TRACE("(%p)\n",This);
353 static HRESULT WINAPI IStream_fnClone (IStream * iface,
356 IUMCacheStream *This = (IUMCacheStream *)iface;
358 TRACE("(%p)\n",This);
363 static const IStreamVtbl stvt =
365 IStream_fnQueryInterface,
375 IStream_fnLockRegion,
376 IStream_fnUnlockRegion,