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.

683 lines
16 KiB

  1. //***************************************************************************
  2. //
  3. // UPDATECFG.H
  4. //
  5. // Module: WMI Framework Instance provider
  6. //
  7. // Purpose: Defines class NlbConfigurationUpdate, used for
  8. // async update of NLB properties associated with a particular NIC.
  9. //
  10. // Copyright (c)2001 Microsoft Corporation, All Rights Reserved
  11. //
  12. // History:
  13. //
  14. // 04/05/01 JosephJ Created
  15. //
  16. //***************************************************************************
  17. typedef struct _NLB_IP_ADDRESS_INFO NLB_IP_ADDRESS_INFO;
  18. //
  19. // This structure contains all information associated with a particular NIC
  20. // that is relevant to NLB. This includes the IP addresses bound the NIC,
  21. // whether or not NLB is bound to the NIC, and if NLB is bound, all
  22. // the NLB-specific properties.
  23. //
  24. class NLB_EXTENDED_CLUSTER_CONFIGURATION
  25. {
  26. public:
  27. NLB_EXTENDED_CLUSTER_CONFIGURATION(VOID) {ZeroMemory(this, sizeof(*this));}
  28. ~NLB_EXTENDED_CLUSTER_CONFIGURATION()
  29. {
  30. if (pIpAddressInfo != NULL)
  31. {
  32. delete (pIpAddressInfo);
  33. }
  34. };
  35. WBEMSTATUS
  36. Update(
  37. IN const NLB_EXTENDED_CLUSTER_CONFIGURATION *pNewCfg
  38. );
  39. WBEMSTATUS
  40. SetNetworkAddresses(
  41. IN LPCWSTR *pszNetworkAddresses,
  42. IN UINT NumNetworkAddresses
  43. );
  44. WBEMSTATUS
  45. SetNetworkAddressesSafeArray(
  46. IN SAFEARRAY *pSA
  47. );
  48. WBEMSTATUS
  49. GetNetworkAddresses(
  50. OUT LPWSTR **ppszNetworkAddresses, // free using delete
  51. OUT UINT *pNumNetworkAddresses
  52. );
  53. WBEMSTATUS
  54. GetNetworkAddressesSafeArray(
  55. OUT SAFEARRAY **ppSA
  56. );
  57. WBEMSTATUS
  58. SetNetworkAddresPairs(
  59. IN LPCWSTR *pszIpAddresses,
  60. IN LPCWSTR *pszSubnetMasks,
  61. IN UINT NumNetworkAddresses
  62. );
  63. WBEMSTATUS
  64. GetNetworkAddressPairs(
  65. OUT LPWSTR **ppszIpAddresses, // free using delete
  66. OUT LPWSTR **ppszIpSubnetMasks, // free using delete
  67. OUT UINT *pNumNetworkAddresses
  68. );
  69. WBEMSTATUS
  70. GetPortRules(
  71. OUT LPWSTR **ppszPortRules,
  72. OUT UINT *pNumPortRules
  73. );
  74. WBEMSTATUS
  75. SetPortRules(
  76. IN LPCWSTR *pszPortRules,
  77. IN UINT NumPortRules
  78. );
  79. WBEMSTATUS
  80. GetPortRulesSafeArray(
  81. OUT SAFEARRAY **ppSA
  82. );
  83. WBEMSTATUS
  84. SetPortRulesSafeArray(
  85. IN SAFEARRAY *pSA
  86. );
  87. UINT GetGeneration(VOID) {return Generation;}
  88. BOOL IsNlbBound(VOID) {return fBound;}
  89. BOOL IsValidNlbConfig(VOID) {return fBound && fValidNlbCfg;}
  90. WBEMSTATUS
  91. GetClusterName(
  92. OUT LPWSTR *pszName
  93. );
  94. VOID
  95. SetClusterName(
  96. IN LPCWSTR szName // NULL ok
  97. );
  98. WBEMSTATUS
  99. GetClusterNetworkAddress(
  100. OUT LPWSTR *pszAddress
  101. );
  102. VOID
  103. SetClusterNetworkAddress(
  104. IN LPCWSTR szAddress // NULL ok
  105. );
  106. WBEMSTATUS
  107. GetDedicatedNetworkAddress(
  108. OUT LPWSTR *pszAddress
  109. );
  110. VOID
  111. SetDedicatedNetworkAddress(
  112. IN LPCWSTR szAddress // NULL ok
  113. );
  114. typedef enum
  115. {
  116. TRAFFIC_MODE_UNICAST,
  117. TRAFFIC_MODE_MULTICAST,
  118. TRAFFIC_MODE_IGMPMULTICAST
  119. } TRAFFIC_MODE;
  120. TRAFFIC_MODE
  121. GetTrafficMode(
  122. VOID
  123. );
  124. VOID
  125. SetTrafficMode(
  126. TRAFFIC_MODE Mode
  127. );
  128. UINT
  129. GetHostPriority(
  130. VOID
  131. );
  132. VOID
  133. SetHostPriority(
  134. UINT Priority
  135. );
  136. typedef enum
  137. {
  138. START_MODE_STARTED,
  139. START_MODE_STOPPED
  140. } START_MODE;
  141. START_MODE
  142. GetClusterModeOnStart(
  143. VOID
  144. );
  145. VOID
  146. SetClusterModeOnStart(
  147. START_MODE
  148. );
  149. BOOL
  150. GetRemoteControlEnabled(
  151. VOID
  152. );
  153. VOID
  154. SetRemoteControlEnabled(
  155. BOOL fEnabled
  156. );
  157. //
  158. // Following fields are public because this class started out as a
  159. // structure. TODO: wrap these with access methods.
  160. //
  161. BOOL fValidNlbCfg; // True iff all the information is valid.
  162. UINT Generation; // Generation ID of this Update.
  163. BOOL fBound; // Whether or not NLB is bound to this NIC.
  164. BOOL fAddDedicatedIp; // Whether to add the dedicated ip address
  165. //
  166. // When GETTING configuration info, the following provide the full
  167. // list of statically configured IP addresses on the specified NIC.
  168. //
  169. // When SETTING configuration info, the following can either be zero
  170. // or non-zero. If zero, the set of IP addresses to be added will
  171. // be inferred from other fields (like cluster vip, per-port vips, etc.)
  172. // If non-zero, the exact set of VIPS specified will be used.
  173. //
  174. UINT NumIpAddresses; // Number of IP addresses bound to the NIC
  175. NLB_IP_ADDRESS_INFO *pIpAddressInfo; // The actual IP addresses & masks
  176. WLBS_REG_PARAMS NlbParams; // The WLBS-specific configuration
  177. };
  178. typedef NLB_EXTENDED_CLUSTER_CONFIGURATION *PNLB_EXTENDED_CLUSTER_CONFIGURATION;
  179. //
  180. // The header of a completion header stored as a REG_BINARY value in
  181. // the registry.
  182. //
  183. typedef struct {
  184. UINT Version;
  185. UINT Generation; // Redundant, used for internal consistancy check
  186. UINT CompletionCode;
  187. UINT Reserved;
  188. } NLB_COMPLETION_RECORD, *PNLB_COMPLETION_RECORD;
  189. #define NLB_CURRENT_COMPLETION_RECORD_VERSION 0x3d7376e2
  190. //
  191. // Prefix of the global event name used to control update access to the specifed
  192. // NIC.
  193. // Name has format <prefix><NicGuid>
  194. // Example event name: NLB_D6901862{EBE09517-07B4-4E88-AAF1-E06F5540608B}
  195. //
  196. // The value "D6901862" is a random number.
  197. //
  198. #define NLB_CONFIGURATION_EVENT_PREFIX L"NLB_D6901862"
  199. //
  200. // The maximum generation difference between the oldest valid completion
  201. // record and the current one. Records older then the oldest valid record
  202. // are subject to pruning.
  203. //
  204. #define NLB_MAX_GENERATION_GAP 10
  205. class NlbConfigurationUpdate
  206. {
  207. public:
  208. //
  209. // Static initialization function -- call in process-attach
  210. //
  211. static
  212. VOID
  213. Initialize(
  214. VOID
  215. );
  216. //
  217. // Static deinitialization function -- call in process-detach
  218. //
  219. static
  220. VOID
  221. Deinitialize(
  222. VOID
  223. );
  224. //
  225. // Returns the current configuration on the specific NIC.
  226. //
  227. static
  228. WBEMSTATUS
  229. GetConfiguration(
  230. IN LPCWSTR szNicGuid,
  231. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCurrentCfg
  232. );
  233. //
  234. // Called to initiate update to a new cluster state on that NIC. This
  235. // could include moving from a NLB-bound state to the NLB-unbound state.
  236. // *pGeneration is used to reference this particular update request.
  237. //
  238. static
  239. WBEMSTATUS
  240. DoUpdate(
  241. IN LPCWSTR szNicGuid,
  242. IN LPCWSTR szClientDescription,
  243. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pNewState,
  244. OUT UINT *pGeneration,
  245. OUT WCHAR **ppLog // free using delete operator.
  246. );
  247. /*++
  248. ppLog -- will point to a NULL-terminated string which contains
  249. any messages to be displayed to the user. The string may contain
  250. embedded (WCHAR) '\n' characters to delimit lines.
  251. NOTE: ppLog will be filled out properly EVEN ON FAILURE. If non-null
  252. it must be deleted by the caller.
  253. --*/
  254. //
  255. // Called to get the status of an update request, identified by
  256. // Generation.
  257. //
  258. static
  259. WBEMSTATUS
  260. GetUpdateStatus(
  261. IN LPCWSTR szNicGuid,
  262. IN UINT Generation,
  263. IN BOOL fDelete, // Delete record if it exists
  264. OUT WBEMSTATUS *pCompletionStatus,
  265. OUT WCHAR **ppLog // free using delete operator.
  266. );
  267. static
  268. DWORD
  269. WINAPI
  270. s_AsyncUpdateThreadProc(
  271. LPVOID lpParameter // thread data
  272. );
  273. private:
  274. ///////////////////////////////////////////////////////////////////////////////
  275. //
  276. // S T A T I C S T U F F
  277. //
  278. ///////////////////////////////////////////////////////////////////////////////
  279. //
  280. // A single static lock serialzes all access.
  281. // Use sfn_Lock and sfn_Unlock.
  282. //
  283. static
  284. CRITICAL_SECTION s_Crit;
  285. static
  286. BOOL
  287. s_fDeinitializing; // Set to true if we're in the process of
  288. // de-initializing, in which case we don't want to
  289. // handle any *new* update requests or even queries.
  290. //
  291. // Global list of current updates, one per NIC.
  292. //
  293. static
  294. LIST_ENTRY
  295. s_listCurrentUpdates;
  296. static
  297. VOID
  298. sfn_Lock(
  299. VOID
  300. )
  301. {
  302. EnterCriticalSection(&s_Crit);
  303. }
  304. static
  305. VOID
  306. sfn_Unlock(
  307. VOID
  308. )
  309. {
  310. LeaveCriticalSection(&s_Crit);
  311. }
  312. //
  313. // Looks up the current update for the specific NIC.
  314. // We don't bother to reference count because this object never
  315. // goes away once created -- it's one per unique NIC GUID for as long as
  316. // the DLL is loaded (may want to revisit this).
  317. //
  318. //
  319. static
  320. WBEMSTATUS
  321. sfn_LookupUpdate(
  322. IN LPCWSTR szNic,
  323. IN BOOL fCreate, // Create if required
  324. OUT NlbConfigurationUpdate ** ppUpdate
  325. );
  326. //
  327. // Save the specified completion status to the registry.
  328. //
  329. static
  330. WBEMSTATUS
  331. sfn_RegSetCompletion(
  332. IN LPCWSTR szNicGuid,
  333. IN UINT Generation,
  334. IN WBEMSTATUS CompletionStatus
  335. );
  336. //
  337. // Retrieve the specified completion status from the registry.
  338. //
  339. static
  340. WBEMSTATUS
  341. sfn_RegGetCompletion(
  342. IN LPCWSTR szNicGuid,
  343. IN UINT Generation,
  344. OUT WBEMSTATUS *pCompletionStatus,
  345. OUT WCHAR **ppLog // free using delete operator.
  346. );
  347. //
  348. // Delete the specified completion status from the registry.
  349. //
  350. static
  351. VOID
  352. sfn_RegDeleteCompletion(
  353. IN LPCWSTR szNicGuid,
  354. IN UINT Generation
  355. );
  356. //
  357. // Create the specified subkey key (for r/w access) for the specified
  358. // the specified NIC.
  359. //
  360. static
  361. HKEY
  362. sfn_RegCreateKey(
  363. IN LPCWSTR szNicGuid,
  364. IN LPCWSTR szSubKey,
  365. IN BOOL fVolatile,
  366. OUT BOOL *fExists
  367. );
  368. //
  369. // Open the specified subkey key (for r/w access) for the specified
  370. // the specified NIC.
  371. //
  372. static
  373. HKEY
  374. sfn_RegOpenKey(
  375. IN LPCWSTR szNicGuid,
  376. IN LPCWSTR szSubKey
  377. );
  378. static
  379. VOID
  380. sfn_ReadLog(
  381. IN HKEY hKeyLog,
  382. IN UINT Generation,
  383. OUT LPWSTR *ppLog
  384. );
  385. static
  386. VOID
  387. sfn_WriteLog(
  388. IN HKEY hKeyLog,
  389. IN UINT Generation,
  390. IN LPCWSTR pLog,
  391. IN BOOL fAppend
  392. );
  393. ///////////////////////////////////////////////////////////////////////////////
  394. //
  395. // P E R I N S T A N C E S T U F F
  396. //
  397. ///////////////////////////////////////////////////////////////////////////////
  398. //
  399. // Used in the global one-per-NIC list of updates maintained in
  400. // s_listCurrentUpdates;
  401. //
  402. LIST_ENTRY m_linkUpdates;
  403. #define NLB_GUID_LEN 38
  404. #define NLB_GUID_STRING_SIZE 40 // 38 for the GUID plus trailing NULL + pad
  405. WCHAR m_szNicGuid[NLB_GUID_STRING_SIZE]; // NIC's GUID in text form
  406. LONG m_RefCount;
  407. #if OBSOLETE
  408. //
  409. // Used by the mfn_Log function;
  410. //
  411. struct {
  412. WCHAR *Start; // Points to first WCHAR in log.
  413. WCHAR *End; // Points to next place to write.
  414. UINT_PTR CharsLeft; // WCHARS left in log.
  415. } m_Log;
  416. #endif // OBSOLETE
  417. typedef enum
  418. {
  419. UNITIALIZED, // IDLE -- no ongoing updates
  420. IDLE, // IDLE -- no ongoing updates
  421. ACTIVE // There is an ongoing update
  422. } MyState;
  423. MyState m_State;
  424. HANDLE m_hEvent; // Handle to machine-wide update event -- this
  425. // event is claimed for as long as the current
  426. // update is ongoing.
  427. //
  428. // The following fields are valid only when the state is ACTIVE
  429. //
  430. UINT m_Generation; // Current generation count
  431. #define NLBUPD_MAX_CLIENT_DESCRIPTION_LENGTH 64
  432. WCHAR m_szClientDescription[NLBUPD_MAX_CLIENT_DESCRIPTION_LENGTH+1];
  433. DWORD m_AsyncThreadId; // Thread doing async config update operation.
  434. HANDLE m_hAsyncThread; // ID of above thread.
  435. HKEY m_hCompletionKey; // Key to the registry where
  436. // completions are stored
  437. //
  438. // A snapshot of the cluster configuration state at the start
  439. // of the update
  440. //
  441. NLB_EXTENDED_CLUSTER_CONFIGURATION m_OldClusterConfig;
  442. //
  443. // The requested final state
  444. //
  445. NLB_EXTENDED_CLUSTER_CONFIGURATION m_NewClusterConfig;
  446. //
  447. // Completion status of the current update.
  448. // Could be PENDING.
  449. //
  450. WBEMSTATUS m_CompletionStatus;
  451. //
  452. // END -- of fields that are valid only when the state is ACTIVE
  453. //
  454. //
  455. // Constructor and destructor -- note that these are private
  456. // In fact, the constructor is only called from sfn_LookupUpdate
  457. // and the destructor from mfn_Dereference.
  458. //
  459. NlbConfigurationUpdate(VOID);
  460. ~NlbConfigurationUpdate();
  461. //
  462. // Try to acquire the machine-wide
  463. // NLB configuration update event for this NIC, and create the
  464. // appropriate keys in the registry to track this update.
  465. // NOTE: ppLog will be filled out EVEN ON FAILURE -- it should always
  466. // be deleted by the caller (using the delete operator) if non-NULL.
  467. //
  468. WBEMSTATUS
  469. mfn_StartUpdate(
  470. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pNewState,
  471. IN LPCWSTR szClientDescription,
  472. OUT BOOL *pfDoAsync,
  473. OUT WCHAR ** ppLog
  474. );
  475. //
  476. // Increment ref count. Object stays alive as long as refcount is nonzero.
  477. //
  478. VOID
  479. mfn_Reference(
  480. VOID
  481. );
  482. //
  483. // Decrement ref count. Object is deleted when refcount goes to zero.
  484. //
  485. VOID
  486. mfn_Dereference(
  487. VOID
  488. );
  489. //
  490. // Release the machine-wide update event for this NIC, and delete any
  491. // temporary entries in the registry that were used for this update.
  492. // ppLog must be deleted by caller useing the delete operator.
  493. //
  494. VOID
  495. mfn_StopUpdate(
  496. OUT WCHAR ** ppLog
  497. );
  498. //
  499. // Looks up the completion record identified by Generation, for
  500. // specific NIC (identified by *this).
  501. //
  502. //
  503. BOOL
  504. mfn_LookupCompletion(
  505. IN UINT Generation,
  506. OUT PNLB_COMPLETION_RECORD *pCompletionRecord
  507. );
  508. //
  509. // Uses various windows APIs to fill up the current extended cluster
  510. // information for a specific nic (identified by *this).
  511. // It fills out pNewCfg.
  512. // The pNewCfg->field is set to TRUE IFF there were
  513. // no errors trying to fill out the information.
  514. //
  515. //
  516. WBEMSTATUS
  517. mfn_GetCurrentClusterConfiguration(
  518. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
  519. );
  520. //
  521. // Analyzes the nature of the update, mainly to decide whether or not
  522. // we need to do the update asynchronously.
  523. // This also performs parameter validation.
  524. //
  525. WBEMSTATUS
  526. mfn_AnalyzeUpdate(
  527. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pNewCfg,
  528. IN BOOL *pDoAsync
  529. );
  530. //
  531. // Does the update synchronously -- this is where the meat of the update
  532. // logic exists. It can range from a NoOp, through changing the
  533. // fields of a single port rule, through binding NLB, setting up cluster
  534. // parameters and adding the relevant IP addresses in TCPIP.
  535. //
  536. VOID
  537. mfn_ReallyDoUpdate(
  538. VOID
  539. );
  540. VOID
  541. mfn_Log(
  542. UINT Id, // Resource ID of format,
  543. ...
  544. );
  545. //
  546. // Following is a shortcut where you directly specify a format string.
  547. //
  548. VOID
  549. mfn_Log(
  550. LPCWSTR szFormat,
  551. ...
  552. );
  553. VOID
  554. mfn_LogRawText(
  555. LPCWSTR szText
  556. );
  557. #if OBSOLETE
  558. //
  559. // Extracts a copy of the current log.
  560. // The default delete operator should be used to delete *pLog, if NON-NULL.
  561. //
  562. VOID
  563. mfn_ExtractLog(
  564. OUT LPWSTR *ppLog
  565. );
  566. #endif // OBSOLETE
  567. //
  568. // Stop the current cluster and take out its vips.
  569. //
  570. VOID
  571. mfn_TakeOutVips(
  572. VOID
  573. );
  574. };
  575. VOID
  576. test_port_rule_string(
  577. VOID
  578. );