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