ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

filedefext.cpp
Go to the documentation of this file.
00001 /*
00002  * Provides default file shell extension
00003  *
00004  * Copyright 2005 Johannes Anderwald
00005  * Copyright 2012 Rafal Harabien
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include <precomp.h>
00023 
00024 WINE_DEFAULT_DEBUG_CHANNEL(shell);
00025 
00026 BOOL PathIsExeW(LPCWSTR lpszPath);
00027 
00028 BOOL CFileVersionInfo::Load(LPCWSTR pwszPath)
00029 {
00030     ULONG cbInfo = GetFileVersionInfoSizeW(pwszPath, NULL);
00031     if (!cbInfo)
00032     {
00033         WARN("GetFileVersionInfoSize %ls failed\n", pwszPath);
00034         return FALSE;
00035     }
00036 
00037     m_pInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbInfo);
00038     if (!m_pInfo)
00039     {
00040         ERR("HeapAlloc failed bytes %x\n", cbInfo);
00041         return FALSE;
00042     }
00043 
00044     if (!GetFileVersionInfoW(pwszPath, 0, cbInfo, m_pInfo))
00045     {
00046         ERR("GetFileVersionInfoW failed\n");
00047         return FALSE;
00048     }
00049 
00050     LPLANGANDCODEPAGE lpLangCode;
00051     UINT cBytes;
00052     if (!VerQueryValueW(m_pInfo, L"\\VarFileInfo\\Translation", (LPVOID *)&lpLangCode, &cBytes) || cBytes < sizeof(LANGANDCODEPAGE))
00053     {
00054         ERR("VerQueryValueW failed\n");
00055         return FALSE;
00056     }
00057 
00058     /* FIXME: find language from current locale / if not available,
00059      * default to english
00060      * for now default to first available language
00061      */
00062     m_wLang = lpLangCode->wLang;
00063     m_wCode = lpLangCode->wCode;
00064     TRACE("Lang %hx Code %hu\n", m_wLang, m_wCode);
00065 
00066     return TRUE;
00067 }
00068 
00069 LPCWSTR CFileVersionInfo::GetString(LPCWSTR pwszName)
00070 {
00071     if (!m_pInfo)
00072         return NULL;
00073 
00074     WCHAR wszBuf[256];
00075     swprintf(wszBuf, L"\\StringFileInfo\\%04x%04x\\%s", m_wLang, m_wCode, pwszName);
00076 
00077     /* Query string in version block */
00078     LPCWSTR pwszResult = NULL;
00079     UINT cBytes = 0;
00080     if (!VerQueryValueW(m_pInfo, wszBuf, (LPVOID *)&pwszResult, &cBytes))
00081         pwszResult = NULL;
00082 
00083     if (!m_wLang && !m_wCode)
00084     {
00085         /* Try US English */
00086         swprintf(wszBuf, L"\\StringFileInfo\\%04x%04x\\%s", MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 1252, pwszName);
00087         if (!VerQueryValueW(m_pInfo, wszBuf, (LPVOID *)&pwszResult, &cBytes))
00088             pwszResult = NULL;
00089     }
00090 
00091     if (!pwszResult)
00092         ERR("VerQueryValueW %ls failed\n", pwszName);
00093     else
00094         TRACE("%ls: %ls\n", pwszName, pwszResult);
00095 
00096     return pwszResult;
00097 }
00098         
00099 VS_FIXEDFILEINFO *CFileVersionInfo::GetFixedInfo()
00100 {
00101     if (!m_pInfo)
00102         return NULL;
00103 
00104     VS_FIXEDFILEINFO *pInfo;
00105     UINT cBytes;
00106     if (!VerQueryValueW(m_pInfo, L"\\", (PVOID*)&pInfo, &cBytes))
00107         return NULL;
00108     return pInfo;
00109 }
00110 
00111 LPCWSTR CFileVersionInfo::GetLangName()
00112 {
00113     if (!m_pInfo)
00114         return NULL;
00115 
00116     if (!m_wszLang[0])
00117     {
00118         if (!VerLanguageNameW(m_wLang, m_wszLang, _countof(m_wszLang)))
00119             ERR("VerLanguageNameW failed\n");
00120     }
00121 
00122     return m_wszLang;
00123 }
00124 
00125 UINT
00126 SH_FormatInteger(LONGLONG Num, LPWSTR pwszResult, UINT cchResultMax)
00127 {
00128     // Print the number in uniform mode
00129     WCHAR wszNumber[24];
00130     swprintf(wszNumber, L"%I64u", Num);
00131 
00132     // Get system strings for decimal and thousand separators.
00133     WCHAR wszDecimalSep[8], wszThousandSep[8];
00134     GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, wszDecimalSep, _countof(wszDecimalSep));
00135     GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, wszThousandSep, _countof(wszThousandSep));
00136 
00137     // Initialize format for printing the number in bytes
00138     NUMBERFMTW nf;
00139     ZeroMemory(&nf, sizeof(nf));
00140     nf.lpDecimalSep = wszDecimalSep;
00141     nf.lpThousandSep = wszThousandSep;
00142 
00143     // Get system string for groups separator
00144     WCHAR wszGrouping[12];
00145     INT cchGrouping = GetLocaleInfoW(LOCALE_USER_DEFAULT,
00146                                      LOCALE_SGROUPING,
00147                                      wszGrouping,
00148                                      _countof(wszGrouping));
00149 
00150     // Convert grouping specs from string to integer
00151     for (INT i = 0; i < cchGrouping; i++)
00152     {
00153         WCHAR wch = wszGrouping[i];
00154 
00155         if (wch >= L'0' && wch <= L'9')
00156             nf.Grouping = nf.Grouping * 10 + (wch - L'0');
00157         else if (wch != L';')
00158             break;
00159     }
00160 
00161     if ((nf.Grouping % 10) == 0)
00162         nf.Grouping /= 10;
00163     else
00164         nf.Grouping *= 10;
00165 
00166     // Format the number
00167     INT cchResult = GetNumberFormatW(LOCALE_USER_DEFAULT,
00168                                     0,
00169                                     wszNumber,
00170                                     &nf,
00171                                     pwszResult,
00172                                     cchResultMax);
00173 
00174     if (!cchResult)
00175         return 0;
00176 
00177     // GetNumberFormatW returns number of characters including UNICODE_NULL
00178     return cchResult - 1;
00179 }
00180 
00181 UINT
00182 SH_FormatByteSize(LONGLONG cbSize, LPWSTR pwszResult, UINT cchResultMax)
00183 {
00184     /* Write formated bytes count */
00185     INT cchWritten = SH_FormatInteger(cbSize, pwszResult, cchResultMax);
00186     if (!cchWritten)
00187         return 0;
00188 
00189     /* Copy " bytes" to buffer */
00190     LPWSTR pwszEnd = pwszResult + cchWritten;
00191     size_t cchRemaining = cchResultMax - cchWritten;
00192     StringCchCopyExW(pwszEnd, cchRemaining, L" ", &pwszEnd, &cchRemaining, NULL);
00193     cchWritten = LoadStringW(shell32_hInstance, IDS_BYTES_FORMAT, pwszEnd, cchRemaining);
00194     cchRemaining -= cchWritten;
00195 
00196     return cchResultMax - cchRemaining;
00197 }
00198 
00199 /*************************************************************************
00200  *
00201  * SH_FormatFileSizeWithBytes
00202  *
00203  * Format a size in bytes to string.
00204  *
00205  * lpQwSize = Pointer to 64bit large integer to format
00206  * pszBuf   = Buffer to fill with output string
00207  * cchBuf   = size of pszBuf in characters
00208  *
00209  */
00210 
00211 LPWSTR
00212 SH_FormatFileSizeWithBytes(const PULARGE_INTEGER lpQwSize, LPWSTR pwszResult, UINT cchResultMax)
00213 {
00214     /* Format bytes in KBs, MBs etc */
00215     if (StrFormatByteSizeW(lpQwSize->QuadPart, pwszResult, cchResultMax) == NULL)
00216         return NULL;
00217 
00218     /* If there is less bytes than 1KB, we have nothing to do */
00219     if (lpQwSize->QuadPart < 1024)
00220         return pwszResult;
00221 
00222     /* Concate " (" */
00223     UINT cchWritten = wcslen(pwszResult);
00224     LPWSTR pwszEnd = pwszResult + cchWritten;
00225     size_t cchRemaining = cchResultMax - cchWritten;
00226     StringCchCopyExW(pwszEnd, cchRemaining, L" (", &pwszEnd, &cchRemaining, 0);
00227 
00228     /* Write formated bytes count */
00229     cchWritten = SH_FormatByteSize(lpQwSize->QuadPart, pwszEnd, cchRemaining);
00230     pwszEnd += cchWritten;
00231     cchRemaining -= cchWritten;
00232 
00233     /* Copy ")" to the buffer */
00234     StringCchCopyW(pwszEnd, cchRemaining, L")");
00235 
00236     return pwszResult;
00237 }
00238 
00239 /*************************************************************************
00240  *
00241  * SH_CreatePropertySheetPage [Internal]
00242  *
00243  * creates a property sheet page from an resource name
00244  *
00245  */
00246 
00247 HPROPSHEETPAGE
00248 SH_CreatePropertySheetPage(WORD wDialogId, DLGPROC pfnDlgProc, LPARAM lParam, LPCWSTR pwszTitle)
00249 {
00250     HRSRC hRes = FindResourceW(shell32_hInstance, MAKEINTRESOURCEW(wDialogId), (LPWSTR)RT_DIALOG);
00251     if (hRes == NULL)
00252     {
00253         ERR("failed to find resource id\n");
00254         return NULL;
00255     }
00256 
00257     LPVOID pTemplate = LoadResource(shell32_hInstance, hRes);
00258     if (pTemplate == NULL)
00259     {
00260         ERR("failed to load resource\n");
00261         return NULL;
00262     }
00263 
00264     PROPSHEETPAGEW Page;
00265     memset(&Page, 0x0, sizeof(PROPSHEETPAGEW));
00266     Page.dwSize = sizeof(PROPSHEETPAGEW);
00267     Page.dwFlags = PSP_DLGINDIRECT;
00268     Page.pResource = (DLGTEMPLATE*)pTemplate;
00269     Page.pfnDlgProc = pfnDlgProc;
00270     Page.lParam = lParam;
00271     Page.pszTitle = pwszTitle;
00272 
00273     if (pwszTitle)
00274         Page.dwFlags |= PSP_USETITLE;
00275 
00276     return CreatePropertySheetPageW(&Page);
00277 }
00278 
00279 VOID
00280 CFileDefExt::InitOpensWithField(HWND hwndDlg)
00281 {
00282     WCHAR wszBuf[MAX_PATH] = L"";
00283     WCHAR wszPath[MAX_PATH] = L"";
00284     DWORD dwSize = sizeof(wszBuf);
00285     BOOL bUnknownApp = TRUE;
00286     LPCWSTR pwszExt = PathFindExtensionW(m_wszPath);
00287 
00288     if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize) == ERROR_SUCCESS)
00289     {
00290         bUnknownApp = FALSE;
00291         StringCbCatW(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
00292         dwSize = sizeof(wszPath);
00293         if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL, wszPath, &dwSize) == ERROR_SUCCESS)
00294         {
00295             /* Get path from command line */
00296             ExpandEnvironmentStringsW(wszPath, wszBuf, _countof(wszBuf));
00297             PathRemoveArgs(wszBuf);
00298             PathUnquoteSpacesW(wszBuf);
00299             PathSearchAndQualify(wszBuf, wszPath, _countof(wszPath));
00300 
00301             HICON hIcon;
00302             if (ExtractIconExW(wszPath, 0, NULL, &hIcon, 1))
00303             {
00304                 HWND hIconCtrl = GetDlgItem(hwndDlg, 14025);
00305                 HWND hDescrCtrl = GetDlgItem(hwndDlg, 14007);
00306                 ShowWindow(hIconCtrl, SW_SHOW);
00307                 RECT rcIcon, rcDescr;
00308                 GetWindowRect(hIconCtrl, &rcIcon);
00309                 if (rcIcon.left == rcIcon.right)
00310                     ERR("Icon control has invalid width: %d-%d\n", rcIcon.left, rcIcon.right);
00311                 MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rcIcon, 2);
00312                 GetWindowRect(hDescrCtrl, &rcDescr);
00313                 MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rcDescr, 2);
00314                 INT cxOffset = rcIcon.right + 2 - rcDescr.left;
00315                 SetWindowPos(hDescrCtrl, NULL,
00316                              rcDescr.left + cxOffset, rcDescr.top,
00317                              rcDescr.right - rcDescr.left - cxOffset, rcDescr.bottom - rcDescr.top,
00318                              SWP_NOZORDER);
00319                 SendMessageW(hIconCtrl, STM_SETICON, (WPARAM)hIcon, 0);
00320             } else
00321                 ERR("Failed to extract icon\n");
00322 
00323             if (PathFileExistsW(wszPath))
00324             {
00325                 /* Get file description */
00326                 CFileVersionInfo VerInfo;
00327                 VerInfo.Load(wszPath);
00328                 LPCWSTR pwszDescr = VerInfo.GetString(L"FileDescription");
00329                 if (pwszDescr)
00330                     SetDlgItemTextW(hwndDlg, 14007, pwszDescr);
00331                 else
00332                 {
00333                     /* File has no description - display filename */
00334                     LPWSTR pwszFilename = PathFindFileNameW(wszPath);
00335                     PathRemoveExtension(pwszFilename);
00336                     pwszFilename[0] = towupper(pwszFilename[0]);
00337                     SetDlgItemTextW(hwndDlg, 14007, pwszFilename);
00338                 }
00339             }
00340             else
00341                 bUnknownApp = TRUE;
00342         } else
00343             WARN("RegGetValueW %ls failed\n", wszBuf);
00344     } else
00345         WARN("RegGetValueW %ls failed\n", pwszExt);
00346 
00347     if (bUnknownApp)
00348     {
00349         /* Unknown application */
00350         LoadStringW(shell32_hInstance, IDS_UNKNOWN_APP, wszBuf, _countof(wszBuf));
00351         SetDlgItemTextW(hwndDlg, 14007, wszBuf);
00352     }
00353 }
00354 
00355 /*************************************************************************
00356  *
00357  * SH_FileGeneralFileType [Internal]
00358  *
00359  * retrieves file extension description from registry and sets it in dialog
00360  *
00361  * TODO: retrieve file extension default icon and load it
00362  *       find executable name from registry, retrieve description from executable
00363  */
00364 
00365 BOOL
00366 CFileDefExt::InitFileType(HWND hwndDlg)
00367 {
00368     TRACE("path %s\n", debugstr_w(m_wszPath));
00369 
00370     HWND hDlgCtrl = GetDlgItem(hwndDlg, 14005);
00371     if (hDlgCtrl == NULL)
00372         return FALSE;
00373 
00374     /* Get file information */
00375     SHFILEINFO fi;
00376     if (!SHGetFileInfoW(m_wszPath, 0, &fi, sizeof(fi), SHGFI_TYPENAME|SHGFI_ICON))
00377     {
00378         ERR("SHGetFileInfoW failed for %ls (%lu)\n", m_wszPath, GetLastError());
00379         fi.szTypeName[0] = L'\0';
00380         fi.hIcon = NULL;
00381     }
00382 
00383     LPCWSTR pwszExt = PathFindExtensionW(m_wszPath);
00384     if (pwszExt[0])
00385     {
00386         WCHAR wszBuf[256];
00387 
00388         if (!fi.szTypeName[0])
00389         {
00390             /* The file type is unknown, so default to string "FileExtension File" */
00391             size_t cchRemaining = 0;
00392             LPWSTR pwszEnd = NULL;
00393 
00394             StringCchPrintfExW(wszBuf, _countof(wszBuf), &pwszEnd, &cchRemaining, 0, L"%s ", pwszExt + 1);
00395             SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)cchRemaining, (LPARAM)pwszEnd);
00396 
00397             SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)wszBuf);
00398         }
00399         else
00400         {
00401             /* Update file type */
00402             StringCbPrintfW(wszBuf, sizeof(wszBuf), L"%s (%s)", fi.szTypeName, pwszExt);
00403             SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)wszBuf);
00404         }
00405     }
00406 
00407     /* Update file icon */
00408     if (fi.hIcon)
00409         SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)fi.hIcon, 0);
00410     else
00411         ERR("No icon %ls\n", m_wszPath);
00412 
00413     return TRUE;
00414 }
00415 
00416 /*************************************************************************
00417  *
00418  * CFileDefExt::InitFilePath [Internal]
00419  *
00420  * sets file path string and filename string
00421  *
00422  */
00423 
00424 BOOL
00425 CFileDefExt::InitFilePath(HWND hwndDlg)
00426 {
00427     /* Find the filename */
00428     WCHAR *pwszFilename = PathFindFileNameW(m_wszPath);
00429 
00430     if (pwszFilename > m_wszPath)
00431     {
00432         /* Location field */
00433         WCHAR wszLocation[MAX_PATH];
00434         StringCchCopyNW(wszLocation, _countof(wszLocation), m_wszPath, pwszFilename - m_wszPath);
00435         PathRemoveBackslashW(wszLocation);
00436 
00437         SetDlgItemTextW(hwndDlg, 14009, wszLocation);
00438     }
00439 
00440     /* Filename field */
00441     SetDlgItemTextW(hwndDlg, 14001, pwszFilename);
00442 
00443     return TRUE;
00444 }
00445 
00446 /*************************************************************************
00447  *
00448  * CFileDefExt::GetFileTimeString [Internal]
00449  *
00450  * formats a given LPFILETIME struct into readable user format
00451  */
00452 
00453 BOOL
00454 CFileDefExt::GetFileTimeString(LPFILETIME lpFileTime, LPWSTR pwszResult, UINT cchResult)
00455 {
00456     FILETIME ft;
00457     SYSTEMTIME st;
00458 
00459     if (!FileTimeToLocalFileTime(lpFileTime, &ft) || !FileTimeToSystemTime(&ft, &st))
00460         return FALSE;
00461 
00462     size_t cchRemaining = cchResult;
00463     LPWSTR pwszEnd = pwszResult;
00464     int cchWritten = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, pwszEnd, cchRemaining);
00465     if (cchWritten)
00466         --cchWritten; // GetDateFormatW returns count with terminating zero
00467     else
00468         ERR("GetDateFormatW failed\n");
00469     cchRemaining -= cchWritten;
00470     pwszEnd += cchWritten;
00471 
00472     StringCchCopyExW(pwszEnd, cchRemaining, L", ", &pwszEnd, &cchRemaining, 0);
00473 
00474     cchWritten = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, pwszEnd, cchRemaining);
00475     if (cchWritten)
00476         --cchWritten; // GetTimeFormatW returns count with terminating zero
00477     else
00478         ERR("GetTimeFormatW failed\n");
00479     TRACE("result %s\n", debugstr_w(pwszResult));
00480     return TRUE;
00481 }
00482 
00483 /*************************************************************************
00484  *
00485  * CFileDefExt::InitFileAttr [Internal]
00486  *
00487  * retrieves file information from file and sets in dialog
00488  *
00489  */
00490 
00491 BOOL
00492 CFileDefExt::InitFileAttr(HWND hwndDlg)
00493 {
00494     WCHAR wszBuf[MAX_PATH];
00495 
00496     TRACE("InitFileAttr %ls\n", m_wszPath);
00497 
00498     WIN32_FILE_ATTRIBUTE_DATA FileInfo;
00499     if (GetFileAttributesExW(m_wszPath, GetFileExInfoStandard, &FileInfo))
00500     {
00501         /* Update attribute checkboxes */
00502         if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
00503             SendDlgItemMessage(hwndDlg, 14021, BM_SETCHECK, BST_CHECKED, 0);
00504         if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
00505             SendDlgItemMessage(hwndDlg, 14022, BM_SETCHECK, BST_CHECKED, 0);
00506         if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
00507             SendDlgItemMessage(hwndDlg, 14023, BM_SETCHECK, BST_CHECKED, 0);
00508 
00509         /* Update creation time */
00510         if (GetFileTimeString(&FileInfo.ftCreationTime, wszBuf, _countof(wszBuf)))
00511             SetDlgItemTextW(hwndDlg, 14015, wszBuf);
00512 
00513         /* For files display last access and last write time */
00514         if (!m_bDir)
00515         {
00516             if (GetFileTimeString(&FileInfo.ftLastAccessTime, wszBuf, _countof(wszBuf)))
00517                 SetDlgItemTextW(hwndDlg, 14019, wszBuf);
00518 
00519             if (GetFileTimeString(&FileInfo.ftLastWriteTime, wszBuf, _countof(wszBuf)))
00520                 SetDlgItemTextW(hwndDlg, 14017, wszBuf);
00521 
00522             /* Update size of file */
00523             ULARGE_INTEGER FileSize;
00524             FileSize.u.LowPart = FileInfo.nFileSizeLow;
00525             FileSize.u.HighPart = FileInfo.nFileSizeHigh;
00526             if (SH_FormatFileSizeWithBytes(&FileSize, wszBuf, _countof(wszBuf)))
00527                 SetDlgItemTextW(hwndDlg, 14011, wszBuf);
00528         }
00529     }
00530 
00531     if (m_bDir)
00532     {
00533         /* For directories files have to be counted */
00534         StringCchCopyW(wszBuf, _countof(wszBuf), m_wszPath);
00535         CountFolderAndFiles(wszBuf, _countof(wszBuf));
00536 
00537         /* Update size filed */
00538         if (SH_FormatFileSizeWithBytes(&m_DirSize, wszBuf, _countof(wszBuf)))
00539             SetDlgItemTextW(hwndDlg, 14011, wszBuf);
00540 
00541         /* Display files and folders count */
00542         WCHAR wszFormat[256];
00543         LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, wszFormat, _countof(wszFormat));
00544         StringCchPrintfW(wszBuf, _countof(wszBuf), wszFormat, m_cFiles, m_cFolders);
00545         SetDlgItemTextW(hwndDlg, 14027, wszBuf);
00546     }
00547 
00548     /* Hide Advanced button. TODO: Implement advanced dialog and enable this button if filesystem supports compression or encryption */
00549     ShowWindow(GetDlgItem(hwndDlg, 14028), SW_HIDE);
00550 
00551     return TRUE;
00552 }
00553 
00554 /*************************************************************************
00555  *
00556  * CFileDefExt::InitGeneralPage [Internal]
00557  *
00558  * sets all file general properties in dialog
00559  */
00560 
00561 BOOL
00562 CFileDefExt::InitGeneralPage(HWND hwndDlg)
00563 {
00564     /* Set general text properties filename filelocation and icon */
00565     InitFilePath(hwndDlg);
00566 
00567     /* Set file type and icon */
00568     InitFileType(hwndDlg);
00569 
00570     /* Set open with application */
00571     if (!m_bDir)
00572     {
00573         if (!PathIsExeW(m_wszPath))
00574             InitOpensWithField(hwndDlg);
00575         else
00576         {
00577             WCHAR wszBuf[MAX_PATH];
00578             LoadStringW(shell32_hInstance, IDS_EXE_DESCRIPTION, wszBuf, _countof(wszBuf));
00579             SetDlgItemTextW(hwndDlg, 14006, wszBuf);
00580             ShowWindow(GetDlgItem(hwndDlg, 14024), SW_HIDE);
00581             LPCWSTR pwszDescr = m_VerInfo.GetString(L"FileDescription");
00582             if (pwszDescr)
00583                 SetDlgItemTextW(hwndDlg, 14007, pwszDescr);
00584             else
00585             {
00586                 StringCbCopyW(wszBuf, sizeof(wszBuf), PathFindFileNameW(m_wszPath));
00587                 PathRemoveExtension(wszBuf);
00588                 SetDlgItemTextW(hwndDlg, 14007, wszBuf);
00589             }
00590         }
00591     }
00592 
00593     /* Set file created/modfied/accessed time, size and attributes */
00594     InitFileAttr(hwndDlg);
00595 
00596     return TRUE;
00597 }
00598 
00599 /*************************************************************************
00600  *
00601  * CFileDefExt::GeneralPageProc
00602  *
00603  * wnd proc of 'General' property sheet page
00604  *
00605  */
00606 
00607 INT_PTR CALLBACK
00608 CFileDefExt::GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
00609 {
00610     switch (uMsg)
00611     {
00612         case WM_INITDIALOG:
00613         {
00614             LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam;
00615 
00616             if (ppsp == NULL || !ppsp->lParam)
00617                 break;
00618 
00619             TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n", hwndDlg, lParam, ppsp->lParam);
00620 
00621             CFileDefExt *pFileDefExt = (CFileDefExt*)ppsp->lParam;
00622             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pFileDefExt);
00623             pFileDefExt->InitGeneralPage(hwndDlg);
00624             break;
00625         }
00626         case WM_COMMAND:
00627             if (LOWORD(wParam) == 14024) /* Opens With - Change */
00628             {
00629                 CFileDefExt *pFileDefExt = (CFileDefExt*)GetWindowLongPtr(hwndDlg, DWLP_USER);
00630                 OPENASINFO oainfo;
00631                 oainfo.pcszFile = pFileDefExt->m_wszPath;
00632                 oainfo.pcszClass = NULL;
00633                 oainfo.oaifInFlags = OAIF_REGISTER_EXT|OAIF_FORCE_REGISTRATION;
00634                 return SUCCEEDED(SHOpenWithDialog(hwndDlg, &oainfo));
00635             }
00636             else if (LOWORD(wParam) == 14021 || LOWORD(wParam) == 14022 || LOWORD(wParam) == 14023) /* checkboxes */
00637                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
00638            else if (LOWORD(wParam) == 14001) /* Name */
00639             {
00640                 if (HIWORD(wParam) == EN_CHANGE)
00641                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
00642             }
00643             break;
00644         case WM_NOTIFY:
00645         {
00646             LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
00647             if (lppsn->hdr.code == PSN_APPLY)
00648             {
00649                 CFileDefExt *pFileDefExt = (CFileDefExt*)GetWindowLongPtr(hwndDlg, DWLP_USER);
00650 
00651                 /* Update attributes first */
00652                 DWORD dwAttr = GetFileAttributesW(pFileDefExt->m_wszPath);
00653                 if (dwAttr)
00654                 {
00655                     dwAttr &= ~(FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_ARCHIVE);
00656 
00657                     if (BST_CHECKED == SendDlgItemMessageW(hwndDlg, 14021, BM_GETCHECK, 0, 0))
00658                         dwAttr |= FILE_ATTRIBUTE_READONLY;
00659                     if (BST_CHECKED == SendDlgItemMessageW(hwndDlg, 14022, BM_GETCHECK, 0, 0))
00660                         dwAttr |= FILE_ATTRIBUTE_HIDDEN;
00661                     if (BST_CHECKED == SendDlgItemMessageW(hwndDlg, 14023, BM_GETCHECK, 0, 0))
00662                         dwAttr |= FILE_ATTRIBUTE_ARCHIVE;
00663 
00664                     if (!SetFileAttributesW(pFileDefExt->m_wszPath, dwAttr))
00665                         ERR("SetFileAttributesW failed\n");
00666                 }
00667 
00668                 /* Update filename now */
00669                 WCHAR wszBuf[MAX_PATH];
00670                 StringCchCopyW(wszBuf, _countof(wszBuf), pFileDefExt->m_wszPath);
00671                 LPWSTR pwszFilename = PathFindFileNameW(wszBuf);
00672                 UINT cchFilenameMax = _countof(wszBuf) - (pwszFilename - wszBuf);
00673                 if (GetDlgItemTextW(hwndDlg, 14001, pwszFilename, cchFilenameMax))
00674                 {
00675                     if (!MoveFileW(pFileDefExt->m_wszPath, wszBuf))
00676                         ERR("MoveFileW failed\n");
00677                 }
00678                     
00679                 SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
00680                 return TRUE;
00681             }
00682             break;
00683         }
00684         default:
00685             break;
00686     }
00687 
00688     return FALSE;
00689 }
00690 
00691 /*************************************************************************
00692  *
00693  * CFileDefExt::InitVersionPage [Internal]
00694  *
00695  * sets all file version properties in dialog
00696  */
00697 
00698 BOOL
00699 CFileDefExt::InitVersionPage(HWND hwndDlg)
00700 {
00701     /* Get fixed info */
00702     VS_FIXEDFILEINFO *pInfo = m_VerInfo.GetFixedInfo();
00703     if (pInfo)
00704     {
00705         WCHAR wszVersion[256];
00706         swprintf(wszVersion, L"%u.%u.%u.%u", HIWORD(pInfo->dwFileVersionMS),
00707                  LOWORD(pInfo->dwFileVersionMS),
00708                  HIWORD(pInfo->dwFileVersionLS),
00709                  LOWORD(pInfo->dwFileVersionLS));
00710         TRACE("MS %x LS %x ver %s \n", pInfo->dwFileVersionMS, pInfo->dwFileVersionLS, debugstr_w(wszVersion));
00711         SetDlgItemTextW(hwndDlg, 14001, wszVersion);
00712     }
00713 
00714     /* Update labels */
00715     SetVersionLabel(hwndDlg, 14003, L"FileDescription");
00716     SetVersionLabel(hwndDlg, 14005, L"LegalCopyright");
00717 
00718     /* Add items to listbox */
00719     AddVersionString(hwndDlg, L"CompanyName");
00720     LPCWSTR pwszLang = m_VerInfo.GetLangName();
00721     if (pwszLang)
00722     {
00723         HWND hDlgCtrl = GetDlgItem(hwndDlg, 14009);
00724         UINT Index = SendMessageW(hDlgCtrl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)L"Language");
00725         SendMessageW(hDlgCtrl, LB_SETITEMDATA, (WPARAM)Index, (LPARAM)(WCHAR *)pwszLang);
00726     }
00727     AddVersionString(hwndDlg, L"ProductName");
00728     AddVersionString(hwndDlg, L"InternalName");
00729     AddVersionString(hwndDlg, L"OriginalFilename");
00730     AddVersionString(hwndDlg, L"FileVersion");
00731     AddVersionString(hwndDlg, L"ProductVersion");
00732 
00733     /* Attach file version to dialog window */
00734     SetWindowLongPtr(hwndDlg, DWL_USER, (LONG_PTR)this);
00735 
00736     /* Select first item */
00737     HWND hDlgCtrl = GetDlgItem(hwndDlg, 14009);
00738     SendMessageW(hDlgCtrl, LB_SETCURSEL, 0, 0);
00739     LPCWSTR pwszText = (LPCWSTR)SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)0, (LPARAM)NULL);
00740     if (pwszText && pwszText != (LPCWSTR)LB_ERR)
00741         SetDlgItemTextW(hwndDlg, 14010, pwszText);
00742 
00743     return TRUE;
00744 }
00745 
00746 /*************************************************************************
00747  *
00748  * CFileDefExt::SetVersionLabel [Internal]
00749  *
00750  * retrieves a version string and uses it to set label text
00751  */
00752 
00753 BOOL
00754 CFileDefExt::SetVersionLabel(HWND hwndDlg, DWORD idCtrl, LPCWSTR pwszName)
00755 {
00756     if (hwndDlg == NULL || pwszName == NULL)
00757         return FALSE;
00758 
00759     LPCWSTR pwszValue = m_VerInfo.GetString(pwszName);
00760     if (pwszValue)
00761     {
00762         /* file description property */
00763         TRACE("%s :: %s\n", debugstr_w(pwszName), debugstr_w(pwszValue));
00764         SetDlgItemTextW(hwndDlg, idCtrl, pwszValue);
00765         return TRUE;
00766     }
00767 
00768     return FALSE;
00769 }
00770 
00771 /*************************************************************************
00772  *
00773  * CFileDefExt::AddVersionString [Internal]
00774  *
00775  * retrieves a version string and adds it to listbox
00776  */
00777 
00778 BOOL
00779 CFileDefExt::AddVersionString(HWND hwndDlg, LPCWSTR pwszName)
00780 {
00781     TRACE("pwszName %s, hwndDlg %p\n", debugstr_w(pwszName), hwndDlg);
00782 
00783     if (hwndDlg == NULL || pwszName == NULL)
00784         return FALSE;
00785 
00786     LPCWSTR pwszValue = m_VerInfo.GetString(pwszName);
00787     if (pwszValue)
00788     {
00789         /* listbox name property */
00790         HWND hDlgCtrl = GetDlgItem(hwndDlg, 14009);
00791         TRACE("%s :: %s\n", debugstr_w(pwszName), debugstr_w(pwszValue));
00792         UINT Index = SendMessageW(hDlgCtrl, LB_ADDSTRING, (WPARAM) -1, (LPARAM)pwszName);
00793         SendMessageW(hDlgCtrl, LB_SETITEMDATA, (WPARAM)Index, (LPARAM)(WCHAR *)pwszValue);
00794         return TRUE;
00795     }
00796 
00797     return FALSE;
00798 }
00799 
00800 /*************************************************************************
00801  *
00802  * CFileDefExt::VersionPageProc
00803  *
00804  * wnd proc of 'Version' property sheet page
00805  */
00806 
00807 INT_PTR CALLBACK
00808 CFileDefExt::VersionPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
00809 {
00810     switch (uMsg)
00811     {
00812         case WM_INITDIALOG:
00813         {
00814             LPPROPSHEETPAGE ppsp = (LPPROPSHEETPAGE)lParam;
00815 
00816             if (ppsp == NULL || !ppsp->lParam)
00817                 break;
00818 
00819             TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n", hwndDlg, lParam, ppsp->lParam);
00820 
00821             CFileDefExt *pFileDefExt = (CFileDefExt*)ppsp->lParam;
00822             return pFileDefExt->InitVersionPage(hwndDlg);
00823         }
00824         case WM_COMMAND:
00825             if (LOWORD(wParam) == 14009 && HIWORD(wParam) == LBN_SELCHANGE)
00826             {
00827                 HWND hDlgCtrl = (HWND)lParam;
00828 
00829                 LRESULT Index = SendMessageW(hDlgCtrl, LB_GETCURSEL, (WPARAM)NULL, (LPARAM)NULL);
00830                 if (Index == LB_ERR)
00831                     break;
00832 
00833                 LPCWSTR pwszData = (LPCWSTR)SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)Index, (LPARAM)NULL);
00834                 if (pwszData == NULL)
00835                     break;
00836 
00837                 TRACE("hDlgCtrl %x string %s\n", hDlgCtrl, debugstr_w(pwszData));
00838                 SetDlgItemTextW(hwndDlg, 14010, pwszData);
00839 
00840                 return TRUE;
00841             }
00842             break;
00843         case WM_DESTROY:
00844             break;
00845         default:
00846             break;
00847     }
00848 
00849     return FALSE;
00850 }
00851 
00852 CFileDefExt::CFileDefExt():
00853     m_bDir(FALSE), m_cFiles(0), m_cFolders(0)
00854 {
00855     m_wszPath[0] = L'\0';
00856     m_DirSize.QuadPart = 0ull;
00857 }
00858 
00859 CFileDefExt::~CFileDefExt()
00860 {
00861     
00862 }
00863 
00864 HRESULT WINAPI
00865 CFileDefExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pDataObj, HKEY hkeyProgID)
00866 {
00867     FORMATETC format;
00868     STGMEDIUM stgm;
00869     HRESULT hr;
00870 
00871     TRACE("%p %p %p %p\n", this, pidlFolder, pDataObj, hkeyProgID);
00872 
00873     if (!pDataObj)
00874         return E_FAIL;
00875 
00876     format.cfFormat = CF_HDROP;
00877     format.ptd = NULL;
00878     format.dwAspect = DVASPECT_CONTENT;
00879     format.lindex = -1;
00880     format.tymed = TYMED_HGLOBAL;
00881 
00882     hr = pDataObj->GetData(&format, &stgm);
00883     if (FAILED(hr))
00884         return hr;
00885 
00886     if (!DragQueryFileW((HDROP)stgm.hGlobal, 0, m_wszPath, _countof(m_wszPath)))
00887     {
00888         ERR("DragQueryFileW failed\n");
00889         ReleaseStgMedium(&stgm);
00890         return E_FAIL;
00891     }
00892 
00893     ReleaseStgMedium(&stgm);
00894 
00895     TRACE("File properties %ls\n", m_wszPath);
00896     m_bDir = PathIsDirectoryW(m_wszPath) ? TRUE : FALSE;
00897     if (!m_bDir)
00898         m_VerInfo.Load(m_wszPath);
00899 
00900     return S_OK;
00901 }
00902 
00903 HRESULT WINAPI
00904 CFileDefExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
00905 {
00906     UNIMPLEMENTED;
00907     return E_NOTIMPL;
00908 }
00909 
00910 HRESULT WINAPI
00911 CFileDefExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
00912 {
00913     UNIMPLEMENTED;
00914     return E_NOTIMPL;
00915 }
00916 
00917 HRESULT WINAPI
00918 CFileDefExt::GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax)
00919 {
00920     UNIMPLEMENTED;
00921     return E_NOTIMPL;
00922 }
00923 
00924 HRESULT WINAPI
00925 CFileDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam)
00926 {
00927     HPROPSHEETPAGE hPage;
00928     WORD wResId = m_bDir ? IDD_FOLDER_PROPERTIES : IDD_FILE_PROPERTIES;
00929 
00930     hPage = SH_CreatePropertySheetPage(wResId,
00931                                        GeneralPageProc,
00932                                        (LPARAM)this,
00933                                        NULL);
00934     if (hPage)
00935         pfnAddPage(hPage, lParam);
00936 
00937     if (!m_bDir && GetFileVersionInfoSizeW(m_wszPath, NULL))
00938     {
00939         hPage = SH_CreatePropertySheetPage(IDD_FILE_VERSION,
00940                                             VersionPageProc,
00941                                             (LPARAM)this,
00942                                             NULL);
00943         if (hPage)
00944             pfnAddPage(hPage, lParam);
00945     }
00946 
00947     return S_OK;
00948 }
00949 
00950 HRESULT WINAPI
00951 CFileDefExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam)
00952 {
00953     UNIMPLEMENTED;
00954     return E_NOTIMPL;
00955 }
00956 
00957 HRESULT WINAPI
00958 CFileDefExt::SetSite(IUnknown *punk)
00959 {
00960     UNIMPLEMENTED;
00961     return E_NOTIMPL;
00962 }
00963 
00964 HRESULT WINAPI
00965 CFileDefExt::GetSite(REFIID iid, void **ppvSite)
00966 {
00967     UNIMPLEMENTED;
00968     return E_NOTIMPL;
00969 }
00970 
00971 BOOL
00972 CFileDefExt::CountFolderAndFiles(LPWSTR pwszBuf, UINT cchBufMax)
00973 {
00974     /* Find filename position */
00975     UINT cchBuf = wcslen(pwszBuf);
00976     WCHAR *pwszFilename = pwszBuf + cchBuf;
00977     size_t cchFilenameMax = cchBufMax - cchBuf;
00978     if (!cchFilenameMax)
00979         return FALSE;
00980     *(pwszFilename++) = '\\';
00981     --cchFilenameMax;
00982 
00983     /* Find all files, FIXME: shouldn't be "*"? */
00984     StringCchCopyW(pwszFilename, cchFilenameMax, L"*");
00985 
00986     WIN32_FIND_DATAW wfd;
00987     HANDLE hFind = FindFirstFileW(pwszBuf, &wfd);
00988     if (hFind == INVALID_HANDLE_VALUE)
00989     {
00990         ERR("FindFirstFileW %ls failed\n", pwszBuf);
00991         return FALSE;
00992     }
00993 
00994     do
00995     {
00996         if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00997         {
00998             /* Don't process "." and ".." items */
00999             if (!wcscmp(wfd.cFileName, L".") || !wcscmp(wfd.cFileName, L".."))
01000                 continue;
01001 
01002             ++m_cFolders;
01003 
01004             StringCchCopyW(pwszFilename, cchFilenameMax, wfd.cFileName);
01005             CountFolderAndFiles(pwszBuf, cchBufMax);
01006         }
01007         else
01008         {
01009             m_cFiles++;
01010 
01011             ULARGE_INTEGER FileSize;
01012             FileSize.u.LowPart  = wfd.nFileSizeLow;
01013             FileSize.u.HighPart = wfd.nFileSizeHigh;
01014             m_DirSize.QuadPart += FileSize.QuadPart;
01015         }
01016     } while(FindNextFileW(hFind, &wfd));
01017 
01018     FindClose(hFind);
01019     return TRUE;
01020 }

Generated on Sun May 27 2012 04:26:20 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.