2 * This class implements a pure IStream object
3 * and can be used for many purposes.
5 * The main reason for implementing this was
6 * a cleaner implementation of IShellLink which
7 * needs to be able to load lnks from an IStream
8 * interface so it was obvious to capsule the file
9 * access in an IStream to.
11 * Copyright 1999 Juergen Schmied
12 * Copyright 2003 Mike McCormack for CodeWeavers
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 #include "wine/debug.h"
41 #include "shell32_main.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(shell);
45 #define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f)
46 #define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0)
47 #define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000)
51 const IStreamVtbl *lpvtst;
56 /**************************************************************************
57 * IStream_fnQueryInterface
59 static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj)
61 ISHFileStream *This = (ISHFileStream *)iface;
63 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
67 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IStream))
72 IStream_AddRef((IStream*)*ppvObj);
73 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
76 TRACE("-- Interface: E_NOINTERFACE\n");
80 /**************************************************************************
83 static ULONG WINAPI IStream_fnAddRef(IStream *iface)
85 ISHFileStream *This = (ISHFileStream *)iface;
86 ULONG refCount = InterlockedIncrement(&This->ref);
88 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
93 /**************************************************************************
96 static ULONG WINAPI IStream_fnRelease(IStream *iface)
98 ISHFileStream *This = (ISHFileStream *)iface;
99 ULONG refCount = InterlockedDecrement(&This->ref);
101 TRACE("(%p)->(count=%lu)\n", This, refCount + 1);
105 TRACE(" destroying SHFileStream (%p)\n",This);
106 CloseHandle(This->handle);
107 HeapFree(GetProcessHeap(),0,This);
112 static HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead)
114 ISHFileStream *This = (ISHFileStream *)iface;
116 TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
119 return STG_E_INVALIDPOINTER;
121 if ( ! ReadFile( This->handle, pv, cb, pcbRead, NULL ) )
127 static HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb, ULONG* pcbWritten)
130 ISHFileStream *This = (ISHFileStream *)iface;
132 TRACE("(%p)\n",This);
135 return STG_E_INVALIDPOINTER;
137 /* WriteFile() doesn't allow to specify NULL as write count pointer */
139 pcbWritten = &dummy_count;
141 if( ! WriteFile( This->handle, pv, cb, pcbWritten, NULL ) )
147 static HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
149 DWORD pos, newposlo, newposhi;
151 ISHFileStream *This = (ISHFileStream *)iface;
153 TRACE("(%p)\n",This);
155 pos = dlibMove.QuadPart; /* FIXME: truncates */
157 newposlo = SetFilePointer( This->handle, pos, &newposhi, dwOrigin );
158 if( newposlo == INVALID_SET_FILE_POINTER )
161 plibNewPosition->QuadPart = newposlo | ( (LONGLONG)newposhi<<32);
166 static HRESULT WINAPI IStream_fnSetSize (IStream * iface, ULARGE_INTEGER libNewSize)
168 ISHFileStream *This = (ISHFileStream *)iface;
170 TRACE("(%p)\n",This);
172 if( ! SetFilePointer( This->handle, libNewSize.QuadPart, NULL, FILE_BEGIN ) )
175 if( ! SetEndOfFile( This->handle ) )
180 static HRESULT WINAPI IStream_fnCopyTo (IStream * iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
182 ISHFileStream *This = (ISHFileStream *)iface;
184 TRACE("(%p)\n",This);
188 static HRESULT WINAPI IStream_fnCommit (IStream * iface, DWORD grfCommitFlags)
190 ISHFileStream *This = (ISHFileStream *)iface;
192 TRACE("(%p)\n",This);
196 static HRESULT WINAPI IStream_fnRevert (IStream * iface)
198 ISHFileStream *This = (ISHFileStream *)iface;
200 TRACE("(%p)\n",This);
204 static HRESULT WINAPI IStream_fnLockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
206 ISHFileStream *This = (ISHFileStream *)iface;
208 TRACE("(%p)\n",This);
212 static HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
214 ISHFileStream *This = (ISHFileStream *)iface;
216 TRACE("(%p)\n",This);
220 static HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG* pstatstg, DWORD grfStatFlag)
222 ISHFileStream *This = (ISHFileStream *)iface;
224 TRACE("(%p)\n",This);
228 static HRESULT WINAPI IStream_fnClone (IStream * iface, IStream** ppstm)
230 ISHFileStream *This = (ISHFileStream *)iface;
232 TRACE("(%p)\n",This);
237 static const IStreamVtbl stvt =
239 IStream_fnQueryInterface,
249 IStream_fnLockRegion,
250 IStream_fnUnlockRegion,
255 /**************************************************************************
256 * CreateStreamOnFile()
258 * similar to CreateStreamOnHGlobal
260 HRESULT CreateStreamOnFile (LPCWSTR pszFilename, DWORD grfMode, IStream ** ppstm)
264 DWORD access = GENERIC_READ, creat;
266 if( grfMode & STGM_TRANSACTED )
269 switch( STGM_ACCESS_MODE( grfMode ) )
272 access = GENERIC_READ;
276 access = GENERIC_WRITE | GENERIC_READ;
279 return STG_E_INVALIDFLAG;
282 switch( STGM_CREATE_MODE( grfMode ) )
285 creat = CREATE_ALWAYS;
287 case STGM_FAILIFTHERE:
288 creat = OPEN_EXISTING;
291 return STG_E_INVALIDFLAG;
294 handle = CreateFileW( pszFilename, access,
295 FILE_SHARE_READ, NULL, creat, 0, NULL );
296 if( handle == INVALID_HANDLE_VALUE )
297 return HRESULT_FROM_WIN32(GetLastError());
299 fstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ISHFileStream));
301 return E_OUTOFMEMORY;
302 fstr->lpvtst = &stvt;
304 fstr->handle = handle;
306 (*ppstm) = (IStream*)fstr;