3 * (HKEY_CLASSES_ROOT - Stuff)
5 * Copyright 1998, 1999, 2000 Juergen Schmied
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/debug.h"
38 #include "shell32_main.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
46 #define MAX_EXTENSION_LENGTH 20
48 BOOL
HCR_MapTypeToValueW(LPCWSTR szExtension
, LPWSTR szFileType
, LONG len
, BOOL bPrependDot
)
51 WCHAR szTemp
[MAX_EXTENSION_LENGTH
+ 2];
53 TRACE("%s %p\n", debugstr_w(szExtension
), szFileType
);
55 /* added because we do not want to have double dots */
56 if (szExtension
[0] == '.')
62 lstrcpynW(szTemp
+ (bPrependDot
?1:0), szExtension
, MAX_EXTENSION_LENGTH
);
64 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, szTemp
, 0, KEY_READ
, &hkey
))
69 if (RegQueryValueW(hkey
, NULL
, szFileType
, &len
))
77 TRACE("--UE;\n} %s\n", debugstr_w(szFileType
));
82 BOOL
HCR_MapTypeToValueA(LPCSTR szExtension
, LPSTR szFileType
, LONG len
, BOOL bPrependDot
)
85 char szTemp
[MAX_EXTENSION_LENGTH
+ 2];
87 TRACE("%s %p\n", szExtension
, szFileType
);
89 /* added because we do not want to have double dots */
90 if (szExtension
[0] == '.')
96 lstrcpynA(szTemp
+ (bPrependDot
?1:0), szExtension
, MAX_EXTENSION_LENGTH
);
98 if (RegOpenKeyExA(HKEY_CLASSES_ROOT
, szTemp
, 0, KEY_READ
, &hkey
))
103 if (RegQueryValueA(hkey
, NULL
, szFileType
, &len
))
111 TRACE("--UE;\n} %s\n", szFileType
);
116 BOOL
HCR_GetDefaultVerbW( HKEY hkeyClass
, LPCWSTR szVerb
, LPWSTR szDest
, DWORD len
)
118 WCHAR sTemp
[MAX_PATH
];
122 TRACE("%p %s %p\n", hkeyClass
, debugstr_w(szVerb
), szDest
);
124 if (szVerb
&& *szVerb
)
126 lstrcpynW(szDest
, szVerb
, len
);
132 if (!RegQueryValueW(hkeyClass
, L
"shell\\", szDest
, &size
) && *szDest
)
134 /* The MSDN says to first try the default verb */
135 lstrcpyW(sTemp
, L
"shell\\");
136 lstrcatW(sTemp
, szDest
);
137 lstrcatW(sTemp
, L
"\\command");
138 if (!RegOpenKeyExW(hkeyClass
, sTemp
, 0, 0, &hkey
))
141 TRACE("default verb=%s\n", debugstr_w(szDest
));
146 /* then fallback to 'open' */
147 lstrcpyW(sTemp
, L
"shell\\open\\command");
148 if (!RegOpenKeyExW(hkeyClass
, sTemp
, 0, 0, &hkey
))
151 lstrcpynW(szDest
, L
"open", len
);
152 TRACE("default verb=open\n");
156 /* and then just use the first verb on Windows >= 2000 */
157 if (!RegEnumKeyW(hkeyClass
, 0, szDest
, len
) && *szDest
)
159 TRACE("default verb=first verb=%s\n", debugstr_w(szDest
));
163 TRACE("no default verb!\n");
167 BOOL
HCR_GetExecuteCommandW( HKEY hkeyClass
, LPCWSTR szClass
, LPCWSTR szVerb
, LPWSTR szDest
, DWORD len
)
169 WCHAR sTempVerb
[MAX_PATH
];
172 TRACE("%p %s %s %p\n", hkeyClass
, debugstr_w(szClass
), debugstr_w(szVerb
), szDest
);
175 RegOpenKeyExW(HKEY_CLASSES_ROOT
, szClass
, 0, KEY_READ
, &hkeyClass
);
180 if (HCR_GetDefaultVerbW(hkeyClass
, szVerb
, sTempVerb
, ARRAY_SIZE(sTempVerb
)))
182 WCHAR sTemp
[MAX_PATH
];
183 lstrcpyW(sTemp
, L
"shell\\");
184 lstrcatW(sTemp
, sTempVerb
);
185 lstrcatW(sTemp
, L
"\\command");
186 ret
= (ERROR_SUCCESS
== SHGetValueW(hkeyClass
, sTemp
, NULL
, NULL
, szDest
, &len
));
189 RegCloseKey(hkeyClass
);
191 TRACE("-- %s\n", debugstr_w(szDest
) );
195 /***************************************************************************************
196 * HCR_GetDefaultIcon [internal]
198 * Gets the icon for a filetype
200 static BOOL
HCR_RegOpenClassIDKey(REFIID riid
, HKEY
*hkey
)
203 sprintf( xriid
, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
204 riid
->Data1
, riid
->Data2
, riid
->Data3
,
205 riid
->Data4
[0], riid
->Data4
[1], riid
->Data4
[2], riid
->Data4
[3],
206 riid
->Data4
[4], riid
->Data4
[5], riid
->Data4
[6], riid
->Data4
[7] );
208 TRACE("%s\n",xriid
);
210 return !RegOpenKeyExA(HKEY_CLASSES_ROOT
, xriid
, 0, KEY_READ
, hkey
);
213 static BOOL
HCR_RegGetDefaultIconW(HKEY hkey
, LPWSTR szDest
, DWORD len
, int* picon_idx
)
215 DWORD dwType
, size
= len
* sizeof(WCHAR
);
216 WCHAR sTemp
[MAX_PATH
];
219 if (!RegQueryValueExW(hkey
, NULL
, 0, &dwType
, (LPBYTE
)szDest
, &size
))
221 if (dwType
== REG_EXPAND_SZ
)
223 ExpandEnvironmentStringsW(szDest
, sTemp
, MAX_PATH
);
224 lstrcpynW(szDest
, sTemp
, len
);
226 if (ParseFieldW (szDest
, 2, sNum
, 5))
227 *picon_idx
= wcstol(sNum
, NULL
, 10);
229 *picon_idx
=0; /* sometimes the icon number is missing */
230 ParseFieldW (szDest
, 1, szDest
, len
);
231 PathUnquoteSpacesW(szDest
);
237 static BOOL
HCR_RegGetDefaultIconA(HKEY hkey
, LPSTR szDest
, DWORD len
, int* picon_idx
)
240 char sTemp
[MAX_PATH
];
243 if (!RegQueryValueExA(hkey
, NULL
, 0, &dwType
, (LPBYTE
)szDest
, &len
))
245 if (dwType
== REG_EXPAND_SZ
)
247 ExpandEnvironmentStringsA(szDest
, sTemp
, MAX_PATH
);
248 lstrcpynA(szDest
, sTemp
, len
);
250 if (ParseFieldA (szDest
, 2, sNum
, 5))
251 *picon_idx
=atoi(sNum
);
253 *picon_idx
=0; /* sometimes the icon number is missing */
254 ParseFieldA (szDest
, 1, szDest
, len
);
255 PathUnquoteSpacesA(szDest
);
261 BOOL
HCR_GetDefaultIconW(LPCWSTR szClass
, LPWSTR szDest
, DWORD len
, int* picon_idx
)
264 WCHAR sTemp
[MAX_PATH
];
267 TRACE("%s\n",debugstr_w(szClass
) );
269 lstrcpynW(sTemp
, szClass
, MAX_PATH
);
270 lstrcatW(sTemp
, L
"\\DefaultIcon");
272 if (!RegOpenKeyExW(HKEY_CLASSES_ROOT
, sTemp
, 0, KEY_READ
, &hkey
))
274 ret
= HCR_RegGetDefaultIconW(hkey
, szDest
, len
, picon_idx
);
279 TRACE("-- %s %i\n", debugstr_w(szDest
), *picon_idx
);
281 TRACE("-- not found\n");
286 BOOL
HCR_GetDefaultIconA(LPCSTR szClass
, LPSTR szDest
, DWORD len
, int* picon_idx
)
289 char sTemp
[MAX_PATH
];
292 TRACE("%s\n",szClass
);
294 sprintf(sTemp
, "%s\\DefaultIcon",szClass
);
296 if (!RegOpenKeyExA(HKEY_CLASSES_ROOT
, sTemp
, 0, KEY_READ
, &hkey
))
298 ret
= HCR_RegGetDefaultIconA(hkey
, szDest
, len
, picon_idx
);
303 TRACE("-- %s %i\n", szDest
, *picon_idx
);
305 TRACE("-- not found\n");
310 /***************************************************************************************
311 * HCR_GetClassName [internal]
313 * Gets the name of a registered class
315 BOOL
HCR_GetClassNameW(REFIID riid
, LPWSTR szDest
, DWORD len
)
319 DWORD buflen
= len
* sizeof(WCHAR
);
322 if (HCR_RegOpenClassIDKey(riid
, &hkey
))
324 if (!RegLoadMUIStringW(hkey
, L
"LocalizedString", szDest
, buflen
, NULL
, 0, NULL
) ||
325 !RegQueryValueExW(hkey
, L
"", 0, NULL
, (LPBYTE
)szDest
, &buflen
))
332 if (!ret
|| !szDest
[0])
334 if(IsEqualIID(riid
, &CLSID_ShellDesktop
))
336 if (LoadStringW(shell32_hInstance
, IDS_DESKTOP
, szDest
, len
))
339 else if (IsEqualIID(riid
, &CLSID_MyComputer
))
341 if(LoadStringW(shell32_hInstance
, IDS_MYCOMPUTER
, szDest
, len
))
345 TRACE("-- %s\n", debugstr_w(szDest
));
349 BOOL
HCR_GetClassNameA(REFIID riid
, LPSTR szDest
, DWORD len
)
355 if (HCR_RegOpenClassIDKey(riid
, &hkey
))
357 if (!RegLoadMUIStringA(hkey
,"LocalizedString",szDest
,len
,NULL
,0,NULL
) ||
358 !RegQueryValueExA(hkey
,"",0,NULL
,(LPBYTE
)szDest
,&len
))
365 if (!ret
|| !szDest
[0])
367 if(IsEqualIID(riid
, &CLSID_ShellDesktop
))
369 if (LoadStringA(shell32_hInstance
, IDS_DESKTOP
, szDest
, buflen
))
372 else if (IsEqualIID(riid
, &CLSID_MyComputer
))
374 if(LoadStringA(shell32_hInstance
, IDS_MYCOMPUTER
, szDest
, buflen
))
379 TRACE("-- (%s)\n", szDest
);
384 /******************************************************************************
385 * HCR_GetFolderAttributes [Internal]
387 * Query the registry for a shell folders' attributes
390 * pidlFolder [I] A simple pidl of type PT_GUID.
391 * pdwAttributes [IO] In: Attributes to be queried, OUT: Resulting attributes.
394 * TRUE: Found information for the attributes in the registry
395 * FALSE: No attribute information found
398 * If queried for an attribute, which is set in the CallForAttributes registry
399 * value, the function binds to the shellfolder objects and queries it.
401 BOOL
HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder
, LPDWORD pdwAttributes
)
407 WCHAR wszShellFolderKey
[] = L
"CLSID\\{00021400-0000-0000-C000-000000000046}\\ShellFolder";
409 TRACE("(pidlFolder=%p, pdwAttributes=%p)\n", pidlFolder
, pdwAttributes
);
411 if (!_ILIsPidlSimple(pidlFolder
)) {
412 static BOOL firstHit
= TRUE
;
414 ERR("should be called for simple PIDL's only!\n");
420 if (!_ILIsDesktop(pidlFolder
)) {
421 if (FAILED(StringFromCLSID(_ILGetGUIDPointer(pidlFolder
), &pwszCLSID
))) return FALSE
;
422 memcpy(&wszShellFolderKey
[6], pwszCLSID
, 38 * sizeof(WCHAR
));
423 CoTaskMemFree(pwszCLSID
);
426 lResult
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, wszShellFolderKey
, 0, KEY_READ
, &hSFKey
);
427 if (lResult
!= ERROR_SUCCESS
) return FALSE
;
429 dwLen
= sizeof(DWORD
);
430 lResult
= RegQueryValueExW(hSFKey
, L
"CallForAttributes", 0, NULL
, (LPBYTE
)&dwTemp
, &dwLen
);
431 if ((lResult
== ERROR_SUCCESS
) && (dwTemp
& *pdwAttributes
)) {
432 LPSHELLFOLDER psfDesktop
, psfFolder
;
436 hr
= SHGetDesktopFolder(&psfDesktop
);
438 hr
= IShellFolder_BindToObject(psfDesktop
, pidlFolder
, NULL
, &IID_IShellFolder
,
439 (LPVOID
*)&psfFolder
);
441 hr
= IShellFolder_GetAttributesOf(psfFolder
, 0, NULL
, pdwAttributes
);
442 IShellFolder_Release(psfFolder
);
444 IShellFolder_Release(psfDesktop
);
446 if (FAILED(hr
)) return FALSE
;
448 lResult
= RegQueryValueExW(hSFKey
, L
"Attributes", 0, NULL
, (LPBYTE
)&dwTemp
, &dwLen
);
450 if (lResult
== ERROR_SUCCESS
) {
451 *pdwAttributes
&= dwTemp
;
457 TRACE("-- *pdwAttributes == 0x%08lx\n", *pdwAttributes
);