I'm trying to get some info via COM, and i've got as far as getting an instance
of IAsyncOperation. Now i need to wait for it to complete *somehow*, but it's
unclear how to do it. All MS examples use some advanced C++ at the very least.

I've tried to implement an AsyncActionCompletedHandler object myself, but the
program crashes when i call IAsyncOperation_put_Completed() with that object.

The program is attached.

I suspect that actually getting the handler invoked will require more work
(such as running a message pump), but i'll burn that bridge when i cross it.
#define INITGUID
#define COBJMACROS
#define _WIN32_WINNT 0x0602
#include <winstring.h>
#include <roapi.h>
#include <windows.foundation.h>

#include <stdio.h>

typedef interface IPackageStatus IPackageStatus;

typedef interface IIterator IIterator;

typedef struct IIteratorVtbl {
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(
        IIterator *This,
        REFIID riid,
        void **ppvObject);

    ULONG (STDMETHODCALLTYPE *AddRef)(
        IIterator *This);

    ULONG (STDMETHODCALLTYPE *Release)(
        IIterator *This);

    /*** IInspectable methods ***/
    HRESULT (STDMETHODCALLTYPE *GetIids)(
        IIterator *This,
        UINT32 *count,
        IID **ids);

    HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(
        IIterator *This,
        HSTRING *className);

    HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(
        IIterator *This,
        TrustLevel *trustLevel);

    /*** IIterator methods ***/
    HRESULT (STDMETHODCALLTYPE *get_Current)(
        IIterator *This,
        IUnknown **current);

    HRESULT (STDMETHODCALLTYPE *get_HasCurrent)(
        IIterator *This,
        CHAR *hasCurrent);

    HRESULT (STDMETHODCALLTYPE *MoveNext)(
        IIterator *This,
        CHAR *hasCurrent);

    HRESULT (STDMETHODCALLTYPE *GetMany)(
        IIterator *This,
        UINT capacity,
        void *value,
        UINT *actual);

    END_INTERFACE
} IIteratorVtbl;


interface IIterator {
    CONST_VTBL IIteratorVtbl* lpVtbl;
};

/*** IUnknown methods ***/
#define IIterator_QueryInterface(This,riid,ppvObject) 
(This)->lpVtbl->QueryInterface(This,riid,ppvObject)
#define IIterator_AddRef(This) (This)->lpVtbl->AddRef(This)
#define IIterator_Release(This) (This)->lpVtbl->Release(This)
/*** IInspectable methods ***/
#define IIterator_GetIids(This,count,ids) 
(This)->lpVtbl->GetIids(This,count,ids)
#define IIterator_GetRuntimeClassName(This,name) 
(This)->lpVtbl->GetRuntimeClassName(This,name)
#define IIterator_GetTrustLevel(This,level) 
(This)->lpVtbl->GetTrustLevel(This,level)
/*** IIterator methods ***/
#define IIterator_get_Current(This,current) 
(This)->lpVtbl->get_Current(This,current)
#define IIterator_get_HasCurrent(This,hasCurrent) 
(This)->lpVtbl->get_HasCurrent(This,hasCurrent)
#define IIterator_MoveNext(This,hasCurrent) 
(This)->lpVtbl->MoveNext(This,hasCurrent)
#define IIterator_GetMany(This,capacity,value,actual) 
(This)->lpVtbl->GetMany(This,capacity,value,actual)

#define E_BOUNDS ((HRESULT)0x8000000BL)

typedef interface IIterable IIterable;

typedef struct IIterableVtbl {
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(
        IIterable *This,
        REFIID riid,
        void **ppvObject);

    ULONG (STDMETHODCALLTYPE *AddRef)(
        IIterable *This);

    ULONG (STDMETHODCALLTYPE *Release)(
        IIterable *This);

    /*** IInspectable methods ***/
    HRESULT (STDMETHODCALLTYPE *GetIids)(
        IIterable *This,
        UINT32 *count,
        IID **ids);

    HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(
        IIterable *This,
        HSTRING *className);

    HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(
        IIterable *This,
        TrustLevel *trustLevel);

    /*** IIterable methods ***/
    HRESULT (STDMETHODCALLTYPE *First)(
        IIterable *This,
        IIterator **first);

    END_INTERFACE
} IIterableVtbl;

