Memperbarui Titik Koneksi Layanan
Contoh kode berikut menunjukkan cara memperbarui titik koneksi layanan. Kode ini biasanya dijalankan oleh layanan saat dimulai.
Contoh ini mengambil string pengikatan GUID SCP yang di-cache penginstal layanan di registri. Ini menggunakan string ini untuk mengikat ke penunjuk IDirectoryObject pada objek SCP, lalu memanggil metode IDirectoryObject::GetObjectAttributes untuk mendapatkan atribut serviceDNSName dan serviceBindingInformation scp. Ketahuilah bahwa layanan Anda mungkin perlu memverifikasi dan memperbarui atribut tambahan.
Kode membandingkan nilai serviceDNSName dengan nama DNS yang dikembalikan oleh fungsi GetComputerNameEx . Ini juga membandingkan nomor port layanan saat ini dengan nomor port yang disimpan dalam atribut serviceBindingInformation . Jika salah satu nilai ini telah berubah, kode memanggil metode IDirectoryObject::SetObjectAttributes untuk memperbarui atribut SCP.
DWORD
ScpUpdate(USHORT usPort)
{
DWORD dwStat, dwType, dwLen;
BOOL bUpdate=FALSE;
HKEY hReg;
TCHAR szAdsPath[MAX_PATH];
TCHAR szServer[MAX_PATH];
TCHAR szPort[8];
TCHAR *pszAttrs[]={
{TEXT("serviceDNSName")},
{TEXT("serviceBindingInformation")},
};
HRESULT hr;
IDirectoryObject *pObj;
DWORD dwAttrs;
int i;
PADS_ATTR_INFO pAttribs;
ADSVALUE dnsname,binding;
ADS_ATTR_INFO Attribs[]={
{TEXT("serviceDnsName"),ADS_ATTR_UPDATE,ADSTYPE_CASE_IGNORE_STRING,&dnsname,1},
{TEXT("serviceBindingInformation"),ADS_ATTR_UPDATE,ADSTYPE_CASE_IGNORE_STRING,&binding,1},
};
// Open the service registry key.
dwStat = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("Software\\Microsoft\\Windows 2000 Auth-O-Matic"),
0,
KEY_QUERY_VALUE,
&hReg);
if (dwStat != NO_ERROR)
{
ReportServiceError("RegOpenKeyEx failed", dwStat);
return dwStat;
}
// Get the GUID binding string used to bind to the service SCP.
dwLen = sizeof(szAdsPath);
dwStat = RegQueryValueEx(hReg, TEXT("GUIDBindingString"), 0, &dwType,
(LPBYTE)szAdsPath, &dwLen);
if (dwStat != NO_ERROR) {
ReportServiceError("RegQueryValueEx failed", dwStat);
return dwStat;
}
RegCloseKey(hReg);
// Bind to the SCP.
hr = ADsGetObject(szAdsPath, IID_IDirectoryObject, (void **)&pObj);
if (FAILED(hr))
{
char szMsg1[1024];
sprintf_s(szMsg1,
"ADsGetObject failed to bind to GUID (bind string: %S): ",
szAdsPath);
ReportServiceError(szMsg1, hr);
if(pObj)
{
pObj->Release();
}
return dwStat;
}
// Retrieve attributes from the SCP.
hr = pObj->GetObjectAttributes(pszAttrs, 2, &pAttribs, &dwAttrs);
if (FAILED(hr)) {
ReportServiceError("GetObjectAttributes failed", hr);
pObj->Release();
return hr;
}
// Get the current port and DNS name of the host server.
_stprintf_s(szPort,TEXT("%d"),usPort);
dwLen = sizeof(szServer);
if (!GetComputerNameEx(ComputerNameDnsFullyQualified,szServer,&dwLen))
{
pObj->Release();
return GetLastError();
}
// Compare the current DNS name and port to the values retrieved from
// the SCP. Update the SCP only if nothing has changed.
for (i=0; i<(LONG)dwAttrs; i++)
{
if ((_tcscmp(TEXT("serviceDNSName"),pAttribs[i].pszAttrName)==0) &&
(pAttribs[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING))
{
if (_tcscmp(szServer,pAttribs[i].pADsValues->CaseIgnoreString) != 0)
{
ReportServiceError("serviceDNSName being updated", 0);
bUpdate = TRUE;
}
else
ReportServiceError("serviceDNSName okay", 0);
}
if ((_tcscmp(TEXT("serviceBindingInformation"),pAttribs[i].pszAttrName)==0) &&
(pAttribs[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING))
{
if (_tcscmp(szPort,pAttribs[i].pADsValues->CaseIgnoreString) != 0)
{
ReportServiceError("serviceBindingInformation being updated", 0);
bUpdate = TRUE;
}
else
ReportServiceError("serviceBindingInformation okay", 0);
}
}
FreeADsMem(pAttribs);
// The binding data or server name have changed,
// so update the SCP values.
if (bUpdate)
{
dnsname.dwType = ADSTYPE_CASE_IGNORE_STRING;
dnsname.CaseIgnoreString = szServer;
binding.dwType = ADSTYPE_CASE_IGNORE_STRING;
binding.CaseIgnoreString = szPort;
hr = pObj->SetObjectAttributes(Attribs, 2, &dwAttrs);
if (FAILED(hr))
{
ReportServiceError("ScpUpdate: Failed to set SCP values.", hr);
pObj->Release();
return hr;
}
}
pObj->Release();
return dwStat;
}