blob: 5c00c8b4399e82f627142bb6b762d76b97956825 [file] [log] [blame]
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +00001/*
Vincent Béron9a624912002-05-31 23:06:46 +00002 * file type mapping
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +00003 * (HKEY_CLASSES_ROOT - Stuff)
4 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00005 * Copyright 1998, 1999, 2000 Juergen Schmied
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +00006 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00007 * 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
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000020 */
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000021
Steven Edwards9f573fa2002-07-29 23:28:29 +000022#include "config.h"
23#include "wine/port.h"
24
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000025#include <stdlib.h>
26#include <string.h>
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000027#include <stdarg.h>
Alexandre Julliard383da682000-02-10 22:15:21 +000028#include <stdio.h>
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000029#include "wine/debug.h"
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000030#include "winerror.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000031#include "windef.h"
32#include "winbase.h"
Marcus Meissner317af321999-02-17 13:51:06 +000033#include "winreg.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000034#include "wingdi.h"
35#include "winuser.h"
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000036
Juergen Schmiedba28ba11999-01-23 14:12:48 +000037#include "shlobj.h"
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000038#include "shell32_main.h"
Juergen Schmiedd72ace41999-08-15 14:24:49 +000039#include "shlguid.h"
40#include "shresdef.h"
Juergen Schmied1e5ec882002-07-24 01:56:03 +000041#include "shlwapi.h"
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000042#include "wine/unicode.h"
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000043
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000044WINE_DEFAULT_DEBUG_CHANNEL(shell);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000045
Juergen Schmied166cfd51999-07-25 12:19:12 +000046#define MAX_EXTENSION_LENGTH 20
47
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000048BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, DWORD len, BOOL bPrependDot)
49{
50 HKEY hkey;
51 WCHAR szTemp[MAX_EXTENSION_LENGTH + 2];
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000052
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000053 TRACE("%s %p\n", debugstr_w(szExtension), debugstr_w(szFileType));
Juergen Schmied98f6cf01998-12-11 10:58:48 +000054
Aric Stewart3ae80eb2001-10-23 00:25:15 +000055 /* added because we do not want to have double dots */
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000056 if (szExtension[0] == '.')
57 bPrependDot = 0;
Aric Stewart3ae80eb2001-10-23 00:25:15 +000058
Juergen Schmiedd72ace41999-08-15 14:24:49 +000059 if (bPrependDot)
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000060 szTemp[0] = '.';
Juergen Schmiedd72ace41999-08-15 14:24:49 +000061
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000062 lstrcpynW(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH);
Vincent Béron9a624912002-05-31 23:06:46 +000063
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000064 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szTemp, 0, 0x02000000, &hkey))
65 {
66 return FALSE;
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000067 }
68
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000069 if (RegQueryValueW(hkey, NULL, szFileType, &len))
70 {
71 RegCloseKey(hkey);
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000072 return FALSE;
Vincent Béron9a624912002-05-31 23:06:46 +000073 }
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000074
75 RegCloseKey(hkey);
76
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000077 TRACE("--UE;\n} %s\n", debugstr_w(szFileType));
Juergen Schmieda9a4f4e1998-11-22 18:26:23 +000078
79 return TRUE;
80}
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +000081
82BOOL 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
Alexandre Julliarde025c592004-01-16 23:06:25 +0000117BOOL HCR_GetExecuteCommandW( HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len )
Marcelo Duarte36002732003-12-10 00:39:31 +0000118{
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)
Alexandre Julliarde025c592004-01-16 23:06:25 +0000126 RegOpenKeyExW(HKEY_CLASSES_ROOT, szClass, 0, 0x02000000, &hkeyClass);
Marcelo Duarte36002732003-12-10 00:39:31 +0000127
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
Juergen Schmied01fc2ba1998-12-14 17:33:00 +0000145/***************************************************************************************
146* HCR_GetDefaultIcon [internal]
147*
148* Gets the icon for a filetype
149*/
Juergen Schmied799e6ce2003-01-10 01:45:57 +0000150static BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey)
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000151{
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
Juergen Schmied799e6ce2003-01-10 01:45:57 +0000160 return !RegOpenKeyExA(HKEY_CLASSES_ROOT, xriid, 0, KEY_READ, hkey);
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000161}
162
163static 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
186static 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
209BOOL 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
230BOOL HCR_GetDefaultIconA(LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr)
Juergen Schmied1dbf403d2000-06-24 12:56:08 +0000231{
232 HKEY hkey;
233 char sTemp[MAX_PATH];
Juergen Schmied1dbf403d2000-06-24 12:56:08 +0000234 BOOL ret = FALSE;
Juergen Schmied01fc2ba1998-12-14 17:33:00 +0000235
Alexandre Julliarda099a551999-06-12 15:45:58 +0000236 TRACE("%s\n",szClass );
Juergen Schmied01fc2ba1998-12-14 17:33:00 +0000237
238 sprintf(sTemp, "%s\\DefaultIcon",szClass);
239
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000240 if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
Juergen Schmied1dbf403d2000-06-24 12:56:08 +0000241 {
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000242 ret = HCR_RegGetDefaultIconA(hkey, szDest, len, dwNr);
Juergen Schmied1dbf403d2000-06-24 12:56:08 +0000243 RegCloseKey(hkey);
Juergen Schmied01fc2ba1998-12-14 17:33:00 +0000244 }
Alexandre Julliarda099a551999-06-12 15:45:58 +0000245 TRACE("-- %s %li\n", szDest, *dwNr );
Juergen Schmied1dbf403d2000-06-24 12:56:08 +0000246 return ret;
Juergen Schmied166cfd51999-07-25 12:19:12 +0000247}
Juergen Schmied01fc2ba1998-12-14 17:33:00 +0000248
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000249BOOL HCR_GetDefaultIconFromGUIDW(REFIID riid, LPWSTR szDest, DWORD len, LPDWORD dwNr)
250{
251 HKEY hkey;
252 BOOL ret = FALSE;
253
Juergen Schmied799e6ce2003-01-10 01:45:57 +0000254 if (HCR_RegOpenClassIDKey(riid, &hkey))
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000255 {
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
Juergen Schmied166cfd51999-07-25 12:19:12 +0000263/***************************************************************************************
264* HCR_GetClassName [internal]
265*
266* Gets the name of a registred class
267*/
Francois Gouget6a6c85c2004-04-19 20:12:14 +0000268static const WCHAR swEmpty[] = {0};
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000269
270BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len)
271{
272 HKEY hkey;
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000273 BOOL ret = FALSE;
274 DWORD buflen = len;
Juergen Schmied166cfd51999-07-25 12:19:12 +0000275
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000276 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 }
Juergen Schmied166cfd51999-07-25 12:19:12 +0000285
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000286 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
303BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len)
304{ HKEY hkey;
305 BOOL ret = FALSE;
306 DWORD buflen = len;
Juergen Schmied166cfd51999-07-25 12:19:12 +0000307
Juergen Schmieded93b632000-02-20 18:38:19 +0000308 szDest[0] = 0;
Rolf Kalbermattercaf31ce2002-12-13 23:45:36 +0000309 if (HCR_RegOpenClassIDKey(riid, &hkey))
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000310 {
311 if (!RegQueryValueExA(hkey,"",0,NULL,szDest,&len))
312 {
313 ret = TRUE;
314 }
315 RegCloseKey(hkey);
Juergen Schmied166cfd51999-07-25 12:19:12 +0000316 }
317
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000318 if (!ret || !szDest[0])
Vincent Béron9a624912002-05-31 23:06:46 +0000319 {
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000320 if(IsEqualIID(riid, &CLSID_ShellDesktop))
321 {
Juergen Schmieded93b632000-02-20 18:38:19 +0000322 if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
323 ret = TRUE;
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000324 }
Juergen Schmiedafe53ed1999-11-23 22:31:18 +0000325 else if (IsEqualIID(riid, &CLSID_MyComputer))
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000326 {
Juergen Schmieded93b632000-02-20 18:38:19 +0000327 if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
328 ret = TRUE;
Vincent Béron9a624912002-05-31 23:06:46 +0000329 }
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000330 }
Juergen Schmied166cfd51999-07-25 12:19:12 +0000331
332 TRACE("-- %s\n", szDest);
333
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000334 return ret;
Juergen Schmied166cfd51999-07-25 12:19:12 +0000335}
336
337/***************************************************************************************
338* HCR_GetFolderAttributes [internal]
339*
340* gets the folder attributes of a class
Juergen Schmiedafe53ed1999-11-23 22:31:18 +0000341*
342* FIXME
343* verify the defaultvalue for *szDest
Juergen Schmied166cfd51999-07-25 12:19:12 +0000344*/
345BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
346{ HKEY hkey;
347 char xriid[60];
348 DWORD attributes;
349 DWORD len = 4;
350
Alexandre Julliard91791032000-06-23 16:13:33 +0000351 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] );
Juergen Schmied166cfd51999-07-25 12:19:12 +0000355 TRACE("%s\n",xriid );
356
Juergen Schmiedafe53ed1999-11-23 22:31:18 +0000357 if (!szDest) return FALSE;
358 *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
Vincent Béron9a624912002-05-31 23:06:46 +0000359
Juergen Schmied166cfd51999-07-25 12:19:12 +0000360 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;
Juergen Schmiedd72ace41999-08-15 14:24:49 +0000371 }
Juergen Schmied166cfd51999-07-25 12:19:12 +0000372
373 RegCloseKey(hkey);
374
375 TRACE("-- 0x%08lx\n", attributes);
376
377 *szDest = attributes;
378
379 return TRUE;
Juergen Schmied01fc2ba1998-12-14 17:33:00 +0000380}