mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 04:07:02 -06:00
Normalize all the line endings
This commit is contained in:
@@ -1,246 +1,246 @@
|
||||
// ExtractCallbackSfx.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "ExtractCallbackSfx.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
static LPCSTR const kCantDeleteFile = "Can not delete output file";
|
||||
static LPCSTR const kCantOpenFile = "Can not open output file";
|
||||
static LPCSTR const kUnsupportedMethod = "Unsupported Method";
|
||||
|
||||
void CExtractCallbackImp::Init(IInArchive *archiveHandler,
|
||||
const FString &directoryPath,
|
||||
const UString &itemDefaultName,
|
||||
const FILETIME &defaultMTime,
|
||||
UInt32 defaultAttributes)
|
||||
{
|
||||
_message.Empty();
|
||||
_isCorrupt = false;
|
||||
_itemDefaultName = itemDefaultName;
|
||||
_defaultMTime = defaultMTime;
|
||||
_defaultAttributes = defaultAttributes;
|
||||
_archiveHandler = archiveHandler;
|
||||
_directoryPath = directoryPath;
|
||||
NName::NormalizeDirPathPrefix(_directoryPath);
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_CheckBreak()
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
return ProgressDialog.Sync.ProcessStopAndPause();
|
||||
#else
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
return ProgressDialog.Sync.ProcessStopAndPause();
|
||||
#else
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_Finished()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size)
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
ProgressDialog.Sync.SetProgress(size, 0);
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
RINOK(ProgressDialog.Sync.ProcessStopAndPause());
|
||||
if (completeValue != NULL)
|
||||
ProgressDialog.Sync.SetPos(*completeValue);
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
|
||||
{
|
||||
FString fullPath = _directoryPath;
|
||||
FOR_VECTOR (i, dirPathParts)
|
||||
{
|
||||
fullPath += us2fs(dirPathParts[i]);
|
||||
CreateDir(fullPath);
|
||||
fullPath.Add_PathSepar();
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
|
||||
ISequentialOutStream **outStream, Int32 askExtractMode)
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
if (ProgressDialog.Sync.GetStopped())
|
||||
return E_ABORT;
|
||||
#endif
|
||||
_outFileStream.Release();
|
||||
|
||||
UString fullPath;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
fullPath = _itemDefaultName;
|
||||
else
|
||||
{
|
||||
if (prop.vt != VT_BSTR)
|
||||
return E_FAIL;
|
||||
fullPath.SetFromBstr(prop.bstrVal);
|
||||
}
|
||||
_filePath = fullPath;
|
||||
}
|
||||
|
||||
if (askExtractMode == NArchive::NExtract::NAskMode::kExtract)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
_processedFileInfo.Attributes = _defaultAttributes;
|
||||
else
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_FAIL;
|
||||
_processedFileInfo.Attributes = prop.ulVal;
|
||||
}
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop));
|
||||
_processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal);
|
||||
|
||||
bool isAnti = false;
|
||||
{
|
||||
NCOM::CPropVariant propTemp;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp));
|
||||
if (propTemp.vt == VT_BOOL)
|
||||
isAnti = VARIANT_BOOLToBool(propTemp.boolVal);
|
||||
}
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
|
||||
switch (prop.vt)
|
||||
{
|
||||
case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break;
|
||||
case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break;
|
||||
default: return E_FAIL;
|
||||
}
|
||||
|
||||
UStringVector pathParts;
|
||||
SplitPathToParts(fullPath, pathParts);
|
||||
if (pathParts.IsEmpty())
|
||||
return E_FAIL;
|
||||
|
||||
UString processedPath = fullPath;
|
||||
|
||||
if (!_processedFileInfo.IsDir)
|
||||
pathParts.DeleteBack();
|
||||
if (!pathParts.IsEmpty())
|
||||
{
|
||||
if (!isAnti)
|
||||
CreateComplexDirectory(pathParts);
|
||||
}
|
||||
|
||||
FString fullProcessedPath = _directoryPath + us2fs(processedPath);
|
||||
|
||||
if (_processedFileInfo.IsDir)
|
||||
{
|
||||
_diskFilePath = fullProcessedPath;
|
||||
|
||||
if (isAnti)
|
||||
RemoveDir(_diskFilePath);
|
||||
else
|
||||
SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
NFind::CFileInfo fileInfo;
|
||||
if (fileInfo.Find(fullProcessedPath))
|
||||
{
|
||||
if (!DeleteFileAlways(fullProcessedPath))
|
||||
{
|
||||
_message = kCantDeleteFile;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAnti)
|
||||
{
|
||||
_outFileStreamSpec = new COutFileStream;
|
||||
CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
|
||||
if (!_outFileStreamSpec->Create(fullProcessedPath, true))
|
||||
{
|
||||
_message = kCantOpenFile;
|
||||
return E_FAIL;
|
||||
}
|
||||
_outFileStream = outStreamLoc;
|
||||
*outStream = outStreamLoc.Detach();
|
||||
}
|
||||
_diskFilePath = fullProcessedPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
*outStream = NULL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)
|
||||
{
|
||||
_extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)
|
||||
{
|
||||
switch (resultEOperationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kOK:
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
_outFileStream.Release();
|
||||
switch (resultEOperationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
|
||||
_message = kUnsupportedMethod;
|
||||
break;
|
||||
default:
|
||||
_isCorrupt = true;
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
if (_outFileStream != NULL)
|
||||
{
|
||||
_outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
|
||||
RINOK(_outFileStreamSpec->Close());
|
||||
}
|
||||
_outFileStream.Release();
|
||||
if (_extractMode)
|
||||
SetFileAttrib(_diskFilePath, _processedFileInfo.Attributes);
|
||||
return S_OK;
|
||||
}
|
||||
// ExtractCallbackSfx.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "ExtractCallbackSfx.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
static LPCSTR const kCantDeleteFile = "Can not delete output file";
|
||||
static LPCSTR const kCantOpenFile = "Can not open output file";
|
||||
static LPCSTR const kUnsupportedMethod = "Unsupported Method";
|
||||
|
||||
void CExtractCallbackImp::Init(IInArchive *archiveHandler,
|
||||
const FString &directoryPath,
|
||||
const UString &itemDefaultName,
|
||||
const FILETIME &defaultMTime,
|
||||
UInt32 defaultAttributes)
|
||||
{
|
||||
_message.Empty();
|
||||
_isCorrupt = false;
|
||||
_itemDefaultName = itemDefaultName;
|
||||
_defaultMTime = defaultMTime;
|
||||
_defaultAttributes = defaultAttributes;
|
||||
_archiveHandler = archiveHandler;
|
||||
_directoryPath = directoryPath;
|
||||
NName::NormalizeDirPathPrefix(_directoryPath);
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_CheckBreak()
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
return ProgressDialog.Sync.ProcessStopAndPause();
|
||||
#else
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
return ProgressDialog.Sync.ProcessStopAndPause();
|
||||
#else
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_Finished()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size)
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
ProgressDialog.Sync.SetProgress(size, 0);
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
RINOK(ProgressDialog.Sync.ProcessStopAndPause());
|
||||
if (completeValue != NULL)
|
||||
ProgressDialog.Sync.SetPos(*completeValue);
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
|
||||
{
|
||||
FString fullPath = _directoryPath;
|
||||
FOR_VECTOR (i, dirPathParts)
|
||||
{
|
||||
fullPath += us2fs(dirPathParts[i]);
|
||||
CreateDir(fullPath);
|
||||
fullPath.Add_PathSepar();
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
|
||||
ISequentialOutStream **outStream, Int32 askExtractMode)
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
if (ProgressDialog.Sync.GetStopped())
|
||||
return E_ABORT;
|
||||
#endif
|
||||
_outFileStream.Release();
|
||||
|
||||
UString fullPath;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
fullPath = _itemDefaultName;
|
||||
else
|
||||
{
|
||||
if (prop.vt != VT_BSTR)
|
||||
return E_FAIL;
|
||||
fullPath.SetFromBstr(prop.bstrVal);
|
||||
}
|
||||
_filePath = fullPath;
|
||||
}
|
||||
|
||||
if (askExtractMode == NArchive::NExtract::NAskMode::kExtract)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
_processedFileInfo.Attributes = _defaultAttributes;
|
||||
else
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_FAIL;
|
||||
_processedFileInfo.Attributes = prop.ulVal;
|
||||
}
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop));
|
||||
_processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal);
|
||||
|
||||
bool isAnti = false;
|
||||
{
|
||||
NCOM::CPropVariant propTemp;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp));
|
||||
if (propTemp.vt == VT_BOOL)
|
||||
isAnti = VARIANT_BOOLToBool(propTemp.boolVal);
|
||||
}
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
|
||||
switch (prop.vt)
|
||||
{
|
||||
case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break;
|
||||
case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break;
|
||||
default: return E_FAIL;
|
||||
}
|
||||
|
||||
UStringVector pathParts;
|
||||
SplitPathToParts(fullPath, pathParts);
|
||||
if (pathParts.IsEmpty())
|
||||
return E_FAIL;
|
||||
|
||||
UString processedPath = fullPath;
|
||||
|
||||
if (!_processedFileInfo.IsDir)
|
||||
pathParts.DeleteBack();
|
||||
if (!pathParts.IsEmpty())
|
||||
{
|
||||
if (!isAnti)
|
||||
CreateComplexDirectory(pathParts);
|
||||
}
|
||||
|
||||
FString fullProcessedPath = _directoryPath + us2fs(processedPath);
|
||||
|
||||
if (_processedFileInfo.IsDir)
|
||||
{
|
||||
_diskFilePath = fullProcessedPath;
|
||||
|
||||
if (isAnti)
|
||||
RemoveDir(_diskFilePath);
|
||||
else
|
||||
SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
NFind::CFileInfo fileInfo;
|
||||
if (fileInfo.Find(fullProcessedPath))
|
||||
{
|
||||
if (!DeleteFileAlways(fullProcessedPath))
|
||||
{
|
||||
_message = kCantDeleteFile;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAnti)
|
||||
{
|
||||
_outFileStreamSpec = new COutFileStream;
|
||||
CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
|
||||
if (!_outFileStreamSpec->Create(fullProcessedPath, true))
|
||||
{
|
||||
_message = kCantOpenFile;
|
||||
return E_FAIL;
|
||||
}
|
||||
_outFileStream = outStreamLoc;
|
||||
*outStream = outStreamLoc.Detach();
|
||||
}
|
||||
_diskFilePath = fullProcessedPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
*outStream = NULL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)
|
||||
{
|
||||
_extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)
|
||||
{
|
||||
switch (resultEOperationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kOK:
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
_outFileStream.Release();
|
||||
switch (resultEOperationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
|
||||
_message = kUnsupportedMethod;
|
||||
break;
|
||||
default:
|
||||
_isCorrupt = true;
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
if (_outFileStream != NULL)
|
||||
{
|
||||
_outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
|
||||
RINOK(_outFileStreamSpec->Close());
|
||||
}
|
||||
_outFileStream.Release();
|
||||
if (_extractMode)
|
||||
SetFileAttrib(_diskFilePath, _processedFileInfo.Attributes);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1,86 +1,86 @@
|
||||
// ExtractCallbackSfx.h
|
||||
|
||||
#ifndef __EXTRACT_CALLBACK_SFX_H
|
||||
#define __EXTRACT_CALLBACK_SFX_H
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#include "../../../Windows/ResourceString.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#include "../../UI/FileManager/LangUtils.h"
|
||||
|
||||
#ifndef _NO_PROGRESS
|
||||
#include "../../UI/FileManager/ProgressDialog.h"
|
||||
#endif
|
||||
#include "../../UI/Common/ArchiveOpenCallback.h"
|
||||
|
||||
class CExtractCallbackImp:
|
||||
public IArchiveExtractCallback,
|
||||
public IOpenCallbackUI,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
INTERFACE_IArchiveExtractCallback(;)
|
||||
INTERFACE_IOpenCallbackUI(;)
|
||||
|
||||
private:
|
||||
CMyComPtr<IInArchive> _archiveHandler;
|
||||
FString _directoryPath;
|
||||
UString _filePath;
|
||||
FString _diskFilePath;
|
||||
|
||||
bool _extractMode;
|
||||
struct CProcessedFileInfo
|
||||
{
|
||||
FILETIME MTime;
|
||||
bool IsDir;
|
||||
UInt32 Attributes;
|
||||
} _processedFileInfo;
|
||||
|
||||
COutFileStream *_outFileStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> _outFileStream;
|
||||
|
||||
UString _itemDefaultName;
|
||||
FILETIME _defaultMTime;
|
||||
UInt32 _defaultAttributes;
|
||||
|
||||
void CreateComplexDirectory(const UStringVector &dirPathParts);
|
||||
public:
|
||||
#ifndef _NO_PROGRESS
|
||||
CProgressDialog ProgressDialog;
|
||||
#endif
|
||||
|
||||
bool _isCorrupt;
|
||||
UString _message;
|
||||
|
||||
void Init(IInArchive *archiveHandler,
|
||||
const FString &directoryPath,
|
||||
const UString &itemDefaultName,
|
||||
const FILETIME &defaultMTime,
|
||||
UInt32 defaultAttributes);
|
||||
|
||||
#ifndef _NO_PROGRESS
|
||||
HRESULT StartProgressDialog(const UString &title, NWindows::CThread &thread)
|
||||
{
|
||||
ProgressDialog.Create(title, thread, 0);
|
||||
{
|
||||
ProgressDialog.SetText(LangString(IDS_PROGRESS_EXTRACTING));
|
||||
}
|
||||
|
||||
ProgressDialog.Show(SW_SHOWNORMAL);
|
||||
return S_OK;
|
||||
}
|
||||
virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
// ExtractCallbackSfx.h
|
||||
|
||||
#ifndef __EXTRACT_CALLBACK_SFX_H
|
||||
#define __EXTRACT_CALLBACK_SFX_H
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#include "../../../Windows/ResourceString.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#include "../../UI/FileManager/LangUtils.h"
|
||||
|
||||
#ifndef _NO_PROGRESS
|
||||
#include "../../UI/FileManager/ProgressDialog.h"
|
||||
#endif
|
||||
#include "../../UI/Common/ArchiveOpenCallback.h"
|
||||
|
||||
class CExtractCallbackImp:
|
||||
public IArchiveExtractCallback,
|
||||
public IOpenCallbackUI,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
INTERFACE_IArchiveExtractCallback(;)
|
||||
INTERFACE_IOpenCallbackUI(;)
|
||||
|
||||
private:
|
||||
CMyComPtr<IInArchive> _archiveHandler;
|
||||
FString _directoryPath;
|
||||
UString _filePath;
|
||||
FString _diskFilePath;
|
||||
|
||||
bool _extractMode;
|
||||
struct CProcessedFileInfo
|
||||
{
|
||||
FILETIME MTime;
|
||||
bool IsDir;
|
||||
UInt32 Attributes;
|
||||
} _processedFileInfo;
|
||||
|
||||
COutFileStream *_outFileStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> _outFileStream;
|
||||
|
||||
UString _itemDefaultName;
|
||||
FILETIME _defaultMTime;
|
||||
UInt32 _defaultAttributes;
|
||||
|
||||
void CreateComplexDirectory(const UStringVector &dirPathParts);
|
||||
public:
|
||||
#ifndef _NO_PROGRESS
|
||||
CProgressDialog ProgressDialog;
|
||||
#endif
|
||||
|
||||
bool _isCorrupt;
|
||||
UString _message;
|
||||
|
||||
void Init(IInArchive *archiveHandler,
|
||||
const FString &directoryPath,
|
||||
const UString &itemDefaultName,
|
||||
const FILETIME &defaultMTime,
|
||||
UInt32 defaultAttributes);
|
||||
|
||||
#ifndef _NO_PROGRESS
|
||||
HRESULT StartProgressDialog(const UString &title, NWindows::CThread &thread)
|
||||
{
|
||||
ProgressDialog.Create(title, thread, 0);
|
||||
{
|
||||
ProgressDialog.SetText(LangString(IDS_PROGRESS_EXTRACTING));
|
||||
}
|
||||
|
||||
ProgressDialog.Show(SW_SHOWNORMAL);
|
||||
return S_OK;
|
||||
}
|
||||
virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,137 +1,137 @@
|
||||
// ExtractEngine.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/Thread.h"
|
||||
|
||||
#include "../../UI/Common/OpenArchive.h"
|
||||
|
||||
#include "../../UI/FileManager/FormatUtils.h"
|
||||
#include "../../UI/FileManager/LangUtils.h"
|
||||
|
||||
#include "ExtractCallbackSfx.h"
|
||||
#include "ExtractEngine.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
static LPCSTR const kCantFindArchive = "Can not find archive file";
|
||||
static LPCSTR const kCantOpenArchive = "Can not open the file as archive";
|
||||
|
||||
struct CThreadExtracting
|
||||
{
|
||||
CCodecs *Codecs;
|
||||
FString FileName;
|
||||
FString DestFolder;
|
||||
|
||||
CExtractCallbackImp *ExtractCallbackSpec;
|
||||
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
|
||||
|
||||
CArchiveLink ArchiveLink;
|
||||
HRESULT Result;
|
||||
UString ErrorMessage;
|
||||
|
||||
void Process2()
|
||||
{
|
||||
NFind::CFileInfo fi;
|
||||
if (!fi.Find(FileName))
|
||||
{
|
||||
ErrorMessage = kCantFindArchive;
|
||||
Result = E_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
CObjectVector<COpenType> incl;
|
||||
CIntVector excl;
|
||||
COpenOptions options;
|
||||
options.codecs = Codecs;
|
||||
options.types = &incl;
|
||||
options.excludedFormats = !
|
||||
options.filePath = fs2us(FileName);
|
||||
|
||||
Result = ArchiveLink.Open2(options, ExtractCallbackSpec);
|
||||
if (Result != S_OK)
|
||||
{
|
||||
ErrorMessage = kCantOpenArchive;
|
||||
return;
|
||||
}
|
||||
|
||||
FString dirPath = DestFolder;
|
||||
NName::NormalizeDirPathPrefix(dirPath);
|
||||
|
||||
if (!CreateComplexDir(dirPath))
|
||||
{
|
||||
ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
|
||||
#ifdef LANG
|
||||
0x02000603,
|
||||
#endif
|
||||
fs2us(dirPath));
|
||||
Result = E_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, (UString)"Default", fi.MTime, 0);
|
||||
|
||||
Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback);
|
||||
}
|
||||
|
||||
void Process()
|
||||
{
|
||||
try
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
CProgressCloser closer(ExtractCallbackSpec->ProgressDialog);
|
||||
#endif
|
||||
Process2();
|
||||
}
|
||||
catch(...) { Result = E_FAIL; }
|
||||
}
|
||||
|
||||
static THREAD_FUNC_DECL MyThreadFunction(void *param)
|
||||
{
|
||||
((CThreadExtracting *)param)->Process();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
|
||||
bool showProgress, bool &isCorrupt, UString &errorMessage)
|
||||
{
|
||||
isCorrupt = false;
|
||||
CThreadExtracting t;
|
||||
|
||||
t.Codecs = codecs;
|
||||
t.FileName = fileName;
|
||||
t.DestFolder = destFolder;
|
||||
|
||||
t.ExtractCallbackSpec = new CExtractCallbackImp;
|
||||
t.ExtractCallback = t.ExtractCallbackSpec;
|
||||
|
||||
#ifndef _NO_PROGRESS
|
||||
|
||||
if (showProgress)
|
||||
{
|
||||
t.ExtractCallbackSpec->ProgressDialog.IconID = IDI_ICON;
|
||||
NWindows::CThread thread;
|
||||
RINOK(thread.Create(CThreadExtracting::MyThreadFunction, &t));
|
||||
|
||||
UString title;
|
||||
LangString(IDS_PROGRESS_EXTRACTING, title);
|
||||
t.ExtractCallbackSpec->StartProgressDialog(title, thread);
|
||||
}
|
||||
else
|
||||
|
||||
#endif
|
||||
{
|
||||
t.Process2();
|
||||
}
|
||||
|
||||
errorMessage = t.ErrorMessage;
|
||||
if (errorMessage.IsEmpty())
|
||||
errorMessage = t.ExtractCallbackSpec->_message;
|
||||
isCorrupt = t.ExtractCallbackSpec->_isCorrupt;
|
||||
return t.Result;
|
||||
}
|
||||
// ExtractEngine.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/Thread.h"
|
||||
|
||||
#include "../../UI/Common/OpenArchive.h"
|
||||
|
||||
#include "../../UI/FileManager/FormatUtils.h"
|
||||
#include "../../UI/FileManager/LangUtils.h"
|
||||
|
||||
#include "ExtractCallbackSfx.h"
|
||||
#include "ExtractEngine.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
static LPCSTR const kCantFindArchive = "Can not find archive file";
|
||||
static LPCSTR const kCantOpenArchive = "Can not open the file as archive";
|
||||
|
||||
struct CThreadExtracting
|
||||
{
|
||||
CCodecs *Codecs;
|
||||
FString FileName;
|
||||
FString DestFolder;
|
||||
|
||||
CExtractCallbackImp *ExtractCallbackSpec;
|
||||
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
|
||||
|
||||
CArchiveLink ArchiveLink;
|
||||
HRESULT Result;
|
||||
UString ErrorMessage;
|
||||
|
||||
void Process2()
|
||||
{
|
||||
NFind::CFileInfo fi;
|
||||
if (!fi.Find(FileName))
|
||||
{
|
||||
ErrorMessage = kCantFindArchive;
|
||||
Result = E_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
CObjectVector<COpenType> incl;
|
||||
CIntVector excl;
|
||||
COpenOptions options;
|
||||
options.codecs = Codecs;
|
||||
options.types = &incl;
|
||||
options.excludedFormats = !
|
||||
options.filePath = fs2us(FileName);
|
||||
|
||||
Result = ArchiveLink.Open2(options, ExtractCallbackSpec);
|
||||
if (Result != S_OK)
|
||||
{
|
||||
ErrorMessage = kCantOpenArchive;
|
||||
return;
|
||||
}
|
||||
|
||||
FString dirPath = DestFolder;
|
||||
NName::NormalizeDirPathPrefix(dirPath);
|
||||
|
||||
if (!CreateComplexDir(dirPath))
|
||||
{
|
||||
ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
|
||||
#ifdef LANG
|
||||
0x02000603,
|
||||
#endif
|
||||
fs2us(dirPath));
|
||||
Result = E_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, (UString)"Default", fi.MTime, 0);
|
||||
|
||||
Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback);
|
||||
}
|
||||
|
||||
void Process()
|
||||
{
|
||||
try
|
||||
{
|
||||
#ifndef _NO_PROGRESS
|
||||
CProgressCloser closer(ExtractCallbackSpec->ProgressDialog);
|
||||
#endif
|
||||
Process2();
|
||||
}
|
||||
catch(...) { Result = E_FAIL; }
|
||||
}
|
||||
|
||||
static THREAD_FUNC_DECL MyThreadFunction(void *param)
|
||||
{
|
||||
((CThreadExtracting *)param)->Process();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
|
||||
bool showProgress, bool &isCorrupt, UString &errorMessage)
|
||||
{
|
||||
isCorrupt = false;
|
||||
CThreadExtracting t;
|
||||
|
||||
t.Codecs = codecs;
|
||||
t.FileName = fileName;
|
||||
t.DestFolder = destFolder;
|
||||
|
||||
t.ExtractCallbackSpec = new CExtractCallbackImp;
|
||||
t.ExtractCallback = t.ExtractCallbackSpec;
|
||||
|
||||
#ifndef _NO_PROGRESS
|
||||
|
||||
if (showProgress)
|
||||
{
|
||||
t.ExtractCallbackSpec->ProgressDialog.IconID = IDI_ICON;
|
||||
NWindows::CThread thread;
|
||||
RINOK(thread.Create(CThreadExtracting::MyThreadFunction, &t));
|
||||
|
||||
UString title;
|
||||
LangString(IDS_PROGRESS_EXTRACTING, title);
|
||||
t.ExtractCallbackSpec->StartProgressDialog(title, thread);
|
||||
}
|
||||
else
|
||||
|
||||
#endif
|
||||
{
|
||||
t.Process2();
|
||||
}
|
||||
|
||||
errorMessage = t.ErrorMessage;
|
||||
if (errorMessage.IsEmpty())
|
||||
errorMessage = t.ExtractCallbackSpec->_message;
|
||||
isCorrupt = t.ExtractCallbackSpec->_isCorrupt;
|
||||
return t.Result;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// ExtractEngine.h
|
||||
|
||||
#ifndef __EXTRACT_ENGINE_H
|
||||
#define __EXTRACT_ENGINE_H
|
||||
|
||||
#include "../../UI/Common/LoadCodecs.h"
|
||||
|
||||
HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
|
||||
bool showProgress, bool &isCorrupt, UString &errorMessage);
|
||||
|
||||
#endif
|
||||
// ExtractEngine.h
|
||||
|
||||
#ifndef __EXTRACT_ENGINE_H
|
||||
#define __EXTRACT_ENGINE_H
|
||||
|
||||
#include "../../UI/Common/LoadCodecs.h"
|
||||
|
||||
HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
|
||||
bool showProgress, bool &isCorrupt, UString &errorMessage);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "SFXSetup"=.\SFXSetup.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "SFXSetup"=.\SFXSetup.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
@@ -1,364 +1,364 @@
|
||||
// Main.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#include "../../../Common/MyInitGuid.h"
|
||||
|
||||
#include "../../../Common/CommandLineParser.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/TextConfig.h"
|
||||
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/FileIO.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/NtCheck.h"
|
||||
#include "../../../Windows/ResourceString.h"
|
||||
|
||||
#include "../../UI/Explorer/MyMessages.h"
|
||||
|
||||
#include "ExtractEngine.h"
|
||||
|
||||
#include "../../../../C/DllSecur.h"
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
static CFSTR const kTempDirPrefix = FTEXT("7zS");
|
||||
|
||||
#define _SHELL_EXECUTE
|
||||
|
||||
static bool ReadDataString(CFSTR fileName, LPCSTR startID,
|
||||
LPCSTR endID, AString &stringResult)
|
||||
{
|
||||
stringResult.Empty();
|
||||
NIO::CInFile inFile;
|
||||
if (!inFile.Open(fileName))
|
||||
return false;
|
||||
const int kBufferSize = (1 << 12);
|
||||
|
||||
Byte buffer[kBufferSize];
|
||||
int signatureStartSize = MyStringLen(startID);
|
||||
int signatureEndSize = MyStringLen(endID);
|
||||
|
||||
UInt32 numBytesPrev = 0;
|
||||
bool writeMode = false;
|
||||
UInt64 posTotal = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (posTotal > (1 << 20))
|
||||
return (stringResult.IsEmpty());
|
||||
UInt32 numReadBytes = kBufferSize - numBytesPrev;
|
||||
UInt32 processedSize;
|
||||
if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize))
|
||||
return false;
|
||||
if (processedSize == 0)
|
||||
return true;
|
||||
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
|
||||
UInt32 pos = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (writeMode)
|
||||
{
|
||||
if (pos > numBytesInBuffer - signatureEndSize)
|
||||
break;
|
||||
if (memcmp(buffer + pos, endID, signatureEndSize) == 0)
|
||||
return true;
|
||||
char b = buffer[pos];
|
||||
if (b == 0)
|
||||
return false;
|
||||
stringResult += b;
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos > numBytesInBuffer - signatureStartSize)
|
||||
break;
|
||||
if (memcmp(buffer + pos, startID, signatureStartSize) == 0)
|
||||
{
|
||||
writeMode = true;
|
||||
pos += signatureStartSize;
|
||||
}
|
||||
else
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
numBytesPrev = numBytesInBuffer - pos;
|
||||
posTotal += pos;
|
||||
memmove(buffer, buffer + pos, numBytesPrev);
|
||||
}
|
||||
}
|
||||
|
||||
static char kStartID[] = { ',','!','@','I','n','s','t','a','l','l','@','!','U','T','F','-','8','!', 0 };
|
||||
static char kEndID[] = { ',','!','@','I','n','s','t','a','l','l','E','n','d','@','!', 0 };
|
||||
|
||||
struct CInstallIDInit
|
||||
{
|
||||
CInstallIDInit()
|
||||
{
|
||||
kStartID[0] = ';';
|
||||
kEndID[0] = ';';
|
||||
};
|
||||
} g_CInstallIDInit;
|
||||
|
||||
|
||||
#define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return 1;
|
||||
|
||||
static void ShowErrorMessageSpec(const UString &name)
|
||||
{
|
||||
UString message = NError::MyFormatMessage(::GetLastError());
|
||||
int pos = message.Find(L"%1");
|
||||
if (pos >= 0)
|
||||
{
|
||||
message.Delete(pos, 2);
|
||||
message.Insert(pos, name);
|
||||
}
|
||||
ShowErrorMessage(NULL, message);
|
||||
}
|
||||
|
||||
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 ("." STRING_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, "Title");
|
||||
UString installPrompt = GetTextConfigValue(pairs, "BeginPrompt");
|
||||
UString progress = GetTextConfigValue(pairs, "Progress");
|
||||
if (progress.IsEqualTo_Ascii_NoCase("no"))
|
||||
showProgress = false;
|
||||
int index = FindTextConfigItem(pairs, "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, "RunProgram");
|
||||
|
||||
#ifdef _SHELL_EXECUTE
|
||||
executeFile = GetTextConfigValue(pairs, "ExecuteFile");
|
||||
executeParameters = GetTextConfigValue(pairs, "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;
|
||||
}
|
||||
// Main.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#include "../../../Common/MyInitGuid.h"
|
||||
|
||||
#include "../../../Common/CommandLineParser.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/TextConfig.h"
|
||||
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/FileIO.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/NtCheck.h"
|
||||
#include "../../../Windows/ResourceString.h"
|
||||
|
||||
#include "../../UI/Explorer/MyMessages.h"
|
||||
|
||||
#include "ExtractEngine.h"
|
||||
|
||||
#include "../../../../C/DllSecur.h"
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
static CFSTR const kTempDirPrefix = FTEXT("7zS");
|
||||
|
||||
#define _SHELL_EXECUTE
|
||||
|
||||
static bool ReadDataString(CFSTR fileName, LPCSTR startID,
|
||||
LPCSTR endID, AString &stringResult)
|
||||
{
|
||||
stringResult.Empty();
|
||||
NIO::CInFile inFile;
|
||||
if (!inFile.Open(fileName))
|
||||
return false;
|
||||
const int kBufferSize = (1 << 12);
|
||||
|
||||
Byte buffer[kBufferSize];
|
||||
int signatureStartSize = MyStringLen(startID);
|
||||
int signatureEndSize = MyStringLen(endID);
|
||||
|
||||
UInt32 numBytesPrev = 0;
|
||||
bool writeMode = false;
|
||||
UInt64 posTotal = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (posTotal > (1 << 20))
|
||||
return (stringResult.IsEmpty());
|
||||
UInt32 numReadBytes = kBufferSize - numBytesPrev;
|
||||
UInt32 processedSize;
|
||||
if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize))
|
||||
return false;
|
||||
if (processedSize == 0)
|
||||
return true;
|
||||
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
|
||||
UInt32 pos = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (writeMode)
|
||||
{
|
||||
if (pos > numBytesInBuffer - signatureEndSize)
|
||||
break;
|
||||
if (memcmp(buffer + pos, endID, signatureEndSize) == 0)
|
||||
return true;
|
||||
char b = buffer[pos];
|
||||
if (b == 0)
|
||||
return false;
|
||||
stringResult += b;
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos > numBytesInBuffer - signatureStartSize)
|
||||
break;
|
||||
if (memcmp(buffer + pos, startID, signatureStartSize) == 0)
|
||||
{
|
||||
writeMode = true;
|
||||
pos += signatureStartSize;
|
||||
}
|
||||
else
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
numBytesPrev = numBytesInBuffer - pos;
|
||||
posTotal += pos;
|
||||
memmove(buffer, buffer + pos, numBytesPrev);
|
||||
}
|
||||
}
|
||||
|
||||
static char kStartID[] = { ',','!','@','I','n','s','t','a','l','l','@','!','U','T','F','-','8','!', 0 };
|
||||
static char kEndID[] = { ',','!','@','I','n','s','t','a','l','l','E','n','d','@','!', 0 };
|
||||
|
||||
struct CInstallIDInit
|
||||
{
|
||||
CInstallIDInit()
|
||||
{
|
||||
kStartID[0] = ';';
|
||||
kEndID[0] = ';';
|
||||
};
|
||||
} g_CInstallIDInit;
|
||||
|
||||
|
||||
#define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return 1;
|
||||
|
||||
static void ShowErrorMessageSpec(const UString &name)
|
||||
{
|
||||
UString message = NError::MyFormatMessage(::GetLastError());
|
||||
int pos = message.Find(L"%1");
|
||||
if (pos >= 0)
|
||||
{
|
||||
message.Delete(pos, 2);
|
||||
message.Insert(pos, name);
|
||||
}
|
||||
ShowErrorMessage(NULL, message);
|
||||
}
|
||||
|
||||
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 ("." STRING_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, "Title");
|
||||
UString installPrompt = GetTextConfigValue(pairs, "BeginPrompt");
|
||||
UString progress = GetTextConfigValue(pairs, "Progress");
|
||||
if (progress.IsEqualTo_Ascii_NoCase("no"))
|
||||
showProgress = false;
|
||||
int index = FindTextConfigItem(pairs, "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, "RunProgram");
|
||||
|
||||
#ifdef _SHELL_EXECUTE
|
||||
executeFile = GetTextConfigValue(pairs, "ExecuteFile");
|
||||
executeParameters = GetTextConfigValue(pairs, "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;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
// #define printf(x) NO_PRINTF_(x)
|
||||
// #define sprintf(x) NO_SPRINTF_(x)
|
||||
|
||||
#endif
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
// #define printf(x) NO_PRINTF_(x)
|
||||
// #define sprintf(x) NO_SPRINTF_(x)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define IDI_ICON 1
|
||||
|
||||
#define IDS_EXTRACTION_ERROR_TITLE 7
|
||||
#define IDS_EXTRACTION_ERROR_MESSAGE 8
|
||||
#define IDS_CANNOT_CREATE_FOLDER 3003
|
||||
#define IDS_PROGRESS_EXTRACTING 3300
|
||||
#define IDI_ICON 1
|
||||
|
||||
#define IDS_EXTRACTION_ERROR_TITLE 7
|
||||
#define IDS_EXTRACTION_ERROR_MESSAGE 8
|
||||
#define IDS_CANNOT_CREATE_FOLDER 3003
|
||||
#define IDS_PROGRESS_EXTRACTING 3300
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
#include "resource.h"
|
||||
|
||||
MY_VERSION_INFO_APP("7z Setup SFX", "7zS.sfx")
|
||||
|
||||
IDI_ICON ICON "setup.ico"
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_EXTRACTION_ERROR_TITLE "Extraction Failed"
|
||||
IDS_EXTRACTION_ERROR_MESSAGE "File is corrupt"
|
||||
IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'"
|
||||
IDS_PROGRESS_EXTRACTING "Extracting"
|
||||
END
|
||||
|
||||
#include "../../UI/FileManager/ProgressDialog.rc"
|
||||
#include "../../MyVersionInfo.rc"
|
||||
#include "resource.h"
|
||||
|
||||
MY_VERSION_INFO_APP("7z Setup SFX", "7zS.sfx")
|
||||
|
||||
IDI_ICON ICON "setup.ico"
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_EXTRACTION_ERROR_TITLE "Extraction Failed"
|
||||
IDS_EXTRACTION_ERROR_MESSAGE "File is corrupt"
|
||||
IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'"
|
||||
IDS_PROGRESS_EXTRACTING "Extracting"
|
||||
END
|
||||
|
||||
#include "../../UI/FileManager/ProgressDialog.rc"
|
||||
|
||||
Reference in New Issue
Block a user