From be3b47d0d504a3409ce66bd77bb8c0acff87c4f5 Mon Sep 17 00:00:00 2001 From: kh1 Date: Thu, 15 Mar 2012 14:53:47 +0100 Subject: Reorganize the tree, have better ifw.pri. Shadow build support. Change-Id: I01fb12537f863ed0744979973c7e4153889cc5cb Reviewed-by: Tim Jenssen --- .../7zip/unix/CPP/7zip/UI/Common/CompressCall.cpp | 470 +++++++++++++++++++++ 1 file changed, 470 insertions(+) create mode 100644 src/libs/7zip/unix/CPP/7zip/UI/Common/CompressCall.cpp (limited to 'src/libs/7zip/unix/CPP/7zip/UI/Common/CompressCall.cpp') diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/CompressCall.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/CompressCall.cpp new file mode 100644 index 000000000..fdc6c66f1 --- /dev/null +++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/CompressCall.cpp @@ -0,0 +1,470 @@ +// CompressCall.cpp + +#include "StdAfx.h" + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#undef _WIN32 + +#include "CompressCall.h" + +// FIXME #include "Common/Random.h" +#include "Common/IntToString.h" +#include "Common/MyCom.h" +#include "Common/StringConvert.h" + +#include "Windows/Synchronization.h" +// FIXME #include "Windows/FileMapping.h" +#include "Windows/FileDir.h" + +#include "../FileManager/ProgramLocation.h" +#include "../FileManager/RegistryUtils.h" + +#define NEED_NAME_WINDOWS_TO_UNIX +#include "myPrivate.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif // _UNICODE + +using namespace NWindows; + +static LPCWSTR kShowDialogSwitch = L" -ad"; +static LPCWSTR kEmailSwitch = L" -seml."; +static LPCWSTR kMapSwitch = L" -i#"; +static LPCWSTR kArchiveNoNameSwitch = L" -an"; +static LPCWSTR kArchiveTypeSwitch = L" -t"; +static LPCWSTR kArchiveMapSwitch = L" -ai#"; +static LPCWSTR kStopSwitchParsing = L" --"; +static LPCWSTR kLargePagesDisable = L" -slp-"; + +static void AddLagePagesSwitch(UString ¶ms) +{ +#ifdef _WIN32 + if (!ReadLockMemoryEnable()) + params += kLargePagesDisable; +#endif +} + +HRESULT MyCreateProcess(const UString ¶ms, + LPCWSTR curDir, bool waitFinish, + NWindows::NSynchronization::CBaseEvent *event) +{ + printf("MyCreateProcess: waitFinish=%d event=%p\n",(unsigned)waitFinish,event); + printf("\tparams : %ls\n",(const wchar_t*)params); + printf("\tcurDir : %ls\n",(const wchar_t*)curDir); + + wxString cmd(params); + wxString memoCurDir = wxGetCwd(); + + if (curDir) { // FIXME + wxSetWorkingDirectory(wxString(curDir)); + + + // under MacOSX, a bundle does not keep the current directory + // between 7zFM and 7zG ... + // So, try to use the environment variable P7ZIP_CURRENT_DIR + + char p7zip_current_dir[MAX_PATH]; + + AString aCurPath = GetAnsiString(curDir); + + const char *dir2 = nameWindowToUnix((const char *)aCurPath); + + snprintf(p7zip_current_dir,sizeof(p7zip_current_dir),"P7ZIP_CURRENT_DIR=%s/",dir2); + + p7zip_current_dir[sizeof(p7zip_current_dir)-1] = 0; + + putenv(p7zip_current_dir); + + printf("putenv(%s)\n",p7zip_current_dir); + + } + + + printf("MyCreateProcess: cmd='%ls'\n",(const wchar_t *)cmd); + long pid = 0; + if (waitFinish) pid = wxExecute(cmd, wxEXEC_SYNC); // FIXME process never ends and stays zombie ... + else pid = wxExecute(cmd, wxEXEC_ASYNC); + + if (curDir) wxSetWorkingDirectory(memoCurDir); + + + // FIXME if (pid == 0) return E_FAIL; + + return S_OK; +#ifdef _WIN32 // FIXME + const UString params2 = params; + BOOL result; + { + STARTUPINFOW startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + result = ::CreateProcessW(NULL, (LPWSTR)(LPCWSTR)params, + NULL, NULL, FALSE, 0, NULL, + curDir, + &startupInfo, &processInformation); + } + if (result == 0) + return ::GetLastError(); + else + { + ::CloseHandle(processInformation.hThread); + if (waitFinish) + WaitForSingleObject(processInformation.hProcess, INFINITE); + else if (event != NULL) + { + HANDLE handles[] = {processInformation.hProcess, *event }; + ::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]), + handles, FALSE, INFINITE); + } + ::CloseHandle(processInformation.hProcess); + } + return S_OK; +#endif +} + +UString GetQuotedString(const UString &s) +{ + return UString(L"\"") + s + UString(L"\""); +} + +static UString Get7zGuiPath() +{ + UString path; + UString folder; + if (GetProgramFolderPath(folder)) + path += folder; +#ifdef _WIN32 + path += L"7zG.exe"; +#else + path += L"7zG"; +#endif + return GetQuotedString(path); +} + +#ifdef _WIN32 +static HRESULT CreateTempEvent(const wchar_t *name, + NSynchronization::CManualResetEvent &event, UString &eventName) +{ + CRandom random; + random.Init(GetTickCount()); + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString((UInt32)number, temp); + eventName = name; + eventName += temp; + RINOK(event.CreateWithName(false, GetSystemString(eventName))); + if (::GetLastError() != ERROR_ALREADY_EXISTS) + return S_OK; + event.Close(); + } +} + +static HRESULT CreateMap(const UStringVector &names, + const UString &id, + CFileMapping &fileMapping, NSynchronization::CManualResetEvent &event, + UString ¶ms) +{ + UInt32 extraSize = 2; + UInt32 dataSize = 0; + for (int i = 0; i < names.Size(); i++) + dataSize += (names[i].Length() + 1) * sizeof(wchar_t); + UInt32 totalSize = extraSize + dataSize; + + UString mappingName; + + CRandom random; + random.Init(GetTickCount()); + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + mappingName = id; + mappingName += L"Mapping"; + mappingName += temp; + if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, totalSize, GetSystemString(mappingName))) + return E_FAIL; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + fileMapping.Close(); + } + + UString eventName; + RINOK(CreateTempEvent(id + L"MappingEndEvent", event, eventName)); + + params += mappingName; + params += L":"; + wchar_t string[10]; + ConvertUInt64ToString(totalSize, string); + params += string; + + params += L":"; + params += eventName; + + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize); + if (data == NULL) + return E_FAIL; + { + wchar_t *curData = (wchar_t *)data; + *curData = 0; + curData++; + for (int i = 0; i < names.Size(); i++) + { + const UString &s = names[i]; + memcpy(curData, (const wchar_t *)s, s.Length() * sizeof(wchar_t)); + curData += s.Length(); + *curData++ = L'\0'; + } + } + return S_OK; +} +#endif + +HRESULT CompressFiles( + const UString &curDir, + const UString &archiveName, + const UString &archiveType, + const UStringVector &names, + // const UString &outFolder, + bool email, + bool showDialog, + bool waitFinish) +{ + /* + UString curDir; + if (names.Size() > 0) + { + NFile::NDirectory::GetOnlyDirPrefix(names[0], curDir); + } + */ + UString params; + params = Get7zGuiPath(); + params += L" a"; +#ifdef _WIN32 + params += kMapSwitch; + // params += _fileNames[0]; + + UInt32 extraSize = 2; + UInt32 dataSize = 0; + for (int i = 0; i < names.Size(); i++) + dataSize += (names[i].Length() + 1) * sizeof(wchar_t); + UInt32 totalSize = extraSize + dataSize; + + UString mappingName; + + CFileMapping fileMapping; + CRandom random; + random.Init(GetTickCount()); + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + mappingName = L"7zCompressMapping"; + mappingName += temp; + if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, totalSize, GetSystemString(mappingName))) + { + // MyMessageBox(IDS_ERROR, 0x02000605); + return E_FAIL; + } + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + fileMapping.Close(); + } + + NSynchronization::CManualResetEvent event; + UString eventName; + RINOK(CreateTempEvent(L"7zCompressMappingEndEvent", event, eventName)); + + params += mappingName; + params += L":"; + wchar_t string[10]; + ConvertUInt64ToString(totalSize, string); + params += string; + + params += L":"; + params += eventName; +#else + char tempFile[256]; + static int count = 1000; + + sprintf(tempFile,"/tmp/7zCompress_%d_%d.tmp",(int)getpid(),count++); + + FILE * file = fopen(tempFile,"w"); + if (file) + { + for (int i = 0; i < names.Size(); i++) { + fprintf(file,"%ls\n",(const wchar_t *)names[i]); + printf(" TMP_%d : '%ls'\n",i,(const wchar_t *)names[i]); + } + + fclose(file); + } + params += L" -i@"; + params += GetUnicodeString(tempFile); +#endif + + if (!archiveType.IsEmpty()) + { + params += kArchiveTypeSwitch; + params += archiveType; + } + + if (email) + params += kEmailSwitch; + + if (showDialog) + params += kShowDialogSwitch; + + AddLagePagesSwitch(params); + + params += kStopSwitchParsing; + params += L" "; + + params += GetQuotedString(archiveName); + +#ifdef _WIN32 + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize); + if (data == NULL) + { + // MyMessageBox(IDS_ERROR, 0x02000605); + return E_FAIL; + } + try + { + wchar_t *curData = (wchar_t *)data; + *curData = 0; + curData++; + for (int i = 0; i < names.Size(); i++) + { + const UString &unicodeString = names[i]; + memcpy(curData, (const wchar_t *)unicodeString , + unicodeString .Length() * sizeof(wchar_t)); + curData += unicodeString.Length(); + *curData++ = L'\0'; + } + // MessageBox(0, params, 0, 0); + RINOK(MyCreateProcess(params, + (curDir.IsEmpty()? 0: (LPCWSTR)curDir), + waitFinish, &event)); + } + catch(...) + { + UnmapViewOfFile(data); + throw; + } + UnmapViewOfFile(data); + + + /* + CThreadCompressMain *compressor = new CThreadCompressMain();; + compressor->FileNames = _fileNames; + CThread thread; + if (!thread.Create(CThreadCompressMain::MyThreadFunction, compressor)) + throw 271824; + */ +#else + printf("CompressFiles : -%ls-\n",(const wchar_t *)params); + HRESULT res = MyCreateProcess(params, + (curDir.IsEmpty()? 0: (LPCWSTR)curDir), + true, /* &event FIXME */ 0); + printf("CompressFiles : END\n"); + + remove(tempFile); +#endif + return S_OK; +} + +static HRESULT ExtractGroupCommand(const UStringVector &archivePaths, + const UString ¶ms) +{ + UString params2 = params; + AddLagePagesSwitch(params2); + params2 += kArchiveNoNameSwitch; +#ifdef _WIN32 + params2 += kArchiveMapSwitch; + CFileMapping fileMapping; + NSynchronization::CManualResetEvent event; + RINOK(CreateMap(archivePaths, L"7zExtract", fileMapping, event, params2)); + return MyCreateProcess(params2, 0, false, &event); +#else + char tempFile[256]; + static int count = 1000; + + sprintf(tempFile,"/tmp/7zExtract_%d_%d.tmp",(int)getpid(),count++); + + FILE * file = fopen(tempFile,"w"); + if (file) + { + for (int i = 0; i < archivePaths.Size(); i++) { + fprintf(file,"%ls\n",(const wchar_t *)archivePaths[i]); + printf(" TMP_%d : '%ls'\n",i,(const wchar_t *)archivePaths[i]); + } + + fclose(file); + } + params2 += L" -ai@"; + params2 += GetUnicodeString(tempFile); + printf("ExtractGroupCommand : -%ls-\n",(const wchar_t *)params2); + HRESULT res = MyCreateProcess(params2, 0, true, /* &event FIXME */ 0); + printf("ExtractGroupCommand : END\n"); + + remove(tempFile); + + return res; +#endif +} + +HRESULT ExtractArchives(const UStringVector &archivePaths, + const UString &outFolder, bool showDialog) +{ + UString params; + params = Get7zGuiPath(); + params += L" x"; + if (!outFolder.IsEmpty()) + { + params += L" \"-o"; + params += outFolder; + params += L"\""; + } + if (showDialog) + params += kShowDialogSwitch; + return ExtractGroupCommand(archivePaths, params); +} + +HRESULT TestArchives(const UStringVector &archivePaths) +{ + UString params; + params = Get7zGuiPath(); + params += L" t"; + return ExtractGroupCommand(archivePaths, params); +} + +HRESULT Benchmark() +{ + UString params; + params = Get7zGuiPath(); + params += L" b"; + return MyCreateProcess(params, 0, false, NULL); +} -- cgit v1.2.3