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

📄 stg_prop.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
                else
                    hr = STG_E_INSUFFICIENTMEMORY;
            }
            if (SUCCEEDED(hr))
            {
                len = WideCharToMultiByte(dstCP, 0, wideStr, -1, NULL, 0,
                 NULL, NULL);
                *dst = CoTaskMemAlloc(len);
                if (!*dst)
                    hr = STG_E_INSUFFICIENTMEMORY;
                else
                {
                    BOOL defCharUsed = FALSE;

                    if (WideCharToMultiByte(dstCP, 0, wideStr, -1, *dst, len,
                     NULL, &defCharUsed) == 0 || defCharUsed)
                    {
                        CoTaskMemFree(*dst);
                        *dst = NULL;
                        hr = HRESULT_FROM_WIN32(ERROR_NO_UNICODE_TRANSLATION);
                    }
                }
            }
            HeapFree(GetProcessHeap(), 0, wideStr_tmp);
        }
    }
    TRACE("returning 0x%08x (%s)\n", hr,
     dstCP == CP_UNICODE ? debugstr_w((LPCWSTR)*dst) : debugstr_a(*dst));
    return hr;
}

static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop,
 const PROPVARIANT *propvar, LCID targetCP, LCID srcCP)
{
    HRESULT hr = S_OK;

    assert(prop);
    assert(propvar);
    if (propvar->vt == VT_LPSTR)
    {
        hr = PropertyStorage_StringCopy(propvar->u.pszVal, srcCP,
         &prop->u.pszVal, targetCP);
        if (SUCCEEDED(hr))
            prop->vt = VT_LPSTR;
    }
    else
        PropVariantCopy(prop, propvar);
    return hr;
}

/* Stores the property with id propid and value propvar into this property
 * storage.  lcid is ignored if propvar's type is not VT_LPSTR.  If propvar's
 * type is VT_LPSTR, converts the string using lcid as the source code page
 * and This->codePage as the target code page before storing.
 * As a side effect, may change This->format to 1 if the type of propvar is
 * a version 1-only property.
 */
static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
 PROPID propid, const PROPVARIANT *propvar, LCID lcid)
{
    HRESULT hr = S_OK;
    PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);

    assert(propvar);
    if (propvar->vt & VT_BYREF || propvar->vt & VT_ARRAY)
        This->format = 1;
    switch (propvar->vt)
    {
    case VT_DECIMAL:
    case VT_I1:
    case VT_INT:
    case VT_UINT:
    case VT_VECTOR|VT_I1:
        This->format = 1;
    }
    TRACE("Setting 0x%08x to type %d\n", propid, propvar->vt);
    if (prop)
    {
        PropVariantClear(prop);
        hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
         lcid);
    }
    else
    {
        prop = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
         sizeof(PROPVARIANT));
        if (prop)
        {
            hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
             lcid);
            if (SUCCEEDED(hr))
            {
                dictionary_insert(This->propid_to_prop, (void *)propid, prop);
                if (propid > This->highestProp)
                    This->highestProp = propid;
            }
            else
                HeapFree(GetProcessHeap(), 0, prop);
        }
        else
            hr = STG_E_INSUFFICIENTMEMORY;
    }
    return hr;
}

/* Adds the name srcName to the name dictionaries, mapped to property ID id.
 * srcName is encoded in code page cp, and is converted to This->codePage.
 * If cp is CP_UNICODE, srcName is actually a unicode string.
 * As a side effect, may change This->format to 1 if srcName is too long for
 * a version 0 property storage.
 * Doesn't validate id.
 */
