⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stg_prop.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (FAILED(hr))
        goto end;

    seek.QuadPart = SECTIONHEADER_OFFSET + *sectionOffset;
    hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
    if (FAILED(hr))
        goto end;
    StorageUtl_WriteDWord((LPBYTE)&dwType, 0, var->vt);
    hr = IStream_Write(This->stm, &dwType, sizeof(dwType), &count);
    if (FAILED(hr))
        goto end;
    *sectionOffset += sizeof(dwType);

    switch (var->vt)
    {
    case VT_EMPTY:
    case VT_NULL:
        bytesWritten = 0;
        break;
    case VT_I1:
    case VT_UI1:
        hr = IStream_Write(This->stm, &var->u.cVal, sizeof(var->u.cVal),
         &count);
        bytesWritten = count;
        break;
    case VT_I2:
    case VT_UI2:
    {
        WORD wTemp;

        StorageUtl_WriteWord((LPBYTE)&wTemp, 0, var->u.iVal);
        hr = IStream_Write(This->stm, &wTemp, sizeof(wTemp), &count);
        bytesWritten = count;
        break;
    }
    case VT_I4:
    case VT_UI4:
    {
        DWORD dwTemp;

        StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, var->u.lVal);
        hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
        bytesWritten = count;
        break;
    }
    case VT_LPSTR:
    {
        DWORD len, dwTemp;

        if (This->codePage == CP_UNICODE)
            len = (lstrlenW(var->u.pwszVal) + 1) * sizeof(WCHAR);
        else
            len = lstrlenA(var->u.pszVal) + 1;
        StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, len);
        hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
        if (FAILED(hr))
            goto end;
        hr = IStream_Write(This->stm, var->u.pszVal, len, &count);
        bytesWritten = count + sizeof(DWORD);
        break;
    }
    case VT_LPWSTR:
    {
        DWORD len = lstrlenW(var->u.pwszVal) + 1, dwTemp;

        StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, len);
        hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
        if (FAILED(hr))
            goto end;
        hr = IStream_Write(This->stm, var->u.pwszVal, len * sizeof(WCHAR),
         &count);
        bytesWritten = count + sizeof(DWORD);
        break;
    }
    case VT_FILETIME:
    {
        FILETIME temp;

        StorageUtl_WriteULargeInteger((BYTE *)&temp, 0,
         (const ULARGE_INTEGER *)&var->u.filetime);
        hr = IStream_Write(This->stm, &temp, sizeof(FILETIME), &count);
        bytesWritten = count;
        break;
    }
    case VT_CF:
    {
        DWORD cf_hdr[2], len;

        len = var->u.pclipdata->cbSize;
        StorageUtl_WriteDWord((LPBYTE)&cf_hdr[0], 0, len + 8);
        StorageUtl_WriteDWord((LPBYTE)&cf_hdr[1], 0, var->u.pclipdata->ulClipFmt);
        hr = IStream_Write(This->stm, &cf_hdr, sizeof(cf_hdr), &count);
        if (FAILED(hr))
            goto end;
        hr = IStream_Write(This->stm, &var->u.pclipdata->pClipData, len, &count);
        if (FAILED(hr))
            goto end;
        bytesWritten = count + sizeof cf_hdr;
        break;
    }
    default:
        FIXME("unsupported type: %d\n", var->vt);
        return STG_E_INVALIDPARAMETER;
    }

    if (SUCCEEDED(hr))
    {
        *sectionOffset += bytesWritten;
        if (bytesWritten % sizeof(DWORD))
        {
            DWORD padding = sizeof(DWORD) - bytesWritten % sizeof(DWORD);
            TRACE("adding %d bytes of padding\n", padding);
            *sectionOffset += padding;
        }
    }

end:
    return hr;
}

struct PropertyClosure
{
    HRESULT hr;
    DWORD   propNum;
    DWORD  *sectionOffset;
};

static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value,
 void *extra, void *closure)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)extra;
    struct PropertyClosure *c = (struct PropertyClosure *)closure;

    assert(key);
    assert(value);
    assert(extra);
    assert(closure);
    c->hr = PropertyStorage_WritePropertyToStream(This, c->propNum++,
     (DWORD)key, value, c->sectionOffset);
    return SUCCEEDED(c->hr);
}

