[2/5] schedsvc: Implement SchRpcCreateFolder.

Dmitry Timoshkov dmitry at baikal.ru
Wed Mar 5 03:07:38 CST 2014


---
 dlls/schedsvc/schedsvc.c         | 84 +++++++++++++++++++++++++++++++++++++++-
 dlls/schedsvc/schedsvc_private.h | 53 +++++++++++++++++++++++++
 loader/wine.inf.in               |  1 +
 3 files changed, 136 insertions(+), 2 deletions(-)
 create mode 100644 dlls/schedsvc/schedsvc_private.h

diff --git a/dlls/schedsvc/schedsvc.c b/dlls/schedsvc/schedsvc.c
index 400ab5d..def6367 100644
--- a/dlls/schedsvc/schedsvc.c
+++ b/dlls/schedsvc/schedsvc.c
@@ -24,6 +24,8 @@
 #include "schrpc.h"
 #include "wine/debug.h"
 
+#include "schedsvc_private.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);
 
 HRESULT __cdecl SchRpcHighestVersion(DWORD *version)
@@ -34,6 +36,72 @@ HRESULT __cdecl SchRpcHighestVersion(DWORD *version)
     return S_OK;
 }
 
+static WCHAR *get_full_name(const WCHAR *path, WCHAR **relative_path)
+{
+    static const WCHAR tasksW[] = { '\\','t','a','s','k','s','\\',0 };
+    WCHAR *target;
+    int len;
+
+    len = GetSystemDirectoryW(NULL, 0);
+    len += strlenW(tasksW) + strlenW(path);
+
+    target = heap_alloc(len * sizeof(WCHAR));
+    if (target)
+    {
+        GetSystemDirectoryW(target, len);
+        strcatW(target, tasksW);
+        if (relative_path)
+            *relative_path = target + strlenW(target) - 1;
+        while (*path == '\\') path++;
+        strcatW(target, path);
+    }
+    return target;
+}
+
+/*
+ * Recursively create all directories in the path.
+ */
+static HRESULT create_directory(const WCHAR *path)
+{
+    HRESULT hr = S_OK;
+    WCHAR *new_path;
+    int len;
+
+    new_path = heap_alloc((strlenW(path) + 1) * sizeof(WCHAR));
+    if (!new_path) return E_OUTOFMEMORY;
+
+    strcpyW(new_path, path);
+
+    len = strlenW(new_path);
+    while (len && new_path[len - 1] == '\\')
+    {
+        new_path[len - 1] = 0;
+        len--;
+    }
+
+    while (!CreateDirectoryW(new_path, NULL))
+    {
+        WCHAR *slash;
+        DWORD last_error = GetLastError();
+
+        if (last_error == ERROR_ALREADY_EXISTS || last_error != ERROR_PATH_NOT_FOUND ||
+            !(slash = strrchrW(new_path, '\\')))
+        {
+            hr = HRESULT_FROM_WIN32(last_error);
+            break;
+        }
+
+        len = slash - new_path;
+        new_path[len] = 0;
+        hr = create_directory(new_path);
+        if (hr != S_OK) break;
+        new_path[len] = '\\';
+    }
+
+    heap_free(new_path);
+    return hr;
+}
+
 HRESULT __cdecl SchRpcRegisterTask(const WCHAR *path, const WCHAR *xml, DWORD flags, const WCHAR *sddl,
                                    DWORD task_logon_type, DWORD n_creds, const TASK_USER_CRED *creds,
                                    WCHAR **actual_path, TASK_XML_ERROR_INFO **xml_error_info)
@@ -51,8 +119,20 @@ HRESULT __cdecl SchRpcRetrieveTask(const WCHAR *path, const WCHAR *languages, UL
 
 HRESULT __cdecl SchRpcCreateFolder(const WCHAR *path, const WCHAR *sddl, DWORD flags)
 {
-    WINE_FIXME("%s,%s,%#x: stub\n", wine_dbgstr_w(path), wine_dbgstr_w(sddl), flags);
-    return E_NOTIMPL;
+    WCHAR *full_name;
+    HRESULT hr;
+
+    WINE_TRACE("%s,%s,%#x\n", wine_dbgstr_w(path), wine_dbgstr_w(sddl), flags);
+
+    if (flags) return E_INVALIDARG;
+
+    full_name = get_full_name(path, NULL);
+    if (!full_name) return E_OUTOFMEMORY;
+
+    hr = create_directory(full_name);
+
+    heap_free(full_name);
+    return hr;
 }
 
 HRESULT __cdecl SchRpcSetSecurity(const WCHAR *path, const WCHAR *sddl, DWORD flags)
diff --git a/dlls/schedsvc/schedsvc_private.h b/dlls/schedsvc/schedsvc_private.h
new file mode 100644
index 0000000..082bda5
--- /dev/null
+++ b/dlls/schedsvc/schedsvc_private.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2014 Dmitry Timoshkov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_SCHEDSVC_PRIVATE_H__
+#define __WINE_SCHEDSVC_PRIVATE_H__
+
+#include "wine/unicode.h"
+
+static void *heap_alloc_zero(SIZE_T size) __WINE_ALLOC_SIZE(1);
+static inline void *heap_alloc_zero(SIZE_T size)
+{
+    void *ptr = MIDL_user_allocate(size);
+    if (ptr) memset(ptr, 0, size);
+    return ptr;
+}
+
+static void *heap_alloc(SIZE_T size) __WINE_ALLOC_SIZE(1);
+static inline void *heap_alloc(SIZE_T size)
+{
+    return MIDL_user_allocate(size);
+}
+
+static inline void heap_free(void *ptr)
+{
+    MIDL_user_free(ptr);
+}
+
+static inline WCHAR *heap_strdupW(const WCHAR *src)
+{
+    WCHAR *dst;
+    unsigned len;
+    if (!src) return NULL;
+    len = (strlenW(src) + 1) * sizeof(WCHAR);
+    if ((dst = heap_alloc(len))) memcpy(dst, src, len);
+    return dst;
+}
+
+#endif /* __WINE_SCHEDSVC_PRIVATE_H__ */
diff --git a/loader/wine.inf.in b/loader/wine.inf.in
index 5d2a629..578ca8c 100644
--- a/loader/wine.inf.in
+++ b/loader/wine.inf.in
@@ -2513,6 +2513,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G"
 10,logs,
 10,temp,
 11,mui,
+11,tasks,
 11,spool\drivers\color,
 11,spool\printers,
 10,,explorer.exe
-- 
1.8.5.5




More information about the wine-patches mailing list