1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * regexpl - Console Registry Explorer
3*c2c66affSColin Finck  *
4*c2c66affSColin Finck  * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
5*c2c66affSColin Finck  *
6*c2c66affSColin Finck  * This program is free software; you can redistribute it and/or modify
7*c2c66affSColin Finck  * it under the terms of the GNU General Public License as published by
8*c2c66affSColin Finck  * the Free Software Foundation; either version 2 of the License, or
9*c2c66affSColin Finck  * (at your option) any later version.
10*c2c66affSColin Finck  *
11*c2c66affSColin Finck  * This program is distributed in the hope that it will be useful,
12*c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*c2c66affSColin Finck  * GNU General Public License for more details.
15*c2c66affSColin Finck  *
16*c2c66affSColin Finck  * You should have received a copy of the GNU General Public License
17*c2c66affSColin Finck  * along with this program; see the file COPYING.  If not, write to
18*c2c66affSColin Finck  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19*c2c66affSColin Finck  * Boston, MA 02111-1307, USA.
20*c2c66affSColin Finck  */
21*c2c66affSColin Finck 
22*c2c66affSColin Finck // ShellCommandOwner.cpp: implementation of the CShellCommandOwner class.
23*c2c66affSColin Finck //
24*c2c66affSColin Finck //////////////////////////////////////////////////////////////////////
25*c2c66affSColin Finck 
26*c2c66affSColin Finck #include "ph.h"
27*c2c66affSColin Finck #include "ShellCommandOwner.h"
28*c2c66affSColin Finck #include "RegistryExplorer.h"
29*c2c66affSColin Finck #include "SecurityDescriptor.h"
30*c2c66affSColin Finck 
31*c2c66affSColin Finck #define OWNER_CMD			_T("OWNER")
32*c2c66affSColin Finck #define OWNER_CMD_LENGTH	COMMAND_LENGTH(OWNER_CMD)
33*c2c66affSColin Finck #define OWNER_CMD_SHORT_DESC	OWNER_CMD _T(" command is used to view")/*"/change"*/_T(" key's owner.\n")
34*c2c66affSColin Finck 
35*c2c66affSColin Finck //////////////////////////////////////////////////////////////////////
36*c2c66affSColin Finck // Construction/Destruction
37*c2c66affSColin Finck //////////////////////////////////////////////////////////////////////
38*c2c66affSColin Finck 
CShellCommandOwner(CRegistryTree & rTree)39*c2c66affSColin Finck CShellCommandOwner::CShellCommandOwner(CRegistryTree& rTree):m_rTree(rTree)
40*c2c66affSColin Finck {
41*c2c66affSColin Finck }
42*c2c66affSColin Finck 
~CShellCommandOwner()43*c2c66affSColin Finck CShellCommandOwner::~CShellCommandOwner()
44*c2c66affSColin Finck {
45*c2c66affSColin Finck }
46*c2c66affSColin Finck 
Match(const TCHAR * pchCommand)47*c2c66affSColin Finck BOOL CShellCommandOwner::Match(const TCHAR *pchCommand)
48*c2c66affSColin Finck {
49*c2c66affSColin Finck 	if (_tcsicmp(pchCommand,OWNER_CMD) == 0)
50*c2c66affSColin Finck 		return TRUE;
51*c2c66affSColin Finck 	if (_tcsnicmp(pchCommand,OWNER_CMD _T(".."),OWNER_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
52*c2c66affSColin Finck 		return TRUE;
53*c2c66affSColin Finck 	if (_tcsnicmp(pchCommand,OWNER_CMD _T("/") ,OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
54*c2c66affSColin Finck 		return TRUE;
55*c2c66affSColin Finck 	if (_tcsnicmp(pchCommand,OWNER_CMD _T("\\"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
56*c2c66affSColin Finck 		return TRUE;
57*c2c66affSColin Finck 	return FALSE;
58*c2c66affSColin Finck }
59*c2c66affSColin Finck 
Execute(CConsole & rConsole,CArgumentParser & rArguments)60*c2c66affSColin Finck int CShellCommandOwner::Execute(CConsole &rConsole, CArgumentParser& rArguments)
61*c2c66affSColin Finck {
62*c2c66affSColin Finck 	const TCHAR *pchKey = NULL;
63*c2c66affSColin Finck 	BOOL blnDo = TRUE;
64*c2c66affSColin Finck 	BOOL blnBadParameter = FALSE;
65*c2c66affSColin Finck 	BOOL blnHelp = FALSE;
66*c2c66affSColin Finck 	const TCHAR *pchParameter;
67*c2c66affSColin Finck 	DWORD dwError;
68*c2c66affSColin Finck 
69*c2c66affSColin Finck 	rArguments.ResetArgumentIteration();
70*c2c66affSColin Finck 	const TCHAR *pchCommandItself = rArguments.GetNextArgument();
71*c2c66affSColin Finck 
72*c2c66affSColin Finck 	if ((_tcsnicmp(pchCommandItself,OWNER_CMD _T(".."),OWNER_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
73*c2c66affSColin Finck 		(_tcsnicmp(pchCommandItself,OWNER_CMD _T("\\"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
74*c2c66affSColin Finck 	{
75*c2c66affSColin Finck 		pchKey = pchCommandItself + OWNER_CMD_LENGTH;
76*c2c66affSColin Finck 	}
77*c2c66affSColin Finck 	else if (_tcsnicmp(pchCommandItself,OWNER_CMD _T("/"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
78*c2c66affSColin Finck 	{
79*c2c66affSColin Finck 		pchParameter = pchCommandItself + OWNER_CMD_LENGTH;
80*c2c66affSColin Finck 		goto CheckOwnerArgument;
81*c2c66affSColin Finck 	}
82*c2c66affSColin Finck 
83*c2c66affSColin Finck 	while((pchParameter = rArguments.GetNextArgument()) != NULL)
84*c2c66affSColin Finck 	{
85*c2c66affSColin Finck CheckOwnerArgument:
86*c2c66affSColin Finck 		blnBadParameter = FALSE;
87*c2c66affSColin Finck 		if ((_tcsicmp(pchParameter,_T("/?")) == 0)
88*c2c66affSColin Finck 			||(_tcsicmp(pchParameter,_T("-?")) == 0))
89*c2c66affSColin Finck 		{
90*c2c66affSColin Finck 			blnHelp = TRUE;
91*c2c66affSColin Finck 			blnDo = pchKey != NULL;
92*c2c66affSColin Finck 		}
93*c2c66affSColin Finck 		else if (!pchKey)
94*c2c66affSColin Finck 		{
95*c2c66affSColin Finck 			pchKey = pchParameter;
96*c2c66affSColin Finck 			blnDo = TRUE;
97*c2c66affSColin Finck 		}
98*c2c66affSColin Finck 		else
99*c2c66affSColin Finck 		{
100*c2c66affSColin Finck 			blnBadParameter = TRUE;
101*c2c66affSColin Finck 		}
102*c2c66affSColin Finck 		if (blnBadParameter)
103*c2c66affSColin Finck 		{
104*c2c66affSColin Finck 			rConsole.Write(_T("Bad parameter: "));
105*c2c66affSColin Finck 			rConsole.Write(pchParameter);
106*c2c66affSColin Finck 			rConsole.Write(_T("\n"));
107*c2c66affSColin Finck 		}
108*c2c66affSColin Finck 	}
109*c2c66affSColin Finck 
110*c2c66affSColin Finck 	CRegistryKey Key;
111*c2c66affSColin Finck 
112*c2c66affSColin Finck   if (!m_rTree.GetKey(pchKey?pchKey:_T("."),KEY_QUERY_VALUE|READ_CONTROL,Key))
113*c2c66affSColin Finck   {
114*c2c66affSColin Finck     rConsole.Write(m_rTree.GetLastErrorDescription());
115*c2c66affSColin Finck     blnDo = FALSE;
116*c2c66affSColin Finck   }
117*c2c66affSColin Finck 
118*c2c66affSColin Finck 	if (blnHelp)
119*c2c66affSColin Finck 	{
120*c2c66affSColin Finck 		rConsole.Write(GetHelpString());
121*c2c66affSColin Finck 	}
122*c2c66affSColin Finck 
123*c2c66affSColin Finck 	if (blnDo&&blnHelp) rConsole.Write(_T("\n"));
124*c2c66affSColin Finck 
125*c2c66affSColin Finck 	if (!blnDo)
126*c2c66affSColin Finck     return 0;
127*c2c66affSColin Finck 
128*c2c66affSColin Finck   if (Key.IsRoot())
129*c2c66affSColin Finck   {	// root key
130*c2c66affSColin Finck     rConsole.Write(OWNER_CMD COMMAND_NA_ON_ROOT);
131*c2c66affSColin Finck     return 0;
132*c2c66affSColin Finck   }
133*c2c66affSColin Finck 
134*c2c66affSColin Finck   PISECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
135*c2c66affSColin Finck   TCHAR *pchName = NULL, *pchDomainName = NULL;
136*c2c66affSColin Finck   try
137*c2c66affSColin Finck   {
138*c2c66affSColin Finck     DWORD dwSecurityDescriptorLength;
139*c2c66affSColin Finck     rConsole.Write(_T("Key : "));
140*c2c66affSColin Finck     rConsole.Write(_T("\\"));
141*c2c66affSColin Finck     rConsole.Write(Key.GetKeyName());
142*c2c66affSColin Finck     rConsole.Write(_T("\n"));
143*c2c66affSColin Finck     dwError = Key.GetSecurityDescriptorLength(&dwSecurityDescriptorLength);
144*c2c66affSColin Finck     if (dwError != ERROR_SUCCESS) throw dwError;
145*c2c66affSColin Finck 
146*c2c66affSColin Finck     pSecurityDescriptor = (PISECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength];
147*c2c66affSColin Finck     DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength;
148*c2c66affSColin Finck     dwError = Key.GetSecurityDescriptor((SECURITY_INFORMATION)OWNER_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1);
149*c2c66affSColin Finck     if (dwError != ERROR_SUCCESS) throw dwError;
150*c2c66affSColin Finck     PSID psidOwner;
151*c2c66affSColin Finck     BOOL blnOwnerDefaulted;
152*c2c66affSColin Finck     if (!GetSecurityDescriptorOwner(pSecurityDescriptor,&psidOwner,&blnOwnerDefaulted))
153*c2c66affSColin Finck       throw GetLastError();
154*c2c66affSColin Finck     if (psidOwner == NULL)
155*c2c66affSColin Finck     {
156*c2c66affSColin Finck       rConsole.Write(_T("Key has no owner."));
157*c2c66affSColin Finck     }
158*c2c66affSColin Finck     else
159*c2c66affSColin Finck     {
160*c2c66affSColin Finck       if (!IsValidSid(psidOwner))
161*c2c66affSColin Finck       {
162*c2c66affSColin Finck         rConsole.Write(_T("Key has invalid owner SID."));
163*c2c66affSColin Finck       }
164*c2c66affSColin Finck       else
165*c2c66affSColin Finck       {
166*c2c66affSColin Finck         rConsole.Write(_T("Key Owner: \n"));
167*c2c66affSColin Finck         DWORD dwSIDStringSize = 0;
168*c2c66affSColin Finck         BOOL blnRet = GetTextualSid(psidOwner,NULL,&dwSIDStringSize);
169*c2c66affSColin Finck         ASSERT(!blnRet);
170*c2c66affSColin Finck         ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
171*c2c66affSColin Finck         TCHAR *pchSID = new TCHAR[dwSIDStringSize];
172*c2c66affSColin Finck         if(!GetTextualSid(psidOwner,pchSID,&dwSIDStringSize))
173*c2c66affSColin Finck         {
174*c2c66affSColin Finck           dwError = GetLastError();
175*c2c66affSColin Finck           ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
176*c2c66affSColin Finck           rConsole.Write(_T("Error "));
177*c2c66affSColin Finck           TCHAR Buffer[256];
178*c2c66affSColin Finck           rConsole.Write(_itoa(dwError,Buffer,10));
179*c2c66affSColin Finck           rConsole.Write(_T("\nGetting string representation of SID\n"));
180*c2c66affSColin Finck         }
181*c2c66affSColin Finck         else
182*c2c66affSColin Finck         {
183*c2c66affSColin Finck           rConsole.Write(_T("\tSID: "));
184*c2c66affSColin Finck           rConsole.Write(pchSID);
185*c2c66affSColin Finck           rConsole.Write(_T("\n"));
186*c2c66affSColin Finck         }
187*c2c66affSColin Finck         delete [] pchSID;
188*c2c66affSColin Finck         DWORD dwNameBufferLength, dwDomainNameBufferLength;
189*c2c66affSColin Finck         dwNameBufferLength = 1024;
190*c2c66affSColin Finck         dwDomainNameBufferLength = 1024;
191*c2c66affSColin Finck         pchName = new TCHAR [dwNameBufferLength];
192*c2c66affSColin Finck         pchDomainName = new TCHAR [dwDomainNameBufferLength];
193*c2c66affSColin Finck         DWORD dwNameLength = dwNameBufferLength, dwDomainNameLength = dwDomainNameBufferLength;
194*c2c66affSColin Finck         SID_NAME_USE Use;
195*c2c66affSColin Finck         if (!LookupAccountSid(NULL,psidOwner,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use))
196*c2c66affSColin Finck           throw GetLastError();
197*c2c66affSColin Finck         else
198*c2c66affSColin Finck         {
199*c2c66affSColin Finck           rConsole.Write(_T("\tOwner Domain: "));
200*c2c66affSColin Finck           rConsole.Write(pchDomainName);
201*c2c66affSColin Finck           rConsole.Write(_T("\n"));
202*c2c66affSColin Finck           rConsole.Write(_T("\tOwner Name: "));
203*c2c66affSColin Finck           rConsole.Write(pchName);
204*c2c66affSColin Finck           rConsole.Write(_T("\n\tSID type: "));
205*c2c66affSColin Finck           rConsole.Write(GetSidTypeName(Use));
206*c2c66affSColin Finck           rConsole.Write(_T("\n"));
207*c2c66affSColin Finck           rConsole.Write(_T("\tOwner defaulted: "));
208*c2c66affSColin Finck           rConsole.Write(blnOwnerDefaulted?_T("Yes"):_T("No"));
209*c2c66affSColin Finck           rConsole.Write(_T("\n"));
210*c2c66affSColin Finck         }
211*c2c66affSColin Finck         delete [] pchName;
212*c2c66affSColin Finck         pchName = NULL;
213*c2c66affSColin Finck         delete [] pchDomainName;
214*c2c66affSColin Finck         pchDomainName = NULL;
215*c2c66affSColin Finck 
216*c2c66affSColin Finck       }
217*c2c66affSColin Finck     }
218*c2c66affSColin Finck     delete [] pSecurityDescriptor;
219*c2c66affSColin Finck   }
220*c2c66affSColin Finck   catch (DWORD dwError)
221*c2c66affSColin Finck   {
222*c2c66affSColin Finck     rConsole.Write(_T("Error "));
223*c2c66affSColin Finck     TCHAR Buffer[256];
224*c2c66affSColin Finck     rConsole.Write(_itoa(dwError,Buffer,10));
225*c2c66affSColin Finck     rConsole.Write(_T("\n"));
226*c2c66affSColin Finck     if (pchName) delete [] pchName;
227*c2c66affSColin Finck     if (pchDomainName) delete [] pchDomainName;
228*c2c66affSColin Finck     if (pSecurityDescriptor) delete [] pSecurityDescriptor;
229*c2c66affSColin Finck   }
230*c2c66affSColin Finck 
231*c2c66affSColin Finck 	return 0;
232*c2c66affSColin Finck }
233*c2c66affSColin Finck 
GetHelpString()234*c2c66affSColin Finck const TCHAR * CShellCommandOwner::GetHelpString()
235*c2c66affSColin Finck {
236*c2c66affSColin Finck 	return OWNER_CMD_SHORT_DESC
237*c2c66affSColin Finck 			_T("Syntax: ") OWNER_CMD _T(" [<KEY>] [/?]\n\n")
238*c2c66affSColin Finck 			_T("    <KEY> - Optional relative path of desired key.\n")
239*c2c66affSColin Finck 			_T("    /?    - This help.\n\n")
240*c2c66affSColin Finck 			_T("Without parameters, command displays information about owner of current key.\n");
241*c2c66affSColin Finck }
242*c2c66affSColin Finck 
GetHelpShortDescriptionString()243*c2c66affSColin Finck const TCHAR * CShellCommandOwner::GetHelpShortDescriptionString()
244*c2c66affSColin Finck {
245*c2c66affSColin Finck 	return OWNER_CMD_SHORT_DESC;
246*c2c66affSColin Finck }
247*c2c66affSColin Finck 
248