示例#1
0
文件: moniker.c 项目: bilboed/wine
static HRESULT WINAPI ITS_IMonikerImpl_BindToStorage(
    IMoniker* iface,
    IBindCtx* pbc,
    IMoniker* pmkToLeft,
    REFIID riid,
    void** ppvObj)
{
    ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
    DWORD grfMode = STGM_SIMPLE | STGM_READ | STGM_SHARE_EXCLUSIVE;
    HRESULT r;
    IStorage *stg = NULL;

    TRACE("%p %p %p %s %p\n", This,
           pbc, pmkToLeft, debugstr_guid(riid), ppvObj);

    r = ITSS_StgOpenStorage( This->szFile, NULL, grfMode, 0, 0, &stg );
    if( r == S_OK )
    {
        TRACE("Opened storage %s\n", debugstr_w( This->szFile ) );
        if (IsEqualGUID(riid, &IID_IStream))
            r = IStorage_OpenStream( stg, This->szHtml,
                       NULL, grfMode, 0, (IStream**)ppvObj );
        else if (IsEqualGUID(riid, &IID_IStorage))
            r = IStorage_OpenStorage( stg, This->szHtml,
                       NULL, grfMode, NULL, 0, (IStorage**)ppvObj );
        else
            r = STG_E_ACCESSDENIED;
        IStorage_Release( stg );
    }

    return r;
}
示例#2
0
文件: main.c 项目: RareHare/reactos
/***********************************************************************
 *              MsiSIPIsMyTypeOfFile (MSISIP.@)
 */
BOOL WINAPI MsiSIPIsMyTypeOfFile(WCHAR *name, GUID *subject)
{
    BOOL ret = FALSE;
    IStorage *stg = NULL;
    HRESULT r;

    TRACE("(%s, %p)\n", debugstr_w(name), subject);

    r = StgOpenStorage(name, NULL, STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE,
     NULL, 0, &stg);
    if (SUCCEEDED(r))
    {
        STATSTG stat;

        r = IStorage_Stat(stg, &stat, STATFLAG_NONAME);
        if (SUCCEEDED(r))
        {
            if (IsEqualGUID(&stat.clsid, &CLSID_MsiDatabase) ||
             IsEqualGUID(&stat.clsid, &CLSID_MsiPatch) ||
             IsEqualGUID(&stat.clsid, &CLSID_MsiTransform))
            {
                ret = TRUE;
                *subject = mySubject;
            }
        }
        IStorage_Release(stg);
    }
    return ret;
}
示例#3
0
文件: richole.c 项目: Eltechs/wine
void ME_DeleteReObject(REOBJECT* reo)
{
    if (reo->poleobj)   IOleObject_Release(reo->poleobj);
    if (reo->pstg)      IStorage_Release(reo->pstg);
    if (reo->polesite)  IOleClientSite_Release(reo->polesite);
    FREE_OBJ(reo);
}
示例#4
0
文件: main.c 项目: bilboed/wine
/***********************************************************************
 *              MsiSIPIsMyTypeOfFile (MSISIP.@)
 */
