2 * Shell Library Functions
4 * Copyright 2005 Johannes Anderwald
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
25 #define MAX_PROPERTY_SHEET_PAGE 32
27 typedef struct _LANGANDCODEPAGE_
31 } LANGANDCODEPAGE
, *LPLANGANDCODEPAGE
;
33 HPSXA WINAPI
SHCreatePropSheetExtArrayEx(HKEY hKey
, LPCWSTR pszSubKey
, UINT max_iface
, IDataObject
*pDataObj
);
34 /*************************************************************************
36 * SH_CreatePropertySheetPage [Internal]
38 * creates a property sheet page from an resource name
42 SH_CreatePropertySheetPage(LPSTR resname
, DLGPROC dlgproc
, LPARAM lParam
, LPWSTR szTitle
)
49 return (HPROPSHEETPAGE
)0;
51 hRes
= FindResourceA(shell32_hInstance
, resname
, (LPSTR
)RT_DIALOG
);
55 ERR("failed to find resource name\n");
56 return (HPROPSHEETPAGE
)0;
58 lpsztemplate
= LoadResource(shell32_hInstance
, hRes
);
59 if (lpsztemplate
== NULL
)
60 return (HPROPSHEETPAGE
)0;
62 memset(&ppage
, 0x0, sizeof(PROPSHEETPAGEW
));
63 ppage
.dwSize
= sizeof(PROPSHEETPAGEW
);
64 ppage
.dwFlags
= PSP_DLGINDIRECT
;
65 ppage
.u
.pResource
= lpsztemplate
;
66 ppage
.pfnDlgProc
= dlgproc
;
67 ppage
.lParam
= lParam
;
68 ppage
.pszTitle
= szTitle
;
71 ppage
.dwFlags
|= PSP_USETITLE
;
73 return CreatePropertySheetPageW(&ppage
);
82 /*************************************************************************
84 * SH_FileGeneralFileType [Internal]
86 * retrieves file extension description from registry and sets it in dialog
88 * TODO: retrieve file extension default icon and load it
89 * find executable name from registry, retrieve description from executable
93 SH_FileGeneralSetFileType(HWND hwndDlg
, WCHAR
* filext
)
96 WCHAR value
[MAX_PATH
];
97 DWORD lname
= MAX_PATH
;
98 DWORD lvalue
= MAX_PATH
;
104 TRACE("fileext %s\n", debugstr_w(filext
));
109 hDlgCtrl
= GetDlgItem(hwndDlg
, 14005);
111 if (hDlgCtrl
== NULL
)
114 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, filext
, &hKey
) != ERROR_SUCCESS
)
116 /* the fileextension is unknown, so default to string "FileExtension File" */
117 SendMessageW(hDlgCtrl
, WM_GETTEXT
, (WPARAM
)MAX_PATH
, (LPARAM
)value
);
118 swprintf(name
, value
, &filext
[1]);
119 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)name
);
122 result
= RegEnumValueW(hKey
, 0, name
, &lname
, NULL
, NULL
, (LPBYTE
)value
, &lvalue
);
125 if (result
!= ERROR_SUCCESS
)
127 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, value
, &hKey
) == ERROR_SUCCESS
)
129 if (RegLoadMUIStringW(hKey
, L
"FriendlyTypeName", value
, MAX_PATH
, NULL
, 0, NULL
) != ERROR_SUCCESS
)
131 lvalue
= lname
= MAX_PATH
;
132 result
= RegEnumValueW(hKey
,0, name
, &lname
, NULL
, NULL
, (LPBYTE
)value
, &lvalue
);
135 if (RegGetValueW(hKey
, L
"DefaultIcon", NULL
, RRF_RT_REG_SZ
, NULL
, name
, &lname
) == ERROR_SUCCESS
)
138 WCHAR szBuffer
[MAX_PATH
];
142 LPVOID pResource
= NULL
;
145 Offset
= wcsrchr(name
, L
',');
148 IconIndex
= _wtoi(Offset
+ 2);
150 name
[MAX_PATH
-1] = L
'\0';
151 if (ExpandEnvironmentStringsW(name
, szBuffer
, MAX_PATH
))
153 szBuffer
[MAX_PATH
-1] = L
'\0';
154 hLibrary
= LoadLibraryExW(szBuffer
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
157 hResource
= FindResourceW(hLibrary
, MAKEINTRESOURCEW(IconIndex
), (LPCWSTR
)RT_ICON
);
160 hGlobal
= LoadResource(shell32_hInstance
, hResource
);
163 pResource
= LockResource(hGlobal
);
164 if (pResource
!= NULL
)
166 hIcon
= CreateIconFromResource(pResource
, SizeofResource(shell32_hInstance
, hResource
), TRUE
, 0x00030000);
167 TRACE("hIcon %p,- szBuffer %s IconIndex %u error %u icon %p hResource %p pResource %p\n", hIcon
, debugstr_w(szBuffer
), IconIndex
, MAKEINTRESOURCEW(IconIndex
), hResource
, pResource
);
168 SendDlgItemMessageW(hwndDlg
, 14000, STM_SETICON
, (WPARAM
)hIcon
, 0);
172 FreeLibrary(hLibrary
);
180 /* file extension type */
181 value
[MAX_PATH
-1] = L
'\0';
182 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)value
);
185 /*************************************************************************
187 * SHFileGeneralGetFileTimeString [Internal]
189 * formats a given LPFILETIME struct into readable user format
193 SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime
, WCHAR
* lpResult
)
198 static const WCHAR wFormat
[] = {'%','0','2','d','/','%','0','2','d','/','%','0','4','d',' ',' ','%','0','2','d',':','%','0','2','u',0};
200 if (lpFileTime
== NULL
|| lpResult
== NULL
)
203 if (!FileTimeToLocalFileTime(lpFileTime
, &ft
))
206 FileTimeToSystemTime(&ft
, &dt
);
210 swprintf (lpResult
, wFormat
, dt
.wDay
, dt
.wMonth
, wYear
, dt
.wHour
, dt
.wMinute
);
212 TRACE("result %s\n",debugstr_w(lpResult
));
216 /*************************************************************************
218 * SH_FileGeneralSetText [Internal]
220 * sets file path string and filename string
225 SH_FileGeneralSetText(HWND hwndDlg
, WCHAR
* lpstr
)
230 WCHAR buff
[MAX_PATH
];
236 lpdir
= wcschr(lpstr
, '\\'); /* find the last occurence of '\\' */
238 plength
= wcslen(lpstr
);
239 flength
= wcslen(lpdir
);
243 /* location text field */
244 wcsncpy(buff
, lpstr
, plength
- flength
);
245 buff
[plength
- flength
] = UNICODE_NULL
;
246 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
247 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
252 /* text filename field */
253 wcsncpy(buff
, &lpdir
[1], flength
);
254 hDlgCtrl
= GetDlgItem(hwndDlg
, 14001);
255 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
261 /*************************************************************************
263 * SH_FileGeneralSetFileSizeTime [Internal]
265 * retrieves file information from file and sets in dialog
270 SH_FileGeneralSetFileSizeTime(HWND hwndDlg
, WCHAR
* lpfilename
, PULARGE_INTEGER lpfilesize
)
274 FILETIME create_time
;
275 FILETIME accessed_time
;
277 WCHAR resultstr
[MAX_PATH
];
279 LARGE_INTEGER file_size
;
281 if (lpfilename
== NULL
)
284 hFile
= CreateFileW(lpfilename
,
286 FILE_SHARE_READ
,NULL
,
288 FILE_ATTRIBUTE_NORMAL
,
291 if (hFile
== INVALID_HANDLE_VALUE
)
293 WARN("failed to open file %s\n", debugstr_w(lpfilename
));
297 result
= GetFileTime(hFile
, &create_time
, &accessed_time
, &write_time
);
301 WARN("GetFileTime failed\n");
304 if (SHFileGeneralGetFileTimeString(&create_time
,resultstr
))
306 hDlgCtrl
= GetDlgItem(hwndDlg
, 14015);
307 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
310 if (SHFileGeneralGetFileTimeString(&accessed_time
, resultstr
))
312 hDlgCtrl
= GetDlgItem(hwndDlg
, 14017);
313 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
316 if (SHFileGeneralGetFileTimeString(&write_time
, resultstr
))
318 hDlgCtrl
= GetDlgItem(hwndDlg
, 14019);
319 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
322 if (!GetFileSizeEx(hFile
, &file_size
))
324 WARN("GetFileSize failed\n");
329 if (!StrFormatByteSizeW(file_size
.QuadPart
, resultstr
, sizeof(resultstr
) / sizeof(WCHAR
)))
331 hDlgCtrl
= GetDlgItem(hwndDlg
, 14011);
332 TRACE("result size %u resultstr %s\n", file_size
.QuadPart
, debugstr_w(resultstr
));
333 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
336 lpfilesize
->QuadPart
= (ULONGLONG
)file_size
.QuadPart
;
341 /*************************************************************************
343 * SH_SetFileVersionText [Internal]
349 SH_FileVersionQuerySetText(HWND hwndDlg
, DWORD dlgId
, LPVOID pInfo
, WCHAR
* text
, WCHAR
** resptr
)
354 if(hwndDlg
== NULL
|| resptr
== NULL
|| text
== NULL
)
357 if(VerQueryValueW(pInfo
, text
, (LPVOID
*)resptr
, &reslen
))
359 /* file description property */
360 hDlgCtrl
= GetDlgItem(hwndDlg
, dlgId
);
361 TRACE("%s :: %s\n",debugstr_w(text
), debugstr_w(*resptr
));
362 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)0, (LPARAM
)*resptr
);
368 /*************************************************************************
370 * SH_FileVersionQuerySetListText [Internal]
372 * retrieves a version string and adds it to listbox
378 SH_FileVersionQuerySetListText(HWND hwndDlg
, LPVOID pInfo
, const WCHAR
* text
, WCHAR
**resptr
, WORD lang
, WORD code
)
383 static const WCHAR wFormat
[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n',
384 'f','o','\\','%','0','4','x','%','0','4','x','\\','%','s',0 };
387 TRACE("text %s, resptr %p hwndDlg %p\n",debugstr_w(text
), resptr
, hwndDlg
);
389 if(hwndDlg
== NULL
|| resptr
== NULL
|| text
== NULL
)
392 swprintf(buff
, wFormat
, lang
, code
, text
);
393 if(VerQueryValueW(pInfo
, buff
, (LPVOID
*)resptr
, &reslen
))
395 /* listbox name property */
396 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
397 TRACE("%s :: %s\n",debugstr_w(text
), debugstr_w(*resptr
));
398 index
= SendMessageW(hDlgCtrl
, LB_ADDSTRING
, (WPARAM
)-1, (LPARAM
)text
);
399 SendMessageW(hDlgCtrl
, LB_SETITEMDATA
, (WPARAM
)index
, (LPARAM
)(WCHAR
*)*resptr
);
405 /*************************************************************************
407 * SH_FileVersionInitialize [Internal]
409 * sets all file version properties in dialog
412 SH_FileVersionInitialize(HWND hwndDlg
, WCHAR
* lpfilename
)
423 LPLANGANDCODEPAGE lplangcode
;
425 static const WCHAR wVersionFormat
[] = { '%','d','.','%','d','.','%','d','.','%','d',0 };
426 static const WCHAR wFileDescriptionFormat
[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
427 '\\','%','0','4','x','%','0','4','x','\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0 };
428 static const WCHAR wLegalCopyrightFormat
[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
429 '\\','%','0','4','x','%','0','4','x','\\','L','e','g','a','l','C','o','p','y','r','i','g','h','t',0 };
430 static const WCHAR wTranslation
[] = { 'V','a','r','F','i','l','e','I','n','f','o','\\','T','r','a','n','s','l','a','t','i','o','n',0 };
431 static const WCHAR wCompanyName
[] = { 'C','o','m','p','a','n','y','N','a','m','e',0 };
432 static const WCHAR wFileVersion
[] = { 'F','i','l','e','V','e','r','s','i','o','n',0 };
433 static const WCHAR wInternalName
[] = { 'I','n','t','e','r','n','a','l','N','a','m','e',0 };
434 static const WCHAR wOriginalFilename
[] = { 'O','r','i','g','i','n','a','l','F','i','l','e','n','a','m','e',0 };
435 static const WCHAR wProductName
[] = { 'P','r','o','d','u','c','t','N','a','m','e',0 };
436 static const WCHAR wProductVersion
[] = { 'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0 };
437 static const WCHAR wSlash
[] = { '\\',0 };
443 if(!(versize
= GetFileVersionInfoSizeW(lpfilename
, &handle
)))
445 WARN("GetFileVersionInfoSize failed\n");
449 if(!(pBuf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, versize
)))
451 WARN("HeapAlloc failed bytes %x\n",versize
);
455 if(!GetFileVersionInfoW(lpfilename
, handle
, versize
, pBuf
))
457 HeapFree(GetProcessHeap(), 0, pBuf
);
460 if(VerQueryValueW(pBuf
, wSlash
, &info
, &infolen
))
462 VS_FIXEDFILEINFO
* inf
= (VS_FIXEDFILEINFO
*)info
;
463 swprintf(buff
, wVersionFormat
, HIWORD(inf
->dwFileVersionMS
),
464 LOWORD(inf
->dwFileVersionMS
),
465 HIWORD(inf
->dwFileVersionLS
),
466 LOWORD(inf
->dwFileVersionLS
));
468 hDlgCtrl
= GetDlgItem(hwndDlg
, 14001);
469 TRACE("MS %x LS %x res %s \n",inf
->dwFileVersionMS
, inf
->dwFileVersionLS
, debugstr_w(buff
));
470 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
472 if(VerQueryValueW(pBuf
, wTranslation
, (LPVOID
*)&lplangcode
, &infolen
))
474 /* FIXME find language from current locale / if not available,
476 * for now default to first available language
478 lang
= lplangcode
->lang
;
479 code
= lplangcode
->code
;
482 swprintf(buff
, wFileDescriptionFormat
, lang
, code
);
483 SH_FileVersionQuerySetText(hwndDlg
, 14003, pBuf
, buff
, &str
);
485 swprintf(buff
, wLegalCopyrightFormat
, lang
, code
);
486 SH_FileVersionQuerySetText(hwndDlg
, 14005, pBuf
, buff
, &str
);
488 /* listbox properties */
489 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wCompanyName
, &str
, lang
, code
);
490 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wFileVersion
, &str
, lang
, code
);
491 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wInternalName
, &str
, lang
, code
);
493 /* FIXME insert language identifier */
495 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wOriginalFilename
, &str
, lang
, code
);
496 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wProductName
, &str
, lang
, code
);
497 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wProductVersion
, &str
, lang
, code
);
498 SetWindowLong(hwndDlg
, DWL_USER
, (LONG
)pBuf
);
500 /* select first item */
501 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
502 SendMessageW(hDlgCtrl
, LB_SETCURSEL
, 0, 0);
503 str
= (WCHAR
*)SendMessageW(hDlgCtrl
, LB_GETITEMDATA
, (WPARAM
)0, (LPARAM
)NULL
);
504 hDlgCtrl
= GetDlgItem(hwndDlg
, 14010);
505 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)str
);
509 /*************************************************************************
511 * SH_FileVersionDlgProc
513 * wnd proc of 'Version' property sheet page
517 SH_FileVersionDlgProc(
524 LPPROPSHEETPAGE ppsp
;
530 ppsp
= (LPPROPSHEETPAGE
)lParam
;
534 TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n",hwndDlg
, lParam
, ppsp
->lParam
);
536 lpstr
= (WCHAR
*)ppsp
->lParam
;
541 return SH_FileVersionInitialize(hwndDlg
, lpstr
);
545 if(LOWORD(wParam
) == 14009 && HIWORD(wParam
) == LBN_DBLCLK
)
551 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
552 lresult
= SendMessageW(hDlgCtrl
, LB_GETCURSEL
, (WPARAM
)NULL
, (LPARAM
)NULL
);
553 if(lresult
== LB_ERR
)
557 str
= (WCHAR
*)SendMessageW(hDlgCtrl
, LB_GETITEMDATA
, (WPARAM
)lresult
, (LPARAM
)NULL
);
563 hDlgCtrl
= GetDlgItem(hwndDlg
, 14010);
564 TRACE("hDlgCtrl %x string %s \n",hDlgCtrl
, debugstr_w(str
));
565 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)str
);
571 buf
= (LPVOID
)GetWindowLong(hwndDlg
, DWL_USER
);
572 HeapFree(GetProcessHeap(), 0, buf
);
581 /*************************************************************************
583 * SH_FileGeneralDlgProc
585 * wnd proc of 'General' property sheet page
591 SH_FileGeneralDlgProc(
598 LPPROPSHEETPAGEW ppsp
;
603 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
606 TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n",hwndDlg
, lParam
, ppsp
->lParam
);
608 lpstr
= (WCHAR
*)ppsp
->lParam
;
612 ERR("no filename\n");
615 /* set general text properties filename filelocation and icon */
616 SH_FileGeneralSetText(hwndDlg
, lpstr
);
617 /* enumerate file extension from registry and application which opens it*/
618 SH_FileGeneralSetFileType(hwndDlg
, wcsrchr(lpstr
, '.'));
619 /* set file time create/modfied/accessed */
620 SH_FileGeneralSetFileSizeTime(hwndDlg
, lpstr
, NULL
);
628 BOOL CALLBACK
AddShellPropSheetExCallback(HPROPSHEETPAGE hPage
, LPARAM lParam
)
630 PROPSHEETHEADERW
*pinfo
= (PROPSHEETHEADERW
*)lParam
;
632 if (pinfo
->nPages
< MAX_PROPERTY_SHEET_PAGE
)
634 pinfo
->u3
.phpage
[pinfo
->nPages
++] = hPage
;
642 EnumPropSheetExt(LPWSTR wFileName
, PROPSHEETHEADERW
*pinfo
, int NumPages
, HPSXA
* hpsxa
, IDataObject
*pDataObj
)
644 WCHAR szName
[MAX_PATH
] = {0};
651 pOffset
= wcsrchr(wFileName
, L
'.');
654 Length
= wcslen(szName
);
655 if (Length
+ 6 > sizeof(szName
)/sizeof(szName
[0]))
658 if (CLSIDFromString(wFileName
, &clsid
) == NOERROR
)
660 wcscpy(szName
, L
"CLSID\\");
661 wcscpy(&szName
[6], wFileName
);
665 wcscpy(szName
, wFileName
);
670 Length
= wcslen(pOffset
);
671 if (Length
>= sizeof(szName
)/sizeof(szName
[0]))
673 wcscpy(szName
, pOffset
);
675 TRACE("EnumPropSheetExt szName %s\n", debugstr_w(szName
));
676 hpsxa
[0] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, szName
, NumPages
, pDataObj
);
677 Pages
= SHAddFromPropSheetExtArray(hpsxa
[0], AddShellPropSheetExCallback
, (LPARAM
)pinfo
);
682 /* try to load property sheet handlers from prog id key */
683 dwName
= sizeof(szName
);
684 if (RegGetValueW(HKEY_CLASSES_ROOT
, pOffset
, NULL
, RRF_RT_REG_SZ
, NULL
, szName
, &dwName
) == ERROR_SUCCESS
)
686 TRACE("EnumPropSheetExt szName %s, pOffset %s\n", debugstr_w(szName
), debugstr_w(pOffset
));
687 szName
[(sizeof(szName
)/sizeof(WCHAR
))-1] = L
'\0';
688 hpsxa
[1] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, szName
, NumPages
- Pages
, pDataObj
);
689 Pages
+=SHAddFromPropSheetExtArray(hpsxa
[1], AddShellPropSheetExCallback
, (LPARAM
)pinfo
);
697 /*************************************************************************
699 * SH_ShowPropertiesDialog
701 * called from ShellExecuteExW32
703 * lpf contains (quoted) path of folder/file
705 * TODO: provide button change application type if file has registered type
706 * make filename field editable and apply changes to filename on close
710 SH_ShowPropertiesDialog(WCHAR
* lpf
, LPCITEMIDLIST pidlFolder
, LPCITEMIDLIST
* apidl
)
712 PROPSHEETHEADERW pinfo
;
713 HPROPSHEETPAGE hppages
[MAX_PROPERTY_SHEET_PAGE
];
714 WCHAR wFileName
[MAX_PATH
];
719 IDataObject
* pDataObj
= NULL
;
722 TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(lpf
));
730 memset(hppages
, 0x0, sizeof(HPROPSHEETPAGE
) * MAX_PROPERTY_SHEET_PAGE
);
733 /* remove quotes from lpf */
734 LPCWSTR src
= lpf
+ 1;
735 LPWSTR dst
= wFileName
;
737 while(*src
&& *src
!='"')
744 wcscpy(wFileName
, lpf
);
747 if (PathIsDirectoryW(wFileName
))
749 return SH_ShowFolderProperties(wFileName
);
752 if (wcslen(wFileName
) == 3)
754 return SH_ShowDriveProperties(wFileName
, pidlFolder
, apidl
);
758 pFileName
= wcsrchr(wFileName
, '\\');
760 pFileName
= wFileName
;
765 memset(&pinfo
, 0x0, sizeof(PROPSHEETHEADERW
));
766 pinfo
.dwSize
= sizeof(PROPSHEETHEADERW
);
767 pinfo
.dwFlags
= PSH_NOCONTEXTHELP
| PSH_PROPTITLE
;
768 pinfo
.u3
.phpage
= hppages
;
769 pinfo
.pszCaption
= pFileName
;
771 hppages
[pinfo
.nPages
] = SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG", SH_FileGeneralDlgProc
, (LPARAM
)wFileName
, NULL
);
772 if (hppages
[pinfo
.nPages
])
776 hResult
= SHCreateDataObject(pidlFolder
, 1, apidl
, NULL
, &IID_IDataObject
, (LPVOID
*)&pDataObj
);
779 if (!EnumPropSheetExt(wFileName
, &pinfo
, MAX_PROPERTY_SHEET_PAGE
-1, hpsxa
, pDataObj
))
786 if ( GetFileVersionInfoSizeW(lpf
, &dwHandle
))
788 hppages
[pinfo
.nPages
] = SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",SH_FileVersionDlgProc
, (LPARAM
)wFileName
, NULL
);
789 if (hppages
[pinfo
.nPages
])
793 res
= PropertySheetW(&pinfo
);
797 SHDestroyPropSheetExtArray(hpsxa
[0]);
798 SHDestroyPropSheetExtArray(hpsxa
[1]);
799 IDataObject_Release(pDataObj
);