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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 #include "wine/unicode.h"
41 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(itss);
47 /*****************************************************************************/
50 IMonikerVtbl *vtbl_ITS_IMoniker;
56 /*** IUnknown methods ***/
57 static HRESULT WINAPI ITS_IMonikerImpl_QueryInterface(
62 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
64 if (IsEqualGUID(riid, &IID_IUnknown)
65 || IsEqualGUID(riid, &IID_IParseDisplayName))
67 IClassFactory_AddRef(iface);
72 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
76 static ULONG WINAPI ITS_IMonikerImpl_AddRef(
79 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
84 static ULONG WINAPI ITS_IMonikerImpl_Release(
87 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
88 ULONG ref = --This->ref;
91 HeapFree(GetProcessHeap(), 0, This);
96 /*** IPersist methods ***/
97 static HRESULT WINAPI ITS_IMonikerImpl_GetClassID(
101 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
103 TRACE("%p %p\n", This, pClassID);
104 memcpy( pClassID, &CLSID_ITStorage, sizeof (CLSID) );
108 /*** IPersistStream methods ***/
109 static HRESULT WINAPI ITS_IMonikerImpl_IsDirty(
116 static HRESULT WINAPI ITS_IMonikerImpl_Load(
124 static HRESULT WINAPI ITS_IMonikerImpl_Save(
133 static HRESULT WINAPI ITS_IMonikerImpl_GetSizeMax(
135 ULARGE_INTEGER* pcbSize)
141 /*** IMoniker methods ***/
142 static HRESULT WINAPI ITS_IMonikerImpl_BindToObject(
153 static HRESULT WINAPI ITS_IMonikerImpl_BindToStorage(
160 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
161 DWORD grfMode = STGM_SIMPLE | STGM_READ | STGM_SHARE_EXCLUSIVE;
163 IStorage *stg = NULL;
165 TRACE("%p %p %p %s %p\n", This,
166 pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
168 r = ITSS_StgOpenStorage( This->szFile, NULL, grfMode, 0, 0, &stg );
171 TRACE("Opened storage %s\n", debugstr_w( This->szFile ) );
172 if (IsEqualGUID(riid, &IID_IStream))
173 r = IStorage_OpenStream( stg, This->szHtml,
174 NULL, grfMode, 0, (IStream**)ppvObj );
175 else if (IsEqualGUID(riid, &IID_IStorage))
176 r = IStorage_OpenStorage( stg, This->szHtml,
177 NULL, grfMode, NULL, 0, (IStorage**)ppvObj );
179 r = STG_E_ACCESSDENIED;
180 IStorage_Release( stg );
186 static HRESULT WINAPI ITS_IMonikerImpl_Reduce(
189 DWORD dwReduceHowFar,
190 IMoniker** ppmkToLeft,
191 IMoniker** ppmkReduced)
197 static HRESULT WINAPI ITS_IMonikerImpl_ComposeWith(
200 BOOL fOnlyIfNotGeneric,
201 IMoniker** ppmkComposite)
207 static HRESULT WINAPI ITS_IMonikerImpl_Enum(
210 IEnumMoniker** ppenumMoniker)
216 static HRESULT WINAPI ITS_IMonikerImpl_IsEqual(
218 IMoniker* pmkOtherMoniker)
224 static HRESULT WINAPI ITS_IMonikerImpl_Hash(
232 static HRESULT WINAPI ITS_IMonikerImpl_IsRunning(
236 IMoniker* pmkNewlyRunning)
242 static HRESULT WINAPI ITS_IMonikerImpl_GetTimeOfLastChange(
252 static HRESULT WINAPI ITS_IMonikerImpl_Inverse(
260 static HRESULT WINAPI ITS_IMonikerImpl_CommonPrefixWith(
263 IMoniker** ppmkPrefix)
269 static HRESULT WINAPI ITS_IMonikerImpl_RelativePathTo(
272 IMoniker** ppmkRelPath)
278 static HRESULT WINAPI ITS_IMonikerImpl_GetDisplayName(
282 LPOLESTR* ppszDisplayName)
284 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
285 static const WCHAR szFormat[] = {
286 'm','s','-','i','t','s',':','%','s',':',':','%','s',0 };
287 DWORD len = sizeof szFormat / sizeof(WCHAR);
290 TRACE("%p %p %p %p\n", iface, pbc, pmkToLeft, ppszDisplayName);
292 len = strlenW( This->szFile ) + strlenW( This->szHtml );
293 str = CoTaskMemAlloc( len*sizeof(WCHAR) );
294 sprintfW( str, szFormat, This->szFile, This->szHtml );
296 *ppszDisplayName = str;
301 static HRESULT WINAPI ITS_IMonikerImpl_ParseDisplayName(
305 LPOLESTR pszDisplayName,
313 static HRESULT WINAPI ITS_IMonikerImpl_IsSystemMoniker(
321 static IMonikerVtbl ITS_IMonikerImpl_Vtbl =
323 ITS_IMonikerImpl_QueryInterface,
324 ITS_IMonikerImpl_AddRef,
325 ITS_IMonikerImpl_Release,
326 ITS_IMonikerImpl_GetClassID,
327 ITS_IMonikerImpl_IsDirty,
328 ITS_IMonikerImpl_Load,
329 ITS_IMonikerImpl_Save,
330 ITS_IMonikerImpl_GetSizeMax,
331 ITS_IMonikerImpl_BindToObject,
332 ITS_IMonikerImpl_BindToStorage,
333 ITS_IMonikerImpl_Reduce,
334 ITS_IMonikerImpl_ComposeWith,
335 ITS_IMonikerImpl_Enum,
336 ITS_IMonikerImpl_IsEqual,
337 ITS_IMonikerImpl_Hash,
338 ITS_IMonikerImpl_IsRunning,
339 ITS_IMonikerImpl_GetTimeOfLastChange,
340 ITS_IMonikerImpl_Inverse,
341 ITS_IMonikerImpl_CommonPrefixWith,
342 ITS_IMonikerImpl_RelativePathTo,
343 ITS_IMonikerImpl_GetDisplayName,
344 ITS_IMonikerImpl_ParseDisplayName,
345 ITS_IMonikerImpl_IsSystemMoniker
348 static HRESULT ITS_IMoniker_create( IMoniker **ppObj, LPWSTR name, DWORD n )
350 ITS_IMonikerImpl *itsmon;
353 /* szFile[1] has space for one character already */
354 sz = sizeof(ITS_IMonikerImpl) + strlenW( name )*sizeof(WCHAR);
356 itsmon = HeapAlloc( GetProcessHeap(), 0, sz );
357 itsmon->vtbl_ITS_IMoniker = &ITS_IMonikerImpl_Vtbl;
359 strcpyW( itsmon->szFile, name );
360 itsmon->szHtml = &itsmon->szFile[n];
362 while( *itsmon->szHtml == ':' )
363 *itsmon->szHtml++ = 0;
365 TRACE("-> %p %s %s\n", itsmon,
366 debugstr_w(itsmon->szFile), debugstr_w(itsmon->szHtml) );
367 *ppObj = (IMoniker*) itsmon;
372 /*****************************************************************************/
375 IParseDisplayNameVtbl *vtbl_ITS_IParseDisplayName;
377 } ITS_IParseDisplayNameImpl;
379 static HRESULT WINAPI ITS_IParseDisplayNameImpl_QueryInterface(
380 IParseDisplayName* iface,
384 ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
386 if (IsEqualGUID(riid, &IID_IUnknown)
387 || IsEqualGUID(riid, &IID_IParseDisplayName))
389 IClassFactory_AddRef(iface);
394 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
395 return E_NOINTERFACE;
398 static ULONG WINAPI ITS_IParseDisplayNameImpl_AddRef(
399 IParseDisplayName* iface)
401 ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
403 return ++(This->ref);
406 static ULONG WINAPI ITS_IParseDisplayNameImpl_Release(
407 IParseDisplayName* iface)
409 ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
410 ULONG ref = --This->ref;
413 HeapFree(GetProcessHeap(), 0, This);
418 static HRESULT WINAPI ITS_IParseDisplayNameImpl_ParseDisplayName(
419 IParseDisplayName *iface,
421 LPOLESTR pszDisplayName,
425 static const WCHAR szPrefix[] = {
426 '@','M','S','I','T','S','t','o','r','e',':',0 };
427 const DWORD prefix_len = (sizeof szPrefix/sizeof szPrefix[0])-1;
430 ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
432 TRACE("%p %s %p %p\n", This,
433 debugstr_w( pszDisplayName ), pchEaten, ppmkOut );
435 if( strncmpW( pszDisplayName, szPrefix, prefix_len ) )
438 /* search backwards for a double colon */
439 for( n = strlenW( pszDisplayName ) - 3; prefix_len <= n; n-- )
440 if( ( pszDisplayName[n] == ':' ) && ( pszDisplayName[n+1] == ':' ) )
446 if( !pszDisplayName[n+2] )
449 *pchEaten = strlenW( pszDisplayName ) - n - 3;
451 return ITS_IMoniker_create( ppmkOut,
452 &pszDisplayName[prefix_len], n-prefix_len );
455 static IParseDisplayNameVtbl ITS_IParseDisplayNameImpl_Vtbl =
457 ITS_IParseDisplayNameImpl_QueryInterface,
458 ITS_IParseDisplayNameImpl_AddRef,
459 ITS_IParseDisplayNameImpl_Release,
460 ITS_IParseDisplayNameImpl_ParseDisplayName
463 HRESULT ITS_IParseDisplayName_create(IUnknown *pUnkOuter, LPVOID *ppObj)
465 ITS_IParseDisplayNameImpl *its;
467 its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITS_IParseDisplayNameImpl) );
468 its->vtbl_ITS_IParseDisplayName = &ITS_IParseDisplayNameImpl_Vtbl;
471 TRACE("-> %p\n", its);
472 *ppObj = (LPVOID) its;