Don't prepend '\\' to the subkey name.
[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         TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
227         return ret;
228 }
229
230 BOOL HCR_GetDefaultIconA(LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr)
231 {
232         HKEY    hkey;
233         char    sTemp[MAX_PATH];
234         BOOL    ret = FALSE;
235
236         TRACE("%s\n",szClass );
237
238         sprintf(sTemp, "%s\\DefaultIcon",szClass);
239
240         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
241         {
242           ret = HCR_RegGetDefaultIconA(hkey, szDest, len, dwNr);
243           RegCloseKey(hkey);
244         }
245         TRACE("-- %s %li\n", szDest, *dwNr );
246         return ret;
247 }
248
249 BOOL HCR_GetDefaultIconFromGUIDW(REFIID riid, LPWSTR szDest, DWORD len, LPDWORD dwNr)
250 {
251         HKEY    hkey;
252         BOOL    ret = FALSE;
253
254         if (HCR_RegOpenClassIDKey(riid, &hkey))
255         {
256           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
257           RegCloseKey(hkey);
258         }
259         TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
260         return ret;
261 }
262
263 /***************************************************************************************
264 *       HCR_GetClassName        [internal]
265 *
266 * Gets the name of a registered class
267 */
268 static const WCHAR swEmpty[] = {0};
269
270 BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len)
271 {       
272         HKEY    hkey;
273         BOOL ret = FALSE;
274         DWORD buflen = len;
275
276         szDest[0] = 0;
277         if (HCR_RegOpenClassIDKey(riid, &hkey))
278         {
279           if (!RegQueryValueExW(hkey, swEmpty, 0, NULL, (LPBYTE)szDest, &len))
280           {
281             ret = TRUE;
282           }
283           RegCloseKey(hkey);
284         }
285
286         if (!ret || !szDest[0])
287         {
288           if(IsEqualIID(riid, &CLSID_ShellDesktop))
289           {
290             if (LoadStringW(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
291               ret = TRUE;
292           }
293           else if (IsEqualIID(riid, &CLSID_MyComputer))
294           {
295             if(LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
296               ret = TRUE;
297           }
298         }
299         TRACE("-- %s\n", debugstr_w(szDest));
300         return ret;
301 }
302
303 BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len)
304 {       HKEY    hkey;
305         BOOL ret = FALSE;
306         DWORD buflen = len;
307
308         szDest[0] = 0;
309         if (HCR_RegOpenClassIDKey(riid, &hkey))
310         {
311           if (!RegQueryValueExA(hkey,"",0,NULL,szDest,&len))
312           {
313             ret = TRUE;
314           }
315           RegCloseKey(hkey);
316         }
317
318         if (!ret || !szDest[0])
319         {
320           if(IsEqualIID(riid, &CLSID_ShellDesktop))
321           {
322             if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
323               ret = TRUE;
324           }
325           else if (IsEqualIID(riid, &CLSID_MyComputer))
326           {
327             if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
328               ret = TRUE;
329           }
330         }
331
332         TRACE("-- %s\n", szDest);
333
334         return ret;
335 }
336
337 /***************************************************************************************
338 *       HCR_GetFolderAttributes [internal]
339 *
340 * gets the folder attributes of a class
341 *
342 * FIXME
343 *       verify the defaultvalue for *szDest
344 */
345 BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
346 {       HKEY    hkey;
347         char    xriid[60];
348         DWORD   attributes;
349         DWORD   len = 4;
350
351         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
352                  riid->Data1, riid->Data2, riid->Data3,
353                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
354                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
355         TRACE("%s\n",xriid );
356
357         if (!szDest) return FALSE;
358         *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
359
360         strcat (xriid, "\\ShellFolder");
361
362         if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
363         {
364           return FALSE;
365         }
366
367         if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len))
368         {
369           RegCloseKey(hkey);
370           return FALSE;
371         }
372
373         RegCloseKey(hkey);
374
375         TRACE("-- 0x%08lx\n", attributes);
376
377         *szDest = attributes;
378
379         return TRUE;
380 }