diff --git a/reactos/dll/win32/CMakeLists.txt b/reactos/dll/win32/CMakeLists.txt index 198e0698da9..acdf633d640 100644 --- a/reactos/dll/win32/CMakeLists.txt +++ b/reactos/dll/win32/CMakeLists.txt @@ -165,6 +165,7 @@ add_subdirectory(samlib) add_subdirectory(samsrv) add_subdirectory(sccbase) add_subdirectory(schannel) +add_subdirectory(scrrun) add_subdirectory(secur32) add_subdirectory(security) add_subdirectory(sensapi) diff --git a/reactos/dll/win32/scrrun/CMakeLists.txt b/reactos/dll/win32/scrrun/CMakeLists.txt new file mode 100644 index 00000000000..a30bdbe74eb --- /dev/null +++ b/reactos/dll/win32/scrrun/CMakeLists.txt @@ -0,0 +1,27 @@ + +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) +add_definitions(-D__WINESRC__) +spec2def(scrrun.dll scrrun.spec) + +add_idl_headers(scrrun_idlheader scrrun.idl) +add_typelib(scrrun.idl) + +list(APPEND SOURCE + dictionary.c + filesystem.c + scrrun.c + ${CMAKE_CURRENT_BINARY_DIR}/scrrun_stubs.c + ${CMAKE_CURRENT_BINARY_DIR}/scrrun.def) + +list(APPEND scrrun_rc_deps + ${CMAKE_CURRENT_SOURCE_DIR}/scrrun.rgs + ${CMAKE_CURRENT_SOURCE_DIR}/scrrun_tlb.rgs + ${CMAKE_CURRENT_BINARY_DIR}/scrrun.tlb) + +set_source_files_properties(scrrun.rc PROPERTIES OBJECT_DEPENDS "${scrrun_rc_deps}") +add_library(scrrun SHARED ${SOURCE} scrrun.rc) +add_dependencies(scrrun scrrun_idlheader stdole2) +set_module_type(scrrun win32dll) +target_link_libraries(scrrun uuid wine) +add_importlibs(scrrun oleaut32 version advapi32 msvcrt kernel32 ntdll) +add_cd_file(TARGET scrrun DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/win32/scrrun/dictionary.c b/reactos/dll/win32/scrrun/dictionary.c new file mode 100644 index 00000000000..4fcaedd6cfc --- /dev/null +++ b/reactos/dll/win32/scrrun/dictionary.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2012 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "dispex.h" +#include "scrrun.h" +#include "scrrun_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(scrrun); + +typedef struct +{ + IDictionary IDictionary_iface; + + LONG ref; +} dictionary; + +static inline dictionary *impl_from_IDictionary(IDictionary *iface) +{ + return CONTAINING_RECORD(iface, dictionary, IDictionary_iface); +} + +static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, void **obj) +{ + dictionary *This = impl_from_IDictionary(iface); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj); + + *obj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID_IDictionary)) + { + *obj = &This->IDictionary_iface; + } + else if ( IsEqualGUID( riid, &IID_IDispatchEx )) + { + TRACE("Interface IDispatchEx not supported - returning NULL\n"); + *obj = NULL; + return E_NOINTERFACE; + } + else if ( IsEqualGUID( riid, &IID_IObjectWithSite )) + { + TRACE("Interface IObjectWithSite not supported - returning NULL\n"); + *obj = NULL; + return E_NOINTERFACE; + } + else + { + WARN("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IDictionary_AddRef(iface); + return S_OK; +} + +static ULONG WINAPI dictionary_AddRef(IDictionary *iface) +{ + dictionary *This = impl_from_IDictionary(iface); + TRACE("(%p)\n", This); + + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI dictionary_Release(IDictionary *iface) +{ + dictionary *This = impl_from_IDictionary(iface); + LONG ref; + + TRACE("(%p)\n", This); + + ref = InterlockedDecrement(&This->ref); + if(ref == 0) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI dictionary_GetTypeInfoCount(IDictionary *iface, UINT *pctinfo) +{ + dictionary *This = impl_from_IDictionary(iface); + + TRACE("(%p)->()\n", This); + + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI dictionary_GetTypeInfo(IDictionary *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + dictionary *This = impl_from_IDictionary(iface); + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + return get_typeinfo(IDictionary_tid, ppTInfo); +} + +static HRESULT WINAPI dictionary_GetIDsOfNames(IDictionary *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) +{ + dictionary *This = impl_from_IDictionary(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + hr = get_typeinfo(IDictionary_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI dictionary_Invoke(IDictionary *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + dictionary *This = impl_from_IDictionary(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + hr = get_typeinfo(IDictionary_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &This->IDictionary_iface, dispIdMember, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI dictionary_putref_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, pRetItem); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_put_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, pRetItem); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_get_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, pRetItem ); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_Add(IDictionary *iface, VARIANT *Key, VARIANT *Item) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, Item); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_get_Count(IDictionary *iface, LONG *pCount) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, pCount); + + *pCount = 0; + + return S_OK; +} + +static HRESULT WINAPI dictionary_Exists(IDictionary *iface, VARIANT *Key, VARIANT_BOOL *pExists) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, pExists); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_Items(IDictionary *iface, VARIANT *pItemsArray) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, pItemsArray); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_put_Key(IDictionary *iface, VARIANT *Key, VARIANT *rhs) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, rhs); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_Keys(IDictionary *iface, VARIANT *pKeysArray) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, pKeysArray); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_Remove(IDictionary *iface, VARIANT *Key) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, Key); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_RemoveAll(IDictionary *iface) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->()\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_put_CompareMode(IDictionary *iface, CompareMethod pcomp) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->()\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_get_CompareMode(IDictionary *iface, CompareMethod *pcomp) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, pcomp); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ppunk) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, ppunk); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *Key, VARIANT *HashVal) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, HashVal); + + return E_NOTIMPL; +} + + +static const struct IDictionaryVtbl dictionary_vtbl = +{ + dictionary_QueryInterface, + dictionary_AddRef, + dictionary_Release, + dictionary_GetTypeInfoCount, + dictionary_GetTypeInfo, + dictionary_GetIDsOfNames, + dictionary_Invoke, + dictionary_putref_Item, + dictionary_put_Item, + dictionary_get_Item, + dictionary_Add, + dictionary_get_Count, + dictionary_Exists, + dictionary_Items, + dictionary_put_Key, + dictionary_Keys, + dictionary_Remove, + dictionary_RemoveAll, + dictionary_put_CompareMode, + dictionary_get_CompareMode, + dictionary__NewEnum, + dictionary_get_HashVal +}; + +HRESULT WINAPI Dictionary_CreateInstance(IClassFactory *factory,IUnknown *outer,REFIID riid, void **obj) +{ + dictionary *This; + + TRACE("(%p)\n", obj); + + *obj = NULL; + + This = heap_alloc(sizeof(*This)); + if(!This) return E_OUTOFMEMORY; + + This->IDictionary_iface.lpVtbl = &dictionary_vtbl; + This->ref = 1; + + *obj = &This->IDictionary_iface; + + return S_OK; +} diff --git a/reactos/dll/win32/scrrun/filesystem.c b/reactos/dll/win32/scrrun/filesystem.c new file mode 100644 index 00000000000..2750108fb30 --- /dev/null +++ b/reactos/dll/win32/scrrun/filesystem.c @@ -0,0 +1,1866 @@ +/* + * Copyright 2012 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "olectl.h" +#include "dispex.h" +#include "ntsecapi.h" +#include "scrrun.h" +#include "scrrun_private.h" + +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(scrrun); + +struct folder { + IFolder IFolder_iface; + LONG ref; +}; + +struct file { + IFile IFile_iface; + LONG ref; + + WCHAR *path; +}; + +struct textstream { + ITextStream ITextStream_iface; + LONG ref; + + IOMode mode; +}; + +enum iotype { + IORead, + IOWrite +}; + +static inline struct folder *impl_from_IFolder(IFolder *iface) +{ + return CONTAINING_RECORD(iface, struct folder, IFolder_iface); +} + +static inline struct file *impl_from_IFile(IFile *iface) +{ + return CONTAINING_RECORD(iface, struct file, IFile_iface); +} + +static inline struct textstream *impl_from_ITextStream(ITextStream *iface) +{ + return CONTAINING_RECORD(iface, struct textstream, ITextStream_iface); +} + +static inline HRESULT create_error(DWORD err) +{ + switch(err) { + case ERROR_FILE_NOT_FOUND: return CTL_E_FILENOTFOUND; + case ERROR_PATH_NOT_FOUND: return CTL_E_PATHNOTFOUND; + case ERROR_ACCESS_DENIED: return CTL_E_PERMISSIONDENIED; + case ERROR_FILE_EXISTS: return CTL_E_FILEALREADYEXISTS; + case ERROR_ALREADY_EXISTS: return CTL_E_FILEALREADYEXISTS; + default: + FIXME("Unsupported error code: %d\n", err); + return E_FAIL; + } +} + +static int textstream_check_iomode(struct textstream *This, enum iotype type) +{ + if (type == IORead) + return This->mode == ForWriting || This->mode == ForAppending; + else + return 1; +} + +static HRESULT WINAPI textstream_QueryInterface(ITextStream *iface, REFIID riid, void **obj) +{ + struct textstream *This = impl_from_ITextStream(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_ITextStream) || + IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + ITextStream_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI textstream_AddRef(ITextStream *iface) +{ + struct textstream *This = impl_from_ITextStream(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + return ref; +} + +static ULONG WINAPI textstream_Release(ITextStream *iface) +{ + struct textstream *This = impl_from_ITextStream(iface); + ULONG ref = InterlockedDecrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + + if (!ref) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI textstream_GetTypeInfoCount(ITextStream *iface, UINT *pctinfo) +{ + struct textstream *This = impl_from_ITextStream(iface); + TRACE("(%p)->(%p)\n", This, pctinfo); + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI textstream_GetTypeInfo(ITextStream *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + struct textstream *This = impl_from_ITextStream(iface); + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + return get_typeinfo(ITextStream_tid, ppTInfo); +} + +static HRESULT WINAPI textstream_GetIDsOfNames(ITextStream *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + struct textstream *This = impl_from_ITextStream(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + hr = get_typeinfo(ITextStream_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI textstream_Invoke(ITextStream *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + struct textstream *This = impl_from_ITextStream(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + hr = get_typeinfo(ITextStream_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI textstream_get_Line(ITextStream *iface, LONG *line) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%p): stub\n", This, line); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_get_Column(ITextStream *iface, LONG *column) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%p): stub\n", This, column); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_get_AtEndOfStream(ITextStream *iface, VARIANT_BOOL *eos) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%p): stub\n", This, eos); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_get_AtEndOfLine(ITextStream *iface, VARIANT_BOOL *eol) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%p): stub\n", This, eol); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_Read(ITextStream *iface, LONG len, BSTR *text) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%p): stub\n", This, text); + + if (textstream_check_iomode(This, IORead)) + return CTL_E_BADFILEMODE; + + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_ReadLine(ITextStream *iface, BSTR *text) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%p): stub\n", This, text); + + if (textstream_check_iomode(This, IORead)) + return CTL_E_BADFILEMODE; + + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_ReadAll(ITextStream *iface, BSTR *text) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%p): stub\n", This, text); + + if (textstream_check_iomode(This, IORead)) + return CTL_E_BADFILEMODE; + + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_Write(ITextStream *iface, BSTR text) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%s): stub\n", This, debugstr_w(text)); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_WriteLine(ITextStream *iface, BSTR text) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%s): stub\n", This, debugstr_w(text)); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_WriteBlankLines(ITextStream *iface, LONG lines) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%d): stub\n", This, lines); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_Skip(ITextStream *iface, LONG count) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p)->(%d): stub\n", This, count); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_SkipLine(ITextStream *iface) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI textstream_Close(ITextStream *iface) +{ + struct textstream *This = impl_from_ITextStream(iface); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static const ITextStreamVtbl textstreamvtbl = { + textstream_QueryInterface, + textstream_AddRef, + textstream_Release, + textstream_GetTypeInfoCount, + textstream_GetTypeInfo, + textstream_GetIDsOfNames, + textstream_Invoke, + textstream_get_Line, + textstream_get_Column, + textstream_get_AtEndOfStream, + textstream_get_AtEndOfLine, + textstream_Read, + textstream_ReadLine, + textstream_ReadAll, + textstream_Write, + textstream_WriteLine, + textstream_WriteBlankLines, + textstream_Skip, + textstream_SkipLine, + textstream_Close +}; + +static HRESULT create_textstream(IOMode mode, ITextStream **ret) +{ + struct textstream *stream; + + stream = heap_alloc(sizeof(struct textstream)); + if (!stream) return E_OUTOFMEMORY; + + stream->ITextStream_iface.lpVtbl = &textstreamvtbl; + stream->ref = 1; + stream->mode = mode; + + *ret = &stream->ITextStream_iface; + return S_OK; +} + +static HRESULT WINAPI folder_QueryInterface(IFolder *iface, REFIID riid, void **obj) +{ + struct folder *This = impl_from_IFolder(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + + *obj = NULL; + + if (IsEqualGUID( riid, &IID_IFolder ) || + IsEqualGUID( riid, &IID_IUnknown)) + { + *obj = iface; + IFolder_AddRef(iface); + } + else + return E_NOINTERFACE; + + return S_OK; +} + +static ULONG WINAPI folder_AddRef(IFolder *iface) +{ + struct folder *This = impl_from_IFolder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + return ref; +} + +static ULONG WINAPI folder_Release(IFolder *iface) +{ + struct folder *This = impl_from_IFolder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + + if (!ref) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI folder_GetTypeInfoCount(IFolder *iface, UINT *pctinfo) +{ + struct folder *This = impl_from_IFolder(iface); + TRACE("(%p)->(%p)\n", This, pctinfo); + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI folder_GetTypeInfo(IFolder *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + struct folder *This = impl_from_IFolder(iface); + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + return get_typeinfo(IFolder_tid, ppTInfo); +} + +static HRESULT WINAPI folder_GetIDsOfNames(IFolder *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + struct folder *This = impl_from_IFolder(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + hr = get_typeinfo(IFolder_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI folder_Invoke(IFolder *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + struct folder *This = impl_from_IFolder(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + hr = get_typeinfo(IFolder_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI folder_get_Path(IFolder *iface, BSTR *path) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, path); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_Name(IFolder *iface, BSTR *name) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, name); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_put_Name(IFolder *iface, BSTR name) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%s): stub\n", This, debugstr_w(name)); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_ShortPath(IFolder *iface, BSTR *path) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, path); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_ShortName(IFolder *iface, BSTR *name) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, name); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_Drive(IFolder *iface, IDrive **drive) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, drive); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_ParentFolder(IFolder *iface, IFolder **parent) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, parent); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_Attributes(IFolder *iface, FileAttribute *attr) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, attr); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_put_Attributes(IFolder *iface, FileAttribute attr) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(0x%x): stub\n", This, attr); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_DateCreated(IFolder *iface, DATE *date) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, date); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_DateLastModified(IFolder *iface, DATE *date) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, date); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_DateLastAccessed(IFolder *iface, DATE *date) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, date); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_Type(IFolder *iface, BSTR *type) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_Delete(IFolder *iface, VARIANT_BOOL force) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%x): stub\n", This, force); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_Copy(IFolder *iface, BSTR dest, VARIANT_BOOL overwrite) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%s %x): stub\n", This, debugstr_w(dest), overwrite); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_Move(IFolder *iface, BSTR dest) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%s): stub\n", This, debugstr_w(dest)); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_IsRootFolder(IFolder *iface, VARIANT_BOOL *isroot) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, isroot); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_Size(IFolder *iface, VARIANT *size) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, size); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_SubFolders(IFolder *iface, IFolderCollection **folders) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, folders); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_get_Files(IFolder *iface, IFileCollection **files) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%p): stub\n", This, files); + return E_NOTIMPL; +} + +static HRESULT WINAPI folder_CreateTextFile(IFolder *iface, BSTR filename, VARIANT_BOOL overwrite, + VARIANT_BOOL unicode, ITextStream **stream) +{ + struct folder *This = impl_from_IFolder(iface); + FIXME("(%p)->(%s %x %x %p): stub\n", This, debugstr_w(filename), overwrite, unicode, stream); + return E_NOTIMPL; +} + +static const IFolderVtbl foldervtbl = { + folder_QueryInterface, + folder_AddRef, + folder_Release, + folder_GetTypeInfoCount, + folder_GetTypeInfo, + folder_GetIDsOfNames, + folder_Invoke, + folder_get_Path, + folder_get_Name, + folder_put_Name, + folder_get_ShortPath, + folder_get_ShortName, + folder_get_Drive, + folder_get_ParentFolder, + folder_get_Attributes, + folder_put_Attributes, + folder_get_DateCreated, + folder_get_DateLastModified, + folder_get_DateLastAccessed, + folder_get_Type, + folder_Delete, + folder_Copy, + folder_Move, + folder_get_IsRootFolder, + folder_get_Size, + folder_get_SubFolders, + folder_get_Files, + folder_CreateTextFile +}; + +static HRESULT create_folder(IFolder **folder) +{ + struct folder *This; + + This = heap_alloc(sizeof(struct folder)); + if (!This) return E_OUTOFMEMORY; + + This->IFolder_iface.lpVtbl = &foldervtbl; + This->ref = 1; + + *folder = &This->IFolder_iface; + + return S_OK; +} + +static HRESULT WINAPI file_QueryInterface(IFile *iface, REFIID riid, void **obj) +{ + struct file *This = impl_from_IFile(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IFile) || + IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IFile_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI file_AddRef(IFile *iface) +{ + struct file *This = impl_from_IFile(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI file_Release(IFile *iface) +{ + struct file *This = impl_from_IFile(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) + heap_free(This->path); + + return ref; +} + +static HRESULT WINAPI file_GetTypeInfoCount(IFile *iface, UINT *pctinfo) +{ + struct file *This = impl_from_IFile(iface); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI file_GetTypeInfo(IFile *iface, + UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + struct file *This = impl_from_IFile(iface); + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + return get_typeinfo(IFile_tid, ppTInfo); +} + +static HRESULT WINAPI file_GetIDsOfNames(IFile *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + struct file *This = impl_from_IFile(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), + rgszNames, cNames, lcid, rgDispId); + + hr = get_typeinfo(IFile_tid, &typeinfo); + if(SUCCEEDED(hr)) { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + return hr; +} + +static HRESULT WINAPI file_Invoke(IFile *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + struct file *This = impl_from_IFile(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + hr = get_typeinfo(IFile_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + return hr; +} + +static HRESULT WINAPI file_get_Path(IFile *iface, BSTR *pbstrPath) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, pbstrPath); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_Name(IFile *iface, BSTR *pbstrName) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, pbstrName); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_put_Name(IFile *iface, BSTR pbstrName) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(pbstrName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_ShortPath(IFile *iface, BSTR *pbstrPath) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, pbstrPath); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_ShortName(IFile *iface, BSTR *pbstrName) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, pbstrName); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_Drive(IFile *iface, IDrive **ppdrive) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, ppdrive); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_ParentFolder(IFile *iface, IFolder **ppfolder) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, ppfolder); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_Attributes(IFile *iface, FileAttribute *pfa) +{ + struct file *This = impl_from_IFile(iface); + DWORD fa; + + TRACE("(%p)->(%p)\n", This, pfa); + + if(!pfa) + return E_POINTER; + + fa = GetFileAttributesW(This->path); + if(fa == INVALID_FILE_ATTRIBUTES) + return create_error(GetLastError()); + + *pfa = fa & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE | + FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED); + return S_OK; +} + +static HRESULT WINAPI file_put_Attributes(IFile *iface, FileAttribute pfa) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%x)\n", This, pfa); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_DateCreated(IFile *iface, DATE *pdate) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, pdate); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_DateLastModified(IFile *iface, DATE *pdate) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, pdate); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_DateLastAccessed(IFile *iface, DATE *pdate) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, pdate); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_get_Size(IFile *iface, VARIANT *pvarSize) +{ + struct file *This = impl_from_IFile(iface); + WIN32_FIND_DATAW fd; + HANDLE f; + + TRACE("(%p)->(%p)\n", This, pvarSize); + + if(!pvarSize) + return E_POINTER; + + f = FindFirstFileW(This->path, &fd); + if(f == INVALID_HANDLE_VALUE) + return create_error(GetLastError()); + FindClose(f); + + if(fd.nFileSizeHigh || fd.nFileSizeLow>INT_MAX) { + V_VT(pvarSize) = VT_R8; + V_R8(pvarSize) = ((ULONGLONG)fd.nFileSizeHigh<<32) + fd.nFileSizeLow; + }else { + V_VT(pvarSize) = VT_I4; + V_I4(pvarSize) = fd.nFileSizeLow; + } + return S_OK; +} + +static HRESULT WINAPI file_get_Type(IFile *iface, BSTR *pbstrType) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%p)\n", This, pbstrType); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_Delete(IFile *iface, VARIANT_BOOL Force) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%x)\n", This, Force); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_Copy(IFile *iface, BSTR Destination, VARIANT_BOOL OverWriteFiles) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%s %x)\n", This, debugstr_w(Destination), OverWriteFiles); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_Move(IFile *iface, BSTR Destination) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(Destination)); + return E_NOTIMPL; +} + +static HRESULT WINAPI file_OpenAsTextStream(IFile *iface, IOMode IOMode, Tristate Format, ITextStream **ppts) +{ + struct file *This = impl_from_IFile(iface); + FIXME("(%p)->(%x %x %p)\n", This, IOMode, Format, ppts); + return E_NOTIMPL; +} + +static const IFileVtbl file_vtbl = { + file_QueryInterface, + file_AddRef, + file_Release, + file_GetTypeInfoCount, + file_GetTypeInfo, + file_GetIDsOfNames, + file_Invoke, + file_get_Path, + file_get_Name, + file_put_Name, + file_get_ShortPath, + file_get_ShortName, + file_get_Drive, + file_get_ParentFolder, + file_get_Attributes, + file_put_Attributes, + file_get_DateCreated, + file_get_DateLastModified, + file_get_DateLastAccessed, + file_get_Size, + file_get_Type, + file_Delete, + file_Copy, + file_Move, + file_OpenAsTextStream +}; + +static HRESULT create_file(BSTR path, IFile **file) +{ + struct file *f; + DWORD len, attrs; + + *file = NULL; + + f = heap_alloc(sizeof(struct file)); + if(!f) + return E_OUTOFMEMORY; + + f->IFile_iface.lpVtbl = &file_vtbl; + f->ref = 1; + + len = GetFullPathNameW(path, 0, NULL, NULL); + if(!len) { + heap_free(f); + return E_FAIL; + } + + f->path = heap_alloc(len*sizeof(WCHAR)); + if(!f->path) { + heap_free(f); + return E_OUTOFMEMORY; + } + + if(!GetFullPathNameW(path, len, f->path, NULL)) { + heap_free(f->path); + heap_free(f); + return E_FAIL; + } + + if(path[len-1]=='/' || path[len-1]=='\\') + path[len-1] = 0; + + attrs = GetFileAttributesW(f->path); + if(attrs==INVALID_FILE_ATTRIBUTES || + (attrs&(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))) { + heap_free(f->path); + heap_free(f); + return create_error(GetLastError()); + } + + *file = &f->IFile_iface; + return S_OK; +} + +static HRESULT WINAPI filesys_QueryInterface(IFileSystem3 *iface, REFIID riid, void **ppvObject) +{ + TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject); + + if ( IsEqualGUID( riid, &IID_IFileSystem3 ) || + IsEqualGUID( riid, &IID_IFileSystem ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else if ( IsEqualGUID( riid, &IID_IDispatchEx )) + { + TRACE("Interface IDispatchEx not supported - returning NULL\n"); + *ppvObject = NULL; + return E_NOINTERFACE; + } + else if ( IsEqualGUID( riid, &IID_IObjectWithSite )) + { + TRACE("Interface IObjectWithSite not supported - returning NULL\n"); + *ppvObject = NULL; + return E_NOINTERFACE; + } + else + { + FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IFileSystem3_AddRef(iface); + + return S_OK; +} + +static ULONG WINAPI filesys_AddRef(IFileSystem3 *iface) +{ + TRACE("%p\n", iface); + + return 2; +} + +static ULONG WINAPI filesys_Release(IFileSystem3 *iface) +{ + TRACE("%p\n", iface); + + return 1; +} + +static HRESULT WINAPI filesys_GetTypeInfoCount(IFileSystem3 *iface, UINT *pctinfo) +{ + TRACE("(%p)->(%p)\n", iface, pctinfo); + + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI filesys_GetTypeInfo(IFileSystem3 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + TRACE("(%p)->(%u %u %p)\n", iface, iTInfo, lcid, ppTInfo); + return get_typeinfo(IFileSystem3_tid, ppTInfo); +} + +static HRESULT WINAPI filesys_GetIDsOfNames(IFileSystem3 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%s %p %u %u %p)\n", iface, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + hr = get_typeinfo(IFileSystem3_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI filesys_Invoke(IFileSystem3 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", iface, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + hr = get_typeinfo(IFileSystem3_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI filesys_get_Drives(IFileSystem3 *iface, IDriveCollection **ppdrives) +{ + FIXME("%p %p\n", iface, ppdrives); + + return E_NOTIMPL; +} + +static HRESULT WINAPI filesys_BuildPath(IFileSystem3 *iface, BSTR Path, + BSTR Name, BSTR *pbstrResult) +{ + FIXME("%p %s %s %p\n", iface, debugstr_w(Path), debugstr_w(Name), pbstrResult); + + return E_NOTIMPL; +} + +static HRESULT WINAPI filesys_GetDriveName(IFileSystem3 *iface, BSTR Path, + BSTR *pbstrResult) +{ + FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult); + + return E_NOTIMPL; +} + +static inline DWORD get_parent_folder_name(const WCHAR *path, DWORD len) +{ + int i; + + if(!path) + return 0; + + for(i=len-1; i>=0; i--) + if(path[i]!='/' && path[i]!='\\') + break; + + for(; i>=0; i--) + if(path[i]=='/' || path[i]=='\\') + break; + + for(; i>=0; i--) + if(path[i]!='/' && path[i]!='\\') + break; + + if(i < 0) + return 0; + + if(path[i]==':' && i==1) + i++; + return i+1; +} + +static HRESULT WINAPI filesys_GetParentFolderName(IFileSystem3 *iface, BSTR Path, + BSTR *pbstrResult) +{ + DWORD len; + + TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult); + + if(!pbstrResult) + return E_POINTER; + + len = get_parent_folder_name(Path, SysStringLen(Path)); + if(!len) { + *pbstrResult = NULL; + return S_OK; + } + + *pbstrResult = SysAllocStringLen(Path, len); + if(!*pbstrResult) + return E_OUTOFMEMORY; + return S_OK; +} + +static HRESULT WINAPI filesys_GetFileName(IFileSystem3 *iface, BSTR Path, + BSTR *pbstrResult) +{ + int i, end; + + TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult); + + if(!pbstrResult) + return E_POINTER; + + if(!Path) { + *pbstrResult = NULL; + return S_OK; + } + + for(end=strlenW(Path)-1; end>=0; end--) + if(Path[end]!='/' && Path[end]!='\\') + break; + + for(i=end; i>=0; i--) + if(Path[i]=='/' || Path[i]=='\\') + break; + i++; + + if(i>end || (i==0 && end==1 && Path[1]==':')) { + *pbstrResult = NULL; + return S_OK; + } + + *pbstrResult = SysAllocStringLen(Path+i, end-i+1); + if(!*pbstrResult) + return E_OUTOFMEMORY; + return S_OK; +} + +static HRESULT WINAPI filesys_GetBaseName(IFileSystem3 *iface, BSTR Path, + BSTR *pbstrResult) +{ + int i, end; + + TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult); + + if(!pbstrResult) + return E_POINTER; + + if(!Path) { + *pbstrResult = NULL; + return S_OK; + } + + for(end=strlenW(Path)-1; end>=0; end--) + if(Path[end]!='/' && Path[end]!='\\') + break; + + for(i=end; i>=0; i--) { + if(Path[i]=='.' && Path[end+1]!='.') + end = i-1; + if(Path[i]=='/' || Path[i]=='\\') + break; + } + i++; + + if((i>end && Path[end+1]!='.') || (i==0 && end==1 && Path[1]==':')) { + *pbstrResult = NULL; + return S_OK; + } + + *pbstrResult = SysAllocStringLen(Path+i, end-i+1); + if(!*pbstrResult) + return E_OUTOFMEMORY; + return S_OK; +} + +static HRESULT WINAPI filesys_GetExtensionName(IFileSystem3 *iface, BSTR Path, + BSTR *pbstrResult) +{ + FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult); + + return E_NOTIMPL; +} + +static HRESULT WINAPI filesys_GetAbsolutePathName(IFileSystem3 *iface, BSTR Path, + BSTR *pbstrResult) +{ + static const WCHAR cur_path[] = {'.',0}; + + WCHAR buf[MAX_PATH], ch; + const WCHAR *path; + DWORD i, beg, len, exp_len; + WIN32_FIND_DATAW fdata; + HANDLE fh; + + TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult); + + if(!pbstrResult) + return E_POINTER; + + if(!Path) + path = cur_path; + else + path = Path; + + len = GetFullPathNameW(path, MAX_PATH, buf, NULL); + if(!len) + return E_FAIL; + + buf[0] = toupperW(buf[0]); + if(len>3 && buf[len-1] == '\\') + buf[--len] = 0; + + for(beg=3, i=3; i<=len; i++) { + if(buf[i]!='\\' && buf[i]) + continue; + + ch = buf[i]; + buf[i] = 0; + fh = FindFirstFileW(buf, &fdata); + if(fh == INVALID_HANDLE_VALUE) + break; + + exp_len = strlenW(fdata.cFileName); + if(exp_len == i-beg) + memcpy(buf+beg, fdata.cFileName, exp_len*sizeof(WCHAR)); + FindClose(fh); + buf[i] = ch; + beg = i+1; + } + + *pbstrResult = SysAllocString(buf); + if(!*pbstrResult) + return E_OUTOFMEMORY; + return S_OK; +} + +static HRESULT WINAPI filesys_GetTempName(IFileSystem3 *iface, BSTR *pbstrResult) +{ + static const WCHAR fmt[] = {'r','a','d','%','0','5','X','.','t','x','t',0}; + + DWORD random; + + TRACE("%p %p\n", iface, pbstrResult); + + if(!pbstrResult) + return E_POINTER; + + *pbstrResult = SysAllocStringLen(NULL, 12); + if(!*pbstrResult) + return E_OUTOFMEMORY; + + if(!RtlGenRandom(&random, sizeof(random))) + return E_FAIL; + sprintfW(*pbstrResult, fmt, random & 0xfffff); + return S_OK; +} + +static HRESULT WINAPI filesys_DriveExists(IFileSystem3 *iface, BSTR DriveSpec, + VARIANT_BOOL *pfExists) +{ + FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), pfExists); + + return E_NOTIMPL; +} + +static HRESULT WINAPI filesys_FileExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret) +{ + DWORD attrs; + TRACE("%p %s %p\n", iface, debugstr_w(path), ret); + + if (!ret) return E_POINTER; + + attrs = GetFileAttributesW(path); + *ret = attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY) ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; +} + +static HRESULT WINAPI filesys_FolderExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret) +{ + DWORD attrs; + TRACE("%p %s %p\n", iface, debugstr_w(path), ret); + + if (!ret) return E_POINTER; + + attrs = GetFileAttributesW(path); + *ret = attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) ? VARIANT_TRUE : VARIANT_FALSE; + + return S_OK; +} + +static HRESULT WINAPI filesys_GetDrive(IFileSystem3 *iface, BSTR DriveSpec, + IDrive **ppdrive) +{ + FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), ppdrive); + + return E_NOTIMPL; +} + +static HRESULT WINAPI filesys_GetFile(IFileSystem3 *iface, BSTR FilePath, + IFile **ppfile) +{ + TRACE("%p %s %p\n", iface, debugstr_w(FilePath), ppfile); + + if(!ppfile) + return E_POINTER; + if(!FilePath) + return E_INVALIDARG; + + return create_file(FilePath, ppfile); +} + +static HRESULT WINAPI filesys_GetFolder(IFileSystem3 *iface, BSTR FolderPath, + IFolder **ppfolder) +{ + FIXME("%p %s %p\n", iface, debugstr_w(FolderPath), ppfolder); + + return E_NOTIMPL; +} + +static HRESULT WINAPI filesys_GetSpecialFolder(IFileSystem3 *iface, + SpecialFolderConst SpecialFolder, + IFolder **ppfolder) +{ + FIXME("%p %d %p\n", iface, SpecialFolder, ppfolder); + + return E_NOTIMPL; +} + +static inline HRESULT delete_file(const WCHAR *file, DWORD file_len, VARIANT_BOOL force) +{ + WCHAR path[MAX_PATH]; + DWORD len, name_len; + WIN32_FIND_DATAW ffd; + HANDLE f; + + f = FindFirstFileW(file, &ffd); + if(f == INVALID_HANDLE_VALUE) + return create_error(GetLastError()); + + len = get_parent_folder_name(file, file_len); + if(len+1 >= MAX_PATH) { + FindClose(f); + return E_FAIL; + } + if(len) { + memcpy(path, file, len*sizeof(WCHAR)); + path[len++] = '\\'; + } + + do { + if(ffd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE)) + continue; + + name_len = strlenW(ffd.cFileName); + if(len+name_len+1 >= MAX_PATH) { + FindClose(f); + return E_FAIL; + } + memcpy(path+len, ffd.cFileName, (name_len+1)*sizeof(WCHAR)); + + TRACE("deleting %s\n", debugstr_w(path)); + + if(!DeleteFileW(path)) { + if(!force || !SetFileAttributesW(path, FILE_ATTRIBUTE_NORMAL) + || !DeleteFileW(path)) { + FindClose(f); + return create_error(GetLastError()); + } + } + } while(FindNextFileW(f, &ffd)); + FindClose(f); + + return S_OK; +} + +static HRESULT WINAPI filesys_DeleteFile(IFileSystem3 *iface, BSTR FileSpec, + VARIANT_BOOL Force) +{ + TRACE("%p %s %d\n", iface, debugstr_w(FileSpec), Force); + + if(!FileSpec) + return E_POINTER; + + return delete_file(FileSpec, SysStringLen(FileSpec), Force); +} + +static HRESULT delete_folder(const WCHAR *folder, DWORD folder_len, VARIANT_BOOL force) +{ + WCHAR path[MAX_PATH]; + DWORD len, name_len; + WIN32_FIND_DATAW ffd; + HANDLE f; + HRESULT hr; + + f = FindFirstFileW(folder, &ffd); + if(f == INVALID_HANDLE_VALUE) + return create_error(GetLastError()); + + len = get_parent_folder_name(folder, folder_len); + if(len+1 >= MAX_PATH) { + FindClose(f); + return E_FAIL; + } + if(len) { + memcpy(path, folder, len*sizeof(WCHAR)); + path[len++] = '\\'; + } + + do { + if(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + continue; + if(ffd.cFileName[0]=='.' && (ffd.cFileName[1]==0 || + (ffd.cFileName[1]=='.' && ffd.cFileName[2]==0))) + continue; + + name_len = strlenW(ffd.cFileName); + if(len+name_len+3 >= MAX_PATH) { + FindClose(f); + return E_FAIL; + } + memcpy(path+len, ffd.cFileName, name_len*sizeof(WCHAR)); + path[len+name_len] = '\\'; + path[len+name_len+1] = '*'; + path[len+name_len+2] = 0; + + hr = delete_file(path, len+name_len+2, force); + if(FAILED(hr)) { + FindClose(f); + return hr; + } + + hr = delete_folder(path, len+name_len+2, force); + if(FAILED(hr)) { + FindClose(f); + return hr; + } + + path[len+name_len] = 0; + TRACE("deleting %s\n", debugstr_w(path)); + + if(!RemoveDirectoryW(path)) { + FindClose(f); + return create_error(GetLastError()); + } + } while(FindNextFileW(f, &ffd)); + FindClose(f); + + return S_OK; +} + +static HRESULT WINAPI filesys_DeleteFolder(IFileSystem3 *iface, BSTR FolderSpec, + VARIANT_BOOL Force) +{ + TRACE("%p %s %d\n", iface, debugstr_w(FolderSpec), Force); + + if(!FolderSpec) + return E_POINTER; + + return delete_folder(FolderSpec, SysStringLen(FolderSpec), Force); +} + +static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR Source, + BSTR Destination) +{ + FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface,BSTR Source, + BSTR Destination) +{ + FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination)); + + return E_NOTIMPL; +} + +static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, + const WCHAR *destination, DWORD destination_len, VARIANT_BOOL overwrite) +{ + DWORD attrs; + WCHAR src_path[MAX_PATH], dst_path[MAX_PATH]; + DWORD src_len, dst_len, name_len; + WIN32_FIND_DATAW ffd; + HANDLE f; + HRESULT hr; + + if(!source[0] || !destination[0]) + return E_INVALIDARG; + + attrs = GetFileAttributesW(destination); + if(attrs==INVALID_FILE_ATTRIBUTES || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) { + attrs = GetFileAttributesW(source); + if(attrs == INVALID_FILE_ATTRIBUTES) + return create_error(GetLastError()); + else if(attrs & FILE_ATTRIBUTE_DIRECTORY) + return CTL_E_FILENOTFOUND; + + if(!CopyFileW(source, destination, !overwrite)) + return create_error(GetLastError()); + return S_OK; + } + + f = FindFirstFileW(source, &ffd); + if(f == INVALID_HANDLE_VALUE) + return CTL_E_FILENOTFOUND; + + src_len = get_parent_folder_name(source, source_len); + if(src_len+1 >= MAX_PATH) + return E_FAIL; + if(src_len) { + memcpy(src_path, source, src_len*sizeof(WCHAR)); + src_path[src_len++] = '\\'; + } + + dst_len = destination_len; + if(dst_len+1 >= MAX_PATH) { + FindClose(f); + return E_FAIL; + } + memcpy(dst_path, destination, dst_len*sizeof(WCHAR)); + if(dst_path[dst_len-1]!= '\\' && dst_path[dst_len-1]!='/') + dst_path[dst_len++] = '\\'; + + hr = CTL_E_FILENOTFOUND; + do { + if(ffd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE)) + continue; + + name_len = strlenW(ffd.cFileName); + if(src_len+name_len+1>=MAX_PATH || dst_len+name_len+1>=MAX_PATH) { + FindClose(f); + return E_FAIL; + } + memcpy(src_path+src_len, ffd.cFileName, (name_len+1)*sizeof(WCHAR)); + memcpy(dst_path+dst_len, ffd.cFileName, (name_len+1)*sizeof(WCHAR)); + + TRACE("copying %s to %s\n", debugstr_w(src_path), debugstr_w(dst_path)); + + if(!CopyFileW(src_path, dst_path, !overwrite)) { + FindClose(f); + return create_error(GetLastError()); + }else { + hr = S_OK; + } + } while(FindNextFileW(f, &ffd)); + FindClose(f); + + return hr; +} + +static HRESULT WINAPI filesys_CopyFile(IFileSystem3 *iface, BSTR Source, + BSTR Destination, VARIANT_BOOL OverWriteFiles) +{ + TRACE("%p %s %s %d\n", iface, debugstr_w(Source), debugstr_w(Destination), OverWriteFiles); + + if(!Source || !Destination) + return E_POINTER; + + return copy_file(Source, SysStringLen(Source), Destination, + SysStringLen(Destination), OverWriteFiles); +} + +static HRESULT copy_folder(const WCHAR *source, DWORD source_len, const WCHAR *destination, + DWORD destination_len, VARIANT_BOOL overwrite) +{ + DWORD tmp, src_len, dst_len, name_len; + WCHAR src[MAX_PATH], dst[MAX_PATH]; + WIN32_FIND_DATAW ffd; + HANDLE f; + HRESULT hr; + BOOL copied = FALSE; + + if(!source[0] || !destination[0]) + return E_INVALIDARG; + + dst_len = destination_len; + if(dst_len+1 >= MAX_PATH) + return E_FAIL; + memcpy(dst, destination, (dst_len+1)*sizeof(WCHAR)); + + if(dst[dst_len-1]!='\\' && dst[dst_len-1]!='/' && + (tmp = GetFileAttributesW(source))!=INVALID_FILE_ATTRIBUTES && + tmp&FILE_ATTRIBUTE_DIRECTORY) { + if(!CreateDirectoryW(dst, NULL)) { + if(overwrite && GetLastError()==ERROR_ALREADY_EXISTS) { + tmp = GetFileAttributesW(dst); + if(tmp==INVALID_FILE_ATTRIBUTES || !(tmp&FILE_ATTRIBUTE_DIRECTORY)) + return CTL_E_FILEALREADYEXISTS; + }else { + return create_error(GetLastError()); + } + } + copied = TRUE; + + src_len = source_len; + if(src_len+2 >= MAX_PATH) + return E_FAIL; + memcpy(src, source, src_len*sizeof(WCHAR)); + src[src_len++] = '\\'; + src[src_len] = '*'; + src[src_len+1] = 0; + + hr = copy_file(src, src_len+1, dst, dst_len, overwrite); + if(FAILED(hr) && hr!=CTL_E_FILENOTFOUND) + return create_error(GetLastError()); + + f = FindFirstFileW(src, &ffd); + }else { + src_len = get_parent_folder_name(source, source_len); + if(src_len+2 >= MAX_PATH) + return E_FAIL; + memcpy(src, source, src_len*sizeof(WCHAR)); + if(src_len) + src[src_len++] = '\\'; + + f = FindFirstFileW(source, &ffd); + } + if(f == INVALID_HANDLE_VALUE) + return CTL_E_PATHNOTFOUND; + + dst[dst_len++] = '\\'; + dst[dst_len] = 0; + + do { + if(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + continue; + if(ffd.cFileName[0]=='.' && (ffd.cFileName[1]==0 || + (ffd.cFileName[1]=='.' && ffd.cFileName[2]==0))) + continue; + + name_len = strlenW(ffd.cFileName); + if(dst_len+name_len>=MAX_PATH || src_len+name_len+2>=MAX_PATH) { + FindClose(f); + return E_FAIL; + } + memcpy(dst+dst_len, ffd.cFileName, name_len*sizeof(WCHAR)); + dst[dst_len+name_len] = 0; + memcpy(src+src_len, ffd.cFileName, name_len*sizeof(WCHAR)); + src[src_len+name_len] = '\\'; + src[src_len+name_len+1] = '*'; + src[src_len+name_len+2] = 0; + + TRACE("copying %s to %s\n", debugstr_w(src), debugstr_w(dst)); + + if(!CreateDirectoryW(dst, NULL)) { + if(overwrite && GetLastError()==ERROR_ALREADY_EXISTS) { + tmp = GetFileAttributesW(dst); + if(tmp==INVALID_FILE_ATTRIBUTES || !(tmp&FILE_ATTRIBUTE_DIRECTORY)) { + FindClose(f); + return CTL_E_FILEALREADYEXISTS; + } + }else { + FindClose(f); + return create_error(GetLastError()); + } + return create_error(GetLastError()); + } + copied = TRUE; + + hr = copy_file(src, src_len+name_len+2, dst, dst_len+name_len, overwrite); + if(FAILED(hr) && hr!=CTL_E_FILENOTFOUND) { + FindClose(f); + return hr; + } + + hr = copy_folder(src, src_len+name_len+2, dst, dst_len+name_len, overwrite); + if(FAILED(hr) && hr!=CTL_E_PATHNOTFOUND) { + FindClose(f); + return hr; + } + } while(FindNextFileW(f, &ffd)); + FindClose(f); + + return copied ? S_OK : CTL_E_PATHNOTFOUND; +} + +static HRESULT WINAPI filesys_CopyFolder(IFileSystem3 *iface, BSTR Source, + BSTR Destination, VARIANT_BOOL OverWriteFiles) +{ + TRACE("%p %s %s %d\n", iface, debugstr_w(Source), debugstr_w(Destination), OverWriteFiles); + + if(!Source || !Destination) + return E_POINTER; + + return copy_folder(Source, SysStringLen(Source), Destination, + SysStringLen(Destination), OverWriteFiles); +} + +static HRESULT WINAPI filesys_CreateFolder(IFileSystem3 *iface, BSTR path, + IFolder **folder) +{ + BOOL ret; + + TRACE("(%p)->(%s %p)\n", iface, debugstr_w(path), folder); + + ret = CreateDirectoryW(path, NULL); + if (!ret) + { + *folder = NULL; + if (GetLastError() == ERROR_ALREADY_EXISTS) return CTL_E_FILEALREADYEXISTS; + return HRESULT_FROM_WIN32(GetLastError()); + } + + return create_folder(folder); +} + +static HRESULT WINAPI filesys_CreateTextFile(IFileSystem3 *iface, BSTR FileName, + VARIANT_BOOL Overwrite, VARIANT_BOOL Unicode, + ITextStream **ppts) +{ + FIXME("%p %s %d %d %p\n", iface, debugstr_w(FileName), Overwrite, Unicode, ppts); + + return E_NOTIMPL; +} + +static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename, + IOMode mode, VARIANT_BOOL create, + Tristate format, ITextStream **stream) +{ + FIXME("(%p)->(%s %d %d %d %p)\n", iface, debugstr_w(filename), mode, create, format, stream); + return create_textstream(mode, stream); +} + +static HRESULT WINAPI filesys_GetStandardStream(IFileSystem3 *iface, + StandardStreamTypes StandardStreamType, + VARIANT_BOOL Unicode, + ITextStream **ppts) +{ + FIXME("%p %d %d %p\n", iface, StandardStreamType, Unicode, ppts); + + return E_NOTIMPL; +} + +static void get_versionstring(VS_FIXEDFILEINFO *info, WCHAR *ver) +{ + static WCHAR fmtW[] = {'%','d','.','%','d','.','%','d','.','%','d',0}; + DWORDLONG version; + WORD a, b, c, d; + + version = (((DWORDLONG)info->dwFileVersionMS) << 32) + info->dwFileVersionLS; + a = (WORD)( version >> 48); + b = (WORD)((version >> 32) & 0xffff); + c = (WORD)((version >> 16) & 0xffff); + d = (WORD)( version & 0xffff); + + sprintfW(ver, fmtW, a, b, c, d); +} + +static HRESULT WINAPI filesys_GetFileVersion(IFileSystem3 *iface, BSTR name, BSTR *version) +{ + static const WCHAR rootW[] = {'\\',0}; + VS_FIXEDFILEINFO *info; + WCHAR ver[30]; + void *ptr; + DWORD len; + BOOL ret; + + TRACE("%p %s %p\n", iface, debugstr_w(name), version); + + len = GetFileVersionInfoSizeW(name, NULL); + if (!len) + return HRESULT_FROM_WIN32(GetLastError()); + + ptr = heap_alloc(len); + if (!GetFileVersionInfoW(name, 0, len, ptr)) + { + heap_free(ptr); + return HRESULT_FROM_WIN32(GetLastError()); + } + + ret = VerQueryValueW(ptr, rootW, (void**)&info, &len); + heap_free(ptr); + if (!ret) + return HRESULT_FROM_WIN32(GetLastError()); + + get_versionstring(info, ver); + *version = SysAllocString(ver); + TRACE("version=%s\n", debugstr_w(ver)); + + return S_OK; +} + +static const struct IFileSystem3Vtbl filesys_vtbl = +{ + filesys_QueryInterface, + filesys_AddRef, + filesys_Release, + filesys_GetTypeInfoCount, + filesys_GetTypeInfo, + filesys_GetIDsOfNames, + filesys_Invoke, + filesys_get_Drives, + filesys_BuildPath, + filesys_GetDriveName, + filesys_GetParentFolderName, + filesys_GetFileName, + filesys_GetBaseName, + filesys_GetExtensionName, + filesys_GetAbsolutePathName, + filesys_GetTempName, + filesys_DriveExists, + filesys_FileExists, + filesys_FolderExists, + filesys_GetDrive, + filesys_GetFile, + filesys_GetFolder, + filesys_GetSpecialFolder, + filesys_DeleteFile, + filesys_DeleteFolder, + filesys_MoveFile, + filesys_MoveFolder, + filesys_CopyFile, + filesys_CopyFolder, + filesys_CreateFolder, + filesys_CreateTextFile, + filesys_OpenTextFile, + filesys_GetStandardStream, + filesys_GetFileVersion +}; + +static IFileSystem3 filesystem = { &filesys_vtbl }; + +HRESULT WINAPI FileSystem_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) +{ + TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv); + + return IFileSystem3_QueryInterface(&filesystem, riid, ppv); +} diff --git a/reactos/dll/win32/scrrun/scrrun.c b/reactos/dll/win32/scrrun/scrrun.c new file mode 100644 index 00000000000..82f494fd2e3 --- /dev/null +++ b/reactos/dll/win32/scrrun/scrrun.c @@ -0,0 +1,230 @@ +/* + * Copyright 2011 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "rpcproxy.h" + +#include +#include "scrrun.h" +#include "scrrun_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(scrrun); + +static HINSTANCE scrrun_instance; + +typedef HRESULT (*fnCreateInstance)(LPVOID *ppObj); + +static HRESULT WINAPI scrruncf_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv ) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv); + *ppv = iface; + }else if(IsEqualGUID(&IID_IClassFactory, riid)) { + TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv); + *ppv = iface; + } + + if(*ppv) { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI scrruncf_AddRef(IClassFactory *iface ) +{ + TRACE("(%p)\n", iface); + return 2; +} + +static ULONG WINAPI scrruncf_Release(IClassFactory *iface ) +{ + TRACE("(%p)\n", iface); + return 1; +} + +static HRESULT WINAPI scrruncf_LockServer(IClassFactory *iface, BOOL fLock) +{ + TRACE("(%p)->(%x)\n", iface, fLock); + return S_OK; +} + +static const struct IClassFactoryVtbl scrruncf_vtbl = +{ + scrruncf_QueryInterface, + scrruncf_AddRef, + scrruncf_Release, + FileSystem_CreateInstance, + scrruncf_LockServer +}; + +static const struct IClassFactoryVtbl dictcf_vtbl = +{ + scrruncf_QueryInterface, + scrruncf_AddRef, + scrruncf_Release, + Dictionary_CreateInstance, + scrruncf_LockServer +}; + +static IClassFactory FileSystemFactory = { &scrruncf_vtbl }; +static IClassFactory DictionaryFactory = { &dictcf_vtbl }; + +static ITypeLib *typelib; +static ITypeInfo *typeinfos[LAST_tid]; + +static REFIID tid_ids[] = { + &IID_NULL, + &IID_IDictionary, + &IID_IFileSystem3, + &IID_IFolder, + &IID_IFile +}; + +static HRESULT load_typelib(void) +{ + HRESULT hres; + ITypeLib *tl; + + hres = LoadRegTypeLib(&LIBID_Scripting, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); + if(FAILED(hres)) { + ERR("LoadRegTypeLib failed: %08x\n", hres); + return hres; + } + + if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) + ITypeLib_Release(tl); + return hres; +} + +HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) +{ + HRESULT hres; + + if (!typelib) + hres = load_typelib(); + if (!typelib) + return hres; + + if(!typeinfos[tid]) { + ITypeInfo *ti; + + hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); + if(FAILED(hres)) { + ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres); + return hres; + } + + if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) + ITypeInfo_Release(ti); + } + + *typeinfo = typeinfos[tid]; + return S_OK; +} + +static void release_typelib(void) +{ + unsigned i; + + if(!typelib) + return; + + for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) + if(typeinfos[i]) + ITypeInfo_Release(typeinfos[i]); + + ITypeLib_Release(typelib); +} + +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) +{ + TRACE("%p, %u, %p\n", hinst, reason, reserved); + + switch (reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls( hinst ); + scrrun_instance = hinst; + break; + case DLL_PROCESS_DETACH: + if (reserved) break; + release_typelib(); + break; + } + return TRUE; +} + +/*********************************************************************** + * DllRegisterServer (scrrun.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + TRACE("()\n"); + return __wine_register_resources(scrrun_instance); +} + +/*********************************************************************** + * DllUnregisterServer (scrrun.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + TRACE("()\n"); + return __wine_unregister_resources(scrrun_instance); +} + +/*********************************************************************** + * DllGetClassObject (scrrun.@) + */ + +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + if(IsEqualGUID(&CLSID_FileSystemObject, rclsid)) { + TRACE("(CLSID_WshShell %s %p)\n", debugstr_guid(riid), ppv); + return IClassFactory_QueryInterface(&FileSystemFactory, riid, ppv); + } + else if(IsEqualGUID(&CLSID_Dictionary, rclsid)) { + TRACE("(CLSID_WshShell %s %p)\n", debugstr_guid(riid), ppv); + return IClassFactory_QueryInterface(&DictionaryFactory, riid, ppv); + } + + FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + return CLASS_E_CLASSNOTAVAILABLE; +} + +/*********************************************************************** + * DllCanUnloadNow (scrrun.@) + */ +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_FALSE; +} diff --git a/reactos/dll/win32/scrrun/scrrun.idl b/reactos/dll/win32/scrrun/scrrun.idl new file mode 100644 index 00000000000..4b18af140d7 --- /dev/null +++ b/reactos/dll/win32/scrrun/scrrun.idl @@ -0,0 +1,692 @@ +/* + * Copyright (C) 2012 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +import "unknwn.idl"; +import "objidl.idl"; +import "oaidl.idl"; + +cpp_quote("#ifdef WINE_NO_UNICODE_MACROS") +cpp_quote("#undef CopyFile") +cpp_quote("#undef DeleteFile") +cpp_quote("#undef MoveFile") +cpp_quote("#endif") + +[ + uuid(420B2830-E718-11CF-893D-00A0C9054228), + version(1.0) +] +library Scripting +{ + importlib("stdole2.tlb"); + + interface IDictionary; + interface IDrive; + interface IDriveCollection; + interface IFile; + interface IFileCollection; + interface IFileSystem; + interface IFileSystem3; + interface IFolder; + interface IFolderCollection; + interface IScriptEncoder; + interface ITextStream; + + typedef enum CompareMethod + { + BinaryCompare = 0, + TextCompare = 1, + DatabaseCompare = 2 + } CompareMethod; + + typedef enum IOMode + { + ForReading = 1, + ForWriting = 2, + ForAppending = 8 + } IOMode; + + typedef enum Tristate + { + TristateTrue = 0xffffffff, + TristateFalse = 0, + TristateUseDefault = 0xfffffffe, + TristateMixed = 0xfffffffe + } Tristate; + + typedef enum FileAttribute + { + Normal = 0, + ReadOnly = 1, + Hidden = 2, + System = 4, + Volume = 8, + Directory = 16, + Archive = 32, + Alias = 1024, + Compressed = 2048 + } FileAttribute; + + typedef enum SpecialFolderConst + { + WindowsFolder = 0, + SystemFolder = 1, + TemporaryFolder = 2 + } SpecialFolderConst; + + typedef enum DriveTypeConst + { + UnknownType = 0, + Removable = 1, + Fixed = 2, + Remote = 3, + CDRom = 4, + RamDisk = 5 + } DriveTypeConst; + + typedef enum StandardStreamTypes + { + StdIn = 0, + StdOut = 1, + StdErr = 2 + } StandardStreamTypes; + + [ + odl, + uuid(42C642C1-97E1-11CF-978F-00A02463E06F), + hidden, + dual, + oleautomation + ] + interface IDictionary : IDispatch + { + [id(00000000), propputref] + HRESULT Item([in] VARIANT* Key, [in] VARIANT* pRetItem); + + [id(00000000), propput] + HRESULT Item([in] VARIANT* Key, [in] VARIANT* pRetItem); + + [id(00000000), propget] + HRESULT Item([in] VARIANT* Key, [out, retval] VARIANT* pRetItem); + + [id(0x00000001)] + HRESULT Add([in] VARIANT* Key, [in] VARIANT* Item); + + [id(0x00000002), propget] + HRESULT Count([out, retval] long* pCount); + + [id(0x00000003)] + HRESULT Exists([in] VARIANT* Key, [out, retval] VARIANT_BOOL* pExists); + + [id(0x00000004)] + HRESULT Items([out, retval] VARIANT* pItemsArray); + + [id(0x00000005), propput] + HRESULT Key([in] VARIANT* Key, [in] VARIANT* rhs); + + [id(0x00000006)] + HRESULT Keys([out, retval] VARIANT* pKeysArray); + + [id(0x00000007)] + HRESULT Remove([in] VARIANT* Key); + + [id(0x00000008)] + HRESULT RemoveAll(); + + [id(0x00000009), propput] + HRESULT CompareMode([in] CompareMethod pcomp); + + [id(0x00000009), propget] + HRESULT CompareMode([out, retval] CompareMethod* pcomp); + + [id(DISPID_NEWENUM), restricted] + HRESULT _NewEnum([out, retval] IUnknown** ppunk); + + [id(0x0000000a), propget, hidden] + HRESULT HashVal([in] VARIANT* Key, [out, retval] VARIANT* HashVal); + } + + [ + odl, + uuid(0AB5A3D0-E5B6-11D0-ABF5-00A0C90FFFC0), + hidden, + dual, + nonextensible, + oleautomation + ] + interface IFileSystem : IDispatch + { + [id(0x0000271a), propget] + HRESULT Drives([out, retval] IDriveCollection** ppdrives); + + [id(0x00002710)] + HRESULT BuildPath([in] BSTR Path, [in] BSTR Name, [out, retval] BSTR* pbstrResult); + + [id(0x00002714)] + HRESULT GetDriveName([in] BSTR Path, [out, retval] BSTR* pbstrResult); + + [id(0x00002715)] + HRESULT GetParentFolderName([in] BSTR Path, [out, retval] BSTR* pbstrResult); + + [id(0x00002716)] + HRESULT GetFileName([in] BSTR Path, [out, retval] BSTR* pbstrResult); + + [id(0x00002717)] + HRESULT GetBaseName([in] BSTR Path, [out, retval] BSTR* pbstrResult); + + [id(0x00002718)] + HRESULT GetExtensionName([in] BSTR Path, [out, retval] BSTR* pbstrResult); + + [id(0x00002712)] + HRESULT GetAbsolutePathName([in] BSTR Path, [out, retval] BSTR* pbstrResult); + + [id(0x00002713)] + HRESULT GetTempName([out, retval] BSTR* pbstrResult); + + [id(0x0000271f)] + HRESULT DriveExists([in] BSTR DriveSpec, [out, retval] VARIANT_BOOL* pfExists); + + [id(0x00002720)] + HRESULT FileExists([in] BSTR FileSpec, [out, retval] VARIANT_BOOL* pfExists); + + [id(0x00002721)] + HRESULT FolderExists([in] BSTR FolderSpec, [out, retval] VARIANT_BOOL* pfExists); + + [id(0x0000271b)] + HRESULT GetDrive([in] BSTR DriveSpec, [out, retval] IDrive** ppdrive); + + [id(0x0000271c)] + HRESULT GetFile([in] BSTR FilePath, [out, retval] IFile** ppfile); + + [id(0x0000271d)] + HRESULT GetFolder([in] BSTR FolderPath, [out, retval] IFolder** ppfolder); + + [id(0x0000271e)] + HRESULT GetSpecialFolder([in] SpecialFolderConst SpecialFolder, [out, retval] IFolder** ppfolder); + + [id(0x000004b0)] + HRESULT DeleteFile([in] BSTR FileSpec, [in, optional, defaultvalue(0)] VARIANT_BOOL Force); + + [id(0x000004b1)] + HRESULT DeleteFolder([in] BSTR FolderSpec, [in, optional, defaultvalue(0)] VARIANT_BOOL Force); + + [id(0x000004b4), helpstring("Move a file"), helpcontext(0x00214bab)] + HRESULT MoveFile([in] BSTR Source, [in] BSTR Destination); + + [id(0x000004b5)] + HRESULT MoveFolder([in] BSTR Source, [in] BSTR Destination); + + [id(0x000004b2)] + HRESULT CopyFile([in] BSTR Source, [in] BSTR Destination, + [in, optional, defaultvalue(-1)] VARIANT_BOOL OverWriteFiles); + + [id(0x000004b3)] + HRESULT CopyFolder([in] BSTR Source, [in] BSTR Destination, + [in, optional, defaultvalue(-1)] VARIANT_BOOL OverWriteFiles); + + [id(0x00000460)] + HRESULT CreateFolder([in] BSTR Path, [out, retval] IFolder** ppfolder); + + [id(0x0000044d)] + HRESULT CreateTextFile([in] BSTR FileName, [in, optional, defaultvalue(-1)] VARIANT_BOOL Overwrite, + [in, optional, defaultvalue(0)] VARIANT_BOOL Unicode, [out, retval] ITextStream** ppts); + + [id(0x0000044c)] + HRESULT OpenTextFile([in] BSTR FileName, [in, optional, defaultvalue(1)] IOMode IOMode, + [in, optional, defaultvalue(0)] VARIANT_BOOL Create, + [in, optional, defaultvalue(0)] Tristate Format, + [out, retval] ITextStream** ppts); + } + + [ + odl, + uuid(C7C3F5A1-88A3-11D0-ABCB-00A0C90FFFC0), + hidden, + dual, + nonextensible, + oleautomation + ] + interface IDriveCollection : IDispatch { + [id(00000000)] + HRESULT Item([in] VARIANT Key, [out, retval] IDrive** ppdrive); + + [id(DISPID_NEWENUM), propget, restricted, hidden] + HRESULT _NewEnum([out, retval] IUnknown** ppenum); + + [id(0x00000001), propget] + HRESULT Count([out, retval] long* plCount); + } + + [ + odl, + uuid(C7C3F5A0-88A3-11D0-ABCB-00A0C90FFFC0), + hidden, + dual, + nonextensible, + oleautomation + ] + interface IDrive : IDispatch + { + [id(00000000), propget] + HRESULT Path([out, retval] BSTR* pbstrPath); + + [id(0x00002710), propget] + HRESULT DriveLetter([out, retval] BSTR* pbstrLetter) +; + [id(0x00002711), propget] + HRESULT ShareName([out, retval] BSTR* pbstrShareName); + + [id(0x00002712), propget] + HRESULT DriveType([out, retval] DriveTypeConst* pdt); + + [id(0x00002713), propget] + HRESULT RootFolder([out, retval] IFolder** ppfolder); + + [id(0x00002715), propget] + HRESULT AvailableSpace([out, retval] VARIANT* pvarAvail); + + [id(0x00002714), propget] + HRESULT FreeSpace([out, retval] VARIANT* pvarFree); + + [id(0x00002716), propget] + HRESULT TotalSize([out, retval] VARIANT* pvarTotal); + + [id(0x00002717), propget] + HRESULT VolumeName([out, retval] BSTR* pbstrName); + + [id(0x00002717), propput] + HRESULT VolumeName([in] BSTR pbstrName); + + [id(0x00002718), propget] + HRESULT FileSystem([out, retval] BSTR* pbstrFileSystem); + + [id(0x00002719), propget] + HRESULT SerialNumber([out, retval] long* pulSerialNumber); + + [id(0x0000271a), propget] + HRESULT IsReady([out, retval] VARIANT_BOOL* pfReady); + } + + [ + odl, + uuid(C7C3F5A2-88A3-11D0-ABCB-00A0C90FFFC0), + hidden, + dual, + nonextensible, + oleautomation + ] + interface IFolder : IDispatch + { + [id(00000000), propget] + HRESULT Path([out, retval] BSTR* pbstrPath); + + [id(0x000003e8), propget] + HRESULT Name([out, retval] BSTR* pbstrName); + + [id(0x000003e8), propput] + HRESULT Name([in] BSTR pbstrName); + + [id(0x000003ea), propget] + HRESULT ShortPath([out, retval] BSTR* pbstrPath); + + [id(0x000003e9), propget] + HRESULT ShortName([out, retval] BSTR* pbstrName); + + [id(0x000003ec), propget] + HRESULT Drive([out, retval] IDrive** ppdrive); + + [id(0x000003ed), propget] + HRESULT ParentFolder([out, retval] IFolder** ppfolder); + + [id(0x000003eb), propget] + HRESULT Attributes([out, retval] FileAttribute* pfa); + + [id(0x000003eb), propput] + HRESULT Attributes([in] FileAttribute pfa); + + [id(0x000003ee), propget] + HRESULT DateCreated([out, retval] DATE* pdate); + + [id(0x000003ef), propget] + HRESULT DateLastModified([out, retval] DATE* pdate); + + [id(0x000003f0), propget] + HRESULT DateLastAccessed([out, retval] DATE* pdate); + + [id(0x000003f2), propget] + HRESULT Type([out, retval] BSTR* pbstrType); + + [id(0x000004b1)] + HRESULT Delete([in, optional, defaultvalue(0)] VARIANT_BOOL Force); + + [id(0x000004b3)] + HRESULT Copy([in] BSTR Destination, [in, optional, defaultvalue(-1)] VARIANT_BOOL OverWriteFiles); + + [id(0x000004b5)] + HRESULT Move([in] BSTR Destination); + + [id(0x00002710), propget] + HRESULT IsRootFolder([out, retval] VARIANT_BOOL* pfRootFolder); + + [id(0x000003f1), propget] + HRESULT Size([out, retval] VARIANT* pvarSize); + + [id(0x00002711), propget] + HRESULT SubFolders([out, retval] IFolderCollection** ppfolders); + + [id(0x00002712), propget] + HRESULT Files([out, retval] IFileCollection** ppfiles); + + [id(0x0000044d)] + HRESULT CreateTextFile([in] BSTR FileName, [in, optional, defaultvalue(-1)] VARIANT_BOOL Overwrite, + [in, optional, defaultvalue(0)] VARIANT_BOOL Unicode, [out, retval] ITextStream** ppts); + } + + [ + odl, + uuid(C7C3F5A3-88A3-11D0-ABCB-00A0C90FFFC0), + hidden, + dual, + nonextensible, + oleautomation + ] + interface IFolderCollection : IDispatch + { + [id(0x00000002)] + HRESULT Add([in] BSTR Name, [out, retval] IFolder** ppfolder); + + [id(00000000), propget] + HRESULT Item([in] VARIANT Key, [out, retval] IFolder** ppfolder); + + [id(DISPID_NEWENUM), propget, restricted, hidden] + HRESULT _NewEnum([out, retval] IUnknown** ppenum); + + [id(0x00000001), propget] + HRESULT Count([out, retval] long* plCount); + } + + [ + odl, + uuid(C7C3F5A5-88A3-11D0-ABCB-00A0C90FFFC0), + hidden, + dual, + nonextensible, + oleautomation + ] + interface IFileCollection : IDispatch + { + [id(00000000), propget] + HRESULT Item([in] VARIANT Key, [out, retval] IFile** ppfile); + + [id(DISPID_NEWENUM), propget, restricted, hidden] + HRESULT _NewEnum([out, retval] IUnknown** ppenum); + + [id(0x00000001), propget] + HRESULT Count([out, retval] long* plCount); + } + + [ + odl, + uuid(C7C3F5A4-88A3-11D0-ABCB-00A0C90FFFC0), + hidden, + dual, + nonextensible, + oleautomation + ] + interface IFile : IDispatch + { + [id(00000000), propget] + HRESULT Path([out, retval] BSTR* pbstrPath); + + [id(0x000003e8), propget] + HRESULT Name([out, retval] BSTR* pbstrName); + + [id(0x000003e8), propput] + HRESULT Name([in] BSTR pbstrName); + + [id(0x000003ea), propget] + HRESULT ShortPath([out, retval] BSTR* pbstrPath); + + [id(0x000003e9), propget] + HRESULT ShortName([out, retval] BSTR* pbstrName); + + [id(0x000003ec), propget] + HRESULT Drive([out, retval] IDrive** ppdrive); + + [id(0x000003ed), propget] + HRESULT ParentFolder([out, retval] IFolder** ppfolder); + + [id(0x000003eb), propget] + HRESULT Attributes([out, retval] FileAttribute* pfa); + + [id(0x000003eb), propput] + HRESULT Attributes([in] FileAttribute pfa); + + [id(0x000003ee), propget] + HRESULT DateCreated([out, retval] DATE* pdate); + + [id(0x000003ef), propget] + HRESULT DateLastModified([out, retval] DATE* pdate); + + [id(0x000003f0), propget] + HRESULT DateLastAccessed([out, retval] DATE* pdate); + + [id(0x000003f1), propget] + HRESULT Size([out, retval] VARIANT* pvarSize); + + [id(0x000003f2), propget] + HRESULT Type([out, retval] BSTR* pbstrType); + + [id(0x000004b0)] + HRESULT Delete([in, optional, defaultvalue(0)] VARIANT_BOOL Force); + + [id(0x000004b2)] + HRESULT Copy([in] BSTR Destination, [in, optional, defaultvalue(-1)] VARIANT_BOOL OverWriteFiles); + + [id(0x000004b4)] + HRESULT Move([in] BSTR Destination); + + [id(0x0000044c)] + HRESULT OpenAsTextStream([in, optional, defaultvalue(1)] IOMode IOMode, + [in, optional, defaultvalue(0)] Tristate Format, [out, retval] ITextStream** ppts); + } + + [ + odl, + uuid(53BAD8C1-E718-11CF-893D-00A0C9054228), + hidden, + dual, + nonextensible, + oleautomation + ] + interface ITextStream : IDispatch + { + [id(0x00002710), propget] + HRESULT Line([out, retval] long* Line); + + [id(0xfffffdef), propget] + HRESULT Column([out, retval] long* Column); + + [id(0x00002712), propget] + HRESULT AtEndOfStream([out, retval] VARIANT_BOOL* EOS); + + [id(0x00002713), propget] + HRESULT AtEndOfLine([out, retval] VARIANT_BOOL* EOL); + + [id(0x00002714)] + HRESULT Read([in] long Characters, [out, retval] BSTR* Text); + + [id(0x00002715)] + HRESULT ReadLine([out, retval] BSTR* Text); + + [id(0x00002716)] + HRESULT ReadAll([out, retval] BSTR* Text); + + [id(0x00002717)] + HRESULT Write([in] BSTR Text); + + [id(0x00002718)] + HRESULT WriteLine([in, optional, defaultvalue("")] BSTR Text); + + [id(0x00002719)] + HRESULT WriteBlankLines([in] long Lines); + + [id(0x0000271a)] + HRESULT Skip([in] long Characters); + + [id(0x0000271b)] + HRESULT SkipLine(); + + [id(0x0000271c)] + HRESULT Close(); + } + + [ + odl, + uuid(2A0B9D10-4B87-11D3-A97A-00104B365C9F), + dual, + nonextensible, + oleautomation + ] + interface IFileSystem3 : IFileSystem + { + [id(0x00004e20)] + HRESULT GetStandardStream([in] StandardStreamTypes StandardStreamType, + [in, optional, defaultvalue(0)] VARIANT_BOOL Unicode, [out, retval] ITextStream** ppts); + + [id(0x00004e2a)] + HRESULT GetFileVersion([in] BSTR FileName, [out, retval] BSTR* FileVersion); + } + + [ + odl, + uuid(AADC65F6-CFF1-11D1-B747-00C04FC2B085), + dual, + oleautomation + ] + interface IScriptEncoder : IDispatch + { + [id(00000000)] + HRESULT EncodeScriptFile([in] BSTR szExt, [in] BSTR bstrStreamIn, [in] long cFlags, + [in] BSTR bstrDefaultLang, [out, retval] BSTR* pbstrStreamOut); + } + + [ + uuid(EE09B103-97E0-11CF-978F-00A02463E06F), + version(1.0), + helpstring("Scripting.Dictionary"), + threading(apartment), + progid("Scripting.Dictionary") + ] + coclass Dictionary + { + [default] interface IDictionary; + } + + [ + uuid(0D43FE01-F093-11CF-8940-00A0C9054228), + version(1.0), + helpstring("FileSystem Object"), + threading(both), + progid("Scripting.FileSystemObject") + ] + coclass FileSystemObject + { + [default] interface IFileSystem3; + } + + [ + uuid(C7C3F5B1-88A3-11D0-ABCB-00A0C90FFFC0), + noncreatable, + version(1.0) + ] + coclass Drive + { + [default] interface IDrive; + } + + [ + uuid(C7C3F5B2-88A3-11D0-ABCB-00A0C90FFFC0), + noncreatable, + version(1.0) + ] + coclass Drives + { + [default] interface IDriveCollection; + } + + [ + uuid(C7C3F5B3-88A3-11D0-ABCB-00A0C90FFFC0), + noncreatable, + version(1.0) + ] + coclass Folder + { + [default] interface IFolder; + } + + [ + uuid(C7C3F5B4-88A3-11D0-ABCB-00A0C90FFFC0), + noncreatable, + version(1.0) + ] + coclass Folders + { + [default] interface IFolderCollection; + } + + [ + uuid(C7C3F5B5-88A3-11D0-ABCB-00A0C90FFFC0), + noncreatable, + version(1.0) + ] + coclass File + { + [default] interface IFile; + } + + [ + uuid(C7C3F5B6-88A3-11D0-ABCB-00A0C90FFFC0), + noncreatable, + version(1.0) + ] + coclass Files + { + [default] interface IFileCollection; + } + + [ + uuid(0BB02EC0-EF49-11CF-8940-00A0C9054228), + noncreatable, + version(1.0) + ] + coclass TextStream + { + [default] interface ITextStream; + } + + [ + uuid(32DA2B15-CFED-11D1-B747-00C04FC2B085), + version(1.0), + helpstring("Script Encoder Object"), + threading(apartment), + progid("Scripting.Encoder") + ] + coclass Encoder + { + [default] interface IScriptEncoder; + } +} diff --git a/reactos/dll/win32/scrrun/scrrun.rc b/reactos/dll/win32/scrrun/scrrun.rc new file mode 100644 index 00000000000..e28e5f7bb60 --- /dev/null +++ b/reactos/dll/win32/scrrun/scrrun.rc @@ -0,0 +1,32 @@ +/* + * Copyright 2011 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* @makedep: scrrun.rgs */ +1 WINE_REGISTRY scrrun.rgs +2 WINE_REGISTRY scrrun_tlb.rgs + +1 TYPELIB scrrun.tlb + +#define WINE_FILEDESCRIPTION_STR "Wine ScrRun dll" +#define WINE_FILENAME_STR "scrrun.dll" +#define WINE_FILEVERSION 5,8,7600,16385 +#define WINE_FILEVERSION_STR "5.8.7600.16385" +#define WINE_PRODUCTVERSION 5,8,7600,16385 +#define WINE_PRODUCTVERSION_STR "5.8.7600.16385" + +#include "wine/wine_common_ver.rc" diff --git a/reactos/dll/win32/scrrun/scrrun.rgs b/reactos/dll/win32/scrrun/scrrun.rgs new file mode 100644 index 00000000000..d10d6ca6ef7 --- /dev/null +++ b/reactos/dll/win32/scrrun/scrrun.rgs @@ -0,0 +1,5 @@ +HKCR +{ + ForceRemove '.js' = s 'JSFile' + ForceRemove '.vbs' = s 'VBSFile' +} diff --git a/reactos/dll/win32/scrrun/scrrun.spec b/reactos/dll/win32/scrrun/scrrun.spec new file mode 100644 index 00000000000..e71b683c64c --- /dev/null +++ b/reactos/dll/win32/scrrun/scrrun.spec @@ -0,0 +1,6 @@ +@ stub DLLGetDocumentation +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() +@ stub DoOpenPipeStream diff --git a/reactos/dll/win32/scrrun/scrrun_private.h b/reactos/dll/win32/scrrun/scrrun_private.h new file mode 100644 index 00000000000..aa24ddee228 --- /dev/null +++ b/reactos/dll/win32/scrrun/scrrun_private.h @@ -0,0 +1,47 @@ +/* + * Copyright 2012 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef _SCRRUN_PRIVATE_H_ +#define _SCRRUN_PRIVATE_H + +extern HRESULT WINAPI FileSystem_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN; +extern HRESULT WINAPI Dictionary_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN; + +typedef enum tid_t +{ + NULL_tid, + IDictionary_tid, + IFileSystem3_tid, + IFolder_tid, + ITextStream_tid, + IFile_tid, + LAST_tid +} tid_t; + +HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) DECLSPEC_HIDDEN; + +static inline void *heap_alloc(size_t len) +{ + return HeapAlloc(GetProcessHeap(), 0, len); +} + +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} + +#endif diff --git a/reactos/dll/win32/scrrun/scrrun_tlb.rgs b/reactos/dll/win32/scrrun/scrrun_tlb.rgs new file mode 100644 index 00000000000..beea9215524 --- /dev/null +++ b/reactos/dll/win32/scrrun/scrrun_tlb.rgs @@ -0,0 +1,119 @@ +HKCR +{ + NoRemove Typelib + { + NoRemove '{420B2830-E718-11CF-893D-00A0C9054228}' + { + '1.0' = s 'Scripting' + { + '0' { win32 = s '%MODULE%' } + FLAGS = s '0' + } + } + } + NoRemove Interface + { + '{42C642C1-97E1-11CF-978F-00A02463E06F}' = s 'IDictionary' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{0AB5A3D0-E5B6-11D0-ABF5-00A0C90FFFC0}' = s 'IFileSystem' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{C7C3F5A1-88A3-11D0-ABCB-00A0C90FFFC0}' = s 'IDriveCollection' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{C7C3F5A0-88A3-11D0-ABCB-00A0C90FFFC0}' = s 'IDrive' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{C7C3F5A2-88A3-11D0-ABCB-00A0C90FFFC0}' = s 'IFolder' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{C7C3F5A3-88A3-11D0-ABCB-00A0C90FFFC0}' = s 'IFolderCollection' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{C7C3F5A5-88A3-11D0-ABCB-00A0C90FFFC0}' = s 'IFileCollection' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{C7C3F5A4-88A3-11D0-ABCB-00A0C90FFFC0}' = s 'IFile' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{53BAD8C1-E718-11CF-893D-00A0C9054228}' = s 'ITextStream' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{2A0B9D10-4B87-11D3-A97A-00104B365C9F}' = s 'IFileSystem3' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + '{AADC65F6-CFF1-11D1-B747-00C04FC2B085}' = s 'IScriptEncoder' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' { val Version = s '1.0' } + } + } + NoRemove CLSID + { + '{EE09B103-97E0-11CF-978F-00A02463E06F}' = s 'Scripting.Dictionary' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } + ProgId = s 'Scripting.Dictionary' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' + Version = s '1.0' + } + '{0D43FE01-F093-11CF-8940-00A0C9054228}' = s 'FileSystem Object' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + ProgId = s 'Scripting.FileSystemObject' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' + Version = s '1.0' + } + '{32DA2B15-CFED-11D1-B747-00C04FC2B085}' = s 'Script Encoder Object' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } + ProgId = s 'Scripting.Encoder' + TypeLib = s '{420B2830-E718-11CF-893D-00A0C9054228}' + Version = s '1.0' + } + } + 'Scripting.Dictionary' = s 'Scripting.Dictionary' + { + CLSID = s '{EE09B103-97E0-11CF-978F-00A02463E06F}' + } + 'Scripting.FileSystemObject' = s 'FileSystem Object' + { + CLSID = s '{0D43FE01-F093-11CF-8940-00A0C9054228}' + } + 'Scripting.Encoder' = s 'Script Encoder Object' + { + CLSID = s '{32DA2B15-CFED-11D1-B747-00C04FC2B085}' + } +} diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 20ca721cf9b..6a8e96c9eaa 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -159,6 +159,7 @@ reactos/dll/win32/rsabase # Autosync reactos/dll/win32/rsaenh # Synced to Wine-1.5.4 reactos/dll/win32/sccbase # Synced to Wine-1.5.19 reactos/dll/win32/schannel # Synced to Wine-1.5.19 +reactos/dll/win32/scrrun # Synced to Wine-1.7.1 reactos/dll/win32/secur32 # Forked reactos/dll/win32/security # Forked (different .spec) reactos/dll/win32/sensapi # Synced to Wine-1.5.4 diff --git a/reactos/media/inf/syssetup.inf b/reactos/media/inf/syssetup.inf index 8f7c8c52a52..c63420a8361 100644 --- a/reactos/media/inf/syssetup.inf +++ b/reactos/media/inf/syssetup.inf @@ -87,6 +87,7 @@ AddReg=Classes 11,,rpcrt4.dll,1 11,,rsabase.dll,1 11,,rsaenh.dll,1 +11,,scrrun.dll,1 11,,shdocvw.dll,3 11,,shell32.dll,3 11,,softpub.dll,1