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.
787 lines
19 KiB
787 lines
19 KiB
/*
|
|
** Copyright (c) 1998 Microsoft Corporation
|
|
** All Rights Reserved
|
|
**
|
|
*/
|
|
#include <windows.h>
|
|
#include <wchar.h>
|
|
#include <objbase.h>
|
|
#include <winbase.h>
|
|
|
|
// Required by SSPI.H
|
|
#define SECURITY_WIN32
|
|
#include <sspi.h>
|
|
|
|
#include <dsgetdc.h>
|
|
#include <ntdsapi.h>
|
|
#include <lmcons.h>
|
|
#include <lmapibuf.h>
|
|
#include <activeds.h>
|
|
|
|
#define CWSTR_SIZE(x) (sizeof(x) - (sizeof(WCHAR) * 2))
|
|
#define DWSTR_SIZE(x) ((wcslen(x) + 1) * sizeof(WCHAR))
|
|
|
|
#define LICENSE_SETTINGS L"TS-Enterprise-License-Server"
|
|
#define LICENSE_SETTINGS2 L"CN=TS-Enterprise-License-Server"
|
|
#define LICENSE_SETTINGS_OBJECT_CLASS L"LicensingSiteSettings"
|
|
#define LICENSE_SETTINGS_FORMAT L"LDAP://CN=%ws,CN=%ws,CN=%ws,%ws"
|
|
#define LICENSE_SETTINGS_SIZE CWSTR_SIZE(LICENSE_SETTINGS)
|
|
#define LICENSE_SETTINGS_FORMAT_SIZE CWSTR_SIZE(LICENSE_SETTINGS_FORMAT)
|
|
#define SITES L"sites"
|
|
#define SITES_SIZE CWSTR_SIZE(SITES)
|
|
#define SITE_SERVER L"siteServer"
|
|
#define SITE_FORMAT L"LDAP://CN=%ws,CN=%ws,%ws"
|
|
#define SITE_FORMAT_SIZE CWSTR_SIZE(SITE_FORMAT)
|
|
#define CONFIG_CNTNR L"ConfigurationNamingContext"
|
|
#define ROOT_DSE_PATH L"LDAP://RootDSE"
|
|
|
|
HRESULT GetLicenseSettingsObjectP(VARIANT *pvar,
|
|
LPWSTR *ppwszLicenseSettings,
|
|
LPWSTR *ppwszSiteName,
|
|
IADs **ppADs)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwErr;
|
|
LPWSTR pwszConfigContainer;
|
|
IADs * pADs = NULL;
|
|
|
|
VariantInit(pvar);
|
|
|
|
dwErr = DsGetSiteName(NULL, ppwszSiteName);
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsGetSiteName failed %d - 0x%x\n",dwErr,HRESULT_FROM_WIN32(dwErr));
|
|
#endif
|
|
return HRESULT_FROM_WIN32(dwErr);
|
|
}
|
|
|
|
//
|
|
// Obtain the path to the configuration container.
|
|
//
|
|
|
|
hr = ADsGetObject(ROOT_DSE_PATH, IID_IADs, (void **)&pADs);
|
|
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"ADsGetObject (%ws) failed 0x%x \n",ROOT_DSE_PATH,dwErr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr = pADs->Get(CONFIG_CNTNR, pvar);
|
|
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"Get (%ws) failed 0x%x \n",CONFIG_CNTNR,hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
if (V_VT(pvar) != VT_BSTR) {
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"Bad pvar 0x%x \n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
pwszConfigContainer = pvar->bstrVal; // For sake of readability.
|
|
|
|
//
|
|
// Build the X.500 path to the LicenseSettings object.
|
|
//
|
|
|
|
*ppwszLicenseSettings = (LPWSTR)LocalAlloc(
|
|
LPTR,
|
|
LICENSE_SETTINGS_FORMAT_SIZE
|
|
+ LICENSE_SETTINGS_SIZE
|
|
+ DWSTR_SIZE(*ppwszSiteName)
|
|
+ SITES_SIZE
|
|
+ DWSTR_SIZE(pwszConfigContainer)
|
|
+ sizeof(WCHAR));
|
|
|
|
if (*ppwszLicenseSettings == NULL) {
|
|
hr = E_OUTOFMEMORY;
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"LocalAlloc failed 0x%x \n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
wsprintf(*ppwszLicenseSettings,
|
|
LICENSE_SETTINGS_FORMAT,
|
|
LICENSE_SETTINGS,
|
|
*ppwszSiteName,
|
|
SITES,
|
|
pwszConfigContainer);
|
|
|
|
hr = ADsGetObject(*ppwszLicenseSettings, IID_IADs, (void **)ppADs);
|
|
|
|
CleanExit:
|
|
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"ADsGetObject (%ws) failed? 0x%x \n",*ppwszLicenseSettings,hr);
|
|
#endif
|
|
|
|
if (NULL != pADs) {
|
|
pADs->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
GetServerPos(IADs *pADs,
|
|
VARIANT *pvar,
|
|
LONG *plLower,
|
|
LONG *plUpper,
|
|
LONG *plPos,
|
|
WCHAR *ComputerName
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
VARIANT var;
|
|
SAFEARRAY *psaServers;
|
|
|
|
VariantInit(&var);
|
|
|
|
hr = pADs->GetEx(SITE_SERVER,pvar);
|
|
if (FAILED(hr))
|
|
{
|
|
hr = S_FALSE; // already gone
|
|
goto CleanExit;
|
|
}
|
|
|
|
psaServers = V_ARRAY(pvar);
|
|
if (NULL == psaServers)
|
|
{
|
|
hr = S_FALSE; // already gone
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr= SafeArrayGetLBound( psaServers, 1, plLower );
|
|
if (FAILED(hr))
|
|
{
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr= SafeArrayGetUBound( psaServers, 1, plUpper );
|
|
if (FAILED(hr))
|
|
{
|
|
goto CleanExit;
|
|
}
|
|
|
|
for( *plPos = *plLower; *plPos <= *plUpper; *plPos++ )
|
|
{
|
|
VariantClear( &var );
|
|
hr = SafeArrayGetElement( psaServers, plPos, &var );
|
|
if (SUCCEEDED(hr) && (V_VT(&var) == VT_BSTR) && (V_BSTR(&var) != NULL))
|
|
{
|
|
if (0 == lstrcmpi(V_BSTR(&var),ComputerName))
|
|
{
|
|
hr = S_OK;
|
|
goto CleanExit;
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = S_FALSE;
|
|
|
|
CleanExit:
|
|
VariantClear(&var);
|
|
|
|
return hr;
|
|
}
|
|
|
|
extern "C"
|
|
HRESULT
|
|
PublishEnterpriseServer()
|
|
{
|
|
LPWSTR pwszSiteName = NULL;
|
|
DWORD dwErr;
|
|
LPWSTR pwszConfigContainer;
|
|
IADs * pADs = NULL;
|
|
IADs * pADs2 = NULL;
|
|
IADsContainer * pADsContainer = NULL;
|
|
VARIANT var;
|
|
VARIANT var2;
|
|
VARIANT var3;
|
|
VARIANT var4;
|
|
LPWSTR pwszLicenseSettings = NULL;
|
|
LPWSTR pwszSite = NULL;
|
|
IDispatch * pDisp = NULL;
|
|
WCHAR ComputerName[MAX_PATH+1];
|
|
ULONG ulen;
|
|
BOOL br;
|
|
HRESULT hr;
|
|
LONG lLower,lUpper,lPos;
|
|
SAFEARRAYBOUND sabServers;
|
|
LPWSTR pwszDN = NULL;
|
|
DS_NAME_RESULT * pDsResult = NULL;
|
|
HANDLE hDS;
|
|
LPWSTR rgpwszNames[2];
|
|
DOMAIN_CONTROLLER_INFO *pDCInfo = NULL;
|
|
LPWSTR pwszDomain;
|
|
WCHAR wszName[MAX_PATH + 1];
|
|
|
|
//
|
|
// We're going to use ADSI, so initialize COM. We don't
|
|
// care about OLE 1.0 so disable OLE 1 DDE
|
|
//
|
|
hr = CoInitializeEx(NULL,COINIT_MULTITHREADED| COINIT_DISABLE_OLE1DDE);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"CoInitializeEx failed 0x%lx\n",hr);
|
|
#endif
|
|
return hr;
|
|
}
|
|
|
|
VariantInit(&var);
|
|
VariantInit(&var2);
|
|
VariantInit(&var3);
|
|
VariantInit(&var4);
|
|
|
|
// Get the computer name of the local computer.
|
|
ulen = sizeof(ComputerName) / sizeof(TCHAR);
|
|
br = GetComputerName(ComputerName, &ulen);
|
|
|
|
if (!br)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"GetComputerName failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
//
|
|
// Get domain name
|
|
//
|
|
hr = DsGetDcName(NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
DS_DIRECTORY_SERVICE_PREFERRED | DS_RETURN_FLAT_NAME,
|
|
&pDCInfo);
|
|
|
|
|
|
if (hr != ERROR_SUCCESS) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsGetDcName failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
pwszDomain = pDCInfo->DomainName;
|
|
|
|
//
|
|
// Bind to the DS (get a handle for use with DsCrackNames).
|
|
//
|
|
|
|
hr = DsBind(NULL, pwszDomain, &hDS);
|
|
|
|
if (hr != ERROR_SUCCESS) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsBind failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
//
|
|
// Request the DS-DN of this server's computer object.
|
|
//
|
|
|
|
if (lstrlen(pwszDomain) + lstrlen(ComputerName) + 3 > sizeof(wszName) / sizeof(WCHAR))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"Domain or ComputerName too long\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
wsprintf(wszName,
|
|
L"%ws\\%ws$",
|
|
pwszDomain,
|
|
ComputerName);
|
|
|
|
rgpwszNames[0] = wszName;
|
|
rgpwszNames[1] = NULL;
|
|
|
|
hr = DsCrackNames(hDS,
|
|
DS_NAME_NO_FLAGS,
|
|
DS_UNKNOWN_NAME,
|
|
DS_FQDN_1779_NAME,
|
|
1,
|
|
&rgpwszNames[0],
|
|
&pDsResult);
|
|
|
|
DsUnBind(&hDS);
|
|
|
|
if (hr != ERROR_SUCCESS)
|
|
{
|
|
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsCrackNames failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
if (pDsResult->rItems[0].status != DS_NAME_NO_ERROR) {
|
|
if (pDsResult->rItems[0].status == DS_NAME_ERROR_RESOLVING) {
|
|
hr = ERROR_PATH_NOT_FOUND;
|
|
}
|
|
else {
|
|
hr = pDsResult->rItems[0].status;
|
|
}
|
|
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsCrackNames (%ws) result bad 0x%lx\n",ComputerName,hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
V_VT(&var3) = VT_BSTR;
|
|
pwszDN = pDsResult->rItems[0].pName;
|
|
V_BSTR(&var3) = SysAllocString(pwszDN);
|
|
|
|
if (NULL == V_BSTR(&var3))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr = GetLicenseSettingsObjectP(&var,
|
|
&pwszLicenseSettings,
|
|
&pwszSiteName,
|
|
&pADs);
|
|
|
|
pwszConfigContainer = var.bstrVal;
|
|
|
|
if (hr == HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT))
|
|
{
|
|
// Doesn't yet exist, create it
|
|
|
|
//
|
|
// Build the X.500 path to the Site object.
|
|
//
|
|
|
|
pwszSite = (LPWSTR)LocalAlloc(LPTR,
|
|
SITE_FORMAT_SIZE
|
|
+ DWSTR_SIZE(pwszSiteName)
|
|
+ SITES_SIZE
|
|
+ DWSTR_SIZE(pwszConfigContainer)
|
|
+ sizeof(WCHAR));
|
|
|
|
if (pwszSite == NULL) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto CleanExit;
|
|
}
|
|
|
|
wsprintf(pwszSite,
|
|
SITE_FORMAT,
|
|
pwszSiteName,
|
|
SITES,
|
|
pwszConfigContainer);
|
|
|
|
hr = ADsGetObject(pwszSite,
|
|
IID_IADsContainer,
|
|
(void **)&pADsContainer);
|
|
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"ADsGetObject (%ws) failed 0x%lx\n",pwszSite,hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"Got container (%ws)\n",pwszSite);
|
|
#endif
|
|
|
|
//
|
|
// Create the license settings leaf object.
|
|
//
|
|
|
|
hr = pADsContainer->Create(LICENSE_SETTINGS_OBJECT_CLASS,
|
|
LICENSE_SETTINGS2,
|
|
&pDisp);
|
|
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"Create (LICENSE_SETTINGS) failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"Created (%ws)\n",LICENSE_SETTINGS2);
|
|
#endif
|
|
|
|
hr = pDisp->QueryInterface(IID_IADs,
|
|
(void **)&pADs2);
|
|
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"QueryInterface failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr = pADs2->Put(SITE_SERVER,var3);
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"Put (%ws) failed 0x%lx\n",SITE_SERVER,hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
//
|
|
// Persist the change via SetInfo.
|
|
//
|
|
|
|
hr = pADs2->SetInfo();
|
|
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"SetInfo (%ws)=(%ws) failed 0x%lx\n",SITE_SERVER,V_BSTR(&var3),hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
} else if (SUCCEEDED(hr))
|
|
{
|
|
// Already exists; update it
|
|
|
|
hr = GetServerPos(pADs,&var2,&lLower,&lUpper,&lPos,pwszDN);
|
|
|
|
if (FAILED(hr) || (hr == S_OK))
|
|
{
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"GetServerPos failed ? 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr = ADsBuildVarArrayStr( &(V_BSTR(&var3)), 1, &var4);
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"ADsBuildVarArrayStr (%ws) failed 0x%lx\n",V_BSTR(&var3),hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr = pADs->PutEx(ADS_PROPERTY_APPEND,SITE_SERVER,var4);
|
|
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"PutEx (%ws)=(%ws) failed 0x%lx\n",SITE_SERVER,V_BSTR(&var3),hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr = pADs->SetInfo();
|
|
if (FAILED(hr)) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"SetInfo 2 failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
} else
|
|
{
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"GetLicenseSettingsObject failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
CleanExit:
|
|
VariantClear(&var);
|
|
VariantClear(&var2);
|
|
VariantClear(&var3);
|
|
VariantClear(&var4);
|
|
|
|
if (pwszSiteName != NULL) { // Allocated from DsGetSiteName
|
|
NetApiBufferFree(pwszSiteName);
|
|
}
|
|
|
|
if (pwszLicenseSettings != NULL) {
|
|
LocalFree(pwszLicenseSettings);
|
|
}
|
|
|
|
if (pwszSite != NULL) {
|
|
LocalFree(pwszSite);
|
|
}
|
|
|
|
if (NULL != pADs) {
|
|
pADs->Release();
|
|
}
|
|
|
|
if (NULL != pADs2) {
|
|
pADs2->Release();
|
|
}
|
|
|
|
if (NULL != pDisp) {
|
|
pDisp->Release();
|
|
}
|
|
|
|
if (NULL != pADsContainer) {
|
|
pADsContainer->Release();
|
|
}
|
|
|
|
if (pDsResult != NULL) {
|
|
DsFreeNameResult(pDsResult);
|
|
}
|
|
|
|
if (pDCInfo != NULL) {
|
|
NetApiBufferFree(pDCInfo); // Allocated from DsGetDcName
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
return hr;
|
|
}
|
|
|
|
extern "C"
|
|
HRESULT
|
|
UnpublishEnterpriseServer()
|
|
{
|
|
IADs * pADs = NULL;
|
|
HRESULT hr;
|
|
LPWSTR pwszLicenseSettings = NULL;
|
|
LPWSTR pwszSiteName = NULL;
|
|
VARIANT var;
|
|
VARIANT var2;
|
|
VARIANT var3;
|
|
SAFEARRAYBOUND sabServers;
|
|
WCHAR ComputerName[MAX_PATH+1];
|
|
ULONG ulen;
|
|
BOOL br;
|
|
LONG lPos,lLower, lUpper;
|
|
DS_NAME_RESULT * pDsResult = NULL;
|
|
HANDLE hDS;
|
|
LPWSTR rgpwszNames[2];
|
|
LPWSTR pwszDN;
|
|
DOMAIN_CONTROLLER_INFO *pDCInfo = NULL;
|
|
LPWSTR pwszDomain;
|
|
WCHAR wszName[MAX_PATH + 1];
|
|
|
|
// We're going to use ADSI, so initialize COM. We don't
|
|
// care about OLE 1.0 so disable OLE 1 DDE
|
|
|
|
hr = CoInitializeEx(NULL,COINIT_MULTITHREADED| COINIT_DISABLE_OLE1DDE);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
VariantInit(&var);
|
|
VariantInit(&var2);
|
|
VariantInit(&var3);
|
|
|
|
// Get the computer name of the local computer.
|
|
ulen = sizeof(ComputerName) / sizeof(TCHAR);
|
|
br=GetComputerName(ComputerName,
|
|
&ulen);
|
|
if (!br)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto CleanExit;
|
|
}
|
|
|
|
//
|
|
// Get domain name
|
|
//
|
|
hr = DsGetDcName(NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
DS_DIRECTORY_SERVICE_PREFERRED | DS_RETURN_FLAT_NAME,
|
|
&pDCInfo);
|
|
|
|
|
|
if (hr != ERROR_SUCCESS) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsGetDcName failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
pwszDomain = pDCInfo->DomainName;
|
|
|
|
//
|
|
// Bind to the DS (get a handle for use with DsCrackNames).
|
|
//
|
|
|
|
hr = DsBind(NULL, pwszDomain, &hDS);
|
|
|
|
if (hr != ERROR_SUCCESS) {
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsBind failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
//
|
|
// Request the DS-DN of this server's computer object.
|
|
//
|
|
|
|
if (lstrlen(pwszDomain) + lstrlen(ComputerName) + 3 > sizeof(wszName) / sizeof(WCHAR))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"Domain or ComputerName too long\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
wsprintf(wszName,
|
|
L"%ws\\%ws$",
|
|
pwszDomain,
|
|
ComputerName);
|
|
|
|
rgpwszNames[0] = wszName;
|
|
rgpwszNames[1] = NULL;
|
|
|
|
hr = DsCrackNames(hDS,
|
|
DS_NAME_NO_FLAGS,
|
|
DS_UNKNOWN_NAME,
|
|
DS_FQDN_1779_NAME,
|
|
1,
|
|
&rgpwszNames[0],
|
|
&pDsResult);
|
|
|
|
DsUnBind(&hDS);
|
|
|
|
if (hr != ERROR_SUCCESS)
|
|
{
|
|
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsCrackNames failed 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
if (pDsResult->rItems[0].status != DS_NAME_NO_ERROR) {
|
|
if (pDsResult->rItems[0].status == DS_NAME_ERROR_RESOLVING) {
|
|
hr = ERROR_PATH_NOT_FOUND;
|
|
}
|
|
else {
|
|
hr = pDsResult->rItems[0].status;
|
|
}
|
|
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"DsCrackNames result bad 0x%lx\n",hr);
|
|
#endif
|
|
goto CleanExit;
|
|
}
|
|
|
|
V_VT(&var3) = VT_BSTR;
|
|
pwszDN = pDsResult->rItems[0].pName;
|
|
V_BSTR(&var3) = SysAllocString(pwszDN);
|
|
|
|
if (NULL == V_BSTR(&var3))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto CleanExit;
|
|
}
|
|
|
|
hr = GetLicenseSettingsObjectP(&var,
|
|
&pwszLicenseSettings,
|
|
&pwszSiteName,
|
|
&pADs);
|
|
|
|
if (hr == HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT))
|
|
{
|
|
hr = S_OK; // already gone
|
|
goto CleanExit;
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
goto CleanExit;
|
|
}
|
|
|
|
#ifdef PRIVATEDEBUG
|
|
wprintf(L"pADs %ws NULL \n",(pADs == NULL) ? L"==" : L"!=");
|
|
if (NULL == pADs)
|
|
{
|
|
goto CleanExit;
|
|
}
|
|
#endif
|
|
|
|
hr = GetServerPos(pADs,&var2,&lLower,&lUpper,&lPos,pwszDN);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
goto CleanExit;
|
|
}
|
|
|
|
if (hr == S_FALSE)
|
|
{
|
|
hr = S_OK; // Already gone
|
|
goto CleanExit;
|
|
}
|
|
|
|
if (lLower == lUpper)
|
|
{
|
|
// only one element, delete
|
|
hr = pADs->PutEx(ADS_PROPERTY_CLEAR,SITE_SERVER,var2);
|
|
if (FAILED(hr)) {
|
|
goto CleanExit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (lPos != lUpper)
|
|
{
|
|
// move the last element here
|
|
SafeArrayGetElement(V_ARRAY(&var2),&lUpper,&var3);
|
|
SafeArrayPutElement(V_ARRAY(&var2),&lPos,&var3);
|
|
}
|
|
|
|
sabServers.lLbound = lLower;
|
|
sabServers.cElements = lUpper-lLower;
|
|
|
|
SafeArrayRedim(V_ARRAY(&var2),&sabServers);
|
|
|
|
hr = pADs->Put(SITE_SERVER,var2);
|
|
if (FAILED(hr)) {
|
|
goto CleanExit;
|
|
}
|
|
}
|
|
|
|
hr = pADs->SetInfo();
|
|
if (FAILED(hr)) {
|
|
goto CleanExit;
|
|
}
|
|
|
|
CleanExit:
|
|
VariantClear(&var);
|
|
VariantClear(&var2);
|
|
VariantClear(&var3);
|
|
|
|
if (pwszSiteName != NULL) { // Allocated from DsGetSiteName
|
|
NetApiBufferFree(pwszSiteName);
|
|
}
|
|
|
|
if (pwszLicenseSettings != NULL) {
|
|
LocalFree(pwszLicenseSettings);
|
|
}
|
|
|
|
if (NULL != pADs) {
|
|
pADs->Release();
|
|
}
|
|
|
|
if (pDCInfo != NULL) {
|
|
NetApiBufferFree(pDCInfo); // Allocated from DsGetDcName
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
return hr;
|
|
}
|