static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This,
 LPCSTR srcName, LCID cp, PROPID id)
{
    LPSTR name;
    HRESULT hr;

    assert(srcName);

    hr = PropertyStorage_StringCopy((LPCSTR)srcName, cp, &name, This->codePage);
    if (SUCCEEDED(hr))
    {
        if (This->codePage == CP_UNICODE)
        {
            if (lstrlenW((LPWSTR)name) >= MAX_VERSION_0_PROP_NAME_LENGTH)
                This->format = 1;
        }
        else
        {
            if (strlen(name) >= MAX_VERSION_0_PROP_NAME_LENGTH)
                This->format = 1;
        }
        TRACE("Adding prop name %s, propid %d\n",
         This->codePage == CP_UNICODE ? debugstr_w((LPCWSTR)name) :
         debugstr_a(name), id);
        dictionary_insert(This->name_to_propid, name, (void *)id);
        dictionary_insert(This->propid_to_name, (void *)id, name);
    }
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnWriteMultiple (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
    IPropertyStorage* iface,
    ULONG cpspec,
    const PROPSPEC rgpspec[],
    const PROPVARIANT rgpropvar[],
    PROPID propidNameFirst)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    HRESULT hr = S_OK;
    ULONG i;

    TRACE("(%p, %d, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);

    if (cpspec && (!rgpspec || !rgpropvar))
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    EnterCriticalSection(&This->cs);
    This->dirty = TRUE;
    This->originatorOS = (DWORD)MAKELONG(LOWORD(GetVersion()),
     PROPSETHDR_OSVER_KIND_WIN32) ;
    for (i = 0; i < cpspec; i++)
    {
        if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
        {
            PROPVARIANT *prop = PropertyStorage_FindPropertyByName(This,
             rgpspec[i].u.lpwstr);

            if (prop)
                PropVariantCopy(prop, &rgpropvar[i]);
            else
            {
                /* Note that I don't do the special cases here that I do below,
                 * because naming the special PIDs isn't supported.
                 */
                if (propidNameFirst < PID_FIRST_USABLE ||
                 propidNameFirst >= PID_MIN_READONLY)
                    hr = STG_E_INVALIDPARAMETER;
                else
                {
                    PROPID nextId = max(propidNameFirst, This->highestProp + 1);

                    hr = PropertyStorage_StoreNameWithId(This,
                     (LPCSTR)rgpspec[i].u.lpwstr, CP_UNICODE, nextId);
                    if (SUCCEEDED(hr))
                        hr = PropertyStorage_StorePropWithId(This, nextId,
                         &rgpropvar[i], GetACP());
                }
            }
        }
        else
        {
            switch (rgpspec[i].u.propid)
            {
            case PID_DICTIONARY:
                /* Can't set the dictionary */
                hr = STG_E_INVALIDPARAMETER;
                break;
            case PID_CODEPAGE:
                /* Can only set the code page if nothing else has been set */
                if (dictionary_num_entries(This->propid_to_prop) == 0 &&
                 rgpropvar[i].vt == VT_I2)
                {
                    This->codePage = rgpropvar[i].u.iVal;
                    if (This->codePage == CP_UNICODE)
                        This->grfFlags &= ~PROPSETFLAG_ANSI;
                    else
                        This->grfFlags |= PROPSETFLAG_ANSI;
                }
                else
                    hr = STG_E_INVALIDPARAMETER;
                break;
            case PID_LOCALE:
                /* Can only set the locale if nothing else has been set */
                if (dictionary_num_entries(This->propid_to_prop) == 0 &&
                 rgpropvar[i].vt == VT_I4)
                    This->locale = rgpropvar[i].u.lVal;
                else
                    hr = STG_E_INVALIDPARAMETER;
                break;
            case PID_ILLEGAL:
                /* silently ignore like MSDN says */
                break;
            default:
                if (rgpspec[i].u.propid >= PID_MIN_READONLY)
                    hr = STG_E_INVALIDPARAMETER;
                else
                    hr = PropertyStorage_StorePropWithId(This,
                     rgpspec[i].u.propid, &rgpropvar[i], GetACP());
            }
        }
    }
    if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
        IPropertyStorage_Commit(iface, STGC_DEFAULT);
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnDeleteMultiple (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
    IPropertyStorage* iface,
    ULONG cpspec,
    const PROPSPEC rgpspec[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG i;
    HRESULT hr;

    TRACE("(%p, %d, %p)\n", iface, cpspec, rgpspec);

    if (cpspec && !rgpspec)
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    hr = S_OK;
    EnterCriticalSection(&This->cs);
    This->dirty = TRUE;
    for (i = 0; i < cpspec; i++)
    {
        if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
        {
            PROPID propid;

            if (dictionary_find(This->name_to_propid,
             (void *)rgpspec[i].u.lpwstr, (void **)&propid))
                dictionary_remove(This->propid_to_prop, (void *)propid);
        }
        else
        {
            if (rgpspec[i].u.propid >= PID_FIRST_USABLE &&
             rgpspec[i].u.propid < PID_MIN_READONLY)
                dictionary_remove(This->propid_to_prop,
                 (void *)rgpspec[i].u.propid);
            else
                hr = STG_E_INVALIDPARAMETER;
        }
    }
    if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
        IPropertyStorage_Commit(iface, STGC_DEFAULT);
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnReadPropertyNames (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(
    IPropertyStorage* iface,
    ULONG cpropid,
    const PROPID rgpropid[],
    LPOLESTR rglpwstrName[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG i;
    HRESULT hr = S_FALSE;

    TRACE("(%p, %d, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);

    if (cpropid && (!rgpropid || !rglpwstrName))
        return E_INVALIDARG;
    EnterCriticalSection(&This->cs);
    for (i = 0; i < cpropid && SUCCEEDED(hr); i++)
    {
        LPWSTR name = PropertyStorage_FindPropertyNameById(This, rgpropid[i]);

        if (name)
        {
            size_t len = lstrlenW(name);

            hr = S_OK;
            rglpwstrName[i] = CoTaskMemAlloc((len + 1) * sizeof(WCHAR));
            if (rglpwstrName)
                memcpy(rglpwstrName, name, (len + 1) * sizeof(WCHAR));
            else
                hr = STG_E_INSUFFICIENTMEMORY;
        }
        else
            rglpwstrName[i] = NULL;
    }
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnWritePropertyNames (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
    IPropertyStorage* iface,
    ULONG cpropid,
    const PROPID rgpropid[],
    const LPOLESTR rglpwstrName[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG i;
    HRESULT hr;

    TRACE("(%p, %d, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);

    if (cpropid && (!rgpropid || !rglpwstrName))
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    hr = S_OK;
    EnterCriticalSection(&This->cs);
    This->dirty = TRUE;
    for (i = 0; SUCCEEDED(hr) && i < cpropid; i++)
    {
        if (rgpropid[i] != PID_ILLEGAL)
            hr = PropertyStorage_StoreNameWithId(This, (LPCSTR)rglpwstrName[i],
             CP_UNICODE, rgpropid[i]);
    }
    if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
        IPropertyStorage_Commit(iface, STGC_DEFAULT);
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnDeletePropertyNames (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
    IPropertyStorage* iface,
    ULONG cpropid,
    const PROPID rgpropid[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG i;
    HRESULT hr;

    TRACE("(%p, %d, %p)\n", iface, cpropid, rgpropid);

    if (cpropid && !rgpropid)
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    hr = S_OK;
    EnterCriticalSection(&This->cs);
    This->dirty = TRUE;
    for (i = 0; i < cpropid; i++)
    {
        LPWSTR name = NULL;

        if (dictionary_find(This->propid_to_name, (void *)rgpropid[i],
         (void **)&name))
        {
            dictionary_remove(This->propid_to_name, (void *)rgpropid[i]);
            dictionary_remove(This->name_to_propid, name);
        }
    }
    if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
        IPropertyStorage_Commit(iface, STGC_DEFAULT);
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnCommit (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnCommit(
    IPropertyStorage* iface,
    DWORD grfCommitFlags)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;

⌨️ 快捷键说明

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