winejoystick: Fix a crash on accessing a CFArray past its end due to an off-by-one...
[wine/multimedia.git] / dlls / shell32 / shelldispatch.c
blobd83b277cd6a299e2b695a0bd8dc23f1cd55948ec
1 /*
2 * IShellDispatch implementation
4 * Copyright 2010 Alexander Morozov for Etersoft
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdarg.h>
26 #define COBJMACROS
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winreg.h"
33 #include "winsvc.h"
34 #include "shlwapi.h"
35 #include "shlobj.h"
36 #include "shldisp.h"
37 #include "debughlp.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(shell);
43 enum tid_t {
44 NULL_tid,
45 IShellDispatch5_tid,
46 Folder3_tid,
47 FolderItem2_tid,
48 LAST_tid
51 static ITypeLib *typelib;
52 static const IID * const tid_ids[] =
54 &IID_NULL,
55 &IID_IShellDispatch5,
56 &IID_Folder3,
57 &IID_FolderItem2
59 static ITypeInfo *typeinfos[LAST_tid];
61 typedef struct {
62 IShellDispatch5 IShellDispatch5_iface;
63 LONG ref;
64 } ShellDispatch;
66 typedef struct {
67 Folder3 Folder3_iface;
68 LONG ref;
69 VARIANT dir;
70 } FolderImpl;
72 typedef struct {
73 FolderItem2 FolderItem2_iface;
74 LONG ref;
75 VARIANT dir;
76 } FolderItemImpl;
78 static inline ShellDispatch *impl_from_IShellDispatch5(IShellDispatch5 *iface)
80 return CONTAINING_RECORD(iface, ShellDispatch, IShellDispatch5_iface);
83 static inline FolderImpl *impl_from_Folder(Folder3 *iface)
85 return CONTAINING_RECORD(iface, FolderImpl, Folder3_iface);
88 static inline FolderItemImpl *impl_from_FolderItem(FolderItem2 *iface)
90 return CONTAINING_RECORD(iface, FolderItemImpl, FolderItem2_iface);
93 static HRESULT load_typelib(void)
95 ITypeLib *tl;
96 HRESULT hr;
98 hr = LoadRegTypeLib(&LIBID_Shell32, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
99 if (FAILED(hr)) {
100 ERR("LoadRegTypeLib failed: %08x\n", hr);
101 return hr;
104 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
105 ITypeLib_Release(tl);
106 return hr;
109 void release_typelib(void)
111 unsigned i;
113 if (!typelib)
114 return;
116 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
117 if (typeinfos[i])
118 ITypeInfo_Release(typeinfos[i]);
120 ITypeLib_Release(typelib);
123 static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
125 HRESULT hr;
127 if (!typelib)
128 hr = load_typelib();
129 if (!typelib)
130 return hr;
132 if (!typeinfos[tid])
134 ITypeInfo *ti;
136 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
137 if (FAILED(hr))
139 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
140 return hr;
143 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
144 ITypeInfo_Release(ti);
147 *typeinfo = typeinfos[tid];
148 return S_OK;
151 static HRESULT WINAPI FolderItemImpl_QueryInterface(FolderItem2 *iface,
152 REFIID riid, LPVOID *ppv)
154 FolderItemImpl *This = impl_from_FolderItem(iface);
156 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
158 if (!ppv) return E_INVALIDARG;
160 if (IsEqualIID(&IID_IUnknown, riid) ||
161 IsEqualIID(&IID_IDispatch, riid) ||
162 IsEqualIID(&IID_FolderItem, riid) ||
163 IsEqualIID(&IID_FolderItem2, riid))
164 *ppv = &This->FolderItem2_iface;
165 else
167 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
168 *ppv = NULL;
169 return E_NOINTERFACE;
171 IUnknown_AddRef((IUnknown*)*ppv);
172 return S_OK;
175 static ULONG WINAPI FolderItemImpl_AddRef(FolderItem2 *iface)
177 FolderItemImpl *This = impl_from_FolderItem(iface);
178 ULONG ref = InterlockedIncrement(&This->ref);
180 TRACE("(%p), new refcount=%i\n", iface, ref);
182 return ref;
185 static ULONG WINAPI FolderItemImpl_Release(FolderItem2 *iface)
187 FolderItemImpl *This = impl_from_FolderItem(iface);
188 ULONG ref = InterlockedDecrement(&This->ref);
190 TRACE("(%p), new refcount=%i\n", iface, ref);
192 if (!ref)
194 VariantClear(&This->dir);
195 HeapFree(GetProcessHeap(), 0, This);
197 return ref;
200 static HRESULT WINAPI FolderItemImpl_GetTypeInfoCount(FolderItem2 *iface,
201 UINT *pctinfo)
203 TRACE("(%p,%p)\n", iface, pctinfo);
205 *pctinfo = 1;
206 return S_OK;
209 static HRESULT WINAPI FolderItemImpl_GetTypeInfo(FolderItem2 *iface, UINT iTInfo,
210 LCID lcid, ITypeInfo **ppTInfo)
212 HRESULT hr;
214 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
216 hr = get_typeinfo(FolderItem2_tid, ppTInfo);
217 if (SUCCEEDED(hr))
218 ITypeInfo_AddRef(*ppTInfo);
219 return hr;
222 static HRESULT WINAPI FolderItemImpl_GetIDsOfNames(FolderItem2 *iface,
223 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
224 DISPID *rgDispId)
226 ITypeInfo *ti;
227 HRESULT hr;
229 TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
230 rgDispId);
232 hr = get_typeinfo(FolderItem2_tid, &ti);
233 if (SUCCEEDED(hr))
234 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
235 return hr;
238 static HRESULT WINAPI FolderItemImpl_Invoke(FolderItem2 *iface,
239 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
240 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
241 UINT *puArgErr)
243 FolderItemImpl *This = impl_from_FolderItem(iface);
244 ITypeInfo *ti;
245 HRESULT hr;
247 TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
248 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
250 hr = get_typeinfo(FolderItem2_tid, &ti);
251 if (SUCCEEDED(hr))
252 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
253 return hr;
256 static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem2 *iface,
257 IDispatch **ppid)
259 FIXME("(%p,%p)\n", iface, ppid);
261 *ppid = NULL;
262 return E_NOTIMPL;
265 static HRESULT WINAPI FolderItemImpl_get_Parent(FolderItem2 *iface,
266 IDispatch **ppid)
268 FIXME("(%p,%p)\n", iface, ppid);
270 *ppid = NULL;
271 return E_NOTIMPL;
274 static HRESULT WINAPI FolderItemImpl_get_Name(FolderItem2 *iface, BSTR *pbs)
276 FIXME("(%p,%p)\n", iface, pbs);
278 *pbs = NULL;
279 return E_NOTIMPL;
282 static HRESULT WINAPI FolderItemImpl_put_Name(FolderItem2 *iface, BSTR bs)
284 FIXME("(%p,%s)\n", iface, debugstr_w(bs));
286 return E_NOTIMPL;
289 static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem2 *iface, BSTR *pbs)
291 FolderItemImpl *This = impl_from_FolderItem(iface);
292 HRESULT ret = S_OK;
293 WCHAR *pathW;
294 int len;
296 TRACE("(%p,%p)\n", iface, pbs);
298 *pbs = NULL;
299 if (V_VT(&This->dir) == VT_I4)
301 pathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
302 if (!pathW) return E_OUTOFMEMORY;
303 ret = SHGetFolderPathW(NULL, V_I4(&This->dir), NULL, SHGFP_TYPE_CURRENT,
304 pathW);
305 if (ret == S_OK)
306 *pbs = SysAllocString(pathW);
307 else if (ret == E_INVALIDARG)
309 FIXME("not implemented for %#x\n", V_I4(&This->dir));
310 ret = E_NOTIMPL;
312 HeapFree(GetProcessHeap(), 0, pathW);
314 else /* VT_BSTR */
316 pathW = V_BSTR(&This->dir);
317 len = lstrlenW(pathW);
318 *pbs = SysAllocStringLen(pathW, pathW[len - 1] == '\\' ? len - 1 : len);
320 if (ret == S_OK && !*pbs)
321 ret = E_OUTOFMEMORY;
322 return ret;
325 static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem2 *iface,
326 IDispatch **ppid)
328 FIXME("(%p,%p)\n", iface, ppid);
330 *ppid = NULL;
331 return E_NOTIMPL;
334 static HRESULT WINAPI FolderItemImpl_get_GetFolder(FolderItem2 *iface,
335 IDispatch **ppid)
337 FIXME("(%p,%p)\n", iface, ppid);
339 *ppid = NULL;
340 return E_NOTIMPL;
343 static HRESULT WINAPI FolderItemImpl_get_IsLink(FolderItem2 *iface,
344 VARIANT_BOOL *pb)
346 FIXME("(%p,%p)\n", iface, pb);
348 return E_NOTIMPL;
351 static HRESULT WINAPI FolderItemImpl_get_IsFolder(FolderItem2 *iface,
352 VARIANT_BOOL *pb)
354 FIXME("(%p,%p)\n", iface, pb);
356 return E_NOTIMPL;
359 static HRESULT WINAPI FolderItemImpl_get_IsFileSystem(FolderItem2 *iface,
360 VARIANT_BOOL *pb)
362 FIXME("(%p,%p)\n", iface, pb);
364 return E_NOTIMPL;
367 static HRESULT WINAPI FolderItemImpl_get_IsBrowsable(FolderItem2 *iface,
368 VARIANT_BOOL *pb)
370 FIXME("(%p,%p)\n", iface, pb);
372 return E_NOTIMPL;
375 static HRESULT WINAPI FolderItemImpl_get_ModifyDate(FolderItem2 *iface,
376 DATE *pdt)
378 FIXME("(%p,%p)\n", iface, pdt);
380 return E_NOTIMPL;
383 static HRESULT WINAPI FolderItemImpl_put_ModifyDate(FolderItem2 *iface, DATE dt)
385 FIXME("(%p,%f)\n", iface, dt);
387 return E_NOTIMPL;
390 static HRESULT WINAPI FolderItemImpl_get_Size(FolderItem2 *iface, LONG *pul)
392 FIXME("(%p,%p)\n", iface, pul);
394 return E_NOTIMPL;
397 static HRESULT WINAPI FolderItemImpl_get_Type(FolderItem2 *iface, BSTR *pbs)
399 FIXME("(%p,%p)\n", iface, pbs);
401 *pbs = NULL;
402 return E_NOTIMPL;
405 static HRESULT WINAPI FolderItemImpl_Verbs(FolderItem2 *iface,
406 FolderItemVerbs **ppfic)
408 FIXME("(%p,%p)\n", iface, ppfic);
410 *ppfic = NULL;
411 return E_NOTIMPL;
414 static HRESULT WINAPI FolderItemImpl_InvokeVerb(FolderItem2 *iface,
415 VARIANT vVerb)
417 FIXME("(%p)\n", iface);
419 return E_NOTIMPL;
422 static HRESULT WINAPI FolderItemImpl_InvokeVerbEx(FolderItem2 *iface, VARIANT verb, VARIANT args)
424 FIXME("(%p): stub\n", iface);
426 return E_NOTIMPL;
429 static HRESULT WINAPI FolderItemImpl_ExtendedProperty(FolderItem2 *iface, BSTR propname, VARIANT *ret)
431 FIXME("(%p)->(%s %p): stub\n", iface, debugstr_w(propname), ret);
433 return E_NOTIMPL;
436 static const FolderItem2Vtbl FolderItemImpl_Vtbl = {
437 FolderItemImpl_QueryInterface,
438 FolderItemImpl_AddRef,
439 FolderItemImpl_Release,
440 FolderItemImpl_GetTypeInfoCount,
441 FolderItemImpl_GetTypeInfo,
442 FolderItemImpl_GetIDsOfNames,
443 FolderItemImpl_Invoke,
444 FolderItemImpl_get_Application,
445 FolderItemImpl_get_Parent,
446 FolderItemImpl_get_Name,
447 FolderItemImpl_put_Name,
448 FolderItemImpl_get_Path,
449 FolderItemImpl_get_GetLink,
450 FolderItemImpl_get_GetFolder,
451 FolderItemImpl_get_IsLink,
452 FolderItemImpl_get_IsFolder,
453 FolderItemImpl_get_IsFileSystem,
454 FolderItemImpl_get_IsBrowsable,
455 FolderItemImpl_get_ModifyDate,
456 FolderItemImpl_put_ModifyDate,
457 FolderItemImpl_get_Size,
458 FolderItemImpl_get_Type,
459 FolderItemImpl_Verbs,
460 FolderItemImpl_InvokeVerb,
461 FolderItemImpl_InvokeVerbEx,
462 FolderItemImpl_ExtendedProperty
465 static HRESULT FolderItem_Constructor(VARIANT *dir, FolderItem **ppfi)
467 FolderItemImpl *This;
468 HRESULT ret;
470 *ppfi = NULL;
472 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemImpl));
473 if (!This) return E_OUTOFMEMORY;
474 This->FolderItem2_iface.lpVtbl = &FolderItemImpl_Vtbl;
475 This->ref = 1;
477 VariantInit(&This->dir);
478 ret = VariantCopy(&This->dir, dir);
479 if (FAILED(ret))
481 HeapFree(GetProcessHeap(), 0, This);
482 return E_OUTOFMEMORY;
485 *ppfi = (FolderItem*)&This->FolderItem2_iface;
486 return ret;
489 static HRESULT WINAPI FolderImpl_QueryInterface(Folder3 *iface, REFIID riid,
490 LPVOID *ppv)
492 FolderImpl *This = impl_from_Folder(iface);
494 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
496 if (!ppv) return E_INVALIDARG;
498 if (IsEqualIID(&IID_IUnknown, riid) ||
499 IsEqualIID(&IID_IDispatch, riid) ||
500 IsEqualIID(&IID_Folder, riid) ||
501 IsEqualIID(&IID_Folder2, riid) ||
502 IsEqualIID(&IID_Folder3, riid))
503 *ppv = &This->Folder3_iface;
504 else
506 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
507 *ppv = NULL;
508 return E_NOINTERFACE;
510 IUnknown_AddRef((IUnknown*)*ppv);
511 return S_OK;
514 static ULONG WINAPI FolderImpl_AddRef(Folder3 *iface)
516 FolderImpl *This = impl_from_Folder(iface);
517 ULONG ref = InterlockedIncrement(&This->ref);
519 TRACE("(%p), new refcount=%i\n", iface, ref);
521 return ref;
524 static ULONG WINAPI FolderImpl_Release(Folder3 *iface)
526 FolderImpl *This = impl_from_Folder(iface);
527 ULONG ref = InterlockedDecrement(&This->ref);
529 TRACE("(%p), new refcount=%i\n", iface, ref);
531 if (!ref)
533 VariantClear(&This->dir);
534 HeapFree(GetProcessHeap(), 0, This);
536 return ref;
539 static HRESULT WINAPI FolderImpl_GetTypeInfoCount(Folder3 *iface, UINT *pctinfo)
541 TRACE("(%p,%p)\n", iface, pctinfo);
543 *pctinfo = 1;
544 return S_OK;
547 static HRESULT WINAPI FolderImpl_GetTypeInfo(Folder3 *iface, UINT iTInfo,
548 LCID lcid, ITypeInfo **ppTInfo)
550 HRESULT hr;
552 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
554 hr = get_typeinfo(Folder3_tid, ppTInfo);
555 if (SUCCEEDED(hr))
556 ITypeInfo_AddRef(*ppTInfo);
558 return hr;
561 static HRESULT WINAPI FolderImpl_GetIDsOfNames(Folder3 *iface, REFIID riid,
562 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
564 ITypeInfo *ti;
565 HRESULT hr;
567 TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
568 rgDispId);
570 hr = get_typeinfo(Folder3_tid, &ti);
571 if (SUCCEEDED(hr))
572 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
573 return hr;
576 static HRESULT WINAPI FolderImpl_Invoke(Folder3 *iface, DISPID dispIdMember,
577 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
578 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
580 FolderImpl *This = impl_from_Folder(iface);
581 ITypeInfo *ti;
582 HRESULT hr;
584 TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
585 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
587 hr = get_typeinfo(Folder3_tid, &ti);
588 if (SUCCEEDED(hr))
589 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
590 return hr;
593 static HRESULT WINAPI FolderImpl_get_Title(Folder3 *iface, BSTR *pbs)
595 FolderImpl *This = impl_from_Folder(iface);
596 WCHAR *p;
597 int len;
599 TRACE("(%p,%p)\n", iface, pbs);
601 *pbs = NULL;
603 if (V_VT(&This->dir) == VT_I4)
605 FIXME("special folder constants are not supported\n");
606 return E_NOTIMPL;
608 p = PathFindFileNameW(V_BSTR(&This->dir));
609 len = lstrlenW(p);
610 *pbs = SysAllocStringLen(p, p[len - 1] == '\\' ? len - 1 : len);
611 return *pbs ? S_OK : E_OUTOFMEMORY;
614 static HRESULT WINAPI FolderImpl_get_Application(Folder3 *iface,
615 IDispatch **ppid)
617 FIXME("(%p,%p)\n", iface, ppid);
619 *ppid = NULL;
620 return E_NOTIMPL;
623 static HRESULT WINAPI FolderImpl_get_Parent(Folder3 *iface, IDispatch **ppid)
625 FIXME("(%p,%p)\n", iface, ppid);
627 *ppid = NULL;
628 return E_NOTIMPL;
631 static HRESULT WINAPI FolderImpl_get_ParentFolder(Folder3 *iface, Folder **ppsf)
633 FIXME("(%p,%p)\n", iface, ppsf);
635 *ppsf = NULL;
636 return E_NOTIMPL;
639 static HRESULT WINAPI FolderImpl_Items(Folder3 *iface, FolderItems **ppid)
641 FIXME("(%p,%p)\n", iface, ppid);
643 *ppid = NULL;
644 return E_NOTIMPL;
647 static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR bName,
648 FolderItem **ppid)
650 FIXME("(%p,%s,%p)\n", iface, debugstr_w(bName), ppid);
652 *ppid = NULL;
653 return E_NOTIMPL;
656 static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR bName,
657 VARIANT vOptions)
659 FIXME("(%p,%s)\n", iface, debugstr_w(bName));
661 return E_NOTIMPL;
664 static HRESULT WINAPI FolderImpl_MoveHere(Folder3 *iface, VARIANT vItem,
665 VARIANT vOptions)
667 FIXME("(%p)\n", iface);
669 return E_NOTIMPL;
672 static HRESULT WINAPI FolderImpl_CopyHere(Folder3 *iface, VARIANT vItem,
673 VARIANT vOptions)
675 FIXME("(%p)\n", iface);
677 return E_NOTIMPL;
680 static HRESULT WINAPI FolderImpl_GetDetailsOf(Folder3 *iface, VARIANT vItem,
681 int iColumn, BSTR *pbs)
683 FIXME("(%p,%d,%p)\n", iface, iColumn, pbs);
685 *pbs = NULL;
686 return E_NOTIMPL;
689 static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **ppfi)
691 FolderImpl *This = impl_from_Folder(iface);
693 TRACE("(%p,%p)\n", iface, ppfi);
695 return FolderItem_Constructor(&This->dir, ppfi);
698 static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
700 FIXME("(%p,%p)\n", iface, pul);
702 return E_NOTIMPL;
705 static HRESULT WINAPI FolderImpl_Synchronize(Folder3 *iface)
707 FIXME("(%p)\n", iface);
709 return E_NOTIMPL;
712 static HRESULT WINAPI FolderImpl_get_HaveToShowWebViewBarricade(Folder3 *iface,
713 VARIANT_BOOL *pbHaveToShowWebViewBarricade)
715 FIXME("(%p,%p)\n", iface, pbHaveToShowWebViewBarricade);
717 return E_NOTIMPL;
720 static HRESULT WINAPI FolderImpl_DismissedWebViewBarricade(Folder3 *iface)
722 FIXME("(%p)\n", iface);
724 return E_NOTIMPL;
727 static HRESULT WINAPI FolderImpl_get_ShowWebViewBarricade(Folder3 *iface,
728 VARIANT_BOOL *pbShowWebViewBarricade)
730 FIXME("(%p,%p)\n", iface, pbShowWebViewBarricade);
732 return E_NOTIMPL;
735 static HRESULT WINAPI FolderImpl_put_ShowWebViewBarricade(Folder3 *iface,
736 VARIANT_BOOL bShowWebViewBarricade)
738 FIXME("(%p,%d)\n", iface, bShowWebViewBarricade);
740 return E_NOTIMPL;
743 static const Folder3Vtbl FolderImpl_Vtbl = {
744 FolderImpl_QueryInterface,
745 FolderImpl_AddRef,
746 FolderImpl_Release,
747 FolderImpl_GetTypeInfoCount,
748 FolderImpl_GetTypeInfo,
749 FolderImpl_GetIDsOfNames,
750 FolderImpl_Invoke,
751 FolderImpl_get_Title,
752 FolderImpl_get_Application,
753 FolderImpl_get_Parent,
754 FolderImpl_get_ParentFolder,
755 FolderImpl_Items,
756 FolderImpl_ParseName,
757 FolderImpl_NewFolder,
758 FolderImpl_MoveHere,
759 FolderImpl_CopyHere,
760 FolderImpl_GetDetailsOf,
761 FolderImpl_get_Self,
762 FolderImpl_get_OfflineStatus,
763 FolderImpl_Synchronize,
764 FolderImpl_get_HaveToShowWebViewBarricade,
765 FolderImpl_DismissedWebViewBarricade,
766 FolderImpl_get_ShowWebViewBarricade,
767 FolderImpl_put_ShowWebViewBarricade
770 static HRESULT Folder_Constructor(VARIANT *dir, Folder **ppsdf)
772 FolderImpl *This;
773 HRESULT ret;
775 *ppsdf = NULL;
777 switch (V_VT(dir))
779 case VT_I4:
780 /* FIXME: add some checks */
781 break;
782 case VT_BSTR:
783 if (PathIsDirectoryW(V_BSTR(dir)) &&
784 !PathIsRelativeW(V_BSTR(dir)) &&
785 PathFileExistsW(V_BSTR(dir)))
786 break;
787 default:
788 return S_FALSE;
791 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderImpl));
792 if (!This) return E_OUTOFMEMORY;
793 This->Folder3_iface.lpVtbl = &FolderImpl_Vtbl;
794 This->ref = 1;
796 VariantInit(&This->dir);
797 ret = VariantCopy(&This->dir, dir);
798 if (FAILED(ret))
800 HeapFree(GetProcessHeap(), 0, This);
801 return E_OUTOFMEMORY;
804 *ppsdf = (Folder*)This;
805 return ret;
808 static HRESULT WINAPI ShellDispatch_QueryInterface(IShellDispatch5 *iface,
809 REFIID riid, LPVOID *ppv)
811 ShellDispatch *This = impl_from_IShellDispatch5(iface);
813 TRACE("(%p,%p,%p)\n", iface, riid, ppv);
815 if (!ppv) return E_INVALIDARG;
817 if (IsEqualIID(&IID_IUnknown, riid) ||
818 IsEqualIID(&IID_IDispatch, riid) ||
819 IsEqualIID(&IID_IShellDispatch, riid) ||
820 IsEqualIID(&IID_IShellDispatch2, riid) ||
821 IsEqualIID(&IID_IShellDispatch3, riid) ||
822 IsEqualIID(&IID_IShellDispatch4, riid) ||
823 IsEqualIID(&IID_IShellDispatch5, riid))
824 *ppv = &This->IShellDispatch5_iface;
825 else
827 FIXME("not implemented for %s\n", shdebugstr_guid(riid));
828 *ppv = NULL;
829 return E_NOINTERFACE;
832 IShellDispatch5_AddRef(iface);
833 return S_OK;
836 static ULONG WINAPI ShellDispatch_AddRef(IShellDispatch5 *iface)
838 ShellDispatch *This = impl_from_IShellDispatch5(iface);
839 ULONG ref = InterlockedIncrement(&This->ref);
841 TRACE("(%p), new refcount=%i\n", iface, ref);
843 return ref;
846 static ULONG WINAPI ShellDispatch_Release(IShellDispatch5 *iface)
848 ShellDispatch *This = impl_from_IShellDispatch5(iface);
849 ULONG ref = InterlockedDecrement(&This->ref);
851 TRACE("(%p), new refcount=%i\n", iface, ref);
853 if (!ref)
854 HeapFree(GetProcessHeap(), 0, This);
856 return ref;
859 static HRESULT WINAPI ShellDispatch_GetTypeInfoCount(IShellDispatch5 *iface,
860 UINT *pctinfo)
862 TRACE("(%p,%p)\n", iface, pctinfo);
864 *pctinfo = 1;
865 return S_OK;
868 static HRESULT WINAPI ShellDispatch_GetTypeInfo(IShellDispatch5 *iface,
869 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
871 HRESULT hr;
873 TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);
875 hr = get_typeinfo(IShellDispatch5_tid, ppTInfo);
876 if (SUCCEEDED(hr))
877 ITypeInfo_AddRef(*ppTInfo);
878 return hr;
881 static HRESULT WINAPI ShellDispatch_GetIDsOfNames(IShellDispatch5 *iface,
882 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
884 ITypeInfo *ti;
885 HRESULT hr;
887 TRACE("(%p,%p,%p,%u,%d,%p)\n", iface, riid, rgszNames, cNames, lcid,
888 rgDispId);
890 hr = get_typeinfo(IShellDispatch5_tid, &ti);
891 if (SUCCEEDED(hr))
892 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
893 return hr;
896 static HRESULT WINAPI ShellDispatch_Invoke(IShellDispatch5 *iface,
897 DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
898 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
899 UINT *puArgErr)
901 ShellDispatch *This = impl_from_IShellDispatch5(iface);
902 ITypeInfo *ti;
903 HRESULT hr;
905 TRACE("(%p,%d,%p,%d,%u,%p,%p,%p,%p)\n", iface, dispIdMember, riid, lcid,
906 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
908 hr = get_typeinfo(IShellDispatch5_tid, &ti);
909 if (SUCCEEDED(hr))
910 hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams,
911 pVarResult, pExcepInfo, puArgErr);
912 return hr;
915 static HRESULT WINAPI ShellDispatch_get_Application(IShellDispatch5 *iface,
916 IDispatch **ppid)
918 FIXME("(%p,%p)\n", iface, ppid);
920 *ppid = NULL;
921 return E_NOTIMPL;
924 static HRESULT WINAPI ShellDispatch_get_Parent(IShellDispatch5 *iface,
925 IDispatch **ppid)
927 FIXME("(%p,%p)\n", iface, ppid);
929 *ppid = NULL;
930 return E_NOTIMPL;
933 static HRESULT WINAPI ShellDispatch_NameSpace(IShellDispatch5 *iface,
934 VARIANT vDir, Folder **ppsdf)
936 TRACE("(%p,%p)\n", iface, ppsdf);
938 return Folder_Constructor(&vDir, ppsdf);
941 static HRESULT WINAPI ShellDispatch_BrowseForFolder(IShellDispatch5 *iface,
942 LONG Hwnd, BSTR Title, LONG Options, VARIANT RootFolder, Folder **ppsdf)
944 FIXME("(%p,%x,%s,%x,%p)\n", iface, Hwnd, debugstr_w(Title), Options, ppsdf);
946 *ppsdf = NULL;
947 return E_NOTIMPL;
950 static HRESULT WINAPI ShellDispatch_Windows(IShellDispatch5 *iface,
951 IDispatch **ppid)
953 FIXME("(%p,%p)\n", iface, ppid);
955 *ppid = NULL;
956 return E_NOTIMPL;
959 static HRESULT WINAPI ShellDispatch_Open(IShellDispatch5 *iface, VARIANT vDir)
961 FIXME("(%p)\n", iface);
963 return E_NOTIMPL;
966 static HRESULT WINAPI ShellDispatch_Explore(IShellDispatch5 *iface, VARIANT vDir)
968 FIXME("(%p)\n", iface);
970 return E_NOTIMPL;
973 static HRESULT WINAPI ShellDispatch_MinimizeAll(IShellDispatch5 *iface)
975 FIXME("(%p)\n", iface);
977 return E_NOTIMPL;
980 static HRESULT WINAPI ShellDispatch_UndoMinimizeALL(IShellDispatch5 *iface)
982 FIXME("(%p)\n", iface);
984 return E_NOTIMPL;
987 static HRESULT WINAPI ShellDispatch_FileRun(IShellDispatch5 *iface)
989 FIXME("(%p)\n", iface);
991 return E_NOTIMPL;
994 static HRESULT WINAPI ShellDispatch_CascadeWindows(IShellDispatch5 *iface)
996 FIXME("(%p)\n", iface);
998 return E_NOTIMPL;
1001 static HRESULT WINAPI ShellDispatch_TileVertically(IShellDispatch5 *iface)
1003 FIXME("(%p)\n", iface);
1005 return E_NOTIMPL;
1008 static HRESULT WINAPI ShellDispatch_TileHorizontally(IShellDispatch5 *iface)
1010 FIXME("(%p)\n", iface);
1012 return E_NOTIMPL;
1015 static HRESULT WINAPI ShellDispatch_ShutdownWindows(IShellDispatch5 *iface)
1017 FIXME("(%p)\n", iface);
1019 return E_NOTIMPL;
1022 static HRESULT WINAPI ShellDispatch_Suspend(IShellDispatch5 *iface)
1024 FIXME("(%p)\n", iface);
1026 return E_NOTIMPL;
1029 static HRESULT WINAPI ShellDispatch_EjectPC(IShellDispatch5 *iface)
1031 FIXME("(%p)\n", iface);
1033 return E_NOTIMPL;
1036 static HRESULT WINAPI ShellDispatch_SetTime(IShellDispatch5 *iface)
1038 FIXME("(%p)\n", iface);
1040 return E_NOTIMPL;
1043 static HRESULT WINAPI ShellDispatch_TrayProperties(IShellDispatch5 *iface)
1045 FIXME("(%p)\n", iface);
1047 return E_NOTIMPL;
1050 static HRESULT WINAPI ShellDispatch_Help(IShellDispatch5 *iface)
1052 FIXME("(%p)\n", iface);
1054 return E_NOTIMPL;
1057 static HRESULT WINAPI ShellDispatch_FindFiles(IShellDispatch5 *iface)
1059 FIXME("(%p)\n", iface);
1061 return E_NOTIMPL;
1064 static HRESULT WINAPI ShellDispatch_FindComputer(IShellDispatch5 *iface)
1066 FIXME("(%p)\n", iface);
1068 return E_NOTIMPL;
1071 static HRESULT WINAPI ShellDispatch_RefreshMenu(IShellDispatch5 *iface)
1073 FIXME("(%p)\n", iface);
1075 return E_NOTIMPL;
1078 static HRESULT WINAPI ShellDispatch_ControlPanelItem(IShellDispatch5 *iface,
1079 BSTR szDir)
1081 FIXME("(%p,%s)\n", iface, debugstr_w(szDir));
1083 return E_NOTIMPL;
1086 static HRESULT WINAPI ShellDispatch_IsRestricted(IShellDispatch5 *iface, BSTR group, BSTR restriction, LONG *value)
1088 FIXME("(%s, %s, %p): stub\n", debugstr_w(group), debugstr_w(restriction), value);
1089 return E_NOTIMPL;
1092 static HRESULT WINAPI ShellDispatch_ShellExecute(IShellDispatch5 *iface, BSTR file, VARIANT args, VARIANT dir,
1093 VARIANT op, VARIANT show)
1095 FIXME("(%s): stub\n", debugstr_w(file));
1096 return E_NOTIMPL;
1099 static HRESULT WINAPI ShellDispatch_FindPrinter(IShellDispatch5 *iface, BSTR name, BSTR location, BSTR model)
1101 FIXME("(%s, %s, %s): stub\n", debugstr_w(name), debugstr_w(location), debugstr_w(model));
1102 return E_NOTIMPL;
1105 static HRESULT WINAPI ShellDispatch_GetSystemInformation(IShellDispatch5 *iface, BSTR name, VARIANT *ret)
1107 FIXME("(%s, %p): stub\n", debugstr_w(name), ret);
1108 return E_NOTIMPL;
1111 static HRESULT WINAPI ShellDispatch_ServiceStart(IShellDispatch5 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1113 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1114 return E_NOTIMPL;
1117 static HRESULT WINAPI ShellDispatch_ServiceStop(IShellDispatch5 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
1119 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1120 return E_NOTIMPL;
1123 static HRESULT WINAPI ShellDispatch_IsServiceRunning(IShellDispatch5 *iface, BSTR name, VARIANT *running)
1125 SERVICE_STATUS_PROCESS status;
1126 SC_HANDLE scm, service;
1127 DWORD dummy;
1129 TRACE("(%s, %p)\n", debugstr_w(name), running);
1131 V_VT(running) = VT_BOOL;
1132 V_BOOL(running) = VARIANT_FALSE;
1134 scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
1135 if (!scm)
1137 ERR("failed to connect to service manager\n");
1138 return S_OK;
1141 service = OpenServiceW(scm, name, SERVICE_QUERY_STATUS);
1142 if (!service)
1144 ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
1145 CloseServiceHandle(scm);
1146 return S_OK;
1149 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status,
1150 sizeof(SERVICE_STATUS_PROCESS), &dummy))
1152 TRACE("failed to query service status (%u)\n", GetLastError());
1153 CloseServiceHandle(service);
1154 CloseServiceHandle(scm);
1155 return S_OK;
1158 if (status.dwCurrentState == SERVICE_RUNNING)
1159 V_BOOL(running) = VARIANT_TRUE;
1161 CloseServiceHandle(service);
1162 CloseServiceHandle(scm);
1164 return S_OK;
1167 static HRESULT WINAPI ShellDispatch_CanStartStopService(IShellDispatch5 *iface, BSTR service, VARIANT *ret)
1169 FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
1170 return E_NOTIMPL;
1173 static HRESULT WINAPI ShellDispatch_ShowBrowserBar(IShellDispatch5 *iface, BSTR clsid, VARIANT show, VARIANT *ret)
1175 FIXME("(%s, %p): stub\n", debugstr_w(clsid), ret);
1176 return E_NOTIMPL;
1179 static HRESULT WINAPI ShellDispatch_AddToRecent(IShellDispatch5 *iface, VARIANT file, BSTR category)
1181 FIXME("(%s): stub\n", debugstr_w(category));
1182 return E_NOTIMPL;
1185 static HRESULT WINAPI ShellDispatch_WindowsSecurity(IShellDispatch5 *iface)
1187 FIXME("stub\n");
1188 return E_NOTIMPL;
1191 static HRESULT WINAPI ShellDispatch_ToggleDesktop(IShellDispatch5 *iface)
1193 FIXME("stub\n");
1194 return E_NOTIMPL;
1197 static HRESULT WINAPI ShellDispatch_ExplorerPolicy(IShellDispatch5 *iface, BSTR policy, VARIANT *value)
1199 FIXME("(%s, %p): stub\n", debugstr_w(policy), value);
1200 return E_NOTIMPL;
1203 static HRESULT WINAPI ShellDispatch_GetSetting(IShellDispatch5 *iface, LONG setting, VARIANT_BOOL *result)
1205 FIXME("(%d %p): stub\n", setting, result);
1206 return E_NOTIMPL;
1209 static HRESULT WINAPI ShellDispatch_WindowSwitcher(IShellDispatch5 *iface)
1211 FIXME("stub\n");
1212 return E_NOTIMPL;
1215 static const IShellDispatch5Vtbl ShellDispatch5Vtbl = {
1216 ShellDispatch_QueryInterface,
1217 ShellDispatch_AddRef,
1218 ShellDispatch_Release,
1219 ShellDispatch_GetTypeInfoCount,
1220 ShellDispatch_GetTypeInfo,
1221 ShellDispatch_GetIDsOfNames,
1222 ShellDispatch_Invoke,
1223 ShellDispatch_get_Application,
1224 ShellDispatch_get_Parent,
1225 ShellDispatch_NameSpace,
1226 ShellDispatch_BrowseForFolder,
1227 ShellDispatch_Windows,
1228 ShellDispatch_Open,
1229 ShellDispatch_Explore,
1230 ShellDispatch_MinimizeAll,
1231 ShellDispatch_UndoMinimizeALL,
1232 ShellDispatch_FileRun,
1233 ShellDispatch_CascadeWindows,
1234 ShellDispatch_TileVertically,
1235 ShellDispatch_TileHorizontally,
1236 ShellDispatch_ShutdownWindows,
1237 ShellDispatch_Suspend,
1238 ShellDispatch_EjectPC,
1239 ShellDispatch_SetTime,
1240 ShellDispatch_TrayProperties,
1241 ShellDispatch_Help,
1242 ShellDispatch_FindFiles,
1243 ShellDispatch_FindComputer,
1244 ShellDispatch_RefreshMenu,
1245 ShellDispatch_ControlPanelItem,
1246 ShellDispatch_IsRestricted,
1247 ShellDispatch_ShellExecute,
1248 ShellDispatch_FindPrinter,
1249 ShellDispatch_GetSystemInformation,
1250 ShellDispatch_ServiceStart,
1251 ShellDispatch_ServiceStop,
1252 ShellDispatch_IsServiceRunning,
1253 ShellDispatch_CanStartStopService,
1254 ShellDispatch_ShowBrowserBar,
1255 ShellDispatch_AddToRecent,
1256 ShellDispatch_WindowsSecurity,
1257 ShellDispatch_ToggleDesktop,
1258 ShellDispatch_ExplorerPolicy,
1259 ShellDispatch_GetSetting,
1260 ShellDispatch_WindowSwitcher
1263 HRESULT WINAPI IShellDispatch_Constructor(IUnknown *outer, REFIID riid, void **ppv)
1265 ShellDispatch *This;
1266 HRESULT ret;
1268 TRACE("(%p, %s)\n", outer, debugstr_guid(riid));
1270 *ppv = NULL;
1272 if (outer) return CLASS_E_NOAGGREGATION;
1274 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellDispatch));
1275 if (!This) return E_OUTOFMEMORY;
1276 This->IShellDispatch5_iface.lpVtbl = &ShellDispatch5Vtbl;
1277 This->ref = 1;
1279 ret = IShellDispatch5_QueryInterface(&This->IShellDispatch5_iface, riid, ppv);
1280 IShellDispatch5_Release(&This->IShellDispatch5_iface);
1281 return ret;