mirror of https://github.com/tongzx/nt5src
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
799 lines
22 KiB
/*++
|
|
|
|
Copyright (c) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
node.c
|
|
|
|
Abstract:
|
|
|
|
Fix up Routines for Upgrade and Rolling Upgrades
|
|
|
|
Author:
|
|
|
|
Sunita Shrivastava(sunitas) 18-Mar-1998
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
/****
|
|
@doc EXTERNAL INTERFACES CLUSSVC DM
|
|
****/
|
|
|
|
#define UNICODE 1
|
|
|
|
#include "nmp.h"
|
|
|
|
//
|
|
// Cluster registry API function pointers.
|
|
//
|
|
CLUSTER_REG_APIS
|
|
NmpFixupRegApis = {
|
|
(PFNCLRTLCREATEKEY) DmRtlCreateKey,
|
|
(PFNCLRTLOPENKEY) DmRtlOpenKey,
|
|
(PFNCLRTLCLOSEKEY) DmCloseKey,
|
|
(PFNCLRTLSETVALUE) DmSetValue,
|
|
(PFNCLRTLQUERYVALUE) DmQueryValue,
|
|
(PFNCLRTLENUMVALUE) DmEnumValue,
|
|
(PFNCLRTLDELETEVALUE) DmDeleteValue,
|
|
(PFNCLRTLLOCALCREATEKEY) DmRtlLocalCreateKey,
|
|
(PFNCLRTLLOCALSETVALUE) DmLocalSetValue,
|
|
(PFNCLRTLLOCALDELETEVALUE) DmLocalDeleteValue,
|
|
};
|
|
|
|
//
|
|
// Data
|
|
//
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmJoinFixupSDProperties[]=
|
|
{
|
|
{
|
|
CLUSREG_NAME_CLUS_SD, NULL, CLUSPROP_FORMAT_BINARY,
|
|
0, 0, 0,
|
|
0,
|
|
0
|
|
},
|
|
{
|
|
0
|
|
}
|
|
};
|
|
|
|
// Fixup Table for WINS
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmJoinFixupWINSProperties[]=
|
|
{
|
|
{
|
|
CLUSREG_NAME_RESTYPE_IS_ALIVE, CLUS_RESTYPE_NAME_WINS , CLUSPROP_FORMAT_DWORD,
|
|
0,CLUSTER_RESTYPE_MINIMUM_IS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_IS_ALIVE ,
|
|
0,
|
|
0
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_LOOKS_ALIVE,CLUS_RESTYPE_NAME_WINS ,CLUSPROP_FORMAT_DWORD,
|
|
0,CLUSTER_RESTYPE_MINIMUM_LOOKS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_LOOKS_ALIVE ,
|
|
0,
|
|
sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_DLL_NAME,CLUS_RESTYPE_NAME_WINS ,CLUSPROP_FORMAT_SZ,
|
|
0,0,0,
|
|
0,
|
|
2*sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_NAME,CLUS_RESTYPE_NAME_WINS ,CLUSPROP_FORMAT_SZ,
|
|
0,0,0,
|
|
0,
|
|
2*sizeof(DWORD)+sizeof(LPWSTR*)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_ADMIN_EXTENSIONS,CLUS_RESTYPE_NAME_WINS,CLUSPROP_FORMAT_MULTI_SZ,
|
|
0,0,0,
|
|
0,
|
|
2*sizeof(DWORD)+2*sizeof(LPWSTR*)
|
|
},
|
|
|
|
{
|
|
0
|
|
}
|
|
}; //NmJoinFixupWINSProperties
|
|
|
|
//Fixup Table for DHCP
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmJoinFixupDHCPProperties[]=
|
|
{
|
|
{
|
|
CLUSREG_NAME_RESTYPE_IS_ALIVE, CLUS_RESTYPE_NAME_DHCP , CLUSPROP_FORMAT_DWORD,
|
|
0,CLUSTER_RESTYPE_MINIMUM_IS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_IS_ALIVE ,
|
|
0,
|
|
0
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_LOOKS_ALIVE,CLUS_RESTYPE_NAME_DHCP ,CLUSPROP_FORMAT_DWORD,
|
|
0,CLUSTER_RESTYPE_MINIMUM_LOOKS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_LOOKS_ALIVE ,
|
|
0,
|
|
sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_DLL_NAME,CLUS_RESTYPE_NAME_DHCP ,CLUSPROP_FORMAT_SZ,
|
|
0,0,0,
|
|
0,
|
|
2*sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_NAME,CLUS_RESTYPE_NAME_DHCP ,CLUSPROP_FORMAT_SZ,
|
|
0,0,0,
|
|
0,
|
|
2*sizeof(DWORD)+sizeof(LPWSTR*)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_ADMIN_EXTENSIONS,CLUS_RESTYPE_NAME_DHCP,CLUSPROP_FORMAT_MULTI_SZ,
|
|
0,0,0,
|
|
0,
|
|
2*sizeof(DWORD)+2*sizeof(LPWSTR*)
|
|
},
|
|
|
|
{
|
|
0
|
|
}
|
|
};//NmJoinFixupDHCPProperties
|
|
|
|
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmJoinFixupNewMSMQProperties[]=
|
|
{
|
|
{
|
|
CLUSREG_NAME_RESTYPE_IS_ALIVE, CLUS_RESTYPE_NAME_NEW_MSMQ,CLUSPROP_FORMAT_DWORD,
|
|
0,CLUSTER_RESTYPE_MINIMUM_IS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_IS_ALIVE ,
|
|
0,
|
|
0
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_LOOKS_ALIVE,CLUS_RESTYPE_NAME_NEW_MSMQ,CLUSPROP_FORMAT_DWORD,
|
|
0,CLUSTER_RESTYPE_MINIMUM_LOOKS_ALIVE ,CLUSTER_RESTYPE_MAXIMUM_LOOKS_ALIVE ,
|
|
0,
|
|
sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_DLL_NAME,CLUS_RESTYPE_NAME_NEW_MSMQ,CLUSPROP_FORMAT_SZ,
|
|
0,0,0,
|
|
0,
|
|
2*sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_RESTYPE_NAME,CLUS_RESTYPE_NAME_NEW_MSMQ,CLUSPROP_FORMAT_SZ,
|
|
0,0,0,
|
|
0,
|
|
2*sizeof(DWORD)+sizeof(LPWSTR*)
|
|
},
|
|
|
|
{
|
|
0
|
|
}
|
|
};//NmJoinFixupNewMSMQProperties
|
|
|
|
|
|
//Fixup Table for changing thr dl name of MSDTC resource type
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmJoinFixupMSDTCProperties[]=
|
|
{
|
|
{
|
|
CLUSREG_NAME_RESTYPE_DLL_NAME,CLUS_RESTYPE_NAME_MSDTC,CLUSPROP_FORMAT_SZ,
|
|
0,0,0,
|
|
0,
|
|
0
|
|
},
|
|
|
|
{
|
|
0
|
|
}
|
|
|
|
};//NmJoinFixupMSDTCProperties
|
|
|
|
|
|
//Fixup table for node version info
|
|
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmFixupVersionInfo[]=
|
|
{
|
|
{
|
|
CLUSREG_NAME_NODE_MAJOR_VERSION,NULL,CLUSPROP_FORMAT_DWORD,
|
|
0,0,((DWORD)-1),
|
|
0,
|
|
0
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_NODE_MINOR_VERSION,NULL,CLUSPROP_FORMAT_DWORD,
|
|
0,0,((DWORD)-1),
|
|
0,
|
|
sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_NODE_BUILD_NUMBER,NULL,CLUSPROP_FORMAT_DWORD,
|
|
0,0,((DWORD)-1),
|
|
0,
|
|
2*sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_NODE_CSDVERSION,NULL,CLUSPROP_FORMAT_SZ,
|
|
0,0,0,
|
|
0,
|
|
3*sizeof(DWORD)
|
|
},
|
|
|
|
{
|
|
CLUSREG_NAME_NODE_PRODUCT_SUITE,NULL,CLUSPROP_FORMAT_DWORD,
|
|
0,0,((DWORD)-1),
|
|
0,
|
|
3*sizeof(DWORD) + sizeof(LPWSTR*)
|
|
},
|
|
|
|
{
|
|
0
|
|
}
|
|
|
|
}; //NmFixupVersionInfo
|
|
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmFixupClusterProperties[] =
|
|
{
|
|
{
|
|
CLUSREG_NAME_ADMIN_EXT, NULL, CLUSPROP_FORMAT_MULTI_SZ,
|
|
0, 0, 0,
|
|
0,
|
|
0
|
|
},
|
|
{
|
|
0
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Used by NmUpdatePerformFixups update
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmpJoinFixupProperties[] =
|
|
{
|
|
{
|
|
CLUSREG_NAME_CLUS_SD, NULL, CLUSPROP_FORMAT_BINARY,
|
|
0, 0, 0,
|
|
0,
|
|
0
|
|
},
|
|
{
|
|
0
|
|
}
|
|
};
|
|
|
|
|
|
RESUTIL_PROPERTY_ITEM
|
|
NmpFormFixupProperties[] =
|
|
{
|
|
{
|
|
CLUSREG_NAME_CLUS_SD, NULL, CLUSPROP_FORMAT_BINARY,
|
|
0, 0, 0,
|
|
0,
|
|
0
|
|
},
|
|
{
|
|
0
|
|
}
|
|
};
|
|
|
|
NM_FIXUP_CB_RECORD FixupTable[]=
|
|
{
|
|
{ ApiFixupNotifyCb, NM_FORM_FIXUP|NM_JOIN_FIXUP}
|
|
};
|
|
|
|
// Fixup Table used for NmUpdatePerformFixups2 update type
|
|
NM_FIXUP_CB_RECORD2 FixupTable2[]=
|
|
{
|
|
{ ApiFixupNotifyCb, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmpJoinFixupProperties},
|
|
{ FmBuildWINS, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmJoinFixupWINSProperties,},
|
|
{ FmBuildDHCP, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmJoinFixupDHCPProperties},
|
|
{ FmBuildNewMSMQ, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmJoinFixupNewMSMQProperties},
|
|
{ FmBuildMSDTC, NM_FORM_FIXUP|NM_JOIN_FIXUP, NmJoinFixupMSDTCProperties},
|
|
{ NmpBuildVersionInfo, NM_JOIN_FIXUP|NM_FORM_FIXUP, NmFixupVersionInfo},
|
|
{ FmBuildClusterProp, NM_FORM_FIXUP|NM_JOIN_FIXUP,NmFixupClusterProperties}
|
|
};
|
|
|
|
|
|
NM_POST_FIXUP_CB PostFixupCbTable[]=
|
|
{
|
|
NULL,
|
|
FmFixupNotifyCb,
|
|
FmFixupNotifyCb,
|
|
FmFixupNotifyCb,
|
|
FmFixupNotifyCb,
|
|
NmFixupNotifyCb,
|
|
NULL
|
|
};
|
|
|
|
|
|
|
|
|
|
/****
|
|
@func DWORD | NmPerformFixups| This is called when a cluster is being
|
|
formed/or joining. Issues NmUpdateperforfixups GUM update
|
|
for registry fixups of SECURITY_DESCRIPTOR when NT5 node joins
|
|
NT4 node.Also issues NmUpdateperforfixups2 GUM update for
|
|
WINS and DHCP fixups when NT5 joins NT4. This update type can
|
|
be extended in future to do more fixups for postNT5 and NT5 scenario.
|
|
If later it is guaranteed that there is no NT4 node in cluster,
|
|
NmUpdatePerformFixups update type won't be needed and hence can
|
|
be taken out.
|
|
|
|
@comm The first time the cluster service forms a cluster after an
|
|
upgrade, it might have registry fixups it wants to make to the
|
|
existing cluster registry. Also, when an uplevel node
|
|
joins a downlevel node, join fixups can be performed.
|
|
Note that this is called on every form/join
|
|
|
|
@rdesc Returns a result code. ERROR_SUCCESS on success.
|
|
|
|
@xref <f NmpUpdatePerformFixups> <f NmpUpdatePerformFixups2>
|
|
****/
|
|
|
|
DWORD NmPerformFixups(
|
|
IN DWORD dwFixupType)
|
|
{
|
|
|
|
DWORD dwCount = sizeof(FixupTable)/sizeof(NM_FIXUP_CB_RECORD);
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
PNM_FIXUP_CB_RECORD pFixupCbRec;
|
|
PNM_FIXUP_CB_RECORD2 pFixupCbRec2;
|
|
PVOID pPropertyList = NULL;
|
|
DWORD dwPropertyListSize;
|
|
DWORD i,j;
|
|
DWORD dwSize;
|
|
DWORD Required;
|
|
LPWSTR szKeyName=NULL;
|
|
LPBYTE pBuffer=NULL;
|
|
PRESUTIL_PROPERTY_ITEM pPropertyItem;
|
|
|
|
ClRtlLogPrint(LOG_NOISE,"[NM] NmPerformFixups Entry, dwFixupType=%1!u!\r\n",
|
|
dwFixupType);
|
|
|
|
// using old gum update handler - this is needed to maintain compataility
|
|
// with NT4, can be discarded later. See comments above.
|
|
//
|
|
|
|
for (i=0; i < dwCount ; i++)
|
|
{
|
|
|
|
pFixupCbRec = &FixupTable[i];
|
|
|
|
//if this fixup doesnt need to be applied, skip it
|
|
if (!(pFixupCbRec->dwFixupMask & dwFixupType))
|
|
continue;
|
|
|
|
dwStatus = (pFixupCbRec->pfnFixupNotifyCb)(dwFixupType, &pPropertyList,
|
|
&dwPropertyListSize,&szKeyName);
|
|
|
|
if (dwStatus != ERROR_SUCCESS)
|
|
{
|
|
goto FnExit;
|
|
}
|
|
if (pPropertyList && dwPropertyListSize)
|
|
{
|
|
//
|
|
// Issue a global update
|
|
//
|
|
dwStatus = GumSendUpdateEx(
|
|
GumUpdateMembership,
|
|
NmUpdatePerformFixups,
|
|
2,
|
|
dwPropertyListSize,
|
|
pPropertyList,
|
|
sizeof(DWORD),
|
|
&dwPropertyListSize
|
|
);
|
|
|
|
LocalFree(pPropertyList);
|
|
pPropertyList = NULL;
|
|
if(szKeyName)
|
|
{
|
|
LocalFree(szKeyName);
|
|
szKeyName=NULL;
|
|
}
|
|
}
|
|
|
|
if (dwStatus != ERROR_SUCCESS)
|
|
goto FnExit;
|
|
}
|
|
|
|
|
|
// Rohit (rjain): introduced new update type to fix the registry and
|
|
// in-memory structures after a node with a higher version of clustering
|
|
// service joins a node with a lower version. To make it extensible in future
|
|
// all the information needed for a fixup is passed as arguments to the fixup
|
|
// function. Any new fix can be added by adding suitable record to FixupTable2 and
|
|
// a postfixup function callback to PostfixupCbTable.
|
|
|
|
dwCount= sizeof(FixupTable2)/sizeof(NM_FIXUP_CB_RECORD2);
|
|
for (i=0; i < dwCount ; i++)
|
|
{
|
|
|
|
pFixupCbRec2 = &FixupTable2[i];
|
|
|
|
//if this fixup doesnt need to be applied, skip it
|
|
if (!(pFixupCbRec2->dwFixupMask & dwFixupType))
|
|
continue;
|
|
|
|
dwStatus = (pFixupCbRec2->pfnFixupNotifyCb)(dwFixupType, &pPropertyList,
|
|
&dwPropertyListSize,&szKeyName);
|
|
|
|
if (dwStatus != ERROR_SUCCESS)
|
|
{
|
|
goto FnExit;
|
|
}
|
|
if (pPropertyList && dwPropertyListSize)
|
|
{
|
|
// Marshall PropertyTable into byte array
|
|
Required=sizeof(DWORD);
|
|
AllocMem:
|
|
pBuffer=(LPBYTE)LocalAlloc(LMEM_FIXED,Required);
|
|
if (pBuffer==NULL)
|
|
{
|
|
dwStatus=GetLastError();
|
|
goto FnExit;
|
|
}
|
|
dwSize=Required;
|
|
dwStatus=ClRtlMarshallPropertyTable(pFixupCbRec2->pPropertyTable,dwSize,pBuffer,&Required);
|
|
if(dwStatus!= ERROR_SUCCESS)
|
|
{
|
|
LocalFree(pBuffer);
|
|
pBuffer=NULL;
|
|
// ClRtlLogPrint(LOG_NOISE,"[NM] NmPerformFixups - Memory Required=%1!u!\r\n",
|
|
// Required);
|
|
goto AllocMem;
|
|
}
|
|
//
|
|
// Issue a global update
|
|
//
|
|
dwStatus = GumSendUpdateEx(
|
|
GumUpdateMembership,
|
|
NmUpdatePerformFixups2,
|
|
5,
|
|
dwPropertyListSize,
|
|
pPropertyList,
|
|
sizeof(DWORD),
|
|
&dwPropertyListSize,
|
|
sizeof(DWORD),
|
|
&i,
|
|
(lstrlenW(szKeyName)+1)*sizeof(WCHAR),
|
|
szKeyName,
|
|
Required,
|
|
pBuffer
|
|
);
|
|
|
|
LocalFree(pPropertyList);
|
|
pPropertyList = NULL;
|
|
LocalFree(pBuffer);
|
|
pBuffer= NULL;
|
|
if(szKeyName)
|
|
{
|
|
LocalFree(szKeyName);
|
|
szKeyName= NULL;
|
|
}
|
|
}
|
|
|
|
if (dwStatus != ERROR_SUCCESS)
|
|
break;
|
|
}
|
|
|
|
|
|
FnExit:
|
|
if(szKeyName)
|
|
{
|
|
LocalFree(szKeyName);
|
|
szKeyName=NULL;
|
|
}
|
|
ClRtlLogPrint(LOG_NOISE,"[NM] NmPerformFixups Exit, dwStatus=%1!u!\r\n",
|
|
dwStatus);
|
|
|
|
return(dwStatus);
|
|
|
|
} //NmPerformFixups
|
|
|
|
|
|
|
|
/****
|
|
@func DWORD | NmpUpdatePerformFixups| The gum update handler for
|
|
doing the registry fixups.
|
|
|
|
@parm IN DWORD | IsSourceNode| If the gum request originated at this
|
|
node.
|
|
|
|
@parm IN PVOID| pPropertyList| Pointer to a property list structure.
|
|
|
|
@parm IN DWORD | pdwPropertyListSize | A pointer to a DWORD containing
|
|
the size of the property list structure.
|
|
|
|
@comm The gum update handler commits this fixup to the cluster registry
|
|
as a transaction.
|
|
|
|
@rdesc Returns a result code. ERROR_SUCCESS on success.
|
|
|
|
@xref <f NmJoinFixup> <f NmFormFixup>
|
|
****/
|
|
DWORD NmpUpdatePerformFixups(
|
|
IN BOOL IsSourceNode,
|
|
IN PVOID pPropertyList,
|
|
IN LPDWORD pdwPropertyListSize
|
|
)
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
HLOCALXSACTION hXaction;
|
|
|
|
|
|
if (!NmpEnterApi(NmStateOnline)) {
|
|
ClRtlLogPrint(LOG_NOISE,
|
|
"[NM] Not in valid state to process PerformFixups update. "
|
|
"update.\n"
|
|
);
|
|
return(ERROR_NODE_NOT_AVAILABLE);
|
|
}
|
|
|
|
//
|
|
// Begin a transaction
|
|
//
|
|
hXaction = DmBeginLocalUpdate();
|
|
|
|
if (hXaction != NULL) {
|
|
dwStatus = ClRtlSetPropertyTable(
|
|
hXaction,
|
|
DmClusterParametersKey,
|
|
&NmpFixupRegApis,
|
|
NmpJoinFixupProperties,
|
|
NULL,
|
|
FALSE,
|
|
pPropertyList,
|
|
*pdwPropertyListSize,
|
|
FALSE /*bForceWrite*/,
|
|
NULL
|
|
);
|
|
|
|
if (dwStatus == ERROR_SUCCESS) {
|
|
DmCommitLocalUpdate(hXaction);
|
|
}
|
|
else {
|
|
DmAbortLocalUpdate(hXaction);
|
|
}
|
|
}
|
|
else {
|
|
dwStatus = GetLastError();
|
|
ClRtlLogPrint(LOG_CRITICAL, "[NM] Failed to begin a transaction "
|
|
"to perform fixups, status %1!u!\n",
|
|
dwStatus
|
|
);
|
|
}
|
|
|
|
NmpLeaveApi();
|
|
|
|
return(dwStatus);
|
|
|
|
} // NmpUpdatePerformFixups
|
|
|
|
|
|
/****
|
|
@func DWORD | NmpUpdatePerformFixups2| The gum update handler for
|
|
doing the registry fixups and updating in-memory fixups.New fixups
|
|
can be added by adding suitable record to FixupTable2. However,
|
|
for these new fixups only registry fixup will be carried out.
|
|
|
|
@parm IN DWORD | IsSourceNode| If the gum request originated at this node.
|
|
|
|
@parm IN PVOID| pPropertyList| Pointer to a property list structure.
|
|
|
|
@parm IN DWORD | pdwPropertyListSize | Pointer to a DWORD containing
|
|
the size of the property list structure.
|
|
|
|
@parm IN LPDWORD | lpdeFixupNum | Pointer to DWORD which specifies the
|
|
the index in NmpJoinFixupProperties table.
|
|
@parm IN PVOID | lpKeyName | Registry Key which needs to be updated
|
|
|
|
@parm IN PVOID | pPropertyBuffer| Registry update table in marshalled form
|
|
|
|
@comm The gum update handler commits this fixup to the cluster registry
|
|
as a transaction.
|
|
|
|
@rdesc Returns a result code. ERROR_SUCCESS on success.
|
|
|
|
@xref <f NmJoinFixup> <f NmFormFixup> <f PostFixupCbTable>
|
|
****/
|
|
|
|
DWORD NmpUpdatePerformFixups2(
|
|
IN BOOL IsSourceNode,
|
|
IN PVOID pPropertyList,
|
|
IN LPDWORD pdwPropertyListSize,
|
|
IN LPDWORD lpdwFixupNum,
|
|
IN PVOID lpKeyName,
|
|
IN PVOID pPropertyBuffer
|
|
)
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
HLOCALXSACTION hXaction = NULL;
|
|
HDMKEY hdmKey;
|
|
PRESUTIL_PROPERTY_ITEM pPropertyTable=NULL;
|
|
PRESUTIL_PROPERTY_ITEM propertyItem;
|
|
|
|
|
|
if (!NmpEnterApi(NmStateOnline)) {
|
|
ClRtlLogPrint(LOG_NOISE,
|
|
"[NM] Not in valid state to process PerformFixups2 update. "
|
|
"update.\n"
|
|
);
|
|
return(ERROR_NODE_NOT_AVAILABLE);
|
|
}
|
|
|
|
if(pPropertyBuffer == NULL)
|
|
{
|
|
ClRtlLogPrint(LOG_CRITICAL,
|
|
"[NM] NmpUpdatePerformJoinFixups2: Bad Arguments\n"
|
|
);
|
|
dwStatus = ERROR_BAD_ARGUMENTS;
|
|
goto FnExit;
|
|
}
|
|
|
|
// Begin a transaction
|
|
//
|
|
hXaction = DmBeginLocalUpdate();
|
|
|
|
if (hXaction == NULL) {
|
|
dwStatus = GetLastError();
|
|
ClRtlLogPrint(LOG_CRITICAL,
|
|
"[NM] NmpUpdatePerformJoinFixups2: Failed to begin a transaction, "
|
|
"status %1!u!\n",
|
|
dwStatus
|
|
);
|
|
goto FnExit;
|
|
}
|
|
|
|
// special case - if fixup is for the property of key "Cluster"
|
|
if(!lstrcmpW((LPCWSTR)lpKeyName,CLUSREG_KEYNAME_CLUSTER))
|
|
{
|
|
hdmKey=DmClusterParametersKey;
|
|
}
|
|
else
|
|
{
|
|
hdmKey=DmOpenKey(DmClusterParametersKey,
|
|
(LPCWSTR)lpKeyName,
|
|
KEY_ALL_ACCESS
|
|
);
|
|
if (hdmKey == NULL)
|
|
{
|
|
dwStatus = GetLastError();
|
|
ClRtlLogPrint(LOG_CRITICAL,
|
|
"[NM] NmpUpdatePerformJoinFixups2: DmOpenKey failed to "
|
|
"open key %1!ws! : error %2!u!\n",
|
|
lpKeyName,dwStatus);
|
|
goto FnExit;
|
|
}
|
|
}
|
|
|
|
//unmarshall pPropertyBuffer into a RESUTIL_PROPERTY_ITEM table
|
|
//
|
|
dwStatus=ClRtlUnmarshallPropertyTable(&pPropertyTable,pPropertyBuffer);
|
|
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
goto FnExit;
|
|
|
|
dwStatus=ClRtlSetPropertyTable(
|
|
hXaction,
|
|
hdmKey,
|
|
&NmpFixupRegApis,
|
|
pPropertyTable,
|
|
NULL,
|
|
FALSE,
|
|
pPropertyList,
|
|
*pdwPropertyListSize,
|
|
FALSE, // bForceWrite
|
|
NULL
|
|
);
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
goto FnExit;
|
|
}
|
|
|
|
// callback function to update in-memory structures
|
|
// for any new fixup introduced in later version,
|
|
// the in-memory fixups will not be applied.
|
|
if (*lpdwFixupNum < (sizeof(PostFixupCbTable)/sizeof(NM_POST_FIXUP_CB)))
|
|
{
|
|
if (PostFixupCbTable[*lpdwFixupNum] !=NULL){
|
|
dwStatus=(PostFixupCbTable[*lpdwFixupNum])();
|
|
ClRtlLogPrint(LOG_UNUSUAL,
|
|
"[NM] NmpUpdatePerformJoinFixups2: called postfixup "
|
|
"notifycb function with status %1!u!\n",
|
|
dwStatus
|
|
);
|
|
}
|
|
}
|
|
|
|
FnExit:
|
|
if (hXaction != NULL)
|
|
{
|
|
if (dwStatus == ERROR_SUCCESS){
|
|
DmCommitLocalUpdate(hXaction);
|
|
}
|
|
else {
|
|
DmAbortLocalUpdate(hXaction);
|
|
}
|
|
}
|
|
|
|
if((hdmKey!= DmClusterParametersKey) && (hdmKey!= NULL)) {
|
|
DmCloseKey(hdmKey);
|
|
}
|
|
|
|
if (pPropertyTable != NULL) {
|
|
// Free pPropertyTable structure
|
|
propertyItem=pPropertyTable;
|
|
|
|
if(propertyItem!=NULL){
|
|
while(propertyItem->Name != NULL)
|
|
{
|
|
LocalFree(propertyItem->Name);
|
|
if(propertyItem->KeyName!=NULL)
|
|
LocalFree(propertyItem->KeyName);
|
|
propertyItem++;
|
|
}
|
|
|
|
LocalFree(pPropertyTable);
|
|
}
|
|
}
|
|
|
|
NmpLeaveApi();
|
|
|
|
return(dwStatus);
|
|
|
|
} // NmpUpdatePerformFixups2
|
|
|
|
|
|
|
|
DWORD NmFixupNotifyCb(VOID)
|
|
{
|
|
|
|
ClRtlLogPrint(LOG_NOISE,
|
|
"[NM] NmFixupNotifyCb: Calculating Cluster Node Limit\r\n");
|
|
//update the product suite information
|
|
//when the node objects are created we assume that the suite
|
|
//type is Enterprise.
|
|
//Here after a node has joined and informed us about its suite
|
|
//type by making fixups to the registry, we read the registry
|
|
//and update the node structure
|
|
NmpRefreshNodeObjects();
|
|
//recalc the cluster node limit
|
|
NmpResetClusterNodeLimit();
|
|
|
|
//SS: This is ugly---we should pass in the product suits early on
|
|
//also the fixup interface needs to to be richer so that the postcallback
|
|
//function nodes whether it is a form fixup or a join fixup and if it
|
|
//is a join fixup, which node is joining. This could certainly optimize
|
|
//some of the fixup processing
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
|