1 /*
2  * PROJECT:     ReactOS Zip Shell Extension
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Ask the user for a password
5  * COPYRIGHT:   Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 class CZipPassword : public CDialogImpl<CZipPassword>
11 {
12 private:
13     CStringA m_Filename;
14     CStringA* m_pPassword;
15 public:
16     CZipPassword(const char* filename, CStringA* Password)
17         :m_pPassword(Password)
18     {
19         if (filename != NULL)
20             m_Filename = filename;
21     }
22 
23     LRESULT OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
24     {
25         CenterWindow(GetParent());
26 
27         /* No filename, so this is the question before starting to extract */
28         if (m_Filename.IsEmpty())
29         {
30             CStringA message(MAKEINTRESOURCE(IDS_PASSWORD_ZIP_TEXT));
31             ::SetDlgItemTextA(m_hWnd, IDC_MESSAGE, message);
32             ::ShowWindow(GetDlgItem(IDSKIP), SW_HIDE);
33         }
34         else
35         {
36             /* Our CString does not support FormatMessage yet */
37             CStringA message(MAKEINTRESOURCE(IDS_PASSWORD_FILE_TEXT));
38             CHeapPtr<CHAR, CLocalAllocator> formatted;
39 
40             DWORD_PTR args[2] =
41             {
42                 (DWORD_PTR)m_Filename.GetString(),
43                 NULL
44             };
45 
46             ::FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY,
47                              message, 0, 0, (LPSTR)&formatted, 0, (va_list*)args);
48 
49             ::SetDlgItemTextA(m_hWnd, IDC_MESSAGE, formatted);
50         }
51         return TRUE;
52     }
53 
54     LRESULT OnButton(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
55     {
56         if (wID == IDOK)
57         {
58             HWND item = GetDlgItem(IDC_PASSWORD);
59             int len = ::GetWindowTextLengthA(item);
60             len = ::GetDlgItemTextA(m_hWnd, IDC_PASSWORD, m_pPassword->GetBuffer(len+1), len+1);
61             m_pPassword->ReleaseBuffer(len);
62         }
63         EndDialog(wID);
64         return 0;
65     }
66 
67 public:
68     enum { IDD = IDD_PASSWORD };
69 
70     BEGIN_MSG_MAP(CZipPassword)
71         MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
72         COMMAND_ID_HANDLER(IDOK, OnButton)
73         COMMAND_ID_HANDLER(IDSKIP, OnButton)
74         COMMAND_ID_HANDLER(IDCANCEL, OnButton)
75     END_MSG_MAP()
76 };
77 
78 eZipPasswordResponse _CZipAskPassword(HWND hDlg, const char* filename, CStringA& Password)
79 {
80     if (filename)
81         filename = PathFindFileNameA(filename);
82     CZipPassword password(filename, &Password);
83     INT_PTR Result = password.DoModal(hDlg);
84     switch (Result)
85     {
86     case IDOK: return eAccept;
87     case IDSKIP: return eSkip;
88     default:
89     case IDCANCEL: return eAbort;
90     }
91 }
92