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 // ShellCommandDeleteValue.cpp: implementation of the CShellCommandDeleteValue class.
23 //
24 //////////////////////////////////////////////////////////////////////
25 
26 #include "ph.h"
27 #include "ShellCommandDeleteValue.h"
28 #include "RegistryExplorer.h"
29 #include "Pattern.h"
30 
31 #define DV_CMD			_T("DV")
32 #define DV_CMD_LENGTH		COMMAND_LENGTH(DV_CMD)
33 #define DV_CMD_SHORT_DESC	DV_CMD _T(" command is used to delete value.\n")
34 
35 //////////////////////////////////////////////////////////////////////
36 // Construction/Destruction
37 //////////////////////////////////////////////////////////////////////
38 
CShellCommandDeleteValue(CRegistryTree & rTree)39 CShellCommandDeleteValue::CShellCommandDeleteValue(CRegistryTree& rTree):m_rTree(rTree)
40 {
41 }
42 
~CShellCommandDeleteValue()43 CShellCommandDeleteValue::~CShellCommandDeleteValue()
44 {
45 }
46 
Match(const TCHAR * pszCommand)47 BOOL CShellCommandDeleteValue::Match(const TCHAR *pszCommand)
48 {
49 	return _tcsicmp(pszCommand,DV_CMD) == 0;
50 }
51 
Execute(CConsole & rConsole,CArgumentParser & rArguments)52 int CShellCommandDeleteValue::Execute(CConsole &rConsole, CArgumentParser& rArguments)
53 {
54   rArguments.ResetArgumentIteration();
55   TCHAR *pszCommandItself = rArguments.GetNextArgument();
56 
57   TCHAR *pszParameter;
58   TCHAR *pszValueFull = NULL;
59   BOOL blnHelp = FALSE;
60 
61   if ((_tcsnicmp(pszCommandItself,DV_CMD _T(".."),DV_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
62       (_tcsnicmp(pszCommandItself,DV_CMD _T("\\"),DV_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
63   {
64     pszValueFull = pszCommandItself + DV_CMD_LENGTH;
65   }
66   else if (_tcsnicmp(pszCommandItself,DV_CMD _T("/"),DV_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
67   {
68     pszParameter = pszCommandItself + DV_CMD_LENGTH;
69     goto CheckValueArgument;
70   }
71 
72   while((pszParameter = rArguments.GetNextArgument()) != NULL)
73   {
74 CheckValueArgument:
75     if ((_tcsicmp(pszParameter,_T("/?")) == 0)
76         ||(_tcsicmp(pszParameter,_T("-?")) == 0))
77     {
78       blnHelp = TRUE;
79       break;
80     }
81     else if (!pszValueFull)
82     {
83       pszValueFull = pszParameter;
84     }
85     else
86     {
87       rConsole.Write(_T("Bad parameter: "));
88       rConsole.Write(pszParameter);
89       rConsole.Write(_T("\n"));
90     }
91   }
92 
93   CRegistryKey Key;
94   TCHAR *pszValueNamePattern;
95   const TCHAR *pszEmpty = _T("");
96   const TCHAR *pszPath;
97 
98   if (blnHelp)
99   {
100     rConsole.Write(GetHelpString());
101     return 0;
102   }
103 
104   if (pszValueFull)
105   {
106     if (_tcscmp(pszValueFull,_T("\\")) == 0)
107       goto CommandNAonRoot;
108 
109     TCHAR *pchSep = _tcsrchr(pszValueFull,_T('\\'));
110     pszValueNamePattern = pchSep?(pchSep+1):(pszValueFull);
111     pszPath = pchSep?pszValueFull:_T(".");
112 
113     if (pchSep)
114       *pchSep = 0;
115   }
116   else
117   {
118     pszValueNamePattern = (TCHAR*)pszEmpty;
119     pszPath = _T(".");
120   }
121 
122   {
123     size_t s = _tcslen(pszValueNamePattern);
124     if (s && (pszValueNamePattern[0] == _T('\"'))&&(pszValueNamePattern[s-1] == _T('\"')))
125     {
126       pszValueNamePattern[s-1] = 0;
127       pszValueNamePattern++;
128     }
129   }
130 
131   if (!m_rTree.GetKey(pszPath,KEY_QUERY_VALUE|KEY_SET_VALUE,Key))
132   {
133     rConsole.Write(m_rTree.GetLastErrorDescription());
134     return 0;
135   }
136 
137   if (!Key.IsRoot())
138   {	// not root key ???
139     TCHAR Buffer[254];
140     DWORD dwMaxValueNameLength;
141     LONG nError = Key.GetMaxValueNameLength(dwMaxValueNameLength);
142     if (nError != ERROR_SUCCESS)
143     {
144       _stprintf(Buffer,_T("Cannot query info about %s key. Error is %u\n"),Key.GetKeyName(),(unsigned int)nError);
145       rConsole.Write(Buffer);
146       return 0;
147     }
148 
149     TCHAR *pszValueName = new (std::nothrow) TCHAR[dwMaxValueNameLength];
150     if (!pszValueName)
151     {
152       rConsole.Write("Out of memory.");
153       return 0;
154     }
155 
156     Key.InitValueEnumeration(pszValueName,dwMaxValueNameLength,NULL,0,NULL);
157 
158     while ((nError = Key.GetNextValue()) == ERROR_SUCCESS)
159     {
160       if (PatternMatch(pszValueNamePattern,pszValueName))
161       {
162         nError = Key.DeleteValue(pszValueName);
163         if (nError != ERROR_SUCCESS)
164         {
165           _stprintf(Buffer,_T("Cannot delete value. Error is %u\n"),(unsigned int)nError);
166           rConsole.Write(Buffer);
167         }
168         else
169         {
170           InvalidateCompletion();
171         }
172         Key.InitValueEnumeration(pszValueName,dwMaxValueNameLength,NULL,0,NULL); // reset iteration
173       }
174     }
175   } // if (pKey)
176   else
177   {
178 CommandNAonRoot:
179     rConsole.Write(DV_CMD COMMAND_NA_ON_ROOT);
180   }
181 
182   return 0;
183 }
184 
GetHelpString()185 const TCHAR * CShellCommandDeleteValue::GetHelpString()
186 {
187 	return DV_CMD_SHORT_DESC
188 			_T("Syntax: ") DV_CMD _T(" [<PATH>][<VALUE_NAME>] [/?]\n\n")
189 			_T("    <PATH>       - Optional relative path of key which value will be delete.\n")
190 			_T("    <VALUE_NAME> - Name pattern of key's value. Default is key's default value.\n")
191 			_T("    /? - This help.\n\n");
192 }
193 
GetHelpShortDescriptionString()194 const TCHAR * CShellCommandDeleteValue::GetHelpShortDescriptionString()
195 {
196 	return DV_CMD_SHORT_DESC;
197 }
198