Something went wrong. Try again.
Reactos
Something went wrong. Try again.
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435/* * 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. */
// ShellCommandSetValue.cpp: implementation of the CShellCommandSetValue class.////////////////////////////////////////////////////////////////////////
#include "ph.h"#include "ShellCommandSetValue.h"#include "RegistryExplorer.h"#include "RegistryTree.h"#include "RegistryKey.h"
#define SET_VALUE_CMD _T("SV")#define SET_VALUE_CMD_LENGTH COMMAND_LENGTH(SET_VALUE_CMD)#define SET_VALUE_CMD_SHORT_DESC SET_VALUE_CMD _T(" command is used to set value.\n")
BOOL StringToDWORD(DWORD& rdwOut, const TCHAR *pszIn){ const TCHAR *pszDigits; const TCHAR *pszOctalNumbers = _T("01234567"); const TCHAR *pszDecimalNumbers = _T("0123456789"); const TCHAR *pszHexNumbers = _T("0123456789ABCDEF"); const TCHAR *pszNumbers; unsigned int nBase = 0; if (*pszIn == _T('0')) { if ((*(pszIn+1) == _T('x'))||((*(pszIn+1) == _T('X')))) { // hex nBase = 16; pszDigits = pszIn+2; pszNumbers = pszHexNumbers; } else { // octal nBase = 8; pszDigits = pszIn+1; pszNumbers = pszOctalNumbers; } } else { //decimal nBase = 10; pszDigits = pszIn; pszNumbers = pszDecimalNumbers; }
const TCHAR *pszDigit = pszDigits; pszDigit += _tcslen(pszDigit);
DWORD nMul = 1; rdwOut = 0; DWORD dwAdd; const TCHAR *pszNumber; while (pszDigit > pszDigits) { pszDigit--; pszNumber = _tcschr(pszNumbers,*pszDigit); if (!pszNumber) return FALSE; // wrong char in input string
dwAdd = (pszNumber-pszNumbers)*nMul;
if (rdwOut + dwAdd < rdwOut) return FALSE; // overflow rdwOut += dwAdd;
if (nMul * nBase < nMul) return FALSE; // overflow nMul *= nBase; };
return TRUE;}
//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////
CShellCommandSetValue::CShellCommandSetValue(CRegistryTree& rTree):m_rTree(rTree){}
CShellCommandSetValue::~CShellCommandSetValue(){}
BOOL CShellCommandSetValue::Match(const TCHAR *pszCommand){ if (_tcsicmp(pszCommand,SET_VALUE_CMD) == 0) return TRUE; if (_tcsnicmp(pszCommand,SET_VALUE_CMD _T(".."),SET_VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0) return TRUE; if (_tcsnicmp(pszCommand,SET_VALUE_CMD _T("/"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) return TRUE; if (_tcsnicmp(pszCommand,SET_VALUE_CMD _T("\\"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) return TRUE; return FALSE;}
int CShellCommandSetValue::Execute(CConsole &rConsole, CArgumentParser& rArguments){ LONG nError;
rArguments.ResetArgumentIteration(); TCHAR *pszCommandItself = rArguments.GetNextArgument();
TCHAR *pszParameter; TCHAR *pszValueFull = NULL; TCHAR *pszValueData = NULL; BOOL blnBadParameter = FALSE; BOOL blnHelp = FALSE; DWORD dwValueSize = 0; DWORD dwType = REG_NONE; BYTE *pDataBuffer = NULL;
if ((_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T(".."),SET_VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)|| (_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T("\\"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)) { pszValueFull = pszCommandItself + SET_VALUE_CMD_LENGTH; } else if (_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T("/"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) { pszParameter = pszCommandItself + SET_VALUE_CMD_LENGTH; goto CheckValueArgument; }
while((pszParameter = rArguments.GetNextArgument()) != NULL) {CheckValueArgument: blnBadParameter = FALSE; if (((*pszParameter == _T('/'))||(*pszParameter == _T('-'))) &&(*(pszParameter+1) == _T('?'))) { blnHelp = TRUE; } else if (dwType == REG_NONE) { if (_tcsicmp(pszParameter,_T("b")) == 0) { dwType = REG_BINARY; } else if (_tcsicmp(pszParameter,_T("dw")) == 0) { dwType = REG_DWORD; } else if (_tcsicmp(pszParameter,_T("dwle")) == 0) { dwType = REG_DWORD_LITTLE_ENDIAN; } else if (_tcsicmp(pszParameter,_T("dwbe")) == 0) { dwType = REG_DWORD_BIG_ENDIAN; } else if (_tcsicmp(pszParameter,_T("sz")) == 0) { dwType = REG_SZ; } else if (_tcsicmp(pszParameter,_T("esz")) == 0) { dwType = REG_EXPAND_SZ; } else { blnBadParameter = TRUE; } } else if (pszValueData == NULL) { pszValueData = pszParameter; } else if (!pszValueFull) { pszValueFull = pszParameter; } else { blnBadParameter = TRUE; } if (blnBadParameter) { rConsole.Write(_T("Bad parameter: ")); rConsole.Write(pszParameter); rConsole.Write(_T("\n")); } }
if (!pszValueData) blnHelp = TRUE;
CRegistryKey Key; TCHAR *pszValueName; const TCHAR *pszEmpty = _T(""); const TCHAR *pszPath;
if (blnHelp) { rConsole.Write(GetHelpString());
if (pDataBuffer) delete pDataBuffer;
return 0; }
if (pszValueFull) { if (_tcscmp(pszValueFull,_T("\\")) == 0) goto CommandNAonRoot;
TCHAR *pchSep = _tcsrchr(pszValueFull,_T('\\')); pszValueName = pchSep?(pchSep+1):(pszValueFull); pszPath = pchSep?pszValueFull:_T(".");
//if (_tcsrchr(pszValueName,_T('.'))) //{ // pszValueName = _T(""); // pszPath = pszValueFull; //} //else if (pchSep) *pchSep = 0; } else { pszValueName = (TCHAR*)pszEmpty; pszPath = _T("."); }
if (!m_rTree.GetKey(pszPath,KEY_SET_VALUE,Key)) { rConsole.Write(m_rTree.GetLastErrorDescription()); goto SkipCommand; }
if (Key.IsRoot()) goto CommandNAonRoot;
switch (dwType) { case REG_BINARY: { HANDLE hFile; DWORD dwBytesReaded; hFile = CreateFile(pszValueData,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); if (hFile == INVALID_HANDLE_VALUE) { rConsole.Write(_T("Cannot open file ")); rConsole.Write(pszValueData); rConsole.Write(_T("\n")); goto SkipCommand; } dwValueSize = GetFileSize(hFile,NULL); if (dwValueSize == (DWORD)-1) // ok, that's right, we compare signed with unsigned here. // GetFileSize is documented and declared to return DWORD. // Error is indicated by checking if return is -1. Design->documentation bug ??? { rConsole.Write(_T("Cannot get size of file ")); rConsole.Write(pszValueData); rConsole.Write(_T("\n")); VERIFY(CloseHandle(hFile)); goto SkipCommand; } pDataBuffer = new BYTE [dwValueSize]; if (!pDataBuffer) { rConsole.Write(_T("Cannot load file into memory. Out of memory.\n")); VERIFY(CloseHandle(hFile)); goto SkipCommand; } if (!ReadFile(hFile,pDataBuffer,dwValueSize,&dwBytesReaded,NULL)) { rConsole.Write(_T("Cannot load file into memory. Error reading file.\n")); VERIFY(CloseHandle(hFile)); goto SkipCommand; }
VERIFY(CloseHandle(hFile)); ASSERT(dwBytesReaded == dwValueSize); } break; case REG_DWORD_LITTLE_ENDIAN: case REG_DWORD_BIG_ENDIAN: dwValueSize = 4; pDataBuffer = (BYTE *) new BYTE [dwValueSize]; if (!StringToDWORD(*(DWORD *)pDataBuffer,pszValueData)) { rConsole.Write(_T("Cannot convert ")); rConsole.Write(pszValueData); rConsole.Write(_T(" to DWORD \n")); goto SkipCommand; } if (dwType == REG_DWORD_BIG_ENDIAN) { unsigned char nByte; nByte = *pDataBuffer; *pDataBuffer = *(pDataBuffer+3); *(pDataBuffer+3) = nByte; nByte = *(pDataBuffer+1); *(pDataBuffer+1) = *(pDataBuffer+2); *(pDataBuffer+2) = nByte; } break; case REG_SZ: case REG_EXPAND_SZ: dwValueSize = _tcslen(pszValueData)+1; if (*pszValueData == _T('\"')) { dwValueSize -= 2; *(pszValueData+dwValueSize) = 0; pszValueData++; } dwValueSize *= sizeof(TCHAR); pDataBuffer = (BYTE *) new BYTE [dwValueSize];
{ const TCHAR *pchSrc = pszValueData; TCHAR *pchDest = (TCHAR *)pDataBuffer; while(*pchSrc) { if (pchSrc[0] == _T('^')) { if (pchSrc[1] == _T('a')) *pchDest = _T('\a'); else if (pchSrc[1] == _T('b')) *pchDest = _T('\b'); else if (pchSrc[1] == _T('f')) *pchDest = _T('\f'); else if (pchSrc[1] == _T('n')) *pchDest = _T('\n'); else if (pchSrc[1] == _T('r')) *pchDest = _T('\r'); else if (pchSrc[1] == _T('t')) *pchDest = _T('\t'); else *pchDest = pchSrc[1];
pchSrc +=2; pchDest++; dwValueSize--; } else { *pchDest = *pchSrc; pchSrc++; pchDest++; } } *pchDest = _T('\0'); } break; default: ASSERT(FALSE); }
{ size_t s = _tcslen(pszValueName); if (s && (pszValueName[0] == _T('\"'))&&(pszValueName[s-1] == _T('\"'))) { pszValueName[s-1] = 0; pszValueName++; } }
nError = Key.SetValue(pszValueName,dwType,pDataBuffer,dwValueSize); if (nError != ERROR_SUCCESS) { char Buffer[254]; _stprintf(Buffer,_T("Cannot set value. Error is %u\n"),(unsigned int)nError); rConsole.Write(Buffer); } else { InvalidateCompletion(); }
SkipCommand: if (pDataBuffer) delete[] pDataBuffer; return 0;
CommandNAonRoot: rConsole.Write(SET_VALUE_CMD COMMAND_NA_ON_ROOT); return 0;}
const TCHAR * CShellCommandSetValue::GetHelpString(){ return SET_VALUE_CMD_SHORT_DESC _T("Syntax: ") SET_VALUE_CMD _T(" <TYPE> <VALUE> [<PATH>][<VALUE_NAME>] [/?]\n\n") _T(" <TYPE> - Type of value to be set. Must be one of following:\n") _T(" b - binary value.\n") _T(" dw - A 32-bit number.\n") _T(" dwle - A 32-bit number in little-endian format.\n") _T(" dwbe - A 32-bit number in big-endian format.\n") _T(" sz - A null-terminated string.\n") _T(" esz - A null-terminated string that contains unexpanded\n") _T(" references to environment variables.\n")// _T(" msz - An array of null-terminated strings,\n")// _T(" terminated by two null characters.\n") _T(" <VALUE> - The data to be set. According to <TYPE>, <VALUE> means:\n") _T(" b - name of file from which to read binary data.\n") _T(" dw \\\n") _T(" dwle - number with syntax: [0 [{ x | X }]] [digits]\n") _T(" dwbe /\n") _T(" sz \\\n") _T(" esz - <VALUE> string is interpreted as string\n") _T(" <PATH> - Optional relative path of key which value will be processed. ^ is the escape char\n") _T(" <VALUE_NAME> - Name of key's value. Default is key's default value.\n") _T(" /? - This help.\n");}
const TCHAR * CShellCommandSetValue::GetHelpShortDescriptionString(){ return SET_VALUE_CMD_SHORT_DESC;}