Module: wine Branch: master Commit: 3266b490f72ab231262ed2e37ebaf3e0d65ce1e0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3266b490f72ab231262ed2e37e...
Author: Dmitry Timoshkov dmitry@baikal.ru Date: Fri Mar 7 12:10:37 2014 +0900
schedsvc: Implement SchRpcCreateFolder.
---
dlls/schedsvc/schedsvc.c | 84 +++++++++++++++++++++++++++++++++++++- dlls/schedsvc/schedsvc_private.h | 53 ++++++++++++++++++++++++ loader/wine.inf.in | 1 + 3 files changed, 136 insertions(+), 2 deletions(-)
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