diff options
Diffstat (limited to 'winpr/libwinpr/shell')
-rw-r--r-- | winpr/libwinpr/shell/CMakeLists.txt | 20 | ||||
-rw-r--r-- | winpr/libwinpr/shell/ModuleOptions.cmake | 9 | ||||
-rw-r--r-- | winpr/libwinpr/shell/shell.c | 145 |
3 files changed, 174 insertions, 0 deletions
diff --git a/winpr/libwinpr/shell/CMakeLists.txt b/winpr/libwinpr/shell/CMakeLists.txt new file mode 100644 index 0000000..24b47e3 --- /dev/null +++ b/winpr/libwinpr/shell/CMakeLists.txt @@ -0,0 +1,20 @@ +# WinPR: Windows Portable Runtime +# libwinpr-shell cmake build script +# +# Copyright 2015 Dell Software <Mike.McDonald@software.dell.com> +# +# 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. + +if (NOT ANDROID) + winpr_module_add(shell.c) +endif() diff --git a/winpr/libwinpr/shell/ModuleOptions.cmake b/winpr/libwinpr/shell/ModuleOptions.cmake new file mode 100644 index 0000000..116680d --- /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 0000000..244ab7a --- /dev/null +++ b/winpr/libwinpr/shell/shell.c @@ -0,0 +1,145 @@ +/** + * WinPR: Windows Portable Runtime + * Shell Functions + * + * Copyright 2015 Dell Software <Mike.McDonald@software.dell.com> + * + * 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. + */ + +#include <winpr/config.h> + +#include <winpr/shell.h> + +/** + * shell32.dll: + * + * GetUserProfileDirectoryA + * GetUserProfileDirectoryW + */ + +#ifndef _WIN32 + +#include <winpr/crt.h> + +#ifdef WINPR_HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <pwd.h> +#include <grp.h> + +#include "../handle/handle.h" + +#include "../security/security.h" + +BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWORD lpcchSize) +{ + char* buf = NULL; + int buflen = 0; + int status = 0; + DWORD cchDirSize = 0; + struct passwd pwd; + struct passwd* pw = NULL; + WINPR_ACCESS_TOKEN* token = NULL; + token = (WINPR_ACCESS_TOKEN*)hToken; + + if (!AccessTokenIsValid(hToken)) + return FALSE; + + if (!lpcchSize) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + + if (buflen == -1) + buflen = 8196; + + buf = (char*)malloc(buflen); + + if (!buf) + return FALSE; + + status = getpwnam_r(token->Username, &pwd, buf, buflen, &pw); + + if ((status != 0) || !pw) + { + SetLastError(ERROR_INVALID_PARAMETER); + free(buf); + return FALSE; + } + + cchDirSize = strlen(pw->pw_dir) + 1; + + if (!lpProfileDir || (*lpcchSize < cchDirSize)) + { + *lpcchSize = cchDirSize; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + free(buf); + return FALSE; + } + + ZeroMemory(lpProfileDir, *lpcchSize); + sprintf_s(lpProfileDir, *lpcchSize, "%s", pw->pw_dir); + *lpcchSize = cchDirSize; + free(buf); + return TRUE; +} + +BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize) +{ + BOOL bStatus = 0; + DWORD cchSizeA = 0; + LPSTR lpProfileDirA = NULL; + + if (!lpcchSize) + { + 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) + { + SSIZE_T size = ConvertUtf8NToWChar(lpProfileDirA, cchSizeA, lpProfileDir, *lpcchSize); + bStatus = size >= 0; + } + + if (lpProfileDirA) + { + free(lpProfileDirA); + } + + *lpcchSize = cchSizeA; + return bStatus; +} + +#endif |