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 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 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 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 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 142 int wmain(int argc, WCHAR *argv[]) 143 { 144 WCHAR szRootPath[] = L" :\\"; 145 WCHAR szBuffer[80]; 146 WCHAR szLabel[80]; 147 WCHAR szOldLabel[80]; 148 DWORD dwSerialNr; 149 INT len, i; 150 151 /* Initialize the Console Standard Streams */ 152 ConInitStdStreams(); 153 154 /* set empty label string */ 155 szLabel[0] = UNICODE_NULL; 156 157 /* print help */ 158 if (argc > 1 && wcscmp(argv[1], L"/?") == 0) 159 { 160 ConResPuts(StdOut, STRING_LABEL_HELP); 161 return 0; 162 } 163 164 if (argc > 1) 165 { 166 len = 0; 167 for (i = 1; i < argc; i++) 168 { 169 if (i > 1) 170 len++; 171 len += wcslen(argv[i]); 172 } 173 174 if (len > MAX_LABEL_LENGTH + MAX_DRIVE_LENGTH) 175 { 176 ConResPuts(StdOut, STRING_ERROR_INVALID_LABEL); 177 return 1; 178 } 179 180 for (i = 1; i < argc; i++) 181 { 182 if (i > 1) 183 wcscat(szBuffer, L" "); 184 wcscat(szBuffer, argv[i]); 185 } 186 } 187 188 if (wcslen(szBuffer) > 0) 189 { 190 if (szBuffer[1] == L':') 191 { 192 szRootPath[0] = towupper(szBuffer[0]); 193 wcscpy(szLabel, &szBuffer[2]); 194 } 195 else 196 { 197 wcscpy(szLabel, szBuffer); 198 } 199 } 200 201 if (wcslen(szLabel) > MAX_LABEL_LENGTH) 202 { 203 ConResPuts(StdOut, STRING_ERROR_INVALID_LABEL); 204 return 1; 205 } 206 207 if (szRootPath[0] == L' ') 208 { 209 /* get label of current drive */ 210 WCHAR szCurPath[MAX_PATH]; 211 GetCurrentDirectoryW(MAX_PATH, szCurPath); 212 szRootPath[0] = szCurPath[0]; 213 } 214 215 /* check root path */ 216 if (!IsValidPathName(szRootPath)) 217 { 218 ConResPuts(StdErr, STRING_ERROR_INVALID_DRIVE); 219 return 1; 220 } 221 222 if (wcslen(szLabel) == 0) 223 { 224 GetVolumeInformationW(szRootPath, szOldLabel, ARRAYSIZE(szOldLabel), &dwSerialNr, 225 NULL, NULL, NULL, 0); 226 227 /* print drive info */ 228 if (szOldLabel[0] != UNICODE_NULL) 229 { 230 ConResPrintf(StdOut, STRING_LABEL_TEXT1, towupper(szRootPath[0]), szOldLabel); 231 } 232 else 233 { 234 ConResPrintf(StdOut, STRING_LABEL_TEXT2, towupper(szRootPath[0])); 235 } 236 237 /* print the volume serial number */ 238 ConResPrintf(StdOut, STRING_LABEL_TEXT3, HIWORD(dwSerialNr), LOWORD(dwSerialNr)); 239 240 ConResPuts(StdOut, STRING_LABEL_TEXT4); 241 242 ConInString(szLabel, ARRAYSIZE(szLabel)); 243 ConPuts(StdOut, L"\n"); 244 245 if (wcslen(szLabel) == 0) 246 { 247 if (PromptYesNo() == FALSE) 248 return 0; 249 } 250 } 251 252 if (!SetVolumeLabelW(szRootPath, szLabel)) 253 { 254 ConFormatMessage(StdOut, GetLastError()); 255 return 1; 256 } 257 258 return 0; 259 } 260 261 /* EOF */ 262