scrrun: Added IProvideClassInfo support for filesystem objects.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ba2e6fb2be
commit
eda5d61c54
@ -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;
|
||||
}
|
||||
|
||||
*obj = NULL;
|
||||
else if (IsEqualIID(riid, &IID_IProvideClassInfo))
|
||||
{
|
||||
*obj = &This->classinfo.IProvideClassInfo_iface;
|
||||
}
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
*obj = NULL;
|
||||
else if (IsEqualIID( riid, &IID_IProvideClassInfo ))
|
||||
{
|
||||
*obj = &This->classinfo.IProvideClassInfo_iface;
|
||||
}
|
||||
else
|
||||
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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user