diff --git a/reactos/dll/win32/scrrun/dictionary.c b/reactos/dll/win32/scrrun/dictionary.c index 54dc30c1062..17810ce7787 100644 --- a/reactos/dll/win32/scrrun/dictionary.c +++ b/reactos/dll/win32/scrrun/dictionary.c @@ -52,6 +52,7 @@ struct keyitem_pair { typedef struct { + struct provideclassinfo classinfo; IDictionary IDictionary_iface; LONG ref; @@ -227,19 +228,19 @@ static HRESULT WINAPI dict_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, static ULONG WINAPI dict_enum_AddRef(IEnumVARIANT *iface) { struct dictionary_enum *This = impl_from_IEnumVARIANT(iface); - TRACE("(%p)\n", This); - return InterlockedIncrement(&This->ref); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(%u)\n", This, ref); + return ref; } static ULONG WINAPI dict_enum_Release(IEnumVARIANT *iface) { struct dictionary_enum *This = impl_from_IEnumVARIANT(iface); - LONG ref; + LONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p)\n", This); + TRACE("(%p)->(%u)\n", This, ref); - ref = InterlockedDecrement(&This->ref); - if(ref == 0) { + if (!ref) { list_remove(&This->notify); IDictionary_Release(&This->dict->IDictionary_iface); heap_free(This); @@ -373,6 +374,10 @@ static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, { *obj = &This->IDictionary_iface; } + else if (IsEqualIID(riid, &IID_IProvideClassInfo)) + { + *obj = &This->classinfo.IProvideClassInfo_iface; + } else if ( IsEqualGUID( riid, &IID_IDispatchEx )) { TRACE("Interface IDispatchEx not supported - returning NULL\n"); @@ -391,27 +396,28 @@ static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, return E_NOINTERFACE; } - IDictionary_AddRef(iface); + IUnknown_AddRef((IUnknown*)*obj); return S_OK; } static ULONG WINAPI dictionary_AddRef(IDictionary *iface) { dictionary *This = impl_from_IDictionary(iface); - TRACE("(%p)\n", This); + ULONG ref = InterlockedIncrement(&This->ref); - return InterlockedIncrement(&This->ref); + TRACE("(%p)->(%u)\n", This, ref); + + return ref; } static ULONG WINAPI dictionary_Release(IDictionary *iface) { dictionary *This = impl_from_IDictionary(iface); - LONG ref; + ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p)\n", This); + TRACE("(%p)->(%u)\n", This, ref); - ref = InterlockedDecrement(&This->ref); - if(ref == 0) { + if (!ref) { IDictionary_RemoveAll(iface); heap_free(This); } @@ -423,7 +429,7 @@ static HRESULT WINAPI dictionary_GetTypeInfoCount(IDictionary *iface, UINT *pcti { dictionary *This = impl_from_IDictionary(iface); - TRACE("(%p)->()\n", This); + TRACE("(%p)->(%p)\n", This, pctinfo); *pctinfo = 1; return S_OK; @@ -872,7 +878,7 @@ HRESULT WINAPI Dictionary_CreateInstance(IClassFactory *factory,IUnknown *outer, { dictionary *This; - TRACE("(%p)\n", obj); + TRACE("(%p, %p, %s, %p)\n", factory, outer, debugstr_guid(riid), obj); *obj = NULL; @@ -887,6 +893,7 @@ HRESULT WINAPI Dictionary_CreateInstance(IClassFactory *factory,IUnknown *outer, list_init(&This->notifier); memset(This->buckets, 0, sizeof(This->buckets)); + init_classinfo(&CLSID_Dictionary, (IUnknown *)&This->IDictionary_iface, &This->classinfo); *obj = &This->IDictionary_iface; return S_OK; diff --git a/reactos/dll/win32/scrrun/filesystem.c b/reactos/dll/win32/scrrun/filesystem.c index db82f59fe19..14c1e36db6f 100644 --- a/reactos/dll/win32/scrrun/filesystem.c +++ b/reactos/dll/win32/scrrun/filesystem.c @@ -26,19 +26,27 @@ static const WCHAR bsW[] = {'\\',0}; static const WCHAR utf16bom = 0xfeff; +struct filesystem { + struct provideclassinfo classinfo; + IFileSystem3 IFileSystem3_iface; +}; + struct foldercollection { + struct provideclassinfo classinfo; IFolderCollection IFolderCollection_iface; LONG ref; BSTR path; }; struct filecollection { + struct provideclassinfo classinfo; IFileCollection IFileCollection_iface; LONG ref; BSTR path; }; struct drivecollection { + struct provideclassinfo classinfo; IDriveCollection IDriveCollection_iface; LONG ref; DWORD drives; @@ -74,18 +82,21 @@ struct enumvariant { }; struct drive { + struct provideclassinfo classinfo; IDrive IDrive_iface; LONG ref; BSTR root; }; struct folder { + struct provideclassinfo classinfo; IFolder IFolder_iface; LONG ref; BSTR path; }; struct file { + struct provideclassinfo classinfo; IFile IFile_iface; LONG ref; @@ -93,6 +104,7 @@ struct file { }; struct textstream { + struct provideclassinfo classinfo; ITextStream ITextStream_iface; LONG ref; @@ -108,6 +120,11 @@ enum iotype { IOWrite }; +static inline struct filesystem *impl_from_IFileSystem3(IFileSystem3 *iface) +{ + return CONTAINING_RECORD(iface, struct filesystem, IFileSystem3_iface); +} + static inline struct drive *impl_from_IDrive(IDrive *iface) { return CONTAINING_RECORD(iface, struct drive, IDrive_iface); @@ -213,13 +230,17 @@ static HRESULT WINAPI textstream_QueryInterface(ITextStream *iface, REFIID riid, IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) { - *obj = iface; - ITextStream_AddRef(iface); - return S_OK; + *obj = &This->ITextStream_iface; } + else if (IsEqualIID(riid, &IID_IProvideClassInfo)) + { + *obj = &This->classinfo.IProvideClassInfo_iface; + } + else + return E_NOINTERFACE; - *obj = NULL; - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*obj); + return S_OK; } static ULONG WINAPI textstream_AddRef(ITextStream *iface) @@ -708,6 +729,7 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod } } + init_classinfo(&CLSID_TextStream, (IUnknown *)&stream->ITextStream_iface, &stream->classinfo); *ret = &stream->ITextStream_iface; return S_OK; } @@ -724,12 +746,16 @@ static HRESULT WINAPI drive_QueryInterface(IDrive *iface, REFIID riid, void **ob IsEqualIID( riid, &IID_IDispatch ) || IsEqualIID( riid, &IID_IUnknown)) { - *obj = iface; - IDrive_AddRef(iface); + *obj = &This->IDrive_iface; + } + else if (IsEqualIID( riid, &IID_IProvideClassInfo )) + { + *obj = &This->classinfo.IProvideClassInfo_iface; } else return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*obj); return S_OK; } @@ -1067,6 +1093,7 @@ static HRESULT create_drive(WCHAR letter, IDrive **drive) This->root[2] = '\\'; This->root[3] = 0; + init_classinfo(&CLSID_Drive, (IUnknown *)&This->IDrive_iface, &This->classinfo); *drive = &This->IDrive_iface; return S_OK; } @@ -1560,12 +1587,16 @@ static HRESULT WINAPI foldercoll_QueryInterface(IFolderCollection *iface, REFIID IsEqualIID( riid, &IID_IDispatch ) || IsEqualIID( riid, &IID_IUnknown )) { - *obj = iface; - IFolderCollection_AddRef(iface); + *obj = &This->IFolderCollection_iface; + } + else if (IsEqualIID( riid, &IID_IProvideClassInfo )) + { + *obj = &This->classinfo.IProvideClassInfo_iface; } else return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*obj); return S_OK; } @@ -1740,6 +1771,7 @@ static HRESULT create_foldercoll(BSTR path, IFolderCollection **folders) return E_OUTOFMEMORY; } + init_classinfo(&CLSID_Folders, (IUnknown *)&This->IFolderCollection_iface, &This->classinfo); *folders = &This->IFolderCollection_iface; return S_OK; @@ -1757,12 +1789,16 @@ static HRESULT WINAPI filecoll_QueryInterface(IFileCollection *iface, REFIID rii IsEqualIID( riid, &IID_IDispatch ) || IsEqualIID( riid, &IID_IUnknown )) { - *obj = iface; - IFileCollection_AddRef(iface); + *obj = &This->IFileCollection_iface; + } + else if (IsEqualIID( riid, &IID_IProvideClassInfo )) + { + *obj = &This->classinfo.IProvideClassInfo_iface; } else return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*obj); return S_OK; } @@ -1929,6 +1965,7 @@ static HRESULT create_filecoll(BSTR path, IFileCollection **files) return E_OUTOFMEMORY; } + init_classinfo(&CLSID_Files, (IUnknown *)&This->IFileCollection_iface, &This->classinfo); *files = &This->IFileCollection_iface; return S_OK; } @@ -1945,12 +1982,16 @@ static HRESULT WINAPI drivecoll_QueryInterface(IDriveCollection *iface, REFIID r IsEqualIID( riid, &IID_IDispatch ) || IsEqualIID( riid, &IID_IUnknown )) { - *obj = iface; - IDriveCollection_AddRef(iface); + *obj = &This->IDriveCollection_iface; + } + else if (IsEqualIID( riid, &IID_IProvideClassInfo )) + { + *obj = &This->classinfo.IProvideClassInfo_iface; } else return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*obj); return S_OK; } @@ -2094,6 +2135,7 @@ static HRESULT create_drivecoll(IDriveCollection **drives) for (This->count = 0; mask; This->count++) mask &= mask - 1; + init_classinfo(&CLSID_Drives, (IUnknown *)&This->IDriveCollection_iface, &This->classinfo); *drives = &This->IDriveCollection_iface; return S_OK; } @@ -2110,12 +2152,16 @@ static HRESULT WINAPI folder_QueryInterface(IFolder *iface, REFIID riid, void ** IsEqualIID( riid, &IID_IDispatch ) || IsEqualIID( riid, &IID_IUnknown)) { - *obj = iface; - IFolder_AddRef(iface); + *obj = &This->IFolder_iface; + } + else if (IsEqualIID( riid, &IID_IProvideClassInfo )) + { + *obj = &This->classinfo.IProvideClassInfo_iface; } else return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*obj); return S_OK; } @@ -2434,6 +2480,7 @@ HRESULT create_folder(const WCHAR *path, IFolder **folder) return E_OUTOFMEMORY; } + init_classinfo(&CLSID_Folder, (IUnknown *)&This->IFolder_iface, &This->classinfo); *folder = &This->IFolder_iface; return S_OK; @@ -2445,17 +2492,23 @@ static HRESULT WINAPI file_QueryInterface(IFile *iface, REFIID riid, void **obj) TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + *obj = NULL; + if (IsEqualIID(riid, &IID_IFile) || IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) { - *obj = iface; - IFile_AddRef(iface); - return S_OK; + *obj = &This->IFile_iface; } + else if (IsEqualIID( riid, &IID_IProvideClassInfo )) + { + *obj = &This->classinfo.IProvideClassInfo_iface; + } + else + return E_NOINTERFACE; - *obj = NULL; - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*obj); + return S_OK; } static ULONG WINAPI file_AddRef(IFile *iface) @@ -2800,12 +2853,15 @@ static HRESULT create_file(BSTR path, IFile **file) return create_error(GetLastError()); } + init_classinfo(&CLSID_File, (IUnknown *)&f->IFile_iface, &f->classinfo); *file = &f->IFile_iface; return S_OK; } static HRESULT WINAPI filesys_QueryInterface(IFileSystem3 *iface, REFIID riid, void **ppvObject) { + struct filesystem *This = impl_from_IFileSystem3(iface); + TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject); if ( IsEqualGUID( riid, &IID_IFileSystem3 ) || @@ -2813,7 +2869,11 @@ static HRESULT WINAPI filesys_QueryInterface(IFileSystem3 *iface, REFIID riid, v IsEqualGUID( riid, &IID_IDispatch ) || IsEqualGUID( riid, &IID_IUnknown ) ) { - *ppvObject = iface; + *ppvObject = &This->IFileSystem3_iface; + } + else if (IsEqualGUID( riid, &IID_IProvideClassInfo )) + { + *ppvObject = &This->classinfo.IProvideClassInfo_iface; } else if ( IsEqualGUID( riid, &IID_IDispatchEx )) { @@ -2833,7 +2893,7 @@ static HRESULT WINAPI filesys_QueryInterface(IFileSystem3 *iface, REFIID riid, v return E_NOINTERFACE; } - IFileSystem3_AddRef(iface); + IUnknown_AddRef((IUnknown*)*ppvObject); return S_OK; } @@ -3878,11 +3938,13 @@ static const struct IFileSystem3Vtbl filesys_vtbl = filesys_GetFileVersion }; -static IFileSystem3 filesystem = { &filesys_vtbl }; +static struct filesystem filesystem; 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); + filesystem.IFileSystem3_iface.lpVtbl = &filesys_vtbl; + init_classinfo(&CLSID_FileSystemObject, (IUnknown *)&filesystem.IFileSystem3_iface, &filesystem.classinfo); + return IFileSystem3_QueryInterface(&filesystem.IFileSystem3_iface, riid, ppv); } diff --git a/reactos/dll/win32/scrrun/scrrun.c b/reactos/dll/win32/scrrun/scrrun.c index 19d831a97dc..946f8b71ec9 100644 --- a/reactos/dll/win32/scrrun/scrrun.c +++ b/reactos/dll/win32/scrrun/scrrun.c @@ -22,6 +22,11 @@ static HINSTANCE scrrun_instance; +static inline struct provideclassinfo *impl_from_IProvideClassInfo(IProvideClassInfo *iface) +{ + return CONTAINING_RECORD(iface, struct provideclassinfo, IProvideClassInfo_iface); +} + typedef HRESULT (*fnCreateInstance)(LPVOID *ppObj); static HRESULT WINAPI scrruncf_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv ) @@ -105,6 +110,9 @@ static HRESULT load_typelib(void) HRESULT hres; ITypeLib *tl; + if(typelib) + return S_OK; + hres = LoadRegTypeLib(&LIBID_Scripting, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); if(FAILED(hres)) { ERR("LoadRegTypeLib failed: %08x\n", hres); @@ -116,13 +124,21 @@ static HRESULT load_typelib(void) return hres; } +static HRESULT get_typeinfo_of_guid(const GUID *guid, ITypeInfo **tinfo) +{ + HRESULT hres; + + if(FAILED(hres = load_typelib())) + return hres; + + return ITypeLib_GetTypeInfoOfGuid(typelib, guid, tinfo); +} + HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) { HRESULT hres; - if (!typelib) - hres = load_typelib(); - if (!typelib) + if (FAILED(hres = load_typelib())) return hres; if(!typeinfos[tid]) { @@ -157,6 +173,56 @@ static void release_typelib(void) ITypeLib_Release(typelib); } +static HRESULT WINAPI provideclassinfo_QueryInterface(IProvideClassInfo *iface, REFIID riid, void **obj) +{ + struct provideclassinfo *This = impl_from_IProvideClassInfo(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IProvideClassInfo)) { + *obj = iface; + IProvideClassInfo_AddRef(iface); + return S_OK; + } + else + return IUnknown_QueryInterface(This->outer, riid, obj); +} + +static ULONG WINAPI provideclassinfo_AddRef(IProvideClassInfo *iface) +{ + struct provideclassinfo *This = impl_from_IProvideClassInfo(iface); + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI provideclassinfo_Release(IProvideClassInfo *iface) +{ + struct provideclassinfo *This = impl_from_IProvideClassInfo(iface); + return IUnknown_Release(This->outer); +} + +static HRESULT WINAPI provideclassinfo_GetClassInfo(IProvideClassInfo *iface, ITypeInfo **ti) +{ + struct provideclassinfo *This = impl_from_IProvideClassInfo(iface); + + TRACE("(%p)->(%p)\n", This, ti); + + return get_typeinfo_of_guid(This->guid, ti); +} + +static const IProvideClassInfoVtbl provideclassinfovtbl = { + provideclassinfo_QueryInterface, + provideclassinfo_AddRef, + provideclassinfo_Release, + provideclassinfo_GetClassInfo +}; + +void init_classinfo(const GUID *guid, IUnknown *outer, struct provideclassinfo *classinfo) +{ + classinfo->IProvideClassInfo_iface.lpVtbl = &provideclassinfovtbl; + classinfo->outer = outer; + classinfo->guid = guid; +} + BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) { TRACE("%p, %u, %p\n", hinst, reason, reserved); diff --git a/reactos/dll/win32/scrrun/scrrun_private.h b/reactos/dll/win32/scrrun/scrrun_private.h index f3ba4aab81e..69ff610a45b 100644 --- a/reactos/dll/win32/scrrun/scrrun_private.h +++ b/reactos/dll/win32/scrrun/scrrun_private.h @@ -60,7 +60,15 @@ typedef enum tid_t HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) DECLSPEC_HIDDEN; -static inline void *heap_alloc(size_t len) +struct provideclassinfo { + IProvideClassInfo IProvideClassInfo_iface; + IUnknown *outer; + const GUID *guid; +}; + +extern void init_classinfo(const GUID *guid, IUnknown *outer, struct provideclassinfo *classinfo) DECLSPEC_HIDDEN; + +static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 024fddc69f0..7cff334dd0c 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -165,7 +165,7 @@ reactos/dll/win32/rsabase # Synced to WineStaging-1.9.11 reactos/dll/win32/rsaenh # Synced to WineStaging-1.9.11 reactos/dll/win32/sccbase # Synced to WineStaging-1.9.11 reactos/dll/win32/schannel # Synced to WineStaging-1.9.11 -reactos/dll/win32/scrrun # Synced to WineStaging-1.9.11 +reactos/dll/win32/scrrun # Synced to WineStaging-2.2 reactos/dll/win32/secur32 # Forked reactos/dll/win32/security # Forked (different .spec) reactos/dll/win32/sensapi # Synced to WineStaging-1.9.11