xref: /reactos/sdk/lib/ucrt/misc/drivfree.cpp (revision a6a07059)
1 /***
2 *drivfree.c - Get the size of a disk
3 *
4 *       Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 *Purpose:
7 *       This file has _getdiskfree()
8 *
9 *******************************************************************************/
10 
11 #include <corecrt_internal.h>
12 #include <direct.h>
13 
14 
15 
16 // Gets the size information for the given drive.  The 'drive_number' must be a
17 // number, 1 through 26, corresponding to drives A: through Z:.  Returns zero on
18 // success; a system error code on failure.
19 extern "C" unsigned __cdecl _getdiskfree(
20     unsigned     const drive_number,
21     _diskfree_t* const result
22 )
23 {
24     _VALIDATE_RETURN(result != nullptr,  EINVAL, ERROR_INVALID_PARAMETER);
25     _VALIDATE_RETURN(drive_number <= 26, EINVAL, ERROR_INVALID_PARAMETER);
26 
27     *result = _diskfree_t();
28 
29     wchar_t drive_name_buffer[4] = { '_', ':', '\\', '\0' };
30 
31     wchar_t const* const drive_name = drive_number == 0
32         ? nullptr
33         : drive_name_buffer;
34 
35     if (drive_number != 0)
36     {
37         drive_name_buffer[0] = static_cast<wchar_t>(drive_number) + static_cast<wchar_t>(L'A' - 1);
38     }
39 
40     static_assert(sizeof(result->sectors_per_cluster) == sizeof(DWORD), "Unexpected sizeof long");
41 
42     if (!GetDiskFreeSpaceW(drive_name,
43         reinterpret_cast<LPDWORD>(&result->sectors_per_cluster),
44         reinterpret_cast<LPDWORD>(&result->bytes_per_sector),
45         reinterpret_cast<LPDWORD>(&result->avail_clusters),
46         reinterpret_cast<LPDWORD>(&result->total_clusters)))
47     {
48         int const os_error = GetLastError();
49         errno = __acrt_errno_from_os_error(os_error);
50 
51         return os_error;
52     }
53 
54     return 0;
55 }
56