ReactOS 0.4.16-dev-1025-gd3456f5
getcwd.cpp
Go to the documentation of this file.
1/***
2*getcwd.cpp - get current working directory
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7*
8* contains functions _getcwd, _getdcwd and _getcdrv for getting the
9* current working directory. getcwd gets the c.w.d. for the default disk
10* drive, whereas _getdcwd allows one to get the c.w.d. for whatever disk
11* drive is specified. _getcdrv gets the current drive.
12*
13*******************************************************************************/
14#include <corecrt_internal.h>
16#include <direct.h>
17#include <errno.h>
18#include <malloc.h>
19#include <stdlib.h>
20
21
22
23// Tests whether the specified drive number is valid. Returns zero if the drive
24// does not exist; returns one if the drive exists. Pass zero as an argument to
25// check the default drive.
26static int __cdecl is_valid_drive(unsigned const drive_number) throw()
27{
28 if (drive_number > 26)
29 {
31 _VALIDATE_RETURN(("Invalid Drive Index" ,0), EACCES, 0);
32 }
33
34 if (drive_number == 0)
35 return 1;
36
37#pragma warning(suppress:__WARNING_UNUSED_ASSIGNMENT) // 28931
38 wchar_t const drive_letter = static_cast<wchar_t>(L'A' + drive_number - 1);
39 wchar_t const drive_string[] = { drive_letter, L':', L'\\', L'\0' };
40
41 UINT const drive_type = GetDriveTypeW(drive_string);
42 if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR)
43 return 0;
44
45 return 1;
46}
47
48
49
50/***
51*_TSCHAR *_getcwd(pnbuf, maxlen) - get current working directory of default drive
52*
53*Purpose:
54* _getcwd gets the current working directory for the user,
55* placing it in the buffer pointed to by pnbuf. If the length
56* of the string exceeds the length of the buffer, maxlen,
57* then nullptr is returned. If pnbuf = nullptr, a buffer of at
58* least size maxlen is automatically allocated using
59* malloc() -- a pointer to which is returned by _getcwd().
60* An entry point "_getdcwd()" is defined which takes the above
61* parameters, plus a drive number. "_getcwd()" is implemented
62* as a call to "_getdcwd()" with the default drive (0).
63*
64* side effects: no global data is used or affected
65*
66*Entry:
67* _TSCHAR *pnbuf = pointer to a buffer maintained by the user;
68* int maxlen = length of the buffer pointed to by pnbuf;
69*
70*Exit:
71* Returns pointer to the buffer containing the c.w.d. name
72* (same as pnbuf if non-nullptr; otherwise, malloc is
73* used to allocate a buffer)
74*
75*Exceptions:
76*
77*******************************************************************************/
78
79/***
80*_TSCHAR *_getdcwd(drive, pnbuf, maxlen) - get c.w.d. for given drive
81*
82*Purpose:
83* _getdcwd gets the current working directory for the user,
84* placing it in the buffer pointed to by pnbuf. If the length
85* of the string exceeds the length of the buffer, maxlen,
86* then nullptr is returned. If pnbuf = nullptr, a buffer of at
87* least size maxlen is automatically allocated using
88* malloc() -- a pointer to which is returned by _getdcwd().
89*
90* side effects: no global data is used or affected
91*
92*Entry:
93* int drive - number of the drive being inquired about
94* 0 = default, 1 = 'a:', 2 = 'b:', etc.
95* _TSCHAR *pnbuf - pointer to a buffer maintained by the user;
96* int maxlen - length of the buffer pointed to by pnbuf;
97*
98*Exit:
99* Returns pointer to the buffer containing the c.w.d. name
100* (same as pnbuf if non-nullptr; otherwise, malloc is
101* used to allocate a buffer)
102*
103*Exceptions:
104*
105*******************************************************************************/
106
107template <typename Character>
108_Success_(return != 0)
110static Character* __cdecl common_getdcwd(
111 int drive_number,
112 _Out_writes_opt_z_(max_count) Character* user_buffer,
118{
119 typedef __crt_char_traits<Character> traits;
120
121 _VALIDATE_RETURN(max_count >= 0, EINVAL, nullptr);
122
123 if (drive_number != 0)
124 {
125 // A drive other than the default drive was requested; make sure it
126 // is a valid drive number:
128 {
130 _VALIDATE_RETURN(("Invalid Drive", 0), EACCES, nullptr);
131 }
132 }
133 else
134 {
135 // Otherwise, get the drive number of the default drive:
137 }
138
139 Character drive_string[4];
140 if (drive_number != 0)
141 {
142 drive_string[0] = static_cast<Character>('A' - 1 + drive_number);
143 drive_string[1] = ':';
144 drive_string[2] = '.';
145 drive_string[3] = '\0';
146 }
147 else
148 {
149 drive_string[0] = '.';
150 drive_string[1] = '\0';
151 }
152
153 if (user_buffer == nullptr)
154 { // Always new memory suitable for debug mode and releasing to the user.
157 );
158 buffer.allocate(max_count);
159 if (!traits::get_full_path_name(drive_string, buffer))
160 {
161 return buffer.detach();
162 }
163 return nullptr;
164 }
165
166 // Using user buffer. Fail if not enough space.
167 _VALIDATE_RETURN(max_count > 0, EINVAL, nullptr);
168 user_buffer[0] = '\0';
169
171 if (!traits::get_full_path_name(drive_string, buffer))
172 {
173 return user_buffer;
174 }
175 return nullptr;
176};
177
178
179
180extern "C" char* __cdecl _getcwd(
181 char* const user_buffer,
182 int const max_length
183 )
184{
185 return common_getdcwd(0, user_buffer, max_length, _NORMAL_BLOCK, nullptr, 0);
186}
187
188extern "C" wchar_t* __cdecl _wgetcwd(
189 wchar_t* const user_buffer,
190 int const max_length
191 )
192{
193 return common_getdcwd(0, user_buffer, max_length, _NORMAL_BLOCK, nullptr, 0);
194}
195
196extern "C" char* __cdecl _getdcwd(
197 int const drive_number,
198 char* const user_buffer,
199 int const max_length
200 )
201{
202 return common_getdcwd(drive_number, user_buffer, max_length, _NORMAL_BLOCK, nullptr, 0);
203}
204
205extern "C" wchar_t* __cdecl _wgetdcwd(
206 int const drive_number,
207 wchar_t* const user_buffer,
208 int const max_length
209 )
210{
211 return common_getdcwd(drive_number, user_buffer, max_length, _NORMAL_BLOCK, nullptr, 0);
212}
213
214#ifdef _DEBUG
215
216#undef _getcwd_dbg
217#undef _getdcwd_dbg
218
219extern "C" char* __cdecl _getcwd_dbg(
220 char* const user_buffer,
221 int const max_length,
222 int const block_use,
223 char const* const file_name,
224 int const line_number
225 )
226{
227 return common_getdcwd(0, user_buffer, max_length, block_use, file_name, line_number);
228}
229
230extern "C" wchar_t* __cdecl _wgetcwd_dbg(
231 wchar_t* const user_buffer,
232 int const max_length,
233 int const block_use,
234 char const* const file_name,
235 int const line_number
236 )
237{
238 return common_getdcwd(0, user_buffer, max_length, block_use, file_name, line_number);
239}
240
241extern "C" char* __cdecl _getdcwd_dbg(
242 int const drive_number,
243 char* const user_buffer,
244 int const max_length,
245 int const block_use,
246 char const* const file_name,
247 int const line_number
248 )
249{
250 return common_getdcwd(drive_number, user_buffer, max_length, block_use, file_name, line_number);
251}
252
253extern "C" wchar_t* __cdecl _wgetdcwd_dbg(
254 int const drive_number,
255 wchar_t* const user_buffer,
256 int const max_length,
257 int const block_use,
258 char const* const file_name,
259 int const line_number
260 )
261{
262 return common_getdcwd(drive_number, user_buffer, max_length, block_use, file_name, line_number);
263}
264
265#endif // _DEBUG
#define EINVAL
Definition: acclib.h:90
#define EACCES
Definition: acclib.h:85
#define __cdecl
Definition: accygwin.h:79
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
#define _wgetdcwd_dbg(d, s, le, t, f, l)
Definition: crtdbg.h:233
#define _getdcwd_dbg(d, s, le, t, f, l)
Definition: crtdbg.h:232
#define _NORMAL_BLOCK
Definition: crtdbg.h:67
#define _wgetcwd_dbg(s, le, t, f, l)
Definition: crtdbg.h:231
#define _getcwd_dbg(s, le, t, f, l)
Definition: crtdbg.h:230
_Check_return_ _CRTIMP int __cdecl _getdrive(void)
Definition: getdrive.c:20
int const char const *const int const line_number
Definition: debug_heap.cpp:499
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
char *__cdecl _getdcwd(int const drive_number, char *const user_buffer, int const max_length)
Definition: getcwd.cpp:196
char *__cdecl _getcwd(char *const user_buffer, int const max_length)
Definition: getcwd.cpp:180
static int __cdecl is_valid_drive(unsigned const drive_number)
Definition: getcwd.cpp:26
int const int const _In_opt_z_ char const *const int const line_number throw()
Definition: getcwd.cpp:117
wchar_t *__cdecl _wgetdcwd(int const drive_number, wchar_t *const user_buffer, int const max_length)
Definition: getcwd.cpp:205
wchar_t *__cdecl _wgetcwd(wchar_t *const user_buffer, int const max_length)
Definition: getcwd.cpp:188
int const max_count
Definition: getcwd.cpp:113
int const int const _In_opt_z_ char const *const file_name
Definition: getcwd.cpp:115
int const int const block_use
Definition: getcwd.cpp:114
GLuint buffer
Definition: glext.h:5915
#define _doserrno
Definition: stdlib.h:131
__u8 drive_number
Definition: mkdosfs.c:0
unsigned int UINT
Definition: ndis.h:50
#define _Success_(c)
Definition: no_sal2.h:84
#define _In_opt_z_
Definition: no_sal2.h:218
#define _Out_writes_opt_z_(s)
Definition: no_sal2.h:230
#define _Ret_z_
Definition: no_sal2.h:306
#define L(x)
Definition: ntvdm.h:50
#define DRIVE_UNKNOWN
Definition: winbase.h:282
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:283
#define ERROR_INVALID_DRIVE
Definition: winerror.h:118
#define const
Definition: zconf.h:233