BOOL WINAPI MsiSIPIsMyTypeOfFile(WCHAR *name, GUID *subject)
{
    static const WCHAR msi[] = { '.','m','s','i',0 };
    static const WCHAR msp[] = { '.','m','s','p',0 };
    BOOL ret = FALSE;

    TRACE("(%s, %p)\n", debugstr_w(name), subject);

    if (lstrlenW(name) < lstrlenW(msi))
        return FALSE;
    else if (lstrcmpiW(name + lstrlenW(name) - lstrlenW(msi), msi) &&
     lstrcmpiW(name + lstrlenW(name) - lstrlenW(msp), msp))
        return FALSE;
    else
    {
        IStorage *stg = NULL;
        HRESULT r = StgOpenStorage(name, NULL,
         STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);

        if (SUCCEEDED(r))
        {
            IStorage_Release(stg);
            *subject = mySubject;
            ret = TRUE;
        }
    }
    return ret;
}
示例#5
0
文件: patch.c 项目: pstrealer/wine
static void create_patch( const char *filename )
{
    IStorage *stg = NULL, *stg1 = NULL, *stg2 = NULL;
    WCHAR *filenameW;
    HRESULT r;
    int len;
    const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;

    const CLSID CLSID_MsiPatch = {0xc1086, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
    const CLSID CLSID_MsiTransform = {0xc1082, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};

    len = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
    filenameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
    MultiByteToWideChar( CP_ACP, 0, filename, -1, filenameW, len );

    r = StgCreateDocfile( filenameW, mode, 0, &stg );
    HeapFree( GetProcessHeap(), 0, filenameW );
    ok( r == S_OK, "failed to create storage 0x%08x\n", r );
    if (!stg)
        return;

    r = IStorage_SetClass( stg, &CLSID_MsiPatch );
    ok( r == S_OK, "failed to set storage type 0x%08x\n", r );

    write_tables( stg, table_patch_data, NUM_PATCH_TABLES );

    r = IStorage_CreateStorage( stg, p_name7, mode, 0, 0, &stg1 );
    ok( r == S_OK, "failed to create substorage 0x%08x\n", r );

    r = IStorage_SetClass( stg1, &CLSID_MsiTransform );
    ok( r == S_OK, "failed to set storage type 0x%08x\n", r );

    write_tables( stg1, table_transform1_data, NUM_TRANSFORM1_TABLES );
    IStorage_Release( stg1 );

    r = IStorage_CreateStorage( stg, p_name8, mode, 0, 0, &stg2 );
    ok( r == S_OK, "failed to create substorage 0x%08x\n", r );

    r = IStorage_SetClass( stg2, &CLSID_MsiTransform );
    ok( r == S_OK, "failed to set storage type 0x%08x\n", r );

    write_tables( stg2, table_transform2_data, NUM_TRANSFORM2_TABLES );
    IStorage_Release( stg2 );
    IStorage_Release( stg );
}
示例#6
0
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
{
    MSIDATABASE *db = (MSIDATABASE *) arg;
    DWORD r;

    free_cached_tables( db );
    msi_free_transforms( db );
    msi_destroy_stringtable( db->strings );
    r = IStorage_Release( db->storage );
    if( r )
        ERR("database reference count was not zero (%ld)\n", r);
}
示例#7
0
文件: storage.c 项目: GYGit/reactos
static ULONG WINAPI ITSS_IStream_Release(
    IStream* iface)
{
    IStream_Impl *This = impl_from_IStream(iface);

    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
    {
        IStorage_Release( &This->stg->IStorage_iface );
        HeapFree(GetProcessHeap(), 0, This);
        ITSS_UnlockModule();
    }

    return ref;
}
示例#8
0
/* Open a CHM storage object (folder) by name and find all items with
 * the requested text.  The last found item is returned.
 */
static SearchItem *SearchCHM_Folder(SearchItem *item, IStorage *pStorage,
                                    const WCHAR *folder, const char *needle)
{
    IStorage *temp_storage = NULL;
    HRESULT hres;

    hres = IStorage_OpenStorage(pStorage, folder, NULL, STGM_READ, NULL, 0, &temp_storage);
    if(FAILED(hres))
    {
        FIXME("Could not open '%s' storage object: %08x\n", debugstr_w(folder), hres);
        return NULL;
    }
    item = SearchCHM_Storage(item, temp_storage, needle);

    IStorage_Release(temp_storage);
    return item;
}
示例#9
0
static void test_olestream(void)
{
    HRESULT hr;
    const CLSID non_existent_class = {0xa5f1772f, 0x3772, 0x490f, {0x9e, 0xc6, 0x77, 0x13, 0xe8, 0xb3, 0x4b, 0x5d}};
    IOleObject *ole_obj;
    IPersistStorage *persist;
    IStorage *stg;
    IStream *stm;
    static const WCHAR olestream[] = {1,'O','l','e',0};
    ULONG read;
    ole_stream_header_t header;

    hr = create_storage(&stg);
    ok(hr == S_OK, "got %08x\n", hr);

    hr = IStorage_OpenStream(stg, olestream, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stm);
    ok(hr == STG_E_FILENOTFOUND, "got %08x\n", hr);

    hr = OleCreateDefaultHandler(&non_existent_class, 0, &IID_IOleObject, (void**)&ole_obj);
    ok(hr == S_OK, "got %08x\n", hr);

    hr = IOleObject_QueryInterface(ole_obj, &IID_IPersistStorage, (void**)&persist);
    ok(hr == S_OK, "got %08x\n", hr);

    hr = IPersistStorage_InitNew(persist, stg);
    ok(hr == S_OK, "got %08x\n", hr);

    hr = IStorage_OpenStream(stg, olestream, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stm);
    ok(hr == S_OK, "got %08x\n", hr);
    hr = IStream_Read(stm, &header, sizeof(header), &read);
    ok(hr == S_OK, "got %08x\n", hr);
    ok(read == sizeof(header), "read %d\n", read);
    ok(header.version == 0x02000001, "got version %08x\n", header.version);
    ok(header.flags == 0x0, "got flags %08x\n", header.flags);
    ok(header.link_update_opt == 0x0, "got link update option %08x\n", header.link_update_opt);
    ok(header.res == 0x0, "got reserved %08x\n", header.res);
    ok(header.moniker_size == 0x0, "got moniker size %08x\n", header.moniker_size);

    IStream_Release(stm);

    IPersistStorage_Release(persist);
    IOleObject_Release(ole_obj);

    IStorage_Release(stg);
}
示例#10
0
static void DataCache_Destroy(
  DataCache* ptrToDestroy)
{
  TRACE("()\n");

  if (ptrToDestroy->sinkInterface != NULL)
  {
    IAdviseSink_Release(ptrToDestroy->sinkInterface);
    ptrToDestroy->sinkInterface = NULL;
  }

  if (ptrToDestroy->presentationStorage != NULL)
  {
    IStorage_Release(ptrToDestroy->presentationStorage);
    ptrToDestroy->presentationStorage = NULL;
  }

  /*
   * Free the datacache pointer.
   */
  HeapFree(GetProcessHeap(), 0, ptrToDestroy);
}
示例#11
0
文件: stg_prop.c 项目: AlexSteel/wine
/* FIXME: this creates an ANSI storage, try to find conditions under which
 * Unicode translation fails
 */
static void testProps(void)
{
    static const WCHAR szDot[] = { '.',0 };
    static const WCHAR szPrefix[] = { 's','t','g',0 };
    static WCHAR propName[] = { 'p','r','o','p',0 };
    static char val[] = "l33t auth0r";
    WCHAR filename[MAX_PATH];
    HRESULT hr;
    IStorage *storage = NULL;
    IPropertySetStorage *propSetStorage = NULL;
    IPropertyStorage *propertyStorage = NULL;
    PROPSPEC spec;
    PROPVARIANT var;
    CLIPDATA clipdata;
    unsigned char clipcontent[] = "foobar";
    GUID anyOldGuid = { 0x12345678,0xdead,0xbeef, {
     0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 } };

    if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
        return;

    DeleteFileW(filename);

    hr = StgCreateDocfile(filename,
     STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &storage);
    ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);

    if(!pStgCreatePropSetStg)
    {
        IStorage_Release(storage);
        DeleteFileW(filename);
        return;
    }
    hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
    ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);

    hr = IPropertySetStorage_Create(propSetStorage,
     &FMTID_SummaryInformation, NULL, PROPSETFLAG_ANSI,
     STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
     &propertyStorage);
    ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);

    hr = IPropertyStorage_WriteMultiple(propertyStorage, 0, NULL, NULL, 0);
    ok(hr == S_OK, "WriteMultiple with 0 args failed: 0x%08x\n", hr);
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, NULL, NULL, 0);
    ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);

    /* test setting one that I can't set */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_DICTIONARY;
    var.vt = VT_I4;
    U(var).lVal = 1;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == STG_E_INVALIDPARAMETER,
     "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);

    /* test setting one by name with an invalid propidNameFirst */
    spec.ulKind = PRSPEC_LPWSTR;
    U(spec).lpwstr = propName;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var,
     PID_DICTIONARY);
    ok(hr == STG_E_INVALIDPARAMETER,
     "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);

    /* test setting behavior (case-sensitive) */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_BEHAVIOR;
    U(var).lVal = 1;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == STG_E_INVALIDPARAMETER,
     "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);

    /* set one by value.. */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_FIRST_USABLE;
    U(var).lVal = 1;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);

    /* set one by name */
    spec.ulKind = PRSPEC_LPWSTR;
    U(spec).lpwstr = propName;
    U(var).lVal = 2;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var,
     PID_FIRST_USABLE);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);

    /* set a string value */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PIDSI_AUTHOR;
    var.vt = VT_LPSTR;
    U(var).pszVal = val;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);

    /* set a clipboard value */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PIDSI_THUMBNAIL;
    var.vt = VT_CF;
    clipdata.cbSize = sizeof clipcontent + sizeof (ULONG);
    clipdata.ulClipFmt = CF_ENHMETAFILE;
    clipdata.pClipData = clipcontent;
    U(var).pclipdata = &clipdata;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);


    /* check reading */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 0, NULL, NULL);
    ok(hr == S_FALSE, "ReadMultiple with 0 args failed: 0x%08x\n", hr);
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, NULL, NULL);
    ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
    /* read by propid */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_FIRST_USABLE;
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_I4 && U(var).lVal == 1,
     "Didn't get expected type or value for property (got type %d, value %d)\n",
     var.vt, U(var).lVal);
    /* read by name */
    spec.ulKind = PRSPEC_LPWSTR;
    U(spec).lpwstr = propName;
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_I4 && U(var).lVal == 2,
     "Didn't get expected type or value for property (got type %d, value %d)\n",
     var.vt, U(var).lVal);
    /* read string value */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PIDSI_AUTHOR;
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_LPSTR && !lstrcmpA(U(var).pszVal, val),
     "Didn't get expected type or value for property (got type %d, value %s)\n",
     var.vt, U(var).pszVal);
    PropVariantClear(&var);

    /* read clipboard format */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PIDSI_THUMBNAIL;
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_CF, "variant type wrong\n");
    ok(U(var).pclipdata->ulClipFmt == CF_ENHMETAFILE,
        "clipboard type wrong\n");
    ok(U(var).pclipdata->cbSize == sizeof clipcontent + sizeof (ULONG),
        "clipboard size wrong\n");
    ok(!memcmp(U(var).pclipdata->pClipData, clipcontent, sizeof clipcontent),
        "clipboard contents wrong\n");
    ok(S_OK == PropVariantClear(&var), "failed to clear variant\n");

    /* check deleting */
    hr = IPropertyStorage_DeleteMultiple(propertyStorage, 0, NULL);
    ok(hr == S_OK, "DeleteMultiple with 0 args failed: 0x%08x\n", hr);
    hr = IPropertyStorage_DeleteMultiple(propertyStorage, 1, NULL);
    ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
    /* contrary to what the docs say, you can't delete the dictionary */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_DICTIONARY;
    hr = IPropertyStorage_DeleteMultiple(propertyStorage, 1, &spec);
    ok(hr == STG_E_INVALIDPARAMETER,
     "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);
    /* now delete the first value.. */
    U(spec).propid = PID_FIRST_USABLE;
    hr = IPropertyStorage_DeleteMultiple(propertyStorage, 1, &spec);
    ok(hr == S_OK, "DeleteMultiple failed: 0x%08x\n", hr);
    /* and check that it's no longer readable */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_FALSE, "Expected S_FALSE, got 0x%08x\n", hr);

    hr = IPropertyStorage_Commit(propertyStorage, STGC_DEFAULT);
    ok(hr == S_OK, "Commit failed: 0x%08x\n", hr);

    /* check reverting */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_FIRST_USABLE;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    hr = IPropertyStorage_Revert(propertyStorage);
    ok(hr == S_OK, "Revert failed: 0x%08x\n", hr);
    /* now check that it's still not there */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_FALSE, "Expected S_FALSE, got 0x%08x\n", hr);
    /* set an integer value again */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_FIRST_USABLE;
    var.vt = VT_I4;
    U(var).lVal = 1;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    /* commit it */
    hr = IPropertyStorage_Commit(propertyStorage, STGC_DEFAULT);
    ok(hr == S_OK, "Commit failed: 0x%08x\n", hr);
    /* set it to a string value */
    var.vt = VT_LPSTR;
    U(var).pszVal = val;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    /* revert it */
    hr = IPropertyStorage_Revert(propertyStorage);
    ok(hr == S_OK, "Revert failed: 0x%08x\n", hr);
    /* Oddly enough, there's no guarantee that a successful revert actually
     * implies the value wasn't saved.  Maybe transactional mode needs to be
     * used for that?
     */

    IPropertyStorage_Release(propertyStorage);
    propertyStorage = NULL;
    IPropertySetStorage_Release(propSetStorage);
    propSetStorage = NULL;
    IStorage_Release(storage);
    storage = NULL;

    /* now open it again */
    hr = StgOpenStorage(filename, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
     NULL, 0, &storage);
    ok(hr == S_OK, "StgOpenStorage failed: 0x%08x\n", hr);

    hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
    ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);

    hr = IPropertySetStorage_Open(propSetStorage, &FMTID_SummaryInformation,
     STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage);
    ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr);

    /* check properties again */
    spec.ulKind = PRSPEC_LPWSTR;
    U(spec).lpwstr = propName;
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_I4 && U(var).lVal == 2,
     "Didn't get expected type or value for property (got type %d, value %d)\n",
     var.vt, U(var).lVal);
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PIDSI_AUTHOR;
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_LPSTR && !lstrcmpA(U(var).pszVal, val),
     "Didn't get expected type or value for property (got type %d, value %s)\n",
     var.vt, U(var).pszVal);
    PropVariantClear(&var);

    IPropertyStorage_Release(propertyStorage);
    IPropertySetStorage_Release(propSetStorage);
    IStorage_Release(storage);

    DeleteFileW(filename);

    /* Test creating a property set storage with a random GUID */
    hr = StgCreateDocfile(filename,
     STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &storage);
    ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);

    if(!pStgCreatePropSetStg)
    {
        IStorage_Release(storage);
        DeleteFileW(filename);
        return;
    }
    hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
    ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);

    hr = IPropertySetStorage_Create(propSetStorage,
     &anyOldGuid, NULL, PROPSETFLAG_ANSI,
     STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
     &propertyStorage);
    ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);

    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_FIRST_USABLE;
    var.vt = VT_I4;
    U(var).lVal = 1;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);

    hr = IPropertyStorage_Commit(propertyStorage, STGC_DEFAULT);
    ok(hr == S_OK, "Commit failed: 0x%08x\n", hr);

    IPropertyStorage_Release(propertyStorage);
    IPropertySetStorage_Release(propSetStorage);
    IStorage_Release(storage);
    propertyStorage = NULL;

    /* now open it again */
    hr = StgOpenStorage(filename, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
     NULL, 0, &storage);
    ok(hr == S_OK, "StgOpenStorage failed: 0x%08x\n", hr);

    hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
    ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);

    hr = IPropertySetStorage_Open(propSetStorage, &anyOldGuid,
     STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage);
    ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr);

    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_FIRST_USABLE;
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);

    ok(var.vt == VT_I4 && U(var).lVal == 1,
     "Didn't get expected type or value for property (got type %d, value %d)\n",
     var.vt, U(var).lVal);

    IPropertyStorage_Release(propertyStorage);
    IPropertySetStorage_Release(propSetStorage);
    IStorage_Release(storage);

    DeleteFileW(filename);
}
示例#12
0
文件: stg_prop.c 项目: AlexSteel/wine
static void testCodepage(void)
{
    static const WCHAR szDot[] = { '.',0 };
    static const WCHAR szPrefix[] = { 's','t','g',0 };
    static CHAR aval[] = "hi";
    static WCHAR wval[] = { 'h','i',0 };
    HRESULT hr;
    IStorage *storage = NULL;
    IPropertySetStorage *propSetStorage = NULL;
    IPropertyStorage *propertyStorage = NULL;
    PROPSPEC spec;
    PROPVARIANT var;
    WCHAR fileName[MAX_PATH];

    if(!GetTempFileNameW(szDot, szPrefix, 0, fileName))
        return;

    hr = StgCreateDocfile(fileName,
     STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &storage);
    ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);

    if(!pStgCreatePropSetStg)
    {
        IStorage_Release(storage);
        DeleteFileW(fileName);
        return;
    }
    hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
    ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);

    hr = IPropertySetStorage_Create(propSetStorage,
     &FMTID_SummaryInformation, NULL, PROPSETFLAG_DEFAULT,
     STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
     &propertyStorage);
    ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);

    PropVariantInit(&var);
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_CODEPAGE;
    /* check code page before it's been explicitly set */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_I2 && U(var).iVal == 1200,
     "Didn't get expected type or value for property\n");
    /* Set the code page to ascii */
    var.vt = VT_I2;
    U(var).iVal = 1252;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    /* check code page */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_I2 && U(var).iVal == 1252,
     "Didn't get expected type or value for property\n");
    /* Set code page to Unicode */
    U(var).iVal = 1200;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    /* check code page */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_I2 && U(var).iVal == 1200,
     "Didn't get expected type or value for property\n");
    /* Set a string value */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_FIRST_USABLE;
    var.vt = VT_LPSTR;
    U(var).pszVal = aval;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, "hi"),
     "Didn't get expected type or value for property\n");
    PropVariantClear(&var);
    /* This seemingly non-sensical test is to show that the string is indeed
     * interpreted according to the current system code page, not according to
     * the property set's code page.  (If the latter were true, the whole
     * string would be maintained.  As it is, only the first character is.)
     */
    var.vt = VT_LPSTR;
    U(var).pszVal = (LPSTR)wval;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, "h"),
     "Didn't get expected type or value for property\n");
    PropVariantClear(&var);

    /* now that a property's been set, you can't change the code page */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_CODEPAGE;
    var.vt = VT_I2;
    U(var).iVal = 1200;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == STG_E_INVALIDPARAMETER,
     "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);

    IPropertyStorage_Release(propertyStorage);
    IPropertySetStorage_Release(propSetStorage);
    IStorage_Release(storage);

    DeleteFileW(fileName);

    /* same tests, but with PROPSETFLAG_ANSI */
    hr = StgCreateDocfile(fileName,
     STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &storage);
    ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);

    hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
    ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);

    hr = IPropertySetStorage_Create(propSetStorage,
     &FMTID_SummaryInformation, NULL, PROPSETFLAG_ANSI,
     STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
     &propertyStorage);
    ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);

    /* check code page before it's been explicitly set */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_I2, "Didn't get expected type for property (%u)\n", var.vt);
    /* Set code page to Unicode */
    U(var).iVal = 1200;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    /* check code page */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_I2 && U(var).iVal == 1200,
     "Didn't get expected type or value for property\n");
    /* This test is commented out for documentation.  It fails under Wine,
     * and I expect it would under Windows as well, yet it succeeds.  There's
     * obviously something about string conversion I don't understand.
     */
    if(0) {
    static unsigned char strVal[] = { 0x81, 0xff, 0x04, 0 };
    /* Set code page to 950 (Traditional Chinese) */
    U(var).iVal = 950;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    /* Try writing an invalid string: lead byte 0x81 is unused in Traditional
     * Chinese.
     */
    spec.ulKind = PRSPEC_PROPID;
    U(spec).propid = PID_FIRST_USABLE;
    var.vt = VT_LPSTR;
    U(var).pszVal = (LPSTR)strVal;
    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
    ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
    /* Check returned string */
    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
    ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
    ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, (LPCSTR)strVal),
     "Didn't get expected type or value for property\n");
    }

    IPropertyStorage_Release(propertyStorage);
    IPropertySetStorage_Release(propSetStorage);
    IStorage_Release(storage);

    DeleteFileW(fileName);
}
示例#13
0
文件: main.c 项目: RareHare/reactos
/***********************************************************************
 *              MsiSIPGetSignedDataMsg  (MSISIP.@)
 */
