Skip to content

Commit

Permalink
[ZIPFLDR] Allow the shell extension to extract passworded zip files
Browse files Browse the repository at this point in the history
  • Loading branch information
learn-more committed Mar 6, 2019
1 parent a672665 commit 08deb1d
Show file tree
Hide file tree
Showing 17 changed files with 352 additions and 22 deletions.
1 change: 1 addition & 0 deletions dll/shellext/zipfldr/CMakeLists.txt
Expand Up @@ -31,6 +31,7 @@ list(APPEND SOURCE
CZipEnumerator.hpp
CZipExtract.cpp
CZipFolder.hpp
CZipPassword.cpp
Debug.cpp
zipfldr.spec
precomp.h
Expand Down
63 changes: 55 additions & 8 deletions dll/shellext/zipfldr/CZipExtract.cpp
Expand Up @@ -2,7 +2,7 @@
* PROJECT: ReactOS Zip Shell Extension
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Zip extraction
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
* COPYRIGHT: Copyright 2017-2019 Mark Jansen (mark.jansen@reactos.org)
*/

#include "precomp.h"
Expand All @@ -12,6 +12,7 @@ class CZipExtract :
{
CStringW m_Filename;
CStringW m_Directory;
CStringA m_Password;
bool m_DirectoryChanged;
unzFile uf;
public:
Expand Down Expand Up @@ -70,11 +71,13 @@ class CZipExtract :
{
private:
CZipExtract* m_pExtract;
CStringA* m_pPassword;

public:
CExtractSettingsPage(CZipExtract* extract)
CExtractSettingsPage(CZipExtract* extract, CStringA* password)
:CPropertyPageImpl<CExtractSettingsPage>(MAKEINTRESOURCE(IDS_WIZ_TITLE))
,m_pExtract(extract)
,m_pPassword(password)
{
m_psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_WIZ_DEST_TITLE);
m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_WIZ_DEST_SUBTITLE);
Expand All @@ -85,7 +88,6 @@ class CZipExtract :
{
SetDlgItemTextW(IDC_DIRECTORY, m_pExtract->m_Directory);
m_pExtract->m_DirectoryChanged = false;
::EnableWindow(GetDlgItem(IDC_PASSWORD), FALSE); /* Not supported for now */
GetParent().CenterWindow(::GetDesktopWindow());
SetWizardButtons(PSWIZB_NEXT);
return 0;
Expand All @@ -108,7 +110,7 @@ class CZipExtract :

::EnableWindow(GetDlgItem(IDC_BROWSE), TRUE);
::EnableWindow(GetDlgItem(IDC_DIRECTORY), TRUE);
::EnableWindow(GetDlgItem(IDC_PASSWORD), FALSE); /* Not supported for now */
::EnableWindow(GetDlgItem(IDC_PASSWORD), TRUE);
SetWizardButtons(PSWIZB_NEXT);

return TRUE;
Expand Down Expand Up @@ -171,6 +173,11 @@ class CZipExtract :

LRESULT OnPassword(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
CStringA Password;
if (_CZipAskPassword(m_hWnd, NULL, Password) == eAccept)
{
*m_pPassword = Password;
}
return 0;
}

Expand Down Expand Up @@ -247,7 +254,7 @@ class CZipExtract :
psh.dwFlags = PSH_WIZARD97 | PSH_HEADER;
psh.hInstance = _AtlBaseModule.GetResourceInstance();

CExtractSettingsPage extractPage(this);
CExtractSettingsPage extractPage(this, &m_Password);
CCompleteSettingsPage completePage(this);
HPROPSHEETPAGE hpsp[] =
{
Expand Down Expand Up @@ -288,6 +295,7 @@ class CZipExtract :
BYTE Buffer[2048];
CStringA BaseDirectory = m_Directory;
CStringA Name;
CStringA Password = m_Password;
unz_file_info64 Info;
int CurrentFile = 0;
bool bOverwriteAll = false;
Expand All @@ -310,9 +318,48 @@ class CZipExtract :
if (is_dir)
continue;

const char* password = NULL;
/* FIXME: Process password, if required and not specified, prompt the user */
err = unzOpenCurrentFilePassword(uf, password);
if (Info.flag & MINIZIP_PASSWORD_FLAG)
{
eZipPasswordResponse Response = eAccept;
do
{
/* If there is a password set, try it */
if (!Password.IsEmpty())
{
err = unzOpenCurrentFilePassword(uf, Password);
if (err == UNZ_OK)
{
/* Try to read some bytes, because unzOpenCurrentFilePassword does not return failure */
char Buf[10];
err = unzReadCurrentFile(uf, Buf, sizeof(Buf));
unzCloseCurrentFile(uf);
if (err >= UNZ_OK)
{
/* 're'-open the file so that we can begin to extract */
err = unzOpenCurrentFilePassword(uf, Password);
break;
}
}
}
Response = _CZipAskPassword(hDlg, Name, Password);
} while (Response == eAccept);

if (Response == eSkip)
{
Progress.SendMessage(PBM_SETPOS, CurrentFile, 0);
continue;
}
else if (Response == eAbort)
{
Close();
return false;
}
}
else
{
err = unzOpenCurrentFile(uf);
}

if (err != UNZ_OK)
{
DPRINT1("ERROR, unzOpenCurrentFilePassword: 0x%x\n", err);
Expand Down
91 changes: 91 additions & 0 deletions dll/shellext/zipfldr/CZipPassword.cpp
@@ -0,0 +1,91 @@
/*
* PROJECT: ReactOS Zip Shell Extension
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Ask the user for a password
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
*/

#include "precomp.h"

class CZipPassword : public CDialogImpl<CZipPassword>
{
private:
CStringA m_Filename;
CStringA* m_pPassword;
public:
CZipPassword(const char* filename, CStringA* Password)
:m_pPassword(Password)
{
if (filename != NULL)
m_Filename = filename;
}

LRESULT OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
CenterWindow(GetParent());

/* No filename, so this is the question before starting to extract */
if (m_Filename.IsEmpty())
{
CStringA message(MAKEINTRESOURCE(IDS_PASSWORD_ZIP_TEXT));
::SetDlgItemTextA(m_hWnd, IDC_MESSAGE, message);
::ShowWindow(GetDlgItem(IDSKIP), SW_HIDE);
}
else
{
/* Our CString does not support FormatMessage yet */
CStringA message(MAKEINTRESOURCE(IDS_PASSWORD_FILE_TEXT));
CHeapPtr<CHAR, CLocalAllocator> formatted;

DWORD_PTR args[2] =
{
(DWORD_PTR)m_Filename.GetString(),
NULL
};

::FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY,
message, 0, 0, (LPSTR)&formatted, 0, (va_list*)args);

::SetDlgItemTextA(m_hWnd, IDC_MESSAGE, formatted);
}
return TRUE;
}

LRESULT OnButton(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
if (wID == IDOK)
{
HWND item = GetDlgItem(IDC_PASSWORD);
int len = ::GetWindowTextLengthA(item);
len = ::GetDlgItemTextA(m_hWnd, IDC_PASSWORD, m_pPassword->GetBuffer(len+1), len+1);
m_pPassword->ReleaseBuffer(len);
}
EndDialog(wID);
return 0;
}

public:
enum { IDD = IDD_PASSWORD };

BEGIN_MSG_MAP(CZipPassword)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_ID_HANDLER(IDOK, OnButton)
COMMAND_ID_HANDLER(IDSKIP, OnButton)
COMMAND_ID_HANDLER(IDCANCEL, OnButton)
END_MSG_MAP()
};

eZipPasswordResponse _CZipAskPassword(HWND hDlg, const char* filename, CStringA& Password)
{
if (filename)
filename = PathFindFileNameA(filename);
CZipPassword password(filename, &Password);
INT_PTR Result = password.DoModal(hDlg);
switch (Result)
{
case IDOK: return eAccept;
case IDSKIP: return eSkip;
default:
case IDCANCEL: return eAbort;
}
}
17 changes: 16 additions & 1 deletion dll/shellext/zipfldr/lang/de-DE.rc
Expand Up @@ -37,13 +37,26 @@ CAPTION "Ersetzen von Dateien bestätigen"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "&Ja",IDYES,6,36,62,14
PUSHBUTTON "Abbrechen",IDCANCEL,204,36,62,14
PUSHBUTTON "Alle",IDYESALL,72,36,62,14
PUSHBUTTON "&Nein",IDNO,138,36,62,14
PUSHBUTTON "Abbrechen",IDCANCEL,204,36,62,14
ICON "",IDC_EXCLAMATION_ICON,6,6,24,22
LTEXT "",IDC_MESSAGE,36,6,228,24
END

IDD_PASSWORD DIALOGEX 0, 0, 243, 62
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Password needed"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_PASSWORD,72,42,108,13,ES_PASSWORD | ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,186,6,50,14
PUSHBUTTON "Skip File",IDSKIP,186,24,50,14
PUSHBUTTON "Cancel",IDCANCEL,186,42,50,14
LTEXT "Static",IDC_MESSAGE,24,6,156,30
LTEXT "Password:",IDC_STATIC,24,44,44,8
END

STRINGTABLE
BEGIN
IDS_COL_NAME "Name"
Expand All @@ -64,6 +77,8 @@ BEGIN
IDS_WIZ_BROWSE_TITLE "Wählen Sie ein Ziel zum Extrahieren der Dateien."

IDS_OVERWRITEFILE_TEXT "Dieser Ordner enthält bereits eine Datei '%1'.\nMöchten Sie die existierende Datei ersetzen?"
IDS_PASSWORD_FILE_TEXT "The file '%1' is password protected. Please enter the password."
IDS_PASSWORD_ZIP_TEXT "Please specify the password to use when extracting this zip file."

IDS_MENUITEM "&Alle Extrahieren..."
IDS_HELPTEXT "Ordnerinhalt extrahieren"
Expand Down
19 changes: 17 additions & 2 deletions dll/shellext/zipfldr/lang/en-US.rc
Expand Up @@ -2,7 +2,7 @@
* PROJECT: ReactOS Zip Shell Extension
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: English (United States) resource translation
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
* COPYRIGHT: Copyright 2017-2019 Mark Jansen (mark.jansen@reactos.org)
*/

LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
Expand Down Expand Up @@ -37,13 +37,26 @@ CAPTION "Confirm File Replace"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "&Yes",IDYES,6,36,62,14
PUSHBUTTON "Cancel",IDCANCEL,204,36,62,14
PUSHBUTTON "Yes &To All",IDYESALL,72,36,62,14
PUSHBUTTON "&No",IDNO,138,36,62,14
PUSHBUTTON "Cancel",IDCANCEL,204,36,62,14
ICON "",IDC_EXCLAMATION_ICON,6,6,24,22
LTEXT "",IDC_MESSAGE,36,6,228,24
END

IDD_PASSWORD DIALOGEX 0, 0, 243, 62
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Password needed"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_PASSWORD,72,42,108,13,ES_PASSWORD | ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,186,6,50,14
PUSHBUTTON "Skip File",IDSKIP,186,24,50,14
PUSHBUTTON "Cancel",IDCANCEL,186,42,50,14
LTEXT "Static",IDC_MESSAGE,24,6,156,30
LTEXT "Password:",IDC_STATIC,24,44,44,8
END

STRINGTABLE
BEGIN
IDS_COL_NAME "Name"
Expand All @@ -64,6 +77,8 @@ BEGIN
IDS_WIZ_BROWSE_TITLE "Select the place where you want to extract the selected items."

IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\nDo you want to replace it?"
IDS_PASSWORD_FILE_TEXT "The file '%1' is password protected. Please enter the password."
IDS_PASSWORD_ZIP_TEXT "Please specify the password to use when extracting this zip file."

IDS_MENUITEM "Extract &All..."
IDS_HELPTEXT "Extracts folder contents"
Expand Down
17 changes: 16 additions & 1 deletion dll/shellext/zipfldr/lang/et-EE.rc
Expand Up @@ -37,13 +37,26 @@ CAPTION "Kinnita faili ülekirjutus"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "&Jah",IDYES,6,36,62,14
PUSHBUTTON "Loobu",IDCANCEL,204,36,62,14
PUSHBUTTON "Jah &kõigile",IDYESALL,72,36,62,14
PUSHBUTTON "&Ei",IDNO,138,36,62,14
PUSHBUTTON "Loobu",IDCANCEL,204,36,62,14
ICON "",IDC_EXCLAMATION_ICON,6,6,24,22
LTEXT "",IDC_MESSAGE,36,6,228,24
END

IDD_PASSWORD DIALOGEX 0, 0, 243, 62
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Password needed"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_PASSWORD,72,42,108,13,ES_PASSWORD | ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,186,6,50,14
PUSHBUTTON "Skip File",IDSKIP,186,24,50,14
PUSHBUTTON "Cancel",IDCANCEL,186,42,50,14
LTEXT "Static",IDC_MESSAGE,24,6,156,30
LTEXT "Password:",IDC_STATIC,24,44,44,8
END

STRINGTABLE
BEGIN
IDS_COL_NAME "Nimi"
Expand All @@ -64,6 +77,8 @@ BEGIN
IDS_WIZ_BROWSE_TITLE "Vali koht kuhu soovid ekstraktida valitud üksused."

IDS_OVERWRITEFILE_TEXT "See kaust juba sisaldab faili nimega '%1'.\nKas tahad seda asendada?"
IDS_PASSWORD_FILE_TEXT "The file '%1' is password protected. Please enter the password."
IDS_PASSWORD_ZIP_TEXT "Please specify the password to use when extracting this zip file."

IDS_MENUITEM "Ekstrakti &kõik..."
IDS_HELPTEXT "Ekstraktib kausta sisu"
Expand Down
17 changes: 16 additions & 1 deletion dll/shellext/zipfldr/lang/fr-FR.rc
Expand Up @@ -37,13 +37,26 @@ CAPTION "Confirmer le remplacement de fichier"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "&Oui",IDYES,6,36,62,14
PUSHBUTTON "Annuler",IDCANCEL,204,36,62,14
PUSHBUTTON "Oui à &tous",IDYESALL,72,36,62,14
PUSHBUTTON "&Non",IDNO,138,36,62,14
PUSHBUTTON "Annuler",IDCANCEL,204,36,62,14
ICON "",IDC_EXCLAMATION_ICON,6,6,24,22
LTEXT "",IDC_MESSAGE,36,6,228,24
END

IDD_PASSWORD DIALOGEX 0, 0, 243, 62
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Password needed"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_PASSWORD,72,42,108,13,ES_PASSWORD | ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,186,6,50,14
PUSHBUTTON "Skip File",IDSKIP,186,24,50,14
PUSHBUTTON "Cancel",IDCANCEL,186,42,50,14
LTEXT "Static",IDC_MESSAGE,24,6,156,30
LTEXT "Password:",IDC_STATIC,24,44,44,8
END

STRINGTABLE
BEGIN
IDS_COL_NAME "Nom"
Expand All @@ -64,6 +77,8 @@ BEGIN
IDS_WIZ_BROWSE_TITLE "Choisissez l'endroit où vous voulez extraits les éléments sélectionnés."

IDS_OVERWRITEFILE_TEXT "Ce répertoire contient déjà un fichier nommé '%1'.\nVoulez-vous le remplacer ?"
IDS_PASSWORD_FILE_TEXT "The file '%1' is password protected. Please enter the password."
IDS_PASSWORD_ZIP_TEXT "Please specify the password to use when extracting this zip file."

IDS_MENUITEM "&Tout extraire..."
IDS_HELPTEXT "Extrait le contenu du répertoire"
Expand Down

0 comments on commit 08deb1d

Please sign in to comment.