Extract binary resources to files, to fit the standard.
[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(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         WCHAR   sTemp[MAX_PATH];
122
123         TRACE("%s %s %p\n",debugstr_w(szClass), debugstr_w(szVerb), szDest);
124
125         lstrcpyW(sTemp, szClass);
126         lstrcatW(sTemp, swShell);
127         lstrcatW(sTemp, szVerb);
128         lstrcatW(sTemp, swCommand);
129
130         if (ERROR_SUCCESS == SHGetValueW(HKEY_CLASSES_ROOT, sTemp, NULL, NULL, szDest, &len)) {
131             TRACE("-- %s\n", debugstr_w(szDest) );
132             return TRUE;
133         }
134         return FALSE;
135 }
136
137 BOOL HCR_GetExecuteCommandA(LPCSTR szClass, LPCSTR szVerb, LPSTR szDest, DWORD len)
138 {
139         char    sTemp[MAX_PATH];
140
141         TRACE("%s %s\n",szClass, szVerb );
142
143         snprintf(sTemp, MAX_PATH, "%s\\shell\\%s\\command",szClass, szVerb);
144
145         if (ERROR_SUCCESS == SHGetValueA(HKEY_CLASSES_ROOT, sTemp, NULL, NULL, szDest, &len)) {
146             TRACE("-- %s\n", debugstr_a(szDest) );
147             return TRUE;
148         }
149         return FALSE;
150 }
151
152 BOOL HCR_GetExecuteCommandEx( HKEY hkeyClass, LPCSTR szClass, LPCSTR szVerb, LPSTR szDest, DWORD len )
153 {
154         BOOL    ret = FALSE;
155
156         TRACE("%p %s %s\n", hkeyClass, szClass, szVerb );
157
158         if (szClass)
159             RegOpenKeyExA(hkeyClass,szClass,0,0x02000000,&hkeyClass);
160
161         if (hkeyClass)
162         {
163             char sTemp[MAX_PATH];
164
165             snprintf(sTemp, MAX_PATH, "shell\\%s\\command", szVerb);
166
167             ret = (ERROR_SUCCESS == SHGetValueA(hkeyClass, sTemp, NULL, NULL, szDest, &len));
168
169             if (szClass)
170                RegCloseKey(hkeyClass);
171         }
172
173         TRACE("-- %s\n", szDest );
174         return ret;
175 }
176
177 /***************************************************************************************
178 *       HCR_GetDefaultIcon      [internal]
179 *
180 * Gets the icon for a filetype
181 */
182 static BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey)
183 {
184         char    xriid[50];
185     sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
186                  riid->Data1, riid->Data2, riid->Data3,
187                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
188                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
189
190         TRACE("%s\n",xriid );
191
192         return !RegOpenKeyExA(HKEY_CLASSES_ROOT, xriid, 0, KEY_READ, hkey);
193 }
194
195 static BOOL HCR_RegGetDefaultIconW(HKEY hkey, LPWSTR szDest, DWORD len, LPDWORD dwNr)
196 {
197         DWORD dwType;
198         WCHAR sTemp[MAX_PATH];
199         WCHAR sNum[5];
200
201         if (!RegQueryValueExW(hkey, NULL, 0, &dwType, (LPBYTE)szDest, &len))
202         {
203       if (dwType == REG_EXPAND_SZ)
204           {
205             ExpandEnvironmentStringsW(szDest, sTemp, MAX_PATH);
206             lstrcpynW(szDest, sTemp, len);
207           }
208           if (ParseFieldW (szDest, 2, sNum, 5))
209              *dwNr = atoiW(sNum);
210           else
211              *dwNr=0; /* sometimes the icon number is missing */
212           ParseFieldW (szDest, 1, szDest, len);
213           return TRUE;
214         }
215         return FALSE;
216 }
217
218 static BOOL HCR_RegGetDefaultIconA(HKEY hkey, LPSTR szDest, DWORD len, LPDWORD dwNr)
219 {
220         DWORD dwType;
221         char sTemp[MAX_PATH];
222         char  sNum[5];
223
224         if (!RegQueryValueExA(hkey, NULL, 0, &dwType, szDest, &len))
225         {
226       if (dwType == REG_EXPAND_SZ)
227           {
228             ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH);
229             lstrcpynA(szDest, sTemp, len);
230           }
231           if (ParseFieldA (szDest, 2, sNum, 5))
232              *dwNr=atoi(sNum);
233           else
234              *dwNr=0; /* sometimes the icon number is missing */
235           ParseFieldA (szDest, 1, szDest, len);
236           return TRUE;
237         }
238         return FALSE;
239 }
240
241 BOOL HCR_GetDefaultIconW(LPCWSTR szClass, LPWSTR szDest, DWORD len, LPDWORD dwNr)
242 {
243         static const WCHAR swDefaultIcon[] = {'\\','D','e','f','a','u','l','t','I','c','o','n',0};
244         HKEY    hkey;
245         WCHAR   sTemp[MAX_PATH];
246         BOOL    ret = FALSE;
247
248         TRACE("%s\n",debugstr_w(szClass) );
249
250         lstrcpynW(sTemp, szClass, MAX_PATH);
251         lstrcatW(sTemp, swDefaultIcon);
252
253         if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
254         {
255           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
256           RegCloseKey(hkey);
257         }
258         TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
259         return ret;
260 }
261
262 BOOL HCR_GetDefaultIconA(LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr)
263 {
264         HKEY    hkey;
265         char    sTemp[MAX_PATH];
266         BOOL    ret = FALSE;
267
268         TRACE("%s\n",szClass );
269
270         sprintf(sTemp, "%s\\DefaultIcon",szClass);
271
272         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
273         {
274           ret = HCR_RegGetDefaultIconA(hkey, szDest, len, dwNr);
275           RegCloseKey(hkey);
276         }
277         TRACE("-- %s %li\n", szDest, *dwNr );
278         return ret;
279 }
280
281 BOOL HCR_GetDefaultIconFromGUIDW(REFIID riid, LPWSTR szDest, DWORD len, LPDWORD dwNr)
282 {
283         HKEY    hkey;
284         BOOL    ret = FALSE;
285
286         if (HCR_RegOpenClassIDKey(riid, &hkey))
287         {
288           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
289           RegCloseKey(hkey);
290         }
291         TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
292         return ret;
293 }
294
295 /***************************************************************************************
296 *       HCR_GetClassName        [internal]
297 *
298 * Gets the name of a registred class
299 */
300 static WCHAR swEmpty[] = {0};
301
302 BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len)
303 {       
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 (!RegQueryValueExW(hkey, swEmpty, 0, NULL, (LPBYTE)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 (LoadStringW(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
323               ret = TRUE;
324           }
325           else if (IsEqualIID(riid, &CLSID_MyComputer))
326           {
327             if(LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
328               ret = TRUE;
329           }
330         }
331         TRACE("-- %s\n", debugstr_w(szDest));
332         return ret;
333 }
334
335 BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len)
336 {       HKEY    hkey;
337         BOOL ret = FALSE;
338         DWORD buflen = len;
339
340         szDest[0] = 0;
341         if (HCR_RegOpenClassIDKey(riid, &hkey))
342         {
343           if (!RegQueryValueExA(hkey,"",0,NULL,szDest,&len))
344           {
345             ret = TRUE;
346           }
347           RegCloseKey(hkey);
348         }
349
350         if (!ret || !szDest[0])
351         {
352           if(IsEqualIID(riid, &CLSID_ShellDesktop))
353           {
354             if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
355               ret = TRUE;
356           }
357           else if (IsEqualIID(riid, &CLSID_MyComputer))
358           {
359             if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
360               ret = TRUE;
361           }
362         }
363
364         TRACE("-- %s\n", szDest);
365
366         return ret;
367 }
368
369 /***************************************************************************************
370 *       HCR_GetFolderAttributes [internal]
371 *
372 * gets the folder attributes of a class
373 *
374 * FIXME
375 *       verify the defaultvalue for *szDest
376 */
377 BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
378 {       HKEY    hkey;
379         char    xriid[60];
380         DWORD   attributes;
381         DWORD   len = 4;
382
383         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
384                  riid->Data1, riid->Data2, riid->Data3,
385                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
386                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
387         TRACE("%s\n",xriid );
388
389         if (!szDest) return FALSE;
390         *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
391
392         strcat (xriid, "\\ShellFolder");
393
394         if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
395         {
396           return FALSE;
397         }
398
399         if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len))
400         {
401           RegCloseKey(hkey);
402           return FALSE;
403         }
404
405         RegCloseKey(hkey);
406
407         TRACE("-- 0x%08lx\n", attributes);
408
409         *szDest = attributes;
410
411         return TRUE;
412 }