1 #include "InstallerMain.h"
2 #include "InstallerUtil.h"
3 #include "PerformInstall.h"
4 #include "CCriticalSection.h"
6 #define WMU_INSTALLER_DONE WM_USER+2
7 #define PBAR_RANGE_HIGH 100
8 #define PBAR_RANGE_LOW 0
10 ICopyMethod *g_pCopyMethod = NULL;
11 HANDLE g_hCopyThread = NULL;
12 copy_thread_args_t g_thread_args = {NULL, NULL, NULL, false, false};
13 CCriticalSection g_update_window;
15 class TrackProgress : public ICopyProgress
18 void Initialize(HWND hTextBar, HWND hCurBar, HWND hTotalBar, size_t total_size)
20 m_hTextBar = hTextBar;
22 m_hTotalBar = hTotalBar;
23 m_TotalSize = total_size;
25 RedrawProgressBars(0.0, 0.0);
29 RedrawProgressBars(100.0, 100.0);
32 void StartingNewFile(const TCHAR *filename)
36 if (g_update_window.TryEnter())
38 UTIL_Format(buffer, sizeof(buffer) / sizeof(TCHAR), _T("Copying: %s"), filename);
39 SendMessage(m_hTextBar, WM_SETTEXT, 0, (LPARAM)buffer);
40 UpdateWindow(m_hTextBar);
41 g_update_window.Leave();
44 void UpdateProgress(size_t bytes, size_t total_bytes)
46 float fCur = (float)bytes / (float)total_bytes;
47 float fTotal = ((float)m_TotalDone + (float)bytes) / (float)m_TotalSize;
48 RedrawProgressBars(fCur, fTotal);
50 void FileDone(size_t total_size)
52 m_TotalDone += total_size;
53 RedrawProgressBars(0.0, (float)m_TotalDone / (float)m_TotalSize);
56 void RedrawProgressBar(HWND hBar, float fPerc)
58 /* Get a percentage point in the range */
59 float fPointInRange = (float)(PBAR_RANGE_HIGH - PBAR_RANGE_LOW) * fPerc;
60 int iPointInRange = (int)fPointInRange;
63 iPointInRange += PBAR_RANGE_LOW;
65 if (g_update_window.TryEnter())
71 g_update_window.Leave();
74 void RedrawProgressBars(float fCurrent, float fTotal)
76 RedrawProgressBar(m_hCurBar, fCurrent);
77 RedrawProgressBar(m_hTotalBar, fTotal);
87 void CancelPerformInstall()
89 delete g_thread_args.pFileList;
90 g_thread_args.pFileList = NULL;
93 void SetInstallMethod(ICopyMethod *pCopyMethod)
95 g_pCopyMethod = pCopyMethod;
98 bool CopyStructureRecursively(ICopyMethod *pCopyMethod,
100 const TCHAR *basepath,
101 const TCHAR *local_path,
105 TCHAR file_path[MAX_PATH];
109 if (!pCopyMethod->SetCurrentFolder(local_path, errbuf, maxchars))
115 while ((file = pFileList->PeekCurrentFile()) != NULL)
117 if (local_path == NULL)
119 UTIL_PathFormat(file_path,
120 sizeof(file_path) / sizeof(TCHAR),
127 UTIL_PathFormat(file_path,
128 sizeof(file_path) / sizeof(TCHAR),
135 if (!pCopyMethod->SendFile(file_path, errbuf, maxchars))
140 pFileList->PopCurrentFile();
143 /* Now copy folders */
144 while ((pSubList = pFileList->PeekCurrentFolder()) != NULL)
146 /* Try creating the folder */
147 if (!pCopyMethod->CreateFolder(pSubList->GetFolderName(), errbuf, maxchars))
152 TCHAR new_local_path[MAX_PATH];
153 if (local_path == NULL)
155 UTIL_PathFormat(new_local_path,
156 sizeof(new_local_path) / sizeof(TCHAR),
158 pSubList->GetFolderName());
162 UTIL_PathFormat(new_local_path,
163 sizeof(new_local_path) / sizeof(TCHAR),
166 pSubList->GetFolderName());
169 if (!CopyStructureRecursively(pCopyMethod,
179 pFileList->PopCurrentFolder();
181 /* Set the current folder again for the next operation */
182 if (!pCopyMethod->SetCurrentFolder(local_path, errbuf, maxchars))
191 DWORD WINAPI T_CopyFiles(LPVOID arg)
194 CopyStructureRecursively(g_thread_args.pCopyMethod,
195 g_thread_args.pFileList,
196 g_thread_args.basepath,
199 sizeof(g_thread_args.error) / sizeof(TCHAR));
201 PostMessage(g_thread_args.hWnd, WMU_INSTALLER_DONE, result ? TRUE : FALSE, 0);
206 bool StartFileCopy(HWND hWnd)
208 g_thread_args.m_bWasCancelled = false;
209 g_thread_args.hWnd = hWnd;
210 if ((g_hCopyThread = CreateThread(NULL,
220 _T("Could not initialize copy thread."),
221 _T("SourceMod Installer"),
230 g_thread_args.m_bWasCancelled = true;
231 g_pCopyMethod->CancelCurrentCopy();
233 if (g_hCopyThread != NULL)
235 g_update_window.Enter();
236 WaitForSingleObject(g_hCopyThread, INFINITE);
237 g_update_window.Leave();
238 CloseHandle(g_hCopyThread);
239 g_hCopyThread = NULL;
243 bool RequestCancelInstall(HWND hWnd)
247 int val = MessageBox(
249 _T("Are you sure you want to cancel the install?"),
250 _T("SourceMod Installer"),
251 MB_YESNO|MB_ICONQUESTION);
258 if (g_thread_args.pFileList == NULL)
263 /* Start the thread, note our return value is opposite */
264 return !StartFileCopy(hWnd);
267 bool StartInstallProcess(HWND hWnd)
269 if (g_pCopyMethod->CheckForExistingInstall())
271 int val = MessageBox(
273 _T("It looks like a previous SourceMod installation exists. Do you want to upgrade? Select \"Yes\" to upgrade and keep configuration files. Select \"No\" to perform a full re-install."),
274 _T("SourceMod Installer"),
275 MB_YESNO|MB_ICONQUESTION);
277 if (val == 0 || val == IDYES)
286 TCHAR cur_path[MAX_PATH];
287 if (_tgetcwd(cur_path, sizeof(cur_path)) == NULL)
291 _T("Could not locate current directory!"),
292 _T("SourceMod Installer"),
299 UTIL_PathFormat(source_path,
300 sizeof(source_path) / sizeof(TCHAR),
304 UTIL_PathFormat(g_thread_args.basepath,
305 sizeof(g_thread_args.basepath) / sizeof(TCHAR),
306 _T("C:\\real\\done\\base"));
309 if (GetFileAttributes(g_thread_args.basepath) == INVALID_FILE_ATTRIBUTES)
313 _T("Could not locate the source installation files!"),
314 _T("SourceMod Installer"),
319 delete g_thread_args.pFileList;
320 g_thread_args.pFileList = CFileList::BuildFileList(_T(""), g_thread_args.basepath);
322 s_ProgressTracker.Initialize(
323 GetDlgItem(hWnd, IDC_PROGRESS_CURCOPY),
324 GetDlgItem(hWnd, IDC_PROGRESS_CURRENT),
325 GetDlgItem(hWnd, IDC_PROGRESS_TOTAL),
326 (size_t)g_thread_args.pFileList->GetRecursiveSize());
327 g_pCopyMethod->TrackProgress(&s_ProgressTracker);
328 g_thread_args.pCopyMethod = g_pCopyMethod;
330 return StartFileCopy(hWnd);
333 INT_PTR CALLBACK PerformInstallHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
339 SetToGlobalPosition(hDlg);
340 return (INT_PTR)TRUE;
344 if (LOWORD(wParam) == ID_INSTALL_CANCEL
345 || LOWORD(wParam) == ID_CLOSE)
347 if (RequestCancelInstall(hDlg))
349 CancelPerformInstall();
350 UpdateGlobalPosition(hDlg);
351 EndDialog(hDlg, NULL);
353 return (INT_PTR)TRUE;
355 else if (LOWORD(wParam) == ID_INSTALL_START)
357 HWND hButton = GetDlgItem(hDlg, ID_INSTALL_START);
358 EnableWindow(hButton, FALSE);
359 StartInstallProcess(hDlg);
363 case WMU_INSTALLER_DONE:
367 s_ProgressTracker.Finished();
369 _T("SourceMod was successfully installed! Please visit http://www.sourcemod.net/ for documentation."),
370 _T("SourceMod Installer"),
372 CancelPerformInstall();
373 UpdateGlobalPosition(hDlg);
374 EndDialog(hDlg, NULL);
375 return (INT_PTR)TRUE;
377 else if (!g_thread_args.m_bWasCancelled)
382 sizeof(buffer) / sizeof(TCHAR),
383 _T("Encountered error: %s"),
384 g_thread_args.error);
385 int res = MessageBox(hDlg,
387 _T("SourceMod Installer"),
388 MB_ICONERROR|MB_RETRYCANCEL);
396 CancelPerformInstall();
397 UpdateGlobalPosition(hDlg);
398 EndDialog(hDlg, NULL);
399 return (INT_PTR)TRUE;
406 return (INT_PTR)FALSE;
409 void *DisplayPerformInstall(HWND hWnd)
413 if ((val = DialogBox(
415 MAKEINTRESOURCE(IDD_PERFORM_INSTALL),
417 PerformInstallHandler)) == -1)