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
22 #define NONAMELESSUNION
25 #include "wine/port.h"
36 #include "wine/debug.h"
41 #include "shell32_main.h"
43 #include "undocshell.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
48 #define MAX_PROPERTY_SHEET_PAGE 32
50 typedef struct _LANGANDCODEPAGE_
54 } LANGANDCODEPAGE
, *LPLANGANDCODEPAGE
;
56 HPSXA WINAPI
SHCreatePropSheetExtArrayEx(HKEY hKey
, LPCWSTR pszSubKey
, UINT max_iface
, IDataObject
*pDataObj
);
57 /*************************************************************************
59 * SH_CreatePropertySheetPage [Internal]
61 * creates a property sheet page from an resource name
65 SH_CreatePropertySheetPage(LPSTR resname
, DLGPROC dlgproc
, LPARAM lParam
, LPWSTR szTitle
)
72 return (HPROPSHEETPAGE
)0;
74 hRes
= FindResourceA(shell32_hInstance
, resname
, (LPSTR
)RT_DIALOG
);
78 ERR("failed to find resource name\n");
79 return (HPROPSHEETPAGE
)0;
81 lpsztemplate
= LoadResource(shell32_hInstance
, hRes
);
82 if (lpsztemplate
== NULL
)
83 return (HPROPSHEETPAGE
)0;
85 memset(&ppage
, 0x0, sizeof(PROPSHEETPAGEW
));
86 ppage
.dwSize
= sizeof(PROPSHEETPAGEW
);
87 ppage
.dwFlags
= PSP_DLGINDIRECT
;
88 ppage
.u
.pResource
= lpsztemplate
;
89 ppage
.pfnDlgProc
= dlgproc
;
90 ppage
.lParam
= lParam
;
91 ppage
.pszTitle
= szTitle
;
94 ppage
.dwFlags
|= PSP_USETITLE
;
96 return CreatePropertySheetPageW(&ppage
);
105 /*************************************************************************
107 * SH_FileGeneralFileType [Internal]
109 * retrieves file extension description from registry and sets it in dialog
111 * TODO: retrieve file extension default icon and load it
112 * find executable name from registry, retrieve description from executable
116 SH_FileGeneralSetFileType(HWND hwndDlg
, WCHAR
* filext
)
118 WCHAR name
[MAX_PATH
];
119 WCHAR value
[MAX_PATH
];
120 DWORD lname
= MAX_PATH
;
121 DWORD lvalue
= MAX_PATH
;
127 TRACE("fileext %s\n", debugstr_w(filext
));
132 hDlgCtrl
= GetDlgItem(hwndDlg
, 14005);
134 if (hDlgCtrl
== NULL
)
137 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, filext
, &hKey
) != ERROR_SUCCESS
)
139 /* the fileextension is unknown, so default to string "FileExtension File" */
140 SendMessageW(hDlgCtrl
, WM_GETTEXT
, (WPARAM
)MAX_PATH
, (LPARAM
)value
);
141 sprintfW(name
, value
, &filext
[1]);
142 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)name
);
145 result
= RegEnumValueW(hKey
, 0, name
, &lname
, NULL
, NULL
, (LPBYTE
)value
, &lvalue
);
148 if (result
!= ERROR_SUCCESS
)
150 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, value
, &hKey
) == ERROR_SUCCESS
)
152 if (RegLoadMUIStringW(hKey
, L
"FriendlyTypeName", value
, MAX_PATH
, NULL
, 0, NULL
) != ERROR_SUCCESS
)
154 lvalue
= lname
= MAX_PATH
;
155 result
= RegEnumValueW(hKey
,0, name
, &lname
, NULL
, NULL
, (LPBYTE
)value
, &lvalue
);
158 if (RegGetValueW(hKey
, L
"DefaultIcon", NULL
, RRF_RT_REG_SZ
, NULL
, name
, &lname
) == ERROR_SUCCESS
)
161 WCHAR szBuffer
[MAX_PATH
];
165 LPVOID pResource
= NULL
;
168 Offset
= wcsrchr(name
, L
',');
171 IconIndex
= _wtoi(Offset
+ 2);
173 name
[MAX_PATH
-1] = L
'\0';
174 if (ExpandEnvironmentStringsW(name
, szBuffer
, MAX_PATH
))
176 szBuffer
[MAX_PATH
-1] = L
'\0';
177 hLibrary
= LoadLibraryExW(szBuffer
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
180 hResource
= FindResourceW(hLibrary
, MAKEINTRESOURCEW(IconIndex
), (LPCWSTR
)RT_ICON
);
183 hGlobal
= LoadResource(shell32_hInstance
, hResource
);
186 pResource
= LockResource(hGlobal
);
187 if (pResource
!= NULL
)
189 hIcon
= CreateIconFromResource(pResource
, SizeofResource(shell32_hInstance
, hResource
), TRUE
, 0x00030000);
190 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
);
191 SendDlgItemMessageW(hwndDlg
, 14000, STM_SETICON
, (WPARAM
)hIcon
, 0);
195 FreeLibrary(hLibrary
);
203 /* file extension type */
204 value
[MAX_PATH
-1] = L
'\0';
205 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)value
);
208 /*************************************************************************
210 * SHFileGeneralGetFileTimeString [Internal]
212 * formats a given LPFILETIME struct into readable user format
216 SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime
, WCHAR
* lpResult
)
221 static const WCHAR wFormat
[] = {'%','0','2','d','/','%','0','2','d','/','%','0','4','d',' ',' ','%','0','2','d',':','%','0','2','u',0};
223 if (lpFileTime
== NULL
|| lpResult
== NULL
)
226 if (!FileTimeToLocalFileTime(lpFileTime
, &ft
))
229 FileTimeToSystemTime(&ft
, &dt
);
233 sprintfW (lpResult
, wFormat
, dt
.wDay
, dt
.wMonth
, wYear
, dt
.wHour
, dt
.wMinute
);
235 TRACE("result %s\n",debugstr_w(lpResult
));
239 /*************************************************************************
241 * SH_FileGeneralSetText [Internal]
243 * sets file path string and filename string
248 SH_FileGeneralSetText(HWND hwndDlg
, WCHAR
* lpstr
)
253 WCHAR buff
[MAX_PATH
];
259 lpdir
= strrchrW(lpstr
, '\\'); /* find the last occurence of '\\' */
261 plength
= strlenW(lpstr
);
262 flength
= strlenW(lpdir
);
266 /* location text field */
267 strncpyW(buff
, lpstr
, plength
- flength
);
268 buff
[plength
- flength
] = UNICODE_NULL
;
269 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
270 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
275 /* text filename field */
276 strncpyW(buff
, &lpdir
[1], flength
);
277 hDlgCtrl
= GetDlgItem(hwndDlg
, 14001);
278 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
284 /*************************************************************************
286 * SH_FileGeneralSetFileSizeTime [Internal]
288 * retrieves file information from file and sets in dialog
293 SH_FileGeneralSetFileSizeTime(HWND hwndDlg
, WCHAR
* lpfilename
, PULARGE_INTEGER lpfilesize
)
297 FILETIME create_time
;
298 FILETIME accessed_time
;
300 WCHAR resultstr
[MAX_PATH
];
302 LARGE_INTEGER file_size
;
304 if (lpfilename
== NULL
)
307 hFile
= CreateFileW(lpfilename
,
309 FILE_SHARE_READ
,NULL
,
311 FILE_ATTRIBUTE_NORMAL
,
314 if (hFile
== INVALID_HANDLE_VALUE
)
316 WARN("failed to open file %s\n", debugstr_w(lpfilename
));
320 result
= GetFileTime(hFile
, &create_time
, &accessed_time
, &write_time
);
324 WARN("GetFileTime failed\n");
327 if (SHFileGeneralGetFileTimeString(&create_time
,resultstr
))
329 hDlgCtrl
= GetDlgItem(hwndDlg
, 14015);
330 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
333 if (SHFileGeneralGetFileTimeString(&accessed_time
, resultstr
))
335 hDlgCtrl
= GetDlgItem(hwndDlg
, 14017);
336 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
339 if (SHFileGeneralGetFileTimeString(&write_time
, resultstr
))
341 hDlgCtrl
= GetDlgItem(hwndDlg
, 14019);
342 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
345 if (!GetFileSizeEx(hFile
, &file_size
))
347 WARN("GetFileSize failed\n");
352 if (!StrFormatByteSizeW(file_size
.QuadPart
, resultstr
, sizeof(resultstr
)/sizeof(resultstr
[0])));
354 hDlgCtrl
= GetDlgItem(hwndDlg
, 14011);
355 ERR("result size %u resultstr %s %s\n", file_size
.QuadPart
, debugstr_w(resultstr
), resultstr
);
356 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)resultstr
);
359 lpfilesize
->QuadPart
= (ULONGLONG
)file_size
.QuadPart
;
364 /*************************************************************************
366 * SH_SetFileVersionText [Internal]
372 SH_FileVersionQuerySetText(HWND hwndDlg
, DWORD dlgId
, LPVOID pInfo
, WCHAR
* text
, WCHAR
** resptr
)
377 if(hwndDlg
== NULL
|| resptr
== NULL
|| text
== NULL
)
380 if(VerQueryValueW(pInfo
, text
, (LPVOID
*)resptr
, &reslen
))
382 /* file description property */
383 hDlgCtrl
= GetDlgItem(hwndDlg
, dlgId
);
384 TRACE("%s :: %s\n",debugstr_w(text
), debugstr_w(*resptr
));
385 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)0, (LPARAM
)*resptr
);
391 /*************************************************************************
393 * SH_FileVersionQuerySetListText [Internal]
395 * retrieves a version string and adds it to listbox
401 SH_FileVersionQuerySetListText(HWND hwndDlg
, LPVOID pInfo
, const WCHAR
* text
, WCHAR
**resptr
, WORD lang
, WORD code
)
406 static const WCHAR wFormat
[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n',
407 'f','o','\\','%','0','4','x','%','0','4','x','\\','%','s',0 };
410 TRACE("text %s, resptr %p hwndDlg %p\n",debugstr_w(text
), resptr
, hwndDlg
);
412 if(hwndDlg
== NULL
|| resptr
== NULL
|| text
== NULL
)
415 sprintfW(buff
, wFormat
, lang
, code
, text
);
416 if(VerQueryValueW(pInfo
, buff
, (LPVOID
*)resptr
, &reslen
))
418 /* listbox name property */
419 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
420 TRACE("%s :: %s\n",debugstr_w(text
), debugstr_w(*resptr
));
421 index
= SendMessageW(hDlgCtrl
, LB_ADDSTRING
, (WPARAM
)-1, (LPARAM
)text
);
422 SendMessageW(hDlgCtrl
, LB_SETITEMDATA
, (WPARAM
)index
, (LPARAM
)(WCHAR
*)*resptr
);
428 /*************************************************************************
430 * SH_FileVersionInitialize [Internal]
432 * sets all file version properties in dialog
435 SH_FileVersionInitialize(HWND hwndDlg
, WCHAR
* lpfilename
)
446 LPLANGANDCODEPAGE lplangcode
;
448 static const WCHAR wVersionFormat
[] = { '%','d','.','%','d','.','%','d','.','%','d',0 };
449 static const WCHAR wFileDescriptionFormat
[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
450 '\\','%','0','4','x','%','0','4','x','\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0 };
451 static const WCHAR wLegalCopyrightFormat
[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
452 '\\','%','0','4','x','%','0','4','x','\\','L','e','g','a','l','C','o','p','y','r','i','g','h','t',0 };
453 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 };
454 static const WCHAR wCompanyName
[] = { 'C','o','m','p','a','n','y','N','a','m','e',0 };
455 static const WCHAR wFileVersion
[] = { 'F','i','l','e','V','e','r','s','i','o','n',0 };
456 static const WCHAR wInternalName
[] = { 'I','n','t','e','r','n','a','l','N','a','m','e',0 };
457 static const WCHAR wOriginalFilename
[] = { 'O','r','i','g','i','n','a','l','F','i','l','e','n','a','m','e',0 };
458 static const WCHAR wProductName
[] = { 'P','r','o','d','u','c','t','N','a','m','e',0 };
459 static const WCHAR wProductVersion
[] = { 'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0 };
460 static const WCHAR wSlash
[] = { '\\',0 };
466 if(!(versize
= GetFileVersionInfoSizeW(lpfilename
, &handle
)))
468 WARN("GetFileVersionInfoSize failed\n");
472 if(!(pBuf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, versize
)))
474 WARN("HeapAlloc failed bytes %x\n",versize
);
478 if(!GetFileVersionInfoW(lpfilename
, handle
, versize
, pBuf
))
480 HeapFree(GetProcessHeap(), 0, pBuf
);
483 if(VerQueryValueW(pBuf
, wSlash
, &info
, &infolen
))
485 VS_FIXEDFILEINFO
* inf
= (VS_FIXEDFILEINFO
*)info
;
486 sprintfW(buff
, wVersionFormat
, HIWORD(inf
->dwFileVersionMS
),
487 LOWORD(inf
->dwFileVersionMS
),
488 HIWORD(inf
->dwFileVersionLS
),
489 LOWORD(inf
->dwFileVersionLS
));
491 hDlgCtrl
= GetDlgItem(hwndDlg
, 14001);
492 TRACE("MS %x LS %x res %s \n",inf
->dwFileVersionMS
, inf
->dwFileVersionLS
, debugstr_w(buff
));
493 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)buff
);
495 if(VerQueryValueW(pBuf
, wTranslation
, (LPVOID
*)&lplangcode
, &infolen
))
497 /* FIXME find language from current locale / if not available,
499 * for now default to first available language
501 lang
= lplangcode
->lang
;
502 code
= lplangcode
->code
;
505 sprintfW(buff
, wFileDescriptionFormat
, lang
, code
);
506 SH_FileVersionQuerySetText(hwndDlg
, 14003, pBuf
, buff
, &str
);
508 sprintfW(buff
, wLegalCopyrightFormat
, lang
, code
);
509 SH_FileVersionQuerySetText(hwndDlg
, 14005, pBuf
, buff
, &str
);
511 /* listbox properties */
512 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wCompanyName
, &str
, lang
, code
);
513 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wFileVersion
, &str
, lang
, code
);
514 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wInternalName
, &str
, lang
, code
);
516 /* FIXME insert language identifier */
518 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wOriginalFilename
, &str
, lang
, code
);
519 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wProductName
, &str
, lang
, code
);
520 SH_FileVersionQuerySetListText(hwndDlg
, pBuf
, wProductVersion
, &str
, lang
, code
);
521 SetWindowLong(hwndDlg
, DWL_USER
, (LONG
)pBuf
);
523 /* select first item */
524 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
525 SendMessageW(hDlgCtrl
, LB_SETCURSEL
, 0, 0);
526 str
= (WCHAR
*)SendMessageW(hDlgCtrl
, LB_GETITEMDATA
, (WPARAM
)0, (LPARAM
)NULL
);
527 hDlgCtrl
= GetDlgItem(hwndDlg
, 14010);
528 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)str
);
532 /*************************************************************************
534 * SH_FileVersionDlgProc
536 * wnd proc of 'Version' property sheet page
540 SH_FileVersionDlgProc(
547 LPPROPSHEETPAGE ppsp
;
553 ppsp
= (LPPROPSHEETPAGE
)lParam
;
557 TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n",hwndDlg
, lParam
, ppsp
->lParam
);
559 lpstr
= (WCHAR
*)ppsp
->lParam
;
564 return SH_FileVersionInitialize(hwndDlg
, lpstr
);
568 if(LOWORD(wParam
) == 14009 && HIWORD(wParam
) == LBN_DBLCLK
)
574 hDlgCtrl
= GetDlgItem(hwndDlg
, 14009);
575 lresult
= SendMessageW(hDlgCtrl
, LB_GETCURSEL
, (WPARAM
)NULL
, (LPARAM
)NULL
);
576 if(lresult
== LB_ERR
)
580 str
= (WCHAR
*)SendMessageW(hDlgCtrl
, LB_GETITEMDATA
, (WPARAM
)lresult
, (LPARAM
)NULL
);
586 hDlgCtrl
= GetDlgItem(hwndDlg
, 14010);
587 TRACE("hDlgCtrl %x string %s \n",hDlgCtrl
, debugstr_w(str
));
588 SendMessageW(hDlgCtrl
, WM_SETTEXT
, (WPARAM
)NULL
, (LPARAM
)str
);
594 buf
= (LPVOID
)GetWindowLong(hwndDlg
, DWL_USER
);
595 HeapFree(GetProcessHeap(), 0, buf
);
604 /*************************************************************************
606 * SH_FileGeneralDlgProc
608 * wnd proc of 'General' property sheet page
614 SH_FileGeneralDlgProc(
621 LPPROPSHEETPAGEW ppsp
;
626 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
629 TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n",hwndDlg
, lParam
, ppsp
->lParam
);
631 lpstr
= (WCHAR
*)ppsp
->lParam
;
635 ERR("no filename\n");
638 /* set general text properties filename filelocation and icon */
639 SH_FileGeneralSetText(hwndDlg
, lpstr
);
640 /* enumerate file extension from registry and application which opens it*/
641 SH_FileGeneralSetFileType(hwndDlg
, strrchrW(lpstr
, '.'));
642 /* set file time create/modfied/accessed */
643 SH_FileGeneralSetFileSizeTime(hwndDlg
, lpstr
, NULL
);
651 BOOL CALLBACK
AddShellPropSheetExCallback(HPROPSHEETPAGE hPage
, LPARAM lParam
)
654 HPROPSHEETPAGE
* hppages
= (HPROPSHEETPAGE
*)lParam
;
656 TRACE("AddShellPropSheetExCallback called\n");
657 for(iIndex
= 0; iIndex
< MAX_PROPERTY_SHEET_PAGE
; iIndex
++)
659 if (hppages
[iIndex
] == NULL
)
661 hppages
[iIndex
] = hPage
;
670 EnumPropSheetExt(LPWSTR wFileName
, HPROPSHEETPAGE
* hppages
, int NumPages
, HPSXA
* hpsxa
, IDataObject
*pDataObj
)
679 pOffset
= wcsrchr(wFileName
, L
'.');
682 Length
= wcslen(szName
);
686 if (CLSIDFromString(wFileName
, &clsid
) == NOERROR
)
688 wcscpy(szName
, L
"CLSID\\");
689 wcscpy(&szName
[6], wFileName
);
693 wcscpy(szName
, wFileName
);
698 Length
= wcslen(pOffset
);
701 wcscpy(szName
, pOffset
);
703 TRACE("EnumPropSheetExt szName %s\n", debugstr_w(szName
));
704 hpsxa
[0] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, szName
, NumPages
, pDataObj
);
705 Pages
= SHAddFromPropSheetExtArray(hpsxa
[0], AddShellPropSheetExCallback
, (LPARAM
)hppages
);
710 /* try to load property sheet handlers from prog id key */
711 dwName
= sizeof(szName
);
712 if (RegGetValueW(HKEY_CLASSES_ROOT
, pOffset
, NULL
, RRF_RT_REG_SZ
, NULL
, szName
, &dwName
) == ERROR_SUCCESS
)
714 TRACE("EnumPropSheetExt szName %s, pOffset %s\n", debugstr_w(szName
), debugstr_w(pOffset
));
715 szName
[(sizeof(szName
)/sizeof(WCHAR
))-1] = L
'\0';
716 hpsxa
[1] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, szName
, NumPages
- Pages
, pDataObj
);
717 Pages
+=SHAddFromPropSheetExtArray(hpsxa
[1], AddShellPropSheetExCallback
, (LPARAM
)hppages
);
725 /*************************************************************************
727 * SH_ShowPropertiesDialog
729 * called from ShellExecuteExW32
731 * lpf contains (quoted) path of folder/file
733 * TODO: provide button change application type if file has registered type
734 * make filename field editable and apply changes to filename on close
738 SH_ShowPropertiesDialog(PCWSTR lpf
)
740 PROPSHEETHEADERW pinfo
;
741 HPROPSHEETPAGE hppages
[MAX_PROPERTY_SHEET_PAGE
];
742 HPROPSHEETPAGE hpage
;
743 WCHAR wFileName
[MAX_PATH
];
749 LPITEMIDLIST pidlChild
, pidlFolder
;
750 WCHAR szTemp
[MAX_PATH
];
751 IDataObject
* pDataObj
= NULL
;
754 TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(lpf
));
762 memset(hppages
, 0x0, sizeof(HPROPSHEETPAGE
) * MAX_PROPERTY_SHEET_PAGE
);
765 /* remove quotes from lpf */
766 LPCWSTR src
= lpf
+ 1;
767 LPWSTR dst
= wFileName
;
769 while(*src
&& *src
!='"')
776 strcpyW(wFileName
, lpf
);
779 if (PathIsDirectoryW(wFileName
))
781 return SH_ShowFolderProperties(wFileName
);
784 if (wcslen(wFileName
) == 3)
786 return SH_ShowDriveProperties(wFileName
);
789 wcscpy(szTemp
, wFileName
);
790 pFileName
= wcsrchr(szTemp
, '\\');
793 pFileName
[0] = L
'\0';
795 pidlChild
= ILCreateFromPathW(pFileName
);
796 pidlFolder
= ILCreateFromPathW(szTemp
);
797 if (pidlChild
&& pidlFolder
)
799 hResult
= SHCreateDataObject(pidlFolder
, 1, (LPCITEMIDLIST
*)&pidlChild
, NULL
, &IID_IDataObject
, (LPVOID
*)&pDataObj
);
808 hpage
= SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG", SH_FileGeneralDlgProc
, (LPARAM
)wFileName
, NULL
);
813 hppages
[num_pages
] = hpage
;
815 num_pages
+= EnumPropSheetExt(wFileName
, hppages
, MAX_PROPERTY_SHEET_PAGE
-1, hpsxa
, pDataObj
);
817 if ( GetFileVersionInfoSizeW(lpf
, &dwHandle
) && num_pages
)
819 if ( (hpage
= SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",SH_FileVersionDlgProc
, (LPARAM
)wFileName
, NULL
))!= NULL
)
821 hppages
[num_pages
] = hpage
;
826 pFileName
= wcsrchr(wFileName
, '\\');
828 pFileName
= wFileName
;
833 memset(&pinfo
, 0x0, sizeof(PROPSHEETHEADERW
));
834 pinfo
.dwSize
= sizeof(PROPSHEETHEADERW
);
835 pinfo
.dwFlags
= PSH_NOCONTEXTHELP
| PSH_PROPTITLE
;
836 pinfo
.nPages
= num_pages
;
837 pinfo
.u3
.phpage
= hppages
;
838 pinfo
.pszCaption
= pFileName
;
840 TRACE("SH_ShowPropertiesDialog pages %u\n", num_pages
);
841 res
= PropertySheetW(&pinfo
);
843 SHDestroyPropSheetExtArray(hpsxa
[0]);
844 SHDestroyPropSheetExtArray(hpsxa
[1]);
846 IDataObject_Release(pDataObj
);