interface IIterable {
    CONST_VTBL IIterableVtbl* lpVtbl;
};

/*** IUnknown methods ***/
#define IIterable_QueryInterface(This,riid,ppvObject) 
(This)->lpVtbl->QueryInterface(This,riid,ppvObject)
#define IIterable_AddRef(This) (This)->lpVtbl->AddRef(This)
#define IIterable_Release(This) (This)->lpVtbl->Release(This)
/*** IInspectable methods ***/
#define IIterable_GetIids(This,count,ids) 
(This)->lpVtbl->GetIids(This,count,ids)
#define IIterable_GetRuntimeClassName(This,name) 
(This)->lpVtbl->GetRuntimeClassName(This,name)
#define IIterable_GetTrustLevel(This,level) 
(This)->lpVtbl->GetTrustLevel(This,level)
/*** IIterable methods ***/
#define IIterable_First(This,retval) (This)->lpVtbl->First(This,retval)

typedef interface IPackageManager IPackageManager;

DEFINE_GUID(IID_IPackageManager, 0x9A7D4B65, 0x5E8F, 0x4FC7, 0xA2, 0xE5, 0x7F, 
0x69, 0x25, 0xCB, 0x8B, 0x53);

typedef struct IPackageManagerVtbl {
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(
        IPackageManager *This,
        REFIID riid,
        void **ppvObject);

    ULONG (STDMETHODCALLTYPE *AddRef)(
        IPackageManager *This);

    ULONG (STDMETHODCALLTYPE *Release)(
        IPackageManager *This);

    /*** IInspectable methods ***/
    HRESULT (STDMETHODCALLTYPE *GetIids)(
        IPackageManager *This,
        UINT32 *count,
        IID **ids);

    HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(
        IPackageManager *This,
        HSTRING *className);

    HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(
        IPackageManager *This,
        TrustLevel *trustLevel);

    /*** IPackageManager methods ***/
    HRESULT (STDMETHODCALLTYPE *stub_AddPackageAsync)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_UpdatePackageAsync)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_RemovePackageAsync)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_StagePackageAsync)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_RegisterPackageAsync)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *FindPackages)(
        IPackageManager *This,
        IIterable **retval);

    HRESULT (STDMETHODCALLTYPE *FindPackagesByUserSecurityId)(
        IPackageManager *This,
        HSTRING userSecurityId,
        IIterable **retval);

    HRESULT (STDMETHODCALLTYPE *stub_FindPackagesByNamePublisher)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_FindPackagesByUserSecurityIdNamePublisher)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_FindUsers)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_SetPackageState)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_FindPackageByPackageFullName)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_CleanupPackageForUserAsync)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE *stub_FindPackagesByPackageFamilyName)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE 
*stub_FindPackagesByUserSecurityIdPackageFamilyName)(
        IPackageManager *This);

    HRESULT (STDMETHODCALLTYPE 
*stub_FindPackageByUserSecurityIdPackageFullName)(
        IPackageManager *This);

    END_INTERFACE
} IPackageManagerVtbl;

interface IPackageManager {
    CONST_VTBL IPackageManagerVtbl* lpVtbl;
};

/*** IUnknown methods ***/
#define IPackageManager_QueryInterface(This,riid,ppvObject) 
(This)->lpVtbl->QueryInterface(This,riid,ppvObject)
#define IPackageManager_AddRef(This) (This)->lpVtbl->AddRef(This)
#define IPackageManager_Release(This) (This)->lpVtbl->Release(This)
/*** IInspectable methods ***/
#define IPackageManager_GetIids(This,count,ids) 
(This)->lpVtbl->GetIids(This,count,ids)
#define IPackageManager_GetRuntimeClassName(This,name) 
(This)->lpVtbl->GetRuntimeClassName(This,name)
#define IPackageManager_GetTrustLevel(This,level) 
(This)->lpVtbl->GetTrustLevel(This,level)
/*** IPackageManager methods ***/
#define IPackageManager_FindPackages(This,retval) 
(This)->lpVtbl->FindPackages(This,retval)
#define 
IPackageManager_FindPackagesByUserSecurityId(This,userSecurityId,retval) 
(This)->lpVtbl->FindPackagesByUserSecurityId(This,userSecurityId,retval)


