ReactOS 0.4.16-dev-853-g88d9285
drive.cpp
Go to the documentation of this file.
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 {
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 {
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 {
73 return -1;
74 }
75
76 return 0;
77}
#define ENOMEM
Definition: acclib.h:84
#define EACCES
Definition: acclib.h:85
#define __cdecl
Definition: accygwin.h:79
void __cdecl __acrt_errno_map_os_error(unsigned long)
Definition: errno.cpp:91
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
unsigned long DWORD
Definition: ntddk_ex.h:95
#define _doserrno
Definition: stdlib.h:131
__forceinline int __CRTDECL __ascii_towupper(int const _C)
Definition: ctype.h:185
__u8 drive_number
Definition: mkdosfs.c:0
#define L(x)
Definition: ntvdm.h:50
#define errno
Definition: errno.h:18
int __cdecl _chdrive(int const drive_number)
Definition: drive.cpp:58
int __cdecl _getdrive()
Definition: drive.cpp:25
static int __cdecl get_drive_number_from_path(wchar_t const *const path)
Definition: drive.cpp:13
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_INVALID_DRIVE
Definition: winerror.h:118