[PATCH 3/3] scrrun: Added IProvideClassInfo support for filesystem objects
Nikolay Sivov
nsivov at codeweavers.com
Wed Dec 7 04:33:59 CST 2016
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/scrrun/filesystem.c | 110 ++++++++++++++++++++++++++++++++---------
dlls/scrrun/tests/filesystem.c | 36 ++++++++++++++
2 files changed, 122 insertions(+), 24 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c
index 818079e..45040b3 100644
--- a/dlls/scrrun/filesystem.c
+++ b/dlls/scrrun/filesystem.c
@@ -39,19 +39,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(scrrun);
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;
@@ -87,18 +95,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;
@@ -106,6 +117,7 @@ struct file {
};
struct textstream {
+ struct provideclassinfo classinfo;
ITextStream ITextStream_iface;
LONG ref;
@@ -121,6 +133,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);
@@ -226,13 +243,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)
@@ -721,6 +742,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;
}
@@ -737,12 +759,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;
}
@@ -1080,6 +1106,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;
}
@@ -1573,12 +1600,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;
}
@@ -1753,6 +1784,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;
@@ -1770,12 +1802,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;
}
@@ -1942,6 +1978,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;
}
@@ -1958,12 +1995,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;
}
@@ -2107,6 +2148,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;
}
@@ -2123,12 +2165,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;
}
@@ -2447,6 +2493,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;
@@ -2458,17 +2505,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)
@@ -2813,12 +2866,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 ) ||
@@ -2826,7 +2882,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 ))
{
@@ -2846,7 +2906,7 @@ static HRESULT WINAPI filesys_QueryInterface(IFileSystem3 *iface, REFIID riid, v
return E_NOINTERFACE;
}
- IFileSystem3_AddRef(iface);
+ IUnknown_AddRef((IUnknown*)*ppvObject);
return S_OK;
}
@@ -3891,11 +3951,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/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c
index cd0e6d6..5516099 100644
--- a/dlls/scrrun/tests/filesystem.c
+++ b/dlls/scrrun/tests/filesystem.c
@@ -100,6 +100,31 @@ static IDrive *get_fixed_drive(void)
return drive;
}
+#define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__)
+static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line)
+{
+ IProvideClassInfo *classinfo;
+ TYPEATTR *attr;
+ ITypeInfo *ti;
+ HRESULT hr;
+
+ hr = IDispatch_QueryInterface(disp, &IID_IProvideClassInfo, (void **)&classinfo);
+ ok_(__FILE__,line) (hr == S_OK, "Failed to get IProvideClassInfo, %#x.\n", hr);
+
+ hr = IProvideClassInfo_GetClassInfo(classinfo, &ti);
+ ok_(__FILE__,line) (hr == S_OK, "GetClassInfo() failed, %#x.\n", hr);
+
+ hr = ITypeInfo_GetTypeAttr(ti, &attr);
+ ok_(__FILE__,line) (hr == S_OK, "GetTypeAttr() failed, %#x.\n", hr);
+
+ ok_(__FILE__,line) (IsEqualGUID(&attr->guid, guid), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr->guid),
+ wine_dbgstr_guid(guid));
+
+ IProvideClassInfo_Release(classinfo);
+ ITypeInfo_ReleaseTypeAttr(ti, attr);
+ ITypeInfo_Release(ti);
+}
+
static void test_interfaces(void)
{
static const WCHAR nonexistent_dirW[] = {
@@ -122,6 +147,8 @@ static void test_interfaces(void)
lstrcpyW(file_path, windows_path);
lstrcatW(file_path, file_kernel32W);
+ test_provideclassinfo(disp, &CLSID_FileSystemObject);
+
hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
@@ -927,6 +954,7 @@ static void test_GetFolder(void)
hr = IFileSystem3_GetFolder(fs3, str, &folder);
ok(hr == S_OK, "got 0x%08x\n", hr);
SysFreeString(str);
+ test_provideclassinfo(folder, &CLSID_Folder);
IFolder_Release(folder);
}
@@ -978,6 +1006,7 @@ static void test_FolderCollection(void)
hr = IFolder_get_SubFolders(folder, &folders);
ok(hr == S_OK, "got 0x%08x\n", hr);
+ test_provideclassinfo(folders, &CLSID_Folders);
IFolder_Release(folder);
count = 0;
@@ -1153,6 +1182,7 @@ static void test_FileCollection(void)
hr = IFolder_get_Files(folder, &files);
ok(hr == S_OK, "got 0x%08x\n", hr);
+ test_provideclassinfo(files, &CLSID_Files);
IFolder_Release(folder);
count = 0;
@@ -1220,6 +1250,7 @@ static void test_FileCollection(void)
hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IFile, (void **)&file);
ok(hr == S_OK, "got 0x%08x\n", hr);
+ test_provideclassinfo(file, &CLSID_File);
str = NULL;
hr = IFile_get_Name(file, &str);
@@ -1292,6 +1323,8 @@ static void test_DriveCollection(void)
hr = IFileSystem3_get_Drives(fs3, &drives);
ok(hr == S_OK, "got 0x%08x\n", hr);
+ test_provideclassinfo(drives, &CLSID_Drives);
+
hr = IDriveCollection_get__NewEnum(drives, (IUnknown**)&enumvar);
ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -1419,6 +1452,8 @@ static void test_CreateTextFile(void)
hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
ok(hr == S_OK, "got 0x%08x\n", hr);
+ test_provideclassinfo(stream, &CLSID_TextStream);
+
hr = ITextStream_Read(stream, 1, &str);
ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
@@ -2033,6 +2068,7 @@ static void test_GetDrive(void)
wine_dbgstr_w(ptr->drivespec));
SysFreeString(driveletter);
}
+ test_provideclassinfo(drive, &CLSID_Drive);
IDrive_Release(drive);
} else
ok(drive == NULL, "got %p for drive spec %s\n", drive, wine_dbgstr_w(ptr->drivespec));
--
2.10.2
More information about the wine-patches
mailing list