[1/3] schedsvc: Implement SchRpcEnumFolders.
Dmitry Timoshkov
dmitry at baikal.ru
Fri Apr 4 01:15:24 CDT 2014
---
dlls/schedsvc/schedsvc.c | 129 ++++++++++++++++++++++++++++++++++++++-
dlls/schedsvc/schedsvc_private.h | 6 ++
2 files changed, 133 insertions(+), 2 deletions(-)
diff --git a/dlls/schedsvc/schedsvc.c b/dlls/schedsvc/schedsvc.c
index 5c7d359..a1fa4e0 100644
--- a/dlls/schedsvc/schedsvc.c
+++ b/dlls/schedsvc/schedsvc.c
@@ -326,11 +326,136 @@ HRESULT __cdecl SchRpcGetSecurity(const WCHAR *path, DWORD flags, WCHAR **sddl)
return E_NOTIMPL;
}
+static void free_list(TASK_NAMES list, LONG count)
+{
+ LONG i;
+
+ for (i = 0; i < count; i++)
+ heap_free(list[i]);
+
+ heap_free(list);
+}
+
+static inline BOOL is_directory(const WIN32_FIND_DATAW *data)
+{
+ if (data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ if (data->cFileName[0] == '.')
+ {
+ if (!data->cFileName[1] || (data->cFileName[1] == '.' && !data->cFileName[2]))
+ return FALSE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
HRESULT __cdecl SchRpcEnumFolders(const WCHAR *path, DWORD flags, DWORD *start_index, DWORD n_requested,
DWORD *n_names, TASK_NAMES *names)
{
- FIXME("%s,%#x,%p,%u,%p,%p: stub\n", debugstr_w(path), flags, start_index, n_requested, n_names, names);
- return E_NOTIMPL;
+ static const WCHAR allW[] = {'\\','*',0};
+ HRESULT hr = S_OK;
+ WCHAR *full_name;
+ WCHAR pathW[MAX_PATH];
+ WIN32_FIND_DATAW data;
+ HANDLE handle;
+ DWORD allocated, count, index;
+ TASK_NAMES list;
+
+ TRACE("%s,%#x,%u,%u,%p,%p\n", debugstr_w(path), flags, *start_index, n_requested, n_names, names);
+
+ *n_names = 0;
+ *names = NULL;
+
+ if (flags & ~TASK_ENUM_HIDDEN) return E_INVALIDARG;
+
+ if (!n_requested) n_requested = ~0u;
+
+ full_name = get_full_name(path, NULL);
+ if (!full_name) return E_OUTOFMEMORY;
+
+ if (strlenW(full_name) + 2 > MAX_PATH)
+ {
+ heap_free(full_name);
+ return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
+ }
+
+ strcpyW(pathW, full_name);
+ strcatW(pathW, allW);
+
+ heap_free(full_name);
+
+ allocated = 64;
+ list = heap_alloc(allocated * sizeof(list[0]));
+ if (!list) return E_OUTOFMEMORY;
+
+ index = count = 0;
+
+ handle = FindFirstFileW(pathW, &data);
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ heap_free(list);
+ if (GetLastError() == ERROR_PATH_NOT_FOUND)
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ do
+ {
+ if (is_directory(&data) && index++ >= *start_index)
+ {
+ if (count >= allocated)
+ {
+ TASK_NAMES new_list;
+ allocated *= 2;
+ new_list = heap_realloc(list, allocated * sizeof(list[0]));
+ if (!new_list)
+ {
+ hr = E_OUTOFMEMORY;
+ break;
+ }
+ list = new_list;
+ }
+
+ TRACE("adding %s\n", debugstr_w(data.cFileName));
+
+ list[count] = heap_strdupW(data.cFileName);
+ if (!list[count])
+ {
+ hr = E_OUTOFMEMORY;
+ break;
+ }
+
+ count++;
+
+ if (count >= n_requested)
+ {
+ hr = S_FALSE;
+ break;
+ }
+ }
+ } while (FindNextFileW(handle, &data));
+
+ FindClose(handle);
+
+ if (FAILED(hr))
+ {
+ free_list(list, count);
+ return hr;
+ }
+
+ *n_names = count;
+
+ if (count)
+ {
+ *names = list;
+ *start_index = index;
+ return hr;
+ }
+
+ heap_free(list);
+ *names = NULL;
+ return *start_index ? S_FALSE : S_OK;
}
HRESULT __cdecl SchRpcEnumTasks(const WCHAR *path, DWORD flags, DWORD *start_index, DWORD n_requested,
diff --git a/dlls/schedsvc/schedsvc_private.h b/dlls/schedsvc/schedsvc_private.h
index fd0225f..4138aa0 100644
--- a/dlls/schedsvc/schedsvc_private.h
+++ b/dlls/schedsvc/schedsvc_private.h
@@ -37,6 +37,12 @@ static inline void *heap_alloc(SIZE_T size)
return MIDL_user_allocate(size);
}
+static void *heap_realloc(void *ptr, SIZE_T size) __WINE_ALLOC_SIZE(2);
+static inline void *heap_realloc(void *ptr, SIZE_T size)
+{
+ return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
+}
+
static inline void heap_free(void *ptr)
{
MIDL_user_free(ptr);
--
1.9.1
More information about the wine-patches
mailing list