28f7862ff398c6ff58a40dffb6395e5b8c406e48
[reactos.git] / rosapps / sysutils / regexpl / ShellCommandOwner.cpp
1 /* $Id: ShellCommandOwner.cpp,v 1.4 2001/01/13 23:55:37 narnaoud Exp $
2 *
3 * regexpl - Console Registry Explorer
4 *
5 * Copyright (C) 2000,2001 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 CRegistryKey Key;
112
113 if (!m_rTree.GetKey(pchKey?pchKey:_T("."),KEY_QUERY_VALUE|READ_CONTROL,Key))
114 {
115 rConsole.Write(m_rTree.GetLastErrorDescription());
116 blnDo = FALSE;
117 }
118
119 if (blnHelp)
120 {
121 rConsole.Write(GetHelpString());
122 }
123
124 if (blnDo&&blnHelp) rConsole.Write(_T("\n"));
125
126 if (!blnDo)
127 return 0;
128
129 if (Key.IsRoot())
130 { // root key
131 rConsole.Write(OWNER_CMD COMMAND_NA_ON_ROOT);
132 return 0;
133 }
134
135 PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
136 TCHAR *pchName = NULL, *pchDomainName = NULL;
137 try
138 {
139 DWORD dwSecurityDescriptorLength;
140 rConsole.Write(_T("Key : "));
141 rConsole.Write(_T("\\"));
142 rConsole.Write(Key.GetKeyName());
143 rConsole.Write(_T("\n"));
144 dwError = Key.GetSecurityDescriptorLength(&dwSecurityDescriptorLength);
145 if (dwError != ERROR_SUCCESS) throw dwError;
146
147 pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength];
148 DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength;
149 dwError = Key.GetSecurityDescriptor((SECURITY_INFORMATION)OWNER_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1);
150 if (dwError != ERROR_SUCCESS) throw dwError;
151 PSID psidOwner;
152 BOOL blnOwnerDefaulted;
153 if (!GetSecurityDescriptorOwner(pSecurityDescriptor,&psidOwner,&blnOwnerDefaulted))
154 throw GetLastError();
155 if (psidOwner == NULL)
156 {
157 rConsole.Write(_T("Key has no owner."));
158 }
159 else
160 {
161 if (!IsValidSid(psidOwner))
162 {
163 rConsole.Write(_T("Key has invalid owner SID."));
164 }
165 else
166 {
167 rConsole.Write(_T("Key Owner: \n"));
168 DWORD dwSIDStringSize = 0;
169 BOOL blnRet = GetTextualSid(psidOwner,NULL,&dwSIDStringSize);
170 ASSERT(!blnRet);
171 ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
172 TCHAR *pchSID = new TCHAR[dwSIDStringSize];
173 if(!GetTextualSid(psidOwner,pchSID,&dwSIDStringSize))
174 {
175 dwError = GetLastError();
176 ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
177 rConsole.Write(_T("Error "));
178 TCHAR Buffer[256];
179 rConsole.Write(_itot(dwError,Buffer,10));
180 rConsole.Write(_T("\nGetting string representation of SID\n"));
181 }
182 else
183 {
184 rConsole.Write(_T("\tSID: "));
185 rConsole.Write(pchSID);
186 rConsole.Write(_T("\n"));
187 }
188 delete [] pchSID;
189 DWORD dwNameBufferLength, dwDomainNameBufferLength;
190 dwNameBufferLength = 1024;
191 dwDomainNameBufferLength = 1024;
192 pchName = new TCHAR [dwNameBufferLength];
193 pchDomainName = new TCHAR [dwDomainNameBufferLength];
194 DWORD dwNameLength = dwNameBufferLength, dwDomainNameLength = dwDomainNameBufferLength;
195 SID_NAME_USE Use;
196 if (!LookupAccountSid(NULL,psidOwner,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use))
197 throw GetLastError();
198 else
199 {
200 rConsole.Write(_T("\tOwner Domain: "));
201 rConsole.Write(pchDomainName);
202 rConsole.Write(_T("\n"));
203 rConsole.Write(_T("\tOwner Name: "));
204 rConsole.Write(pchName);
205 rConsole.Write(_T("\n\tSID type: "));
206 rConsole.Write(GetSidTypeName(Use));
207 rConsole.Write(_T("\n"));
208 rConsole.Write(_T("\tOwner defaulted: "));
209 rConsole.Write(blnOwnerDefaulted?_T("Yes"):_T("No"));
210 rConsole.Write(_T("\n"));
211 }
212 delete [] pchName;
213 pchName = NULL;
214 delete [] pchDomainName;
215 pchDomainName = NULL;
216
217 }
218 }
219 delete [] pSecurityDescriptor;
220 }
221 catch (DWORD dwError)
222 {
223 rConsole.Write(_T("Error "));
224 TCHAR Buffer[256];
225 rConsole.Write(_itot(dwError,Buffer,10));
226 rConsole.Write(_T("\n"));
227 if (pchName) delete [] pchName;
228 if (pchDomainName) delete [] pchDomainName;
229 if (pSecurityDescriptor) delete [] pSecurityDescriptor;
230 }
231
232 return 0;
233 }
234
235 const TCHAR * CShellCommandOwner::GetHelpString()
236 {
237 return OWNER_CMD_SHORT_DESC
238 _T("Syntax: ") OWNER_CMD _T(" [<KEY>] [/?]\n\n")
239 _T(" <KEY> - Optional relative path of desired key.\n")
240 _T(" /? - This help.\n\n")
241 _T("Without parameters, command displays information about owner of current key.\n");
242 }
243
244 const TCHAR * CShellCommandOwner::GetHelpShortDescriptionString()
245 {
246 return OWNER_CMD_SHORT_DESC;
247 }
248