1075 lines
23 KiB
C++
1075 lines
23 KiB
C++
|
#include "dsbase.hxx"
|
|||
|
|
|||
|
HRESULT PackGuid2Variant(
|
|||
|
GUID guidData,
|
|||
|
VARIANT * pvData
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
SAFEARRAYBOUND size; // Get rid of 16
|
|||
|
SAFEARRAY FAR *psa;
|
|||
|
CHAR HUGEP *pArray=NULL;
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
size.cElements = sizeof(GUID);
|
|||
|
size.lLbound = 0;
|
|||
|
|
|||
|
if (!pvData) {
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
psa = SafeArrayCreate(VT_UI1, 1, &size);
|
|||
|
if (!psa) {
|
|||
|
return(E_OUTOFMEMORY);
|
|||
|
}
|
|||
|
|
|||
|
hr = SafeArrayAccessData( psa, (void HUGEP * FAR *) &pArray );
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
memcpy( pArray, &guidData, size.cElements );
|
|||
|
SafeArrayUnaccessData( psa );
|
|||
|
|
|||
|
V_VT(pvData) = VT_ARRAY | VT_UI1;
|
|||
|
V_ARRAY(pvData) = psa;
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
HRESULT PackGuidArray2Variant(
|
|||
|
GUID *guidData,
|
|||
|
ULONG cguids,
|
|||
|
VARIANT * pvData
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
SAFEARRAYBOUND size, sizeguid;
|
|||
|
SAFEARRAY FAR *psa, *psaOctetString;
|
|||
|
CHAR HUGEP *pArray=NULL;
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
HRESULT hr;
|
|||
|
VARIANT *var;
|
|||
|
ULONG i;
|
|||
|
|
|||
|
if (!pvData) {
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
var = new VARIANT[cguids];
|
|||
|
if (!var)
|
|||
|
return E_OUTOFMEMORY;
|
|||
|
|
|||
|
sizeguid.cElements = cguids;
|
|||
|
sizeguid.lLbound = 0;
|
|||
|
|
|||
|
psa = SafeArrayCreate(VT_VARIANT, 1, &sizeguid);
|
|||
|
if (!psa)
|
|||
|
return E_OUTOFMEMORY;
|
|||
|
|
|||
|
size.cElements = sizeof(GUID);
|
|||
|
size.lLbound = 0;
|
|||
|
|
|||
|
for (i = 0; i < cguids; i++) {
|
|||
|
|
|||
|
psaOctetString = SafeArrayCreate(VT_UI1, 1, &size);
|
|||
|
if (!psaOctetString) {
|
|||
|
return(E_OUTOFMEMORY);
|
|||
|
}
|
|||
|
|
|||
|
hr = SafeArrayAccessData( psaOctetString, (void HUGEP * FAR *) &pArray );
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
memcpy( pArray, &(guidData[i]), size.cElements );
|
|||
|
SafeArrayUnaccessData( psaOctetString );
|
|||
|
|
|||
|
V_VT(var+i) = VT_ARRAY | VT_UI1;
|
|||
|
V_ARRAY(var+i) = psaOctetString;
|
|||
|
|
|||
|
SafeArrayPutElement(psa, (LONG *)&i, var+i);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
}
|
|||
|
V_VT(pvData) = VT_ARRAY | VT_VARIANT;
|
|||
|
V_ARRAY(pvData) = psa;
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
HRESULT PackDWORDArray2Variant(
|
|||
|
DWORD * pdwData,
|
|||
|
ULONG cdword,
|
|||
|
VARIANT * pvData
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
SAFEARRAYBOUND size, sizedword;
|
|||
|
SAFEARRAY FAR *psa;
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
VARIANT *var = NULL;
|
|||
|
ULONG i;
|
|||
|
|
|||
|
if (!pvData) {
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
var = new VARIANT[cdword];
|
|||
|
if (!var)
|
|||
|
return E_OUTOFMEMORY;
|
|||
|
|
|||
|
sizedword.cElements = cdword;
|
|||
|
sizedword.lLbound = 0;
|
|||
|
|
|||
|
psa = SafeArrayCreate(VT_VARIANT, 1, &sizedword);
|
|||
|
if (!psa)
|
|||
|
return E_OUTOFMEMORY;
|
|||
|
|
|||
|
size.cElements = 1;
|
|||
|
size.lLbound = 0;
|
|||
|
|
|||
|
for (i = 0; i < cdword; i++) {
|
|||
|
V_VT(var+i) = VT_I4;
|
|||
|
var[i].lVal = pdwData[i];
|
|||
|
SafeArrayPutElement(psa, (LONG *)&i, var+i);
|
|||
|
}
|
|||
|
|
|||
|
V_VT(pvData) = VT_ARRAY | VT_VARIANT;
|
|||
|
V_ARRAY(pvData) = psa;
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
HRESULT GetPropertyListAlloc(IADs *pADs,
|
|||
|
LPOLESTR pszPropName,
|
|||
|
DWORD *pCount,
|
|||
|
LPOLESTR **ppList)
|
|||
|
{
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
VARIANT v;
|
|||
|
LONG i;
|
|||
|
HRESULT hr = S_OK;
|
|||
|
VARIANT var;
|
|||
|
|
|||
|
*pCount = 0;
|
|||
|
*ppList = NULL;
|
|||
|
|
|||
|
VariantInit(&var);
|
|||
|
|
|||
|
hr = pADs->Get(pszPropName, &var);
|
|||
|
|
|||
|
if (hr == E_ADS_PROPERTY_NOT_FOUND)
|
|||
|
{
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
if(!((V_VT(&var) & VT_VARIANT)))
|
|||
|
{
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// The following is a work around
|
|||
|
//
|
|||
|
if (!V_ISARRAY(&var))
|
|||
|
{
|
|||
|
(*ppList) = (LPOLESTR *) CoTaskMemAlloc(sizeof(LPOLESTR));
|
|||
|
*pCount = 1;
|
|||
|
*(*ppList) = (LPOLESTR) CoTaskMemAlloc (sizeof(WCHAR) * (wcslen(var.bstrVal)+1));
|
|||
|
wcscpy (*(*ppList), var.bstrVal);
|
|||
|
VariantClear(&var);
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check that there is only one dimension in this array
|
|||
|
//
|
|||
|
|
|||
|
if ((V_ARRAY(&var))->cDims != 1)
|
|||
|
{
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
//
|
|||
|
// Check that there is atleast one element in this array
|
|||
|
//
|
|||
|
if ((V_ARRAY(&var))->rgsabound[0].cElements == 0)
|
|||
|
{
|
|||
|
*ppList = NULL;
|
|||
|
return S_OK; // was E_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We know that this is a valid single dimension array
|
|||
|
//
|
|||
|
|
|||
|
hr = SafeArrayGetLBound(V_ARRAY(&var),
|
|||
|
1,
|
|||
|
(long FAR *)&dwSLBound
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SafeArrayGetUBound(V_ARRAY(&var),
|
|||
|
1,
|
|||
|
(long FAR *)&dwSUBound
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
(*ppList) = (LPOLESTR *) CoTaskMemAlloc(sizeof(LPOLESTR)*(dwSUBound-dwSLBound+1));
|
|||
|
|
|||
|
for (i = dwSLBound; i <= dwSUBound; i++)
|
|||
|
{
|
|||
|
VariantInit(&v);
|
|||
|
hr = SafeArrayGetElement(V_ARRAY(&var),
|
|||
|
(long FAR *)&i,
|
|||
|
&v
|
|||
|
);
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (i <= dwSUBound)
|
|||
|
{
|
|||
|
(*ppList)[*pCount] = (LPOLESTR) CoTaskMemAlloc
|
|||
|
(sizeof (WCHAR) * (wcslen(v.bstrVal) + 1));
|
|||
|
wcscpy ((*ppList)[*pCount], v.bstrVal);
|
|||
|
VariantClear(&v);
|
|||
|
(*pCount)++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VariantClear(&var);
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT SetPropertyGuid (IADs *pADs, LPOLESTR pszPropName, GUID guidPropVal)
|
|||
|
{
|
|||
|
VARIANT var;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
VariantInit(&var);
|
|||
|
hr = PackGuid2Variant(guidPropVal, &var);
|
|||
|
hr = pADs->Put(pszPropName, var);
|
|||
|
VariantClear(&var);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// replacing ADsBuildVarArrStr b'cos of mem leaks.
|
|||
|
|
|||
|
HRESULT
|
|||
|
BuildVarArrayStr(
|
|||
|
LPWSTR *lppPathNames,
|
|||
|
DWORD dwPathNames,
|
|||
|
VARIANT * pVar
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
VARIANT v;
|
|||
|
SAFEARRAYBOUND sabNewArray;
|
|||
|
DWORD i;
|
|||
|
SAFEARRAY *psa = NULL;
|
|||
|
HRESULT hr = E_FAIL;
|
|||
|
|
|||
|
|
|||
|
if (!pVar) {
|
|||
|
hr = E_ADS_BAD_PARAMETER;
|
|||
|
goto Fail;
|
|||
|
}
|
|||
|
VariantInit(pVar);
|
|||
|
|
|||
|
sabNewArray.cElements = dwPathNames;
|
|||
|
sabNewArray.lLbound = 0;
|
|||
|
psa = SafeArrayCreate(VT_VARIANT, 1, &sabNewArray);
|
|||
|
|
|||
|
if (!psa) {
|
|||
|
goto Fail;
|
|||
|
}
|
|||
|
|
|||
|
for (i = 0; i < dwPathNames; i++) {
|
|||
|
|
|||
|
VariantInit(&v);
|
|||
|
V_VT(&v) = VT_BSTR;
|
|||
|
V_BSTR(&v) = SysAllocString(*(lppPathNames + i));
|
|||
|
hr = SafeArrayPutElement(psa,
|
|||
|
(long FAR *)&i,
|
|||
|
&v
|
|||
|
);
|
|||
|
|
|||
|
SysFreeString(v.bstrVal);
|
|||
|
VariantClear(&v);
|
|||
|
|
|||
|
if (FAILED(hr)) {
|
|||
|
goto Fail;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
V_VT(pVar) = VT_ARRAY | VT_VARIANT;
|
|||
|
|
|||
|
V_ARRAY(pVar) = psa;
|
|||
|
|
|||
|
return(ResultFromScode(S_OK));
|
|||
|
|
|||
|
|
|||
|
Fail:
|
|||
|
|
|||
|
if (psa) {
|
|||
|
SafeArrayDestroy(psa);
|
|||
|
}
|
|||
|
|
|||
|
return(E_FAIL);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT SetPropertyList(IADs *pADs, LPWSTR pszPropName, DWORD Count,
|
|||
|
LPWSTR *pList)
|
|||
|
{
|
|||
|
VARIANT Var;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
VariantInit(&Var);
|
|||
|
|
|||
|
hr = BuildVarArrayStr(pList, Count, &Var);
|
|||
|
|
|||
|
hr = pADs->Put(pszPropName, Var);
|
|||
|
VariantClear(&Var);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT SetPropertyListMerge(IADs *pADs, LPWSTR pszPropName, DWORD Count,
|
|||
|
LPWSTR *pList)
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
LPOLESTR *pszProps = NULL, *pszMergedProps = NULL;
|
|||
|
DWORD cProps = 0, cMergedProps = 0;
|
|||
|
DWORD i, j;
|
|||
|
|
|||
|
hr = GetPropertyListAlloc(pADs, pszPropName, &cProps, &pszProps);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
// get the property already stored.
|
|||
|
|
|||
|
pszMergedProps = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*(cProps+Count));
|
|||
|
for (i = 0; i < cProps; i++)
|
|||
|
pszMergedProps[i] = pszProps[i];
|
|||
|
|
|||
|
// copy all the prop got.
|
|||
|
|
|||
|
cMergedProps = cProps;
|
|||
|
for (j = 0; j < Count; j++) {
|
|||
|
for (i = 0; i < cProps; i++) {
|
|||
|
if (wcscmp(pList[j], pszMergedProps[i]) == 0) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
// if this element was not found already add it.
|
|||
|
if (i == cProps)
|
|||
|
pszMergedProps[cMergedProps++] = pList[j];
|
|||
|
}
|
|||
|
|
|||
|
hr = SetPropertyList(pADs, pszPropName, cMergedProps, pszMergedProps);
|
|||
|
|
|||
|
for (i = 0; i < cProps; i++)
|
|||
|
CoTaskMemFree(pszProps[i]);
|
|||
|
|
|||
|
CoTaskMemFree(pszProps);
|
|||
|
CoTaskMemFree(pszMergedProps);
|
|||
|
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
HRESULT GetPropertyGuid(IADs *pADs, LPOLESTR pszPropName, GUID *pguidPropVal)
|
|||
|
{
|
|||
|
VARIANT varGet;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
VariantInit(&varGet);
|
|||
|
hr = pADs->Get(pszPropName, &varGet);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = UnpackGuidFromVariant(varGet, pguidPropVal);
|
|||
|
|
|||
|
VariantClear(&varGet);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
HRESULT UnpackGuidFromVariant(VARIANT varGet, GUID *pguidPropVal)
|
|||
|
{
|
|||
|
HRESULT hr=S_OK;
|
|||
|
SAFEARRAY FAR *psa;
|
|||
|
CHAR HUGEP *pArray=NULL;
|
|||
|
|
|||
|
if (V_VT(&varGet) != (VT_ARRAY | VT_UI1))
|
|||
|
return E_FAIL;
|
|||
|
if ((V_ARRAY(&varGet))->rgsabound[0].cElements != sizeof(GUID))
|
|||
|
return E_FAIL;
|
|||
|
|
|||
|
psa = V_ARRAY(&varGet);
|
|||
|
|
|||
|
hr = SafeArrayAccessData( psa, (void HUGEP * FAR *) &pArray );
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
memcpy( pguidPropVal, pArray, sizeof(GUID)); // check for size
|
|||
|
SafeArrayUnaccessData( psa );
|
|||
|
|
|||
|
// BUGBUG:: any more freeing to do ??
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// assumption that this is going to be a variant structure with
|
|||
|
|
|||
|
HRESULT GetPropertyListAllocGuid(IADs *pADs,
|
|||
|
LPOLESTR pszPropName,
|
|||
|
DWORD *pCount,
|
|||
|
GUID **ppList)
|
|||
|
{
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
VARIANT v;
|
|||
|
LONG i;
|
|||
|
HRESULT hr = S_OK;
|
|||
|
VARIANT var;
|
|||
|
|
|||
|
*pCount = 0;
|
|||
|
VariantInit(&var);
|
|||
|
|
|||
|
hr = pADs->Get(pszPropName, &var);
|
|||
|
|
|||
|
if (hr == E_ADS_PROPERTY_NOT_FOUND)
|
|||
|
{
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
//
|
|||
|
// The following is a work around
|
|||
|
//
|
|||
|
if (V_VT(&var) == (VT_ARRAY | VT_UI1))
|
|||
|
{
|
|||
|
(*ppList) = (GUID *) CoTaskMemAlloc(sizeof(GUID));
|
|||
|
*pCount = 1;
|
|||
|
UnpackGuidFromVariant(var, *ppList);
|
|||
|
VariantClear(&var);
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check that there is only one dimension in this array
|
|||
|
//
|
|||
|
|
|||
|
if ((V_ARRAY(&var))->cDims != 1)
|
|||
|
{
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
//
|
|||
|
// Check that there is atleast one element in this array
|
|||
|
//
|
|||
|
if ((V_ARRAY(&var))->rgsabound[0].cElements == 0)
|
|||
|
{
|
|||
|
*ppList = NULL;
|
|||
|
return S_OK; // was E_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We know that this is a valid single dimension array
|
|||
|
//
|
|||
|
|
|||
|
hr = SafeArrayGetLBound(V_ARRAY(&var),
|
|||
|
1,
|
|||
|
(long FAR *)&dwSLBound
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SafeArrayGetUBound(V_ARRAY(&var),
|
|||
|
1,
|
|||
|
(long FAR *)&dwSUBound
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
(*ppList) = (GUID *) CoTaskMemAlloc(sizeof(GUID)*(dwSUBound-dwSLBound+1));
|
|||
|
|
|||
|
for (i = dwSLBound; i <= dwSUBound; i++)
|
|||
|
{
|
|||
|
VariantInit(&v);
|
|||
|
hr = SafeArrayGetElement(V_ARRAY(&var),
|
|||
|
(long FAR *)&i,
|
|||
|
&v
|
|||
|
);
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (i <= dwSUBound)
|
|||
|
{
|
|||
|
UnpackGuidFromVariant(v, (*ppList)+(*pCount));
|
|||
|
VariantClear(&v);
|
|||
|
(*pCount)++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VariantClear(&var);
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT SetPropertyListGuid(IADs *pADs, LPOLESTR pszPropName,
|
|||
|
DWORD cCount, GUID *ppList)
|
|||
|
{
|
|||
|
|
|||
|
VARIANT Var;
|
|||
|
HRESULT hr=S_OK;
|
|||
|
|
|||
|
VariantInit(&Var);
|
|||
|
hr = PackGuidArray2Variant(ppList, cCount, &Var);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = pADs->Put(pszPropName, Var);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
VariantClear(&Var);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
HRESULT
|
|||
|
PackString2Variant(
|
|||
|
LPWSTR lpszData,
|
|||
|
VARIANT * pvData
|
|||
|
)
|
|||
|
{
|
|||
|
BSTR bstrData = NULL;
|
|||
|
|
|||
|
if (!lpszData || !*lpszData) {
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
if (!pvData) {
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
bstrData = SysAllocString(lpszData);
|
|||
|
|
|||
|
if (!bstrData) {
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
pvData->vt = VT_BSTR;
|
|||
|
pvData->bstrVal = bstrData;
|
|||
|
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT
|
|||
|
PackDWORD2Variant(
|
|||
|
DWORD dwData,
|
|||
|
VARIANT * pvData
|
|||
|
)
|
|||
|
{
|
|||
|
if (!pvData) {
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
pvData->vt = VT_I4;
|
|||
|
pvData->lVal = dwData;
|
|||
|
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT
|
|||
|
PackBOOL2Variant(
|
|||
|
BOOL fData,
|
|||
|
VARIANT * pvData
|
|||
|
)
|
|||
|
{
|
|||
|
pvData->vt = VT_BOOL;
|
|||
|
pvData->boolVal = fData;
|
|||
|
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT GetPropertyList(IADs *pADs,
|
|||
|
LPOLESTR pszPropName,
|
|||
|
DWORD *pCount,
|
|||
|
LPOLESTR *pList)
|
|||
|
{
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
VARIANT v;
|
|||
|
LONG i;
|
|||
|
HRESULT hr = S_OK;
|
|||
|
VARIANT var;
|
|||
|
|
|||
|
*pCount = 0;
|
|||
|
VariantInit(&var);
|
|||
|
|
|||
|
hr = pADs->Get(pszPropName, &var);
|
|||
|
|
|||
|
if (hr == E_ADS_PROPERTY_NOT_FOUND)
|
|||
|
{
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
if(!((V_VT(&var) & VT_VARIANT)))
|
|||
|
{
|
|||
|
return(E_FAIL);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// The following is a work around for the package detail field
|
|||
|
//
|
|||
|
if (!V_ISARRAY(&var))
|
|||
|
{
|
|||
|
*pCount = 1;
|
|||
|
*pList = (LPOLESTR) CoTaskMemAlloc (sizeof(WCHAR) * (wcslen(var.bstrVal)+1));
|
|||
|
wcscpy (*pList, var.bstrVal);
|
|||
|
VariantClear(&var);
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check that there is only one dimension in this array
|
|||
|
//
|
|||
|
|
|||
|
if ((V_ARRAY(&var))->cDims != 1)
|
|||
|
{
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
//
|
|||
|
// Check that there is atleast one element in this array
|
|||
|
//
|
|||
|
if ((V_ARRAY(&var))->rgsabound[0].cElements == 0)
|
|||
|
{
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We know that this is a valid single dimension array
|
|||
|
//
|
|||
|
|
|||
|
hr = SafeArrayGetLBound(V_ARRAY(&var),
|
|||
|
1,
|
|||
|
(long FAR *)&dwSLBound
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SafeArrayGetUBound(V_ARRAY(&var),
|
|||
|
1,
|
|||
|
(long FAR *)&dwSUBound
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
for (i = dwSLBound; i <= dwSUBound; i++) {
|
|||
|
VariantInit(&v);
|
|||
|
hr = SafeArrayGetElement(V_ARRAY(&var),
|
|||
|
(long FAR *)&i,
|
|||
|
&v
|
|||
|
);
|
|||
|
if (FAILED(hr)) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (i <= dwSUBound)
|
|||
|
{
|
|||
|
*pList = (LPOLESTR) CoTaskMemAlloc
|
|||
|
(sizeof (WCHAR) * (wcslen(v.bstrVal) + 1));
|
|||
|
wcscpy (*pList, v.bstrVal);
|
|||
|
VariantClear(&v);
|
|||
|
(*pCount)++;
|
|||
|
++pList;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VariantClear(&var);
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT GetPropertyAlloc (IADs *pADs, LPOLESTR pszPropName, LPOLESTR *ppszPropVal)
|
|||
|
{
|
|||
|
VARIANT varGet;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
if (!ppszPropVal)
|
|||
|
return S_OK;
|
|||
|
|
|||
|
VariantInit(&varGet);
|
|||
|
hr = pADs->Get(pszPropName, &varGet);
|
|||
|
if (hr == E_ADS_PROPERTY_NOT_FOUND)
|
|||
|
{
|
|||
|
*ppszPropVal = NULL;
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
*ppszPropVal = (LPOLESTR) CoTaskMemAlloc (sizeof(WCHAR) * (wcslen(varGet.bstrVal)+1));
|
|||
|
wcscpy (*ppszPropVal, varGet.bstrVal);
|
|||
|
VariantClear(&varGet);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT GetProperty (IADs *pADs, LPOLESTR pszPropName, LPOLESTR pszPropVal)
|
|||
|
{
|
|||
|
VARIANT varGet;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
VariantInit(&varGet);
|
|||
|
hr = pADs->Get(pszPropName, &varGet);
|
|||
|
if (hr == E_ADS_PROPERTY_NOT_FOUND)
|
|||
|
{
|
|||
|
pszPropVal[0] = NULL;
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
wcscpy (pszPropVal, varGet.bstrVal);
|
|||
|
VariantClear(&varGet);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT GetPropertyDW (IADs *pADs, LPOLESTR pszPropName, DWORD *pdwPropVal)
|
|||
|
{
|
|||
|
VARIANT varGet;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
VariantInit(&varGet);
|
|||
|
hr = pADs->Get(pszPropName, &varGet);
|
|||
|
if (hr == E_ADS_PROPERTY_NOT_FOUND)
|
|||
|
{
|
|||
|
*pdwPropVal = 0;
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
*pdwPropVal = varGet.lVal;
|
|||
|
VariantClear(&varGet);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
HRESULT GetPropertyListAllocDW (IADs *pADs, LPOLESTR pszPropName, DWORD *pCount, DWORD **pdwPropVal)
|
|||
|
{
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
VARIANT v;
|
|||
|
LONG i;
|
|||
|
HRESULT hr = S_OK;
|
|||
|
VARIANT var;
|
|||
|
|
|||
|
*pCount = 0;
|
|||
|
*pdwPropVal = NULL;
|
|||
|
|
|||
|
VariantInit(&var);
|
|||
|
|
|||
|
hr = pADs->Get(pszPropName, &var);
|
|||
|
|
|||
|
if (hr == E_ADS_PROPERTY_NOT_FOUND)
|
|||
|
{
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
if (!V_ISARRAY(&var))
|
|||
|
{
|
|||
|
*pCount = 1;
|
|||
|
*pdwPropVal = (DWORD *) CoTaskMemAlloc (sizeof(DWORD));
|
|||
|
(*pdwPropVal)[0] = var.lVal;
|
|||
|
VariantClear(&var);
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check that there is only one dimension in this array
|
|||
|
//
|
|||
|
|
|||
|
if ((V_ARRAY(&var))->cDims != 1)
|
|||
|
{
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
//
|
|||
|
// Check that there is atleast one element in this array
|
|||
|
//
|
|||
|
if ((V_ARRAY(&var))->rgsabound[0].cElements == 0)
|
|||
|
{
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We know that this is a valid single dimension array
|
|||
|
//
|
|||
|
|
|||
|
hr = SafeArrayGetLBound(V_ARRAY(&var),
|
|||
|
1,
|
|||
|
(long FAR *)&dwSLBound
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
hr = SafeArrayGetUBound(V_ARRAY(&var),
|
|||
|
1,
|
|||
|
(long FAR *)&dwSUBound
|
|||
|
);
|
|||
|
RETURN_ON_FAILURE(hr);
|
|||
|
|
|||
|
*pdwPropVal = (DWORD *)CoTaskMemAlloc(sizeof(DWORD)*
|
|||
|
(dwSUBound - dwSLBound + 1));
|
|||
|
|
|||
|
if (!(*pdwPropVal))
|
|||
|
return E_OUTOFMEMORY;
|
|||
|
|
|||
|
for (i = dwSLBound; i <= dwSUBound; i++) {
|
|||
|
VariantInit(&v);
|
|||
|
hr = SafeArrayGetElement(V_ARRAY(&var),
|
|||
|
(long FAR *)&i,
|
|||
|
&v
|
|||
|
);
|
|||
|
if (FAILED(hr)) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
(*pdwPropVal)[*pCount] = v.lVal;
|
|||
|
VariantClear(&v);
|
|||
|
(*pCount)++;
|
|||
|
}
|
|||
|
|
|||
|
VariantClear(&var);
|
|||
|
return(S_OK);
|
|||
|
}
|
|||
|
|
|||
|
HRESULT SetPropertyListDW (IADs *pADs, LPOLESTR pszPropName, DWORD dwCount, DWORD *pdwPropVal)
|
|||
|
{
|
|||
|
VARIANT Var;
|
|||
|
HRESULT hr = S_OK;
|
|||
|
|
|||
|
VariantInit(&Var);
|
|||
|
|
|||
|
// BUGBUG:: THis doesn't seem to work.
|
|||
|
// hr = ADsBuildVarArrayInt(pdwPropVal, dwCount, &Var);
|
|||
|
|
|||
|
hr = PackDWORDArray2Variant(pdwPropVal, dwCount, &Var);
|
|||
|
|
|||
|
if (SUCCEEDED(hr))
|
|||
|
hr = pADs->Put(pszPropName, Var);
|
|||
|
|
|||
|
VariantClear(&Var);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
HRESULT SetProperty (IADs *pADs, LPOLESTR pszPropName, LPOLESTR pszPropVal)
|
|||
|
{
|
|||
|
VARIANT var;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
if ((pszPropVal == NULL) || (*pszPropVal == NULL))
|
|||
|
return S_OK;
|
|||
|
VariantInit(&var);
|
|||
|
PackString2Variant(pszPropVal, &var);
|
|||
|
hr = pADs->Put(pszPropName, var);
|
|||
|
SysFreeString(var.bstrVal);
|
|||
|
VariantClear(&var);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
HRESULT SetPropertyDW (IADs *pADs, LPOLESTR pszPropName, DWORD dwPropVal)
|
|||
|
{
|
|||
|
VARIANT var;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
VariantInit(&var);
|
|||
|
PackDWORD2Variant(dwPropVal, &var);
|
|||
|
hr = pADs->Put(pszPropName, var);
|
|||
|
VariantClear(&var);
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
HRESULT StoreIt (IADs *pADs)
|
|||
|
{
|
|||
|
HRESULT hr;
|
|||
|
hr = pADs->SetInfo();
|
|||
|
if (hr == HRESULT_FROM_WIN32(ERROR_EXTENDED_ERROR))
|
|||
|
{
|
|||
|
DWORD proverr;
|
|||
|
hr = ADsGetLastError (&proverr, NULL, 0, NULL, 0);
|
|||
|
if (SUCCEEDED(hr)
|
|||
|
// && (proverr == LDAP_NO_SUCH_ATTRIBUTE)
|
|||
|
)
|
|||
|
{
|
|||
|
printf ("Ldap Error = %d.\n", proverr);
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
else
|
|||
|
return hr; //E_INVALIDARG;
|
|||
|
}
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT GetFromVariant(VARIANT *pVar,
|
|||
|
DWORD *pCount, // In, Out
|
|||
|
LPOLESTR *rpgList)
|
|||
|
{
|
|||
|
LONG dwSLBound = 0;
|
|||
|
LONG dwSUBound = 0;
|
|||
|
LONG j;
|
|||
|
HRESULT hr = S_OK;
|
|||
|
ULONG cFetch = *pCount;
|
|||
|
void HUGEP *pArray;
|
|||
|
|
|||
|
pArray = NULL;
|
|||
|
|
|||
|
if( !(pVar->vt & VT_ARRAY))
|
|||
|
return E_FAIL;
|
|||
|
|
|||
|
hr = SafeArrayGetLBound(V_ARRAY(pVar),
|
|||
|
1,
|
|||
|
(long FAR *) &dwSLBound );
|
|||
|
|
|||
|
hr = SafeArrayGetUBound(V_ARRAY(pVar),
|
|||
|
1,
|
|||
|
(long FAR *) &dwSUBound );
|
|||
|
|
|||
|
hr = SafeArrayAccessData( V_ARRAY(pVar), &pArray );
|
|||
|
|
|||
|
*pCount = 0;
|
|||
|
for (j=dwSLBound; (j<=dwSUBound) && (*pCount < cFetch); j++)
|
|||
|
{
|
|||
|
switch(pVar->vt & ~VT_ARRAY)
|
|||
|
{
|
|||
|
|
|||
|
case VT_BSTR:
|
|||
|
*rpgList = (LPOLESTR) CoTaskMemAlloc
|
|||
|
(sizeof (WCHAR) * (wcslen(((BSTR *)pArray)[j]) + 1));
|
|||
|
wcscpy (*rpgList, ((BSTR *)pArray)[j]);
|
|||
|
(*pCount)++;
|
|||
|
++rpgList;
|
|||
|
break;
|
|||
|
|
|||
|
case VT_I4:
|
|||
|
*rpgList = (LPOLESTR)(((DWORD *) pArray)[j]);
|
|||
|
(*pCount)++;
|
|||
|
++rpgList;
|
|||
|
break;
|
|||
|
|
|||
|
case VT_VARIANT:
|
|||
|
VARIANT *pV;
|
|||
|
pV = (VARIANT *)pArray + j;
|
|||
|
|
|||
|
if (pV->vt == (VT_ARRAY | VT_UI1))
|
|||
|
{ /* binary data, only GUID */
|
|||
|
UnpackGuidFromVariant(*pV, (GUID *)rpgList);
|
|||
|
}
|
|||
|
else if (pV->vt == VT_I4)
|
|||
|
{
|
|||
|
*rpgList = (LPOLESTR) pV->lVal;
|
|||
|
(*pCount)++;
|
|||
|
++rpgList;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*rpgList = (LPOLESTR) CoTaskMemAlloc
|
|||
|
(sizeof (WCHAR) * (wcslen(pV->bstrVal)+1));
|
|||
|
wcscpy (*rpgList, pV->bstrVal);
|
|||
|
(*pCount)++;
|
|||
|
++rpgList;
|
|||
|
}
|
|||
|
break;
|
|||
|
/*
|
|||
|
case VT_I8:
|
|||
|
wprintf(L"%I64d # ",((__int64 *) pArray)[j]);
|
|||
|
break;
|
|||
|
*/
|
|||
|
default:
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
SafeArrayUnaccessData( V_ARRAY(pVar) );
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
HRESULT GetCategoryLocaleDesc(LPOLESTR *pdesc, ULONG cdesc, LCID *plcid,
|
|||
|
LPOLESTR szDescription)
|
|||
|
{
|
|||
|
LCID plgid;
|
|||
|
LPOLESTR ptr;
|
|||
|
if (!cdesc)
|
|||
|
return E_FAIL; // CAT_E_NODESCRIPTION;
|
|||
|
|
|||
|
// Try locale passed in
|
|||
|
if (FindDescription(pdesc, cdesc, plcid, szDescription, 0))
|
|||
|
return S_OK;
|
|||
|
|
|||
|
// Get default sublang local
|
|||
|
plgid = PRIMARYLANGID((WORD)*plcid);
|
|||
|
*plcid = MAKELCID(MAKELANGID(plgid, SUBLANG_DEFAULT), SORT_DEFAULT);
|
|||
|
if (FindDescription(pdesc, cdesc, plcid, szDescription, 0))
|
|||
|
return S_OK;
|
|||
|
|
|||
|
// Get matching lang id
|
|||
|
if (FindDescription(pdesc, cdesc, plcid, szDescription, 1))
|
|||
|
return S_OK;
|
|||
|
|
|||
|
// Get User Default
|
|||
|
*plcid = GetUserDefaultLCID();
|
|||
|
if (FindDescription(pdesc, cdesc, plcid, szDescription, 0))
|
|||
|
return S_OK;
|
|||
|
|
|||
|
// Get System Default
|
|||
|
*plcid = GetUserDefaultLCID();
|
|||
|
if (FindDescription(pdesc, cdesc, plcid, szDescription, 0))
|
|||
|
return S_OK;
|
|||
|
|
|||
|
// Get the first one
|
|||
|
*plcid = wcstoul(pdesc[0], &ptr, 16);
|
|||
|
if (szDescription)
|
|||
|
wcscpy(szDescription, (ptr+wcslen(CATSEPERATOR)+2));
|
|||
|
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
//-------------------------------------------
|
|||
|
// Returns the description corresp. to a LCID
|
|||
|
// desc: list of descs+lcid
|
|||
|
// cdesc: number of elements.
|
|||
|
// plcid: the lcid in/out
|
|||
|
// szDescription:description returned.
|
|||
|
// GetPrimary: Match only the primary.
|
|||
|
//---------------------------------------
|
|||
|
|
|||
|
ULONG FindDescription(LPOLESTR *desc, ULONG cdesc, LCID *plcid, LPOLESTR szDescription, BOOL GetPrimary)
|
|||
|
{
|
|||
|
ULONG i;
|
|||
|
LCID newlcid;
|
|||
|
LPOLESTR ptr;
|
|||
|
for (i = 0; i < cdesc; i++)
|
|||
|
{
|
|||
|
newlcid = wcstoul(desc[i], &ptr, 16); // to be changed
|
|||
|
// error to be checked.
|
|||
|
if ((newlcid == *plcid) || ((GetPrimary) &&
|
|||
|
(PRIMARYLANGID((WORD)*plcid) == PRIMARYLANGID(LANGIDFROMLCID(newlcid)))))
|
|||
|
{
|
|||
|
if (szDescription)
|
|||
|
wcscpy(szDescription, (ptr+wcslen(CATSEPERATOR)+2));
|
|||
|
if (GetPrimary)
|
|||
|
*plcid = newlcid;
|
|||
|
return i+1;
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|