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.

799 lines
22 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. node.c
  5. Abstract:
  6. Fix up Routines for Upgrade and Rolling Upgrades
  7. Author:
  8. Sunita Shrivastava(sunitas) 18-Mar-1998
  9. Revision History:
  10. --*/
  11. /****
  12. @doc EXTERNAL INTERFACES CLUSSVC DM
  13. ****/
  14. #define UNICODE 1
  15. #include "nmp.h"
  16. //
  17. // Cluster registry API function pointers.
  18. //
  19. CLUSTER_REG_APIS
  20. NmpFixupRegApis = {
  21. (PFNCLRTLCREATEKEY) DmRtlCreateKey,
  22. (PFNCLRTLOPENKEY) DmRtlOpenKey,
  23. (PFNCLRTLCLOSEKEY) DmCloseKey,
  24. (PFNCLRTLSETVALUE) DmSetValue,
  25. (PFNCLRTLQUERYVALUE) DmQueryValue,
  26. (PFNCLRTLENUMVALUE) DmEnumValue,
  27. (PFNCLRTLDELETEVALUE) DmDeleteValue,
  28. (PFNCLRTLLOCALCREATEKEY) DmRtlLocalCreateKey,
  29. (PFNCLRTLLOCALSETVALUE) DmLocalSetValue,
  30. (PFNCLRTLLOCALDELETEVALUE) DmLocalDeleteValue,
  31. };
  32. //
  33. // Data
  34. //
  35. RESUTIL_PROPERTY_ITEM
  36. NmJoinFixupSDProperties[]=
  37. {
  38. {
  39. CLUSREG_NAME_CLUS_SD, NULL, CLUSPROP_FORMAT_BINARY,
  40. 0, 0, 0,
  41. 0,
  42. 0
  43. },
  44. {
  45. 0
  46. }
  47. };
  48. // Fixup Table for WINS
  49. RESUTIL_PROPERTY_ITEM
  50. NmJoinFixupWINSProperties[]=
  51. {
  52. {
  53. CLUSREG_NAME_RESTYPE_IS_ALIVE, CLUS_RESTYPE_NAME_WINS , CLUSPROP_FORMAT_DWORD,
  54. 0,CLUSTER_RESTYPE_MINIMUM_IS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_IS_ALIVE ,
  55. 0,
  56. 0
  57. },
  58. {
  59. CLUSREG_NAME_RESTYPE_LOOKS_ALIVE,CLUS_RESTYPE_NAME_WINS ,CLUSPROP_FORMAT_DWORD,
  60. 0,CLUSTER_RESTYPE_MINIMUM_LOOKS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_LOOKS_ALIVE ,
  61. 0,
  62. sizeof(DWORD)
  63. },
  64. {
  65. CLUSREG_NAME_RESTYPE_DLL_NAME,CLUS_RESTYPE_NAME_WINS ,CLUSPROP_FORMAT_SZ,
  66. 0,0,0,
  67. 0,
  68. 2*sizeof(DWORD)
  69. },
  70. {
  71. CLUSREG_NAME_RESTYPE_NAME,CLUS_RESTYPE_NAME_WINS ,CLUSPROP_FORMAT_SZ,
  72. 0,0,0,
  73. 0,
  74. 2*sizeof(DWORD)+sizeof(LPWSTR*)
  75. },
  76. {
  77. CLUSREG_NAME_RESTYPE_ADMIN_EXTENSIONS,CLUS_RESTYPE_NAME_WINS,CLUSPROP_FORMAT_MULTI_SZ,
  78. 0,0,0,
  79. 0,
  80. 2*sizeof(DWORD)+2*sizeof(LPWSTR*)
  81. },
  82. {
  83. 0
  84. }
  85. }; //NmJoinFixupWINSProperties
  86. //Fixup Table for DHCP
  87. RESUTIL_PROPERTY_ITEM
  88. NmJoinFixupDHCPProperties[]=
  89. {
  90. {
  91. CLUSREG_NAME_RESTYPE_IS_ALIVE, CLUS_RESTYPE_NAME_DHCP , CLUSPROP_FORMAT_DWORD,
  92. 0,CLUSTER_RESTYPE_MINIMUM_IS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_IS_ALIVE ,
  93. 0,
  94. 0
  95. },
  96. {
  97. CLUSREG_NAME_RESTYPE_LOOKS_ALIVE,CLUS_RESTYPE_NAME_DHCP ,CLUSPROP_FORMAT_DWORD,
  98. 0,CLUSTER_RESTYPE_MINIMUM_LOOKS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_LOOKS_ALIVE ,
  99. 0,
  100. sizeof(DWORD)
  101. },
  102. {
  103. CLUSREG_NAME_RESTYPE_DLL_NAME,CLUS_RESTYPE_NAME_DHCP ,CLUSPROP_FORMAT_SZ,
  104. 0,0,0,
  105. 0,
  106. 2*sizeof(DWORD)
  107. },
  108. {
  109. CLUSREG_NAME_RESTYPE_NAME,CLUS_RESTYPE_NAME_DHCP ,CLUSPROP_FORMAT_SZ,
  110. 0,0,0,
  111. 0,
  112. 2*sizeof(DWORD)+sizeof(LPWSTR*)
  113. },
  114. {
  115. CLUSREG_NAME_RESTYPE_ADMIN_EXTENSIONS,CLUS_RESTYPE_NAME_DHCP,CLUSPROP_FORMAT_MULTI_SZ,
  116. 0,0,0,
  117. 0,
  118. 2*sizeof(DWORD)+2*sizeof(LPWSTR*)
  119. },
  120. {
  121. 0
  122. }
  123. };//NmJoinFixupDHCPProperties
  124. RESUTIL_PROPERTY_ITEM
  125. NmJoinFixupNewMSMQProperties[]=
  126. {
  127. {
  128. CLUSREG_NAME_RESTYPE_IS_ALIVE, CLUS_RESTYPE_NAME_NEW_MSMQ,CLUSPROP_FORMAT_DWORD,
  129. 0,CLUSTER_RESTYPE_MINIMUM_IS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_IS_ALIVE ,
  130. 0,
  131. 0
  132. },
  133. {
  134. CLUSREG_NAME_RESTYPE_LOOKS_ALIVE,CLUS_RESTYPE_NAME_NEW_MSMQ,CLUSPROP_FORMAT_DWORD,
  135. 0,CLUSTER_RESTYPE_MINIMUM_LOOKS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_LOOKS_ALIVE ,
  136. 0,
  137. sizeof(DWORD)
  138. },
  139. {
  140. CLUSREG_NAME_RESTYPE_DLL_NAME,CLUS_RESTYPE_NAME_NEW_MSMQ,CLUSPROP_FORMAT_SZ,
  141. 0,0,0,
  142. 0,
  143. 2*sizeof(DWORD)
  144. },
  145. {
  146. CLUSREG_NAME_RESTYPE_NAME,CLUS_RESTYPE_NAME_NEW_MSMQ,CLUSPROP_FORMAT_SZ,
  147. 0,0,0,
  148. 0,
  149. 2*sizeof(DWORD)+sizeof(LPWSTR*)
  150. },
  151. {
  152. 0
  153. }
  154. };//NmJoinFixupNewMSMQProperties
  155. //Fixup Table for changing thr dl name of MSDTC resource type
  156. RESUTIL_PROPERTY_ITEM
  157. NmJoinFixupMSDTCProperties[]=
  158. {
  159. {
  160. CLUSREG_NAME_RESTYPE_DLL_NAME,CLUS_RESTYPE_NAME_MSDTC,CLUSPROP_FORMAT_SZ,
  161. 0,0,0,
  162. 0,
  163. 0
  164. },
  165. {
  166. 0
  167. }
  168. };//NmJoinFixupMSDTCProperties
  169. //Fixup table for node version info
  170. RESUTIL_PROPERTY_ITEM
  171. NmFixupVersionInfo[]=
  172. {
  173. {
  174. CLUSREG_NAME_NODE_MAJOR_VERSION,NULL,CLUSPROP_FORMAT_DWORD,
  175. 0,0,((DWORD)-1),
  176. 0,
  177. 0
  178. },
  179. {
  180. CLUSREG_NAME_NODE_MINOR_VERSION,NULL,CLUSPROP_FORMAT_DWORD,
  181. 0,0,((DWORD)-1),
  182. 0,
  183. sizeof(DWORD)
  184. },
  185. {
  186. CLUSREG_NAME_NODE_BUILD_NUMBER,NULL,CLUSPROP_FORMAT_DWORD,
  187. 0,0,((DWORD)-1),
  188. 0,
  189. 2*sizeof(DWORD)
  190. },
  191. {
  192. CLUSREG_NAME_NODE_CSDVERSION,NULL,CLUSPROP_FORMAT_SZ,
  193. 0,0,0,
  194. 0,
  195. 3*sizeof(DWORD)
  196. },
  197. {
  198. CLUSREG_NAME_NODE_PRODUCT_SUITE,NULL,CLUSPROP_FORMAT_DWORD,
  199. 0,0,((DWORD)-1),
  200. 0,
  201. 3*sizeof(DWORD) + sizeof(LPWSTR*)
  202. },
  203. {
  204. 0
  205. }
  206. }; //NmFixupVersionInfo
  207. RESUTIL_PROPERTY_ITEM
  208. NmFixupClusterProperties[] =
  209. {
  210. {
  211. CLUSREG_NAME_ADMIN_EXT, NULL, CLUSPROP_FORMAT_MULTI_SZ,
  212. 0, 0, 0,
  213. 0,
  214. 0
  215. },
  216. {
  217. 0
  218. }
  219. };
  220. //Used by NmUpdatePerformFixups update
  221. RESUTIL_PROPERTY_ITEM
  222. NmpJoinFixupProperties[] =
  223. {
  224. {
  225. CLUSREG_NAME_CLUS_SD, NULL, CLUSPROP_FORMAT_BINARY,
  226. 0, 0, 0,
  227. 0,
  228. 0
  229. },
  230. {
  231. 0
  232. }
  233. };
  234. RESUTIL_PROPERTY_ITEM
  235. NmpFormFixupProperties[] =
  236. {
  237. {
  238. CLUSREG_NAME_CLUS_SD, NULL, CLUSPROP_FORMAT_BINARY,
  239. 0, 0, 0,
  240. 0,
  241. 0
  242. },
  243. {
  244. 0
  245. }
  246. };
  247. NM_FIXUP_CB_RECORD FixupTable[]=
  248. {
  249. { ApiFixupNotifyCb, NM_FORM_FIXUP|NM_JOIN_FIXUP}
  250. };
  251. // Fixup Table used for NmUpdatePerformFixups2 update type
  252. NM_FIXUP_CB_RECORD2 FixupTable2[]=
  253. {
  254. { ApiFixupNotifyCb, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmpJoinFixupProperties},
  255. { FmBuildWINS, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmJoinFixupWINSProperties,},
  256. { FmBuildDHCP, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmJoinFixupDHCPProperties},
  257. { FmBuildNewMSMQ, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmJoinFixupNewMSMQProperties},
  258. { FmBuildMSDTC, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmJoinFixupMSDTCProperties},
  259. { NmpBuildVersionInfo, NM_JOIN_FIXUP|NM_FORM_FIXUP, NmFixupVersionInfo},
  260. { FmBuildClusterProp, NM_FORM_FIXUP|NM_JOIN_FIXUP,NmFixupClusterProperties}
  261. };
  262. NM_POST_FIXUP_CB PostFixupCbTable[]=
  263. {
  264. NULL,
  265. FmFixupNotifyCb,
  266. FmFixupNotifyCb,
  267. FmFixupNotifyCb,
  268. FmFixupNotifyCb,
  269. NmFixupNotifyCb,
  270. NULL
  271. };
  272. /****
  273. @func DWORD | NmPerformFixups| This is called when a cluster is being
  274. formed/or joining. Issues NmUpdateperforfixups GUM update
  275. for registry fixups of SECURITY_DESCRIPTOR when NT5 node joins
  276. NT4 node.Also issues NmUpdateperforfixups2 GUM update for
  277. WINS and DHCP fixups when NT5 joins NT4. This update type can
  278. be extended in future to do more fixups for postNT5 and NT5 scenario.
  279. If later it is guaranteed that there is no NT4 node in cluster,
  280. NmUpdatePerformFixups update type won't be needed and hence can
  281. be taken out.
  282. @comm The first time the cluster service forms a cluster after an
  283. upgrade, it might have registry fixups it wants to make to the
  284. existing cluster registry. Also, when an uplevel node
  285. joins a downlevel node, join fixups can be performed.
  286. Note that this is called on every form/join
  287. @rdesc Returns a result code. ERROR_SUCCESS on success.
  288. @xref <f NmpUpdatePerformFixups> <f NmpUpdatePerformFixups2>
  289. ****/
  290. DWORD NmPerformFixups(
  291. IN DWORD dwFixupType)
  292. {
  293. DWORD dwCount = sizeof(FixupTable)/sizeof(NM_FIXUP_CB_RECORD);
  294. DWORD dwStatus = ERROR_SUCCESS;
  295. PNM_FIXUP_CB_RECORD pFixupCbRec;
  296. PNM_FIXUP_CB_RECORD2 pFixupCbRec2;
  297. PVOID pPropertyList = NULL;
  298. DWORD dwPropertyListSize;
  299. DWORD i,j;
  300. DWORD dwSize;
  301. DWORD Required;
  302. LPWSTR szKeyName=NULL;
  303. LPBYTE pBuffer=NULL;
  304. PRESUTIL_PROPERTY_ITEM pPropertyItem;
  305. ClRtlLogPrint(LOG_NOISE,"[NM] NmPerformFixups Entry, dwFixupType=%1!u!\r\n",
  306. dwFixupType);
  307. // using old gum update handler - this is needed to maintain compataility
  308. // with NT4, can be discarded later. See comments above.
  309. //
  310. for (i=0; i < dwCount ; i++)
  311. {
  312. pFixupCbRec = &FixupTable[i];
  313. //if this fixup doesnt need to be applied, skip it
  314. if (!(pFixupCbRec->dwFixupMask & dwFixupType))
  315. continue;
  316. dwStatus = (pFixupCbRec->pfnFixupNotifyCb)(dwFixupType, &pPropertyList,
  317. &dwPropertyListSize,&szKeyName);
  318. if (dwStatus != ERROR_SUCCESS)
  319. {
  320. goto FnExit;
  321. }
  322. if (pPropertyList && dwPropertyListSize)
  323. {
  324. //
  325. // Issue a global update
  326. //
  327. dwStatus = GumSendUpdateEx(
  328. GumUpdateMembership,
  329. NmUpdatePerformFixups,
  330. 2,
  331. dwPropertyListSize,
  332. pPropertyList,
  333. sizeof(DWORD),
  334. &dwPropertyListSize
  335. );
  336. LocalFree(pPropertyList);
  337. pPropertyList = NULL;
  338. if(szKeyName)
  339. {
  340. LocalFree(szKeyName);
  341. szKeyName=NULL;
  342. }
  343. }
  344. if (dwStatus != ERROR_SUCCESS)
  345. goto FnExit;
  346. }
  347. // Rohit (rjain): introduced new update type to fix the registry and
  348. // in-memory structures after a node with a higher version of clustering
  349. // service joins a node with a lower version. To make it extensible in future
  350. // all the information needed for a fixup is passed as arguments to the fixup
  351. // function. Any new fix can be added by adding suitable record to FixupTable2 and
  352. // a postfixup function callback to PostfixupCbTable.
  353. dwCount= sizeof(FixupTable2)/sizeof(NM_FIXUP_CB_RECORD2);
  354. for (i=0; i < dwCount ; i++)
  355. {
  356. pFixupCbRec2 = &FixupTable2[i];
  357. //if this fixup doesnt need to be applied, skip it
  358. if (!(pFixupCbRec2->dwFixupMask & dwFixupType))
  359. continue;
  360. dwStatus = (pFixupCbRec2->pfnFixupNotifyCb)(dwFixupType, &pPropertyList,
  361. &dwPropertyListSize,&szKeyName);
  362. if (dwStatus != ERROR_SUCCESS)
  363. {
  364. goto FnExit;
  365. }
  366. if (pPropertyList && dwPropertyListSize)
  367. {
  368. // Marshall PropertyTable into byte array
  369. Required=sizeof(DWORD);
  370. AllocMem:
  371. pBuffer=(LPBYTE)LocalAlloc(LMEM_FIXED,Required);
  372. if (pBuffer==NULL)
  373. {
  374. dwStatus=GetLastError();
  375. goto FnExit;
  376. }
  377. dwSize=Required;
  378. dwStatus=ClRtlMarshallPropertyTable(pFixupCbRec2->pPropertyTable,dwSize,pBuffer,&Required);
  379. if(dwStatus!= ERROR_SUCCESS)
  380. {
  381. LocalFree(pBuffer);
  382. pBuffer=NULL;
  383. // ClRtlLogPrint(LOG_NOISE,"[NM] NmPerformFixups - Memory Required=%1!u!\r\n",
  384. // Required);
  385. goto AllocMem;
  386. }
  387. //
  388. // Issue a global update
  389. //
  390. dwStatus = GumSendUpdateEx(
  391. GumUpdateMembership,
  392. NmUpdatePerformFixups2,
  393. 5,
  394. dwPropertyListSize,
  395. pPropertyList,
  396. sizeof(DWORD),
  397. &dwPropertyListSize,
  398. sizeof(DWORD),
  399. &i,
  400. (lstrlenW(szKeyName)+1)*sizeof(WCHAR),
  401. szKeyName,
  402. Required,
  403. pBuffer
  404. );
  405. LocalFree(pPropertyList);
  406. pPropertyList = NULL;
  407. LocalFree(pBuffer);
  408. pBuffer= NULL;
  409. if(szKeyName)
  410. {
  411. LocalFree(szKeyName);
  412. szKeyName= NULL;
  413. }
  414. }
  415. if (dwStatus != ERROR_SUCCESS)
  416. break;
  417. }
  418. FnExit:
  419. if(szKeyName)
  420. {
  421. LocalFree(szKeyName);
  422. szKeyName=NULL;
  423. }
  424. ClRtlLogPrint(LOG_NOISE,"[NM] NmPerformFixups Exit, dwStatus=%1!u!\r\n",
  425. dwStatus);
  426. return(dwStatus);
  427. } //NmPerformFixups
  428. /****
  429. @func DWORD | NmpUpdatePerformFixups| The gum update handler for
  430. doing the registry fixups.
  431. @parm IN DWORD | IsSourceNode| If the gum request originated at this
  432. node.
  433. @parm IN PVOID| pPropertyList| Pointer to a property list structure.
  434. @parm IN DWORD | pdwPropertyListSize | A pointer to a DWORD containing
  435. the size of the property list structure.
  436. @comm The gum update handler commits this fixup to the cluster registry
  437. as a transaction.
  438. @rdesc Returns a result code. ERROR_SUCCESS on success.
  439. @xref <f NmJoinFixup> <f NmFormFixup>
  440. ****/
  441. DWORD NmpUpdatePerformFixups(
  442. IN BOOL IsSourceNode,
  443. IN PVOID pPropertyList,
  444. IN LPDWORD pdwPropertyListSize
  445. )
  446. {
  447. DWORD dwStatus = ERROR_SUCCESS;
  448. HLOCALXSACTION hXaction;
  449. if (!NmpEnterApi(NmStateOnline)) {
  450. ClRtlLogPrint(LOG_NOISE,
  451. "[NM] Not in valid state to process PerformFixups update. "
  452. "update.\n"
  453. );
  454. return(ERROR_NODE_NOT_AVAILABLE);
  455. }
  456. //
  457. // Begin a transaction
  458. //
  459. hXaction = DmBeginLocalUpdate();
  460. if (hXaction != NULL) {
  461. dwStatus = ClRtlSetPropertyTable(
  462. hXaction,
  463. DmClusterParametersKey,
  464. &NmpFixupRegApis,
  465. NmpJoinFixupProperties,
  466. NULL,
  467. FALSE,
  468. pPropertyList,
  469. *pdwPropertyListSize,
  470. FALSE /*bForceWrite*/,
  471. NULL
  472. );
  473. if (dwStatus == ERROR_SUCCESS) {
  474. DmCommitLocalUpdate(hXaction);
  475. }
  476. else {
  477. DmAbortLocalUpdate(hXaction);
  478. }
  479. }
  480. else {
  481. dwStatus = GetLastError();
  482. ClRtlLogPrint(LOG_CRITICAL, "[NM] Failed to begin a transaction "
  483. "to perform fixups, status %1!u!\n",
  484. dwStatus
  485. );
  486. }
  487. NmpLeaveApi();
  488. return(dwStatus);
  489. } // NmpUpdatePerformFixups
  490. /****
  491. @func DWORD | NmpUpdatePerformFixups2| The gum update handler for
  492. doing the registry fixups and updating in-memory fixups.New fixups
  493. can be added by adding suitable record to FixupTable2. However,
  494. for these new fixups only registry fixup will be carried out.
  495. @parm IN DWORD | IsSourceNode| If the gum request originated at this node.
  496. @parm IN PVOID| pPropertyList| Pointer to a property list structure.
  497. @parm IN DWORD | pdwPropertyListSize | Pointer to a DWORD containing
  498. the size of the property list structure.
  499. @parm IN LPDWORD | lpdeFixupNum | Pointer to DWORD which specifies the
  500. the index in NmpJoinFixupProperties table.
  501. @parm IN PVOID | lpKeyName | Registry Key which needs to be updated
  502. @parm IN PVOID | pPropertyBuffer| Registry update table in marshalled form
  503. @comm The gum update handler commits this fixup to the cluster registry
  504. as a transaction.
  505. @rdesc Returns a result code. ERROR_SUCCESS on success.
  506. @xref <f NmJoinFixup> <f NmFormFixup> <f PostFixupCbTable>
  507. ****/
  508. DWORD NmpUpdatePerformFixups2(
  509. IN BOOL IsSourceNode,
  510. IN PVOID pPropertyList,
  511. IN LPDWORD pdwPropertyListSize,
  512. IN LPDWORD lpdwFixupNum,
  513. IN PVOID lpKeyName,
  514. IN PVOID pPropertyBuffer
  515. )
  516. {
  517. DWORD dwStatus = ERROR_SUCCESS;
  518. HLOCALXSACTION hXaction = NULL;
  519. HDMKEY hdmKey;
  520. PRESUTIL_PROPERTY_ITEM pPropertyTable=NULL;
  521. PRESUTIL_PROPERTY_ITEM propertyItem;
  522. if (!NmpEnterApi(NmStateOnline)) {
  523. ClRtlLogPrint(LOG_NOISE,
  524. "[NM] Not in valid state to process PerformFixups2 update. "
  525. "update.\n"
  526. );
  527. return(ERROR_NODE_NOT_AVAILABLE);
  528. }
  529. if(pPropertyBuffer == NULL)
  530. {
  531. ClRtlLogPrint(LOG_CRITICAL,
  532. "[NM] NmpUpdatePerformJoinFixups2: Bad Arguments\n"
  533. );
  534. dwStatus = ERROR_BAD_ARGUMENTS;
  535. goto FnExit;
  536. }
  537. // Begin a transaction
  538. //
  539. hXaction = DmBeginLocalUpdate();
  540. if (hXaction == NULL) {
  541. dwStatus = GetLastError();
  542. ClRtlLogPrint(LOG_CRITICAL,
  543. "[NM] NmpUpdatePerformJoinFixups2: Failed to begin a transaction, "
  544. "status %1!u!\n",
  545. dwStatus
  546. );
  547. goto FnExit;
  548. }
  549. // special case - if fixup is for the property of key "Cluster"
  550. if(!lstrcmpW((LPCWSTR)lpKeyName,CLUSREG_KEYNAME_CLUSTER))
  551. {
  552. hdmKey=DmClusterParametersKey;
  553. }
  554. else
  555. {
  556. hdmKey=DmOpenKey(DmClusterParametersKey,
  557. (LPCWSTR)lpKeyName,
  558. KEY_ALL_ACCESS
  559. );
  560. if (hdmKey == NULL)
  561. {
  562. dwStatus = GetLastError();
  563. ClRtlLogPrint(LOG_CRITICAL,
  564. "[NM] NmpUpdatePerformJoinFixups2: DmOpenKey failed to "
  565. "open key %1!ws! : error %2!u!\n",
  566. lpKeyName,dwStatus);
  567. goto FnExit;
  568. }
  569. }
  570. //unmarshall pPropertyBuffer into a RESUTIL_PROPERTY_ITEM table
  571. //
  572. dwStatus=ClRtlUnmarshallPropertyTable(&pPropertyTable,pPropertyBuffer);
  573. if(dwStatus != ERROR_SUCCESS)
  574. goto FnExit;
  575. dwStatus=ClRtlSetPropertyTable(
  576. hXaction,
  577. hdmKey,
  578. &NmpFixupRegApis,
  579. pPropertyTable,
  580. NULL,
  581. FALSE,
  582. pPropertyList,
  583. *pdwPropertyListSize,
  584. FALSE, // bForceWrite
  585. NULL
  586. );
  587. if (dwStatus != ERROR_SUCCESS) {
  588. goto FnExit;
  589. }
  590. // callback function to update in-memory structures
  591. // for any new fixup introduced in later version,
  592. // the in-memory fixups will not be applied.
  593. if (*lpdwFixupNum < (sizeof(PostFixupCbTable)/sizeof(NM_POST_FIXUP_CB)))
  594. {
  595. if (PostFixupCbTable[*lpdwFixupNum] !=NULL){
  596. dwStatus=(PostFixupCbTable[*lpdwFixupNum])();
  597. ClRtlLogPrint(LOG_UNUSUAL,
  598. "[NM] NmpUpdatePerformJoinFixups2: called postfixup "
  599. "notifycb function with status %1!u!\n",
  600. dwStatus
  601. );
  602. }
  603. }
  604. FnExit:
  605. if (hXaction != NULL)
  606. {
  607. if (dwStatus == ERROR_SUCCESS){
  608. DmCommitLocalUpdate(hXaction);
  609. }
  610. else {
  611. DmAbortLocalUpdate(hXaction);
  612. }
  613. }
  614. if((hdmKey!= DmClusterParametersKey) && (hdmKey!= NULL)) {
  615. DmCloseKey(hdmKey);
  616. }
  617. if (pPropertyTable != NULL) {
  618. // Free pPropertyTable structure
  619. propertyItem=pPropertyTable;
  620. if(propertyItem!=NULL){
  621. while(propertyItem->Name != NULL)
  622. {
  623. LocalFree(propertyItem->Name);
  624. if(propertyItem->KeyName!=NULL)
  625. LocalFree(propertyItem->KeyName);
  626. propertyItem++;
  627. }
  628. LocalFree(pPropertyTable);
  629. }
  630. }
  631. NmpLeaveApi();
  632. return(dwStatus);
  633. } // NmpUpdatePerformFixups2
  634. DWORD NmFixupNotifyCb(VOID)
  635. {
  636. ClRtlLogPrint(LOG_NOISE,
  637. "[NM] NmFixupNotifyCb: Calculating Cluster Node Limit\r\n");
  638. //update the product suite information
  639. //when the node objects are created we assume that the suite
  640. //type is Enterprise.
  641. //Here after a node has joined and informed us about its suite
  642. //type by making fixups to the registry, we read the registry
  643. //and update the node structure
  644. NmpRefreshNodeObjects();
  645. //recalc the cluster node limit
  646. NmpResetClusterNodeLimit();
  647. //SS: This is ugly---we should pass in the product suits early on
  648. //also the fixup interface needs to to be richer so that the postcallback
  649. //function nodes whether it is a form fixup or a join fixup and if it
  650. //is a join fixup, which node is joining. This could certainly optimize
  651. //some of the fixup processing
  652. return(ERROR_SUCCESS);
  653. }