typedef interface IPackageVersion IPackageVersion;
typedef interface IProcessorArchitecture IProcessorArchitecture;

typedef interface IPackageId IPackageId;


typedef struct IPackageIdVtbl {
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(
        IPackageId *This,
        REFIID riid,
        void **ppvObject);

    ULONG (STDMETHODCALLTYPE *AddRef)(
        IPackageId *This);

    ULONG (STDMETHODCALLTYPE *Release)(
        IPackageId *This);

    /*** IInspectable methods ***/
    HRESULT (STDMETHODCALLTYPE *GetIids)(
        IPackageId *This,
        UINT32 *count,
        IID **ids);

    HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(
        IPackageId *This,
        HSTRING *className);

    HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(
        IPackageId *This,
        TrustLevel *trustLevel);

    /*** IPackageId methods ***/
    HRESULT (STDMETHODCALLTYPE *get_Name)(
        IPackageId *This,
        HSTRING *value);

    HRESULT (STDMETHODCALLTYPE *get_Version)(
        IPackageId *This,
        IPackageVersion *value);

    HRESULT (STDMETHODCALLTYPE *get_Architecture)(
        IPackageId *This,
        IProcessorArchitecture *value);

    HRESULT (STDMETHODCALLTYPE *get_ResourceId)(
        IPackageId *This,
        HSTRING *value);

    HRESULT (STDMETHODCALLTYPE *get_Publisher)(
        IPackageId *This,
        HSTRING *value);

    HRESULT (STDMETHODCALLTYPE *get_PublisherId)(
        IPackageId *This,
        HSTRING *value);

    HRESULT (STDMETHODCALLTYPE *get_FullName)(
        IPackageId *This,
        HSTRING *value);

    HRESULT (STDMETHODCALLTYPE *get_FamilyName)(
        IPackageId *This,
        HSTRING *value);

    END_INTERFACE
} IPackageIdVtbl;

interface IPackageId {
    CONST_VTBL IPackageIdVtbl* lpVtbl;
};

/*** IUnknown methods ***/
#define IPackageId_QueryInterface(This,riid,ppvObject) 
(This)->lpVtbl->QueryInterface(This,riid,ppvObject)
#define IPackageId_AddRef(This) (This)->lpVtbl->AddRef(This)
#define IPackageId_Release(This) (This)->lpVtbl->Release(This)
/*** IInspectable methods ***/
#define IPackageId_GetIids(This,count,ids) 
(This)->lpVtbl->GetIids(This,count,ids)
#define IPackageId_GetRuntimeClassName(This,name) 
(This)->lpVtbl->GetRuntimeClassName(This,name)
#define IPackageId_GetTrustLevel(This,level) 
(This)->lpVtbl->GetTrustLevel(This,level)
/*** IPackageId methods ***/
#define IPackageId_get_Name(This,value) (This)->lpVtbl->get_Name(This,value)
#define IPackageId_get_Version(This,value) 
(This)->lpVtbl->get_Version(This,value)
#define IPackageId_get_Architecture(This,value) 
(This)->lpVtbl->get_Architecture(This,value)
#define IPackageId_get_ResourceId(This,value) 
(This)->lpVtbl->get_ResourceId(This,value)
#define IPackageId_get_Publisher(This,value) 
(This)->lpVtbl->get_Publisher(This,value)
#define IPackageId_get_PublisherId(This,value) 
(This)->lpVtbl->get_PublisherId(This,value)
#define IPackageId_get_FullName(This,value) 
(This)->lpVtbl->get_FullName(This,value)
#define IPackageId_get_FamilyName(This,value) 
(This)->lpVtbl->get_FamilyName(This,value)





typedef interface IPackage IPackage;

DEFINE_GUID(IID_IPackage, 0x163C792F, 0xBD75, 0x413C, 0xBF, 0x23, 0xB1, 0xFE, 
0x7B, 0x95, 0xD8, 0x25);

