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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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;
57 for (c = pszURL; *c && *c != '#' && *c != '?'; ++c)
61 else if (*c == '/' || *c == '\\')
68 ext = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (c - eloc + 1));
69 memcpy(ext, eloc, sizeof(WCHAR) * (c - eloc));
72 if(!CreateUrlCacheEntryW(pszURL, dwSize, ext, pszFileName, 0))
73 hr = HRESULT_FROM_WIN32(GetLastError());
77 HeapFree(GetProcessHeap(), 0, ext);
82 TRACE("Opening %s\n", debugstr_w(pszFileName) );
84 handle = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL );
85 if( handle == INVALID_HANDLE_VALUE )
86 return HRESULT_FROM_WIN32(GetLastError());
90 /* Call CreateFileW again because we need a handle with its own file pointer, and DuplicateHandle will return
91 * a handle that shares its file pointer with the original.
93 *phfile = CreateFileW( pszFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
95 if (*phfile == (HANDLE) HFILE_ERROR)
97 DWORD dwError = GetLastError();
100 return HRESULT_FROM_WIN32(dwError);
104 ucstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(IUMCacheStream));
107 ucstr->pszURL = HeapAlloc(GetProcessHeap(),
109 sizeof(WCHAR) * (lstrlenW(pszURL) + 1));
112 ucstr->pszFileName = HeapAlloc(GetProcessHeap(),
114 sizeof(WCHAR) * (lstrlenW(pszFileName) + 1));
115 if (ucstr->pszFileName)
119 ucstr->handle = handle;
121 lstrcpyW(ucstr->pszURL, pszURL);
122 lstrcpyW(ucstr->pszFileName, pszFileName);
128 HeapFree(GetProcessHeap(), 0, ucstr->pszURL);
130 HeapFree(GetProcessHeap(), 0, ucstr);
134 CloseHandle(*phfile);
135 return E_OUTOFMEMORY;
138 void UMCloseCacheFileStream(IUMCacheStream *This)
144 ftZero.dwLowDateTime = ftZero.dwHighDateTime = 0;
147 CommitUrlCacheEntryW(This->pszURL,
159 /**************************************************************************
160 * IStream_fnQueryInterface
162 static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface,
166 IUMCacheStream *This = (IUMCacheStream *)iface;
168 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
172 if(IsEqualIID(riid, &IID_IUnknown) ||
173 IsEqualIID(riid, &IID_IStream))
180 IStream_AddRef((IStream*)*ppvObj);
181 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
184 TRACE("-- Interface: E_NOINTERFACE\n");
185 return E_NOINTERFACE;
188 /**************************************************************************
191 static ULONG WINAPI IStream_fnAddRef(IStream *iface)
193 IUMCacheStream *This = (IUMCacheStream *)iface;
194 ULONG refCount = InterlockedIncrement(&This->ref);
196 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
201 /**************************************************************************
204 static ULONG WINAPI IStream_fnRelease(IStream *iface)
206 IUMCacheStream *This = (IUMCacheStream *)iface;
207 ULONG refCount = InterlockedDecrement(&This->ref);
209 TRACE("(%p)->(count=%lu)\n", This, refCount + 1);
213 TRACE(" destroying UMCacheStream (%p)\n",This);
214 UMCloseCacheFileStream(This);
215 CloseHandle(This->handle);
216 HeapFree(GetProcessHeap(), 0, This->pszFileName);
217 HeapFree(GetProcessHeap(), 0, This->pszURL);
218 HeapFree(GetProcessHeap(),0,This);
223 static HRESULT WINAPI IStream_fnRead (IStream * iface,
228 IUMCacheStream *This = (IUMCacheStream *)iface;
230 TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
233 return STG_E_INVALIDPOINTER;
235 if ( ! ReadFile( This->handle, pv, cb, pcbRead, NULL ) )
239 return This->closed ? S_FALSE : E_PENDING;
243 static HRESULT WINAPI IStream_fnWrite (IStream * iface,
251 static HRESULT WINAPI IStream_fnSeek ( IStream * iface,
252 LARGE_INTEGER dlibMove,
254 ULARGE_INTEGER* plibNewPosition)
259 IUMCacheStream *This = (IUMCacheStream *)iface;
261 TRACE("(%p)\n",This);
263 pos = dlibMove.QuadPart; /* FIXME: truncates */
265 newposlo = SetFilePointer( This->handle, pos, &newposhi, dwOrigin );
266 if( newposlo == INVALID_SET_FILE_POINTER && GetLastError())
270 plibNewPosition->QuadPart = newposlo | ( (LONGLONG)newposhi<<32);
275 static HRESULT WINAPI IStream_fnSetSize (IStream * iface,
276 ULARGE_INTEGER libNewSize)
278 IUMCacheStream *This = (IUMCacheStream *)iface;
280 TRACE("(%p)\n",This);
282 if( ! SetFilePointer( This->handle, libNewSize.QuadPart, NULL, FILE_BEGIN ) )
285 if( ! SetEndOfFile( This->handle ) )
291 static HRESULT WINAPI IStream_fnCopyTo (IStream * iface,
294 ULARGE_INTEGER* pcbRead,
295 ULARGE_INTEGER* pcbWritten)
297 IUMCacheStream *This = (IUMCacheStream *)iface;
299 TRACE("(%p)\n",This);
304 static HRESULT WINAPI IStream_fnCommit (IStream * iface,
305 DWORD grfCommitFlags)
307 IUMCacheStream *This = (IUMCacheStream *)iface;
309 TRACE("(%p)\n",This);
314 static HRESULT WINAPI IStream_fnRevert (IStream * iface)
316 IUMCacheStream *This = (IUMCacheStream *)iface;
318 TRACE("(%p)\n",This);
322 static HRESULT WINAPI IStream_fnLockRegion (IStream * iface,
323 ULARGE_INTEGER libOffset,
327 IUMCacheStream *This = (IUMCacheStream *)iface;
329 TRACE("(%p)\n",This);
333 static HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface,
334 ULARGE_INTEGER libOffset,
338 IUMCacheStream *This = (IUMCacheStream *)iface;
340 TRACE("(%p)\n",This);
344 static HRESULT WINAPI IStream_fnStat (IStream * iface,
348 IUMCacheStream *This = (IUMCacheStream *)iface;
350 TRACE("(%p)\n",This);
354 static HRESULT WINAPI IStream_fnClone (IStream * iface,
357 IUMCacheStream *This = (IUMCacheStream *)iface;
359 TRACE("(%p)\n",This);
364 static const IStreamVtbl stvt =
366 IStream_fnQueryInterface,
376 IStream_fnLockRegion,
377 IStream_fnUnlockRegion,