blob: a6446eea4abd59b83c5fdc8371790a22015ad576 [file]
/* **********************************************************
* 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);
}