typedef struct IPackageVtbl {
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(
        IPackage *This,
        REFIID riid,
        void **ppvObject);

    ULONG (STDMETHODCALLTYPE *AddRef)(
        IPackage *This);

    ULONG (STDMETHODCALLTYPE *Release)(
        IPackage *This);

    /*** IInspectable methods ***/
    HRESULT (STDMETHODCALLTYPE *GetIids)(
        IPackage *This,
        UINT32 *count,
        IID **ids);

    HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(
        IPackage *This,
        HSTRING *className);

    HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(
        IPackage *This,
        TrustLevel *trustLevel);

    /*** IPackage methods ***/
    HRESULT (STDMETHODCALLTYPE *get_Id)(
        IPackage *This,
        IPackageId **value);

    HRESULT (STDMETHODCALLTYPE *get_InstalledLocation)(
        IPackage *This,
        void **value);

    HRESULT (STDMETHODCALLTYPE *get_IsFramework)(
        IPackage *This,
        CHAR *value);

    HRESULT (STDMETHODCALLTYPE *get_Dependencies)(
        IPackage *This,
        void **value);

    END_INTERFACE
} IPackageVtbl;

interface IPackage {
    CONST_VTBL IPackageVtbl* lpVtbl;
};

/*** IUnknown methods ***/
#define IPackage_QueryInterface(This,riid,ppvObject) 
(This)->lpVtbl->QueryInterface(This,riid,ppvObject)
#define IPackage_AddRef(This) (This)->lpVtbl->AddRef(This)
#define IPackage_Release(This) (This)->lpVtbl->Release(This)
/*** IInspectable methods ***/
#define IPackage_GetIids(This,count,ids) (This)->lpVtbl->GetIids(This,count,ids)
#define IPackage_GetRuntimeClassName(This,name) 
(This)->lpVtbl->GetRuntimeClassName(This,name)
#define IPackage_GetTrustLevel(This,level) 
(This)->lpVtbl->GetTrustLevel(This,level)
/*** IPackage methods ***/
#define IPackage_get_Id(This,value) (This)->lpVtbl->get_Id(This,value)
#define IPackage_get_InstalledLocation(This,value) 
(This)->lpVtbl->get_InstalledLocation(This,value)
#define IPackage_get_IsFramework(This,value) 
(This)->lpVtbl->get_IsFramework(This,value)
#define IPackage_get_Dependencies(This,value) 
(This)->lpVtbl->get_Dependencies(This,value)



typedef interface IPackage2 IPackage2;

DEFINE_GUID(IID_IPackage2, 0xA6612FB6, 0x7688, 0x4ACE, 0x95, 0xFB, 0x35, 0x95, 
0x38, 0xE7, 0xAA, 0x01);

typedef struct IPackage2Vtbl {
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(
        IPackage2 *This,
        REFIID riid,
        void **ppvObject);

    ULONG (STDMETHODCALLTYPE *AddRef)(
        IPackage2 *This);

    ULONG (STDMETHODCALLTYPE *Release)(
        IPackage2 *This);

    /*** IInspectable methods ***/
    HRESULT (STDMETHODCALLTYPE *GetIids)(
        IPackage2 *This,
        UINT32 *count,
        IID **ids);

    HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(
        IPackage2 *This,
        HSTRING *className);

    HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(
        IPackage2 *This,
        TrustLevel *trustLevel);

    /*** IPackage2 methods ***/
    HRESULT (STDMETHODCALLTYPE *get_DisplayName)(
        IPackage2 *This,
        HSTRING *value);

    HRESULT (STDMETHODCALLTYPE *get_PublisherDisplayName)(
        IPackage2 *This,
        HSTRING *value);

    HRESULT (STDMETHODCALLTYPE *get_Description)(
        IPackage2 *This,
        HSTRING *value);

    HRESULT (STDMETHODCALLTYPE *get_Logo)(
        IPackage2 *This,
        void **value);

    HRESULT (STDMETHODCALLTYPE *get_IsResourcePackage)(
        IPackage2 *This,
        CHAR *value);

    HRESULT (STDMETHODCALLTYPE *get_IsBundle)(
        IPackage2 *This,
        CHAR *value);

    HRESULT (STDMETHODCALLTYPE *get_IsDevelopmentMode)(
        IPackage2 *This,
        CHAR *value);

    END_INTERFACE
} IPackage2Vtbl;

interface IPackage2 {
    CONST_VTBL IPackage2Vtbl* lpVtbl;
};

