ReactOS 0.4.17-dev-357-ga8f14ff
regstream.c
Go to the documentation of this file.
1/*
2 * SHLWAPI Registry Stream functions
3 *
4 * Copyright 1999 Juergen Schmied
5 * Copyright 2002 Jon Griffiths
6 *
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.
11 *
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.
16 *
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
20 */
21
22#include <stdarg.h>
23#include <string.h>
24
25#define COBJMACROS
26
27#include "winerror.h"
28#include "windef.h"
29#include "winbase.h"
30#include "objbase.h"
31#include "winreg.h"
32#include "shlwapi.h"
33
34#include "wine/debug.h"
35
37
38typedef struct
39{
47 union {
50 }u;
53
55{
56 return CONTAINING_RECORD(iface, ISHRegStream, IStream_iface);
57}
58
59/**************************************************************************
60* IStream_fnQueryInterface
61*/
63{
65
66 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
67
68 *ppvObj = NULL;
69
70 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IStream))
71 *ppvObj = &This->IStream_iface;
72
73 if(*ppvObj)
74 {
75 IStream_AddRef((IStream*)*ppvObj);
76 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
77 return S_OK;
78 }
79 TRACE("-- Interface: E_NOINTERFACE\n");
80 return E_NOINTERFACE;
81}
82
83/**************************************************************************
84* IStream_fnAddRef
85*/
87{
89 ULONG refCount = InterlockedIncrement(&This->ref);
90
91 TRACE("(%p)->(ref before=%lu)\n",This, refCount - 1);
92
93 return refCount;
94}
95
96/**************************************************************************
97* IStream_fnRelease
98*/
100{
102 ULONG refCount = InterlockedDecrement(&This->ref);
103
104 TRACE("(%p)->(ref before=%lu)\n",This, refCount + 1);
105
106 if (!refCount)
107 {
108 TRACE(" destroying SHReg IStream (%p)\n",This);
109
110 if (This->hKey)
111 {
112 /* write back data in REG_BINARY */
113 if (This->dwMode == STGM_READWRITE || This->dwMode == STGM_WRITE)
114 {
115 if (This->dwLength)
116 {
117 if (This->bUnicode)
118 RegSetValueExW(This->hKey, This->u.keyNameW, 0, REG_BINARY,
119 (const BYTE *) This->pbBuffer, This->dwLength);
120 else
121 RegSetValueExA(This->hKey, This->u.keyNameA, 0, REG_BINARY,
122 (const BYTE *) This->pbBuffer, This->dwLength);
123 }
124 else
125 {
126 if (This->bUnicode)
127 RegDeleteValueW(This->hKey, This->u.keyNameW);
128 else
129 RegDeleteValueA(This->hKey, This->u.keyNameA);
130 }
131 }
132
133 RegCloseKey(This->hKey);
134 }
135
136 HeapFree(GetProcessHeap(),0,This->u.keyNameA);
137 HeapFree(GetProcessHeap(),0,This->pbBuffer);
139 return 0;
140 }
141
142 return refCount;
143}
144
145/**************************************************************************
146 * IStream_fnRead
147 */
148static HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead)
149{
151 DWORD dwBytesToRead;
152
153 TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
154
155 if (This->dwPos >= This->dwLength)
156 dwBytesToRead = 0;
157 else
158 dwBytesToRead = This->dwLength - This->dwPos;
159
160 dwBytesToRead = (cb > dwBytesToRead) ? dwBytesToRead : cb;
161 if (dwBytesToRead != 0) /* not at end of buffer and we want to read something */
162 {
163 memmove(pv, This->pbBuffer + This->dwPos, dwBytesToRead);
164 This->dwPos += dwBytesToRead; /* adjust pointer */
165 }
166
167 if (pcbRead)
168 *pcbRead = dwBytesToRead;
169
170 return S_OK;
171}
172
173/**************************************************************************
174 * IStream_fnWrite
175 */
176static HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb, ULONG* pcbWritten)
177{
179 DWORD newLen = This->dwPos + cb;
180
181 TRACE("(%p, %p, %ld, %p)\n",This, pv, cb, pcbWritten);
182
183 if (newLen < This->dwPos) /* overflow */
185
186 if (newLen > This->dwLength)
187 {
188 BYTE *newBuf = _recalloc(This->pbBuffer, 1, newLen);
189 if (!newBuf)
191
192 This->dwLength = newLen;
193 This->pbBuffer = newBuf;
194 }
195 memmove(This->pbBuffer + This->dwPos, pv, cb);
196 This->dwPos += cb; /* adjust pointer */
197
198 if (pcbWritten)
199 *pcbWritten = cb;
200
201 return S_OK;
202}
203
204/**************************************************************************
205 * IStream_fnSeek
206 */
207static HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
208{
210 LARGE_INTEGER tmp;
211 TRACE("(%p, %s, %ld %p)\n", This,
212 wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition);
213
214 if (dwOrigin == STREAM_SEEK_SET)
215 tmp = dlibMove;
216 else if (dwOrigin == STREAM_SEEK_CUR)
217 tmp.QuadPart = This->dwPos + dlibMove.QuadPart;
218 else if (dwOrigin == STREAM_SEEK_END)
219 tmp.QuadPart = This->dwLength + dlibMove.QuadPart;
220 else
222
223 if (tmp.QuadPart < 0)
225
226 /* we cut off the high part here */
227 This->dwPos = tmp.u.LowPart;
228
229 if (plibNewPosition)
230 plibNewPosition->QuadPart = This->dwPos;
231 return S_OK;
232}
233
234/**************************************************************************
235 * IStream_fnSetSize
236 */
238{
240 DWORD newLen;
241 LPBYTE newBuf;
242
243 TRACE("(%p, %s)\n", This, wine_dbgstr_longlong(libNewSize.QuadPart));
244
245 /* we cut off the high part here */
246 newLen = libNewSize.u.LowPart;
247 newBuf = _recalloc(This->pbBuffer, 1, newLen);
248 if (!newBuf)
250
251 This->pbBuffer = newBuf;
252 This->dwLength = newLen;
253
254 return S_OK;
255}
256
257/**************************************************************************
258 * IStream_fnCopyTo
259 */
261{
263
264 TRACE("(%p)\n",This);
265 if (pcbRead)
266 pcbRead->QuadPart = 0;
267 if (pcbWritten)
268 pcbWritten->QuadPart = 0;
269
270 /* TODO implement */
271 return E_NOTIMPL;
272}
273
274/**************************************************************************
275 * IStream_fnCommit
276 */
277static HRESULT WINAPI IStream_fnCommit (IStream * iface, DWORD grfCommitFlags)
278{
280
281 TRACE("(%p)\n",This);
282
283 /* commit not supported by this stream */
284 return E_NOTIMPL;
285}
286
287/**************************************************************************
288 * IStream_fnRevert
289 */
291{
293
294 TRACE("(%p)\n",This);
295
296 /* revert not supported by this stream */
297 return E_NOTIMPL;
298}
299
300/**************************************************************************
301 * IStream_fnLockUnlockRegion
302 */
304{
306
307 TRACE("(%p)\n",This);
308
309 /* lock/unlock not supported by this stream */
310 return E_NOTIMPL;
311}
312
313/*************************************************************************
314 * IStream_fnStat
315 */
316static HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG* pstatstg, DWORD grfStatFlag)
317{
319
320 TRACE("(%p, %p, %ld)\n",This,pstatstg,grfStatFlag);
321
322 pstatstg->pwcsName = NULL;
323 pstatstg->type = STGTY_STREAM;
324 pstatstg->cbSize.QuadPart = This->dwLength;
325 pstatstg->mtime.dwHighDateTime = 0;
326 pstatstg->mtime.dwLowDateTime = 0;
327 pstatstg->ctime.dwHighDateTime = 0;
328 pstatstg->ctime.dwLowDateTime = 0;
329 pstatstg->atime.dwHighDateTime = 0;
330 pstatstg->atime.dwLowDateTime = 0;
331 pstatstg->grfMode = This->dwMode;
332 pstatstg->grfLocksSupported = 0;
333 pstatstg->clsid = CLSID_NULL;
334 pstatstg->grfStateBits = 0;
335 pstatstg->reserved = 0;
336
337 return S_OK;
338}
339
340/*************************************************************************
341 * IStream_fnClone
342 */
344{
346
347 TRACE("(%p)\n",This);
348 *ppstm = NULL;
349
350 /* clone not supported by this stream */
351 return E_NOTIMPL;
352}
353
354static const IStreamVtbl rstvt =
355{
370};
371
372/**************************************************************************
373 * IStream_Create
374 *
375 * Internal helper: Create and initialise a new registry stream object.
376 */
378{
379 ISHRegStream* regStream;
380
381 regStream = malloc(sizeof(ISHRegStream));
382
383 if (regStream)
384 {
385 regStream->IStream_iface.lpVtbl = &rstvt;
386 regStream->ref = 1;
387 regStream->hKey = hKey;
388 regStream->pbBuffer = pbBuffer;
389 regStream->dwLength = dwLength;
390 regStream->dwPos = 0;
391 regStream->dwMode = STGM_READWRITE;
392 regStream->u.keyNameA = NULL;
393 regStream->bUnicode = FALSE;
394 }
395 TRACE ("Returning %p\n", regStream);
396 return regStream;
397}
398
399/*************************************************************************
400 * SHCreateStreamWrapper [SHLWAPI.@]
401 *
402 * Create an IStream object on a block of memory.
403 *
404 * PARAMS
405 * lpbData [I] Memory block to create the IStream object on
406 * dwDataLen [I] Length of data block
407 * dwReserved [I] Reserved, Must be 0.
408 * lppStream [O] Destination for IStream object
409 *
410 * RETURNS
411 * Success: S_OK. lppStream contains the new IStream object.
412 * Failure: E_INVALIDARG, if any parameters are invalid,
413 * E_OUTOFMEMORY if memory allocation fails.
414 *
415 * NOTES
416 * The stream assumes ownership of the memory passed to it.
417 */
419 DWORD dwReserved, IStream **lppStream)
420{
421 ISHRegStream *strm;
422
423 if (lppStream)
424 *lppStream = NULL;
425
426 if(dwReserved || !lppStream)
427 return E_INVALIDARG;
428
429 strm = IStream_Create(NULL, lpbData, dwDataLen);
430
431 if(!strm)
432 return E_OUTOFMEMORY;
433
434 IStream_QueryInterface(&strm->IStream_iface, &IID_IStream, (void**)lppStream);
435 IStream_Release(&strm->IStream_iface);
436 return S_OK;
437}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2287
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
#define GetProcessHeap()
Definition: compat.h:736
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define HeapFree(x, y, z)
Definition: compat.h:735
static DWORD DWORD * dwLength
Definition: fusion.c:86
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
_ACRTIMP void *__cdecl _recalloc(void *, size_t, size_t) __WINE_ALLOC_SIZE(2
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define debugstr_guid
Definition: kernel32.h:35
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
#define REG_BINARY
Definition: nt_native.h:1499
#define STGM_READWRITE
Definition: objbase.h:938
#define STGM_WRITE
Definition: objbase.h:937
long LONG
Definition: pedump.c:60
#define CLSID_NULL
Definition: guiddef.h:99
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static const IStreamVtbl rstvt
Definition: regstream.c:354
static HRESULT WINAPI IStream_fnSeek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: regstream.c:207
static HRESULT WINAPI IStream_fnSetSize(IStream *iface, ULARGE_INTEGER libNewSize)
Definition: regstream.c:237
static ISHRegStream * impl_from_IStream(IStream *iface)
Definition: regstream.c:54
HRESULT WINAPI SHCreateStreamWrapper(LPBYTE lpbData, DWORD dwDataLen, DWORD dwReserved, IStream **lppStream)
Definition: regstream.c:418
static HRESULT WINAPI IStream_fnCopyTo(IStream *iface, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
Definition: regstream.c:260
static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj)
Definition: regstream.c:62
static HRESULT WINAPI IStream_fnStat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag)
Definition: regstream.c:316
static HRESULT WINAPI IStream_fnWrite(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: regstream.c:176
static ULONG WINAPI IStream_fnRelease(IStream *iface)
Definition: regstream.c:99
static HRESULT WINAPI IStream_fnRevert(IStream *iface)
Definition: regstream.c:290
static HRESULT WINAPI IStream_fnLockUnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: regstream.c:303
static HRESULT WINAPI IStream_fnCommit(IStream *iface, DWORD grfCommitFlags)
Definition: regstream.c:277
static HRESULT WINAPI IStream_fnRead(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: regstream.c:148
static HRESULT WINAPI IStream_fnClone(IStream *iface, IStream **ppstm)
Definition: regstream.c:343
static ULONG WINAPI IStream_fnAddRef(IStream *iface)
Definition: regstream.c:86
static ISHRegStream * IStream_Create(HKEY hKey, LPBYTE pbBuffer, DWORD dwLength)
Definition: regstream.c:377
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR keyNameW
Definition: regstream.c:49
union ISHRegStream::@598 u
LPSTR keyNameA
Definition: regstream.c:48
LPBYTE pbBuffer
Definition: regstream.c:43
BOOL bUnicode
Definition: regstream.c:51
DWORD dwLength
Definition: regstream.c:44
DWORD dwMode
Definition: regstream.c:46
DWORD dwPos
Definition: regstream.c:45
IStream IStream_iface
Definition: regstream.c:40
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
struct _ULARGE_INTEGER::@4623 u
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2513 u
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
#define STG_E_INVALIDPARAMETER
Definition: winerror.h:3675
#define STG_E_INVALIDFUNCTION
Definition: winerror.h:3659
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:3665
unsigned char BYTE
Definition: xxhash.c:193