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 #include "shell32_version.h"
25 #include <reactos/version.h>
27 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
29 const char * const SHELL_Authors
[] = { "Copyright 1993-"COPYRIGHT_YEAR
" WINE team", "Copyright 1998-"COPYRIGHT_YEAR
" ReactOS Team", 0 };
32 /*************************************************************************
33 * CommandLineToArgvW [SHELL32.@]
35 * We must interpret the quotes in the command line to rebuild the argv
37 * - arguments are separated by spaces or tabs
38 * - quotes serve as optional argument delimiters
40 * - escaped quotes must be converted back to '"'
42 * - consecutive backslashes preceding a quote see their number halved with
43 * the remainder escaping the quote:
44 * 2n backslashes + quote -> n backslashes + quote as an argument delimiter
45 * 2n+1 backslashes + quote -> n backslashes + literal quote
46 * - backslashes that are not followed by a quote are copied literally:
49 * - in quoted strings, consecutive quotes see their number divided by three
50 * with the remainder modulo 3 deciding whether to close the string or not.
51 * Note that the opening quote must be counted in the consecutive quotes,
52 * that's the (1+) below:
53 * (1+) 3n quotes -> n quotes
54 * (1+) 3n+1 quotes -> n quotes plus closes the quoted string
55 * (1+) 3n+2 quotes -> n+1 quotes plus closes the quoted string
56 * - in unquoted strings, the first quote opens the quoted string and the
57 * remaining consecutive quotes follow the above rule.
59 LPWSTR
* WINAPI
CommandLineToArgvW(LPCWSTR lpCmdline
, int* numargs
)
70 SetLastError(ERROR_INVALID_PARAMETER
);
76 /* Return the path to the executable */
77 DWORD len
, deslen
=MAX_PATH
, size
;
79 size
= sizeof(LPWSTR
) + deslen
*sizeof(WCHAR
) + sizeof(LPWSTR
);
82 if (!(argv
= (LPWSTR
*)LocalAlloc(LMEM_FIXED
, size
))) return NULL
;
83 len
= GetModuleFileNameW(0, (LPWSTR
)(argv
+1), deslen
);
89 if (len
< deslen
) break;
91 size
= sizeof(LPWSTR
) + deslen
*sizeof(WCHAR
) + sizeof(LPWSTR
);
94 argv
[0]=(LPWSTR
)(argv
+1);
100 /* --- First count the arguments */
103 /* The first argument, the executable path, follows special rules */
106 /* The executable path ends at the next quote, no matter what */
114 /* The executable path ends at the next space, no matter what */
115 while (*s
&& *s
!=' ' && *s
!='\t')
118 /* skip to the first argument, if any */
119 while (*s
==' ' || *s
=='\t')
124 /* Analyze the remaining arguments */
128 if ((*s
==' ' || *s
=='\t') && qcount
==0)
130 /* skip to the next argument and count it if any */
131 while (*s
==' ' || *s
=='\t')
139 /* '\', count them */
147 qcount
++; /* unescaped '"' */
150 /* consecutive quotes, see comment in copying code below */
162 /* a regular character */
168 /* Allocate in a single lump, the string array, and the strings that go
169 * with it. This way the caller can make a single LocalFree() call to free
172 argv
=(LPWSTR
*)LocalAlloc(LMEM_FIXED
, argc
*sizeof(LPWSTR
)+(strlenW(lpCmdline
)+1)*sizeof(WCHAR
));
175 cmdline
=(LPWSTR
)(argv
+argc
);
176 strcpyW(cmdline
, lpCmdline
);
178 /* --- Then split and copy the arguments */
181 /* The first argument, the executable path, follows special rules */
184 /* The executable path ends at the next quote, no matter what */
198 /* The executable path ends at the next space, no matter what */
199 while (*d
&& *d
!=' ' && *d
!='\t')
205 /* close the executable path */
207 /* skip to the first argument and initialize it if any */
208 while (*s
==' ' || *s
=='\t')
212 /* There are no parameters so we are all done */
217 /* Split and copy the remaining arguments */
222 if ((*s
==' ' || *s
=='\t') && qcount
==0)
224 /* close the argument */
228 /* skip to the next one and initialize it if any */
231 } while (*s
==' ' || *s
=='\t');
244 /* Preceded by an even number of '\', this is half that
245 * number of '\', plus a quote which we erase.
252 /* Preceded by an odd number of '\', this is half that
253 * number of '\' followed by a '"'
260 /* Now count the number of consecutive quotes. Note that qcount
261 * already takes into account the opening quote if any, as well as
262 * the quote that lead us here.
278 /* a regular character */
289 static DWORD
shgfi_get_exe_type(LPCWSTR szFullPath
)
294 IMAGE_DOS_HEADER mz_header
;
299 status
= GetBinaryTypeW (szFullPath
, &BinaryType
);
302 if (BinaryType
== SCS_DOS_BINARY
|| BinaryType
== SCS_PIF_BINARY
)
305 hfile
= CreateFileW( szFullPath
, GENERIC_READ
, FILE_SHARE_READ
,
306 NULL
, OPEN_EXISTING
, 0, 0 );
307 if ( hfile
== INVALID_HANDLE_VALUE
)
311 * The next section is adapted from MODULE_GetBinaryType, as we need
312 * to examine the image header to get OS and version information. We
313 * know from calling GetBinaryTypeA that the image is valid and either
314 * an NE or PE, so much error handling can be omitted.
315 * Seek to the start of the file and read the header information.
318 SetFilePointer( hfile
, 0, NULL
, SEEK_SET
);
319 ReadFile( hfile
, &mz_header
, sizeof(mz_header
), &len
, NULL
);
321 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
322 ReadFile( hfile
, magic
, sizeof(magic
), &len
, NULL
);
324 if ( *(DWORD
*)magic
== IMAGE_NT_SIGNATURE
)
326 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
327 ReadFile( hfile
, &nt
, sizeof(nt
), &len
, NULL
);
328 CloseHandle( hfile
);
330 /* DLL files are not executable and should return 0 */
331 if (nt
.FileHeader
.Characteristics
& IMAGE_FILE_DLL
)
334 if (nt
.OptionalHeader
.Subsystem
== IMAGE_SUBSYSTEM_WINDOWS_GUI
)
336 return IMAGE_NT_SIGNATURE
|
337 (nt
.OptionalHeader
.MajorSubsystemVersion
<< 24) |
338 (nt
.OptionalHeader
.MinorSubsystemVersion
<< 16);
340 return IMAGE_NT_SIGNATURE
;
342 else if ( *(WORD
*)magic
== IMAGE_OS2_SIGNATURE
)
345 SetFilePointer( hfile
, mz_header
.e_lfanew
, NULL
, SEEK_SET
);
346 ReadFile( hfile
, &ne
, sizeof(ne
), &len
, NULL
);
347 CloseHandle( hfile
);
349 if (ne
.ne_exetyp
== 2)
350 return IMAGE_OS2_SIGNATURE
| (ne
.ne_expver
<< 16);
353 CloseHandle( hfile
);
357 /*************************************************************************
358 * SHELL_IsShortcut [internal]
360 * Decide if an item id list points to a shell shortcut
362 BOOL
SHELL_IsShortcut(LPCITEMIDLIST pidlLast
)
364 char szTemp
[MAX_PATH
];
368 if (_ILGetExtension(pidlLast
, szTemp
, MAX_PATH
) &&
369 HCR_MapTypeToValueA(szTemp
, szTemp
, MAX_PATH
, TRUE
))
371 if (ERROR_SUCCESS
== RegOpenKeyExA(HKEY_CLASSES_ROOT
, szTemp
, 0, KEY_QUERY_VALUE
, &keyCls
))
373 if (ERROR_SUCCESS
== RegQueryValueExA(keyCls
, "IsShortcut", NULL
, NULL
, NULL
, NULL
))
383 #define SHGFI_KNOWN_FLAGS \
384 (SHGFI_SMALLICON | SHGFI_OPENICON | SHGFI_SHELLICONSIZE | SHGFI_PIDL | \
385 SHGFI_USEFILEATTRIBUTES | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX | \
386 SHGFI_ICON | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ATTRIBUTES | \
387 SHGFI_ICONLOCATION | SHGFI_EXETYPE | SHGFI_SYSICONINDEX | \
388 SHGFI_LINKOVERLAY | SHGFI_SELECTED | SHGFI_ATTR_SPECIFIED)
390 /*************************************************************************
391 * SHGetFileInfoW [SHELL32.@]
394 DWORD_PTR WINAPI
SHGetFileInfoW(LPCWSTR path
,DWORD dwFileAttributes
,
395 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
397 WCHAR szLocation
[MAX_PATH
], szFullPath
[MAX_PATH
];
399 DWORD_PTR ret
= TRUE
;
400 DWORD dwAttributes
= 0;
401 CComPtr
<IShellFolder
> psfParent
;
402 CComPtr
<IExtractIconW
> pei
;
403 LPITEMIDLIST pidlLast
= NULL
, pidl
= NULL
;
405 BOOL IconNotYetLoaded
=TRUE
;
408 TRACE("%s fattr=0x%x sfi=%p(attr=0x%08x) size=0x%x flags=0x%x\n",
409 (flags
& SHGFI_PIDL
)? "pidl" : debugstr_w(path
), dwFileAttributes
,
410 psfi
, psfi
->dwAttributes
, sizeofpsfi
, flags
);
415 /* windows initializes these values regardless of the flags */
418 psfi
->szDisplayName
[0] = '\0';
419 psfi
->szTypeName
[0] = '\0';
423 if (!(flags
& SHGFI_PIDL
))
425 /* SHGetFileInfo should work with absolute and relative paths */
426 if (PathIsRelativeW(path
))
428 GetCurrentDirectoryW(MAX_PATH
, szLocation
);
429 PathCombineW(szFullPath
, szLocation
, path
);
433 lstrcpynW(szFullPath
, path
, MAX_PATH
);
437 if (flags
& SHGFI_EXETYPE
)
439 if (flags
!= SHGFI_EXETYPE
)
441 return shgfi_get_exe_type(szFullPath
);
445 * psfi is NULL normally to query EXE type. If it is NULL, none of the
446 * below makes sense anyway. Windows allows this and just returns FALSE
452 * translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES
454 * The pidl functions fail on not existing file names
457 if (flags
& SHGFI_PIDL
)
459 pidl
= ILClone((LPCITEMIDLIST
)path
);
461 else if (!(flags
& SHGFI_USEFILEATTRIBUTES
))
463 hr
= SHILCreateFromPathW(szFullPath
, &pidl
, &dwAttributes
);
466 if ((flags
& SHGFI_PIDL
) || !(flags
& SHGFI_USEFILEATTRIBUTES
))
468 /* get the parent shellfolder */
471 hr
= SHBindToParent( pidl
, IID_PPV_ARG(IShellFolder
, &psfParent
),
472 (LPCITEMIDLIST
*)&pidlLast
);
474 pidlLast
= ILClone(pidlLast
);
479 ERR("pidl is null!\n");
484 /* get the attributes of the child */
485 if (SUCCEEDED(hr
) && (flags
& SHGFI_ATTRIBUTES
))
487 if (!(flags
& SHGFI_ATTR_SPECIFIED
))
489 psfi
->dwAttributes
= 0xffffffff;
491 if (psfParent
!= NULL
)
492 psfParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidlLast
,
493 &(psfi
->dwAttributes
) );
496 /* get the displayname */
497 if (SUCCEEDED(hr
) && (flags
& SHGFI_DISPLAYNAME
))
499 if (flags
& SHGFI_USEFILEATTRIBUTES
)
501 wcscpy (psfi
->szDisplayName
, PathFindFileNameW(szFullPath
));
506 hr
= psfParent
->GetDisplayNameOf(pidlLast
,
507 SHGDN_INFOLDER
, &str
);
508 StrRetToStrNW (psfi
->szDisplayName
, MAX_PATH
, &str
, pidlLast
);
512 /* get the type name */
513 if (SUCCEEDED(hr
) && (flags
& SHGFI_TYPENAME
))
515 static const WCHAR szFile
[] = { 'F','i','l','e',0 };
516 static const WCHAR szDashFile
[] = { '-','f','i','l','e',0 };
518 if (!(flags
& SHGFI_USEFILEATTRIBUTES
))
522 _ILGetFileType(pidlLast
, ftype
, 80);
523 MultiByteToWideChar(CP_ACP
, 0, ftype
, -1, psfi
->szTypeName
, 80 );
527 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
528 wcscat (psfi
->szTypeName
, szFile
);
533 wcscpy(sTemp
,PathFindExtensionW(szFullPath
));
534 if (!( HCR_MapTypeToValueW(sTemp
, sTemp
, 64, TRUE
) &&
535 HCR_MapTypeToValueW(sTemp
, psfi
->szTypeName
, 80, FALSE
)))
537 lstrcpynW (psfi
->szTypeName
, sTemp
, 64);
538 wcscat (psfi
->szTypeName
, szDashFile
);
545 if (flags
& SHGFI_OPENICON
)
546 uGilFlags
|= GIL_OPENICON
;
548 if (flags
& SHGFI_LINKOVERLAY
)
549 uGilFlags
|= GIL_FORSHORTCUT
;
550 else if ((flags
&SHGFI_ADDOVERLAYS
) ||
551 (flags
&(SHGFI_ICON
|SHGFI_SMALLICON
))==SHGFI_ICON
)
553 if (SHELL_IsShortcut(pidlLast
))
554 uGilFlags
|= GIL_FORSHORTCUT
;
557 if (flags
& SHGFI_OVERLAYINDEX
)
558 FIXME("SHGFI_OVERLAYINDEX unhandled\n");
560 if (flags
& SHGFI_SELECTED
)
561 FIXME("set icon to selected, stub\n");
563 if (flags
& SHGFI_SHELLICONSIZE
)
564 FIXME("set icon to shell size, stub\n");
566 /* get the iconlocation */
567 if (SUCCEEDED(hr
) && (flags
& SHGFI_ICONLOCATION
))
571 if (flags
& SHGFI_USEFILEATTRIBUTES
)
573 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
575 wcscpy(psfi
->szDisplayName
, swShell32Name
);
576 psfi
->iIcon
= -IDI_SHELL_FOLDER
;
581 static const WCHAR p1W
[] = {'%','1',0};
582 WCHAR sTemp
[MAX_PATH
];
584 szExt
= PathFindExtensionW(szFullPath
);
585 TRACE("szExt=%s\n", debugstr_w(szExt
));
587 HCR_MapTypeToValueW(szExt
, sTemp
, MAX_PATH
, TRUE
) &&
588 HCR_GetIconW(sTemp
, sTemp
, NULL
, MAX_PATH
, &psfi
->iIcon
))
590 if (lstrcmpW(p1W
, sTemp
))
591 wcscpy(psfi
->szDisplayName
, sTemp
);
594 /* the icon is in the file */
595 wcscpy(psfi
->szDisplayName
, szFullPath
);
604 hr
= psfParent
->GetUIObjectOf(0, 1,
605 (LPCITEMIDLIST
*)&pidlLast
, IID_IExtractIconW
,
606 &uDummy
, (LPVOID
*)&pei
);
609 hr
= pei
->GetIconLocation(uGilFlags
,
610 szLocation
, MAX_PATH
, &iIndex
, &uFlags
);
612 if (uFlags
& GIL_NOTFILENAME
)
616 wcscpy (psfi
->szDisplayName
, szLocation
);
617 psfi
->iIcon
= iIndex
;
623 /* get icon index (or load icon)*/
624 if (SUCCEEDED(hr
) && (flags
& (SHGFI_ICON
| SHGFI_SYSICONINDEX
)))
626 if (flags
& SHGFI_USEFILEATTRIBUTES
&& !(flags
& SHGFI_PIDL
))
628 WCHAR sTemp
[MAX_PATH
];
632 lstrcpynW(sTemp
, szFullPath
, MAX_PATH
);
634 if (dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
635 psfi
->iIcon
= SIC_GetIconIndex(swShell32Name
, -IDI_SHELL_FOLDER
, 0);
638 static const WCHAR p1W
[] = {'%','1',0};
641 szExt
= PathFindExtensionW(sTemp
);
643 HCR_MapTypeToValueW(szExt
, sTemp
, MAX_PATH
, TRUE
) &&
644 HCR_GetIconW(sTemp
, sTemp
, NULL
, MAX_PATH
, &icon_idx
))
646 if (!lstrcmpW(p1W
,sTemp
)) /* icon is in the file */
647 wcscpy(sTemp
, szFullPath
);
649 if (flags
& SHGFI_SYSICONINDEX
)
651 psfi
->iIcon
= SIC_GetIconIndex(sTemp
,icon_idx
,0);
652 if (psfi
->iIcon
== -1)
658 if (flags
& SHGFI_SMALLICON
)
659 ret
= PrivateExtractIconsW( sTemp
,icon_idx
,
660 GetSystemMetrics( SM_CXSMICON
),
661 GetSystemMetrics( SM_CYSMICON
),
662 &psfi
->hIcon
, 0, 1, 0);
664 ret
= PrivateExtractIconsW( sTemp
, icon_idx
,
665 GetSystemMetrics( SM_CXICON
),
666 GetSystemMetrics( SM_CYICON
),
667 &psfi
->hIcon
, 0, 1, 0);
669 if (ret
!= 0 && ret
!= 0xFFFFFFFF)
671 IconNotYetLoaded
=FALSE
;
672 psfi
->iIcon
= icon_idx
;
680 if (!(PidlToSicIndex(psfParent
, pidlLast
, !(flags
& SHGFI_SMALLICON
),
681 uGilFlags
, &(psfi
->iIcon
))))
686 if (ret
&& (flags
& SHGFI_SYSICONINDEX
))
688 if (flags
& SHGFI_SMALLICON
)
689 ret
= (DWORD_PTR
) ShellSmallIconList
;
691 ret
= (DWORD_PTR
) ShellBigIconList
;
696 if (SUCCEEDED(hr
) && (flags
& SHGFI_ICON
) && IconNotYetLoaded
)
698 if (flags
& SHGFI_SMALLICON
)
699 psfi
->hIcon
= ImageList_GetIcon( ShellSmallIconList
, psfi
->iIcon
, ILD_NORMAL
);
701 psfi
->hIcon
= ImageList_GetIcon( ShellBigIconList
, psfi
->iIcon
, ILD_NORMAL
);
704 if (flags
& ~SHGFI_KNOWN_FLAGS
)
705 FIXME("unknown flags %08x\n", flags
& ~SHGFI_KNOWN_FLAGS
);
713 TRACE ("icon=%p index=0x%08x attr=0x%08x name=%s type=%s ret=0x%08lx\n",
714 psfi
->hIcon
, psfi
->iIcon
, psfi
->dwAttributes
,
715 debugstr_w(psfi
->szDisplayName
), debugstr_w(psfi
->szTypeName
), ret
);
721 /*************************************************************************
722 * SHGetFileInfoA [SHELL32.@]
725 * MSVBVM60.__vbaNew2 expects this function to return a value in range
726 * 1 .. 0x7fff when the function succeeds and flags does not contain
727 * SHGFI_EXETYPE or SHGFI_SYSICONINDEX (see bug 7701)
729 DWORD_PTR WINAPI
SHGetFileInfoA(LPCSTR path
,DWORD dwFileAttributes
,
730 SHFILEINFOA
*psfi
, UINT sizeofpsfi
,
734 LPWSTR temppath
= NULL
;
737 SHFILEINFOW temppsfi
;
739 if (flags
& SHGFI_PIDL
)
741 /* path contains a pidl */
742 pathW
= (LPCWSTR
)path
;
746 len
= MultiByteToWideChar(CP_ACP
, 0, path
, -1, NULL
, 0);
747 temppath
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
748 MultiByteToWideChar(CP_ACP
, 0, path
, -1, temppath
, len
);
752 if (psfi
&& (flags
& SHGFI_ATTR_SPECIFIED
))
753 temppsfi
.dwAttributes
=psfi
->dwAttributes
;
756 ret
= SHGetFileInfoW(pathW
, dwFileAttributes
, NULL
, sizeof(temppsfi
), flags
);
758 ret
= SHGetFileInfoW(pathW
, dwFileAttributes
, &temppsfi
, sizeof(temppsfi
), flags
);
762 if(flags
& SHGFI_ICON
)
763 psfi
->hIcon
=temppsfi
.hIcon
;
764 if(flags
& (SHGFI_SYSICONINDEX
|SHGFI_ICON
|SHGFI_ICONLOCATION
))
765 psfi
->iIcon
=temppsfi
.iIcon
;
766 if(flags
& SHGFI_ATTRIBUTES
)
767 psfi
->dwAttributes
=temppsfi
.dwAttributes
;
768 if(flags
& (SHGFI_DISPLAYNAME
|SHGFI_ICONLOCATION
))
770 WideCharToMultiByte(CP_ACP
, 0, temppsfi
.szDisplayName
, -1,
771 psfi
->szDisplayName
, sizeof(psfi
->szDisplayName
), NULL
, NULL
);
773 if(flags
& SHGFI_TYPENAME
)
775 WideCharToMultiByte(CP_ACP
, 0, temppsfi
.szTypeName
, -1,
776 psfi
->szTypeName
, sizeof(psfi
->szTypeName
), NULL
, NULL
);
780 HeapFree(GetProcessHeap(), 0, temppath
);
785 /*************************************************************************
786 * DuplicateIcon [SHELL32.@]
788 EXTERN_C HICON WINAPI
DuplicateIcon( HINSTANCE hInstance
, HICON hIcon
)
793 TRACE("%p %p\n", hInstance
, hIcon
);
795 if (GetIconInfo(hIcon
, &IconInfo
))
797 hDupIcon
= CreateIconIndirect(&IconInfo
);
799 /* clean up hbmMask and hbmColor */
800 DeleteObject(IconInfo
.hbmMask
);
801 DeleteObject(IconInfo
.hbmColor
);
807 /*************************************************************************
808 * ExtractIconA [SHELL32.@]
810 HICON WINAPI
ExtractIconA(HINSTANCE hInstance
, LPCSTR lpszFile
, UINT nIconIndex
)
813 INT len
= MultiByteToWideChar(CP_ACP
, 0, lpszFile
, -1, NULL
, 0);
814 LPWSTR lpwstrFile
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
816 TRACE("%p %s %d\n", hInstance
, lpszFile
, nIconIndex
);
818 MultiByteToWideChar(CP_ACP
, 0, lpszFile
, -1, lpwstrFile
, len
);
819 ret
= ExtractIconW(hInstance
, lpwstrFile
, nIconIndex
);
820 HeapFree(GetProcessHeap(), 0, lpwstrFile
);
825 /*************************************************************************
826 * ExtractIconW [SHELL32.@]
828 HICON WINAPI
ExtractIconW(HINSTANCE hInstance
, LPCWSTR lpszFile
, UINT nIconIndex
)
832 UINT cx
= GetSystemMetrics(SM_CXICON
), cy
= GetSystemMetrics(SM_CYICON
);
834 TRACE("%p %s %d\n", hInstance
, debugstr_w(lpszFile
), nIconIndex
);
836 if (nIconIndex
== 0xFFFFFFFF)
838 ret
= PrivateExtractIconsW(lpszFile
, 0, cx
, cy
, NULL
, NULL
, 0, LR_DEFAULTCOLOR
);
839 if (ret
!= 0xFFFFFFFF && ret
)
840 return (HICON
)(UINT_PTR
)ret
;
844 ret
= PrivateExtractIconsW(lpszFile
, nIconIndex
, cx
, cy
, &hIcon
, NULL
, 1, LR_DEFAULTCOLOR
);
846 if (ret
== 0xFFFFFFFF)
848 else if (ret
> 0 && hIcon
)
854 /*************************************************************************
855 * Printer_LoadIconsW [SHELL32.205]
857 EXTERN_C VOID WINAPI
Printer_LoadIconsW(LPCWSTR wsPrinterName
, HICON
* pLargeIcon
, HICON
* pSmallIcon
)
859 INT iconindex
=IDI_SHELL_PRINTERS_FOLDER
;
861 TRACE("(%s, %p, %p)\n", debugstr_w(wsPrinterName
), pLargeIcon
, pSmallIcon
);
863 /* We should check if wsPrinterName is
864 1. the Default Printer or not
866 3. a Local Printer or a Network-Printer
867 and use different Icons
869 if((wsPrinterName
!= NULL
) && (wsPrinterName
[0] != 0))
871 FIXME("(select Icon by PrinterName %s not implemented)\n", debugstr_w(wsPrinterName
));
874 if(pLargeIcon
!= NULL
)
875 *pLargeIcon
= (HICON
)LoadImageW(shell32_hInstance
,
876 (LPCWSTR
) MAKEINTRESOURCE(iconindex
), IMAGE_ICON
,
877 0, 0, LR_DEFAULTCOLOR
|LR_DEFAULTSIZE
);
879 if(pSmallIcon
!= NULL
)
880 *pSmallIcon
= (HICON
)LoadImageW(shell32_hInstance
,
881 (LPCWSTR
) MAKEINTRESOURCE(iconindex
), IMAGE_ICON
,
882 16, 16, LR_DEFAULTCOLOR
);
885 /*************************************************************************
886 * Printers_RegisterWindowW [SHELL32.213]
887 * used by "printui.dll":
888 * find the Window of the given Type for the specific Printer and
889 * return the already existent hwnd or open a new window
891 EXTERN_C BOOL WINAPI
Printers_RegisterWindowW(LPCWSTR wsPrinter
, DWORD dwType
,
892 HANDLE
* phClassPidl
, HWND
* phwnd
)
894 FIXME("(%s, %x, %p (%p), %p (%p)) stub!\n", debugstr_w(wsPrinter
), dwType
,
895 phClassPidl
, (phClassPidl
!= NULL
) ? *(phClassPidl
) : NULL
,
896 phwnd
, (phwnd
!= NULL
) ? *(phwnd
) : NULL
);
901 /*************************************************************************
902 * Printers_UnregisterWindow [SHELL32.214]
904 EXTERN_C VOID WINAPI
Printers_UnregisterWindow(HANDLE hClassPidl
, HWND hwnd
)
906 FIXME("(%p, %p) stub!\n", hClassPidl
, hwnd
);
909 /*************************************************************************/
914 LPCWSTR szOtherStuff
;
918 #define DROP_FIELD_TOP (-15)
919 #define DROP_FIELD_HEIGHT 15
921 /*************************************************************************
922 * SHAppBarMessage [SHELL32.@]
924 UINT_PTR WINAPI
SHAppBarMessage(DWORD msg
, PAPPBARDATA data
)
926 int width
=data
->rc
.right
- data
->rc
.left
;
927 int height
=data
->rc
.bottom
- data
->rc
.top
;
930 TRACE("msg=%d, data={cb=%d, hwnd=%p, callback=%x, edge=%d, rc=%s, lparam=%lx}\n",
931 msg
, data
->cbSize
, data
->hWnd
, data
->uCallbackMessage
, data
->uEdge
,
932 wine_dbgstr_rect(&data
->rc
), data
->lParam
);
937 return ABS_ALWAYSONTOP
| ABS_AUTOHIDE
;
939 case ABM_GETTASKBARPOS
:
940 GetWindowRect(data
->hWnd
, &rec
);
945 SetActiveWindow(data
->hWnd
);
948 case ABM_GETAUTOHIDEBAR
:
949 return 0; /* pretend there is no autohide bar */
952 /* cbSize, hWnd, and uCallbackMessage are used. All other ignored */
953 SetWindowPos(data
->hWnd
,HWND_TOP
,0,0,0,0,SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOSIZE
);
957 GetWindowRect(data
->hWnd
, &(data
->rc
));
961 FIXME("ABM_REMOVE broken\n");
962 /* FIXME: this is wrong; should it be DestroyWindow instead? */
963 /*CloseHandle(data->hWnd);*/
966 case ABM_SETAUTOHIDEBAR
:
967 SetWindowPos(data
->hWnd
,HWND_TOP
,rec
.left
+1000,rec
.top
,
968 width
,height
,SWP_SHOWWINDOW
);
972 data
->uEdge
=(ABE_RIGHT
| ABE_LEFT
);
973 SetWindowPos(data
->hWnd
,HWND_TOP
,data
->rc
.left
,data
->rc
.top
,
974 width
,height
,SWP_SHOWWINDOW
);
977 case ABM_WINDOWPOSCHANGED
:
984 /*************************************************************************
985 * SHHelpShortcuts_RunDLLA [SHELL32.@]
988 EXTERN_C DWORD WINAPI
SHHelpShortcuts_RunDLLA(DWORD dwArg1
, DWORD dwArg2
, DWORD dwArg3
, DWORD dwArg4
)
990 FIXME("(%x, %x, %x, %x) stub!\n", dwArg1
, dwArg2
, dwArg3
, dwArg4
);
994 /*************************************************************************
995 * SHHelpShortcuts_RunDLLA [SHELL32.@]
998 EXTERN_C DWORD WINAPI
SHHelpShortcuts_RunDLLW(DWORD dwArg1
, DWORD dwArg2
, DWORD dwArg3
, DWORD dwArg4
)
1000 FIXME("(%x, %x, %x, %x) stub!\n", dwArg1
, dwArg2
, dwArg3
, dwArg4
);
1004 /*************************************************************************
1005 * SHLoadInProc [SHELL32.@]
1006 * Create an instance of specified object class from within
1007 * the shell process and release it immediately
1009 EXTERN_C HRESULT WINAPI
SHLoadInProc (REFCLSID rclsid
)
1011 CComPtr
<IUnknown
> ptr
;
1013 TRACE("%s\n", debugstr_guid(&rclsid
));
1015 CoCreateInstance(rclsid
, NULL
, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void **)&ptr
);
1018 return DISP_E_MEMBERNOTFOUND
;
1021 static VOID
SetRegTextData(HWND hWnd
, HKEY hKey
, LPCWSTR Value
, UINT uID
)
1027 if( RegQueryValueExW(hKey
, Value
, NULL
, &dwType
, NULL
, &dwBufferSize
) == ERROR_SUCCESS
)
1029 if(dwType
== REG_SZ
)
1031 lpBuffer
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, dwBufferSize
);
1035 if( RegQueryValueExW(hKey
, Value
, NULL
, &dwType
, (LPBYTE
)lpBuffer
, &dwBufferSize
) == ERROR_SUCCESS
)
1037 SetDlgItemTextW(hWnd
, uID
, lpBuffer
);
1040 HeapFree(GetProcessHeap(), 0, lpBuffer
);
1046 INT_PTR CALLBACK
AboutAuthorsDlgProc( HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1052 const char* const *pstr
= SHELL_Authors
;
1054 // Add the authors to the list
1055 SendDlgItemMessageW( hWnd
, IDC_ABOUT_AUTHORS_LISTBOX
, WM_SETREDRAW
, FALSE
, 0 );
1061 /* authors list is in utf-8 format */
1062 MultiByteToWideChar( CP_UTF8
, 0, *pstr
, -1, name
, sizeof(name
)/sizeof(WCHAR
) );
1063 SendDlgItemMessageW( hWnd
, IDC_ABOUT_AUTHORS_LISTBOX
, LB_ADDSTRING
, (WPARAM
)-1, (LPARAM
)name
);
1067 SendDlgItemMessageW( hWnd
, IDC_ABOUT_AUTHORS_LISTBOX
, WM_SETREDRAW
, TRUE
, 0 );
1075 /*************************************************************************
1076 * AboutDlgProc (internal)
1078 INT_PTR CALLBACK
AboutDlgProc( HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1080 static DWORD cxLogoBmp
;
1081 static DWORD cyLogoBmp
;
1082 static HBITMAP hLogoBmp
;
1083 static HWND hWndAuthors
;
1089 ABOUT_INFO
*info
= (ABOUT_INFO
*)lParam
;
1093 const WCHAR szRegKey
[] = L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
1095 MEMORYSTATUSEX MemStat
;
1096 WCHAR szAppTitle
[512];
1097 WCHAR szAppTitleTemplate
[512];
1098 WCHAR szAuthorsText
[20];
1100 // Preload the ROS bitmap
1101 hLogoBmp
= (HBITMAP
)LoadImage(shell32_hInstance
, MAKEINTRESOURCE(IDB_SHELL_ABOUT_LOGO_24BPP
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1107 GetObject( hLogoBmp
, sizeof(BITMAP
), &bmpLogo
);
1109 cxLogoBmp
= bmpLogo
.bmWidth
;
1110 cyLogoBmp
= bmpLogo
.bmHeight
;
1113 // Set App-specific stuff (icon, app name, szOtherStuff string)
1114 SendDlgItemMessageW(hWnd
, IDC_ABOUT_ICON
, STM_SETICON
, (WPARAM
)info
->hIcon
, 0);
1116 GetWindowTextW( hWnd
, szAppTitleTemplate
, sizeof(szAppTitleTemplate
) / sizeof(WCHAR
) );
1117 swprintf( szAppTitle
, szAppTitleTemplate
, info
->szApp
);
1118 SetWindowTextW( hWnd
, szAppTitle
);
1120 SetDlgItemTextW( hWnd
, IDC_ABOUT_APPNAME
, info
->szApp
);
1121 SetDlgItemTextW( hWnd
, IDC_ABOUT_OTHERSTUFF
, info
->szOtherStuff
);
1123 // Set the registered user and organization name
1124 if(RegOpenKeyExW( HKEY_LOCAL_MACHINE
, szRegKey
, 0, KEY_QUERY_VALUE
, &hRegKey
) == ERROR_SUCCESS
)
1126 SetRegTextData( hWnd
, hRegKey
, L
"RegisteredOwner", IDC_ABOUT_REG_USERNAME
);
1127 SetRegTextData( hWnd
, hRegKey
, L
"RegisteredOrganization", IDC_ABOUT_REG_ORGNAME
);
1129 RegCloseKey( hRegKey
);
1132 // Set the value for the installed physical memory
1133 MemStat
.dwLength
= sizeof(MemStat
);
1134 if( GlobalMemoryStatusEx(&MemStat
) )
1138 if (MemStat
.ullTotalPhys
> 1024 * 1024 * 1024)
1141 WCHAR szDecimalSeparator
[4];
1144 // We're dealing with GBs or more
1145 MemStat
.ullTotalPhys
/= 1024 * 1024;
1147 if (MemStat
.ullTotalPhys
> 1024 * 1024)
1149 // We're dealing with TBs or more
1150 MemStat
.ullTotalPhys
/= 1024;
1152 if (MemStat
.ullTotalPhys
> 1024 * 1024)
1154 // We're dealing with PBs or more
1155 MemStat
.ullTotalPhys
/= 1024;
1157 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
1158 wcscpy( szUnits
, L
"PB" );
1162 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
1163 wcscpy( szUnits
, L
"TB" );
1168 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
1169 wcscpy( szUnits
, L
"GB" );
1172 // We need the decimal point of the current locale to display the RAM size correctly
1173 if (GetLocaleInfoW(LOCALE_USER_DEFAULT
, LOCALE_SDECIMAL
,
1175 sizeof(szDecimalSeparator
) / sizeof(WCHAR
)) > 0)
1180 uIntegral
= (UINT
)dTotalPhys
;
1181 uDecimals
= (UCHAR
)((UINT
)(dTotalPhys
* 100) - uIntegral
* 100);
1183 // Display the RAM size with 2 decimals
1184 swprintf(szBuf
, L
"%u%s%02u %s", uIntegral
, szDecimalSeparator
, uDecimals
, szUnits
);
1189 // We're dealing with MBs, don't show any decimals
1190 swprintf( szBuf
, L
"%u MB", (UINT
)MemStat
.ullTotalPhys
/ 1024 / 1024 );
1193 SetDlgItemTextW( hWnd
, IDC_ABOUT_PHYSMEM
, szBuf
);
1196 // Add the Authors dialog
1197 hWndAuthors
= CreateDialogW( shell32_hInstance
, MAKEINTRESOURCEW(IDD_ABOUT_AUTHORS
), hWnd
, AboutAuthorsDlgProc
);
1198 LoadStringW( shell32_hInstance
, IDS_SHELL_ABOUT_AUTHORS
, szAuthorsText
, sizeof(szAuthorsText
) / sizeof(WCHAR
) );
1199 SetDlgItemTextW( hWnd
, IDC_ABOUT_AUTHORS
, szAuthorsText
);
1213 hdc
= BeginPaint(hWnd
, &ps
);
1214 hdcMem
= CreateCompatibleDC(hdc
);
1218 SelectObject(hdcMem
, hLogoBmp
);
1219 BitBlt(hdc
, 0, 0, cxLogoBmp
, cyLogoBmp
, hdcMem
, 0, 0, SRCCOPY
);
1224 EndPaint(hWnd
, &ps
);
1234 EndDialog(hWnd
, TRUE
);
1237 case IDC_ABOUT_AUTHORS
:
1239 static BOOL bShowingAuthors
= FALSE
;
1240 WCHAR szAuthorsText
[20];
1244 LoadStringW( shell32_hInstance
, IDS_SHELL_ABOUT_AUTHORS
, szAuthorsText
, sizeof(szAuthorsText
) / sizeof(WCHAR
) );
1245 ShowWindow( hWndAuthors
, SW_HIDE
);
1249 LoadStringW( shell32_hInstance
, IDS_SHELL_ABOUT_BACK
, szAuthorsText
, sizeof(szAuthorsText
) / sizeof(WCHAR
) );
1250 ShowWindow( hWndAuthors
, SW_SHOW
);
1253 SetDlgItemTextW( hWnd
, IDC_ABOUT_AUTHORS
, szAuthorsText
);
1254 bShowingAuthors
= !bShowingAuthors
;
1261 EndDialog(hWnd
, TRUE
);
1269 /*************************************************************************
1270 * ShellAboutA [SHELL32.288]
1272 BOOL WINAPI
ShellAboutA( HWND hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
, HICON hIcon
)
1275 LPWSTR appW
= NULL
, otherW
= NULL
;
1280 len
= MultiByteToWideChar(CP_ACP
, 0, szApp
, -1, NULL
, 0);
1281 appW
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1282 MultiByteToWideChar(CP_ACP
, 0, szApp
, -1, appW
, len
);
1286 len
= MultiByteToWideChar(CP_ACP
, 0, szOtherStuff
, -1, NULL
, 0);
1287 otherW
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1288 MultiByteToWideChar(CP_ACP
, 0, szOtherStuff
, -1, otherW
, len
);
1291 ret
= ShellAboutW(hWnd
, appW
, otherW
, hIcon
);
1293 HeapFree(GetProcessHeap(), 0, otherW
);
1294 HeapFree(GetProcessHeap(), 0, appW
);
1299 /*************************************************************************
1300 * ShellAboutW [SHELL32.289]
1302 BOOL WINAPI
ShellAboutW( HWND hWnd
, LPCWSTR szApp
, LPCWSTR szOtherStuff
,
1307 DLGTEMPLATE
*DlgTemplate
;
1312 // DialogBoxIndirectParamW will be called with the hInstance of the calling application, so we have to preload the dialog template
1313 hRes
= FindResourceW(shell32_hInstance
, MAKEINTRESOURCEW(IDD_ABOUT
), (LPWSTR
)RT_DIALOG
);
1317 DlgTemplate
= (DLGTEMPLATE
*)LoadResource(shell32_hInstance
, hRes
);
1322 info
.szOtherStuff
= szOtherStuff
;
1323 info
.hIcon
= hIcon
? hIcon
: LoadIconW( 0, (LPWSTR
)IDI_WINLOGO
);
1325 bRet
= DialogBoxIndirectParamW((HINSTANCE
)GetWindowLongPtrW( hWnd
, GWLP_HINSTANCE
),
1326 DlgTemplate
, hWnd
, AboutDlgProc
, (LPARAM
)&info
);
1330 /*************************************************************************
1331 * FreeIconList (SHELL32.@)
1333 EXTERN_C
void WINAPI
FreeIconList( DWORD dw
)
1335 FIXME("%x: stub\n",dw
);
1338 /*************************************************************************
1339 * SHLoadNonloadedIconOverlayIdentifiers (SHELL32.@)
1341 EXTERN_C HRESULT WINAPI
SHLoadNonloadedIconOverlayIdentifiers(VOID
)
1347 class CShell32Module
: public CComModule
1353 BEGIN_OBJECT_MAP(ObjectMap
)
1354 OBJECT_ENTRY(CLSID_ShellFSFolder
, CFSFolder
)
1355 OBJECT_ENTRY(CLSID_MyComputer
, CDrivesFolder
)
1356 OBJECT_ENTRY(CLSID_ShellDesktop
, CDesktopFolder
)
1357 OBJECT_ENTRY(CLSID_ShellItem
, CShellItem
)
1358 OBJECT_ENTRY(CLSID_ShellLink
, CShellLink
)
1359 OBJECT_ENTRY(CLSID_DragDropHelper
, CDropTargetHelper
)
1360 OBJECT_ENTRY(CLSID_ControlPanel
, CControlPanelFolder
)
1361 OBJECT_ENTRY(CLSID_AutoComplete
, CAutoComplete
)
1362 OBJECT_ENTRY(CLSID_MyDocuments
, CMyDocsFolder
)
1363 OBJECT_ENTRY(CLSID_NetworkPlaces
, CNetFolder
)
1364 OBJECT_ENTRY(CLSID_FontsFolderShortcut
, CFontsFolder
)
1365 OBJECT_ENTRY(CLSID_Printers
, CPrinterFolder
)
1366 OBJECT_ENTRY(CLSID_AdminFolderShortcut
, CAdminToolsFolder
)
1367 OBJECT_ENTRY(CLSID_RecycleBin
, CRecycleBin
)
1368 OBJECT_ENTRY(CLSID_OpenWithMenu
, COpenWithMenu
)
1369 OBJECT_ENTRY(CLSID_NewMenu
, CNewMenu
)
1370 OBJECT_ENTRY(CLSID_StartMenu
, CStartMenu
)
1371 OBJECT_ENTRY(CLSID_MenuBandSite
, CMenuBandSite
)
1372 OBJECT_ENTRY(CLSID_MenuBand
, CMenuBand
)
1373 OBJECT_ENTRY(CLSID_MenuDeskBar
, CMenuDeskBar
)
1374 OBJECT_ENTRY(CLSID_ExeDropHandler
, CExeDropHandler
)
1377 CShell32Module gModule
;
1380 /***********************************************************************
1381 * DllGetVersion [SHELL32.@]
1383 * Retrieves version information of the 'SHELL32.DLL'
1386 * pdvi [O] pointer to version information structure.
1390 * Failure: E_INVALIDARG
1393 * Returns version of a shell32.dll from IE4.01 SP1.
1396 STDAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1398 /* FIXME: shouldn't these values come from the version resource? */
1399 if (pdvi
->cbSize
== sizeof(DLLVERSIONINFO
) ||
1400 pdvi
->cbSize
== sizeof(DLLVERSIONINFO2
))
1402 pdvi
->dwMajorVersion
= WINE_FILEVERSION_MAJOR
;
1403 pdvi
->dwMinorVersion
= WINE_FILEVERSION_MINOR
;
1404 pdvi
->dwBuildNumber
= WINE_FILEVERSION_BUILD
;
1405 pdvi
->dwPlatformID
= WINE_FILEVERSION_PLATFORMID
;
1406 if (pdvi
->cbSize
== sizeof(DLLVERSIONINFO2
))
1408 DLLVERSIONINFO2
*pdvi2
= (DLLVERSIONINFO2
*)pdvi
;
1411 pdvi2
->ullVersion
= MAKEDLLVERULL(WINE_FILEVERSION_MAJOR
,
1412 WINE_FILEVERSION_MINOR
,
1413 WINE_FILEVERSION_BUILD
,
1414 WINE_FILEVERSION_PLATFORMID
);
1416 TRACE("%u.%u.%u.%u\n",
1417 pdvi
->dwMajorVersion
, pdvi
->dwMinorVersion
,
1418 pdvi
->dwBuildNumber
, pdvi
->dwPlatformID
);
1423 WARN("wrong DLLVERSIONINFO size from app\n");
1424 return E_INVALIDARG
;
1428 /*************************************************************************
1429 * global variables of the shell32.dll
1430 * all are once per process
1433 HINSTANCE shell32_hInstance
;
1434 HIMAGELIST ShellSmallIconList
= 0;
1435 HIMAGELIST ShellBigIconList
= 0;
1437 void *operator new (size_t, void *buf
)
1442 /*************************************************************************
1446 * calling oleinitialize here breaks sone apps.
1448 STDAPI_(BOOL
) DllMain(HINSTANCE hInstance
, DWORD dwReason
, LPVOID fImpLoad
)
1450 TRACE("%p 0x%x %p\n", hInstance
, dwReason
, fImpLoad
);
1451 if (dwReason
== DLL_PROCESS_ATTACH
)
1453 /* HACK - the global constructors don't run, so I placement new them here */
1454 new (&gModule
) CShell32Module
;
1455 new (&_AtlWinModule
) CAtlWinModule
;
1456 new (&_AtlBaseModule
) CAtlBaseModule
;
1457 new (&_AtlComModule
) CAtlComModule
;
1459 shell32_hInstance
= hInstance
;
1460 gModule
.Init(ObjectMap
, hInstance
, NULL
);
1462 DisableThreadLibraryCalls (hInstance
);
1464 /* get full path to this DLL for IExtractIconW_fnGetIconLocation() */
1465 GetModuleFileNameW(hInstance
, swShell32Name
, MAX_PATH
);
1466 swShell32Name
[MAX_PATH
- 1] = '\0';
1468 /* Initialize comctl32 */
1469 INITCOMMONCONTROLSEX InitCtrls
;
1470 InitCtrls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
1471 InitCtrls
.dwICC
= ICC_WIN95_CLASSES
| ICC_DATE_CLASSES
| ICC_USEREX_CLASSES
;
1472 InitCommonControlsEx(&InitCtrls
);
1475 InitChangeNotifications();
1478 else if (dwReason
== DLL_PROCESS_DETACH
)
1480 shell32_hInstance
= NULL
;
1482 FreeChangeNotifications();
1488 /***********************************************************************
1489 * DllCanUnloadNow (SHELL32.@)
1491 STDAPI
DllCanUnloadNow()
1493 return gModule
.DllCanUnloadNow();
1496 /*************************************************************************
1497 * DllGetClassObject [SHELL32.@]
1498 * SHDllGetClassObject [SHELL32.128]
1500 STDAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1504 TRACE("CLSID:%s,IID:%s\n", shdebugstr_guid(&rclsid
), shdebugstr_guid(&riid
));
1506 hResult
= gModule
.DllGetClassObject(rclsid
, riid
, ppv
);
1507 TRACE("-- pointer to class factory: %p\n", *ppv
);
1511 /***********************************************************************
1512 * DllRegisterServer (SHELL32.@)
1514 STDAPI
DllRegisterServer()
1518 hr
= gModule
.DllRegisterServer(FALSE
);
1522 hr
= gModule
.UpdateRegistryFromResource(IDR_FOLDEROPTIONS
, TRUE
, NULL
);
1526 hr
= SHELL_RegisterShellFolders();
1533 /***********************************************************************
1534 * DllUnregisterServer (SHELL32.@)
1536 STDAPI
DllUnregisterServer()
1540 hr
= gModule
.DllUnregisterServer(FALSE
);
1544 hr
= gModule
.UpdateRegistryFromResource(IDR_FOLDEROPTIONS
, FALSE
, NULL
);
1551 /*************************************************************************
1552 * DllInstall [SHELL32.@]
1556 * BOOL bInstall - TRUE for install, FALSE for uninstall
1557 * LPCWSTR pszCmdLine - command line (unused by shell32?)
1560 HRESULT WINAPI
DllInstall(BOOL bInstall
, LPCWSTR cmdline
)
1562 FIXME("%s %s: stub\n", bInstall
? "TRUE":"FALSE", debugstr_w(cmdline
));
1563 return S_OK
; /* indicate success */