/*** IUnknown methods ***/
#define IPackage2_QueryInterface(This,riid,ppvObject) 
(This)->lpVtbl->QueryInterface(This,riid,ppvObject)
#define IPackage2_AddRef(This) (This)->lpVtbl->AddRef(This)
#define IPackage2_Release(This) (This)->lpVtbl->Release(This)
/*** IInspectable methods ***/
#define IPackage2_GetIids(This,count,ids) 
(This)->lpVtbl->GetIids(This,count,ids)
#define IPackage2_GetRuntimeClassName(This,name) 
(This)->lpVtbl->GetRuntimeClassName(This,name)
#define IPackage2_GetTrustLevel(This,level) 
(This)->lpVtbl->GetTrustLevel(This,level)
/*** IPackage2 methods ***/
#define IPackage2_get_DisplayName(This,value) 
(This)->lpVtbl->get_DisplayName(This,value)
#define IPackage2_get_PublisherDisplayName(This,value) 
(This)->lpVtbl->get_PublisherDisplayName(This,value)
#define IPackage2_get_Description(This,value) 
(This)->lpVtbl->get_Description(This,value)
#define IPackage2_get_Logo(This,value) (This)->lpVtbl->get_Logo(This,value)
#define IPackage2_get_IsResourcePackage(This,value) 
(This)->lpVtbl->get_IsResourcePackage(This,value)
#define IPackage2_get_IsBundle(This,value) 
(This)->lpVtbl->get_IsBundle(This,value)
#define IPackage2_get_IsDevelopmentMode(This,value) 
(This)->lpVtbl->get_IsDevelopmentMode(This,value)



typedef interface IPackage3 IPackage3;


DEFINE_GUID(IID_IPackage3, 0x5F738B61, 0xF86A, 0x4917, 0x93, 0xD1, 0xF1, 0xEE, 
0x9D, 0x3B, 0x35, 0xD9);

typedef struct IPackage3Vtbl {
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(
        IPackage3 *This,
        REFIID riid,
        void **ppvObject);

    ULONG (STDMETHODCALLTYPE *AddRef)(
        IPackage3 *This);

    ULONG (STDMETHODCALLTYPE *Release)(
        IPackage3 *This);

    /*** IInspectable methods ***/
    HRESULT (STDMETHODCALLTYPE *GetIids)(
        IPackage3 *This,
        UINT32 *count,
        IID **ids);

    HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(
        IPackage3 *This,
        HSTRING *className);

    HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(
        IPackage3 *This,
        TrustLevel *trustLevel);

    /*** IPackage3 methods ***/
    HRESULT (STDMETHODCALLTYPE *get_Status)(
        IPackage3 *This,
        IPackageStatus **value);

    HRESULT (STDMETHODCALLTYPE *get_InstalledDate)(
        IPackage3 *This,
        DateTime *value);

    HRESULT (STDMETHODCALLTYPE *GetAppListEntriesAsync)(
        IPackage3 *This,
        IAsyncOperation **operation);

    END_INTERFACE
} IPackage3Vtbl;

interface IPackage3 {
    CONST_VTBL IPackage3Vtbl* lpVtbl;
};

/*** IUnknown methods ***/
#define IPackage3_QueryInterface(This,riid,ppvObject) 
(This)->lpVtbl->QueryInterface(This,riid,ppvObject)
#define IPackage3_AddRef(This) (This)->lpVtbl->AddRef(This)
#define IPackage3_Release(This) (This)->lpVtbl->Release(This)
/*** IInspectable methods ***/
#define IPackage3_GetIids(This,count,ids) 
(This)->lpVtbl->GetIids(This,count,ids)
#define IPackage3_GetRuntimeClassName(This,name) 
(This)->lpVtbl->GetRuntimeClassName(This,name)
#define IPackage3_GetTrustLevel(This,level) 
(This)->lpVtbl->GetTrustLevel(This,level)
/*** IPackage3 methods ***/
#define IPackage3_get_Status(This,value) (This)->lpVtbl->get_Status(This,value)
#define IPackage3_get_InstalledDate(This,value) 
(This)->lpVtbl->get_InstalledDate(This,value)
#define IPackage3_GetAppListEntriesAsync(This,operation) 
(This)->lpVtbl->GetAppListEntriesAsync(This,operation)




