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
34 #include "wine/itss.h"
35 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(itss
);
41 /*****************************************************************************/
44 IMoniker IMoniker_iface
;
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(
61 ITS_IMonikerImpl
*This
= impl_from_IMoniker(iface
);
63 if (IsEqualGUID(riid
, &IID_IUnknown
)
64 || IsEqualGUID(riid
, &IID_IParseDisplayName
))
66 IMoniker_AddRef(iface
);
71 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
75 static ULONG WINAPI
ITS_IMonikerImpl_AddRef(
78 ITS_IMonikerImpl
*This
= impl_from_IMoniker(iface
);
80 return InterlockedIncrement(&This
->ref
);
83 static ULONG WINAPI
ITS_IMonikerImpl_Release(
86 ITS_IMonikerImpl
*This
= impl_from_IMoniker(iface
);
87 ULONG ref
= InterlockedDecrement(&This
->ref
);
90 HeapFree(GetProcessHeap(), 0, This
);
97 /*** IPersist methods ***/
98 static HRESULT WINAPI
ITS_IMonikerImpl_GetClassID(
102 ITS_IMonikerImpl
*This
= impl_from_IMoniker(iface
);
104 TRACE("%p %p\n", This
, pClassID
);
105 *pClassID
= CLSID_ITStorage
;
109 /*** IPersistStream methods ***/
110 static HRESULT WINAPI
ITS_IMonikerImpl_IsDirty(
117 static HRESULT WINAPI
ITS_IMonikerImpl_Load(
125 static HRESULT WINAPI
ITS_IMonikerImpl_Save(
134 static HRESULT WINAPI
ITS_IMonikerImpl_GetSizeMax(
136 ULARGE_INTEGER
* pcbSize
)
142 /*** IMoniker methods ***/
143 static HRESULT WINAPI
ITS_IMonikerImpl_BindToObject(
154 static HRESULT WINAPI
ITS_IMonikerImpl_BindToStorage(
161 ITS_IMonikerImpl
*This
= impl_from_IMoniker(iface
);
162 DWORD grfMode
= STGM_SIMPLE
| STGM_READ
| STGM_SHARE_EXCLUSIVE
;
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
);
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
);
180 r
= STG_E_ACCESSDENIED
;
181 IStorage_Release( stg
);
187 static HRESULT WINAPI
ITS_IMonikerImpl_Reduce(
190 DWORD dwReduceHowFar
,
191 IMoniker
** ppmkToLeft
,
192 IMoniker
** ppmkReduced
)
198 static HRESULT WINAPI
ITS_IMonikerImpl_ComposeWith(
201 BOOL fOnlyIfNotGeneric
,
202 IMoniker
** ppmkComposite
)
208 static HRESULT WINAPI
ITS_IMonikerImpl_Enum(
211 IEnumMoniker
** ppenumMoniker
)
217 static HRESULT WINAPI
ITS_IMonikerImpl_IsEqual(
219 IMoniker
* pmkOtherMoniker
)
225 static HRESULT WINAPI
ITS_IMonikerImpl_Hash(
233 static HRESULT WINAPI
ITS_IMonikerImpl_IsRunning(
237 IMoniker
* pmkNewlyRunning
)
243 static HRESULT WINAPI
ITS_IMonikerImpl_GetTimeOfLastChange(
253 static HRESULT WINAPI
ITS_IMonikerImpl_Inverse(
261 static HRESULT WINAPI
ITS_IMonikerImpl_CommonPrefixWith(
264 IMoniker
** ppmkPrefix
)
270 static HRESULT WINAPI
ITS_IMonikerImpl_RelativePathTo(
273 IMoniker
** ppmkRelPath
)
279 static HRESULT WINAPI
ITS_IMonikerImpl_GetDisplayName(
283 LPOLESTR
* ppszDisplayName
)
285 ITS_IMonikerImpl
*This
= impl_from_IMoniker(iface
);
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
;
300 static HRESULT WINAPI
ITS_IMonikerImpl_ParseDisplayName(
304 LPOLESTR pszDisplayName
,
312 static HRESULT WINAPI
ITS_IMonikerImpl_IsSystemMoniker(
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
;
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
;
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
;
372 /*****************************************************************************/
375 IParseDisplayName IParseDisplayName_iface
;
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
,
389 ITS_IParseDisplayNameImpl
*This
= impl_from_IParseDisplayName(iface
);
391 if (IsEqualGUID(riid
, &IID_IUnknown
)
392 || IsEqualGUID(riid
, &IID_IParseDisplayName
))
394 IParseDisplayName_AddRef(iface
);
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
);
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
);
418 HeapFree(GetProcessHeap(), 0, This
);
425 static HRESULT WINAPI
ITS_IParseDisplayNameImpl_ParseDisplayName(
426 IParseDisplayName
*iface
,
428 LPOLESTR pszDisplayName
,
432 static const WCHAR szPrefix
[] = L
"@MSITStore:";
433 const DWORD prefix_len
= ARRAY_SIZE(szPrefix
)-1;
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
) )
444 /* search backwards for a double colon */
445 for( n
= lstrlenW( pszDisplayName
) - 3; prefix_len
<= n
; n
-- )
446 if( ( pszDisplayName
[n
] == ':' ) && ( pszDisplayName
[n
+1] == ':' ) )
452 if( !pszDisplayName
[n
+2] )
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
;
474 return CLASS_E_NOAGGREGATION
;
476 its
= HeapAlloc( GetProcessHeap(), 0, sizeof(ITS_IParseDisplayNameImpl
) );
477 its
->IParseDisplayName_iface
.lpVtbl
= &ITS_IParseDisplayNameImpl_Vtbl
;
480 TRACE("-> %p\n", its
);