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
,