Reactos
at master 77 lines 2.1 kB view raw
1// 2// drive.cpp 3// 4// Copyright (c) Microsoft Corporation. All rights reserved. 5// 6// The _getdrive() and _chdrive() functions, which get and set the current drive. 7// 8#include <corecrt_internal.h> 9#include <ctype.h> 10#include <direct.h> 11#include <errno.h> 12 13static int __cdecl get_drive_number_from_path(wchar_t const* const path) throw() 14{ 15 if (path[0] == L'\0' || path[1] != L':') 16 return 0; 17 18 return __ascii_towupper(path[0]) - L'A' + 1; 19} 20 21 22 23// Gets the current drive number (A: => 1, B: => 2, etc.). Returns zero if the 24// current drive cannot be determined. 25extern "C" int __cdecl _getdrive() 26{ 27 wchar_t cwd[MAX_PATH + 1] = { 0 }; 28 29 DWORD const cwd_length = GetCurrentDirectoryW(MAX_PATH + 1, cwd); 30 if (cwd_length <= MAX_PATH) 31 { 32 return get_drive_number_from_path(cwd); 33 } 34 35 // Otherwise, we need more space for the path, so we'll need to dynamically 36 // allocate a buffer: 37 __crt_unique_heap_ptr<wchar_t> const heap_cwd(_calloc_crt_t(wchar_t, cwd_length + 1)); 38 if (heap_cwd.get() == nullptr) 39 { 40 errno = ENOMEM; 41 return 0; 42 } 43 44 DWORD const heap_cwd_length = GetCurrentDirectoryW(cwd_length + 1, heap_cwd.get()); 45 if (heap_cwd_length == 0) 46 { 47 errno = ENOMEM; 48 return 0; 49 } 50 51 return get_drive_number_from_path(heap_cwd.get()); 52} 53 54 55 56// Changes the current drive to the specified drive number. Returns zero on 57// success; returns -1 and sets errno and _doserrno on failure. 58extern "C" int __cdecl _chdrive(int const drive_number) 59{ 60 if (drive_number < 1 || drive_number > 26) 61 { 62 _doserrno = ERROR_INVALID_DRIVE; 63 _VALIDATE_RETURN(("Invalid Drive Index", 0), EACCES, -1); 64 } 65 66#pragma warning(suppress:__WARNING_UNUSED_ASSIGNMENT) // 28931 unused assignment of variable drive_letter 67 wchar_t const drive_letter = static_cast<wchar_t>(L'A' + drive_number - 1); 68 wchar_t const drive_string[] = { drive_letter, L':', L'\0' }; 69 70 if (!SetCurrentDirectoryW(drive_string)) 71 { 72 __acrt_errno_map_os_error(GetLastError()); 73 return -1; 74 } 75 76 return 0; 77}