Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1614 lines
55 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. dhcpcomp.cpp
  7. This file contains the derived implementations from CComponent
  8. and CComponentData for the DHCP admin snapin.
  9. FILE HISTORY:
  10. */
  11. #include "stdafx.h"
  12. #include "dhcpcomp.h"
  13. #include "croot.h"
  14. #include "server.h"
  15. #include "servbrow.h"
  16. #include <util.h> // for InitWatermarkInfo
  17. #include <atlimpl.cpp>
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. #define DHCPSNAP_HELP_FILE_NAME "dhcpsnap.chm"
  24. LARGE_INTEGER gliDhcpsnapVersion;
  25. CAuthServerList g_AuthServerList;
  26. WATERMARKINFO g_WatermarkInfoServer = {0};
  27. WATERMARKINFO g_WatermarkInfoScope = {0};
  28. UINT aColumns[DHCPSNAP_NODETYPE_MAX][MAX_COLUMNS] =
  29. {
  30. {IDS_ROOT_NAME, IDS_STATUS, 0, 0, 0, 0, 0},
  31. {IDS_DHCPSERVER_NAME, IDS_STATUS, IDS_DESCRIPTION, 0, 0, 0, 0},
  32. {IDS_BOOT_IMAGE, IDS_FILE_NAME, IDS_FILE_SERVER, 0, 0, 0, 0},
  33. {IDS_SUPERSCOPE_NAME, IDS_STATUS, IDS_DESCRIPTION, 0, 0, 0, 0},
  34. {IDS_SCOPE_NAME, 0, 0, 0, 0, 0, 0},
  35. {IDS_SCOPE_NAME, 0, 0, 0, 0, 0, 0},
  36. {IDS_START_IP_ADDR, IDS_END_IP_ADDR, IDS_DESCRIPTION, 0, 0, 0, 0},
  37. {IDS_CLIENT_IP_ADDR, IDS_NAME, IDS_LEASE, IDS_TYPE, IDS_UID, IDS_COMMENT, 0},
  38. {IDS_CLIENT_IP_ADDR, IDS_NAME, IDS_LEASE_START, IDS_LEASE, IDS_CLIENT_ID, 0, 0},
  39. {IDS_RESERVATIONS_FOLDER, 0, 0, 0, 0, 0, 0},
  40. {IDS_OPTION_NAME, IDS_VENDOR, IDS_VALUE, IDS_CLASS, 0, 0, 0},
  41. {IDS_OPTION_NAME, IDS_VENDOR, IDS_VALUE, IDS_CLASS, 0, 0, 0},
  42. {IDS_OPTION_NAME, IDS_VENDOR, IDS_VALUE, IDS_CLASS, 0, 0, 0},
  43. {IDS_NAME, IDS_COMMENT, 0, 0, 0, 0, 0},
  44. {0,0,0,0,0,0,0}
  45. };
  46. //
  47. // CODEWORK this should be in a resource, for example code on loading data resources see
  48. // D:\nt\private\net\ui\common\src\applib\applib\lbcolw.cxx ReloadColumnWidths()
  49. // JonN 10/11/96
  50. //
  51. int aColumnWidths[DHCPSNAP_NODETYPE_MAX][MAX_COLUMNS] =
  52. {
  53. {200 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_ROOT
  54. {250 ,150 ,200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SERVER
  55. {175 ,175 ,175 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_BOOTP_TABLE
  56. {200 ,150 ,200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SUPERSCOPE
  57. {150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SCOPE
  58. {150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_MSCOPE
  59. {150 ,150 ,250 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_ADDRESS_POOL
  60. {125 ,125 ,200 ,75 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_ACTIVE_LEASES
  61. {125 ,125 ,200 ,200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_MSCOPE_LEASES
  62. {200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_RESERVATIONS
  63. {175 ,100 ,200 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_RESERVATION_CLIENT
  64. {175 ,100 ,200 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SCOPE_OPTIONS
  65. {175 ,100 ,200 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // DHCPSNAP_SERVER_OPTIONS
  66. {175 ,200 ,200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH} // DHCPSNAP_CLASSID_HOLDER
  67. };
  68. // array to hold all of the possible toolbar buttons
  69. MMCBUTTON g_SnapinButtons[] =
  70. {
  71. { TOOLBAR_IDX_ADD_SERVER, IDS_ADD_SERVER, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  72. { TOOLBAR_IDX_REFRESH, IDS_REFRESH, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  73. { TOOLBAR_IDX_CREATE_SCOPE, IDS_CREATE_NEW_SCOPE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  74. { TOOLBAR_IDX_CREATE_SUPERSCOPE, IDS_CREATE_NEW_SUPERSCOPE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  75. { TOOLBAR_IDX_DEACTIVATE, IDS_DEACTIVATE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  76. { TOOLBAR_IDX_ACTIVATE, IDS_ACTIVATE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  77. { TOOLBAR_IDX_ADD_BOOTP, IDS_CREATE_NEW_BOOT_IMAGE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  78. { TOOLBAR_IDX_ADD_RESERVATION, IDS_CREATE_NEW_RESERVATION, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  79. { TOOLBAR_IDX_ADD_EXCLUSION, IDS_CREATE_NEW_EXCLUSION, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  80. { TOOLBAR_IDX_OPTION_GLOBAL, IDS_CREATE_OPTION_GLOBAL, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  81. { TOOLBAR_IDX_OPTION_SCOPE, IDS_CREATE_OPTION_SCOPE, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  82. { TOOLBAR_IDX_OPTION_RESERVATION,IDS_CREATE_OPTION_RESERVATION, TBSTATE_HIDDEN, TBSTYLE_BUTTON, NULL, NULL },
  83. };
  84. // array to hold resource IDs for the toolbar button text
  85. int g_SnapinButtonStrings[TOOLBAR_IDX_MAX][2] =
  86. {
  87. {IDS_TB_TEXT_ADD_SERVER, IDS_TB_TOOLTIP_ADD_SERVER}, // TOOLBAR_IDX_ADD_SERVER
  88. {IDS_TB_TEXT_REFRESH, IDS_TB_TOOLTIP_REFRESH}, // TOOLBAR_IDX_REFRESH
  89. {IDS_TB_TEXT_CREATE_SCOPE, IDS_TB_TOOLTIP_CREATE_SCOPE}, // TOOLBAR_IDX_CREATE_SCOPE
  90. {IDS_TB_TEXT_CREATE_SUPERSCOPE, IDS_TB_TOOLTIP_CREATE_SUPERSCOPE}, // TOOLBAR_IDX_CREATE_SUPERSCOPE
  91. {IDS_TB_TEXT_DEACTIVATE, IDS_TB_TOOLTIP_DEACTIVATE}, // TOOLBAR_IDX_DEACTIVATE
  92. {IDS_TB_TEXT_ACTIVATE, IDS_TB_TOOLTIP_ACTIVATE}, // TOOLBAR_IDX_ACTIVATE
  93. {IDS_TB_TEXT_ADD_BOOTP, IDS_TB_TOOLTIP_ADD_BOOTP}, // TOOLBAR_IDX_ADD_BOOTP
  94. {IDS_TB_TEXT_ADD_RESERVATION, IDS_TB_TOOLTIP_ADD_RESERVATION}, // TOOLBAR_IDX_ADD_RESERVATION
  95. {IDS_TB_TEXT_ADD_EXCLUSION, IDS_TB_TOOLTIP_ADD_EXCLUSION}, // TOOLBAR_IDX_ADD_EXCLUSION
  96. {IDS_TB_TEXT_OPTION_GLOBAL, IDS_TB_TOOLTIP_OPTION_GLOBAL}, // TOOLBAR_IDX_OPTION_GLOBAL
  97. {IDS_TB_TEXT_OPTION_SCOPE, IDS_TB_TOOLTIP_OPTION_SCOPE}, // TOOLBAR_IDX_OPTION_SCOPE
  98. {IDS_TB_TEXT_OPTION_RESERVATION, IDS_TB_TOOLTIP_OPTION_RESERVATION}, // TOOLBAR_IDX_OPTION_RESERVATION
  99. };
  100. #define HI HIDDEN
  101. #define EN ENABLED
  102. // default states for the toolbar buttons (only scope pane items have toolbar buttons)
  103. MMC_BUTTON_STATE g_SnapinButtonStates[DHCPSNAP_NODETYPE_MAX][TOOLBAR_IDX_MAX] =
  104. {
  105. {EN, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ROOT
  106. {HI, HI, EN, EN, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_SERVER
  107. {HI, HI, HI, HI, HI, HI, EN, HI, HI, HI, HI, HI}, // DHCPSNAP_BOOTP_TABLE
  108. {HI, HI, EN, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_SUPERSCOPE
  109. {HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_SCOPE
  110. {HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_MSCOPE
  111. {HI, HI, HI, HI, HI, HI, HI, HI, EN, HI, HI, HI}, // DHCPSNAP_ADDRESS_POOL
  112. {HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ACTIVE_LEASES
  113. {HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_MSCOPE_LEASES
  114. {HI, HI, HI, HI, HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_RESERVATIONS
  115. {HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, EN}, // DHCPSNAP_RESERVATION_CLIENT
  116. {HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_SCOPE_OPTIONS
  117. {HI, HI, HI, HI, HI, HI, HI, HI, HI, EN, HI, HI}, // DHCPSNAP_SERVER_OPTIONS
  118. {HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_CLASSID_HOLDER
  119. };
  120. MMC_CONSOLE_VERB g_ConsoleVerbs[] =
  121. {
  122. MMC_VERB_OPEN,
  123. MMC_VERB_COPY,
  124. MMC_VERB_PASTE,
  125. MMC_VERB_DELETE,
  126. MMC_VERB_PROPERTIES,
  127. MMC_VERB_RENAME,
  128. MMC_VERB_REFRESH,
  129. MMC_VERB_PRINT
  130. };
  131. // default states for the console verbs
  132. MMC_BUTTON_STATE g_ConsoleVerbStates[DHCPSNAP_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] =
  133. {
  134. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ROOT
  135. {HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_SERVER
  136. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_BOOTP_TABLE
  137. {HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_SUPERSCOPE
  138. {HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_SCOPE
  139. {HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_MSCOPE
  140. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_ADDRESS_POOL
  141. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_ACTIVE_LEASES
  142. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_MSCOPE_LEASES
  143. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_RESERVATIONS
  144. {HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_RESERVATION_CLIENT
  145. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_SCOPE_OPTIONS
  146. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_SERVER_OPTIONS
  147. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_CLASSID_HOLDER
  148. {HI, HI, HI, EN, HI, HI, EN, HI}, // DHCPSNAP_ACTIVE_LEASE
  149. {HI, HI, HI, HI, HI, HI, EN, HI}, // DHCPSNAP_ALLOCATION_RANGE
  150. {HI, HI, HI, EN, HI, HI, EN, HI}, // DHCPSNAP_EXCLUSION_RANGE
  151. {HI, HI, HI, EN, HI, HI, EN, HI}, // DHCPSNAP_BOOTP_ENTRY
  152. {HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_OPTION_ITEM
  153. {HI, HI, HI, EN, EN, HI, EN, HI}, // DHCPSNAP_CLASSID
  154. {HI, HI, HI, EN, HI, HI, EN, HI} // DHCPSNAP_MCAST_LEASE
  155. };
  156. // default states for the console verbs
  157. MMC_BUTTON_STATE g_ConsoleVerbStatesMultiSel[DHCPSNAP_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] =
  158. {
  159. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ROOT
  160. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_SERVER
  161. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_BOOTP_TABLE
  162. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_SUPERSCOPE
  163. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_SCOPE
  164. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_MSCOPE
  165. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_ADDRESS_POOL
  166. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_ACTIVE_LEASES
  167. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_MSCOPE_LEASES
  168. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_RESERVATIONS
  169. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_RESERVATION_CLIENT
  170. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_SCOPE_OPTIONS
  171. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_SERVER_OPTIONS
  172. {HI, HI, HI, EN, HI, HI, HI, HI}, // DHCPSNAP_CLASSID_HOLDER
  173. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ACTIVE_LEASE
  174. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_ALLOCATION_RANGE
  175. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_EXCLUSION_RANGE
  176. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_BOOTP_ENTRY
  177. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_OPTION_ITEM
  178. {HI, HI, HI, HI, HI, HI, HI, HI}, // DHCPSNAP_CLASSID
  179. {HI, HI, HI, HI, HI, HI, HI, HI} // DHCPSNAP_MCAST_LEASE
  180. };
  181. // Help ID array for help on scope items
  182. DWORD g_dwMMCHelp[DHCPSNAP_NODETYPE_MAX] =
  183. {
  184. DHCPSNAP_HELP_ROOT, // DHCPSNAP_ROOT
  185. DHCPSNAP_HELP_SERVER, // DHCPSNAP_SERVER
  186. DHCPSNAP_HELP_BOOTP_TABLE, // DHCPSNAP_BOOTP_TABLE
  187. DHCPSNAP_HELP_SUPERSCOPE, // DHCPSNAP_SUPERSCOPE
  188. DHCPSNAP_HELP_SCOPE, // DHCPSNAP_SCOPE
  189. DHCPSNAP_HELP_MSCOPE, // DHCPSNAP_MSCOPE
  190. DHCPSNAP_HELP_ADDRESS_POOL, // DHCPSNAP_ADDRESS_POOL
  191. DHCPSNAP_HELP_ACTIVE_LEASES, // DHCPSNAP_ACTIVE_LEASES
  192. DHCPSNAP_HELP_ACTIVE_LEASES, // DHCPSNAP_MSCOPE_LEASES
  193. DHCPSNAP_HELP_RESERVATIONS, // DHCPSNAP_RESERVATIONS
  194. DHCPSNAP_HELP_RESERVATION_CLIENT, // DHCPSNAP_RESERVATION_CLIENT
  195. DHCPSNAP_HELP_SCOPE_OPTIONS, // DHCPSNAP_SCOPE_OPTIONS
  196. DHCPSNAP_HELP_GLOBAL_OPTIONS, // DHCPSNAP_SERVER_OPTIONS
  197. DHCPSNAP_HELP_CLASSID_HOLDER, // DHCPSNAP_CLASSID_HOLDER
  198. DHCPSNAP_HELP_ACTIVE_LEASE, // DHCPSNAP_ACTIVE_LEASE
  199. DHCPSNAP_HELP_ALLOCATION_RANGE, // DHCPSNAP_ALLOCATION_RANGE
  200. DHCPSNAP_HELP_EXCLUSION_RANGE, // DHCPSNAP_EXCLUSION_RANGE
  201. DHCPSNAP_HELP_BOOTP_ENTRY, // DHCPSNAP_BOOTP_ENTRY
  202. DHCPSNAP_HELP_OPTION_ITEM, // DHCPSNAP_OPTION_ITEM
  203. DHCPSNAP_HELP_CLASSID, // DHCPSNAP_CLASSID
  204. DHCPSNAP_HELP_MCAST_LEASE // DHCPSNAP_MCAST_LEASE
  205. };
  206. // help mapper for dialogs and property pages
  207. struct ContextHelpMap
  208. {
  209. UINT uID;
  210. const DWORD * pdwMap;
  211. };
  212. ContextHelpMap g_uContextHelp[DHCPSNAP_NUM_HELP_MAPS] =
  213. {
  214. {IDD_ADD_SERVER, g_aHelpIDs_IDD_ADD_SERVER},
  215. {IDD_ADD_TO_SUPERSCOPE, g_aHelpIDs_IDD_ADD_TO_SUPERSCOPE},
  216. {IDD_BINARY_EDITOR, g_aHelpIDs_IDD_BINARY_EDITOR},
  217. {IDD_BOOTP_NEW, g_aHelpIDs_IDD_BOOTP_NEW},
  218. {IDD_BROWSE_SERVERS, g_aHelpIDs_IDD_BROWSE_SERVERS},
  219. {IDD_CLASSES, g_aHelpIDs_IDD_CLASSES},
  220. {IDD_CLASSID_NEW, g_aHelpIDs_IDD_CLASSID_NEW},
  221. {IDD_CREDENTIALS, g_aHelpIDs_IDD_CREDENTIALS},
  222. {IDD_DATA_ENTRY_BINARY, g_aHelpIDs_IDD_DATA_ENTRY_BINARY},
  223. {IDD_DATA_ENTRY_BINARY_ARRAY, g_aHelpIDs_IDD_DATA_ENTRY_BINARY_ARRAY},
  224. {IDD_DATA_ENTRY_DWORD, g_aHelpIDs_IDD_DATA_ENTRY_DWORD},
  225. {IDD_DATA_ENTRY_IPADDRESS, g_aHelpIDs_IDD_DATA_ENTRY_IPADDRESS},
  226. {IDD_DATA_ENTRY_IPADDRESS_ARRAY, g_aHelpIDs_IDD_DATA_ENTRY_IPADDRESS_ARRAY},
  227. {IDD_DATA_ENTRY_NONE, NULL},
  228. {IDD_DATA_ENTRY_STRING, g_aHelpIDs_IDD_DATA_ENTRY_STRING},
  229. {IDD_DATA_ENTRY_ROUTE_ARRAY, g_aHelpIDs_IDD_DATA_ENTRY_ROUTE_ARRAY},
  230. {IDD_DEFAULT_VALUE, g_aHelpIDs_IDD_DEFAULT_VALUE},
  231. {IDD_DEFINE_PARAM, g_aHelpIDs_IDD_DEFINE_PARAM},
  232. {IDD_EXCLUSION_NEW, g_aHelpIDs_IDD_EXCLUSION_NEW},
  233. {IDD_GET_SERVER, g_aHelpIDs_IDD_GET_SERVER},
  234. {IDD_GET_SERVER_CONFIRM, g_aHelpIDs_IDD_GET_SERVER_CONFIRM},
  235. {IDD_IP_ARRAY_EDIT, g_aHelpIDs_IDD_IP_ARRAY_EDIT},
  236. {IDD_RECONCILIATION, g_aHelpIDs_IDD_RECONCILIATION},
  237. {IDD_RESERVATION_NEW, g_aHelpIDs_IDD_RESERVATION_NEW},
  238. {IDD_SERVER_BINDINGS, g_aHelpIDs_IDD_SERVER_BINDINGS},
  239. {IDD_STATS_NARROW, NULL},
  240. {IDP_BOOTP_GENERAL, g_aHelpIDs_IDP_BOOTP_GENERAL},
  241. {IDP_DNS_INFORMATION, g_aHelpIDs_IDP_DNS_INFORMATION},
  242. {IDP_MSCOPE_GENERAL, g_aHelpIDs_IDP_MSCOPE_GENERAL},
  243. {IDP_MSCOPE_LIFETIME, g_aHelpIDs_IDP_MSCOPE_LIFETIME},
  244. {IDP_OPTION_ADVANCED, g_aHelpIDs_IDP_OPTION_ADVANCED},
  245. {IDP_OPTION_BASIC, g_aHelpIDs_IDP_OPTION_BASIC},
  246. {IDP_RESERVED_CLIENT_GENERAL, g_aHelpIDs_IDP_RESERVED_CLIENT_GENERAL},
  247. {IDP_SCOPE_ADVANCED, g_aHelpIDs_IDP_SCOPE_ADVANCED},
  248. {IDP_SCOPE_GENERAL, g_aHelpIDs_IDP_SCOPE_GENERAL},
  249. {IDP_SERVER_ADVANCED, g_aHelpIDs_IDP_SERVER_ADVANCED},
  250. {IDP_SERVER_GENERAL, g_aHelpIDs_IDP_SERVER_GENERAL},
  251. {IDP_SUPERSCOPE_GENERAL, g_aHelpIDs_IDP_SUPERSCOPE_GENERAL},
  252. };
  253. CDhcpContextHelpMap g_dhcpContextHelpMap;
  254. DWORD * DhcpGetHelpMap(UINT uID)
  255. {
  256. DWORD * pdwMap = NULL;
  257. g_dhcpContextHelpMap.Lookup(uID, pdwMap);
  258. return pdwMap;
  259. }
  260. UINT g_uIconMap[ICON_IDX_MAX + 1][2] =
  261. {
  262. {IDI_ICON01, ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN},
  263. {IDI_ICON02, ICON_IDX_ACTIVE_LEASES_LEAF},
  264. {IDI_ICON03, ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED},
  265. {IDI_ICON04, ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN_BUSY},
  266. {IDI_ICON05, ICON_IDX_ACTIVE_LEASES_LEAF_BUSY},
  267. {IDI_ICON06, ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED_BUSY},
  268. {IDI_ICON07, ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN_LOST_CONNECTION},
  269. {IDI_ICON08, ICON_IDX_ACTIVE_LEASES_LEAF_LOST_CONNECTION},
  270. {IDI_ICON09, ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED_LOST_CONNECTION},
  271. {IDI_ICON10, ICON_IDX_ADDR_POOL_FOLDER_OPEN},
  272. {IDI_ICON11, ICON_IDX_ADDR_POOL_LEAF},
  273. {IDI_ICON12, ICON_IDX_ADDR_POOL_FOLDER_CLOSED},
  274. {IDI_ICON13, ICON_IDX_ADDR_POOL_FOLDER_OPEN_BUSY},
  275. {IDI_ICON14, ICON_IDX_ADDR_POOL_LEAF_BUSY},
  276. {IDI_ICON15, ICON_IDX_ADDR_POOL_FOLDER_CLOSED_BUSY},
  277. {IDI_ICON16, ICON_IDX_ADDR_POOL_FOLDER_OPEN_LOST_CONNECTION},
  278. {IDI_ICON17, ICON_IDX_ADDR_POOL_LEAF_LOST_CONNECTION},
  279. {IDI_ICON18, ICON_IDX_ADDR_POOL_FOLDER_CLOSED_LOST_CONNECTION},
  280. {IDI_ICON19, ICON_IDX_ALLOCATION_RANGE},
  281. {IDI_ICON20, ICON_IDX_BOOTP_ENTRY},
  282. {IDI_ICON21, ICON_IDX_BOOTP_TABLE_CLOSED},
  283. {IDI_ICON22, ICON_IDX_BOOTP_TABLE_OPEN},
  284. {IDI_ICON87, ICON_IDX_BOOTP_TABLE_OPEN_LOST_CONNECTION},
  285. {IDI_ICON88, ICON_IDX_BOOTP_TABLE_OPEN_BUSY},
  286. {IDI_ICON89, ICON_IDX_BOOTP_TABLE_CLOSED_LOST_CONNECTION},
  287. {IDI_ICON90, ICON_IDX_BOOTP_TABLE_CLOSED_BUSY},
  288. {IDI_ICON23, ICON_IDX_CLIENT},
  289. {IDI_ICON24, ICON_IDX_CLIENT_DNS_REGISTERING},
  290. {IDI_ICON25, ICON_IDX_CLIENT_EXPIRED},
  291. {IDI_ICON26, ICON_IDX_CLIENT_RAS},
  292. {IDI_ICON27, ICON_IDX_CLIENT_OPTION_FOLDER_OPEN},
  293. {IDI_ICON28, ICON_IDX_CLIENT_OPTION_LEAF},
  294. {IDI_ICON29, ICON_IDX_CLIENT_OPTION_FOLDER_CLOSED},
  295. {IDI_ICON30, ICON_IDX_CLIENT_OPTION_FOLDER_OPEN_BUSY},
  296. {IDI_ICON31, ICON_IDX_CLIENT_OPTION_LEAF_BUSY},
  297. {IDI_ICON32, ICON_IDX_CLIENT_OPTION_FOLDER_CLOSED_BUSY},
  298. {IDI_ICON33, ICON_IDX_CLIENT_OPTION_FOLDER_OPEN_LOST_CONNECTION},
  299. {IDI_ICON34, ICON_IDX_CLIENT_OPTION_LEAF_LOST_CONNECTION},
  300. {IDI_ICON35, ICON_IDX_CLIENT_OPTION_FOLDER_CLOSED_LOST_CONNECTION},
  301. {IDI_ICON36, ICON_IDX_EXCLUSION_RANGE},
  302. {IDI_ICON37, ICON_IDX_FOLDER_CLOSED},
  303. {IDI_ICON38, ICON_IDX_FOLDER_OPEN},
  304. {IDI_ICON39, ICON_IDX_RES_CLIENT},
  305. {IDI_ICON40, ICON_IDX_RES_CLIENT_BUSY},
  306. {IDI_ICON41, ICON_IDX_RES_CLIENT_LOST_CONNECTION},
  307. {IDI_ICON42, ICON_IDX_RESERVATIONS_FOLDER_OPEN},
  308. {IDI_ICON43, ICON_IDX_RESERVATIONS_FOLDER_CLOSED},
  309. {IDI_ICON44, ICON_IDX_RESERVATIONS_FOLDER_OPEN_BUSY},
  310. {IDI_ICON45, ICON_IDX_RESERVATIONS_FOLDER_CLOSED_BUSY},
  311. {IDI_ICON46, ICON_IDX_RESERVATIONS_FOLDER_OPEN_LOST_CONNECTION},
  312. {IDI_ICON47, ICON_IDX_RESERVATIONS_FOLDER_CLOSED_LOST_CONNECTION},
  313. {IDI_ICON48, ICON_IDX_SCOPE_OPTION_FOLDER_OPEN},
  314. {IDI_ICON49, ICON_IDX_SCOPE_OPTION_LEAF},
  315. {IDI_ICON50, ICON_IDX_SCOPE_OPTION_FOLDER_CLOSED},
  316. {IDI_ICON51, ICON_IDX_SCOPE_OPTION_FOLDER_OPEN_BUSY},
  317. {IDI_ICON52, ICON_IDX_SCOPE_OPTION_LEAF_BUSY},
  318. {IDI_ICON53, ICON_IDX_SCOPE_OPTION_FOLDER_CLOSED_BUSY},
  319. {IDI_ICON54, ICON_IDX_SCOPE_OPTION_FOLDER_OPEN_LOST_CONNECTION},
  320. {IDI_ICON55, ICON_IDX_SCOPE_OPTION_FOLDER_CLOSED_LOST_CONNECTION},
  321. {IDI_ICON56, ICON_IDX_SCOPE_OPTION_LEAF_LOST_CONNECTION},
  322. {IDI_ICON57, ICON_IDX_SERVER},
  323. {IDI_ICON58, ICON_IDX_SERVER_WARNING},
  324. {IDI_ICON59, ICON_IDX_SERVER_BUSY},
  325. {IDI_ICON60, ICON_IDX_SERVER_CONNECTED},
  326. {IDI_ICON61, ICON_IDX_SERVER_GROUP},
  327. {IDI_ICON62, ICON_IDX_SERVER_ROGUE},
  328. {IDI_ICON63, ICON_IDX_SERVER_LOST_CONNECTION},
  329. {IDI_ICON64, ICON_IDX_SERVER_NO_ACCESS},
  330. {IDI_ICON65, ICON_IDX_SERVER_ALERT},
  331. {IDI_ICON66, ICON_IDX_SERVER_OPTION_FOLDER_OPEN},
  332. {IDI_ICON67, ICON_IDX_SERVER_OPTION_LEAF},
  333. {IDI_ICON68, ICON_IDX_SERVER_OPTION_FOLDER_CLOSED},
  334. {IDI_ICON69, ICON_IDX_SERVER_OPTION_FOLDER_OPEN_BUSY},
  335. {IDI_ICON70, ICON_IDX_SERVER_OPTION_LEAF_BUSY},
  336. {IDI_ICON71, ICON_IDX_SERVER_OPTION_FOLDER_CLOSED_BUSY},
  337. {IDI_ICON72, ICON_IDX_SERVER_OPTION_FOLDER_OPEN_LOST_CONNECTION},
  338. {IDI_ICON73, ICON_IDX_SERVER_OPTION_LEAF_LOST_CONNECTION},
  339. {IDI_ICON74, ICON_IDX_SERVER_OPTION_FOLDER_CLOSED_LOST_CONNECTION},
  340. {IDI_ICON75, ICON_IDX_SCOPE_FOLDER_OPEN},
  341. {IDI_ICON91, ICON_IDX_SCOPE_FOLDER_OPEN_BUSY},
  342. {IDI_ICON92, ICON_IDX_SCOPE_FOLDER_CLOSED_BUSY},
  343. {IDI_ICON76, ICON_IDX_SCOPE_FOLDER_OPEN_WARNING},
  344. {IDI_ICON77, ICON_IDX_SCOPE_FOLDER_CLOSED_WARNING},
  345. {IDI_ICON78, ICON_IDX_SCOPE_FOLDER_OPEN_LOST_CONNECTION},
  346. {IDI_ICON79, ICON_IDX_SCOPE_FOLDER_CLOSED_LOST_CONNECTION},
  347. {IDI_ICON80, ICON_IDX_SCOPE_FOLDER_OPEN_ALERT},
  348. {IDI_ICON81, ICON_IDX_SCOPE_INACTIVE_FOLDER_OPEN},
  349. {IDI_ICON82, ICON_IDX_SCOPE_INACTIVE_FOLDER_CLOSED},
  350. {IDI_ICON83, ICON_IDX_SCOPE_INACTIVE_FOLDER_OPEN_LOST_CONNECTION},
  351. {IDI_ICON84, ICON_IDX_SCOPE_INACTIVE_FOLDER_CLOSED_LOST_CONNECTION},
  352. {IDI_ICON85, ICON_IDX_SCOPE_FOLDER_CLOSED},
  353. {IDI_ICON86, ICON_IDX_SCOPE_FOLDER_CLOSED_ALERT},
  354. {IDI_DHCP_SNAPIN, ICON_IDX_APPLICATION},
  355. {0, 0}
  356. };
  357. /*!--------------------------------------------------------------------------
  358. FilterOption
  359. Filters returns whether or not to filter out the given option.
  360. Some options we don't want the user to see.
  361. Author: EricDav
  362. ---------------------------------------------------------------------------*/
  363. BOOL
  364. FilterOption
  365. (
  366. DHCP_OPTION_ID id
  367. )
  368. {
  369. //
  370. // Filter out subnet mask, lease duration,
  371. // T1, and T2
  372. //
  373. return (id == 1 || // Subnet mask
  374. id == 51 || // Client Lease Time
  375. id == 58 || // Time between addr assignment to RENEWING state
  376. id == 59 || // Time from addr assignment to REBINDING state
  377. id == 81); // Client DNS name registration
  378. }
  379. /*!--------------------------------------------------------------------------
  380. FilterUserClassOption
  381. Filters returns whether or not to filter out the given option for
  382. a user class. Some options we don't want the user to see.
  383. Author: EricDav
  384. ---------------------------------------------------------------------------*/
  385. BOOL
  386. FilterUserClassOption
  387. (
  388. DHCP_OPTION_ID id
  389. )
  390. {
  391. //
  392. // Filter out subnet mask,
  393. // T1, and T2
  394. //
  395. return (id == 1 || // Subnet mask
  396. id == 58 || // Time between addr assignment to RENEWING state
  397. id == 59 || // Time from addr assignment to REBINDING state
  398. id == 81); // Client DNS name registration
  399. }
  400. /*!--------------------------------------------------------------------------
  401. IsBasicOption
  402. Returns whether the given option is what we've defined as a
  403. basic option.
  404. Author: EricDav
  405. ---------------------------------------------------------------------------*/
  406. BOOL
  407. IsBasicOption
  408. (
  409. DHCP_OPTION_ID id
  410. )
  411. {
  412. //
  413. // Basic Options are:
  414. // Router
  415. // DNS Server
  416. // Domain Name
  417. // WINS/NBNS Servers
  418. // WINS/NBT Node Type
  419. //
  420. return (id == 3 ||
  421. id == 6 ||
  422. id == 15 ||
  423. id == 44 ||
  424. id == 46);
  425. }
  426. /*!--------------------------------------------------------------------------
  427. IsAdvancedOption
  428. Returns whether the given option is what we've defined as an
  429. advanced option.
  430. Author: EricDav
  431. ---------------------------------------------------------------------------*/
  432. BOOL
  433. IsAdvancedOption
  434. (
  435. DHCP_OPTION_ID id
  436. )
  437. {
  438. //
  439. // All non-basic and non-custom options are advanced.
  440. //
  441. return (id < 128 && !IsBasicOption(id));
  442. }
  443. /*!--------------------------------------------------------------------------
  444. IsCustomOption
  445. Returns whether the given option is a user defined option.
  446. Author: EricDav
  447. ---------------------------------------------------------------------------*/
  448. BOOL
  449. IsCustomOption
  450. (
  451. DHCP_OPTION_ID id
  452. )
  453. {
  454. //
  455. // Custom options are anything with an id > 128
  456. //
  457. return (id > 128);
  458. }
  459. /*!--------------------------------------------------------------------------
  460. GetSystemMessage
  461. Use FormatMessage() to get a system error message
  462. Author: EricDav
  463. ---------------------------------------------------------------------------*/
  464. LONG
  465. GetSystemMessage
  466. (
  467. UINT nId,
  468. TCHAR * chBuffer,
  469. int cbBuffSize
  470. )
  471. {
  472. TCHAR * pszText = NULL ;
  473. HINSTANCE hdll = NULL ;
  474. DWORD flags = FORMAT_MESSAGE_IGNORE_INSERTS
  475. | FORMAT_MESSAGE_MAX_WIDTH_MASK;
  476. //
  477. // Interpret the error. Need to special case
  478. // the lmerr & ntstatus ranges, as well as
  479. // dhcp server error messages.
  480. //
  481. if ( nId >= NERR_BASE && nId <= MAX_NERR )
  482. {
  483. hdll = LoadLibraryEx( _T("netmsg.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE);
  484. }
  485. else
  486. if ( nId >= 20000 && nId <= 20099 )
  487. {
  488. // DHCP Server error
  489. hdll = LoadLibraryEx( _T("dhcpsapi.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE );
  490. }
  491. else
  492. if (nId >= 0x5000 && nId < 0x50FF)
  493. {
  494. // It's an ADSI error.
  495. hdll = LoadLibraryEx( _T("activeds.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE );
  496. nId |= 0x80000000;
  497. }
  498. else
  499. if( nId >= 0x40000000L )
  500. {
  501. hdll = LoadLibraryEx( _T("ntdll.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE );
  502. }
  503. if ( hdll == NULL )
  504. {
  505. flags |= FORMAT_MESSAGE_FROM_SYSTEM;
  506. }
  507. else
  508. {
  509. flags |= FORMAT_MESSAGE_FROM_HMODULE;
  510. }
  511. //
  512. // Let FormatMessage do the dirty work.
  513. //
  514. DWORD dwResult = ::FormatMessage( flags,
  515. (LPVOID) hdll,
  516. nId,
  517. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  518. chBuffer,
  519. cbBuffSize,
  520. NULL ) ;
  521. if ( hdll != NULL )
  522. {
  523. LONG err = GetLastError();
  524. FreeLibrary( hdll );
  525. if ( dwResult == 0 )
  526. {
  527. ::SetLastError( err );
  528. }
  529. }
  530. return dwResult ? 0 : ::GetLastError() ;
  531. }
  532. /*!--------------------------------------------------------------------------
  533. LoadMessage
  534. Loads the error message from the correct DLL.
  535. Author: EricDav
  536. ---------------------------------------------------------------------------*/
  537. BOOL
  538. LoadMessage
  539. (
  540. UINT nIdPrompt,
  541. TCHAR * chMsg,
  542. int nMsgSize
  543. )
  544. {
  545. BOOL bOk;
  546. //
  547. // Substitute a friendly message for "RPC server not
  548. // available" and "No more endpoints available from
  549. // the endpoint mapper".
  550. //
  551. if (nIdPrompt == EPT_S_NOT_REGISTERED ||
  552. nIdPrompt == RPC_S_SERVER_UNAVAILABLE)
  553. {
  554. nIdPrompt = IDS_ERR_DHCP_DOWN;
  555. }
  556. else if (nIdPrompt == RPC_S_PROCNUM_OUT_OF_RANGE)
  557. {
  558. nIdPrompt = IDS_ERR_RPC_NO_ENTRY;
  559. }
  560. //
  561. // If it's a socket error or our error, the text is in our resource fork.
  562. // Otherwise, use FormatMessage() and the appropriate DLL.
  563. //
  564. if ( (nIdPrompt >= IDS_ERR_BASE && nIdPrompt < IDS_MESG_MAX) ||
  565. (nIdPrompt >= WSABASEERR && nIdPrompt < WSABASEERR + 2000)
  566. )
  567. {
  568. //
  569. // It's in our resource fork
  570. //
  571. bOk = ::LoadString( AfxGetInstanceHandle(), nIdPrompt, chMsg, nMsgSize ) != 0 ;
  572. }
  573. else
  574. {
  575. //
  576. // It's in the system somewhere.
  577. //
  578. bOk = GetSystemMessage( nIdPrompt, chMsg, nMsgSize ) == 0 ;
  579. }
  580. //
  581. // If the error message did not compute, replace it.
  582. //
  583. if ( ! bOk )
  584. {
  585. TCHAR chBuff [STRING_LENGTH_MAX] ;
  586. static const TCHAR * pszReplacement = _T("System Error: %ld");
  587. const TCHAR * pszMsg = pszReplacement ;
  588. //
  589. // Try to load the generic (translatable) error message text
  590. //
  591. if ( ::LoadString( AfxGetInstanceHandle(), IDS_ERR_MESSAGE_GENERIC,
  592. chBuff, sizeof(chBuff)/sizeof(TCHAR) ) != 0 )
  593. {
  594. pszMsg = chBuff ;
  595. }
  596. ::wsprintf( chMsg, pszMsg, nIdPrompt ) ;
  597. }
  598. return bOk;
  599. }
  600. /*!--------------------------------------------------------------------------
  601. DhcpMessageBox
  602. Puts up a message box with the corresponding error text.
  603. Author: EricDav
  604. ---------------------------------------------------------------------------*/
  605. int
  606. DhcpMessageBox
  607. (
  608. DWORD dwIdPrompt,
  609. UINT nType,
  610. const TCHAR * pszSuffixString,
  611. UINT nHelpContext
  612. )
  613. {
  614. TCHAR chMesg [4000] ;
  615. BOOL bOk ;
  616. UINT nIdPrompt = (UINT) dwIdPrompt;
  617. bOk = LoadMessage(nIdPrompt, chMesg, sizeof(chMesg)/sizeof(TCHAR));
  618. if ( pszSuffixString )
  619. {
  620. ::lstrcat( chMesg, _T(" ") ) ;
  621. ::lstrcat( chMesg, pszSuffixString ) ;
  622. }
  623. return ::AfxMessageBox( chMesg, nType, nHelpContext ) ;
  624. }
  625. /*!--------------------------------------------------------------------------
  626. DhcpMessageBoxEx
  627. Puts up a message box with the corresponding error text.
  628. Author: EricDav
  629. ---------------------------------------------------------------------------*/
  630. int
  631. DhcpMessageBoxEx
  632. (
  633. DWORD dwIdPrompt,
  634. LPCTSTR pszPrefixMessage,
  635. UINT nType,
  636. UINT nHelpContext
  637. )
  638. {
  639. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  640. TCHAR chMesg[4000];
  641. CString strMessage;
  642. BOOL bOk;
  643. UINT nIdPrompt = (UINT) dwIdPrompt;
  644. bOk = LoadMessage(nIdPrompt, chMesg, sizeof(chMesg)/sizeof(TCHAR));
  645. if ( pszPrefixMessage )
  646. {
  647. strMessage = pszPrefixMessage;
  648. strMessage += _T("\n");
  649. strMessage += _T("\n");
  650. strMessage += chMesg;
  651. }
  652. else
  653. {
  654. strMessage = chMesg;
  655. }
  656. return AfxMessageBox(strMessage, nType, nHelpContext);
  657. }
  658. /*---------------------------------------------------------------------------
  659. Class CDhcpComponent implementation
  660. ---------------------------------------------------------------------------*/
  661. CDhcpComponent::CDhcpComponent()
  662. {
  663. m_pbmpToolbar = NULL;
  664. }
  665. CDhcpComponent::~CDhcpComponent()
  666. {
  667. if (m_pbmpToolbar)
  668. {
  669. delete m_pbmpToolbar;
  670. m_pbmpToolbar = NULL;
  671. }
  672. }
  673. STDMETHODIMP CDhcpComponent::InitializeBitmaps(MMC_COOKIE cookie)
  674. {
  675. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  676. ASSERT(m_spImageList != NULL);
  677. // Set the images
  678. HICON hIcon;
  679. HRESULT hr;
  680. LPOLESTR pszGuid = NULL;
  681. long lViewOptions = 0;
  682. CLSID clsid;
  683. CORg (GetResultViewType(cookie, &pszGuid, &lViewOptions));
  684. CLSIDFromString(pszGuid, &clsid);
  685. // if the result pane is not the message view then add the icons
  686. if (clsid != CLSID_MessageView)
  687. {
  688. for (int i = 0; i < ICON_IDX_MAX; i++)
  689. {
  690. hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
  691. if (hIcon)
  692. {
  693. // call mmc
  694. hr = m_spImageList->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1]);
  695. }
  696. }
  697. }
  698. Error:
  699. return S_OK;
  700. }
  701. /*!--------------------------------------------------------------------------
  702. CDhcpComponentData::QueryDataObject
  703. For multiple select we need to add things to the data object.....
  704. In order to do this we need to call into the result handler for
  705. the node
  706. Author: EricDav
  707. ---------------------------------------------------------------------------*/
  708. STDMETHODIMP CDhcpComponent::QueryDataObject
  709. (
  710. MMC_COOKIE cookie,
  711. DATA_OBJECT_TYPES type,
  712. LPDATAOBJECT* ppDataObject
  713. )
  714. {
  715. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  716. HRESULT hr = hrOK;
  717. SPITFSNode spRootNode;
  718. // this is a special case for multiple select. We need to build a list
  719. // of GUIDs and the code to do this is in the handler...
  720. if (cookie == MMC_MULTI_SELECT_COOKIE)
  721. {
  722. SPITFSNode spNode;
  723. SPITFSResultHandler spResultHandler;
  724. CORg (GetSelectedNode(&spNode));
  725. CORg (spNode->GetResultHandler(&spResultHandler));
  726. spResultHandler->OnCreateDataObject(this, cookie, type, ppDataObject);
  727. }
  728. else
  729. if (cookie == MMC_WINDOW_COOKIE)
  730. {
  731. // this cookie needs the text for the static root node, so build the DO with
  732. // the root node cookie
  733. m_spNodeMgr->GetRootNode(&spRootNode);
  734. CORg (m_spComponentData->QueryDataObject((MMC_COOKIE) spRootNode->GetData(TFS_DATA_COOKIE), type, ppDataObject));
  735. }
  736. else
  737. {
  738. // Delegate it to the IComponentData
  739. Assert(m_spComponentData != NULL);
  740. CORg (m_spComponentData->QueryDataObject(cookie, type, ppDataObject));
  741. }
  742. Error:
  743. return hr;
  744. }
  745. /*!--------------------------------------------------------------------------
  746. CDhcpComponentData::SetControlbar
  747. -
  748. Author: EricDav, KennT
  749. ---------------------------------------------------------------------------*/
  750. HRESULT
  751. CDhcpComponent::SetControlbar
  752. (
  753. LPCONTROLBAR pControlbar
  754. )
  755. {
  756. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  757. HRESULT hr = hrOK;
  758. SPIToolbar spToolbar;
  759. COM_PROTECT_TRY
  760. {
  761. if (pControlbar)
  762. {
  763. // Create the Toolbar
  764. GetToolbar(&spToolbar);
  765. if (!spToolbar)
  766. {
  767. CORg(pControlbar->Create(TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&spToolbar)));
  768. if (!spToolbar)
  769. goto Error;
  770. SetToolbar(spToolbar);
  771. // Add the bitmap
  772. m_pbmpToolbar = new CBitmap;
  773. m_pbmpToolbar->LoadBitmap(IDB_TOOLBAR);
  774. hr = spToolbar->AddBitmap(TOOLBAR_IDX_MAX, *m_pbmpToolbar, 16, 16, RGB(192, 192, 192));
  775. ASSERT(SUCCEEDED(hr));
  776. // Add the buttons to the toolbar
  777. for (int i = 0; i < TOOLBAR_IDX_MAX; i++)
  778. {
  779. CString strText, strTooltip;
  780. strText.LoadString(g_SnapinButtonStrings[i][0]);
  781. strTooltip.LoadString(g_SnapinButtonStrings[i][1]);
  782. g_SnapinButtons[i].lpButtonText = (LPOLESTR) ((LPCTSTR) strText);
  783. g_SnapinButtons[i].lpTooltipText = (LPOLESTR) ((LPCTSTR) strTooltip);
  784. hr = spToolbar->InsertButton(i, &g_SnapinButtons[i]);
  785. ASSERT(SUCCEEDED(hr));
  786. }
  787. }
  788. }
  789. }
  790. COM_PROTECT_CATCH
  791. // store the control bar away for future use
  792. Error:
  793. m_spControlbar.Set(pControlbar);
  794. return hr;
  795. }
  796. /*!--------------------------------------------------------------------------
  797. CDhcpComponentData::ControlbarNotify
  798. -
  799. Author: EricDav
  800. ---------------------------------------------------------------------------*/
  801. STDMETHODIMP
  802. CDhcpComponent::ControlbarNotify
  803. (
  804. MMC_NOTIFY_TYPE event,
  805. LPARAM arg,
  806. LPARAM param
  807. )
  808. {
  809. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  810. HRESULT hr = hrOK;
  811. SPINTERNAL spInternal;
  812. SPITFSNode spNode;
  813. MMC_COOKIE cookie;
  814. LPDATAOBJECT pDataObject;
  815. SPIDataObject spDataObject;
  816. DHCPTOOLBARNOTIFY dhcpToolbarNotify;
  817. SPIControlBar spControlbar;
  818. SPIToolbar spToolbar;
  819. SPITFSNodeHandler spNodeHandler;
  820. SPITFSResultHandler spResultHandler;
  821. BOOL bScope;
  822. BOOL bSelect;
  823. COM_PROTECT_TRY
  824. {
  825. CORg(GetControlbar(&spControlbar));
  826. Assert(spControlbar != NULL);
  827. CORg(GetToolbar(&spToolbar));
  828. Assert(spToolbar != NULL);
  829. // set the controlbar and toolbar pointers in the notify struct
  830. dhcpToolbarNotify.pControlbar = spControlbar;
  831. dhcpToolbarNotify.pToolbar = spToolbar;
  832. switch (event)
  833. {
  834. case MMCN_SELECT:
  835. // extract the node information from the data object
  836. bScope = LOWORD(arg);
  837. bSelect = HIWORD(arg);
  838. if (!bScope)
  839. {
  840. Assert(param);
  841. pDataObject = reinterpret_cast<LPDATAOBJECT>(param);
  842. if (pDataObject == NULL)
  843. return hr;
  844. if ( IS_SPECIAL_DATAOBJECT(pDataObject) ||
  845. IsMMCMultiSelectDataObject(pDataObject) )
  846. {
  847. // CODEWORK: Do we need to do anything special to the toolbar
  848. // during multiselect? Disable our toolbar buttons?
  849. GetSelectedNode(&spNode);
  850. }
  851. else
  852. {
  853. CORg(ExtractNodeFromDataObject(m_spNodeMgr,
  854. m_spTFSComponentData->GetCoClassID(),
  855. pDataObject,
  856. FALSE,
  857. &spNode,
  858. NULL,
  859. &spInternal));
  860. if (spInternal->m_type == CCT_RESULT)
  861. {
  862. // a result item was selected
  863. cookie = spNode->GetData(TFS_DATA_COOKIE);
  864. }
  865. else
  866. {
  867. // a scope item in the result pane was selected
  868. cookie = NULL;
  869. }
  870. }
  871. if (spNode)
  872. {
  873. CORg( spNode->GetResultHandler(&spResultHandler) );
  874. dhcpToolbarNotify.event = event;
  875. dhcpToolbarNotify.id = param;
  876. dhcpToolbarNotify.bSelect = bSelect;
  877. if (spResultHandler)
  878. CORg( spResultHandler->UserResultNotify(spNode, DHCP_MSG_CONTROLBAR_NOTIFY, (LPARAM) &dhcpToolbarNotify) );
  879. }
  880. }
  881. else
  882. {
  883. dhcpToolbarNotify.cookie = 0;
  884. dhcpToolbarNotify.event = event;
  885. dhcpToolbarNotify.id = 0;
  886. dhcpToolbarNotify.bSelect = bSelect;
  887. // check to see if an item is being deselected
  888. Assert(param);
  889. pDataObject = reinterpret_cast<LPDATAOBJECT>(param);
  890. if (pDataObject == NULL)
  891. return hr;
  892. CORg(ExtractNodeFromDataObject(m_spNodeMgr,
  893. m_spTFSComponentData->GetCoClassID(),
  894. pDataObject,
  895. FALSE,
  896. &spNode,
  897. NULL,
  898. &spInternal));
  899. CORg( spNode->GetHandler(&spNodeHandler) );
  900. if (spNodeHandler)
  901. CORg( spNodeHandler->UserNotify(spNode, DHCP_MSG_CONTROLBAR_NOTIFY, (LPARAM) &dhcpToolbarNotify) );
  902. }
  903. break;
  904. case MMCN_BTN_CLICK:
  905. Assert(arg);
  906. pDataObject = reinterpret_cast<LPDATAOBJECT>(arg);
  907. if (pDataObject == NULL)
  908. return hr;
  909. if ( IS_SPECIAL_DATAOBJECT(pDataObject) )
  910. {
  911. // get a data object for the selected node.
  912. GetSelectedNode(&spNode);
  913. CORg(QueryDataObject((MMC_COOKIE) spNode->GetData(TFS_DATA_COOKIE), CCT_SCOPE, &spDataObject));
  914. spNode.Release();
  915. pDataObject = spDataObject;
  916. }
  917. CORg(ExtractNodeFromDataObject(m_spNodeMgr,
  918. m_spTFSComponentData->GetCoClassID(),
  919. pDataObject,
  920. FALSE,
  921. &spNode,
  922. NULL,
  923. &spInternal));
  924. if (spInternal)
  925. {
  926. switch (spInternal->m_type)
  927. {
  928. case CCT_RESULT:
  929. cookie = spNode->GetData(TFS_DATA_COOKIE);
  930. CORg( spNode->GetResultHandler(&spResultHandler) );
  931. dhcpToolbarNotify.cookie = cookie;
  932. dhcpToolbarNotify.event = event;
  933. dhcpToolbarNotify.id = param;
  934. dhcpToolbarNotify.bSelect = TRUE;
  935. if (spResultHandler)
  936. CORg( spResultHandler->UserResultNotify(spNode,
  937. DHCP_MSG_CONTROLBAR_NOTIFY,
  938. (LPARAM) &dhcpToolbarNotify) );
  939. break;
  940. case CCT_SCOPE:
  941. CORg( spNode->GetHandler(&spNodeHandler) );
  942. dhcpToolbarNotify.cookie = 0;
  943. dhcpToolbarNotify.event = event;
  944. dhcpToolbarNotify.id = param;
  945. dhcpToolbarNotify.bSelect = TRUE;
  946. if (spNodeHandler)
  947. CORg( spNodeHandler->UserNotify(spNode,
  948. DHCP_MSG_CONTROLBAR_NOTIFY,
  949. (LPARAM) &dhcpToolbarNotify) );
  950. break;
  951. default:
  952. Assert(FALSE);
  953. break;
  954. }
  955. }
  956. break;
  957. case MMCN_DESELECT_ALL:
  958. // what are we supposed to do here???
  959. break;
  960. default:
  961. Panic1("CDhcpComponent::ControlbarNotify - Unknown event %d", event);
  962. break;
  963. }
  964. COM_PROTECT_ERROR_LABEL;
  965. }
  966. COM_PROTECT_CATCH
  967. return hr;
  968. }
  969. /*!--------------------------------------------------------------------------
  970. CDhcpComponentData::OnSnapinHelp
  971. -
  972. Author: EricDav
  973. ---------------------------------------------------------------------------*/
  974. STDMETHODIMP
  975. CDhcpComponent::OnSnapinHelp
  976. (
  977. LPDATAOBJECT pDataObject,
  978. LPARAM arg,
  979. LPARAM param
  980. )
  981. {
  982. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  983. HRESULT hr = hrOK;
  984. HtmlHelpA(NULL, DHCPSNAP_HELP_FILE_NAME, HH_DISPLAY_TOPIC, 0);
  985. return hr;
  986. }
  987. /*---------------------------------------------------------------------------
  988. Class CDhcpComponentData implementation
  989. ---------------------------------------------------------------------------*/
  990. CDhcpComponentData::CDhcpComponentData()
  991. {
  992. gliDhcpsnapVersion.LowPart = DHCPSNAP_MINOR_VERSION;
  993. gliDhcpsnapVersion.HighPart = DHCPSNAP_MAJOR_VERSION;
  994. // initialize our global help map
  995. for (int i = 0; i < DHCPSNAP_NUM_HELP_MAPS; i++)
  996. {
  997. g_dhcpContextHelpMap.SetAt(g_uContextHelp[i].uID, (LPDWORD) g_uContextHelp[i].pdwMap);
  998. }
  999. }
  1000. /*!--------------------------------------------------------------------------
  1001. CDhcpComponentData::OnInitialize
  1002. -
  1003. Author: EricDav, KennT
  1004. ---------------------------------------------------------------------------*/
  1005. STDMETHODIMP CDhcpComponentData::OnInitialize(LPIMAGELIST pScopeImage)
  1006. {
  1007. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1008. HICON hIcon;
  1009. // thread deletes itself
  1010. CStandaloneAuthServerWorker * pWorker = new CStandaloneAuthServerWorker();
  1011. pWorker->CreateThread();
  1012. // initialize icon images with MMC
  1013. for (int i = 0; i < ICON_IDX_MAX; i++)
  1014. {
  1015. hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
  1016. if (hIcon)
  1017. {
  1018. // call mmc
  1019. VERIFY(SUCCEEDED(pScopeImage->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1])));
  1020. }
  1021. }
  1022. return hrOK;
  1023. }
  1024. /*!--------------------------------------------------------------------------
  1025. CDhcpComponentData::OnDestroy
  1026. -
  1027. Author: EricDav, KennT
  1028. ---------------------------------------------------------------------------*/
  1029. STDMETHODIMP CDhcpComponentData::OnDestroy()
  1030. {
  1031. m_spNodeMgr.Release();
  1032. if (g_bDhcpDsInitialized)
  1033. {
  1034. ::DhcpDsCleanup();
  1035. g_bDhcpDsInitialized = FALSE;
  1036. }
  1037. return hrOK;
  1038. }
  1039. /*!--------------------------------------------------------------------------
  1040. CDhcpComponentData::OnInitializeNodeMgr
  1041. -
  1042. Author: KennT
  1043. ---------------------------------------------------------------------------*/
  1044. STDMETHODIMP
  1045. CDhcpComponentData::OnInitializeNodeMgr
  1046. (
  1047. ITFSComponentData * pTFSCompData,
  1048. ITFSNodeMgr * pNodeMgr
  1049. )
  1050. {
  1051. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1052. // For now create a new node handler for each new node,
  1053. // this is rather bogus as it can get expensive. We can
  1054. // consider creating only a single node handler for each
  1055. // node type.
  1056. CDhcpRootHandler * pHandler = NULL;
  1057. SPITFSNodeHandler spHandler;
  1058. SPITFSNode spNode;
  1059. HRESULT hr = hrOK;
  1060. try
  1061. {
  1062. pHandler = new CDhcpRootHandler(pTFSCompData);
  1063. // Do this so that it will get released correctly
  1064. spHandler = pHandler;
  1065. }
  1066. catch(...)
  1067. {
  1068. hr = E_OUTOFMEMORY;
  1069. }
  1070. CORg( hr );
  1071. // Create the root node for this sick puppy
  1072. CORg( CreateContainerTFSNode(&spNode,
  1073. &GUID_DhcpRootNodeType,
  1074. pHandler,
  1075. pHandler, /* result handler */
  1076. pNodeMgr) );
  1077. // Need to initialize the data for the root node
  1078. pHandler->InitializeNode(spNode);
  1079. CORg( pNodeMgr->SetRootNode(spNode) );
  1080. m_spRootNode.Set(spNode);
  1081. // setup watermark info
  1082. if (g_WatermarkInfoServer.hHeader == NULL)
  1083. {
  1084. // haven't been initialized yet
  1085. InitWatermarkInfo(AfxGetInstanceHandle(),
  1086. &g_WatermarkInfoServer,
  1087. IDB_SRVWIZ_BANNER, // Header ID
  1088. IDB_SRVWIZ_WATERMARK, // Watermark ID
  1089. NULL, // hPalette
  1090. FALSE); // bStretch
  1091. InitWatermarkInfo(AfxGetInstanceHandle(),
  1092. &g_WatermarkInfoScope,
  1093. IDB_SCPWIZ_BANNER, // Header ID
  1094. IDB_SCPWIZ_WATERMARK, // Watermark ID
  1095. NULL, // hPalette
  1096. FALSE); // bStretch
  1097. }
  1098. pTFSCompData->SetHTMLHelpFileName(_T(DHCPSNAP_HELP_FILE_NAME));
  1099. // disable taskpads by default
  1100. pTFSCompData->SetTaskpadState(TASKPAD_ROOT_INDEX, FALSE);
  1101. pTFSCompData->SetTaskpadState(TASKPAD_SERVER_INDEX, FALSE);
  1102. Error:
  1103. return hr;
  1104. }
  1105. /*!--------------------------------------------------------------------------
  1106. CDhcpComponentData::OnCreateComponent
  1107. -
  1108. Author: EricDav, KennT
  1109. ---------------------------------------------------------------------------*/
  1110. STDMETHODIMP
  1111. CDhcpComponentData::OnCreateComponent
  1112. (
  1113. LPCOMPONENT *ppComponent
  1114. )
  1115. {
  1116. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1117. ASSERT(ppComponent != NULL);
  1118. HRESULT hr = hrOK;
  1119. CDhcpComponent * pComp = NULL;
  1120. try
  1121. {
  1122. pComp = new CDhcpComponent;
  1123. }
  1124. catch(...)
  1125. {
  1126. hr = E_OUTOFMEMORY;
  1127. }
  1128. if (FHrSucceeded(hr))
  1129. {
  1130. pComp->Construct(m_spNodeMgr,
  1131. static_cast<IComponentData *>(this),
  1132. m_spTFSComponentData);
  1133. *ppComponent = static_cast<IComponent *>(pComp);
  1134. }
  1135. return hr;
  1136. }
  1137. /*!--------------------------------------------------------------------------
  1138. CDhcpComponentData::GetCoClassID
  1139. -
  1140. Author: KennT
  1141. ---------------------------------------------------------------------------*/
  1142. STDMETHODIMP_(const CLSID *)
  1143. CDhcpComponentData::GetCoClassID()
  1144. {
  1145. return &CLSID_DhcpSnapin;
  1146. }
  1147. /*!--------------------------------------------------------------------------
  1148. CDhcpComponentData::OnCreateDataObject
  1149. -
  1150. Author: KennT
  1151. ---------------------------------------------------------------------------*/
  1152. STDMETHODIMP
  1153. CDhcpComponentData::OnCreateDataObject
  1154. (
  1155. MMC_COOKIE cookie,
  1156. DATA_OBJECT_TYPES type,
  1157. IDataObject ** ppDataObject
  1158. )
  1159. {
  1160. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1161. Assert(ppDataObject != NULL);
  1162. CDataObject * pObject = NULL;
  1163. SPIDataObject spDataObject;
  1164. pObject = new CDataObject;
  1165. spDataObject = pObject; // do this so that it gets released correctly
  1166. Assert(pObject != NULL);
  1167. // Save cookie and type for delayed rendering
  1168. pObject->SetType(type);
  1169. pObject->SetCookie(cookie);
  1170. // Store the coclass with the data object
  1171. pObject->SetClsid(*GetCoClassID());
  1172. pObject->SetTFSComponentData(m_spTFSComponentData);
  1173. return pObject->QueryInterface(IID_IDataObject,
  1174. reinterpret_cast<void**>(ppDataObject));
  1175. }
  1176. ///////////////////////////////////////////////////////////////////////////////
  1177. //// IPersistStream interface members
  1178. STDMETHODIMP
  1179. CDhcpComponentData::GetClassID
  1180. (
  1181. CLSID *pClassID
  1182. )
  1183. {
  1184. ASSERT(pClassID != NULL);
  1185. // Copy the CLSID for this snapin
  1186. *pClassID = CLSID_DhcpSnapin;
  1187. return hrOK;
  1188. }
  1189. STDMETHODIMP
  1190. CDhcpComponentData::IsDirty()
  1191. {
  1192. return m_spRootNode->GetData(TFS_DATA_DIRTY) ? hrOK : hrFalse;
  1193. }
  1194. STDMETHODIMP
  1195. CDhcpComponentData::Load
  1196. (
  1197. IStream *pStm
  1198. )
  1199. {
  1200. HRESULT hr = hrOK;
  1201. LARGE_INTEGER liSavedVersion;
  1202. CString str;
  1203. ASSERT(pStm);
  1204. CStringArray strArrayIp;
  1205. CStringArray strArrayName;
  1206. CDWordArray dwArrayServerOptions;
  1207. CDWordArray dwArrayRefreshInterval;
  1208. CDWordArray dwArrayColumnInfo;
  1209. DWORD dwFileVersion;
  1210. CDhcpRootHandler * pRootHandler;
  1211. DWORD dwFlags = 0;
  1212. int i, j;
  1213. ASSERT(pStm);
  1214. // set the mode for this stream
  1215. XferStream xferStream(pStm, XferStream::MODE_READ);
  1216. // read the version of the file format
  1217. CORg(xferStream.XferDWORD(DHCPSTRM_TAG_VERSION, &dwFileVersion));
  1218. if (dwFileVersion < DHCPSNAP_FILE_VERSION)
  1219. {
  1220. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1221. AfxMessageBox(_T("This console file was saved with a previous version of the snapin and is not compatible. The settings could not be restored."));
  1222. return hr;
  1223. }
  1224. // Read the version # of the admin tool
  1225. CORg(xferStream.XferLARGEINTEGER(DHCPSTRM_TAG_VERSIONADMIN, &liSavedVersion));
  1226. if (liSavedVersion.QuadPart < gliDhcpsnapVersion.QuadPart)
  1227. {
  1228. // File is an older version. Warn the user and then don't
  1229. // load anything else
  1230. Assert(FALSE);
  1231. }
  1232. // Read the root node name
  1233. CORg(xferStream.XferCString(DHCPSTRM_TAB_SNAPIN_NAME, &str));
  1234. Assert(m_spRootNode);
  1235. pRootHandler = GETHANDLER(CDhcpRootHandler, m_spRootNode);
  1236. pRootHandler->SetDisplayName(str);
  1237. // now read all of the server information
  1238. CORg(xferStream.XferCStringArray(DHCPSTRM_TAG_SERVER_IP, &strArrayIp));
  1239. CORg(xferStream.XferCStringArray(DHCPSTRM_TAG_SERVER_NAME, &strArrayName));
  1240. CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_SERVER_OPTIONS, &dwArrayServerOptions));
  1241. CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_SERVER_REFRESH_INTERVAL, &dwArrayRefreshInterval));
  1242. // now load the column information
  1243. for (i = 0; i < NUM_SCOPE_ITEMS; i++)
  1244. {
  1245. CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
  1246. for (j = 0; j < MAX_COLUMNS; j++)
  1247. {
  1248. // mmc now saves column widths for us, but we don't want to change the
  1249. // format of this file, so just don't set our internal struct
  1250. //aColumnWidths[i][j] = dwArrayColumnInfo[j];
  1251. }
  1252. }
  1253. // now create the servers based on the information
  1254. for (i = 0; i < strArrayIp.GetSize(); i++)
  1255. {
  1256. //
  1257. // now create the server object
  1258. //
  1259. pRootHandler->AddServer((LPCWSTR) strArrayIp[i],
  1260. strArrayName[i],
  1261. FALSE,
  1262. dwArrayServerOptions[i],
  1263. dwArrayRefreshInterval[i]);
  1264. }
  1265. // read in flags (for taskpads)
  1266. CORg(xferStream.XferDWORD(DHCPSTRM_TAG_SNAPIN_OPTIONS, &dwFlags));
  1267. if (!FUseTaskpadsByDefault(NULL))
  1268. dwFlags = 0;
  1269. // disable taskpads, the default is off
  1270. //m_spTFSComponentData->SetTaskpadState(TASKPAD_ROOT_INDEX, dwFlags & TASKPAD_ROOT_FLAG);
  1271. //m_spTFSComponentData->SetTaskpadState(TASKPAD_SERVER_INDEX, dwFlags & TASKPAD_SERVER_FLAG);
  1272. Error:
  1273. return SUCCEEDED(hr) ? S_OK : E_FAIL;
  1274. }
  1275. STDMETHODIMP
  1276. CDhcpComponentData::Save
  1277. (
  1278. IStream *pStm,
  1279. BOOL fClearDirty
  1280. )
  1281. {
  1282. HRESULT hr = hrOK;
  1283. CStringArray strArrayIp;
  1284. CStringArray strArrayName;
  1285. CDWordArray dwArrayServerOptions;
  1286. CDWordArray dwArrayRefreshInterval;
  1287. CDWordArray dwArrayColumnInfo;
  1288. CString str;
  1289. DWORD dwFileVersion = DHCPSNAP_FILE_VERSION;
  1290. CDhcpRootHandler * pRootHandler;
  1291. SPITFSNodeEnum spNodeEnum;
  1292. SPITFSNode spCurrentNode;
  1293. ULONG nNumReturned = 0;
  1294. int nNumServers = 0, nVisibleCount = 0;
  1295. int i, j, nCount = 0;
  1296. CDhcpServer * pServer;
  1297. DWORD dwFlags = 0;
  1298. ASSERT(pStm);
  1299. // set the mode for this stream
  1300. XferStream xferStream(pStm, XferStream::MODE_WRITE);
  1301. // Write the version # of the file format
  1302. CORg(xferStream.XferDWORD(DHCPSTRM_TAG_VERSION, &dwFileVersion));
  1303. // Write the version # of the admin tool
  1304. CORg(xferStream.XferLARGEINTEGER(DHCPSTRM_TAG_VERSIONADMIN, &gliDhcpsnapVersion));
  1305. // write the root node name
  1306. Assert(m_spRootNode);
  1307. pRootHandler = GETHANDLER(CDhcpRootHandler, m_spRootNode);
  1308. str = pRootHandler->GetDisplayName();
  1309. CORg(xferStream.XferCString(DHCPSTRM_TAB_SNAPIN_NAME, &str));
  1310. //
  1311. // Build our array of servers
  1312. //
  1313. hr = m_spRootNode->GetChildCount(&nVisibleCount, &nNumServers);
  1314. strArrayIp.SetSize(nNumServers);
  1315. strArrayName.SetSize(nNumServers);
  1316. dwArrayServerOptions.SetSize(nNumServers);
  1317. dwArrayRefreshInterval.SetSize(nNumServers);
  1318. dwArrayColumnInfo.SetSize(MAX_COLUMNS);
  1319. //
  1320. // loop and save off all the server's attributes
  1321. //
  1322. m_spRootNode->GetEnum(&spNodeEnum);
  1323. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1324. while (nNumReturned)
  1325. {
  1326. pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  1327. // query the server for it's options:
  1328. // auto refresh, bootp and classid visibility
  1329. // NOTE: the audit logging state is also kept in here, but
  1330. // it will get updated when the server node is enumerated
  1331. dwArrayServerOptions[nCount] = pServer->GetServerOptions();
  1332. pServer->GetAutoRefresh(NULL, &dwArrayRefreshInterval[nCount]);
  1333. // put the information in our array
  1334. strArrayIp[nCount] = pServer->GetIpAddress();
  1335. strArrayName[nCount] = pServer->GetName();
  1336. // go to the next node
  1337. spCurrentNode.Release();
  1338. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1339. nCount++;
  1340. }
  1341. // now write out all of the server information
  1342. CORg(xferStream.XferCStringArray(DHCPSTRM_TAG_SERVER_IP, &strArrayIp));
  1343. CORg(xferStream.XferCStringArray(DHCPSTRM_TAG_SERVER_NAME, &strArrayName));
  1344. CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_SERVER_OPTIONS, &dwArrayServerOptions));
  1345. CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_SERVER_REFRESH_INTERVAL, &dwArrayRefreshInterval));
  1346. // now save the column information
  1347. for (i = 0; i < NUM_SCOPE_ITEMS; i++)
  1348. {
  1349. CORg(xferStream.XferDWORDArray(DHCPSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
  1350. for (j = 0; j < MAX_COLUMNS; j++)
  1351. {
  1352. dwArrayColumnInfo[j] = aColumnWidths[i][j];
  1353. }
  1354. }
  1355. if (fClearDirty)
  1356. {
  1357. m_spRootNode->SetData(TFS_DATA_DIRTY, FALSE);
  1358. }
  1359. // save off taskpad states
  1360. // root node taskpad state
  1361. if (m_spTFSComponentData->GetTaskpadState(TASKPAD_ROOT_INDEX))
  1362. dwFlags |= TASKPAD_ROOT_FLAG;
  1363. // server node taskpad state
  1364. if (m_spTFSComponentData->GetTaskpadState(TASKPAD_SERVER_INDEX))
  1365. dwFlags |= TASKPAD_SERVER_FLAG;
  1366. CORg(xferStream.XferDWORD(DHCPSTRM_TAG_SNAPIN_OPTIONS, &dwFlags));
  1367. Error:
  1368. return SUCCEEDED(hr) ? S_OK : STG_E_CANTSAVE;
  1369. }
  1370. STDMETHODIMP
  1371. CDhcpComponentData::GetSizeMax
  1372. (
  1373. ULARGE_INTEGER *pcbSize
  1374. )
  1375. {
  1376. ASSERT(pcbSize);
  1377. // Set the size of the string to be saved
  1378. ULISet32(*pcbSize, 10240);
  1379. return S_OK;
  1380. }
  1381. STDMETHODIMP
  1382. CDhcpComponentData::InitNew()
  1383. {
  1384. return hrOK;
  1385. }
  1386. HRESULT
  1387. CDhcpComponentData::FinalConstruct()
  1388. {
  1389. HRESULT hr = hrOK;
  1390. hr = CComponentData::FinalConstruct();
  1391. if (FHrSucceeded(hr))
  1392. {
  1393. m_spTFSComponentData->GetNodeMgr(&m_spNodeMgr);
  1394. }
  1395. return hr;
  1396. }
  1397. void
  1398. CDhcpComponentData::FinalRelease()
  1399. {
  1400. CComponentData::FinalRelease();
  1401. }