Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266/****getcwd.cpp - get current working directory** Copyright (c) Microsoft Corporation. All rights reserved.**Purpose:** contains functions _getcwd, _getdcwd and _getcdrv for getting the* current working directory. getcwd gets the c.w.d. for the default disk* drive, whereas _getdcwd allows one to get the c.w.d. for whatever disk* drive is specified. _getcdrv gets the current drive.********************************************************************************/#include <corecrt_internal.h>#include <corecrt_internal_traits.h>#include <direct.h>#include <errno.h>#include <malloc.h>#include <stdlib.h>
// Tests whether the specified drive number is valid. Returns zero if the drive// does not exist; returns one if the drive exists. Pass zero as an argument to// check the default drive.static int __cdecl is_valid_drive(unsigned const drive_number) throw(){ if (drive_number > 26) { _doserrno = ERROR_INVALID_DRIVE; _VALIDATE_RETURN(("Invalid Drive Index" ,0), EACCES, 0); }
if (drive_number == 0) return 1;
#pragma warning(suppress:__WARNING_UNUSED_ASSIGNMENT) // 28931 wchar_t const drive_letter = static_cast<wchar_t>(L'A' + drive_number - 1); wchar_t const drive_string[] = { drive_letter, L':', L'\\', L'\0' };
UINT const drive_type = GetDriveTypeW(drive_string); if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR) return 0;
return 1;}
/****_TSCHAR *_getcwd(pnbuf, maxlen) - get current working directory of default drive**Purpose:* _getcwd gets the current working directory for the user,* placing it in the buffer pointed to by pnbuf. If the length* of the string exceeds the length of the buffer, maxlen,* then nullptr is returned. If pnbuf = nullptr, a buffer of at* least size maxlen is automatically allocated using* malloc() -- a pointer to which is returned by _getcwd().* An entry point "_getdcwd()" is defined which takes the above* parameters, plus a drive number. "_getcwd()" is implemented* as a call to "_getdcwd()" with the default drive (0).** side effects: no global data is used or affected**Entry:* _TSCHAR *pnbuf = pointer to a buffer maintained by the user;* int maxlen = length of the buffer pointed to by pnbuf;**Exit:* Returns pointer to the buffer containing the c.w.d. name* (same as pnbuf if non-nullptr; otherwise, malloc is* used to allocate a buffer)**Exceptions:********************************************************************************/
/****_TSCHAR *_getdcwd(drive, pnbuf, maxlen) - get c.w.d. for given drive**Purpose:* _getdcwd gets the current working directory for the user,* placing it in the buffer pointed to by pnbuf. If the length* of the string exceeds the length of the buffer, maxlen,* then nullptr is returned. If pnbuf = nullptr, a buffer of at* least size maxlen is automatically allocated using* malloc() -- a pointer to which is returned by _getdcwd().** side effects: no global data is used or affected**Entry:* int drive - number of the drive being inquired about* 0 = default, 1 = 'a:', 2 = 'b:', etc.* _TSCHAR *pnbuf - pointer to a buffer maintained by the user;* int maxlen - length of the buffer pointed to by pnbuf;**Exit:* Returns pointer to the buffer containing the c.w.d. name* (same as pnbuf if non-nullptr; otherwise, malloc is* used to allocate a buffer)**Exceptions:********************************************************************************/
template <typename Character>_Success_(return != 0)_Ret_z_static Character* __cdecl common_getdcwd( int drive_number, _Out_writes_opt_z_(max_count) Character* user_buffer, int const max_count, int const block_use, _In_opt_z_ char const* const file_name, int const line_number ) throw(){ typedef __crt_char_traits<Character> traits;
_VALIDATE_RETURN(max_count >= 0, EINVAL, nullptr);
if (drive_number != 0) { // A drive other than the default drive was requested; make sure it // is a valid drive number: if (!is_valid_drive(drive_number)) { _doserrno = ERROR_INVALID_DRIVE; _VALIDATE_RETURN(("Invalid Drive", 0), EACCES, nullptr); } } else { // Otherwise, get the drive number of the default drive: drive_number = _getdrive(); }
Character drive_string[4]; if (drive_number != 0) { drive_string[0] = static_cast<Character>('A' - 1 + drive_number); drive_string[1] = ':'; drive_string[2] = '.'; drive_string[3] = '\0'; } else { drive_string[0] = '.'; drive_string[1] = '\0'; }
if (user_buffer == nullptr) { // 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) ); buffer.allocate(max_count); if (!traits::get_full_path_name(drive_string, buffer)) { return buffer.detach(); } return nullptr; }
// Using user buffer. Fail if not enough space. _VALIDATE_RETURN(max_count > 0, EINVAL, nullptr); user_buffer[0] = '\0';
__crt_no_alloc_win32_buffer<Character> buffer(user_buffer, max_count); if (!traits::get_full_path_name(drive_string, buffer)) { return user_buffer; } return nullptr;};
extern "C" char* __cdecl _getcwd( char* const user_buffer, int const max_length ){ return common_getdcwd(0, user_buffer, max_length, _NORMAL_BLOCK, nullptr, 0);}
extern "C" wchar_t* __cdecl _wgetcwd( wchar_t* const user_buffer, int const max_length ){ return common_getdcwd(0, user_buffer, max_length, _NORMAL_BLOCK, nullptr, 0);}
extern "C" char* __cdecl _getdcwd( int const drive_number, char* const user_buffer, int const max_length ){ return common_getdcwd(drive_number, user_buffer, max_length, _NORMAL_BLOCK, nullptr, 0);}
extern "C" wchar_t* __cdecl _wgetdcwd( int const drive_number, wchar_t* const user_buffer, int const max_length ){ return common_getdcwd(drive_number, user_buffer, max_length, _NORMAL_BLOCK, nullptr, 0);}
#ifdef _DEBUG
#undef _getcwd_dbg#undef _getdcwd_dbg
extern "C" char* __cdecl _getcwd_dbg( char* const user_buffer, int const max_length, int const block_use, char const* const file_name, int const line_number ){ return common_getdcwd(0, user_buffer, max_length, block_use, file_name, line_number);}
extern "C" wchar_t* __cdecl _wgetcwd_dbg( wchar_t* const user_buffer, int const max_length, int const block_use, char const* const file_name, int const line_number ){ return common_getdcwd(0, user_buffer, max_length, block_use, file_name, line_number);}
extern "C" char* __cdecl _getdcwd_dbg( int const drive_number, char* const user_buffer, int const max_length, int const block_use, char const* const file_name, int const line_number ){ return common_getdcwd(drive_number, user_buffer, max_length, block_use, file_name, line_number);}
extern "C" wchar_t* __cdecl _wgetdcwd_dbg( int const drive_number, wchar_t* const user_buffer, int const max_length, int const block_use, char const* const file_name, int const line_number ){ return common_getdcwd(drive_number, user_buffer, max_length, block_use, file_name, line_number);}
#endif // _DEBUG