|  | /* | 
|  | * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
|  | * | 
|  | */ | 
|  | #include "config.h" | 
|  | #include "wine/port.h" | 
|  |  | 
|  | #include <stdarg.h> | 
|  |  | 
|  | #include "windef.h" | 
|  | #include "winbase.h" | 
|  | #include "winreg.h" | 
|  | #include "winuser.h" | 
|  | #include "shlobj.h" | 
|  | #include "shell32_main.h" | 
|  |  | 
|  | #include "debughlp.h" | 
|  | #include "wine/debug.h" | 
|  |  | 
|  | WINE_DEFAULT_DEBUG_CHANNEL(pidl); | 
|  |  | 
|  | /*********************************************************************** | 
|  | * IFileSystemBindData implementation | 
|  | */ | 
|  | typedef struct | 
|  | { | 
|  | ICOM_VFIELD(IFileSystemBindData); | 
|  | DWORD              ref; | 
|  | WIN32_FIND_DATAW findFile; | 
|  | } IFileSystemBindDataImpl; | 
|  |  | 
|  | static HRESULT WINAPI IFileSystemBindData_fnQueryInterface(IFileSystemBindData *iface, REFIID riid, LPVOID* ppvObj); | 
|  | static ULONG WINAPI IFileSystemBindData_fnAddRef(IFileSystemBindData *iface); | 
|  | static ULONG WINAPI IFileSystemBindData_fnRelease(IFileSystemBindData *iface); | 
|  | static HRESULT WINAPI IFileSystemBindData_fnGetFindData(IFileSystemBindData *iface, WIN32_FIND_DATAW *pfd); | 
|  | static HRESULT WINAPI IFileSystemBindData_fnSetFindData(IFileSystemBindData *iface, const WIN32_FIND_DATAW *pfd); | 
|  |  | 
|  | static struct ICOM_VTABLE(IFileSystemBindData) sbvt = | 
|  | { | 
|  | ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | 
|  | IFileSystemBindData_fnQueryInterface, | 
|  | IFileSystemBindData_fnAddRef, | 
|  | IFileSystemBindData_fnRelease, | 
|  | IFileSystemBindData_fnGetFindData, | 
|  | IFileSystemBindData_fnSetFindData, | 
|  | }; | 
|  |  | 
|  | static WCHAR wFileSystemBindData[] = {'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d','D','a','t','a',0}; | 
|  |  | 
|  | HRESULT WINAPI FileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV) | 
|  | { | 
|  | IFileSystemBindDataImpl *sb; | 
|  | HRESULT ret = E_OUTOFMEMORY; | 
|  |  | 
|  | TRACE("%p, %p", pfd, ppV); | 
|  |  | 
|  | if (!ppV) | 
|  | return E_INVALIDARG; | 
|  |  | 
|  | *ppV = NULL; | 
|  |  | 
|  | sb = (IFileSystemBindDataImpl*)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, wFileSystemBindData, (LPUNKNOWN)sb); | 
|  |  | 
|  | IFileSystemBindData_Release((IFileSystemBindData*)sb); | 
|  | } | 
|  | else | 
|  | HeapFree(GetProcessHeap(), 0, sb); | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | HRESULT WINAPI FileSystemBindData_GetFindData(LPBC pbc, WIN32_FIND_DATAW *pfd) | 
|  | { | 
|  | LPUNKNOWN pUnk; | 
|  | IFileSystemBindData *pfsbd = NULL; | 
|  | HRESULT ret; | 
|  |  | 
|  | TRACE("%p, %p", pbc, pfd); | 
|  |  | 
|  | if (!pfd) | 
|  | return E_INVALIDARG; | 
|  |  | 
|  | ret = IBindCtx_GetObjectParam(pbc, wFileSystemBindData, &pUnk); | 
|  | if (SUCCEEDED(ret)) | 
|  | { | 
|  | ret = IUnknown_QueryInterface(pUnk, &IID_IFileSystemBindData, (LPVOID *)&pfsbd); | 
|  | if (SUCCEEDED(ret)) | 
|  | { | 
|  | ret = IFileSystemBindData_GetFindData(pfsbd, pfd); | 
|  | IFileSystemBindData_Release(pfsbd); | 
|  | } | 
|  | IUnknown_Release(pUnk); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | HRESULT WINAPI FileSystemBindData_SetFindData(LPBC pbc, const WIN32_FIND_DATAW *pfd) | 
|  | { | 
|  | LPUNKNOWN pUnk; | 
|  | IFileSystemBindData *pfsbd = NULL; | 
|  | HRESULT ret; | 
|  |  | 
|  | TRACE("%p, %p", pbc, pfd); | 
|  |  | 
|  | ret = IBindCtx_GetObjectParam(pbc, wFileSystemBindData, &pUnk); | 
|  | if (SUCCEEDED(ret)) | 
|  | { | 
|  | ret = IUnknown_QueryInterface(pUnk, &IID_IFileSystemBindData, (LPVOID *)&pfsbd); | 
|  | if (SUCCEEDED(ret)) | 
|  | { | 
|  | ret = IFileSystemBindData_SetFindData(pfsbd, pfd); | 
|  | IFileSystemBindData_Release(pfsbd); | 
|  | } | 
|  | IUnknown_Release(pUnk); | 
|  | } | 
|  | return ret;} | 
|  |  | 
|  |  | 
|  |  | 
|  | static HRESULT WINAPI IFileSystemBindData_fnQueryInterface(IFileSystemBindData *iface, REFIID riid, LPVOID *ppV) | 
|  | { | 
|  | ICOM_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)) | 
|  | { | 
|  | *ppV = (IFileSystemBindData*)This; | 
|  | } | 
|  |  | 
|  | if (*ppV) | 
|  | { | 
|  | IUnknown_AddRef((IUnknown*)(*ppV)); | 
|  | TRACE("-- Interface: (%p)->(%p)\n", ppV, *ppV); | 
|  | return S_OK; | 
|  | } | 
|  | TRACE("-- Interface: E_NOINTERFACE\n"); | 
|  | return E_NOINTERFACE; | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI IFileSystemBindData_fnAddRef(IFileSystemBindData *iface) | 
|  | { | 
|  | ICOM_THIS(IFileSystemBindDataImpl, iface); | 
|  | TRACE("(%p)\n", This); | 
|  | return InterlockedIncrement(&This->ref); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI IFileSystemBindData_fnRelease(IFileSystemBindData *iface) | 
|  | { | 
|  | ICOM_THIS(IFileSystemBindDataImpl, iface); | 
|  | TRACE("(%p)\n", This); | 
|  |  | 
|  | if (!InterlockedDecrement(&This->ref)) | 
|  | { | 
|  | TRACE(" destroying ISFBindPidl(%p)\n",This); | 
|  | HeapFree(GetProcessHeap(), 0, This); | 
|  | return 0; | 
|  | } | 
|  | return This->ref; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI IFileSystemBindData_fnGetFindData(IFileSystemBindData *iface, WIN32_FIND_DATAW *pfd) | 
|  | { | 
|  | ICOM_THIS(IFileSystemBindDataImpl, iface); | 
|  | TRACE("(%p), %p\n", This, pfd); | 
|  |  | 
|  | if (!pfd) | 
|  | return E_INVALIDARG; | 
|  |  | 
|  | memcpy(pfd, &This->findFile, sizeof(WIN32_FIND_DATAW)); | 
|  | return NOERROR; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI IFileSystemBindData_fnSetFindData(IFileSystemBindData *iface, const WIN32_FIND_DATAW *pfd) | 
|  | { | 
|  | ICOM_THIS(IFileSystemBindDataImpl, iface); | 
|  | TRACE("(%p), %p\n", This, pfd); | 
|  |  | 
|  | if (pfd) | 
|  | memcpy(&This->findFile, pfd, sizeof(WIN32_FIND_DATAW)); | 
|  | else | 
|  | memset(&This->findFile, 0, sizeof(WIN32_FIND_DATAW)); | 
|  | return NOERROR; | 
|  | } |