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