Reactos
at listview 282 lines 7.2 kB view raw
1/* 2 * PROJECT: ReactOS Replace Command 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Internal helpers. See cmd/internal.c 5 * COPYRIGHT: Copyright Samuel Erdtman (samuel@erdtman.se) 6 * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 7 */ 8 9#include "replace.h" 10 11BOOL bCtrlBreak = FALSE; /* Ctrl-Break or Ctrl-C hit */ 12 13/* 14 * Helper function for getting the current path from drive 15 * without changing the drive. Return code: 0 = ok, 1 = fail. 16 * 'InPath' can have any size; if the two first letters are 17 * not a drive with ':' it will get the current path on 18 * the current drive exactly as GetCurrentDirectory() does. 19 */ 20INT 21GetRootPath( 22 IN LPCTSTR InPath, 23 OUT LPTSTR OutPath, 24 IN INT size) 25{ 26 if (InPath[0] && InPath[1] == _T(':')) 27 { 28 INT t = 0; 29 30 if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9'))) 31 { 32 t = (InPath[0] - _T('0')) + 28; 33 } 34 else if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z'))) 35 { 36 t = (InPath[0] - _T('a')) + 1; 37 } 38 else if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z'))) 39 { 40 t = (InPath[0] - _T('A')) + 1; 41 } 42 43 return (_tgetdcwd(t, OutPath, size) == NULL); 44 } 45 46 /* Get current directory */ 47 return !GetCurrentDirectory(size, OutPath); 48} 49 50/* 51 * Takes a path in and returns it with the correct case of the letters 52 */ 53VOID GetPathCase( TCHAR * Path, TCHAR * OutPath) 54{ 55 UINT i = 0; 56 TCHAR TempPath[MAX_PATH]; 57 WIN32_FIND_DATA FindFileData; 58 HANDLE hFind; 59 _tcscpy(TempPath, _T("")); 60 _tcscpy(OutPath, _T("")); 61 62 for(i = 0; i < _tcslen(Path); i++) 63 { 64 if (Path[i] != _T('\\')) 65 { 66 _tcsncat(TempPath, &Path[i], 1); 67 if (i != _tcslen(Path) - 1) 68 continue; 69 } 70 /* Handle the base part of the path different. 71 Because if you put it into findfirstfile, it will 72 return your current folder */ 73 if (_tcslen(TempPath) == 2 && TempPath[1] == _T(':')) 74 { 75 _tcscat(OutPath, TempPath); 76 _tcscat(OutPath, _T("\\")); 77 _tcscat(TempPath, _T("\\")); 78 } 79 else 80 { 81 hFind = FindFirstFile(TempPath,&FindFileData); 82 if (hFind == INVALID_HANDLE_VALUE) 83 { 84 _tcscpy(OutPath, Path); 85 return; 86 } 87 _tcscat(TempPath, _T("\\")); 88 _tcscat(OutPath, FindFileData.cFileName); 89 _tcscat(OutPath, _T("\\")); 90 FindClose(hFind); 91 } 92 } 93} 94 95/* 96 * Checks if a file exists (is accessible) 97 */ 98BOOL IsExistingFile(IN LPCTSTR pszPath) 99{ 100 DWORD attr = GetFileAttributes(pszPath); 101 return ((attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_DIRECTORY)); 102} 103 104BOOL IsExistingDirectory(IN LPCTSTR pszPath) 105{ 106 DWORD attr = GetFileAttributes(pszPath); 107 return ((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY)); 108} 109 110INT FilePromptYNA (UINT resID) 111{ 112 TCHAR szMsg[RC_STRING_MAX_SIZE]; 113// TCHAR cKey = 0; 114// LPTSTR szKeys = _T("yna"); 115 116 TCHAR szIn[10]; 117 LPTSTR p; 118 119 if (resID != 0) 120 ConOutResPrintf (resID); 121 122 /* preliminary fix */ 123 ConInString(szIn, 10); 124 125 _tcsupr (szIn); 126 for (p = szIn; _istspace (*p); p++) 127 ; 128 129 LoadString(NULL, STRING_COPY_OPTION, szMsg, ARRAYSIZE(szMsg)); 130 131 if (_tcsncmp(p, &szMsg[0], 1) == 0) 132 return PROMPT_YES; 133 else if (_tcsncmp(p, &szMsg[1], 1) == 0) 134 return PROMPT_NO; 135 else if (_tcsncmp(p, &szMsg[2], 1) == 0) 136 return PROMPT_ALL; 137#if 0 138 else if (*p == _T('\03')) 139 return PROMPT_BREAK; 140#endif 141 142 return PROMPT_NO; 143 144 /* unfinished solution */ 145#if 0 146 RemoveBreakHandler(); 147 ConInDisable(); 148 149 do 150 { 151 ConInKey (&ir); 152 cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); 153 if (_tcschr (szKeys, cKey[0]) == NULL) 154 cKey = 0; 155 } 156 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || 157 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || 158 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); 159 160 AddBreakHandler(); 161 ConInEnable(); 162 163 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || 164 ((ir.Event.KeyEvent.wVirtualKeyCode == _T('C')) && 165 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) 166 return PROMPT_BREAK; 167 168 return PROMPT_YES; 169#endif 170} 171 172VOID ConInString(LPTSTR lpInput, DWORD dwLength) 173{ 174 DWORD dwOldMode; 175 DWORD dwRead = 0; 176 HANDLE hFile; 177 178 LPTSTR p; 179 PCHAR pBuf; 180 181#ifdef _UNICODE 182 pBuf = (PCHAR)malloc(dwLength - 1); 183#else 184 pBuf = lpInput; 185#endif 186 ZeroMemory(lpInput, dwLength * sizeof(TCHAR)); 187 hFile = GetStdHandle(STD_INPUT_HANDLE); 188 GetConsoleMode(hFile, &dwOldMode); 189 190 SetConsoleMode(hFile, ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); 191 192 ReadFile(hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL); 193 194#ifdef _UNICODE 195 MultiByteToWideChar(GetConsoleCP(), 0, pBuf, dwRead, lpInput, dwLength - 1); 196 free(pBuf); 197#endif 198 for (p = lpInput; *p; p++) 199 { 200 if (*p == _T('\r')) // Terminate at the carriage-return. 201 { 202 *p = _T('\0'); 203 break; 204 } 205 } 206 207 SetConsoleMode(hFile, dwOldMode); 208} 209 210VOID msg_pause(VOID) 211{ 212 ConOutResPuts(STRING_ERROR_D_PAUSEMSG); 213} 214 215VOID __cdecl ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...) 216{ 217 INT Len; 218 va_list arg_ptr; 219 220 va_start(arg_ptr, MessageId); 221 Len = ConMsgPrintfV(Stream, 222 FORMAT_MESSAGE_FROM_SYSTEM, 223 NULL, 224 MessageId, 225 LANG_USER_DEFAULT, 226 &arg_ptr); 227 va_end(arg_ptr); 228 229 if (Len <= 0) 230 ConResPrintf(Stream, STRING_CONSOLE_ERROR, MessageId); 231} 232 233VOID ConOutChar(TCHAR c) 234{ 235 ConWrite(StdOut, &c, 1); 236} 237 238/* 239 * get a character out-of-band and honor Ctrl-Break characters 240 */ 241TCHAR 242cgetchar (VOID) 243{ 244 HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); 245 INPUT_RECORD irBuffer; 246 DWORD dwRead; 247 248 do 249 { 250 ReadConsoleInput (hInput, &irBuffer, 1, &dwRead); 251 if ((irBuffer.EventType == KEY_EVENT) && 252 (irBuffer.Event.KeyEvent.bKeyDown != FALSE)) 253 { 254 if (irBuffer.Event.KeyEvent.dwControlKeyState & 255 (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) 256 { 257 if (irBuffer.Event.KeyEvent.wVirtualKeyCode == 'C') 258 { 259 bCtrlBreak = TRUE; 260 break; 261 } 262 } 263 else if ((irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || 264 (irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || 265 (irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)) 266 { 267 // Nothing to do 268 } 269 else 270 { 271 break; 272 } 273 } 274 } 275 while (TRUE); 276 277#ifndef _UNICODE 278 return irBuffer.Event.KeyEvent.uChar.AsciiChar; 279#else 280 return irBuffer.Event.KeyEvent.uChar.UnicodeChar; 281#endif /* _UNICODE */ 282}