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 // ShellCommandSetValue.cpp: implementation of the CShellCommandSetValue class.
25 //////////////////////////////////////////////////////////////////////
28 #include "ShellCommandSetValue.h"
29 #include "RegistryExplorer.h"
30 #include "RegistryTree.h"
31 #include "RegistryKey.h"
33 #define SET_VALUE_CMD _T("SV")
34 #define SET_VALUE_CMD_LENGTH COMMAND_LENGTH(SET_VALUE_CMD)
35 #define SET_VALUE_CMD_SHORT_DESC SET_VALUE_CMD _T(" command is used to set value.\n")
37 BOOL
StringToDWORD(DWORD
& rdwOut
, const TCHAR
*pszIn
)
39 const TCHAR
*pszDigits
;
40 const TCHAR
*pszOctalNumbers
= _T("01234567");
41 const TCHAR
*pszDecimalNumbers
= _T("0123456789");
42 const TCHAR
*pszHexNumbers
= _T("0123456789ABCDEF");
43 const TCHAR
*pszNumbers
;
44 unsigned int nBase
= 0;
45 if (*pszIn
== _T('0'))
47 if ((*(pszIn
+1) == _T('x'))||((*(pszIn
+1) == _T('X'))))
51 pszNumbers
= pszHexNumbers
;
57 pszNumbers
= pszOctalNumbers
;
64 pszNumbers
= pszDecimalNumbers
;
67 const TCHAR
*pszDigit
= pszDigits
;
68 pszDigit
+= _tcslen(pszDigit
);
73 const TCHAR
*pszNumber
;
74 while (pszDigit
> pszDigits
)
77 pszNumber
= _tcschr(pszNumbers
,*pszDigit
);
79 return FALSE
; // wrong char in input string
81 dwAdd
= (pszNumber
-pszNumbers
)*nMul
;
83 if (rdwOut
+ dwAdd
< rdwOut
)
84 return FALSE
; // overflow
87 if (nMul
* nBase
< nMul
)
88 return FALSE
; // overflow
95 //////////////////////////////////////////////////////////////////////
96 // Construction/Destruction
97 //////////////////////////////////////////////////////////////////////
99 CShellCommandSetValue::CShellCommandSetValue(CRegistryTree
& rTree
):m_rTree(rTree
)
103 CShellCommandSetValue::~CShellCommandSetValue()
107 BOOL
CShellCommandSetValue::Match(const TCHAR
*pszCommand
)
109 if (_tcsicmp(pszCommand
,SET_VALUE_CMD
) == 0)
111 if (_tcsnicmp(pszCommand
,SET_VALUE_CMD
_T(".."),SET_VALUE_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)
113 if (_tcsnicmp(pszCommand
,SET_VALUE_CMD
_T("/"),SET_VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
115 if (_tcsnicmp(pszCommand
,SET_VALUE_CMD
_T("\\"),SET_VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
120 int CShellCommandSetValue::Execute(CConsole
&rConsole
, CArgumentParser
& rArguments
)
124 rArguments
.ResetArgumentIteration();
125 TCHAR
*pszCommandItself
= rArguments
.GetNextArgument();
128 TCHAR
*pszValueFull
= NULL
;
129 TCHAR
*pszValueData
= NULL
;
130 BOOL blnBadParameter
= FALSE
;
131 BOOL blnHelp
= FALSE
;
132 DWORD dwValueSize
= 0;
133 DWORD dwType
= REG_NONE
;
134 BYTE
*pDataBuffer
= NULL
;
136 if ((_tcsnicmp(pszCommandItself
,SET_VALUE_CMD
_T(".."),SET_VALUE_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)||
137 (_tcsnicmp(pszCommandItself
,SET_VALUE_CMD
_T("\\"),SET_VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0))
139 pszValueFull
= pszCommandItself
+ SET_VALUE_CMD_LENGTH
;
141 else if (_tcsnicmp(pszCommandItself
,SET_VALUE_CMD
_T("/"),SET_VALUE_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
143 pszParameter
= pszCommandItself
+ SET_VALUE_CMD_LENGTH
;
144 goto CheckValueArgument
;
147 while((pszParameter
= rArguments
.GetNextArgument()) != NULL
)
150 blnBadParameter
= FALSE
;
151 if (((*pszParameter
== _T('/'))||(*pszParameter
== _T('-')))
152 &&(*(pszParameter
+1) == _T('?')))
156 else if (dwType
== REG_NONE
)
158 if (_tcsicmp(pszParameter
,_T("b")) == 0)
162 else if (_tcsicmp(pszParameter
,_T("dw")) == 0)
166 else if (_tcsicmp(pszParameter
,_T("dwle")) == 0)
168 dwType
= REG_DWORD_LITTLE_ENDIAN
;
170 else if (_tcsicmp(pszParameter
,_T("dwbe")) == 0)
172 dwType
= REG_DWORD_BIG_ENDIAN
;
174 else if (_tcsicmp(pszParameter
,_T("sz")) == 0)
178 else if (_tcsicmp(pszParameter
,_T("esz")) == 0)
180 dwType
= REG_EXPAND_SZ
;
184 blnBadParameter
= TRUE
;
187 else if (pszValueData
== NULL
)
189 pszValueData
= pszParameter
;
191 else if (!pszValueFull
)
193 pszValueFull
= pszParameter
;
197 blnBadParameter
= TRUE
;
201 rConsole
.Write(_T("Bad parameter: "));
202 rConsole
.Write(pszParameter
);
203 rConsole
.Write(_T("\n"));
212 const TCHAR
*pszPath
;
216 rConsole
.Write(GetHelpString());
226 if (_tcscmp(pszValueFull
,_T("\\")) == 0)
227 goto CommandNAonRoot
;
229 TCHAR
*pchSep
= _tcsrchr(pszValueFull
,_T('\\'));
230 pszValueName
= pchSep
?(pchSep
+1):(pszValueFull
);
231 pszPath
= pchSep
?pszValueFull
:_T(".");
233 //if (_tcsrchr(pszValueName,_T('.')))
235 // pszValueName = _T("");
236 // pszPath = pszValueFull;
244 pszValueName
= _T("");
248 if (!m_rTree
.GetKey(pszPath
,KEY_SET_VALUE
,Key
))
250 rConsole
.Write(m_rTree
.GetLastErrorDescription());
255 goto CommandNAonRoot
;
263 hFile
= CreateFile(pszValueData
,GENERIC_READ
,FILE_SHARE_READ
,NULL
,OPEN_EXISTING
,0,NULL
);
264 if (hFile
== INVALID_HANDLE_VALUE
)
266 rConsole
.Write(_T("Cannot open file "));
267 rConsole
.Write(pszValueData
);
268 rConsole
.Write(_T("\n"));
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 ???
276 rConsole
.Write(_T("Cannot get size of file "));
277 rConsole
.Write(pszValueData
);
278 rConsole
.Write(_T("\n"));
279 VERIFY(CloseHandle(hFile
));
282 pDataBuffer
= new BYTE
[dwValueSize
];
285 rConsole
.Write(_T("Cannot load file into memory. Out of memory.\n"));
286 VERIFY(CloseHandle(hFile
));
289 if (!ReadFile(hFile
,pDataBuffer
,dwValueSize
,&dwBytesReaded
,NULL
))
291 rConsole
.Write(_T("Cannot load file into memory. Error reading file.\n"));
292 VERIFY(CloseHandle(hFile
));
296 VERIFY(CloseHandle(hFile
));
297 ASSERT(dwBytesReaded
== dwValueSize
);
300 case REG_DWORD_LITTLE_ENDIAN
:
301 case REG_DWORD_BIG_ENDIAN
:
303 pDataBuffer
= (BYTE
*) new BYTE
[dwValueSize
];
304 if (!StringToDWORD(*(DWORD
*)pDataBuffer
,pszValueData
))
306 rConsole
.Write(_T("Cannot convert "));
307 rConsole
.Write(pszValueData
);
308 rConsole
.Write(_T(" to DWORD \n"));
311 if (dwType
== REG_DWORD_BIG_ENDIAN
)
314 nByte
= *pDataBuffer
;
315 *pDataBuffer
= *(pDataBuffer
+3);
316 *(pDataBuffer
+3) = nByte
;
317 nByte
= *(pDataBuffer
+1);
318 *(pDataBuffer
+1) = *(pDataBuffer
+2);
319 *(pDataBuffer
+2) = nByte
;
324 dwValueSize
= _tcslen(pszValueData
)+1;
325 if (*pszValueData
== _T('\"'))
328 *(pszValueData
+dwValueSize
) = 0;
331 dwValueSize
*= sizeof(TCHAR
);
332 pDataBuffer
= (BYTE
*) new BYTE
[dwValueSize
];
335 const TCHAR
*pchSrc
= pszValueData
;
336 TCHAR
*pchDest
= (TCHAR
*)pDataBuffer
;
339 if (pchSrc
[0] == _T('^'))
341 if (pchSrc
[1] == _T('a'))
343 else if (pchSrc
[1] == _T('b'))
345 else if (pchSrc
[1] == _T('f'))
347 else if (pchSrc
[1] == _T('n'))
349 else if (pchSrc
[1] == _T('r'))
351 else if (pchSrc
[1] == _T('t'))
354 *pchDest
= pchSrc
[1];
375 size_t s
= _tcslen(pszValueName
);
376 if (s
&& (pszValueName
[0] == _T('\"'))&&(pszValueName
[s
-1] == _T('\"')))
378 pszValueName
[s
-1] = 0;
383 nError
= Key
.SetValue(pszValueName
,dwType
,pDataBuffer
,dwValueSize
);
384 if (nError
!= ERROR_SUCCESS
)
387 _stprintf(Buffer
,_T("Cannot set value. Error is %u\n"),(unsigned int)nError
);
388 rConsole
.Write(Buffer
);
392 InvalidateCompletion();
401 rConsole
.Write(SET_VALUE_CMD COMMAND_NA_ON_ROOT
);
405 const TCHAR
* CShellCommandSetValue::GetHelpString()
407 return SET_VALUE_CMD_SHORT_DESC
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")
422 _T(" dwle - number with syntax: [0 [{ x | X }]] [digits]\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");
431 const TCHAR
* CShellCommandSetValue::GetHelpShortDescriptionString()
433 return SET_VALUE_CMD_SHORT_DESC
;