3 * regexpl - Console Registry Explorer
5 * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
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.
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.
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.
23 // ShellCommandValue.cpp: implementation of the CShellCommandValue class.
25 //////////////////////////////////////////////////////////////////////
28 #include "RegistryExplorer.h"
29 #include "ShellCommandValue.h"
30 #include "RegistryTree.h"
31 #include "RegistryKey.h"
33 #define VALUE_CMD _T("VV")
34 #define VALUE_CMD_LENGTH COMMAND_LENGTH(VALUE_CMD)
35 #define VALUE_CMD_SHORT_DESC VALUE_CMD _T(" command is used to view value.\n")
37 //////////////////////////////////////////////////////////////////////
38 // Construction/Destruction
39 //////////////////////////////////////////////////////////////////////
41 CShellCommandValue::CShellCommandValue(CRegistryTree
& rTree
):m_rTree(rTree
)
45 CShellCommandValue::~CShellCommandValue()
49 BOOL
CShellCommandValue::Match(const TCHAR
*pchCommand
)
51 if (_tcsicmp(pchCommand
,VALUE_CMD
) == 0)
53 if (_tcsnicmp(pchCommand
,VALUE_CMD
_T(".."),VALUE_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)
55 if (_tcsnicmp(pchCommand
,VALUE_CMD
_T("/"),VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
57 if (_tcsnicmp(pchCommand
,VALUE_CMD
_T("\\"),VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
62 int CShellCommandValue::Execute(CConsole
&rConsole
, CArgumentParser
& rArguments
)
64 rArguments
.ResetArgumentIteration();
65 TCHAR
*pchCommandItself
= rArguments
.GetNextArgument();
68 TCHAR
*pchValueFull
= NULL
;
69 BOOL blnUnicodeDump
= FALSE
;
70 BOOL blnBadParameter
= FALSE
;
74 DWORD dwType
= REG_NONE
;
75 BYTE
*pDataBuffer
= NULL
;
76 TCHAR
*pchFilename
= NULL
;
78 if ((_tcsnicmp(pchCommandItself
,VALUE_CMD
_T(".."),VALUE_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)||
79 (_tcsnicmp(pchCommandItself
,VALUE_CMD
_T("\\"),VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0))
81 pchValueFull
= pchCommandItself
+ VALUE_CMD_LENGTH
;
83 else if (_tcsnicmp(pchCommandItself
,VALUE_CMD
_T("/"),VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
85 pchParameter
= pchCommandItself
+ VALUE_CMD_LENGTH
;
86 goto CheckValueArgument
;
89 while((pchParameter
= rArguments
.GetNextArgument()) != NULL
)
92 blnBadParameter
= FALSE
;
93 if ((_tcsicmp(pchParameter
,_T("/?")) == 0)
94 ||(_tcsicmp(pchParameter
,_T("-?")) == 0))
99 else if (_tcsicmp(pchParameter
,_T("/u")) == 0)
101 blnUnicodeDump
= TRUE
;
103 else if ((*pchParameter
== _T('/'))&&(*(pchParameter
+1) == _T('f')))
105 pchFilename
= pchParameter
+2;
107 else if (!pchValueFull
)
109 pchValueFull
= pchParameter
;
113 blnBadParameter
= TRUE
;
117 rConsole
.Write(_T("Bad parameter: "));
118 rConsole
.Write(pchParameter
);
119 rConsole
.Write(_T("\n"));
125 const TCHAR
*pszPath
;
129 rConsole
.Write(GetHelpString());
139 if (_tcscmp(pchValueFull
,_T("\\")) == 0)
140 goto ValueCommandNAonRoot
;
142 TCHAR
*pchSep
= _tcsrchr(pchValueFull
,_T('\\'));
143 pchValueName
= pchSep
?(pchSep
+1):(pchValueFull
);
144 pszPath
= pchSep
?pchValueFull
:_T(".");
146 //if (_tcsrchr(pchValueName,_T('.')))
148 // pchValueName = _T("");
149 // pchPath = pchValueFull;
157 pchValueName
= _T("");
161 if (!m_rTree
.GetKey(pszPath
,KEY_READ
,Key
))
163 rConsole
.Write(m_rTree
.GetLastErrorDescription());
164 goto SkipValueCommand
;
168 goto ValueCommandNAonRoot
;
171 rConsole
.Write(_T("Value name : \""));
172 rConsole
.Write(_T("\\"));
173 rConsole
.Write(Key
.GetKeyName());
174 size_t l
= _tcslen(pchValueName
);
176 (*pchValueName
== _T('\"'))&&
177 (pchValueName
[l
-1] == _T('\"')))
179 pchValueName
[l
-1] = 0;
182 rConsole
.Write(pchValueName
);
183 rConsole
.Write(_T("\"\n"));
185 nError
= Key
.GetValue(pchValueName
,NULL
,NULL
,&dwValueSize
);
186 if (nError
== ERROR_SUCCESS
)
188 pDataBuffer
= new BYTE
[dwValueSize
];
189 Key
.GetValue(pchValueName
,&dwType
,pDataBuffer
,&dwValueSize
);
190 rConsole
.Write(_T("Value type : "));
191 rConsole
.Write(CRegistryKey::GetValueTypeName(dwType
));
192 rConsole
.Write(_T("\nValue data : "));
195 case REG_DWORD_LITTLE_ENDIAN
:
198 rConsole
.Write(_T("0x"));
199 for (unsigned int i
= 0 ; i
< dwValueSize
; i
++)
201 _stprintf(Buffer
,_T("%02X"),*(pDataBuffer
+((dwValueSize
-1)-i
)));
202 rConsole
.Write(Buffer
);
205 rConsole
.Write(_T("\n"));
207 case REG_DWORD_BIG_ENDIAN
:
210 rConsole
.Write(_T("0x"));
211 for (unsigned int i
= 0 ; i
< dwValueSize
; i
++)
213 _stprintf(Buffer
,_T("%02X"),*(pDataBuffer
+i
));
214 rConsole
.Write(Buffer
);
217 rConsole
.Write(_T("\n"));
223 TCHAR
*pchCurrentString
= (TCHAR
*)pDataBuffer
;
224 rConsole
.Write(_T("\n"));
225 while(*pchCurrentString
)
227 rConsole
.Write(_T("\""));
228 rConsole
.Write(pchCurrentString
);
229 rConsole
.Write(_T("\"\n"));
230 pchCurrentString
+= _tcslen(pchCurrentString
)+1;
234 case REG_RESOURCE_LIST
:
238 rConsole
.Write(_T("\""));
239 rConsole
.Write((TCHAR
*)pDataBuffer
);
240 rConsole
.Write(_T("\"\n"));
247 for (i
= 0 ; i
< dwValueSize
; i
++)
250 { // ok this is begining of line
251 rConsole
.Write(_T("\n"));
253 _stprintf(Buffer
,_T("0x%08X "),(unsigned int)i
);
254 rConsole
.Write(Buffer
);
257 { // this is the additional space between 7th and 8th byte in current line
258 rConsole
.Write(_T(" "));
261 // print current byte
262 unsigned int n
= *(pDataBuffer
+i
);
263 _stprintf(Buffer
,_T("%02X "),n
);
264 rConsole
.Write(Buffer
);
266 if (i
&& (i
%16 == 15))
267 { // if this is the last byte in line
268 // Dump text representation
269 for (j
= i
-15; j
<= i
; j
+= blnUnicodeDump
?2:1)\
271 if ((j
%8 == 0)&&(j
%16 != 0))
272 { // this is the additional space between 7th and 8th byte in current line
273 rConsole
.Write(_T(" "));
276 // write current char representation
280 wchar_t ch
= *(TCHAR
*)(pDataBuffer
+j
);
286 // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3))
287 // %C in format string is a Microsoft extension.
290 iswprint(ch
)?ch
:L
'.');
294 unsigned char ch
= *(pDataBuffer
+j
);
298 // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3))
299 // %C in format string is a Microsoft extension.
306 rConsole
.Write(Buffer
);
311 // print text representation of last line if it is not full (it have less than 16 bytes)
312 // k is pseudo offset
313 for (DWORD k
= i
; k
%16 != 0; k
++)
316 { // this is the additional space between 7th and 8th byte in current line
317 rConsole
.Write(_T(" "));
319 _tcscpy(Buffer
,_T(" ")); // the replacement of two digit of current byte + spacing
320 rConsole
.Write(Buffer
);
321 if (k
&& (k
%16 == 15))
322 { // if this is the last byte in line
323 ASSERT((k
-15)%16 == 0); // k-15 must point at begin of last line
324 for (j
= k
-15; j
< i
; j
+= blnUnicodeDump
?2:1)
326 if (blnUnicodeDump
&&(j
+1 >= i
))
327 { // ok, buffer size is odd number, so we don't display last byte.
331 if ((j
%8 == 0)&&(j
%16 != 0))
332 { // this is the additional space between 7th and 8th byte in current line
333 rConsole
.Write(_T(" "));
336 // write current char representation
340 wchar_t ch
= *(TCHAR
*)(pDataBuffer
+j
);
346 // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3))
347 // %C in format string is a Microsoft extension.
350 iswprint(ch
)?ch
:L
'.');
354 unsigned char ch
= *(pDataBuffer
+j
);
358 // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3))
359 // %C in format string is a Microsoft extension.
366 rConsole
.Write(Buffer
);
371 rConsole
.Write(_T("\n"));
373 rConsole
.Write(_T("\n"));
377 rConsole
.Write(_T("Exporting value data to "));
378 rConsole
.Write(pchFilename
);
379 rConsole
.Write(_T(" ...\n"));
381 HANDLE hFile
= CreateFile(pchFilename
,GENERIC_WRITE
,0,NULL
,CREATE_NEW
,FILE_ATTRIBUTE_NORMAL
,NULL
);
382 if (hFile
== INVALID_HANDLE_VALUE
)
384 rConsole
.Write(_T("Cannot create new file "));
385 rConsole
.Write(pchFilename
);
386 rConsole
.Write(_T("\n"));
387 goto SkipValueCommand
;
390 DWORD dwBytesWritten
;
391 if (!WriteFile(hFile
,pDataBuffer
,dwValueSize
,&dwBytesWritten
,NULL
))
393 rConsole
.Write(_T("Error writting file.\n"));
394 VERIFY(CloseHandle(hFile
));
395 goto SkipValueCommand
;
398 ASSERT(dwBytesWritten
== dwValueSize
);
399 VERIFY(CloseHandle(hFile
));
404 rConsole
.Write(_T("Error "));
406 rConsole
.Write(_itoa(nError
,Buffer
,10));
407 rConsole
.Write(_T("\n"));
408 if (nError
== ERROR_FILE_NOT_FOUND
)
410 rConsole
.Write(_T("(System cannot find the value specified)\n"));
419 ValueCommandNAonRoot
:
420 rConsole
.Write(VALUE_CMD COMMAND_NA_ON_ROOT
);
424 const TCHAR
* CShellCommandValue::GetHelpString()
426 return VALUE_CMD_SHORT_DESC
427 _T("Syntax: ") VALUE_CMD
_T(" [<PATH>][<VALUE_NAME>] [/u] [/?]\n\n")
428 _T(" <PATH> - Optional relative path of key which value will be processed.\n")
429 _T(" <VALUE_NAME> - Name of key's value. Default is key's default value.\n")
430 _T(" /u - On binary dump view as Unicode.\n")
431 _T(" /fFILE - Export value data to FILE.\n")
432 _T(" /? - This help.\n\n")
433 _T("Without parameters, command displays default value of current key.\n");
436 const TCHAR
* CShellCommandValue::GetHelpShortDescriptionString()
438 return VALUE_CMD_SHORT_DESC
;