GPL sync + delete value implemented
[reactos.git] / rosapps / sysutils / regexpl / ShellCommandDir.cpp
1 /* $Id: ShellCommandDir.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $
2 *
3 * regexpl - Console Registry Explorer
4 *
5 * Copyright (C) 2000 Nedko Arnaoudov <nedkohome@atia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23 // ShellCommandDir.cpp: implementation of the CShellCommandDir class.
24 //
25 //////////////////////////////////////////////////////////////////////
26
27 #include "ph.h"
28 #include "RegistryExplorer.h"
29 #include "ShellCommandDir.h"
30 #include "RegistryTree.h"
31 #include "RegistryKey.h"
32
33 // *** THIS SHOULD GO IN A MINGW/ROS HEADER (tchar.h ???) - Begin
34 #if 1 // #ifndef _ui64tot ???
35 #ifdef _UNICODE
36 #define _ui64tot _ui64tow
37 #else
38 #define _ui64tot _ui64toa
39 #endif
40 #endif
41 // *** THIS SHOULD GO IN A MINGW/ROS HEADER - End
42
43 #define DIR_CMD _T("DIR")
44 #define DIR_CMD_LENGTH COMMAND_LENGTH(DIR_CMD)
45 #define DIR_CMD_SHORT_DESC DIR_CMD _T(" command lists keys and values of any key.\n")
46
47 //////////////////////////////////////////////////////////////////////
48 // Construction/Destruction
49 //////////////////////////////////////////////////////////////////////
50
51 CShellCommandDir::CShellCommandDir(CRegistryTree& rTree):m_rTree(rTree)
52 {
53 }
54
55 CShellCommandDir::~CShellCommandDir()
56 {
57 }
58
59 BOOL CShellCommandDir::Match(const TCHAR *pchCommand)
60 {
61 if (_tcsicmp(pchCommand,DIR_CMD) == 0)
62 return TRUE;
63 if (_tcsnicmp(pchCommand,DIR_CMD _T(".."),DIR_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
64 return TRUE;
65 if (_tcsnicmp(pchCommand,DIR_CMD _T("/"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
66 return TRUE;
67 if (_tcsnicmp(pchCommand,DIR_CMD _T("\\"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
68 return TRUE;
69 return FALSE;
70 }
71
72 int CShellCommandDir::Execute(CConsole &rConsole, CArgumentParser& rArguments)
73 {
74 rArguments.ResetArgumentIteration();
75
76 const TCHAR *pchKey = NULL;
77 BOOL blnDo = TRUE,blnBadParameter, blnHelp = FALSE;
78 const TCHAR *pchParameter;
79 const TCHAR *pchCommandItself = rArguments.GetNextArgument();
80
81 if ((_tcsnicmp(pchCommandItself,DIR_CMD _T(".."),DIR_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
82 (_tcsnicmp(pchCommandItself,DIR_CMD _T("\\"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
83 {
84 pchKey = pchCommandItself + DIR_CMD_LENGTH;
85 }
86 else if (_tcsnicmp(pchCommandItself,DIR_CMD _T("/"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
87 {
88 pchParameter = pchCommandItself + DIR_CMD_LENGTH;
89 goto CheckDirArgument;
90 }
91
92 while((pchParameter = rArguments.GetNextArgument()) != NULL)
93 {
94 CheckDirArgument:
95 blnBadParameter = FALSE;
96 if ((_tcsicmp(pchParameter,_T("/?")) == 0)
97 ||(_tcsicmp(pchParameter,_T("-?")) == 0))
98 {
99 blnHelp = TRUE;
100 blnDo = pchKey != NULL;
101 }
102 else if (!pchKey)
103 {
104 pchKey = pchParameter;
105 blnDo = TRUE;
106 }
107 else
108 {
109 blnBadParameter = TRUE;
110 }
111 if (blnBadParameter)
112 {
113 rConsole.Write(_T("Bad parameter: "));
114 rConsole.Write(pchParameter);
115 rConsole.Write(_T("\n"));
116 }
117 }
118
119 CRegistryTree *pTree = NULL;
120 CRegistryKey *pKey = NULL;
121 if (pchKey)
122 {
123 pTree = new CRegistryTree(m_rTree);
124 if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)||
125 (!pTree->ChangeCurrentKey(pchKey)))
126 {
127 rConsole.Write(_T("Cannot open key "));
128 rConsole.Write(pchKey);
129 rConsole.Write(_T("\n"));
130 //blnHelp = TRUE;
131 blnDo = FALSE;
132 }
133 else
134 {
135 pKey = pTree->GetCurrentKey();
136 }
137 }
138 else
139 {
140 pKey = m_rTree.GetCurrentKey();
141 }
142
143 if (blnHelp)
144 {
145 rConsole.Write(GetHelpString());
146 }
147
148 DWORD dwError;
149
150 if (blnDo)
151 {
152 rConsole.Write(_T("\n Key is "));
153 // rConsole.Write(_T("\\"));
154 rConsole.Write(pTree?pTree->GetCurrentPath():m_rTree.GetCurrentPath());
155 if (pKey)
156 {
157 rConsole.Write(_T("\n Last modify time is "));
158 rConsole.Write(pKey->GetLastWriteTime());
159 }
160 rConsole.Write(_T("\n\n"));
161 unsigned __int64 nTotalItems = 0;
162 if (!pKey)
163 {
164 rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_CLASSES_ROOT\\\n"));
165 rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_CURRENT_USER\\\n"));
166 rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_LOCAL_MACHINE\\\n"));
167 rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_USERS\\\n"));
168 rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_PERFORMANCE_DATA\\\n"));
169 rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_CURRENT_CONFIG\\\n"));
170 rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_DYN_DATA\\\n"));
171 nTotalItems = 7;
172 }
173 else
174 {
175 dwError = ERROR_SUCCESS;
176 try
177 {
178 if (!pKey->IsPredefined())
179 {
180 dwError = pKey->Open(KEY_QUERY_VALUE|KEY_READ);
181 if (dwError != ERROR_SUCCESS) throw dwError;
182 }
183
184 ASSERT(nTotalItems == 0);
185 rConsole.Write(_T("\t(KEY)\t\t\t\t..\\\n")); // parent key abstraction
186 nTotalItems = 1;
187
188 pKey->InitSubKeyEnumeration();
189 TCHAR *pchSubKeyName;
190 while ((pchSubKeyName = pKey->GetSubKeyName(dwError)) != NULL)
191 {
192 rConsole.Write(_T("\t(KEY)\t\t\t\t"));
193 rConsole.Write(pchSubKeyName);
194 rConsole.Write(_T("\\\n"));
195 nTotalItems++;
196 }
197 if ((dwError != ERROR_SUCCESS)&&(dwError != ERROR_NO_MORE_ITEMS)) throw dwError;
198
199 pKey->InitValueEnumeration();
200 TCHAR *pchValueName;
201 DWORD dwValueNameLength, dwMaxValueNameLength;
202 dwError = pKey->GetMaxValueNameLength(dwMaxValueNameLength);
203 if (dwError != ERROR_SUCCESS) throw dwError;
204 dwMaxValueNameLength++;
205 pchValueName = new TCHAR [dwMaxValueNameLength];
206 DWORD Type;
207 for(;;)
208 {
209 dwValueNameLength = dwMaxValueNameLength;
210 //dwValueSize = dwMaxValueSize;
211 dwError = pKey->GetNextValue(pchValueName,dwValueNameLength,&Type,
212 NULL,//pDataBuffer
213 NULL//&dwValueSize
214 );
215 if (dwError == ERROR_NO_MORE_ITEMS) break;
216 if (dwError != ERROR_SUCCESS) throw dwError;
217 rConsole.Write(_T("\t"));
218 rConsole.Write(CRegistryKey::GetValueTypeName(Type));
219 rConsole.Write(_T("\t"));
220 rConsole.Write((dwValueNameLength == 0)?_T("(Default)"):pchValueName);
221 rConsole.Write(_T("\n"));
222 nTotalItems++;
223 } // for
224 delete [] pchValueName;
225 } // try
226 catch (DWORD dwError)
227 {
228 rConsole.Write(_T("Error "));
229 TCHAR Buffer[256];
230 rConsole.Write(_itot(dwError,Buffer,10));
231 rConsole.Write(_T("\n"));
232 }
233 } // else (Tree.IsCurrentRoot())
234
235 rConsole.Write(_T("\n Total: "));
236 TCHAR Buffer[256];
237 rConsole.Write(_ui64tot(nTotalItems,Buffer,10));
238 rConsole.Write(_T(" item(s) listed.\n"));
239 if (pTree) delete pTree;
240 } // if (blnDo)
241
242 return 0;
243 }
244
245 const TCHAR * CShellCommandDir::GetHelpString()
246 {
247 return DIR_CMD_SHORT_DESC
248 _T("Syntax: ") DIR_CMD _T(" [<KEY>] [/?]\n\n")
249 _T(" <KEY> - Optional relative path to the key on which command will be executed\n")
250 _T(" /? - This help.\n\n")
251 _T("Without parameters, command lists keys and values of current key.\n");
252 }
253
254 const TCHAR * CShellCommandDir::GetHelpShortDescriptionString()
255 {
256 return DIR_CMD_SHORT_DESC;
257 }