1489 lines
41 KiB
C++
1489 lines
41 KiB
C++
|
//
|
|||
|
// Author: DebiM
|
|||
|
// Date: January 97
|
|||
|
//
|
|||
|
//
|
|||
|
// Class Store Administration Implementation
|
|||
|
//
|
|||
|
// This source file contains implementations for
|
|||
|
// IClassAdmin interface.
|
|||
|
//
|
|||
|
// It uses ADs interfaces (over LDAP) to talk to an LDAP
|
|||
|
// provider such as NTDS.
|
|||
|
//
|
|||
|
//---------------------------------------------------------------------
|
|||
|
|
|||
|
#include "cstore.hxx"
|
|||
|
void GetCurrentUsn(LPOLESTR pStoreUsn);
|
|||
|
|
|||
|
//----------------------------------------------------------
|
|||
|
// Implementation for CClassContainer
|
|||
|
//----------------------------------------------------------
|
|||
|
//
|
|||
|
CClassContainer::CClassContainer()
|
|||
|
|
|||
|
{
|
|||
|
m_fOpen = FALSE;
|
|||
|
m_ADsContainer = NULL;
|
|||
|
m_pADsClassStore = NULL;
|
|||
|
m_ADsClassContainer = NULL;
|
|||
|
m_ADsPackageContainer = NULL;
|
|||
|
m_ADsCategoryContainer = NULL;
|
|||
|
|
|||
|
m_uRefs = 1;
|
|||
|
StartQuery(&m_pIDBCreateCommand);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// CClassContainer implementation
|
|||
|
//
|
|||
|
CClassContainer::CClassContainer(LPOLESTR szStoreName,
|
|||
|
HRESULT *phr)
|
|||
|
|
|||
|
{
|
|||
|
IADs *pADs = NULL;
|
|||
|
LPOLESTR pszName = NULL;
|
|||
|
DWORD dwStoreVersion = 0;
|
|||
|
|
|||
|
*phr = S_OK;
|
|||
|
|
|||
|
m_fOpen = FALSE;
|
|||
|
m_ADsContainer = NULL;
|
|||
|
m_pADsClassStore = NULL;
|
|||
|
m_ADsClassContainer = NULL;
|
|||
|
m_ADsPackageContainer = NULL;
|
|||
|
m_ADsCategoryContainer = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// For every interface pointer, we create a separate Query session
|
|||
|
//
|
|||
|
StartQuery(&m_pIDBCreateCommand);
|
|||
|
|
|||
|
// Bind to a Class Store Container Object
|
|||
|
// Cache the interface pointer
|
|||
|
//
|
|||
|
wcscpy (m_szContainerName, szStoreName);
|
|||
|
|
|||
|
*phr = ADsGetObject(
|
|||
|
szStoreName,
|
|||
|
IID_IADsContainer,
|
|||
|
(void **)&m_ADsContainer
|
|||
|
);
|
|||
|
|
|||
|
if (!SUCCEEDED(*phr))
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// Check the Schema Version of this container
|
|||
|
//
|
|||
|
|
|||
|
*phr = m_ADsContainer->QueryInterface (IID_IADs, (void **)&m_pADsClassStore);
|
|||
|
if (!SUCCEEDED(*phr))
|
|||
|
return;
|
|||
|
|
|||
|
*phr = GetPropertyDW (m_pADsClassStore, STOREVERSION, &dwStoreVersion);
|
|||
|
|
|||
|
if ((!SUCCEEDED(*phr)) ||
|
|||
|
(dwStoreVersion != SCHEMA_VERSION_NUMBER))
|
|||
|
{
|
|||
|
*phr = CS_E_INVALID_VERSION;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Bind to the class container Object
|
|||
|
// Cache the interface pointer
|
|||
|
//
|
|||
|
|
|||
|
m_ADsClassContainer = NULL;
|
|||
|
|
|||
|
*phr = m_ADsContainer->GetObject(
|
|||
|
NULL,
|
|||
|
CLASSCONTAINERNAME,
|
|||
|
(IDispatch **)&pADs
|
|||
|
);
|
|||
|
|
|||
|
if (!SUCCEEDED(*phr))
|
|||
|
return;
|
|||
|
|
|||
|
pADs->QueryInterface(IID_IADsContainer,
|
|||
|
(void **)&m_ADsClassContainer
|
|||
|
);
|
|||
|
|
|||
|
*phr = pADs->get_ADsPath(&pszName);
|
|||
|
wcscpy (m_szClassName, pszName);
|
|||
|
SysFreeString(pszName);
|
|||
|
|
|||
|
pADs->Release();
|
|||
|
pADs = NULL;
|
|||
|
|
|||
|
if (!SUCCEEDED(*phr))
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// Bind to the Package container Object
|
|||
|
// Cache the interface pointer
|
|||
|
//
|
|||
|
|
|||
|
m_ADsPackageContainer = NULL;
|
|||
|
|
|||
|
*phr = m_ADsContainer->GetObject(
|
|||
|
NULL,
|
|||
|
PACKAGECONTAINERNAME,
|
|||
|
(IDispatch **)&pADs);
|
|||
|
|
|||
|
if (!SUCCEEDED(*phr))
|
|||
|
return;
|
|||
|
|
|||
|
pADs->QueryInterface(IID_IADsContainer,
|
|||
|
(void **)&m_ADsPackageContainer
|
|||
|
);
|
|||
|
|
|||
|
*phr = pADs->get_ADsPath(&pszName);
|
|||
|
wcscpy (m_szPackageName, pszName);
|
|||
|
SysFreeString(pszName);
|
|||
|
pADs->Release();
|
|||
|
pADs = NULL;
|
|||
|
|
|||
|
if (!SUCCEEDED(*phr))
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// Bind to the category container Object
|
|||
|
// Cache the interface pointer
|
|||
|
//
|
|||
|
m_ADsCategoryContainer = NULL;
|
|||
|
|
|||
|
*phr = m_ADsContainer->GetObject(
|
|||
|
NULL,
|
|||
|
CATEGORYCONTAINERNAME,
|
|||
|
(IDispatch **)&pADs);
|
|||
|
|
|||
|
if (!SUCCEEDED(*phr))
|
|||
|
return;
|
|||
|
|
|||
|
pADs->QueryInterface(IID_IADsContainer,
|
|||
|
(void **)&m_ADsCategoryContainer
|
|||
|
);
|
|||
|
|
|||
|
pADs->Release();
|
|||
|
pADs = NULL;
|
|||
|
|
|||
|
m_fOpen = TRUE;
|
|||
|
m_uRefs = 1;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
CClassContainer::~CClassContainer(void)
|
|||
|
{
|
|||
|
UINT i;
|
|||
|
|
|||
|
EndQuery(m_pIDBCreateCommand);
|
|||
|
m_pIDBCreateCommand = NULL;
|
|||
|
|
|||
|
|
|||
|
if (m_fOpen)
|
|||
|
{
|
|||
|
m_fOpen = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if (m_ADsClassContainer)
|
|||
|
{
|
|||
|
m_ADsClassContainer->Release();
|
|||
|
m_ADsClassContainer = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if (m_ADsPackageContainer)
|
|||
|
{
|
|||
|
m_ADsPackageContainer->Release();
|
|||
|
m_ADsPackageContainer = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if (m_ADsCategoryContainer)
|
|||
|
{
|
|||
|
m_ADsCategoryContainer->Release();
|
|||
|
m_ADsCategoryContainer = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if (m_ADsContainer)
|
|||
|
{
|
|||
|
m_ADsContainer->Release();
|
|||
|
m_ADsContainer = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if (m_pADsClassStore)
|
|||
|
{
|
|||
|
m_pADsClassStore->Release();
|
|||
|
m_pADsClassStore = NULL;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Removing a class from the database
|
|||
|
//
|
|||
|
|
|||
|
HRESULT CClassContainer::DeleteClass (LPOLESTR szClsid)
|
|||
|
{
|
|||
|
|
|||
|
WCHAR szName[_MAX_PATH];
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADs *pADs = NULL;
|
|||
|
DWORD refcount = 0;
|
|||
|
|
|||
|
if (!m_fOpen)
|
|||
|
return E_FAIL;
|
|||
|
|
|||
|
wsprintf(szName, L"CN=%s", szClsid);
|
|||
|
hr = m_ADsClassContainer->GetObject(NULL, szName, (IDispatch **)&pADs);
|
|||
|
|
|||
|
if (SUCCEEDED(hr))
|
|||
|
hr = GetPropertyDW(pADs, CLASSREFCOUNTER, &refcount);
|
|||
|
|
|||
|
if (refcount <= 1)
|
|||
|
hr = m_ADsClassContainer->Delete(CLASS_CS_CLASS, szName);
|
|||
|
else {
|
|||
|
refcount--;
|
|||
|
hr = SetPropertyDW(pADs, CLASSREFCOUNTER, refcount);
|
|||
|
|
|||
|
if (SUCCEEDED(hr))
|
|||
|
hr = StoreIt(pADs);
|
|||
|
}
|
|||
|
|
|||
|
if (pADs)
|
|||
|
pADs->Release();
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
extern LPOLESTR szPackageInfoColumns;
|
|||
|
|
|||
|
HRESULT CClassContainer::EnumPackages(
|
|||
|
LPOLESTR pszFileExt,
|
|||
|
GUID *pCategory,
|
|||
|
DWORD dwAppFlags,
|
|||
|
DWORD *pdwLocale,
|
|||
|
CSPLATFORM *pPlatform,
|
|||
|
IEnumPackage **ppIEnumPackage
|
|||
|
)
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
CEnumPackage *pEnum = NULL;
|
|||
|
WCHAR szCommand[1000], szQry[1000];
|
|||
|
|
|||
|
if (pszFileExt && IsBadStringPtr(pszFileExt, _MAX_PATH))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (pCategory && !IsValidReadPtrIn(pCategory, sizeof(GUID)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidPtrOut(ppIEnumPackage, sizeof(IEnumPackage *)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
*ppIEnumPackage = NULL;
|
|||
|
|
|||
|
pEnum = new CEnumPackage;
|
|||
|
if(NULL == pEnum)
|
|||
|
return E_OUTOFMEMORY;
|
|||
|
|
|||
|
//
|
|||
|
// Create a CommandText
|
|||
|
//
|
|||
|
|
|||
|
wsprintf(szCommand, L"<%s>;(& (objectClass=packageRegistration) ", m_szPackageName);
|
|||
|
|
|||
|
if (pszFileExt)
|
|||
|
{
|
|||
|
wsprintf(szQry, L"(%s=%s*) ", PKGFILEEXTNLIST, pszFileExt);
|
|||
|
wcscat(szCommand, szQry);
|
|||
|
}
|
|||
|
|
|||
|
if (pCategory)
|
|||
|
{
|
|||
|
STRINGGUID szCat;
|
|||
|
StringFromGUID (*pCategory, szCat);
|
|||
|
wsprintf(szQry, L"(%s=%s) ", PKGCATEGORYLIST, szCat);
|
|||
|
wcscat(szCommand, szQry);
|
|||
|
}
|
|||
|
|
|||
|
wcscat(szCommand, L");");
|
|||
|
|
|||
|
wsprintf(szQry, L" %s", szPackageInfoColumns);
|
|||
|
wcscat(szCommand, szQry);
|
|||
|
|
|||
|
hr = pEnum->Initialize(szCommand, dwAppFlags, pdwLocale, pPlatform);
|
|||
|
|
|||
|
if (FAILED(hr)) {
|
|||
|
delete pEnum;
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
hr = pEnum->QueryInterface(IID_IEnumPackage, (void**)ppIEnumPackage);
|
|||
|
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
// GetPackageDetails
|
|||
|
// pszPackageName : name of the package to be got.
|
|||
|
// pInstallInfo : InstallInfo to be filled in. ignored if NULL.
|
|||
|
// pPlatformInfo : PlatformInfo to be filled in. ignored if NULL.
|
|||
|
// both can be sent in as NULL to check whether package exists or not.
|
|||
|
|
|||
|
|
|||
|
HRESULT CClassContainer::GetPackageDetails (
|
|||
|
LPOLESTR pszPackageName,
|
|||
|
PACKAGEDETAIL *pPackageDetail)
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADs *pPackageADs = NULL;
|
|||
|
WCHAR szRdn [_MAX_PATH];
|
|||
|
|
|||
|
if ((!pszPackageName) || IsBadStringPtr(pszPackageName, _MAX_PATH))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
wcscpy (szRdn, L"CN=");
|
|||
|
wcscat (szRdn, pszPackageName);
|
|||
|
|
|||
|
hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pPackageADs);
|
|||
|
if (!SUCCEEDED(hr))
|
|||
|
return CS_E_PACKAGE_NOTFOUND;
|
|||
|
|
|||
|
hr = GetPackageDetail (pPackageADs, pPackageDetail);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT CClassContainer::ChangePackageProperties(
|
|||
|
LPOLESTR pszPackageName,
|
|||
|
LPOLESTR pszNewName,
|
|||
|
DWORD *pdwFlags,
|
|||
|
LPOLESTR pszUrl,
|
|||
|
LPOLESTR pszScriptPath,
|
|||
|
UINT *pInstallUiLevel
|
|||
|
)
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADs *pPackageADs = NULL;
|
|||
|
WCHAR szRdn [_MAX_PATH];
|
|||
|
WCHAR szNewRdn [_MAX_PATH];
|
|||
|
LPOLESTR pszPackageDN;
|
|||
|
WCHAR Usn[20];
|
|||
|
|
|||
|
if ((!pszPackageName) || IsBadStringPtr(pszPackageName, _MAX_PATH))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
wcscpy (szRdn, L"CN=");
|
|||
|
wcscat (szRdn, pszPackageName);
|
|||
|
|
|||
|
if (pszNewName)
|
|||
|
{
|
|||
|
//
|
|||
|
// rename package
|
|||
|
//
|
|||
|
|
|||
|
if (IsBadStringPtr(pszNewName, _MAX_PATH))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
//
|
|||
|
// Check to see if any other change is requested.
|
|||
|
//
|
|||
|
|
|||
|
if (pszScriptPath ||
|
|||
|
pszUrl ||
|
|||
|
pdwFlags ||
|
|||
|
pInstallUiLevel)
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
BuildADsPathFromParent (m_szPackageName, szRdn, &pszPackageDN);
|
|||
|
wcscpy (szNewRdn, L"CN=");
|
|||
|
wcscat (szNewRdn, pszNewName);
|
|||
|
hr = m_ADsPackageContainer->MoveHere(pszPackageDN, szNewRdn, (IDispatch **)&pPackageADs);
|
|||
|
FreeADsMem(pszPackageDN);
|
|||
|
|
|||
|
if (SUCCEEDED(hr))
|
|||
|
{
|
|||
|
hr = SetProperty(pPackageADs, PACKAGENAME, pszNewName);
|
|||
|
if (SUCCEEDED(hr))
|
|||
|
hr = StoreIt(pPackageADs);
|
|||
|
pPackageADs->Release();
|
|||
|
}
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
if (!(pszScriptPath ||
|
|||
|
pszUrl ||
|
|||
|
pdwFlags ||
|
|||
|
pInstallUiLevel))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
//
|
|||
|
// No rename.
|
|||
|
// Just change some properties.
|
|||
|
//
|
|||
|
hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pPackageADs);
|
|||
|
if (!SUCCEEDED(hr))
|
|||
|
return CS_E_PACKAGE_NOTFOUND;
|
|||
|
//
|
|||
|
// Update the TimeStamp
|
|||
|
//
|
|||
|
GetCurrentUsn(&Usn[0]);
|
|||
|
hr = UsnUpd(pPackageADs, PKGUSN, &Usn[0]);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
//
|
|||
|
// Change Package Flags
|
|||
|
//
|
|||
|
if (pdwFlags)
|
|||
|
{
|
|||
|
hr = SetPropertyDW (pPackageADs, PACKAGEFLAGS, *pdwFlags);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Change Package Script
|
|||
|
//
|
|||
|
if (pszScriptPath)
|
|||
|
{
|
|||
|
hr = SetProperty(pPackageADs, SCRIPTPATH, pszScriptPath);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Change Package Help URL
|
|||
|
//
|
|||
|
if (pszUrl)
|
|||
|
{
|
|||
|
hr = SetProperty(pPackageADs, HELPURL, pszUrl);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Change UI Level
|
|||
|
//
|
|||
|
if (pInstallUiLevel)
|
|||
|
{
|
|||
|
hr = SetPropertyDW (pPackageADs, UILEVEL, *pInstallUiLevel);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
hr = StoreIt(pPackageADs);
|
|||
|
|
|||
|
Error_Cleanup:
|
|||
|
pPackageADs->Release();
|
|||
|
return hr;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT CClassContainer::ChangePackageCategories(
|
|||
|
LPOLESTR pszPackageName,
|
|||
|
UINT cCategories,
|
|||
|
GUID *rpCategory
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// Does not change USN
|
|||
|
//
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADs *pPackageADs = NULL;
|
|||
|
WCHAR szRdn [_MAX_PATH];
|
|||
|
LPOLESTR *pszGuid = NULL;
|
|||
|
UINT count;
|
|||
|
|
|||
|
wcscpy (szRdn, L"CN=");
|
|||
|
wcscat (szRdn, pszPackageName);
|
|||
|
|
|||
|
if ((!cCategories) ||
|
|||
|
(!rpCategory) ||
|
|||
|
(!IsValidReadPtrIn(rpCategory, sizeof(GUID) * cCategories)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pPackageADs);
|
|||
|
if (!SUCCEEDED(hr))
|
|||
|
return CS_E_PACKAGE_NOTFOUND;
|
|||
|
|
|||
|
// fill in the categories
|
|||
|
pszGuid = (LPOLESTR *)CoTaskMemAlloc(cCategories * sizeof(LPOLESTR));
|
|||
|
if (!pszGuid)
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
for (count = 0; (count < cCategories); count++)
|
|||
|
{
|
|||
|
pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(STRINGGUIDLEN*sizeof(WCHAR));
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
StringFromGUID(rpCategory[count], pszGuid[count]);
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pPackageADs, PKGCATEGORYLIST, cCategories,
|
|||
|
pszGuid);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
for (count = 0; (count < cCategories); count++)
|
|||
|
CoTaskMemFree(pszGuid[count]);
|
|||
|
|
|||
|
CoTaskMemFree(pszGuid);
|
|||
|
hr = StoreIt(pPackageADs);
|
|||
|
|
|||
|
Error_Cleanup:
|
|||
|
pPackageADs->Release();
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT CClassContainer::SetPriorityByFileExt(
|
|||
|
LPOLESTR pszPackageName,
|
|||
|
LPOLESTR pszFileExt,
|
|||
|
UINT Priority
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// Does not change USN
|
|||
|
//
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADs *pPackageADs = NULL;
|
|||
|
WCHAR szRdn [_MAX_PATH];
|
|||
|
LPOLESTR *prgFileExt = NULL;
|
|||
|
ULONG cShellFileExt;
|
|||
|
UINT i;
|
|||
|
|
|||
|
wcscpy (szRdn, L"CN=");
|
|||
|
wcscat (szRdn, pszPackageName);
|
|||
|
|
|||
|
hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pPackageADs);
|
|||
|
if (!SUCCEEDED(hr))
|
|||
|
return CS_E_PACKAGE_NOTFOUND;
|
|||
|
|
|||
|
hr = GetPropertyListAlloc (pPackageADs, PKGFILEEXTNLIST,
|
|||
|
&cShellFileExt,
|
|||
|
&prgFileExt);
|
|||
|
|
|||
|
for (i=0; i < cShellFileExt; ++i)
|
|||
|
{
|
|||
|
if (wcsncmp(prgFileExt[i], pszFileExt, wcslen(pszFileExt)) == 0)
|
|||
|
{
|
|||
|
wsprintf(prgFileExt[i], L"%s:%2d",
|
|||
|
pszFileExt,
|
|||
|
Priority);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (i == cShellFileExt)
|
|||
|
{
|
|||
|
hr = CS_E_PACKAGE_NOTFOUND;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pPackageADs, PKGFILEEXTNLIST, cShellFileExt, prgFileExt);
|
|||
|
|
|||
|
hr = StoreIt(pPackageADs);
|
|||
|
|
|||
|
Error_Cleanup:
|
|||
|
pPackageADs->Release();
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
extern LPOLESTR szAppCategoryColumns;
|
|||
|
|
|||
|
HRESULT CClassContainer::GetAppCategories (
|
|||
|
LCID Locale,
|
|||
|
APPCATEGORYINFOLIST *pAppCategoryList
|
|||
|
)
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
WCHAR szCommand[1000], szQry[1000];
|
|||
|
WCHAR szRootPath[_MAX_PATH],
|
|||
|
szAppCategoryContainer[_MAX_PATH];
|
|||
|
IRowset * pIRow = NULL;
|
|||
|
HACCESSOR HAcc;
|
|||
|
IAccessor * pIAccessor = NULL;
|
|||
|
IDBCreateCommand * pIDBCreateCommand = NULL;
|
|||
|
LPOLESTR ** ppszDesc = NULL;
|
|||
|
DWORD cgot = 0;
|
|||
|
|
|||
|
if (!IsValidPtrOut(pAppCategoryList, sizeof(APPCATEGORYINFOLIST)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
hr = GetRootPath(szRootPath);
|
|||
|
wsprintf(szAppCategoryContainer, L"%s%s%s", LDAPPREFIX,
|
|||
|
APPCATEGORYCONTAINERNAME, szRootPath+wcslen(LDAPPREFIX));
|
|||
|
|
|||
|
wsprintf(szCommand, L"<%s>; (objectClass=categoryRegistration); %s", szAppCategoryContainer,
|
|||
|
szAppCategoryColumns);
|
|||
|
|
|||
|
hr = StartQuery(&(pIDBCreateCommand));
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = ExecuteQuery (pIDBCreateCommand,
|
|||
|
szCommand,
|
|||
|
APPCATEGORY_COLUMN_COUNT,
|
|||
|
NULL,
|
|||
|
&HAcc,
|
|||
|
&pIAccessor,
|
|||
|
&pIRow
|
|||
|
);
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
pAppCategoryList->cCategory = 500;
|
|||
|
// upper limit presently.
|
|||
|
|
|||
|
hr = FetchCategory(pIRow,
|
|||
|
HAcc,
|
|||
|
(pAppCategoryList->cCategory),
|
|||
|
&cgot,
|
|||
|
&(pAppCategoryList->pCategoryInfo),
|
|||
|
Locale);
|
|||
|
|
|||
|
pAppCategoryList->cCategory = cgot;
|
|||
|
|
|||
|
CloseQuery(pIAccessor,
|
|||
|
HAcc,
|
|||
|
pIRow);
|
|||
|
|
|||
|
EndQuery(pIDBCreateCommand);
|
|||
|
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT CClassContainer::RegisterAppCategory (
|
|||
|
APPCATEGORYINFO *pAppCategory
|
|||
|
)
|
|||
|
{
|
|||
|
WCHAR szRootPath[_MAX_PATH], *localedescription = NULL,
|
|||
|
szAppCategoryContainer[_MAX_PATH], szRDN[_MAX_PATH];
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADsContainer *pADsContainer = NULL;
|
|||
|
IADs *pADs = NULL;
|
|||
|
IDispatch *pUnknown = NULL;
|
|||
|
ULONG i, j, cdesc, posn;
|
|||
|
LPOLESTR *pszDescExisting = NULL, *pszDesc = NULL;
|
|||
|
|
|||
|
|
|||
|
if (!pAppCategory || !IsValidReadPtrIn(pAppCategory, sizeof(APPCATEGORYINFO)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if ((pAppCategory->pszDescription == NULL) ||
|
|||
|
IsBadStringPtr(pAppCategory->pszDescription, _MAX_PATH))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (IsNullGuid(pAppCategory->AppCategoryId))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
hr = GetRootPath(szRootPath);
|
|||
|
|
|||
|
// Bind to a AppCategory container
|
|||
|
wsprintf(szAppCategoryContainer, L"%s%s%s", LDAPPREFIX,
|
|||
|
APPCATEGORYCONTAINERNAME, szRootPath+wcslen(LDAPPREFIX));
|
|||
|
|
|||
|
hr = ADsGetObject(
|
|||
|
szAppCategoryContainer,
|
|||
|
IID_IADsContainer,
|
|||
|
(void **)&pADsContainer
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
RdnFromGUID(pAppCategory->AppCategoryId, szRDN);
|
|||
|
|
|||
|
localedescription = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR)*(128+16));
|
|||
|
|
|||
|
wsprintf(localedescription, L"%x %s %s", pAppCategory->Locale, CATSEPERATOR,
|
|||
|
pAppCategory->pszDescription);
|
|||
|
|
|||
|
hr = pADsContainer->GetObject(NULL, szRDN, (IDispatch **)&pADs);
|
|||
|
|
|||
|
if (SUCCEEDED(hr))
|
|||
|
{
|
|||
|
hr = GetPropertyListAlloc (pADs, LOCALEDESCRIPTION, &cdesc, &pszDescExisting);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
// Existing list of descriptions
|
|||
|
|
|||
|
pszDesc = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*(cdesc+1));
|
|||
|
if ((cdesc) && (!pszDesc)) {
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
for (j = 0; j < cdesc; j++)
|
|||
|
pszDesc[j] = pszDescExisting[j];
|
|||
|
|
|||
|
if (!(posn = FindDescription(pszDescExisting, cdesc, &(pAppCategory->Locale), NULL, 0)))
|
|||
|
{
|
|||
|
// if no description exists for the lcid.
|
|||
|
pszDesc[cdesc] = localedescription;
|
|||
|
cdesc++;
|
|||
|
}
|
|||
|
else
|
|||
|
{ // overwrite the old value
|
|||
|
CoTaskMemFree(pszDesc[posn-1]);
|
|||
|
pszDesc[posn-1] = localedescription;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
hr = pADsContainer->Create(
|
|||
|
CLASS_CS_CATEGORY,
|
|||
|
szRDN,
|
|||
|
&pUnknown
|
|||
|
);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
pszDesc = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR));
|
|||
|
if (!pszDesc) {
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
cdesc = 1;
|
|||
|
pszDesc[0] = localedescription;
|
|||
|
|
|||
|
hr = pUnknown->QueryInterface(IID_IADs, (void **)&pADs);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
pUnknown->Release();
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyGuid(pADs, CATEGORYCATID, pAppCategory->AppCategoryId);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SetPropertyList(pADs, LOCALEDESCRIPTION, cdesc, pszDesc);
|
|||
|
for (j = 0; j < cdesc; j++)
|
|||
|
CoTaskMemFree(pszDesc[j]);
|
|||
|
CoTaskMemFree(pszDesc);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = StoreIt(pADs);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
Error_Cleanup:
|
|||
|
|
|||
|
if (pADs)
|
|||
|
pADs->Release();
|
|||
|
|
|||
|
if (pADsContainer)
|
|||
|
pADsContainer->Release();
|
|||
|
|
|||
|
// Add this category.
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT CClassContainer::UnregisterAppCategory (
|
|||
|
GUID *pAppCategoryId
|
|||
|
)
|
|||
|
{
|
|||
|
WCHAR szRootPath[_MAX_PATH], szRDN[_MAX_PATH],
|
|||
|
szAppCategoryContainer[_MAX_PATH];
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADsContainer *pADsContainer = NULL;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pAppCategoryId, sizeof(GUID)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
hr = GetRootPath(szRootPath);
|
|||
|
// Bind to a AppCategory container
|
|||
|
wsprintf(szAppCategoryContainer, L"%s%s%s", LDAPPREFIX,
|
|||
|
APPCATEGORYCONTAINERNAME, szRootPath+wcslen(LDAPPREFIX));
|
|||
|
|
|||
|
hr = ADsGetObject(
|
|||
|
szAppCategoryContainer,
|
|||
|
IID_IADsContainer,
|
|||
|
(void **)&pADsContainer
|
|||
|
);
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
RdnFromGUID(*pAppCategoryId, szRDN);
|
|||
|
|
|||
|
hr = pADsContainer->Delete(CLASS_CS_CATEGORY, szRDN);
|
|||
|
pADsContainer->Release();
|
|||
|
|
|||
|
// Delete this category
|
|||
|
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//+
|
|||
|
|
|||
|
HRESULT CClassContainer::RemovePackage (LPOLESTR pszPackageName)
|
|||
|
//
|
|||
|
// Remove a Package and the associated Classes from class store
|
|||
|
//
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADs *pADs = NULL;
|
|||
|
DWORD cClasses = 0, count = 0;
|
|||
|
WCHAR szRdn [_MAX_PATH];
|
|||
|
LPOLESTR *szClasses;
|
|||
|
|
|||
|
if ((!pszPackageName) || IsBadStringPtr(pszPackageName, _MAX_PATH))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if ((pszPackageName == NULL) ||
|
|||
|
(*(pszPackageName) == NULL))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
wcscpy (szRdn, L"CN=");
|
|||
|
wcscat (szRdn, pszPackageName);
|
|||
|
|
|||
|
if (!m_fOpen)
|
|||
|
return E_FAIL;
|
|||
|
|
|||
|
hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pADs);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = GetPropertyListAlloc(pADs, PKGCLSIDLIST, &cClasses, &szClasses);
|
|||
|
|
|||
|
for (count = 0; count < cClasses; count++)
|
|||
|
hr = DeleteClass(szClasses[count]);
|
|||
|
// ignore errors
|
|||
|
|
|||
|
for (count = 0; count < cClasses; count++)
|
|||
|
CoTaskMemFree(szClasses[count]);
|
|||
|
CoTaskMemFree(szClasses);
|
|||
|
|
|||
|
pADs->Release();
|
|||
|
|
|||
|
hr = m_ADsPackageContainer->Delete(CLASS_CS_PACKAGE, szRdn);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
//+
|
|||
|
|
|||
|
HRESULT CClassContainer::NewClass (CLASSDETAIL *pClassDetail)
|
|||
|
|
|||
|
//
|
|||
|
// Add a new class to the database
|
|||
|
//
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
IADs * pADs = NULL;
|
|||
|
IDispatch * pUnknown = NULL;
|
|||
|
STRINGGUID szGUID;
|
|||
|
WCHAR szRDN [_MAX_PATH];
|
|||
|
|
|||
|
if (!m_fOpen)
|
|||
|
return E_FAIL;
|
|||
|
|
|||
|
//
|
|||
|
// Cant be a NULL guid
|
|||
|
//
|
|||
|
if (IsNullGuid(pClassDetail->Clsid))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
StringFromGUID(pClassDetail->Clsid, szGUID);
|
|||
|
|
|||
|
//
|
|||
|
// Create the RDN for the Class Object
|
|||
|
//
|
|||
|
|
|||
|
// BUGBUG:: attaching package name creates problems.
|
|||
|
wsprintf(szRDN, L"CN=%s", szGUID);
|
|||
|
|
|||
|
hr = m_ADsClassContainer->Create(
|
|||
|
CLASS_CS_CLASS,
|
|||
|
szRDN,
|
|||
|
&pUnknown
|
|||
|
);
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = pUnknown->QueryInterface(
|
|||
|
IID_IADs,
|
|||
|
(void **)&pADs
|
|||
|
);
|
|||
|
|
|||
|
pUnknown->Release();
|
|||
|
|
|||
|
hr = SetProperty (pADs, CLASSCLSID, szGUID);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
if (pClassDetail->cProgId)
|
|||
|
{
|
|||
|
hr = SetPropertyList(pADs, PROGIDLIST, pClassDetail->cProgId,
|
|||
|
pClassDetail->prgProgId);
|
|||
|
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
if (!IsNullGuid(pClassDetail->TreatAs))
|
|||
|
{
|
|||
|
StringFromGUID(pClassDetail->TreatAs, szGUID);
|
|||
|
hr = SetProperty (pADs, TREATASCLSID, szGUID);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyDW(pADs, CLASSREFCOUNTER, 1);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = StoreIt (pADs);
|
|||
|
|
|||
|
// this does not return an error for an alreay existing entry.
|
|||
|
|
|||
|
if (hr == E_ADS_LDAP_ALREADY_EXISTS)
|
|||
|
{
|
|||
|
|
|||
|
DWORD refcount = 0;
|
|||
|
|
|||
|
pADs->Release(); // release the interface pointer already got.
|
|||
|
|
|||
|
hr = m_ADsClassContainer->GetObject(NULL, // CLASS_CS_CLASS
|
|||
|
szRDN,
|
|||
|
(IDispatch **)&pADs);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
if (pClassDetail->cProgId)
|
|||
|
{
|
|||
|
hr = SetPropertyListMerge(pADs, PROGIDLIST, pClassDetail->cProgId,
|
|||
|
pClassDetail->prgProgId);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
// increment reference counter.
|
|||
|
hr = GetPropertyDW(pADs, CLASSREFCOUNTER, &refcount);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
refcount++;
|
|||
|
|
|||
|
hr = SetPropertyDW(pADs, CLASSREFCOUNTER, refcount);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
// No merging of the treatas.
|
|||
|
|
|||
|
hr = StoreIt(pADs);
|
|||
|
}
|
|||
|
|
|||
|
Error_Cleanup:
|
|||
|
|
|||
|
pADs->Release();
|
|||
|
return hr;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
#define SCRIPT_IN_DIRECTORY 256
|
|||
|
|
|||
|
|
|||
|
HRESULT CClassContainer::AddPackage(LPOLESTR pszPackageName,
|
|||
|
PACKAGEDETAIL *pPackageDetail)
|
|||
|
{
|
|||
|
HRESULT hr;
|
|||
|
IADs *pPackageADs = NULL;
|
|||
|
IDispatch *pUnknown = NULL;
|
|||
|
WCHAR szRDN [_MAX_PATH];
|
|||
|
LPOLESTR *pszGuid, *pszProgId;
|
|||
|
DWORD *pdwArch=NULL, count = 0, cPackProgId = 0;
|
|||
|
WCHAR Usn[20];
|
|||
|
|
|||
|
if (!pszPackageName)
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!pPackageDetail)
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail, sizeof(PACKAGEDETAIL)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
LPWSTR pName = pszPackageName;
|
|||
|
while (*pName)
|
|||
|
{
|
|||
|
if ((*pName == L':') ||
|
|||
|
(*pName == L',') ||
|
|||
|
(*pName == L';') ||
|
|||
|
(*pName == L'/') ||
|
|||
|
(*pName == L'<') ||
|
|||
|
(*pName == L'>') ||
|
|||
|
(*pName == L'\\'))
|
|||
|
return E_INVALIDARG;
|
|||
|
++pName;
|
|||
|
}
|
|||
|
|
|||
|
// Validating ActivationInfo
|
|||
|
|
|||
|
if (pPackageDetail->pActInfo)
|
|||
|
{
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pActInfo, sizeof(ACTIVATIONINFO)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pActInfo->pClasses,
|
|||
|
sizeof(CLASSDETAIL) * (pPackageDetail->pActInfo->cClasses)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pActInfo->prgShellFileExt,
|
|||
|
sizeof(LPOLESTR) * (pPackageDetail->pActInfo->cShellFileExt)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
for (count = 0; count < (pPackageDetail->pActInfo->cShellFileExt); count++)
|
|||
|
{
|
|||
|
if (!pPackageDetail->pActInfo->prgShellFileExt[count])
|
|||
|
return E_INVALIDARG;
|
|||
|
}
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pActInfo->prgPriority,
|
|||
|
sizeof(UINT) * (pPackageDetail->pActInfo->cShellFileExt)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pActInfo->prgInterfaceId,
|
|||
|
sizeof(IID) * (pPackageDetail->pActInfo->cInterfaces)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pActInfo->prgTlbId,
|
|||
|
sizeof(GUID) * (pPackageDetail->pActInfo->cTypeLib)))
|
|||
|
return E_INVALIDARG;
|
|||
|
}
|
|||
|
|
|||
|
// Validating InstallInfo
|
|||
|
|
|||
|
if ((pPackageDetail->pInstallInfo == NULL) ||
|
|||
|
(!IsValidReadPtrIn(pPackageDetail->pInstallInfo, sizeof(INSTALLINFO)))
|
|||
|
)
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pInstallInfo->prgUpgradeFlag,
|
|||
|
sizeof(DWORD)*(pPackageDetail->pInstallInfo->cUpgrades)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pInstallInfo->prgUpgradeScript,
|
|||
|
sizeof(LPOLESTR)*(pPackageDetail->pInstallInfo->cUpgrades)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
for (count = 0; count < (pPackageDetail->pInstallInfo->cUpgrades); count++)
|
|||
|
{
|
|||
|
if ((!(pPackageDetail->pInstallInfo->prgUpgradeScript[count])) ||
|
|||
|
IsBadStringPtr((pPackageDetail->pInstallInfo->prgUpgradeScript[count]), _MAX_PATH))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if ((pPackageDetail->pInstallInfo->prgUpgradeFlag[count] != UPGFLG_Uninstall) &&
|
|||
|
(pPackageDetail->pInstallInfo->prgUpgradeFlag[count] != UPGFLG_NoUninstall))
|
|||
|
return E_INVALIDARG;
|
|||
|
}
|
|||
|
|
|||
|
// Validating PlatformInfo
|
|||
|
|
|||
|
if ((pPackageDetail->pPlatformInfo == NULL) ||
|
|||
|
(!IsValidReadPtrIn(pPackageDetail->pPlatformInfo, sizeof(PLATFORMINFO)))
|
|||
|
)
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pPlatformInfo->prgPlatform,
|
|||
|
sizeof(CSPLATFORM) * (pPackageDetail->pPlatformInfo->cPlatforms)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if ((pPackageDetail->pPlatformInfo->cLocales == 0) ||
|
|||
|
(pPackageDetail->pPlatformInfo->cPlatforms == 0))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->pPlatformInfo->prgLocale,
|
|||
|
sizeof(LCID) * (pPackageDetail->pPlatformInfo->cLocales)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
// Validating other fields in PackageDetail structure
|
|||
|
|
|||
|
if ((pPackageDetail->pszSourceList == NULL) ||
|
|||
|
(!IsValidReadPtrIn(pPackageDetail->pszSourceList,
|
|||
|
sizeof(LPOLESTR) * (pPackageDetail->cSources)))
|
|||
|
)
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
for (count = 0; count < (pPackageDetail->cSources); count++)
|
|||
|
if (!pPackageDetail->pszSourceList[count])
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
|
|||
|
if (pPackageDetail->rpCategory)
|
|||
|
{
|
|||
|
if (!IsValidReadPtrIn(pPackageDetail->rpCategory,
|
|||
|
sizeof(GUID) * (pPackageDetail->cCategories)))
|
|||
|
return E_INVALIDARG;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Now we create the package
|
|||
|
//
|
|||
|
|
|||
|
wcscpy (szRDN, L"CN=");
|
|||
|
wcscat (szRDN, pszPackageName);
|
|||
|
|
|||
|
pUnknown = NULL;
|
|||
|
hr = m_ADsPackageContainer->Create(
|
|||
|
CLASS_CS_PACKAGE,
|
|||
|
szRDN,
|
|||
|
&pUnknown
|
|||
|
);
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = pUnknown->QueryInterface(
|
|||
|
IID_IADs,
|
|||
|
(void **)&pPackageADs
|
|||
|
);
|
|||
|
|
|||
|
pUnknown->Release();
|
|||
|
|
|||
|
// fill in the activation info
|
|||
|
|
|||
|
if (pPackageDetail->pActInfo)
|
|||
|
{
|
|||
|
|
|||
|
if ((pPackageDetail->pActInfo)->cClasses)
|
|||
|
{
|
|||
|
pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->pActInfo->cClasses)*sizeof(LPOLESTR));
|
|||
|
if (!pszGuid)
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
for (count = 0; count < pPackageDetail->pActInfo->cClasses; count++)
|
|||
|
{
|
|||
|
pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR)*STRINGGUIDLEN);
|
|||
|
StringFromGUID(pPackageDetail->pActInfo->pClasses[count].Clsid, pszGuid[count]);
|
|||
|
cPackProgId += pPackageDetail->pActInfo->pClasses[count].cProgId;
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pPackageADs, PKGCLSIDLIST, (pPackageDetail->pActInfo)->cClasses, pszGuid);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
for (count = 0; (count < pPackageDetail->pActInfo->cClasses); count++)
|
|||
|
CoTaskMemFree(pszGuid[count]);
|
|||
|
CoTaskMemFree(pszGuid);
|
|||
|
}
|
|||
|
|
|||
|
// collecting all the progids from the various clsids.
|
|||
|
if (cPackProgId)
|
|||
|
{
|
|||
|
pszProgId = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*cPackProgId);
|
|||
|
if (!pszProgId)
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
for (count = 0, cPackProgId = 0; count < pPackageDetail->pActInfo->cClasses; count++)
|
|||
|
{
|
|||
|
DWORD cClassProgId = 0;
|
|||
|
for (cClassProgId = 0; cClassProgId < pPackageDetail->pActInfo->pClasses[count].cProgId;
|
|||
|
cClassProgId++)
|
|||
|
{
|
|||
|
pszProgId[cPackProgId++] =
|
|||
|
pPackageDetail->pActInfo->pClasses[count].prgProgId[cClassProgId];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pPackageADs, PROGIDLIST, cPackProgId, pszProgId);
|
|||
|
|
|||
|
CoTaskMemFree(pszProgId);
|
|||
|
}
|
|||
|
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
if (pPackageDetail->pActInfo->cShellFileExt)
|
|||
|
{
|
|||
|
//
|
|||
|
// Store a tuple in the format <file ext>:<priority>
|
|||
|
//
|
|||
|
pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->pActInfo->cShellFileExt) * sizeof(LPOLESTR));
|
|||
|
if (!pszGuid)
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
for (count = 0; count < pPackageDetail->pActInfo->cShellFileExt; count++)
|
|||
|
{
|
|||
|
pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) *
|
|||
|
(wcslen(pPackageDetail->pActInfo->prgShellFileExt[count])+1+2+1));
|
|||
|
// format is fileext+:+nn+NULL where nn = 2 digit priority
|
|||
|
wsprintf(pszGuid[count], L"%s:%2d",
|
|||
|
pPackageDetail->pActInfo->prgShellFileExt[count],
|
|||
|
pPackageDetail->pActInfo->prgPriority[count]);
|
|||
|
}
|
|||
|
hr = SetPropertyList(pPackageADs, PKGFILEEXTNLIST, pPackageDetail->pActInfo->cShellFileExt, pszGuid);
|
|||
|
for (count = 0; (count < pPackageDetail->pActInfo->cShellFileExt); count++)
|
|||
|
CoTaskMemFree(pszGuid[count]);
|
|||
|
CoTaskMemFree(pszGuid);
|
|||
|
|
|||
|
//
|
|||
|
// Now IDS Workaround
|
|||
|
// BUGBUG. Remove this when the DS bug is fixed. 130491 in NTDEV
|
|||
|
//
|
|||
|
hr = SetPropertyList(pPackageADs,
|
|||
|
QRYFILEEXT,
|
|||
|
pPackageDetail->pActInfo->cShellFileExt,
|
|||
|
pPackageDetail->pActInfo->prgShellFileExt);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
if (pPackageDetail->pActInfo->cInterfaces)
|
|||
|
{
|
|||
|
pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->pActInfo->cInterfaces)*sizeof(LPOLESTR));
|
|||
|
if (!pszGuid)
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
for (count = 0; (count < (pPackageDetail->pActInfo->cInterfaces)); count++)
|
|||
|
{
|
|||
|
pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(STRINGGUIDLEN*sizeof(WCHAR));
|
|||
|
if (!pszGuid[count])
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
StringFromGUID((pPackageDetail->pActInfo->prgInterfaceId)[count], pszGuid[count]);
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pPackageADs, PKGIIDLIST, pPackageDetail->pActInfo->cInterfaces,
|
|||
|
pszGuid);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
for (count = 0; (count < (pPackageDetail->pActInfo->cInterfaces)); count++)
|
|||
|
CoTaskMemFree(pszGuid[count]);
|
|||
|
CoTaskMemFree(pszGuid);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (pPackageDetail->pActInfo->cTypeLib)
|
|||
|
{
|
|||
|
pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->pActInfo->cTypeLib)*sizeof(LPOLESTR));
|
|||
|
if (!pszGuid)
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
for (count = 0; (count < (pPackageDetail->pActInfo)->cTypeLib); count++)
|
|||
|
{
|
|||
|
pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(STRINGGUIDLEN*sizeof(WCHAR));
|
|||
|
if (!pszGuid[count])
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
StringFromGUID((pPackageDetail->pActInfo->prgTlbId)[count], pszGuid[count]);
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pPackageADs, PKGTLBIDLIST, pPackageDetail->pActInfo->cTypeLib,
|
|||
|
pszGuid);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
for (count = 0; (count < (pPackageDetail->pActInfo->cTypeLib)); count++)
|
|||
|
CoTaskMemFree(pszGuid[count]);
|
|||
|
CoTaskMemFree(pszGuid);
|
|||
|
}
|
|||
|
}
|
|||
|
// fill in the platforminfo
|
|||
|
|
|||
|
// BUGBUG::***os version
|
|||
|
if ((pPackageDetail->pPlatformInfo)->cPlatforms)
|
|||
|
{
|
|||
|
pdwArch = (DWORD *)CoTaskMemAlloc(sizeof(DWORD)*
|
|||
|
((pPackageDetail->pPlatformInfo)->cPlatforms));
|
|||
|
|
|||
|
for (count = 0; (count < (pPackageDetail->pPlatformInfo)->cPlatforms); count++)
|
|||
|
UnpackPlatform (pdwArch+count, ((pPackageDetail->pPlatformInfo)->prgPlatform)+count);
|
|||
|
|
|||
|
hr = SetPropertyListDW (pPackageADs, ARCHLIST, (pPackageDetail->pPlatformInfo)->cPlatforms, pdwArch);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
CoTaskMemFree(pdwArch);
|
|||
|
}
|
|||
|
|
|||
|
if ((pPackageDetail->pPlatformInfo)->cLocales)
|
|||
|
{
|
|||
|
hr = SetPropertyListDW (pPackageADs,
|
|||
|
LOCALEID, (pPackageDetail->pPlatformInfo)->cLocales,
|
|||
|
(pPackageDetail->pPlatformInfo)->prgLocale);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
// fill in the installinfo
|
|||
|
|
|||
|
hr = SetProperty(pPackageADs, PACKAGENAME, pszPackageName);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SetPropertyDW (pPackageADs, PACKAGETYPE, (DWORD)pPackageDetail->pInstallInfo->PathType);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
if (pPackageDetail->pInstallInfo->pszScriptPath)
|
|||
|
{
|
|||
|
hr = SetProperty(pPackageADs, SCRIPTPATH, pPackageDetail->pInstallInfo->pszScriptPath);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
if (pPackageDetail->pInstallInfo->pszSetupCommand)
|
|||
|
{
|
|||
|
hr = SetProperty(pPackageADs, SETUPCOMMAND, pPackageDetail->pInstallInfo->pszSetupCommand);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
if (pPackageDetail->pInstallInfo->pszUrl)
|
|||
|
{
|
|||
|
hr = SetProperty(pPackageADs, HELPURL, pPackageDetail->pInstallInfo->pszUrl);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
GetCurrentUsn(&Usn[0]);
|
|||
|
hr = UsnUpd(pPackageADs, PKGUSN, &Usn[0]);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SetPropertyDW (pPackageADs, PACKAGEFLAGS, pPackageDetail->pInstallInfo->dwActFlags);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SetPropertyDW (pPackageADs, CLASSCTX, pPackageDetail->pInstallInfo->dwComClassContext);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SetPropertyDW (pPackageADs, VERSIONHI, pPackageDetail->pInstallInfo->dwVersionHi);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SetPropertyDW (pPackageADs, VERSIONLO, pPackageDetail->pInstallInfo->dwVersionLo);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SetPropertyDW (pPackageADs, SCRIPTSIZE, pPackageDetail->pInstallInfo->cScriptLen);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SetPropertyDW (pPackageADs, UILEVEL, (DWORD)pPackageDetail->pInstallInfo->InstallUiLevel);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
if (pPackageDetail->pInstallInfo->cUpgrades)
|
|||
|
{
|
|||
|
LPOLESTR *rpszUpgrades;
|
|||
|
rpszUpgrades = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*pPackageDetail->pInstallInfo->cUpgrades);
|
|||
|
for (count = 0; (count < pPackageDetail->pInstallInfo->cUpgrades); count++)
|
|||
|
{
|
|||
|
UINT l = wcslen(pPackageDetail->pInstallInfo->prgUpgradeScript[count]);
|
|||
|
rpszUpgrades[count] = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) *(4+l));
|
|||
|
wsprintf(rpszUpgrades[count], L"%s:%1d",
|
|||
|
pPackageDetail->pInstallInfo->prgUpgradeScript[count],
|
|||
|
pPackageDetail->pInstallInfo->prgUpgradeFlag[count]);
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pPackageADs, UPGRADESCRIPTNAMES, pPackageDetail->pInstallInfo->cUpgrades,
|
|||
|
rpszUpgrades);
|
|||
|
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
for (count = 0; (count < pPackageDetail->pInstallInfo->cUpgrades); count++)
|
|||
|
CoTaskMemFree(rpszUpgrades[count]);
|
|||
|
CoTaskMemFree(rpszUpgrades);
|
|||
|
}
|
|||
|
|
|||
|
// fill in the sources
|
|||
|
if (pPackageDetail->cSources)
|
|||
|
{
|
|||
|
hr = SetPropertyList(pPackageADs, MSIFILELIST, pPackageDetail->cSources,
|
|||
|
pPackageDetail->pszSourceList);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
// fill in the categories
|
|||
|
if (pPackageDetail->cCategories)
|
|||
|
{
|
|||
|
pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->cCategories) * sizeof(LPOLESTR));
|
|||
|
if (!pszGuid)
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
for (count = 0; (count < pPackageDetail->cCategories); count++)
|
|||
|
{
|
|||
|
pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(STRINGGUIDLEN*sizeof(WCHAR));
|
|||
|
if (!pszGuid[count])
|
|||
|
{
|
|||
|
hr = E_OUTOFMEMORY;
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
|
|||
|
StringFromGUID((pPackageDetail->rpCategory)[count], pszGuid[count]);
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pPackageADs, PKGCATEGORYLIST, pPackageDetail->cCategories,
|
|||
|
pszGuid);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
for (count = 0; (count < pPackageDetail->cCategories); count++)
|
|||
|
CoTaskMemFree(pszGuid[count]);
|
|||
|
CoTaskMemFree(pszGuid);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Store the script in the directory
|
|||
|
//
|
|||
|
/*
|
|||
|
if ((pPackageDetail->pInstallInfo->dwActFlags & SCRIPT_IN_DIRECTORY) &&
|
|||
|
(pPackageDetail->pInstallInfo->cScriptLen))
|
|||
|
{
|
|||
|
|
|||
|
if ((pPackageDetail->pInstallInfo->cScriptLen) &&
|
|||
|
(!IsValidReadPtrIn(pPackageDetail->pInstallInfo->pScript, pPackageDetail->pInstallInfo->cScriptLen)))
|
|||
|
return E_INVALIDARG;
|
|||
|
|
|||
|
SAFEARRAYBOUND size; // Get rid of 16
|
|||
|
SAFEARRAY FAR *psa;
|
|||
|
CHAR HUGEP *pArray=NULL;
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
VARIANT vData;
|
|||
|
|
|||
|
VariantInit(&vData);
|
|||
|
size.cElements = pPackageDetail->pInstallInfo->cScriptLen;
|
|||
|
size.lLbound = 0;
|
|||
|
|
|||
|
psa = SafeArrayCreate(VT_UI1, 1, &size);
|
|||
|
if (!psa) {
|
|||
|
return(E_OUTOFMEMORY);
|
|||
|
}
|
|||
|
|
|||
|
hr = SafeArrayAccessData( psa, (void HUGEP * FAR *) &pArray );
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
memcpy( pArray, pPackageDetail->pInstallInfo->pScript, size.cElements );
|
|||
|
SafeArrayUnaccessData( psa );
|
|||
|
|
|||
|
V_VT(&vData) = VT_ARRAY | VT_UI1;
|
|||
|
V_ARRAY(&vData) = psa;
|
|||
|
hr = pPackageADs->Put(PKGSCRIPT, vData);
|
|||
|
VariantClear(&vData);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
hr = StoreIt(pPackageADs);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
|
|||
|
if (pPackageDetail->pActInfo)
|
|||
|
{
|
|||
|
for (count = 0; count < pPackageDetail->pActInfo->cClasses; count++)
|
|||
|
{
|
|||
|
hr = NewClass((pPackageDetail->pActInfo->pClasses)+count);
|
|||
|
ERROR_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
Error_Cleanup:
|
|||
|
pPackageADs->Release();
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|