static HRESULT PropertyStorage_WritePropertiesToStream(
 PropertyStorage_impl *This, DWORD startingPropNum, DWORD *sectionOffset)
{
    struct PropertyClosure closure;

    assert(sectionOffset);
    closure.hr = S_OK;
    closure.propNum = startingPropNum;
    closure.sectionOffset = sectionOffset;
    dictionary_enumerate(This->propid_to_prop, PropertyStorage_PropertiesWriter,
     &closure);
    return closure.hr;
}

static HRESULT PropertyStorage_WriteHeadersToStream(PropertyStorage_impl *This)
{
    HRESULT hr;
    ULONG count = 0;
    LARGE_INTEGER seek = { {0} };
    PROPERTYSETHEADER hdr;
    FORMATIDOFFSET fmtOffset;

    hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
    if (FAILED(hr))
        goto end;
    PropertyStorage_MakeHeader(This, &hdr);
    hr = IStream_Write(This->stm, &hdr, sizeof(hdr), &count);
    if (FAILED(hr))
        goto end;
    if (count != sizeof(hdr))
    {
        hr = STG_E_WRITEFAULT;
        goto end;
    }

    PropertyStorage_MakeFmtIdOffset(This, &fmtOffset);
    hr = IStream_Write(This->stm, &fmtOffset, sizeof(fmtOffset), &count);
    if (FAILED(hr))
        goto end;
    if (count != sizeof(fmtOffset))
    {
        hr = STG_E_WRITEFAULT;
        goto end;
    }
    hr = S_OK;

end:
    return hr;
}

static HRESULT PropertyStorage_WriteToStream(PropertyStorage_impl *This)
{
    PROPERTYSECTIONHEADER sectionHdr;
    HRESULT hr;
    ULONG count;
    LARGE_INTEGER seek;
    DWORD numProps, prop, sectionOffset, dwTemp;
    PROPVARIANT var;

    PropertyStorage_WriteHeadersToStream(This);

    /* Count properties.  Always at least one property, the code page */
    numProps = 1;
    if (dictionary_num_entries(This->name_to_propid))
        numProps++;
    if (This->locale != LOCALE_SYSTEM_DEFAULT)
        numProps++;
    if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
        numProps++;
    numProps += dictionary_num_entries(This->propid_to_prop);

    /* Write section header with 0 bytes right now, I'll adjust it after
     * writing properties.
     */
    PropertyStorage_MakeSectionHdr(0, numProps, &sectionHdr);
    seek.QuadPart = SECTIONHEADER_OFFSET;
    hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
    if (FAILED(hr))
        goto end;
    hr = IStream_Write(This->stm, &sectionHdr, sizeof(sectionHdr), &count);
    if (FAILED(hr))
        goto end;

    prop = 0;
    sectionOffset = sizeof(PROPERTYSECTIONHEADER) +
     numProps * sizeof(PROPERTYIDOFFSET);

    if (dictionary_num_entries(This->name_to_propid))
    {
        prop++;
        hr = PropertyStorage_WriteDictionaryToStream(This, &sectionOffset);
        if (FAILED(hr))
            goto end;
    }

    PropVariantInit(&var);

    var.vt = VT_I2;
    var.u.iVal = This->codePage;
    hr = PropertyStorage_WritePropertyToStream(This, prop++, PID_CODEPAGE,
     &var, &sectionOffset);
    if (FAILED(hr))
        goto end;

    if (This->locale != LOCALE_SYSTEM_DEFAULT)
    {
        var.vt = VT_I4;
        var.u.lVal = This->locale;
        hr = PropertyStorage_WritePropertyToStream(This, prop++, PID_LOCALE,
         &var, &sectionOffset);
        if (FAILED(hr))
            goto end;
    }

    if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
    {
        var.vt = VT_I4;
        var.u.lVal = 1;
        hr = PropertyStorage_WritePropertyToStream(This, prop++, PID_BEHAVIOR,
         &var, &sectionOffset);
        if (FAILED(hr))
            goto end;
    }

    hr = PropertyStorage_WritePropertiesToStream(This, prop, &sectionOffset);
    if (FAILED(hr))
        goto end;

    /* Now write the byte count of the section */
    seek.QuadPart = SECTIONHEADER_OFFSET;
    hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
    if (FAILED(hr))
        goto end;
    StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, sectionOffset);
    hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);

