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;
|
||
}
|
||
|
||
|
||
|
||
|