2 * Copyright 2011 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "wshom_private.h"
26 #include "wine/debug.h"
27 #include "wine/unicode.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(wshom
);
31 static const char *debugstr_variant(const VARIANT
*v
)
42 return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v
));
44 return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v
));
46 return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v
)));
48 return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v
));
50 return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v
));
52 return wine_dbg_sprintf("{VT_UNKNOWN: %p}", V_UNKNOWN(v
));
54 return wine_dbg_sprintf("{VT_UINT: %u}", V_UINT(v
));
55 case VT_BSTR
|VT_BYREF
:
56 return wine_dbg_sprintf("{VT_BSTR|VT_BYREF: ptr %p, data %s}",
57 V_BSTRREF(v
), debugstr_w(V_BSTRREF(v
) ? *V_BSTRREF(v
) : NULL
));
59 return wine_dbg_sprintf("{vt %d}", V_VT(v
));
63 static IWshShell3 WshShell3
;
67 IWshCollection IWshCollection_iface
;
73 IWshShortcut IWshShortcut_iface
;
82 IWshEnvironment IWshEnvironment_iface
;
86 static inline WshCollection
*impl_from_IWshCollection( IWshCollection
*iface
)
88 return CONTAINING_RECORD(iface
, WshCollection
, IWshCollection_iface
);
91 static inline WshShortcut
*impl_from_IWshShortcut( IWshShortcut
*iface
)
93 return CONTAINING_RECORD(iface
, WshShortcut
, IWshShortcut_iface
);
96 static inline WshEnvironment
*impl_from_IWshEnvironment( IWshEnvironment
*iface
)
98 return CONTAINING_RECORD(iface
, WshEnvironment
, IWshEnvironment_iface
);
101 static HRESULT WINAPI
WshEnvironment_QueryInterface(IWshEnvironment
*iface
, REFIID riid
, void **obj
)
103 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
105 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), obj
);
107 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
108 IsEqualGUID(riid
, &IID_IDispatch
) ||
109 IsEqualGUID(riid
, &IID_IWshEnvironment
))
113 FIXME("Unknown iface %s\n", debugstr_guid(riid
));
115 return E_NOINTERFACE
;
118 IUnknown_AddRef((IUnknown
*)*obj
);
122 static ULONG WINAPI
WshEnvironment_AddRef(IWshEnvironment
*iface
)
124 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
125 LONG ref
= InterlockedIncrement(&This
->ref
);
126 TRACE("(%p) ref = %d\n", This
, ref
);
130 static ULONG WINAPI
WshEnvironment_Release(IWshEnvironment
*iface
)
132 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
133 LONG ref
= InterlockedDecrement(&This
->ref
);
134 TRACE("(%p) ref = %d\n", This
, ref
);
137 HeapFree(GetProcessHeap(), 0, This
);
142 static HRESULT WINAPI
WshEnvironment_GetTypeInfoCount(IWshEnvironment
*iface
, UINT
*pctinfo
)
144 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
145 TRACE("(%p)->(%p)\n", This
, pctinfo
);
150 static HRESULT WINAPI
WshEnvironment_GetTypeInfo(IWshEnvironment
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
152 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
153 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
154 return get_typeinfo(IWshEnvironment_tid
, ppTInfo
);
157 static HRESULT WINAPI
WshEnvironment_GetIDsOfNames(IWshEnvironment
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
158 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
160 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
164 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
166 hr
= get_typeinfo(IWshEnvironment_tid
, &typeinfo
);
169 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
170 ITypeInfo_Release(typeinfo
);
176 static HRESULT WINAPI
WshEnvironment_Invoke(IWshEnvironment
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
177 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
179 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
183 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
184 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
186 hr
= get_typeinfo(IWshEnvironment_tid
, &typeinfo
);
189 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IWshEnvironment_iface
, dispIdMember
, wFlags
,
190 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
191 ITypeInfo_Release(typeinfo
);
197 static HRESULT WINAPI
WshEnvironment_get_Item(IWshEnvironment
*iface
, BSTR name
, BSTR
*value
)
199 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
200 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_w(name
), value
);
204 static HRESULT WINAPI
WshEnvironment_put_Item(IWshEnvironment
*iface
, BSTR name
, BSTR value
)
206 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
207 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(name
), debugstr_w(value
));
211 static HRESULT WINAPI
WshEnvironment_Count(IWshEnvironment
*iface
, LONG
*count
)
213 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
214 FIXME("(%p)->(%p): stub\n", This
, count
);
218 static HRESULT WINAPI
WshEnvironment_get_length(IWshEnvironment
*iface
, LONG
*len
)
220 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
221 FIXME("(%p)->(%p): stub\n", This
, len
);
225 static HRESULT WINAPI
WshEnvironment__NewEnum(IWshEnvironment
*iface
, IUnknown
**penum
)
227 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
228 FIXME("(%p)->(%p): stub\n", This
, penum
);
232 static HRESULT WINAPI
WshEnvironment_Remove(IWshEnvironment
*iface
, BSTR name
)
234 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
235 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(name
));
239 static const IWshEnvironmentVtbl WshEnvironmentVtbl
= {
240 WshEnvironment_QueryInterface
,
241 WshEnvironment_AddRef
,
242 WshEnvironment_Release
,
243 WshEnvironment_GetTypeInfoCount
,
244 WshEnvironment_GetTypeInfo
,
245 WshEnvironment_GetIDsOfNames
,
246 WshEnvironment_Invoke
,
247 WshEnvironment_get_Item
,
248 WshEnvironment_put_Item
,
249 WshEnvironment_Count
,
250 WshEnvironment_get_length
,
251 WshEnvironment__NewEnum
,
252 WshEnvironment_Remove
255 static HRESULT
WshEnvironment_Create(IWshEnvironment
**env
)
257 WshEnvironment
*This
;
259 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
260 if (!This
) return E_OUTOFMEMORY
;
262 This
->IWshEnvironment_iface
.lpVtbl
= &WshEnvironmentVtbl
;
265 *env
= &This
->IWshEnvironment_iface
;
270 static HRESULT WINAPI
WshCollection_QueryInterface(IWshCollection
*iface
, REFIID riid
, void **ppv
)
272 WshCollection
*This
= impl_from_IWshCollection(iface
);
274 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppv
);
276 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
277 IsEqualGUID(riid
, &IID_IDispatch
) ||
278 IsEqualGUID(riid
, &IID_IWshCollection
))
282 FIXME("Unknown iface %s\n", debugstr_guid(riid
));
284 return E_NOINTERFACE
;
287 IUnknown_AddRef((IUnknown
*)*ppv
);
291 static ULONG WINAPI
WshCollection_AddRef(IWshCollection
*iface
)
293 WshCollection
*This
= impl_from_IWshCollection(iface
);
294 LONG ref
= InterlockedIncrement(&This
->ref
);
295 TRACE("(%p) ref = %d\n", This
, ref
);
299 static ULONG WINAPI
WshCollection_Release(IWshCollection
*iface
)
301 WshCollection
*This
= impl_from_IWshCollection(iface
);
302 LONG ref
= InterlockedDecrement(&This
->ref
);
303 TRACE("(%p) ref = %d\n", This
, ref
);
306 HeapFree(GetProcessHeap(), 0, This
);
311 static HRESULT WINAPI
WshCollection_GetTypeInfoCount(IWshCollection
*iface
, UINT
*pctinfo
)
313 WshCollection
*This
= impl_from_IWshCollection(iface
);
314 TRACE("(%p)->(%p)\n", This
, pctinfo
);
319 static HRESULT WINAPI
WshCollection_GetTypeInfo(IWshCollection
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
321 WshCollection
*This
= impl_from_IWshCollection(iface
);
322 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
323 return get_typeinfo(IWshCollection_tid
, ppTInfo
);
326 static HRESULT WINAPI
WshCollection_GetIDsOfNames(IWshCollection
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
327 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
329 WshCollection
*This
= impl_from_IWshCollection(iface
);
333 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
335 hr
= get_typeinfo(IWshCollection_tid
, &typeinfo
);
338 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
339 ITypeInfo_Release(typeinfo
);
345 static HRESULT WINAPI
WshCollection_Invoke(IWshCollection
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
346 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
348 WshCollection
*This
= impl_from_IWshCollection(iface
);
352 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
353 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
355 hr
= get_typeinfo(IWshCollection_tid
, &typeinfo
);
358 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IWshCollection_iface
, dispIdMember
, wFlags
,
359 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
360 ITypeInfo_Release(typeinfo
);
366 static HRESULT WINAPI
WshCollection_Item(IWshCollection
*iface
, VARIANT
*index
, VARIANT
*value
)
368 WshCollection
*This
= impl_from_IWshCollection(iface
);
369 static const WCHAR allusersdesktopW
[] = {'A','l','l','U','s','e','r','s','D','e','s','k','t','o','p',0};
370 static const WCHAR allusersprogramsW
[] = {'A','l','l','U','s','e','r','s','P','r','o','g','r','a','m','s',0};
371 static const WCHAR desktopW
[] = {'D','e','s','k','t','o','p',0};
372 PIDLIST_ABSOLUTE pidl
;
373 WCHAR pathW
[MAX_PATH
];
378 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(index
), value
);
380 if (V_VT(index
) != VT_BSTR
)
382 FIXME("only BSTR index supported, got %d\n", V_VT(index
));
386 folder
= V_BSTR(index
);
387 if (!strcmpiW(folder
, desktopW
))
388 kind
= CSIDL_DESKTOP
;
389 else if (!strcmpiW(folder
, allusersdesktopW
))
390 kind
= CSIDL_COMMON_DESKTOPDIRECTORY
;
391 else if (!strcmpiW(folder
, allusersprogramsW
))
392 kind
= CSIDL_COMMON_PROGRAMS
;
395 FIXME("folder kind %s not supported\n", debugstr_w(folder
));
399 hr
= SHGetSpecialFolderLocation(NULL
, kind
, &pidl
);
400 if (hr
!= S_OK
) return hr
;
402 if (SHGetPathFromIDListW(pidl
, pathW
))
404 V_VT(value
) = VT_BSTR
;
405 V_BSTR(value
) = SysAllocString(pathW
);
406 hr
= V_BSTR(value
) ? S_OK
: E_OUTOFMEMORY
;
416 static HRESULT WINAPI
WshCollection_Count(IWshCollection
*iface
, LONG
*count
)
418 WshCollection
*This
= impl_from_IWshCollection(iface
);
419 FIXME("(%p)->(%p): stub\n", This
, count
);
423 static HRESULT WINAPI
WshCollection_get_length(IWshCollection
*iface
, LONG
*count
)
425 WshCollection
*This
= impl_from_IWshCollection(iface
);
426 FIXME("(%p)->(%p): stub\n", This
, count
);
430 static HRESULT WINAPI
WshCollection__NewEnum(IWshCollection
*iface
, IUnknown
*Enum
)
432 WshCollection
*This
= impl_from_IWshCollection(iface
);
433 FIXME("(%p)->(%p): stub\n", This
, Enum
);
437 static const IWshCollectionVtbl WshCollectionVtbl
= {
438 WshCollection_QueryInterface
,
439 WshCollection_AddRef
,
440 WshCollection_Release
,
441 WshCollection_GetTypeInfoCount
,
442 WshCollection_GetTypeInfo
,
443 WshCollection_GetIDsOfNames
,
444 WshCollection_Invoke
,
447 WshCollection_get_length
,
448 WshCollection__NewEnum
451 static HRESULT
WshCollection_Create(IWshCollection
**collection
)
455 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
456 if (!This
) return E_OUTOFMEMORY
;
458 This
->IWshCollection_iface
.lpVtbl
= &WshCollectionVtbl
;
461 *collection
= &This
->IWshCollection_iface
;
467 static HRESULT WINAPI
WshShortcut_QueryInterface(IWshShortcut
*iface
, REFIID riid
, void **ppv
)
469 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
471 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppv
);
473 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
474 IsEqualGUID(riid
, &IID_IDispatch
) ||
475 IsEqualGUID(riid
, &IID_IWshShortcut
))
479 FIXME("Unknown iface %s\n", debugstr_guid(riid
));
481 return E_NOINTERFACE
;
484 IUnknown_AddRef((IUnknown
*)*ppv
);
488 static ULONG WINAPI
WshShortcut_AddRef(IWshShortcut
*iface
)
490 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
491 LONG ref
= InterlockedIncrement(&This
->ref
);
492 TRACE("(%p) ref = %d\n", This
, ref
);
496 static ULONG WINAPI
WshShortcut_Release(IWshShortcut
*iface
)
498 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
499 LONG ref
= InterlockedDecrement(&This
->ref
);
500 TRACE("(%p) ref = %d\n", This
, ref
);
504 SysFreeString(This
->path_link
);
505 IShellLinkW_Release(This
->link
);
506 HeapFree(GetProcessHeap(), 0, This
);
512 static HRESULT WINAPI
WshShortcut_GetTypeInfoCount(IWshShortcut
*iface
, UINT
*pctinfo
)
514 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
515 TRACE("(%p)->(%p)\n", This
, pctinfo
);
520 static HRESULT WINAPI
WshShortcut_GetTypeInfo(IWshShortcut
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
522 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
523 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
524 return get_typeinfo(IWshShortcut_tid
, ppTInfo
);
527 static HRESULT WINAPI
WshShortcut_GetIDsOfNames(IWshShortcut
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
528 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
530 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
534 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
536 hr
= get_typeinfo(IWshShortcut_tid
, &typeinfo
);
539 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
540 ITypeInfo_Release(typeinfo
);
546 static HRESULT WINAPI
WshShortcut_Invoke(IWshShortcut
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
547 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
549 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
553 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
554 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
556 hr
= get_typeinfo(IWshShortcut_tid
, &typeinfo
);
559 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IWshShortcut_iface
, dispIdMember
, wFlags
,
560 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
561 ITypeInfo_Release(typeinfo
);
567 static HRESULT WINAPI
WshShortcut_get_FullName(IWshShortcut
*iface
, BSTR
*name
)
569 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
570 FIXME("(%p)->(%p): stub\n", This
, name
);
574 static HRESULT WINAPI
WshShortcut_get_Arguments(IWshShortcut
*iface
, BSTR
*Arguments
)
576 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
577 WCHAR buffW
[INFOTIPSIZE
];
580 TRACE("(%p)->(%p)\n", This
, Arguments
);
587 hr
= IShellLinkW_GetArguments(This
->link
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
591 *Arguments
= SysAllocString(buffW
);
592 return *Arguments
? S_OK
: E_OUTOFMEMORY
;
595 static HRESULT WINAPI
WshShortcut_put_Arguments(IWshShortcut
*iface
, BSTR Arguments
)
597 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
599 TRACE("(%p)->(%s)\n", This
, debugstr_w(Arguments
));
601 return IShellLinkW_SetArguments(This
->link
, Arguments
);
604 static HRESULT WINAPI
WshShortcut_get_Description(IWshShortcut
*iface
, BSTR
*Description
)
606 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
607 FIXME("(%p)->(%p): stub\n", This
, Description
);
611 static HRESULT WINAPI
WshShortcut_put_Description(IWshShortcut
*iface
, BSTR Description
)
613 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
614 TRACE("(%p)->(%s)\n", This
, debugstr_w(Description
));
615 return IShellLinkW_SetDescription(This
->link
, Description
);
618 static HRESULT WINAPI
WshShortcut_get_Hotkey(IWshShortcut
*iface
, BSTR
*Hotkey
)
620 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
621 FIXME("(%p)->(%p): stub\n", This
, Hotkey
);
625 static HRESULT WINAPI
WshShortcut_put_Hotkey(IWshShortcut
*iface
, BSTR Hotkey
)
627 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
628 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(Hotkey
));
632 static HRESULT WINAPI
WshShortcut_get_IconLocation(IWshShortcut
*iface
, BSTR
*IconPath
)
634 static const WCHAR fmtW
[] = {'%','s',',',' ','%','d',0};
635 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
636 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
640 TRACE("(%p)->(%p)\n", This
, IconPath
);
645 hr
= IShellLinkW_GetIconLocation(This
->link
, buffW
, sizeof(buffW
)/sizeof(WCHAR
), &icon
);
646 if (FAILED(hr
)) return hr
;
648 sprintfW(pathW
, fmtW
, buffW
, icon
);
649 *IconPath
= SysAllocString(pathW
);
650 if (!*IconPath
) return E_OUTOFMEMORY
;
655 static HRESULT WINAPI
WshShortcut_put_IconLocation(IWshShortcut
*iface
, BSTR IconPath
)
657 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
663 TRACE("(%p)->(%s)\n", This
, debugstr_w(IconPath
));
665 /* scan for icon id */
666 ptr
= strrchrW(IconPath
, ',');
669 WARN("icon index not found\n");
673 path
= SysAllocStringLen(IconPath
, ptr
-IconPath
);
675 /* skip spaces if any */
676 while (isspaceW(*++ptr
))
681 hr
= IShellLinkW_SetIconLocation(This
->link
, path
, icon
);
687 static HRESULT WINAPI
WshShortcut_put_RelativePath(IWshShortcut
*iface
, BSTR rhs
)
689 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
690 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(rhs
));
694 static HRESULT WINAPI
WshShortcut_get_TargetPath(IWshShortcut
*iface
, BSTR
*Path
)
696 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
697 FIXME("(%p)->(%p): stub\n", This
, Path
);
701 static HRESULT WINAPI
WshShortcut_put_TargetPath(IWshShortcut
*iface
, BSTR Path
)
703 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
704 TRACE("(%p)->(%s)\n", This
, debugstr_w(Path
));
705 return IShellLinkW_SetPath(This
->link
, Path
);
708 static HRESULT WINAPI
WshShortcut_get_WindowStyle(IWshShortcut
*iface
, int *ShowCmd
)
710 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
711 TRACE("(%p)->(%p)\n", This
, ShowCmd
);
712 return IShellLinkW_GetShowCmd(This
->link
, ShowCmd
);
715 static HRESULT WINAPI
WshShortcut_put_WindowStyle(IWshShortcut
*iface
, int ShowCmd
)
717 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
718 TRACE("(%p)->(%d)\n", This
, ShowCmd
);
719 return IShellLinkW_SetShowCmd(This
->link
, ShowCmd
);
722 static HRESULT WINAPI
WshShortcut_get_WorkingDirectory(IWshShortcut
*iface
, BSTR
*WorkingDirectory
)
724 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
725 WCHAR buffW
[MAX_PATH
];
728 TRACE("(%p)->(%p)\n", This
, WorkingDirectory
);
730 if (!WorkingDirectory
)
733 *WorkingDirectory
= NULL
;
734 hr
= IShellLinkW_GetWorkingDirectory(This
->link
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
735 if (FAILED(hr
)) return hr
;
737 *WorkingDirectory
= SysAllocString(buffW
);
738 return *WorkingDirectory
? S_OK
: E_OUTOFMEMORY
;
741 static HRESULT WINAPI
WshShortcut_put_WorkingDirectory(IWshShortcut
*iface
, BSTR WorkingDirectory
)
743 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
744 TRACE("(%p)->(%s)\n", This
, debugstr_w(WorkingDirectory
));
745 return IShellLinkW_SetWorkingDirectory(This
->link
, WorkingDirectory
);
748 static HRESULT WINAPI
WshShortcut_Load(IWshShortcut
*iface
, BSTR PathLink
)
750 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
751 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(PathLink
));
755 static HRESULT WINAPI
WshShortcut_Save(IWshShortcut
*iface
)
757 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
761 TRACE("(%p)\n", This
);
763 IShellLinkW_QueryInterface(This
->link
, &IID_IPersistFile
, (void**)&file
);
764 hr
= IPersistFile_Save(file
, This
->path_link
, TRUE
);
765 IPersistFile_Release(file
);
770 static const IWshShortcutVtbl WshShortcutVtbl
= {
771 WshShortcut_QueryInterface
,
774 WshShortcut_GetTypeInfoCount
,
775 WshShortcut_GetTypeInfo
,
776 WshShortcut_GetIDsOfNames
,
778 WshShortcut_get_FullName
,
779 WshShortcut_get_Arguments
,
780 WshShortcut_put_Arguments
,
781 WshShortcut_get_Description
,
782 WshShortcut_put_Description
,
783 WshShortcut_get_Hotkey
,
784 WshShortcut_put_Hotkey
,
785 WshShortcut_get_IconLocation
,
786 WshShortcut_put_IconLocation
,
787 WshShortcut_put_RelativePath
,
788 WshShortcut_get_TargetPath
,
789 WshShortcut_put_TargetPath
,
790 WshShortcut_get_WindowStyle
,
791 WshShortcut_put_WindowStyle
,
792 WshShortcut_get_WorkingDirectory
,
793 WshShortcut_put_WorkingDirectory
,
798 static HRESULT
WshShortcut_Create(const WCHAR
*path
, IDispatch
**shortcut
)
805 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
806 if (!This
) return E_OUTOFMEMORY
;
808 This
->IWshShortcut_iface
.lpVtbl
= &WshShortcutVtbl
;
811 hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
812 &IID_IShellLinkW
, (void**)&This
->link
);
815 HeapFree(GetProcessHeap(), 0, This
);
819 This
->path_link
= SysAllocString(path
);
820 if (!This
->path_link
)
822 IShellLinkW_Release(This
->link
);
823 HeapFree(GetProcessHeap(), 0, This
);
824 return E_OUTOFMEMORY
;
827 *shortcut
= (IDispatch
*)&This
->IWshShortcut_iface
;
832 static HRESULT WINAPI
WshShell3_QueryInterface(IWshShell3
*iface
, REFIID riid
, void **ppv
)
834 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
838 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
839 IsEqualGUID(riid
, &IID_IDispatch
) ||
840 IsEqualGUID(riid
, &IID_IWshShell3
))
844 else if (IsEqualGUID(riid
, &IID_IDispatchEx
))
846 return E_NOINTERFACE
;
850 FIXME("Unknown iface %s\n", debugstr_guid(riid
));
851 return E_NOINTERFACE
;
854 IWshShell3_AddRef(iface
);
858 static ULONG WINAPI
WshShell3_AddRef(IWshShell3
*iface
)
864 static ULONG WINAPI
WshShell3_Release(IWshShell3
*iface
)
870 static HRESULT WINAPI
WshShell3_GetTypeInfoCount(IWshShell3
*iface
, UINT
*pctinfo
)
872 TRACE("(%p)\n", pctinfo
);
877 static HRESULT WINAPI
WshShell3_GetTypeInfo(IWshShell3
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
879 TRACE("(%u %u %p)\n", iTInfo
, lcid
, ppTInfo
);
880 return get_typeinfo(IWshShell3_tid
, ppTInfo
);
883 static HRESULT WINAPI
WshShell3_GetIDsOfNames(IWshShell3
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
884 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
889 TRACE("(%s %p %u %u %p)\n", debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
891 hr
= get_typeinfo(IWshShell3_tid
, &typeinfo
);
894 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
895 ITypeInfo_Release(typeinfo
);
901 static HRESULT WINAPI
WshShell3_Invoke(IWshShell3
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
902 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
907 TRACE("(%d %s %d %d %p %p %p %p)\n", dispIdMember
, debugstr_guid(riid
),
908 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
910 hr
= get_typeinfo(IWshShell3_tid
, &typeinfo
);
913 hr
= ITypeInfo_Invoke(typeinfo
, &WshShell3
, dispIdMember
, wFlags
,
914 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
915 ITypeInfo_Release(typeinfo
);
921 static HRESULT WINAPI
WshShell3_get_SpecialFolders(IWshShell3
*iface
, IWshCollection
**folders
)
923 TRACE("(%p)\n", folders
);
924 return WshCollection_Create(folders
);
927 static HRESULT WINAPI
WshShell3_get_Environment(IWshShell3
*iface
, VARIANT
*type
, IWshEnvironment
**env
)
929 FIXME("(%s %p): semi-stub\n", debugstr_variant(type
), env
);
930 return WshEnvironment_Create(env
);
933 static HRESULT WINAPI
WshShell3_Run(IWshShell3
*iface
, BSTR cmd
, VARIANT
*style
, VARIANT
*WaitOnReturn
, int *exit_code
)
935 SHELLEXECUTEINFOW info
;
940 TRACE("(%s %s %s %p)\n", debugstr_w(cmd
), debugstr_variant(style
), debugstr_variant(WaitOnReturn
), exit_code
);
943 hr
= VariantChangeType(&s
, style
, 0, VT_I4
);
946 ERR("failed to convert style argument, 0x%08x\n", hr
);
951 hr
= VariantChangeType(&w
, WaitOnReturn
, 0, VT_I4
);
954 ERR("failed to convert wait argument, 0x%08x\n", hr
);
958 memset(&info
, 0, sizeof(info
));
959 info
.cbSize
= sizeof(info
);
961 waitforprocess
= V_I4(&w
);
963 info
.fMask
= waitforprocess
? SEE_MASK_NOASYNC
| SEE_MASK_NOCLOSEPROCESS
: SEE_MASK_DEFAULT
;
965 info
.nShow
= V_I4(&s
);
967 if (!ShellExecuteExW(&info
))
969 TRACE("ShellExecute failed, %d\n", GetLastError());
970 return HRESULT_FROM_WIN32(GetLastError());
979 GetExitCodeProcess(info
.hProcess
, &code
);
982 CloseHandle(info
.hProcess
);
985 if (exit_code
) *exit_code
= 0;
991 static HRESULT WINAPI
WshShell3_Popup(IWshShell3
*iface
, BSTR Text
, VARIANT
* SecondsToWait
, VARIANT
*Title
, VARIANT
*Type
, int *button
)
993 FIXME("(%s %s %s %s %p): stub\n", debugstr_w(Text
), debugstr_variant(SecondsToWait
),
994 debugstr_variant(Title
), debugstr_variant(Type
), button
);
998 static HRESULT WINAPI
WshShell3_CreateShortcut(IWshShell3
*iface
, BSTR PathLink
, IDispatch
** Shortcut
)
1000 TRACE("(%s %p)\n", debugstr_w(PathLink
), Shortcut
);
1001 return WshShortcut_Create(PathLink
, Shortcut
);
1004 static HRESULT WINAPI
WshShell3_ExpandEnvironmentStrings(IWshShell3
*iface
, BSTR Src
, BSTR
* Dst
)
1008 TRACE("(%s %p)\n", debugstr_w(Src
), Dst
);
1010 if (!Src
|| !Dst
) return E_POINTER
;
1012 ret
= ExpandEnvironmentStringsW(Src
, NULL
, 0);
1013 *Dst
= SysAllocStringLen(NULL
, ret
);
1014 if (!*Dst
) return E_OUTOFMEMORY
;
1016 if (ExpandEnvironmentStringsW(Src
, *Dst
, ret
))
1020 SysFreeString(*Dst
);
1022 return HRESULT_FROM_WIN32(GetLastError());
1026 static HRESULT WINAPI
WshShell3_RegRead(IWshShell3
*iface
, BSTR Name
, VARIANT
* out_Value
)
1028 FIXME("(%s %p): stub\n", debugstr_w(Name
), out_Value
);
1032 static HRESULT WINAPI
WshShell3_RegWrite(IWshShell3
*iface
, BSTR Name
, VARIANT
*Value
, VARIANT
*Type
)
1034 FIXME("(%s %s %s): stub\n", debugstr_w(Name
), debugstr_variant(Value
), debugstr_variant(Type
));
1038 static HRESULT WINAPI
WshShell3_RegDelete(IWshShell3
*iface
, BSTR Name
)
1040 FIXME("(%s): stub\n", debugstr_w(Name
));
1044 static HRESULT WINAPI
WshShell3_LogEvent(IWshShell3
*iface
, VARIANT
*Type
, BSTR Message
, BSTR Target
, VARIANT_BOOL
*out_Success
)
1046 FIXME("(%s %s %s %p): stub\n", debugstr_variant(Type
), debugstr_w(Message
), debugstr_w(Target
), out_Success
);
1050 static HRESULT WINAPI
WshShell3_AppActivate(IWshShell3
*iface
, VARIANT
*App
, VARIANT
*Wait
, VARIANT_BOOL
*out_Success
)
1052 FIXME("(%s %s %p): stub\n", debugstr_variant(App
), debugstr_variant(Wait
), out_Success
);
1056 static HRESULT WINAPI
WshShell3_SendKeys(IWshShell3
*iface
, BSTR Keys
, VARIANT
*Wait
)
1058 FIXME("(%s %p): stub\n", debugstr_w(Keys
), Wait
);
1062 static const IWshShell3Vtbl WshShell3Vtbl
= {
1063 WshShell3_QueryInterface
,
1066 WshShell3_GetTypeInfoCount
,
1067 WshShell3_GetTypeInfo
,
1068 WshShell3_GetIDsOfNames
,
1070 WshShell3_get_SpecialFolders
,
1071 WshShell3_get_Environment
,
1074 WshShell3_CreateShortcut
,
1075 WshShell3_ExpandEnvironmentStrings
,
1078 WshShell3_RegDelete
,
1080 WshShell3_AppActivate
,
1084 static IWshShell3 WshShell3
= { &WshShell3Vtbl
};
1086 HRESULT WINAPI
WshShellFactory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID riid
, void **ppv
)
1088 TRACE("(%p %s %p)\n", outer
, debugstr_guid(riid
), ppv
);
1090 return IWshShell3_QueryInterface(&WshShell3
, riid
, ppv
);