[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