mirror of
https://github.com/reactos/reactos.git
synced 2025-05-01 11:39:58 +00:00

Imported from https://www.nuget.org/packages/Microsoft.Windows.SDK.CRTSource/10.0.22621.3 License: MIT
153 lines
4.7 KiB
C++
153 lines
4.7 KiB
C++
/***
|
|
*fullpath.c -
|
|
*
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
*
|
|
*Purpose: contains the function _fullpath which makes an absolute path out
|
|
* of a relative path. i.e. ..\pop\..\main.c => c:\src\main.c if the
|
|
* current directory is c:\src\src
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <direct.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <corecrt_internal_traits.h>
|
|
#include <windows.h>
|
|
|
|
/***
|
|
*_TCHAR *_fullpath( _TCHAR *buf, const _TCHAR *path, maxlen );
|
|
*
|
|
*Purpose:
|
|
*
|
|
* _fullpath - combines the current directory with path to form
|
|
* an absolute path. i.e. _fullpath takes care of .\ and ..\
|
|
* in the path.
|
|
*
|
|
* The result is placed in buf. If the length of the result
|
|
* is greater than maxlen nullptr is returned, otherwise
|
|
* the address of buf is returned.
|
|
*
|
|
* If buf is nullptr then a buffer is malloc'ed and maxlen is
|
|
* ignored. If there are no errors then the address of this
|
|
* buffer is returned.
|
|
*
|
|
* If path specifies a drive, the curent directory of this
|
|
* drive is combined with path. If the drive is not valid
|
|
* and _fullpath needs the current directory of this drive
|
|
* then nullptr is returned. If the current directory of this
|
|
* non existant drive is not needed then a proper value is
|
|
* returned.
|
|
* For example: path = "z:\\pop" does not need z:'s current
|
|
* directory but path = "z:pop" does.
|
|
*
|
|
*
|
|
*
|
|
*Entry:
|
|
* _TCHAR *buf - pointer to a buffer maintained by the user;
|
|
* _TCHAR *path - path to "add" to the current directory
|
|
* int maxlen - length of the buffer pointed to by buf
|
|
*
|
|
*Exit:
|
|
* Returns pointer to the buffer containing the absolute path
|
|
* (same as buf if non-nullptr; otherwise, malloc is
|
|
* used to allocate a buffer)
|
|
*
|
|
*Exceptions:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
template <typename Character>
|
|
_Success_(return != 0)
|
|
static Character* __cdecl common_fullpath(
|
|
_Out_writes_z_(max_count) Character* const user_buffer,
|
|
Character const* const path,
|
|
size_t const max_count,
|
|
int const block_use,
|
|
char const* const file_name,
|
|
int const line_number
|
|
) throw()
|
|
{
|
|
// These are referenced only in the Debug CRT build
|
|
UNREFERENCED_PARAMETER(block_use);
|
|
UNREFERENCED_PARAMETER(file_name);
|
|
UNREFERENCED_PARAMETER(line_number);
|
|
|
|
typedef __crt_char_traits<Character> traits;
|
|
|
|
// If the path is empty, we have no work to do:
|
|
if (path == nullptr || path[0] == '\0')
|
|
{
|
|
#pragma warning(suppress:__WARNING_POSTCONDITION_NULLTERMINATION_VIOLATION) // 26036 Prefast does not understand perfect forwarding.
|
|
return traits::tgetcwd(user_buffer, static_cast<int>(__min(max_count, INT_MAX)));
|
|
}
|
|
|
|
if (user_buffer != nullptr) {
|
|
// Using user buffer. Fail if not enough space.
|
|
__crt_no_alloc_win32_buffer<Character> buffer(user_buffer, max_count);
|
|
if (!traits::get_full_path_name(path, buffer)) {
|
|
return user_buffer;
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
} else {
|
|
// Always new memory suitable for debug mode and releasing to the user.
|
|
__crt_public_win32_buffer<Character> buffer(
|
|
__crt_win32_buffer_debug_info(block_use, file_name, line_number)
|
|
);
|
|
traits::get_full_path_name(path, buffer);
|
|
return buffer.detach();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
extern "C" char* __cdecl _fullpath(
|
|
char* const user_buffer,
|
|
char const* const path,
|
|
size_t const max_count
|
|
)
|
|
{
|
|
return common_fullpath(user_buffer, path, max_count, _NORMAL_BLOCK, nullptr, 0);
|
|
}
|
|
|
|
extern "C" wchar_t* __cdecl _wfullpath(
|
|
wchar_t* const user_buffer,
|
|
wchar_t const* const path,
|
|
size_t const max_count
|
|
)
|
|
{
|
|
return common_fullpath(user_buffer, path, max_count, _NORMAL_BLOCK, nullptr, 0);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
|
|
#undef _fullpath_dbg
|
|
#undef _wfullpath_dbg
|
|
|
|
extern "C" char* __cdecl _fullpath_dbg(
|
|
char* const user_buffer,
|
|
char const* const path,
|
|
size_t const max_count,
|
|
int const block_use,
|
|
char const* const file_name,
|
|
int const line_number
|
|
)
|
|
{
|
|
return common_fullpath(user_buffer, path, max_count, block_use, file_name, line_number);
|
|
}
|
|
|
|
extern "C" wchar_t* __cdecl _wfullpath_dbg(
|
|
wchar_t* const user_buffer,
|
|
wchar_t const* const path,
|
|
size_t const max_count,
|
|
int const block_use,
|
|
char const* const file_name,
|
|
int const line_number
|
|
)
|
|
{
|
|
return common_fullpath(user_buffer, path, max_count, block_use, file_name, line_number);
|
|
}
|
|
|
|
#endif // _DEBUG
|