| /* |
| * 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 |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| * |
| */ |
| #include "config.h" |
| #include "wine/port.h" |
| |
| #include <stdarg.h> |
| |
| #define COBJMACROS |
| |
| #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 |
| { |
| IFileSystemBindData IFileSystemBindData_iface; |
| LONG ref; |
| WIN32_FIND_DATAW findFile; |
| } FileSystemBindData; |
| |
| static inline FileSystemBindData *impl_from_IFileSystemBindData(IFileSystemBindData *iface) |
| { |
| return CONTAINING_RECORD(iface, FileSystemBindData, IFileSystemBindData_iface); |
| } |
| |
| static HRESULT WINAPI FileSystemBindData_QueryInterface( |
| IFileSystemBindData *iface, REFIID riid, LPVOID *ppV) |
| { |
| FileSystemBindData *This = impl_from_IFileSystemBindData(iface); |
| |
| TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppV); |
| |
| *ppV = NULL; |
| |
| if (IsEqualIID(riid, &IID_IUnknown) || |
| IsEqualIID(riid, &IID_IFileSystemBindData)) |
| { |
| *ppV = &This->IFileSystemBindData_iface; |
| } |
| |
| if (*ppV) |
| { |
| IFileSystemBindData_AddRef(iface); |
| TRACE("-- Interface: (%p)->(%p)\n", ppV, *ppV); |
| return S_OK; |
| } |
| TRACE("-- Interface: E_NOINTERFACE\n"); |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI FileSystemBindData_AddRef(IFileSystemBindData *iface) |
| { |
| FileSystemBindData *This = impl_from_IFileSystemBindData(iface); |
| ULONG ref = InterlockedIncrement(&This->ref); |
| TRACE("(%p)->(%u)\n", This, ref); |
| return ref; |
| } |
| |
| static ULONG WINAPI FileSystemBindData_Release(IFileSystemBindData *iface) |
| { |
| FileSystemBindData *This = impl_from_IFileSystemBindData(iface); |
| ULONG ref = InterlockedDecrement(&This->ref); |
| |
| TRACE("(%p)->(%u)\n", This, ref); |
| |
| if (!ref) |
| HeapFree(GetProcessHeap(), 0, This); |
| |
| return ref; |
| } |
| |
| static HRESULT WINAPI FileSystemBindData_GetFindData(IFileSystemBindData *iface, WIN32_FIND_DATAW *pfd) |
| { |
| FileSystemBindData *This = impl_from_IFileSystemBindData(iface); |
| |
| TRACE("(%p)->(%p)\n", This, pfd); |
| |
| if (!pfd) |
| return E_INVALIDARG; |
| |
| *pfd = This->findFile; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI FileSystemBindData_SetFindData(IFileSystemBindData *iface, const WIN32_FIND_DATAW *pfd) |
| { |
| FileSystemBindData *This = impl_from_IFileSystemBindData(iface); |
| |
| TRACE("(%p)->(%p)\n", This, pfd); |
| |
| if (pfd) |
| This->findFile = *pfd; |
| else |
| memset(&This->findFile, 0, sizeof(WIN32_FIND_DATAW)); |
| return S_OK; |
| } |
| |
| static const IFileSystemBindDataVtbl FileSystemBindDataVtbl = { |
| FileSystemBindData_QueryInterface, |
| FileSystemBindData_AddRef, |
| FileSystemBindData_Release, |
| FileSystemBindData_SetFindData, |
| FileSystemBindData_GetFindData, |
| }; |
| |
| HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *find_data, LPBC *ppV) |
| { |
| FileSystemBindData *This; |
| HRESULT ret; |
| |
| TRACE("(%p %p)\n", find_data, ppV); |
| |
| if (!ppV) |
| return E_INVALIDARG; |
| |
| *ppV = NULL; |
| |
| This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); |
| if (!This) return E_OUTOFMEMORY; |
| |
| This->IFileSystemBindData_iface.lpVtbl = &FileSystemBindDataVtbl; |
| This->ref = 1; |
| IFileSystemBindData_SetFindData(&This->IFileSystemBindData_iface, find_data); |
| |
| ret = CreateBindCtx(0, ppV); |
| if (SUCCEEDED(ret)) |
| { |
| static const WCHAR nameW[] = { |
| 'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d',' ','D','a','t','a',0}; |
| 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, (WCHAR*)nameW, (IUnknown*)&This->IFileSystemBindData_iface); |
| |
| IFileSystemBindData_Release(&This->IFileSystemBindData_iface); |
| } |
| else |
| HeapFree(GetProcessHeap(), 0, This); |
| return ret; |
| } |