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