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