Something went wrong. Try again.
Reactos
Something went wrong. Try again.
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440/* * regexpl - Console Registry Explorer * * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */
// ShellCommandValue.cpp: implementation of the CShellCommandValue class.////////////////////////////////////////////////////////////////////////
#include "ph.h"#include "RegistryExplorer.h"#include "ShellCommandValue.h"#include "RegistryTree.h"#include "RegistryKey.h"
#define VALUE_CMD _T("VV")#define VALUE_CMD_LENGTH COMMAND_LENGTH(VALUE_CMD)#define VALUE_CMD_SHORT_DESC VALUE_CMD _T(" command is used to view value.\n")
//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////
CShellCommandValue::CShellCommandValue(CRegistryTree& rTree):m_rTree(rTree){}
CShellCommandValue::~CShellCommandValue(){}
BOOL CShellCommandValue::Match(const TCHAR *pchCommand){ if (_tcsicmp(pchCommand,VALUE_CMD) == 0) return TRUE; if (_tcsnicmp(pchCommand,VALUE_CMD _T(".."),VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0) return TRUE; if (_tcsnicmp(pchCommand,VALUE_CMD _T("/"),VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) return TRUE; if (_tcsnicmp(pchCommand,VALUE_CMD _T("\\"),VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) return TRUE; return FALSE;}
int CShellCommandValue::Execute(CConsole &rConsole, CArgumentParser& rArguments){ rArguments.ResetArgumentIteration(); TCHAR *pchCommandItself = rArguments.GetNextArgument();
TCHAR *pchParameter; TCHAR *pchValueFull = NULL; BOOL blnUnicodeDump = FALSE; BOOL blnBadParameter = FALSE; BOOL blnHelp = FALSE; LONG nError; DWORD dwValueSize; DWORD dwType = REG_NONE; BYTE *pDataBuffer = NULL; TCHAR *pchFilename = NULL;
if ((_tcsnicmp(pchCommandItself,VALUE_CMD _T(".."),VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)|| (_tcsnicmp(pchCommandItself,VALUE_CMD _T("\\"),VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)) { pchValueFull = pchCommandItself + VALUE_CMD_LENGTH; } else if (_tcsnicmp(pchCommandItself,VALUE_CMD _T("/"),VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) { pchParameter = pchCommandItself + VALUE_CMD_LENGTH; goto CheckValueArgument; }
while((pchParameter = rArguments.GetNextArgument()) != NULL) {CheckValueArgument: blnBadParameter = FALSE; if ((_tcsicmp(pchParameter,_T("/?")) == 0) ||(_tcsicmp(pchParameter,_T("-?")) == 0)) { blnHelp = TRUE; break; } else if (_tcsicmp(pchParameter,_T("/u")) == 0) { blnUnicodeDump = TRUE; } else if ((*pchParameter == _T('/'))&&(*(pchParameter+1) == _T('f'))) { pchFilename = pchParameter+2; } else if (!pchValueFull) { pchValueFull = pchParameter; } else { blnBadParameter = TRUE; } if (blnBadParameter) { rConsole.Write(_T("Bad parameter: ")); rConsole.Write(pchParameter); rConsole.Write(_T("\n")); } }
CRegistryKey Key; TCHAR *pchValueName; const TCHAR *pszEmpty = _T(""); const TCHAR *pszPath;
if (blnHelp) { rConsole.Write(GetHelpString());
if (pDataBuffer) delete pDataBuffer;
return 0; }
if (pchValueFull) { if (_tcscmp(pchValueFull,_T("\\")) == 0) goto ValueCommandNAonRoot;
TCHAR *pchSep = _tcsrchr(pchValueFull,_T('\\')); pchValueName = pchSep?(pchSep+1):(pchValueFull); pszPath = pchSep?pchValueFull:_T(".");
//if (_tcsrchr(pchValueName,_T('.'))) //{ // pchValueName = _T(""); // pchPath = pchValueFull; //} //else if (pchSep) *pchSep = 0; } else { pchValueName = (TCHAR*)pszEmpty; pszPath = _T("."); }
if (!m_rTree.GetKey(pszPath,KEY_READ,Key)) { rConsole.Write(m_rTree.GetLastErrorDescription()); goto SkipValueCommand; }
if (Key.IsRoot()) goto ValueCommandNAonRoot;
{ rConsole.Write(_T("Value name : \"")); rConsole.Write(_T("\\")); rConsole.Write(Key.GetKeyName()); size_t l = _tcslen(pchValueName); if (l&& (*pchValueName == _T('\"'))&& (pchValueName[l-1] == _T('\"'))) { pchValueName[l-1] = 0; pchValueName++; } rConsole.Write(pchValueName); rConsole.Write(_T("\"\n"));
nError = Key.GetValue(pchValueName,NULL,NULL,&dwValueSize); if (nError == ERROR_SUCCESS) { pDataBuffer = new BYTE [dwValueSize]; Key.GetValue(pchValueName,&dwType,pDataBuffer,&dwValueSize); rConsole.Write(_T("Value type : ")); rConsole.Write(CRegistryKey::GetValueTypeName(dwType)); rConsole.Write(_T("\nValue data : ")); switch(dwType) { case REG_DWORD_LITTLE_ENDIAN: { TCHAR Buffer[3]; rConsole.Write(_T("0x")); for (unsigned int i = 0 ; i < dwValueSize ; i++) { _stprintf(Buffer,_T("%02X"),*(pDataBuffer+((dwValueSize-1)-i))); rConsole.Write(Buffer); } } rConsole.Write(_T("\n")); break; case REG_DWORD_BIG_ENDIAN: { TCHAR Buffer[3]; rConsole.Write(_T("0x")); for (unsigned int i = 0 ; i < dwValueSize ; i++) { _stprintf(Buffer,_T("%02X"),*(pDataBuffer+i)); rConsole.Write(Buffer); } } rConsole.Write(_T("\n")); break; case REG_LINK: break; case REG_MULTI_SZ: { TCHAR *pchCurrentString = (TCHAR *)pDataBuffer; rConsole.Write(_T("\n")); while(*pchCurrentString) { rConsole.Write(_T("\"")); rConsole.Write(pchCurrentString); rConsole.Write(_T("\"\n")); pchCurrentString += _tcslen(pchCurrentString)+1; } } break; case REG_RESOURCE_LIST: break; case REG_SZ: case REG_EXPAND_SZ: rConsole.Write(_T("\"")); rConsole.Write((TCHAR *)pDataBuffer); rConsole.Write(_T("\"\n")); break; case REG_BINARY: default: { TCHAR Buffer[256]; DWORD i, j; for (i = 0 ; i < dwValueSize ; i++) { if (i%16 == 0) { // ok this is begining of line rConsole.Write(_T("\n")); // print offset _stprintf(Buffer,_T("0x%08X "),(unsigned int)i); rConsole.Write(Buffer); } else if (i%8 == 0) { // this is the additional space between 7th and 8th byte in current line rConsole.Write(_T(" ")); }
// print current byte unsigned int n = *(pDataBuffer+i); _stprintf(Buffer,_T("%02X "),n); rConsole.Write(Buffer);
if (i && (i%16 == 15)) { // if this is the last byte in line // Dump text representation for (j = i-15; j <= i; j += blnUnicodeDump?2:1)\ { if ((j%8 == 0)&&(j%16 != 0)) { // this is the additional space between 7th and 8th byte in current line rConsole.Write(_T(" ")); } ASSERT(i-j < 16); // write current char representation if (blnUnicodeDump) { ASSERT(j%2 == 0); wchar_t ch = *(TCHAR *)(pDataBuffer+j);
_stprintf(Buffer,#ifdef _UNICODE _T("%c"),#else // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3)) // %C in format string is a Microsoft extension. _T("%C"),#endif iswprint(ch)?ch:L'.'); } else { unsigned char ch = *(pDataBuffer+j);
_stprintf(Buffer,#ifdef _UNICODE // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3)) // %C in format string is a Microsoft extension. _T("%C"),#else _T("%c"),#endif isprint(ch)?ch:'.'); } rConsole.Write(Buffer); } // for } // if } // for
// print text representation of last line if it is not full (it have less than 16 bytes) // k is pseudo offset for (DWORD k = i; k%16 != 0; k++) { if (k%8 == 0) { // this is the additional space between 7th and 8th byte in current line rConsole.Write(_T(" ")); } _tcscpy(Buffer,_T(" ")); // the replacement of two digit of current byte + spacing rConsole.Write(Buffer); if (k && (k%16 == 15)) { // if this is the last byte in line ASSERT((k-15)%16 == 0); // k-15 must point at begin of last line for (j = k-15; j < i; j += blnUnicodeDump?2:1) { if (blnUnicodeDump&&(j+1 >= i)) { // ok, buffer size is odd number, so we don't display last byte. ASSERT(j+1 == i); break; } if ((j%8 == 0)&&(j%16 != 0)) { // this is the additional space between 7th and 8th byte in current line rConsole.Write(_T(" ")); }
// write current char representation if (blnUnicodeDump) { ASSERT(j%2 == 0); wchar_t ch = *(TCHAR *)(pDataBuffer+j);
_stprintf(Buffer,#ifdef _UNICODE _T("%c"),#else // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3)) // %C in format string is a Microsoft extension. _T("%C"),#endif iswprint(ch)?ch:L'.'); } else { unsigned char ch = *(pDataBuffer+j);
_stprintf(Buffer,#ifdef _UNICODE // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3)) // %C in format string is a Microsoft extension. _T("%C"),#else _T("%c"),#endif isprint(ch)?ch:'.'); } rConsole.Write(Buffer); } // for } // if } // for } // default: rConsole.Write(_T("\n")); } // switch rConsole.Write(_T("\n"));
if (pchFilename) { rConsole.Write(_T("Exporting value data to ")); rConsole.Write(pchFilename); rConsole.Write(_T(" ...\n"));
HANDLE hFile = CreateFile(pchFilename,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL); if (hFile == INVALID_HANDLE_VALUE) { rConsole.Write(_T("Cannot create new file ")); rConsole.Write(pchFilename); rConsole.Write(_T("\n")); goto SkipValueCommand; }
DWORD dwBytesWritten; if (!WriteFile(hFile,pDataBuffer,dwValueSize,&dwBytesWritten,NULL)) { rConsole.Write(_T("Error writing file.\n")); VERIFY(CloseHandle(hFile)); goto SkipValueCommand; }
ASSERT(dwBytesWritten == dwValueSize); VERIFY(CloseHandle(hFile)); } } else { rConsole.Write(_T("Error ")); TCHAR Buffer[256]; rConsole.Write(_itoa(nError,Buffer,10)); rConsole.Write(_T("\n")); if (nError == ERROR_FILE_NOT_FOUND) { rConsole.Write(_T("(System cannot find the value specified)\n")); } } }
SkipValueCommand: if (pDataBuffer) delete[] pDataBuffer; return 0;ValueCommandNAonRoot: rConsole.Write(VALUE_CMD COMMAND_NA_ON_ROOT); return 0;}
const TCHAR * CShellCommandValue::GetHelpString(){ return VALUE_CMD_SHORT_DESC _T("Syntax: ") VALUE_CMD _T(" [<PATH>][<VALUE_NAME>] [/u] [/?]\n\n") _T(" <PATH> - Optional relative path of key which value will be processed.\n") _T(" <VALUE_NAME> - Name of key's value. Default is key's default value.\n") _T(" /u - On binary dump view as Unicode.\n") _T(" /fFILE - Export value data to FILE.\n") _T(" /? - This help.\n\n") _T("Without parameters, command displays default value of current key.\n");}
const TCHAR * CShellCommandValue::GetHelpShortDescriptionString(){ return VALUE_CMD_SHORT_DESC;}