Fixed wrong cast; MSDN says lpDropFileStruct->pFiles is offset in
[wine] / dlls / shell32 / classes.c
1 /*
2  *      file type mapping
3  *      (HKEY_CLASSES_ROOT - Stuff)
4  *
5  * Copyright 1998, 1999, 2000 Juergen Schmied
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include "wine/debug.h"
26 #include "winerror.h"
27 #include "winreg.h"
28
29 #include "shlobj.h"
30 #include "shell32_main.h"
31 #include "shlguid.h"
32 #include "shresdef.h"
33 #include "wine/obj_queryassociations.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(shell);
36
37 #define MAX_EXTENSION_LENGTH 20
38
39 BOOL HCR_MapTypeToValue ( LPCSTR szExtension, LPSTR szFileType, DWORD len, BOOL bPrependDot)
40 {       HKEY    hkey;
41         char    szTemp[MAX_EXTENSION_LENGTH + 2];
42
43         TRACE("%s %p\n",szExtension, szFileType );
44
45     /* added because we do not want to have double dots */
46     if (szExtension[0]=='.')
47         bPrependDot=0;
48
49         if (bPrependDot)
50           strcpy(szTemp, ".");
51
52         lstrcpynA(szTemp+((bPrependDot)?1:0), szExtension, MAX_EXTENSION_LENGTH);
53
54         if (RegOpenKeyExA(HKEY_CLASSES_ROOT,szTemp,0,0x02000000,&hkey))
55         { return FALSE;
56         }
57
58         if (RegQueryValueA(hkey,NULL,szFileType,&len))
59         { RegCloseKey(hkey);
60           return FALSE;
61         }
62
63         RegCloseKey(hkey);
64
65         TRACE("-- %s\n", szFileType );
66
67         return TRUE;
68 }
69 BOOL HCR_GetExecuteCommand ( LPCSTR szClass, LPCSTR szVerb, LPSTR szDest, DWORD len )
70 {
71         HKEY    hkey;
72         char    sTemp[MAX_PATH];
73         DWORD   dwType;
74         BOOL    ret = FALSE;
75
76         TRACE("%s %s\n",szClass, szVerb );
77
78         sprintf(sTemp, "%s\\shell\\%s\\command",szClass, szVerb);
79
80         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT,sTemp,0,0x02000000,&hkey))
81         {
82           if (!RegQueryValueExA(hkey, NULL, 0, &dwType, szDest, &len))
83           {
84             if (dwType == REG_EXPAND_SZ)
85             {
86               ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH);
87               strcpy(szDest, sTemp);
88             }
89             ret = TRUE;
90           }
91           RegCloseKey(hkey);
92         }
93         TRACE("-- %s\n", szDest );
94         return ret;
95 }
96 /***************************************************************************************
97 *       HCR_GetDefaultIcon      [internal]
98 *
99 * Gets the icon for a filetype
100 */
101 BOOL HCR_GetDefaultIcon (LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr)
102 {
103         HKEY    hkey;
104         char    sTemp[MAX_PATH];
105         char    sNum[5];
106         DWORD   dwType;
107         BOOL    ret = FALSE;
108
109         TRACE("%s\n",szClass );
110
111         sprintf(sTemp, "%s\\DefaultIcon",szClass);
112
113         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT,sTemp,0,0x02000000,&hkey))
114         {
115           if (!RegQueryValueExA(hkey, NULL, 0, &dwType, szDest, &len))
116           {
117             if (dwType == REG_EXPAND_SZ)
118             {
119               ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH);
120               strcpy(szDest, sTemp);
121             }
122             if (ParseFieldA (szDest, 2, sNum, 5))
123                *dwNr=atoi(sNum);
124             else
125                *dwNr=0; /* sometimes the icon number is missing */
126             ParseFieldA (szDest, 1, szDest, len);
127             ret = TRUE;
128           }
129           RegCloseKey(hkey);
130         }
131         TRACE("-- %s %li\n", szDest, *dwNr );
132         return ret;
133 }
134
135 /***************************************************************************************
136 *       HCR_GetClassName        [internal]
137 *
138 * Gets the name of a registred class
139 */
140 BOOL HCR_GetClassName (REFIID riid, LPSTR szDest, DWORD len)
141 {       HKEY    hkey;
142         char    xriid[50];
143         BOOL ret = FALSE;
144         DWORD buflen = len;
145
146         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
147                  riid->Data1, riid->Data2, riid->Data3,
148                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
149                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
150
151         TRACE("%s\n",xriid );
152
153         szDest[0] = 0;
154         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
155         {
156           if (!RegQueryValueExA(hkey,"",0,NULL,szDest,&len))
157           {
158             ret = TRUE;
159           }
160           RegCloseKey(hkey);
161         }
162
163         if (!ret || !szDest[0])
164         {
165           if(IsEqualIID(riid, &CLSID_ShellDesktop))
166           {
167             if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
168               ret = TRUE;
169           }
170           else if (IsEqualIID(riid, &CLSID_MyComputer))
171           {
172             if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
173               ret = TRUE;
174           }
175         }
176
177         TRACE("-- %s\n", szDest);
178
179         return ret;
180 }
181
182 /***************************************************************************************
183 *       HCR_GetFolderAttributes [internal]
184 *
185 * gets the folder attributes of a class
186 *
187 * FIXME
188 *       verify the defaultvalue for *szDest
189 */
190 BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
191 {       HKEY    hkey;
192         char    xriid[60];
193         DWORD   attributes;
194         DWORD   len = 4;
195
196         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
197                  riid->Data1, riid->Data2, riid->Data3,
198                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
199                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
200         TRACE("%s\n",xriid );
201
202         if (!szDest) return FALSE;
203         *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
204
205         strcat (xriid, "\\ShellFolder");
206
207         if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
208         {
209           return FALSE;
210         }
211
212         if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len))
213         {
214           RegCloseKey(hkey);
215           return FALSE;
216         }
217
218         RegCloseKey(hkey);
219
220         TRACE("-- 0x%08lx\n", attributes);
221
222         *szDest = attributes;
223
224         return TRUE;
225 }
226
227 typedef struct
228 {       ICOM_VFIELD(IQueryAssociations);
229         DWORD   ref;
230 } IQueryAssociationsImpl;
231
232 static struct ICOM_VTABLE(IQueryAssociations) qavt;
233
234 /**************************************************************************
235 *  IQueryAssociations_Constructor
236 */
237 IQueryAssociations* IQueryAssociations_Constructor(void)
238 {
239         IQueryAssociationsImpl* ei;
240
241         ei=(IQueryAssociationsImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IQueryAssociationsImpl));
242         ei->ref=1;
243         ICOM_VTBL(ei) = &qavt;
244
245         TRACE("(%p)\n",ei);
246         shell32_ObjCount++;
247         return (IQueryAssociations *)ei;
248 }
249 /**************************************************************************
250  *  IQueryAssociations_QueryInterface
251  */
252 static HRESULT WINAPI IQueryAssociations_fnQueryInterface(
253         IQueryAssociations * iface,
254         REFIID riid,
255         LPVOID *ppvObj)
256 {
257         ICOM_THIS(IQueryAssociationsImpl,iface);
258
259          TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
260
261         *ppvObj = NULL;
262
263         if(IsEqualIID(riid, &IID_IUnknown))             /*IUnknown*/
264         {
265           *ppvObj = This;
266         }
267         else if(IsEqualIID(riid, &IID_IQueryAssociations))      /*IExtractIcon*/
268         {
269           *ppvObj = (IQueryAssociations*)This;
270         }
271
272         if(*ppvObj)
273         {
274           IQueryAssociations_AddRef((IQueryAssociations*) *ppvObj);
275           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
276           return S_OK;
277         }
278         TRACE("-- Interface: E_NOINTERFACE\n");
279         return E_NOINTERFACE;
280 }
281
282 /**************************************************************************
283 *  IQueryAssociations_AddRef
284 */
285 static ULONG WINAPI IQueryAssociations_fnAddRef(IQueryAssociations * iface)
286 {
287         ICOM_THIS(IQueryAssociationsImpl,iface);
288
289         TRACE("(%p)->(count=%lu)\n",This, This->ref );
290
291         shell32_ObjCount++;
292
293         return ++(This->ref);
294 }
295 /**************************************************************************
296 *  IQueryAssociations_Release
297 */
298 static ULONG WINAPI IQueryAssociations_fnRelease(IQueryAssociations * iface)
299 {
300         ICOM_THIS(IQueryAssociationsImpl,iface);
301
302         TRACE("(%p)->()\n",This);
303
304         shell32_ObjCount--;
305
306         if (!--(This->ref))
307         {
308           TRACE(" destroying IExtractIcon(%p)\n",This);
309           HeapFree(GetProcessHeap(),0,This);
310           return 0;
311         }
312         return This->ref;
313 }
314
315 static HRESULT WINAPI IQueryAssociations_fnInit(
316         IQueryAssociations * iface,
317         ASSOCF flags,
318         LPCWSTR pszAssoc,
319         HKEY hkProgid,
320         HWND hwnd)
321 {
322         return E_NOTIMPL;
323 }
324
325 static HRESULT WINAPI IQueryAssociations_fnGetString(
326         IQueryAssociations * iface,
327         ASSOCF flags,
328         ASSOCSTR str,
329         LPCWSTR pszExtra,
330         LPWSTR pszOut,
331         DWORD *pcchOut)
332 {
333         return E_NOTIMPL;
334 }
335
336 static HRESULT WINAPI IQueryAssociations_fnGetKey(
337         IQueryAssociations * iface,
338         ASSOCF flags,
339         ASSOCKEY key,
340         LPCWSTR pszExtra,
341         HKEY *phkeyOut)
342 {
343         return E_NOTIMPL;
344 }
345
346 static HRESULT WINAPI IQueryAssociations_fnGetData(
347         IQueryAssociations * iface,
348         ASSOCF flags,
349         ASSOCDATA data,
350         LPCWSTR pszExtra,
351         LPVOID pvOut,
352         DWORD *pcbOut)
353 {
354         return E_NOTIMPL;
355 }
356 static HRESULT WINAPI IQueryAssociations_fnGetEnum(
357         IQueryAssociations * iface,
358         ASSOCF flags,
359         ASSOCENUM assocenum,
360         LPCWSTR pszExtra,
361         REFIID riid,
362         LPVOID *ppvOut)
363 {
364         return E_NOTIMPL;
365 }
366
367 static struct ICOM_VTABLE(IQueryAssociations) qavt =
368 {
369         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
370         IQueryAssociations_fnQueryInterface,
371         IQueryAssociations_fnAddRef,
372         IQueryAssociations_fnRelease,
373         IQueryAssociations_fnInit,
374         IQueryAssociations_fnGetString,
375         IQueryAssociations_fnGetKey,
376         IQueryAssociations_fnGetData,
377         IQueryAssociations_fnGetEnum
378 };