msi: automation: Generalize list implementation.

Same structures and functions can be used for both StringList and RecordList.
This commit is contained in:
Misha Koshelev 2007-05-18 11:23:01 -05:00 committed by Alexandre Julliard
parent 2521111bc7
commit 4ccdbc5845
3 changed files with 40 additions and 37 deletions

View File

@ -84,9 +84,9 @@ interface AutomationObject {
*/ */
typedef struct { typedef struct {
int iCount; ULONG ulCount;
LPWSTR *pszStrings; VARIANT *pVars;
} StringListData; } ListData;
typedef struct { typedef struct {
/* The parent Installer object */ /* The parent Installer object */
@ -635,7 +635,7 @@ static HRESULT WINAPI RecordImpl_Invoke(
return S_OK; return S_OK;
} }
static HRESULT WINAPI StringListImpl_Invoke( static HRESULT WINAPI ListImpl_Invoke(
AutomationObject* This, AutomationObject* This,
DISPID dispIdMember, DISPID dispIdMember,
REFIID riid, REFIID riid,
@ -646,7 +646,7 @@ static HRESULT WINAPI StringListImpl_Invoke(
EXCEPINFO* pExcepInfo, EXCEPINFO* pExcepInfo,
UINT* puArgErr) UINT* puArgErr)
{ {
StringListData *data = (StringListData *)private_data(This); ListData *data = (ListData *)private_data(This);
HRESULT hr; HRESULT hr;
VARIANTARG varg0; VARIANTARG varg0;
@ -654,22 +654,21 @@ static HRESULT WINAPI StringListImpl_Invoke(
switch (dispIdMember) switch (dispIdMember)
{ {
case DISPID_STRINGLIST_ITEM: case DISPID_LIST_ITEM:
if (wFlags & DISPATCH_PROPERTYGET) { if (wFlags & DISPATCH_PROPERTYGET) {
hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr); hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
if (V_I4(&varg0) < 0 || V_I4(&varg0) >= data->iCount) if (V_I4(&varg0) < 0 || V_I4(&varg0) >= data->ulCount)
return DISP_E_BADINDEX; return DISP_E_BADINDEX;
V_VT(pVarResult) = VT_BSTR; VariantCopy(pVarResult, &data->pVars[V_I4(&varg0)]);
V_BSTR(pVarResult) = SysAllocString(data->pszStrings[V_I4(&varg0)]);
} }
else return DISP_E_MEMBERNOTFOUND; else return DISP_E_MEMBERNOTFOUND;
break; break;
case DISPID_STRINGLIST_COUNT: case DISPID_LIST_COUNT:
if (wFlags & DISPATCH_PROPERTYGET) { if (wFlags & DISPATCH_PROPERTYGET) {
V_VT(pVarResult) = VT_I4; V_VT(pVarResult) = VT_I4;
V_I4(pVarResult) = data->iCount; V_I4(pVarResult) = data->ulCount;
} }
else return DISP_E_MEMBERNOTFOUND; else return DISP_E_MEMBERNOTFOUND;
break; break;
@ -683,14 +682,14 @@ static HRESULT WINAPI StringListImpl_Invoke(
return S_OK; return S_OK;
} }
static void WINAPI StringListImpl_Free(AutomationObject *This) static void WINAPI ListImpl_Free(AutomationObject *This)
{ {
StringListData *data = private_data(This); ListData *data = private_data(This);
int idx; ULONG idx;
for (idx=0; idx<data->iCount; idx++) for (idx=0; idx<data->ulCount; idx++)
SysFreeString(data->pszStrings[idx]); VariantClear(&data->pVars[idx]);
HeapFree(GetProcessHeap(), 0, data->pszStrings); HeapFree(GetProcessHeap(), 0, data->pVars);
} }
static HRESULT WINAPI ViewImpl_Invoke( static HRESULT WINAPI ViewImpl_Invoke(
@ -1388,8 +1387,8 @@ static HRESULT WINAPI InstallerImpl_Invoke(
case DISPID_INSTALLER_PRODUCTS: case DISPID_INSTALLER_PRODUCTS:
if (wFlags & DISPATCH_PROPERTYGET) if (wFlags & DISPATCH_PROPERTYGET)
{ {
StringListData *sldata = NULL; ListData *ldata = NULL;
int idx = 0; ULONG idx = 0;
WCHAR szProductBuf[GUID_SIZE]; WCHAR szProductBuf[GUID_SIZE];
/* Find number of products */ /* Find number of products */
@ -1401,22 +1400,24 @@ static HRESULT WINAPI InstallerImpl_Invoke(
} }
V_VT(pVarResult) = VT_DISPATCH; V_VT(pVarResult) = VT_DISPATCH;
if (SUCCEEDED(hr = create_automation_object(0, NULL, (LPVOID*)&pDispatch, &DIID_StringList, StringListImpl_Invoke, StringListImpl_Free, sizeof(StringListData)))) if (SUCCEEDED(hr = create_automation_object(0, NULL, (LPVOID*)&pDispatch, &DIID_StringList, ListImpl_Invoke, ListImpl_Free, sizeof(ListData))))
{ {
IDispatch_AddRef(pDispatch); IDispatch_AddRef(pDispatch);
V_DISPATCH(pVarResult) = pDispatch; V_DISPATCH(pVarResult) = pDispatch;
/* Save product strings */ /* Save product strings */
sldata = (StringListData *)private_data((AutomationObject *)pDispatch); ldata = (ListData *)private_data((AutomationObject *)pDispatch);
if (!(sldata->pszStrings = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LPWSTR)*sldata->iCount))) if (!(ldata->pVars = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*idx)))
ERR("Out of memory\n"); ERR("Out of memory\n");
else else
{ {
sldata->iCount = idx; ldata->ulCount = idx;
for (idx = 0; idx < sldata->iCount; idx++) for (idx = 0; idx < ldata->ulCount; idx++)
{ {
ret = MsiEnumProductsW(idx, szProductBuf); ret = MsiEnumProductsW(idx, szProductBuf);
sldata->pszStrings[idx] = SysAllocString(szProductBuf); VariantInit(&ldata->pVars[idx]);
V_VT(&ldata->pVars[idx]) = VT_BSTR;
V_BSTR(&ldata->pVars[idx]) = SysAllocString(szProductBuf);
} }
} }
} }
@ -1429,8 +1430,8 @@ static HRESULT WINAPI InstallerImpl_Invoke(
case DISPID_INSTALLER_RELATEDPRODUCTS: case DISPID_INSTALLER_RELATEDPRODUCTS:
if (wFlags & DISPATCH_PROPERTYGET) if (wFlags & DISPATCH_PROPERTYGET)
{ {
StringListData *sldata = NULL; ListData *ldata = NULL;
int idx = 0; ULONG idx = 0;
WCHAR szProductBuf[GUID_SIZE]; WCHAR szProductBuf[GUID_SIZE];
hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
@ -1446,22 +1447,24 @@ static HRESULT WINAPI InstallerImpl_Invoke(
} }
V_VT(pVarResult) = VT_DISPATCH; V_VT(pVarResult) = VT_DISPATCH;
if (SUCCEEDED(hr = create_automation_object(0, NULL, (LPVOID*)&pDispatch, &DIID_StringList, StringListImpl_Invoke, StringListImpl_Free, sizeof(StringListData)))) if (SUCCEEDED(hr = create_automation_object(0, NULL, (LPVOID*)&pDispatch, &DIID_StringList, ListImpl_Invoke, ListImpl_Free, sizeof(ListData))))
{ {
IDispatch_AddRef(pDispatch); IDispatch_AddRef(pDispatch);
V_DISPATCH(pVarResult) = pDispatch; V_DISPATCH(pVarResult) = pDispatch;
/* Save product strings */ /* Save product strings */
sldata = (StringListData *)private_data((AutomationObject *)pDispatch); ldata = (ListData *)private_data((AutomationObject *)pDispatch);
if (!(sldata->pszStrings = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LPWSTR)*sldata->iCount))) if (!(ldata->pVars = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*idx)))
ERR("Out of memory\n"); ERR("Out of memory\n");
else else
{ {
sldata->iCount = idx; ldata->ulCount = idx;
for (idx = 0; idx < sldata->iCount; idx++) for (idx = 0; idx < ldata->ulCount; idx++)
{ {
ret = MsiEnumRelatedProductsW(V_BSTR(&varg0), 0, idx, szProductBuf); ret = MsiEnumRelatedProductsW(V_BSTR(&varg0), 0, idx, szProductBuf);
sldata->pszStrings[idx] = SysAllocString(szProductBuf); VariantInit(&ldata->pVars[idx]);
V_VT(&ldata->pVars[idx]) = VT_BSTR;
V_BSTR(&ldata->pVars[idx]) = SysAllocString(szProductBuf);
} }
} }
} }

View File

@ -114,9 +114,9 @@ library WindowsInstaller
{ {
properties: properties:
methods: methods:
[id(DISPID_STRINGLIST_ITEM), propget] [id(DISPID_LIST_ITEM), propget]
BSTR Item(long Index); BSTR Item(long Index);
[id(DISPID_STRINGLIST_COUNT), propget] [id(DISPID_LIST_COUNT), propget]
long Count(); long Count();
} }

View File

@ -29,8 +29,8 @@
#define DISPID_RECORD_STRINGDATA 1 #define DISPID_RECORD_STRINGDATA 1
#define DISPID_RECORD_INTEGERDATA 2 #define DISPID_RECORD_INTEGERDATA 2
#define DISPID_STRINGLIST_ITEM 0 #define DISPID_LIST_ITEM 0
#define DISPID_STRINGLIST_COUNT 1 #define DISPID_LIST_COUNT 1
#define DISPID_VIEW_EXECUTE 1 #define DISPID_VIEW_EXECUTE 1
#define DISPID_VIEW_FETCH 2 #define DISPID_VIEW_FETCH 2