Module: wine Branch: master Commit: 18ccad835190731c0f9ed34d7358aba00e3c7d55 URL: http://source.winehq.org/git/wine.git/?a=commit;h=18ccad835190731c0f9ed34d73...
Author: Dmitry Timoshkov dmitry@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);