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
41 #include "commoncontrols.h"
44 #include "shell32_main.h"
50 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
54 static DWORD
shgfi_get_exe_type(LPCWSTR szFullPath
)
59 IMAGE_DOS_HEADER mz_header
;
64 status
= GetBinaryTypeW (szFullPath
, &BinaryType
);
67 if (BinaryType
== SCS_DOS_BINARY
|| BinaryType
== SCS_PIF_BINARY
)
70 hfile
= CreateFileW( szFullPath
, GENERIC_READ
, FILE_SHARE_READ
,
71 NULL
, OPEN_EXISTING
, 0, 0 );
72 if ( hfile
== INVALID_HANDLE_VALUE
)
76 * The next section is adapted from MODULE_GetBinaryType, as we need
77 * to examine the image header to get OS and version information. We
78 * know from calling GetBinaryTypeA that the image is valid and either
79 * an NE or PE, so much error handling can be omitted.
80 * Seek to the start of the file and read the header information.
83 SetFilePointer( hfile
, 0, NULL
, SEEK_SET
);
84 ReadFile( hfile
, &mz_header
, sizeof(mz_header
), &len
, NULL
);
86 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
87 ReadFile( hfile
, magic
, sizeof(magic
), &len
, NULL
);
88 if ( *(DWORD
*)magic
== IMAGE_NT_SIGNATURE
)
90 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
91 ReadFile( hfile
, &nt
, sizeof(nt
), &len
, NULL
);
93 /* DLL files are not executable and should return 0 */
94 if (nt
.FileHeader
.Characteristics
& IMAGE_FILE_DLL
)
96 if (nt
.OptionalHeader
.Subsystem
== IMAGE_SUBSYSTEM_WINDOWS_GUI
)
98 return IMAGE_NT_SIGNATURE
|
99 (nt
.OptionalHeader
.MajorSubsystemVersion
<< 24) |
100 (nt
.OptionalHeader
.MinorSubsystemVersion
<< 16);
102 return IMAGE_NT_SIGNATURE
;
104 else if ( *(WORD
*)magic
== IMAGE_OS2_SIGNATURE
)
107 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
108 ReadFile( hfile
, &ne
, sizeof(ne
), &len
, NULL
);
109 CloseHandle( hfile
);
110 if (ne
.ne_exetyp
== 2)
111 return IMAGE_OS2_SIGNATURE
| (ne
.ne_expver
<< 16);
114 CloseHandle( hfile
);
118 /*************************************************************************
119 * SHELL_IsShortcut [internal]
121 * Decide if an item id list points to a shell shortcut
123 BOOL
SHELL_IsShortcut(LPCITEMIDLIST pidlLast
)
125 char szTemp
[MAX_PATH
];
129 if (_ILGetExtension(pidlLast
, szTemp
, MAX_PATH
) &&
130 HCR_MapTypeToValueA(szTemp
, szTemp
, MAX_PATH
, TRUE
))
132 if (ERROR_SUCCESS
== RegOpenKeyExA(HKEY_CLASSES_ROOT
, szTemp
, 0, KEY_QUERY_VALUE
, &keyCls
))
134 if (ERROR_SUCCESS
== RegQueryValueExA(keyCls
, "IsShortcut", NULL
, NULL
, NULL
, NULL
))
144 #define SHGFI_KNOWN_FLAGS \
145 (SHGFI_SMALLICON | SHGFI_OPENICON | SHGFI_SHELLICONSIZE | SHGFI_PIDL | \
146 SHGFI_USEFILEATTRIBUTES | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX | \
147 SHGFI_ICON | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ATTRIBUTES | \
148 SHGFI_ICONLOCATION | SHGFI_EXETYPE | SHGFI_SYSICONINDEX | \
149 SHGFI_LINKOVERLAY | SHGFI_SELECTED | SHGFI_ATTR_SPECIFIED)
151 /*************************************************************************
152 * SHGetFileInfoW [SHELL32.@]
155 DWORD_PTR WINAPI
SHGetFileInfoW(LPCWSTR path
,DWORD dwFileAttributes
,
156 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
158 WCHAR szLocation
[MAX_PATH
], szFullPath
[MAX_PATH
];
160 DWORD_PTR ret
= TRUE
;
161 DWORD dwAttributes
= 0;
162 IShellFolder
* psfParent
= NULL
;
163 IExtractIconW
* pei
= NULL
;
164 LPITEMIDLIST pidlLast
= NULL
, pidl
= NULL
;
168 TRACE("%s fattr=0x%lx sfi=%p(attr=0x%08lx) size=0x%x flags=0x%x\n",
169 (flags
& SHGFI_PIDL
)? "pidl" : debugstr_w(path
), dwFileAttributes
,
170 psfi
, psfi
? psfi
->dwAttributes
: 0, sizeofpsfi
, flags
);
175 /* windows initializes these values regardless of the flags */
178 psfi
->szDisplayName
[0] = '\0';
179 psfi
->szTypeName
[0] = '\0';
183 if (!(flags
& SHGFI_PIDL
))
185 /* SHGetFileInfo should work with absolute and relative paths */
186 if (PathIsRelativeW(path
))
188 GetCurrentDirectoryW(MAX_PATH
, szLocation
);
189 PathCombineW(szFullPath
, szLocation
, path
);
193 lstrcpynW(szFullPath
, path
, MAX_PATH
);
197 if (flags
& SHGFI_EXETYPE
)
199 if (flags
!= SHGFI_EXETYPE
)
201 return shgfi_get_exe_type(szFullPath
);
205 * psfi is NULL normally to query EXE type. If it is NULL, none of the
206 * below makes sense anyway. Windows allows this and just returns FALSE
212 * translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES
214 * The pidl functions fail on not existing file names
217 if (flags
& SHGFI_PIDL
)
219 pidl
= ILClone((LPCITEMIDLIST
)path
);
221 else if (!(flags
& SHGFI_USEFILEATTRIBUTES
))
223 hr
= SHILCreateFromPathW(szFullPath
, &pidl
, &dwAttributes
);
226 if ((flags
& SHGFI_PIDL
) || !(flags
& SHGFI_USEFILEATTRIBUTES
))
228 /* get the parent shellfolder */
231 hr
= SHBindToParent( pidl
, &IID_IShellFolder
, (LPVOID
*)&psfParent
,
232 (LPCITEMIDLIST
*)&pidlLast
);
234 pidlLast
= ILClone(pidlLast
);
239 ERR("pidl is null!\n");
244 /* get the attributes of the child */
245 if (SUCCEEDED(hr
) && (flags
& SHGFI_ATTRIBUTES
))
247 if (!(flags
& SHGFI_ATTR_SPECIFIED
))
249 psfi
->dwAttributes
= 0xffffffff;
252 IShellFolder_GetAttributesOf( psfParent
, 1, (LPCITEMIDLIST
*)&pidlLast
,
253 &(psfi
->dwAttributes
) );
256 /* get the displayname */
257 if (SUCCEEDED(hr
) && (flags
& SHGFI_DISPLAYNAME
))
259 if (flags
& SHGFI_USEFILEATTRIBUTES
&& !(flags
& SHGFI_PIDL
))
261 lstrcpyW (psfi
->szDisplayName
, PathFindFileNameW(szFullPath
));
266 hr
= IShellFolder_GetDisplayNameOf( psfParent
, pidlLast
,
267 SHGDN_INFOLDER
, &str
);
268 StrRetToStrNW (psfi
->szDisplayName
, MAX_PATH
, &str
, pidlLast
);
272 /* get the type name */
273 if (SUCCEEDED(hr
) && (flags
& SHGFI_TYPENAME
))
275 if (!(flags
& SHGFI_USEFILEATTRIBUTES
) || (flags
& SHGFI_PIDL
))
279 _ILGetFileType(pidlLast
, ftype
, 80);
280 MultiByteToWideChar(CP_ACP
, 0, ftype
, -1, psfi
->szTypeName
, 80 );
284 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
285 lstrcatW (psfi
->szTypeName
, L
"Folder");
290 lstrcpyW(sTemp
,PathFindExtensionW(szFullPath
));
291 if (sTemp
[0] == 0 || (sTemp
[0] == '.' && sTemp
[1] == 0))
293 /* "name" or "name." => "File" */
294 lstrcpynW (psfi
->szTypeName
, L
"File", 64);
296 else if (!( HCR_MapTypeToValueW(sTemp
, sTemp
, 64, TRUE
) &&
297 HCR_MapTypeToValueW(sTemp
, psfi
->szTypeName
, 80, FALSE
)))
301 lstrcpynW (psfi
->szTypeName
, sTemp
, 64);
302 lstrcatW (psfi
->szTypeName
, L
" file");
306 lstrcpynW (psfi
->szTypeName
, L
"File", 64);
314 if (flags
& SHGFI_OPENICON
)
315 uGilFlags
|= GIL_OPENICON
;
317 if (flags
& SHGFI_LINKOVERLAY
)
318 uGilFlags
|= GIL_FORSHORTCUT
;
319 else if ((flags
&SHGFI_ADDOVERLAYS
) ||
320 (flags
&(SHGFI_ICON
|SHGFI_SMALLICON
))==SHGFI_ICON
)
322 if (SHELL_IsShortcut(pidlLast
))
323 uGilFlags
|= GIL_FORSHORTCUT
;
326 if (flags
& SHGFI_OVERLAYINDEX
)
327 FIXME("SHGFI_OVERLAYINDEX unhandled\n");
329 if (flags
& SHGFI_SELECTED
)
330 FIXME("set icon to selected, stub\n");
332 /* get the iconlocation */
333 if (SUCCEEDED(hr
) && (flags
& SHGFI_ICONLOCATION
))
337 if (flags
& SHGFI_USEFILEATTRIBUTES
&& !(flags
& SHGFI_PIDL
))
339 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
341 lstrcpyW(psfi
->szDisplayName
, swShell32Name
);
342 psfi
->iIcon
= -IDI_SHELL_FOLDER
;
347 WCHAR sTemp
[MAX_PATH
];
349 szExt
= PathFindExtensionW(szFullPath
);
350 TRACE("szExt=%s\n", debugstr_w(szExt
));
352 HCR_MapTypeToValueW(szExt
, sTemp
, MAX_PATH
, TRUE
) &&
353 HCR_GetDefaultIconW(sTemp
, sTemp
, MAX_PATH
, &psfi
->iIcon
))
355 if (wcscmp(L
"%1", sTemp
))
356 lstrcpyW(psfi
->szDisplayName
, sTemp
);
359 /* the icon is in the file */
360 lstrcpyW(psfi
->szDisplayName
, szFullPath
);
369 hr
= IShellFolder_GetUIObjectOf(psfParent
, 0, 1,
370 (LPCITEMIDLIST
*)&pidlLast
, &IID_IExtractIconW
,
371 &uDummy
, (LPVOID
*)&pei
);
374 hr
= IExtractIconW_GetIconLocation(pei
, uGilFlags
,
375 szLocation
, MAX_PATH
, &iIndex
, &uFlags
);
377 if (uFlags
& GIL_NOTFILENAME
)
381 lstrcpyW (psfi
->szDisplayName
, szLocation
);
382 psfi
->iIcon
= iIndex
;
384 IExtractIconW_Release(pei
);
389 /* get icon index (or load icon)*/
390 if (SUCCEEDED(hr
) && (flags
& (SHGFI_ICON
| SHGFI_SYSICONINDEX
)))
392 IImageList
*icon_list
;
393 SHGetImageList( (flags
& SHGFI_SMALLICON
) ? SHIL_SMALL
: SHIL_LARGE
, &IID_IImageList
, (void **)&icon_list
);
395 if (flags
& SHGFI_USEFILEATTRIBUTES
&& !(flags
& SHGFI_PIDL
))
397 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
398 psfi
->iIcon
= SIC_GetIconIndex(swShell32Name
, -IDI_SHELL_FOLDER
, 0);
401 WCHAR sTemp
[MAX_PATH
];
405 lstrcpynW(sTemp
, szFullPath
, MAX_PATH
);
408 szExt
= PathFindExtensionW(sTemp
);
410 HCR_MapTypeToValueW(szExt
, sTemp
, MAX_PATH
, TRUE
) &&
411 HCR_GetDefaultIconW(sTemp
, sTemp
, MAX_PATH
, &icon_idx
))
413 if (!wcscmp(L
"%1",sTemp
)) /* icon is in the file */
414 lstrcpyW(sTemp
, szFullPath
);
416 psfi
->iIcon
= SIC_GetIconIndex(sTemp
, icon_idx
, 0);
417 if (psfi
->iIcon
== -1)
424 if (!(PidlToSicIndex(psfParent
, pidlLast
, !(flags
& SHGFI_SMALLICON
),
425 uGilFlags
, &(psfi
->iIcon
))))
430 if (ret
&& (flags
& SHGFI_SYSICONINDEX
))
432 IImageList_AddRef( icon_list
);
433 ret
= (DWORD_PTR
)icon_list
;
435 if (ret
&& (flags
& SHGFI_ICON
))
437 if (flags
& SHGFI_SHELLICONSIZE
)
438 hr
= IImageList_GetIcon( icon_list
, psfi
->iIcon
, ILD_NORMAL
, &psfi
->hIcon
);
441 int width
= GetSystemMetrics( (flags
& SHGFI_SMALLICON
) ? SM_CXSMICON
: SM_CXICON
);
442 int height
= GetSystemMetrics( (flags
& SHGFI_SMALLICON
) ? SM_CYSMICON
: SM_CYICON
);
443 int list_width
, list_height
;
445 IImageList_GetIconSize( icon_list
, &list_width
, &list_height
);
446 if (list_width
== width
&& list_height
== height
)
447 hr
= IImageList_GetIcon( icon_list
, psfi
->iIcon
, ILD_NORMAL
, &psfi
->hIcon
);
448 else /* Use SHIL_SYSSMALL for SHFI_SMALLICONS when we implement it */
450 WCHAR buf
[MAX_PATH
], *file
= buf
;
451 DWORD size
= sizeof(buf
);
454 while ((hr
= SIC_get_location( psfi
->iIcon
, file
, &size
, &icon_idx
)) == E_NOT_SUFFICIENT_BUFFER
)
456 if (file
== buf
) file
= malloc( size
);
457 else file
= realloc( file
, size
);
462 ret
= PrivateExtractIconsW( file
, icon_idx
, width
, height
, &psfi
->hIcon
, 0, 1, 0);
463 if (ret
== 0 || ret
== (UINT
)-1) hr
= E_FAIL
;
465 if (file
!= buf
) free( file
);
469 IImageList_Release( icon_list
);
472 if (flags
& ~SHGFI_KNOWN_FLAGS
)
473 FIXME("unknown flags %08x\n", flags
& ~SHGFI_KNOWN_FLAGS
);
476 IShellFolder_Release(psfParent
);
483 TRACE ("icon=%p index=0x%08x attr=0x%08lx name=%s type=%s ret=0x%08Ix\n",
484 psfi
->hIcon
, psfi
->iIcon
, psfi
->dwAttributes
,
485 debugstr_w(psfi
->szDisplayName
), debugstr_w(psfi
->szTypeName
), ret
);
490 /*************************************************************************
491 * SHGetFileInfoA [SHELL32.@]
494 * MSVBVM60.__vbaNew2 expects this function to return a value in range
495 * 1 .. 0x7fff when the function succeeds and flags does not contain
496 * SHGFI_EXETYPE or SHGFI_SYSICONINDEX (see bug 7701)
498 DWORD_PTR WINAPI
SHGetFileInfoA(LPCSTR path
,DWORD dwFileAttributes
,
499 SHFILEINFOA
*psfi
, UINT sizeofpsfi
,
503 LPWSTR temppath
= NULL
;
506 SHFILEINFOW temppsfi
;
508 if (flags
& SHGFI_PIDL
)
510 /* path contains a pidl */
511 pathW
= (LPCWSTR
)path
;
515 len
= MultiByteToWideChar(CP_ACP
, 0, path
, -1, NULL
, 0);
516 temppath
= malloc(len
* sizeof(WCHAR
));
517 MultiByteToWideChar(CP_ACP
, 0, path
, -1, temppath
, len
);
521 if (psfi
&& (flags
& SHGFI_ATTR_SPECIFIED
))
522 temppsfi
.dwAttributes
=psfi
->dwAttributes
;
525 ret
= SHGetFileInfoW(pathW
, dwFileAttributes
, NULL
, sizeof(temppsfi
), flags
);
527 ret
= SHGetFileInfoW(pathW
, dwFileAttributes
, &temppsfi
, sizeof(temppsfi
), flags
);
531 if(flags
& SHGFI_ICON
)
532 psfi
->hIcon
=temppsfi
.hIcon
;
533 if(flags
& (SHGFI_SYSICONINDEX
|SHGFI_ICON
|SHGFI_ICONLOCATION
))
534 psfi
->iIcon
=temppsfi
.iIcon
;
535 if(flags
& SHGFI_ATTRIBUTES
)
536 psfi
->dwAttributes
=temppsfi
.dwAttributes
;
537 if(flags
& (SHGFI_DISPLAYNAME
|SHGFI_ICONLOCATION
))
539 WideCharToMultiByte(CP_ACP
, 0, temppsfi
.szDisplayName
, -1,
540 psfi
->szDisplayName
, sizeof(psfi
->szDisplayName
), NULL
, NULL
);
542 if(flags
& SHGFI_TYPENAME
)
544 WideCharToMultiByte(CP_ACP
, 0, temppsfi
.szTypeName
, -1,
545 psfi
->szTypeName
, sizeof(psfi
->szTypeName
), NULL
, NULL
);
554 /*************************************************************************
555 * DuplicateIcon [SHELL32.@]
557 HICON WINAPI
DuplicateIcon( HINSTANCE hInstance
, HICON hIcon
)
562 TRACE("%p %p\n", hInstance
, hIcon
);
564 if (GetIconInfo(hIcon
, &IconInfo
))
566 hDupIcon
= CreateIconIndirect(&IconInfo
);
568 /* clean up hbmMask and hbmColor */
569 DeleteObject(IconInfo
.hbmMask
);
570 DeleteObject(IconInfo
.hbmColor
);
576 /*************************************************************************
577 * ExtractIconA [SHELL32.@]
579 HICON WINAPI
ExtractIconA(HINSTANCE hInstance
, const char *file
, UINT nIconIndex
)
584 TRACE("%p %s %d\n", hInstance
, debugstr_a(file
), nIconIndex
);
586 fileW
= strdupAtoW(file
);
587 ret
= ExtractIconW(hInstance
, fileW
, nIconIndex
);
593 /*************************************************************************
594 * ExtractIconW [SHELL32.@]
596 HICON WINAPI
ExtractIconW(HINSTANCE hInstance
, LPCWSTR lpszFile
, UINT nIconIndex
)
600 UINT cx
= GetSystemMetrics(SM_CXICON
), cy
= GetSystemMetrics(SM_CYICON
);
602 TRACE("%p %s %d\n", hInstance
, debugstr_w(lpszFile
), nIconIndex
);
604 if (nIconIndex
== (UINT
)-1)
606 ret
= PrivateExtractIconsW(lpszFile
, 0, cx
, cy
, NULL
, NULL
, 0, LR_DEFAULTCOLOR
);
607 if (ret
!= (UINT
)-1 && ret
)
608 return (HICON
)(UINT_PTR
)ret
;
612 ret
= PrivateExtractIconsW(lpszFile
, nIconIndex
, cx
, cy
, &hIcon
, NULL
, 1, LR_DEFAULTCOLOR
);
613 if (ret
> 0 && hIcon
)
619 HRESULT WINAPI
SHCreateFileExtractIconW(LPCWSTR file
, DWORD attribs
, REFIID riid
, void **ppv
)
621 FIXME("%s, %lx, %s, %p\n", debugstr_w(file
), attribs
, debugstr_guid(riid
), ppv
);
626 /*************************************************************************
627 * Printer_LoadIconsW [SHELL32.205]
629 VOID WINAPI
Printer_LoadIconsW(LPCWSTR wsPrinterName
, HICON
* pLargeIcon
, HICON
* pSmallIcon
)
631 INT iconindex
=IDI_SHELL_PRINTER
;
633 TRACE("(%s, %p, %p)\n", debugstr_w(wsPrinterName
), pLargeIcon
, pSmallIcon
);
635 /* We should check if wsPrinterName is
636 1. the Default Printer or not
638 3. a Local Printer or a Network-Printer
639 and use different Icons
641 if((wsPrinterName
!= NULL
) && (wsPrinterName
[0] != 0))
643 FIXME("(select Icon by PrinterName %s not implemented)\n", debugstr_w(wsPrinterName
));
646 if(pLargeIcon
!= NULL
)
647 *pLargeIcon
= LoadImageW(shell32_hInstance
,
648 (LPCWSTR
) MAKEINTRESOURCE(iconindex
), IMAGE_ICON
,
649 0, 0, LR_DEFAULTCOLOR
|LR_DEFAULTSIZE
);
651 if(pSmallIcon
!= NULL
)
652 *pSmallIcon
= LoadImageW(shell32_hInstance
,
653 (LPCWSTR
) MAKEINTRESOURCE(iconindex
), IMAGE_ICON
,
654 16, 16, LR_DEFAULTCOLOR
);
657 /*************************************************************************
658 * Printers_RegisterWindowW [SHELL32.213]
659 * used by "printui.dll":
660 * find the Window of the given Type for the specific Printer and
661 * return the already existent hwnd or open a new window
663 BOOL WINAPI
Printers_RegisterWindowW(LPCWSTR wsPrinter
, DWORD dwType
,
664 HANDLE
* phClassPidl
, HWND
* phwnd
)
666 FIXME("(%s, %lx, %p (%p), %p (%p)) stub!\n", debugstr_w(wsPrinter
), dwType
,
667 phClassPidl
, (phClassPidl
!= NULL
) ? *(phClassPidl
) : NULL
,
668 phwnd
, (phwnd
!= NULL
) ? *(phwnd
) : NULL
);
673 /*************************************************************************
674 * Printers_UnregisterWindow [SHELL32.214]
676 VOID WINAPI
Printers_UnregisterWindow(HANDLE hClassPidl
, HWND hwnd
)
678 FIXME("(%p, %p) stub!\n", hClassPidl
, hwnd
);
681 struct window_prop_store
683 IPropertyStore IPropertyStore_iface
;
687 static inline struct window_prop_store
*impl_from_IPropertyStore(IPropertyStore
*iface
)
689 return CONTAINING_RECORD(iface
, struct window_prop_store
, IPropertyStore_iface
);
692 static ULONG WINAPI
window_prop_store_AddRef(IPropertyStore
*iface
)
694 struct window_prop_store
*store
= impl_from_IPropertyStore(iface
);
695 LONG ref
= InterlockedIncrement(&store
->ref
);
696 TRACE("returning %ld\n", ref
);
700 static ULONG WINAPI
window_prop_store_Release(IPropertyStore
*iface
)
702 struct window_prop_store
*store
= impl_from_IPropertyStore(iface
);
703 LONG ref
= InterlockedDecrement(&store
->ref
);
704 if (!ref
) free(store
);
705 TRACE("returning %ld\n", ref
);
709 static HRESULT WINAPI
window_prop_store_QueryInterface(IPropertyStore
*iface
, REFIID iid
, void **obj
)
711 struct window_prop_store
*store
= impl_from_IPropertyStore(iface
);
712 TRACE("%p, %s, %p\n", iface
, debugstr_guid(iid
), obj
);
714 if (!obj
) return E_POINTER
;
715 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IPropertyStore
))
717 *obj
= &store
->IPropertyStore_iface
;
721 FIXME("no interface for %s\n", debugstr_guid(iid
));
723 return E_NOINTERFACE
;
726 IUnknown_AddRef((IUnknown
*)*obj
);
730 static HRESULT WINAPI
window_prop_store_GetCount(IPropertyStore
*iface
, DWORD
*count
)
732 FIXME("%p, %p\n", iface
, count
);
736 static HRESULT WINAPI
window_prop_store_GetAt(IPropertyStore
*iface
, DWORD prop
, PROPERTYKEY
*key
)
738 FIXME("%p, %lu,%p\n", iface
, prop
, key
);
742 static HRESULT WINAPI
window_prop_store_GetValue(IPropertyStore
*iface
, const PROPERTYKEY
*key
, PROPVARIANT
*var
)
744 FIXME("%p, {%s,%lu}, %p\n", iface
, debugstr_guid(&key
->fmtid
), key
->pid
, var
);
748 static HRESULT WINAPI
window_prop_store_SetValue(IPropertyStore
*iface
, const PROPERTYKEY
*key
, const PROPVARIANT
*var
)
750 FIXME("%p, {%s,%lu}, %p\n", iface
, debugstr_guid(&key
->fmtid
), key
->pid
, var
);
754 static HRESULT WINAPI
window_prop_store_Commit(IPropertyStore
*iface
)
756 FIXME("%p\n", iface
);
760 static const IPropertyStoreVtbl window_prop_store_vtbl
=
762 window_prop_store_QueryInterface
,
763 window_prop_store_AddRef
,
764 window_prop_store_Release
,
765 window_prop_store_GetCount
,
766 window_prop_store_GetAt
,
767 window_prop_store_GetValue
,
768 window_prop_store_SetValue
,
769 window_prop_store_Commit
772 static HRESULT
create_window_prop_store(IPropertyStore
**obj
)
774 struct window_prop_store
*store
;
776 if (!(store
= malloc(sizeof(*store
)))) return E_OUTOFMEMORY
;
777 store
->IPropertyStore_iface
.lpVtbl
= &window_prop_store_vtbl
;
780 *obj
= &store
->IPropertyStore_iface
;
784 /*************************************************************************
785 * SHGetPropertyStoreForWindow [SHELL32.@]
787 HRESULT WINAPI
SHGetPropertyStoreForWindow(HWND hwnd
, REFIID riid
, void **ppv
)
789 IPropertyStore
*store
;
792 FIXME("(%p %p %p) stub!\n", hwnd
, riid
, ppv
);
794 if ((hr
= create_window_prop_store( &store
)) != S_OK
) return hr
;
795 hr
= IPropertyStore_QueryInterface( store
, riid
, ppv
);
796 IPropertyStore_Release( store
);
800 /*************************************************************************/
805 LPCWSTR szOtherStuff
;
810 #define DROP_FIELD_TOP (-12)
812 static void paint_dropline( HDC hdc
, HWND hWnd
)
814 HWND hWndCtl
= GetDlgItem(hWnd
, IDC_ABOUT_WINE_TEXT
);
817 if (!hWndCtl
) return;
818 GetWindowRect( hWndCtl
, &rect
);
819 MapWindowPoints( 0, hWnd
, (LPPOINT
)&rect
, 2 );
820 rect
.top
+= DROP_FIELD_TOP
;
821 rect
.bottom
= rect
.top
+ 2;
822 DrawEdge( hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
);
825 /*************************************************************************
826 * SHHelpShortcuts_RunDLLA [SHELL32.@]
829 DWORD WINAPI
SHHelpShortcuts_RunDLLA(DWORD dwArg1
, DWORD dwArg2
, DWORD dwArg3
, DWORD dwArg4
)
831 FIXME("(%lx, %lx, %lx, %lx) stub!\n", dwArg1
, dwArg2
, dwArg3
, dwArg4
);
835 /*************************************************************************
836 * SHHelpShortcuts_RunDLLA [SHELL32.@]
839 DWORD WINAPI
SHHelpShortcuts_RunDLLW(DWORD dwArg1
, DWORD dwArg2
, DWORD dwArg3
, DWORD dwArg4
)
841 FIXME("(%lx, %lx, %lx, %lx) stub!\n", dwArg1
, dwArg2
, dwArg3
, dwArg4
);
845 /*************************************************************************
846 * SHLoadInProc [SHELL32.@]
847 * Create an instance of specified object class from within
848 * the shell process and release it immediately
850 HRESULT WINAPI
SHLoadInProc (REFCLSID rclsid
)
854 TRACE("%s\n", debugstr_guid(rclsid
));
856 CoCreateInstance(rclsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,&ptr
);
859 IUnknown
* pUnk
= ptr
;
860 IUnknown_Release(pUnk
);
863 return DISP_E_MEMBERNOTFOUND
;
866 static void add_authors( HWND list
)
868 WCHAR
*strW
, *start
, *end
;
869 HRSRC rsrc
= FindResourceW( shell32_hInstance
, L
"AUTHORS", (LPCWSTR
)RT_RCDATA
);
870 char *strA
= LockResource( LoadResource( shell32_hInstance
, rsrc
));
871 DWORD sizeW
, sizeA
= SizeofResource( shell32_hInstance
, rsrc
);
874 sizeW
= MultiByteToWideChar( CP_UTF8
, 0, strA
, sizeA
, NULL
, 0 ) + 1;
875 if (!(strW
= malloc( sizeW
* sizeof(WCHAR
) ))) return;
876 MultiByteToWideChar( CP_UTF8
, 0, strA
, sizeA
, strW
, sizeW
);
879 start
= wcspbrk( strW
, L
"\r\n" ); /* skip the header line */
882 while (*start
&& wcschr( L
"\r\n", *start
)) start
++;
884 end
= wcspbrk( start
, L
"\r\n" );
886 SendMessageW( list
, LB_ADDSTRING
, -1, (LPARAM
)start
);
892 /*************************************************************************
893 * AboutDlgProc (internal)
895 static INT_PTR CALLBACK
AboutDlgProc( HWND hWnd
, UINT msg
, WPARAM wParam
,
906 ABOUT_INFO
*info
= (ABOUT_INFO
*)lParam
;
907 WCHAR
template[512], buffer
[512], version
[64];
908 const char *(CDECL
*wine_get_build_id
)(void);
912 wine_get_build_id
= (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"),
913 "wine_get_build_id");
914 SendDlgItemMessageW(hWnd
, stc1
, STM_SETICON
,(WPARAM
)info
->hIcon
, 0);
915 GetWindowTextW( hWnd
, template, ARRAY_SIZE(template) );
916 swprintf( buffer
, ARRAY_SIZE(buffer
), template, info
->szApp
);
917 SetWindowTextW( hWnd
, buffer
);
918 SetWindowTextW( GetDlgItem(hWnd
, IDC_ABOUT_STATIC_TEXT1
), info
->szApp
);
919 SetWindowTextW( GetDlgItem(hWnd
, IDC_ABOUT_STATIC_TEXT2
), info
->szOtherStuff
);
920 GetWindowTextW( GetDlgItem(hWnd
, IDC_ABOUT_STATIC_TEXT3
),
921 template, ARRAY_SIZE(template) );
922 if (wine_get_build_id
)
924 MultiByteToWideChar( CP_UTF8
, 0, wine_get_build_id(), -1, version
, ARRAY_SIZE(version
) );
925 swprintf( buffer
, ARRAY_SIZE(buffer
), template, version
);
926 SetWindowTextW( GetDlgItem(hWnd
, IDC_ABOUT_STATIC_TEXT3
), buffer
);
928 hWndCtl
= GetDlgItem(hWnd
, IDC_ABOUT_LISTBOX
);
929 SendMessageW( hWndCtl
, WM_SETREDRAW
, 0, 0 );
930 SendMessageW( hWndCtl
, WM_SETFONT
, (WPARAM
)info
->hFont
, 0 );
931 add_authors( hWndCtl
);
932 SendMessageW( hWndCtl
, WM_SETREDRAW
, 1, 0 );
940 HDC hDC
= BeginPaint( hWnd
, &ps
);
941 paint_dropline( hDC
, hWnd
);
942 EndPaint( hWnd
, &ps
);
947 if (wParam
== IDOK
|| wParam
== IDCANCEL
)
949 EndDialog(hWnd
, TRUE
);
952 if (wParam
== IDC_ABOUT_LICENSE
)
954 MSGBOXPARAMSW params
;
956 params
.cbSize
= sizeof(params
);
957 params
.hwndOwner
= hWnd
;
958 params
.hInstance
= shell32_hInstance
;
959 params
.lpszText
= MAKEINTRESOURCEW(IDS_LICENSE
);
960 params
.lpszCaption
= MAKEINTRESOURCEW(IDS_LICENSE_CAPTION
);
961 params
.dwStyle
= MB_ICONINFORMATION
| MB_OK
;
963 params
.dwContextHelpId
= 0;
964 params
.lpfnMsgBoxCallback
= NULL
;
965 params
.dwLanguageId
= LANG_NEUTRAL
;
966 MessageBoxIndirectW( ¶ms
);
970 EndDialog(hWnd
, TRUE
);
978 /*************************************************************************
979 * ShellAboutA [SHELL32.288]
981 BOOL WINAPI
ShellAboutA( HWND hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
, HICON hIcon
)
984 LPWSTR appW
= NULL
, otherW
= NULL
;
989 len
= MultiByteToWideChar(CP_ACP
, 0, szApp
, -1, NULL
, 0);
990 appW
= malloc(len
* sizeof(WCHAR
));
991 MultiByteToWideChar(CP_ACP
, 0, szApp
, -1, appW
, len
);
995 len
= MultiByteToWideChar(CP_ACP
, 0, szOtherStuff
, -1, NULL
, 0);
996 otherW
= malloc(len
* sizeof(WCHAR
));
997 MultiByteToWideChar(CP_ACP
, 0, szOtherStuff
, -1, otherW
, len
);
1000 ret
= ShellAboutW(hWnd
, appW
, otherW
, hIcon
);
1008 /*************************************************************************
1009 * ShellAboutW [SHELL32.289]
1011 BOOL WINAPI
ShellAboutW( HWND hWnd
, LPCWSTR szApp
, LPCWSTR szOtherStuff
,
1020 if (!hIcon
) hIcon
= LoadImageW( 0, (LPWSTR
)IDI_WINLOGO
, IMAGE_ICON
, 48, 48, LR_SHARED
);
1022 info
.szOtherStuff
= szOtherStuff
;
1025 SystemParametersInfoW( SPI_GETICONTITLELOGFONT
, 0, &logFont
, 0 );
1026 info
.hFont
= CreateFontIndirectW( &logFont
);
1028 bRet
= DialogBoxParamW( shell32_hInstance
, L
"SHELL_ABOUT_MSGBOX", hWnd
, AboutDlgProc
, (LPARAM
)&info
);
1029 DeleteObject(info
.hFont
);
1033 /*************************************************************************
1034 * FreeIconList (SHELL32.@)
1036 void WINAPI
FreeIconList( DWORD dw
)
1038 FIXME("%lx: stub\n",dw
);
1041 /*************************************************************************
1042 * SHLoadNonloadedIconOverlayIdentifiers (SHELL32.@)
1044 HRESULT WINAPI
SHLoadNonloadedIconOverlayIdentifiers( VOID
)
1050 /***********************************************************************
1051 * DllGetVersion [SHELL32.@]
1053 * Retrieves version information of the 'SHELL32.DLL'
1056 * pdvi [O] pointer to version information structure.
1060 * Failure: E_INVALIDARG
1063 * Returns version of a shell32.dll from IE4.01 SP1.
1066 HRESULT WINAPI
DllGetVersion (DLLVERSIONINFO
*pdvi
)
1068 /* FIXME: shouldn't these values come from the version resource? */
1069 if (pdvi
->cbSize
== sizeof(DLLVERSIONINFO
) ||
1070 pdvi
->cbSize
== sizeof(DLLVERSIONINFO2
))
1072 pdvi
->dwMajorVersion
= WINE_FILEVERSION_MAJOR
;
1073 pdvi
->dwMinorVersion
= WINE_FILEVERSION_MINOR
;
1074 pdvi
->dwBuildNumber
= WINE_FILEVERSION_BUILD
;
1075 pdvi
->dwPlatformID
= WINE_FILEVERSION_PLATFORMID
;
1076 if (pdvi
->cbSize
== sizeof(DLLVERSIONINFO2
))
1078 DLLVERSIONINFO2
*pdvi2
= (DLLVERSIONINFO2
*)pdvi
;
1081 pdvi2
->ullVersion
= MAKEDLLVERULL(WINE_FILEVERSION_MAJOR
,
1082 WINE_FILEVERSION_MINOR
,
1083 WINE_FILEVERSION_BUILD
,
1084 WINE_FILEVERSION_PLATFORMID
);
1086 TRACE("%lu.%lu.%lu.%lu\n",
1087 pdvi
->dwMajorVersion
, pdvi
->dwMinorVersion
,
1088 pdvi
->dwBuildNumber
, pdvi
->dwPlatformID
);
1093 WARN("wrong DLLVERSIONINFO size from app\n");
1094 return E_INVALIDARG
;
1098 /*************************************************************************
1099 * global variables of the shell32.dll
1100 * all are once per process
1103 HINSTANCE shell32_hInstance
= 0;
1106 /*************************************************************************
1110 * calling oleinitialize here breaks some apps.
1112 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID fImpLoad
)
1114 TRACE("%p 0x%lx %p\n", hinstDLL
, fdwReason
, fImpLoad
);
1118 case DLL_PROCESS_ATTACH
:
1119 shell32_hInstance
= hinstDLL
;
1120 DisableThreadLibraryCalls(shell32_hInstance
);
1122 /* get full path to this DLL for IExtractIconW_fnGetIconLocation() */
1123 GetModuleFileNameW(hinstDLL
, swShell32Name
, MAX_PATH
);
1124 swShell32Name
[MAX_PATH
- 1] = '\0';
1126 InitChangeNotifications();
1129 case DLL_PROCESS_DETACH
:
1130 if (fImpLoad
) break;
1132 FreeChangeNotifications();
1133 release_desktop_folder();
1140 WCHAR
*shell_get_resource_string(UINT id
)
1142 const WCHAR
*resource
;
1146 size
= LoadStringW(shell32_hInstance
, id
, (WCHAR
*)&resource
, 0);
1147 ret
= malloc((size
+ 1) * sizeof(WCHAR
));
1148 memcpy(ret
, resource
, size
* sizeof(WCHAR
));
1153 /*************************************************************************
1154 * DllInstall [SHELL32.@]
1158 * BOOL bInstall - TRUE for install, FALSE for uninstall
1159 * LPCWSTR pszCmdLine - command line (unused by shell32?)
1162 HRESULT WINAPI
DllInstall(BOOL bInstall
, LPCWSTR cmdline
)
1164 FIXME("%s %s: stub\n", bInstall
? "TRUE":"FALSE", debugstr_w(cmdline
));
1165 return S_OK
; /* indicate success */
1168 /***********************************************************************
1169 * DllRegisterServer (SHELL32.@)
1171 HRESULT WINAPI
DllRegisterServer(void)
1173 HRESULT hr
= __wine_register_resources();
1174 if (SUCCEEDED(hr
)) hr
= SHELL_RegisterShellFolders();
1178 /***********************************************************************
1179 * DllUnregisterServer (SHELL32.@)
1181 HRESULT WINAPI
DllUnregisterServer(void)
1183 return __wine_unregister_resources();
1186 /***********************************************************************
1187 * ExtractVersionResource16W (SHELL32.@)
1189 BOOL WINAPI
ExtractVersionResource16W(LPWSTR s
, DWORD d
)
1191 FIXME("(%s %lx) stub!\n", debugstr_w(s
), d
);
1195 /***********************************************************************
1196 * InitNetworkAddressControl (SHELL32.@)
1198 BOOL WINAPI
InitNetworkAddressControl(void)
1204 /***********************************************************************
1205 * ShellHookProc (SHELL32.@)
1207 LRESULT CALLBACK
ShellHookProc(DWORD a
, DWORD b
, DWORD c
)
1213 /***********************************************************************
1214 * SHGetLocalizedName (SHELL32.@)
1216 HRESULT WINAPI
SHGetLocalizedName(LPCWSTR path
, LPWSTR module
, UINT size
, INT
*res
)
1218 FIXME("%s %p %u %p: stub\n", debugstr_w(path
), module
, size
, res
);
1222 /***********************************************************************
1223 * SHSetUnreadMailCountW (SHELL32.@)
1225 HRESULT WINAPI
SHSetUnreadMailCountW(LPCWSTR mailaddress
, DWORD count
, LPCWSTR executecommand
)
1227 FIXME("%s %lx %s: stub\n", debugstr_w(mailaddress
), count
, debugstr_w(executecommand
));
1231 /***********************************************************************
1232 * SHEnumerateUnreadMailAccountsW (SHELL32.@)
1234 HRESULT WINAPI
SHEnumerateUnreadMailAccountsW(HKEY user
, DWORD idx
, LPWSTR mailaddress
, INT mailaddresslen
)
1236 FIXME("%p %ld %p %d: stub\n", user
, idx
, mailaddress
, mailaddresslen
);
1240 /***********************************************************************
1241 * SHQueryUserNotificationState (SHELL32.@)
1243 HRESULT WINAPI
SHQueryUserNotificationState(QUERY_USER_NOTIFICATION_STATE
*state
)
1245 FIXME("%p: stub\n", state
);
1246 *state
= QUNS_ACCEPTS_NOTIFICATIONS
;
1250 /***********************************************************************
1251 * SHCreateDataObject (SHELL32.@)
1253 HRESULT WINAPI
SHCreateDataObject(PCIDLIST_ABSOLUTE pidl_folder
, UINT count
, PCUITEMID_CHILD_ARRAY pidl_array
,
1254 IDataObject
*object
, REFIID riid
, void **ppv
)
1256 FIXME("%p %d %p %p %s %p: stub\n", pidl_folder
, count
, pidl_array
, object
, debugstr_guid(riid
), ppv
);