STDMETHODIMP CHashCheck::QueryContextMenu( HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags ) { if (uFlags & (CMF_DEFAULTONLY | CMF_NOVERBS)) return(MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0)); // Ugly hack: work around a bug in Windows 5.x that causes a spurious // separator to be added when invoking the context menu from the Start Menu if (g_uWinVer < 0x0600 && !(uFlags & (0x20000 | CMF_EXPLORE)) && GetModuleHandleA("explorer.exe")) return(MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0)); // Load the menu display settings HASHCHECKOPTIONS opt; opt.dwFlags = HCOF_MENUDISPLAY; OptionsLoad(&opt); // Do not show if the settings prohibit it if (opt.dwMenuDisplay == 2 || (opt.dwMenuDisplay == 1 && !(uFlags & CMF_EXTENDEDVERBS))) return(MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0)); // Load the localized menu text TCHAR szMenuText[MAX_STRINGMSG]; LoadString(g_hModThisDll, IDS_HS_MENUTEXT, szMenuText, countof(szMenuText)); if (InsertMenu(hmenu, indexMenu, MF_STRING | MF_BYPOSITION, idCmdFirst, szMenuText)) return(MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 1)); return(MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0)); }
VOID WINAPI HashCalcInitSave( PHASHCALCCONTEXT phcctx ) { HWND hWnd = phcctx->hWnd; // We can use the extended portion of the scratch buffer for the file name PTSTR pszFile = (PTSTR)phcctx->scratch.ext; // Default result value phcctx->hFileOut = INVALID_HANDLE_VALUE; // Load settings phcctx->opt.dwFlags = HCOF_FILTERINDEX | HCOF_SAVEENCODING; OptionsLoad(&phcctx->opt); // Initialize the struct for the first time, if needed if (phcctx->ofn.lStructSize == 0) { phcctx->ofn.lStructSize = sizeof(phcctx->ofn); phcctx->ofn.hwndOwner = hWnd; phcctx->ofn.lpstrFilter = SAVE_FILTERS; phcctx->ofn.nFilterIndex = phcctx->opt.dwFilterIndex; phcctx->ofn.lpstrFile = pszFile; phcctx->ofn.nMaxFile = MAX_PATH_BUFFER + 10; phcctx->ofn.Flags = OFN_DONTADDTORECENT | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; phcctx->ofn.lpstrDefExt = TEXT(""); // Set the initial file name { PTSTR pszOrigPath; SLReset(phcctx->hListRaw); pszOrigPath = SLGetDataAndStep(phcctx->hListRaw); if (SLCheck(phcctx->hListRaw)) { // Multiple items were selected in Explorer SSChainNCpy2( pszFile, pszOrigPath, phcctx->cchPrefix, SAVE_DEFAULT_NAME, countof(SAVE_DEFAULT_NAME) ); } else { // Only one item was selected in Explorer (may be a single // file or a directory containing multiple files) SSChainCpyCat(pszFile, pszOrigPath, SAVE_EXTS[phcctx->ofn.nFilterIndex]); } } } // We should also do a sanity check to make sure that the filter index // is set to a valid value since we depend on that to determine the format if ( GetSaveFileName(&phcctx->ofn) && phcctx->ofn.nFilterIndex && phcctx->ofn.nFilterIndex <= 4 ) { BOOL bSuccess = FALSE; // Save the filter in the user's preferences if (phcctx->opt.dwFilterIndex != phcctx->ofn.nFilterIndex) { phcctx->opt.dwFilterIndex = phcctx->ofn.nFilterIndex; phcctx->opt.dwFlags = HCOF_FILTERINDEX; OptionsSave(&phcctx->opt); } // Extension fixup: Correct the extension to match the selected // type, but only if the extension was one of the 4 in the list if (phcctx->ofn.nFileExtension) { PTSTR pszExt = pszFile + phcctx->ofn.nFileExtension - 1; if ( StrCmpI(pszExt, TEXT(".sfv")) == 0 || StrCmpI(pszExt, TEXT(".md4")) == 0 || StrCmpI(pszExt, TEXT(".md5")) == 0 || StrCmpI(pszExt, TEXT(".sha1")) == 0 ) { if (StrCmpI(pszExt, SAVE_EXTS[phcctx->ofn.nFilterIndex])) SSCpy(pszExt, SAVE_EXTS[phcctx->ofn.nFilterIndex]); } } // Adjust the file paths for the output path, if necessary HashCalcSetSavePrefix(phcctx, pszFile); // Open the file for output phcctx->hFileOut = CreateFile( pszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); if (phcctx->hFileOut != INVALID_HANDLE_VALUE) { // The actual format will be set when HashCalcWriteResult is called phcctx->szFormat[0] = 0; if (phcctx->opt.dwSaveEncoding == 1) { // Write the BOM for UTF-16LE WCHAR BOM = 0xFEFF; DWORD cbWritten; WriteFile(phcctx->hFileOut, &BOM, sizeof(WCHAR), &cbWritten, NULL); } } else { TCHAR szMessage[MAX_STRINGMSG]; LoadString(g_hModThisDll, IDS_HC_SAVE_ERROR, szMessage, countof(szMessage)); MessageBox(hWnd, szMessage, NULL, MB_OK | MB_ICONERROR); } } }