HRESULT ExtractGUI( CCodecs *codecs, const CObjectVector<COpenType> &formatIndices, const CIntVector &excludedFormatIndices, UStringVector &archivePaths, UStringVector &archivePathsFull, const NWildcard::CCensorNode &wildcardCensor, CExtractOptions &options, #ifndef _SFX CHashBundle *hb, #endif bool showDialog, bool &messageWasDisplayed, CExtractCallbackImp *extractCallback, HWND hwndParent) { messageWasDisplayed = false; CThreadExtracting extracter; extracter.codecs = codecs; extracter.FormatIndices = &formatIndices; extracter.ExcludedFormatIndices = &excludedFormatIndices; if (!options.TestMode) { FString outputDir = options.OutputDir; #ifndef UNDER_CE if (outputDir.IsEmpty()) GetCurrentDir(outputDir); #endif if (showDialog) { CExtractDialog dialog; FString outputDirFull; if (!MyGetFullPathName(outputDir, outputDirFull)) { ShowErrorMessage(kIncorrectOutDir); messageWasDisplayed = true; return E_FAIL; } NName::NormalizeDirPathPrefix(outputDirFull); dialog.DirPath = fs2us(outputDirFull); dialog.OverwriteMode = options.OverwriteMode; dialog.OverwriteMode_Force = options.OverwriteMode_Force; dialog.PathMode = options.PathMode; dialog.PathMode_Force = options.PathMode_Force; dialog.ElimDup = options.ElimDup; if (archivePathsFull.Size() == 1) dialog.ArcPath = archivePathsFull[0]; #ifndef _SFX // dialog.AltStreams = options.NtOptions.AltStreams; dialog.NtSecurity = options.NtOptions.NtSecurity; if (extractCallback->PasswordIsDefined) dialog.Password = extractCallback->Password; #endif if (dialog.Create(hwndParent) != IDOK) return E_ABORT; outputDir = us2fs(dialog.DirPath); options.OverwriteMode = dialog.OverwriteMode; options.PathMode = dialog.PathMode; options.ElimDup = dialog.ElimDup; #ifndef _SFX // options.NtOptions.AltStreams = dialog.AltStreams; options.NtOptions.NtSecurity = dialog.NtSecurity; extractCallback->Password = dialog.Password; extractCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); #endif } if (!MyGetFullPathName(outputDir, options.OutputDir)) { ShowErrorMessage(kIncorrectOutDir); messageWasDisplayed = true; return E_FAIL; } NName::NormalizeDirPathPrefix(options.OutputDir); /* if (!CreateComplexDirectory(options.OutputDir)) { UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, #ifdef LANG 0x02000603, #endif options.OutputDir); s2.Add_LF(); s2 += s; MyMessageBox(s2); return E_FAIL; } */ } UString title = LangString(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING); extracter.Title = title; extracter.ExtractCallbackSpec = extractCallback; extracter.ExtractCallbackSpec->ProgressDialog = &extracter; extracter.ExtractCallback = extractCallback; extracter.ExtractCallbackSpec->Init(); extracter.CompressingMode = false; extracter.ArchivePaths = &archivePaths; extracter.ArchivePathsFull = &archivePathsFull; extracter.WildcardCensor = &wildcardCensor; extracter.Options = &options; #ifndef _SFX extracter.HashBundle = hb; #endif extracter.IconID = IDI_ICON; RINOK(extracter.Create(title, hwndParent)); messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed; return extracter.Result; }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, #ifdef UNDER_CE LPWSTR #else LPSTR #endif /* lpCmdLine */,int /* nCmdShow */) { g_hInstance = (HINSTANCE)hInstance; NT_CHECK // 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.Left(2).IsEqualToNoCase(L"-y")) { assumeYes = true; switches = switches.Mid(2, switches.Len() - 2); switches.Trim(); } AString config; if (!ReadDataString(fullPath, kStartID, kEndID, config)) { if (!assumeYes) ShowErrorMessageRes(IDS_CANT_LOAD_CONFIG_INFO); // 変更 return 1; } UString dirPrefix = L"." WSTRING_PATH_SEPARATOR; UString appLaunched; bool showProgress = true; UString friendlyName; // 追加 UString installPrompt; // 追加 bool isInstaller; // 追加 if (!config.IsEmpty()) { CObjectVector<CTextConfigPair> pairs; if (!GetTextConfig(config, pairs)) { if (!assumeYes) ShowErrorMessageRes(IDS_CONFIG_FAILED); // 変更 return 1; } friendlyName = GetTextConfigValue(pairs, L"Title"); // 変更 installPrompt = GetTextConfigValue(pairs, L"BeginPrompt"); // 変更 isInstaller = GetTextConfigValue(pairs, L"IsInstaller").IsEqualToNoCase(L"yes"); // 追加 if (isInstaller) // 追加 { // 追加 UString progress = GetTextConfigValue(pairs, L"Progress"); if (progress.IsEqualToNoCase(L"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") + switches; #endif } // 追加 } NFile::NDir::CTempDir tempDir; /* 追加 */ UString tempDirPath; if (isInstaller) { if (!tempDir.Create(kTempDirPrefix)) { if (!assumeYes) ShowErrorMessageRes(IDS_CANT_CREATE_TEMP_FOLDER); return 1; } tempDirPath = GetUnicodeString(tempDir.GetPath()); } else { tempDirPath = fullPath.Mid(0, fullPath.ReverseFind('\\') + 1); if (!assumeYes) { if (friendlyName.IsEmpty()) friendlyName = NWindows::MyLoadString(IDS_EXTRACT_FRIENDLY_NAME); if (installPrompt.IsEmpty()) installPrompt = NWindows::MyLoadString(IDS_EXTRACT_INSTALL_PROMPT); CExtractDialog dlg; if (dlg.Create(friendlyName, installPrompt, tempDirPath, 0) != IDOK) return 0; tempDirPath = dlg.GetFolderName(); } } /* 追加ここまで*/ /* 削除 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) { ShowErrorMessageRes(IDS_CANT_LOAD_CODECS); // 変更 return 1; } // FString tempDirPath = tempDir.GetPath(); // 削除 { 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) { errorMessage = NWindows::MyLoadString(IDS_EXTRACTION_ERROR_MESSAGE); result = E_FAIL; } if (result != E_ABORT && !errorMessage.IsEmpty()) ::MessageBoxW(0, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); } return 1; } } if (!isInstaller) // 追加 return 0; // 追加 #ifndef UNDER_CE CCurrentDirRestorer currentDirRestorer; if (!NFile::NDir::SetCurrentDir(tempDir.GetPath())) 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 += 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) ShowErrorMessageRes(IDS_CANT_OPEN_FILE); // 変更 return 1; } hProcess = execInfo.hProcess; } else #endif { if (appLaunched.IsEmpty()) { appLaunched = L"setup.exe"; if (!NFile::NFind::DoesFileExist(us2fs(appLaunched))) { if (!assumeYes) ShowErrorMessageRes(IDS_CANT_FIND_SETUP); // 変更 return 1; } } { FString s2 = tempDirPath; NFile::NName::NormalizeDirPathPrefix(s2); appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, fs2us(s2)); } appLaunched.Replace(L"%%T", fs2us(tempDirPath)); if (!switches.IsEmpty()) { appLaunched += L' '; 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) ShowLastErrorMessage(); return 1; } ::CloseHandle(processInformation.hThread); hProcess = processInformation.hProcess; } if (hProcess != 0) { WaitForSingleObject(hProcess, INFINITE); ::CloseHandle(hProcess); } return 0; }
HRESULT ExtractGUI( CCodecs *codecs, const CIntVector &formatIndices, UStringVector &archivePaths, UStringVector &archivePathsFull, const NWildcard::CCensorNode &wildcardCensor, CExtractOptions &options, bool showDialog, CExtractCallbackImp *extractCallback) { CThreadExtracting extracter; extracter.codecs = codecs; extracter.FormatIndices = formatIndices; if (!options.TestMode) { UString outputDir = options.OutputDir; if (outputDir.IsEmpty()) NFile::NDirectory::MyGetCurrentDirectory(outputDir); if (showDialog) { CExtractDialog dialog; if (!NFile::NDirectory::MyGetFullPathName(outputDir, dialog.DirectoryPath)) { ShowErrorMessage(kIncorrectOutDir); return E_FAIL; } NFile::NName::NormalizeDirPathPrefix(dialog.DirectoryPath); // dialog.OverwriteMode = options.OverwriteMode; // dialog.PathMode = options.PathMode; if(dialog.Create(0) != IDOK) return E_ABORT; outputDir = dialog.DirectoryPath; options.OverwriteMode = dialog.OverwriteMode; options.PathMode = dialog.PathMode; #ifndef _SFX extractCallback->Password = dialog.Password; extractCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); #endif } if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir)) { ShowErrorMessage(kIncorrectOutDir); return E_FAIL; } NFile::NName::NormalizeDirPathPrefix(options.OutputDir); /* if(!NFile::NDirectory::CreateComplexDirectory(options.OutputDir)) { UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, #ifdef LANG 0x02000603, #endif options.OutputDir); MyMessageBox(s2 + UString(L"\n") + s); return E_FAIL; } */ } UString title = LangStringSpec(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING, options.TestMode ? 0x02000F90: 0x02000890); extracter.ExtractCallbackSpec = extractCallback; extracter.ExtractCallback = extractCallback; extracter.ExtractCallbackSpec->Init(); extracter.ArchivePaths = &archivePaths; extracter.ArchivePathsFull = &archivePathsFull; extracter.WildcardCensor = &wildcardCensor; extracter.Options = &options; NWindows::CThread thread; RINOK(thread.Create(CThreadExtracting::MyThreadFunction, &extracter)); extracter.ExtractCallbackSpec->StartProgressDialog(title); if (extracter.Result == S_OK && options.TestMode && extracter.ExtractCallbackSpec->Messages.IsEmpty() && extracter.ExtractCallbackSpec->NumArchiveErrors == 0) { #ifndef _SFX UString s; AddValuePair(IDS_ARCHIVES_COLON, 0x02000324, extracter.Stat.NumArchives, s); AddValuePair(IDS_FOLDERS_COLON, 0x02000321, extracter.Stat.NumFolders, s); AddValuePair(IDS_FILES_COLON, 0x02000320, extracter.Stat.NumFiles, s); AddSizePair(IDS_SIZE_COLON, 0x02000322, extracter.Stat.UnpackSize, s); AddSizePair(IDS_COMPRESSED_COLON, 0x02000323, extracter.Stat.PackSize, s); s += L"\n"; s += LangString(IDS_MESSAGE_NO_ERRORS, 0x02000608); MessageBoxW(0, s, LangString(IDS_PROGRESS_TESTING, 0x02000F90), 0); #endif } if (extracter.Result != S_OK) if (!extracter.ErrorMessage.IsEmpty()) throw extracter.ErrorMessage; return extracter.Result; }