Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
30
third_party/FreeRDP/winpr/libwinpr/path/CMakeLists.txt
vendored
Normal file
30
third_party/FreeRDP/winpr/libwinpr/path/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-path cmake build script
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.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.
|
||||
|
||||
winpr_module_add(path.c shell.c)
|
||||
|
||||
if(MSVC OR MINGW)
|
||||
winpr_library_add_public(shlwapi)
|
||||
endif()
|
||||
|
||||
if(IOS)
|
||||
winpr_module_add(shell_ios.m)
|
||||
endif(IOS)
|
||||
|
||||
if(BUILD_TESTING_INTERNAL OR BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
9
third_party/FreeRDP/winpr/libwinpr/path/ModuleOptions.cmake
vendored
Normal file
9
third_party/FreeRDP/winpr/libwinpr/path/ModuleOptions.cmake
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
set(MINWIN_LAYER "1")
|
||||
set(MINWIN_GROUP "core")
|
||||
set(MINWIN_MAJOR_VERSION "1")
|
||||
set(MINWIN_MINOR_VERSION "0")
|
||||
set(MINWIN_SHORT_NAME "path")
|
||||
set(MINWIN_LONG_NAME "Path Functions")
|
||||
set(MODULE_LIBRARY_NAME
|
||||
"api-ms-win-${MINWIN_GROUP}-${MINWIN_SHORT_NAME}-l${MINWIN_LAYER}-${MINWIN_MAJOR_VERSION}-${MINWIN_MINOR_VERSION}"
|
||||
)
|
||||
174
third_party/FreeRDP/winpr/libwinpr/path/include/PathAllocCombine.h
vendored
Normal file
174
third_party/FreeRDP/winpr/libwinpr/path/include/PathAllocCombine.h
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
|
||||
/*
|
||||
#define DEFINE_UNICODE FALSE
|
||||
#define CUR_PATH_SEPARATOR_CHR '\\'
|
||||
#define CUR_PATH_SEPARATOR_STR "\\"
|
||||
#define PATH_ALLOC_COMBINE PathAllocCombineA
|
||||
*/
|
||||
|
||||
/**
|
||||
* FIXME: These implementations of the PathAllocCombine functions have
|
||||
* several issues:
|
||||
* - pszPathIn or pszMore may be nullptr (but not both)
|
||||
* - no check if pszMore is fully qualified (if so, it must be directly
|
||||
* copied to the output buffer without being combined with pszPathIn.
|
||||
* - if pszMore begins with a _single_ backslash it must be combined with
|
||||
* only the root of the path pointed to by pszPathIn and there's no code
|
||||
* to extract the root of pszPathIn.
|
||||
* - the function will crash with some short string lengths of the parameters
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/string.h>
|
||||
#include <winpr/error.h>
|
||||
#include <winpr/wlog.h>
|
||||
|
||||
#if DEFINE_UNICODE
|
||||
|
||||
HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore,
|
||||
WINPR_ATTR_UNUSED unsigned long dwFlags, PWSTR* ppszPathOut)
|
||||
{
|
||||
WLog_WARN("TODO", "has known bugs and needs fixing.");
|
||||
|
||||
if (!ppszPathOut)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pszPathIn && !pszMore)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pszMore)
|
||||
return E_FAIL; /* valid but not implemented, see top comment */
|
||||
|
||||
if (!pszPathIn)
|
||||
return E_FAIL; /* valid but not implemented, see top comment */
|
||||
|
||||
const size_t pszPathInLength = _wcslen(pszPathIn);
|
||||
const size_t pszMoreLength = _wcslen(pszMore);
|
||||
|
||||
/* prevent segfaults - the complete implementation below is buggy */
|
||||
if (pszPathInLength < 3)
|
||||
return E_FAIL;
|
||||
|
||||
const BOOL backslashIn =
|
||||
(pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
|
||||
const BOOL backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
|
||||
|
||||
if (backslashMore)
|
||||
{
|
||||
if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
|
||||
{
|
||||
const WCHAR colon[] = { ':', '\0' };
|
||||
const size_t pszPathOutLength = sizeof(WCHAR) + pszMoreLength;
|
||||
const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
|
||||
PWSTR pszPathOut = (PWSTR)calloc(sizeOfBuffer, sizeof(WCHAR));
|
||||
|
||||
if (!pszPathOut)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
_wcsncat(pszPathOut, &pszPathIn[0], 1);
|
||||
_wcsncat(pszPathOut, colon, ARRAYSIZE(colon));
|
||||
_wcsncat(pszPathOut, pszMore, pszMoreLength);
|
||||
*ppszPathOut = pszPathOut;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t pszPathOutLength = pszPathInLength + pszMoreLength;
|
||||
const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
|
||||
PWSTR pszPathOut = (PWSTR)calloc(sizeOfBuffer, 2);
|
||||
|
||||
if (!pszPathOut)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
_wcsncat(pszPathOut, pszPathIn, pszPathInLength);
|
||||
if (!backslashIn)
|
||||
_wcsncat(pszPathOut, CUR_PATH_SEPARATOR_STR, ARRAYSIZE(CUR_PATH_SEPARATOR_STR));
|
||||
_wcsncat(pszPathOut, pszMore, pszMoreLength);
|
||||
|
||||
*ppszPathOut = pszPathOut;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, WINPR_ATTR_UNUSED unsigned long dwFlags,
|
||||
PSTR* ppszPathOut)
|
||||
{
|
||||
WLog_WARN("TODO", "has known bugs and needs fixing.");
|
||||
|
||||
if (!ppszPathOut)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pszPathIn && !pszMore)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pszMore)
|
||||
return E_FAIL; /* valid but not implemented, see top comment */
|
||||
|
||||
if (!pszPathIn)
|
||||
return E_FAIL; /* valid but not implemented, see top comment */
|
||||
|
||||
const size_t pszPathInLength = strlen(pszPathIn);
|
||||
const size_t pszMoreLength = strlen(pszMore);
|
||||
|
||||
/* prevent segfaults - the complete implementation below is buggy */
|
||||
if (pszPathInLength < 3)
|
||||
return E_FAIL;
|
||||
|
||||
const BOOL backslashIn =
|
||||
(pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
|
||||
const BOOL backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
|
||||
|
||||
if (backslashMore)
|
||||
{
|
||||
if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
|
||||
{
|
||||
const size_t pszPathOutLength = 2 + pszMoreLength;
|
||||
const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
|
||||
PSTR pszPathOut = calloc(sizeOfBuffer, 2);
|
||||
|
||||
if (!pszPathOut)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
(void)sprintf_s(pszPathOut, sizeOfBuffer, "%c:%s", pszPathIn[0], pszMore);
|
||||
*ppszPathOut = pszPathOut;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t pszPathOutLength = pszPathInLength + pszMoreLength;
|
||||
const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
|
||||
PSTR pszPathOut = calloc(sizeOfBuffer, 2);
|
||||
|
||||
if (!pszPathOut)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (backslashIn)
|
||||
(void)sprintf_s(pszPathOut, sizeOfBuffer, "%s%s", pszPathIn, pszMore);
|
||||
else
|
||||
(void)sprintf_s(pszPathOut, sizeOfBuffer, "%s%s%s", pszPathIn, CUR_PATH_SEPARATOR_STR,
|
||||
pszMore);
|
||||
|
||||
*ppszPathOut = pszPathOut;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
#undef DEFINE_UNICODE
|
||||
#undef CUR_PATH_SEPARATOR_CHR
|
||||
#undef CUR_PATH_SEPARATOR_STR
|
||||
#undef PATH_ALLOC_COMBINE
|
||||
*/
|
||||
101
third_party/FreeRDP/winpr/libwinpr/path/include/PathCchAddExtension.h
vendored
Normal file
101
third_party/FreeRDP/winpr/libwinpr/path/include/PathCchAddExtension.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
/*
|
||||
#define DEFINE_UNICODE FALSE
|
||||
#define CUR_PATH_SEPARATOR_CHR '\\'
|
||||
#define PATH_CCH_ADD_EXTENSION PathCchAddExtensionA
|
||||
*/
|
||||
|
||||
#if DEFINE_UNICODE
|
||||
|
||||
HRESULT PATH_CCH_ADD_EXTENSION(PWSTR pszPath, size_t cchPath, PCWSTR pszExt)
|
||||
{
|
||||
LPWSTR pDot;
|
||||
BOOL bExtDot;
|
||||
LPWSTR pBackslash;
|
||||
size_t pszExtLength;
|
||||
size_t pszPathLength;
|
||||
|
||||
if (!pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pszExt)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pszExtLength = _wcslen(pszExt);
|
||||
pszPathLength = _wcslen(pszPath);
|
||||
bExtDot = (pszExt[0] == '.') ? TRUE : FALSE;
|
||||
|
||||
pDot = _wcsrchr(pszPath, '.');
|
||||
pBackslash = _wcsrchr(pszPath, CUR_PATH_SEPARATOR_CHR);
|
||||
|
||||
if (pDot && pBackslash)
|
||||
{
|
||||
if (pDot > pBackslash)
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if (cchPath > pszPathLength + pszExtLength + ((bExtDot) ? 0 : 1))
|
||||
{
|
||||
const WCHAR dot[] = { '.', '\0' };
|
||||
WCHAR* ptr = &pszPath[pszPathLength];
|
||||
*ptr = '\0';
|
||||
|
||||
if (!bExtDot)
|
||||
_wcsncat(ptr, dot, _wcslen(dot));
|
||||
_wcsncat(ptr, pszExt, pszExtLength);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
HRESULT PATH_CCH_ADD_EXTENSION(PSTR pszPath, size_t cchPath, PCSTR pszExt)
|
||||
{
|
||||
CHAR* pDot;
|
||||
BOOL bExtDot;
|
||||
CHAR* pBackslash;
|
||||
size_t pszExtLength;
|
||||
size_t pszPathLength;
|
||||
|
||||
if (!pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pszExt)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pszExtLength = strlen(pszExt);
|
||||
pszPathLength = strlen(pszPath);
|
||||
bExtDot = (pszExt[0] == '.') ? TRUE : FALSE;
|
||||
|
||||
pDot = strrchr(pszPath, '.');
|
||||
pBackslash = strrchr(pszPath, CUR_PATH_SEPARATOR_CHR);
|
||||
|
||||
if (pDot && pBackslash)
|
||||
{
|
||||
if (pDot > pBackslash)
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if (cchPath > pszPathLength + pszExtLength + ((bExtDot) ? 0 : 1))
|
||||
{
|
||||
if (bExtDot)
|
||||
sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, "%s", pszExt);
|
||||
else
|
||||
sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, ".%s", pszExt);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
#undef DEFINE_UNICODE
|
||||
#undef CUR_PATH_SEPARATOR_CHR
|
||||
#undef PATH_CCH_ADD_EXTENSION
|
||||
*/
|
||||
64
third_party/FreeRDP/winpr/libwinpr/path/include/PathCchAddSeparator.h
vendored
Normal file
64
third_party/FreeRDP/winpr/libwinpr/path/include/PathCchAddSeparator.h
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
/*
|
||||
#define DEFINE_UNICODE FALSE
|
||||
#define CUR_PATH_SEPARATOR_CHR '\\'
|
||||
#define PATH_CCH_ADD_SEPARATOR PathCchAddBackslashA
|
||||
*/
|
||||
|
||||
#if DEFINE_UNICODE
|
||||
|
||||
HRESULT PATH_CCH_ADD_SEPARATOR(PWSTR pszPath, size_t cchPath)
|
||||
{
|
||||
size_t pszPathLength;
|
||||
|
||||
if (!pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pszPathLength = _wcslen(pszPath);
|
||||
|
||||
if (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR)
|
||||
return S_FALSE;
|
||||
|
||||
if (cchPath > (pszPathLength + 1))
|
||||
{
|
||||
pszPath[pszPathLength] = CUR_PATH_SEPARATOR_CHR;
|
||||
pszPath[pszPathLength + 1] = '\0';
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
HRESULT PATH_CCH_ADD_SEPARATOR(PSTR pszPath, size_t cchPath)
|
||||
{
|
||||
size_t pszPathLength;
|
||||
|
||||
if (!pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pszPathLength = strlen(pszPath);
|
||||
|
||||
if (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR)
|
||||
return S_FALSE;
|
||||
|
||||
if (cchPath > (pszPathLength + 1))
|
||||
{
|
||||
pszPath[pszPathLength] = CUR_PATH_SEPARATOR_CHR;
|
||||
pszPath[pszPathLength + 1] = '\0';
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
#undef DEFINE_UNICODE
|
||||
#undef CUR_PATH_SEPARATOR_CHR
|
||||
#undef PATH_CCH_ADD_SEPARATOR
|
||||
*/
|
||||
69
third_party/FreeRDP/winpr/libwinpr/path/include/PathCchAddSeparatorEx.h
vendored
Normal file
69
third_party/FreeRDP/winpr/libwinpr/path/include/PathCchAddSeparatorEx.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
/*
|
||||
#define DEFINE_UNICODE FALSE
|
||||
#define CUR_PATH_SEPARATOR_CHR '\\'
|
||||
#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddBackslashExA
|
||||
*/
|
||||
|
||||
#if DEFINE_UNICODE
|
||||
|
||||
HRESULT PATH_CCH_ADD_SEPARATOR_EX(PWSTR pszPath, size_t cchPath, WINPR_ATTR_UNUSED PWSTR* ppszEnd,
|
||||
WINPR_ATTR_UNUSED size_t* pcchRemaining)
|
||||
{
|
||||
size_t pszPathLength;
|
||||
|
||||
if (!pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pszPathLength = _wcslen(pszPath);
|
||||
|
||||
if (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR)
|
||||
return S_FALSE;
|
||||
|
||||
if (cchPath > (pszPathLength + 1))
|
||||
{
|
||||
pszPath[pszPathLength] = CUR_PATH_SEPARATOR_CHR;
|
||||
pszPath[pszPathLength + 1] = '\0';
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
HRESULT PATH_CCH_ADD_SEPARATOR_EX(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED size_t cchPath,
|
||||
WINPR_ATTR_UNUSED PSTR* ppszEnd,
|
||||
WINPR_ATTR_UNUSED size_t* pcchRemaining)
|
||||
{
|
||||
size_t pszPathLength;
|
||||
|
||||
if (!pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pszPathLength = strlen(pszPath);
|
||||
|
||||
if (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR)
|
||||
return S_FALSE;
|
||||
|
||||
if (cchPath > (pszPathLength + 1))
|
||||
{
|
||||
pszPath[pszPathLength] = CUR_PATH_SEPARATOR_CHR;
|
||||
pszPath[pszPathLength + 1] = '\0';
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
#undef DEFINE_UNICODE
|
||||
#undef CUR_PATH_SEPARATOR_CHR
|
||||
#undef PATH_CCH_ADD_SEPARATOR_EX
|
||||
*/
|
||||
136
third_party/FreeRDP/winpr/libwinpr/path/include/PathCchAppend.h
vendored
Normal file
136
third_party/FreeRDP/winpr/libwinpr/path/include/PathCchAppend.h
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
/*
|
||||
#define DEFINE_UNICODE FALSE
|
||||
#define CUR_PATH_SEPARATOR_CHR '\\'
|
||||
#define CUR_PATH_SEPARATOR_STR "\\"
|
||||
#define PATH_CCH_APPEND PathCchAppendA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/error.h>
|
||||
#include <winpr/path.h>
|
||||
|
||||
#if defined(DEFINE_UNICODE) && (DEFINE_UNICODE != 0)
|
||||
|
||||
HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore)
|
||||
{
|
||||
if (!pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pszMore)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if ((cchPath == 0) || (cchPath > PATHCCH_MAX_CCH))
|
||||
return E_INVALIDARG;
|
||||
|
||||
const size_t pszMoreLength = _wcsnlen(pszMore, cchPath);
|
||||
const size_t pszPathLength = _wcsnlen(pszPath, cchPath);
|
||||
|
||||
BOOL pathBackslash = FALSE;
|
||||
if (pszPathLength > 0)
|
||||
pathBackslash = (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
|
||||
|
||||
const BOOL moreBackslash = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
|
||||
|
||||
if (pathBackslash && moreBackslash)
|
||||
{
|
||||
if (pszMoreLength < 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if ((pszPathLength + pszMoreLength - 1) < cchPath)
|
||||
{
|
||||
WCHAR* ptr = &pszPath[pszPathLength];
|
||||
*ptr = '\0';
|
||||
_wcsncat(ptr, &pszMore[1], pszMoreLength - 1);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else if ((pathBackslash && !moreBackslash) || (!pathBackslash && moreBackslash))
|
||||
{
|
||||
if ((pszPathLength + pszMoreLength) < cchPath)
|
||||
{
|
||||
WCHAR* ptr = &pszPath[pszPathLength];
|
||||
*ptr = '\0';
|
||||
_wcsncat(ptr, pszMore, pszMoreLength);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else if (!pathBackslash && !moreBackslash)
|
||||
{
|
||||
if ((pszPathLength + pszMoreLength + 1) < cchPath)
|
||||
{
|
||||
WCHAR* ptr = &pszPath[pszPathLength];
|
||||
*ptr = '\0';
|
||||
_wcsncat(ptr, CUR_PATH_SEPARATOR_STR,
|
||||
_wcsnlen(CUR_PATH_SEPARATOR_STR, ARRAYSIZE(CUR_PATH_SEPARATOR_STR)));
|
||||
_wcsncat(ptr, pszMore, pszMoreLength);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
HRESULT PATH_CCH_APPEND(PSTR pszPath, size_t cchPath, PCSTR pszMore)
|
||||
{
|
||||
BOOL pathBackslash = FALSE;
|
||||
BOOL moreBackslash = FALSE;
|
||||
|
||||
if (!pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pszMore)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if ((cchPath == 0) || (cchPath > PATHCCH_MAX_CCH))
|
||||
return E_INVALIDARG;
|
||||
|
||||
const size_t pszPathLength = strnlen(pszPath, cchPath);
|
||||
if (pszPathLength > 0)
|
||||
pathBackslash = (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
|
||||
|
||||
const size_t pszMoreLength = strnlen(pszMore, cchPath);
|
||||
if (pszMoreLength > 0)
|
||||
moreBackslash = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
|
||||
|
||||
if (pathBackslash && moreBackslash)
|
||||
{
|
||||
if ((pszPathLength + pszMoreLength - 1) < cchPath)
|
||||
{
|
||||
sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, "%s", &pszMore[1]);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else if ((pathBackslash && !moreBackslash) || (!pathBackslash && moreBackslash))
|
||||
{
|
||||
if ((pszPathLength + pszMoreLength) < cchPath)
|
||||
{
|
||||
sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, "%s", pszMore);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else if (!pathBackslash && !moreBackslash)
|
||||
{
|
||||
if ((pszPathLength + pszMoreLength + 1) < cchPath)
|
||||
{
|
||||
sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, "%s%s",
|
||||
CUR_PATH_SEPARATOR_STR, pszMore);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
#undef DEFINE_UNICODE
|
||||
#undef CUR_PATH_SEPARATOR_CHR
|
||||
#undef CUR_PATH_SEPARATOR_STR
|
||||
#undef PATH_CCH_APPEND
|
||||
*/
|
||||
1258
third_party/FreeRDP/winpr/libwinpr/path/path.c
vendored
Normal file
1258
third_party/FreeRDP/winpr/libwinpr/path/path.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
905
third_party/FreeRDP/winpr/libwinpr/path/shell.c
vendored
Normal file
905
third_party/FreeRDP/winpr/libwinpr/path/shell.c
vendored
Normal file
@@ -0,0 +1,905 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Path Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.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/build-config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/platform.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/environment.h>
|
||||
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/wlog.h>
|
||||
|
||||
#include "../file/file.h"
|
||||
|
||||
#include "../log.h"
|
||||
#define TAG WINPR_TAG("path.shell")
|
||||
|
||||
#if defined(__IOS__)
|
||||
#include "shell_ios.h"
|
||||
#endif
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
static char* GetPath_XDG_CONFIG_HOME(void);
|
||||
static char* GetPath_XDG_RUNTIME_DIR(void);
|
||||
|
||||
/**
|
||||
* SHGetKnownFolderPath function:
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188/
|
||||
*/
|
||||
|
||||
#if defined(WIN32) && !defined(_UWP)
|
||||
|
||||
static char* win_get_known_folder(REFKNOWNFOLDERID id, BOOL currentUser)
|
||||
{
|
||||
WCHAR* wpath = nullptr;
|
||||
HANDLE handle = currentUser ? nullptr : (HANDLE)-1;
|
||||
if (FAILED(SHGetKnownFolderPath(id, 0, handle, &wpath)))
|
||||
return nullptr;
|
||||
|
||||
if (!wpath)
|
||||
return nullptr;
|
||||
|
||||
char* path = ConvertWCharToUtf8Alloc(wpath, nullptr);
|
||||
CoTaskMemFree(wpath);
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* XDG Base Directory Specification:
|
||||
* http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
*/
|
||||
|
||||
char* GetEnvAlloc(LPCSTR lpName)
|
||||
{
|
||||
DWORD nSize = 0;
|
||||
DWORD nStatus = 0;
|
||||
char* env = nullptr;
|
||||
|
||||
nSize = GetEnvironmentVariableX(lpName, nullptr, 0);
|
||||
|
||||
if (nSize > 0)
|
||||
{
|
||||
env = malloc(nSize);
|
||||
|
||||
if (!env)
|
||||
return nullptr;
|
||||
|
||||
nStatus = GetEnvironmentVariableX(lpName, env, nSize);
|
||||
|
||||
if (nStatus != (nSize - 1))
|
||||
{
|
||||
free(env);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
static char* GetPath_HOME(void)
|
||||
{
|
||||
char* path = nullptr;
|
||||
#ifdef _WIN32
|
||||
path = GetEnvAlloc("UserProfile");
|
||||
#elif defined(__IOS__)
|
||||
path = ios_get_home();
|
||||
#else
|
||||
path = GetEnvAlloc("HOME");
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
static char* GetPath_TEMP(void)
|
||||
{
|
||||
char* path = nullptr;
|
||||
#ifdef _WIN32
|
||||
path = GetEnvAlloc("TEMP");
|
||||
#elif defined(__IOS__)
|
||||
path = ios_get_temp();
|
||||
#else
|
||||
path = GetEnvAlloc("TMPDIR");
|
||||
|
||||
if (!path)
|
||||
path = _strdup("/tmp");
|
||||
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
static char* GetPath_XDG_DATA_HOME(void)
|
||||
{
|
||||
char* path = nullptr;
|
||||
#if defined(WIN32) || defined(__IOS__)
|
||||
path = GetPath_XDG_CONFIG_HOME();
|
||||
#else
|
||||
size_t size = 0;
|
||||
char* home = nullptr;
|
||||
/**
|
||||
* There is a single base directory relative to which user-specific data files should be
|
||||
* written. This directory is defined by the environment variable $XDG_DATA_HOME.
|
||||
*
|
||||
* $XDG_DATA_HOME defines the base directory relative to which user specific data files should
|
||||
* be stored. If $XDG_DATA_HOME is either not set or empty, a default equal to
|
||||
* $HOME/.local/share should be used.
|
||||
*/
|
||||
path = GetEnvAlloc("XDG_DATA_HOME");
|
||||
|
||||
if (path)
|
||||
return path;
|
||||
|
||||
home = GetPath_HOME();
|
||||
|
||||
if (!home)
|
||||
return nullptr;
|
||||
|
||||
size = strlen(home) + strlen("/.local/share") + 1;
|
||||
path = (char*)malloc(size);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
free(home);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
(void)sprintf_s(path, size, "%s%s", home, "/.local/share");
|
||||
free(home);
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
static char* GetPath_XDG_CONFIG_HOME(void)
|
||||
{
|
||||
char* path = nullptr;
|
||||
#if defined(WIN32) && !defined(_UWP)
|
||||
|
||||
path = win_get_known_folder(&FOLDERID_RoamingAppData, TRUE);
|
||||
|
||||
#elif defined(__IOS__)
|
||||
path = ios_get_data();
|
||||
#else
|
||||
size_t size = 0;
|
||||
char* home = nullptr;
|
||||
/**
|
||||
* There is a single base directory relative to which user-specific configuration files should
|
||||
* be written. This directory is defined by the environment variable $XDG_CONFIG_HOME.
|
||||
*
|
||||
* $XDG_CONFIG_HOME defines the base directory relative to which user specific configuration
|
||||
* files should be stored. If $XDG_CONFIG_HOME is either not set or empty, a default equal to
|
||||
* $HOME/.config should be used.
|
||||
*/
|
||||
path = GetEnvAlloc("XDG_CONFIG_HOME");
|
||||
|
||||
if (path)
|
||||
return path;
|
||||
|
||||
home = GetPath_HOME();
|
||||
|
||||
if (!home)
|
||||
home = GetPath_TEMP();
|
||||
|
||||
if (!home)
|
||||
return nullptr;
|
||||
|
||||
size = strlen(home) + strlen("/.config") + 1;
|
||||
path = (char*)malloc(size);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
free(home);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
(void)sprintf_s(path, size, "%s%s", home, "/.config");
|
||||
free(home);
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
static char* GetPath_SYSTEM_CONFIG_HOME(void)
|
||||
{
|
||||
char* path = nullptr;
|
||||
#if defined(WIN32) && !defined(_UWP)
|
||||
|
||||
path = win_get_known_folder(&FOLDERID_ProgramData, FALSE);
|
||||
|
||||
#elif defined(__IOS__)
|
||||
path = ios_get_data();
|
||||
#else
|
||||
path = _strdup(WINPR_INSTALL_SYSCONFDIR);
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
static char* GetPath_XDG_CACHE_HOME(void)
|
||||
{
|
||||
char* path = nullptr;
|
||||
#if defined(WIN32)
|
||||
{
|
||||
char* home = GetPath_XDG_RUNTIME_DIR();
|
||||
|
||||
if (home)
|
||||
{
|
||||
path = GetCombinedPath(home, "cache");
|
||||
|
||||
if (!winpr_PathFileExists(path))
|
||||
if (!winpr_PathMakePath(path, nullptr))
|
||||
path = nullptr;
|
||||
}
|
||||
|
||||
free(home);
|
||||
}
|
||||
#elif defined(__IOS__)
|
||||
path = ios_get_cache();
|
||||
#else
|
||||
size_t size = 0;
|
||||
/**
|
||||
* There is a single base directory relative to which user-specific non-essential (cached) data
|
||||
* should be written. This directory is defined by the environment variable $XDG_CACHE_HOME.
|
||||
*
|
||||
* $XDG_CACHE_HOME defines the base directory relative to which user specific non-essential data
|
||||
* files should be stored. If $XDG_CACHE_HOME is either not set or empty, a default equal to
|
||||
* $HOME/.cache should be used.
|
||||
*/
|
||||
path = GetEnvAlloc("XDG_CACHE_HOME");
|
||||
|
||||
if (path)
|
||||
return path;
|
||||
|
||||
char* home = GetPath_HOME();
|
||||
|
||||
if (!home)
|
||||
return nullptr;
|
||||
|
||||
size = strlen(home) + strlen("/.cache") + 1;
|
||||
path = (char*)malloc(size);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
free(home);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
(void)sprintf_s(path, size, "%s%s", home, "/.cache");
|
||||
free(home);
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
char* GetPath_XDG_RUNTIME_DIR(void)
|
||||
{
|
||||
char* path = nullptr;
|
||||
#if defined(WIN32) && !defined(_UWP)
|
||||
|
||||
path = win_get_known_folder(&FOLDERID_LocalAppData, TRUE);
|
||||
|
||||
#else
|
||||
/**
|
||||
* There is a single base directory relative to which user-specific runtime files and other file
|
||||
* objects should be placed. This directory is defined by the environment variable
|
||||
* $XDG_RUNTIME_DIR.
|
||||
*
|
||||
* $XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential
|
||||
* runtime files and other file objects (such as sockets, named pipes, ...) should be stored.
|
||||
* The directory MUST be owned by the user, and he MUST be the only one having read and write
|
||||
* access to it. Its Unix access mode MUST be 0700.
|
||||
*
|
||||
* The lifetime of the directory MUST be bound to the user being logged in. It MUST be created
|
||||
* when the user first logs in and if the user fully logs out the directory MUST be removed. If
|
||||
* the user logs in more than once he should get pointed to the same directory, and it is
|
||||
* mandatory that the directory continues to exist from his first login to his last logout on
|
||||
* the system, and not removed in between. Files in the directory MUST not survive reboot or a
|
||||
* full logout/login cycle.
|
||||
*
|
||||
* The directory MUST be on a local file system and not shared with any other system. The
|
||||
* directory MUST by fully-featured by the standards of the operating system. More specifically,
|
||||
* on Unix-like operating systems AF_UNIX sockets, symbolic links, hard links, proper
|
||||
* permissions, file locking, sparse files, memory mapping, file change notifications, a
|
||||
* reliable hard link count must be supported, and no restrictions on the file name character
|
||||
* set should be imposed. Files in this directory MAY be subjected to periodic clean-up. To
|
||||
* ensure that your files are not removed, they should have their access time timestamp modified
|
||||
* at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.
|
||||
*
|
||||
* If $XDG_RUNTIME_DIR is not set applications should fall back to a replacement directory with
|
||||
* similar capabilities and print a warning message. Applications should use this directory for
|
||||
* communication and synchronization purposes and should not place larger files in it, since it
|
||||
* might reside in runtime memory and cannot necessarily be swapped out to disk.
|
||||
*/
|
||||
path = GetEnvAlloc("XDG_RUNTIME_DIR");
|
||||
#endif
|
||||
|
||||
if (path)
|
||||
return path;
|
||||
|
||||
path = GetPath_TEMP();
|
||||
return path;
|
||||
}
|
||||
|
||||
char* GetKnownPath(eKnownPathTypes id)
|
||||
{
|
||||
char* path = nullptr;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case KNOWN_PATH_HOME:
|
||||
path = GetPath_HOME();
|
||||
break;
|
||||
|
||||
case KNOWN_PATH_TEMP:
|
||||
path = GetPath_TEMP();
|
||||
break;
|
||||
|
||||
case KNOWN_PATH_XDG_DATA_HOME:
|
||||
path = GetPath_XDG_DATA_HOME();
|
||||
break;
|
||||
|
||||
case KNOWN_PATH_XDG_CONFIG_HOME:
|
||||
path = GetPath_XDG_CONFIG_HOME();
|
||||
break;
|
||||
|
||||
case KNOWN_PATH_XDG_CACHE_HOME:
|
||||
path = GetPath_XDG_CACHE_HOME();
|
||||
break;
|
||||
|
||||
case KNOWN_PATH_XDG_RUNTIME_DIR:
|
||||
path = GetPath_XDG_RUNTIME_DIR();
|
||||
break;
|
||||
|
||||
case KNOWN_PATH_SYSTEM_CONFIG_HOME:
|
||||
path = GetPath_SYSTEM_CONFIG_HOME();
|
||||
break;
|
||||
|
||||
default:
|
||||
path = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!path)
|
||||
WLog_WARN(TAG, "Path %s is nullptr",
|
||||
GetKnownPathIdString(WINPR_ASSERTING_INT_CAST(int, id)));
|
||||
return path;
|
||||
}
|
||||
|
||||
char* GetKnownSubPath(eKnownPathTypes id, const char* path)
|
||||
{
|
||||
if (!path)
|
||||
return GetKnownSubPathV(id, "%s", "");
|
||||
return GetKnownSubPathV(id, "%s", path);
|
||||
}
|
||||
|
||||
char* GetKnownSubPathV(eKnownPathTypes id, const char* path, ...)
|
||||
{
|
||||
va_list ap = WINPR_C_ARRAY_INIT;
|
||||
|
||||
va_start(ap, path);
|
||||
char* str = GetKnownSubPathVA(id, path, ap);
|
||||
va_end(ap);
|
||||
return str;
|
||||
}
|
||||
|
||||
char* GetKnownSubPathVA(eKnownPathTypes id, const char* path, va_list ap)
|
||||
{
|
||||
char* knownPath = GetKnownPath(id);
|
||||
if (!knownPath)
|
||||
return nullptr;
|
||||
|
||||
char* subPath = GetCombinedPathVA(knownPath, path, ap);
|
||||
free(knownPath);
|
||||
return subPath;
|
||||
}
|
||||
|
||||
char* GetEnvironmentPath(char* name)
|
||||
{
|
||||
char* env = nullptr;
|
||||
DWORD nSize = 0;
|
||||
DWORD nStatus = 0;
|
||||
nSize = GetEnvironmentVariableX(name, nullptr, 0);
|
||||
|
||||
if (nSize)
|
||||
{
|
||||
env = (LPSTR)malloc(nSize);
|
||||
|
||||
if (!env)
|
||||
return nullptr;
|
||||
|
||||
nStatus = GetEnvironmentVariableX(name, env, nSize);
|
||||
|
||||
if (nStatus != (nSize - 1))
|
||||
{
|
||||
free(env);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
char* GetEnvironmentSubPath(char* name, const char* path)
|
||||
{
|
||||
if (!path)
|
||||
return GetEnvironmentSubPathV(name, "%s", "");
|
||||
return GetEnvironmentSubPathV(name, "%s", path);
|
||||
}
|
||||
|
||||
char* GetEnvironmentSubPathV(char* name, const char* path, ...)
|
||||
{
|
||||
va_list ap = WINPR_C_ARRAY_INIT;
|
||||
va_start(ap, path);
|
||||
char* str = GetEnvironmentSubPathVA(name, path, ap);
|
||||
va_end(ap);
|
||||
return str;
|
||||
}
|
||||
|
||||
char* GetEnvironmentSubPathVA(char* name, WINPR_FORMAT_ARG const char* path, va_list ap)
|
||||
{
|
||||
char* env = GetEnvironmentPath(name);
|
||||
|
||||
if (!env)
|
||||
return nullptr;
|
||||
|
||||
char* subpath = GetCombinedPathVA(env, path, ap);
|
||||
free(env);
|
||||
return subpath;
|
||||
}
|
||||
|
||||
char* GetCombinedPath(const char* basePath, const char* subPathFmt)
|
||||
{
|
||||
if (!subPathFmt)
|
||||
return GetCombinedPathV(basePath, "%s", "");
|
||||
return GetCombinedPathV(basePath, "%s", subPathFmt);
|
||||
}
|
||||
|
||||
char* GetCombinedPathV(const char* basePath, const char* subPathFmt, ...)
|
||||
{
|
||||
va_list ap = WINPR_C_ARRAY_INIT;
|
||||
|
||||
va_start(ap, subPathFmt);
|
||||
char* str = GetCombinedPathVA(basePath, subPathFmt, ap);
|
||||
va_end(ap);
|
||||
return str;
|
||||
}
|
||||
|
||||
char* GetCombinedPathVA(const char* basePath, WINPR_FORMAT_ARG const char* subPathFmt, va_list ap)
|
||||
{
|
||||
HRESULT status = 0;
|
||||
char* subPathCpy = nullptr;
|
||||
size_t basePathLength = 0;
|
||||
size_t subPathLength = 0;
|
||||
|
||||
if (basePath)
|
||||
basePathLength = strlen(basePath);
|
||||
|
||||
bool haveSubPath = subPathFmt && (*subPathFmt != '\0');
|
||||
if (haveSubPath)
|
||||
{
|
||||
const int rc = winpr_vasprintf(&subPathCpy, &subPathLength, subPathFmt, ap);
|
||||
if (rc < 0)
|
||||
return nullptr;
|
||||
if (rc == 0)
|
||||
{
|
||||
free(subPathCpy);
|
||||
subPathCpy = nullptr;
|
||||
subPathLength = 0;
|
||||
haveSubPath = false;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t length = basePathLength + subPathLength + 1;
|
||||
char* path = (char*)calloc(1, length + 1);
|
||||
|
||||
if (!path)
|
||||
goto fail;
|
||||
|
||||
if (basePath)
|
||||
CopyMemory(path, basePath, basePathLength);
|
||||
|
||||
if (FAILED(PathCchConvertStyleA(path, basePathLength, PATH_STYLE_NATIVE)))
|
||||
goto fail;
|
||||
|
||||
if (!haveSubPath)
|
||||
return path;
|
||||
|
||||
if (!subPathCpy)
|
||||
goto fail;
|
||||
|
||||
if (FAILED(PathCchConvertStyleA(subPathCpy, subPathLength, PATH_STYLE_NATIVE)))
|
||||
goto fail;
|
||||
|
||||
status = NativePathCchAppendA(path, length + 1, subPathCpy);
|
||||
if (FAILED(status))
|
||||
goto fail;
|
||||
|
||||
free(subPathCpy);
|
||||
return path;
|
||||
|
||||
fail:
|
||||
free(path);
|
||||
free(subPathCpy);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BOOL PathMakePathA(LPCSTR path, WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpAttributes)
|
||||
{
|
||||
#if defined(_UWP)
|
||||
return FALSE;
|
||||
#elif defined(_WIN32)
|
||||
return (SHCreateDirectoryExA(nullptr, path, lpAttributes) == ERROR_SUCCESS);
|
||||
#else
|
||||
const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
|
||||
char* dup = nullptr;
|
||||
BOOL result = TRUE;
|
||||
/* we only operate on a non-null, absolute path */
|
||||
#if defined(__OS2__)
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
#else
|
||||
|
||||
if (!path || *path != delim)
|
||||
return FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
if (!(dup = _strdup(path)))
|
||||
return FALSE;
|
||||
|
||||
#ifdef __OS2__
|
||||
p = (strlen(dup) > 3) && (dup[1] == ':') && (dup[2] == delim)) ? &dup[3] : dup;
|
||||
|
||||
while (p)
|
||||
#else
|
||||
for (char* p = dup; p;)
|
||||
#endif
|
||||
{
|
||||
if ((p = strchr(p + 1, delim)))
|
||||
*p = '\0';
|
||||
|
||||
if (mkdir(dup, 0777) != 0)
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p)
|
||||
*p = delim;
|
||||
}
|
||||
|
||||
free(dup);
|
||||
return (result);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL PathMakePathW(LPCWSTR path, WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpAttributes)
|
||||
{
|
||||
#if defined(_UWP)
|
||||
return FALSE;
|
||||
#elif defined(_WIN32)
|
||||
return (SHCreateDirectoryExW(nullptr, path, lpAttributes) == ERROR_SUCCESS);
|
||||
#else
|
||||
const WCHAR wdelim = PathGetSeparatorW(PATH_STYLE_NATIVE);
|
||||
const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
|
||||
char* dup = nullptr;
|
||||
BOOL result = TRUE;
|
||||
/* we only operate on a non-null, absolute path */
|
||||
#if defined(__OS2__)
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
#else
|
||||
|
||||
if (!path || *path != wdelim)
|
||||
return FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
dup = ConvertWCharToUtf8Alloc(path, nullptr);
|
||||
if (!dup)
|
||||
return FALSE;
|
||||
|
||||
#ifdef __OS2__
|
||||
p = (strlen(dup) > 3) && (dup[1] == ':') && (dup[2] == delim)) ? &dup[3] : dup;
|
||||
|
||||
while (p)
|
||||
#else
|
||||
for (char* p = dup; p;)
|
||||
#endif
|
||||
{
|
||||
if ((p = strchr(p + 1, delim)))
|
||||
*p = '\0';
|
||||
|
||||
if (mkdir(dup, 0777) != 0)
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p)
|
||||
*p = delim;
|
||||
}
|
||||
|
||||
free(dup);
|
||||
return (result);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) || defined(_UWP)
|
||||
|
||||
BOOL PathIsRelativeA(LPCSTR pszPath)
|
||||
{
|
||||
if (!pszPath)
|
||||
return FALSE;
|
||||
|
||||
return pszPath[0] != '/';
|
||||
}
|
||||
|
||||
BOOL PathIsRelativeW(LPCWSTR pszPath)
|
||||
{
|
||||
LPSTR lpFileNameA = nullptr;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!pszPath)
|
||||
goto fail;
|
||||
|
||||
lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, nullptr);
|
||||
if (!lpFileNameA)
|
||||
goto fail;
|
||||
ret = PathIsRelativeA(lpFileNameA);
|
||||
fail:
|
||||
free(lpFileNameA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL PathFileExistsA(LPCSTR pszPath)
|
||||
{
|
||||
struct stat stat_info;
|
||||
|
||||
return (stat(pszPath, &stat_info) == 0);
|
||||
}
|
||||
|
||||
BOOL PathFileExistsW(LPCWSTR pszPath)
|
||||
{
|
||||
LPSTR lpFileNameA = nullptr;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!pszPath)
|
||||
goto fail;
|
||||
lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, nullptr);
|
||||
if (!lpFileNameA)
|
||||
goto fail;
|
||||
|
||||
ret = winpr_PathFileExists(lpFileNameA);
|
||||
fail:
|
||||
free(lpFileNameA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL PathIsDirectoryEmptyA(LPCSTR pszPath)
|
||||
{
|
||||
struct dirent* dp = nullptr;
|
||||
int empty = 1;
|
||||
DIR* dir = opendir(pszPath);
|
||||
|
||||
if (dir == nullptr) /* Not a directory or doesn't exist */
|
||||
return 1;
|
||||
|
||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
||||
while ((dp = readdir(dir)) != nullptr)
|
||||
{
|
||||
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
|
||||
continue; /* Skip . and .. */
|
||||
|
||||
empty = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return empty;
|
||||
}
|
||||
|
||||
BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath)
|
||||
{
|
||||
LPSTR lpFileNameA = nullptr;
|
||||
BOOL ret = FALSE;
|
||||
if (!pszPath)
|
||||
goto fail;
|
||||
lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, nullptr);
|
||||
if (!lpFileNameA)
|
||||
goto fail;
|
||||
ret = PathIsDirectoryEmptyA(lpFileNameA);
|
||||
fail:
|
||||
free(lpFileNameA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)
|
||||
{
|
||||
return winpr_MoveFileEx(lpExistingFileName, lpNewFileName, 0);
|
||||
}
|
||||
|
||||
BOOL winpr_MoveFileEx(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct stat st;
|
||||
int ret = 0;
|
||||
ret = stat(lpNewFileName, &st);
|
||||
|
||||
if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == 0)
|
||||
{
|
||||
if (ret == 0)
|
||||
{
|
||||
SetLastError(ERROR_ALREADY_EXISTS);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret == 0 && (st.st_mode & S_IWUSR) == 0)
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ret = rename(lpExistingFileName, lpNewFileName);
|
||||
|
||||
if (ret != 0)
|
||||
SetLastError(map_posix_err(errno));
|
||||
|
||||
return ret == 0;
|
||||
#else
|
||||
BOOL result = FALSE;
|
||||
LPWSTR lpExistingFileNameW = nullptr;
|
||||
LPWSTR lpNewFileNameW = nullptr;
|
||||
|
||||
if (!lpExistingFileName || !lpNewFileName)
|
||||
return FALSE;
|
||||
|
||||
lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, nullptr);
|
||||
if (!lpExistingFileNameW)
|
||||
goto cleanup;
|
||||
lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, nullptr);
|
||||
if (!lpNewFileNameW)
|
||||
goto cleanup;
|
||||
|
||||
result = MoveFileExW(lpExistingFileNameW, lpNewFileNameW, dwFlags);
|
||||
|
||||
cleanup:
|
||||
free(lpExistingFileNameW);
|
||||
free(lpNewFileNameW);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL winpr_DeleteFile(const char* lpFileName)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if (!lpFileName)
|
||||
return FALSE;
|
||||
|
||||
const int status = unlink(lpFileName);
|
||||
return (status != -1);
|
||||
#else
|
||||
LPWSTR lpFileNameW = nullptr;
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (lpFileName)
|
||||
lpFileNameW = ConvertUtf8ToWCharAlloc(lpFileName, nullptr);
|
||||
|
||||
if (!lpFileNameW)
|
||||
goto cleanup;
|
||||
|
||||
result = DeleteFileW(lpFileNameW);
|
||||
|
||||
cleanup:
|
||||
free(lpFileNameW);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL winpr_RemoveDirectory(LPCSTR lpPathName)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
int ret = rmdir(lpPathName);
|
||||
|
||||
if (ret != 0)
|
||||
SetLastError(map_posix_err(errno));
|
||||
else
|
||||
SetLastError(STATUS_SUCCESS);
|
||||
|
||||
return ret == 0;
|
||||
#else
|
||||
LPWSTR lpPathNameW = nullptr;
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (lpPathName)
|
||||
lpPathNameW = ConvertUtf8ToWCharAlloc(lpPathName, nullptr);
|
||||
|
||||
if (!lpPathNameW)
|
||||
goto cleanup;
|
||||
|
||||
result = RemoveDirectoryW(lpPathNameW);
|
||||
|
||||
cleanup:
|
||||
free(lpPathNameW);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL winpr_PathFileExists(const char* pszPath)
|
||||
{
|
||||
if (!pszPath)
|
||||
return FALSE;
|
||||
#ifndef _WIN32
|
||||
return PathFileExistsA(pszPath);
|
||||
#else
|
||||
WCHAR* pathW = ConvertUtf8ToWCharAlloc(pszPath, nullptr);
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!pathW)
|
||||
return FALSE;
|
||||
|
||||
result = PathFileExistsW(pathW);
|
||||
free(pathW);
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL winpr_PathMakePath(const char* path, LPSECURITY_ATTRIBUTES lpAttributes)
|
||||
{
|
||||
if (!path)
|
||||
return FALSE;
|
||||
#ifndef _WIN32
|
||||
return PathMakePathA(path, lpAttributes);
|
||||
#else
|
||||
WCHAR* pathW = ConvertUtf8ToWCharAlloc(path, nullptr);
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!pathW)
|
||||
return FALSE;
|
||||
|
||||
result = SHCreateDirectoryExW(nullptr, pathW, lpAttributes) == ERROR_SUCCESS;
|
||||
free(pathW);
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
9
third_party/FreeRDP/winpr/libwinpr/path/shell_ios.h
vendored
Normal file
9
third_party/FreeRDP/winpr/libwinpr/path/shell_ios.h
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef SHELL_IOS_H_
|
||||
#define SHELL_IOS_H_
|
||||
|
||||
char* ios_get_home(void);
|
||||
char* ios_get_temp(void);
|
||||
char* ios_get_data(void);
|
||||
char* ios_get_cache(void);
|
||||
|
||||
#endif
|
||||
54
third_party/FreeRDP/winpr/libwinpr/path/shell_ios.m
vendored
Normal file
54
third_party/FreeRDP/winpr/libwinpr/path/shell_ios.m
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Path Functions
|
||||
*
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.om>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <winpr/config.h>
|
||||
|
||||
#include "shell_ios.h"
|
||||
|
||||
static NSString *ios_get_directory_for_search_path(NSSearchPathDirectory searchPath)
|
||||
{
|
||||
return [NSSearchPathForDirectoriesInDomains(searchPath, NSUserDomainMask, YES) lastObject];
|
||||
}
|
||||
|
||||
char *ios_get_home(void)
|
||||
{
|
||||
NSString *path = ios_get_directory_for_search_path(NSDocumentDirectory);
|
||||
return strdup([path UTF8String]);
|
||||
}
|
||||
|
||||
char *ios_get_temp(void)
|
||||
{
|
||||
NSString *tmp_path = NSTemporaryDirectory();
|
||||
return strdup([tmp_path UTF8String]);
|
||||
}
|
||||
|
||||
char *ios_get_data(void)
|
||||
{
|
||||
NSString *path = ios_get_directory_for_search_path(NSApplicationSupportDirectory);
|
||||
return strdup([path UTF8String]);
|
||||
}
|
||||
|
||||
char *ios_get_cache(void)
|
||||
{
|
||||
NSString *path = ios_get_directory_for_search_path(NSCachesDirectory);
|
||||
return strdup([path UTF8String]);
|
||||
}
|
||||
48
third_party/FreeRDP/winpr/libwinpr/path/test/CMakeLists.txt
vendored
Normal file
48
third_party/FreeRDP/winpr/libwinpr/path/test/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
set(MODULE_NAME "TestPath")
|
||||
set(MODULE_PREFIX "TEST_PATH")
|
||||
|
||||
disable_warnings_for_directory(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS
|
||||
TestPathCchAddBackslash.c
|
||||
TestPathCchRemoveBackslash.c
|
||||
TestPathCchAddBackslashEx.c
|
||||
TestPathCchRemoveBackslashEx.c
|
||||
TestPathCchAddExtension.c
|
||||
TestPathCchAppend.c
|
||||
TestPathCchAppendEx.c
|
||||
TestPathCchCanonicalize.c
|
||||
TestPathCchCanonicalizeEx.c
|
||||
TestPathAllocCanonicalize.c
|
||||
TestPathCchCombine.c
|
||||
TestPathCchCombineEx.c
|
||||
TestPathAllocCombine.c
|
||||
TestPathCchFindExtension.c
|
||||
TestPathCchRenameExtension.c
|
||||
TestPathCchRemoveExtension.c
|
||||
TestPathCchIsRoot.c
|
||||
TestPathIsUNCEx.c
|
||||
TestPathCchSkipRoot.c
|
||||
TestPathCchStripToRoot.c
|
||||
TestPathCchStripPrefix.c
|
||||
TestPathCchRemoveFileSpec.c
|
||||
TestPathShell.c
|
||||
TestPathMakePath.c
|
||||
)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} ${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} winpr)
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(test ${${MODULE_PREFIX}_TESTS})
|
||||
get_filename_component(TestName ${test} NAME_WE)
|
||||
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
|
||||
endforeach()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathAllocCanonicalize(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
98
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathAllocCombine.c
vendored
Normal file
98
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathAllocCombine.c
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
static const TCHAR testBasePathBackslash[] = _T("C:\\Program Files\\");
|
||||
static const TCHAR testBasePathNoBackslash[] = _T("C:\\Program Files");
|
||||
static const TCHAR testMorePathBackslash[] = _T("\\Microsoft Visual Studio 11.0");
|
||||
static const TCHAR testMorePathNoBackslash[] = _T("Microsoft Visual Studio 11.0");
|
||||
static const TCHAR testPathOut[] = _T("C:\\Program Files\\Microsoft Visual Studio 11.0");
|
||||
static const TCHAR testPathOutMorePathBackslash[] = _T("C:\\Microsoft Visual Studio 11.0");
|
||||
|
||||
int TestPathAllocCombine(int argc, char* argv[])
|
||||
{
|
||||
HRESULT status = 0;
|
||||
LPTSTR PathOut = nullptr;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
/* Base Path: Backslash, More Path: No Backslash */
|
||||
|
||||
status = PathAllocCombine(testBasePathBackslash, testMorePathNoBackslash, 0, &PathOut);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathAllocCombine status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcscmp(PathOut, testPathOut) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch 1: Actual: %s, Expected: %s\n"), PathOut, testPathOut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(PathOut);
|
||||
|
||||
/* Base Path: Backslash, More Path: Backslash */
|
||||
|
||||
status = PathAllocCombine(testBasePathBackslash, testMorePathBackslash, 0, &PathOut);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathAllocCombine status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcscmp(PathOut, testPathOutMorePathBackslash) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch 2: Actual: %s, Expected: %s\n"), PathOut,
|
||||
testPathOutMorePathBackslash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(PathOut);
|
||||
|
||||
/* Base Path: No Backslash, More Path: Backslash */
|
||||
|
||||
status = PathAllocCombine(testBasePathNoBackslash, testMorePathBackslash, 0, &PathOut);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathAllocCombine status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcscmp(PathOut, testPathOutMorePathBackslash) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch 3: Actual: %s, Expected: %s\n"), PathOut,
|
||||
testPathOutMorePathBackslash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(PathOut);
|
||||
|
||||
/* Base Path: No Backslash, More Path: No Backslash */
|
||||
|
||||
status = PathAllocCombine(testBasePathNoBackslash, testMorePathNoBackslash, 0, &PathOut);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathAllocCombine status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcscmp(PathOut, testPathOut) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch 4: Actual: %s, Expected: %s\n"), PathOut, testPathOut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(PathOut);
|
||||
|
||||
return 0;
|
||||
}
|
||||
101
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAddBackslash.c
vendored
Normal file
101
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAddBackslash.c
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
static const TCHAR testPathBackslash[] = _T("C:\\Program Files\\");
|
||||
static const TCHAR testPathNoBackslash[] = _T("C:\\Program Files");
|
||||
|
||||
int TestPathCchAddBackslash(int argc, char* argv[])
|
||||
{
|
||||
HRESULT status = 0;
|
||||
TCHAR Path[PATHCCH_MAX_CCH] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
/**
|
||||
* PathCchAddBackslash returns S_OK if the function was successful,
|
||||
* S_FALSE if the path string already ends in a backslash,
|
||||
* or an error code otherwise.
|
||||
*/
|
||||
|
||||
_tcsncpy(Path, testPathNoBackslash, ARRAYSIZE(Path));
|
||||
|
||||
/* Add a backslash to a path without a trailing backslash, expect S_OK */
|
||||
|
||||
status = PathCchAddBackslash(Path, PATHCCH_MAX_CCH);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAddBackslash status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathBackslash, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathBackslash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Add a backslash to a path with a trailing backslash, expect S_FALSE */
|
||||
|
||||
_tcsncpy(Path, testPathBackslash, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddBackslash(Path, PATHCCH_MAX_CCH);
|
||||
|
||||
if (status != S_FALSE)
|
||||
{
|
||||
_tprintf(_T("PathCchAddBackslash status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathBackslash, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathBackslash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Use nullptr PSTR, expect FAILED(status) */
|
||||
|
||||
status = PathCchAddBackslash(nullptr, PATHCCH_MAX_CCH);
|
||||
|
||||
if (SUCCEEDED(status))
|
||||
{
|
||||
_tprintf(
|
||||
_T("PathCchAddBackslash unexpectedly succeeded with null buffer. Status: 0x%08") _T(
|
||||
PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Use insufficient size value, expect FAILED(status) */
|
||||
|
||||
_tcsncpy(Path, _T("C:\\tmp"), ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddBackslash(Path, 7);
|
||||
|
||||
if (SUCCEEDED(status))
|
||||
{
|
||||
_tprintf(_T("PathCchAddBackslash unexpectedly succeeded with insufficient buffer size. ")
|
||||
_T("Status: 0x%08") _T(PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Use minimum required size value, expect S_OK */
|
||||
|
||||
_tcsncpy(Path, _T("C:\\tmp"), ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddBackslash(Path, 8);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAddBackslash failed with status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
103
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c
vendored
Normal file
103
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
static const TCHAR testPathBackslash[] = _T("C:\\Program Files\\");
|
||||
static const TCHAR testPathNoBackslash[] = _T("C:\\Program Files");
|
||||
|
||||
int TestPathCchAddBackslashEx(int argc, char* argv[])
|
||||
{
|
||||
HRESULT status = 0;
|
||||
LPTSTR pszEnd = nullptr;
|
||||
size_t cchRemaining = 0;
|
||||
TCHAR Path[PATHCCH_MAX_CCH] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
/**
|
||||
* PathCchAddBackslashEx returns S_OK if the function was successful,
|
||||
* S_FALSE if the path string already ends in a backslash,
|
||||
* or an error code otherwise.
|
||||
*/
|
||||
|
||||
_tcsncpy(Path, testPathNoBackslash, ARRAYSIZE(Path));
|
||||
|
||||
/* Add a backslash to a path without a trailing backslash, expect S_OK */
|
||||
|
||||
status = PathCchAddBackslashEx(Path, sizeof(Path) / sizeof(TCHAR), &pszEnd, &cchRemaining);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAddBackslash status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathBackslash, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathBackslash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Add a backslash to a path with a trailing backslash, expect S_FALSE */
|
||||
|
||||
_tcsncpy(Path, testPathBackslash, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddBackslashEx(Path, sizeof(Path) / sizeof(TCHAR), &pszEnd, &cchRemaining);
|
||||
|
||||
if (status != S_FALSE)
|
||||
{
|
||||
_tprintf(_T("PathCchAddBackslash status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathBackslash, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathBackslash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Use nullptr PSTR, expect FAILED(status) */
|
||||
|
||||
status = PathCchAddBackslashEx(nullptr, PATHCCH_MAX_CCH, nullptr, nullptr);
|
||||
|
||||
if (SUCCEEDED(status))
|
||||
{
|
||||
_tprintf(
|
||||
_T("PathCchAddBackslashEx unexpectedly succeeded with null buffer. Status: 0x%08") _T(
|
||||
PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Use insufficient size value, expect FAILED(status) */
|
||||
|
||||
_tcsncpy(Path, _T("C:\\tmp"), ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddBackslashEx(Path, 7, nullptr, nullptr);
|
||||
|
||||
if (SUCCEEDED(status))
|
||||
{
|
||||
_tprintf(_T("PathCchAddBackslashEx unexpectedly succeeded with insufficient buffer size. ")
|
||||
_T("Status: 0x%08") _T(PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Use minimum required size value, expect S_OK */
|
||||
|
||||
_tcsncpy(Path, _T("C:\\tmp"), ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddBackslashEx(Path, 8, nullptr, nullptr);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAddBackslashEx failed with status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
140
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAddExtension.c
vendored
Normal file
140
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAddExtension.c
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
static const TCHAR testExtDot[] = _T(".exe");
|
||||
static const TCHAR testExtNoDot[] = _T("exe");
|
||||
static const TCHAR testPathNoExtension[] = _T("C:\\Windows\\System32\\cmd");
|
||||
static const TCHAR testPathExtension[] = _T("C:\\Windows\\System32\\cmd.exe");
|
||||
|
||||
int TestPathCchAddExtension(int argc, char* argv[])
|
||||
{
|
||||
HRESULT status = 0;
|
||||
TCHAR Path[PATHCCH_MAX_CCH] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
/* Path: no extension, Extension: dot */
|
||||
|
||||
_tcsncpy(Path, testPathNoExtension, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, testExtDot);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAddExtension status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathExtension, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathExtension);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Path: no extension, Extension: no dot */
|
||||
|
||||
_tcsncpy(Path, testPathNoExtension, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, testExtNoDot);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAddExtension status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathExtension, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathExtension);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Path: extension, Extension: dot */
|
||||
|
||||
_tcsncpy(Path, testPathExtension, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, testExtDot);
|
||||
|
||||
if (status != S_FALSE)
|
||||
{
|
||||
_tprintf(_T("PathCchAddExtension status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathExtension, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathExtension);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Path: extension, Extension: no dot */
|
||||
|
||||
_tcsncpy(Path, testPathExtension, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, testExtDot);
|
||||
|
||||
if (status != S_FALSE)
|
||||
{
|
||||
_tprintf(_T("PathCchAddExtension status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathExtension, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathExtension);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Path: nullptr */
|
||||
|
||||
status = PathCchAddExtension(nullptr, PATHCCH_MAX_CCH, testExtDot);
|
||||
if (status != E_INVALIDARG)
|
||||
{
|
||||
_tprintf(_T("PathCchAddExtension with null buffer returned status: 0x%08") _T(
|
||||
PRIX32) _T(" (expected E_INVALIDARG)\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Extension: nullptr */
|
||||
|
||||
status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, nullptr);
|
||||
if (status != E_INVALIDARG)
|
||||
{
|
||||
_tprintf(_T("PathCchAddExtension with null extension returned status: 0x%08") _T(
|
||||
PRIX32) _T(" (expected E_INVALIDARG)\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Insufficient Buffer size */
|
||||
|
||||
_tcsncpy(Path, _T("C:\\456789"), ARRAYSIZE(Path));
|
||||
status = PathCchAddExtension(Path, 9 + 4, _T(".jpg"));
|
||||
if (SUCCEEDED(status))
|
||||
{
|
||||
_tprintf(_T("PathCchAddExtension with insufficient buffer unexpectedly succeeded with ")
|
||||
_T("status: 0x%08") _T(PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Minimum required buffer size */
|
||||
|
||||
_tcsncpy(Path, _T("C:\\456789"), ARRAYSIZE(Path));
|
||||
status = PathCchAddExtension(Path, 9 + 4 + 1, _T(".jpg"));
|
||||
if (FAILED(status))
|
||||
{
|
||||
_tprintf(_T("PathCchAddExtension with sufficient buffer unexpectedly failed with status: ")
|
||||
_T("0x%08") _T(PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
151
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAppend.c
vendored
Normal file
151
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAppend.c
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
static const TCHAR testBasePathBackslash[] = _T("C:\\Program Files\\");
|
||||
static const TCHAR testBasePathNoBackslash[] = _T("C:\\Program Files");
|
||||
static const TCHAR testMorePathBackslash[] = _T("\\Microsoft Visual Studio 11.0");
|
||||
static const TCHAR testMorePathNoBackslash[] = _T("Microsoft Visual Studio 11.0");
|
||||
static const TCHAR testPathOut[] = _T("C:\\Program Files\\Microsoft Visual Studio 11.0");
|
||||
|
||||
int TestPathCchAppend(int argc, char* argv[])
|
||||
{
|
||||
HRESULT status = 0;
|
||||
TCHAR Path[PATHCCH_MAX_CCH];
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
/* Base Path: Backslash, More Path: No Backslash */
|
||||
|
||||
_tcsncpy(Path, testBasePathBackslash, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAppend(Path, PATHCCH_MAX_CCH, testMorePathNoBackslash);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAppend status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathOut, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathOut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Base Path: Backslash, More Path: Backslash */
|
||||
|
||||
_tcsncpy(Path, testBasePathBackslash, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAppend(Path, PATHCCH_MAX_CCH, testMorePathBackslash);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAppend status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathOut, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathOut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Base Path: No Backslash, More Path: Backslash */
|
||||
|
||||
_tcsncpy(Path, testBasePathNoBackslash, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAppend(Path, PATHCCH_MAX_CCH, testMorePathBackslash);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAppend status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathOut, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathOut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Base Path: No Backslash, More Path: No Backslash */
|
||||
|
||||
_tcsncpy(Path, testBasePathNoBackslash, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchAppend(Path, PATHCCH_MAX_CCH, testMorePathNoBackslash);
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchAppend status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathOut, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathOut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* According to msdn a nullptr Path is an invalid argument */
|
||||
status = PathCchAppend(nullptr, PATHCCH_MAX_CCH, testMorePathNoBackslash);
|
||||
if (status != E_INVALIDARG)
|
||||
{
|
||||
_tprintf(_T("PathCchAppend with nullptr path unexpectedly returned status: 0x%08") _T(
|
||||
PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* According to msdn a nullptr pszMore is an invalid argument (although optional !?) */
|
||||
_tcsncpy(Path, testBasePathNoBackslash, ARRAYSIZE(Path));
|
||||
status = PathCchAppend(Path, PATHCCH_MAX_CCH, nullptr);
|
||||
if (status != E_INVALIDARG)
|
||||
{
|
||||
_tprintf(_T("PathCchAppend with nullptr pszMore unexpectedly returned status: 0x%08") _T(
|
||||
PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* According to msdn cchPath must be > 0 and <= PATHCCH_MAX_CCH */
|
||||
_tcsncpy(Path, testBasePathNoBackslash, ARRAYSIZE(Path));
|
||||
status = PathCchAppend(Path, 0, testMorePathNoBackslash);
|
||||
if (status != E_INVALIDARG)
|
||||
{
|
||||
_tprintf(_T("PathCchAppend with cchPath value 0 unexpectedly returned status: 0x%08") _T(
|
||||
PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
_tcsncpy(Path, testBasePathNoBackslash, ARRAYSIZE(Path));
|
||||
status = PathCchAppend(Path, PATHCCH_MAX_CCH + 1, testMorePathNoBackslash);
|
||||
if (status != E_INVALIDARG)
|
||||
{
|
||||
_tprintf(_T("PathCchAppend with cchPath value > PATHCCH_MAX_CCH unexpectedly returned ")
|
||||
_T("status: 0x%08") _T(PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Resulting file must not exceed PATHCCH_MAX_CCH */
|
||||
|
||||
for (size_t i = 0; i < PATHCCH_MAX_CCH - 1; i++)
|
||||
Path[i] = _T('X');
|
||||
|
||||
Path[PATHCCH_MAX_CCH - 1] = 0;
|
||||
|
||||
status = PathCchAppend(Path, PATHCCH_MAX_CCH, _T("\\This cannot be appended to Path"));
|
||||
if (SUCCEEDED(status))
|
||||
{
|
||||
_tprintf(_T("PathCchAppend unexpectedly succeeded with status: 0x%08") _T(PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAppendEx.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchAppendEx.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchAppendEx(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchCanonicalize.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchCanonicalize.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchCanonicalize(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchCanonicalizeEx(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchCombine.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchCombine.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchCombine(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchCombineEx.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchCombineEx.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchCombineEx(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
114
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchFindExtension.c
vendored
Normal file
114
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchFindExtension.c
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
static const char testPathExtension[] = "C:\\Windows\\System32\\cmd.exe";
|
||||
|
||||
int TestPathCchFindExtension(int argc, char* argv[])
|
||||
{
|
||||
PCSTR pszExt = nullptr;
|
||||
PCSTR pszTmp = nullptr;
|
||||
HRESULT hr = 0;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
/* Test invalid args */
|
||||
|
||||
hr = PathCchFindExtensionA(nullptr, sizeof(testPathExtension), &pszExt);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
printf("PathCchFindExtensionA unexpectedly succeeded with pszPath = nullptr. result: "
|
||||
"0x%08" PRIX32 "\n",
|
||||
hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hr = PathCchFindExtensionA(testPathExtension, 0, &pszExt);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
printf("PathCchFindExtensionA unexpectedly succeeded with cchPath = 0. result: 0x%08" PRIX32
|
||||
"\n",
|
||||
hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hr = PathCchFindExtensionA(testPathExtension, sizeof(testPathExtension), nullptr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
printf("PathCchFindExtensionA unexpectedly succeeded with ppszExt = nullptr. result: "
|
||||
"0x%08" PRIX32 "\n",
|
||||
hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test missing null-termination of pszPath */
|
||||
|
||||
hr = PathCchFindExtensionA("c:\\45.789", 9, &pszExt); /* nb: correct would be 10 */
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
printf("PathCchFindExtensionA unexpectedly succeeded with unterminated pszPath. result: "
|
||||
"0x%08" PRIX32 "\n",
|
||||
hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test passing of an empty terminated string (must succeed) */
|
||||
|
||||
pszExt = nullptr;
|
||||
pszTmp = "";
|
||||
hr = PathCchFindExtensionA(pszTmp, 1, &pszExt);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
printf("PathCchFindExtensionA failed with an empty terminated string. result: 0x%08" PRIX32
|
||||
"\n",
|
||||
hr);
|
||||
return -1;
|
||||
}
|
||||
/* pszExt must point to the strings terminating 0 now */
|
||||
if (pszExt != pszTmp)
|
||||
{
|
||||
printf("PathCchFindExtensionA failed with an empty terminated string: pszExt pointer "
|
||||
"mismatch\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test a path without file extension (must succeed) */
|
||||
|
||||
pszExt = nullptr;
|
||||
pszTmp = "c:\\4.678\\";
|
||||
hr = PathCchFindExtensionA(pszTmp, 10, &pszExt);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
printf("PathCchFindExtensionA failed with a directory path. result: 0x%08" PRIX32 "\n", hr);
|
||||
return -1;
|
||||
}
|
||||
/* The extension must not have been found and pszExt must point to the
|
||||
* strings terminating nullptr now */
|
||||
if (pszExt != &pszTmp[9])
|
||||
{
|
||||
printf("PathCchFindExtensionA failed with a directory path: pszExt pointer mismatch\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Non-special tests */
|
||||
|
||||
pszExt = nullptr;
|
||||
if (PathCchFindExtensionA(testPathExtension, sizeof(testPathExtension), &pszExt) != S_OK)
|
||||
{
|
||||
printf("PathCchFindExtensionA failure: expected S_OK\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!pszExt || strcmp(pszExt, ".exe") != 0)
|
||||
{
|
||||
printf("PathCchFindExtensionA failure: unexpected extension\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Extension: %s\n", pszExt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchIsRoot.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchIsRoot.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchIsRoot(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchRemoveBackslash(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchRemoveBackslashEx(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchRemoveExtension(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchRemoveFileSpec(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRenameExtension.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchRenameExtension.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchRenameExtension(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchSkipRoot.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchSkipRoot.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchSkipRoot(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
128
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchStripPrefix.c
vendored
Normal file
128
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchStripPrefix.c
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
/**
|
||||
* Naming Files, Paths, and Namespaces:
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247/
|
||||
*/
|
||||
|
||||
static const TCHAR testPathPrefixFileNamespace[] = _T("\\\\?\\C:\\Program Files\\");
|
||||
static const TCHAR testPathNoPrefixFileNamespace[] = _T("C:\\Program Files\\");
|
||||
static const TCHAR testPathPrefixFileNamespaceMinimum[] = _T("\\\\?\\C:");
|
||||
static const TCHAR testPathNoPrefixFileNamespaceMinimum[] = _T("C:");
|
||||
|
||||
static const TCHAR testPathPrefixDeviceNamespace[] = _T("\\\\?\\GLOBALROOT");
|
||||
|
||||
int TestPathCchStripPrefix(int argc, char* argv[])
|
||||
{
|
||||
HRESULT status = 0;
|
||||
TCHAR Path[PATHCCH_MAX_CCH] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
/**
|
||||
* PathCchStripPrefix returns S_OK if the prefix was removed, S_FALSE if
|
||||
* the path did not have a prefix to remove, or an HRESULT failure code.
|
||||
*/
|
||||
|
||||
/* Path with prefix (File Namespace) */
|
||||
|
||||
_tcsncpy(Path, testPathPrefixFileNamespace, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchStripPrefix(Path, sizeof(testPathPrefixFileNamespace) / sizeof(TCHAR));
|
||||
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchStripPrefix status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathNoPrefixFileNamespace, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path,
|
||||
testPathNoPrefixFileNamespace);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Path with prefix (Device Namespace) */
|
||||
|
||||
_tcsncpy(Path, testPathPrefixDeviceNamespace, ARRAYSIZE(Path));
|
||||
|
||||
status = PathCchStripPrefix(Path, ARRAYSIZE(testPathPrefixDeviceNamespace));
|
||||
|
||||
if (status != S_FALSE)
|
||||
{
|
||||
_tprintf(_T("PathCchStripPrefix status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Path, testPathPrefixDeviceNamespace, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path,
|
||||
testPathPrefixDeviceNamespace);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* nullptr Path */
|
||||
status = PathCchStripPrefix(nullptr, PATHCCH_MAX_CCH);
|
||||
if (status != E_INVALIDARG)
|
||||
{
|
||||
_tprintf(
|
||||
_T("PathCchStripPrefix with null path unexpectedly succeeded with status 0x%08") _T(
|
||||
PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invalid cchPath values: 0, 1, 2, 3 and > PATHCCH_MAX_CCH */
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
_tcsncpy(Path, testPathPrefixFileNamespace, ARRAYSIZE(Path));
|
||||
if (i == 4)
|
||||
i = PATHCCH_MAX_CCH + 1;
|
||||
status = PathCchStripPrefix(Path, i);
|
||||
if (status != E_INVALIDARG)
|
||||
{
|
||||
_tprintf(_T("PathCchStripPrefix with invalid cchPath value %d unexpectedly succeeded ")
|
||||
_T("with status 0x%08") _T(PRIX32) _T("\n"),
|
||||
i, status);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Minimum Path that would get successfully stripped on windows */
|
||||
_tcsncpy(Path, testPathPrefixFileNamespaceMinimum, ARRAYSIZE(Path));
|
||||
size_t i = ARRAYSIZE(testPathPrefixFileNamespaceMinimum);
|
||||
i = i - 1; /* include testing of a non-null terminated string */
|
||||
status = PathCchStripPrefix(Path, i);
|
||||
if (status != S_OK)
|
||||
{
|
||||
_tprintf(_T("PathCchStripPrefix with minimum valid strippable path length unexpectedly ")
|
||||
_T("returned status 0x%08") _T(PRIX32) _T("\n"),
|
||||
status);
|
||||
return -1;
|
||||
}
|
||||
if (_tcsncmp(Path, testPathNoPrefixFileNamespaceMinimum, ARRAYSIZE(Path)) != 0)
|
||||
{
|
||||
_tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path,
|
||||
testPathNoPrefixFileNamespaceMinimum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invalid drive letter symbol */
|
||||
_tcsncpy(Path, _T("\\\\?\\5:"), ARRAYSIZE(Path));
|
||||
status = PathCchStripPrefix(Path, 6);
|
||||
if (status == S_OK)
|
||||
{
|
||||
_tprintf(
|
||||
_T("PathCchStripPrefix with invalid drive letter symbol unexpectedly succeeded\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchStripToRoot.c
vendored
Normal file
12
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathCchStripToRoot.c
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathCchStripToRoot(int argc, char* argv[])
|
||||
{
|
||||
printf("Warning: %s is not implemented!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
52
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathIsUNCEx.c
vendored
Normal file
52
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathIsUNCEx.c
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
static const TCHAR testServer[] = _T("server\\share\\path\\file");
|
||||
static const TCHAR testPathUNC[] = _T("\\\\server\\share\\path\\file");
|
||||
static const TCHAR testPathNotUNC[] = _T("C:\\share\\path\\file");
|
||||
|
||||
int TestPathIsUNCEx(int argc, char* argv[])
|
||||
{
|
||||
BOOL status = 0;
|
||||
LPCTSTR Server = nullptr;
|
||||
TCHAR Path[PATHCCH_MAX_CCH] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
/* Path is UNC */
|
||||
|
||||
_tcsncpy(Path, testPathUNC, ARRAYSIZE(Path));
|
||||
|
||||
status = PathIsUNCEx(Path, &Server);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
_tprintf(_T("PathIsUNCEx status: 0x%d\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_tcsncmp(Server, testServer, ARRAYSIZE(testServer)) != 0)
|
||||
{
|
||||
_tprintf(_T("Server Name Mismatch: Actual: %s, Expected: %s\n"), Server, testServer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Path is not UNC */
|
||||
|
||||
_tcsncpy(Path, testPathNotUNC, ARRAYSIZE(Path));
|
||||
|
||||
status = PathIsUNCEx(Path, &Server);
|
||||
|
||||
if (status)
|
||||
{
|
||||
_tprintf(_T("PathIsUNCEx status: 0x%08") _T(PRIX32) _T("\n"), status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
96
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathMakePath.c
vendored
Normal file
96
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathMakePath.c
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/path.h>
|
||||
|
||||
static UINT32 prand(UINT32 max)
|
||||
{
|
||||
UINT32 tmp = 0;
|
||||
if (max <= 1)
|
||||
return 1;
|
||||
if (winpr_RAND(&tmp, sizeof(tmp)) < 0)
|
||||
{
|
||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
||||
exit(-1);
|
||||
}
|
||||
return tmp % (max - 1) + 1;
|
||||
}
|
||||
|
||||
int TestPathMakePath(int argc, char* argv[])
|
||||
{
|
||||
size_t baseLen = 0;
|
||||
BOOL success = 0;
|
||||
char tmp[64] = WINPR_C_ARRAY_INIT;
|
||||
char* path = nullptr;
|
||||
char* cur = nullptr;
|
||||
char delim = PathGetSeparatorA(0);
|
||||
char* base = GetKnownPath(KNOWN_PATH_TEMP);
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
if (!base)
|
||||
{
|
||||
(void)fprintf(stderr, "Failed to get temporary directory!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
baseLen = strlen(base);
|
||||
|
||||
for (int x = 0; x < 5; x++)
|
||||
{
|
||||
(void)sprintf_s(tmp, ARRAYSIZE(tmp), "%08" PRIX32, prand(UINT32_MAX));
|
||||
path = GetCombinedPath(base, tmp);
|
||||
free(base);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
(void)fprintf(stderr, "GetCombinedPath failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
base = path;
|
||||
}
|
||||
|
||||
printf("Creating path %s\n", path);
|
||||
success = winpr_PathMakePath(path, nullptr);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
(void)fprintf(stderr, "MakePath failed!\n");
|
||||
free(path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
success = winpr_PathFileExists(path);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
(void)fprintf(stderr, "MakePath lied about success!\n");
|
||||
free(path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (strlen(path) > baseLen)
|
||||
{
|
||||
if (!winpr_RemoveDirectory(path))
|
||||
{
|
||||
(void)fprintf(stderr, "winpr_RemoveDirectory %s failed!\n", path);
|
||||
free(path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cur = strrchr(path, delim);
|
||||
|
||||
if (cur)
|
||||
*cur = '\0';
|
||||
}
|
||||
|
||||
free(path);
|
||||
printf("%s success!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
58
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathShell.c
vendored
Normal file
58
third_party/FreeRDP/winpr/libwinpr/path/test/TestPathShell.c
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestPathShell(int argc, char* argv[])
|
||||
{
|
||||
const int paths[] = { KNOWN_PATH_HOME, KNOWN_PATH_TEMP,
|
||||
KNOWN_PATH_XDG_DATA_HOME, KNOWN_PATH_XDG_CONFIG_HOME,
|
||||
KNOWN_PATH_XDG_CACHE_HOME, KNOWN_PATH_XDG_RUNTIME_DIR,
|
||||
KNOWN_PATH_XDG_CONFIG_HOME };
|
||||
const char* names[] = { "KNOWN_PATH_HOME", "KNOWN_PATH_TEMP",
|
||||
"KNOWN_PATH_XDG_DATA_HOME", "KNOWN_PATH_XDG_CONFIG_HOME",
|
||||
"KNOWN_PATH_XDG_CACHE_HOME", "KNOWN_PATH_XDG_RUNTIME_DIR",
|
||||
"KNOWN_PATH_XDG_CONFIG_HOME" };
|
||||
int rc = 0;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
for (size_t x = 0; x < sizeof(paths) / sizeof(paths[0]); x++)
|
||||
{
|
||||
const int id = paths[x];
|
||||
const char* name = names[x];
|
||||
{
|
||||
char* path = GetKnownPath(id);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
(void)fprintf(stderr, "GetKnownPath(%d) failed\n", id);
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s Path: %s\n", name, path);
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
{
|
||||
char* path = GetKnownSubPath(id, "freerdp");
|
||||
|
||||
if (!path)
|
||||
{
|
||||
(void)fprintf(stderr, "GetKnownSubPath(%d) failed\n", id);
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s SubPath: %s\n", name, path);
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
Reference in New Issue
Block a user