Fixed the behavior for SHGetFileInfo when the SHGFI_USEFILEATTRIBUTES
[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)) *dwNr=atoi(sNum);
108             ParseFieldA (szDest, 1, szDest, len);
109             ret = TRUE;
110           }     
111           RegCloseKey(hkey);
112         }
113         TRACE("-- %s %li\n", szDest, *dwNr );
114         return ret;
115 }
116
117 /***************************************************************************************
118 *       HCR_GetClassName        [internal]
119 *
120 * Gets the name of a registred class
121 */
122 BOOL HCR_GetClassName (REFIID riid, LPSTR szDest, DWORD len)
123 {       HKEY    hkey;
124         char    xriid[50];
125         BOOL ret = FALSE;
126         DWORD buflen = len;
127
128         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
129                  riid->Data1, riid->Data2, riid->Data3,
130                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
131                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
132
133         TRACE("%s\n",xriid );
134
135         szDest[0] = 0;
136         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
137         {
138           if (!RegQueryValueExA(hkey,"",0,NULL,szDest,&len))
139           {
140             ret = TRUE;
141           }
142           RegCloseKey(hkey);
143         }
144
145         if (!ret || !szDest[0])
146         { 
147           if(IsEqualIID(riid, &CLSID_ShellDesktop))
148           {
149             if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
150               ret = TRUE;
151           }
152           else if (IsEqualIID(riid, &CLSID_MyComputer))
153           {
154             if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
155               ret = TRUE;
156           }     
157         }
158
159         TRACE("-- %s\n", szDest);
160
161         return ret;
162 }
163
164 /***************************************************************************************
165 *       HCR_GetFolderAttributes [internal]
166 *
167 * gets the folder attributes of a class
168 *
169 * FIXME
170 *       verify the defaultvalue for *szDest
171 */
172 BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
173 {       HKEY    hkey;
174         char    xriid[60];
175         DWORD   attributes;
176         DWORD   len = 4;
177
178         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
179                  riid->Data1, riid->Data2, riid->Data3,
180                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
181                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
182         TRACE("%s\n",xriid );
183
184         if (!szDest) return FALSE;
185         *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
186         
187         strcat (xriid, "\\ShellFolder");
188
189         if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
190         {
191           return FALSE;
192         }
193
194         if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len))
195         {
196           RegCloseKey(hkey);
197           return FALSE;
198         }
199
200         RegCloseKey(hkey);
201
202         TRACE("-- 0x%08lx\n", attributes);
203
204         *szDest = attributes;
205
206         return TRUE;
207 }
208
209 typedef struct 
210 {       ICOM_VFIELD(IQueryAssociations);
211         DWORD   ref;
212 } IQueryAssociationsImpl;
213
214 static struct ICOM_VTABLE(IQueryAssociations) qavt;
215
216 /**************************************************************************
217 *  IQueryAssociations_Constructor
218 */
219 IQueryAssociations* IQueryAssociations_Constructor(void)
220 {
221         IQueryAssociationsImpl* ei;
222
223         ei=(IQueryAssociationsImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IQueryAssociationsImpl));
224         ei->ref=1;
225         ICOM_VTBL(ei) = &qavt;
226
227         TRACE("(%p)\n",ei);
228         shell32_ObjCount++;
229         return (IQueryAssociations *)ei;
230 }
231 /**************************************************************************
232  *  IQueryAssociations_QueryInterface
233  */
234 static HRESULT WINAPI IQueryAssociations_fnQueryInterface(
235         IQueryAssociations * iface,
236         REFIID riid,
237         LPVOID *ppvObj)
238 {
239         ICOM_THIS(IQueryAssociationsImpl,iface);
240
241          TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
242
243         *ppvObj = NULL;
244
245         if(IsEqualIID(riid, &IID_IUnknown))             /*IUnknown*/
246         {
247           *ppvObj = This; 
248         }
249         else if(IsEqualIID(riid, &IID_IQueryAssociations))      /*IExtractIcon*/
250         {
251           *ppvObj = (IQueryAssociations*)This;
252         }
253
254         if(*ppvObj)
255         {
256           IQueryAssociations_AddRef((IQueryAssociations*) *ppvObj);     
257           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
258           return S_OK;
259         }
260         TRACE("-- Interface: E_NOINTERFACE\n");
261         return E_NOINTERFACE;
262 }
263
264 /**************************************************************************
265 *  IQueryAssociations_AddRef
266 */
267 static ULONG WINAPI IQueryAssociations_fnAddRef(IQueryAssociations * iface)
268 {
269         ICOM_THIS(IQueryAssociationsImpl,iface);
270
271         TRACE("(%p)->(count=%lu)\n",This, This->ref );
272
273         shell32_ObjCount++;
274
275         return ++(This->ref);
276 }
277 /**************************************************************************
278 *  IQueryAssociations_Release
279 */
280 static ULONG WINAPI IQueryAssociations_fnRelease(IQueryAssociations * iface)
281 {
282         ICOM_THIS(IQueryAssociationsImpl,iface);
283
284         TRACE("(%p)->()\n",This);
285
286         shell32_ObjCount--;
287
288         if (!--(This->ref)) 
289         {
290           TRACE(" destroying IExtractIcon(%p)\n",This);
291           HeapFree(GetProcessHeap(),0,This);
292           return 0;
293         }
294         return This->ref;
295 }
296
297 static HRESULT WINAPI IQueryAssociations_fnInit(
298         IQueryAssociations * iface,
299         ASSOCF flags,
300         LPCWSTR pszAssoc,
301         HKEY hkProgid,
302         HWND hwnd)
303 {
304         return E_NOTIMPL;
305 }
306
307 static HRESULT WINAPI IQueryAssociations_fnGetString(
308         IQueryAssociations * iface,
309         ASSOCF flags,
310         ASSOCSTR str,
311         LPCWSTR pszExtra,
312         LPWSTR pszOut,
313         DWORD *pcchOut)
314 {
315         return E_NOTIMPL;
316 }
317
318 static HRESULT WINAPI IQueryAssociations_fnGetKey(
319         IQueryAssociations * iface,
320         ASSOCF flags,
321         ASSOCKEY key,
322         LPCWSTR pszExtra,
323         HKEY *phkeyOut)
324 {
325         return E_NOTIMPL;
326 }
327
328 static HRESULT WINAPI IQueryAssociations_fnGetData(
329         IQueryAssociations * iface,
330         ASSOCF flags,
331         ASSOCDATA data,
332         LPCWSTR pszExtra,
333         LPVOID pvOut,
334         DWORD *pcbOut)
335 {
336         return E_NOTIMPL;
337 }
338 static HRESULT WINAPI IQueryAssociations_fnGetEnum(
339         IQueryAssociations * iface,
340         ASSOCF flags,
341         ASSOCENUM assocenum,
342         LPCWSTR pszExtra,
343         REFIID riid,
344         LPVOID *ppvOut)
345 {
346         return E_NOTIMPL;
347 }
348
349 static struct ICOM_VTABLE(IQueryAssociations) qavt = 
350 {       
351         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
352         IQueryAssociations_fnQueryInterface,
353         IQueryAssociations_fnAddRef,
354         IQueryAssociations_fnRelease,
355         IQueryAssociations_fnInit,
356         IQueryAssociations_fnGetString, 
357         IQueryAssociations_fnGetKey,
358         IQueryAssociations_fnGetData,
359         IQueryAssociations_fnGetEnum
360 };