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
*pszEmpty
= _T("");
213 const TCHAR
*pszPath
;
217 rConsole
.Write(GetHelpString());
227 if (_tcscmp(pszValueFull
,_T("\\")) == 0)
228 goto CommandNAonRoot
;
230 TCHAR
*pchSep
= _tcsrchr(pszValueFull
,_T('\\'));
231 pszValueName
= pchSep
?(pchSep
+1):(pszValueFull
);
232 pszPath
= pchSep
?pszValueFull
:_T(".");
234 //if (_tcsrchr(pszValueName,_T('.')))
236 // pszValueName = _T("");
237 // pszPath = pszValueFull;
245 pszValueName
= (TCHAR
*)pszEmpty
;
249 if (!m_rTree
.GetKey(pszPath
,KEY_SET_VALUE
,Key
))
251 rConsole
.Write(m_rTree
.GetLastErrorDescription());
256 goto CommandNAonRoot
;
264 hFile
= CreateFile(pszValueData
,GENERIC_READ
,FILE_SHARE_READ
,NULL
,OPEN_EXISTING
,0,NULL
);
265 if (hFile
== INVALID_HANDLE_VALUE
)
267 rConsole
.Write(_T("Cannot open file "));
268 rConsole
.Write(pszValueData
);
269 rConsole
.Write(_T("\n"));
272 dwValueSize
= GetFileSize(hFile
,NULL
);
273 if (dwValueSize
== (DWORD
)-1) // ok, that's right, we compare signed with unsigned here.
274 // GetFileSize is documented and declared to return DWORD.
275 // Error is indicated by checking if return is -1. Design->documentation bug ???
277 rConsole
.Write(_T("Cannot get size of file "));
278 rConsole
.Write(pszValueData
);
279 rConsole
.Write(_T("\n"));
280 VERIFY(CloseHandle(hFile
));
283 pDataBuffer
= new BYTE
[dwValueSize
];
286 rConsole
.Write(_T("Cannot load file into memory. Out of memory.\n"));
287 VERIFY(CloseHandle(hFile
));
290 if (!ReadFile(hFile
,pDataBuffer
,dwValueSize
,&dwBytesReaded
,NULL
))
292 rConsole
.Write(_T("Cannot load file into memory. Error reading file.\n"));
293 VERIFY(CloseHandle(hFile
));
297 VERIFY(CloseHandle(hFile
));
298 ASSERT(dwBytesReaded
== dwValueSize
);
301 case REG_DWORD_LITTLE_ENDIAN
:
302 case REG_DWORD_BIG_ENDIAN
:
304 pDataBuffer
= (BYTE
*) new BYTE
[dwValueSize
];
305 if (!StringToDWORD(*(DWORD
*)pDataBuffer
,pszValueData
))
307 rConsole
.Write(_T("Cannot convert "));
308 rConsole
.Write(pszValueData
);
309 rConsole
.Write(_T(" to DWORD \n"));
312 if (dwType
== REG_DWORD_BIG_ENDIAN
)
315 nByte
= *pDataBuffer
;
316 *pDataBuffer
= *(pDataBuffer
+3);
317 *(pDataBuffer
+3) = nByte
;
318 nByte
= *(pDataBuffer
+1);
319 *(pDataBuffer
+1) = *(pDataBuffer
+2);
320 *(pDataBuffer
+2) = nByte
;
325 dwValueSize
= _tcslen(pszValueData
)+1;
326 if (*pszValueData
== _T('\"'))
329 *(pszValueData
+dwValueSize
) = 0;
332 dwValueSize
*= sizeof(TCHAR
);
333 pDataBuffer
= (BYTE
*) new BYTE
[dwValueSize
];
336 const TCHAR
*pchSrc
= pszValueData
;
337 TCHAR
*pchDest
= (TCHAR
*)pDataBuffer
;
340 if (pchSrc
[0] == _T('^'))
342 if (pchSrc
[1] == _T('a'))
344 else if (pchSrc
[1] == _T('b'))
346 else if (pchSrc
[1] == _T('f'))
348 else if (pchSrc
[1] == _T('n'))
350 else if (pchSrc
[1] == _T('r'))
352 else if (pchSrc
[1] == _T('t'))
355 *pchDest
= pchSrc
[1];
376 size_t s
= _tcslen(pszValueName
);
377 if (s
&& (pszValueName
[0] == _T('\"'))&&(pszValueName
[s
-1] == _T('\"')))
379 pszValueName
[s
-1] = 0;
384 nError
= Key
.SetValue(pszValueName
,dwType
,pDataBuffer
,dwValueSize
);
385 if (nError
!= ERROR_SUCCESS
)
388 _stprintf(Buffer
,_T("Cannot set value. Error is %u\n"),(unsigned int)nError
);
389 rConsole
.Write(Buffer
);
393 InvalidateCompletion();
398 delete[] pDataBuffer
;
402 rConsole
.Write(SET_VALUE_CMD COMMAND_NA_ON_ROOT
);
406 const TCHAR
* CShellCommandSetValue::GetHelpString()
408 return SET_VALUE_CMD_SHORT_DESC
409 _T("Syntax: ") SET_VALUE_CMD
_T(" <TYPE> <VALUE> [<PATH>][<VALUE_NAME>] [/?]\n\n")
410 _T(" <TYPE> - Type of value to be set. Must be one of following:\n")
411 _T(" b - binary value.\n")
412 _T(" dw - A 32-bit number.\n")
413 _T(" dwle - A 32-bit number in little-endian format.\n")
414 _T(" dwbe - A 32-bit number in big-endian format.\n")
415 _T(" sz - A null-terminated string.\n")
416 _T(" esz - A null-terminated string that contains unexpanded\n")
417 _T(" references to environment variables.\n")
418 // _T(" msz - An array of null-terminated strings,\n")
419 // _T(" terminated by two null characters.\n")
420 _T(" <VALUE> - The data to be set. According to <TYPE>, <VALUE> means:\n")
421 _T(" b - name of file from which to read binary data.\n")
423 _T(" dwle - number with syntax: [0 [{ x | X }]] [digits]\n")
426 _T(" esz - <VALUE> string is interpreted as string\n")
427 _T(" <PATH> - Optional relative path of key which value will be processed. ^ is the escape char\n")
428 _T(" <VALUE_NAME> - Name of key's value. Default is key's default value.\n")
429 _T(" /? - This help.\n");
432 const TCHAR
* CShellCommandSetValue::GetHelpShortDescriptionString()
434 return SET_VALUE_CMD_SHORT_DESC
;