From 1f717504cbfcd17b14ecf5752e622f2d4f5bad84 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 4 Apr 2014 15:15:24 +0900 Subject: [PATCH] schedsvc: Implement SchRpcEnumFolders. --- 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 5c7d359b31f..a1fa4e0b503 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 fd0225ff12a..4138aa061cf 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);