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
,