GPL sync + delete value implemented
[reactos.git] / rosapps / sysutils / regexpl / ShellCommandOwner.cpp
1 /* $Id: ShellCommandOwner.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $
2 *
3 * regexpl - Console Registry Explorer
4 *
5 * Copyright (C) 2000 Nedko Arnaoudov <nedkohome@atia.com>
6 *
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.
11 *
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.
16 *
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.
21 */
22
23 // ShellCommandOwner.cpp: implementation of the CShellCommandOwner class.
24 //
25 //////////////////////////////////////////////////////////////////////
26
27 #include "ph.h"
28 #include "ShellCommandOwner.h"
29 #include "RegistryExplorer.h"
30 #include "SecurityDescriptor.h"
31
32 #define OWNER_CMD _T("OWNER")
33 #define OWNER_CMD_LENGTH COMMAND_LENGTH(OWNER_CMD)
34 #define OWNER_CMD_SHORT_DESC OWNER_CMD _T(" command is used to view")/*"/change"*/_T(" key's owner.\n")
35
36 //////////////////////////////////////////////////////////////////////
37 // Construction/Destruction
38 //////////////////////////////////////////////////////////////////////
39
40 CShellCommandOwner::CShellCommandOwner(CRegistryTree& rTree):m_rTree(rTree)
41 {
42 }
43
44 CShellCommandOwner::~CShellCommandOwner()
45 {
46 }
47
48 BOOL CShellCommandOwner::Match(const TCHAR *pchCommand)
49 {
50 if (_tcsicmp(pchCommand,OWNER_CMD) == 0)
51 return TRUE;
52 if (_tcsnicmp(pchCommand,OWNER_CMD _T(".."),OWNER_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
53 return TRUE;
54 if (_tcsnicmp(pchCommand,OWNER_CMD _T("/") ,OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
55 return TRUE;
56 if (_tcsnicmp(pchCommand,OWNER_CMD _T("\\"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
57 return TRUE;
58 return FALSE;
59 }
60
61 int CShellCommandOwner::Execute(CConsole &rConsole, CArgumentParser& rArguments)
62 {
63 const TCHAR *pchKey = NULL;
64 BOOL blnDo = TRUE;
65 BOOL blnBadParameter = FALSE;
66 BOOL blnHelp = FALSE;
67 const TCHAR *pchParameter;
68 DWORD dwError;
69
70 rArguments.ResetArgumentIteration();
71 const TCHAR *pchCommandItself = rArguments.GetNextArgument();
72
73 if ((_tcsnicmp(pchCommandItself,OWNER_CMD _T(".."),OWNER_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
74 (_tcsnicmp(pchCommandItself,OWNER_CMD _T("\\"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
75 {
76 pchKey = pchCommandItself + OWNER_CMD_LENGTH;
77 }
78 else if (_tcsnicmp(pchCommandItself,OWNER_CMD _T("/"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
79 {
80 pchParameter = pchCommandItself + OWNER_CMD_LENGTH;
81 goto CheckOwnerArgument;
82 }
83
84 while((pchParameter = rArguments.GetNextArgument()) != NULL)
85 {
86 CheckOwnerArgument:
87 blnBadParameter = FALSE;
88 if ((_tcsicmp(pchParameter,_T("/?")) == 0)
89 ||(_tcsicmp(pchParameter,_T("-?")) == 0))
90 {
91 blnHelp = TRUE;
92 blnDo = pchKey != NULL;
93 }
94 else if (!pchKey)
95 {
96 pchKey = pchParameter;
97 blnDo = TRUE;
98 }
99 else
100 {
101 blnBadParameter = TRUE;
102 }
103 if (blnBadParameter)
104 {
105 rConsole.Write(_T("Bad parameter: "));
106 rConsole.Write(pchParameter);
107 rConsole.Write(_T("\n"));
108 }
109 }
110
111 CRegistryTree *pTree = NULL;
112 CRegistryKey *pKey = NULL;
113
114 if (pchKey)
115 {
116 pTree = new CRegistryTree(m_rTree);
117 if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)||(!pTree->ChangeCurrentKey(pchKey)))
118 {
119 rConsole.Write(_T("Cannot open key "));
120 rConsole.Write(pchKey);
121 rConsole.Write(_T("\n"));
122 //blnHelp = TRUE;
123 blnDo = FALSE;
124 }
125 else
126 {
127 pKey = pTree->GetCurrentKey();
128 }
129 }
130 else
131 {
132 pKey = m_rTree.GetCurrentKey();
133 }
134
135 if (blnHelp)
136 {
137 rConsole.Write(GetHelpString());
138 }
139
140 if (blnDo&&blnHelp) rConsole.Write(_T("\n"));
141
142 if (blnDo)
143 {
144 if (pKey == NULL)
145 { // root key
146 rConsole.Write(OWNER_CMD COMMAND_NA_ON_ROOT);
147 }
148 else
149 {
150 PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
151 TCHAR *pchName = NULL, *pchDomainName = NULL;
152 try
153 {
154 DWORD dwSecurityDescriptorLength;
155 rConsole.Write(_T("Key : "));
156 rConsole.Write(_T("\\"));
157 rConsole.Write(pTree?pTree->GetCurrentPath():m_rTree.GetCurrentPath());
158 rConsole.Write(_T("\n"));
159 dwError = pKey->GetSecurityDescriptorLength(&dwSecurityDescriptorLength);
160 if (dwError != ERROR_SUCCESS) throw dwError;
161
162 pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength];
163 DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength;
164 dwError = pKey->GetSecurityDescriptor((SECURITY_INFORMATION)OWNER_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1);
165 if (dwError != ERROR_SUCCESS) throw dwError;
166 PSID psidOwner;
167 BOOL blnOwnerDefaulted;
168 if (!GetSecurityDescriptorOwner(pSecurityDescriptor,&psidOwner,&blnOwnerDefaulted))
169 throw GetLastError();
170 if (psidOwner == NULL)
171 {
172 rConsole.Write(_T("Key has no owner."));
173 }
174 else
175 {
176 if (!IsValidSid(psidOwner))
177 {
178 rConsole.Write(_T("Key has invalid owner SID."));
179 }
180 else
181 {
182 rConsole.Write(_T("Key Owner: \n"));
183 DWORD dwSIDStringSize = 0;
184 BOOL blnRet = GetTextualSid(psidOwner,NULL,&dwSIDStringSize);
185 ASSERT(!blnRet);
186 ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
187 TCHAR *pchSID = new TCHAR[dwSIDStringSize];
188 if(!GetTextualSid(psidOwner,pchSID,&dwSIDStringSize))
189 {
190 dwError = GetLastError();
191 ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
192 rConsole.Write(_T("Error "));
193 TCHAR Buffer[256];
194 rConsole.Write(_itot(dwError,Buffer,10));
195 rConsole.Write(_T("\nGetting string representation of SID\n"));
196 }
197 else
198 {
199 rConsole.Write(_T("\tSID: "));
200 rConsole.Write(pchSID);
201 rConsole.Write(_T("\n"));
202 }
203 delete [] pchSID;
204 DWORD dwNameBufferLength, dwDomainNameBufferLength;
205 dwNameBufferLength = 1024;
206 dwDomainNameBufferLength = 1024;
207 pchName = new TCHAR [dwNameBufferLength];
208 pchDomainName = new TCHAR [dwDomainNameBufferLength];
209 DWORD dwNameLength = dwNameBufferLength, dwDomainNameLength = dwDomainNameBufferLength;
210 SID_NAME_USE Use;
211 if (!LookupAccountSid(NULL,psidOwner,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use))
212 throw GetLastError();
213 else
214 {
215 rConsole.Write(_T("\tOwner Domain: "));
216 rConsole.Write(pchDomainName);
217 rConsole.Write(_T("\n"));
218 rConsole.Write(_T("\tOwner Name: "));
219 rConsole.Write(pchName);
220 rConsole.Write(_T("\n\tSID type: "));
221 rConsole.Write(GetSidTypeName(Use));
222 rConsole.Write(_T("\n"));
223 rConsole.Write(_T("\tOwner defaulted: "));
224 rConsole.Write(blnOwnerDefaulted?_T("Yes"):_T("No"));
225 rConsole.Write(_T("\n"));
226 }
227 delete [] pchName;
228 pchName = NULL;
229 delete [] pchDomainName;
230 pchDomainName = NULL;
231
232 }
233 }
234 delete [] pSecurityDescriptor;
235 }
236 catch (DWORD dwError)
237 {
238 rConsole.Write(_T("Error "));
239 TCHAR Buffer[256];
240 rConsole.Write(_itot(dwError,Buffer,10));
241 rConsole.Write(_T("\n"));
242 if (pchName) delete [] pchName;
243 if (pchDomainName) delete [] pchDomainName;
244 if (pSecurityDescriptor) delete [] pSecurityDescriptor;
245 }
246 } // else (pKey == NULL)
247 } // if (blnDo)
248
249 if (pTree)
250 delete pTree;
251
252 return 0;
253 }
254
255 const TCHAR * CShellCommandOwner::GetHelpString()
256 {
257 return OWNER_CMD_SHORT_DESC
258 _T("Syntax: ") OWNER_CMD _T(" [<KEY>] [/?]\n\n")
259 _T(" <KEY> - Optional relative path of desired key.\n")
260 _T(" /? - This help.\n\n")
261 _T("Without parameters, command displays information about owner of current key.\n");
262 }
263
264 const TCHAR * CShellCommandOwner::GetHelpShortDescriptionString()
265 {
266 return OWNER_CMD_SHORT_DESC;
267 }
268