Sort entry points alphabetically.
[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           PathUnquoteSpacesW(szDest);
182           return TRUE;
183         }
184         return FALSE;
185 }
186
187 static BOOL HCR_RegGetDefaultIconA(HKEY hkey, LPSTR szDest, DWORD len, LPDWORD dwNr)
188 {
189         DWORD dwType;
190         char sTemp[MAX_PATH];
191         char  sNum[5];
192
193         if (!RegQueryValueExA(hkey, NULL, 0, &dwType, szDest, &len))
194         {
195       if (dwType == REG_EXPAND_SZ)
196           {
197             ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH);
198             lstrcpynA(szDest, sTemp, len);
199           }
200           if (ParseFieldA (szDest, 2, sNum, 5))
201              *dwNr=atoi(sNum);
202           else
203              *dwNr=0; /* sometimes the icon number is missing */
204           ParseFieldA (szDest, 1, szDest, len);
205           PathUnquoteSpacesA(szDest);
206           return TRUE;
207         }
208         return FALSE;
209 }
210
211 BOOL HCR_GetDefaultIconW(LPCWSTR szClass, LPWSTR szDest, DWORD len, LPDWORD dwNr)
212 {
213         static const WCHAR swDefaultIcon[] = {'\\','D','e','f','a','u','l','t','I','c','o','n',0};
214         HKEY    hkey;
215         WCHAR   sTemp[MAX_PATH];
216         BOOL    ret = FALSE;
217
218         TRACE("%s\n",debugstr_w(szClass) );
219
220         lstrcpynW(sTemp, szClass, MAX_PATH);
221         lstrcatW(sTemp, swDefaultIcon);
222
223         if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
224         {
225           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
226           RegCloseKey(hkey);
227         }
228
229         if(ret)
230             TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
231         else
232             TRACE("-- not found\n");
233
234         return ret;
235 }
236
237 BOOL HCR_GetDefaultIconA(LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr)
238 {
239         HKEY    hkey;
240         char    sTemp[MAX_PATH];
241         BOOL    ret = FALSE;
242
243         TRACE("%s\n",szClass );
244
245         sprintf(sTemp, "%s\\DefaultIcon",szClass);
246
247         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
248         {
249           ret = HCR_RegGetDefaultIconA(hkey, szDest, len, dwNr);
250           RegCloseKey(hkey);
251         }
252         TRACE("-- %s %li\n", szDest, *dwNr );
253         return ret;
254 }
255
256 BOOL HCR_GetDefaultIconFromGUIDW(REFIID riid, LPWSTR szDest, DWORD len, LPDWORD dwNr)
257 {
258         HKEY    hkey;
259         BOOL    ret = FALSE;
260
261         if (HCR_RegOpenClassIDKey(riid, &hkey))
262         {
263           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
264           RegCloseKey(hkey);
265         }
266         TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
267         return ret;
268 }
269
270 /***************************************************************************************
271 *       HCR_GetClassName        [internal]
272 *
273 * Gets the name of a registered class
274 */
275 static const WCHAR swEmpty[] = {0};
276
277 BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len)
278 {       
279         HKEY    hkey;
280         BOOL ret = FALSE;
281         DWORD buflen = len;
282
283         szDest[0] = 0;
284         if (HCR_RegOpenClassIDKey(riid, &hkey))
285         {
286           if (!RegQueryValueExW(hkey, swEmpty, 0, NULL, (LPBYTE)szDest, &len))
287           {
288             ret = TRUE;
289           }
290           RegCloseKey(hkey);
291         }
292
293         if (!ret || !szDest[0])
294         {
295           if(IsEqualIID(riid, &CLSID_ShellDesktop))
296           {
297             if (LoadStringW(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
298               ret = TRUE;
299           }
300           else if (IsEqualIID(riid, &CLSID_MyComputer))
301           {
302             if(LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
303               ret = TRUE;
304           }
305         }
306         TRACE("-- %s\n", debugstr_w(szDest));
307         return ret;
308 }
309
310 BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len)
311 {       HKEY    hkey;
312         BOOL ret = FALSE;
313         DWORD buflen = len;
314
315         szDest[0] = 0;
316         if (HCR_RegOpenClassIDKey(riid, &hkey))
317         {
318           if (!RegQueryValueExA(hkey,"",0,NULL,szDest,&len))
319           {
320             ret = TRUE;
321           }
322           RegCloseKey(hkey);
323         }
324
325         if (!ret || !szDest[0])
326         {
327           if(IsEqualIID(riid, &CLSID_ShellDesktop))
328           {
329             if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
330               ret = TRUE;
331           }
332           else if (IsEqualIID(riid, &CLSID_MyComputer))
333           {
334             if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
335               ret = TRUE;
336           }
337         }
338
339         TRACE("-- %s\n", szDest);
340
341         return ret;
342 }
343
344 /***************************************************************************************
345 *       HCR_GetFolderAttributes [internal]
346 *
347 * gets the folder attributes of a class
348 *
349 * FIXME
350 *       verify the defaultvalue for *szDest
351 */
352 BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
353 {       HKEY    hkey;
354         char    xriid[60];
355         DWORD   attributes;
356         DWORD   len = 4;
357
358         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
359                  riid->Data1, riid->Data2, riid->Data3,
360                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
361                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
362         TRACE("%s\n",xriid );
363
364         if (!szDest) return FALSE;
365         *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
366
367         strcat (xriid, "\\ShellFolder");
368
369         if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
370         {
371           return FALSE;
372         }
373
374         if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len))
375         {
376           RegCloseKey(hkey);
377           return FALSE;
378         }
379
380         RegCloseKey(hkey);
381
382         TRACE("-- 0x%08lx\n", attributes);
383
384         *szDest = attributes;
385
386         return TRUE;
387 }