[3/7] schedsvc: Implement SchRpcCreateFolder. Resend.
Dmitry Timoshkov
dmitry at baikal.ru
Thu Mar 6 21:10:37 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 7486cfd..d6e6994 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