[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