|
|
/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/ /**********************************************************************/
/*
dhcpcomp.cpp This file contains the derived implementations from CComponent and CComponentData for the DHCP admin snapin.
FILE HISTORY: */
#include "stdafx.h"
#include "dhcpcomp.h"
#include "croot.h"
#include "server.h"
#include "servbrow.h"
#include <util.h> // for InitWatermarkInfo
#include <atlimpl.cpp>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
#define DHCPSNAP_HELP_FILE_NAME "dhcpsnap.chm"
LARGE_INTEGER gliDhcpsnapVersion; CAuthServerList g_AuthServerList;
WATERMARKINFO g_WatermarkInfoServer = {0}; WATERMARKINFO g_WatermarkInfoScope = {0};
UINT aColumns[DHCPSNAP_NODETYPE_MAX][MAX_COLUMNS] = { {IDS_ROOT_NAME, IDS_STATUS, 0, 0, 0, 0, 0}, {IDS_DHCPSERVER_NAME, IDS_STATUS, IDS_DESCRIPTION, 0, 0, 0, 0}, {IDS_BOOT_IMAGE, IDS_FILE_NAME, IDS_FILE_SERVER, 0, 0, 0, 0}, {IDS_SUPERSCOPE_NAME, IDS_STATUS, IDS_DESCRIPTION, 0, 0, 0, 0}, {IDS_SCOPE_NAME, 0, 0, 0, 0, 0, 0}, {IDS_SCOPE_NAME, 0, 0, 0, 0, 0, 0}, {IDS_START_IP_ADDR, IDS_END_IP_ADDR, IDS_DESCRIPTION, 0, 0, 0, 0}, {IDS_CLIENT_IP_ADDR, IDS_NAME, IDS_LEASE, IDS_TYPE, IDS_UID, IDS_COMMENT, 0}, {IDS_CLIENT_IP_ADDR, IDS_NAME, IDS_LEASE_START, IDS_LEASE, IDS_CLIENT_ID, 0, 0}, {IDS_RESERVATIONS_FOLDER, 0, 0, 0, 0, 0, 0}, {IDS_OPTION_NAME, IDS_VENDOR, IDS_VALUE, IDS_CLASS, 0, 0, 0}, {IDS_OPTION_NAME, IDS_VENDOR, IDS_VALUE, IDS_CLASS, 0, 0, 0}, {IDS_OPTION_NAME, IDS_VENDOR, IDS_VALUE, IDS_CLASS, 0, 0, 0}, {IDS_NAME, IDS_COMMENT, 0, 0, 0, 0, 0}, {0,0,0,0,0,0,0} };
//
// CODEWORK this should be in a resource, for example code on loading data resources see
// D:\nt\private\net\ui\common\src\applib\applib\lbcolw.cxx ReloadColumnWidths()
// JonN 10/11/96
//
int aColumnWidths[DHCPSNAP_NODETYPE_MAX][MAX_COLUMNS] = { {200 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_ROOT
{250 ,150 ,200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SERVER
{175 ,175 ,175 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_BOOTP_TABLE
{200 ,150 ,200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SUPERSCOPE
{150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SCOPE
{150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_MSCOPE
{150 ,150 ,250 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_ADDRESS_POOL
{125 ,125 ,200 ,75 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_ACTIVE_LEASES
{125 ,125 ,200 ,200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_MSCOPE_LEASES
{200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_RESERVATIONS
{175 ,100 ,200 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_RESERVATION_CLIENT
{175 ,100 ,200 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SCOPE_OPTIONS
{175 ,100 ,200 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SERVER_OPTIONS
{175 ,200 ,200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH} // DHCPSNAP_CLASSID_HOLDER
};
// array to hold all of the possible toolbar buttons
MMCBUTTON g_SnapinButtons[] = { { TOOLBAR_IDX_ADD_SERVER, IDS_ADD_SERVER, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_REFRESH, IDS_REFRESH, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_CREATE_SCOPE, IDS_CREATE_NEW_SCOPE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_CREATE_SUPERSCOPE, IDS_CREATE_NEW_SUPERSCOPE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_DEACTIVATE, IDS_DEACTIVATE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_ACTIVATE, IDS_ACTIVATE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_ADD_BOOTP, IDS_CREATE_NEW_BOOT_IMAGE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_ADD_RESERVATION, IDS_CREATE_NEW_RESERVATION, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_ADD_EXCLUSION, IDS_CREATE_NEW_EXCLUSION, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_OPTION_GLOBAL, IDS_CREATE_OPTION_GLOBAL, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_OPTION_SCOPE, IDS_CREATE_OPTION_SCOPE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, { TOOLBAR_IDX_OPTION_RESERVATION,IDS_CREATE_OPTION_RESERVATION, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL }, };
// array to hold resource IDs for the toolbar button text
int g_SnapinButtonStrings[TOOLBAR_IDX_MAX][2] = { {IDS_TB_TEXT_ADD_SERVER, IDS_TB_TOOLTIP_ADD_SERVER}, // TOOLBAR_IDX_ADD_SERVER
{IDS_TB_TEXT_REFRESH, IDS_TB_TOOLTIP_REFRESH}, // TOOLBAR_IDX_REFRESH
{IDS_TB_TEXT_CREATE_SCOPE, IDS_TB_TOOLTIP_CREATE_SCOPE}, // TOOLBAR_IDX_CREATE_SCOPE
{IDS_TB_TEXT_CREATE_SUPERSCOPE, IDS_TB_TOOLTIP_CREATE_SUPERSCOPE}, // TOOLBAR_IDX_CREATE_SUPERSCOPE
{IDS_TB_TEXT_DEACTIVATE, IDS_TB_TOOLTIP_DEACTIVATE}, // TOOLBAR_IDX_DEACTIVATE
{IDS_TB_TEXT_ACTIVATE, IDS_TB_TOOLTIP_ACTIVATE}, // TOOLBAR_IDX_ACTIVATE
{IDS_TB_TEXT_ADD_BOOTP, IDS_TB_TOOLTIP_ADD_BOOTP}, // TOOLBAR_IDX_ADD_BOOTP
{IDS_TB_TEXT_ADD_RESERVATION, IDS_TB_TOOLTIP_ADD_RESERVATION}, // TOOLBAR_IDX_ADD_RESERVATION
{IDS_TB_TEXT_ADD_EXCLUSION, IDS_TB_TOOLTIP_ADD_EXCLUSION}, // TOOLBAR_IDX_ADD_EXCLUSION
{IDS_TB_TEXT_OPTION_GLOBAL, IDS_TB_TOOLTIP_OPTION_GLOBAL}, // TOOLBAR_IDX_OPTION_GLOBAL
{IDS_TB_TEXT_OPTION_SCOPE, IDS_TB_TOOLTIP_OPTION_SCOPE}, // TOOLBAR_IDX_OPTION_SCOPE
{IDS_TB_TEXT_OPTION_RESERVATION, IDS_TB_TOOLTIP_OPTION_RESERVATION}, // TOOLBAR_IDX_OPTION_RESERVATION
};
#define HI HIDDEN
#define EN ENABLED
// default states for the toolbar buttons (only scope pane items have toolbar buttons)
MMC_BUTTON_STATE g_SnapinButtonStates[DHCPSNAP_NODETYPE_MAX][TOOLBAR_IDX_MAX] = { {EN, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ROOT
{HI, HI, EN, EN, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_SERVER
{HI, HI, HI, HI, HI, HI, EN, HI, HI, HI, HI, HI}, // DHCPSNAP_BOOTP_TABLE
{HI, HI, EN, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_SUPERSCOPE
{HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_SCOPE
{HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_MSCOPE
{HI, HI, HI, HI, HI, HI, HI, HI, EN, HI, HI, HI}, // DHCPSNAP_ADDRESS_POOL
{HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ACTIVE_LEASES
{HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_MSCOPE_LEASES
{HI, HI, HI, HI, HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_RESERVATIONS
{HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, EN}, // DHCPSNAP_RESERVATION_CLIENT
{HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_SCOPE_OPTIONS
{HI, HI, HI, HI, HI, HI, HI, HI, HI, EN, HI, HI}, // DHCPSNAP_SERVER_OPTIONS
{HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_CLASSID_HOLDER
};
MMC_CONSOLE_VERB g_ConsoleVerbs[] = { MMC_VERB_OPEN, MMC_VERB_COPY, MMC_VERB_PASTE, MMC_VERB_DELETE, MMC_VERB_PROPERTIES, MMC_VERB_RENAME, MMC_VERB_REFRESH, MMC_VERB_PRINT };
// default states for the console verbs
MMC_BUTTON_STATE g_ConsoleVerbStates[DHCPSNAP_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] = { {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ROOT
{HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_SERVER
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_BOOTP_TABLE
{HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_SUPERSCOPE
{HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_SCOPE
{HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_MSCOPE
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_ADDRESS_POOL
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_ACTIVE_LEASES
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_MSCOPE_LEASES
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_RESERVATIONS
{HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_RESERVATION_CLIENT
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_SCOPE_OPTIONS
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_SERVER_OPTIONS
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_CLASSID_HOLDER
{HI, HI, HI, EN, HI, HI, EN, HI}, // DHCPSNAP_ACTIVE_LEASE
{HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_ALLOCATION_RANGE
{HI, HI, HI, EN, HI, HI, EN, HI}, // DHCPSNAP_EXCLUSION_RANGE
{HI, HI, HI, EN, HI, HI, EN, HI}, // DHCPSNAP_BOOTP_ENTRY
{HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_OPTION_ITEM
{HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_CLASSID
{HI, HI, HI, EN, HI, HI, EN, HI} // DHCPSNAP_MCAST_LEASE
};
// default states for the console verbs
MMC_BUTTON_STATE g_ConsoleVerbStatesMultiSel[DHCPSNAP_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] = { {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ROOT
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_SERVER
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_BOOTP_TABLE
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_SUPERSCOPE
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_SCOPE
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_MSCOPE
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_ADDRESS_POOL
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_ACTIVE_LEASES
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_MSCOPE_LEASES
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_RESERVATIONS
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_RESERVATION_CLIENT
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_SCOPE_OPTIONS
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_SERVER_OPTIONS
{HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_CLASSID_HOLDER
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ACTIVE_LEASE
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ALLOCATION_RANGE
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_EXCLUSION_RANGE
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_BOOTP_ENTRY
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_OPTION_ITEM
{HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_CLASSID
{HI, HI, HI, HI, HI, HI, HI, HI} // DHCPSNAP_MCAST_LEASE
};
// Help ID array for help on scope items
DWORD g_dwMMCHelp[DHCPSNAP_NODETYPE_MAX] = { DHCPSNAP_HELP_ROOT, // DHCPSNAP_ROOT
DHCPSNAP_HELP_SERVER, // DHCPSNAP_SERVER
DHCPSNAP_HELP_BOOTP_TABLE, // DHCPSNAP_BOOTP_TABLE
DHCPSNAP_HELP_SUPERSCOPE, // DHCPSNAP_SUPERSCOPE
DHCPSNAP_HELP_SCOPE, // DHCPSNAP_SCOPE
DHCPSNAP_HELP_MSCOPE, // DHCPSNAP_MSCOPE
DHCPSNAP_HELP_ADDRESS_POOL, // DHCPSNAP_ADDRESS_POOL
DHCPSNAP_HELP_ACTIVE_LEASES, // DHCPSNAP_ACTIVE_LEASES
DHCPSNAP_HELP_ACTIVE_LEASES, // DHCPSNAP_MSCOPE_LEASES
DHCPSNAP_HELP_RESERVATIONS, // DHCPSNAP_RESERVATIONS
DHCPSNAP_HELP_RESERVATION_CLIENT, // DHCPSNAP_RESERVATION_CLIENT
DHCPSNAP_HELP_SCOPE_OPTIONS, // DHCPSNAP_SCOPE_OPTIONS
DHCPSNAP_HELP_GLOBAL_OPTIONS, // DHCPSNAP_SERVER_OPTIONS
DHCPSNAP_HELP_CLASSID_HOLDER, // DHCPSNAP_CLASSID_HOLDER
DHCPSNAP_HELP_ACTIVE_LEASE, // DHCPSNAP_ACTIVE_LEASE
DHCPSNAP_HELP_ALLOCATION_RANGE, // DHCPSNAP_ALLOCATION_RANGE
DHCPSNAP_HELP_EXCLUSION_RANGE, // DHCPSNAP_EXCLUSION_RANGE
DHCPSNAP_HELP_BOOTP_ENTRY, // DHCPSNAP_BOOTP_ENTRY
DHCPSNAP_HELP_OPTION_ITEM, // DHCPSNAP_OPTION_ITEM
DHCPSNAP_HELP_CLASSID, // DHCPSNAP_CLASSID
DHCPSNAP_HELP_MCAST_LEASE // DHCPSNAP_MCAST_LEASE
};
// help mapper for dialogs and property pages
struct ContextHelpMap { UINT uID; const DWORD * pdwMap; };
ContextHelpMap g_uContextHelp[DHCPSNAP_NUM_HELP_MAPS] = { {IDD_ADD_SERVER, g_aHelpIDs_IDD_ADD_SERVER}, {IDD_ADD_TO_SUPERSCOPE, g_aHelpIDs_IDD_ADD_TO_SUPERSCOPE}, {IDD_BINARY_EDITOR, g_aHelpIDs_IDD_BINARY_EDITOR}, {IDD_BOOTP_NEW, g_aHelpIDs_IDD_BOOTP_NEW}, {IDD_BROWSE_SERVERS, g_aHelpIDs_IDD_BROWSE_SERVERS}, {IDD_CLASSES, g_aHelpIDs_IDD_CLASSES}, {IDD_CLASSID_NEW, g_aHelpIDs_IDD_CLASSID_NEW}, {IDD_CREDENTIALS, g_aHelpIDs_IDD_CREDENTIALS}, {IDD_DATA_ENTRY_BINARY, g_aHelpIDs_IDD_DATA_ENTRY_BINARY}, {IDD_DATA_ENTRY_BINARY_ARRAY, g_aHelpIDs_IDD_DATA_ENTRY_BINARY_ARRAY}, {IDD_DATA_ENTRY_DWORD, g_aHelpIDs_IDD_DATA_ENTRY_DWORD}, {IDD_DATA_ENTRY_IPADDRESS, g_aHelpIDs_IDD_DATA_ENTRY_IPADDRESS}, {IDD_DATA_ENTRY_IPADDRESS_ARRAY, g_aHelpIDs_IDD_DATA_ENTRY_IPADDRESS_ARRAY}, {IDD_DATA_ENTRY_NONE, NULL}, {IDD_DATA_ENTRY_STRING, g_aHelpIDs_IDD_DATA_ENTRY_STRING}, {IDD_DATA_ENTRY_ROUTE_ARRAY, g_aHelpIDs_IDD_DATA_ENTRY_ROUTE_ARRAY}, {IDD_DEFAULT_VALUE, g_aHelpIDs_IDD_DEFAULT_VALUE}, {IDD_DEFINE_PARAM, g_aHelpIDs_IDD_DEFINE_PARAM}, {IDD_EXCLUSION_NEW, g_aHelpIDs_IDD_EXCLUSION_NEW}, {IDD_GET_SERVER, g_aHelpIDs_IDD_GET_SERVER}, {IDD_GET_SERVER_CONFIRM, g_aHelpIDs_IDD_GET_SERVER_CONFIRM}, {IDD_IP_ARRAY_EDIT, g_aHelpIDs_IDD_IP_ARRAY_EDIT}, {IDD_RECONCILIATION, g_aHelpIDs_IDD_RECONCILIATION}, {IDD_RESERVATION_NEW, g_aHelpIDs_IDD_RESERVATION_NEW}, {IDD_SERVER_BINDINGS, g_aHelpIDs_IDD_SERVER_BINDINGS}, {IDD_STATS_NARROW, NULL}, {IDP_BOOTP_GENERAL, g_aHelpIDs_IDP_BOOTP_GENERAL}, {IDP_DNS_INFORMATION, g_aHelpIDs_IDP_DNS_INFORMATION}, {IDP_MSCOPE_GENERAL, g_aHelpIDs_IDP_MSCOPE_GENERAL}, {IDP_MSCOPE_LIFETIME, g_aHelpIDs_IDP_MSCOPE_LIFETIME}, {IDP_OPTION_ADVANCED, g_aHelpIDs_IDP_OPTION_ADVANCED}, {IDP_OPTION_BASIC, g_aHelpIDs_IDP_OPTION_BASIC}, {IDP_RESERVED_CLIENT_GENERAL, g_aHelpIDs_IDP_RESERVED_CLIENT_GENERAL}, {IDP_SCOPE_ADVANCED, g_aHelpIDs_IDP_SCOPE_ADVANCED}, {IDP_SCOPE_GENERAL, g_aHelpIDs_IDP_SCOPE_GENERAL}, {IDP_SERVER_ADVANCED, g_aHelpIDs_IDP_SERVER_ADVANCED}, {IDP_SERVER_GENERAL, g_aHelpIDs_IDP_SERVER_GENERAL}, {IDP_SUPERSCOPE_GENERAL, g_aHelpIDs_IDP_SUPERSCOPE_GENERAL}, {IDD_ADD_ROUTE_DIALOG, g_aHelpIDs_IDD_ADD_ROUTE_DIALOG}, {IDD_ROUTE_ARRAY_EDIT, g_aHelpIDs_IDD_ROUTE_ARRAY_EDIT}, {IDD_STRING_ARRAY_EDIT, g_aHelpIDs_IDD_STRING_ARRAY_EDIT}, };
CDhcpContextHelpMap g_dhcpContextHelpMap;
DWORD * DhcpGetHelpMap(UINT uID) { DWORD * pdwMap = NULL; g_dhcpContextHelpMap.Lookup(uID, pdwMap); return pdwMap; }
UINT g_uIconMap[ICON_IDX_MAX + 1][2] = { {IDI_ICON01, ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN}, {IDI_ICON02, ICON_IDX_ACTIVE_LEASES_LEAF}, {IDI_ICON03, ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED}, {IDI_ICON04, ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN_BUSY}, {IDI_ICON05, ICON_IDX_ACTIVE_LEASES_LEAF_BUSY}, {IDI_ICON06, ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED_BUSY}, {IDI_ICON07, ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN_LOST_CONNECTION}, {IDI_ICON08, ICON_IDX_ACTIVE_LEASES_LEAF_LOST_CONNECTION}, {IDI_ICON09, ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED_LOST_CONNECTION}, {IDI_ICON10, ICON_IDX_ADDR_POOL_FOLDER_OPEN}, {IDI_ICON11, ICON_IDX_ADDR_POOL_LEAF}, {IDI_ICON12, ICON_IDX_ADDR_POOL_FOLDER_CLOSED}, {IDI_ICON13, ICON_IDX_ADDR_POOL_FOLDER_OPEN_BUSY}, {IDI_ICON14, ICON_IDX_ADDR_POOL_LEAF_BUSY}, {IDI_ICON15, ICON_IDX_ADDR_POOL_FOLDER_CLOSED_BUSY}, {IDI_ICON16, ICON_IDX_ADDR_POOL_FOLDER_OPEN_LOST_CONNECTION}, {IDI_ICON17, ICON_IDX_ADDR_POOL_LEAF_LOST_CONNECTION}, {IDI_ICON18, ICON_IDX_ADDR_POOL_FOLDER_CLOSED_LOST_CONNECTION}, {IDI_ICON19, ICON_IDX_ALLOCATION_RANGE}, {IDI_ICON20, ICON_IDX_BOOTP_ENTRY}, {IDI_ICON21, ICON_IDX_BOOTP_TABLE_CLOSED}, {IDI_ICON22, ICON_IDX_BOOTP_TABLE_OPEN}, {IDI_ICON87, ICON_IDX_BOOTP_TABLE_OPEN_LOST_CONNECTION}, {IDI_ICON88, ICON_IDX_BOOTP_TABLE_OPEN_BUSY}, {IDI_ICON89, ICON_IDX_BOOTP_TABLE_CLOSED_LOST_CONNECTION}, {IDI_ICON90, ICON_IDX_BOOTP_TABLE_CLOSED_BUSY}, {IDI_ICON23, ICON_IDX_CLIENT}, {IDI_ICON24, ICON_IDX_CLIENT_DNS_REGISTERING}, {IDI_ICON25, ICON_IDX_CLIENT_EXPIRED}, {IDI_ICON26, ICON_IDX_CLIENT_RAS}, {IDI_ICON27, ICON_IDX_CLIENT_OPTION_FOLDER_OPEN}, {IDI_ICON28, ICON_IDX_CLIENT_OPTION_LEAF}, {IDI_ICON29, ICON_IDX_CLIENT_OPTION_FOLDER_CLOSED}, {IDI_ICON30, ICON_IDX_CLIENT_OPTION_FOLDER_OPEN_BUSY}, {IDI_ICON31, ICON_IDX_CLIENT_OPTION_LEAF_BUSY}, {IDI_ICON32, ICON_IDX_CLIENT_OPTION_FOLDER_CLOSED_BUSY}, {IDI_ICON33, ICON_IDX_CLIENT_OPTION_FOLDER_OPEN_LOST_CONNECTION}, {IDI_ICON34, ICON_IDX_CLIENT_OPTION_LEAF_LOST_CONNECTION}, {IDI_ICON35, ICON_IDX_CLIENT_OPTION_FOLDER_CLOSED_LOST_CONNECTION}, {IDI_ICON36, ICON_IDX_EXCLUSION_RANGE}, {IDI_ICON37, ICON_IDX_FOLDER_CLOSED}, {IDI_ICON38, ICON_IDX_FOLDER_OPEN}, {IDI_ICON39, ICON_IDX_RES_CLIENT}, {IDI_ICON40, ICON_IDX_RES_CLIENT_BUSY}, {IDI_ICON41, ICON_IDX_RES_CLIENT_LOST_CONNECTION}, {IDI_ICON42, ICON_IDX_RESERVATIONS_FOLDER_OPEN}, {IDI_ICON43, ICON_IDX_RESERVATIONS_FOLDER_CLOSED}, {IDI_ICON44, ICON_IDX_RESERVATIONS_FOLDER_OPEN_BUSY}, {IDI_ICON45, ICON_IDX_RESERVATIONS_FOLDER_CLOSED_BUSY}, {IDI_ICON46, ICON_IDX_RESERVATIONS_FOLDER_OPEN_LOST_CONNECTION}, {IDI_ICON47, ICON_IDX_RESERVATIONS_FOLDER_CLOSED_LOST_CONNECTION}, {IDI_ICON48, ICON_IDX_SCOPE_OPTION_FOLDER_OPEN}, {IDI_ICON49, ICON_IDX_SCOPE_OPTION_LEAF}, {IDI_ICON50, ICON_IDX_SCOPE_OPTION_FOLDER_CLOSED}, {IDI_ICON51, ICON_IDX_SCOPE_OPTION_FOLDER_OPEN_BUSY}, {IDI_ICON52, ICON_IDX_SCOPE_OPTION_LEAF_BUSY}, {IDI_ICON53, ICON_IDX_SCOPE_OPTION_FOLDER_CLOSED_BUSY}, {IDI_ICON54, ICON_IDX_SCOPE_OPTION_FOLDER_OPEN_LOST_CONNECTION}, {IDI_ICON55, ICON_IDX_SCOPE_OPTION_FOLDER_CLOSED_LOST_CONNECTION}, {IDI_ICON56, ICON_IDX_SCOPE_OPTION_LEAF_LOST_CONNECTION}, {IDI_ICON57, ICON_IDX_SERVER}, {IDI_ICON58, ICON_IDX_SERVER_WARNING}, {IDI_ICON59, ICON_IDX_SERVER_BUSY}, {IDI_ICON60, ICON_IDX_SERVER_CONNECTED}, {IDI_ICON61, ICON_IDX_SERVER_GROUP}, {IDI_ICON62, ICON_IDX_SERVER_ROGUE}, {IDI_ICON63, ICON_IDX_SERVER_LOST_CONNECTION}, {IDI_ICON64, ICON_IDX_SERVER_NO_ACCESS}, {IDI_ICON65, ICON_IDX_SERVER_ALERT}, {IDI_ICON66, ICON_IDX_SERVER_OPTION_FOLDER_OPEN}, {IDI_ICON67, ICON_IDX_SERVER_OPTION_LEAF}, {IDI_ICON68, ICON_IDX_SERVER_OPTION_FOLDER_CLOSED}, {IDI_ICON69, ICON_IDX_SERVER_OPTION_FOLDER_OPEN_BUSY}, {IDI_ICON70, ICON_IDX_SERVER_OPTION_LEAF_BUSY}, {IDI_ICON71, ICON_IDX_SERVER_OPTION_FOLDER_CLOSED_BUSY}, {IDI_ICON72, ICON_IDX_SERVER_OPTION_FOLDER_OPEN_LOST_CONNECTION}, {IDI_ICON73, ICON_IDX_SERVER_OPTION_LEAF_LOST_CONNECTION}, {IDI_ICON74, ICON_IDX_SERVER_OPTION_FOLDER_CLOSED_LOST_CONNECTION}, {IDI_ICON75, ICON_IDX_SCOPE_FOLDER_OPEN}, {IDI_ICON91, ICON_IDX_SCOPE_FOLDER_OPEN_BUSY}, {IDI_ICON92, ICON_IDX_SCOPE_FOLDER_CLOSED_BUSY}, {IDI_ICON76, ICON_IDX_SCOPE_FOLDER_OPEN_WARNING}, {IDI_ICON77, ICON_IDX_SCOPE_FOLDER_CLOSED_WARNING}, {IDI_ICON78, ICON_IDX_SCOPE_FOLDER_OPEN_LOST_CONNECTION}, {IDI_ICON79, ICON_IDX_SCOPE_FOLDER_CLOSED_LOST_CONNECTION}, {IDI_ICON80, ICON_IDX_SCOPE_FOLDER_OPEN_ALERT}, {IDI_ICON81, ICON_IDX_SCOPE_INACTIVE_FOLDER_OPEN}, {IDI_ICON82, ICON_IDX_SCOPE_INACTIVE_FOLDER_CLOSED}, {IDI_ICON83, ICON_IDX_SCOPE_INACTIVE_FOLDER_OPEN_LOST_CONNECTION}, {IDI_ICON84, ICON_IDX_SCOPE_INACTIVE_FOLDER_CLOSED_LOST_CONNECTION}, {IDI_ICON85, ICON_IDX_SCOPE_FOLDER_CLOSED}, {IDI_ICON86, ICON_IDX_SCOPE_FOLDER_CLOSED_ALERT}, {IDI_DHCP_SNAPIN, ICON_IDX_APPLICATION}, {0, 0} };
/*!--------------------------------------------------------------------------
FilterOption Filters returns whether or not to filter out the given option. Some options we don't want the user to see. Author: EricDav ---------------------------------------------------------------------------*/ BOOL FilterOption ( DHCP_OPTION_ID id ) { //
// Filter out subnet mask, lease duration,
// T1, and T2
//
return (id == 1 || // Subnet mask
id == 51 || // Client Lease Time
id == 58 || // Time between addr assignment to RENEWING state
id == 59 || // Time from addr assignment to REBINDING state
id == 81); // Client DNS name registration
}
/*!--------------------------------------------------------------------------
FilterUserClassOption Filters returns whether or not to filter out the given option for a user class. Some options we don't want the user to see. Author: EricDav ---------------------------------------------------------------------------*/ BOOL FilterUserClassOption ( DHCP_OPTION_ID id ) { //
// Filter out subnet mask,
// T1, and T2
//
return (id == 1 || // Subnet mask
id == 58 || // Time between addr assignment to RENEWING state
id == 59 || // Time from addr assignment to REBINDING state
id == 81); // Client DNS name registration
}
/*!--------------------------------------------------------------------------
IsBasicOption Returns whether the given option is what we've defined as a basic option. Author: EricDav ---------------------------------------------------------------------------*/ BOOL IsBasicOption ( DHCP_OPTION_ID id ) { //
// Basic Options are:
// Router
// DNS Server
// Domain Name
// WINS/NBNS Servers
// WINS/NBT Node Type
//
return (id == 3 || id == 6 || id == 15 || id == 44 || id == 46); }
/*!--------------------------------------------------------------------------
IsAdvancedOption Returns whether the given option is what we've defined as an advanced option. Author: EricDav ---------------------------------------------------------------------------*/ BOOL IsAdvancedOption ( DHCP_OPTION_ID id ) { //
// All non-basic and non-custom options are advanced.
//
return (id < 128 && !IsBasicOption(id)); }
/*!--------------------------------------------------------------------------
IsCustomOption Returns whether the given option is a user defined option. Author: EricDav ---------------------------------------------------------------------------*/ BOOL IsCustomOption ( DHCP_OPTION_ID id ) { //
// Custom options are anything with an id > 128
//
return (id > 128); }
/*!--------------------------------------------------------------------------
GetSystemMessage Use FormatMessage() to get a system error message Author: EricDav ---------------------------------------------------------------------------*/ LONG GetSystemMessage ( UINT nId, TCHAR * chBuffer, int cbBuffSize ) { TCHAR * pszText = NULL ; HINSTANCE hdll = NULL ;
DWORD flags = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK;
//
// Interpret the error. Need to special case
// the lmerr & ntstatus ranges, as well as
// dhcp server error messages.
//
if ( nId >= NERR_BASE && nId <= MAX_NERR ) { hdll = LoadLibraryEx( _T("netmsg.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE); } else if ( nId >= 20000 && nId <= 20099 ) { // DHCP Server error
hdll = LoadLibraryEx( _T("dhcpsapi.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE ); } else if (nId >= 0x5000 && nId < 0x50FF) { // It's an ADSI error.
hdll = LoadLibraryEx( _T("activeds.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE ); nId |= 0x80000000; } else if( nId >= 0x40000000L ) { hdll = LoadLibraryEx( _T("ntdll.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE ); }
if ( hdll == NULL ) { flags |= FORMAT_MESSAGE_FROM_SYSTEM; } else { flags |= FORMAT_MESSAGE_FROM_HMODULE; }
//
// Let FormatMessage do the dirty work.
//
DWORD dwResult = ::FormatMessage( flags, (LPVOID) hdll, nId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), chBuffer, cbBuffSize, NULL ) ;
if ( hdll != NULL ) { LONG err = GetLastError(); FreeLibrary( hdll ); if ( dwResult == 0 ) { ::SetLastError( err ); } }
return dwResult ? 0 : ::GetLastError() ; }
/*!--------------------------------------------------------------------------
LoadMessage Loads the error message from the correct DLL. Author: EricDav ---------------------------------------------------------------------------*/ BOOL LoadMessage ( UINT nIdPrompt, TCHAR * chMsg, int nMsgSize ) { BOOL bOk;
//
// Substitute a friendly message for "RPC server not
// available" and "No more endpoints available from
// the endpoint mapper".
//
if (nIdPrompt == EPT_S_NOT_REGISTERED || nIdPrompt == RPC_S_SERVER_UNAVAILABLE) { nIdPrompt = IDS_ERR_DHCP_DOWN; } else if (nIdPrompt == RPC_S_PROCNUM_OUT_OF_RANGE) { nIdPrompt = IDS_ERR_RPC_NO_ENTRY; }
//
// If it's a socket error or our error, the text is in our resource fork.
// Otherwise, use FormatMessage() and the appropriate DLL.
//
if ( (nIdPrompt >= IDS_ERR_BASE && nIdPrompt < IDS_MESG_MAX) || (nIdPrompt >= WSABASEERR && nIdPrompt < WSABASEERR + 2000) ) { //
// It's in our resource fork
//
bOk = ::LoadString( AfxGetInstanceHandle(), nIdPrompt, chMsg, nMsgSize ) != 0 ; } else { //
// It's in the system somewhere.
//
bOk = GetSystemMessage( nIdPrompt, chMsg, nMsgSize ) == 0 ; }
//
// If the error message did not compute, replace it.
//
if ( ! bOk ) { TCHAR chBuff [STRING_LENGTH_MAX] ; static const TCHAR * pszReplacement = _T("System Error: %ld"); const TCHAR * pszMsg = pszReplacement ;
//
// Try to load the generic (translatable) error message text
//
if ( ::LoadString( AfxGetInstanceHandle(), IDS_ERR_MESSAGE_GENERIC, chBuff, sizeof(chBuff)/sizeof(TCHAR) ) != 0 ) { pszMsg = chBuff ; } ::wsprintf( chMsg, pszMsg, nIdPrompt ) ; }
return bOk; }
/*!--------------------------------------------------------------------------
DhcpMessageBox Puts up a message box with the corresponding error text. Author: EricDav ---------------------------------------------------------------------------*/ int DhcpMessageBox ( DWORD dwIdPrompt, UINT nType, const TCHAR * pszSuffixString, UINT nHelpContext ) { TCHAR chMesg [4000] ; BOOL bOk ;
UINT nIdPrompt = (UINT) dwIdPrompt;
bOk = LoadMessage(nIdPrompt, chMesg, sizeof(chMesg)/sizeof(TCHAR)); if ( pszSuffixString ) { ::lstrcat( chMesg, _T(" ") ) ; ::lstrcat( chMesg, pszSuffixString ) ; }
return ::AfxMessageBox( chMesg, nType, nHelpContext ) ; }
/*!--------------------------------------------------------------------------
DhcpMessageBoxEx Puts up a message box with the corresponding error text. Author: EricDav ---------------------------------------------------------------------------*/ int DhcpMessageBoxEx ( DWORD dwIdPrompt, LPCTSTR pszPrefixMessage, UINT nType, UINT nHelpContext ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
TCHAR chMesg[4000]; CString strMessage; BOOL bOk;
UINT nIdPrompt = (UINT) dwIdPrompt;
bOk = LoadMessage(nIdPrompt, chMesg, sizeof(chMesg)/sizeof(TCHAR)); if ( pszPrefixMessage ) { strMessage = pszPrefixMessage; strMessage += _T("\n"); strMessage += _T("\n"); strMessage += chMesg; } else { strMessage = chMesg; }
return AfxMessageBox(strMessage, nType, nHelpContext); }
/*---------------------------------------------------------------------------
Class CDhcpComponent implementation ---------------------------------------------------------------------------*/ CDhcpComponent::CDhcpComponent() { m_pbmpToolbar = NULL; InitCommonControls(); }
CDhcpComponent::~CDhcpComponent() { if (m_pbmpToolbar) { delete m_pbmpToolbar; m_pbmpToolbar = NULL; } }
STDMETHODIMP CDhcpComponent::InitializeBitmaps(MMC_COOKIE cookie) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(m_spImageList != NULL); // Set the images
HICON hIcon; HRESULT hr; LPOLESTR pszGuid = NULL; long lViewOptions = 0; CLSID clsid;
CORg (GetResultViewType(cookie, &pszGuid, &lViewOptions)); CLSIDFromString(pszGuid, &clsid); CoTaskMemFree( pszGuid );
// if the result pane is not the message view then add the icons
if (clsid != CLSID_MessageView) { for (int i = 0; i < ICON_IDX_MAX; i++) { hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0])); if (hIcon) { // call mmc
hr = m_spImageList->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1]); } } } Error: return S_OK; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::QueryDataObject For multiple select we need to add things to the data object..... In order to do this we need to call into the result handler for the node Author: EricDav ---------------------------------------------------------------------------*/ STDMETHODIMP CDhcpComponent::QueryDataObject ( MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK; SPITFSNode spRootNode;
// this is a special case for multiple select. We need to build a list
// of GUIDs and the code to do this is in the handler...
if (cookie == MMC_MULTI_SELECT_COOKIE) { SPITFSNode spNode; SPITFSResultHandler spResultHandler;
CORg (GetSelectedNode(&spNode)); CORg (spNode->GetResultHandler(&spResultHandler));
spResultHandler->OnCreateDataObject(this, cookie, type, ppDataObject); } else if (cookie == MMC_WINDOW_COOKIE) { // this cookie needs the text for the static root node, so build the DO with
// the root node cookie
m_spNodeMgr->GetRootNode(&spRootNode); CORg (m_spComponentData->QueryDataObject((MMC_COOKIE) spRootNode->GetData(TFS_DATA_COOKIE), type, ppDataObject)); } else { // Delegate it to the IComponentData
Assert(m_spComponentData != NULL); CORg (m_spComponentData->QueryDataObject(cookie, type, ppDataObject)); }
Error: return hr; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::SetControlbar - Author: EricDav, KennT ---------------------------------------------------------------------------*/ HRESULT CDhcpComponent::SetControlbar ( LPCONTROLBAR pControlbar ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK; SPIToolbar spToolbar;
COM_PROTECT_TRY { if (pControlbar) { // Create the Toolbar
GetToolbar(&spToolbar);
if (!spToolbar) { CORg(pControlbar->Create(TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&spToolbar))); if (!spToolbar) goto Error;
SetToolbar(spToolbar);
// Add the bitmap
m_pbmpToolbar = new CBitmap; m_pbmpToolbar->LoadBitmap(IDB_TOOLBAR); hr = spToolbar->AddBitmap(TOOLBAR_IDX_MAX, *m_pbmpToolbar, 16, 16, RGB(192, 192, 192)); ASSERT(SUCCEEDED(hr));
// Add the buttons to the toolbar
for (int i = 0; i < TOOLBAR_IDX_MAX; i++) { CString strText, strTooltip; strText.LoadString(g_SnapinButtonStrings[i][0]); strTooltip.LoadString(g_SnapinButtonStrings[i][1]);
g_SnapinButtons[i].lpButtonText = (LPOLESTR) ((LPCTSTR) strText); g_SnapinButtons[i].lpTooltipText = (LPOLESTR) ((LPCTSTR) strTooltip);
hr = spToolbar->InsertButton(i, &g_SnapinButtons[i]); ASSERT(SUCCEEDED(hr)); } } } } COM_PROTECT_CATCH
// store the control bar away for future use
Error: m_spControlbar.Set(pControlbar);
return hr; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::ControlbarNotify - Author: EricDav ---------------------------------------------------------------------------*/ STDMETHODIMP CDhcpComponent::ControlbarNotify ( MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK; SPINTERNAL spInternal; SPITFSNode spNode; MMC_COOKIE cookie; LPDATAOBJECT pDataObject; SPIDataObject spDataObject; DHCPTOOLBARNOTIFY dhcpToolbarNotify; SPIControlBar spControlbar; SPIToolbar spToolbar; SPITFSNodeHandler spNodeHandler; SPITFSResultHandler spResultHandler; BOOL bScope; BOOL bSelect;
COM_PROTECT_TRY { CORg(GetControlbar(&spControlbar)); Assert(spControlbar != NULL);
CORg(GetToolbar(&spToolbar)); Assert(spToolbar != NULL);
// set the controlbar and toolbar pointers in the notify struct
dhcpToolbarNotify.pControlbar = spControlbar; dhcpToolbarNotify.pToolbar = spToolbar; switch (event) { case MMCN_SELECT: // extract the node information from the data object
bScope = LOWORD(arg); bSelect = HIWORD(arg); if (!bScope) { Assert(param); pDataObject = reinterpret_cast<LPDATAOBJECT>(param); if (pDataObject == NULL) return hr;
if ( IS_SPECIAL_DATAOBJECT(pDataObject) || IsMMCMultiSelectDataObject(pDataObject) ) { // CODEWORK: Do we need to do anything special to the toolbar
// during multiselect? Disable our toolbar buttons?
GetSelectedNode(&spNode); } else { CORg(ExtractNodeFromDataObject(m_spNodeMgr, m_spTFSComponentData->GetCoClassID(), pDataObject, FALSE, &spNode, NULL, &spInternal));
if (spInternal->m_type == CCT_RESULT) { // a result item was selected
cookie = spNode->GetData(TFS_DATA_COOKIE); } else { // a scope item in the result pane was selected
cookie = NULL; } } if (spNode) { CORg( spNode->GetResultHandler(&spResultHandler) );
dhcpToolbarNotify.event = event; dhcpToolbarNotify.id = param; dhcpToolbarNotify.bSelect = bSelect;
if (spResultHandler) CORg( spResultHandler->UserResultNotify(spNode, DHCP_MSG_CONTROLBAR_NOTIFY, (LPARAM) &dhcpToolbarNotify) ); } } else { dhcpToolbarNotify.cookie = 0; dhcpToolbarNotify.event = event; dhcpToolbarNotify.id = 0; dhcpToolbarNotify.bSelect = bSelect;
// check to see if an item is being deselected
Assert(param); pDataObject = reinterpret_cast<LPDATAOBJECT>(param); if (pDataObject == NULL) return hr;
CORg(ExtractNodeFromDataObject(m_spNodeMgr, m_spTFSComponentData->GetCoClassID(), pDataObject, FALSE, &spNode, NULL, &spInternal));
CORg( spNode->GetHandler(&spNodeHandler) ); if (spNodeHandler) CORg( spNodeHandler->UserNotify(spNode, DHCP_MSG_CONTROLBAR_NOTIFY, (LPARAM) &dhcpToolbarNotify) ); } break;
case MMCN_BTN_CLICK: Assert(arg); pDataObject = reinterpret_cast<LPDATAOBJECT>(arg); if (pDataObject == NULL) return hr;
if ( IS_SPECIAL_DATAOBJECT(pDataObject) ) { // get a data object for the selected node.
GetSelectedNode(&spNode);
CORg(QueryDataObject((MMC_COOKIE) spNode->GetData(TFS_DATA_COOKIE), CCT_SCOPE, &spDataObject)); spNode.Release();
pDataObject = spDataObject; }
CORg(ExtractNodeFromDataObject(m_spNodeMgr, m_spTFSComponentData->GetCoClassID(), pDataObject, FALSE, &spNode, NULL, &spInternal));
if (spInternal) { switch (spInternal->m_type) { case CCT_RESULT: cookie = spNode->GetData(TFS_DATA_COOKIE); CORg( spNode->GetResultHandler(&spResultHandler) ); dhcpToolbarNotify.cookie = cookie; dhcpToolbarNotify.event = event; dhcpToolbarNotify.id = param; dhcpToolbarNotify.bSelect = TRUE;
if (spResultHandler) CORg( spResultHandler->UserResultNotify(spNode, DHCP_MSG_CONTROLBAR_NOTIFY, (LPARAM) &dhcpToolbarNotify) );
break;
case CCT_SCOPE: CORg( spNode->GetHandler(&spNodeHandler) ); dhcpToolbarNotify.cookie = 0; dhcpToolbarNotify.event = event; dhcpToolbarNotify.id = param; dhcpToolbarNotify.bSelect = TRUE;
if (spNodeHandler) CORg( spNodeHandler->UserNotify(spNode, DHCP_MSG_CONTROLBAR_NOTIFY, (LPARAM) &dhcpToolbarNotify) ); break; default: Assert(FALSE); break; } } break;
case MMCN_DESELECT_ALL: // what are we supposed to do here???
break;
default: Panic1("CDhcpComponent::ControlbarNotify - Unknown event %d", event); break;
} COM_PROTECT_ERROR_LABEL; } COM_PROTECT_CATCH
return hr; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::OnSnapinHelp - Author: EricDav ---------------------------------------------------------------------------*/ STDMETHODIMP CDhcpComponent::OnSnapinHelp ( LPDATAOBJECT pDataObject, LPARAM arg, LPARAM param ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
HtmlHelpA(NULL, DHCPSNAP_HELP_FILE_NAME, HH_DISPLAY_TOPIC, 0);
return hr; }
/*---------------------------------------------------------------------------
Class CDhcpComponentData implementation ---------------------------------------------------------------------------*/ CDhcpComponentData::CDhcpComponentData() { gliDhcpsnapVersion.LowPart = DHCPSNAP_MINOR_VERSION; gliDhcpsnapVersion.HighPart = DHCPSNAP_MAJOR_VERSION;
// initialize our global help map
for (int i = 0; i < DHCPSNAP_NUM_HELP_MAPS; i++) { g_dhcpContextHelpMap.SetAt(g_uContextHelp[i].uID, (LPDWORD) g_uContextHelp[i].pdwMap); } }
/*!--------------------------------------------------------------------------
CDhcpComponentData::OnInitialize - Author: EricDav, KennT ---------------------------------------------------------------------------*/ STDMETHODIMP CDhcpComponentData::OnInitialize(LPIMAGELIST pScopeImage) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HICON hIcon;
// thread deletes itself
CStandaloneAuthServerWorker * pWorker = new CStandaloneAuthServerWorker(); pWorker->CreateThread();
// initialize icon images with MMC
for (int i = 0; i < ICON_IDX_MAX; i++) { hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0])); if (hIcon) { // call mmc
VERIFY(SUCCEEDED(pScopeImage->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1]))); } }
return hrOK; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::OnDestroy - Author: EricDav, KennT ---------------------------------------------------------------------------*/ STDMETHODIMP CDhcpComponentData::OnDestroy() { m_spNodeMgr.Release();
return hrOK; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::OnInitializeNodeMgr - Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP CDhcpComponentData::OnInitializeNodeMgr ( ITFSComponentData * pTFSCompData, ITFSNodeMgr * pNodeMgr ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
// For now create a new node handler for each new node,
// this is rather bogus as it can get expensive. We can
// consider creating only a single node handler for each
// node type.
CDhcpRootHandler * pHandler = NULL; SPITFSNodeHandler spHandler; SPITFSNode spNode; HRESULT hr = hrOK;
try { pHandler = new CDhcpRootHandler(pTFSCompData);
// Do this so that it will get released correctly
spHandler = pHandler; } catch(...) { hr = E_OUTOFMEMORY; } CORg( hr ); // Create the root node for this sick puppy
CORg( CreateContainerTFSNode(&spNode, &GUID_DhcpRootNodeType, pHandler, pHandler, /* result handler */ pNodeMgr) );
// Need to initialize the data for the root node
pHandler->InitializeNode(spNode);
CORg( pNodeMgr->SetRootNode(spNode) ); m_spRootNode.Set(spNode);
// setup watermark info
if (g_WatermarkInfoServer.hHeader == NULL) { // haven't been initialized yet
InitWatermarkInfo(AfxGetInstanceHandle(), &g_WatermarkInfoServer, IDB_SRVWIZ_BANNER, // Header ID
IDB_SRVWIZ_WATERMARK, // Watermark ID
NULL, // hPalette
FALSE); // bStretch
InitWatermarkInfo(AfxGetInstanceHandle(), &g_WatermarkInfoScope, IDB_SCPWIZ_BANNER, // Header ID
IDB_SCPWIZ_WATERMARK, // Watermark ID
NULL, // hPalette
FALSE); // bStretch
}
pTFSCompData->SetHTMLHelpFileName(_T(DHCPSNAP_HELP_FILE_NAME)); // disable taskpads by default
pTFSCompData->SetTaskpadState(TASKPAD_ROOT_INDEX, FALSE); pTFSCompData->SetTaskpadState(TASKPAD_SERVER_INDEX, FALSE);
Error: return hr; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::OnCreateComponent - Author: EricDav, KennT ---------------------------------------------------------------------------*/ STDMETHODIMP CDhcpComponentData::OnCreateComponent ( LPCOMPONENT *ppComponent ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(ppComponent != NULL);
HRESULT hr = hrOK; CDhcpComponent * pComp = NULL;
try { pComp = new CDhcpComponent; } catch(...) { hr = E_OUTOFMEMORY; }
if ( NULL != pComp ) { pComp->Construct( m_spNodeMgr, static_cast<IComponentData *>(this), m_spTFSComponentData ); *ppComponent = static_cast<IComponent *>(pComp); } else { hr = E_OUTOFMEMORY; } return hr; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::GetCoClassID - Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP_(const CLSID *) CDhcpComponentData::GetCoClassID() { return &CLSID_DhcpSnapin; }
/*!--------------------------------------------------------------------------
CDhcpComponentData::OnCreateDataObject - Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP CDhcpComponentData::OnCreateDataObject ( MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject ** ppDataObject ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
Assert(ppDataObject != NULL);
CDataObject * pObject = NULL; SPIDataObject spDataObject; pObject = new CDataObject; spDataObject = pObject; // do this so that it gets released correctly
Assert(pObject != NULL);
// Save cookie and type for delayed rendering
pObject->SetType(type); pObject->SetCookie(cookie);
// Store the coclass with the data object
pObject->SetClsid(*GetCoClassID());
pObject->SetTFSComponentData(m_spTFSComponentData);
return pObject->QueryInterface(IID_IDataObject, reinterpret_cast<void**>(ppDataObject)); }
///////////////////////////////////////////////////////////////////////////////
//// IPersistStream interface members
STDMETHODIMP CDhcpComponentData::GetClassID ( CLSID *pClassID ) { ASSERT(pClassID != NULL);
// Copy the CLSID for this snapin
*pClassID = CLSID_DhcpSnapin;
return hrOK; }
STDMETHODIMP CDhcpComponentData::IsDirty() { return m_spRootNode->GetData(TFS_DATA_DIRTY) ? hrOK : hrFalse; }
STDMETHODIMP CDhcpComponentData::Load ( IStream *pStm ) { HRESULT hr = hrOK; LARGE_INTEGER liSavedVersion; CString str; ASSERT(pStm);
CStringArray strArrayIp; CStringArray strArrayName; CDWordArray dwArrayServerOptions; CDWordArray dwArrayRefreshInterval; CDWordArray dwArrayColumnInfo; DWORD dwFileVersion; CDhcpRootHandler * pRootHandler; DWORD dwFlags = 0; int i, j;
ASSERT(pStm); // set the mode for this stream
XferStream xferStream(pStm, XferStream::MODE_READ); // read the version of the file format
CORg(xferStream.XferDWORD(DHCPSTRM_TAG_VERSION, &dwFileVersion)); if (dwFileVersion < DHCPSNAP_FILE_VERSION) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); AfxMessageBox(_T("This console file was saved with a previous version of the snapin and is not compatible. The settings could not be restored.")); return hr; }
// Read the version # of the admin tool
CORg(xferStream.XferLARGEINTEGER(DHCPSTRM_TAG_VERSIONADMIN, &liSavedVersion)); if (liSavedVersion.QuadPart < gliDhcpsnapVersion.QuadPart) { // File is an older version. Warn the user and then don't
// load anything else
Assert(FALSE); }
// Read the root node name
CORg(xferStream.XferCString(DHCPSTRM_TAB_SNAPIN_NAME, &str)); Assert(m_spRootNode); pRootHandler = GETHANDLER(CDhcpRootHandler, m_spRootNode); pRootHandler->SetDisplayName(str); // now read all of the server information
CORg(xferStream.XferCStringArray(DHCPSTRM_TAG_SERVER_IP, &strArrayIp)); CORg(xferStream.XferCStringArray(DHCPSTRM_TAG_SERVER_NAME, &strArrayName)); CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_SERVER_OPTIONS, &dwArrayServerOptions)); CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_SERVER_REFRESH_INTERVAL, &dwArrayRefreshInterval));
// now load the column information
for (i = 0; i < NUM_SCOPE_ITEMS; i++) { CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
for (j = 0; j < MAX_COLUMNS; j++) { // mmc now saves column widths for us, but we don't want to change the
// format of this file, so just don't set our internal struct
//aColumnWidths[i][j] = dwArrayColumnInfo[j];
}
}
// now create the servers based on the information
for (i = 0; i < strArrayIp.GetSize(); i++) { //
// now create the server object
//
pRootHandler->AddServer((LPCWSTR) strArrayIp[i], strArrayName[i], FALSE, dwArrayServerOptions[i], dwArrayRefreshInterval[i]); }
// read in flags (for taskpads)
CORg(xferStream.XferDWORD(DHCPSTRM_TAG_SNAPIN_OPTIONS, &dwFlags));
if (!FUseTaskpadsByDefault(NULL)) dwFlags = 0;
// disable taskpads, the default is off
//m_spTFSComponentData->SetTaskpadState(TASKPAD_ROOT_INDEX, dwFlags & TASKPAD_ROOT_FLAG);
//m_spTFSComponentData->SetTaskpadState(TASKPAD_SERVER_INDEX, dwFlags & TASKPAD_SERVER_FLAG);
Error: return SUCCEEDED(hr) ? S_OK : E_FAIL; }
STDMETHODIMP CDhcpComponentData::Save ( IStream *pStm, BOOL fClearDirty ) { HRESULT hr = hrOK; CStringArray strArrayIp; CStringArray strArrayName; CDWordArray dwArrayServerOptions; CDWordArray dwArrayRefreshInterval; CDWordArray dwArrayColumnInfo; CString str; DWORD dwFileVersion = DHCPSNAP_FILE_VERSION; CDhcpRootHandler * pRootHandler; SPITFSNodeEnum spNodeEnum; SPITFSNode spCurrentNode; ULONG nNumReturned = 0; int nNumServers = 0, nVisibleCount = 0; int i, j, nCount = 0; CDhcpServer * pServer; DWORD dwFlags = 0;
ASSERT(pStm); // set the mode for this stream
XferStream xferStream(pStm, XferStream::MODE_WRITE);
// Write the version # of the file format
CORg(xferStream.XferDWORD(DHCPSTRM_TAG_VERSION, &dwFileVersion)); // Write the version # of the admin tool
CORg(xferStream.XferLARGEINTEGER(DHCPSTRM_TAG_VERSIONADMIN, &gliDhcpsnapVersion));
// write the root node name
Assert(m_spRootNode); pRootHandler = GETHANDLER(CDhcpRootHandler, m_spRootNode); str = pRootHandler->GetDisplayName();
CORg(xferStream.XferCString(DHCPSTRM_TAB_SNAPIN_NAME, &str));
//
// Build our array of servers
//
hr = m_spRootNode->GetChildCount(&nVisibleCount, &nNumServers);
strArrayIp.SetSize(nNumServers); strArrayName.SetSize(nNumServers); dwArrayServerOptions.SetSize(nNumServers); dwArrayRefreshInterval.SetSize(nNumServers); dwArrayColumnInfo.SetSize(MAX_COLUMNS);
//
// loop and save off all the server's attributes
//
m_spRootNode->GetEnum(&spNodeEnum);
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); while (nNumReturned) { pServer = GETHANDLER(CDhcpServer, spCurrentNode);
// query the server for it's options:
// auto refresh, bootp and classid visibility
// NOTE: the audit logging state is also kept in here, but
// it will get updated when the server node is enumerated
dwArrayServerOptions[nCount] = pServer->GetServerOptions(); pServer->GetAutoRefresh(NULL, &dwArrayRefreshInterval[nCount]);
// put the information in our array
strArrayIp[nCount] = pServer->GetIpAddress(); strArrayName[nCount] = pServer->GetName();
// go to the next node
spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
nCount++; }
// now write out all of the server information
CORg(xferStream.XferCStringArray(DHCPSTRM_TAG_SERVER_IP, &strArrayIp)); CORg(xferStream.XferCStringArray(DHCPSTRM_TAG_SERVER_NAME, &strArrayName)); CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_SERVER_OPTIONS, &dwArrayServerOptions)); CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_SERVER_REFRESH_INTERVAL, &dwArrayRefreshInterval));
// now save the column information
for (i = 0; i < NUM_SCOPE_ITEMS; i++) { CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
for (j = 0; j < MAX_COLUMNS; j++) { dwArrayColumnInfo[j] = aColumnWidths[i][j]; } }
if (fClearDirty) { m_spRootNode->SetData(TFS_DATA_DIRTY, FALSE); }
// save off taskpad states
// root node taskpad state
if (m_spTFSComponentData->GetTaskpadState(TASKPAD_ROOT_INDEX)) dwFlags |= TASKPAD_ROOT_FLAG;
// server node taskpad state
if (m_spTFSComponentData->GetTaskpadState(TASKPAD_SERVER_INDEX)) dwFlags |= TASKPAD_SERVER_FLAG;
CORg(xferStream.XferDWORD(DHCPSTRM_TAG_SNAPIN_OPTIONS, &dwFlags));
Error: return SUCCEEDED(hr) ? S_OK : STG_E_CANTSAVE; }
STDMETHODIMP CDhcpComponentData::GetSizeMax ( ULARGE_INTEGER *pcbSize ) { ASSERT(pcbSize);
// Set the size of the string to be saved
ULISet32(*pcbSize, 10240);
return S_OK; }
STDMETHODIMP CDhcpComponentData::InitNew() { return hrOK; }
HRESULT CDhcpComponentData::FinalConstruct() { HRESULT hr = hrOK; hr = CComponentData::FinalConstruct(); if (FHrSucceeded(hr)) { m_spTFSComponentData->GetNodeMgr(&m_spNodeMgr); } return hr; }
void CDhcpComponentData::FinalRelease() { DhcpDsCleanup(); CComponentData::FinalRelease(); }
|