4 * Copyright 1998 Marcus Meissner
5 * Copyright 1998 Juergen Schmied (jsch) * <juergen.schmied@metronet.de>
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
24 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
26 extern const char * const SHELL_Authors
[];
29 /*************************************************************************
30 * CommandLineToArgvW [SHELL32.@]
32 * We must interpret the quotes in the command line to rebuild the argv
34 * - arguments are separated by spaces or tabs
35 * - quotes serve as optional argument delimiters
37 * - escaped quotes must be converted back to '"'
39 * - an odd number of '\'s followed by '"' correspond to half that number
40 * of '\' followed by a '"' (extension of the above)
43 * - an even number of '\'s followed by a '"' correspond to half that number
44 * of '\', plus a regular quote serving as an argument delimiter (which
45 * means it does not appear in the result)
46 * 'a\\"b c"' -> 'a\b c'
47 * 'a\\\\"b c"' -> 'a\\b c'
48 * - '\' that are not followed by a '"' are copied literally
58 LPWSTR
* WINAPI
CommandLineToArgvW(LPCWSTR lpCmdline
, int* numargs
)
69 /* Return the path to the executable */
72 argv
=LocalAlloc(LMEM_FIXED
, size
);
75 len
= GetModuleFileNameW(0, (LPWSTR
)(argv
+1), (size
-sizeof(LPWSTR
))/sizeof(WCHAR
));
81 if (len
< size
) break;
83 argv
=LocalReAlloc(argv
, size
, 0);
85 argv
[0]=(LPWSTR
)(argv
+1);
92 /* to get a writable copy */
99 if (*cs
==0 || ((*cs
==0x0009 || *cs
==0x0020) && !in_quotes
))
103 /* skip the remaining spaces */
104 while (*cs
==0x0009 || *cs
==0x0020) {
112 else if (*cs
==0x005c)
114 /* '\', count them */
117 else if ((*cs
==0x0022) && ((bcount
& 1)==0))
120 in_quotes
=!in_quotes
;
125 /* a regular character */
130 /* Allocate in a single lump, the string array, and the strings that go with it.
131 * This way the caller can make a single GlobalFree call to free both, as per MSDN.
133 argv
=LocalAlloc(LMEM_FIXED
, argc
*sizeof(LPWSTR
)+(wcslen(lpCmdline
)+1)*sizeof(WCHAR
));
136 cmdline
=(LPWSTR
)(argv
+argc
);
137 wcscpy(cmdline
, lpCmdline
);
145 if ((*s
==0x0009 || *s
==0x0020) && !in_quotes
)
147 /* Close the argument and copy it */
151 /* skip the remaining spaces */
154 } while (*s
==0x0009 || *s
==0x0020);
156 /* Start with a new argument */
171 /* Preceded by an even number of '\', this is half that
172 * number of '\', plus a quote which we erase.
175 in_quotes
=!in_quotes
;
180 /* Preceded by an odd number of '\', this is half that
181 * number of '\' followed by a '"'
191 /* a regular character */
207 static DWORD
shgfi_get_exe_type(LPCWSTR szFullPath
)
212 IMAGE_DOS_HEADER mz_header
;
217 status
= GetBinaryTypeW (szFullPath
, &BinaryType
);
220 if (BinaryType
== SCS_DOS_BINARY
|| BinaryType
== SCS_PIF_BINARY
)
223 hfile
= CreateFileW( szFullPath
, GENERIC_READ
, FILE_SHARE_READ
,
224 NULL
, OPEN_EXISTING
, 0, 0 );
225 if ( hfile
== INVALID_HANDLE_VALUE
)
229 * The next section is adapted from MODULE_GetBinaryType, as we need
230 * to examine the image header to get OS and version information. We
231 * know from calling GetBinaryTypeA that the image is valid and either
232 * an NE or PE, so much error handling can be omitted.
233 * Seek to the start of the file and read the header information.
236 SetFilePointer( hfile
, 0, NULL
, SEEK_SET
);
237 ReadFile( hfile
, &mz_header
, sizeof(mz_header
), &len
, NULL
);
239 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
240 ReadFile( hfile
, magic
, sizeof(magic
), &len
, NULL
);
241 if ( *(DWORD
*)magic
== IMAGE_NT_SIGNATURE
)
243 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
244 ReadFile( hfile
, &nt
, sizeof(nt
), &len
, NULL
);
245 CloseHandle( hfile
);
246 /* DLL files are not executable and should return 0 */
247 if (nt
.FileHeader
.Characteristics
& IMAGE_FILE_DLL
)
249 if (nt
.OptionalHeader
.Subsystem
== IMAGE_SUBSYSTEM_WINDOWS_GUI
)
251 return IMAGE_NT_SIGNATURE
|
252 (nt
.OptionalHeader
.MajorSubsystemVersion
<< 24) |
253 (nt
.OptionalHeader
.MinorSubsystemVersion
<< 16);
255 return IMAGE_NT_SIGNATURE
;
257 else if ( *(WORD
*)magic
== IMAGE_OS2_SIGNATURE
)
260 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
261 ReadFile( hfile
, &ne
, sizeof(ne
), &len
, NULL
);
262 CloseHandle( hfile
);
263 if (ne
.ne_exetyp
== 2)
264 return IMAGE_OS2_SIGNATURE
| (ne
.ne_expver
<< 16);
267 CloseHandle( hfile
);
271 /*************************************************************************
272 * SHELL_IsShortcut [internal]
274 * Decide if an item id list points to a shell shortcut
276 BOOL
SHELL_IsShortcut(LPCITEMIDLIST pidlLast
)
278 char szTemp
[MAX_PATH
];
282 if (_ILGetExtension(pidlLast
, szTemp
, MAX_PATH
) &&
283 HCR_MapTypeToValueA(szTemp
, szTemp
, MAX_PATH
, TRUE
))
285 if (ERROR_SUCCESS
== RegOpenKeyExA(HKEY_CLASSES_ROOT
, szTemp
, 0, KEY_QUERY_VALUE
, &keyCls
))
287 if (ERROR_SUCCESS
== RegQueryValueExA(keyCls
, "IsShortcut", NULL
, NULL
, NULL
, NULL
))
297 #define SHGFI_KNOWN_FLAGS \
298 (SHGFI_SMALLICON | SHGFI_OPENICON | SHGFI_SHELLICONSIZE | SHGFI_PIDL | \
299 SHGFI_USEFILEATTRIBUTES | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX | \
300 SHGFI_ICON | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ATTRIBUTES | \
301 SHGFI_ICONLOCATION | SHGFI_EXETYPE | SHGFI_SYSICONINDEX | \
302 SHGFI_LINKOVERLAY | SHGFI_SELECTED | SHGFI_ATTR_SPECIFIED)
304 /*************************************************************************
305 * SHGetFileInfoW [SHELL32.@]
308 DWORD_PTR WINAPI
SHGetFileInfoW(LPCWSTR path
,DWORD dwFileAttributes
,
309 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
311 WCHAR szLocation
[MAX_PATH
], szFullPath
[MAX_PATH
];
313 DWORD_PTR ret
= TRUE
;
314 DWORD dwAttributes
= 0;
315 IShellFolder
* psfParent
= NULL
;
316 IExtractIconW
* pei
= NULL
;
317 LPITEMIDLIST pidlLast
= NULL
, pidl
= NULL
;
319 BOOL IconNotYetLoaded
=TRUE
;
322 TRACE("%s fattr=0x%x sfi=%p(attr=0x%08x) size=0x%x flags=0x%x\n",
323 (flags
& SHGFI_PIDL
)? "pidl" : debugstr_w(path
), dwFileAttributes
,
324 psfi
, psfi
->dwAttributes
, sizeofpsfi
, flags
);
329 /* windows initializes these values regardless of the flags */
332 psfi
->szDisplayName
[0] = '\0';
333 psfi
->szTypeName
[0] = '\0';
337 if (!(flags
& SHGFI_PIDL
))
339 /* SHGetFileInfo should work with absolute and relative paths */
340 if (PathIsRelativeW(path
))
342 GetCurrentDirectoryW(MAX_PATH
, szLocation
);
343 PathCombineW(szFullPath
, szLocation
, path
);
347 lstrcpynW(szFullPath
, path
, MAX_PATH
);
351 if (flags
& SHGFI_EXETYPE
)
353 if (flags
!= SHGFI_EXETYPE
)
355 return shgfi_get_exe_type(szFullPath
);
359 * psfi is NULL normally to query EXE type. If it is NULL, none of the
360 * below makes sense anyway. Windows allows this and just returns FALSE
366 * translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES
368 * The pidl functions fail on not existing file names
371 if (flags
& SHGFI_PIDL
)
373 pidl
= ILClone((LPCITEMIDLIST
)path
);
375 else if (!(flags
& SHGFI_USEFILEATTRIBUTES
))
377 hr
= SHILCreateFromPathW(szFullPath
, &pidl
, &dwAttributes
);
380 if ((flags
& SHGFI_PIDL
) || !(flags
& SHGFI_USEFILEATTRIBUTES
))
382 /* get the parent shellfolder */
385 hr
= SHBindToParent( pidl
, &IID_IShellFolder
, (LPVOID
*)&psfParent
,
386 (LPCITEMIDLIST
*)&pidlLast
);
388 pidlLast
= ILClone(pidlLast
);
393 ERR("pidl is null!\n");
398 /* get the attributes of the child */
399 if (SUCCEEDED(hr
) && (flags
& SHGFI_ATTRIBUTES
))
401 if (!(flags
& SHGFI_ATTR_SPECIFIED
))
403 psfi
->dwAttributes
= 0xffffffff;
406 IShellFolder_GetAttributesOf( psfParent
, 1, (LPCITEMIDLIST
*)&pidlLast
,
407 &(psfi
->dwAttributes
) );
410 /* get the displayname */
411 if (SUCCEEDED(hr
) && (flags
& SHGFI_DISPLAYNAME
))
413 if (flags
& SHGFI_USEFILEATTRIBUTES
)
415 wcscpy (psfi
->szDisplayName
, PathFindFileNameW(szFullPath
));
420 hr
= IShellFolder_GetDisplayNameOf( psfParent
, pidlLast
,
421 SHGDN_INFOLDER
, &str
);
422 StrRetToStrNW (psfi
->szDisplayName
, MAX_PATH
, &str
, pidlLast
);
426 /* get the type name */
427 if (SUCCEEDED(hr
) && (flags
& SHGFI_TYPENAME
))
429 static const WCHAR szFile
[] = { 'F','i','l','e',0 };
430 static const WCHAR szDashFile
[] = { '-','f','i','l','e',0 };
432 if (!(flags
& SHGFI_USEFILEATTRIBUTES
))
436 _ILGetFileType(pidlLast
, ftype
, 80);
437 MultiByteToWideChar(CP_ACP
, 0, ftype
, -1, psfi
->szTypeName
, 80 );
441 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
442 wcscat (psfi
->szTypeName
, szFile
);
447 wcscpy(sTemp
,PathFindExtensionW(szFullPath
));
448 if (!( HCR_MapTypeToValueW(sTemp
, sTemp
, 64, TRUE
) &&
449 HCR_MapTypeToValueW(sTemp
, psfi
->szTypeName
, 80, FALSE
)))
451 lstrcpynW (psfi
->szTypeName
, sTemp
, 64);
452 wcscat (psfi
->szTypeName
, szDashFile
);
459 if (flags
& SHGFI_OPENICON
)
460 uGilFlags
|= GIL_OPENICON
;
462 if (flags
& SHGFI_LINKOVERLAY
)
463 uGilFlags
|= GIL_FORSHORTCUT
;
464 else if ((flags
&SHGFI_ADDOVERLAYS
) ||
465 (flags
&(SHGFI_ICON
|SHGFI_SMALLICON
))==SHGFI_ICON
)
467 if (SHELL_IsShortcut(pidlLast
))
468 uGilFlags
|= GIL_FORSHORTCUT
;
471 if (flags
& SHGFI_OVERLAYINDEX
)
472 FIXME("SHGFI_OVERLAYINDEX unhandled\n");
474 if (flags
& SHGFI_SELECTED
)
475 FIXME("set icon to selected, stub\n");
477 if (flags
& SHGFI_SHELLICONSIZE
)
478 FIXME("set icon to shell size, stub\n");
480 /* get the iconlocation */
481 if (SUCCEEDED(hr
) && (flags
& SHGFI_ICONLOCATION
))
485 if (flags
& SHGFI_USEFILEATTRIBUTES
)
487 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
489 wcscpy(psfi
->szDisplayName
, swShell32Name
);
490 psfi
->iIcon
= -IDI_SHELL_FOLDER
;
495 static const WCHAR p1W
[] = {'%','1',0};
496 WCHAR sTemp
[MAX_PATH
];
498 szExt
= PathFindExtensionW(szFullPath
);
499 TRACE("szExt=%s\n", debugstr_w(szExt
));
501 HCR_MapTypeToValueW(szExt
, sTemp
, MAX_PATH
, TRUE
) &&
502 HCR_GetDefaultIconW(sTemp
, sTemp
, MAX_PATH
, &psfi
->iIcon
))
504 if (lstrcmpW(p1W
, sTemp
))
505 wcscpy(psfi
->szDisplayName
, sTemp
);
508 /* the icon is in the file */
509 wcscpy(psfi
->szDisplayName
, szFullPath
);
518 hr
= IShellFolder_GetUIObjectOf(psfParent
, 0, 1,
519 (LPCITEMIDLIST
*)&pidlLast
, &IID_IExtractIconW
,
520 &uDummy
, (LPVOID
*)&pei
);
523 hr
= IExtractIconW_GetIconLocation(pei
, uGilFlags
,
524 szLocation
, MAX_PATH
, &iIndex
, &uFlags
);
526 if (uFlags
& GIL_NOTFILENAME
)
530 wcscpy (psfi
->szDisplayName
, szLocation
);
531 psfi
->iIcon
= iIndex
;
533 IExtractIconW_Release(pei
);
538 /* get icon index (or load icon)*/
539 if (SUCCEEDED(hr
) && (flags
& (SHGFI_ICON
| SHGFI_SYSICONINDEX
)))
541 if (flags
& SHGFI_USEFILEATTRIBUTES
&& !(flags
& SHGFI_PIDL
))
543 WCHAR sTemp
[MAX_PATH
];
547 lstrcpynW(sTemp
, szFullPath
, MAX_PATH
);
549 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
550 psfi
->iIcon
= SIC_GetIconIndex(swShell32Name
, -IDI_SHELL_FOLDER
, 0);
553 static const WCHAR p1W
[] = {'%','1',0};
556 szExt
= PathFindExtensionW(sTemp
);
558 HCR_MapTypeToValueW(szExt
, sTemp
, MAX_PATH
, TRUE
) &&
559 HCR_GetDefaultIconW(sTemp
, sTemp
, MAX_PATH
, &icon_idx
))
561 if (!lstrcmpW(p1W
,sTemp
)) /* icon is in the file */
562 wcscpy(sTemp
, szFullPath
);
564 if (flags
& SHGFI_SYSICONINDEX
)
566 psfi
->iIcon
= SIC_GetIconIndex(sTemp
,icon_idx
,0);
567 if (psfi
->iIcon
== -1)
573 if (flags
& SHGFI_SMALLICON
)
574 ret
= PrivateExtractIconsW( sTemp
,icon_idx
,
575 GetSystemMetrics( SM_CXSMICON
),
576 GetSystemMetrics( SM_CYSMICON
),
577 &psfi
->hIcon
, 0, 1, 0);
579 ret
= PrivateExtractIconsW( sTemp
, icon_idx
,
580 GetSystemMetrics( SM_CXICON
),
581 GetSystemMetrics( SM_CYICON
),
582 &psfi
->hIcon
, 0, 1, 0);
583 if (ret
!= 0 && ret
!= 0xFFFFFFFF)
585 IconNotYetLoaded
=FALSE
;
586 psfi
->iIcon
= icon_idx
;
594 if (!(PidlToSicIndex(psfParent
, pidlLast
, !(flags
& SHGFI_SMALLICON
),
595 uGilFlags
, &(psfi
->iIcon
))))
600 if (ret
&& (flags
& SHGFI_SYSICONINDEX
))
602 if (flags
& SHGFI_SMALLICON
)
603 ret
= (DWORD_PTR
) ShellSmallIconList
;
605 ret
= (DWORD_PTR
) ShellBigIconList
;
610 if (SUCCEEDED(hr
) && (flags
& SHGFI_ICON
) && IconNotYetLoaded
)
612 if (flags
& SHGFI_SMALLICON
)
613 psfi
->hIcon
= ImageList_GetIcon( ShellSmallIconList
, psfi
->iIcon
, ILD_NORMAL
);
615 psfi
->hIcon
= ImageList_GetIcon( ShellBigIconList
, psfi
->iIcon
, ILD_NORMAL
);
618 if (flags
& ~SHGFI_KNOWN_FLAGS
)
619 FIXME("unknown flags %08x\n", flags
& ~SHGFI_KNOWN_FLAGS
);
622 IShellFolder_Release(psfParent
);
630 TRACE ("icon=%p index=0x%08x attr=0x%08x name=%s type=%s ret=0x%08lx\n",
631 psfi
->hIcon
, psfi
->iIcon
, psfi
->dwAttributes
,
632 debugstr_w(psfi
->szDisplayName
), debugstr_w(psfi
->szTypeName
), ret
);
638 /*************************************************************************
639 * SHGetFileInfoA [SHELL32.@]
642 * MSVBVM60.__vbaNew2 expects this function to return a value in range
643 * 1 .. 0x7fff when the function succeeds and flags does not contain
644 * SHGFI_EXETYPE or SHGFI_SYSICONINDEX (see bug 7701)
646 DWORD_PTR WINAPI
SHGetFileInfoA(LPCSTR path
,DWORD dwFileAttributes
,
647 SHFILEINFOA
*psfi
, UINT sizeofpsfi
,
651 LPWSTR temppath
= NULL
;
654 SHFILEINFOW temppsfi
;
656 if (flags
& SHGFI_PIDL
)
658 /* path contains a pidl */
659 pathW
= (LPCWSTR
)path
;
663 len
= MultiByteToWideChar(CP_ACP
, 0, path
, -1, NULL
, 0);
664 temppath
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
665 MultiByteToWideChar(CP_ACP
, 0, path
, -1, temppath
, len
);
669 if (psfi
&& (flags
& SHGFI_ATTR_SPECIFIED
))
670 temppsfi
.dwAttributes
=psfi
->dwAttributes
;
673 ret
= SHGetFileInfoW(pathW
, dwFileAttributes
, NULL
, sizeof(temppsfi
), flags
);
675 ret
= SHGetFileInfoW(pathW
, dwFileAttributes
, &temppsfi
, sizeof(temppsfi
), flags
);
679 if(flags
& SHGFI_ICON
)
680 psfi
->hIcon
=temppsfi
.hIcon
;
681 if(flags
& (SHGFI_SYSICONINDEX
|SHGFI_ICON
|SHGFI_ICONLOCATION
))
682 psfi
->iIcon
=temppsfi
.iIcon
;
683 if(flags
& SHGFI_ATTRIBUTES
)
684 psfi
->dwAttributes
=temppsfi
.dwAttributes
;
685 if(flags
& (SHGFI_DISPLAYNAME
|SHGFI_ICONLOCATION
))
687 WideCharToMultiByte(CP_ACP
, 0, temppsfi
.szDisplayName
, -1,
688 psfi
->szDisplayName
, sizeof(psfi
->szDisplayName
), NULL
, NULL
);
690 if(flags
& SHGFI_TYPENAME
)
692 WideCharToMultiByte(CP_ACP
, 0, temppsfi
.szTypeName
, -1,
693 psfi
->szTypeName
, sizeof(psfi
->szTypeName
), NULL
, NULL
);
697 HeapFree(GetProcessHeap(), 0, temppath
);
702 /*************************************************************************
703 * DuplicateIcon [SHELL32.@]
705 HICON WINAPI
DuplicateIcon( HINSTANCE hInstance
, HICON hIcon
)
710 TRACE("%p %p\n", hInstance
, hIcon
);
712 if (GetIconInfo(hIcon
, &IconInfo
))
714 hDupIcon
= CreateIconIndirect(&IconInfo
);
716 /* clean up hbmMask and hbmColor */
717 DeleteObject(IconInfo
.hbmMask
);
718 DeleteObject(IconInfo
.hbmColor
);
724 /*************************************************************************
725 * ExtractIconA [SHELL32.@]
727 HICON WINAPI
ExtractIconA(HINSTANCE hInstance
, LPCSTR lpszFile
, UINT nIconIndex
)
730 INT len
= MultiByteToWideChar(CP_ACP
, 0, lpszFile
, -1, NULL
, 0);
731 LPWSTR lpwstrFile
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
733 TRACE("%p %s %d\n", hInstance
, lpszFile
, nIconIndex
);
735 MultiByteToWideChar(CP_ACP
, 0, lpszFile
, -1, lpwstrFile
, len
);
736 ret
= ExtractIconW(hInstance
, lpwstrFile
, nIconIndex
);
737 HeapFree(GetProcessHeap(), 0, lpwstrFile
);
742 /*************************************************************************
743 * ExtractIconW [SHELL32.@]
745 HICON WINAPI
ExtractIconW(HINSTANCE hInstance
, LPCWSTR lpszFile
, UINT nIconIndex
)
749 UINT cx
= GetSystemMetrics(SM_CXICON
), cy
= GetSystemMetrics(SM_CYICON
);
751 TRACE("%p %s %d\n", hInstance
, debugstr_w(lpszFile
), nIconIndex
);
753 if (nIconIndex
== 0xFFFFFFFF)
755 ret
= PrivateExtractIconsW(lpszFile
, 0, cx
, cy
, NULL
, NULL
, 0, LR_DEFAULTCOLOR
);
756 if (ret
!= 0xFFFFFFFF && ret
)
757 return (HICON
)(UINT_PTR
)ret
;
761 ret
= PrivateExtractIconsW(lpszFile
, nIconIndex
, cx
, cy
, &hIcon
, NULL
, 1, LR_DEFAULTCOLOR
);
763 if (ret
== 0xFFFFFFFF)
765 else if (ret
> 0 && hIcon
)
771 /*************************************************************************
772 * Printer_LoadIconsW [SHELL32.205]
774 VOID WINAPI
Printer_LoadIconsW(LPCWSTR wsPrinterName
, HICON
* pLargeIcon
, HICON
* pSmallIcon
)
776 INT iconindex
=IDI_SHELL_PRINTERS_FOLDER
;
778 TRACE("(%s, %p, %p)\n", debugstr_w(wsPrinterName
), pLargeIcon
, pSmallIcon
);
780 /* We should check if wsPrinterName is
781 1. the Default Printer or not
783 3. a Local Printer or a Network-Printer
784 and use different Icons
786 if((wsPrinterName
!= NULL
) && (wsPrinterName
[0] != 0))
788 FIXME("(select Icon by PrinterName %s not implemented)\n", debugstr_w(wsPrinterName
));
791 if(pLargeIcon
!= NULL
)
792 *pLargeIcon
= LoadImageW(shell32_hInstance
,
793 (LPCWSTR
) MAKEINTRESOURCE(iconindex
), IMAGE_ICON
,
794 0, 0, LR_DEFAULTCOLOR
|LR_DEFAULTSIZE
);
796 if(pSmallIcon
!= NULL
)
797 *pSmallIcon
= LoadImageW(shell32_hInstance
,
798 (LPCWSTR
) MAKEINTRESOURCE(iconindex
), IMAGE_ICON
,
799 16, 16, LR_DEFAULTCOLOR
);
802 /*************************************************************************
803 * Printers_RegisterWindowW [SHELL32.213]
804 * used by "printui.dll":
805 * find the Window of the given Type for the specific Printer and
806 * return the already existent hwnd or open a new window
808 BOOL WINAPI
Printers_RegisterWindowW(LPCWSTR wsPrinter
, DWORD dwType
,
809 HANDLE
* phClassPidl
, HWND
* phwnd
)
811 FIXME("(%s, %x, %p (%p), %p (%p)) stub!\n", debugstr_w(wsPrinter
), dwType
,
812 phClassPidl
, (phClassPidl
!= NULL
) ? *(phClassPidl
) : NULL
,
813 phwnd
, (phwnd
!= NULL
) ? *(phwnd
) : NULL
);
818 /*************************************************************************
819 * Printers_UnregisterWindow [SHELL32.214]
821 VOID WINAPI
Printers_UnregisterWindow(HANDLE hClassPidl
, HWND hwnd
)
823 FIXME("(%p, %p) stub!\n", hClassPidl
, hwnd
);
826 /*************************************************************************/
831 LPCWSTR szOtherStuff
;
835 #define DROP_FIELD_TOP (-15)
836 #define DROP_FIELD_HEIGHT 15
838 /*************************************************************************
839 * SHAppBarMessage [SHELL32.@]
841 UINT_PTR WINAPI
SHAppBarMessage(DWORD msg
, PAPPBARDATA data
)
843 int width
=data
->rc
.right
- data
->rc
.left
;
844 int height
=data
->rc
.bottom
- data
->rc
.top
;
847 TRACE("msg=%d, data={cb=%d, hwnd=%p, callback=%x, edge=%d, rc=%s, lparam=%lx}\n",
848 msg
, data
->cbSize
, data
->hWnd
, data
->uCallbackMessage
, data
->uEdge
,
849 wine_dbgstr_rect(&data
->rc
), data
->lParam
);
854 return ABS_ALWAYSONTOP
| ABS_AUTOHIDE
;
855 case ABM_GETTASKBARPOS
:
856 GetWindowRect(data
->hWnd
, &rec
);
860 SetActiveWindow(data
->hWnd
);
862 case ABM_GETAUTOHIDEBAR
:
863 return 0; /* pretend there is no autohide bar */
865 /* cbSize, hWnd, and uCallbackMessage are used. All other ignored */
866 SetWindowPos(data
->hWnd
,HWND_TOP
,0,0,0,0,SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOSIZE
);
869 GetWindowRect(data
->hWnd
, &(data
->rc
));
872 FIXME("ABM_REMOVE broken\n");
873 /* FIXME: this is wrong; should it be DestroyWindow instead? */
874 /*CloseHandle(data->hWnd);*/
876 case ABM_SETAUTOHIDEBAR
:
877 SetWindowPos(data
->hWnd
,HWND_TOP
,rec
.left
+1000,rec
.top
,
878 width
,height
,SWP_SHOWWINDOW
);
881 data
->uEdge
=(ABE_RIGHT
| ABE_LEFT
);
882 SetWindowPos(data
->hWnd
,HWND_TOP
,data
->rc
.left
,data
->rc
.top
,
883 width
,height
,SWP_SHOWWINDOW
);
885 case ABM_WINDOWPOSCHANGED
:
891 /*************************************************************************
892 * SHHelpShortcuts_RunDLLA [SHELL32.@]
895 DWORD WINAPI
SHHelpShortcuts_RunDLLA(DWORD dwArg1
, DWORD dwArg2
, DWORD dwArg3
, DWORD dwArg4
)
897 FIXME("(%x, %x, %x, %x) stub!\n", dwArg1
, dwArg2
, dwArg3
, dwArg4
);
901 /*************************************************************************
902 * SHHelpShortcuts_RunDLLA [SHELL32.@]
905 DWORD WINAPI
SHHelpShortcuts_RunDLLW(DWORD dwArg1
, DWORD dwArg2
, DWORD dwArg3
, DWORD dwArg4
)
907 FIXME("(%x, %x, %x, %x) stub!\n", dwArg1
, dwArg2
, dwArg3
, dwArg4
);
911 /*************************************************************************
912 * SHLoadInProc [SHELL32.@]
913 * Create an instance of specified object class from within
914 * the shell process and release it immediately
916 HRESULT WINAPI
SHLoadInProc (REFCLSID rclsid
)
920 TRACE("%s\n", debugstr_guid(rclsid
));
922 CoCreateInstance(rclsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,&ptr
);
925 IUnknown
* pUnk
= ptr
;
926 IUnknown_Release(pUnk
);
929 return DISP_E_MEMBERNOTFOUND
;
932 static VOID
SetRegTextData(HWND hWnd
, HKEY hKey
, LPWSTR Value
, UINT uID
)
938 if( RegQueryValueExW(hKey
, Value
, NULL
, &dwType
, NULL
, &dwBufferSize
) == ERROR_SUCCESS
)
942 lpBuffer
= HeapAlloc(GetProcessHeap(), 0, dwBufferSize
);
946 if( RegQueryValueExW(hKey
, Value
, NULL
, &dwType
, (LPBYTE
)lpBuffer
, &dwBufferSize
) == ERROR_SUCCESS
)
948 SetDlgItemTextW(hWnd
, uID
, lpBuffer
);
951 HeapFree(GetProcessHeap(), 0, lpBuffer
);
957 INT_PTR CALLBACK
AboutAuthorsDlgProc( HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
963 const char* const *pstr
= SHELL_Authors
;
965 // Add the authors to the list
966 SendDlgItemMessageW( hWnd
, IDC_SHELL_ABOUT_AUTHORS_LISTBOX
, WM_SETREDRAW
, FALSE
, 0 );
972 /* authors list is in utf-8 format */
973 MultiByteToWideChar( CP_UTF8
, 0, *pstr
, -1, name
, sizeof(name
)/sizeof(WCHAR
) );
974 SendDlgItemMessageW( hWnd
, IDC_SHELL_ABOUT_AUTHORS_LISTBOX
, LB_ADDSTRING
, (WPARAM
)-1, (LPARAM
)name
);
978 SendDlgItemMessageW( hWnd
, IDC_SHELL_ABOUT_AUTHORS_LISTBOX
, WM_SETREDRAW
, TRUE
, 0 );
986 /*************************************************************************
987 * AboutDlgProc (internal)
989 INT_PTR CALLBACK
AboutDlgProc( HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
991 static DWORD cxLogoBmp
;
992 static DWORD cyLogoBmp
;
993 static HBITMAP hLogoBmp
;
994 static HWND hWndAuthors
;
1000 ABOUT_INFO
*info
= (ABOUT_INFO
*)lParam
;
1004 const WCHAR szRegKey
[] = L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
1006 MEMORYSTATUSEX MemStat
;
1007 WCHAR szAppTitle
[512];
1008 WCHAR szAppTitleTemplate
[512];
1009 WCHAR szAuthorsText
[20];
1011 // Preload the ROS bitmap
1012 hLogoBmp
= LoadImage(shell32_hInstance
, MAKEINTRESOURCE(IDB_SHELL_ABOUT_LOGO_24BPP
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1018 GetObject( hLogoBmp
, sizeof(BITMAP
), &bmpLogo
);
1020 cxLogoBmp
= bmpLogo
.bmWidth
;
1021 cyLogoBmp
= bmpLogo
.bmHeight
;
1024 // Set App-specific stuff (icon, app name, szOtherStuff string)
1025 SendDlgItemMessageW(hWnd
, IDC_SHELL_ABOUT_ICON
, STM_SETICON
, (WPARAM
)info
->hIcon
, 0);
1027 GetWindowTextW( hWnd
, szAppTitleTemplate
, sizeof(szAppTitleTemplate
) / sizeof(WCHAR
) );
1028 swprintf( szAppTitle
, szAppTitleTemplate
, info
->szApp
);
1029 SetWindowTextW( hWnd
, szAppTitle
);
1031 SetDlgItemTextW( hWnd
, IDC_SHELL_ABOUT_APPNAME
, info
->szApp
);
1032 SetDlgItemTextW( hWnd
, IDC_SHELL_ABOUT_OTHERSTUFF
, info
->szOtherStuff
);
1034 // Set the registered user and organization name
1035 if(RegOpenKeyExW( HKEY_LOCAL_MACHINE
, szRegKey
, 0, KEY_QUERY_VALUE
, &hRegKey
) == ERROR_SUCCESS
)
1037 SetRegTextData( hWnd
, hRegKey
, L
"RegisteredOwner", IDC_SHELL_ABOUT_REG_USERNAME
);
1038 SetRegTextData( hWnd
, hRegKey
, L
"RegisteredOrganization", IDC_SHELL_ABOUT_REG_ORGNAME
);
1040 RegCloseKey( hRegKey
);
1043 // Set the value for the installed physical memory
1044 MemStat
.dwLength
= sizeof(MemStat
);
1045 if( GlobalMemoryStatusEx(&MemStat
) )
1049 if (MemStat
.ullTotalPhys
> 1024 * 1024 * 1024)
1052 WCHAR szDecimalSeparator
[4];
1055 // We're dealing with GBs or more
1056 MemStat
.ullTotalPhys
/= 1024 * 1024;
1058 if (MemStat
.ullTotalPhys
> 1024 * 1024)
1060 // We're dealing with TBs or more
1061 MemStat
.ullTotalPhys
/= 1024;
1063 if (MemStat
.ullTotalPhys
> 1024 * 1024)
1065 // We're dealing with PBs or more
1066 MemStat
.ullTotalPhys
/= 1024;
1068 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
1069 wcscpy( szUnits
, L
"PB" );
1073 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
1074 wcscpy( szUnits
, L
"TB" );
1079 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
1080 wcscpy( szUnits
, L
"GB" );
1083 // We need the decimal point of the current locale to display the RAM size correctly
1084 if( GetLocaleInfoW(LOCALE_USER_DEFAULT
, LOCALE_SDECIMAL
, szDecimalSeparator
, sizeof(szDecimalSeparator
) / sizeof(WCHAR
)) > 0)
1089 uIntegral
= (UINT
)dTotalPhys
;
1090 uDecimals
= (UCHAR
)((UINT
)(dTotalPhys
* 100) - uIntegral
* 100);
1092 // Display the RAM size with 2 decimals
1093 swprintf(szBuf
, L
"%u%s%02u %s", uIntegral
, szDecimalSeparator
, uDecimals
, szUnits
);
1098 // We're dealing with MBs, don't show any decimals
1099 swprintf( szBuf
, L
"%u MB", (UINT
)MemStat
.ullTotalPhys
/ 1024 / 1024 );
1102 SetDlgItemTextW( hWnd
, IDC_SHELL_ABOUT_PHYSMEM
, szBuf
);
1105 // Add the Authors dialog
1106 hWndAuthors
= CreateDialogW( shell32_hInstance
, MAKEINTRESOURCEW(IDD_SHELL_ABOUT_AUTHORS
), hWnd
, AboutAuthorsDlgProc
);
1107 LoadStringW( shell32_hInstance
, IDS_SHELL_ABOUT_AUTHORS
, szAuthorsText
, sizeof(szAuthorsText
) / sizeof(WCHAR
) );
1108 SetDlgItemTextW( hWnd
, IDC_SHELL_ABOUT_AUTHORS
, szAuthorsText
);
1122 hdc
= BeginPaint(hWnd
, &ps
);
1123 hdcMem
= CreateCompatibleDC(hdc
);
1127 SelectObject(hdcMem
, hLogoBmp
);
1128 BitBlt(hdc
, 0, 0, cxLogoBmp
, cyLogoBmp
, hdcMem
, 0, 0, SRCCOPY
);
1133 EndPaint(hWnd
, &ps
);
1144 EndDialog(hWnd
, TRUE
);
1147 case IDC_SHELL_ABOUT_AUTHORS
:
1149 static BOOL bShowingAuthors
= FALSE
;
1150 WCHAR szAuthorsText
[20];
1154 LoadStringW( shell32_hInstance
, IDS_SHELL_ABOUT_AUTHORS
, szAuthorsText
, sizeof(szAuthorsText
) / sizeof(WCHAR
) );
1155 ShowWindow( hWndAuthors
, SW_HIDE
);
1159 LoadStringW( shell32_hInstance
, IDS_SHELL_ABOUT_BACK
, szAuthorsText
, sizeof(szAuthorsText
) / sizeof(WCHAR
) );
1160 ShowWindow( hWndAuthors
, SW_SHOW
);
1163 SetDlgItemTextW( hWnd
, IDC_SHELL_ABOUT_AUTHORS
, szAuthorsText
);
1164 bShowingAuthors
= !bShowingAuthors
;
1171 EndDialog(hWnd
, TRUE
);
1179 /*************************************************************************
1180 * ShellAboutA [SHELL32.288]
1182 BOOL WINAPI
ShellAboutA( HWND hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
, HICON hIcon
)
1185 LPWSTR appW
= NULL
, otherW
= NULL
;
1190 len
= MultiByteToWideChar(CP_ACP
, 0, szApp
, -1, NULL
, 0);
1191 appW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1192 MultiByteToWideChar(CP_ACP
, 0, szApp
, -1, appW
, len
);
1196 len
= MultiByteToWideChar(CP_ACP
, 0, szOtherStuff
, -1, NULL
, 0);
1197 otherW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1198 MultiByteToWideChar(CP_ACP
, 0, szOtherStuff
, -1, otherW
, len
);
1201 ret
= ShellAboutW(hWnd
, appW
, otherW
, hIcon
);
1203 HeapFree(GetProcessHeap(), 0, otherW
);
1204 HeapFree(GetProcessHeap(), 0, appW
);
1209 /*************************************************************************
1210 * ShellAboutW [SHELL32.289]
1212 BOOL WINAPI
ShellAboutW( HWND hWnd
, LPCWSTR szApp
, LPCWSTR szOtherStuff
,
1222 // DialogBoxIndirectParamW will be called with the hInstance of the calling application, so we have to preload the dialog template
1223 if(!(hRes
= FindResourceW(shell32_hInstance
, MAKEINTRESOURCEW(IDD_SHELL_ABOUT
), (LPWSTR
)RT_DIALOG
)))
1225 if(!(DlgTemplate
= (LPVOID
)LoadResource(shell32_hInstance
, hRes
)))
1229 info
.szOtherStuff
= szOtherStuff
;
1230 info
.hIcon
= hIcon
? hIcon
: LoadIconW( 0, (LPWSTR
)IDI_WINLOGO
);
1232 bRet
= DialogBoxIndirectParamW((HINSTANCE
)GetWindowLongPtrW( hWnd
, GWLP_HINSTANCE
),
1233 DlgTemplate
, hWnd
, AboutDlgProc
, (LPARAM
)&info
);
1237 /*************************************************************************
1238 * FreeIconList (SHELL32.@)
1240 void WINAPI
FreeIconList( DWORD dw
)
1242 FIXME("%x: stub\n",dw
);
1245 /*************************************************************************
1246 * SHLoadNonloadedIconOverlayIdentifiers (SHELL32.@)
1248 HRESULT WINAPI
SHLoadNonloadedIconOverlayIdentifiers( VOID
)
1254 /***********************************************************************
1255 * DllGetVersion [SHELL32.@]
1257 * Retrieves version information of the 'SHELL32.DLL'
1260 * pdvi [O] pointer to version information structure.
1264 * Failure: E_INVALIDARG
1267 * Returns version of a shell32.dll from IE4.01 SP1.
1270 HRESULT WINAPI
DllGetVersion (DLLVERSIONINFO
*pdvi
)
1272 /* FIXME: shouldn't these values come from the version resource? */
1273 if (pdvi
->cbSize
== sizeof(DLLVERSIONINFO
) ||
1274 pdvi
->cbSize
== sizeof(DLLVERSIONINFO2
))
1276 pdvi
->dwMajorVersion
= WINE_FILEVERSION_MAJOR
;
1277 pdvi
->dwMinorVersion
= WINE_FILEVERSION_MINOR
;
1278 pdvi
->dwBuildNumber
= WINE_FILEVERSION_BUILD
;
1279 pdvi
->dwPlatformID
= WINE_FILEVERSION_PLATFORMID
;
1280 if (pdvi
->cbSize
== sizeof(DLLVERSIONINFO2
))
1282 DLLVERSIONINFO2
*pdvi2
= (DLLVERSIONINFO2
*)pdvi
;
1285 pdvi2
->ullVersion
= MAKEDLLVERULL(WINE_FILEVERSION_MAJOR
,
1286 WINE_FILEVERSION_MINOR
,
1287 WINE_FILEVERSION_BUILD
,
1288 WINE_FILEVERSION_PLATFORMID
);
1290 TRACE("%u.%u.%u.%u\n",
1291 pdvi
->dwMajorVersion
, pdvi
->dwMinorVersion
,
1292 pdvi
->dwBuildNumber
, pdvi
->dwPlatformID
);
1297 WARN("wrong DLLVERSIONINFO size from app\n");
1298 return E_INVALIDARG
;
1302 /*************************************************************************
1303 * global variables of the shell32.dll
1304 * all are once per process
1307 HINSTANCE shell32_hInstance
= 0;
1308 HIMAGELIST ShellSmallIconList
= 0;
1309 HIMAGELIST ShellBigIconList
= 0;
1312 /*************************************************************************
1316 * calling oleinitialize here breaks sone apps.
1318 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID fImpLoad
)
1320 TRACE("%p 0x%x %p\n", hinstDLL
, fdwReason
, fImpLoad
);
1324 case DLL_PROCESS_ATTACH
:
1325 shell32_hInstance
= hinstDLL
;
1326 DisableThreadLibraryCalls(shell32_hInstance
);
1328 /* get full path to this DLL for IExtractIconW_fnGetIconLocation() */
1329 GetModuleFileNameW(hinstDLL
, swShell32Name
, MAX_PATH
);
1330 swShell32Name
[MAX_PATH
- 1] = '\0';
1332 InitCommonControlsEx(NULL
);
1335 InitChangeNotifications();
1339 case DLL_PROCESS_DETACH
:
1340 shell32_hInstance
= 0;
1342 FreeChangeNotifications();
1348 /*************************************************************************
1349 * DllInstall [SHELL32.@]
1353 * BOOL bInstall - TRUE for install, FALSE for uninstall
1354 * LPCWSTR pszCmdLine - command line (unused by shell32?)
1357 HRESULT WINAPI
DllInstall(BOOL bInstall
, LPCWSTR cmdline
)
1359 FIXME("%s %s: stub\n", bInstall
? "TRUE":"FALSE", debugstr_w(cmdline
));
1360 return S_OK
; /* indicate success */
1363 /***********************************************************************
1364 * DllCanUnloadNow (SHELL32.@)
1366 HRESULT WINAPI
DllCanUnloadNow(void)