windows-nt/Source/XPSP1/NT/com/ole32/cs/backend/dscon.cxx
2020-09-26 16:20:57 +08:00

341 lines
8.5 KiB
C++

//
// Author: DebiM
// Date: September 1996
//
//
// Class Store Schema creation and access using ADs
//
// This source file contains implementations for IClassAccess,
// interface for CClassAccess object.
//
//
//---------------------------------------------------------------------
#include "cstore.hxx"
HRESULT CreateContainer (HANDLE pParent,
LPOLESTR szName,
LPOLESTR szDesc
)
{
HRESULT hr;
int l;
ADS_ATTR_INFO Attr[3];
//
// Use the Parent Container interface to Create the child.
//
PackStrToAttr(Attr, OBJECTCLASS, CLASS_CS_CONTAINER);
PackStrToAttr(Attr+1, DESCRIPTION, szDesc);
//
// Set its schema version
//
//PackDWToAttr(Attr+2, STOREVERSION, SCHEMA_VERSION_NUMBER);
hr = ADSICreateDSObject(pParent, szName, Attr, 2);
return hr;
}
HRESULT CreateRepository(LPOLESTR szParentPath, LPOLESTR szStoreName, LPOLESTR szPolicyDn)
{
HRESULT hr = S_OK;
HANDLE hADsParent = NULL;
HANDLE hADsContainer = NULL;
HANDLE hADsPolicy = NULL;
LPOLESTR szContainerName = NULL;
LPOLESTR szPolicyName = NULL;
int l;
WCHAR szPath [_MAX_PATH];
WCHAR * szFullName = NULL;
WCHAR szUsn[30];
ADS_ATTR_INFO pAttr[4];
DWORD cGot = 0, cModified = 0;
BOOL fCreatedContainer = FALSE,
fCreatedCategories = FALSE,
fCreatedClasses = FALSE;
LPOLESTR AttrName = GPNAME;
ADS_ATTR_INFO * pGetAttr = NULL;
if (!szParentPath)
{
hr = GetRootPath(szPath);
//
// If failed go away
//
if (FAILED(hr))
{
return hr;
}
szParentPath = szPath;
}
//
// First get the PolicyName
//
if (szPolicyDn)
{
hr = ADSIOpenDSObject(szPolicyDn, NULL, NULL, ADS_SECURE_AUTHENTICATION,
&hADsPolicy);
RETURN_ON_FAILURE(hr);
//
// Get the PolicyName
//
hr = ADSIGetObjectAttributes(hADsPolicy, &AttrName, 1, &pGetAttr, &cGot);
if (SUCCEEDED(hr) && (cGot))
UnpackStrAllocFrom(pGetAttr[0], &szPolicyName);
if (pGetAttr)
FreeADsMem(pGetAttr);
pGetAttr = NULL;
ADSICloseDSObject(hADsPolicy);
}
hr = ADSIOpenDSObject(szParentPath, NULL, NULL, ADS_SECURE_AUTHENTICATION,
&hADsParent);
RETURN_ON_FAILURE(hr);
hr = CreateContainer(hADsParent,
szStoreName,
L"Application Store");
//
// handle this error correctly
// see if a broken class store is left behind
// this could happen due to DS going down after incomplete creation etc.
// from the class store container property you could tell
//
if ((hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) ||
(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS)))
{
//
// There is a Class Store already
// See if it is a good one.
DWORD dwStoreVersion = 0;
hr = BuildADsPathFromParent(szParentPath, szStoreName, &szFullName);
if (!SUCCEEDED(hr))
return CS_E_OBJECT_ALREADY_EXISTS;
hr = ADSIOpenDSObject(szFullName, NULL, NULL, ADS_SECURE_AUTHENTICATION,
&hADsContainer);
FreeADsMem(szFullName);
if (!SUCCEEDED(hr))
return CS_E_OBJECT_ALREADY_EXISTS;
AttrName = STOREVERSION;
//
// Get the Store Version
//
hr = ADSIGetObjectAttributes(hADsContainer, &AttrName, 1, &pGetAttr, &cGot);
if (SUCCEEDED(hr) && (cGot))
UnpackDWFrom(pGetAttr[0], &dwStoreVersion);
if (pGetAttr)
FreeADsMem(pGetAttr);
ADSICloseDSObject(hADsContainer);
if (dwStoreVersion == SCHEMA_VERSION_NUMBER)
return CS_E_OBJECT_ALREADY_EXISTS;
// if it is zero, then it was aborted in the middle.
if (dwStoreVersion != 0)
return CS_E_SCHEMA_MISMATCH;
// If it is a bad one try to delete it
DeleteRepository(szParentPath, szStoreName);
//
// Then again try to create it and proceed if successful
//
hr = CreateContainer(hADsParent,
szStoreName,
L"Application Store");
}
ERROR_ON_FAILURE(hr);
fCreatedContainer = TRUE;
hr = BuildADsPathFromParent(szParentPath, szStoreName, &szFullName);
ERROR_ON_FAILURE(hr);
hr = ADSIOpenDSObject(szFullName, NULL, NULL, ADS_SECURE_AUTHENTICATION,
&hADsContainer);
ERROR_ON_FAILURE(hr);
//
// Create the class container
//
hr = CreateContainer (hADsContainer,
CLASSCONTAINERNAME,
L"Application Object Classes");
ERROR_ON_FAILURE(hr);
fCreatedClasses = TRUE;
//
// Create the category container
//
hr = CreateContainer (hADsContainer,
CATEGORYCONTAINERNAME,
L"Component Categories");
ERROR_ON_FAILURE(hr);
fCreatedCategories = TRUE;
//
// Create the package container
//
hr = CreateContainer (hADsContainer,
PACKAGECONTAINERNAME,
L"Application Packages");
ERROR_ON_FAILURE(hr);
//
// Store the USN and PolicyID properties
//
GetCurrentUsn(szUsn);
PackStrToAttr(&pAttr[0], STOREUSN, szUsn);
PackStrToAttr(&pAttr[1], POLICYDN, szPolicyDn);
PackStrToAttr(&pAttr[2], POLICYNAME, szPolicyName);
PackDWToAttr(&pAttr[3], STOREVERSION, SCHEMA_VERSION_NUMBER);
hr = ADSISetObjectAttributes(hADsContainer, pAttr, 4, &cModified);
FreeAttr(pAttr[0]);
FreeAttr(pAttr[1]);
FreeAttr(pAttr[2]);
FreeAttr(pAttr[3]);
ADSICloseDSObject(hADsContainer);
ADSICloseDSObject(hADsParent);
FreeADsMem(szFullName);
CoTaskMemFree(szPolicyName);
return RemapErrorCode(hr, szParentPath);
Error_Cleanup:
if (fCreatedCategories)
ADSIDeleteDSObject(hADsContainer, CATEGORYCONTAINERNAME);
if (fCreatedClasses)
ADSIDeleteDSObject(hADsContainer, CLASSCONTAINERNAME);
if (hADsContainer)
ADSICloseDSObject(hADsContainer);
if (fCreatedContainer)
ADSIDeleteDSObject(hADsParent, szStoreName);
if (hADsParent)
ADSICloseDSObject(hADsParent);
if (szFullName)
FreeADsMem(szFullName);
if (szPolicyName)
CoTaskMemFree(szPolicyName);
return RemapErrorCode(hr, szParentPath);
}
HRESULT DeleteRepository(LPOLESTR szParentPath, LPOLESTR szStoreName)
{
HRESULT hr = S_OK;
HANDLE hADsParent = NULL;
HANDLE hADsContainer = NULL;
WCHAR * szFullName = NULL;
hr = ADSIOpenDSObject(szParentPath, NULL, NULL, ADS_SECURE_AUTHENTICATION,
&hADsParent);
RETURN_ON_FAILURE(hr);
hr = BuildADsPathFromParent(szParentPath, szStoreName, &szFullName);
hr = ADSIOpenDSObject(szFullName, NULL, NULL, ADS_SECURE_AUTHENTICATION,
&hADsContainer);
FreeADsMem(szFullName);
ERROR_ON_FAILURE(hr);
ADSIDeleteDSObject(hADsContainer, CATEGORYCONTAINERNAME);
ADSIDeleteDSObject(hADsContainer, CLASSCONTAINERNAME);
ADSIDeleteDSObject(hADsContainer, PACKAGECONTAINERNAME);
ADSICloseDSObject(hADsContainer);
ADSIDeleteDSObject(hADsParent, szStoreName);
ADSICloseDSObject(hADsParent);
return S_OK;
Error_Cleanup:
if (hADsContainer)
ADSICloseDSObject(hADsContainer);
if (hADsParent)
ADSICloseDSObject(hADsParent);
return hr;
}
HRESULT GetRootPath(LPOLESTR szContainer)
{
HRESULT hr = S_OK;
ULONG cGot = 0;
HANDLE hADs = NULL;
LPOLESTR AttrName = {L"defaultNamingContext"}, pDN = NULL;
ADS_ATTR_INFO * pAttr = NULL;
szContainer[0] = L'\0';
//
// Do a bind to the machine by a GetObject for the Path
//
hr = ADSIOpenDSObject(L"LDAP://rootdse", NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND,
&hADs);
RETURN_ON_FAILURE(hr);
hr = ADSIGetObjectAttributes(hADs, &AttrName, 1, &pAttr, &cGot);
if (SUCCEEDED(hr) && (cGot))
UnpackStrFrom(pAttr[0], &pDN);
else
pDN = L"\0";
wsprintf(szContainer, L"%s%s", LDAPPREFIX, pDN);
ADSICloseDSObject(hADs);
if (pAttr)
FreeADsMem(pAttr);
return S_OK;
}