BOOL WINAPI MsiSIPGetSignedDataMsg(SIP_SUBJECTINFO *pSubjectInfo,
 DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg,
 BYTE *pbSignedDataMsg)
{
    static const WCHAR digitalSig[] = { 5,'D','i','g','i','t','a','l',
     'S','i','g','n','a','t','u','r','e',0 };
    BOOL ret = FALSE;
    IStorage *stg = NULL;
    HRESULT r;
    IStream *stm = NULL;
    BYTE hdr[2], len[sizeof(DWORD)];
    DWORD count, lenBytes, dataBytes;

    TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
          pcbSignedDataMsg, pbSignedDataMsg);

    r = StgOpenStorage(pSubjectInfo->pwsFileName, NULL,
     STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
    if (FAILED(r))
    {
        TRACE("couldn't open %s\n", debugstr_w(pSubjectInfo->pwsFileName));
        goto end;
    }

    r = IStorage_OpenStream(stg, digitalSig, 0,
     STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stm);
    if (FAILED(r))
    {
        TRACE("couldn't find digital signature stream\n");
        goto freestorage;
    }

    r = IStream_Read(stm, hdr, sizeof(hdr), &count);
    if (FAILED(r) || count != sizeof(hdr))
        goto freestream;
    if (hdr[0] != 0x30)
    {
        WARN("unexpected data in digital sig: 0x%02x%02x\n", hdr[0], hdr[1]);
        goto freestream;
    }

    /* Read the asn.1 length from the stream.  Only supports definite-length
     * values, which DER-encoded signatures should be.
     */
    if (hdr[1] == 0x80)
    {
        WARN("indefinite-length encoding not supported!\n");
        goto freestream;
    }
    else if (hdr[1] & 0x80)
    {
        DWORD temp;
        LPBYTE ptr;

        lenBytes = hdr[1] & 0x7f;
        if (lenBytes > sizeof(DWORD))
        {
            WARN("asn.1 length too long (%d)\n", lenBytes);
            goto freestream;
        }
        r = IStream_Read(stm, len, lenBytes, &count);
        if (FAILED(r) || count != lenBytes)
            goto freestream;
        dataBytes = 0;
        temp = lenBytes;
        ptr = len;
        while (temp--)
        {
            dataBytes <<= 8;
            dataBytes |= *ptr++;
        }
    }
    else
    {
        lenBytes = 0;
        dataBytes = hdr[1];
    }

    if (!pbSignedDataMsg)
    {
        *pcbSignedDataMsg = 2 + lenBytes + dataBytes;
        ret = TRUE;
    }
    else if (*pcbSignedDataMsg < 2 + lenBytes + dataBytes)
    {
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        *pcbSignedDataMsg = 2 + lenBytes + dataBytes;
    }
    else
    {
        LPBYTE ptr = pbSignedDataMsg;

        memcpy(ptr, hdr, sizeof(hdr));
        ptr += sizeof(hdr);
        if (lenBytes)
        {
            memcpy(ptr, len, lenBytes);
            ptr += lenBytes;
        }
        r = IStream_Read(stm, ptr, dataBytes, &count);
        if (SUCCEEDED(r) && count == dataBytes)
        {
            *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
            *pcbSignedDataMsg = 2 + lenBytes + dataBytes;
            ret = TRUE;
        }
    }

freestream:
    IStream_Release(stm);
freestorage:
    IStorage_Release(stg);
end:

    TRACE("returning %d\n", ret);
    return ret;
}
示例#14
0
static void test_create_database_binary(void)
{
    static const CLSID CLSID_MsiDatabase =
        { 0xc1084, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46 } };
    static const CLSID IID_IPropertySetStorage =
        { 0x13a, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46 } };
    static const CLSID FMTID_SummaryInformation =
        { 0xf29f85e0, 0x4ff9, 0x1068, {0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9}};
    DWORD mode = STGM_CREATE | STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE;
    static const WCHAR msifile[] = {
        'w','i','n','e','t','e','s','t','.','m','s','i',0 };
    IPropertySetStorage *pss = NULL;
    IPropertyStorage *ps = NULL;
    IStorage *stg = NULL;
    IStream *stm = NULL;
    HRESULT r;
    PROPSPEC propspec[10];
    PROPVARIANT propvar[10];
    USHORT data[2] = { 0, 0 };

    r = StgCreateDocfile( msifile, mode, 0, &stg );
    ok( r == S_OK, "failed to create database\n");

    r = IStorage_SetClass( stg, &CLSID_MsiDatabase );
    ok( r == S_OK, "failed to set clsid\n");

    /* create the _StringData stream */
    r = IStorage_CreateStream( stg, sd, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
    ok( r == S_OK, "failed to create stream\n");

    IStream_Release( stm );

    /* create the _StringPool stream */
    r = IStorage_CreateStream( stg, sp, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
    ok( r == S_OK, "failed to create stream\n");

    r = IStream_Write( stm, data, sizeof data, NULL );
    ok( r == S_OK, "failed to write stream\n");

    IStream_Release( stm );

    /* create the _Tables stream */
    r = IStorage_CreateStream( stg, tb, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
    ok( r == S_OK, "failed to create stream\n");

    IStream_Release( stm );

    r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (void**) &pss );
    ok( r == S_OK, "failed to set clsid\n");

    r = IPropertySetStorage_Create( pss, &FMTID_SummaryInformation, NULL, 0, mode, &ps );
    ok( r == S_OK, "failed to create property set\n");

    r = IPropertyStorage_SetClass( ps, &FMTID_SummaryInformation );
    ok( r == S_OK, "failed to set class\n");

    propspec[0].ulKind = PRSPEC_PROPID;
    U(propspec[0]).propid = PID_TITLE;
    propvar[0].vt = VT_LPSTR;
    U(propvar[0]).pszVal = LOSE_CONST("test title");

    propspec[1].ulKind = PRSPEC_PROPID;
    U(propspec[1]).propid = PID_SUBJECT;
    propvar[1].vt = VT_LPSTR;
    U(propvar[1]).pszVal = LOSE_CONST("msi suminfo / property storage test");

    propspec[2].ulKind = PRSPEC_PROPID;
    U(propspec[2]).propid = PID_AUTHOR;
    propvar[2].vt = VT_LPSTR;
    U(propvar[2]).pszVal = LOSE_CONST("mike_m");

    propspec[3].ulKind = PRSPEC_PROPID;
    U(propspec[3]).propid = PID_TEMPLATE;
    propvar[3].vt = VT_LPSTR;
    U(propvar[3]).pszVal = LOSE_CONST(";1033");  /* actually the string table's codepage */

    propspec[4].ulKind = PRSPEC_PROPID;
    U(propspec[4]).propid = PID_REVNUMBER;
    propvar[4].vt = VT_LPSTR;
    U(propvar[4]).pszVal = LOSE_CONST("{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");

    propspec[5].ulKind = PRSPEC_PROPID;
    U(propspec[5]).propid = PID_PAGECOUNT;
    propvar[5].vt = VT_I4;
    U(propvar[5]).lVal = 100;

    propspec[6].ulKind = PRSPEC_PROPID;
    U(propspec[6]).propid = PID_WORDCOUNT;
    propvar[6].vt = VT_I4;
    U(propvar[6]).lVal = 0;

    /* MSDN says that PID_LASTPRINTED should be a VT_FILETIME... */
    propspec[7].ulKind = PRSPEC_PROPID;
    U(propspec[7]).propid = PID_LASTPRINTED;
    propvar[7].vt = VT_LPSTR;
    U(propvar[7]).pszVal = LOSE_CONST("7/1/1999 5:17");

    r = IPropertyStorage_WriteMultiple( ps, 8, propspec, propvar, PID_FIRST_USABLE );
    ok( r == S_OK, "failed to write properties\n");

    IPropertyStorage_Commit( ps, STGC_DEFAULT );

    IPropertyStorage_Release( ps );
    IPropertySetStorage_Release( pss );

    IStorage_Commit( stg, STGC_DEFAULT );
    IStorage_Release( stg );
}
示例#15
0
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
{
    IStorage *stg = NULL;
    HRESULT r;
    MSIDATABASE *db = NULL;
    UINT ret = ERROR_FUNCTION_FAILED;
    LPCWSTR szMode;
    STATSTG stat;

    TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );

    if( !pdb )
        return ERROR_INVALID_PARAMETER;

    szMode = szPersist;
    if( HIWORD( szPersist ) )
    {
        /* UINT len = lstrlenW( szPerist ) + 1; */
        FIXME("don't support persist files yet\b");
        return ERROR_INVALID_PARAMETER;
        /* szMode = msi_alloc( len * sizeof (DWORD) ); */
    }
    else if( szPersist == MSIDBOPEN_READONLY )
    {
        r = StgOpenStorage( szDBPath, NULL,
              STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
    }
    else if( szPersist == MSIDBOPEN_CREATE || szPersist == MSIDBOPEN_CREATEDIRECT )
    {
        /* FIXME: MSIDBOPEN_CREATE should case STGM_TRANSACTED flag to be
         * used here: */
        r = StgCreateDocfile( szDBPath, 
              STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
        if( r == ERROR_SUCCESS )
        {
            IStorage_SetClass( stg, &CLSID_MsiDatabase );
            r = init_string_table( stg );
        }
    }
    else if( szPersist == MSIDBOPEN_TRANSACT )
    {
        /* FIXME: MSIDBOPEN_TRANSACT should case STGM_TRANSACTED flag to be
         * used here: */
        r = StgOpenStorage( szDBPath, NULL,
              STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
    }
    else if( szPersist == MSIDBOPEN_DIRECT )
    {
        r = StgOpenStorage( szDBPath, NULL,
              STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
    }
    else
    {
        ERR("unknown flag %p\n",szPersist);
        return ERROR_INVALID_PARAMETER;
    }

    if( FAILED( r ) )
    {
        FIXME("open failed r = %08lx!\n",r);
        return ERROR_FUNCTION_FAILED;
    }

    r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
    if( FAILED( r ) )
    {
        FIXME("Failed to stat storage\n");
        goto end;
    }

    if ( !IsEqualGUID( &stat.clsid, &CLSID_MsiDatabase ) &&
         !IsEqualGUID( &stat.clsid, &CLSID_MsiPatch ) ) 
    {
        ERR("storage GUID is not a MSI database GUID %s\n",
             debugstr_guid(&stat.clsid) );
        goto end;
    }

    db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
                              MSI_CloseDatabase );
    if( !db )
    {
        FIXME("Failed to allocate a handle\n");
        goto end;
    }

    if( TRACE_ON( msi ) )
        enum_stream_names( stg );

    db->storage = stg;
    db->mode = szMode;
    list_init( &db->tables );
    list_init( &db->transforms );

    db->strings = load_string_table( stg );
    if( !db->strings )
        goto end;

    ret = ERROR_SUCCESS;

    msiobj_addref( &db->hdr );
    IStorage_AddRef( stg );
    *pdb = db;

end:
    if( db )
        msiobj_release( &db->hdr );
    if( stg )
        IStorage_Release( stg );

    return ret;
}
示例#16
0
文件: chm.c 项目: howard5888/wineT
void CHM_CloseCHM(CHMInfo *pCHMInfo)
{
    IITStorage_Release(pCHMInfo->pITStorage);
    IStorage_Release(pCHMInfo->pStorage);
}