parsedisplayname.c 4.55 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 *	IParseDisplayName implementation for DEVENUM.dll
 *
 * Copyright (C) 2002 Robert Shearman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 20 21 22 23 24 25 26 27 28 29
 *
 * NOTES ON THIS FILE:
 * - Implements IParseDisplayName interface which creates a moniker
 *   from a string in a special format
 */
#include "devenum_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(devenum);

30 31
static HRESULT WINAPI DEVENUM_IParseDisplayName_QueryInterface(IParseDisplayName *iface,
        REFIID riid, void **ppv)
32 33 34
{
    TRACE("\n\tIID:\t%s\n",debugstr_guid(riid));

35 36
    if (!ppv)
        return E_POINTER;
37 38 39 40

    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IParseDisplayName))
    {
41 42 43
        *ppv = iface;
        IParseDisplayName_AddRef(iface);
        return S_OK;
44 45
    }

46
    FIXME("- no interface IID: %s\n", debugstr_guid(riid));
47
    *ppv = NULL;
48 49 50
    return E_NOINTERFACE;
}

51
static ULONG WINAPI DEVENUM_IParseDisplayName_AddRef(IParseDisplayName *iface)
52 53 54
{
    TRACE("\n");

55
    DEVENUM_LockModule();
56

57
    return 2; /* non-heap based object */
58 59
}

60
static ULONG WINAPI DEVENUM_IParseDisplayName_Release(IParseDisplayName *iface)
61 62 63
{
    TRACE("\n");

64
    DEVENUM_UnlockModule();
65

66
    return 1; /* non-heap based object */
67 68 69 70 71 72 73 74
}

/**********************************************************************
 * DEVENUM_IParseDisplayName_ParseDisplayName
 *
 *  Creates a moniker referenced to by the display string argument
 *
 * POSSIBLE BUGS:
75 76
 *  Might not handle more complicated strings properly (ie anything
 *  not in "@device:sw:{CLSID1}\<filter name or CLSID>" format
77
 */
78
static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayName *iface,
79
        IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret)
80
{
81
    WCHAR buffer[MAX_PATH];
82
    enum device_type type;
83 84
    MediaCatMoniker *mon;
    CLSID class;
85

86
    TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(name), eaten, ret);
87

88 89
    *ret = NULL;
    if (eaten)
90
        *eaten = lstrlenW(name);
91

92
    name = wcschr(name, ':') + 1;
93

94
    if (!wcsncmp(name, swW, 3))
95 96
    {
        type = DEVICE_FILTER;
97
        name += 3;
98
    }
99
    else if (!wcsncmp(name, cmW, 3))
100 101
    {
        type = DEVICE_CODEC;
102
        name += 3;
103
    }
104
    else if (!wcsncmp(name, dmoW, 4))
105 106 107 108
    {
        type = DEVICE_DMO;
        name += 4;
    }
109 110
    else
    {
111
        FIXME("unhandled device type %s\n", debugstr_w(name));
112 113 114
        return MK_E_SYNTAX;
    }

115
    if (!(mon = DEVENUM_IMediaCatMoniker_Construct()))
116 117
        return E_OUTOFMEMORY;

118
    if (type == DEVICE_DMO)
119
    {
120 121 122 123 124 125 126 127 128 129 130 131 132
        lstrcpynW(buffer, name, CHARS_IN_GUID);
        if (FAILED(CLSIDFromString(buffer, &mon->clsid)))
        {
            IMoniker_Release(&mon->IMoniker_iface);
            return MK_E_SYNTAX;
        }

        lstrcpynW(buffer, name + CHARS_IN_GUID - 1, CHARS_IN_GUID);
        if (FAILED(CLSIDFromString(buffer, &mon->class)))
        {
            IMoniker_Release(&mon->IMoniker_iface);
            return MK_E_SYNTAX;
        }
133
    }
134
    else
135
    {
136 137 138 139 140 141 142 143
        lstrcpynW(buffer, name, CHARS_IN_GUID);
        if (CLSIDFromString(buffer, &class) == S_OK)
        {
            mon->has_class = TRUE;
            mon->class = class;
            name += CHARS_IN_GUID;
        }

144
        if (!(mon->name = CoTaskMemAlloc((lstrlenW(name) + 1) * sizeof(WCHAR))))
145 146 147 148
        {
            IMoniker_Release(&mon->IMoniker_iface);
            return E_OUTOFMEMORY;
        }
149
        lstrcpyW(mon->name, name);
150
    }
151 152

    mon->type = type;
153

154
    *ret = &mon->IMoniker_iface;
155

156
    return S_OK;
157 158 159 160 161
}

/**********************************************************************
 * IParseDisplayName_Vtbl
 */
162
static const IParseDisplayNameVtbl IParseDisplayName_Vtbl =
163 164 165 166 167 168 169 170
{
    DEVENUM_IParseDisplayName_QueryInterface,
    DEVENUM_IParseDisplayName_AddRef,
    DEVENUM_IParseDisplayName_Release,
    DEVENUM_IParseDisplayName_ParseDisplayName
};

/* The one instance of this class */
171
IParseDisplayName DEVENUM_ParseDisplayName = { &IParseDisplayName_Vtbl };