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 IWshShell3 WshShell3
;
35 IWshCollection IWshCollection_iface
;
41 IWshShortcut IWshShortcut_iface
;
50 IWshEnvironment IWshEnvironment_iface
;
56 IWshExec IWshExec_iface
;
58 PROCESS_INFORMATION info
;
61 static inline WshCollection
*impl_from_IWshCollection( IWshCollection
*iface
)
63 return CONTAINING_RECORD(iface
, WshCollection
, IWshCollection_iface
);
66 static inline WshShortcut
*impl_from_IWshShortcut( IWshShortcut
*iface
)
68 return CONTAINING_RECORD(iface
, WshShortcut
, IWshShortcut_iface
);
71 static inline WshEnvironment
*impl_from_IWshEnvironment( IWshEnvironment
*iface
)
73 return CONTAINING_RECORD(iface
, WshEnvironment
, IWshEnvironment_iface
);
76 static inline WshExec
*impl_from_IWshExec( IWshExec
*iface
)
78 return CONTAINING_RECORD(iface
, WshExec
, IWshExec_iface
);
81 static HRESULT WINAPI
WshExec_QueryInterface(IWshExec
*iface
, REFIID riid
, void **obj
)
83 WshExec
*This
= impl_from_IWshExec(iface
);
85 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), obj
);
87 if (IsEqualGUID(riid
, &IID_IDispatch
) ||
88 IsEqualGUID(riid
, &IID_IWshExec
) ||
89 IsEqualGUID(riid
, &IID_IUnknown
))
93 FIXME("Unknown iface %s\n", debugstr_guid(riid
));
98 IWshExec_AddRef(iface
);
102 static ULONG WINAPI
WshExec_AddRef(IWshExec
*iface
)
104 WshExec
*This
= impl_from_IWshExec(iface
);
105 LONG ref
= InterlockedIncrement(&This
->ref
);
106 TRACE("(%p) ref = %d\n", This
, ref
);
110 static ULONG WINAPI
WshExec_Release(IWshExec
*iface
)
112 WshExec
*This
= impl_from_IWshExec(iface
);
113 LONG ref
= InterlockedDecrement(&This
->ref
);
114 TRACE("(%p) ref = %d\n", This
, ref
);
117 CloseHandle(This
->info
.hThread
);
118 CloseHandle(This
->info
.hProcess
);
119 HeapFree(GetProcessHeap(), 0, This
);
125 static HRESULT WINAPI
WshExec_GetTypeInfoCount(IWshExec
*iface
, UINT
*pctinfo
)
127 WshExec
*This
= impl_from_IWshExec(iface
);
128 TRACE("(%p)->(%p)\n", This
, pctinfo
);
133 static HRESULT WINAPI
WshExec_GetTypeInfo(IWshExec
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
135 WshExec
*This
= impl_from_IWshExec(iface
);
136 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
137 return get_typeinfo(IWshExec_tid
, ppTInfo
);
140 static HRESULT WINAPI
WshExec_GetIDsOfNames(IWshExec
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
141 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
143 WshExec
*This
= impl_from_IWshExec(iface
);
147 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
149 hr
= get_typeinfo(IWshExec_tid
, &typeinfo
);
152 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
153 ITypeInfo_Release(typeinfo
);
159 static HRESULT WINAPI
WshExec_Invoke(IWshExec
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
160 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
162 WshExec
*This
= impl_from_IWshExec(iface
);
166 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
167 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
169 hr
= get_typeinfo(IWshExec_tid
, &typeinfo
);
172 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IWshExec_iface
, dispIdMember
, wFlags
,
173 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
174 ITypeInfo_Release(typeinfo
);
180 static HRESULT WINAPI
WshExec_get_Status(IWshExec
*iface
, WshExecStatus
*status
)
182 WshExec
*This
= impl_from_IWshExec(iface
);
185 TRACE("(%p)->(%p)\n", This
, status
);
190 if (!GetExitCodeProcess(This
->info
.hProcess
, &code
))
191 return HRESULT_FROM_WIN32(GetLastError());
196 *status
= WshFinished
;
199 *status
= WshRunning
;
208 static HRESULT WINAPI
WshExec_get_StdIn(IWshExec
*iface
, ITextStream
**stream
)
210 WshExec
*This
= impl_from_IWshExec(iface
);
212 FIXME("(%p)->(%p): stub\n", This
, stream
);
217 static HRESULT WINAPI
WshExec_get_StdOut(IWshExec
*iface
, ITextStream
**stream
)
219 WshExec
*This
= impl_from_IWshExec(iface
);
221 FIXME("(%p)->(%p): stub\n", This
, stream
);
226 static HRESULT WINAPI
WshExec_get_StdErr(IWshExec
*iface
, ITextStream
**stream
)
228 WshExec
*This
= impl_from_IWshExec(iface
);
230 FIXME("(%p)->(%p): stub\n", This
, stream
);
235 static HRESULT WINAPI
WshExec_get_ProcessID(IWshExec
*iface
, DWORD
*pid
)
237 WshExec
*This
= impl_from_IWshExec(iface
);
239 TRACE("(%p)->(%p)\n", This
, pid
);
244 *pid
= This
->info
.dwProcessId
;
248 static HRESULT WINAPI
WshExec_get_ExitCode(IWshExec
*iface
, DWORD
*code
)
250 WshExec
*This
= impl_from_IWshExec(iface
);
252 FIXME("(%p)->(%p): stub\n", This
, code
);
257 static HRESULT WINAPI
WshExec_Terminate(IWshExec
*iface
)
259 WshExec
*This
= impl_from_IWshExec(iface
);
261 FIXME("(%p): stub\n", This
);
266 static const IWshExecVtbl WshExecVtbl
= {
267 WshExec_QueryInterface
,
270 WshExec_GetTypeInfoCount
,
272 WshExec_GetIDsOfNames
,
278 WshExec_get_ProcessID
,
279 WshExec_get_ExitCode
,
283 static HRESULT
WshExec_create(BSTR command
, IWshExec
**ret
)
285 STARTUPINFOW si
= {0};
290 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
292 return E_OUTOFMEMORY
;
294 This
->IWshExec_iface
.lpVtbl
= &WshExecVtbl
;
297 if (!CreateProcessW(NULL
, command
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &This
->info
)) {
298 HeapFree(GetProcessHeap(), 0, This
);
299 return HRESULT_FROM_WIN32(GetLastError());
302 *ret
= &This
->IWshExec_iface
;
306 static HRESULT WINAPI
WshEnvironment_QueryInterface(IWshEnvironment
*iface
, REFIID riid
, void **obj
)
308 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
310 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), obj
);
312 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
313 IsEqualGUID(riid
, &IID_IDispatch
) ||
314 IsEqualGUID(riid
, &IID_IWshEnvironment
))
318 FIXME("Unknown iface %s\n", debugstr_guid(riid
));
320 return E_NOINTERFACE
;
323 IUnknown_AddRef((IUnknown
*)*obj
);
327 static ULONG WINAPI
WshEnvironment_AddRef(IWshEnvironment
*iface
)
329 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
330 LONG ref
= InterlockedIncrement(&This
->ref
);
331 TRACE("(%p) ref = %d\n", This
, ref
);
335 static ULONG WINAPI
WshEnvironment_Release(IWshEnvironment
*iface
)
337 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
338 LONG ref
= InterlockedDecrement(&This
->ref
);
339 TRACE("(%p) ref = %d\n", This
, ref
);
342 HeapFree(GetProcessHeap(), 0, This
);
347 static HRESULT WINAPI
WshEnvironment_GetTypeInfoCount(IWshEnvironment
*iface
, UINT
*pctinfo
)
349 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
350 TRACE("(%p)->(%p)\n", This
, pctinfo
);
355 static HRESULT WINAPI
WshEnvironment_GetTypeInfo(IWshEnvironment
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
357 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
358 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
359 return get_typeinfo(IWshEnvironment_tid
, ppTInfo
);
362 static HRESULT WINAPI
WshEnvironment_GetIDsOfNames(IWshEnvironment
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
363 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
365 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
369 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
371 hr
= get_typeinfo(IWshEnvironment_tid
, &typeinfo
);
374 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
375 ITypeInfo_Release(typeinfo
);
381 static HRESULT WINAPI
WshEnvironment_Invoke(IWshEnvironment
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
382 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
384 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
388 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
389 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
391 hr
= get_typeinfo(IWshEnvironment_tid
, &typeinfo
);
394 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IWshEnvironment_iface
, dispIdMember
, wFlags
,
395 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
396 ITypeInfo_Release(typeinfo
);
402 static HRESULT WINAPI
WshEnvironment_get_Item(IWshEnvironment
*iface
, BSTR name
, BSTR
*value
)
404 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
407 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), value
);
412 len
= GetEnvironmentVariableW(name
, NULL
, 0);
413 *value
= SysAllocStringLen(NULL
, len
);
415 return E_OUTOFMEMORY
;
418 GetEnvironmentVariableW(name
, *value
, len
+1);
423 static HRESULT WINAPI
WshEnvironment_put_Item(IWshEnvironment
*iface
, BSTR name
, BSTR value
)
425 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
426 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(name
), debugstr_w(value
));
430 static HRESULT WINAPI
WshEnvironment_Count(IWshEnvironment
*iface
, LONG
*count
)
432 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
433 FIXME("(%p)->(%p): stub\n", This
, count
);
437 static HRESULT WINAPI
WshEnvironment_get_length(IWshEnvironment
*iface
, LONG
*len
)
439 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
440 FIXME("(%p)->(%p): stub\n", This
, len
);
444 static HRESULT WINAPI
WshEnvironment__NewEnum(IWshEnvironment
*iface
, IUnknown
**penum
)
446 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
447 FIXME("(%p)->(%p): stub\n", This
, penum
);
451 static HRESULT WINAPI
WshEnvironment_Remove(IWshEnvironment
*iface
, BSTR name
)
453 WshEnvironment
*This
= impl_from_IWshEnvironment(iface
);
454 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(name
));
458 static const IWshEnvironmentVtbl WshEnvironmentVtbl
= {
459 WshEnvironment_QueryInterface
,
460 WshEnvironment_AddRef
,
461 WshEnvironment_Release
,
462 WshEnvironment_GetTypeInfoCount
,
463 WshEnvironment_GetTypeInfo
,
464 WshEnvironment_GetIDsOfNames
,
465 WshEnvironment_Invoke
,
466 WshEnvironment_get_Item
,
467 WshEnvironment_put_Item
,
468 WshEnvironment_Count
,
469 WshEnvironment_get_length
,
470 WshEnvironment__NewEnum
,
471 WshEnvironment_Remove
474 static HRESULT
WshEnvironment_Create(IWshEnvironment
**env
)
476 WshEnvironment
*This
;
478 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
479 if (!This
) return E_OUTOFMEMORY
;
481 This
->IWshEnvironment_iface
.lpVtbl
= &WshEnvironmentVtbl
;
484 *env
= &This
->IWshEnvironment_iface
;
489 static HRESULT WINAPI
WshCollection_QueryInterface(IWshCollection
*iface
, REFIID riid
, void **ppv
)
491 WshCollection
*This
= impl_from_IWshCollection(iface
);
493 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppv
);
495 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
496 IsEqualGUID(riid
, &IID_IDispatch
) ||
497 IsEqualGUID(riid
, &IID_IWshCollection
))
501 FIXME("Unknown iface %s\n", debugstr_guid(riid
));
503 return E_NOINTERFACE
;
506 IUnknown_AddRef((IUnknown
*)*ppv
);
510 static ULONG WINAPI
WshCollection_AddRef(IWshCollection
*iface
)
512 WshCollection
*This
= impl_from_IWshCollection(iface
);
513 LONG ref
= InterlockedIncrement(&This
->ref
);
514 TRACE("(%p) ref = %d\n", This
, ref
);
518 static ULONG WINAPI
WshCollection_Release(IWshCollection
*iface
)
520 WshCollection
*This
= impl_from_IWshCollection(iface
);
521 LONG ref
= InterlockedDecrement(&This
->ref
);
522 TRACE("(%p) ref = %d\n", This
, ref
);
525 HeapFree(GetProcessHeap(), 0, This
);
530 static HRESULT WINAPI
WshCollection_GetTypeInfoCount(IWshCollection
*iface
, UINT
*pctinfo
)
532 WshCollection
*This
= impl_from_IWshCollection(iface
);
533 TRACE("(%p)->(%p)\n", This
, pctinfo
);
538 static HRESULT WINAPI
WshCollection_GetTypeInfo(IWshCollection
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
540 WshCollection
*This
= impl_from_IWshCollection(iface
);
541 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
542 return get_typeinfo(IWshCollection_tid
, ppTInfo
);
545 static HRESULT WINAPI
WshCollection_GetIDsOfNames(IWshCollection
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
546 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
548 WshCollection
*This
= impl_from_IWshCollection(iface
);
552 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
554 hr
= get_typeinfo(IWshCollection_tid
, &typeinfo
);
557 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
558 ITypeInfo_Release(typeinfo
);
564 static HRESULT WINAPI
WshCollection_Invoke(IWshCollection
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
565 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
567 WshCollection
*This
= impl_from_IWshCollection(iface
);
571 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
572 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
574 hr
= get_typeinfo(IWshCollection_tid
, &typeinfo
);
577 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IWshCollection_iface
, dispIdMember
, wFlags
,
578 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
579 ITypeInfo_Release(typeinfo
);
585 static HRESULT WINAPI
WshCollection_Item(IWshCollection
*iface
, VARIANT
*index
, VARIANT
*value
)
587 WshCollection
*This
= impl_from_IWshCollection(iface
);
588 static const WCHAR allusersdesktopW
[] = {'A','l','l','U','s','e','r','s','D','e','s','k','t','o','p',0};
589 static const WCHAR allusersprogramsW
[] = {'A','l','l','U','s','e','r','s','P','r','o','g','r','a','m','s',0};
590 static const WCHAR desktopW
[] = {'D','e','s','k','t','o','p',0};
591 PIDLIST_ABSOLUTE pidl
;
592 WCHAR pathW
[MAX_PATH
];
597 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(index
), value
);
599 if (V_VT(index
) != VT_BSTR
)
601 FIXME("only BSTR index supported, got %d\n", V_VT(index
));
605 folder
= V_BSTR(index
);
606 if (!strcmpiW(folder
, desktopW
))
607 kind
= CSIDL_DESKTOP
;
608 else if (!strcmpiW(folder
, allusersdesktopW
))
609 kind
= CSIDL_COMMON_DESKTOPDIRECTORY
;
610 else if (!strcmpiW(folder
, allusersprogramsW
))
611 kind
= CSIDL_COMMON_PROGRAMS
;
614 FIXME("folder kind %s not supported\n", debugstr_w(folder
));
618 hr
= SHGetSpecialFolderLocation(NULL
, kind
, &pidl
);
619 if (hr
!= S_OK
) return hr
;
621 if (SHGetPathFromIDListW(pidl
, pathW
))
623 V_VT(value
) = VT_BSTR
;
624 V_BSTR(value
) = SysAllocString(pathW
);
625 hr
= V_BSTR(value
) ? S_OK
: E_OUTOFMEMORY
;
635 static HRESULT WINAPI
WshCollection_Count(IWshCollection
*iface
, LONG
*count
)
637 WshCollection
*This
= impl_from_IWshCollection(iface
);
638 FIXME("(%p)->(%p): stub\n", This
, count
);
642 static HRESULT WINAPI
WshCollection_get_length(IWshCollection
*iface
, LONG
*count
)
644 WshCollection
*This
= impl_from_IWshCollection(iface
);
645 FIXME("(%p)->(%p): stub\n", This
, count
);
649 static HRESULT WINAPI
WshCollection__NewEnum(IWshCollection
*iface
, IUnknown
*Enum
)
651 WshCollection
*This
= impl_from_IWshCollection(iface
);
652 FIXME("(%p)->(%p): stub\n", This
, Enum
);
656 static const IWshCollectionVtbl WshCollectionVtbl
= {
657 WshCollection_QueryInterface
,
658 WshCollection_AddRef
,
659 WshCollection_Release
,
660 WshCollection_GetTypeInfoCount
,
661 WshCollection_GetTypeInfo
,
662 WshCollection_GetIDsOfNames
,
663 WshCollection_Invoke
,
666 WshCollection_get_length
,
667 WshCollection__NewEnum
670 static HRESULT
WshCollection_Create(IWshCollection
**collection
)
674 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
675 if (!This
) return E_OUTOFMEMORY
;
677 This
->IWshCollection_iface
.lpVtbl
= &WshCollectionVtbl
;
680 *collection
= &This
->IWshCollection_iface
;
686 static HRESULT WINAPI
WshShortcut_QueryInterface(IWshShortcut
*iface
, REFIID riid
, void **ppv
)
688 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
690 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppv
);
692 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
693 IsEqualGUID(riid
, &IID_IDispatch
) ||
694 IsEqualGUID(riid
, &IID_IWshShortcut
))
698 FIXME("Unknown iface %s\n", debugstr_guid(riid
));
700 return E_NOINTERFACE
;
703 IUnknown_AddRef((IUnknown
*)*ppv
);
707 static ULONG WINAPI
WshShortcut_AddRef(IWshShortcut
*iface
)
709 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
710 LONG ref
= InterlockedIncrement(&This
->ref
);
711 TRACE("(%p) ref = %d\n", This
, ref
);
715 static ULONG WINAPI
WshShortcut_Release(IWshShortcut
*iface
)
717 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
718 LONG ref
= InterlockedDecrement(&This
->ref
);
719 TRACE("(%p) ref = %d\n", This
, ref
);
723 SysFreeString(This
->path_link
);
724 IShellLinkW_Release(This
->link
);
725 HeapFree(GetProcessHeap(), 0, This
);
731 static HRESULT WINAPI
WshShortcut_GetTypeInfoCount(IWshShortcut
*iface
, UINT
*pctinfo
)
733 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
734 TRACE("(%p)->(%p)\n", This
, pctinfo
);
739 static HRESULT WINAPI
WshShortcut_GetTypeInfo(IWshShortcut
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
741 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
742 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
743 return get_typeinfo(IWshShortcut_tid
, ppTInfo
);
746 static HRESULT WINAPI
WshShortcut_GetIDsOfNames(IWshShortcut
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
747 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
749 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
753 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
755 hr
= get_typeinfo(IWshShortcut_tid
, &typeinfo
);
758 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
759 ITypeInfo_Release(typeinfo
);
765 static HRESULT WINAPI
WshShortcut_Invoke(IWshShortcut
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
766 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
768 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
772 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
773 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
775 hr
= get_typeinfo(IWshShortcut_tid
, &typeinfo
);
778 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IWshShortcut_iface
, dispIdMember
, wFlags
,
779 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
780 ITypeInfo_Release(typeinfo
);
786 static HRESULT WINAPI
WshShortcut_get_FullName(IWshShortcut
*iface
, BSTR
*name
)
788 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
789 FIXME("(%p)->(%p): stub\n", This
, name
);
793 static HRESULT WINAPI
WshShortcut_get_Arguments(IWshShortcut
*iface
, BSTR
*Arguments
)
795 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
796 WCHAR buffW
[INFOTIPSIZE
];
799 TRACE("(%p)->(%p)\n", This
, Arguments
);
806 hr
= IShellLinkW_GetArguments(This
->link
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
810 *Arguments
= SysAllocString(buffW
);
811 return *Arguments
? S_OK
: E_OUTOFMEMORY
;
814 static HRESULT WINAPI
WshShortcut_put_Arguments(IWshShortcut
*iface
, BSTR Arguments
)
816 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
818 TRACE("(%p)->(%s)\n", This
, debugstr_w(Arguments
));
820 return IShellLinkW_SetArguments(This
->link
, Arguments
);
823 static HRESULT WINAPI
WshShortcut_get_Description(IWshShortcut
*iface
, BSTR
*Description
)
825 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
826 FIXME("(%p)->(%p): stub\n", This
, Description
);
830 static HRESULT WINAPI
WshShortcut_put_Description(IWshShortcut
*iface
, BSTR Description
)
832 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
833 TRACE("(%p)->(%s)\n", This
, debugstr_w(Description
));
834 return IShellLinkW_SetDescription(This
->link
, Description
);
837 static HRESULT WINAPI
WshShortcut_get_Hotkey(IWshShortcut
*iface
, BSTR
*Hotkey
)
839 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
840 FIXME("(%p)->(%p): stub\n", This
, Hotkey
);
844 static HRESULT WINAPI
WshShortcut_put_Hotkey(IWshShortcut
*iface
, BSTR Hotkey
)
846 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
847 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(Hotkey
));
851 static HRESULT WINAPI
WshShortcut_get_IconLocation(IWshShortcut
*iface
, BSTR
*IconPath
)
853 static const WCHAR fmtW
[] = {'%','s',',',' ','%','d',0};
854 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
855 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
859 TRACE("(%p)->(%p)\n", This
, IconPath
);
864 hr
= IShellLinkW_GetIconLocation(This
->link
, buffW
, sizeof(buffW
)/sizeof(WCHAR
), &icon
);
865 if (FAILED(hr
)) return hr
;
867 sprintfW(pathW
, fmtW
, buffW
, icon
);
868 *IconPath
= SysAllocString(pathW
);
869 if (!*IconPath
) return E_OUTOFMEMORY
;
874 static HRESULT WINAPI
WshShortcut_put_IconLocation(IWshShortcut
*iface
, BSTR IconPath
)
876 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
882 TRACE("(%p)->(%s)\n", This
, debugstr_w(IconPath
));
884 /* scan for icon id */
885 ptr
= strrchrW(IconPath
, ',');
888 WARN("icon index not found\n");
892 path
= SysAllocStringLen(IconPath
, ptr
-IconPath
);
894 /* skip spaces if any */
895 while (isspaceW(*++ptr
))
900 hr
= IShellLinkW_SetIconLocation(This
->link
, path
, icon
);
906 static HRESULT WINAPI
WshShortcut_put_RelativePath(IWshShortcut
*iface
, BSTR rhs
)
908 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
909 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(rhs
));
913 static HRESULT WINAPI
WshShortcut_get_TargetPath(IWshShortcut
*iface
, BSTR
*Path
)
915 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
916 FIXME("(%p)->(%p): stub\n", This
, Path
);
920 static HRESULT WINAPI
WshShortcut_put_TargetPath(IWshShortcut
*iface
, BSTR Path
)
922 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
923 TRACE("(%p)->(%s)\n", This
, debugstr_w(Path
));
924 return IShellLinkW_SetPath(This
->link
, Path
);
927 static HRESULT WINAPI
WshShortcut_get_WindowStyle(IWshShortcut
*iface
, int *ShowCmd
)
929 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
930 TRACE("(%p)->(%p)\n", This
, ShowCmd
);
931 return IShellLinkW_GetShowCmd(This
->link
, ShowCmd
);
934 static HRESULT WINAPI
WshShortcut_put_WindowStyle(IWshShortcut
*iface
, int ShowCmd
)
936 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
937 TRACE("(%p)->(%d)\n", This
, ShowCmd
);
938 return IShellLinkW_SetShowCmd(This
->link
, ShowCmd
);
941 static HRESULT WINAPI
WshShortcut_get_WorkingDirectory(IWshShortcut
*iface
, BSTR
*WorkingDirectory
)
943 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
944 WCHAR buffW
[MAX_PATH
];
947 TRACE("(%p)->(%p)\n", This
, WorkingDirectory
);
949 if (!WorkingDirectory
)
952 *WorkingDirectory
= NULL
;
953 hr
= IShellLinkW_GetWorkingDirectory(This
->link
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
954 if (FAILED(hr
)) return hr
;
956 *WorkingDirectory
= SysAllocString(buffW
);
957 return *WorkingDirectory
? S_OK
: E_OUTOFMEMORY
;
960 static HRESULT WINAPI
WshShortcut_put_WorkingDirectory(IWshShortcut
*iface
, BSTR WorkingDirectory
)
962 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
963 TRACE("(%p)->(%s)\n", This
, debugstr_w(WorkingDirectory
));
964 return IShellLinkW_SetWorkingDirectory(This
->link
, WorkingDirectory
);
967 static HRESULT WINAPI
WshShortcut_Load(IWshShortcut
*iface
, BSTR PathLink
)
969 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
970 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(PathLink
));
974 static HRESULT WINAPI
WshShortcut_Save(IWshShortcut
*iface
)
976 WshShortcut
*This
= impl_from_IWshShortcut(iface
);
980 TRACE("(%p)\n", This
);
982 IShellLinkW_QueryInterface(This
->link
, &IID_IPersistFile
, (void**)&file
);
983 hr
= IPersistFile_Save(file
, This
->path_link
, TRUE
);
984 IPersistFile_Release(file
);
989 static const IWshShortcutVtbl WshShortcutVtbl
= {
990 WshShortcut_QueryInterface
,
993 WshShortcut_GetTypeInfoCount
,
994 WshShortcut_GetTypeInfo
,
995 WshShortcut_GetIDsOfNames
,
997 WshShortcut_get_FullName
,
998 WshShortcut_get_Arguments
,
999 WshShortcut_put_Arguments
,
1000 WshShortcut_get_Description
,
1001 WshShortcut_put_Description
,
1002 WshShortcut_get_Hotkey
,
1003 WshShortcut_put_Hotkey
,
1004 WshShortcut_get_IconLocation
,
1005 WshShortcut_put_IconLocation
,
1006 WshShortcut_put_RelativePath
,
1007 WshShortcut_get_TargetPath
,
1008 WshShortcut_put_TargetPath
,
1009 WshShortcut_get_WindowStyle
,
1010 WshShortcut_put_WindowStyle
,
1011 WshShortcut_get_WorkingDirectory
,
1012 WshShortcut_put_WorkingDirectory
,
1017 static HRESULT
WshShortcut_Create(const WCHAR
*path
, IDispatch
**shortcut
)
1024 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
1025 if (!This
) return E_OUTOFMEMORY
;
1027 This
->IWshShortcut_iface
.lpVtbl
= &WshShortcutVtbl
;
1030 hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
1031 &IID_IShellLinkW
, (void**)&This
->link
);
1034 HeapFree(GetProcessHeap(), 0, This
);
1038 This
->path_link
= SysAllocString(path
);
1039 if (!This
->path_link
)
1041 IShellLinkW_Release(This
->link
);
1042 HeapFree(GetProcessHeap(), 0, This
);
1043 return E_OUTOFMEMORY
;
1046 *shortcut
= (IDispatch
*)&This
->IWshShortcut_iface
;
1051 static HRESULT WINAPI
WshShell3_QueryInterface(IWshShell3
*iface
, REFIID riid
, void **ppv
)
1053 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
1057 if (IsEqualGUID(riid
, &IID_IDispatch
) ||
1058 IsEqualGUID(riid
, &IID_IWshShell3
) ||
1059 IsEqualGUID(riid
, &IID_IWshShell2
) ||
1060 IsEqualGUID(riid
, &IID_IWshShell
) ||
1061 IsEqualGUID(riid
, &IID_IUnknown
))
1065 else if (IsEqualGUID(riid
, &IID_IDispatchEx
))
1067 return E_NOINTERFACE
;
1071 WARN("unknown iface %s\n", debugstr_guid(riid
));
1072 return E_NOINTERFACE
;
1075 IWshShell3_AddRef(iface
);
1079 static ULONG WINAPI
WshShell3_AddRef(IWshShell3
*iface
)
1085 static ULONG WINAPI
WshShell3_Release(IWshShell3
*iface
)
1091 static HRESULT WINAPI
WshShell3_GetTypeInfoCount(IWshShell3
*iface
, UINT
*pctinfo
)
1093 TRACE("(%p)\n", pctinfo
);
1098 static HRESULT WINAPI
WshShell3_GetTypeInfo(IWshShell3
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1100 TRACE("(%u %u %p)\n", iTInfo
, lcid
, ppTInfo
);
1101 return get_typeinfo(IWshShell3_tid
, ppTInfo
);
1104 static HRESULT WINAPI
WshShell3_GetIDsOfNames(IWshShell3
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
1105 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1107 ITypeInfo
*typeinfo
;
1110 TRACE("(%s %p %u %u %p)\n", debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1112 hr
= get_typeinfo(IWshShell3_tid
, &typeinfo
);
1115 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1116 ITypeInfo_Release(typeinfo
);
1122 static HRESULT WINAPI
WshShell3_Invoke(IWshShell3
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1123 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1125 ITypeInfo
*typeinfo
;
1128 TRACE("(%d %s %d %d %p %p %p %p)\n", dispIdMember
, debugstr_guid(riid
),
1129 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1131 hr
= get_typeinfo(IWshShell3_tid
, &typeinfo
);
1134 hr
= ITypeInfo_Invoke(typeinfo
, &WshShell3
, dispIdMember
, wFlags
,
1135 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1136 ITypeInfo_Release(typeinfo
);
1142 static HRESULT WINAPI
WshShell3_get_SpecialFolders(IWshShell3
*iface
, IWshCollection
**folders
)
1144 TRACE("(%p)\n", folders
);
1145 return WshCollection_Create(folders
);
1148 static HRESULT WINAPI
WshShell3_get_Environment(IWshShell3
*iface
, VARIANT
*type
, IWshEnvironment
**env
)
1150 FIXME("(%s %p): semi-stub\n", debugstr_variant(type
), env
);
1151 return WshEnvironment_Create(env
);
1154 static inline BOOL
is_optional_argument(const VARIANT
*arg
)
1156 return V_VT(arg
) == VT_ERROR
&& V_ERROR(arg
) == DISP_E_PARAMNOTFOUND
;
1159 static HRESULT WINAPI
WshShell3_Run(IWshShell3
*iface
, BSTR cmd
, VARIANT
*style
, VARIANT
*wait
, DWORD
*exit_code
)
1161 SHELLEXECUTEINFOW info
;
1166 TRACE("(%s %s %s %p)\n", debugstr_w(cmd
), debugstr_variant(style
), debugstr_variant(wait
), exit_code
);
1168 if (!style
|| !wait
|| !exit_code
)
1172 hr
= VariantChangeType(&s
, style
, 0, VT_I4
);
1175 ERR("failed to convert style argument, 0x%08x\n", hr
);
1179 if (is_optional_argument(wait
))
1185 hr
= VariantChangeType(&w
, wait
, 0, VT_I4
);
1189 waitforprocess
= V_I4(&w
);
1192 memset(&info
, 0, sizeof(info
));
1193 info
.cbSize
= sizeof(info
);
1194 info
.fMask
= waitforprocess
? SEE_MASK_NOASYNC
| SEE_MASK_NOCLOSEPROCESS
: SEE_MASK_DEFAULT
;
1196 info
.nShow
= V_I4(&s
);
1198 if (!ShellExecuteExW(&info
))
1200 TRACE("ShellExecute failed, %d\n", GetLastError());
1201 return HRESULT_FROM_WIN32(GetLastError());
1207 GetExitCodeProcess(info
.hProcess
, exit_code
);
1208 CloseHandle(info
.hProcess
);
1217 static HRESULT WINAPI
WshShell3_Popup(IWshShell3
*iface
, BSTR Text
, VARIANT
* SecondsToWait
, VARIANT
*Title
, VARIANT
*Type
, int *button
)
1219 FIXME("(%s %s %s %s %p): stub\n", debugstr_w(Text
), debugstr_variant(SecondsToWait
),
1220 debugstr_variant(Title
), debugstr_variant(Type
), button
);
1224 static HRESULT WINAPI
WshShell3_CreateShortcut(IWshShell3
*iface
, BSTR PathLink
, IDispatch
** Shortcut
)
1226 TRACE("(%s %p)\n", debugstr_w(PathLink
), Shortcut
);
1227 return WshShortcut_Create(PathLink
, Shortcut
);
1230 static HRESULT WINAPI
WshShell3_ExpandEnvironmentStrings(IWshShell3
*iface
, BSTR Src
, BSTR
* Dst
)
1234 TRACE("(%s %p)\n", debugstr_w(Src
), Dst
);
1236 if (!Src
|| !Dst
) return E_POINTER
;
1238 ret
= ExpandEnvironmentStringsW(Src
, NULL
, 0);
1239 *Dst
= SysAllocStringLen(NULL
, ret
);
1240 if (!*Dst
) return E_OUTOFMEMORY
;
1242 if (ExpandEnvironmentStringsW(Src
, *Dst
, ret
))
1246 SysFreeString(*Dst
);
1248 return HRESULT_FROM_WIN32(GetLastError());
1252 static HKEY
get_root_key(const WCHAR
*path
)
1254 static const struct {
1255 const WCHAR full
[20];
1256 const WCHAR abbrev
[5];
1259 { {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R',0}, {'H','K','C','U',0}, HKEY_CURRENT_USER
},
1260 { {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0}, {'H','K','L','M',0}, HKEY_LOCAL_MACHINE
},
1261 { {'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T',0}, {'H','K','C','R',0}, HKEY_CLASSES_ROOT
},
1262 { {'H','K','E','Y','_','U','S','E','R','S',0}, {0}, HKEY_USERS
},
1263 { {'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0}, {0}, HKEY_CURRENT_CONFIG
}
1267 for (i
= 0; i
< sizeof(rootkeys
)/sizeof(rootkeys
[0]); i
++) {
1268 if (!strncmpW(path
, rootkeys
[i
].full
, strlenW(rootkeys
[i
].full
)))
1269 return rootkeys
[i
].hkey
;
1270 if (rootkeys
[i
].abbrev
[0] && !strncmpW(path
, rootkeys
[i
].abbrev
, strlenW(rootkeys
[i
].abbrev
)))
1271 return rootkeys
[i
].hkey
;
1277 /* Caller is responsible to free 'subkey' if 'value' is not NULL */
1278 static HRESULT
split_reg_path(const WCHAR
*path
, WCHAR
**subkey
, WCHAR
**value
)
1282 /* at least one separator should be present */
1283 *subkey
= strchrW(path
, '\\');
1285 return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
);
1287 /* default value or not */
1288 if ((*subkey
)[strlenW(*subkey
)-1] == '\\') {
1293 *value
= strrchrW(*subkey
, '\\');
1294 if (*value
- *subkey
> 1) {
1295 unsigned int len
= *value
- *subkey
- 1;
1298 ret
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
1300 return E_OUTOFMEMORY
;
1302 memcpy(ret
, *subkey
+ 1, len
*sizeof(WCHAR
));
1312 static HRESULT WINAPI
WshShell3_RegRead(IWshShell3
*iface
, BSTR name
, VARIANT
*value
)
1314 DWORD type
, datalen
, ret
;
1315 WCHAR
*subkey
, *val
;
1319 TRACE("(%s %p)\n", debugstr_w(name
), value
);
1321 if (!name
|| !value
)
1324 root
= get_root_key(name
);
1326 return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
);
1328 hr
= split_reg_path(name
, &subkey
, &val
);
1334 ret
= RegGetValueW(root
, subkey
, val
, RRF_RT_ANY
, &type
, NULL
, &datalen
);
1335 if (ret
== ERROR_SUCCESS
) {
1338 data
= HeapAlloc(GetProcessHeap(), 0, datalen
);
1344 ret
= RegGetValueW(root
, subkey
, val
, RRF_RT_ANY
, &type
, data
, &datalen
);
1346 HeapFree(GetProcessHeap(), 0, data
);
1347 hr
= HRESULT_FROM_WIN32(ret
);
1354 V_VT(value
) = VT_BSTR
;
1355 V_BSTR(value
) = SysAllocStringLen((WCHAR
*)data
, datalen
- sizeof(WCHAR
));
1360 V_VT(value
) = VT_I4
;
1361 V_I4(value
) = *(DWORD
*)data
;
1365 BYTE
*ptr
= (BYTE
*)data
;
1366 SAFEARRAYBOUND bound
;
1372 bound
.cElements
= datalen
;
1373 sa
= SafeArrayCreate(VT_VARIANT
, 1, &bound
);
1377 hr
= SafeArrayAccessData(sa
, (void**)&v
);
1379 SafeArrayDestroy(sa
);
1383 for (i
= 0; i
< datalen
; i
++) {
1384 V_VT(&v
[i
]) = VT_UI1
;
1385 V_UI1(&v
[i
]) = ptr
[i
];
1387 SafeArrayUnaccessData(sa
);
1389 V_VT(value
) = VT_ARRAY
|VT_VARIANT
;
1390 V_ARRAY(value
) = sa
;
1395 WCHAR
*ptr
= (WCHAR
*)data
;
1396 SAFEARRAYBOUND bound
;
1400 /* get element count first */
1402 bound
.cElements
= 0;
1405 ptr
+= strlenW(ptr
)+1;
1408 sa
= SafeArrayCreate(VT_VARIANT
, 1, &bound
);
1412 hr
= SafeArrayAccessData(sa
, (void**)&v
);
1414 SafeArrayDestroy(sa
);
1421 V_BSTR(v
) = SysAllocString(ptr
);
1422 ptr
+= strlenW(ptr
)+1;
1426 SafeArrayUnaccessData(sa
);
1427 V_VT(value
) = VT_ARRAY
|VT_VARIANT
;
1428 V_ARRAY(value
) = sa
;
1432 FIXME("value type %d not supported\n", type
);
1436 HeapFree(GetProcessHeap(), 0, data
);
1441 hr
= HRESULT_FROM_WIN32(ret
);
1445 HeapFree(GetProcessHeap(), 0, subkey
);
1449 static HRESULT WINAPI
WshShell3_RegWrite(IWshShell3
*iface
, BSTR name
, VARIANT
*value
, VARIANT
*type
)
1451 static const WCHAR regexpandszW
[] = {'R','E','G','_','E','X','P','A','N','D','_','S','Z',0};
1452 static const WCHAR regszW
[] = {'R','E','G','_','S','Z',0};
1453 static const WCHAR regdwordW
[] = {'R','E','G','_','D','W','O','R','D',0};
1454 static const WCHAR regbinaryW
[] = {'R','E','G','_','B','I','N','A','R','Y',0};
1456 DWORD regtype
, data_len
;
1457 WCHAR
*subkey
, *val
;
1464 TRACE("(%s %s %s)\n", debugstr_w(name
), debugstr_variant(value
), debugstr_variant(type
));
1466 if (!name
|| !value
|| !type
)
1469 root
= get_root_key(name
);
1471 return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
);
1474 if (is_optional_argument(type
))
1477 if (V_VT(type
) != VT_BSTR
)
1478 return E_INVALIDARG
;
1480 if (!strcmpW(V_BSTR(type
), regszW
))
1482 else if (!strcmpW(V_BSTR(type
), regdwordW
))
1483 regtype
= REG_DWORD
;
1484 else if (!strcmpW(V_BSTR(type
), regexpandszW
))
1485 regtype
= REG_EXPAND_SZ
;
1486 else if (!strcmpW(V_BSTR(type
), regbinaryW
))
1487 regtype
= REG_BINARY
;
1489 FIXME("unrecognized value type %s\n", debugstr_w(V_BSTR(type
)));
1494 /* it's always a string or a DWORD */
1500 hr
= VariantChangeType(&v
, value
, 0, VT_BSTR
);
1502 data
= (BYTE
*)V_BSTR(&v
);
1503 data_len
= SysStringByteLen(V_BSTR(&v
)) + sizeof(WCHAR
);
1508 hr
= VariantChangeType(&v
, value
, 0, VT_I4
);
1509 data
= (BYTE
*)&V_I4(&v
);
1510 data_len
= sizeof(DWORD
);
1513 FIXME("unexpected regtype %d\n", regtype
);
1518 FIXME("failed to convert value, regtype %d, 0x%08x\n", regtype
, hr
);
1522 hr
= split_reg_path(name
, &subkey
, &val
);
1526 ret
= RegSetKeyValueW(root
, subkey
, val
, regtype
, data
, data_len
);
1528 hr
= HRESULT_FROM_WIN32(ret
);
1533 HeapFree(GetProcessHeap(), 0, subkey
);
1537 static HRESULT WINAPI
WshShell3_RegDelete(IWshShell3
*iface
, BSTR Name
)
1539 FIXME("(%s): stub\n", debugstr_w(Name
));
1543 static HRESULT WINAPI
WshShell3_LogEvent(IWshShell3
*iface
, VARIANT
*Type
, BSTR Message
, BSTR Target
, VARIANT_BOOL
*out_Success
)
1545 FIXME("(%s %s %s %p): stub\n", debugstr_variant(Type
), debugstr_w(Message
), debugstr_w(Target
), out_Success
);
1549 static HRESULT WINAPI
WshShell3_AppActivate(IWshShell3
*iface
, VARIANT
*App
, VARIANT
*Wait
, VARIANT_BOOL
*out_Success
)
1551 FIXME("(%s %s %p): stub\n", debugstr_variant(App
), debugstr_variant(Wait
), out_Success
);
1555 static HRESULT WINAPI
WshShell3_SendKeys(IWshShell3
*iface
, BSTR Keys
, VARIANT
*Wait
)
1557 FIXME("(%s %p): stub\n", debugstr_w(Keys
), Wait
);
1561 static HRESULT WINAPI
WshShell3_Exec(IWshShell3
*iface
, BSTR command
, IWshExec
**ret
)
1563 TRACE("(%s %p)\n", debugstr_w(command
), ret
);
1569 return DISP_E_EXCEPTION
;
1571 return WshExec_create(command
, ret
);
1574 static HRESULT WINAPI
WshShell3_get_CurrentDirectory(IWshShell3
*iface
, BSTR
*dir
)
1578 TRACE("(%p)\n", dir
);
1580 ret
= GetCurrentDirectoryW(0, NULL
);
1582 return HRESULT_FROM_WIN32(GetLastError());
1584 *dir
= SysAllocStringLen(NULL
, ret
-1);
1586 return E_OUTOFMEMORY
;
1588 ret
= GetCurrentDirectoryW(ret
, *dir
);
1590 SysFreeString(*dir
);
1592 return HRESULT_FROM_WIN32(GetLastError());
1598 static HRESULT WINAPI
WshShell3_put_CurrentDirectory(IWshShell3
*iface
, BSTR dir
)
1600 TRACE("(%s)\n", debugstr_w(dir
));
1603 return E_INVALIDARG
;
1605 if (!SetCurrentDirectoryW(dir
))
1606 return HRESULT_FROM_WIN32(GetLastError());
1611 static const IWshShell3Vtbl WshShell3Vtbl
= {
1612 WshShell3_QueryInterface
,
1615 WshShell3_GetTypeInfoCount
,
1616 WshShell3_GetTypeInfo
,
1617 WshShell3_GetIDsOfNames
,
1619 WshShell3_get_SpecialFolders
,
1620 WshShell3_get_Environment
,
1623 WshShell3_CreateShortcut
,
1624 WshShell3_ExpandEnvironmentStrings
,
1627 WshShell3_RegDelete
,
1629 WshShell3_AppActivate
,
1632 WshShell3_get_CurrentDirectory
,
1633 WshShell3_put_CurrentDirectory
1636 static IWshShell3 WshShell3
= { &WshShell3Vtbl
};
1638 HRESULT WINAPI
WshShellFactory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID riid
, void **ppv
)
1640 TRACE("(%p %s %p)\n", outer
, debugstr_guid(riid
), ppv
);
1642 return IWshShell3_QueryInterface(&WshShell3
, riid
, ppv
);