1 /*
2  * regexpl - Console Registry Explorer
3  *
4  * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; see the file COPYING.  If not, write to
18  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
22 // RegistryExplorer.cpp : Defines the entry point for the Regiistry Explorer.
23 //
24 
25 #include "ph.h"
26 #include "RegistryExplorer.h"
27 #include "Console.h"
28 #include "RegistryKey.h"
29 #include "RegistryTree.h"
30 #include "SecurityDescriptor.h"
31 #include "ArgumentParser.h"
32 #include "ShellCommandsLinkedList.h"
33 #include "ShellCommandExit.h"
34 #include "ShellCommandVersion.h"
35 #include "ShellCommandHelp.h"
36 #include "ShellCommandDir.h"
37 #include "ShellCommandChangeKey.h"
38 #include "ShellCommandValue.h"
39 #include "ShellCommandOwner.h"
40 #include "ShellCommandDACL.h"
41 #include "ShellCommandSACL.h"
42 //#include "ShellCommandDOKA.h"
43 #include "ShellCommandConnect.h"
44 #include "ShellCommandNewKey.h"
45 #include "ShellCommandDeleteKey.h"
46 #include "ShellCommandSetValue.h"
47 #include "ShellCommandDeleteValue.h"
48 #include "Prompt.h"
49 #include "Settings.h"
50 
51 TCHAR pchCurrentKey[PROMPT_BUFFER_SIZE];
52 
53 CRegistryTree Tree;
54 CConsole Console;
55 
56 BOOL blnCommandExecutionInProgress = FALSE;
57 
58 BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
59 {
60 	switch(dwCtrlType)
61 	{
62 	case CTRL_C_EVENT:
63 	case CTRL_BREAK_EVENT:
64 		if (blnCommandExecutionInProgress)
65 		{
66 /*			Beep(1000,100);
67 			Beep(2000,100);
68 			Beep(3000,100);
69 			Beep(4000,100);
70 			Beep(5000,100);
71 			Beep(4000,100);
72 			Beep(3000,100);
73 			Beep(2000,100);
74 			Beep(1000,100);*/
75 			Console.Write(_T("\n"));
76 			Console.DisableWrite();
77 		}
78 		return TRUE;
79 	default:
80 		return FALSE;
81 	}
82 }
83 
84 //int _tmain(/*int argc, TCHAR* argv[], TCHAR* envp[]*/)
85 int main ()
86 {
87   int nRetCode = 0;
88 
89   HRESULT hr;
90 
91   CSettings *pSettings = NULL;
92   CPrompt *pPrompt = NULL;
93 
94   CShellCommandsLinkedList CommandsList(Console);
95 
96   CShellCommandExit ExitCommand;
97   CommandsList.AddCommand(&ExitCommand);
98 
99   CShellCommandVersion VersionCommand;
100   CommandsList.AddCommand(&VersionCommand);
101 
102   CShellCommandHelp HelpCommand(CommandsList);
103   CommandsList.AddCommand(&HelpCommand);
104 
105   CShellCommandDir DirCommand(Tree);
106   CommandsList.AddCommand(&DirCommand);
107 
108   CShellCommandChangeKey ChangeKeyCommand(Tree);
109   CommandsList.AddCommand(&ChangeKeyCommand);
110 
111   CShellCommandValue ValueCommand(Tree);
112   CommandsList.AddCommand(&ValueCommand);
113 
114   CShellCommandOwner OwnerCommand(Tree);
115   CommandsList.AddCommand(&OwnerCommand);
116 
117   CShellCommandDACL DACLCommand(Tree);
118   CommandsList.AddCommand(&DACLCommand);
119 
120   CShellCommandSACL SACLCommand(Tree);
121   CommandsList.AddCommand(&SACLCommand);
122 
123   CShellCommandConnect ConnectCommand(Tree);
124   CommandsList.AddCommand(&ConnectCommand);
125 
126   CShellCommandNewKey NewKeyCommand(Tree);
127   CommandsList.AddCommand(&NewKeyCommand);
128 
129   CShellCommandDeleteKey DeleteKeyCommand(Tree);
130   CommandsList.AddCommand(&DeleteKeyCommand);
131 
132   CShellCommandSetValue SetValueCommand(Tree);
133   CommandsList.AddCommand(&SetValueCommand);
134 
135   CShellCommandDeleteValue DeleteValueCommand(Tree);
136   CommandsList.AddCommand(&DeleteValueCommand);
137 
138   CArgumentParser Parser;
139 
140   pSettings = new (std::nothrow) CSettings();
141   if (!pSettings)
142 	{
143 		_ftprintf(stderr,_T("Cannot initialize settings. Out of memory.\n"));
144 		goto Abort;
145 	}
146 
147   hr = pSettings->Load(SETTINGS_REGISTRY_KEY);
148   if (FAILED(hr))
149 	{
150 		_ftprintf(stderr,_T("Cannot load settings. Error is 0x%X.\n"),(unsigned int)hr);
151 		goto Abort;
152 	}
153 
154   pPrompt = new (std::nothrow) CPrompt(Tree,hr);
155   if (!pPrompt)
156 	{
157 		_ftprintf(stderr,_T("Cannot initialize prompt. Out of memory.\n"));
158 		goto Abort;
159 	}
160 
161   if (FAILED(hr))
162 	{
163 		_ftprintf(stderr,_T("Cannot initialize prompt. Error is 0x%X.\n"),(unsigned int)hr);
164 		goto Abort;
165 	}
166 
167 // input buffer size in chars
168 #define INPUT_BUFFER_SIZE	1024
169 //#define INPUT_BUFFER_SIZE	128
170 //#define INPUT_BUFFER_SIZE	10
171 
172 	TCHAR *pchCommand;
173 
174   pchCommand = Console.Init(INPUT_BUFFER_SIZE,10);
175   if (pchCommand == NULL)
176   {
177     _ftprintf(stderr,_T("Cannot initialize console.\n"));
178     nRetCode = 1;
179     goto Exit;
180   }
181 
182 	Console.SetReplaceCompletionCallback(CompletionCallback);
183 
184 	WORD wOldConsoleAttribute;
185 	if (!Console.GetTextAttribute(wOldConsoleAttribute)) goto Abort;
186 
187 	Console.SetTitle(_T("Registry Explorer"));
188 	Console.SetTextAttribute(pSettings->GetNormalTextAttributes());
189 
190 	VERIFY(SetConsoleCtrlHandler((PHANDLER_ROUTINE)HandlerRoutine,TRUE));
191 
192 	if (!Console.Write(HELLO_MSG
193 	//(_L(__TIMESTAMP__))
194 	)) goto Abort;
195 
196   //Tree.SetDesiredOpenKeyAccess(KEY_READ);
197 
198   hr = pPrompt->SetPrompt(pSettings->GetPrompt());
199   if (FAILED(hr))
200   {
201     _ftprintf(stderr,_T("Cannot initialize prompt. Error is 0x%X.\n"),(unsigned int)hr);
202     goto Abort;
203   }
204 
205 GetCommand:
206 	// prompt
207 	// TODO: make prompt user-customizable
208 	Console.EnableWrite();
209 	pPrompt->ShowPrompt(Console);
210 	Console.FlushInputBuffer();
211 
212 	blnCommandExecutionInProgress = FALSE;
213 
214 	// Set command line color
215   Console.SetTextAttribute(pSettings->GetCommandTextAttributes());
216 	if (!Console.ReadLine())
217     goto Abort;
218 
219 	// Set normal color
220 	Console.SetTextAttribute(pSettings->GetNormalTextAttributes());
221 
222 	Console.BeginScrollingOperation();
223 	blnCommandExecutionInProgress = TRUE;
224 
225 	// Parse command line (1st step - convert to multi sz)
226 	Parser.SetArgumentList(pchCommand);
227 
228 	int nCommandReturnValue;
229 	switch(CommandsList.Execute(Parser,nCommandReturnValue))
230 	{
231 	case -1:	// not recognized command
232 		{
233 			Parser.ResetArgumentIteration();
234 			TCHAR *pchCommandItself = Parser.GetNextArgument();
235 			size_t cmdlen = _tcslen(pchCommandItself);
236 			if ((!cmdlen)||
237 				(pchCommandItself[cmdlen-1] != _T('\\'))||
238 				(Parser.GetNextArgument())||
239 				(!Tree.ChangeCurrentKey(pchCommandItself)))
240 			{
241 				Console.Write(_T("Unknown command \""));
242 				Console.Write(pchCommandItself);
243 				Console.Write(_T("\"\n"));
244 			}
245 		}
246 	case -2:	// empty line
247 		goto GetCommand;
248 	case 0:	// exit command
249 		nRetCode = 0;
250 		Console.SetTextAttribute(wOldConsoleAttribute);
251 		goto Exit;
252 	default:
253 		Console.Write(_T("\n"));
254 		goto GetCommand;
255 	}
256 
257 Abort:
258 	_ftprintf(stderr,_T("Abnormal program termination.\nPlease report bugs to ") EMAIL _T("\n"));
259 	nRetCode = 1;
260 
261 Exit:
262 
263   if (pSettings)
264     delete pSettings;
265 
266   if (pPrompt)
267     delete pPrompt;
268 
269 	return nRetCode;
270 }
271