PathFindNextComponent: return pointer to NULL and not NULL.
[wine] / dlls / shell32 / regstream.c
1 /*
2  *      SHRegOpenStream
3  */
4 #include <string.h>
5
6 #include "wine/obj_storage.h"
7
8 #include "debugtools.h"
9 #include "heap.h"
10 #include "winerror.h"
11 #include "winreg.h"
12
13 #include "shell32_main.h"
14
15 DEFAULT_DEBUG_CHANNEL(shell)
16
17 typedef struct 
18 {       ICOM_VFIELD(IStream);
19         DWORD           ref;
20         HKEY            hKey;
21         LPBYTE          pbBuffer;
22         DWORD           dwLength;
23         DWORD           dwPos;
24 } ISHRegStream;
25
26 static struct ICOM_VTABLE(IStream) rstvt;
27
28 /**************************************************************************
29 *   IStream_ConstructorA        [internal]
30 */
31 IStream *IStream_ConstructorA(HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, DWORD grfMode)
32 {
33         ISHRegStream*   rstr;
34         DWORD           dwType;
35         
36         rstr = (ISHRegStream*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ISHRegStream));
37
38         ICOM_VTBL(rstr)=&rstvt;
39         rstr->ref = 1;
40
41         if (!(RegOpenKeyExA (hKey, pszSubKey, 0, KEY_READ, &(rstr->hKey))))
42         {
43           if (!(RegQueryValueExA(rstr->hKey, pszValue,0,0,0,&(rstr->dwLength))))
44           { 
45             /* read the binary data into the buffer */
46             if((rstr->pbBuffer = HeapAlloc(GetProcessHeap(),0,rstr->dwLength)))
47             {
48               if (!(RegQueryValueExA(rstr->hKey, pszValue,0,&dwType,rstr->pbBuffer,&(rstr->dwLength))))
49               {
50                 if (dwType == REG_BINARY )
51                 {
52                   shell32_ObjCount++;
53                   TRACE ("%p\n", rstr);
54                   return (IStream*)rstr;
55                 }
56               }
57               HeapFree (GetProcessHeap(),0,rstr->pbBuffer);
58             }
59           }
60           RegCloseKey(rstr->hKey);
61         }
62         HeapFree (GetProcessHeap(),0,rstr);
63         return NULL;
64 }
65
66 /**************************************************************************
67 *   IStream_ConstructorW        [internal]
68 */
69 IStream *IStream_ConstructorW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD grfMode)
70 {
71         ISHRegStream*   rstr;
72         DWORD           dwType;
73         
74         rstr = (ISHRegStream*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ISHRegStream));
75
76         ICOM_VTBL(rstr)=&rstvt;
77         rstr->ref = 1;
78
79         if (!(RegOpenKeyExW (hKey, pszSubKey, 0, KEY_READ, &(rstr->hKey))))
80         {
81           if (!(RegQueryValueExW(rstr->hKey, pszValue,0,0,0,&(rstr->dwLength))))
82           { 
83             /* read the binary data into the buffer */
84             if((rstr->pbBuffer = HeapAlloc(GetProcessHeap(),0,rstr->dwLength)))
85             {
86               if (!(RegQueryValueExW(rstr->hKey, pszValue,0,&dwType,rstr->pbBuffer,&(rstr->dwLength))))
87               {
88                 if (dwType == REG_BINARY )
89                 {
90                   shell32_ObjCount++;
91                   TRACE ("%p\n", rstr);
92                   return (IStream*)rstr;
93                 }
94               }
95               HeapFree (GetProcessHeap(),0,rstr->pbBuffer);
96             }
97           }
98           RegCloseKey(rstr->hKey);
99         }
100         HeapFree (GetProcessHeap(),0,rstr);
101         return NULL;
102 }
103
104 /**************************************************************************
105 *  IStream_fnQueryInterface
106 */
107 static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj)
108 {
109         ICOM_THIS(ISHRegStream, iface);
110
111         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
112
113         *ppvObj = NULL;
114
115         if(IsEqualIID(riid, &IID_IUnknown))     /*IUnknown*/
116         { *ppvObj = This; 
117         }
118         else if(IsEqualIID(riid, &IID_IStream)) /*IStream*/
119         { *ppvObj = This;
120         }   
121
122         if(*ppvObj)
123         { 
124           IStream_AddRef((IStream*)*ppvObj);      
125           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
126           return S_OK;
127         }
128         TRACE("-- Interface: E_NOINTERFACE\n");
129         return E_NOINTERFACE;
130 }
131
132 /**************************************************************************
133 *  IStream_fnAddRef
134 */
135 static ULONG WINAPI IStream_fnAddRef(IStream *iface)
136 {
137         ICOM_THIS(ISHRegStream, iface);
138
139         TRACE("(%p)->(count=%lu)\n",This, This->ref);
140
141         shell32_ObjCount++;
142         return ++(This->ref);
143 }
144
145 /**************************************************************************
146 *  IStream_fnRelease
147 */
148 static ULONG WINAPI IStream_fnRelease(IStream *iface)
149 {
150         ICOM_THIS(ISHRegStream, iface);
151
152         TRACE("(%p)->()\n",This);
153
154         shell32_ObjCount--;
155
156         if (!--(This->ref)) 
157         { TRACE(" destroying SHReg IStream (%p)\n",This);
158
159           if (This->pbBuffer)
160             HeapFree(GetProcessHeap(),0,This->pbBuffer);
161
162           if (This->hKey)
163             RegCloseKey(This->hKey);
164
165           HeapFree(GetProcessHeap(),0,This);
166           return 0;
167         }
168         return This->ref;
169 }
170
171 HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead)
172 {
173         ICOM_THIS(ISHRegStream, iface);
174
175         DWORD dwBytesToRead, dwBytesLeft;
176         
177         TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
178         
179         if ( !pv )
180           return STG_E_INVALIDPOINTER;
181           
182         dwBytesLeft = This->dwLength - This->dwPos;
183
184         if ( 0 >= dwBytesLeft )                                         /* end of buffer */
185           return S_FALSE;
186         
187         dwBytesToRead = ( cb > dwBytesLeft) ? dwBytesLeft : cb;
188
189         memmove ( pv, (This->pbBuffer) + (This->dwPos), dwBytesToRead);
190         
191         This->dwPos += dwBytesToRead;                                   /* adjust pointer */
192
193         if (pcbRead)
194           *pcbRead = dwBytesToRead;
195
196         return S_OK;
197 }
198 HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb, ULONG* pcbWritten)
199 {
200         ICOM_THIS(ISHRegStream, iface);
201
202         TRACE("(%p)\n",This);
203
204         return E_NOTIMPL;
205 }
206 HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
207 {
208         ICOM_THIS(ISHRegStream, iface);
209
210         TRACE("(%p)\n",This);
211
212         return E_NOTIMPL;
213 }
214 HRESULT WINAPI IStream_fnSetSize (IStream * iface, ULARGE_INTEGER libNewSize)
215 {
216         ICOM_THIS(ISHRegStream, iface);
217
218         TRACE("(%p)\n",This);
219
220         return E_NOTIMPL;
221 }
222 HRESULT WINAPI IStream_fnCopyTo (IStream * iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
223 {
224         ICOM_THIS(ISHRegStream, iface);
225
226         TRACE("(%p)\n",This);
227
228         return E_NOTIMPL;
229 }
230 HRESULT WINAPI IStream_fnCommit (IStream * iface, DWORD grfCommitFlags)
231 {
232         ICOM_THIS(ISHRegStream, iface);
233
234         TRACE("(%p)\n",This);
235
236         return E_NOTIMPL;
237 }
238 HRESULT WINAPI IStream_fnRevert (IStream * iface)
239 {
240         ICOM_THIS(ISHRegStream, iface);
241
242         TRACE("(%p)\n",This);
243
244         return E_NOTIMPL;
245 }
246 HRESULT WINAPI IStream_fnLockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
247 {
248         ICOM_THIS(ISHRegStream, iface);
249
250         TRACE("(%p)\n",This);
251
252         return E_NOTIMPL;
253 }
254 HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
255 {
256         ICOM_THIS(ISHRegStream, iface);
257
258         TRACE("(%p)\n",This);
259
260         return E_NOTIMPL;
261 }
262 HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG*   pstatstg, DWORD grfStatFlag)
263 {
264         ICOM_THIS(ISHRegStream, iface);
265
266         TRACE("(%p)\n",This);
267
268         return E_NOTIMPL;
269 }
270 HRESULT WINAPI IStream_fnClone (IStream * iface, IStream** ppstm)
271 {
272         ICOM_THIS(ISHRegStream, iface);
273
274         TRACE("(%p)\n",This);
275
276         return E_NOTIMPL;
277 }
278
279 static struct ICOM_VTABLE(IStream) rstvt = 
280 {       
281         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
282         IStream_fnQueryInterface,
283         IStream_fnAddRef,
284         IStream_fnRelease,
285         IStream_fnRead,
286         IStream_fnWrite,
287         IStream_fnSeek,
288         IStream_fnSetSize,
289         IStream_fnCopyTo,
290         IStream_fnCommit,
291         IStream_fnRevert,
292         IStream_fnLockRegion,
293         IStream_fnUnlockRegion,
294         IStream_fnStat,
295         IStream_fnClone
296         
297 };
298
299 /*************************************************************************
300  * SHOpenRegStreamA                             [SHLWAPI.@][SHELL32.85]
301  */
302 IStream * WINAPI SHOpenRegStreamA(
303         HKEY hkey,
304         LPCSTR pszSubkey,
305         LPCSTR pszValue,
306         DWORD grfMode)
307 {
308         TRACE("(0x%08x,%s,%s,0x%08lx)\n",
309         hkey, pszSubkey, pszValue, grfMode);
310
311         return IStream_ConstructorA(hkey, pszSubkey, pszValue, grfMode);
312 }
313
314 /*************************************************************************
315  * SHOpenRegStreamW                             [SHLWAPI.@]
316  */
317 IStream * WINAPI SHOpenRegStreamW(
318         HKEY hkey,
319         LPCWSTR pszSubkey,
320         LPCWSTR pszValue,
321         DWORD grfMode)
322 {
323         TRACE("(0x%08x,%s,%s,0x%08lx)\n",
324         hkey, debugstr_w(pszSubkey), debugstr_w(pszValue), grfMode);
325
326         return IStream_ConstructorW(hkey, pszSubkey, pszValue, grfMode);
327 }