int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, #ifdef UNDER_CE LPWSTR #else LPSTR #endif /* lpCmdLine */,int /* nCmdShow */) { g_hInstance = (HINSTANCE)hInstance; NT_CHECK #ifdef _WIN32 LoadSecurityDlls(); #endif // InitCommonControls(); UString archiveName, switches; #ifdef _SHELL_EXECUTE UString executeFile, executeParameters; #endif NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches); FString fullPath; NDLL::MyGetModuleFileName(fullPath); switches.Trim(); bool assumeYes = false; if (switches.IsPrefixedBy_Ascii_NoCase("-y")) { assumeYes = true; switches = switches.Ptr(2); switches.Trim(); } AString config; if (!ReadDataString(fullPath, kStartID, kEndID, config)) { if (!assumeYes) ShowErrorMessage(L"Can't load config info"); return 1; } UString dirPrefix = L"." WSTRING_PATH_SEPARATOR; UString appLaunched; bool showProgress = true; if (!config.IsEmpty()) { CObjectVector<CTextConfigPair> pairs; if (!GetTextConfig(config, pairs)) { if (!assumeYes) ShowErrorMessage(L"Config failed"); return 1; } UString friendlyName = GetTextConfigValue(pairs, L"Title"); UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt"); UString progress = GetTextConfigValue(pairs, L"Progress"); if (progress.IsEqualTo_Ascii_NoCase("no")) showProgress = false; int index = FindTextConfigItem(pairs, L"Directory"); if (index >= 0) dirPrefix = pairs[index].String; if (!installPrompt.IsEmpty() && !assumeYes) { if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO | MB_ICONQUESTION) != IDYES) return 0; } appLaunched = GetTextConfigValue(pairs, L"RunProgram"); #ifdef _SHELL_EXECUTE executeFile = GetTextConfigValue(pairs, L"ExecuteFile"); executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters"); #endif } CTempDir tempDir; if (!tempDir.Create(kTempDirPrefix)) { if (!assumeYes) ShowErrorMessage(L"Can not create temp folder archive"); return 1; } CCodecs *codecs = new CCodecs; CMyComPtr<IUnknown> compressCodecsInfo = codecs; { HRESULT result = codecs->Load(); if (result != S_OK) { ShowErrorMessage(L"Can not load codecs"); return 1; } } const FString tempDirPath = tempDir.GetPath(); // tempDirPath = L"M:\\1\\"; // to test low disk space { bool isCorrupt = false; UString errorMessage; HRESULT result = ExtractArchive(codecs, fullPath, tempDirPath, showProgress, isCorrupt, errorMessage); if (result != S_OK) { if (!assumeYes) { if (result == S_FALSE || isCorrupt) { NWindows::MyLoadString(IDS_EXTRACTION_ERROR_MESSAGE, errorMessage); result = E_FAIL; } if (result != E_ABORT) { if (errorMessage.IsEmpty()) errorMessage = NError::MyFormatMessage(result); ::MessageBoxW(0, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); } } return 1; } } #ifndef UNDER_CE CCurrentDirRestorer currentDirRestorer; if (!SetCurrentDir(tempDirPath)) return 1; #endif HANDLE hProcess = 0; #ifdef _SHELL_EXECUTE if (!executeFile.IsEmpty()) { CSysString filePath = GetSystemString(executeFile); SHELLEXECUTEINFO execInfo; execInfo.cbSize = sizeof(execInfo); execInfo.fMask = SEE_MASK_NOCLOSEPROCESS #ifndef UNDER_CE | SEE_MASK_FLAG_DDEWAIT #endif ; execInfo.hwnd = NULL; execInfo.lpVerb = NULL; execInfo.lpFile = filePath; if (!switches.IsEmpty()) { executeParameters.Add_Space_if_NotEmpty(); executeParameters += switches; } CSysString parametersSys = GetSystemString(executeParameters); if (parametersSys.IsEmpty()) execInfo.lpParameters = NULL; else execInfo.lpParameters = parametersSys; execInfo.lpDirectory = NULL; execInfo.nShow = SW_SHOWNORMAL; execInfo.hProcess = 0; /* BOOL success = */ ::ShellExecuteEx(&execInfo); UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp; if (result <= 32) { if (!assumeYes) ShowErrorMessage(L"Can not open file"); return 1; } hProcess = execInfo.hProcess; } else #endif { if (appLaunched.IsEmpty()) { appLaunched = L"setup.exe"; if (!NFind::DoesFileExist(us2fs(appLaunched))) { if (!assumeYes) ShowErrorMessage(L"Can not find setup.exe"); return 1; } } { FString s2 = tempDirPath; NName::NormalizeDirPathPrefix(s2); appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, fs2us(s2)); } UString appNameForError = appLaunched; // actually we need to rtemove parameters also appLaunched.Replace(L"%%T", fs2us(tempDirPath)); if (!switches.IsEmpty()) { appLaunched.Add_Space(); appLaunched += switches; } STARTUPINFO startupInfo; startupInfo.cb = sizeof(startupInfo); startupInfo.lpReserved = 0; startupInfo.lpDesktop = 0; startupInfo.lpTitle = 0; startupInfo.dwFlags = 0; startupInfo.cbReserved2 = 0; startupInfo.lpReserved2 = 0; PROCESS_INFORMATION processInformation; CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched); BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys, NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, &startupInfo, &processInformation); if (createResult == 0) { if (!assumeYes) { // we print name of exe file, if error message is // ERROR_BAD_EXE_FORMAT: "%1 is not a valid Win32 application". ShowErrorMessageSpec(appNameForError); } return 1; } ::CloseHandle(processInformation.hThread); hProcess = processInformation.hProcess; } if (hProcess != 0) { WaitForSingleObject(hProcess, INFINITE); ::CloseHandle(hProcess); } return 0; }
void CContentsView::OnCopy(bool move, bool copyToSame) { CContentsView &srcPanel = *this; CContentsView &destPanel = *this; CDisableTimerProcessing disableTimerProcessing1(destPanel); CDisableTimerProcessing disableTimerProcessing2(srcPanel); if (move) { if (!srcPanel.CheckBeforeUpdate(IDS_MOVE)) return; } else if (!srcPanel.DoesItSupportOperations()) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } CRecordVector<UInt32> indices; UString destPath; bool useDestPanel = false; { if (copyToSame) { int focusedItem = srcPanel.GetFocusedItem(); if (focusedItem < 0) return; int realIndex = srcPanel.GetRealItemIndex(focusedItem); if (realIndex == kParentIndex) return; indices.Add(realIndex); destPath = srcPanel.GetItemName(realIndex); } else { srcPanel.GetOperatedIndicesSmart(indices); if (indices.Size() == 0) return; destPath = destPanel.GetFsPath(); ReducePathToRealFileSystemPath(destPath); } } UStringVector copyFolders; // ReadCopyHistory(copyFolders); { CCopyDialog copyDialog; copyDialog.Strings = copyFolders; copyDialog.Value = destPath; LangString(move ? IDS_MOVE : IDS_COPY, copyDialog.Title); LangString(move ? IDS_MOVE_TO : IDS_COPY_TO, copyDialog.Static); copyDialog.Info = srcPanel.GetItemsInfoString(indices); if (copyDialog.DoModal() != IDOK) return; destPath = copyDialog.Value; } { if (destPath.IsEmpty()) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } UString correctName; if (!srcPanel.CorrectFsPath(destPath, correctName)) { srcPanel.MessageBoxError(E_INVALIDARG); return; } if (IsAbsolutePath(destPath)) destPath.Empty(); else destPath = srcPanel.GetFsPath(); destPath += correctName; #if defined(_WIN32) && !defined(UNDER_CE) if (destPath.Len() > 0 && destPath[0] == '\\') if (destPath.Len() == 1 || destPath[1] != '\\') { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } #endif if (CompareFileNames(destPath, destPanel.GetFsPath()) == 0) { srcPanel.MessageBoxMyError(L"Can not copy files onto itself"); return; } bool destIsFsPath = false; if (IsAltPathPrefix(us2fs(destPath))) { // we allow alt streams dest only to alt stream folder in second panel srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; /* FString basePath = us2fs(destPath); basePath.DeleteBack(); if (!DoesFileOrDirExist(basePath)) { srcPanel.MessageBoxError2Lines(basePath, ERROR_FILE_NOT_FOUND); // GetLastError() return; } destIsFsPath = true; */ } else { if (indices.Size() == 1 && !destPath.IsEmpty() && destPath.Back() != WCHAR_PATH_SEPARATOR) { int pos = destPath.ReverseFind_PathSepar(); if (pos < 0) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } { /* #ifdef _WIN32 UString name = destPath.Ptr(pos + 1); if (name.Find(L':') >= 0) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } #endif */ UString prefix = destPath.Left(pos + 1); if (!CreateComplexDir(us2fs(prefix))) { srcPanel.MessageBoxError2Lines(prefix, GetLastError()); return; } } // bool isFolder = srcPanael.IsItem_Folder(indices[0]); } else { NName::NormalizeDirPathPrefix(destPath); if (!CreateComplexDir(us2fs(destPath))) { srcPanel.MessageBoxError2Lines(destPath, GetLastError()); return; } } destIsFsPath = true; } if (!destIsFsPath) useDestPanel = true; // AddUniqueStringToHeadOfList(copyFolders, destPath); while (copyFolders.Size() > 20) copyFolders.DeleteBack(); // SaveCopyHistory(copyFolders); } bool useSrcPanel = !useDestPanel || !srcPanel.Is_IO_FS_Folder(); bool useTemp = useSrcPanel && useDestPanel; if (useTemp) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } CTempDir tempDirectory; FString tempDirPrefix; if (useTemp) { tempDirectory.Create(kTempDirPrefix); tempDirPrefix = tempDirectory.GetPath(); NFile::NName::NormalizeDirPathPrefix(tempDirPrefix); } CSelectedState srcSelState; CSelectedState destSelState; srcPanel.SaveSelectedState(srcSelState); destPanel.SaveSelectedState(destSelState); CDisableNotify disableNotify1(destPanel); CDisableNotify disableNotify2(srcPanel); HRESULT result = S_OK; if (useSrcPanel) { CCopyToOptions options; options.folder = useTemp ? fs2us(tempDirPrefix) : destPath; options.moveMode = move; options.includeAltStreams = true; options.replaceAltStreamChars = false; options.showErrorMessages = true; result = srcPanel.CopyTo(options, indices, NULL); } if (result == S_OK && useDestPanel) { UStringVector filePaths; UString folderPrefix; if (useTemp) folderPrefix = fs2us(tempDirPrefix); else folderPrefix = srcPanel.GetFsPath(); filePaths.ClearAndReserve(indices.Size()); FOR_VECTOR(i, indices) filePaths.AddInReserved(srcPanel.GetItemRelPath2(indices[i])); result = destPanel.CopyFrom(move, folderPrefix, filePaths, true, 0); } if (result != S_OK) { // disableNotify1.Restore(); // disableNotify2.Restore(); // For Password: // srcPanel.SetFocusToList(); // srcPanel.InvalidateList(NULL, true); if (result != E_ABORT) srcPanel.MessageBoxError(result, L"Error"); // return; } RefreshTitle(); if (copyToSame || move) { srcPanel.RefreshListCtrl(srcSelState); } if (!copyToSame) { destPanel.RefreshListCtrl(destSelState); srcPanel.KillSelection(); } disableNotify1.Restore(); disableNotify2.Restore(); srcPanel.SetFocus(); }