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
;
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
,
229 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
231 TRACE("(%p)->(%p,0x%08lx,%p)\n",This
, pv
, cb
, pcbRead
);
234 return STG_E_INVALIDPOINTER
;
237 pcbRead
= &dwBytesRead
;
239 if ( ! ReadFile( This
->handle
, pv
, cb
, (LPDWORD
)pcbRead
, NULL
) )
243 return This
->closed
? S_FALSE
: E_PENDING
;
247 static HRESULT WINAPI
IStream_fnWrite (IStream
* iface
,
255 static HRESULT WINAPI
IStream_fnSeek (IStream
* iface
,
256 LARGE_INTEGER dlibMove
,
258 ULARGE_INTEGER
* plibNewPosition
)
260 LARGE_INTEGER newpos
;
261 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
263 TRACE("(%p)\n",This
);
265 if (!SetFilePointerEx( This
->handle
, dlibMove
, &newpos
, dwOrigin
))
269 plibNewPosition
->QuadPart
= newpos
.QuadPart
;
274 static HRESULT WINAPI
IStream_fnSetSize (IStream
* iface
,
275 ULARGE_INTEGER libNewSize
)
277 LARGE_INTEGER newpos
;
278 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
280 TRACE("(%p)\n",This
);
282 newpos
.QuadPart
= libNewSize
.QuadPart
;
283 if( ! SetFilePointerEx( This
->handle
, newpos
, NULL
, FILE_BEGIN
) )
286 if( ! SetEndOfFile( This
->handle
) )
292 static HRESULT WINAPI
IStream_fnCopyTo (IStream
* iface
,
295 ULARGE_INTEGER
* pcbRead
,
296 ULARGE_INTEGER
* pcbWritten
)
298 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
300 TRACE("(%p)\n",This
);
305 static HRESULT WINAPI
IStream_fnCommit (IStream
* iface
,
306 DWORD grfCommitFlags
)
308 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
310 TRACE("(%p)\n",This
);
315 static HRESULT WINAPI
IStream_fnRevert (IStream
* iface
)
317 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
319 TRACE("(%p)\n",This
);
323 static HRESULT WINAPI
IStream_fnLockRegion (IStream
* iface
,
324 ULARGE_INTEGER libOffset
,
328 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
330 TRACE("(%p)\n",This
);
334 static HRESULT WINAPI
IStream_fnUnlockRegion (IStream
* iface
,
335 ULARGE_INTEGER libOffset
,
339 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
341 TRACE("(%p)\n",This
);
345 static HRESULT WINAPI
IStream_fnStat (IStream
* iface
,
349 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
351 TRACE("(%p)\n",This
);
355 static HRESULT WINAPI
IStream_fnClone (IStream
* iface
,
358 IUMCacheStream
*This
= (IUMCacheStream
*)iface
;
360 TRACE("(%p)\n",This
);
365 static const IStreamVtbl stvt
=
367 IStream_fnQueryInterface
,
377 IStream_fnLockRegion
,
378 IStream_fnUnlockRegion
,