static void
print_and_delete_string (int         j,
                         const char *desc,
                         HSTRING     hstring)
{
  UINT32 buffer_len = 0;
  const wchar_t *buffer = NULL;

  buffer = WindowsGetStringRawBuffer (hstring, &buffer_len);
  if (buffer)
    printf ("%d %s is %u chars long: %S\n", j, desc, buffer_len, buffer);

  WindowsDeleteString (hstring);
}

typedef struct _acomp
{
  AsyncActionCompletedHandler aacomph;
  int ref_count;
} acomp;

static ULONG STDMETHODCALLTYPE
aacomph_addref (AsyncActionCompletedHandler *This)
{
  acomp *self = (acomp *) This;
  int ref_count = ++self->ref_count;

  printf ("aacomph_addref %p %d\n", This, ref_count);

  return ref_count;
}

static HRESULT STDMETHODCALLTYPE
aacomph_queryinterface (AsyncActionCompletedHandler *This,
                        REFIID                       riid,
                        LPVOID                      *ppvObject)
{
  printf ("aacomph_queryinterface %p ", This);

  *ppvObject = NULL;

  if (IsEqualGUID (riid, &IID_IUnknown))
  {
    printf ("IUnknown, return S_OK\n");
    AsyncActionCompletedHandler_AddRef (This);
    *ppvObject = This;
    return S_OK;
  }
  else if (IsEqualGUID (riid, &IID_AsyncActionCompletedHandler))
  {
    printf ("AsyncActionCompletedHandler, return S_OK\n");
    AsyncActionCompletedHandler_AddRef (This);
    *ppvObject = This;
    return S_OK;
  }

  printf ("return E_NOINTERFACE\n");
  return E_NOINTERFACE;
}

static ULONG STDMETHODCALLTYPE
aacomph_release (AsyncActionCompletedHandler *This)
{
  acomp *self = (acomp *) This;
  int ref_count = --self->ref_count;

  printf ("aacomph_release %p %d\n", This, ref_count);

  if (ref_count == 0)
  {
    free (self);
  }

  return ref_count;
}

static HRESULT STDMETHODCALLTYPE
aacomph_invoke (AsyncActionCompletedHandler *This,
                IInspectable                *asyncInfo,
                AsyncStatus                  asyncStatus)
{
/*  acomp *self = (acomp *) This;*/
  
  printf ("aacomph_invoke %p with status %d", This, asyncStatus);

  return S_OK;
}

static AsyncActionCompletedHandlerVtbl aacomph_vtbl = {
  aacomph_queryinterface,
  aacomph_addref,
  aacomph_release,
  aacomph_invoke,
};

static AsyncActionCompletedHandler *
acomp_new ()
{
  acomp *result;

  result = malloc (sizeof (acomp));
  result->aacomph.lpVtbl = &aacomph_vtbl;
  result->ref_count = 0;

  AsyncActionCompletedHandler_AddRef ((AsyncActionCompletedHandler *) result);

  printf ("acomp_new: %p\n", result);

  return (AsyncActionCompletedHandler *) result;
}

