windows-nt/Source/XPSP1/NT/com/ole32/cs/csadmin/appmgr/genpage.cpp
2020-09-26 16:20:57 +08:00

477 lines
15 KiB
C++

// genpage.cpp : implementation file
//
#include "precomp.hxx"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CGeneralPage property page
IMPLEMENT_DYNCREATE(CGeneralPage, CPropertyPage)
CGeneralPage::CGeneralPage() : CPropertyPage(CGeneralPage::IDD)
{
//{{AFX_DATA_INIT(CGeneralPage)
m_szName = _T("");
m_szDeploy = _T("");
m_szDescription = _T("");
m_szLocale = _T("");
m_szPath = _T("");
m_szVer = _T("");
m_fShow = TRUE;
//}}AFX_DATA_INIT
m_hConsoleHandle = NULL;
m_bUpdate = FALSE;
}
CGeneralPage::~CGeneralPage()
{
}
void CGeneralPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGeneralPage)
DDX_Control(pDX, IDC_DEPLOY, m_cbDeploy);
DDX_CBString(pDX, IDC_DEPLOY, m_szDeploy);
DDX_Text(pDX, IDC_NAME, m_szName);
DDX_Text(pDX, IDC_DESCRIPTION, m_szDescription);
DDX_Text(pDX, IDC_LOCALE, m_szLocale);
DDX_Text(pDX, IDC_PATH, m_szPath);
DDX_Text(pDX, IDC_VERSION, m_szVer);
DDX_Control(pDX, IDC_CPU, m_cbCPU);
DDX_Control(pDX, IDC_OS, m_cbOS);
DDX_Check(pDX, IDC_CHECK1, m_fShow);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CGeneralPage, CPropertyPage)
//{{AFX_MSG_MAP(CGeneralPage)
ON_WM_DESTROY()
ON_EN_CHANGE(IDC_NAME, OnChangeName)
ON_EN_CHANGE(IDC_PATH, OnChangePath)
ON_EN_CHANGE(IDC_DESCRIPTION, OnChangeDescription)
ON_BN_CLICKED(IDC_CHECK1, OnChangeShow)
ON_CBN_SELCHANGE(IDC_DEPLOY, OnSelchangeDeploy)
ON_CBN_SELCHANGE(IDC_OS, OnChangeOS)
ON_CBN_SELCHANGE(IDC_CPU, OnChangeCPU)
ON_EN_CHANGE(IDC_VERSION, OnChangeVersion)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGeneralPage message handlers
void CGeneralPage::OnDestroy()
{
// Note - This needs to be called only once.
// If called more than once, it will gracefully return an error.
MMCFreeNotifyHandle(m_hConsoleHandle);
CPropertyPage::OnDestroy();
m_pData->fBlockDeletion = FALSE;
// Delete the CGeneralPage object
delete this;
}
BOOL CGeneralPage::OnApply()
{
if (m_pIAppManagerActions == NULL || m_pIClassAdmin == NULL)
{
return FALSE;
}
// put up an hourglass (this could take a while)
CHourglass hourglass;
CString szNewScriptPath;
CString szOldScriptPath;
HRESULT hr;
if (m_bUpdate == TRUE)
{
PACKAGEDETAIL NewDetails;
memcpy(&NewDetails, m_pData->pDetails, sizeof(PACKAGEDETAIL));
// UNDONE - validate the data
NewDetails.pszPackageName = (LPOLESTR) ((LPCTSTR)m_szName);
swscanf((LPOLESTR)((LPCTSTR)m_szVer), _T("%u.%u"),&(NewDetails.Platform.dwVersionHi),&(NewDetails.Platform.dwVersionLo));
NewDetails.Platform.dwPlatformId = m_cbOS.GetCurSel();
NewDetails.Platform.dwProcessorArch = m_cbCPU.GetCurSel() == 1 ? PROCESSOR_ARCHITECTURE_ALPHA : PROCESSOR_ARCHITECTURE_INTEL;
NewDetails.dwActFlags = (m_pData->pDetails->dwActFlags & (! (ACTFLG_Published | ACTFLG_Assigned | ACTFLG_UserInstall)));
BOOL fAssign = FALSE;
if (m_szDeploy == m_szPublished)
{
NewDetails.dwActFlags |= ACTFLG_Published;
}
else
{
NewDetails.dwActFlags |= ACTFLG_Assigned;
fAssign = TRUE;
}
NewDetails.dwActFlags |= ((!m_fShow) ? 0 : ACTFLG_UserInstall);
BOOL fMoveScript = (NewDetails.dwActFlags & (ACTFLG_Assigned | ACTFLG_Published))
!= (m_pData->pDetails->dwActFlags & (ACTFLG_Assigned | ACTFLG_Published))
|| (NewDetails.Platform.dwProcessorArch != m_pData->pDetails->Platform.dwProcessorArch);
if (fMoveScript)
{
// Find out if script file can in fact be moved
BOOL fCanMoveScript = FALSE;
szOldScriptPath = m_pData->szPath;
CString szTemp = szOldScriptPath;
szTemp.MakeLower();
int i = szTemp.Find(_T("\\published\\"));
if (i < 0)
{
i = szTemp.Find(_T("\\assigned\\")); // cover all the bases
}
if (i >= 0)
{
// finally make sure it's got an .aas extension
if (szTemp.Right(4) == _T(".aas"))
{
DWORD dwAttributes = GetFileAttributes(m_pData->szPath);
if ((dwAttributes != 0xffffffff) && ((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0))
{
fCanMoveScript = TRUE;
}
}
}
if (fCanMoveScript)
{
// Build new path
szNewScriptPath = szOldScriptPath;
// Strip off everything up to "\\published" or "\\assigned"
szNewScriptPath = szNewScriptPath.Left(i);
szNewScriptPath +=
(NewDetails.dwActFlags & ACTFLG_Assigned) != 0
? _T("\\Assigned") : _T("\\Published");
szNewScriptPath +=
NewDetails.Platform.dwProcessorArch == PROCESSOR_ARCHITECTURE_ALPHA
? _T("\\Alpha\\") : _T("\\x86\\");
{
TCHAR Name [_MAX_FNAME];
TCHAR Ext [_MAX_EXT];
TCHAR ScriptNameAndPath[_MAX_PATH ];
_tsplitpath( szOldScriptPath, NULL, NULL, Name, Ext );
szNewScriptPath += Name;
szNewScriptPath += Ext;
}
// Try and move it
if (!MoveFileEx(szOldScriptPath,
szNewScriptPath,
MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH))
{
// wasn't moved
fMoveScript = FALSE;
// UNDONE - put up a message that the scrip file wasn't moved?
}
else
{
m_pData->szPath = szNewScriptPath;
NewDetails.pszPath = (LPOLESTR)(LPCOLESTR)m_pData->szPath;
}
}
else
{
// wasn't moved so make sure we don't try and move it back later
fMoveScript = FALSE;
}
}
NewDetails.pszProductName = (LPOLESTR) ((LPCTSTR)m_szDescription);
BOOL fPathChanged = m_szPath != m_pData->szIconPath;
BOOL fChangeBoth = 0 == wcscmp(m_pData->pDetails->pszPath, m_pData->pDetails->pszIconPath);
if (fPathChanged)
{
// user changed the path
NewDetails.pszIconPath = (LPOLESTR)((LPCTSTR)m_szPath);
if (fChangeBoth)
{
NewDetails.pszPath = (LPOLESTR)((LPCTSTR)m_szPath);
}
}
hr = m_pIClassAdmin->DeletePackage(m_pData->pDetails->pszPackageName);
if (SUCCEEDED(hr))
{
hr = m_pIClassAdmin->NewPackage(&NewDetails);
}
if (FAILED(hr))
{
if (fMoveScript)
{
// changed location for deployment back to what it was
// before we failed to change the info in the class store
// (Note that we're assuming that if we could change it one way
// we can change it back.)
if (MoveFileEx(szNewScriptPath,
szOldScriptPath,
MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH))
{
m_pData->szPath = szOldScriptPath;
m_pData->pDetails->pszPath = (LPOLESTR)(LPCOLESTR)m_pData->szPath;
}
}
hr = m_pIClassAdmin->NewPackage(m_pData->pDetails);
// need to move this message
::MessageBox(NULL,
L"Couldn't apply changes. Verify that the class store's server is active.",
L"ERROR",
MB_OK);
return FALSE;
}
else
{
if (fMoveScript)
{
// Notify clients of change
if (m_pIAppManagerActions)
{
m_pIAppManagerActions->NotifyClients(FALSE);
}
}
}
memcpy(m_pData->pDetails, &NewDetails, sizeof(PACKAGEDETAIL));
if (m_pData->pDetails->dwActFlags & ACTFLG_Assigned)
{
m_pData->type = DT_ASSIGNED;
}
else
{
m_pData->type = DT_PUBLISHED;
}
m_pData->szType = m_szDeploy;
// Up above, we set NewDetails.pszPackageName to m_szName.
// We can't leave it set to that because m_szName is a member
// variable of this property sheet class object and will be released
// when the property sheet goes away. We need to copy it to
// m_pData->szName (which is a CString and therefore has it's own
// memory store) and then set the details back to it so it doesn't
// get freed from under us.
m_pData->szName = m_szName;
m_pData->pDetails->pszPackageName = (LPOLESTR)((LPCTSTR)m_pData->szName);
// same problem with szDesc
m_pData->szDesc = m_szDescription;
m_pData->pDetails->pszProductName = (LPOLESTR)((LPCTSTR)m_pData->szDesc);
if (fPathChanged)
{
m_pData->szIconPath = m_szPath;
m_pData->pDetails->pszIconPath = (LPOLESTR)((LPCTSTR)m_pData->szIconPath);
// user changed the path
if (fChangeBoth)
{
m_pData->szPath = m_szPath;
m_pData->pDetails->pszPath = (LPOLESTR)((LPCTSTR)m_pData->szIconPath);
}
}
if (m_szPath != m_pData->szIconPath)
{
// user changed the path
if (wcscmp(m_pData->pDetails->pszPath, m_pData->pDetails->pszIconPath))
{
// If the paths were the same to start with then change 'em both.
m_pData->szPath = m_szPath;
m_pData->pDetails->pszPath = (LPOLESTR)((LPCTSTR)m_pData->szPath);
}
m_pData->szIconPath = m_szPath;
m_pData->pDetails->pszIconPath = (LPOLESTR)((LPCTSTR)m_pData->szIconPath);
}
SetStringData(m_pData);
MMCPropertyChangeNotify(m_hConsoleHandle, (long) m_cookie);
m_bUpdate = FALSE;
}
return CPropertyPage::OnApply();
}
BOOL CGeneralPage::OnInitDialog()
{
TCHAR szBuffer[256];
m_pData->fBlockDeletion = TRUE;
m_szName = m_pData->szName;
m_szDescription = m_pData->szDesc;
m_szLocale = m_pData->szLoc;
m_szPath = m_pData->szIconPath;
m_szDeploy = m_pData->szType;
wsprintf(szBuffer, _T("%u.%u"), m_pData->pDetails->Platform.dwVersionHi, m_pData->pDetails->Platform.dwVersionLo);
m_szVer = szBuffer;
m_fShow = m_pData->pDetails->dwActFlags & ACTFLG_UserInstall ? 1 : 0;
CPropertyPage::OnInitDialog();
// unmarshal the IAppManagerActions interface
HRESULT hr = CoGetInterfaceAndReleaseStream(m_pIStreamAM, IID_IAppManagerActions, (void **) &m_pIAppManagerActions);
if (!SUCCEEDED(hr))
{
#if DBG == 1
::MessageBox(NULL,
L"Couldn't marshal IAppManagerActions",
L"DEBUG ERROR",
MB_OK);
#endif
m_pIAppManagerActions = NULL;
return FALSE;
// BUGBUG - what should I do here? Disallow changes?
}
// unmarshal the IClassAdmin interface
hr = CoGetInterfaceAndReleaseStream(m_pIStream, IID_IClassAdmin, (void **) &m_pIClassAdmin);
if (!SUCCEEDED(hr))
{
#if DBG == 1
::MessageBox(NULL,
L"Couldn't marshal IClassAdmin",
L"DEBUG ERROR",
MB_OK);
#endif
m_pIClassAdmin = NULL;
// BUGBUG - what should I do here? Disallow changes?
}
::LoadString(ghInstance, IDS_DATATYPES, szBuffer, 256);
m_szAssigned = szBuffer;
// Test to be sure it can be assigned.
// If it's not a Darwin package then it can't be assigned and
// the option won't even be presented to the user.
if (m_pIAppManagerActions)
{
hr = m_pIAppManagerActions->CanPackageBeAssigned(m_cookie);
}
if (hr == ERROR_SUCCESS)
{
m_cbDeploy.AddString(szBuffer);
}
::LoadString(ghInstance, IDS_DATATYPES+1, szBuffer, 256);
m_szPublished = szBuffer;
m_cbDeploy.AddString(szBuffer);
m_cbDeploy.SelectString(0, m_szDeploy);
int i;
for (i = 0; i < (sizeof(m_rgszOS) / sizeof(m_rgszOS[0])); i++)
{
::LoadString(ghInstance, IDS_OS + i + 1, szBuffer, 256);
m_rgszOS[i] = szBuffer;
m_cbOS.AddString(szBuffer);
}
m_cbOS.SetCurSel(m_pData->pDetails->Platform.dwPlatformId);
for (i = 0; i < (sizeof(m_rgszCPU) / sizeof(m_rgszCPU[0])); i++)
{
::LoadString(ghInstance, IDS_HW + (i == 0 ? PROCESSOR_ARCHITECTURE_INTEL : PROCESSOR_ARCHITECTURE_ALPHA), szBuffer, 256);
m_rgszCPU[i] = szBuffer;
m_cbCPU.AddString(szBuffer);
}
m_cbCPU.SetCurSel(m_pData->pDetails->Platform.dwProcessorArch == PROCESSOR_ARCHITECTURE_ALPHA ? 1 : 0);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CGeneralPage::OnChangeShow()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CPropertyPage::OnInitDialog()
// function to send the EM_SETEVENTMASK message to the control
// with the ENM_CHANGE flag ORed into the lParam mask.
// TODO: Add your control notification handler code here
SetModified();
m_bUpdate = TRUE;
}
void CGeneralPage::OnChangePath()
{
SetModified();
m_bUpdate = TRUE;
}
void CGeneralPage::OnChangeCPU()
{
SetModified();
m_bUpdate = TRUE;
}
void CGeneralPage::OnChangeOS()
{
TCHAR * rgszVer[] =
{
_T("3.1"),
_T("4.1"),
_T("5.0")
};
int i = m_cbOS.GetCurSel();
m_szVer = rgszVer[i];
GetDlgItem(IDC_VERSION)->SetWindowText(m_szVer);
SetModified();
m_bUpdate = TRUE;
}
void CGeneralPage::OnChangeVersion()
{
SetModified();
m_bUpdate = TRUE;
}
void CGeneralPage::OnChangeName()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CPropertyPage::OnInitDialog()
// function to send the EM_SETEVENTMASK message to the control
// with the ENM_CHANGE flag ORed into the lParam mask.
// TODO: Add your control notification handler code here
SetModified();
m_bUpdate = TRUE;
}
void CGeneralPage::OnChangeDescription()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CPropertyPage::OnInitDialog()
// function to send the EM_SETEVENTMASK message to the control
// with the ENM_CHANGE flag ORed into the lParam mask.
// TODO: Add your control notification handler code here
SetModified();
m_bUpdate = TRUE;
}
void CGeneralPage::OnSelchangeDeploy()
{
// TODO: Add your control notification handler code here
SetModified();
m_bUpdate = TRUE;
}