From aa6a737fbb5695ab4e787ad4ab41a26ed88c9639 Mon Sep 17 00:00:00 2001 From: Mike McDonald Date: Wed, 4 Mar 2015 16:56:48 -0500 Subject: [PATCH] Added the shell function GetUserProfileDirectory to WinPR. --- winpr/include/winpr/shell.h | 52 ++++++++++ winpr/libwinpr/CMakeLists.txt | 2 +- winpr/libwinpr/shell/CMakeLists.txt | 18 ++++ winpr/libwinpr/shell/ModuleOptions.cmake | 9 ++ winpr/libwinpr/shell/shell.c | 127 +++++++++++++++++++++++ 5 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 winpr/include/winpr/shell.h create mode 100644 winpr/libwinpr/shell/CMakeLists.txt create mode 100644 winpr/libwinpr/shell/ModuleOptions.cmake create mode 100644 winpr/libwinpr/shell/shell.c diff --git a/winpr/include/winpr/shell.h b/winpr/include/winpr/shell.h new file mode 100644 index 000000000..5093925f8 --- /dev/null +++ b/winpr/include/winpr/shell.h @@ -0,0 +1,52 @@ +/** + * WinPR: Windows Portable Runtime + * Shell Functions + * + * Copyright 2015 Dell Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_SHELL_H +#define WINPR_SHELL_H + +#include +#include +#include +#include +#include + +#ifndef _WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + +WINPR_API BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWORD lpcchSize); + +WINPR_API BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize); + +#ifdef __cplusplus +} +#endif + +#ifdef UNICODE +#define GetUserProfileDirectory GetUserProfileDirectoryW +#else +#define GetUserProfileDirectory GetUserProfileDirectoryA +#endif + +#endif + +#endif /* WINPR_SHELL_H */ + diff --git a/winpr/libwinpr/CMakeLists.txt b/winpr/libwinpr/CMakeLists.txt index 4056e8ede..5a802ba49 100644 --- a/winpr/libwinpr/CMakeLists.txt +++ b/winpr/libwinpr/CMakeLists.txt @@ -75,7 +75,7 @@ endmacro() # Level "1" API as defined for MinCore.lib set(WINPR_CORE synch locale library file comm pipe interlocked security - environment crypto registry credentials path io memory input + environment crypto registry credentials path io memory input shell heap utils error com timezone sysinfo pool handle thread) foreach(DIR ${WINPR_CORE}) diff --git a/winpr/libwinpr/shell/CMakeLists.txt b/winpr/libwinpr/shell/CMakeLists.txt new file mode 100644 index 000000000..41796701a --- /dev/null +++ b/winpr/libwinpr/shell/CMakeLists.txt @@ -0,0 +1,18 @@ +# WinPR: Windows Portable Runtime +# libwinpr-shell cmake build script +# +# Copyright 2015 Dell Software +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +winpr_module_add(shell.c) diff --git a/winpr/libwinpr/shell/ModuleOptions.cmake b/winpr/libwinpr/shell/ModuleOptions.cmake new file mode 100644 index 000000000..116680dd7 --- /dev/null +++ b/winpr/libwinpr/shell/ModuleOptions.cmake @@ -0,0 +1,9 @@ + +set(MINWIN_LAYER "0") +set(MINWIN_GROUP "none") +set(MINWIN_MAJOR_VERSION "0") +set(MINWIN_MINOR_VERSION "0") +set(MINWIN_SHORT_NAME "shell") +set(MINWIN_LONG_NAME "Shell Functions") +set(MODULE_LIBRARY_NAME "${MINWIN_SHORT_NAME}") + diff --git a/winpr/libwinpr/shell/shell.c b/winpr/libwinpr/shell/shell.c new file mode 100644 index 000000000..56168e87f --- /dev/null +++ b/winpr/libwinpr/shell/shell.c @@ -0,0 +1,127 @@ +/** + * WinPR: Windows Portable Runtime + * Shell Functions + * + * Copyright 2015 Dell Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +/** + * shell32.dll: + * + * GetUserProfileDirectoryA + * GetUserProfileDirectoryW + */ + +#ifndef _WIN32 + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +#include "../handle/handle.h" + +#include "../security/security.h" + +BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWORD lpcchSize) +{ + DWORD cchDirSize; + struct passwd* pw; + WINPR_ACCESS_TOKEN* token; + + token = (WINPR_ACCESS_TOKEN*) hToken; + + if ((token == NULL) || (token->Type != HANDLE_TYPE_ACCESS_TOKEN) || (lpcchSize == NULL)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + pw = getpwnam(token->Username); + if (pw == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + cchDirSize = strlen(pw->pw_dir) + 1; + + if ((lpProfileDir == NULL) || (*lpcchSize < cchDirSize)) + { + *lpcchSize = cchDirSize; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + ZeroMemory(lpProfileDir, *lpcchSize); + strcpy(lpProfileDir, pw->pw_dir); + *lpcchSize = cchDirSize; + + return TRUE; +} + +BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize) +{ + BOOL bStatus; + DWORD cchSizeA; + LPSTR lpProfileDirA; + + if (lpcchSize == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + cchSizeA = *lpcchSize; + lpProfileDirA = NULL; + + if (lpProfileDir) + { + lpProfileDirA = (LPSTR) malloc(cchSizeA); + if (lpProfileDirA == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + } + + bStatus = GetUserProfileDirectoryA(hToken, lpProfileDirA, &cchSizeA); + if (bStatus) + { + MultiByteToWideChar(CP_ACP, 0, lpProfileDirA, cchSizeA, lpProfileDir, *lpcchSize); + } + + if (lpProfileDirA) + { + free(lpProfileDirA); + } + + *lpcchSize = cchSizeA; + + return bStatus; +} + +#endif +