/*
datalayer.exe

IDataLayer::GetDataStoreNames(devname, dsnames)
IPhoneControl::GetDeviceInfo / EnumDevices
IVirtualFileSystem
*/

// midl datalayer.idl /h datalayer.h
// cl tst-datalayer.cpp include\datalayer_i.c -I include ole32.lib oleaut32.lib
// 

#define _WIN32_DCOM 1
#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <ObjBase.h>
#include <Unknwn.h>
#include <stdio.h>

#include "datalayer.h"

bool enum_datastores(BSTR devname)
{
    IUnknown *dl_u=NULL;
    HRESULT hr= CoCreateInstance(CLSID_DataLayer, NULL, CLSCTX_ALL, IID_IUnknown, (void**)&dl_u);
    if (hr) {
        printf("CoCreateInstance: %08lx\n", hr);
        return false;
    }
    printf("dl_u=%08lx : %08lx[%08lx %08lx] %08lx\n", dl_u, ((DWORD*)dl_u)[0], ((DWORD**)dl_u)[0][0], ((DWORD**)dl_u)[0][1], ((DWORD*)dl_u)[1]);
    IDataLayer *dl=NULL;
    hr = dl_u->QueryInterface(IID_IDataLayer, (void**)&dl);
    if (hr) {
        printf("dl_u->QueryInterface: %08lx\n", hr);
        return false;
    }
#if 0
    hr= dl->GetState();
    printf("dl->GetState= %08lx\n", hr);

    unsigned long devid=0;
    BSTR devname=NULL;
    hr= dl->GetID(&devid, &devname);
    if (hr) {
        printf("dl->GetID: %08lx\n", hr);
        return false;
    }
    printf("devid=%08lx  name=%ls\n", devid, devname);

    BSTR loc=NULL;
    hr= dl->GetDeviceInfoLocation(&loc);
    if (hr) {
        printf("dl->GetDeviceInfoLocation: %08lx\n", hr);
        return false;
    }
    printf("loc=%ls\n", loc);
#endif
    VARIANT v; VariantInit(&v);
    hr= dl->GetDataStoreNames(devname, &v);
    if (hr) {
        printf("dl->GetDataStoreNames(%ls): %08lx\n", devname, hr);
        return false;
    }
    printf("ds: vt=%d\n", v.vt);
    return true;
}

bool enum_devices()
{
    IUnknown *pc_u=NULL;
    HRESULT hr= CoCreateInstance(CLSID_PhoneControl, NULL, CLSCTX_ALL, IID_IUnknown, (void**)&pc_u);
    if (hr) {
        printf("CoCreateInstance: %08lx\n", hr);
        return false;
    }
    printf("pc_u=%08lx : %08lx[%08lx %08lx] %08lx\n", pc_u, ((DWORD*)pc_u)[0], ((DWORD**)pc_u)[0][0], ((DWORD**)pc_u)[0][1], ((DWORD*)pc_u)[1]);
    IPhoneControl *pc=NULL;
    hr = pc_u->QueryInterface(IID_IPhoneControl, (void**)&pc);
    if (hr) {
        printf("pc_u->QueryInterface: %08lx\n", hr);
        return false;
    }
    printf("pc=%08lx\n", pc);
    unsigned int ndevs;
    hr= pc->GetCountOfDevices(&ndevs);
    if (hr) {
        printf("pc->GetCountOfDevices : %08lx\n", hr);
        return false;
    }
    for (long i=0 ; i<ndevs ; i++)
    {
        BSTR NICKNAME=NULL;
        BSTR IMEI=NULL;
        BSTR model=NULL;
        BSTR manu=NULL;
        BSTR friendly=NULL;
        BSTR media=NULL;
        hr = pc->GetDeviceInfo( INDEX, i, &NICKNAME, &IMEI, &model, &manu, &friendly, &media);
        if (hr) {
            printf("pc->GetDeviceInfo(%d): %08lx\n", i, hr);
        }
        else {
            printf("%2d: NICKNAME=%ls IMEI=%ls model=%ls manu=%ls friendly=%ls media=%ls\n",
                i, NICKNAME, IMEI, model, manu, friendly, media);

            printf("NICKNAME\n");    enum_datastores(NICKNAME);
            printf("IMEI\n");        enum_datastores(IMEI);
            printf("model\n");       enum_datastores(model);
            printf("manu\n");        enum_datastores(manu);
            printf("friendly\n");    enum_datastores(friendly);
            printf("media\n");       enum_datastores(media);
        }
    } 
    return true;
}
int main()
{
    HRESULT hr= CoInitializeEx(0,COINIT_MULTITHREADED);
    if (hr) {
        printf("CoInitializeEx: %08lx\n", hr);
        return 1;
    }

    enum_devices();
    //test_datastore();
    CoUninitialize();
    return 0;
}

