Dmitry Timoshkov : taskschd: Implement enumeration of task folders in registry.

Alexandre Julliard julliard at winehq.org
Tue Jan 28 13:33:24 CST 2014


Module: wine
Branch: master
Commit: 18ccad835190731c0f9ed34d7358aba00e3c7d55
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=18ccad835190731c0f9ed34d7358aba00e3c7d55

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Tue Jan 28 11:54:41 2014 +0900

taskschd: Implement enumeration of task folders in registry.

---

 dlls/taskschd/folder_collection.c |  115 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 114 insertions(+), 1 deletion(-)

diff --git a/dlls/taskschd/folder_collection.c b/dlls/taskschd/folder_collection.c
index 4448667..f1a3f3f 100644
--- a/dlls/taskschd/folder_collection.c
+++ b/dlls/taskschd/folder_collection.c
@@ -31,10 +31,15 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(taskschd);
 
+static const char root[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\TaskCache\\Tree";
+
 typedef struct
 {
     ITaskFolderCollection ITaskFolderCollection_iface;
     LONG ref;
+    WCHAR *path;
+    LPWSTR *list;
+    LONG count;
 } TaskFolderCollection;
 
 static inline TaskFolderCollection *impl_from_ITaskFolderCollection(ITaskFolderCollection *iface)
@@ -48,6 +53,16 @@ static ULONG WINAPI folders_AddRef(ITaskFolderCollection *iface)
     return InterlockedIncrement(&folders->ref);
 }
 
+static void free_list(LPWSTR *list, LONG count)
+{
+    LONG i;
+
+    for (i = 0; i < count; i++)
+        heap_free(list[i]);
+
+    heap_free(list);
+}
+
 static ULONG WINAPI folders_Release(ITaskFolderCollection *iface)
 {
     TaskFolderCollection *folders = impl_from_ITaskFolderCollection(iface);
@@ -56,6 +71,8 @@ static ULONG WINAPI folders_Release(ITaskFolderCollection *iface)
     if (!ref)
     {
         TRACE("destroying %p\n", iface);
+        free_list(folders->list, folders->count);
+        heap_free(folders->path);
         heap_free(folders);
     }
 
@@ -140,15 +157,111 @@ static const ITaskFolderCollectionVtbl TaskFolderCollection_vtbl =
     folders_get__NewEnum
 };
 
+static HRESULT reg_open_folder(const WCHAR *path, HKEY *hfolder)
+{
+    HKEY hroot;
+    DWORD ret;
+
+    ret = RegCreateKeyA(HKEY_LOCAL_MACHINE, root, &hroot);
+    if (ret) return HRESULT_FROM_WIN32(ret);
+
+    while (*path == '\\') path++;
+    ret = RegOpenKeyExW(hroot, path, 0, KEY_ALL_ACCESS, hfolder);
+    if (ret == ERROR_FILE_NOT_FOUND)
+        ret = ERROR_PATH_NOT_FOUND;
+
+    RegCloseKey(hroot);
+
+    return HRESULT_FROM_WIN32(ret);
+}
+
+static inline void reg_close_folder(HKEY hfolder)
+{
+    RegCloseKey(hfolder);
+}
+
+static HRESULT create_folders_list(const WCHAR *path, LPWSTR **folders_list, LONG *folders_count)
+{
+    HRESULT hr;
+    HKEY hfolder;
+    WCHAR name[MAX_PATH];
+    LONG ret, idx, allocated, count;
+    LPWSTR *list;
+
+    *folders_list = NULL;
+    *folders_count = 0;
+
+    hr = reg_open_folder(path, &hfolder);
+    if (hr) return hr;
+
+    allocated = 64;
+    list = heap_alloc(allocated * sizeof(LPWSTR));
+    if (!list)
+    {
+        reg_close_folder(hfolder);
+        return E_OUTOFMEMORY;
+    }
+
+    idx = count = 0;
+
+    while (!(ret = RegEnumKeyW(hfolder, idx++, name, MAX_PATH)))
+    {
+        /* FIXME: differentiate between folders and tasks */
+        if (count >= allocated)
+        {
+            LPWSTR *new_list;
+            allocated *= 2;
+            new_list = heap_realloc(list, allocated * sizeof(LPWSTR));
+            if (!new_list)
+            {
+                reg_close_folder(hfolder);
+                free_list(list, count);
+                return E_OUTOFMEMORY;
+            }
+            list = new_list;
+        }
+
+        list[count] = heap_strdupW(name);
+        if (!list[count])
+        {
+            reg_close_folder(hfolder);
+            free_list(list, count);
+            return E_OUTOFMEMORY;
+        }
+
+        count++;
+    }
+
+    reg_close_folder(hfolder);
+
+    *folders_list = list;
+    *folders_count = count;
+
+    return S_OK;
+}
+
 HRESULT TaskFolderCollection_create(const WCHAR *path, ITaskFolderCollection **obj)
 {
     TaskFolderCollection *folders;
+    HRESULT hr;
+    LPWSTR *list;
+    LONG count;
+
+    hr = create_folders_list(path, &list, &count);
+    if (hr) return hr;
 
     folders = heap_alloc(sizeof(*folders));
-    if (!folders) return E_OUTOFMEMORY;
+    if (!folders)
+    {
+        free_list(list, count);
+        return E_OUTOFMEMORY;
+    }
 
     folders->ITaskFolderCollection_iface.lpVtbl = &TaskFolderCollection_vtbl;
     folders->ref = 1;
+    folders->path = heap_strdupW(path);
+    folders->count = count;
+    folders->list = list;
     *obj = &folders->ITaskFolderCollection_iface;
 
     TRACE("created %p\n", *obj);




More information about the wine-cvs mailing list