scrrun: Implement Next() for folder collection.

This commit is contained in:
Nikolay Sivov 2014-01-06 01:22:08 +04:00 committed by Alexandre Julliard
parent 281f69bccf
commit b99b69aac2
2 changed files with 112 additions and 5 deletions

View File

@ -36,6 +36,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(scrrun); WINE_DEFAULT_DEBUG_CHANNEL(scrrun);
static const WCHAR bsW[] = {'\\',0};
struct enumdata { struct enumdata {
union union
{ {
@ -125,6 +127,31 @@ static inline HRESULT create_error(DWORD err)
} }
} }
static HRESULT create_folder(const WCHAR*, IFolder**);
static inline BOOL is_dir_data(const WIN32_FIND_DATAW *data)
{
static const WCHAR dotdotW[] = {'.','.',0};
static const WCHAR dotW[] = {'.',0};
return (data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
strcmpW(data->cFileName, dotdotW) &&
strcmpW(data->cFileName, dotW);
}
static BSTR get_full_path(BSTR path, const WIN32_FIND_DATAW *data)
{
int len = SysStringLen(path);
WCHAR buffW[MAX_PATH];
strcpyW(buffW, path);
if (path[len-1] != '\\')
strcatW(buffW, bsW);
strcatW(buffW, data->cFileName);
return SysAllocString(buffW);
}
static BOOL textstream_check_iomode(struct textstream *This, enum iotype type) static BOOL textstream_check_iomode(struct textstream *This, enum iotype type)
{ {
if (type == IORead) if (type == IORead)
@ -421,8 +448,75 @@ static ULONG WINAPI foldercoll_enumvariant_Release(IEnumVARIANT *iface)
static HRESULT WINAPI foldercoll_enumvariant_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched) static HRESULT WINAPI foldercoll_enumvariant_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched)
{ {
struct enumvariant *This = impl_from_IEnumVARIANT(iface); struct enumvariant *This = impl_from_IEnumVARIANT(iface);
FIXME("(%p)->(%d %p %p): stub\n", This, celt, var, fetched); HANDLE handle = This->data.u.foldercoll.find;
return E_NOTIMPL; WIN32_FIND_DATAW data;
ULONG count = 0;
TRACE("(%p)->(%d %p %p)\n", This, celt, var, fetched);
if (fetched)
*fetched = 0;
if (!handle)
{
static const WCHAR allW[] = {'*',0};
WCHAR pathW[MAX_PATH];
BSTR parent = This->data.u.foldercoll.path;
int len;
strcpyW(pathW, parent);
len = SysStringLen(parent);
if (parent[len-1] != '\\')
strcatW(pathW, bsW);
strcatW(pathW, allW);
handle = FindFirstFileW(pathW, &data);
if (handle == INVALID_HANDLE_VALUE)
return S_FALSE;
/* find first dir */
while (1)
{
if (is_dir_data(&data))
break;
else
if (!FindNextFileW(handle, &data))
{
FindClose(handle);
return S_FALSE;
}
}
This->data.u.foldercoll.find = handle;
}
do
{
if (count >= celt) break;
if (is_dir_data(&data))
{
IFolder *folder;
HRESULT hr;
BSTR str;
str = get_full_path(This->data.u.foldercoll.path, &data);
hr = create_folder(str, &folder);
SysFreeString(str);
if (FAILED(hr)) return hr;
V_VT(&var[count]) = VT_DISPATCH;
V_DISPATCH(&var[count]) = (IDispatch*)folder;
count++;
}
} while (FindNextFileW(handle, &data));
if (count < celt)
return S_FALSE;
if (fetched)
*fetched = count;
return S_OK;
} }
static HRESULT WINAPI foldercoll_enumvariant_Skip(IEnumVARIANT *iface, ULONG celt) static HRESULT WINAPI foldercoll_enumvariant_Skip(IEnumVARIANT *iface, ULONG celt)
@ -972,7 +1066,7 @@ static const IFolderVtbl foldervtbl = {
folder_CreateTextFile folder_CreateTextFile
}; };
static HRESULT create_folder(BSTR path, IFolder **folder) HRESULT create_folder(const WCHAR *path, IFolder **folder)
{ {
struct folder *This; struct folder *This;
@ -1466,7 +1560,6 @@ static HRESULT WINAPI filesys_BuildPath(IFileSystem3 *iface, BSTR Path,
} }
else if (Path[path_len-1] != '\\' && Name[0] != '\\') else if (Path[path_len-1] != '\\' && Name[0] != '\\')
{ {
static const WCHAR bsW[] = {'\\',0};
ret = SysAllocStringLen(NULL, path_len + name_len + 1); ret = SysAllocStringLen(NULL, path_len + name_len + 1);
if (ret) if (ret)
{ {

View File

@ -794,6 +794,8 @@ static void test_FolderCollection(void)
LONG count, count2, ref, ref2; LONG count, count2, ref, ref2;
IUnknown *unk, *unk2; IUnknown *unk, *unk2;
IFolder *folder; IFolder *folder;
ULONG fetched;
VARIANT var;
HRESULT hr; HRESULT hr;
BSTR str; BSTR str;
@ -813,6 +815,7 @@ static void test_FolderCollection(void)
hr = IFolder_get_SubFolders(folder, &folders); hr = IFolder_get_SubFolders(folder, &folders);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
IFolder_Release(folder);
count = 0; count = 0;
hr = IFolderCollection_get_Count(folders, &count); hr = IFolderCollection_get_Count(folders, &count);
@ -870,6 +873,18 @@ if (hr == S_OK) {
hr = IEnumVARIANT_Reset(enumvar); hr = IEnumVARIANT_Reset(enumvar);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
VariantInit(&var);
fetched = 0;
hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(fetched == 1, "got %d\n", fetched);
ok(V_VT(&var) == VT_DISPATCH, "got type %d\n", V_VT(&var));
hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IFolder, (void**)&folder);
ok(hr == S_OK, "got 0x%08x\n", hr);
IFolder_Release(folder);
VariantClear(&var);
IEnumVARIANT_Release(enumvar); IEnumVARIANT_Release(enumvar);
IUnknown_Release(unk); IUnknown_Release(unk);
@ -877,7 +892,6 @@ if (hr == S_OK) {
RemoveDirectoryW(path2W); RemoveDirectoryW(path2W);
IFolderCollection_Release(folders); IFolderCollection_Release(folders);
IFolder_Release(folder);
} }
START_TEST(filesystem) START_TEST(filesystem)