733 lines
12 KiB
C++
733 lines
12 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1994-95 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
srvppgp.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Server property page (services) implementation.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Don Ryan (donryan) 05-Feb-1995
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
User Mode - Win32
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Jeff Parham (jeffparh) 30-Jan-1996
|
||
|
o Fixed to properly abort dialog upon ERROR_ACCESS_DENIED.
|
||
|
o Ported to LlsLocalService API to remove dependencies on configuration
|
||
|
information being in the registry.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "llsmgr.h"
|
||
|
#include "srvppgp.h"
|
||
|
#include "lmoddlg.h"
|
||
|
|
||
|
#define LVID_PRODUCT 0
|
||
|
#define LVID_LICENSING_MODE 1
|
||
|
#define LVID_LICENSES_PURCHASED 2
|
||
|
|
||
|
#define LVCX_PRODUCT 40
|
||
|
#define LVCX_LICENSING_MODE 30
|
||
|
#define LVCX_LICENSES_PURCHASED -1
|
||
|
|
||
|
static LV_COLUMN_INFO g_productColumnInfo = {
|
||
|
|
||
|
0, 0, 3,
|
||
|
{{LVID_PRODUCT, IDS_PRODUCT, 0, LVCX_PRODUCT },
|
||
|
{LVID_LICENSING_MODE, IDS_LICENSING_MODE, 0, LVCX_LICENSING_MODE },
|
||
|
{LVID_LICENSES_PURCHASED, IDS_LICENSES_PURCHASED, 0, LVCX_LICENSES_PURCHASED}},
|
||
|
|
||
|
};
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#undef THIS_FILE
|
||
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
IMPLEMENT_DYNCREATE(CServerPropertyPageProducts, CPropertyPage)
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CServerPropertyPageProducts, CPropertyPage)
|
||
|
//{{AFX_MSG_MAP(CServerPropertyPageProducts)
|
||
|
ON_BN_CLICKED(IDC_PP_SERVER_PRODUCTS_EDIT, OnEdit)
|
||
|
ON_NOTIFY(NM_DBLCLK, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnDblClkProducts)
|
||
|
ON_NOTIFY(NM_RETURN, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnReturnProducts)
|
||
|
ON_NOTIFY(NM_SETFOCUS, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnSetFocusProducts)
|
||
|
ON_NOTIFY(NM_KILLFOCUS, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnKillFocusProducts)
|
||
|
ON_NOTIFY(LVN_COLUMNCLICK, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnColumnClickProducts)
|
||
|
ON_NOTIFY(LVN_GETDISPINFO, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnGetDispInfoProducts)
|
||
|
ON_WM_DESTROY()
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
|
||
|
CServerPropertyPageProducts::CServerPropertyPageProducts() :
|
||
|
CPropertyPage(CServerPropertyPageProducts::IDD)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Constructor for server property page (products).
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
//{{AFX_DATA_INIT(CServerPropertyPageProducts)
|
||
|
//}}AFX_DATA_INIT
|
||
|
|
||
|
m_pServer = NULL;
|
||
|
m_pUpdateHint = NULL;
|
||
|
m_bAreCtrlsInitialized = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
CServerPropertyPageProducts::~CServerPropertyPageProducts()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Destructor for server property page (products).
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
//
|
||
|
// Nothing to do here...
|
||
|
//
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::DoDataExchange(CDataExchange* pDX)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Called by framework to exchange dialog data.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pDX - data exchange object.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
CPropertyPage::DoDataExchange(pDX);
|
||
|
//{{AFX_DATA_MAP(CServerPropertyPageProducts)
|
||
|
DDX_Control(pDX, IDC_PP_SERVER_PRODUCTS_EDIT, m_edtBtn);
|
||
|
DDX_Control(pDX, IDC_PP_SERVER_PRODUCTS_PRODUCTS, m_productList);
|
||
|
//}}AFX_DATA_MAP
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::InitCtrls()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Initializes property page controls.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
m_productList.SetFocus();
|
||
|
m_edtBtn.EnableWindow(FALSE);
|
||
|
|
||
|
m_bAreCtrlsInitialized = TRUE;
|
||
|
|
||
|
::LvInitColumns(&m_productList, &g_productColumnInfo);
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::InitPage(CServer* pServer, DWORD* pUpdateHint)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Initializes property page.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pServer - Server object.
|
||
|
pUpdateHint - update hint.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
ASSERT(pUpdateHint);
|
||
|
VALIDATE_OBJECT(pServer, CServer);
|
||
|
|
||
|
m_pServer = pServer;
|
||
|
m_pUpdateHint = pUpdateHint;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::AbortPageIfNecessary()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Displays status and aborts if connection lost.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
theApp.DisplayLastStatus();
|
||
|
|
||
|
if ( IsConnectionDropped( LlsGetLastStatus() )
|
||
|
|| ( ERROR_ACCESS_DENIED == LlsGetLastStatus() )
|
||
|
|| ( STATUS_ACCESS_DENIED == LlsGetLastStatus() ) )
|
||
|
{
|
||
|
AbortPage(); // bail...
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::AbortPage()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Aborts property page.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
// *m_pUpdateHint = UPDATE_INFO_ABORT;
|
||
|
GetParent()->PostMessage(WM_COMMAND, IDCANCEL);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CServerPropertyPageProducts::OnInitDialog()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Message handler for WM_INITDIALOG.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
Returns false if focus set manually.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
CPropertyPage::OnInitDialog();
|
||
|
|
||
|
PostMessage(WM_COMMAND, ID_INIT_CTRLS);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::OnDestroy()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Message handler for WM_DESTROY.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
::LvReleaseObArray(&m_productList); // release now...
|
||
|
CPropertyPage::OnDestroy();
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CServerPropertyPageProducts::OnSetActive()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Activates property page.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
Returns true if focus accepted.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
BOOL bIsActivated;
|
||
|
|
||
|
if (bIsActivated = CPropertyPage::OnSetActive())
|
||
|
{
|
||
|
if (IsServiceInfoUpdated(*m_pUpdateHint) && !RefreshCtrls())
|
||
|
{
|
||
|
AbortPageIfNecessary(); // display error...
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bIsActivated;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CServerPropertyPageProducts::RefreshCtrls()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Refreshs property page controls.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
Returns true if controls refreshed successfully.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
VALIDATE_OBJECT(m_pServer, CServer);
|
||
|
|
||
|
BOOL bIsRefreshed = FALSE;
|
||
|
|
||
|
VARIANT va;
|
||
|
VariantInit(&va);
|
||
|
|
||
|
BeginWaitCursor(); // hourglass...
|
||
|
|
||
|
CServices* pServices = (CServices*)MKOBJ(m_pServer->GetServices(va));
|
||
|
|
||
|
if (pServices)
|
||
|
{
|
||
|
VALIDATE_OBJECT(pServices, CServices);
|
||
|
|
||
|
bIsRefreshed = ::LvRefreshObArray(
|
||
|
&m_productList,
|
||
|
&g_productColumnInfo,
|
||
|
pServices->m_pObArray
|
||
|
);
|
||
|
|
||
|
pServices->InternalRelease(); // add ref'd individually...
|
||
|
}
|
||
|
|
||
|
if (!bIsRefreshed)
|
||
|
{
|
||
|
::LvReleaseObArray(&m_productList); // reset list now...
|
||
|
}
|
||
|
|
||
|
EndWaitCursor(); // hourglass...
|
||
|
|
||
|
PostMessage(WM_COMMAND, ID_INIT_CTRLS);
|
||
|
|
||
|
return bIsRefreshed;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::OnEdit()
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
View licensing mode of service.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
CService* pService;
|
||
|
|
||
|
if (pService = (CService*)::LvGetSelObj(&m_productList))
|
||
|
{
|
||
|
VALIDATE_OBJECT(pService, CService);
|
||
|
|
||
|
CLicensingModeDialog lmodDlg;
|
||
|
lmodDlg.InitDialog(pService);
|
||
|
lmodDlg.DoModal();
|
||
|
|
||
|
*m_pUpdateHint |= lmodDlg.m_fUpdateHint;
|
||
|
|
||
|
if (IsUpdateAborted(lmodDlg.m_fUpdateHint))
|
||
|
{
|
||
|
AbortPage(); // don't display error...
|
||
|
}
|
||
|
else if (IsServiceInfoUpdated(lmodDlg.m_fUpdateHint) && !RefreshCtrls())
|
||
|
{
|
||
|
AbortPageIfNecessary(); // display error...
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::OnDblClkProducts(NMHDR* pNMHDR, LRESULT* pResult)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Notification handler for NM_DBLCLK.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pNMHDR - notification header.
|
||
|
pResult - return code.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
OnEdit();
|
||
|
*pResult = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::OnReturnProducts(NMHDR* pNMHDR, LRESULT* pResult)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Notification handler for NM_RETURN.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pNMHDR - notification header.
|
||
|
pResult - return code.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
OnEdit();
|
||
|
*pResult = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::OnSetFocusProducts(NMHDR* pNMHDR, LRESULT* pResult)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Notification handler for NM_SETFOCUS.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pNMHDR - notification header.
|
||
|
pResult - return code.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
PostMessage(WM_COMMAND, ID_INIT_CTRLS);
|
||
|
*pResult = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::OnKillFocusProducts(NMHDR* pNMHDR, LRESULT* pResult)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Notification handler for NM_KILLFOCUS.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pNMHDR - notification header.
|
||
|
pResult - return code.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
::LvSelObjIfNecessary(&m_productList); // ensure selection...
|
||
|
|
||
|
PostMessage(WM_COMMAND, ID_INIT_CTRLS);
|
||
|
*pResult = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CServerPropertyPageProducts::OnCommand(WPARAM wParam, LPARAM lParam)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Message handler for WM_COMMAND.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
wParam - message specific.
|
||
|
lParam - message specific.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
Returns true if message processed.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
if (wParam == ID_INIT_CTRLS)
|
||
|
{
|
||
|
if (!m_bAreCtrlsInitialized)
|
||
|
{
|
||
|
InitCtrls();
|
||
|
|
||
|
if (!RefreshCtrls())
|
||
|
{
|
||
|
AbortPageIfNecessary(); // display error...
|
||
|
}
|
||
|
}
|
||
|
|
||
|
::SafeEnableWindow(
|
||
|
&m_edtBtn,
|
||
|
&m_productList,
|
||
|
CDialog::GetFocus(),
|
||
|
m_productList.GetItemCount()
|
||
|
);
|
||
|
|
||
|
return TRUE; // processed...
|
||
|
}
|
||
|
|
||
|
return CDialog::OnCommand(wParam, lParam);
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::OnColumnClickProducts(NMHDR* pNMHDR, LRESULT* pResult)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Notification handler for LVN_COLUMNCLICK.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pNMHDR - notification header.
|
||
|
pResult - return code.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
g_productColumnInfo.bSortOrder = GetKeyState(VK_CONTROL) < 0;
|
||
|
g_productColumnInfo.nSortedItem = ((NM_LISTVIEW*)pNMHDR)->iSubItem;
|
||
|
|
||
|
m_productList.SortItems(CompareServerProducts, 0); // use column info
|
||
|
|
||
|
*pResult = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CServerPropertyPageProducts::OnGetDispInfoProducts(NMHDR* pNMHDR, LRESULT* pResult)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Notification handler for LVN_GETDISPINFO.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pNMHDR - notification header.
|
||
|
pResult - return code.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
CString strLabel;
|
||
|
LV_ITEM* plvItem = &((LV_DISPINFO*)pNMHDR)->item;
|
||
|
|
||
|
CService* pService = (CService*)plvItem->lParam;
|
||
|
VALIDATE_OBJECT(pService, CService);
|
||
|
|
||
|
switch (plvItem->iSubItem)
|
||
|
{
|
||
|
case LVID_PRODUCT:
|
||
|
{
|
||
|
plvItem->iImage = pService->IsPerServer() ? BMPI_PRODUCT_PER_SERVER : BMPI_PRODUCT_PER_SEAT;
|
||
|
BSTR bstrServiceName = pService->GetDisplayName();
|
||
|
lstrcpyn(plvItem->pszText, bstrServiceName, plvItem->cchTextMax);
|
||
|
SysFreeString(bstrServiceName);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LVID_LICENSING_MODE:
|
||
|
strLabel.LoadString(pService->IsPerServer() ? IDS_PER_SERVER : IDS_PER_SEAT);
|
||
|
lstrcpyn(plvItem->pszText, strLabel, plvItem->cchTextMax);
|
||
|
break;
|
||
|
|
||
|
case LVID_LICENSES_PURCHASED:
|
||
|
if (pService->IsPerServer())
|
||
|
{
|
||
|
strLabel.Format(_T("%ld"), pService->GetPerServerLimit());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
strLabel.LoadString(IDS_NOT_APPLICABLE);
|
||
|
}
|
||
|
lstrcpyn(plvItem->pszText, strLabel, plvItem->cchTextMax);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
*pResult = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
int CALLBACK CompareServerProducts(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Notification handler for LVM_SORTITEMS.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
lParam1 - object to sort.
|
||
|
lParam2 - object to sort.
|
||
|
lParamSort - sort criteria.
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
Same as lstrcmp.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
#define pService1 ((CService*)lParam1)
|
||
|
#define pService2 ((CService*)lParam2)
|
||
|
|
||
|
VALIDATE_OBJECT(pService1, CService);
|
||
|
VALIDATE_OBJECT(pService2, CService);
|
||
|
|
||
|
int iResult;
|
||
|
|
||
|
switch (g_productColumnInfo.nSortedItem)
|
||
|
{
|
||
|
case LVID_PRODUCT:
|
||
|
iResult = pService1->m_strName.CompareNoCase(pService2->m_strName);
|
||
|
break;
|
||
|
|
||
|
case LVID_LICENSING_MODE:
|
||
|
iResult = (DWORD)pService1->IsPerServer() - (DWORD)pService2->IsPerServer();
|
||
|
break;
|
||
|
|
||
|
case LVID_LICENSES_PURCHASED:
|
||
|
iResult = pService1->GetPerServerLimit() - pService2->GetPerServerLimit();
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
iResult = 0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return g_productColumnInfo.bSortOrder ? -iResult : iResult;
|
||
|
}
|