cmd: DIR command outputs free space for the path.
[wine.git] / dlls / itss / moniker.c
blob3d0063f2bb7f0b46481241da8bfbc178dbfe0681
1 /*
2 * ITSS Moniker implementation
4 * Copyright 2004 Mike McCormack
6 * Implementation of the infamous mk:@MSITStore moniker
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <stdarg.h>
25 #include <stdio.h>
27 #define COBJMACROS
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "ole2.h"
34 #include "wine/itss.h"
35 #include "wine/debug.h"
37 #include "itsstor.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(itss);
41 /*****************************************************************************/
43 typedef struct {
44 IMoniker IMoniker_iface;
45 LONG ref;
46 LPWSTR szHtml;
47 WCHAR szFile[1];
48 } ITS_IMonikerImpl;
50 static inline ITS_IMonikerImpl *impl_from_IMoniker(IMoniker *iface)
52 return CONTAINING_RECORD(iface, ITS_IMonikerImpl, IMoniker_iface);
55 /*** IUnknown methods ***/
56 static HRESULT WINAPI ITS_IMonikerImpl_QueryInterface(
57 IMoniker* iface,
58 REFIID riid,
59 void** ppvObject)
61 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
63 if (IsEqualGUID(riid, &IID_IUnknown)
64 || IsEqualGUID(riid, &IID_IParseDisplayName))
66 IMoniker_AddRef(iface);
67 *ppvObject = iface;
68 return S_OK;
71 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
72 return E_NOINTERFACE;
75 static ULONG WINAPI ITS_IMonikerImpl_AddRef(
76 IMoniker* iface)
78 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
79 TRACE("%p\n", This);
80 return InterlockedIncrement(&This->ref);
83 static ULONG WINAPI ITS_IMonikerImpl_Release(
84 IMoniker* iface)
86 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
87 ULONG ref = InterlockedDecrement(&This->ref);
89 if (ref == 0) {
90 HeapFree(GetProcessHeap(), 0, This);
91 ITSS_UnlockModule();
94 return ref;
97 /*** IPersist methods ***/
98 static HRESULT WINAPI ITS_IMonikerImpl_GetClassID(
99 IMoniker* iface,
100 CLSID* pClassID)
102 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
104 TRACE("%p %p\n", This, pClassID);
105 *pClassID = CLSID_ITStorage;
106 return S_OK;
109 /*** IPersistStream methods ***/
110 static HRESULT WINAPI ITS_IMonikerImpl_IsDirty(
111 IMoniker* iface)
113 FIXME("\n");
114 return E_NOTIMPL;
117 static HRESULT WINAPI ITS_IMonikerImpl_Load(
118 IMoniker* iface,
119 IStream* pStm)
121 FIXME("\n");
122 return E_NOTIMPL;
125 static HRESULT WINAPI ITS_IMonikerImpl_Save(
126 IMoniker* iface,
127 IStream* pStm,
128 BOOL fClearDirty)
130 FIXME("\n");
131 return E_NOTIMPL;
134 static HRESULT WINAPI ITS_IMonikerImpl_GetSizeMax(
135 IMoniker* iface,
136 ULARGE_INTEGER* pcbSize)
138 FIXME("\n");
139 return E_NOTIMPL;
142 /*** IMoniker methods ***/
143 static HRESULT WINAPI ITS_IMonikerImpl_BindToObject(
144 IMoniker* iface,
145 IBindCtx* pbc,
146 IMoniker* pmkToLeft,
147 REFIID riidResult,
148 void** ppvResult)
150 FIXME("\n");
151 return E_NOTIMPL;
154 static HRESULT WINAPI ITS_IMonikerImpl_BindToStorage(
155 IMoniker* iface,
156 IBindCtx* pbc,
157 IMoniker* pmkToLeft,
158 REFIID riid,
159 void** ppvObj)
161 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
162 DWORD grfMode = STGM_SIMPLE | STGM_READ | STGM_SHARE_EXCLUSIVE;
163 HRESULT r;
164 IStorage *stg = NULL;
166 TRACE("%p %p %p %s %p\n", This,
167 pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
169 r = ITSS_StgOpenStorage( This->szFile, NULL, grfMode, 0, 0, &stg );
170 if( r == S_OK )
172 TRACE("Opened storage %s\n", debugstr_w( This->szFile ) );
173 if (IsEqualGUID(riid, &IID_IStream))
174 r = IStorage_OpenStream( stg, This->szHtml,
175 NULL, grfMode, 0, (IStream**)ppvObj );
176 else if (IsEqualGUID(riid, &IID_IStorage))
177 r = IStorage_OpenStorage( stg, This->szHtml,
178 NULL, grfMode, NULL, 0, (IStorage**)ppvObj );
179 else
180 r = STG_E_ACCESSDENIED;
181 IStorage_Release( stg );
184 return r;
187 static HRESULT WINAPI ITS_IMonikerImpl_Reduce(
188 IMoniker* iface,
189 IBindCtx* pbc,
190 DWORD dwReduceHowFar,
191 IMoniker** ppmkToLeft,
192 IMoniker** ppmkReduced)
194 FIXME("\n");
195 return E_NOTIMPL;
198 static HRESULT WINAPI ITS_IMonikerImpl_ComposeWith(
199 IMoniker* iface,
200 IMoniker* pmkRight,
201 BOOL fOnlyIfNotGeneric,
202 IMoniker** ppmkComposite)
204 FIXME("\n");
205 return E_NOTIMPL;
208 static HRESULT WINAPI ITS_IMonikerImpl_Enum(
209 IMoniker* iface,
210 BOOL fForward,
211 IEnumMoniker** ppenumMoniker)
213 FIXME("\n");
214 return E_NOTIMPL;
217 static HRESULT WINAPI ITS_IMonikerImpl_IsEqual(
218 IMoniker* iface,
219 IMoniker* pmkOtherMoniker)
221 FIXME("\n");
222 return E_NOTIMPL;
225 static HRESULT WINAPI ITS_IMonikerImpl_Hash(
226 IMoniker* iface,
227 DWORD* pdwHash)
229 FIXME("\n");
230 return E_NOTIMPL;
233 static HRESULT WINAPI ITS_IMonikerImpl_IsRunning(
234 IMoniker* iface,
235 IBindCtx* pbc,
236 IMoniker* pmkToLeft,
237 IMoniker* pmkNewlyRunning)
239 FIXME("\n");
240 return E_NOTIMPL;
243 static HRESULT WINAPI ITS_IMonikerImpl_GetTimeOfLastChange(
244 IMoniker* iface,
245 IBindCtx* pbc,
246 IMoniker* pmkToLeft,
247 FILETIME* pFileTime)
249 FIXME("\n");
250 return E_NOTIMPL;
253 static HRESULT WINAPI ITS_IMonikerImpl_Inverse(
254 IMoniker* iface,
255 IMoniker** ppmk)
257 FIXME("\n");
258 return E_NOTIMPL;
261 static HRESULT WINAPI ITS_IMonikerImpl_CommonPrefixWith(
262 IMoniker* iface,
263 IMoniker* pmkOther,
264 IMoniker** ppmkPrefix)
266 FIXME("\n");
267 return E_NOTIMPL;
270 static HRESULT WINAPI ITS_IMonikerImpl_RelativePathTo(
271 IMoniker* iface,
272 IMoniker* pmkOther,
273 IMoniker** ppmkRelPath)
275 FIXME("\n");
276 return E_NOTIMPL;
279 static HRESULT WINAPI ITS_IMonikerImpl_GetDisplayName(
280 IMoniker* iface,
281 IBindCtx* pbc,
282 IMoniker* pmkToLeft,
283 LPOLESTR* ppszDisplayName)
285 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
286 DWORD len;
287 LPWSTR str;
289 TRACE("%p %p %p %p\n", iface, pbc, pmkToLeft, ppszDisplayName);
291 len = lstrlenW( This->szFile ) + lstrlenW( This->szHtml );
292 str = CoTaskMemAlloc( len*sizeof(WCHAR) );
293 swprintf( str, len, L"ms-its:%s::%s", This->szFile, This->szHtml );
295 *ppszDisplayName = str;
297 return S_OK;
300 static HRESULT WINAPI ITS_IMonikerImpl_ParseDisplayName(
301 IMoniker* iface,
302 IBindCtx* pbc,
303 IMoniker* pmkToLeft,
304 LPOLESTR pszDisplayName,
305 ULONG* pchEaten,
306 IMoniker** ppmkOut)
308 FIXME("\n");
309 return E_NOTIMPL;
312 static HRESULT WINAPI ITS_IMonikerImpl_IsSystemMoniker(
313 IMoniker* iface,
314 DWORD* pdwMksys)
316 FIXME("\n");
317 return E_NOTIMPL;
320 static const IMonikerVtbl ITS_IMonikerImpl_Vtbl =
322 ITS_IMonikerImpl_QueryInterface,
323 ITS_IMonikerImpl_AddRef,
324 ITS_IMonikerImpl_Release,
325 ITS_IMonikerImpl_GetClassID,
326 ITS_IMonikerImpl_IsDirty,
327 ITS_IMonikerImpl_Load,
328 ITS_IMonikerImpl_Save,
329 ITS_IMonikerImpl_GetSizeMax,
330 ITS_IMonikerImpl_BindToObject,
331 ITS_IMonikerImpl_BindToStorage,
332 ITS_IMonikerImpl_Reduce,
333 ITS_IMonikerImpl_ComposeWith,
334 ITS_IMonikerImpl_Enum,
335 ITS_IMonikerImpl_IsEqual,
336 ITS_IMonikerImpl_Hash,
337 ITS_IMonikerImpl_IsRunning,
338 ITS_IMonikerImpl_GetTimeOfLastChange,
339 ITS_IMonikerImpl_Inverse,
340 ITS_IMonikerImpl_CommonPrefixWith,
341 ITS_IMonikerImpl_RelativePathTo,
342 ITS_IMonikerImpl_GetDisplayName,
343 ITS_IMonikerImpl_ParseDisplayName,
344 ITS_IMonikerImpl_IsSystemMoniker
347 static HRESULT ITS_IMoniker_create( IMoniker **ppObj, LPCWSTR name, DWORD n )
349 ITS_IMonikerImpl *itsmon;
350 DWORD sz;
352 /* szFile[1] has space for one character already */
353 sz = FIELD_OFFSET( ITS_IMonikerImpl, szFile[lstrlenW( name ) + 1] );
355 itsmon = HeapAlloc( GetProcessHeap(), 0, sz );
356 itsmon->IMoniker_iface.lpVtbl = &ITS_IMonikerImpl_Vtbl;
357 itsmon->ref = 1;
358 lstrcpyW( itsmon->szFile, name );
359 itsmon->szHtml = &itsmon->szFile[n];
361 while( *itsmon->szHtml == ':' )
362 *itsmon->szHtml++ = 0;
364 TRACE("-> %p %s %s\n", itsmon,
365 debugstr_w(itsmon->szFile), debugstr_w(itsmon->szHtml) );
366 *ppObj = &itsmon->IMoniker_iface;
368 ITSS_LockModule();
369 return S_OK;
372 /*****************************************************************************/
374 typedef struct {
375 IParseDisplayName IParseDisplayName_iface;
376 LONG ref;
377 } ITS_IParseDisplayNameImpl;
379 static inline ITS_IParseDisplayNameImpl *impl_from_IParseDisplayName(IParseDisplayName *iface)
381 return CONTAINING_RECORD(iface, ITS_IParseDisplayNameImpl, IParseDisplayName_iface);
384 static HRESULT WINAPI ITS_IParseDisplayNameImpl_QueryInterface(
385 IParseDisplayName* iface,
386 REFIID riid,
387 void** ppvObject)
389 ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
391 if (IsEqualGUID(riid, &IID_IUnknown)
392 || IsEqualGUID(riid, &IID_IParseDisplayName))
394 IParseDisplayName_AddRef(iface);
395 *ppvObject = iface;
396 return S_OK;
399 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
400 return E_NOINTERFACE;
403 static ULONG WINAPI ITS_IParseDisplayNameImpl_AddRef(
404 IParseDisplayName* iface)
406 ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
407 TRACE("%p\n", This);
408 return InterlockedIncrement(&This->ref);
411 static ULONG WINAPI ITS_IParseDisplayNameImpl_Release(
412 IParseDisplayName* iface)
414 ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
415 ULONG ref = InterlockedDecrement(&This->ref);
417 if (ref == 0) {
418 HeapFree(GetProcessHeap(), 0, This);
419 ITSS_UnlockModule();
422 return ref;
425 static HRESULT WINAPI ITS_IParseDisplayNameImpl_ParseDisplayName(
426 IParseDisplayName *iface,
427 IBindCtx * pbc,
428 LPOLESTR pszDisplayName,
429 ULONG * pchEaten,
430 IMoniker ** ppmkOut)
432 static const WCHAR szPrefix[] = L"@MSITStore:";
433 const DWORD prefix_len = ARRAY_SIZE(szPrefix)-1;
434 DWORD n;
436 ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
438 TRACE("%p %s %p %p\n", This,
439 debugstr_w( pszDisplayName ), pchEaten, ppmkOut );
441 if( wcsnicmp( pszDisplayName, szPrefix, prefix_len ) )
442 return MK_E_SYNTAX;
444 /* search backwards for a double colon */
445 for( n = lstrlenW( pszDisplayName ) - 3; prefix_len <= n; n-- )
446 if( ( pszDisplayName[n] == ':' ) && ( pszDisplayName[n+1] == ':' ) )
447 break;
449 if( n < prefix_len )
450 return MK_E_SYNTAX;
452 if( !pszDisplayName[n+2] )
453 return MK_E_SYNTAX;
455 *pchEaten = lstrlenW( pszDisplayName ) - n - 3;
457 return ITS_IMoniker_create( ppmkOut,
458 &pszDisplayName[prefix_len], n-prefix_len );
461 static const IParseDisplayNameVtbl ITS_IParseDisplayNameImpl_Vtbl =
463 ITS_IParseDisplayNameImpl_QueryInterface,
464 ITS_IParseDisplayNameImpl_AddRef,
465 ITS_IParseDisplayNameImpl_Release,
466 ITS_IParseDisplayNameImpl_ParseDisplayName
469 HRESULT ITS_IParseDisplayName_create(IUnknown *pUnkOuter, LPVOID *ppObj)
471 ITS_IParseDisplayNameImpl *its;
473 if( pUnkOuter )
474 return CLASS_E_NOAGGREGATION;
476 its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITS_IParseDisplayNameImpl) );
477 its->IParseDisplayName_iface.lpVtbl = &ITS_IParseDisplayNameImpl_Vtbl;
478 its->ref = 1;
480 TRACE("-> %p\n", its);
481 *ppObj = its;
483 ITSS_LockModule();
484 return S_OK;