xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // UserInputUtils.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Common/StdInStream.h"
6 #include "../../../Common/StringConvert.h"
7 
8 #include "UserInputUtils.h"
9 
10 static const char kYes = 'y';
11 static const char kNo = 'n';
12 static const char kYesAll = 'a';
13 static const char kNoAll = 's';
14 static const char kAutoRenameAll = 'u';
15 static const char kQuit = 'q';
16 
17 static const char * const kFirstQuestionMessage = "? ";
18 static const char * const kHelpQuestionMessage =
19   "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? ";
20 
21 // return true if pressed Quite;
22 
ScanUserYesNoAllQuit(CStdOutStream * outStream)23 NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
24 {
25   if (outStream)
26     *outStream << kFirstQuestionMessage;
27   for (;;)
28   {
29     if (outStream)
30     {
31       *outStream << kHelpQuestionMessage;
32       outStream->Flush();
33     }
34     AString scannedString;
35     if (!g_StdIn.ScanAStringUntilNewLine(scannedString))
36       return NUserAnswerMode::kError;
37     if (g_StdIn.Error())
38       return NUserAnswerMode::kError;
39     scannedString.Trim();
40     if (scannedString.IsEmpty() && g_StdIn.Eof())
41       return NUserAnswerMode::kEof;
42 
43     if (scannedString.Len() == 1)
44       switch (::MyCharLower_Ascii(scannedString[0]))
45       {
46         case kYes:    return NUserAnswerMode::kYes;
47         case kNo:     return NUserAnswerMode::kNo;
48         case kYesAll: return NUserAnswerMode::kYesAll;
49         case kNoAll:  return NUserAnswerMode::kNoAll;
50         case kAutoRenameAll: return NUserAnswerMode::kAutoRenameAll;
51         case kQuit:   return NUserAnswerMode::kQuit;
52         default: break;
53       }
54   }
55 }
56 
57 #ifdef _WIN32
58 #ifndef UNDER_CE
59 #define MY_DISABLE_ECHO
60 #endif
61 #endif
62 
GetPassword(CStdOutStream * outStream,UString & psw)63 static bool GetPassword(CStdOutStream *outStream, UString &psw)
64 {
65   if (outStream)
66   {
67     *outStream << "\nEnter password"
68       #ifdef MY_DISABLE_ECHO
69       " (will not be echoed)"
70       #endif
71       ":";
72     outStream->Flush();
73   }
74 
75   #ifdef MY_DISABLE_ECHO
76 
77   const HANDLE console = GetStdHandle(STD_INPUT_HANDLE);
78 
79   /*
80   GetStdHandle() returns
81     INVALID_HANDLE_VALUE: If the function fails.
82     NULL : If an application does not have associated standard handles,
83            such as a service running on an interactive desktop,
84            and has not redirected them. */
85   bool wasChanged = false;
86   DWORD mode = 0;
87   if (console != INVALID_HANDLE_VALUE && console != NULL)
88     if (GetConsoleMode(console, &mode))
89       wasChanged = (SetConsoleMode(console, mode & ~(DWORD)ENABLE_ECHO_INPUT) != 0);
90   const bool res = g_StdIn.ScanUStringUntilNewLine(psw);
91   if (wasChanged)
92     SetConsoleMode(console, mode);
93 
94   #else
95 
96   const bool res = g_StdIn.ScanUStringUntilNewLine(psw);
97 
98   #endif
99 
100   if (outStream)
101   {
102     *outStream << endl;
103     outStream->Flush();
104   }
105 
106   return res;
107 }
108 
GetPassword_HRESULT(CStdOutStream * outStream,UString & psw)109 HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw)
110 {
111   if (!GetPassword(outStream, psw))
112     return E_INVALIDARG;
113   if (g_StdIn.Error())
114     return E_FAIL;
115   if (g_StdIn.Eof() && psw.IsEmpty())
116     return E_ABORT;
117   return S_OK;
118 }
119