shlfsbind.c 5.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * File System Bind Data object to use as parameter for the bind context to
 * IShellFolder_ParseDisplayName
 *
 * Copyright 2003 Rolf Kalbermatter
 *
 * 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
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 21 22 23 24 25 26
 *
 */
#include "config.h"
#include "wine/port.h"

#include <stdarg.h>

27 28
#define COBJMACROS

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "shlobj.h"
#include "shell32_main.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(pidl);

/***********************************************************************
 * IFileSystemBindData implementation
 */
typedef struct
{
44
    const IFileSystemBindDataVtbl *lpVtbl;
Mike McCormack's avatar
Mike McCormack committed
45
    LONG              ref;
46
    WIN32_FIND_DATAW findFile;
47 48
} IFileSystemBindDataImpl;

49 50 51 52 53
static HRESULT WINAPI IFileSystemBindData_fnQueryInterface(IFileSystemBindData *, REFIID, LPVOID*);
static ULONG WINAPI IFileSystemBindData_fnAddRef(IFileSystemBindData *);
static ULONG WINAPI IFileSystemBindData_fnRelease(IFileSystemBindData *);
static HRESULT WINAPI IFileSystemBindData_fnGetFindData(IFileSystemBindData *, WIN32_FIND_DATAW *);
static HRESULT WINAPI IFileSystemBindData_fnSetFindData(IFileSystemBindData *, const WIN32_FIND_DATAW *);
54

55
static const IFileSystemBindDataVtbl sbvt =
56 57 58 59 60
{
    IFileSystemBindData_fnQueryInterface,
    IFileSystemBindData_fnAddRef,
    IFileSystemBindData_fnRelease,
    IFileSystemBindData_fnSetFindData,
61
    IFileSystemBindData_fnGetFindData,
62 63
};

64 65
static const WCHAR wFileSystemBindData[] = {
    'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d','D','a','t','a',0};
66

67
HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV)
68
{
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    IFileSystemBindDataImpl *sb;
    HRESULT ret = E_OUTOFMEMORY;

    TRACE("%p, %p\n", pfd, ppV);

    if (!ppV)
       return E_INVALIDARG;

    *ppV = NULL;

    sb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IFileSystemBindDataImpl));
    if (!sb)
        return ret;

    sb->lpVtbl = &sbvt;
    sb->ref = 1;
    IFileSystemBindData_fnSetFindData((IFileSystemBindData*)sb, pfd);

    ret = CreateBindCtx(0, ppV);
    if (SUCCEEDED(ret))
    {
        BIND_OPTS bindOpts;

        bindOpts.cbStruct = sizeof(BIND_OPTS);
        bindOpts.grfFlags = 0;
        bindOpts.grfMode = STGM_CREATE;
        bindOpts.dwTickCountDeadline = 0;
        IBindCtx_SetBindOptions(*ppV, &bindOpts);
        IBindCtx_RegisterObjectParam(*ppV, (LPOLESTR)wFileSystemBindData, (LPUNKNOWN)sb);

        IFileSystemBindData_Release((IFileSystemBindData*)sb);
    }
    else
        HeapFree(GetProcessHeap(), 0, sb);
    return ret;
104 105
}

106 107
static HRESULT WINAPI IFileSystemBindData_fnQueryInterface(
                IFileSystemBindData *iface, REFIID riid, LPVOID *ppV)
108
{
109 110 111 112 113 114 115 116
    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
    TRACE("(%p)->(\n\tIID:\t%s, %p)\n", This, debugstr_guid(riid), ppV);

    *ppV = NULL;

    if (IsEqualIID(riid, &IID_IUnknown))
        *ppV = This;
    else if (IsEqualIID(riid, &IID_IFileSystemBindData))
117
        *ppV = This;
118 119 120 121 122 123 124 125 126

    if (*ppV)
    {
        IUnknown_AddRef((IUnknown*)(*ppV));
        TRACE("-- Interface: (%p)->(%p)\n", ppV, *ppV);
        return S_OK;
    }
    TRACE("-- Interface: E_NOINTERFACE\n");
    return E_NOINTERFACE;
127 128 129 130
}

static ULONG WINAPI IFileSystemBindData_fnAddRef(IFileSystemBindData *iface)
{
131 132
    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);
133

134
    TRACE("(%p)->(count=%i)\n", This, refCount - 1);
135

136
    return refCount;
137 138 139 140
}

static ULONG WINAPI IFileSystemBindData_fnRelease(IFileSystemBindData *iface)
{
141 142 143
    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);
    
144
    TRACE("(%p)->(count=%i)\n", This, refCount + 1);
145 146 147 148 149 150 151

    if (!refCount)
    {
        TRACE(" destroying ISFBindPidl(%p)\n",This);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return refCount;
152 153
}

154 155
static HRESULT WINAPI IFileSystemBindData_fnGetFindData(
               IFileSystemBindData *iface, WIN32_FIND_DATAW *pfd)
156
{
157 158
    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
    TRACE("(%p), %p\n", This, pfd);
159

160 161
    if (!pfd)
        return E_INVALIDARG;
162

163
    *pfd = This->findFile;
164
    return NOERROR;
165 166
}

167 168
static HRESULT WINAPI IFileSystemBindData_fnSetFindData(
               IFileSystemBindData *iface, const WIN32_FIND_DATAW *pfd)
169
{
170 171 172 173
    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
    TRACE("(%p), %p\n", This, pfd);

    if (pfd)
174
        This->findFile = *pfd;
175 176 177
    else
        memset(&This->findFile, 0, sizeof(WIN32_FIND_DATAW));
    return NOERROR;
178
}