[5/5] taskschd: Implement ITaskFolder::CreateFolder.

Dmitry Timoshkov dmitry at baikal.ru
Mon Jan 20 01:07:46 CST 2014


---
 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);
-- 
1.8.5.2




More information about the wine-patches mailing list