2 * regexpl - Console Registry Explorer
4 * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
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.
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.
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.
22 // ShellCommandValue.cpp: implementation of the CShellCommandValue class.
24 //////////////////////////////////////////////////////////////////////
27 #include "RegistryExplorer.h"
28 #include "ShellCommandValue.h"
29 #include "RegistryTree.h"
30 #include "RegistryKey.h"
32 #define VALUE_CMD _T("VV")
33 #define VALUE_CMD_LENGTH COMMAND_LENGTH(VALUE_CMD)
34 #define VALUE_CMD_SHORT_DESC VALUE_CMD _T(" command is used to view value.\n")
36 //////////////////////////////////////////////////////////////////////
37 // Construction/Destruction
38 //////////////////////////////////////////////////////////////////////
40 CShellCommandValue::CShellCommandValue(CRegistryTree
& rTree
):m_rTree(rTree
)
44 CShellCommandValue::~CShellCommandValue()
48 BOOL
CShellCommandValue::Match(const TCHAR
*pchCommand
)
50 if (_tcsicmp(pchCommand
,VALUE_CMD
) == 0)
52 if (_tcsnicmp(pchCommand
,VALUE_CMD
_T(".."),VALUE_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)
54 if (_tcsnicmp(pchCommand
,VALUE_CMD
_T("/"),VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
56 if (_tcsnicmp(pchCommand
,VALUE_CMD
_T("\\"),VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
61 int CShellCommandValue::Execute(CConsole
&rConsole
, CArgumentParser
& rArguments
)
63 rArguments
.ResetArgumentIteration();
64 TCHAR
*pchCommandItself
= rArguments
.GetNextArgument();
67 TCHAR
*pchValueFull
= NULL
;
68 BOOL blnUnicodeDump
= FALSE
;
69 BOOL blnBadParameter
= FALSE
;
73 DWORD dwType
= REG_NONE
;
74 BYTE
*pDataBuffer
= NULL
;
75 TCHAR
*pchFilename
= NULL
;
77 if ((_tcsnicmp(pchCommandItself
,VALUE_CMD
_T(".."),VALUE_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)||
78 (_tcsnicmp(pchCommandItself
,VALUE_CMD
_T("\\"),VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0))
80 pchValueFull
= pchCommandItself
+ VALUE_CMD_LENGTH
;
82 else if (_tcsnicmp(pchCommandItself
,VALUE_CMD
_T("/"),VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
84 pchParameter
= pchCommandItself
+ VALUE_CMD_LENGTH
;
85 goto CheckValueArgument
;
88 while((pchParameter
= rArguments
.GetNextArgument()) != NULL
)
91 blnBadParameter
= FALSE
;
92 if ((_tcsicmp(pchParameter
,_T("/?")) == 0)
93 ||(_tcsicmp(pchParameter
,_T("-?")) == 0))
98 else if (_tcsicmp(pchParameter
,_T("/u")) == 0)
100 blnUnicodeDump
= TRUE
;
102 else if ((*pchParameter
== _T('/'))&&(*(pchParameter
+1) == _T('f')))
104 pchFilename
= pchParameter
+2;
106 else if (!pchValueFull
)
108 pchValueFull
= pchParameter
;
112 blnBadParameter
= TRUE
;
116 rConsole
.Write(_T("Bad parameter: "));
117 rConsole
.Write(pchParameter
);
118 rConsole
.Write(_T("\n"));
124 const TCHAR
*pszEmpty
= _T("");
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
= (TCHAR
*)pszEmpty
;
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"));
417 delete[] pDataBuffer
;
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
;