Spelling fixes.
[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 <stdio.h>
28 #include "wine/debug.h"
29 #include "winerror.h"
30 #include "winreg.h"
31
32 #include "shlobj.h"
33 #include "shell32_main.h"
34 #include "shlguid.h"
35 #include "shresdef.h"
36 #include "shlwapi.h"
37 #include "wine/unicode.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(shell);
40
41 #define MAX_EXTENSION_LENGTH 20
42
43 BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, DWORD len, BOOL bPrependDot)
44 {       
45         HKEY    hkey;
46         WCHAR   szTemp[MAX_EXTENSION_LENGTH + 2];
47
48         TRACE("%s %p\n", debugstr_w(szExtension), debugstr_w(szFileType));
49
50     /* added because we do not want to have double dots */
51     if (szExtension[0] == '.')
52         bPrependDot = 0;
53
54         if (bPrependDot)
55           szTemp[0] = '.';
56
57         lstrcpynW(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH);
58
59         if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szTemp, 0, 0x02000000, &hkey))
60         { 
61           return FALSE;
62         }
63
64         if (RegQueryValueW(hkey, NULL, szFileType, &len))
65         { 
66           RegCloseKey(hkey);
67           return FALSE;
68         }
69
70         RegCloseKey(hkey);
71
72         TRACE("--UE;\n} %s\n", debugstr_w(szFileType));
73
74         return TRUE;
75 }
76
77 BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, DWORD len, BOOL bPrependDot)
78 {
79         HKEY    hkey;
80         char    szTemp[MAX_EXTENSION_LENGTH + 2];
81
82         TRACE("%s %p\n", szExtension, szFileType);
83
84     /* added because we do not want to have double dots */
85     if (szExtension[0] == '.')
86         bPrependDot = 0;
87
88         if (bPrependDot)
89           szTemp[0] = '.';
90
91         lstrcpynA(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH);
92
93         if (RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, 0x02000000, &hkey))
94         { 
95           return FALSE;
96         }
97
98         if (RegQueryValueA(hkey, NULL, szFileType, &len))
99         { 
100           RegCloseKey(hkey);
101           return FALSE;
102         }
103
104         RegCloseKey(hkey);
105
106         TRACE("--UE;\n} %s\n", szFileType);
107
108         return TRUE;
109 }
110
111
112 BOOL HCR_GetExecuteCommandW(LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
113 {
114         static const WCHAR swShell[] = {'\\','s','h','e','l','l','\\',0};
115         static const WCHAR swCommand[] = {'\\','c','o','m','m','a','n','d',0};
116         WCHAR   sTemp[MAX_PATH];
117
118         TRACE("%s %s %p\n",debugstr_w(szClass), debugstr_w(szVerb), szDest);
119
120         lstrcpyW(sTemp, szClass);
121         lstrcatW(sTemp, swShell);
122         lstrcatW(sTemp, szVerb);
123         lstrcatW(sTemp, swCommand);
124
125         if (ERROR_SUCCESS == SHGetValueW(HKEY_CLASSES_ROOT, sTemp, NULL, NULL, szDest, &len)) {
126             TRACE("-- %s\n", debugstr_w(szDest) );
127             return TRUE;
128         }
129         return FALSE;
130 }
131
132 BOOL HCR_GetExecuteCommandA(LPCSTR szClass, LPCSTR szVerb, LPSTR szDest, DWORD len)
133 {
134         char    sTemp[MAX_PATH];
135
136         TRACE("%s %s\n",szClass, szVerb );
137
138         snprintf(sTemp, MAX_PATH, "%s\\shell\\%s\\command",szClass, szVerb);
139
140         if (ERROR_SUCCESS == SHGetValueA(HKEY_CLASSES_ROOT, sTemp, NULL, NULL, szDest, &len)) {
141             TRACE("-- %s\n", debugstr_a(szDest) );
142             return TRUE;
143         }
144         return FALSE;
145 }
146
147 BOOL HCR_GetExecuteCommandEx( HKEY hkeyClass, LPCSTR szClass, LPCSTR szVerb, LPSTR szDest, DWORD len )
148 {
149         BOOL    ret = FALSE;
150
151         TRACE("%p %s %s\n", hkeyClass, szClass, szVerb );
152
153         if (szClass)
154             RegOpenKeyExA(hkeyClass,szClass,0,0x02000000,&hkeyClass);
155
156         if (hkeyClass)
157         {
158             char sTemp[MAX_PATH];
159
160             snprintf(sTemp, MAX_PATH, "shell\\%s\\command", szVerb);
161
162             ret = (ERROR_SUCCESS == SHGetValueA(hkeyClass, sTemp, NULL, NULL, szDest, &len));
163
164             if (szClass)
165                RegCloseKey(hkeyClass);
166         }
167
168         TRACE("-- %s\n", szDest );
169         return ret;
170 }
171
172 /***************************************************************************************
173 *       HCR_GetDefaultIcon      [internal]
174 *
175 * Gets the icon for a filetype
176 */
177 static BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey)
178 {
179         char    xriid[50];
180     sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
181                  riid->Data1, riid->Data2, riid->Data3,
182                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
183                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
184
185         TRACE("%s\n",xriid );
186
187         return !RegOpenKeyExA(HKEY_CLASSES_ROOT, xriid, 0, KEY_READ, hkey);
188 }
189
190 static BOOL HCR_RegGetDefaultIconW(HKEY hkey, LPWSTR szDest, DWORD len, LPDWORD dwNr)
191 {
192         DWORD dwType;
193         WCHAR sTemp[MAX_PATH];
194         WCHAR sNum[5];
195
196         if (!RegQueryValueExW(hkey, NULL, 0, &dwType, (LPBYTE)szDest, &len))
197         {
198       if (dwType == REG_EXPAND_SZ)
199           {
200             ExpandEnvironmentStringsW(szDest, sTemp, MAX_PATH);
201             lstrcpynW(szDest, sTemp, len);
202           }
203           if (ParseFieldW (szDest, 2, sNum, 5))
204              *dwNr = atoiW(sNum);
205           else
206              *dwNr=0; /* sometimes the icon number is missing */
207           ParseFieldW (szDest, 1, szDest, len);
208           return TRUE;
209         }
210         return FALSE;
211 }
212
213 static BOOL HCR_RegGetDefaultIconA(HKEY hkey, LPSTR szDest, DWORD len, LPDWORD dwNr)
214 {
215         DWORD dwType;
216         char sTemp[MAX_PATH];
217         char  sNum[5];
218
219         if (!RegQueryValueExA(hkey, NULL, 0, &dwType, szDest, &len))
220         {
221       if (dwType == REG_EXPAND_SZ)
222           {
223             ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH);
224             lstrcpynA(szDest, sTemp, len);
225           }
226           if (ParseFieldA (szDest, 2, sNum, 5))
227              *dwNr=atoi(sNum);
228           else
229              *dwNr=0; /* sometimes the icon number is missing */
230           ParseFieldA (szDest, 1, szDest, len);
231           return TRUE;
232         }
233         return FALSE;
234 }
235
236 BOOL HCR_GetDefaultIconW(LPCWSTR szClass, LPWSTR szDest, DWORD len, LPDWORD dwNr)
237 {
238         static const WCHAR swDefaultIcon[] = {'\\','D','e','f','a','u','l','t','I','c','o','n',0};
239         HKEY    hkey;
240         WCHAR   sTemp[MAX_PATH];
241         BOOL    ret = FALSE;
242
243         TRACE("%s\n",debugstr_w(szClass) );
244
245         lstrcpynW(sTemp, szClass, MAX_PATH);
246         lstrcatW(sTemp, swDefaultIcon);
247
248         if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
249         {
250           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
251           RegCloseKey(hkey);
252         }
253         TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
254         return ret;
255 }
256
257 BOOL HCR_GetDefaultIconA(LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr)
258 {
259         HKEY    hkey;
260         char    sTemp[MAX_PATH];
261         BOOL    ret = FALSE;
262
263         TRACE("%s\n",szClass );
264
265         sprintf(sTemp, "%s\\DefaultIcon",szClass);
266
267         if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, sTemp, 0, 0x02000000, &hkey))
268         {
269           ret = HCR_RegGetDefaultIconA(hkey, szDest, len, dwNr);
270           RegCloseKey(hkey);
271         }
272         TRACE("-- %s %li\n", szDest, *dwNr );
273         return ret;
274 }
275
276 BOOL HCR_GetDefaultIconFromGUIDW(REFIID riid, LPWSTR szDest, DWORD len, LPDWORD dwNr)
277 {
278         HKEY    hkey;
279         BOOL    ret = FALSE;
280
281         if (HCR_RegOpenClassIDKey(riid, &hkey))
282         {
283           ret = HCR_RegGetDefaultIconW(hkey, szDest, len, dwNr);
284           RegCloseKey(hkey);
285         }
286         TRACE("-- %s %li\n", debugstr_w(szDest), *dwNr );
287         return ret;
288 }
289
290 /***************************************************************************************
291 *       HCR_GetClassName        [internal]
292 *
293 * Gets the name of a registred class
294 */
295 static WCHAR swEmpty[] = {0};
296
297 BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len)
298 {       
299         HKEY    hkey;
300         BOOL ret = FALSE;
301         DWORD buflen = len;
302
303         szDest[0] = 0;
304         if (HCR_RegOpenClassIDKey(riid, &hkey))
305         {
306           if (!RegQueryValueExW(hkey, swEmpty, 0, NULL, (LPBYTE)szDest, &len))
307           {
308             ret = TRUE;
309           }
310           RegCloseKey(hkey);
311         }
312
313         if (!ret || !szDest[0])
314         {
315           if(IsEqualIID(riid, &CLSID_ShellDesktop))
316           {
317             if (LoadStringW(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
318               ret = TRUE;
319           }
320           else if (IsEqualIID(riid, &CLSID_MyComputer))
321           {
322             if(LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
323               ret = TRUE;
324           }
325         }
326         TRACE("-- %s\n", debugstr_w(szDest));
327         return ret;
328 }
329
330 BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len)
331 {       HKEY    hkey;
332         BOOL ret = FALSE;
333         DWORD buflen = len;
334
335         szDest[0] = 0;
336         if (HCR_RegOpenClassIDKey(riid, &hkey))
337         {
338           if (!RegQueryValueExA(hkey,"",0,NULL,szDest,&len))
339           {
340             ret = TRUE;
341           }
342           RegCloseKey(hkey);
343         }
344
345         if (!ret || !szDest[0])
346         {
347           if(IsEqualIID(riid, &CLSID_ShellDesktop))
348           {
349             if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
350               ret = TRUE;
351           }
352           else if (IsEqualIID(riid, &CLSID_MyComputer))
353           {
354             if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
355               ret = TRUE;
356           }
357         }
358
359         TRACE("-- %s\n", szDest);
360
361         return ret;
362 }
363
364 /***************************************************************************************
365 *       HCR_GetFolderAttributes [internal]
366 *
367 * gets the folder attributes of a class
368 *
369 * FIXME
370 *       verify the defaultvalue for *szDest
371 */
372 BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
373 {       HKEY    hkey;
374         char    xriid[60];
375         DWORD   attributes;
376         DWORD   len = 4;
377
378         sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
379                  riid->Data1, riid->Data2, riid->Data3,
380                  riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
381                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
382         TRACE("%s\n",xriid );
383
384         if (!szDest) return FALSE;
385         *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
386
387         strcat (xriid, "\\ShellFolder");
388
389         if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
390         {
391           return FALSE;
392         }
393
394         if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len))
395         {
396           RegCloseKey(hkey);
397           return FALSE;
398         }
399
400         RegCloseKey(hkey);
401
402         TRACE("-- 0x%08lx\n", attributes);
403
404         *szDest = attributes;
405
406         return TRUE;
407 }
408
409 typedef struct
410 {       ICOM_VFIELD(IQueryAssociations);
411         DWORD   ref;
412 } IQueryAssociationsImpl;
413
414 static struct ICOM_VTABLE(IQueryAssociations) qavt;
415
416 /**************************************************************************
417 *  IQueryAssociations_Constructor
418 */
419 IQueryAssociations* IQueryAssociations_Constructor(void)
420 {
421         IQueryAssociationsImpl* ei;
422
423         ei=(IQueryAssociationsImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IQueryAssociationsImpl));
424         ei->ref=1;
425         ei->lpVtbl = &qavt;
426
427         TRACE("(%p)\n",ei);
428         return (IQueryAssociations *)ei;
429 }
430 /**************************************************************************
431  *  IQueryAssociations_QueryInterface
432  */
433 static HRESULT WINAPI IQueryAssociations_fnQueryInterface(
434         IQueryAssociations * iface,
435         REFIID riid,
436         LPVOID *ppvObj)
437 {
438         ICOM_THIS(IQueryAssociationsImpl,iface);
439
440          TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
441
442         *ppvObj = NULL;
443
444         if(IsEqualIID(riid, &IID_IUnknown))             /*IUnknown*/
445         {
446           *ppvObj = This;
447         }
448         else if(IsEqualIID(riid, &IID_IQueryAssociations))      /*IExtractIcon*/
449         {
450           *ppvObj = (IQueryAssociations*)This;
451         }
452
453         if(*ppvObj)
454         {
455           IQueryAssociations_AddRef((IQueryAssociations*) *ppvObj);
456           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
457           return S_OK;
458         }
459         TRACE("-- Interface: E_NOINTERFACE\n");
460         return E_NOINTERFACE;
461 }
462
463 /**************************************************************************
464 *  IQueryAssociations_AddRef
465 */
466 static ULONG WINAPI IQueryAssociations_fnAddRef(IQueryAssociations * iface)
467 {
468         ICOM_THIS(IQueryAssociationsImpl,iface);
469
470         TRACE("(%p)->(count=%lu)\n",This, This->ref );
471
472         return ++(This->ref);
473 }
474 /**************************************************************************
475 *  IQueryAssociations_Release
476 */
477 static ULONG WINAPI IQueryAssociations_fnRelease(IQueryAssociations * iface)
478 {
479         ICOM_THIS(IQueryAssociationsImpl,iface);
480
481         TRACE("(%p)->()\n",This);
482
483         if (!--(This->ref))
484         {
485           TRACE(" destroying IExtractIcon(%p)\n",This);
486           HeapFree(GetProcessHeap(),0,This);
487           return 0;
488         }
489         return This->ref;
490 }
491
492 static HRESULT WINAPI IQueryAssociations_fnInit(
493         IQueryAssociations * iface,
494         ASSOCF flags,
495         LPCWSTR pszAssoc,
496         HKEY hkProgid,
497         HWND hwnd)
498 {
499         return E_NOTIMPL;
500 }
501
502 static HRESULT WINAPI IQueryAssociations_fnGetString(
503         IQueryAssociations * iface,
504         ASSOCF flags,
505         ASSOCSTR str,
506         LPCWSTR pszExtra,
507         LPWSTR pszOut,
508         DWORD *pcchOut)
509 {
510         return E_NOTIMPL;
511 }
512
513 static HRESULT WINAPI IQueryAssociations_fnGetKey(
514         IQueryAssociations * iface,
515         ASSOCF flags,
516         ASSOCKEY key,
517         LPCWSTR pszExtra,
518         HKEY *phkeyOut)
519 {
520         return E_NOTIMPL;
521 }
522
523 static HRESULT WINAPI IQueryAssociations_fnGetData(
524         IQueryAssociations * iface,
525         ASSOCF flags,
526         ASSOCDATA data,
527         LPCWSTR pszExtra,
528         LPVOID pvOut,
529         DWORD *pcbOut)
530 {
531         return E_NOTIMPL;
532 }
533 static HRESULT WINAPI IQueryAssociations_fnGetEnum(
534         IQueryAssociations * iface,
535         ASSOCF flags,
536         ASSOCENUM assocenum,
537         LPCWSTR pszExtra,
538         REFIID riid,
539         LPVOID *ppvOut)
540 {
541         return E_NOTIMPL;
542 }
543
544 static struct ICOM_VTABLE(IQueryAssociations) qavt =
545 {
546         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
547         IQueryAssociations_fnQueryInterface,
548         IQueryAssociations_fnAddRef,
549         IQueryAssociations_fnRelease,
550         IQueryAssociations_fnInit,
551         IQueryAssociations_fnGetString,
552         IQueryAssociations_fnGetKey,
553         IQueryAssociations_fnGetData,
554         IQueryAssociations_fnGetEnum
555 };