| /* ********************************************************** |
| * Copyright (c) 2008 VMware, Inc. All rights reserved. |
| * **********************************************************/ |
| |
| /* |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * * Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * * Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * * Neither the name of VMware, Inc. nor the names of its contributors may be |
| * used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| * DAMAGE. |
| */ |
| |
| /* Copyright (c) 2003-2007 Determina Corp. */ |
| /* Copyright (c) 2002-2003 Massachusetts Institute of Technology */ |
| /* Copyright (c) 2002 Hewlett-Packard Company */ |
| |
| #include "stdafx.h" |
| #include "Wizard.h" |
| #include "CopyDlg.h" |
| #include <assert.h> |
| #include <direct.h> // for _chdir |
| #include "WizSheet.h" |
| #include "ShellInterface.h" |
| |
| #ifdef _DEBUG |
| #define new DEBUG_NEW |
| #undef THIS_FILE |
| static char THIS_FILE[] = __FILE__; |
| #endif |
| |
| // for CGO 2008 tutorial we create a zip file from data in our data section |
| static const unsigned char zipdata[] = { |
| #include "zipdump.h" |
| }; |
| #define ZIPNAME _T("DynamoRIO.zip") |
| |
| // we copy the tree rooted at DynamoRIO into here, so only specify parent dir: |
| #define DEFAULT_DIR _T("VMware\\DynamoRIO") |
| |
| // MB of space we take up |
| #define DISK_SPACE_REQUIRED 14 |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // CCopyDlg property page |
| |
| IMPLEMENT_DYNCREATE(CCopyDlg, CPropertyPage) |
| |
| CCopyDlg::CCopyDlg() : CPropertyPage(CCopyDlg::IDD, 0) |
| { |
| //{{AFX_DATA_INIT(CCopyDlg) |
| m_SpaceAvailable = _T(""); |
| m_SpaceRequired = _T(""); |
| m_Target = _T(""); |
| //}}AFX_DATA_INIT |
| |
| m_DefaultDir[0] = _T('\0'); |
| m_psp.dwFlags |= PSP_HIDEHEADER; |
| m_psp.dwFlags &= ~(PSP_HASHELP); |
| } |
| |
| CCopyDlg::~CCopyDlg() |
| { |
| } |
| |
| void CCopyDlg::DoDataExchange(CDataExchange* pDX) |
| { |
| CPropertyPage::DoDataExchange(pDX); |
| //{{AFX_DATA_MAP(CCopyDlg) |
| DDX_Control(pDX, IDC_TARGET, m_TargetEdit); |
| DDX_Text(pDX, IDC_SPACE_AVAILABLE, m_SpaceAvailable); |
| DDX_Text(pDX, IDC_SPACE_REQUIRED, m_SpaceRequired); |
| DDX_Text(pDX, IDC_TARGET, m_Target); |
| //}}AFX_DATA_MAP |
| } |
| |
| |
| BEGIN_MESSAGE_MAP(CCopyDlg, CPropertyPage) |
| //{{AFX_MSG_MAP(CCopyDlg) |
| ON_BN_CLICKED(IDC_BROWSE, OnBrowse) |
| //}}AFX_MSG_MAP |
| END_MESSAGE_MAP() |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // CCopyDlg message handlers |
| |
| BOOL CCopyDlg::OnInitDialog() |
| { |
| CDialog::OnInitDialog(); |
| |
| m_SpaceRequired.Format(_T("%8d"), DISK_SPACE_REQUIRED); |
| ULARGE_INTEGER userbytes, totalbytes, freebytes; |
| // WARNING: GetDiskFreeSpaceEx is not available on NT < 4.0 |
| if (!GetDiskFreeSpaceEx(_T("C:\\"), &userbytes, &totalbytes, &freebytes)) |
| assert(false); |
| __int64 bytes = (freebytes.QuadPart)/(1024*1024); |
| m_SpaceAvailable.Format(_T("%8I64u"), bytes); |
| |
| int res = GetCurrentDirectory(MAX_PATH, m_CWD); |
| assert(res > 0); |
| |
| TCHAR drive[8]; |
| int len = GetEnvironmentVariable(_T("SYSTEMDRIVE"), drive, 7); |
| if (len == 0 || len > 7) |
| _stprintf(drive, _T("C:")); |
| |
| TCHAR buf[MAX_PATH]; |
| len = GetEnvironmentVariable(_T("PROGRAMFILES"), buf, MAX_PATH); |
| if (len == 0 || len > MAX_PATH) { |
| // NT doesn't have this env var...so just hardcode it |
| _stprintf(buf, _T("%s\\Program Files"), drive); |
| len = _tcslen(buf); |
| } |
| if (!SetCurrentDirectory(buf)) { |
| // directory does not exist or is not accessible! |
| _stprintf(buf, _T("%s\\"), drive); |
| if (!SetCurrentDirectory(buf)) { |
| assert(FALSE); |
| } |
| } |
| |
| assert(len + _tcslen(DEFAULT_DIR) + 1 < MAX_PATH); |
| _stprintf(m_DefaultDir, _T("%s\\%s"), buf, DEFAULT_DIR); |
| m_Target.Format(_T("%s"), m_DefaultDir); |
| |
| // must go back to wd |
| if (!SetCurrentDirectory(m_CWD)) { |
| assert(FALSE); |
| } |
| |
| UpdateData(FALSE); |
| |
| return TRUE; |
| } |
| |
| BOOL CCopyDlg::OnSetActive() |
| { |
| CPropertySheet* pSheet = (CPropertySheet*)GetParent(); |
| ASSERT_KINDOF(CPropertySheet, pSheet); |
| // our installer doesn't support Back! |
| // pSheet->SetWizardButtons( PSWIZB_BACK | PSWIZB_NEXT); |
| pSheet->SetWizardButtons( PSWIZB_NEXT); |
| return CPropertyPage::OnSetActive(); |
| } |
| |
| |
| LRESULT CCopyDlg::OnWizardNext() |
| { |
| if (!CopyFiles()) { |
| // select entire directory |
| m_TargetEdit.SetSel(0, -1); |
| m_TargetEdit.SetFocus(); |
| // return to this same wizard page |
| // (we assume problem is with target dir) |
| return -1; |
| } |
| |
| // need to communicate install dir to later pages |
| // use parent Sheet |
| CWizardSheet* pSheet = (CWizardSheet*)GetParent(); |
| // add the DynamoRIO on |
| pSheet->m_InstallDir.Format(_T("%s\\DynamoRIO"), m_Target); |
| |
| return CPropertyPage::OnWizardNext(); |
| } |
| |
| BOOL CCopyDlg::CopyFiles() |
| { |
| TCHAR msg[MAX_PATH*2]; |
| TCHAR cmd[MAX_PATH*2]; |
| |
| UpdateData(TRUE); // get target dir string |
| |
| // make the target directory |
| // have to build each new directory one at a time |
| CString newdir; |
| int pos = 0; |
| int slash = m_Target.Find('\\', pos); |
| |
| // first see if need to clean out existing dir |
| if (SetCurrentDirectory(m_Target)) { |
| _stprintf(msg, _T("Directory %s already exists.\n") |
| _T("Continuing will delete all its existing files.\nContinue?"), m_Target); |
| int res = MessageBox(msg, _T("Confirmation"), MB_OKCANCEL | MYMBFLAGS); |
| if (res == IDCANCEL) |
| return FALSE; |
| // get out of the dir |
| BOOL ok = SetCurrentDirectory(m_CWD); |
| assert(ok); |
| _stprintf(cmd, _T("%s"), m_Target); |
| if (!CShellInterface::DeleteFile(cmd, GetParent()->m_hWnd)) { |
| _stprintf(msg, _T("Error removing existing directory %s"), m_Target); |
| MessageBox(msg, _T("Error Deleting Files"), MB_OK | MYMBFLAGS); |
| return FALSE; |
| } |
| } |
| |
| while (TRUE) { |
| if (slash == -1) |
| newdir = m_Target; |
| else |
| newdir = m_Target.Mid(0, slash); |
| if (!SetCurrentDirectory(newdir)) { |
| _stprintf(msg, _T("Create directory %s?"), newdir); |
| int res = MessageBox(msg, _T("Confirmation"), MB_OKCANCEL | MYMBFLAGS); |
| if (res == IDCANCEL) |
| return FALSE; |
| if (!CreateDirectory(newdir, NULL)) { |
| _stprintf(msg, _T("Could not create directory %s"), newdir); |
| MessageBox(msg, _T("Error Copying Files"), MB_OK | MYMBFLAGS); |
| return FALSE; |
| } |
| } |
| if (slash == -1) |
| break; |
| pos = slash + 1; |
| slash = m_Target.Find('\\', pos); |
| } |
| |
| // now copy the files |
| #if 1 /* CGO 2008 tutorial: create zip file */ |
| DWORD written; |
| BOOL success; |
| TCHAR to[MAX_PATH]; |
| _stprintf(to, _T("%s\\%s"), m_Target, ZIPNAME); |
| HANDLE h = CreateFile(to, // file to open |
| GENERIC_WRITE, // no read access needed |
| 0, // no sharing |
| NULL, // default security |
| CREATE_ALWAYS, // clobber existing file |
| FILE_ATTRIBUTE_NORMAL, // normal file |
| NULL); // no attr. template |
| if (h == NULL) |
| success = FALSE; |
| else { |
| success = WriteFile(h, zipdata, sizeof(zipdata), &written, NULL); |
| CloseHandle(h); |
| } |
| if (!success || written != sizeof(zipdata)) { |
| _stprintf(msg, _T("Error copying file to %s"), to); |
| MessageBox(msg, _T("Error Copying Files"), MB_OK | MYMBFLAGS); |
| return FALSE; |
| } |
| #else |
| TCHAR from[MAX_PATH]; |
| TCHAR to[MAX_PATH]; |
| # if 0 |
| _stprintf(from, _T("%s"), _T("c:\\iye\\rio\\install\\DynamoRIO")); |
| //_stprintf(from, _T("%s"), _T("d:\\bruening\\dynamo\\install\\DynamoRIO")); |
| # else |
| _stprintf(from, _T("%s\\DynamoRIO"), m_CWD); |
| # endif |
| _stprintf(to, _T("%s"), m_Target); |
| if (!CShellInterface::CopyDir(from, to, GetParent()->m_hWnd)) { |
| _stprintf(msg, _T("Error copying files from %s to %s"), from, to); |
| MessageBox(msg, _T("Error Copying Files"), MB_OK | MYMBFLAGS); |
| return FALSE; |
| } |
| #endif |
| |
| return TRUE; |
| } |
| |
| void CCopyDlg::OnBrowse() |
| { |
| TCHAR folder[MAX_PATH]; |
| BROWSEINFO bi; |
| bi.hwndOwner = m_hWnd; |
| bi.pidlRoot = NULL; |
| bi.pszDisplayName = folder; |
| bi.lpszTitle = _T("Select folder to install into"); |
| bi.ulFlags = 0; |
| bi.lpfn = NULL; |
| bi.lParam = NULL; |
| bi.iImage = 0; |
| ITEMIDLIST *id = SHBrowseForFolder(&bi); |
| if (id == NULL) // cancelled |
| return; |
| SHGetPathFromIDList(id, folder); |
| m_Target.Format(_T("%s"), folder); |
| UpdateData(FALSE); |
| } |