Module: wine Branch: master Commit: d6f6b6b798c51119f91a815b8720033ae3e99a01 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d6f6b6b798c51119f91a815b87...
Author: Dmitry Timoshkov dmitry@baikal.ru Date: Mon Jan 20 16:07:46 2014 +0900
taskschd: Implement ITaskFolder::CreateFolder.
---
dlls/taskschd/folder.c | 72 ++++++++++++++++++++++++++++++++------ dlls/taskschd/task.c | 2 +- dlls/taskschd/taskschd_private.h | 2 +- dlls/taskschd/tests/scheduler.c | 15 ++------ 4 files changed, 65 insertions(+), 26 deletions(-)
diff --git a/dlls/taskschd/folder.c b/dlls/taskschd/folder.c index 6871138..4eb7b8a 100644 --- a/dlls/taskschd/folder.c +++ b/dlls/taskschd/folder.c @@ -134,6 +134,30 @@ static HRESULT WINAPI TaskFolder_get_Name(ITaskFolder *iface, BSTR *name) return S_OK; }
+static HRESULT reg_create_folder(const WCHAR *path, HKEY *hfolder) +{ + HKEY hroot; + DWORD ret, disposition; + + ret = RegCreateKeyA(HKEY_LOCAL_MACHINE, root, &hroot); + if (ret) return HRESULT_FROM_WIN32(ret); + + while (*path == '\') path++; + ret = RegCreateKeyExW(hroot, path, 0, NULL, 0, KEY_ALL_ACCESS, NULL, hfolder, &disposition); + if (ret == ERROR_FILE_NOT_FOUND) + ret = ERROR_PATH_NOT_FOUND; + + if (ret == ERROR_SUCCESS && disposition == REG_OPENED_EXISTING_KEY) + { + RegCloseKey(*hfolder); + ret = ERROR_ALREADY_EXISTS; + } + + RegCloseKey(hroot); + + return HRESULT_FROM_WIN32(ret); +} + static HRESULT reg_open_folder(const WCHAR *path, HKEY *hfolder) { HKEY hroot; @@ -203,7 +227,7 @@ static HRESULT WINAPI TaskFolder_GetFolder(ITaskFolder *iface, BSTR path, ITaskF if (!path) return E_INVALIDARG; if (!new_folder) return E_POINTER;
- return TaskFolder_create(folder->path, path, new_folder); + return TaskFolder_create(folder->path, path, new_folder, FALSE); }
static HRESULT WINAPI TaskFolder_GetFolders(ITaskFolder *iface, LONG flags, ITaskFolderCollection **folders) @@ -212,10 +236,32 @@ static HRESULT WINAPI TaskFolder_GetFolders(ITaskFolder *iface, LONG flags, ITas return E_NOTIMPL; }
-static HRESULT WINAPI TaskFolder_CreateFolder(ITaskFolder *iface, BSTR name, VARIANT sddl, ITaskFolder **folder) +static inline BOOL is_variant_null(const VARIANT *var) { - FIXME("%p,%s,%s,%p: stub\n", iface, debugstr_w(name), debugstr_variant(&sddl), folder); - return E_NOTIMPL; + return V_VT(var) == VT_EMPTY || V_VT(var) == VT_NULL || + (V_VT(var) == VT_BSTR && (V_BSTR(var) == NULL || !*V_BSTR(var))); +} + +static HRESULT WINAPI TaskFolder_CreateFolder(ITaskFolder *iface, BSTR path, VARIANT sddl, ITaskFolder **new_folder) +{ + TaskFolder *folder = impl_from_ITaskFolder(iface); + ITaskFolder *tmp_folder = NULL; + HRESULT hr; + + TRACE("%p,%s,%s,%p\n", iface, debugstr_w(path), debugstr_variant(&sddl), folder); + + if (!path) return E_INVALIDARG; + + if (!new_folder) new_folder = &tmp_folder; + + if (!is_variant_null(&sddl)) + FIXME("security descriptor %s is ignored\n", debugstr_variant(&sddl)); + + hr = TaskFolder_create(folder->path, path, new_folder, TRUE); + if (tmp_folder) + ITaskFolder_Release(tmp_folder); + + return hr; }
static HRESULT WINAPI TaskFolder_DeleteFolder(ITaskFolder *iface, BSTR name, LONG flags) @@ -302,7 +348,7 @@ static const ITaskFolderVtbl TaskFolder_vtbl = TaskFolder_SetSecurityDescriptor };
-HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder **obj) +HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder **obj, BOOL create) { static const WCHAR bslash[] = { '\', 0 }; TaskFolder *folder; @@ -328,17 +374,21 @@ HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder ** if (parent) strcpyW(folder_path, parent);
- len = strlenW(folder_path); - if (!len || folder_path[len - 1] != '\') - strcatW(folder_path, bslash); - - if (path) + if (path && *path) { + len = strlenW(folder_path); + if (!len || folder_path[len - 1] != '\') + strcatW(folder_path, bslash); + while (*path == '\') path++; strcatW(folder_path, path); }
- hr = reg_open_folder(folder_path, &hfolder); + len = strlenW(folder_path); + if (!len) + strcatW(folder_path, bslash); + + hr = create ? reg_create_folder(folder_path, &hfolder) : reg_open_folder(folder_path, &hfolder); if (hr) { HeapFree(GetProcessHeap(), 0, folder_path); diff --git a/dlls/taskschd/task.c b/dlls/taskschd/task.c index 632cabb..a13a968 100644 --- a/dlls/taskschd/task.c +++ b/dlls/taskschd/task.c @@ -117,7 +117,7 @@ static HRESULT WINAPI TaskService_GetFolder(ITaskService *iface, BSTR path, ITas
if (!folder) return E_POINTER;
- return TaskFolder_create(path, NULL, folder); + return TaskFolder_create(path, NULL, folder, FALSE); }
static HRESULT WINAPI TaskService_GetRunningTasks(ITaskService *iface, LONG flags, IRunningTaskCollection **tasks) diff --git a/dlls/taskschd/taskschd_private.h b/dlls/taskschd/taskschd_private.h index deebc41..4ef348f 100644 --- a/dlls/taskschd/taskschd_private.h +++ b/dlls/taskschd/taskschd_private.h @@ -17,6 +17,6 @@ */
HRESULT TaskService_create(void **obj) DECLSPEC_HIDDEN; -HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder **obj) DECLSPEC_HIDDEN; +HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder **obj, BOOL create) DECLSPEC_HIDDEN;
const char *debugstr_variant(const VARIANT *v) DECLSPEC_HIDDEN; diff --git a/dlls/taskschd/tests/scheduler.c b/dlls/taskschd/tests/scheduler.c index a976de2..61e4a04 100644 --- a/dlls/taskschd/tests/scheduler.c +++ b/dlls/taskschd/tests/scheduler.c @@ -185,7 +185,6 @@ todo_wine SysFreeString(bstr);
hr = ITaskFolder_CreateFolder(folder, NULL, v_null, &subfolder); -todo_wine ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
/* Just in case something was left from previous runs */ @@ -205,20 +204,14 @@ todo_wine ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
hr = ITaskFolder_CreateFolder(folder, Wine_Folder1_Folder2, v_null, &subfolder); -todo_wine ok(hr == S_OK, "CreateFolder error %#x\n", hr); - if (hr != S_OK) - { - ITaskFolder_Release(folder); - ITaskService_Release(service); - return; - } ITaskFolder_Release(subfolder);
hr = ITaskFolder_CreateFolder(folder, Wine, v_null, NULL); ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
hr = ITaskFolder_CreateFolder(folder, Wine_Folder1_, v_null, &subfolder); +todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr);
hr = ITaskFolder_CreateFolder(folder, Wine, v_null, &subfolder); @@ -239,11 +232,6 @@ todo_wine
hr = ITaskService_GetFolder(service, Wine_Folder1_Folder2, &subfolder); ok(hr == S_OK, "GetFolder error %#x\n", hr); - if (hr != S_OK) - { - ITaskService_Release(service); - return; - }
hr = ITaskFolder_get_Name(subfolder, &bstr); ok (hr == S_OK, "get_Name error %#x\n", hr); @@ -303,6 +291,7 @@ todo_wine SysFreeString(bstr);
hr = ITaskFolder_GetFolder(subfolder, bslash, &subfolder2); +todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr);
hr = ITaskFolder_GetFolder(subfolder, NULL, &subfolder2);