Fix the icon resource ids (most were off by one).
[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 "config.h"
23 #include "wine/port.h"
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include "wine/debug.h"
30 #include "winerror.h"
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winreg.h"
34 #include "wingdi.h"
35 #include "winuser.h"
36
37 #include "shlobj.h"
38 #include "shell32_main.h"
39 #include "shlguid.h"
40 #include "shresdef.h"
41 #include "shlwapi.h"
42 #include "wine/unicode.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(shell);
45
46 #define MAX_EXTENSION_LENGTH 20
47
48 BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, DWORD len, BOOL bPrependDot)
49 {       
50         HKEY    hkey;
51         WCHAR   szTemp[MAX_EXTENSION_LENGTH + 2];
52
53         TRACE("%s %p\n", debugstr_w(szExtension), debugstr_w(szFileType));
54
55     /* added because we do not want to have double dots */
56     if (szExtension[0] == '.')
57         bPrependDot = 0;
58
59         if (bPrependDot)
60           szTemp[0] = '.';
61
62         lstrcpynW(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH);
63
64         if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szTemp, 0, 0x02000000, &hkey))
65         { 
66           return FALSE;
67         }
68
69         if (RegQueryValueW(hkey, NULL, szFileType, &len))
70         { 
71           RegCloseKey(hkey);
72           return FALSE;
73         }
74
75         RegCloseKey(hkey);
76
77         TRACE("--UE;\n} %s\n", debugstr_w(szFileType));
78
79         return TRUE;
80 }
81
82 BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, DWORD len, BOOL bPrependDot)
83 {
84         HKEY    hkey;
85         char    szTemp[MAX_EXTENSION_LENGTH + 2];
86
87         TRACE("%s %p\n", szExtension, szFileType);
88
89     /* added because we do not want to have double dots */
90     if (szExtension[0] == '.')
91         bPrependDot = 0;
92
93         if (bPrependDot)
94           szTemp[0] = '.';
95
96         lstrcpynA(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH);
97
98         if (RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, 0x02000000, &hkey))
99         { 
100           return FALSE;
101         }
102
103         if (RegQueryValueA(hkey, NULL, szFileType, &len))
104         { 
105           RegCloseKey(hkey);
106           return FALSE;
107         }
108
109         RegCloseKey(hkey);
110
111         TRACE("--UE;\n} %s\n", szFileType);
112
113         return TRUE;
114 }
115
116
117 BOOL HCR_GetExecuteCommandW( HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len )
118 {
119         static const WCHAR swShell[] = {'s','h','e','l','l','\\',0};
120         static const WCHAR swCommand[] = {'\\','c','o','m','m','a','n','d',0};
121         BOOL    ret = FALSE;
122
123         TRACE("%p %s %s %p\n", hkeyClass, debugstr_w(szClass), debugstr_w(szVerb), szDest);
124
125         if (szClass)
126             RegOpenKeyExW(HKEY_CLASSES_ROOT, szClass, 0, 0x02000000, &hkeyClass);
127
128         if (hkeyClass)
129         {
130             WCHAR sTemp[MAX_PATH];
131             lstrcpyW(sTemp, swShell);
132             lstrcatW(sTemp, szVerb);
133             lstrcatW(sTemp, swCommand);
134
135             ret = (ERROR_SUCCESS == SHGetValueW(hkeyClass, sTemp, NULL, NULL, szDest, &len));
136
137             if (szClass)
138                RegCloseKey(hkeyClass);
139         }
140
141         TRACE("-- %s\n", debugstr_w(szDest) );
142         return ret;
143 }
144
145 /***************************************************************************************
146 *       HCR_GetDefaultIcon      [internal]
147 *
148 * Gets the icon for a filetype
149 */
150 static BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey)
151 {
152         char    xriid[50];
153     sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
154                  riid->Data1, riid->Data2, riid->Data3,
155                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
156                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
157
158         TRACE("%s\n",xriid );
159
160         return !RegOpenKeyExA(HKEY_CLASSES_ROOT, xriid, 0, KEY_READ, hkey);
161 }
162
163 static BOOL HCR_RegGetDefaultIconW(HKEY hkey, LPWSTR szDest, DWORD len, LPDWORD dwNr)
164 {
165         DWORD dwType;
166         WCHAR sTemp[MAX_PATH];
167         WCHAR sNum[5];
168
169         if (!RegQueryValueExW(hkey, NULL, 0, &dwType, (LPBYTE)szDest, &len))
170         {
171       if (dwType == REG_EXPAND_SZ)
172           {
173             ExpandEnvironmentStringsW(szDest, sTemp, MAX_PATH);
174             lstrcpynW(szDest, sTemp, len);
175           }
176           if (ParseFieldW (szDest, 2, sNum, 5))
177              *dwNr = atoiW(sNum);
178           else
179              *dwNr=0; /* sometimes the icon number is missing */
180           ParseFieldW (szDest, 1, szDest, len);
181           return TRUE;
182         }
183         return FALSE;
184 }
185
186 static BOOL HCR_RegGetDefaultIconA(HKEY hkey, LPSTR szDest, DWORD len, LPDWORD dwNr)
187 {
188         DWORD dwType;
189         char sTemp[MAX_PATH];
190         char  sNum[5];
191
192         if (!RegQueryValueExA(hkey, NULL, 0, &dwType, szDest, &len))
193         {
194       if (dwType == REG_EXPAND_SZ)
195           {
196             ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH);
197             lstrcpynA(szDest, sTemp, len);
198           }
199           if (ParseFieldA (szDest, 2, sNum, 5))
200              *dwNr=atoi(sNum);
201           else
202              *dwNr=0; /* sometimes the icon number is missing */
203           ParseFieldA (szDest, 1, szDest, len);
204           return TRUE;
205         }
206         return FALSE;
207 }
208
209 BOOL HCR_GetDefaultIconW(LPCWSTR szClass, LPWSTR szDest, DWORD len, LPDWORD dwNr)
210 {
211         static const WCHAR swDefaultIcon[] = {'\\','D','e','f','a','u','l','t','I','c','o','n',0};
212         HKEY    hkey;
213         WCHAR   sTemp[MAX_PATH];
214         BOOL    ret = FALSE;
215
216         TRACE("%s\n",debugstr_w(szClass) );
217
218         lstrcpynW(sTemp, szClass, MAX_PATH);
219         lstrcatW(sTemp, swDefaultIcon);
220
221         if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
222         {
223           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
224           RegCloseKey(hkey);
225         }
226
227         if(ret)
228             TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
229         else
230             TRACE("-- not found\n");
231
232         return ret;
233 }
234
235 BOOL HCR_GetDefaultIconA(LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr)
236 {
237         HKEY    hkey;
238         char    sTemp[MAX_PATH];
239         BOOL    ret = FALSE;
240
241         TRACE("%s\n",szClass );
242
243         sprintf(sTemp, "%s\\DefaultIcon",szClass);
244
245         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
246         {
247           ret = HCR_RegGetDefaultIconA(hkey, szDest, len, dwNr);
248           RegCloseKey(hkey);
249         }
250         TRACE("-- %s %li\n", szDest, *dwNr );
251         return ret;
252 }
253
254 BOOL HCR_GetDefaultIconFromGUIDW(REFIID riid, LPWSTR szDest, DWORD len, LPDWORD dwNr)
255 {
256         HKEY    hkey;
257         BOOL    ret = FALSE;
258
259         if (HCR_RegOpenClassIDKey(riid, &hkey))
260         {
261           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
262           RegCloseKey(hkey);
263         }
264         TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
265         return ret;
266 }
267
268 /***************************************************************************************
269 *       HCR_GetClassName        [internal]
270 *
271 * Gets the name of a registered class
272 */
273 static const WCHAR swEmpty[] = {0};
274
275 BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len)
276 {       
277         HKEY    hkey;
278         BOOL ret = FALSE;
279         DWORD buflen = len;
280
281         szDest[0] = 0;
282         if (HCR_RegOpenClassIDKey(riid, &hkey))
283         {
284           if (!RegQueryValueExW(hkey, swEmpty, 0, NULL, (LPBYTE)szDest, &len))
285           {
286             ret = TRUE;
287           }
288           RegCloseKey(hkey);
289         }
290
291         if (!ret || !szDest[0])
292         {
293           if(IsEqualIID(riid, &CLSID_ShellDesktop))
294           {
295             if (LoadStringW(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
296               ret = TRUE;
297           }
298           else if (IsEqualIID(riid, &CLSID_MyComputer))
299           {
300             if(LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
301               ret = TRUE;
302           }
303         }
304         TRACE("-- %s\n", debugstr_w(szDest));
305         return ret;
306 }
307
308 BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len)
309 {       HKEY    hkey;
310         BOOL ret = FALSE;
311         DWORD buflen = len;
312
313         szDest[0] = 0;
314         if (HCR_RegOpenClassIDKey(riid, &hkey))
315         {
316           if (!RegQueryValueExA(hkey,"",0,NULL,szDest,&len))
317           {
318             ret = TRUE;
319           }
320           RegCloseKey(hkey);
321         }
322
323         if (!ret || !szDest[0])
324         {
325           if(IsEqualIID(riid, &CLSID_ShellDesktop))
326           {
327             if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
328               ret = TRUE;
329           }
330           else if (IsEqualIID(riid, &CLSID_MyComputer))
331           {
332             if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
333               ret = TRUE;
334           }
335         }
336
337         TRACE("-- %s\n", szDest);
338
339         return ret;
340 }
341
342 /***************************************************************************************
343 *       HCR_GetFolderAttributes [internal]
344 *
345 * gets the folder attributes of a class
346 *
347 * FIXME
348 *       verify the defaultvalue for *szDest
349 */
350 BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
351 {       HKEY    hkey;
352         char    xriid[60];
353         DWORD   attributes;
354         DWORD   len = 4;
355
356         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
357                  riid->Data1, riid->Data2, riid->Data3,
358                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
359                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
360         TRACE("%s\n",xriid );
361
362         if (!szDest) return FALSE;
363         *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
364
365         strcat (xriid, "\\ShellFolder");
366
367         if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
368         {
369           return FALSE;
370         }
371
372         if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len))
373         {
374           RegCloseKey(hkey);
375           return FALSE;
376         }
377
378         RegCloseKey(hkey);
379
380         TRACE("-- 0x%08lx\n", attributes);
381
382         *szDest = attributes;
383
384         return TRUE;
385 }