1 /*
2 * LABEL.C - label internal command.
3 *
4 *
5 * History:
6 *
7 * 10-Dec-1998 (Eric Kohl)
8 * Started.
9 *
10 * 11-Dec-1998 (Eric Kohl)
11 * Finished.
12 *
13 * 19-Jan-1998 (Eric Kohl)
14 * Unicode ready!
15 *
16 * 28-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
17 * Remove all hardcoded strings in En.rc
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include <windef.h>
24 #include <winbase.h>
25 #include <wincon.h>
26 #include <winnls.h>
27 #include <winuser.h>
28
29 #include <conutils.h>
30
31 #include "resource.h"
32
33 #define MAX_LABEL_LENGTH 32
34 #define MAX_DRIVE_LENGTH 2
35
36
37 static
38 VOID
ConFormatMessage(PCON_STREAM Stream,DWORD MessageId,...)39 ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...)
40 {
41 va_list arg_ptr;
42
43 va_start(arg_ptr, MessageId);
44 ConMsgPrintfV(Stream,
45 FORMAT_MESSAGE_FROM_SYSTEM,
46 NULL,
47 MessageId,
48 LANG_USER_DEFAULT,
49 &arg_ptr);
50 va_end(arg_ptr);
51 }
52
53
54 static
55 VOID
ConInString(LPWSTR lpInput,DWORD dwLength)56 ConInString(LPWSTR lpInput, DWORD dwLength)
57 {
58 DWORD dwOldMode;
59 DWORD dwRead = 0;
60 HANDLE hFile;
61 LPWSTR p;
62 PCHAR pBuf;
63
64 pBuf = (PCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength - 1);
65
66 hFile = GetStdHandle(STD_INPUT_HANDLE);
67 GetConsoleMode(hFile, &dwOldMode);
68
69 SetConsoleMode(hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
70
71 ReadFile(hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL);
72
73 MultiByteToWideChar(GetConsoleCP(), 0, pBuf, dwRead, lpInput, dwLength - 1);
74 HeapFree(GetProcessHeap(), 0, pBuf);
75
76 for (p = lpInput; *p; p++)
77 {
78 if (*p == L'\x0d')
79 {
80 *p = UNICODE_NULL;
81 break;
82 }
83 }
84
85 SetConsoleMode(hFile, dwOldMode);
86 }
87
88
89 static
90 BOOL
IsValidPathName(LPCWSTR pszPath)91 IsValidPathName(LPCWSTR pszPath)
92 {
93 WCHAR szOldPath[MAX_PATH];
94 BOOL bResult;
95
96 GetCurrentDirectoryW(MAX_PATH, szOldPath);
97 bResult = SetCurrentDirectoryW(pszPath);
98
99 SetCurrentDirectoryW(szOldPath);
100
101 return bResult;
102 }
103
104
105 static
106 BOOL
PromptYesNo(VOID)107 PromptYesNo(VOID)
108 {
109 WCHAR szOptions[4];
110 WCHAR szInput[16];
111 BOOL bResult = FALSE;
112
113 LoadString(GetModuleHandle(NULL), STRING_LABEL_OPTIONS, szOptions, ARRAYSIZE(szOptions));
114
115 for (;;)
116 {
117 ConPuts(StdOut, L"\n");
118 ConResPuts(StdOut, STRING_LABEL_PROMPT);
119
120 ConInString(szInput, ARRAYSIZE(szInput));
121
122 if (towupper(szInput[0]) == szOptions[0])
123 {
124 bResult = TRUE;
125 break;
126 }
127 else if (towupper(szInput[0]) == szOptions[1])
128 {
129 bResult = FALSE;
130 break;
131 }
132
133 ConPuts(StdOut, L"\n");
134 }
135
136 ConPuts(StdOut, L"\n");
137
138 return bResult;
139 }
140
141
wmain(int argc,WCHAR * argv[])142 int wmain(int argc, WCHAR *argv[])
143 {
144 WCHAR szRootPath[] = L" :\\";
145 WCHAR szBuffer[80] = L"";
146 WCHAR szLabel[80] = L"";
147 WCHAR szOldLabel[80];
148 DWORD dwSerialNr;
149 INT len, i;
150
151 /* Initialize the Console Standard Streams */
152 ConInitStdStreams();
153
154 /* print help */
155 if (argc > 1 && wcscmp(argv[1], L"/?") == 0)
156 {
157 ConResPuts(StdOut, STRING_LABEL_HELP);
158 return 0;
159 }
160
161 if (argc > 1)
162 {
163 len = 0;
164 for (i = 1; i < argc; i++)
165 {
166 if (i > 1)
167 len++;
168 len += wcslen(argv[i]);
169 }
170
171 if (len > MAX_LABEL_LENGTH + MAX_DRIVE_LENGTH)
172 {
173 ConResPuts(StdOut, STRING_ERROR_INVALID_LABEL);
174 return 1;
175 }
176
177 for (i = 1; i < argc; i++)
178 {
179 if (i > 1)
180 wcscat(szBuffer, L" ");
181 wcscat(szBuffer, argv[i]);
182 }
183 }
184
185 if (wcslen(szBuffer) > 0)
186 {
187 if (szBuffer[1] == L':')
188 {
189 szRootPath[0] = towupper(szBuffer[0]);
190 wcscpy(szLabel, &szBuffer[2]);
191 }
192 else
193 {
194 wcscpy(szLabel, szBuffer);
195 }
196 }
197
198 if (wcslen(szLabel) > MAX_LABEL_LENGTH)
199 {
200 ConResPuts(StdOut, STRING_ERROR_INVALID_LABEL);
201 return 1;
202 }
203
204 if (szRootPath[0] == L' ')
205 {
206 /* get label of current drive */
207 WCHAR szCurPath[MAX_PATH];
208 GetCurrentDirectoryW(MAX_PATH, szCurPath);
209 szRootPath[0] = szCurPath[0];
210 }
211
212 /* check root path */
213 if (!IsValidPathName(szRootPath))
214 {
215 ConResPuts(StdErr, STRING_ERROR_INVALID_DRIVE);
216 return 1;
217 }
218
219 if (wcslen(szLabel) == 0)
220 {
221 GetVolumeInformationW(szRootPath, szOldLabel, ARRAYSIZE(szOldLabel), &dwSerialNr,
222 NULL, NULL, NULL, 0);
223
224 /* print drive info */
225 if (szOldLabel[0] != UNICODE_NULL)
226 {
227 ConResPrintf(StdOut, STRING_LABEL_TEXT1, towupper(szRootPath[0]), szOldLabel);
228 }
229 else
230 {
231 ConResPrintf(StdOut, STRING_LABEL_TEXT2, towupper(szRootPath[0]));
232 }
233
234 /* print the volume serial number */
235 ConResPrintf(StdOut, STRING_LABEL_TEXT3, HIWORD(dwSerialNr), LOWORD(dwSerialNr));
236
237 ConResPuts(StdOut, STRING_LABEL_TEXT4);
238
239 ConInString(szLabel, ARRAYSIZE(szLabel));
240 ConPuts(StdOut, L"\n");
241
242 if (wcslen(szLabel) == 0)
243 {
244 if (PromptYesNo() == FALSE)
245 return 0;
246 }
247 }
248
249 if (!SetVolumeLabelW(szRootPath, szLabel))
250 {
251 ConFormatMessage(StdOut, GetLastError());
252 return 1;
253 }
254
255 return 0;
256 }
257
258 /* EOF */
259