end:
    return hr;
}

/***********************************************************************
 * PropertyStorage_Construct
 */
static void PropertyStorage_DestroyDictionaries(PropertyStorage_impl *This)
{
    dictionary_destroy(This->name_to_propid);
    This->name_to_propid = NULL;
    dictionary_destroy(This->propid_to_name);
    This->propid_to_name = NULL;
    dictionary_destroy(This->propid_to_prop);
    This->propid_to_prop = NULL;
}

static HRESULT PropertyStorage_CreateDictionaries(PropertyStorage_impl *This)
{
    HRESULT hr = S_OK;

    This->name_to_propid = dictionary_create(
     PropertyStorage_PropNameCompare, PropertyStorage_PropNameDestroy,
     This);
    if (!This->name_to_propid)
    {
        hr = STG_E_INSUFFICIENTMEMORY;
        goto end;
    }
    This->propid_to_name = dictionary_create(PropertyStorage_PropCompare,
     NULL, This);
    if (!This->propid_to_name)
    {
        hr = STG_E_INSUFFICIENTMEMORY;
        goto end;
    }
    This->propid_to_prop = dictionary_create(PropertyStorage_PropCompare,
     PropertyStorage_PropertyDestroy, This);
    if (!This->propid_to_prop)
    {
        hr = STG_E_INSUFFICIENTMEMORY;
        goto end;
    }
end:
    if (FAILED(hr))
        PropertyStorage_DestroyDictionaries(This);
    return hr;
}

static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
 REFFMTID rfmtid, DWORD grfMode, PropertyStorage_impl **pps)
{
    HRESULT hr = S_OK;

    assert(pps);
    assert(rfmtid);
    *pps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof **pps);
    if (!*pps)
        return E_OUTOFMEMORY;

    (*pps)->vtbl = &IPropertyStorage_Vtbl;
    (*pps)->ref = 1;
    InitializeCriticalSection(&(*pps)->cs);
    (*pps)->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStorage_impl.cs");
    (*pps)->stm = stm;
    memcpy(&(*pps)->fmtid, rfmtid, sizeof((*pps)->fmtid));
    (*pps)->grfMode = grfMode;

    hr = PropertyStorage_CreateDictionaries(*pps);
    if (FAILED(hr))
    {
        IStream_Release(stm);
        (*pps)->cs.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&(*pps)->cs);
        HeapFree(GetProcessHeap(), 0, *pps);
        *pps = NULL;
    }

    return hr;
}

static HRESULT PropertyStorage_ConstructFromStream(IStream *stm,
 REFFMTID rfmtid, DWORD grfMode, IPropertyStorage** pps)
{
    PropertyStorage_impl *ps;
    HRESULT hr;

    assert(pps);
    hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
    if (SUCCEEDED(hr))
    {
        hr = PropertyStorage_ReadFromStream(ps);
        if (SUCCEEDED(hr))
        {
            *pps = (IPropertyStorage *)ps;
            TRACE("PropertyStorage %p constructed\n", ps);
            hr = S_OK;
        }
        else
        {
            PropertyStorage_DestroyDictionaries(ps);
            HeapFree(GetProcessHeap(), 0, ps);
        }
    }
    return hr;
}

static HRESULT PropertyStorage_ConstructEmpty(IStream *stm,
 REFFMTID rfmtid, DWORD grfFlags, DWORD grfMode, IPropertyStorage** pps)
{
    PropertyStorage_impl *ps;
    HRESULT hr;

    assert(pps);
    hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
    if (SUCCEEDED(hr))
    {
        ps->format = 0;
        ps->grfFlags = grfFlags;
        if (ps->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
            ps->format = 1;
        /* default to Unicode unless told not to, as specified here:
         * http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
         */
        if (ps->grfFlags & PROPSETFLAG_ANSI)
            ps->codePage = GetACP();
        else
            ps->codePage = CP_UNICODE;
        ps->locale = LOCALE_SYSTEM_DEFAULT;
   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -