ReactOS  0.4.14-dev-41-g31d7680
ShellCommandSetValue.cpp
Go to the documentation of this file.
1 /*
2  * regexpl - Console Registry Explorer
3  *
4  * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
5  *
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.
10  *
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.
15  *
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.
20  */
21 
22 // ShellCommandSetValue.cpp: implementation of the CShellCommandSetValue class.
23 //
25 
26 #include "ph.h"
27 #include "ShellCommandSetValue.h"
28 #include "RegistryExplorer.h"
29 #include "RegistryTree.h"
30 #include "RegistryKey.h"
31 
32 #define SET_VALUE_CMD _T("SV")
33 #define SET_VALUE_CMD_LENGTH COMMAND_LENGTH(SET_VALUE_CMD)
34 #define SET_VALUE_CMD_SHORT_DESC SET_VALUE_CMD _T(" command is used to set value.\n")
35 
36 BOOL StringToDWORD(DWORD& rdwOut, const TCHAR *pszIn)
37 {
38  const TCHAR *pszDigits;
39  const TCHAR *pszOctalNumbers = _T("01234567");
40  const TCHAR *pszDecimalNumbers = _T("0123456789");
41  const TCHAR *pszHexNumbers = _T("0123456789ABCDEF");
42  const TCHAR *pszNumbers;
43  unsigned int nBase = 0;
44  if (*pszIn == _T('0'))
45  {
46  if ((*(pszIn+1) == _T('x'))||((*(pszIn+1) == _T('X'))))
47  { // hex
48  nBase = 16;
49  pszDigits = pszIn+2;
50  pszNumbers = pszHexNumbers;
51  }
52  else
53  { // octal
54  nBase = 8;
55  pszDigits = pszIn+1;
56  pszNumbers = pszOctalNumbers;
57  }
58  }
59  else
60  { //decimal
61  nBase = 10;
62  pszDigits = pszIn;
63  pszNumbers = pszDecimalNumbers;
64  }
65 
66  const TCHAR *pszDigit = pszDigits;
67  pszDigit += _tcslen(pszDigit);
68 
69  DWORD nMul = 1;
70  rdwOut = 0;
71  DWORD dwAdd;
72  const TCHAR *pszNumber;
73  while (pszDigit > pszDigits)
74  {
75  pszDigit--;
76  pszNumber = _tcschr(pszNumbers,*pszDigit);
77  if (!pszNumber)
78  return FALSE; // wrong char in input string
79 
80  dwAdd = (pszNumber-pszNumbers)*nMul;
81 
82  if (rdwOut + dwAdd < rdwOut)
83  return FALSE; // overflow
84  rdwOut += dwAdd;
85 
86  if (nMul * nBase < nMul)
87  return FALSE; // overflow
88  nMul *= nBase;
89  };
90 
91  return TRUE;
92 }
93 
95 // Construction/Destruction
97 
99 {
100 }
101 
103 {
104 }
105 
107 {
108  if (_tcsicmp(pszCommand,SET_VALUE_CMD) == 0)
109  return TRUE;
110  if (_tcsnicmp(pszCommand,SET_VALUE_CMD _T(".."),SET_VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
111  return TRUE;
112  if (_tcsnicmp(pszCommand,SET_VALUE_CMD _T("/"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
113  return TRUE;
114  if (_tcsnicmp(pszCommand,SET_VALUE_CMD _T("\\"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
115  return TRUE;
116  return FALSE;
117 }
118 
120 {
121  LONG nError;
122 
123  rArguments.ResetArgumentIteration();
124  TCHAR *pszCommandItself = rArguments.GetNextArgument();
125 
126  TCHAR *pszParameter;
127  TCHAR *pszValueFull = NULL;
128  TCHAR *pszValueData = NULL;
129  BOOL blnBadParameter = FALSE;
130  BOOL blnHelp = FALSE;
131  DWORD dwValueSize = 0;
132  DWORD dwType = REG_NONE;
133  BYTE *pDataBuffer = NULL;
134 
135  if ((_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T(".."),SET_VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
136  (_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T("\\"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
137  {
138  pszValueFull = pszCommandItself + SET_VALUE_CMD_LENGTH;
139  }
140  else if (_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T("/"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
141  {
142  pszParameter = pszCommandItself + SET_VALUE_CMD_LENGTH;
143  goto CheckValueArgument;
144  }
145 
146  while((pszParameter = rArguments.GetNextArgument()) != NULL)
147  {
148 CheckValueArgument:
149  blnBadParameter = FALSE;
150  if (((*pszParameter == _T('/'))||(*pszParameter == _T('-')))
151  &&(*(pszParameter+1) == _T('?')))
152  {
153  blnHelp = TRUE;
154  }
155  else if (dwType == REG_NONE)
156  {
157  if (_tcsicmp(pszParameter,_T("b")) == 0)
158  {
159  dwType = REG_BINARY;
160  }
161  else if (_tcsicmp(pszParameter,_T("dw")) == 0)
162  {
163  dwType = REG_DWORD;
164  }
165  else if (_tcsicmp(pszParameter,_T("dwle")) == 0)
166  {
167  dwType = REG_DWORD_LITTLE_ENDIAN;
168  }
169  else if (_tcsicmp(pszParameter,_T("dwbe")) == 0)
170  {
171  dwType = REG_DWORD_BIG_ENDIAN;
172  }
173  else if (_tcsicmp(pszParameter,_T("sz")) == 0)
174  {
175  dwType = REG_SZ;
176  }
177  else if (_tcsicmp(pszParameter,_T("esz")) == 0)
178  {
179  dwType = REG_EXPAND_SZ;
180  }
181  else
182  {
183  blnBadParameter = TRUE;
184  }
185  }
186  else if (pszValueData == NULL)
187  {
188  pszValueData = pszParameter;
189  }
190  else if (!pszValueFull)
191  {
192  pszValueFull = pszParameter;
193  }
194  else
195  {
196  blnBadParameter = TRUE;
197  }
198  if (blnBadParameter)
199  {
200  rConsole.Write(_T("Bad parameter: "));
201  rConsole.Write(pszParameter);
202  rConsole.Write(_T("\n"));
203  }
204  }
205 
206  if (!pszValueData)
207  blnHelp = TRUE;
208 
210  TCHAR *pszValueName;
211  const TCHAR *pszEmpty = _T("");
212  const TCHAR *pszPath;
213 
214  if (blnHelp)
215  {
216  rConsole.Write(GetHelpString());
217 
218  if (pDataBuffer)
219  delete pDataBuffer;
220 
221  return 0;
222  }
223 
224  if (pszValueFull)
225  {
226  if (_tcscmp(pszValueFull,_T("\\")) == 0)
227  goto CommandNAonRoot;
228 
229  TCHAR *pchSep = _tcsrchr(pszValueFull,_T('\\'));
230  pszValueName = pchSep?(pchSep+1):(pszValueFull);
231  pszPath = pchSep?pszValueFull:_T(".");
232 
233  //if (_tcsrchr(pszValueName,_T('.')))
234  //{
235  // pszValueName = _T("");
236  // pszPath = pszValueFull;
237  //}
238  //else
239  if (pchSep)
240  *pchSep = 0;
241  }
242  else
243  {
244  pszValueName = (TCHAR*)pszEmpty;
245  pszPath = _T(".");
246  }
247 
248  if (!m_rTree.GetKey(pszPath,KEY_SET_VALUE,Key))
249  {
251  goto SkipCommand;
252  }
253 
254  if (Key.IsRoot())
255  goto CommandNAonRoot;
256 
257  switch (dwType)
258  {
259  case REG_BINARY:
260  {
261  HANDLE hFile;
262  DWORD dwBytesReaded;
265  {
266  rConsole.Write(_T("Cannot open file "));
267  rConsole.Write(pszValueData);
268  rConsole.Write(_T("\n"));
269  goto SkipCommand;
270  }
271  dwValueSize = GetFileSize(hFile,NULL);
272  if (dwValueSize == (DWORD)-1) // ok, that's right, we compare signed with unsigned here.
273  // GetFileSize is documented and declared to return DWORD.
274  // Error is indicated by checking if return is -1. Design->documentation bug ???
275  {
276  rConsole.Write(_T("Cannot get size of file "));
277  rConsole.Write(pszValueData);
278  rConsole.Write(_T("\n"));
280  goto SkipCommand;
281  }
282  pDataBuffer = new BYTE [dwValueSize];
283  if (!pDataBuffer)
284  {
285  rConsole.Write(_T("Cannot load file into memory. Out of memory.\n"));
287  goto SkipCommand;
288  }
289  if (!ReadFile(hFile,pDataBuffer,dwValueSize,&dwBytesReaded,NULL))
290  {
291  rConsole.Write(_T("Cannot load file into memory. Error reading file.\n"));
293  goto SkipCommand;
294  }
295 
297  ASSERT(dwBytesReaded == dwValueSize);
298  }
299  break;
302  dwValueSize = 4;
303  pDataBuffer = (BYTE *) new BYTE [dwValueSize];
304  if (!StringToDWORD(*(DWORD *)pDataBuffer,pszValueData))
305  {
306  rConsole.Write(_T("Cannot convert "));
307  rConsole.Write(pszValueData);
308  rConsole.Write(_T(" to DWORD \n"));
309  goto SkipCommand;
310  }
311  if (dwType == REG_DWORD_BIG_ENDIAN)
312  {
313  unsigned char nByte;
314  nByte = *pDataBuffer;
315  *pDataBuffer = *(pDataBuffer+3);
316  *(pDataBuffer+3) = nByte;
317  nByte = *(pDataBuffer+1);
318  *(pDataBuffer+1) = *(pDataBuffer+2);
319  *(pDataBuffer+2) = nByte;
320  }
321  break;
322  case REG_SZ:
323  case REG_EXPAND_SZ:
324  dwValueSize = _tcslen(pszValueData)+1;
325  if (*pszValueData == _T('\"'))
326  {
327  dwValueSize -= 2;
328  *(pszValueData+dwValueSize) = 0;
329  pszValueData++;
330  }
331  dwValueSize *= sizeof(TCHAR);
332  pDataBuffer = (BYTE *) new BYTE [dwValueSize];
333 
334  {
335  const TCHAR *pchSrc = pszValueData;
336  TCHAR *pchDest = (TCHAR *)pDataBuffer;
337  while(*pchSrc)
338  {
339  if (pchSrc[0] == _T('^'))
340  {
341  if (pchSrc[1] == _T('a'))
342  *pchDest = _T('\a');
343  else if (pchSrc[1] == _T('b'))
344  *pchDest = _T('\b');
345  else if (pchSrc[1] == _T('f'))
346  *pchDest = _T('\f');
347  else if (pchSrc[1] == _T('n'))
348  *pchDest = _T('\n');
349  else if (pchSrc[1] == _T('r'))
350  *pchDest = _T('\r');
351  else if (pchSrc[1] == _T('t'))
352  *pchDest = _T('\t');
353  else
354  *pchDest = pchSrc[1];
355 
356  pchSrc +=2;
357  pchDest++;
358  dwValueSize--;
359  }
360  else
361  {
362  *pchDest = *pchSrc;
363  pchSrc++;
364  pchDest++;
365  }
366  }
367  *pchDest = _T('\0');
368  }
369  break;
370  default:
371  ASSERT(FALSE);
372  }
373 
374  {
375  size_t s = _tcslen(pszValueName);
376  if (s && (pszValueName[0] == _T('\"'))&&(pszValueName[s-1] == _T('\"')))
377  {
378  pszValueName[s-1] = 0;
379  pszValueName++;
380  }
381  }
382 
383  nError = Key.SetValue(pszValueName,dwType,pDataBuffer,dwValueSize);
384  if (nError != ERROR_SUCCESS)
385  {
386  char Buffer[254];
387  _stprintf(Buffer,_T("Cannot set value. Error is %u\n"),(unsigned int)nError);
388  rConsole.Write(Buffer);
389  }
390  else
391  {
393  }
394 
395 SkipCommand:
396  if (pDataBuffer)
397  delete[] pDataBuffer;
398  return 0;
399 
400 CommandNAonRoot:
402  return 0;
403 }
404 
406 {
408  _T("Syntax: ") SET_VALUE_CMD _T(" <TYPE> <VALUE> [<PATH>][<VALUE_NAME>] [/?]\n\n")
409  _T(" <TYPE> - Type of value to be set. Must be one of following:\n")
410  _T(" b - binary value.\n")
411  _T(" dw - A 32-bit number.\n")
412  _T(" dwle - A 32-bit number in little-endian format.\n")
413  _T(" dwbe - A 32-bit number in big-endian format.\n")
414  _T(" sz - A null-terminated string.\n")
415  _T(" esz - A null-terminated string that contains unexpanded\n")
416  _T(" references to environment variables.\n")
417 // _T(" msz - An array of null-terminated strings,\n")
418 // _T(" terminated by two null characters.\n")
419  _T(" <VALUE> - The data to be set. According to <TYPE>, <VALUE> means:\n")
420  _T(" b - name of file from which to read binary data.\n")
421  _T(" dw \\\n")
422  _T(" dwle - number with syntax: [0 [{ x | X }]] [digits]\n")
423  _T(" dwbe /\n")
424  _T(" sz \\\n")
425  _T(" esz - <VALUE> string is interpreted as string\n")
426  _T(" <PATH> - Optional relative path of key which value will be processed. ^ is the escape char\n")
427  _T(" <VALUE_NAME> - Name of key's value. Default is key's default value.\n")
428  _T(" /? - This help.\n");
429 }
430 
432 {
434 }
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
virtual const TCHAR * GetHelpShortDescriptionString()
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define _tcsicmp
Definition: xmlstorage.h:205
#define REG_BINARY
Definition: nt_native.h:1496
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
virtual BOOL Match(const TCHAR *pchCommand)
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define FILE_SHARE_READ
Definition: compat.h:125
#define SET_VALUE_CMD_LENGTH
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL GetKey(const TCHAR *pchRelativePath, REGSAM DesiredAccess, CRegistryKey &rKey)
long LONG
Definition: pedump.c:60
#define _tcsnicmp
Definition: xmlstorage.h:207
TCHAR * GetNextArgument()
void ResetArgumentIteration()
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
_TCHAR * _tcschr(const _TCHAR *s, _XINT c)
Definition: tcschr.h:4
#define OPEN_EXISTING
Definition: compat.h:426
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define VERIFY(e)
Definition: ph.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SET_VALUE_CMD_SHORT_DESC
#define REG_DWORD_LITTLE_ENDIAN
Definition: nt_native.h:1498
CShellCommandSetValue(CRegistryTree &rTree)
const TCHAR * GetLastErrorDescription()
unsigned char BYTE
Definition: mem.h:68
GLdouble s
Definition: gl.h:2039
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
#define REG_DWORD_BIG_ENDIAN
Definition: nt_native.h:1499
#define _stprintf
Definition: utility.h:124
#define COMMAND_NA_ON_ROOT
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:904
BOOL Write(const TCHAR *p, DWORD dwChars=0)
Definition: Console.cpp:90
BOOL StringToDWORD(DWORD &rdwOut, const TCHAR *pszIn)
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
_TCHAR * _tcsrchr(const _TCHAR *s, _XINT c)
Definition: tcsrchr.h:4
#define REG_NONE
Definition: nt_native.h:1492
void InvalidateCompletion()
Definition: Completion.cpp:511
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define REG_DWORD
Definition: sdbapi.c:596
virtual int Execute(CConsole &rConsole, CArgumentParser &rArguments)
#define SET_VALUE_CMD
virtual const TCHAR * GetHelpString()
#define REG_SZ
Definition: layer.c:22