2 * SHLWAPI Registry Stream functions
4 * Copyright 1999 Juergen Schmied
5 * Copyright 2002 Jon Griffiths
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
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
40 IStream IStream_iface
;
48 static inline ISHRegStream
*impl_from_IStream(IStream
*iface
)
50 return CONTAINING_RECORD(iface
, ISHRegStream
, IStream_iface
);
53 /**************************************************************************
54 * IStream_fnQueryInterface
56 static HRESULT WINAPI
IStream_fnQueryInterface(IStream
*iface
, REFIID riid
, LPVOID
*ppvObj
)
58 ISHRegStream
*This
= impl_from_IStream(iface
);
60 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
64 if(IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IStream
))
65 *ppvObj
= &This
->IStream_iface
;
69 IStream_AddRef((IStream
*)*ppvObj
);
70 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
73 TRACE("-- Interface: E_NOINTERFACE\n");
77 /**************************************************************************
80 static ULONG WINAPI
IStream_fnAddRef(IStream
*iface
)
82 ISHRegStream
*This
= impl_from_IStream(iface
);
83 ULONG refCount
= InterlockedIncrement(&This
->ref
);
85 TRACE("(%p)->(ref before=%lu)\n",This
, refCount
- 1);
90 /**************************************************************************
93 static ULONG WINAPI
IStream_fnRelease(IStream
*iface
)
95 ISHRegStream
*This
= impl_from_IStream(iface
);
96 ULONG refCount
= InterlockedDecrement(&This
->ref
);
98 TRACE("(%p)->(ref before=%lu)\n",This
, refCount
+ 1);
102 free(This
->pbBuffer
);
110 /**************************************************************************
113 static HRESULT WINAPI
IStream_fnRead (IStream
* iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
)
115 ISHRegStream
*This
= impl_from_IStream(iface
);
118 TRACE("(%p)->(%p,0x%08lx,%p)\n",This
, pv
, cb
, pcbRead
);
120 if (This
->dwPos
>= This
->dwLength
)
123 dwBytesToRead
= This
->dwLength
- This
->dwPos
;
125 dwBytesToRead
= (cb
> dwBytesToRead
) ? dwBytesToRead
: cb
;
126 if (dwBytesToRead
!= 0) /* not at end of buffer and we want to read something */
128 memmove(pv
, This
->pbBuffer
+ This
->dwPos
, dwBytesToRead
);
129 This
->dwPos
+= dwBytesToRead
; /* adjust pointer */
133 *pcbRead
= dwBytesToRead
;
138 /**************************************************************************
141 static HRESULT WINAPI
IStream_fnWrite (IStream
* iface
, const void* pv
, ULONG cb
, ULONG
* pcbWritten
)
143 ISHRegStream
*This
= impl_from_IStream(iface
);
144 DWORD newLen
= This
->dwPos
+ cb
;
146 TRACE("(%p, %p, %ld, %p)\n",This
, pv
, cb
, pcbWritten
);
148 if (newLen
< This
->dwPos
) /* overflow */
149 return STG_E_INSUFFICIENTMEMORY
;
151 if (newLen
> This
->dwLength
)
153 BYTE
*newBuf
= _recalloc(This
->pbBuffer
, 1, newLen
);
155 return STG_E_INSUFFICIENTMEMORY
;
157 This
->dwLength
= newLen
;
158 This
->pbBuffer
= newBuf
;
160 memmove(This
->pbBuffer
+ This
->dwPos
, pv
, cb
);
161 This
->dwPos
+= cb
; /* adjust pointer */
169 /**************************************************************************
172 static HRESULT WINAPI
IStream_fnSeek (IStream
* iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
)
174 ISHRegStream
*This
= impl_from_IStream(iface
);
176 TRACE("(%p, %s, %ld %p)\n", This
,
177 wine_dbgstr_longlong(dlibMove
.QuadPart
), dwOrigin
, plibNewPosition
);
179 if (dwOrigin
== STREAM_SEEK_SET
)
181 else if (dwOrigin
== STREAM_SEEK_CUR
)
182 tmp
.QuadPart
= This
->dwPos
+ dlibMove
.QuadPart
;
183 else if (dwOrigin
== STREAM_SEEK_END
)
184 tmp
.QuadPart
= This
->dwLength
+ dlibMove
.QuadPart
;
186 return STG_E_INVALIDPARAMETER
;
188 if (tmp
.QuadPart
< 0)
189 return STG_E_INVALIDFUNCTION
;
191 /* we cut off the high part here */
192 This
->dwPos
= tmp
.u
.LowPart
;
195 plibNewPosition
->QuadPart
= This
->dwPos
;
199 /**************************************************************************
202 static HRESULT WINAPI
IStream_fnSetSize (IStream
* iface
, ULARGE_INTEGER libNewSize
)
204 ISHRegStream
*This
= impl_from_IStream(iface
);
208 TRACE("(%p, %s)\n", This
, wine_dbgstr_longlong(libNewSize
.QuadPart
));
210 /* we cut off the high part here */
211 newLen
= libNewSize
.u
.LowPart
;
212 newBuf
= _recalloc(This
->pbBuffer
, 1, newLen
);
214 return STG_E_INSUFFICIENTMEMORY
;
216 This
->pbBuffer
= newBuf
;
217 This
->dwLength
= newLen
;
222 /**************************************************************************
225 static HRESULT WINAPI
IStream_fnCopyTo (IStream
* iface
, IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
)
227 ISHRegStream
*This
= impl_from_IStream(iface
);
229 TRACE("(%p)\n",This
);
231 pcbRead
->QuadPart
= 0;
233 pcbWritten
->QuadPart
= 0;
239 /**************************************************************************
242 static HRESULT WINAPI
IStream_fnCommit (IStream
* iface
, DWORD grfCommitFlags
)
244 ISHRegStream
*This
= impl_from_IStream(iface
);
246 TRACE("(%p)\n",This
);
248 /* commit not supported by this stream */
252 /**************************************************************************
255 static HRESULT WINAPI
IStream_fnRevert (IStream
* iface
)
257 ISHRegStream
*This
= impl_from_IStream(iface
);
259 TRACE("(%p)\n",This
);
261 /* revert not supported by this stream */
265 /**************************************************************************
266 * IStream_fnLockUnlockRegion
268 static HRESULT WINAPI
IStream_fnLockUnlockRegion (IStream
* iface
, ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
)
270 ISHRegStream
*This
= impl_from_IStream(iface
);
272 TRACE("(%p)\n",This
);
274 /* lock/unlock not supported by this stream */
278 /*************************************************************************
281 static HRESULT WINAPI
IStream_fnStat (IStream
* iface
, STATSTG
* pstatstg
, DWORD grfStatFlag
)
283 ISHRegStream
*This
= impl_from_IStream(iface
);
285 TRACE("(%p, %p, %ld)\n",This
,pstatstg
,grfStatFlag
);
287 pstatstg
->pwcsName
= NULL
;
288 pstatstg
->type
= STGTY_STREAM
;
289 pstatstg
->cbSize
.QuadPart
= This
->dwLength
;
290 pstatstg
->mtime
.dwHighDateTime
= 0;
291 pstatstg
->mtime
.dwLowDateTime
= 0;
292 pstatstg
->ctime
.dwHighDateTime
= 0;
293 pstatstg
->ctime
.dwLowDateTime
= 0;
294 pstatstg
->atime
.dwHighDateTime
= 0;
295 pstatstg
->atime
.dwLowDateTime
= 0;
296 pstatstg
->grfMode
= This
->dwMode
;
297 pstatstg
->grfLocksSupported
= 0;
298 pstatstg
->clsid
= CLSID_NULL
;
299 pstatstg
->grfStateBits
= 0;
300 pstatstg
->reserved
= 0;
305 /*************************************************************************
308 static HRESULT WINAPI
IStream_fnClone (IStream
* iface
, IStream
** ppstm
)
310 ISHRegStream
*This
= impl_from_IStream(iface
);
312 TRACE("(%p)\n",This
);
315 /* clone not supported by this stream */
319 static const IStreamVtbl rstvt
=
321 IStream_fnQueryInterface
,
331 IStream_fnLockUnlockRegion
,
332 IStream_fnLockUnlockRegion
,
337 /**************************************************************************
340 * Internal helper: Create and initialise a new registry stream object.
342 static ISHRegStream
*IStream_Create(HKEY hKey
, LPBYTE pbBuffer
, DWORD dwLength
)
344 ISHRegStream
* regStream
;
346 regStream
= malloc(sizeof(ISHRegStream
));
350 regStream
->IStream_iface
.lpVtbl
= &rstvt
;
352 regStream
->pbBuffer
= pbBuffer
;
353 regStream
->dwLength
= dwLength
;
354 regStream
->dwPos
= 0;
355 regStream
->dwMode
= STGM_READWRITE
;
357 TRACE ("Returning %p\n", regStream
);
361 /*************************************************************************
362 * SHCreateStreamWrapper [SHLWAPI.@]
364 * Create an IStream object on a block of memory.
367 * lpbData [I] Memory block to create the IStream object on
368 * dwDataLen [I] Length of data block
369 * dwReserved [I] Reserved, Must be 0.
370 * lppStream [O] Destination for IStream object
373 * Success: S_OK. lppStream contains the new IStream object.
374 * Failure: E_INVALIDARG, if any parameters are invalid,
375 * E_OUTOFMEMORY if memory allocation fails.
378 * The stream assumes ownership of the memory passed to it.
380 HRESULT WINAPI
SHCreateStreamWrapper(LPBYTE lpbData
, DWORD dwDataLen
,
381 DWORD dwReserved
, IStream
**lppStream
)
388 if(dwReserved
|| !lppStream
)
391 strm
= IStream_Create(NULL
, lpbData
, dwDataLen
);
394 return E_OUTOFMEMORY
;
396 IStream_QueryInterface(&strm
->IStream_iface
, &IID_IStream
, (void**)lppStream
);
397 IStream_Release(&strm
->IStream_iface
);