wineoss.drv: Avoid potential overflow (Coverity).
[wine.git] / dlls / itss / moniker.c
blob0509c9e1a5fc22c391e3f8c0cc9e33334b710cd6
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
23 #include "config.h"
25 #include <stdarg.h>
26 #include <stdio.h>
28 #define COBJMACROS
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winuser.h"
33 #include "ole2.h"
35 #include "wine/itss.h"
36 #include "wine/unicode.h"
37 #include "wine/debug.h"
39 #include "itsstor.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(itss);
43 /*****************************************************************************/
45 typedef struct {
46 IMoniker IMoniker_iface;
47 LONG ref;
48 LPWSTR szHtml;
49 WCHAR szFile[1];
50 } ITS_IMonikerImpl;
52 static inline ITS_IMonikerImpl *impl_from_IMoniker(IMoniker *iface)
54 return CONTAINING_RECORD(iface, ITS_IMonikerImpl, IMoniker_iface);
57 /*** IUnknown methods ***/
58 static HRESULT WINAPI ITS_IMonikerImpl_QueryInterface(
59 IMoniker* iface,
60 REFIID riid,
61 void** ppvObject)
63 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
65 if (IsEqualGUID(riid, &IID_IUnknown)
66 || IsEqualGUID(riid, &IID_IParseDisplayName))
68 IMoniker_AddRef(iface);
69 *ppvObject = iface;
70 return S_OK;
73 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
74 return E_NOINTERFACE;
77 static ULONG WINAPI ITS_IMonikerImpl_AddRef(
78 IMoniker* iface)
80 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
81 TRACE("%p\n", This);
82 return InterlockedIncrement(&This->ref);
85 static ULONG WINAPI ITS_IMonikerImpl_Release(
86 IMoniker* iface)
88 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
89 ULONG ref = InterlockedDecrement(&This->ref);
91 if (ref == 0) {
92 HeapFree(GetProcessHeap(), 0, This);
93 ITSS_UnlockModule();
96 return ref;
99 /*** IPersist methods ***/
100 static HRESULT WINAPI ITS_IMonikerImpl_GetClassID(
101 IMoniker* iface,
102 CLSID* pClassID)
104 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
106 TRACE("%p %p\n", This, pClassID);
107 *pClassID = CLSID_ITStorage;
108 return S_OK;
111 /*** IPersistStream methods ***/
112 static HRESULT WINAPI ITS_IMonikerImpl_IsDirty(
113 IMoniker* iface)
115 FIXME("\n");
116 return E_NOTIMPL;
119 static HRESULT WINAPI ITS_IMonikerImpl_Load(
120 IMoniker* iface,
121 IStream* pStm)
123 FIXME("\n");
124 return E_NOTIMPL;
127 static HRESULT WINAPI ITS_IMonikerImpl_Save(
128 IMoniker* iface,
129 IStream* pStm,
130 BOOL fClearDirty)
132 FIXME("\n");
133 return E_NOTIMPL;
136 static HRESULT WINAPI ITS_IMonikerImpl_GetSizeMax(
137 IMoniker* iface,
138 ULARGE_INTEGER* pcbSize)
140 FIXME("\n");
141 return E_NOTIMPL;
144 /*** IMoniker methods ***/
145 static HRESULT WINAPI ITS_IMonikerImpl_BindToObject(
146 IMoniker* iface,
147 IBindCtx* pbc,
148 IMoniker* pmkToLeft,
149 REFIID riidResult,
150 void** ppvResult)
152 FIXME("\n");
153 return E_NOTIMPL;
156 static HRESULT WINAPI ITS_IMonikerImpl_BindToStorage(
157 IMoniker* iface,
158 IBindCtx* pbc,
159 IMoniker* pmkToLeft,
160 REFIID riid,
161 void** ppvObj)
163 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
164 DWORD grfMode = STGM_SIMPLE | STGM_READ | STGM_SHARE_EXCLUSIVE;
165 HRESULT r;
166 IStorage *stg = NULL;
168 TRACE("%p %p %p %s %p\n", This,
169 pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
171 r = ITSS_StgOpenStorage( This->szFile, NULL, grfMode, 0, 0, &stg );
172 if( r == S_OK )
174 TRACE("Opened storage %s\n", debugstr_w( This->szFile ) );
175 if (IsEqualGUID(riid, &IID_IStream))
176 r = IStorage_OpenStream( stg, This->szHtml,
177 NULL, grfMode, 0, (IStream**)ppvObj );
178 else if (IsEqualGUID(riid, &IID_IStorage))
179 r = IStorage_OpenStorage( stg, This->szHtml,
180 NULL, grfMode, NULL, 0, (IStorage**)ppvObj );
181 else
182 r = STG_E_ACCESSDENIED;
183 IStorage_Release( stg );
186 return r;
189 static HRESULT WINAPI ITS_IMonikerImpl_Reduce(
190 IMoniker* iface,
191 IBindCtx* pbc,
192 DWORD dwReduceHowFar,
193 IMoniker** ppmkToLeft,
194 IMoniker** ppmkReduced)
196 FIXME("\n");
197 return E_NOTIMPL;
200 static HRESULT WINAPI ITS_IMonikerImpl_ComposeWith(
201 IMoniker* iface,
202 IMoniker* pmkRight,
203 BOOL fOnlyIfNotGeneric,
204 IMoniker** ppmkComposite)
206 FIXME("\n");
207 return E_NOTIMPL;
210 static HRESULT WINAPI ITS_IMonikerImpl_Enum(
211 IMoniker* iface,
212 BOOL fForward,
213 IEnumMoniker** ppenumMoniker)
215 FIXME("\n");
216 return E_NOTIMPL;
219 static HRESULT WINAPI ITS_IMonikerImpl_IsEqual(
220 IMoniker* iface,
221 IMoniker* pmkOtherMoniker)
223 FIXME("\n");
224 return E_NOTIMPL;
227 static HRESULT WINAPI ITS_IMonikerImpl_Hash(
228 IMoniker* iface,
229 DWORD* pdwHash)
231 FIXME("\n");
232 return E_NOTIMPL;
235 static HRESULT WINAPI ITS_IMonikerImpl_IsRunning(
236 IMoniker* iface,
237 IBindCtx* pbc,
238 IMoniker* pmkToLeft,
239 IMoniker* pmkNewlyRunning)
241 FIXME("\n");
242 return E_NOTIMPL;
245 static HRESULT WINAPI ITS_IMonikerImpl_GetTimeOfLastChange(
246 IMoniker* iface,
247 IBindCtx* pbc,
248 IMoniker* pmkToLeft,
249 FILETIME* pFileTime)
251 FIXME("\n");
252 return E_NOTIMPL;
255 static HRESULT WINAPI ITS_IMonikerImpl_Inverse(
256 IMoniker* iface,
257 IMoniker** ppmk)
259 FIXME("\n");
260 return E_NOTIMPL;
263 static HRESULT WINAPI ITS_IMonikerImpl_CommonPrefixWith(
264 IMoniker* iface,
265 IMoniker* pmkOther,
266 IMoniker** ppmkPrefix)
268 FIXME("\n");
269 return E_NOTIMPL;
272 static HRESULT WINAPI ITS_IMonikerImpl_RelativePathTo(
273 IMoniker* iface,
274 IMoniker* pmkOther,
275 IMoniker** ppmkRelPath)
277 FIXME("\n");
278 return E_NOTIMPL;
281 static HRESULT WINAPI ITS_IMonikerImpl_GetDisplayName(
282 IMoniker* iface,
283 IBindCtx* pbc,
284 IMoniker* pmkToLeft,
285 LPOLESTR* ppszDisplayName)
287 ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
288 static const WCHAR szFormat[] = {
289 'm','s','-','i','t','s',':','%','s',':',':','%','s',0 };
290 DWORD len = sizeof szFormat / sizeof(WCHAR);
291 LPWSTR str;
293 TRACE("%p %p %p %p\n", iface, pbc, pmkToLeft, ppszDisplayName);
295 len = strlenW( This->szFile ) + strlenW( This->szHtml );
296 str = CoTaskMemAlloc( len*sizeof(WCHAR) );
297 sprintfW( str, szFormat, This->szFile, This->szHtml );
299 *ppszDisplayName = str;
301 return S_OK;
304 static HRESULT WINAPI ITS_IMonikerImpl_ParseDisplayName(
305 IMoniker* iface,
306 IBindCtx* pbc,
307 IMoniker* pmkToLeft,
308 LPOLESTR pszDisplayName,
309 ULONG* pchEaten,
310 IMoniker** ppmkOut)
312 FIXME("\n");
313 return E_NOTIMPL;
316 static HRESULT WINAPI ITS_IMonikerImpl_IsSystemMoniker(
317 IMoniker* iface,
318 DWORD* pdwMksys)
320 FIXME("\n");
321 return E_NOTIMPL;
324 static const IMonikerVtbl ITS_IMonikerImpl_Vtbl =
326 ITS_IMonikerImpl_QueryInterface,
327 ITS_IMonikerImpl_AddRef,
328 ITS_IMonikerImpl_Release,
329 ITS_IMonikerImpl_GetClassID,
330 ITS_IMonikerImpl_IsDirty,
331 ITS_IMonikerImpl_Load,
332 ITS_IMonikerImpl_Save,
333 ITS_IMonikerImpl_GetSizeMax,
334 ITS_IMonikerImpl_BindToObject,
335 ITS_IMonikerImpl_BindToStorage,
336 ITS_IMonikerImpl_Reduce,
337 ITS_IMonikerImpl_ComposeWith,
338 ITS_IMonikerImpl_Enum,
339 ITS_IMonikerImpl_IsEqual,
340 ITS_IMonikerImpl_Hash,
341 ITS_IMonikerImpl_IsRunning,
342 ITS_IMonikerImpl_GetTimeOfLastChange,
343 ITS_IMonikerImpl_Inverse,
344 ITS_IMonikerImpl_CommonPrefixWith,
345 ITS_IMonikerImpl_RelativePathTo,
346 ITS_IMonikerImpl_GetDisplayName,
347 ITS_IMonikerImpl_ParseDisplayName,
348 ITS_IMonikerImpl_IsSystemMoniker
351 static HRESULT ITS_IMoniker_create( IMoniker **ppObj, LPCWSTR name, DWORD n )
353 ITS_IMonikerImpl *itsmon;
354 DWORD sz;
356 /* szFile[1] has space for one character already */
357 sz = FIELD_OFFSET( ITS_IMonikerImpl, szFile[strlenW( name ) + 1] );
359 itsmon = HeapAlloc( GetProcessHeap(), 0, sz );
360 itsmon->IMoniker_iface.lpVtbl = &ITS_IMonikerImpl_Vtbl;
361 itsmon->ref = 1;
362 strcpyW( itsmon->szFile, name );
363 itsmon->szHtml = &itsmon->szFile[n];
365 while( *itsmon->szHtml == ':' )
366 *itsmon->szHtml++ = 0;
368 TRACE("-> %p %s %s\n", itsmon,
369 debugstr_w(itsmon->szFile), debugstr_w(itsmon->szHtml) );
370 *ppObj = &itsmon->IMoniker_iface;
372 ITSS_LockModule();
373 return S_OK;
376 /*****************************************************************************/
378 typedef struct {
379 IParseDisplayName IParseDisplayName_iface;
380 LONG ref;
381 } ITS_IParseDisplayNameImpl;
383 static inline ITS_IParseDisplayNameImpl *impl_from_IParseDisplayName(IParseDisplayName *iface)
385 return CONTAINING_RECORD(iface, ITS_IParseDisplayNameImpl, IParseDisplayName_iface);
388 static HRESULT WINAPI ITS_IParseDisplayNameImpl_QueryInterface(
389 IParseDisplayName* iface,
390 REFIID riid,
391 void** ppvObject)
393 ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
395 if (IsEqualGUID(riid, &IID_IUnknown)
396 || IsEqualGUID(riid, &IID_IParseDisplayName))
398 IParseDisplayName_AddRef(iface);
399 *ppvObject = iface;
400 return S_OK;
403 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
404 return E_NOINTERFACE;
407 static ULONG WINAPI ITS_IParseDisplayNameImpl_AddRef(
408 IParseDisplayName* iface)
410 ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
411 TRACE("%p\n", This);
412 return InterlockedIncrement(&This->ref);
415 static ULONG WINAPI ITS_IParseDisplayNameImpl_Release(
416 IParseDisplayName* iface)
418 ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
419 ULONG ref = InterlockedDecrement(&This->ref);
421 if (ref == 0) {
422 HeapFree(GetProcessHeap(), 0, This);
423 ITSS_UnlockModule();
426 return ref;
429 static HRESULT WINAPI ITS_IParseDisplayNameImpl_ParseDisplayName(
430 IParseDisplayName *iface,
431 IBindCtx * pbc,
432 LPOLESTR pszDisplayName,
433 ULONG * pchEaten,
434 IMoniker ** ppmkOut)
436 static const WCHAR szPrefix[] = {
437 '@','M','S','I','T','S','t','o','r','e',':',0 };
438 const DWORD prefix_len = (sizeof szPrefix/sizeof szPrefix[0])-1;
439 DWORD n;
441 ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
443 TRACE("%p %s %p %p\n", This,
444 debugstr_w( pszDisplayName ), pchEaten, ppmkOut );
446 if( strncmpiW( pszDisplayName, szPrefix, prefix_len ) )
447 return MK_E_SYNTAX;
449 /* search backwards for a double colon */
450 for( n = strlenW( pszDisplayName ) - 3; prefix_len <= n; n-- )
451 if( ( pszDisplayName[n] == ':' ) && ( pszDisplayName[n+1] == ':' ) )
452 break;
454 if( n < prefix_len )
455 return MK_E_SYNTAX;
457 if( !pszDisplayName[n+2] )
458 return MK_E_SYNTAX;
460 *pchEaten = strlenW( pszDisplayName ) - n - 3;
462 return ITS_IMoniker_create( ppmkOut,
463 &pszDisplayName[prefix_len], n-prefix_len );
466 static const IParseDisplayNameVtbl ITS_IParseDisplayNameImpl_Vtbl =
468 ITS_IParseDisplayNameImpl_QueryInterface,
469 ITS_IParseDisplayNameImpl_AddRef,
470 ITS_IParseDisplayNameImpl_Release,
471 ITS_IParseDisplayNameImpl_ParseDisplayName
474 HRESULT ITS_IParseDisplayName_create(IUnknown *pUnkOuter, LPVOID *ppObj)
476 ITS_IParseDisplayNameImpl *its;
478 if( pUnkOuter )
479 return CLASS_E_NOAGGREGATION;
481 its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITS_IParseDisplayNameImpl) );
482 its->IParseDisplayName_iface.lpVtbl = &ITS_IParseDisplayNameImpl_Vtbl;
483 its->ref = 1;
485 TRACE("-> %p\n", its);
486 *ppObj = its;
488 ITSS_LockModule();
489 return S_OK;