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
);
35 /*************************************************************************
37 * SH_CreatePropertySheetPage [Internal]
39 * creates a property sheet page from an resource name
44 SH_CreatePropertySheetPage(LPSTR resname
, DLGPROC dlgproc
, LPARAM lParam
, LPWSTR szTitle
)
51 return (HPROPSHEETPAGE
)0;
53 hRes
= FindResourceA(shell32_hInstance
, resname
, (LPSTR
)RT_DIALOG
);
57 ERR("failed to find resource name\n");
58 return (HPROPSHEETPAGE
)0;
61 lpsztemplate
= LoadResource(shell32_hInstance
, hRes
);
63 if (lpsztemplate
== NULL
)
64 return (HPROPSHEETPAGE
)0;
66 memset(&ppage
, 0x0, sizeof(PROPSHEETPAGEW
));
67 ppage
.dwSize
= sizeof(PROPSHEETPAGEW
);
68 ppage
.dwFlags
= PSP_DLGINDIRECT
;
69 ppage
.u
.pResource
= lpsztemplate
;
70 ppage
.pfnDlgProc
= dlgproc
;
71 ppage
.lParam
= lParam
;
72 ppage
.pszTitle
= szTitle
;
76 ppage
.dwFlags
|= PSP_USETITLE
;
79 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
;
103 TRACE("fileext %s\n", debugstr_w(filext
));
108 hDlgCtrl
= GetDlgItem(hwndDlg
, 14005);
110 if (hDlgCtrl
== NULL
)
113 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, filext
, &hKey
) != ERROR_SUCCESS
)
115 /* the file extension is unknown, so default to string "FileExtension File" */
116 SendMessageW(hDlgCtrl
, WM_GETTEXT
, (WPARAM
)MAX_PATH
, (LPARAM
)value
);
117 swprintf(name
, value
, &filext
[1]);
118 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
)
128 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, value
, &hKey
) == ERROR_SUCCESS
)
130 if (RegLoadMUIStringW(hKey
, L
"FriendlyTypeName", value
, MAX_PATH
, NULL
, 0, NULL
) != ERROR_SUCCESS
)
132 lvalue
= lname
= MAX_PATH
;
133 result
= RegEnumValueW(hKey
, 0, name
, &lname
, NULL
, NULL
, (LPBYTE
)value
, &lvalue
);
138 if (RegGetValueW(hKey
, L
"DefaultIcon", NULL
, RRF_RT_REG_SZ
, NULL
, name
, &lname
) == ERROR_SUCCESS
)
141 WCHAR szBuffer
[MAX_PATH
];
145 LPVOID pResource
= NULL
;
148 Offset
= wcsrchr(name
, L
',');
152 IconIndex
= _wtoi(Offset
+ 2);
154 name
[MAX_PATH
- 1] = L
'\0';
156 if (ExpandEnvironmentStringsW(name
, szBuffer
, MAX_PATH
))
158 szBuffer
[MAX_PATH
- 1] = L
'\0';
159 hLibrary
= LoadLibraryExW(szBuffer
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
162 hResource
= FindResourceW(hLibrary
, MAKEINTRESOURCEW(IconIndex
), (LPCWSTR
)RT_ICON
);
165 hGlobal
= LoadResource(shell32_hInstance
, hResource
);
168 pResource
= LockResource(hGlobal
);
169 if (pResource
!= NULL
)
171 hIcon
= CreateIconFromResource(pResource
, SizeofResource(shell32_hInstance
, hResource
), TRUE
, 0x00030000);
172 TRACE("hIcon %p,- szBuffer %s IconIndex %u error %u icon %p hResource %p pResource %p\n",
174 debugstr_w(szBuffer
),
176 MAKEINTRESOURCEW(IconIndex
),
179 SendDlgItemMessageW(hwndDlg
, 14000, STM_SETICON
, (WPARAM
)hIcon
, 0);
183 FreeLibrary(hLibrary
);
191 /* file extension type */
192 value
[MAX_PATH
- 1] = L
'\0';
193 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)value
);
198 /*************************************************************************
200 * SHFileGeneralGetFileTimeString [Internal]
202 * formats a given LPFILETIME struct into readable user format
206 SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime
, WCHAR
*lpResult
)
211 static const WCHAR wFormat
[] = {
212 '%', '0', '2', 'd', '/', '%', '0', '2', 'd', '/', '%', '0', '4', 'd',
213 ' ', ' ', '%', '0', '2', 'd', ':', '%', '0', '2', 'u', 0 };
215 if (lpFileTime
== NULL
|| lpResult
== NULL
)
218 if (!FileTimeToLocalFileTime(lpFileTime
, &ft
))
221 FileTimeToSystemTime(&ft
, &dt
);
226 swprintf(lpResult
, wFormat
, dt
.wDay
, dt
.wMonth
, wYear
, dt
.wHour
, dt
.wMinute
);
228 TRACE("result %s\n", debugstr_w(lpResult
));
232 /*************************************************************************
234 * SH_FileGeneralSetText [Internal]
236 * sets file path string and filename string
241 SH_FileGeneralSetText(HWND hwndDlg
, WCHAR
*lpstr
)
246 WCHAR buff
[MAX_PATH
];
252 lpdir
= wcschr(lpstr
, '\\'); /* find the last occurence of '\\' */
254 plength
= wcslen(lpstr
);
255 flength
= wcslen(lpdir
);
259 /* location text field */
260 wcsncpy(buff
, lpstr
, plength
- flength
);
261 buff
[plength
- flength
] = UNICODE_NULL
;
262 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
263 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
268 /* text filename field */
269 wcsncpy(buff
, &lpdir
[1], flength
);
270 hDlgCtrl
= GetDlgItem(hwndDlg
, 14001);
271 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
277 /*************************************************************************
279 * SH_FileGeneralSetFileSizeTime [Internal]
281 * retrieves file information from file and sets in dialog
286 SH_FileGeneralSetFileSizeTime(HWND hwndDlg
, WCHAR
*lpfilename
, PULARGE_INTEGER lpfilesize
)
290 FILETIME create_time
;
291 FILETIME accessed_time
;
293 WCHAR resultstr
[MAX_PATH
];
295 LARGE_INTEGER file_size
;
297 if (lpfilename
== NULL
)
300 hFile
= CreateFileW(lpfilename
,
305 FILE_ATTRIBUTE_NORMAL
,
308 if (hFile
== INVALID_HANDLE_VALUE
)
310 WARN("failed to open file %s\n", debugstr_w(lpfilename
));
314 result
= GetFileTime(hFile
, &create_time
, &accessed_time
, &write_time
);
318 WARN("GetFileTime failed\n");
322 if (SHFileGeneralGetFileTimeString(&create_time
, resultstr
))
324 hDlgCtrl
= GetDlgItem(hwndDlg
, 14015);
325 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
328 if (SHFileGeneralGetFileTimeString(&accessed_time
, resultstr
))
330 hDlgCtrl
= GetDlgItem(hwndDlg
, 14017);
331 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
334 if (SHFileGeneralGetFileTimeString(&write_time
, resultstr
))
336 hDlgCtrl
= GetDlgItem(hwndDlg
, 14019);
337 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
340 if (!GetFileSizeEx(hFile
, &file_size
))
342 WARN("GetFileSize failed\n");
349 if (!StrFormatByteSizeW(file_size
.QuadPart
,
351 sizeof(resultstr
) / sizeof(WCHAR
)))
354 hDlgCtrl
= GetDlgItem(hwndDlg
, 14011);
356 TRACE("result size %u resultstr %s\n", file_size
.QuadPart
, debugstr_w(resultstr
));
357 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
360 lpfilesize
->QuadPart
= (ULONGLONG
)file_size
.QuadPart
;
365 /*************************************************************************
367 * SH_SetFileVersionText [Internal]
373 SH_FileVersionQuerySetText(HWND hwndDlg
, DWORD dlgId
, LPVOID pInfo
, WCHAR
*text
, WCHAR
**resptr
)
378 if (hwndDlg
== NULL
|| resptr
== NULL
|| text
== NULL
)
381 if (VerQueryValueW(pInfo
, text
, (LPVOID
*)resptr
, &reslen
))
383 /* file description property */
384 hDlgCtrl
= GetDlgItem(hwndDlg
, dlgId
);
385 TRACE("%s :: %s\n", debugstr_w(text
), debugstr_w(*resptr
));
386 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)0, (LPARAM
)*resptr
);
393 /*************************************************************************
395 * SH_FileVersionQuerySetListText [Internal]
397 * retrieves a version string and adds it to listbox
402 SH_FileVersionQuerySetListText(HWND hwndDlg
, LPVOID pInfo
, const WCHAR
*text
, WCHAR
**resptr
, WORD lang
, WORD code
)
407 static const WCHAR wFormat
[] = {
408 '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
409 '\\', '%', '0', '4', 'x', '%', '0', '4', 'x', '\\', '%', 's', 0 };
412 TRACE("text %s, resptr %p hwndDlg %p\n", debugstr_w(text
), resptr
, hwndDlg
);
414 if (hwndDlg
== NULL
|| resptr
== NULL
|| text
== NULL
)
417 swprintf(buff
, wFormat
, lang
, code
, text
);
419 if (VerQueryValueW(pInfo
, buff
, (LPVOID
*)resptr
, &reslen
))
421 /* listbox name property */
422 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
423 TRACE("%s :: %s\n", debugstr_w(text
), debugstr_w(*resptr
));
424 index
= SendMessageW(hDlgCtrl
, LB_ADDSTRING
, (WPARAM
)-1, (LPARAM
)text
);
425 SendMessageW(hDlgCtrl
, LB_SETITEMDATA
, (WPARAM
)index
, (LPARAM
)(WCHAR
*)*resptr
);
432 /*************************************************************************
434 * SH_FileVersionInitialize [Internal]
436 * sets all file version properties in dialog
440 SH_FileVersionInitialize(HWND hwndDlg
, WCHAR
*lpfilename
)
451 LPLANGANDCODEPAGE lplangcode
;
453 static const WCHAR wVersionFormat
[] = {
454 '%', 'd', '.', '%', 'd', '.', '%', 'd', '.', '%', 'd', 0 };
455 static const WCHAR wFileDescriptionFormat
[] = {
456 '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
457 '\\', '%', '0', '4', 'x', '%', '0', '4', 'x',
458 '\\', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 0 };
459 static const WCHAR wLegalCopyrightFormat
[] = {
460 '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
461 '\\', '%', '0', '4', 'x', '%', '0', '4', 'x',
462 '\\', 'L', 'e', 'g', 'a', 'l', 'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', 0 };
463 static const WCHAR wTranslation
[] = {
464 'V', 'a', 'r', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
465 '\\', 'T', 'r', 'a', 'n', 's', 'l', 'a', 't', 'i', 'o', 'n', 0 };
466 static const WCHAR wCompanyName
[] = {
467 'C', 'o', 'm', 'p', 'a', 'n', 'y', 'N', 'a', 'm', 'e', 0 };
468 static const WCHAR wFileVersion
[] = {
469 'F', 'i', 'l', 'e', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
470 static const WCHAR wInternalName
[] = {
471 'I', 'n', 't', 'e', 'r', 'n', 'a', 'l', 'N', 'a', 'm', 'e', 0 };
472 static const WCHAR wOriginalFilename
[] = {
473 'O', 'r', 'i', 'g', 'i', 'n', 'a', 'l', 'F', 'i', 'l', 'e', 'n', 'a', 'm', 'e', 0 };
474 static const WCHAR wProductName
[] = {
475 'P', 'r', 'o', 'd', 'u', 'c', 't', 'N', 'a', 'm', 'e', 0 };
476 static const WCHAR wProductVersion
[] = {
477 'P', 'r', 'o', 'd', 'u', 'c', 't', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
478 static const WCHAR wSlash
[] = { '\\', 0 };
483 if (!(versize
= GetFileVersionInfoSizeW(lpfilename
, &handle
)))
485 WARN("GetFileVersionInfoSize failed\n");
489 if (!(pBuf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, versize
)))
491 WARN("HeapAlloc failed bytes %x\n", versize
);
495 if (!GetFileVersionInfoW(lpfilename
, handle
, versize
, pBuf
))
497 HeapFree(GetProcessHeap(), 0, pBuf
);
501 if (VerQueryValueW(pBuf
, wSlash
, &info
, &infolen
))
503 VS_FIXEDFILEINFO
*inf
= (VS_FIXEDFILEINFO
*)info
;
504 swprintf(buff
, wVersionFormat
, HIWORD(inf
->dwFileVersionMS
),
505 LOWORD(inf
->dwFileVersionMS
),
506 HIWORD(inf
->dwFileVersionLS
),
507 LOWORD(inf
->dwFileVersionLS
));
508 hDlgCtrl
= GetDlgItem(hwndDlg
, 14001);
509 TRACE("MS %x LS %x res %s \n", inf
->dwFileVersionMS
, inf
->dwFileVersionLS
, debugstr_w(buff
));
510 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
513 if (VerQueryValueW(pBuf
, wTranslation
, (LPVOID
*)&lplangcode
, &infolen
))
515 /* FIXME find language from current locale / if not available,
517 * for now default to first available language
519 lang
= lplangcode
->lang
;
520 code
= lplangcode
->code
;
523 swprintf(buff
, wFileDescriptionFormat
, lang
, code
);
524 SH_FileVersionQuerySetText(hwndDlg
, 14003, pBuf
, buff
, &str
);
526 swprintf(buff
, wLegalCopyrightFormat
, lang
, code
);
527 SH_FileVersionQuerySetText(hwndDlg
, 14005, pBuf
, buff
, &str
);
529 /* listbox properties */
530 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wCompanyName
, &str
, lang
, code
);
531 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wFileVersion
, &str
, lang
, code
);
532 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wInternalName
, &str
, lang
, code
);
534 /* FIXME insert language identifier */
536 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wOriginalFilename
, &str
, lang
, code
);
537 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wProductName
, &str
, lang
, code
);
538 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wProductVersion
, &str
, lang
, code
);
539 SetWindowLong(hwndDlg
, DWL_USER
, (LONG
)pBuf
);
541 /* select first item */
542 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
543 SendMessageW(hDlgCtrl
, LB_SETCURSEL
, 0, 0);
544 str
= (WCHAR
*) SendMessageW(hDlgCtrl
, LB_GETITEMDATA
, (WPARAM
)0, (LPARAM
)NULL
);
545 hDlgCtrl
= GetDlgItem(hwndDlg
, 14010);
546 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)str
);
551 /*************************************************************************
553 * SH_FileVersionDlgProc
555 * wnd proc of 'Version' property sheet page
560 SH_FileVersionDlgProc(HWND hwndDlg
,
565 LPPROPSHEETPAGE ppsp
;
572 ppsp
= (LPPROPSHEETPAGE
)lParam
;
577 TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n", hwndDlg
, lParam
, ppsp
->lParam
);
579 lpstr
= (WCHAR
*)ppsp
->lParam
;
584 return SH_FileVersionInitialize(hwndDlg
, lpstr
);
587 if (LOWORD(wParam
) == 14009 && HIWORD(wParam
) == LBN_DBLCLK
)
593 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
594 lresult
= SendMessageW(hDlgCtrl
, LB_GETCURSEL
, (WPARAM
)NULL
, (LPARAM
)NULL
);
596 if (lresult
== LB_ERR
)
599 str
= (WCHAR
*) SendMessageW(hDlgCtrl
, LB_GETITEMDATA
, (WPARAM
)lresult
, (LPARAM
)NULL
);
604 hDlgCtrl
= GetDlgItem(hwndDlg
, 14010);
605 TRACE("hDlgCtrl %x string %s \n", hDlgCtrl
, debugstr_w(str
));
606 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)str
);
613 buf
= (LPVOID
) GetWindowLong(hwndDlg
, DWL_USER
);
614 HeapFree(GetProcessHeap(), 0, buf
);
624 /*************************************************************************
626 * SH_FileGeneralDlgProc
628 * wnd proc of 'General' property sheet page
634 SH_FileGeneralDlgProc(HWND hwndDlg
,
639 LPPROPSHEETPAGEW ppsp
;
645 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
650 TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n", hwndDlg
, lParam
, ppsp
->lParam
);
652 lpstr
= (WCHAR
*)ppsp
->lParam
;
656 ERR("no filename\n");
660 /* set general text properties filename filelocation and icon */
661 SH_FileGeneralSetText(hwndDlg
, lpstr
);
663 /* enumerate file extension from registry and application which opens it */
664 SH_FileGeneralSetFileType(hwndDlg
, wcsrchr(lpstr
, '.'));
666 /* set file time create/modfied/accessed */
667 SH_FileGeneralSetFileSizeTime(hwndDlg
, lpstr
, NULL
);
680 AddShellPropSheetExCallback(HPROPSHEETPAGE hPage
,
683 PROPSHEETHEADERW
*pinfo
= (PROPSHEETHEADERW
*)lParam
;
685 if (pinfo
->nPages
< MAX_PROPERTY_SHEET_PAGE
)
687 pinfo
->u3
.phpage
[pinfo
->nPages
++] = hPage
;
695 EnumPropSheetExt(LPWSTR wFileName
, PROPSHEETHEADERW
*pinfo
, int NumPages
, HPSXA
*hpsxa
, IDataObject
*pDataObj
)
697 WCHAR szName
[MAX_PATH
] = { 0 };
704 pOffset
= wcsrchr(wFileName
, L
'.');
708 Length
= wcslen(szName
);
710 if (Length
+ 6 > sizeof(szName
) / sizeof(szName
[0]))
713 if (CLSIDFromString(wFileName
, &clsid
) == NOERROR
)
715 wcscpy(szName
, L
"CLSID\\");
716 wcscpy(&szName
[6], wFileName
);
720 wcscpy(szName
, wFileName
);
725 Length
= wcslen(pOffset
);
727 if (Length
>= sizeof(szName
) / sizeof(szName
[0]))
730 wcscpy(szName
, pOffset
);
733 TRACE("EnumPropSheetExt szName %s\n", debugstr_w(szName
));
735 hpsxa
[0] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, szName
, NumPages
, pDataObj
);
738 Pages
= SHAddFromPropSheetExtArray(hpsxa
[0], AddShellPropSheetExCallback
, (LPARAM
)pinfo
);
742 /* try to load property sheet handlers from prog id key */
743 dwName
= sizeof(szName
);
745 if (RegGetValueW(HKEY_CLASSES_ROOT
, pOffset
, NULL
, RRF_RT_REG_SZ
, NULL
, szName
, &dwName
) == ERROR_SUCCESS
)
747 TRACE("EnumPropSheetExt szName %s, pOffset %s\n", debugstr_w(szName
), debugstr_w(pOffset
));
748 szName
[(sizeof(szName
) / sizeof(WCHAR
)) - 1] = L
'\0';
749 hpsxa
[1] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, szName
, NumPages
- Pages
, pDataObj
);
750 Pages
+= SHAddFromPropSheetExtArray(hpsxa
[1], AddShellPropSheetExCallback
, (LPARAM
)pinfo
);
757 /*************************************************************************
759 * SH_ShowPropertiesDialog
761 * called from ShellExecuteExW32
763 * lpf contains (quoted) path of folder/file
765 * TODO: provide button change application type if file has registered type
766 * make filename field editable and apply changes to filename on close
770 SH_ShowPropertiesDialog(WCHAR
*lpf
, LPCITEMIDLIST pidlFolder
, LPCITEMIDLIST
*apidl
)
772 PROPSHEETHEADERW pinfo
;
773 HPROPSHEETPAGE hppages
[MAX_PROPERTY_SHEET_PAGE
];
774 WCHAR wFileName
[MAX_PATH
];
779 IDataObject
*pDataObj
= NULL
;
782 TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(lpf
));
790 memset(hppages
, 0x0, sizeof(HPROPSHEETPAGE
) * MAX_PROPERTY_SHEET_PAGE
);
794 /* remove quotes from lpf */
795 LPCWSTR src
= lpf
+ 1;
796 LPWSTR dst
= wFileName
;
798 while (*src
&& *src
!= '"')
805 wcscpy(wFileName
, lpf
);
808 if (PathIsDirectoryW(wFileName
))
810 return SH_ShowFolderProperties(wFileName
);
813 if (wcslen(wFileName
) == 3)
815 return SH_ShowDriveProperties(wFileName
, pidlFolder
, apidl
);
818 pFileName
= wcsrchr(wFileName
, '\\');
821 pFileName
= wFileName
;
825 memset(&pinfo
, 0x0, sizeof(PROPSHEETHEADERW
));
826 pinfo
.dwSize
= sizeof(PROPSHEETHEADERW
);
827 pinfo
.dwFlags
= PSH_NOCONTEXTHELP
| PSH_PROPTITLE
;
828 pinfo
.u3
.phpage
= hppages
;
829 pinfo
.pszCaption
= pFileName
;
831 hppages
[pinfo
.nPages
] =
832 SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG",
833 SH_FileGeneralDlgProc
,
837 if (hppages
[pinfo
.nPages
])
840 hResult
= SHCreateDataObject(pidlFolder
, 1, apidl
, NULL
, &IID_IDataObject
, (LPVOID
*)&pDataObj
);
844 if (!EnumPropSheetExt(wFileName
, &pinfo
, MAX_PROPERTY_SHEET_PAGE
- 1, hpsxa
, pDataObj
))
851 if (GetFileVersionInfoSizeW(lpf
, &dwHandle
))
853 hppages
[pinfo
.nPages
] =
854 SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",
855 SH_FileVersionDlgProc
,
858 if (hppages
[pinfo
.nPages
])
862 res
= PropertySheetW(&pinfo
);
866 SHDestroyPropSheetExtArray(hpsxa
[0]);
867 SHDestroyPropSheetExtArray(hpsxa
[1]);
868 IDataObject_Release(pDataObj
);