int
main (int argc, char **argv)
{
  HRESULT hr;
  HSTRING packagemanager_name;
  IInspectable *ii_pm;
  IPackageManager *pm;
  IIterable *packages_iterable;
  IIterator *packages_iterator;
  CHAR has_current;
  int j;

  CoInitialize (NULL);

  #define _PACKMAN L"Windows.Management.Deployment.PackageManager"
  hr = WindowsCreateString (_PACKMAN, wcslen (_PACKMAN), &packagemanager_name);
  #undef _PACKMAN
  printf ("WindowsCreateString() = %lx\n", hr);

  hr = RoActivateInstance (packagemanager_name, &ii_pm);
  printf ("RoActivateInstance() = %lx\n", hr);

  hr = IInspectable_QueryInterface (ii_pm, &IID_IPackageManager, (void**) &pm);
  printf ("IInspectable_QueryInterface() = %lx\n", hr);

  hr = IInspectable_Release (ii_pm);
  printf ("IInspectable_Release() = %lx\n", hr);

  hr = IPackageManager_FindPackagesByUserSecurityId (pm, 0, &packages_iterable);
  printf ("IPackageManager_FindPackagesByUserSecurityId() = %lx\n", hr);

  hr = IIterable_First (packages_iterable, &packages_iterator);
  printf ("IIterable_First() = %lx\n", hr);
  hr = IIterator_get_HasCurrent (packages_iterator, &has_current);
  printf ("IIterator_get_HasCurrent() = %lx, has_current = %x\n", hr, 
has_current);

  for (j = 0; SUCCEEDED (hr) && has_current; j++)
  {
    IUnknown *item;
    IPackage *p;
    IPackage3 *p3;
    IPackageId *id;
    HSTRING display_name = NULL;
    IAsyncOperation *getapplist_op;
    AsyncStatus status;
    AsyncActionCompletedHandler *getapplist_comp;

    hr = IIterator_get_Current (packages_iterator, &item);
    printf ("%d IIterator_get_Current() = %lx\n", j, hr);

    hr = IUnknown_QueryInterface (item, &IID_IPackage, (void **) &p);
    printf ("%d IUnknown_QueryInterface() = %lx\n", j, hr);

    hr = IUnknown_QueryInterface (item, &IID_IPackage3, (void **) &p3);
    printf ("%d IUnknown_QueryInterface() = %lx\n", j, hr);

    hr = IUnknown_Release (item);
    printf ("%d IUnknown_Release() = %lx\n", j, hr);

    hr = IPackage_get_Id (p, &id);
    printf ("%d IPackage_get_Id() = %lx, id = %p\n", j, hr, id);
    hr = IPackage_Release (p);
    printf ("%d IPackage_Release() = %lx\n", j, hr);

    hr = IPackageId_get_Name (id, &display_name);
    printf ("%d IPackageId_get_Name() = %lx, string = %p\n", j, hr, 
display_name);
    print_and_delete_string (j, "package name", display_name);

    hr = IPackageId_get_ResourceId (id, &display_name);
    printf ("%d IPackageId_get_ResourceId() = %lx, string = %p\n", j, hr, 
display_name);
    print_and_delete_string (j, "package resource id", display_name);

    hr = IPackageId_get_Publisher (id, &display_name);
    printf ("%d IPackageId_get_Publisher() = %lx, string = %p\n", j, hr, 
display_name);
    print_and_delete_string (j, "package publisher", display_name);

    hr = IPackageId_get_PublisherId (id, &display_name);
    printf ("%d IPackageId_get_PublisherId() = %lx, string = %p\n", j, hr, 
display_name);
    print_and_delete_string (j, "package publisher id", display_name);

    hr = IPackageId_get_FullName (id, &display_name);
    printf ("%d IPackageId_get_FullName() = %lx, string = %p\n", j, hr, 
display_name);
    print_and_delete_string (j, "package full name", display_name);

    hr = IPackageId_get_FamilyName (id, &display_name);
    printf ("%d IPackageId_get_FamilyName() = %lx, string = %p\n", j, hr, 
display_name);
    print_and_delete_string (j, "package family name", display_name);

    hr = IPackageId_Release (id);
    printf ("%d IPackageId_Release() = %lx\n", j, hr);

    hr = IPackage3_GetAppListEntriesAsync (p3, &getapplist_op);
    printf ("%d IPackage3_GetAppListEntriesAsync() = %lx\n", j, hr);
    hr = IPackage3_Release (p3);
    printf ("%d IPackage3_Release() = %lx\n", j, hr);

    getapplist_comp = acomp_new ();

    hr = IAsyncOperation_put_Completed (getapplist_op, getapplist_comp);
    /* ^^^^ crashes here */
    printf ("%d IAsyncOperation_put_Completed() = %lx\n", j, hr);

    /* TODO: wait */

    hr = IAsyncOperation_get_Status (getapplist_op, &status);
    printf ("%d IAsyncOperation_get_Status() = %lx, status = %d\n", j, hr, 
status);

    hr = AsyncActionCompletedHandler_Release (getapplist_comp);
    printf ("%d AsyncActionCompletedHandler_Release() = %lx\n", j, hr);

    hr = IIterator_MoveNext (packages_iterator, &has_current);
    printf ("%d IIterator_MoveNext() = %lx\n", j, hr);
  }

  printf ("\n");

  hr = IIterator_Release (packages_iterator);
  printf ("IIterator_Release() = %lx\n", hr);

  hr = IIterable_Release (packages_iterable);
  printf ("IIterable_Release() = %lx\n", hr);

  hr = IPackageManager_Release (pm);
  printf ("IPackageManager_Release() = %lx\n", hr);

  return 0;
}

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to