ntdll: Fix race in NtRead/WriteFile.
[wine/testsucceed.git] / dlls / itss / moniker.c
blob76630cd518e650f1f998c76a0c07b00d6a05338b
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 const IMonikerVtbl *vtbl_ITS_IMoniker;
47 LONG ref;
48 LPWSTR szHtml;
49 WCHAR szFile[1];
50 } ITS_IMonikerImpl;
52 /*** IUnknown methods ***/
53 static HRESULT WINAPI ITS_IMonikerImpl_QueryInterface(
54 IMoniker* iface,
55 REFIID riid,
56 void** ppvObject)
58 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
60 if (IsEqualGUID(riid, &IID_IUnknown)
61 || IsEqualGUID(riid, &IID_IParseDisplayName))
63 IClassFactory_AddRef(iface);
64 *ppvObject = This;
65 return S_OK;
68 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
69 return E_NOINTERFACE;
72 static ULONG WINAPI ITS_IMonikerImpl_AddRef(
73 IMoniker* iface)
75 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
76 TRACE("%p\n", This);
77 return InterlockedIncrement(&This->ref);
80 static ULONG WINAPI ITS_IMonikerImpl_Release(
81 IMoniker* iface)
83 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
84 ULONG ref = InterlockedDecrement(&This->ref);
86 if (ref == 0) {
87 HeapFree(GetProcessHeap(), 0, This);
88 ITSS_UnlockModule();
91 return ref;
94 /*** IPersist methods ***/
95 static HRESULT WINAPI ITS_IMonikerImpl_GetClassID(
96 IMoniker* iface,
97 CLSID* pClassID)
99 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
101 TRACE("%p %p\n", This, pClassID);
102 *pClassID = CLSID_ITStorage;
103 return S_OK;
106 /*** IPersistStream methods ***/
107 static HRESULT WINAPI ITS_IMonikerImpl_IsDirty(
108 IMoniker* iface)
110 FIXME("\n");
111 return E_NOTIMPL;
114 static HRESULT WINAPI ITS_IMonikerImpl_Load(
115 IMoniker* iface,
116 IStream* pStm)
118 FIXME("\n");
119 return E_NOTIMPL;
122 static HRESULT WINAPI ITS_IMonikerImpl_Save(
123 IMoniker* iface,
124 IStream* pStm,
125 BOOL fClearDirty)
127 FIXME("\n");
128 return E_NOTIMPL;
131 static HRESULT WINAPI ITS_IMonikerImpl_GetSizeMax(
132 IMoniker* iface,
133 ULARGE_INTEGER* pcbSize)
135 FIXME("\n");
136 return E_NOTIMPL;
139 /*** IMoniker methods ***/
140 static HRESULT WINAPI ITS_IMonikerImpl_BindToObject(
141 IMoniker* iface,
142 IBindCtx* pbc,
143 IMoniker* pmkToLeft,
144 REFIID riidResult,
145 void** ppvResult)
147 FIXME("\n");
148 return E_NOTIMPL;
151 static HRESULT WINAPI ITS_IMonikerImpl_BindToStorage(
152 IMoniker* iface,
153 IBindCtx* pbc,
154 IMoniker* pmkToLeft,
155 REFIID riid,
156 void** ppvObj)
158 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
159 DWORD grfMode = STGM_SIMPLE | STGM_READ | STGM_SHARE_EXCLUSIVE;
160 HRESULT r;
161 IStorage *stg = NULL;
163 TRACE("%p %p %p %s %p\n", This,
164 pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
166 r = ITSS_StgOpenStorage( This->szFile, NULL, grfMode, 0, 0, &stg );
167 if( r == S_OK )
169 TRACE("Opened storage %s\n", debugstr_w( This->szFile ) );
170 if (IsEqualGUID(riid, &IID_IStream))
171 r = IStorage_OpenStream( stg, This->szHtml,
172 NULL, grfMode, 0, (IStream**)ppvObj );
173 else if (IsEqualGUID(riid, &IID_IStorage))
174 r = IStorage_OpenStorage( stg, This->szHtml,
175 NULL, grfMode, NULL, 0, (IStorage**)ppvObj );
176 else
177 r = STG_E_ACCESSDENIED;
178 IStorage_Release( stg );
181 return r;
184 static HRESULT WINAPI ITS_IMonikerImpl_Reduce(
185 IMoniker* iface,
186 IBindCtx* pbc,
187 DWORD dwReduceHowFar,
188 IMoniker** ppmkToLeft,
189 IMoniker** ppmkReduced)
191 FIXME("\n");
192 return E_NOTIMPL;
195 static HRESULT WINAPI ITS_IMonikerImpl_ComposeWith(
196 IMoniker* iface,
197 IMoniker* pmkRight,
198 BOOL fOnlyIfNotGeneric,
199 IMoniker** ppmkComposite)
201 FIXME("\n");
202 return E_NOTIMPL;
205 static HRESULT WINAPI ITS_IMonikerImpl_Enum(
206 IMoniker* iface,
207 BOOL fForward,
208 IEnumMoniker** ppenumMoniker)
210 FIXME("\n");
211 return E_NOTIMPL;
214 static HRESULT WINAPI ITS_IMonikerImpl_IsEqual(
215 IMoniker* iface,
216 IMoniker* pmkOtherMoniker)
218 FIXME("\n");
219 return E_NOTIMPL;
222 static HRESULT WINAPI ITS_IMonikerImpl_Hash(
223 IMoniker* iface,
224 DWORD* pdwHash)
226 FIXME("\n");
227 return E_NOTIMPL;
230 static HRESULT WINAPI ITS_IMonikerImpl_IsRunning(
231 IMoniker* iface,
232 IBindCtx* pbc,
233 IMoniker* pmkToLeft,
234 IMoniker* pmkNewlyRunning)
236 FIXME("\n");
237 return E_NOTIMPL;
240 static HRESULT WINAPI ITS_IMonikerImpl_GetTimeOfLastChange(
241 IMoniker* iface,
242 IBindCtx* pbc,
243 IMoniker* pmkToLeft,
244 FILETIME* pFileTime)
246 FIXME("\n");
247 return E_NOTIMPL;
250 static HRESULT WINAPI ITS_IMonikerImpl_Inverse(
251 IMoniker* iface,
252 IMoniker** ppmk)
254 FIXME("\n");
255 return E_NOTIMPL;
258 static HRESULT WINAPI ITS_IMonikerImpl_CommonPrefixWith(
259 IMoniker* iface,
260 IMoniker* pmkOther,
261 IMoniker** ppmkPrefix)
263 FIXME("\n");
264 return E_NOTIMPL;
267 static HRESULT WINAPI ITS_IMonikerImpl_RelativePathTo(
268 IMoniker* iface,
269 IMoniker* pmkOther,
270 IMoniker** ppmkRelPath)
272 FIXME("\n");
273 return E_NOTIMPL;
276 static HRESULT WINAPI ITS_IMonikerImpl_GetDisplayName(
277 IMoniker* iface,
278 IBindCtx* pbc,
279 IMoniker* pmkToLeft,
280 LPOLESTR* ppszDisplayName)
282 ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
283 static const WCHAR szFormat[] = {
284 'm','s','-','i','t','s',':','%','s',':',':','%','s',0 };
285 DWORD len = sizeof szFormat / sizeof(WCHAR);
286 LPWSTR str;
288 TRACE("%p %p %p %p\n", iface, pbc, pmkToLeft, ppszDisplayName);
290 len = strlenW( This->szFile ) + strlenW( This->szHtml );
291 str = CoTaskMemAlloc( len*sizeof(WCHAR) );
292 sprintfW( str, szFormat, This->szFile, This->szHtml );
294 *ppszDisplayName = str;
296 return S_OK;
299 static HRESULT WINAPI ITS_IMonikerImpl_ParseDisplayName(
300 IMoniker* iface,
301 IBindCtx* pbc,
302 IMoniker* pmkToLeft,
303 LPOLESTR pszDisplayName,
304 ULONG* pchEaten,
305 IMoniker** ppmkOut)
307 FIXME("\n");
308 return E_NOTIMPL;
311 static HRESULT WINAPI ITS_IMonikerImpl_IsSystemMoniker(
312 IMoniker* iface,
313 DWORD* pdwMksys)
315 FIXME("\n");
316 return E_NOTIMPL;
319 static const IMonikerVtbl ITS_IMonikerImpl_Vtbl =
321 ITS_IMonikerImpl_QueryInterface,
322 ITS_IMonikerImpl_AddRef,
323 ITS_IMonikerImpl_Release,
324 ITS_IMonikerImpl_GetClassID,
325 ITS_IMonikerImpl_IsDirty,
326 ITS_IMonikerImpl_Load,
327 ITS_IMonikerImpl_Save,
328 ITS_IMonikerImpl_GetSizeMax,
329 ITS_IMonikerImpl_BindToObject,
330 ITS_IMonikerImpl_BindToStorage,
331 ITS_IMonikerImpl_Reduce,
332 ITS_IMonikerImpl_ComposeWith,
333 ITS_IMonikerImpl_Enum,
334 ITS_IMonikerImpl_IsEqual,
335 ITS_IMonikerImpl_Hash,
336 ITS_IMonikerImpl_IsRunning,
337 ITS_IMonikerImpl_GetTimeOfLastChange,
338 ITS_IMonikerImpl_Inverse,
339 ITS_IMonikerImpl_CommonPrefixWith,
340 ITS_IMonikerImpl_RelativePathTo,
341 ITS_IMonikerImpl_GetDisplayName,
342 ITS_IMonikerImpl_ParseDisplayName,
343 ITS_IMonikerImpl_IsSystemMoniker
346 static HRESULT ITS_IMoniker_create( IMoniker **ppObj, LPCWSTR name, DWORD n )
348 ITS_IMonikerImpl *itsmon;
349 DWORD sz;
351 /* szFile[1] has space for one character already */
352 sz = sizeof(ITS_IMonikerImpl) + strlenW( name )*sizeof(WCHAR);
354 itsmon = HeapAlloc( GetProcessHeap(), 0, sz );
355 itsmon->vtbl_ITS_IMoniker = &ITS_IMonikerImpl_Vtbl;
356 itsmon->ref = 1;
357 strcpyW( itsmon->szFile, name );
358 itsmon->szHtml = &itsmon->szFile[n];
360 while( *itsmon->szHtml == ':' )
361 *itsmon->szHtml++ = 0;
363 TRACE("-> %p %s %s\n", itsmon,
364 debugstr_w(itsmon->szFile), debugstr_w(itsmon->szHtml) );
365 *ppObj = (IMoniker*) itsmon;
367 ITSS_LockModule();
368 return S_OK;
371 /*****************************************************************************/
373 typedef struct {
374 const IParseDisplayNameVtbl *vtbl_ITS_IParseDisplayName;
375 LONG ref;
376 } ITS_IParseDisplayNameImpl;
378 static HRESULT WINAPI ITS_IParseDisplayNameImpl_QueryInterface(
379 IParseDisplayName* iface,
380 REFIID riid,
381 void** ppvObject)
383 ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
385 if (IsEqualGUID(riid, &IID_IUnknown)
386 || IsEqualGUID(riid, &IID_IParseDisplayName))
388 IClassFactory_AddRef(iface);
389 *ppvObject = This;
390 return S_OK;
393 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
394 return E_NOINTERFACE;
397 static ULONG WINAPI ITS_IParseDisplayNameImpl_AddRef(
398 IParseDisplayName* iface)
400 ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
401 TRACE("%p\n", This);
402 return InterlockedIncrement(&This->ref);
405 static ULONG WINAPI ITS_IParseDisplayNameImpl_Release(
406 IParseDisplayName* iface)
408 ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
409 ULONG ref = InterlockedDecrement(&This->ref);
411 if (ref == 0) {
412 HeapFree(GetProcessHeap(), 0, This);
413 ITSS_UnlockModule();
416 return ref;
419 static HRESULT WINAPI ITS_IParseDisplayNameImpl_ParseDisplayName(
420 IParseDisplayName *iface,
421 IBindCtx * pbc,
422 LPOLESTR pszDisplayName,
423 ULONG * pchEaten,
424 IMoniker ** ppmkOut)
426 static const WCHAR szPrefix[] = {
427 '@','M','S','I','T','S','t','o','r','e',':',0 };
428 const DWORD prefix_len = (sizeof szPrefix/sizeof szPrefix[0])-1;
429 DWORD n;
431 ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
433 TRACE("%p %s %p %p\n", This,
434 debugstr_w( pszDisplayName ), pchEaten, ppmkOut );
436 if( strncmpW( pszDisplayName, szPrefix, prefix_len ) )
437 return MK_E_SYNTAX;
439 /* search backwards for a double colon */
440 for( n = strlenW( pszDisplayName ) - 3; prefix_len <= n; n-- )
441 if( ( pszDisplayName[n] == ':' ) && ( pszDisplayName[n+1] == ':' ) )
442 break;
444 if( n < prefix_len )
445 return MK_E_SYNTAX;
447 if( !pszDisplayName[n+2] )
448 return MK_E_SYNTAX;
450 *pchEaten = strlenW( pszDisplayName ) - n - 3;
452 return ITS_IMoniker_create( ppmkOut,
453 &pszDisplayName[prefix_len], n-prefix_len );
456 static const IParseDisplayNameVtbl ITS_IParseDisplayNameImpl_Vtbl =
458 ITS_IParseDisplayNameImpl_QueryInterface,
459 ITS_IParseDisplayNameImpl_AddRef,
460 ITS_IParseDisplayNameImpl_Release,
461 ITS_IParseDisplayNameImpl_ParseDisplayName
464 HRESULT ITS_IParseDisplayName_create(IUnknown *pUnkOuter, LPVOID *ppObj)
466 ITS_IParseDisplayNameImpl *its;
468 if( pUnkOuter )
469 return CLASS_E_NOAGGREGATION;
471 its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITS_IParseDisplayNameImpl) );
472 its->vtbl_ITS_IParseDisplayName = &ITS_IParseDisplayNameImpl_Vtbl;
473 its->ref = 1;
475 TRACE("-> %p\n", its);
476 *ppObj = its;
478 ITSS_LockModule();
479 return S_OK;