Added MORE command.
[reactos.git] / rosapps / cmd / free.c
1 /*
2 * FREE.C - internal command.
3 *
4 *
5 * History:
6 *
7 * 01-Sep-1999 (Eric Kohl)
8 * Started.
9 */
10
11 #include "config.h"
12
13 #ifdef INCLUDE_CMD_FREE
14
15 #include <windows.h>
16 #include <tchar.h>
17 #include <string.h>
18 #include <stdio.h>
19 #include <ctype.h>
20
21 #include "cmd.h"
22
23
24 /*
25 * convert
26 *
27 * insert commas into a number
28 */
29
30 static INT
31 ConvertULargeInteger (ULARGE_INTEGER num, LPTSTR des, INT len)
32 {
33 TCHAR temp[32];
34 INT c = 0;
35 INT n = 0;
36
37 if (num.QuadPart == 0)
38 {
39 des[0] = _T('0');
40 des[1] = _T('\0');
41 n = 1;
42 }
43 else
44 {
45 temp[31] = 0;
46 while (num.QuadPart > 0)
47 {
48 if (((c + 1) % (nNumberGroups + 1)) == 0)
49 temp[30 - c++] = cThousandSeparator;
50 temp[30 - c++] = (TCHAR)(num.QuadPart % 10) + _T('0');
51 num.QuadPart /= 10;
52 }
53
54 for (n = 0; n <= c; n++)
55 des[n] = temp[31 - c + n];
56 }
57
58 return n;
59 }
60
61
62 static VOID
63 PrintDiskInfo (LPTSTR szDisk)
64 {
65 TCHAR szRootPath[4] = "A:\\";
66 TCHAR szDrive[2] = "A";
67 TCHAR szVolume[64];
68 TCHAR szSerial[10];
69 TCHAR szTotal[40];
70 TCHAR szUsed[40];
71 TCHAR szFree[40];
72 DWORD dwSerial;
73 ULARGE_INTEGER uliSize;
74 DWORD dwSecPerCl;
75 DWORD dwBytPerSec;
76 DWORD dwFreeCl;
77 DWORD dwTotCl;
78
79 if (_tcslen (szDisk) < 2 || szDisk[1] != _T(':'))
80 {
81 ConErrPrintf (_T("Invalid drive %s\n"), szDisk);
82 return;
83 }
84
85 szRootPath[0] = szDisk[0];
86 szDrive[0] = _totupper (szRootPath[0]);
87
88 if (!GetVolumeInformation (szRootPath, szVolume, 64, &dwSerial,
89 NULL, NULL, NULL, 0))
90 {
91 ConErrPrintf (_T("Invalid drive %s:\n"), szDrive);
92 return;
93 }
94
95 if (szVolume[0] == _T('\0'))
96 _tcscpy (szVolume, _T("unlabeled"));
97
98 _stprintf (szSerial,
99 _T("%04X-%04X"),
100 HIWORD(dwSerial),
101 LOWORD(dwSerial));
102
103 if (!GetDiskFreeSpace (szRootPath, &dwSecPerCl,
104 &dwBytPerSec, &dwFreeCl, &dwTotCl))
105 {
106 ConErrPrintf (_T("Invalid drive %s:\n"), szDrive);
107 return;
108 }
109
110 uliSize.QuadPart = dwSecPerCl * dwBytPerSec * dwTotCl;
111 ConvertULargeInteger (uliSize, szTotal, 40);
112
113 uliSize.QuadPart = dwSecPerCl * dwBytPerSec * (dwTotCl - dwFreeCl);
114 ConvertULargeInteger (uliSize, szUsed, 40);
115
116 uliSize.QuadPart = dwSecPerCl * dwBytPerSec * dwFreeCl;
117 ConvertULargeInteger (uliSize, szFree, 40);
118
119 ConOutPrintf (_T("\n"
120 " Volume in drive %s is %-11s Serial number is %s\n"
121 " %16s bytes total disk space\n"
122 " %16s bytes used\n"
123 " %16s bytes free\n"),
124 szDrive, szVolume, szSerial,
125 szTotal, szUsed, szFree);
126 }
127
128
129 INT CommandFree (LPTSTR cmd, LPTSTR param)
130 {
131 LPTSTR szParam;
132 TCHAR szDefPath[MAX_PATH];
133 INT argc, i;
134 LPTSTR *arg;
135
136 if (!_tcsncmp (param, _T("/?"), 2))
137 {
138 ConOutPuts (_T("Displays drive information.\n"
139 "\n"
140 "FREE [drive: ...]"));
141 return 0;
142 }
143
144 if (!param || *param == _T('\0'))
145 {
146 GetCurrentDirectory (MAX_PATH, szDefPath);
147 szDefPath[2] = _T('\0');
148 szParam = szDefPath;
149 }
150 else
151 szParam = param;
152
153 arg = split (szParam, &argc);
154
155 for (i = 0; i < argc; i++)
156 PrintDiskInfo (arg[i]);
157
158 freep (arg);
159
160 return 0;
161 }
162
163 #endif /* INCLUDE_CMD_FREE */
164
165 /* EOF */