Guest User

Untitled

a guest
Feb 18th, 2018
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.18 KB | None | 0 0
  1. /*
  2. * Shell Library Functions
  3. *
  4. * Copyright 2005 Johannes Anderwald
  5. *
  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.
  10. *
  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.
  15. *
  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20.  
  21. #include <precomp.h>
  22.  
  23. WINE_DEFAULT_DEBUG_CHANNEL(shell);
  24.  
  25. #define MAX_PROPERTY_SHEET_PAGE 32
  26. #define MAX_NUMSTR_LENGTH 64
  27.  
  28. typedef struct _LANGANDCODEPAGE_
  29. {
  30. WORD lang;
  31. WORD code;
  32. } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
  33.  
  34. EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
  35.  
  36. static LONG SH_GetAssociatedApplication(WCHAR *fileext, WCHAR *wAssocApp)
  37. {
  38. WCHAR wDataType[MAX_PATH] = {0};
  39. HKEY hkey;
  40. LONG result;
  41. DWORD dwLen = MAX_PATH * sizeof(WCHAR);
  42.  
  43. wAssocApp[0] = '\0';
  44. RegCreateKeyExW(HKEY_CLASSES_ROOT, fileext, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL);
  45. result = RegQueryValueExW(hkey, L"", NULL, NULL, (LPBYTE)wDataType, &dwLen);
  46. RegCloseKey(hkey);
  47.  
  48. if (result == ERROR_SUCCESS)
  49. {
  50. wcscat(wDataType, L"\\shell\\open\\command");
  51. dwLen = MAX_PATH * sizeof(WCHAR);
  52. RegCreateKeyExW(HKEY_CLASSES_ROOT, wDataType, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL);
  53. result = (RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)wAssocApp, &dwLen));
  54. RegCloseKey(hkey);
  55.  
  56. if (result != ERROR_SUCCESS)
  57. {
  58. /* FIXME: Make it return full path instead of
  59. notepad.exe "%1"
  60. %systemroot%\notepad.exe "%1"
  61. etc
  62. Maybe there is code to do that somewhere?
  63. dll\win32\shell32\shlexec.c for example?
  64. */
  65. wAssocApp[0] = '\0';
  66. }
  67. }
  68.  
  69. return result;
  70. }
  71.  
  72. void FormatBytes(PLARGE_INTEGER numBytes, wchar_t *wstr)
  73. {
  74. wchar_t strfrmt[MAX_NUMSTR_LENGTH] = {L'\0'};
  75. wchar_t strfrmt2[MAX_NUMSTR_LENGTH] = {L'\0'};
  76. WCHAR FormatBuffer[MAX_NUMSTR_LENGTH];
  77.  
  78. NUMBERFMT numFormat = {0, 0, 3, L'', L",", 0};
  79.  
  80. swprintf(strfrmt, MAX_NUMSTR_LENGTH, L"%I64u", numBytes); //%I64u
  81. if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, strfrmt, &numFormat, strfrmt2, MAX_NUMSTR_LENGTH))
  82. {
  83. if (!LoadStringW(shell32_hInstance, IDS_PROP_BYTES, FormatBuffer, sizeof(FormatBuffer) / sizeof(WCHAR)))
  84. {
  85. /* use default english format string */
  86. wcscpy(FormatBuffer, L"bytes");
  87. }
  88. swprintf(strfrmt, L" (%s %s)", strfrmt2, FormatBuffer);
  89. wcscat(wstr, strfrmt);
  90. }
  91. }
  92.  
  93. static LONG SH_FileGeneralOpensWith(HWND hwndDlg, WCHAR *fileext)
  94. {
  95. HWND hDlgCtrl;
  96. LONG result;
  97. WCHAR wAppName[MAX_PATH] = {0};
  98. WCHAR wAssocApp[MAX_PATH] = {0};
  99.  
  100. hDlgCtrl = GetDlgItem(hwndDlg, 14007);
  101. result = SH_GetAssociatedApplication(fileext, wAssocApp);
  102.  
  103. if (result == ERROR_SUCCESS)
  104. {
  105. _wsplitpath(wAssocApp, NULL, NULL, wAppName, NULL);
  106.  
  107. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)wAppName);
  108. }
  109.  
  110. return result;
  111. }
  112.  
  113. /*************************************************************************
  114. *
  115. * SH_CreatePropertySheetPage [Internal]
  116. *
  117. * creates a property sheet page from an resource name
  118. *
  119. */
  120.  
  121. HPROPSHEETPAGE
  122. SH_CreatePropertySheetPage(LPCSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle)
  123. {
  124. HRSRC hRes;
  125. LPVOID lpsztemplate;
  126. PROPSHEETPAGEW ppage;
  127.  
  128. if (resname == NULL)
  129. return (HPROPSHEETPAGE)0;
  130.  
  131. hRes = FindResourceA(shell32_hInstance, resname, (LPSTR)RT_DIALOG);
  132.  
  133. if (hRes == NULL)
  134. {
  135. ERR("failed to find resource name\n");
  136. return (HPROPSHEETPAGE)0;
  137. }
  138.  
  139. lpsztemplate = LoadResource(shell32_hInstance, hRes);
  140.  
  141. if (lpsztemplate == NULL)
  142. return (HPROPSHEETPAGE)0;
  143.  
  144. memset(&ppage, 0x0, sizeof(PROPSHEETPAGEW));
  145. ppage.dwSize = sizeof(PROPSHEETPAGEW);
  146. ppage.dwFlags = PSP_DLGINDIRECT;
  147. ppage.pResource = (DLGTEMPLATE *)lpsztemplate;
  148. ppage.pfnDlgProc = dlgproc;
  149. ppage.lParam = lParam;
  150. ppage.pszTitle = szTitle;
  151.  
  152. if (szTitle)
  153. {
  154. ppage.dwFlags |= PSP_USETITLE;
  155. }
  156.  
  157. return CreatePropertySheetPageW(&ppage);
  158. }
  159.  
  160. /*************************************************************************
  161. *
  162. * SH_FileGeneralFileType [Internal]
  163. *
  164. * retrieves file extension description from registry and sets it in dialog
  165. *
  166. * TODO: retrieve file extension default icon and load it
  167. * find executable name from registry, retrieve description from executable
  168. */
  169.  
  170. BOOL
  171. SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR *filext)
  172. {
  173. WCHAR name[MAX_PATH];
  174. WCHAR value[MAX_PATH];
  175. DWORD lname = MAX_PATH;
  176. DWORD lvalue = MAX_PATH;
  177. HKEY hKey;
  178. LONG result;
  179. HWND hDlgCtrl;
  180.  
  181. TRACE("fileext %s\n", debugstr_w(filext));
  182.  
  183. if (filext == NULL)
  184. return FALSE;
  185.  
  186. hDlgCtrl = GetDlgItem(hwndDlg, 14005);
  187.  
  188. if (hDlgCtrl == NULL)
  189. return FALSE;
  190.  
  191. if (RegOpenKeyW(HKEY_CLASSES_ROOT, filext, &hKey) != ERROR_SUCCESS)
  192. {
  193. /* the file extension is unknown, so default to string "FileExtension File" */
  194. SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)value);
  195. swprintf(name, L"%s %s", &filext[1], value);
  196. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)name);
  197. return TRUE;
  198. }
  199.  
  200. result = RegEnumValueW(hKey, 0, name, &lname, NULL, NULL, (LPBYTE)value, &lvalue);
  201. RegCloseKey(hKey);
  202.  
  203. if (result != ERROR_SUCCESS)
  204. return FALSE;
  205.  
  206. if (RegOpenKeyW(HKEY_CLASSES_ROOT, value, &hKey) == ERROR_SUCCESS)
  207. {
  208. if (RegLoadMUIStringW(hKey, L"FriendlyTypeName", value, MAX_PATH, NULL, 0, NULL) != ERROR_SUCCESS)
  209. {
  210. lvalue = lname = MAX_PATH;
  211. result = RegEnumValueW(hKey, 0, name, &lname, NULL, NULL, (LPBYTE)value, &lvalue);
  212. }
  213.  
  214. lname = MAX_PATH;
  215.  
  216. if (RegGetValueW(hKey, L"DefaultIcon", NULL, RRF_RT_REG_SZ, NULL, name, &lname) == ERROR_SUCCESS)
  217. {
  218. UINT IconIndex;
  219. WCHAR szBuffer[MAX_PATH];
  220. WCHAR *Offset;
  221. HICON hIcon = 0;
  222. HRSRC hResource;
  223. LPVOID pResource = NULL;
  224. HGLOBAL hGlobal;
  225. HINSTANCE hLibrary;
  226. Offset = wcsrchr(name, L',');
  227.  
  228. if (Offset)
  229. {
  230. IconIndex = _wtoi(Offset + 2);
  231. *Offset = L'\0';
  232. name[MAX_PATH - 1] = L'\0';
  233.  
  234. if (ExpandEnvironmentStringsW(name, szBuffer, MAX_PATH))
  235. {
  236. szBuffer[MAX_PATH - 1] = L'\0';
  237. hLibrary = LoadLibraryExW(szBuffer, NULL, LOAD_LIBRARY_AS_DATAFILE);
  238. if (hLibrary)
  239. {
  240. hResource = FindResourceW(hLibrary, MAKEINTRESOURCEW(IconIndex), (LPCWSTR)RT_ICON);
  241. if (hResource)
  242. {
  243. hGlobal = LoadResource(shell32_hInstance, hResource);
  244. if (hGlobal)
  245. {
  246. pResource = LockResource(hGlobal);
  247. if (pResource != NULL)
  248. {
  249. hIcon = CreateIconFromResource((LPBYTE)pResource, SizeofResource(shell32_hInstance, hResource), TRUE, 0x00030000);
  250. TRACE("hIcon %p,- szBuffer %s IconIndex %u error %u icon %p hResource %p pResource %p\n",
  251. hIcon,
  252. debugstr_w(szBuffer),
  253. IconIndex,
  254. MAKEINTRESOURCEW(IconIndex),
  255. hResource,
  256. pResource);
  257. SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)hIcon, 0);
  258. }
  259. }
  260. }
  261. FreeLibrary(hLibrary);
  262. }
  263. }
  264. }
  265. }
  266. RegCloseKey(hKey);
  267. }
  268.  
  269. /* file extension type */
  270. value[MAX_PATH - 1] = L'\0';
  271. lvalue = wcslen(value);
  272. lname = wcslen(filext);
  273. if (MAX_PATH - lvalue - lname - 3 > 0)
  274. {
  275. wcscat(value, L" (");
  276. wcscat(value, filext);
  277. wcscat(value, L")");
  278. }
  279.  
  280. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)value);
  281.  
  282. return TRUE;
  283. }
  284.  
  285. /*************************************************************************
  286. *
  287. * SHFileGeneralGetFileTimeString [Internal]
  288. *
  289. * formats a given LPFILETIME struct into readable user format
  290. */
  291.  
  292. BOOL
  293. SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime, WCHAR *lpResult)
  294. {
  295. FILETIME ft;
  296. SYSTEMTIME dt;
  297. WORD wYear;
  298. static const WCHAR wFormat[] = {
  299. '%', '0', '2', 'd', '/', '%', '0', '2', 'd', '/', '%', '0', '4', 'd',
  300. ' ', ' ', '%', '0', '2', 'd', ':', '%', '0', '2', 'u', 0 };
  301.  
  302. if (lpFileTime == NULL || lpResult == NULL)
  303. return FALSE;
  304.  
  305. if (!FileTimeToLocalFileTime(lpFileTime, &ft))
  306. return FALSE;
  307.  
  308. FileTimeToSystemTime(&ft, &dt);
  309.  
  310. wYear = dt.wYear;
  311.  
  312. /* ddmmyy */
  313. swprintf(lpResult, wFormat, dt.wDay, dt.wMonth, wYear, dt.wHour, dt.wMinute);
  314.  
  315. TRACE("result %s\n", debugstr_w(lpResult));
  316. return TRUE;
  317. }
  318.  
  319. /*************************************************************************
  320. *
  321. * SH_FileGeneralSetText [Internal]
  322. *
  323. * sets file path string and filename string
  324. *
  325. */
  326.  
  327. BOOL
  328. SH_FileGeneralSetText(HWND hwndDlg, WCHAR *lpstr)
  329. {
  330. int flength;
  331. int plength;
  332. WCHAR *lpdir;
  333. WCHAR buff[MAX_PATH];
  334. HWND hDlgCtrl;
  335.  
  336. if (lpstr == NULL)
  337. return FALSE;
  338.  
  339. lpdir = wcsrchr(lpstr, '\\'); /* find the last occurence of '\\' */
  340.  
  341. plength = wcslen(lpstr);
  342. flength = wcslen(lpdir);
  343.  
  344. if (lpdir)
  345. {
  346. /* location text field */
  347. wcsncpy(buff, lpstr, plength - flength);
  348. buff[plength - flength] = UNICODE_NULL;
  349.  
  350. if (wcslen(buff) == 2)
  351. {
  352. wcscat(buff, L"\\");
  353. }
  354.  
  355. hDlgCtrl = GetDlgItem(hwndDlg, 14009);
  356. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
  357. }
  358.  
  359. if (flength > 1)
  360. {
  361. /* text filename field */
  362. wcsncpy(buff, &lpdir[1], flength);
  363. hDlgCtrl = GetDlgItem(hwndDlg, 14001);
  364. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
  365. }
  366.  
  367. return TRUE;
  368. }
  369.  
  370. /*************************************************************************
  371. *
  372. * SH_FileGeneralSetFileSizeTime [Internal]
  373. *
  374. * retrieves file information from file and sets in dialog
  375. *
  376. */
  377.  
  378. BOOL
  379. SH_FileGeneralSetFileSizeTime(HWND hwndDlg, WCHAR *lpfilename, PULARGE_INTEGER lpfilesize)
  380. {
  381. BOOL result;
  382. HANDLE hFile;
  383. FILETIME create_time;
  384. FILETIME accessed_time;
  385. FILETIME write_time;
  386. WCHAR resultstr[MAX_PATH];
  387. HWND hDlgCtrl;
  388. LARGE_INTEGER file_size;
  389.  
  390. if (lpfilename == NULL)
  391. return FALSE;
  392.  
  393. hFile = CreateFileW(lpfilename,
  394. GENERIC_READ,
  395. FILE_SHARE_READ,
  396. NULL,
  397. OPEN_EXISTING,
  398. FILE_ATTRIBUTE_NORMAL,
  399. NULL);
  400.  
  401. if (hFile == INVALID_HANDLE_VALUE)
  402. {
  403. WARN("failed to open file %s\n", debugstr_w(lpfilename));
  404. return FALSE;
  405. }
  406.  
  407. result = GetFileTime(hFile, &create_time, &accessed_time, &write_time);
  408.  
  409. if (!result)
  410. {
  411. WARN("GetFileTime failed\n");
  412. return FALSE;
  413. }
  414.  
  415. if (SHFileGeneralGetFileTimeString(&create_time, resultstr))
  416. {
  417. hDlgCtrl = GetDlgItem(hwndDlg, 14015);
  418. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
  419. }
  420.  
  421. if (SHFileGeneralGetFileTimeString(&accessed_time, resultstr))
  422. {
  423. hDlgCtrl = GetDlgItem(hwndDlg, 14019);
  424. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
  425. }
  426.  
  427. if (SHFileGeneralGetFileTimeString(&write_time, resultstr))
  428. {
  429. hDlgCtrl = GetDlgItem(hwndDlg, 14017);
  430. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
  431. }
  432.  
  433. if (!GetFileSizeEx(hFile, &file_size))
  434. {
  435. WARN("GetFileSize failed\n");
  436. CloseHandle(hFile);
  437. return FALSE;
  438. }
  439.  
  440. CloseHandle(hFile);
  441.  
  442. if (!StrFormatByteSizeW(file_size.QuadPart,
  443. resultstr,
  444. sizeof(resultstr) / sizeof(WCHAR)))
  445. return FALSE;
  446.  
  447. hDlgCtrl = GetDlgItem(hwndDlg, 14011);
  448. FormatBytes(file_size.QuadPart, resultstr);
  449.  
  450. TRACE("result size %u resultstr %s\n", file_size.QuadPart, debugstr_w(resultstr));
  451. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
  452.  
  453. if (lpfilesize)
  454. lpfilesize->QuadPart = (ULONGLONG)file_size.QuadPart;
  455.  
  456. return TRUE;
  457. }
  458.  
  459. /*************************************************************************
  460. *
  461. * SH_SetFileVersionText [Internal]
  462. *
  463. *
  464. */
  465.  
  466. BOOL
  467. SH_FileVersionQuerySetText(HWND hwndDlg, DWORD dlgId, LPVOID pInfo, WCHAR *text, WCHAR **resptr)
  468. {
  469. UINT reslen;
  470. HWND hDlgCtrl;
  471.  
  472. if (hwndDlg == NULL || resptr == NULL || text == NULL)
  473. return FALSE;
  474.  
  475. if (VerQueryValueW(pInfo, text, (LPVOID *)resptr, &reslen))
  476. {
  477. /* file description property */
  478. hDlgCtrl = GetDlgItem(hwndDlg, dlgId);
  479. TRACE("%s :: %s\n", debugstr_w(text), debugstr_w(*resptr));
  480. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)0, (LPARAM)*resptr);
  481. return TRUE;
  482. }
  483.  
  484. return FALSE;
  485. }
  486.  
  487. /*************************************************************************
  488. *
  489. * SH_FileVersionQuerySetListText [Internal]
  490. *
  491. * retrieves a version string and adds it to listbox
  492. *
  493. */
  494.  
  495. BOOL
  496. SH_FileVersionQuerySetListText(HWND hwndDlg, LPVOID pInfo, const WCHAR *text, WCHAR **resptr, WORD lang, WORD code)
  497. {
  498. UINT reslen;
  499. HWND hDlgCtrl;
  500. UINT index;
  501. static const WCHAR wFormat[] = {
  502. '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
  503. '\\', '%', '0', '4', 'x', '%', '0', '4', 'x', '\\', '%', 's', 0 };
  504. WCHAR buff[256];
  505.  
  506. TRACE("text %s, resptr %p hwndDlg %p\n", debugstr_w(text), resptr, hwndDlg);
  507.  
  508. if (hwndDlg == NULL || resptr == NULL || text == NULL)
  509. return FALSE;
  510.  
  511. swprintf(buff, wFormat, lang, code, text);
  512.  
  513. if (VerQueryValueW(pInfo, buff, (LPVOID *)resptr, &reslen))
  514. {
  515. /* listbox name property */
  516. hDlgCtrl = GetDlgItem(hwndDlg, 14009);
  517. TRACE("%s :: %s\n", debugstr_w(text), debugstr_w(*resptr));
  518. index = SendMessageW(hDlgCtrl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)text);
  519. SendMessageW(hDlgCtrl, LB_SETITEMDATA, (WPARAM)index, (LPARAM)(WCHAR *)*resptr);
  520. return TRUE;
  521. }
  522.  
  523. return FALSE;
  524. }
  525.  
  526. /*************************************************************************
  527. *
  528. * SH_FileVersionInitialize [Internal]
  529. *
  530. * sets all file version properties in dialog
  531. */
  532.  
  533. BOOL
  534. SH_FileVersionInitialize(HWND hwndDlg, WCHAR *lpfilename)
  535. {
  536. LPVOID pBuf;
  537. DWORD versize;
  538. DWORD handle;
  539. LPVOID info = NULL;
  540. UINT infolen;
  541. WCHAR buff[256];
  542. HWND hDlgCtrl;
  543. WORD lang = 0;
  544. WORD code = 0;
  545. LPLANGANDCODEPAGE lplangcode;
  546. WCHAR *str;
  547. static const WCHAR wVersionFormat[] = {
  548. '%', 'd', '.', '%', 'd', '.', '%', 'd', '.', '%', 'd', 0 };
  549. static const WCHAR wFileDescriptionFormat[] = {
  550. '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
  551. '\\', '%', '0', '4', 'x', '%', '0', '4', 'x',
  552. '\\', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 0 };
  553. static const WCHAR wLegalCopyrightFormat[] = {
  554. '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
  555. '\\', '%', '0', '4', 'x', '%', '0', '4', 'x',
  556. '\\', 'L', 'e', 'g', 'a', 'l', 'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', 0 };
  557. static const WCHAR wTranslation[] = {
  558. 'V', 'a', 'r', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
  559. '\\', 'T', 'r', 'a', 'n', 's', 'l', 'a', 't', 'i', 'o', 'n', 0 };
  560. static const WCHAR wCompanyName[] = {
  561. 'C', 'o', 'm', 'p', 'a', 'n', 'y', 'N', 'a', 'm', 'e', 0 };
  562. static const WCHAR wFileVersion[] = {
  563. 'F', 'i', 'l', 'e', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
  564. static const WCHAR wInternalName[] = {
  565. 'I', 'n', 't', 'e', 'r', 'n', 'a', 'l', 'N', 'a', 'm', 'e', 0 };
  566. static const WCHAR wOriginalFilename[] = {
  567. 'O', 'r', 'i', 'g', 'i', 'n', 'a', 'l', 'F', 'i', 'l', 'e', 'n', 'a', 'm', 'e', 0 };
  568. static const WCHAR wProductName[] = {
  569. 'P', 'r', 'o', 'd', 'u', 'c', 't', 'N', 'a', 'm', 'e', 0 };
  570. static const WCHAR wProductVersion[] = {
  571. 'P', 'r', 'o', 'd', 'u', 'c', 't', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
  572. static const WCHAR wSlash[] = { '\\', 0 };
  573.  
  574. if (lpfilename == 0)
  575. return FALSE;
  576.  
  577. if (!(versize = GetFileVersionInfoSizeW(lpfilename, &handle)))
  578. {
  579. WARN("GetFileVersionInfoSize failed\n");
  580. return FALSE;
  581. }
  582.  
  583. if (!(pBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, versize)))
  584. {
  585. WARN("HeapAlloc failed bytes %x\n", versize);
  586. return FALSE;
  587. }
  588.  
  589. if (!GetFileVersionInfoW(lpfilename, handle, versize, pBuf))
  590. {
  591. HeapFree(GetProcessHeap(), 0, pBuf);
  592. return FALSE;
  593. }
  594.  
  595. if (VerQueryValueW(pBuf, const_cast<LPWSTR>(wSlash), &info, &infolen))
  596. {
  597. VS_FIXEDFILEINFO *inf = (VS_FIXEDFILEINFO *)info;
  598. swprintf(buff, wVersionFormat, HIWORD(inf->dwFileVersionMS),
  599. LOWORD(inf->dwFileVersionMS),
  600. HIWORD(inf->dwFileVersionLS),
  601. LOWORD(inf->dwFileVersionLS));
  602. hDlgCtrl = GetDlgItem(hwndDlg, 14001);
  603. TRACE("MS %x LS %x res %s \n", inf->dwFileVersionMS, inf->dwFileVersionLS, debugstr_w(buff));
  604. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
  605. }
  606.  
  607. if (VerQueryValueW(pBuf, const_cast<LPWSTR>(wTranslation), (LPVOID *)&lplangcode, &infolen))
  608. {
  609. /* FIXME find language from current locale / if not available,
  610. * default to english
  611. * for now default to first available language
  612. */
  613. lang = lplangcode->lang;
  614. code = lplangcode->code;
  615. }
  616.  
  617. swprintf(buff, wFileDescriptionFormat, lang, code);
  618. SH_FileVersionQuerySetText(hwndDlg, 14003, pBuf, buff, &str);
  619.  
  620. swprintf(buff, wLegalCopyrightFormat, lang, code);
  621. SH_FileVersionQuerySetText(hwndDlg, 14005, pBuf, buff, &str);
  622.  
  623. /* listbox properties */
  624. SH_FileVersionQuerySetListText(hwndDlg, pBuf, wCompanyName, &str, lang, code);
  625. SH_FileVersionQuerySetListText(hwndDlg, pBuf, wFileVersion, &str, lang, code);
  626. SH_FileVersionQuerySetListText(hwndDlg, pBuf, wInternalName, &str, lang, code);
  627.  
  628. /* FIXME insert language identifier */
  629.  
  630. SH_FileVersionQuerySetListText(hwndDlg, pBuf, wOriginalFilename, &str, lang, code);
  631. SH_FileVersionQuerySetListText(hwndDlg, pBuf, wProductName, &str, lang, code);
  632. SH_FileVersionQuerySetListText(hwndDlg, pBuf, wProductVersion, &str, lang, code);
  633. SetWindowLongPtr(hwndDlg, DWL_USER, (LONG_PTR)pBuf);
  634.  
  635. /* select first item */
  636. hDlgCtrl = GetDlgItem(hwndDlg, 14009);
  637. SendMessageW(hDlgCtrl, LB_SETCURSEL, 0, 0);
  638. str = (WCHAR *) SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)0, (LPARAM)NULL);
  639. hDlgCtrl = GetDlgItem(hwndDlg, 14010);
  640. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)str);
  641.  
  642. return TRUE;
  643. }
  644.  
  645. /*************************************************************************
  646. *
  647. * SH_FileVersionDlgProc
  648. *
  649. * wnd proc of 'Version' property sheet page
  650. */
  651.  
  652. INT_PTR
  653. CALLBACK
  654. SH_FileVersionDlgProc(HWND hwndDlg,
  655. UINT uMsg,
  656. WPARAM wParam,
  657. LPARAM lParam)
  658. {
  659. LPPROPSHEETPAGE ppsp;
  660. WCHAR *lpstr;
  661. LPVOID buf;
  662.  
  663. switch (uMsg)
  664. {
  665. case WM_INITDIALOG:
  666. ppsp = (LPPROPSHEETPAGE)lParam;
  667.  
  668. if (ppsp == NULL)
  669. break;
  670.  
  671. TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n", hwndDlg, lParam, ppsp->lParam);
  672.  
  673. lpstr = (WCHAR *)ppsp->lParam;
  674.  
  675. if (lpstr == NULL)
  676. break;
  677.  
  678. return SH_FileVersionInitialize(hwndDlg, lpstr);
  679.  
  680. case WM_COMMAND:
  681. if (LOWORD(wParam) == 14009 && HIWORD(wParam) == LBN_DBLCLK)
  682. {
  683. HWND hDlgCtrl;
  684. LRESULT lresult;
  685. WCHAR *str;
  686.  
  687. hDlgCtrl = GetDlgItem(hwndDlg, 14009);
  688. lresult = SendMessageW(hDlgCtrl, LB_GETCURSEL, (WPARAM)NULL, (LPARAM)NULL);
  689.  
  690. if (lresult == LB_ERR)
  691. break;
  692.  
  693. str = (WCHAR *) SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)lresult, (LPARAM)NULL);
  694.  
  695. if (str == NULL)
  696. break;
  697.  
  698. hDlgCtrl = GetDlgItem(hwndDlg, 14010);
  699. TRACE("hDlgCtrl %x string %s \n", hDlgCtrl, debugstr_w(str));
  700. SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)str);
  701.  
  702. return TRUE;
  703. }
  704. break;
  705.  
  706. case WM_DESTROY:
  707. buf = (LPVOID) GetWindowLongPtr(hwndDlg, DWL_USER);
  708. HeapFree(GetProcessHeap(), 0, buf);
  709. break;
  710.  
  711. default:
  712. break;
  713. }
  714.  
  715. return FALSE;
  716. }
  717.  
  718. /*************************************************************************
  719. *
  720. * SH_FileGeneralDlgProc
  721. *
  722. * wnd proc of 'General' property sheet page
  723. *
  724. */
  725.  
  726. INT_PTR
  727. CALLBACK
  728. SH_FileGeneralDlgProc(HWND hwndDlg,
  729. UINT uMsg,
  730. WPARAM wParam,
  731. LPARAM lParam)
  732. {
  733. LPPROPSHEETPAGEW ppsp;
  734. WCHAR *lpstr;
  735.  
  736. switch (uMsg)
  737. {
  738. case WM_INITDIALOG:
  739. ppsp = (LPPROPSHEETPAGEW)lParam;
  740.  
  741. if (ppsp == NULL)
  742. break;
  743.  
  744. TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n", hwndDlg, lParam, ppsp->lParam);
  745.  
  746. lpstr = (WCHAR *)ppsp->lParam;
  747.  
  748. if (lpstr == NULL)
  749. {
  750. ERR("no filename\n");
  751. break;
  752. }
  753.  
  754. /* set general text properties filename filelocation and icon */
  755. SH_FileGeneralSetText(hwndDlg, lpstr);
  756.  
  757. /* enumerate file extension from registry and application which opens it */
  758. SH_FileGeneralSetFileType(hwndDlg, wcsrchr(lpstr, '.'));
  759.  
  760. /* set opens with */
  761. SH_FileGeneralOpensWith(hwndDlg, wcsrchr(lpstr, '.'));
  762.  
  763. /* set file time create/modfied/accessed */
  764. SH_FileGeneralSetFileSizeTime(hwndDlg, lpstr, NULL);
  765.  
  766. return TRUE;
  767.  
  768. default:
  769. break;
  770. }
  771.  
  772. return FALSE;
  773. }
  774.  
  775. BOOL
  776. CALLBACK
  777. AddShellPropSheetExCallback(HPROPSHEETPAGE hPage,
  778. LPARAM lParam)
  779. {
  780. PROPSHEETHEADERW *pinfo = (PROPSHEETHEADERW *)lParam;
  781.  
  782. if (pinfo->nPages < MAX_PROPERTY_SHEET_PAGE)
  783. {
  784. pinfo->phpage[pinfo->nPages++] = hPage;
  785. return TRUE;
  786. }
  787.  
  788. return FALSE;
  789. }
  790.  
  791. int
  792. EnumPropSheetExt(LPWSTR wFileName, PROPSHEETHEADERW *pinfo, int NumPages, HPSXA *hpsxa, IDataObject *pDataObj)
  793. {
  794. WCHAR szName[MAX_PATH] = { 0 };
  795. WCHAR *pOffset;
  796. UINT Length;
  797. DWORD dwName;
  798. int Pages;
  799. CLSID clsid;
  800.  
  801. pOffset = wcsrchr(wFileName, L'.');
  802.  
  803. if (!pOffset)
  804. {
  805. Length = wcslen(szName);
  806.  
  807. if (Length + 6 > sizeof(szName) / sizeof(szName[0]))
  808. return 0;
  809.  
  810. if (CLSIDFromString(wFileName, &clsid) == NOERROR)
  811. {
  812. wcscpy(szName, L"CLSID\\");
  813. wcscpy(&szName[6], wFileName);
  814. }
  815. else
  816. {
  817. wcscpy(szName, wFileName);
  818. }
  819. }
  820. else
  821. {
  822. Length = wcslen(pOffset);
  823.  
  824. if (Length >= sizeof(szName) / sizeof(szName[0]))
  825. return 0;
  826.  
  827. wcscpy(szName, pOffset);
  828. }
  829.  
  830. TRACE("EnumPropSheetExt szName %s\n", debugstr_w(szName));
  831.  
  832. hpsxa[0] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, szName, NumPages, pDataObj);
  833. Pages = SHAddFromPropSheetExtArray(hpsxa[0], AddShellPropSheetExCallback, (LPARAM)pinfo);
  834.  
  835. hpsxa[1] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"*", NumPages-Pages, pDataObj);
  836. Pages += SHAddFromPropSheetExtArray(hpsxa[1], AddShellPropSheetExCallback, (LPARAM)pinfo);
  837.  
  838. hpsxa[2] = NULL;
  839.  
  840. if (pOffset)
  841. {
  842. /* try to load property sheet handlers from prog id key */
  843. dwName = sizeof(szName);
  844.  
  845. if (RegGetValueW(HKEY_CLASSES_ROOT, pOffset, NULL, RRF_RT_REG_SZ, NULL, szName, &dwName) == ERROR_SUCCESS)
  846. {
  847. TRACE("EnumPropSheetExt szName %s, pOffset %s\n", debugstr_w(szName), debugstr_w(pOffset));
  848. szName[(sizeof(szName) / sizeof(WCHAR)) - 1] = L'\0';
  849. hpsxa[2] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, szName, NumPages - Pages, pDataObj);
  850. Pages += SHAddFromPropSheetExtArray(hpsxa[2], AddShellPropSheetExCallback, (LPARAM)pinfo);
  851. }
  852. }
  853.  
  854. return Pages;
  855. }
  856.  
  857. /*************************************************************************
  858. *
  859. * SH_ShowPropertiesDialog
  860. *
  861. * called from ShellExecuteExW32
  862. *
  863. * lpf contains (quoted) path of folder/file
  864. *
  865. * TODO: provide button change application type if file has registered type
  866. * make filename field editable and apply changes to filename on close
  867. */
  868.  
  869. BOOL
  870. SH_ShowPropertiesDialog(WCHAR *lpf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl)
  871. {
  872. PROPSHEETHEADERW pinfo;
  873. HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
  874. WCHAR wFileName[MAX_PATH];
  875. DWORD dwHandle = 0;
  876. WCHAR *pFileName;
  877. HPSXA hpsxa[3];
  878. INT_PTR res;
  879. CComPtr<IDataObject> pDataObj;
  880. HRESULT hResult;
  881. DWORD wLength;
  882.  
  883. TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(lpf));
  884.  
  885. if (lpf == NULL)
  886. return FALSE;
  887.  
  888. if (!wcslen(lpf))
  889. return FALSE;
  890.  
  891. memset(hppages, 0x0, sizeof(HPROPSHEETPAGE) * MAX_PROPERTY_SHEET_PAGE);
  892.  
  893. if (lpf[0] == '"')
  894. {
  895. /* remove quotes from lpf */
  896. LPCWSTR src = lpf + 1;
  897. LPWSTR dst = wFileName;
  898.  
  899. while (*src && *src != '"')
  900. *dst++ = *src++;
  901.  
  902. *dst = '\0';
  903. }
  904. else
  905. {
  906. wcscpy(wFileName, lpf);
  907. }
  908.  
  909. //
  910. // get length
  911. //
  912. wLength = wcslen(wFileName);
  913. if (wFileName[wLength-1] == L'\\' && wLength > 3)
  914. {
  915. //
  916. // remove trailing \\ at the end of path
  917. //
  918. wFileName[wLength-1] = L'\0';
  919. }
  920.  
  921. if (PathIsRootW(wFileName))
  922. {
  923. return SH_ShowDriveProperties(wFileName, pidlFolder, apidl);
  924. }
  925.  
  926. if (PathIsDirectoryW(wFileName))
  927. {
  928. return SH_ShowFolderProperties(wFileName, pidlFolder, apidl);
  929. }
  930.  
  931.  
  932. pFileName = wcsrchr(wFileName, '\\');
  933.  
  934. if (!pFileName)
  935. pFileName = wFileName;
  936. else
  937. pFileName++;
  938.  
  939. memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
  940. pinfo.dwSize = sizeof(PROPSHEETHEADERW);
  941. pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE;
  942. pinfo.phpage = hppages;
  943. pinfo.pszCaption = pFileName;
  944.  
  945. hppages[pinfo.nPages] =
  946. SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG",
  947. SH_FileGeneralDlgProc,
  948. (LPARAM)wFileName,
  949. NULL);
  950.  
  951. if (hppages[pinfo.nPages])
  952. pinfo.nPages++;
  953.  
  954. hResult = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (LPVOID *)&pDataObj);
  955.  
  956. if (hResult == S_OK)
  957. {
  958. if (!EnumPropSheetExt(wFileName, &pinfo, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj))
  959. {
  960. hpsxa[0] = NULL;
  961. hpsxa[1] = NULL;
  962. hpsxa[2] = NULL;
  963. }
  964. }
  965.  
  966. if (GetFileVersionInfoSizeW(lpf, &dwHandle))
  967. {
  968. hppages[pinfo.nPages] =
  969. SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",
  970. SH_FileVersionDlgProc,
  971. (LPARAM)wFileName,
  972. NULL);
  973. if (hppages[pinfo.nPages])
  974. pinfo.nPages++;
  975. }
  976.  
  977. res = PropertySheetW(&pinfo);
  978.  
  979. if (hResult == S_OK)
  980. {
  981. SHDestroyPropSheetExtArray(hpsxa[0]);
  982. SHDestroyPropSheetExtArray(hpsxa[1]);
  983. SHDestroyPropSheetExtArray(hpsxa[2]);
  984. }
  985.  
  986. return (res != -1);
  987. }
  988.  
  989. /*EOF */
  990.  
  991. [CC] dll\win32\shell32\fprop.cpp
  992. dll\win32\shell32\fprop.cpp:78:37: error: empty character constant
  993. dll\win32\shell32\fprop.cpp: In function 'void FormatBytes(_LARGE_INTEGER*, wcha
  994. r_t*)':
  995. dll\win32\shell32\fprop.cpp:78: warning: deprecated conversion from string const
  996. ant to 'WCHAR*'
  997. dll\win32\shell32\fprop.cpp:80: error: expected primary-expression before ')' to
  998. ken
  999. dll\win32\shell32\fprop.cpp: In function 'BOOL SH_FileGeneralSetFileSizeTime(HWN
  1000. D__*, WCHAR*, _ULARGE_INTEGER*)':
  1001. dll\win32\shell32\fprop.cpp:448: error: invalid conversion from 'LONGLONG' to '_
  1002. LARGE_INTEGER*'
  1003. dll\win32\shell32\fprop.cpp:448: error: initializing argument 1 of 'void Forma
  1004. tBytes(_LARGE_INTEGER*, wchar_t*)'
  1005. make.exe: *** [obj-i386\dll\win32\shell32\fprop_shell32.o] Error 1
  1006.  
  1007. Total Build Time: 00:00:10
Add Comment
Please, Sign In to add comment