1 /*
2  * PROJECT:     ReactOS Applications
3  * LICENSE:     LGPL - See COPYING in the top level directory
4  * FILE:        base/applications/msconfig_new/fileextractdialog.c
5  * PURPOSE:     File Extract Dialog
6  * COPYRIGHT:   Copyright 2011-2012 Hermes BELUSCA - MAITO <hermes.belusca@sfr.fr>
7  */
8 
9 #include "precomp.h"
10 
11 #include <wingdi.h>
12 #include <commdlg.h> // It needs stuff defined in wingdi.h ...
13 #undef LF_FACESIZE   // but wingdi.h defines LF_FACESIZE, and if LF_FACESIZE is defined ...
14 #include <shlobj.h>  // shlobj.h wants to define NT_CONSOLE_PROPS which needs COORD structure
15                      // to be declared, this means, including wincon.h in a GUI app!!
16                      // WTF!! I don't want that!!
17 
18 // #include <setupapi.h>
19 #include "fileextractdialog.h"
20 #include "comctl32supp.h"
21 #include "utils.h"
22 
23 // #include "callbacks.h"
24 
25 // FIXME: This should be present in PSDK commdlg.h
26 //
27 // FlagsEx Values
28 #if (_WIN32_WINNT >= 0x0500)
29 #define  OFN_EX_NOPLACESBAR         0x00000001
30 #endif // (_WIN32_WINNT >= 0x0500)
31 
32 
33 VOID
34 AddStringToComboList(HWND hWnd,
35                      LPCWSTR lpszString)
36 {
37     /* Try to find an already existing occurrence of the string in the list */
38     LRESULT hPos = ComboBox_FindStringExact(hWnd, -1, lpszString);
39 
40     if (hPos == CB_ERR)
41     {
42         /* The string doesn't exist, so add it to the list and select it */
43         ComboBox_InsertString(hWnd, 0, lpszString);
44         ComboBox_SetCurSel(hWnd, 0);
45     }
46     else
47     {
48         /* The string exists, so select it */
49         ComboBox_SetCurSel(hWnd, hPos);
50     }
51 
52     return;
53 }
54 
55 INT_PTR CALLBACK
56 FileExtractDialogWndProc(HWND hDlg,
57                          UINT message,
58                          WPARAM wParam,
59                          LPARAM lParam)
60 {
61     UNREFERENCED_PARAMETER(lParam);
62 
63     switch (message)
64     {
65         case WM_INITDIALOG:
66             return TRUE;
67 
68         case WM_COMMAND:
69         {
70             switch (LOWORD(wParam))
71             {
72                 case IDOK:
73                 {
74                     LPWSTR szCabPathFileName, szFileName, szDestDir;
75                     size_t cabPathNum, fileNameNum, destDirNum;
76 
77                     cabPathNum = GetWindowTextLengthW(GetDlgItem(hDlg, IDC_DRP_CAB_FILE)) + 1;
78                     szCabPathFileName = (LPWSTR)MemAlloc(0, cabPathNum * sizeof(WCHAR));
79                     GetDlgItemText(hDlg, IDC_DRP_CAB_FILE, szCabPathFileName, (int)cabPathNum);
80 
81                     fileNameNum = GetWindowTextLengthW(GetDlgItem(hDlg, IDC_TXT_FILE_TO_RESTORE)) + 1;
82                     szFileName = (LPWSTR)MemAlloc(0, fileNameNum * sizeof(WCHAR));
83                     GetDlgItemText(hDlg, IDC_TXT_FILE_TO_RESTORE, szFileName, (int)fileNameNum);
84 
85                     destDirNum = GetWindowTextLengthW(GetDlgItem(hDlg, IDC_DRP_DEST_DIR)) + 1;
86                     szDestDir = (LPWSTR)MemAlloc(0, destDirNum * sizeof(WCHAR));
87                     GetDlgItemText(hDlg, IDC_DRP_DEST_DIR, szDestDir, (int)destDirNum);
88 
89 #if 0
90                     if (!ExtractFromCabinet(szCabPathFileName, szFileName, szDestDir))
91                     {
92                         MessageBoxW(NULL, L"An error has occurred!!", L"Error", MB_ICONERROR | MB_OK);
93                     }
94                     else
95                     {
96                         MessageBoxW(NULL, L"All the files were uncompressed successfully.", L"Info", MB_ICONINFORMATION | MB_OK);
97 
98                         // TODO: Save the extraction paths into the registry.
99 
100                         /* Quit */
101                         EndDialog(hDlg, LOWORD(wParam));
102                     }
103 #else
104                     MessageBoxW(NULL, L"File extraction is unimplemented!", L"Info", MB_ICONINFORMATION | MB_OK);
105 #endif
106 
107                     MemFree(szDestDir);
108                     MemFree(szFileName);
109                     MemFree(szCabPathFileName);
110 
111                     return TRUE;
112                 }
113 
114                 case IDCANCEL:
115                     EndDialog(hDlg, LOWORD(wParam));
116                     return TRUE;
117 
118                 case IDC_BTN_BROWSE_ALL_FILES:
119                 {
120                     unsigned int nMaxFilesNum = 255;
121                     size_t newSize = (nMaxFilesNum * (MAX_PATH + 1)) + 1;
122                     LPWSTR szPath  = (LPWSTR)MemAlloc(HEAP_ZERO_MEMORY, newSize * sizeof(WCHAR));
123                     OPENFILENAMEW ofn;
124 
125                     SecureZeroMemory(&ofn, sizeof(ofn));
126                     ofn.lStructSize = sizeof(ofn);
127                     ofn.hwndOwner   = hDlg;
128                     ofn.lpstrTitle  = L"Files to be restored"; // L"Fichiers � restaurer"; // FIXME: Localize!
129                     ofn.Flags       = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_LONGNAMES;
130                     // ofn.FlagsEx     = OFN_EX_NOPLACESBAR;
131                     ofn.lpstrFilter = L"All files (*.*)\0*.*\0";
132                     ofn.nFilterIndex = 0;
133                     ofn.lpstrFile   = szPath;
134                     ofn.nMaxFile    = (DWORD)newSize; // TODO: size_t to DWORD conversion...
135 
136                     if (GetSaveFileName(&ofn))
137                     {
138                         if ( (ofn.Flags & OFN_EXPLORER) &&
139                              (ofn.Flags & OFN_ALLOWMULTISELECT) ) // Must be always true...
140                         {
141                             LPWSTR lpszFiles = szPath + ofn.nFileOffset;
142                             LPWSTR lpszFilePatterns = NULL;
143 
144                             LPWSTR lpszTmp = lpszFiles;
145                             unsigned int n = 0;
146                             size_t numOfChars = 0;
147 
148                             /* Truncate the path, if needed */
149                             szPath[ofn.nFileOffset - 1] = L'\0';
150 
151                             while (*lpszTmp)
152                             {
153                                 ++n;
154                                 numOfChars += wcslen(lpszTmp)+1 + 3; // 3 = 2 quotation marks + 1 space.
155                                 lpszTmp += wcslen(lpszTmp)+1;
156                             }
157 
158                             lpszFilePatterns = (LPWSTR)MemAlloc(HEAP_ZERO_MEMORY, numOfChars*sizeof(WCHAR));
159 
160                             if (n >= 2)
161                             {
162                                 while (*lpszFiles)
163                                 {
164                                     wcscat(lpszFilePatterns, L"\"");
165                                     wcscat(lpszFilePatterns, lpszFiles);
166                                     wcscat(lpszFilePatterns, L"\"");
167 
168                                     lpszFiles += wcslen(lpszFiles)+1;
169                                     if (*lpszFiles)
170                                         wcscat(lpszFilePatterns, L" ");
171                                 }
172                             }
173                             else
174                             {
175                                 wcscpy(lpszFilePatterns, lpszFiles);
176                             }
177 
178                             Edit_SetText(GetDlgItem(hDlg, IDC_TXT_FILE_TO_RESTORE), lpszFilePatterns);
179                             AddStringToComboList(GetDlgItem(hDlg, IDC_DRP_DEST_DIR), szPath);
180 
181                             SetFocus(GetDlgItem(hDlg, IDC_TXT_FILE_TO_RESTORE));
182                             Edit_SetSel(GetDlgItem(hDlg, IDC_TXT_FILE_TO_RESTORE), 0, -1);
183 
184                             MemFree(lpszFilePatterns);
185                         }
186                     }
187 
188                     MemFree(szPath);
189 
190                     break;
191                 }
192 
193                 case IDC_BTN_BROWSE_CAB_FILES:
194                 {
195                     OPENFILENAMEW ofn;
196                     WCHAR szPath[MAX_PATH] = L"";
197 
198                     SecureZeroMemory(&ofn, sizeof(ofn));
199                     ofn.lStructSize = sizeof(ofn);
200                     ofn.hwndOwner   = hDlg;
201                     ofn.lpstrTitle  = L"Open an archive file"; // L"Ouvrir un fichier archive"; // FIXME: Localize!
202                     ofn.Flags       = OFN_EXPLORER | OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_READONLY;
203                     // ofn.FlagsEx     = OFN_EX_NOPLACESBAR;
204                     ofn.lpstrFilter = L"Cabinet files (*.cab)\0*.cab\0";
205                     ofn.lpstrDefExt = L"cab";
206                     ofn.nFilterIndex = 0;
207                     ofn.lpstrFile   = szPath;
208                     ofn.nMaxFile    = ARRAYSIZE(szPath);
209 
210                     if (GetOpenFileName(&ofn))
211                     {
212                         AddStringToComboList(GetDlgItem(hDlg, IDC_DRP_CAB_FILE), szPath);
213                         SetFocus(GetDlgItem(hDlg, IDC_DRP_CAB_FILE));
214                     }
215 
216                     break;
217                 }
218 
219                 case IDC_BTN_BROWSE_DIRS:
220                 {
221                     BROWSEINFOW bi;
222                     WCHAR szPath[MAX_PATH] = L"";
223 
224                     SecureZeroMemory(&bi, sizeof(bi));
225                     bi.hwndOwner = hDlg;
226                     bi.pidlRoot  = NULL;
227                     bi.lpszTitle = L"Select the directory where the restored files should be stored:";
228                                 // L"Choisissez le r�pertoire dans lequel doivent �tre enregistr�s les fichiers restaur�s :"; // FIXME: Localize!
229                     bi.ulFlags   = BIF_USENEWUI | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE | BIF_VALIDATE /* | BIF_BROWSEFILEJUNCTIONS <--- only in Windows 7+ */;
230 
231                     if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
232                     {
233                         /*PIDLIST_ABSOLUTE*/ LPITEMIDLIST pidl = SHBrowseForFolderW(&bi);
234                         if (SHGetPathFromIDListW(pidl, szPath))
235                         {
236                             AddStringToComboList(GetDlgItem(hDlg, IDC_DRP_DEST_DIR), szPath);
237                             SetFocus(GetDlgItem(hDlg, IDC_DRP_DEST_DIR));
238                         }
239 
240                         CoTaskMemFree(pidl);
241                         CoUninitialize();
242                     }
243 
244                     break;
245                 }
246 
247                 default:
248                     //break;
249                     return FALSE;
250             }
251         }
252     }
253 
254     return FALSE;
255 }
256