mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
[SHELLEXT][ZIPFLDR] Implement ZIP creation (#2114)
This PR will implement *.ZFSendToTarget file type that will realize SendTo ZIP folder in future. CORE-16495, CORE-12562
This commit is contained in:
parent
62a95e4943
commit
962ff6e2fa
|
@ -28,6 +28,8 @@ list(APPEND SOURCE
|
|||
CExplorerCommand.cpp
|
||||
CEnumZipContents.cpp
|
||||
CFolderViewCB.cpp
|
||||
CSendToZip.cpp
|
||||
CZipCreater.cpp
|
||||
CZipEnumerator.hpp
|
||||
CZipExtract.cpp
|
||||
CZipFolder.hpp
|
||||
|
|
90
dll/shellext/zipfldr/CSendToZip.cpp
Normal file
90
dll/shellext/zipfldr/CSendToZip.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Zip Shell Extension
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: SendTo handler
|
||||
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
|
||||
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
STDMETHODIMP
|
||||
CSendToZip::DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt,
|
||||
DWORD *pdwEffect)
|
||||
{
|
||||
m_pDataObject = pDataObj;
|
||||
|
||||
FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||||
m_fCanDragDrop = SUCCEEDED(pDataObj->QueryGetData(&etc));
|
||||
|
||||
if (m_fCanDragDrop)
|
||||
*pdwEffect &= DROPEFFECT_COPY;
|
||||
else
|
||||
*pdwEffect = DROPEFFECT_NONE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CSendToZip::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
||||
{
|
||||
if (m_fCanDragDrop)
|
||||
*pdwEffect &= DROPEFFECT_COPY;
|
||||
else
|
||||
*pdwEffect = DROPEFFECT_NONE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CSendToZip::DragLeave()
|
||||
{
|
||||
m_fCanDragDrop = FALSE;
|
||||
m_pDataObject.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CSendToZip::Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt,
|
||||
DWORD *pdwEffect)
|
||||
{
|
||||
m_pDataObject = pDataObj;
|
||||
*pdwEffect &= DROPEFFECT_COPY;
|
||||
|
||||
if (!pDataObj || !m_fCanDragDrop || !*pdwEffect)
|
||||
{
|
||||
DPRINT1("Drop failed: %d %d %d\n",
|
||||
!pDataObj, !m_fCanDragDrop, !*pdwEffect);
|
||||
*pdwEffect = 0;
|
||||
DragLeave();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STGMEDIUM stg;
|
||||
FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||||
HRESULT hr = pDataObj->GetData(&etc, &stg);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
*pdwEffect = 0;
|
||||
DragLeave();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HDROP hDrop = reinterpret_cast<HDROP>(stg.hGlobal);
|
||||
UINT cItems = ::DragQueryFileW(hDrop, -1, NULL, 0);
|
||||
|
||||
CZipCreator *pCreater = CZipCreator::DoCreate();
|
||||
|
||||
for (UINT iItem = 0; iItem < cItems; ++iItem)
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
DragQueryFileW(hDrop, iItem, szPath, _countof(szPath));
|
||||
|
||||
pCreater->DoAddItem(szPath);
|
||||
}
|
||||
|
||||
::ReleaseStgMedium(&stg);
|
||||
|
||||
CZipCreator::runThread(pCreater); // pCreater is deleted in runThread
|
||||
|
||||
DragLeave();
|
||||
return hr;
|
||||
}
|
79
dll/shellext/zipfldr/CSendToZip.hpp
Normal file
79
dll/shellext/zipfldr/CSendToZip.hpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Zip Shell Extension
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: SendTo handler
|
||||
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
|
||||
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#ifndef CSENDTOZIP_HPP_
|
||||
#define CSENDTOZIP_HPP_
|
||||
|
||||
class CSendToZip :
|
||||
public CComCoClass<CSendToZip, &CLSID_ZipFolderSendTo>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IDropTarget,
|
||||
public IPersistFile
|
||||
{
|
||||
CComPtr<IDataObject> m_pDataObject;
|
||||
BOOL m_fCanDragDrop;
|
||||
|
||||
public:
|
||||
CSendToZip() : m_fCanDragDrop(FALSE)
|
||||
{
|
||||
InterlockedIncrement(&g_ModuleRefCnt);
|
||||
}
|
||||
|
||||
virtual ~CSendToZip()
|
||||
{
|
||||
InterlockedDecrement(&g_ModuleRefCnt);
|
||||
}
|
||||
|
||||
// *** IShellFolder2 methods ***
|
||||
STDMETHODIMP DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
||||
STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
||||
STDMETHODIMP DragLeave();
|
||||
STDMETHODIMP Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
||||
|
||||
// *** IPersistFile methods ***
|
||||
STDMETHODIMP IsDirty()
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// *** IPersist methods ***
|
||||
STDMETHODIMP GetClassID(CLSID *pclsid)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
public:
|
||||
DECLARE_NO_REGISTRY() // Handled manually
|
||||
DECLARE_NOT_AGGREGATABLE(CSendToZip)
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CSendToZip)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
|
||||
END_COM_MAP()
|
||||
};
|
||||
|
||||
#endif
|
358
dll/shellext/zipfldr/CZipCreater.cpp
Normal file
358
dll/shellext/zipfldr/CZipCreater.cpp
Normal file
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Zip Shell Extension
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Create a zip file
|
||||
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
|
||||
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include "atlsimpcoll.h"
|
||||
#include "minizip/zip.h"
|
||||
#include "minizip/iowin32.h"
|
||||
#include <process.h>
|
||||
|
||||
static CStringW DoGetZipName(LPCWSTR filename)
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
StringCbCopyW(szPath, sizeof(szPath), filename);
|
||||
PathRemoveExtensionW(szPath);
|
||||
|
||||
CStringW ret = szPath;
|
||||
ret += L".zip";
|
||||
|
||||
UINT i = 2;
|
||||
while (PathFileExistsW(ret))
|
||||
{
|
||||
CStringW str;
|
||||
str.Format(L" (%u).zip", i++);
|
||||
|
||||
ret = szPath;
|
||||
ret += str;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static CStringA DoGetAnsiName(LPCWSTR filename)
|
||||
{
|
||||
CHAR buf[MAX_PATH];
|
||||
WideCharToMultiByte(CP_ACP, 0, filename, -1, buf, _countof(buf), NULL, NULL);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static CStringW DoGetBaseName(LPCWSTR filename)
|
||||
{
|
||||
WCHAR szBaseName[MAX_PATH];
|
||||
StringCbCopyW(szBaseName, sizeof(szBaseName), filename);
|
||||
PathRemoveFileSpecW(szBaseName);
|
||||
PathAddBackslashW(szBaseName);
|
||||
return szBaseName;
|
||||
}
|
||||
|
||||
static CStringA
|
||||
DoGetNameInZip(const CStringW& basename, const CStringW& filename)
|
||||
{
|
||||
CStringW basenameI = basename, filenameI = filename;
|
||||
basenameI.MakeUpper();
|
||||
filenameI.MakeUpper();
|
||||
|
||||
CStringW ret;
|
||||
if (filenameI.Find(basenameI) == 0)
|
||||
ret = filename.Mid(basename.GetLength());
|
||||
else
|
||||
ret = filename;
|
||||
|
||||
ret.Replace(L'\\', L'/');
|
||||
|
||||
return DoGetAnsiName(ret);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
DoReadAllOfFile(LPCWSTR filename, CSimpleArray<BYTE>& contents,
|
||||
zip_fileinfo *pzi)
|
||||
{
|
||||
contents.RemoveAll();
|
||||
|
||||
HANDLE hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DPRINT1("%S: cannot open\n", filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FILETIME ft, ftLocal;
|
||||
ZeroMemory(pzi, sizeof(*pzi));
|
||||
if (GetFileTime(hFile, NULL, NULL, &ft))
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FileTimeToLocalFileTime(&ft, &ftLocal);
|
||||
FileTimeToSystemTime(&ftLocal, &st);
|
||||
pzi->tmz_date.tm_sec = st.wSecond;
|
||||
pzi->tmz_date.tm_min = st.wMinute;
|
||||
pzi->tmz_date.tm_hour = st.wHour;
|
||||
pzi->tmz_date.tm_mday = st.wDay;
|
||||
pzi->tmz_date.tm_mon = st.wMonth - 1;
|
||||
pzi->tmz_date.tm_year = st.wYear;
|
||||
}
|
||||
|
||||
const DWORD cbBuff = 0x7FFF;
|
||||
LPBYTE pbBuff = reinterpret_cast<LPBYTE>(CoTaskMemAlloc(cbBuff));
|
||||
if (!pbBuff)
|
||||
{
|
||||
DPRINT1("Out of memory\n");
|
||||
CloseHandle(hFile);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DWORD cbRead;
|
||||
if (!ReadFile(hFile, pbBuff, cbBuff, &cbRead, NULL) || !cbRead)
|
||||
break;
|
||||
|
||||
for (DWORD i = 0; i < cbRead; ++i)
|
||||
contents.Add(pbBuff[i]);
|
||||
}
|
||||
|
||||
CoTaskMemFree(pbBuff);
|
||||
CloseHandle(hFile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
DoAddFilesFromItem(CSimpleArray<CStringW>& files, LPCWSTR item)
|
||||
{
|
||||
if (!PathIsDirectoryW(item))
|
||||
{
|
||||
files.Add(item);
|
||||
return;
|
||||
}
|
||||
|
||||
WCHAR szPath[MAX_PATH];
|
||||
StringCbCopyW(szPath, sizeof(szPath), item);
|
||||
PathAppendW(szPath, L"*");
|
||||
|
||||
WIN32_FIND_DATAW find;
|
||||
HANDLE hFind = FindFirstFileW(szPath, &find);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
if (wcscmp(find.cFileName, L".") == 0 ||
|
||||
wcscmp(find.cFileName, L"..") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
StringCbCopyW(szPath, sizeof(szPath), item);
|
||||
PathAppendW(szPath, find.cFileName);
|
||||
|
||||
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
DoAddFilesFromItem(files, szPath);
|
||||
else
|
||||
files.Add(szPath);
|
||||
} while (FindNextFileW(hFind, &find));
|
||||
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
struct CZipCreatorImpl
|
||||
{
|
||||
CSimpleArray<CStringW> m_items;
|
||||
|
||||
unsigned JustDoIt();
|
||||
};
|
||||
|
||||
CZipCreator::CZipCreator() : m_pimpl(new CZipCreatorImpl)
|
||||
{
|
||||
InterlockedIncrement(&g_ModuleRefCnt);
|
||||
}
|
||||
|
||||
CZipCreator::~CZipCreator()
|
||||
{
|
||||
InterlockedDecrement(&g_ModuleRefCnt);
|
||||
delete m_pimpl;
|
||||
}
|
||||
|
||||
static unsigned __stdcall
|
||||
create_zip_function(void *arg)
|
||||
{
|
||||
CZipCreator *pCreater = reinterpret_cast<CZipCreator *>(arg);
|
||||
return pCreater->m_pimpl->JustDoIt();
|
||||
}
|
||||
|
||||
BOOL CZipCreator::runThread(CZipCreator *pCreater)
|
||||
{
|
||||
unsigned tid = 0;
|
||||
HANDLE hThread = reinterpret_cast<HANDLE>(
|
||||
_beginthreadex(NULL, 0, create_zip_function, pCreater, 0, &tid));
|
||||
|
||||
if (hThread)
|
||||
{
|
||||
CloseHandle(hThread);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DPRINT1("hThread == NULL\n");
|
||||
|
||||
CStringW strTitle(MAKEINTRESOURCEW(IDS_ERRORTITLE));
|
||||
CStringW strText(MAKEINTRESOURCEW(IDS_CANTSTARTTHREAD));
|
||||
MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
|
||||
|
||||
delete pCreater;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CZipCreator::DoAddItem(LPCWSTR pszFile)
|
||||
{
|
||||
// canonicalize path
|
||||
WCHAR szPath[MAX_PATH];
|
||||
GetFullPathNameW(pszFile, _countof(szPath), szPath, NULL);
|
||||
|
||||
m_pimpl->m_items.Add(szPath);
|
||||
}
|
||||
|
||||
enum CZC_ERROR
|
||||
{
|
||||
CZCERR_ZEROITEMS = 1,
|
||||
CZCERR_NOFILES,
|
||||
CZCERR_CREATE,
|
||||
CZCERR_READ
|
||||
};
|
||||
|
||||
unsigned CZipCreatorImpl::JustDoIt()
|
||||
{
|
||||
// TODO: Show progress.
|
||||
|
||||
if (m_items.GetSize() <= 0)
|
||||
{
|
||||
DPRINT1("GetSize() <= 0\n");
|
||||
return CZCERR_ZEROITEMS;
|
||||
}
|
||||
|
||||
CSimpleArray<CStringW> files;
|
||||
for (INT iItem = 0; iItem < m_items.GetSize(); ++iItem)
|
||||
{
|
||||
DoAddFilesFromItem(files, m_items[iItem]);
|
||||
}
|
||||
|
||||
if (files.GetSize() <= 0)
|
||||
{
|
||||
DPRINT1("files.GetSize() <= 0\n");
|
||||
|
||||
CStringW strTitle(MAKEINTRESOURCEW(IDS_ERRORTITLE));
|
||||
CStringW strText;
|
||||
strText.Format(IDS_NOFILES, static_cast<LPCWSTR>(m_items[0]));
|
||||
MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
|
||||
|
||||
return CZCERR_NOFILES;
|
||||
}
|
||||
|
||||
zlib_filefunc64_def ffunc;
|
||||
fill_win32_filefunc64W(&ffunc);
|
||||
|
||||
CStringW strZipName = DoGetZipName(m_items[0]);
|
||||
zipFile zf = zipOpen2_64(strZipName, APPEND_STATUS_CREATE, NULL, &ffunc);
|
||||
if (zf == 0)
|
||||
{
|
||||
DPRINT1("zf == 0\n");
|
||||
|
||||
int err = CZCERR_CREATE;
|
||||
|
||||
CStringW strTitle(MAKEINTRESOURCEW(IDS_ERRORTITLE));
|
||||
CStringW strText;
|
||||
strText.Format(IDS_CANTCREATEZIP, static_cast<LPCWSTR>(strZipName), err);
|
||||
MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// TODO: password
|
||||
const char *password = NULL;
|
||||
int zip64 = 1; // always zip64
|
||||
zip_fileinfo zi;
|
||||
|
||||
int err = 0;
|
||||
CStringW strTarget, strBaseName = DoGetBaseName(m_items[0]);
|
||||
for (INT iFile = 0; iFile < files.GetSize(); ++iFile)
|
||||
{
|
||||
const CStringW& strFile = files[iFile];
|
||||
|
||||
CSimpleArray<BYTE> contents;
|
||||
if (!DoReadAllOfFile(strFile, contents, &zi))
|
||||
{
|
||||
DPRINT1("DoReadAllOfFile failed\n");
|
||||
err = CZCERR_READ;
|
||||
strTarget = strFile;
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned long crc = 0;
|
||||
if (password)
|
||||
{
|
||||
// TODO: crc = ...;
|
||||
}
|
||||
|
||||
CStringA strNameInZip = DoGetNameInZip(strBaseName, strFile);
|
||||
err = zipOpenNewFileInZip3_64(zf,
|
||||
strNameInZip,
|
||||
&zi,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
Z_DEFLATED,
|
||||
Z_DEFAULT_COMPRESSION,
|
||||
0,
|
||||
-MAX_WBITS,
|
||||
DEF_MEM_LEVEL,
|
||||
Z_DEFAULT_STRATEGY,
|
||||
password,
|
||||
crc,
|
||||
zip64);
|
||||
if (err)
|
||||
{
|
||||
DPRINT1("zipOpenNewFileInZip3_64\n");
|
||||
break;
|
||||
}
|
||||
|
||||
err = zipWriteInFileInZip(zf, contents.GetData(), contents.GetSize());
|
||||
if (err)
|
||||
{
|
||||
DPRINT1("zipWriteInFileInZip\n");
|
||||
break;
|
||||
}
|
||||
|
||||
err = zipCloseFileInZip(zf);
|
||||
if (err)
|
||||
{
|
||||
DPRINT1("zipCloseFileInZip\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zipClose(zf, NULL);
|
||||
|
||||
if (err)
|
||||
{
|
||||
DeleteFileW(strZipName);
|
||||
|
||||
CStringW strTitle(MAKEINTRESOURCEW(IDS_ERRORTITLE));
|
||||
|
||||
CStringW strText;
|
||||
if (err < 0)
|
||||
strText.Format(IDS_CANTCREATEZIP, static_cast<LPCWSTR>(strZipName), err);
|
||||
else
|
||||
strText.Format(IDS_CANTREADFILE, static_cast<LPCWSTR>(strTarget));
|
||||
|
||||
MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
32
dll/shellext/zipfldr/CZipCreater.hpp
Normal file
32
dll/shellext/zipfldr/CZipCreater.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Zip Shell Extension
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Create a zip file
|
||||
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
|
||||
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
#ifndef CZIPCREATER_HPP_
|
||||
#define CZIPCREATER_HPP_
|
||||
|
||||
struct CZipCreatorImpl;
|
||||
|
||||
class CZipCreator
|
||||
{
|
||||
public:
|
||||
struct CZipCreatorImpl *m_pimpl;
|
||||
|
||||
virtual ~CZipCreator();
|
||||
|
||||
static CZipCreator* DoCreate()
|
||||
{
|
||||
return new CZipCreator();
|
||||
}
|
||||
|
||||
virtual void DoAddItem(LPCWSTR pszFile);
|
||||
static BOOL runThread(CZipCreator* pCreater);
|
||||
|
||||
protected:
|
||||
CZipCreator();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Änderungsdatum"
|
||||
IDS_YES "Ja"
|
||||
IDS_NO "Nein"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Extrahier-Assistent"
|
||||
IDS_WIZ_DEST_TITLE "Ziel auswählen"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Date modified"
|
||||
IDS_YES "Yes"
|
||||
IDS_NO "No"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Extraction Wizard"
|
||||
IDS_WIZ_DEST_TITLE "Select a Destination"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Kuupäeval muudetud"
|
||||
IDS_YES "Jah"
|
||||
IDS_NO "Ei"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Ekstraktimise visard"
|
||||
IDS_WIZ_DEST_TITLE "Vali sihtkoht"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Date de modification"
|
||||
IDS_YES "Oui"
|
||||
IDS_NO "Non"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Assistant d'extraction"
|
||||
IDS_WIZ_DEST_TITLE "Choisir une destination"
|
||||
|
|
|
@ -55,6 +55,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "तिथि संशोधित"
|
||||
IDS_YES "हाँ"
|
||||
IDS_NO "नहीं"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "निष्कर्षण विज़ार्ड"
|
||||
IDS_WIZ_DEST_TITLE "एक गंतव्य चुनें"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Data modificata"
|
||||
IDS_YES "Sì"
|
||||
IDS_NO "No"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Estrazione Guidata"
|
||||
IDS_WIZ_DEST_TITLE "Seleziona una Destinazione"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "変更日"
|
||||
IDS_YES "はい"
|
||||
IDS_NO "いいえ"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "展開ウィザード"
|
||||
IDS_WIZ_DEST_TITLE "展開先を選んで下さい"
|
||||
|
|
|
@ -67,6 +67,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Data modyfikacji"
|
||||
IDS_YES "Tak"
|
||||
IDS_NO "Nie"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Kreator wyodrębniania"
|
||||
IDS_WIZ_DEST_TITLE "Wybierz miejsce docelowe"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Data modificată"
|
||||
IDS_YES "Da"
|
||||
IDS_NO "Nu"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Asistent de extracție"
|
||||
IDS_WIZ_DEST_TITLE "Selectați o Destinație"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Дата изменения"
|
||||
IDS_YES "Да"
|
||||
IDS_NO "Нет"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Мастер извлечения архивов"
|
||||
IDS_WIZ_DEST_TITLE "Укажите путь"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "Ändrad den"
|
||||
IDS_YES "Ja"
|
||||
IDS_NO "Nej"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "Extraheringsguiden"
|
||||
IDS_WIZ_DEST_TITLE "Välj ett mål"
|
||||
|
|
|
@ -68,6 +68,11 @@ BEGIN
|
|||
IDS_COL_DATE_MOD "修改日期"
|
||||
IDS_YES "是"
|
||||
IDS_NO "否"
|
||||
IDS_ERRORTITLE "Compressed (zipped) Folders Error"
|
||||
IDS_CANTSTARTTHREAD "Cannot start thread to compress files."
|
||||
IDS_NOFILES "The specified directory '%s' is empty, so Compressed (zipped) Folders cannot add it to the archive."
|
||||
IDS_CANTCREATEZIP "Failed to create a compressed folder '%s' (Error Code: %d)."
|
||||
IDS_CANTREADFILE "Cannot read file '%s'."
|
||||
|
||||
IDS_WIZ_TITLE "解压向导"
|
||||
IDS_WIZ_DEST_TITLE "选择一个目标文件夹"
|
||||
|
|
|
@ -78,5 +78,7 @@ eZipConfirmResponse _CZipAskReplace(HWND hDlg, const char* FullPath);
|
|||
|
||||
#include "CZipEnumerator.hpp"
|
||||
#include "CZipFolder.hpp"
|
||||
#include "CZipCreater.hpp"
|
||||
#include "CSendToZip.hpp"
|
||||
|
||||
#endif /* ZIPFLDR_PRECOMP_H */
|
||||
|
|
|
@ -12,10 +12,26 @@ HKCR
|
|||
val UseDropHandler = s ''
|
||||
}
|
||||
}
|
||||
'{b8cdcb65-b1bf-4b42-9428-1dfdb7ee92af}' = s 'Compressed (zipped) Folder Menu'
|
||||
'{B8CDCB65-B1BF-4B42-9428-1DFDB7EE92AF}' = s 'Compressed (zipped) Folder Menu'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{888DCA60-FC0A-11CF-8F0F-00C04FD7D062}' = s 'Compressed (zipped) Folder SendTo Target'
|
||||
{
|
||||
val EditFlags = d '0x01'
|
||||
val FriendlyTypeName = s '%MODULE%,-10226'
|
||||
val NeverShowExt = s ''
|
||||
val NoOpen = s 'Drag Files onto this icon to compress them.'
|
||||
DefaultIcon = s '%MODULE%' { }
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
ShellEx
|
||||
{
|
||||
DropHandler = s '{888DCA60-FC0A-11CF-8F0F-00C04FD7D062}' { }
|
||||
}
|
||||
}
|
||||
}
|
||||
NoRemove Applications
|
||||
{
|
||||
|
@ -24,7 +40,7 @@ HKCR
|
|||
NoRemove CompressedFolder
|
||||
{
|
||||
FriendlyTypeName = s '%MODULE%,-10195'
|
||||
CLSID = s '{E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31}'
|
||||
CLSID = s '{E88DCCE0-B7B3-11D1-A9F0-00AA0060FA31}'
|
||||
DefaultIcon = s '%MODULE%'
|
||||
|
||||
NoRemove Shell
|
||||
|
@ -41,7 +57,7 @@ HKCR
|
|||
{
|
||||
NoRemove ContextMenuHandlers
|
||||
{
|
||||
ForceRemove '{b8cdcb65-b1bf-4b42-9428-1dfdb7ee92af}' = s 'Compressed (zipped) Folder Menu'
|
||||
ForceRemove '{B8CDCB65-B1BF-4B42-9428-1DFDB7EE92AF}' = s 'Compressed (zipped) Folder Menu'
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -52,3 +68,13 @@ HKCR
|
|||
val 'Content Type' = s 'application/x-zip-compressed'
|
||||
}
|
||||
}
|
||||
HKLM
|
||||
{
|
||||
NoRemove Software
|
||||
{
|
||||
NoRemove Classes
|
||||
{
|
||||
'.ZFSendToTarget' = s 'CLSID\{888DCA60-FC0A-11CF-8F0F-00C04FD7D062}'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,11 @@
|
|||
#define IDS_COL_DATE_MOD 106
|
||||
#define IDS_YES 107
|
||||
#define IDS_NO 108
|
||||
|
||||
#define IDS_ERRORTITLE 109
|
||||
#define IDS_CANTSTARTTHREAD 110
|
||||
#define IDS_NOFILES 111
|
||||
#define IDS_CANTCREATEZIP 112
|
||||
#define IDS_CANTREADFILE 113
|
||||
|
||||
/* Wizard titles */
|
||||
#define IDS_WIZ_TITLE 8000
|
||||
|
|
|
@ -31,6 +31,7 @@ public:
|
|||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
OBJECT_ENTRY(CLSID_ZipFolderStorageHandler, CZipFolder)
|
||||
OBJECT_ENTRY(CLSID_ZipFolderContextMenu, CZipFolder)
|
||||
OBJECT_ENTRY(CLSID_ZipFolderSendTo, CSendToZip)
|
||||
END_OBJECT_MAP()
|
||||
|
||||
CZipFldrModule gModule;
|
||||
|
|
Loading…
Reference in a new issue