1 /* $Id: ShellCommandValue.cpp 54034 2011-10-06 21:36:10Z pschweitzer $
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
*pszEmpty
= _T("");
126 const TCHAR
*pszPath
;
130 rConsole
.Write(GetHelpString());
140 if (_tcscmp(pchValueFull
,_T("\\")) == 0)
141 goto ValueCommandNAonRoot
;
143 TCHAR
*pchSep
= _tcsrchr(pchValueFull
,_T('\\'));
144 pchValueName
= pchSep
?(pchSep
+1):(pchValueFull
);
145 pszPath
= pchSep
?pchValueFull
:_T(".");
147 //if (_tcsrchr(pchValueName,_T('.')))
149 // pchValueName = _T("");
150 // pchPath = pchValueFull;
158 pchValueName
= (TCHAR
*)pszEmpty
;
162 if (!m_rTree
.GetKey(pszPath
,KEY_READ
,Key
))
164 rConsole
.Write(m_rTree
.GetLastErrorDescription());
165 goto SkipValueCommand
;
169 goto ValueCommandNAonRoot
;
172 rConsole
.Write(_T("Value name : \""));
173 rConsole
.Write(_T("\\"));
174 rConsole
.Write(Key
.GetKeyName());
175 size_t l
= _tcslen(pchValueName
);
177 (*pchValueName
== _T('\"'))&&
178 (pchValueName
[l
-1] == _T('\"')))
180 pchValueName
[l
-1] = 0;
183 rConsole
.Write(pchValueName
);
184 rConsole
.Write(_T("\"\n"));
186 nError
= Key
.GetValue(pchValueName
,NULL
,NULL
,&dwValueSize
);
187 if (nError
== ERROR_SUCCESS
)
189 pDataBuffer
= new BYTE
[dwValueSize
];
190 Key
.GetValue(pchValueName
,&dwType
,pDataBuffer
,&dwValueSize
);
191 rConsole
.Write(_T("Value type : "));
192 rConsole
.Write(CRegistryKey::GetValueTypeName(dwType
));
193 rConsole
.Write(_T("\nValue data : "));
196 case REG_DWORD_LITTLE_ENDIAN
:
199 rConsole
.Write(_T("0x"));
200 for (unsigned int i
= 0 ; i
< dwValueSize
; i
++)
202 _stprintf(Buffer
,_T("%02X"),*(pDataBuffer
+((dwValueSize
-1)-i
)));
203 rConsole
.Write(Buffer
);
206 rConsole
.Write(_T("\n"));
208 case REG_DWORD_BIG_ENDIAN
:
211 rConsole
.Write(_T("0x"));
212 for (unsigned int i
= 0 ; i
< dwValueSize
; i
++)
214 _stprintf(Buffer
,_T("%02X"),*(pDataBuffer
+i
));
215 rConsole
.Write(Buffer
);
218 rConsole
.Write(_T("\n"));
224 TCHAR
*pchCurrentString
= (TCHAR
*)pDataBuffer
;
225 rConsole
.Write(_T("\n"));
226 while(*pchCurrentString
)
228 rConsole
.Write(_T("\""));
229 rConsole
.Write(pchCurrentString
);
230 rConsole
.Write(_T("\"\n"));
231 pchCurrentString
+= _tcslen(pchCurrentString
)+1;
235 case REG_RESOURCE_LIST
:
239 rConsole
.Write(_T("\""));
240 rConsole
.Write((TCHAR
*)pDataBuffer
);
241 rConsole
.Write(_T("\"\n"));
248 for (i
= 0 ; i
< dwValueSize
; i
++)
251 { // ok this is begining of line
252 rConsole
.Write(_T("\n"));
254 _stprintf(Buffer
,_T("0x%08X "),(unsigned int)i
);
255 rConsole
.Write(Buffer
);
258 { // this is the additional space between 7th and 8th byte in current line
259 rConsole
.Write(_T(" "));
262 // print current byte
263 unsigned int n
= *(pDataBuffer
+i
);
264 _stprintf(Buffer
,_T("%02X "),n
);
265 rConsole
.Write(Buffer
);
267 if (i
&& (i
%16 == 15))
268 { // if this is the last byte in line
269 // Dump text representation
270 for (j
= i
-15; j
<= i
; j
+= blnUnicodeDump
?2:1)\
272 if ((j
%8 == 0)&&(j
%16 != 0))
273 { // this is the additional space between 7th and 8th byte in current line
274 rConsole
.Write(_T(" "));
277 // write current char representation
281 wchar_t ch
= *(TCHAR
*)(pDataBuffer
+j
);
287 // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3))
288 // %C in format string is a Microsoft extension.
291 iswprint(ch
)?ch
:L
'.');
295 unsigned char ch
= *(pDataBuffer
+j
);
299 // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3))
300 // %C in format string is a Microsoft extension.
307 rConsole
.Write(Buffer
);
312 // print text representation of last line if it is not full (it have less than 16 bytes)
313 // k is pseudo offset
314 for (DWORD k
= i
; k
%16 != 0; k
++)
317 { // this is the additional space between 7th and 8th byte in current line
318 rConsole
.Write(_T(" "));
320 _tcscpy(Buffer
,_T(" ")); // the replacement of two digit of current byte + spacing
321 rConsole
.Write(Buffer
);
322 if (k
&& (k
%16 == 15))
323 { // if this is the last byte in line
324 ASSERT((k
-15)%16 == 0); // k-15 must point at begin of last line
325 for (j
= k
-15; j
< i
; j
+= blnUnicodeDump
?2:1)
327 if (blnUnicodeDump
&&(j
+1 >= i
))
328 { // ok, buffer size is odd number, so we don't display last byte.
332 if ((j
%8 == 0)&&(j
%16 != 0))
333 { // this is the additional space between 7th and 8th byte in current line
334 rConsole
.Write(_T(" "));
337 // write current char representation
341 wchar_t ch
= *(TCHAR
*)(pDataBuffer
+j
);
347 // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3))
348 // %C in format string is a Microsoft extension.
351 iswprint(ch
)?ch
:L
'.');
355 unsigned char ch
= *(pDataBuffer
+j
);
359 // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3))
360 // %C in format string is a Microsoft extension.
367 rConsole
.Write(Buffer
);
372 rConsole
.Write(_T("\n"));
374 rConsole
.Write(_T("\n"));
378 rConsole
.Write(_T("Exporting value data to "));
379 rConsole
.Write(pchFilename
);
380 rConsole
.Write(_T(" ...\n"));
382 HANDLE hFile
= CreateFile(pchFilename
,GENERIC_WRITE
,0,NULL
,CREATE_NEW
,FILE_ATTRIBUTE_NORMAL
,NULL
);
383 if (hFile
== INVALID_HANDLE_VALUE
)
385 rConsole
.Write(_T("Cannot create new file "));
386 rConsole
.Write(pchFilename
);
387 rConsole
.Write(_T("\n"));
388 goto SkipValueCommand
;
391 DWORD dwBytesWritten
;
392 if (!WriteFile(hFile
,pDataBuffer
,dwValueSize
,&dwBytesWritten
,NULL
))
394 rConsole
.Write(_T("Error writting file.\n"));
395 VERIFY(CloseHandle(hFile
));
396 goto SkipValueCommand
;
399 ASSERT(dwBytesWritten
== dwValueSize
);
400 VERIFY(CloseHandle(hFile
));
405 rConsole
.Write(_T("Error "));
407 rConsole
.Write(_itoa(nError
,Buffer
,10));
408 rConsole
.Write(_T("\n"));
409 if (nError
== ERROR_FILE_NOT_FOUND
)
411 rConsole
.Write(_T("(System cannot find the value specified)\n"));
418 delete[] pDataBuffer
;
420 ValueCommandNAonRoot
:
421 rConsole
.Write(VALUE_CMD COMMAND_NA_ON_ROOT
);
425 const TCHAR
* CShellCommandValue::GetHelpString()
427 return VALUE_CMD_SHORT_DESC
428 _T("Syntax: ") VALUE_CMD
_T(" [<PATH>][<VALUE_NAME>] [/u] [/?]\n\n")
429 _T(" <PATH> - Optional relative path of key which value will be processed.\n")
430 _T(" <VALUE_NAME> - Name of key's value. Default is key's default value.\n")
431 _T(" /u - On binary dump view as Unicode.\n")
432 _T(" /fFILE - Export value data to FILE.\n")
433 _T(" /? - This help.\n\n")
434 _T("Without parameters, command displays default value of current key.\n");
437 const TCHAR
* CShellCommandValue::GetHelpShortDescriptionString()
439 return VALUE_CMD_SHORT_DESC
;