1 /*
2  * File System Bind Data object to use as parameter for the bind context to
3  * IShellFolder_ParseDisplayName
4  *
5  * Copyright 2003 Rolf Kalbermatter
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * 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 #include "precomp.h"
24 
25 WINE_DEFAULT_DEBUG_CHANNEL(pidl);
26 
27 /***********************************************************************
28  * IFileSystemBindData implementation
29  */
30 class CFileSysBindData :
31     public CComObjectRootEx<CComMultiThreadModelNoCS>,
32     public IFileSystemBindData
33 {
34 private:
35     WIN32_FIND_DATAW findFile;
36 public:
37     CFileSysBindData();
38     ~CFileSysBindData();
39 
40     // *** IFileSystemBindData methods ***
41     virtual HRESULT STDMETHODCALLTYPE SetFindData(const WIN32_FIND_DATAW *pfd);
42     virtual HRESULT STDMETHODCALLTYPE GetFindData(WIN32_FIND_DATAW *pfd);
43 
44 DECLARE_NOT_AGGREGATABLE(CFileSysBindData)
45 DECLARE_PROTECT_FINAL_CONSTRUCT()
46 
47 BEGIN_COM_MAP(CFileSysBindData)
48     COM_INTERFACE_ENTRY_IID(IID_IFileSystemBindData, IFileSystemBindData)
49 END_COM_MAP()
50 };
51 
52 HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV)
53 {
54     CComPtr<IFileSystemBindData>        fileSystemBindData;
55     CComPtr<IBindCtx>                    bindContext;
56     BIND_OPTS                            bindOpts;
57     HRESULT                                hResult;
58 
59     TRACE("%p, %p\n", pfd, ppV);
60 
61     if (ppV == NULL)
62        return E_INVALIDARG;
63 
64     *ppV = NULL;
65 
66     hResult = CFileSysBindData::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IFileSystemBindData, &fileSystemBindData));
67     if (FAILED(hResult))
68         return hResult;
69     hResult = fileSystemBindData->SetFindData(pfd);
70     if (FAILED(hResult))
71         return hResult;
72 
73     hResult = CreateBindCtx(0, &bindContext);
74     if (FAILED(hResult))
75         return hResult;
76     bindOpts.cbStruct = sizeof(BIND_OPTS);
77     bindOpts.grfFlags = 0;
78     bindOpts.grfMode = STGM_CREATE;
79     bindOpts.dwTickCountDeadline = 0;
80     hResult = bindContext->SetBindOptions(&bindOpts);
81     if (FAILED(hResult))
82         return hResult;
83     hResult = bindContext->RegisterObjectParam((LPOLESTR)STR_FILE_SYS_BIND_DATA, fileSystemBindData);
84     if (FAILED(hResult))
85         return hResult;
86 
87     *ppV = bindContext.Detach();
88 
89     return S_OK;
90 }
91 
92 HRESULT WINAPI FileSystemBindData_GetFindData(LPBC pbc, WIN32_FIND_DATAW *pfd)
93 {
94     CComPtr<IUnknown>                    pUnk;
95     CComPtr<IFileSystemBindData>        pfsbd;
96     HRESULT                                ret;
97 
98     TRACE("%p, %p\n", pbc, pfd);
99 
100     if (!pfd)
101         return E_INVALIDARG;
102 
103     ret = pbc->GetObjectParam((LPOLESTR)STR_FILE_SYS_BIND_DATA, &pUnk);
104     if (SUCCEEDED(ret))
105     {
106         ret = pUnk->QueryInterface(IID_PPV_ARG(IFileSystemBindData, &pfsbd));
107         if (SUCCEEDED(ret))
108             ret = pfsbd->GetFindData(pfd);
109     }
110     return ret;
111 }
112 
113 HRESULT WINAPI FileSystemBindData_SetFindData(LPBC pbc, const WIN32_FIND_DATAW *pfd)
114 {
115     CComPtr<IUnknown>                    pUnk;
116     CComPtr<IFileSystemBindData>        pfsbd;
117     HRESULT                                ret;
118 
119     TRACE("%p, %p\n", pbc, pfd);
120 
121     ret = pbc->GetObjectParam((LPOLESTR)STR_FILE_SYS_BIND_DATA, &pUnk);
122     if (SUCCEEDED(ret))
123     {
124         ret = pUnk->QueryInterface(IID_PPV_ARG(IFileSystemBindData, &pfsbd));
125         if (SUCCEEDED(ret))
126             ret = pfsbd->SetFindData(pfd);
127     }
128     return ret;
129 }
130 
131 CFileSysBindData::CFileSysBindData()
132 {
133     memset(&findFile, 0, sizeof(WIN32_FIND_DATAW));
134 }
135 
136 CFileSysBindData::~CFileSysBindData()
137 {
138     TRACE(" destroying ISFBindPidl(%p)\n", this);
139 }
140 
141 HRESULT WINAPI CFileSysBindData::GetFindData(WIN32_FIND_DATAW *pfd)
142 {
143     TRACE("(%p), %p\n", this, pfd);
144 
145     if (!pfd)
146         return E_INVALIDARG;
147 
148     memcpy(pfd, &findFile, sizeof(WIN32_FIND_DATAW));
149     return S_OK;
150 }
151 
152 HRESULT WINAPI CFileSysBindData::SetFindData(const WIN32_FIND_DATAW *pfd)
153 {
154     TRACE("(%p), %p\n", this, pfd);
155 
156     if (pfd)
157         memcpy(&findFile, pfd, sizeof(WIN32_FIND_DATAW));
158     else
159         memset(&findFile, 0, sizeof(WIN32_FIND_DATAW));
160     return S_OK;
161 }
162