1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32utils/setcap/main.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,248 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32utils\setcap\main.cpp
1.18 +// SETCAP.EXE
1.19 +// Makes a copy of an executable file and gives it the specified capabilities.
1.20 +// It may also, optionally, modify the Secure or Vendor IDs.
1.21 +// This runs under the Symbian OS - it is not a native PC utility.
1.22 +// Command line syntax:
1.23 +// SETCAP source_exe capability [-SID secureId] [-VID vendorId] [destination_path]
1.24 +// source_exe Name and path of an executable file (default path is Z:\SYS\BIN\)
1.25 +// capability Hexadecimal value for capabilities
1.26 +// secureId Optional hexadecimal value of secure ID
1.27 +// vendorId Optional hexadecimal value of vendor ID
1.28 +// destination_path Optional name and path to copy the exe to
1.29 +// (defaults to C:\SYS\BIN\source_exe_name)
1.30 +// Notes
1.31 +// 1. The 'capability' command line argument is the hexadecimal value of the
1.32 +// capabilities when they are represented as a bit-field. E.g. the 3 capabilities
1.33 +// LocalServices, ReadUserData and WriteUserData would together have a value of:
1.34 +// (1<<ECapabilityLocalServices) | (<<ECapabilityReadUserData) | (1<<ECapabilityWriteUserData)
1.35 +// Which in hexadecimal is '1c000'
1.36 +// If the value supplied includes capabilities which aren't supported by the current
1.37 +// OS version, then these are ignored and not added to the file.
1.38 +// 2. If the source executable is in ROM it must be a RAM executable image, not an
1.39 +// execute-in-place image. I.e. its entry in an OBY file must start with "data=" and
1.40 +// not "file=".
1.41 +// For OBY files generated automatically by "ABLD ROMFILE" this needs to be achieved by
1.42 +// using lines similar to the following in the executables MMP file:
1.43 +// ROMTARGET // Empty ROM path means don't include normal execute-in-place file
1.44 +// RAMTARGET \sys\bin\ // Target path (in ROM) for RAM executable image
1.45 +// 3. The Symbian OS only allows one binary file with a given name; the name doesn't
1.46 +// include file path or extension. This means if SETCAP is used to make a copy of a
1.47 +// binary which is already loaded then the copy will not get loaded when used with
1.48 +// RProcess::Create(), instead the already loaded version will be used. To avoid this,
1.49 +// use SETCAP to give the copy a different name. E.g. "SETCAP test.exe 1234 test2.exe"
1.50 +//
1.51 +//
1.52 +
1.53 +/**
1.54 + @file
1.55 +*/
1.56 +
1.57 +#include "setcap.h"
1.58 +
1.59 +#include <f32file.h>
1.60 +
1.61 +TParse SourceName;
1.62 +TParse DestinationName;
1.63 +RFs Fs;
1.64 +
1.65 +#ifdef __WINS__
1.66 +
1.67 +TInt DoIt()
1.68 + {
1.69 + TInt r;
1.70 +
1.71 + TBuf<MAX_PATH> sName;
1.72 + r = MapEmulatedFileName(sName, SourceName.NameAndExt());
1.73 + if(r!=KErrNone)
1.74 + return r;
1.75 +
1.76 + TBuf<MAX_PATH> dName;
1.77 + r = MapEmulatedFileName(dName, DestinationName.FullName());
1.78 + if(r!=KErrNone)
1.79 + return r;
1.80 +
1.81 + if(!Emulator::CopyFile((LPCTSTR)sName.PtrZ(),(LPCTSTR)dName.PtrZ(),FALSE))
1.82 + return KErrGeneral;
1.83 +
1.84 + HANDLE hFile=Emulator::CreateFile((LPCTSTR)dName.PtrZ(),GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
1.85 + if (hFile==INVALID_HANDLE_VALUE)
1.86 + return KErrArgument;
1.87 +
1.88 + return SetCap(hFile);
1.89 + }
1.90 +
1.91 +#else // Not WINS
1.92 +
1.93 +#include <f32file.h>
1.94 +
1.95 +RFile Source;
1.96 +RFile Destination;
1.97 +
1.98 +TInt DoIt()
1.99 + {
1.100 + TInt r;
1.101 +
1.102 + r=Source.Open(Fs,SourceName.FullName(),EFileRead);
1.103 + if(r!=KErrNone)
1.104 + return r;
1.105 +
1.106 + r = Destination.Replace(Fs,DestinationName.FullName(),EFileWrite);
1.107 + if(r!=KErrNone)
1.108 + return r;
1.109 +
1.110 + TUint8* buffer;
1.111 + const TInt KBufferSize = 0x10000;
1.112 +
1.113 + buffer = (TUint8*)User::Alloc(KBufferSize);
1.114 + if(!buffer)
1.115 + return KErrNoMemory;
1.116 +
1.117 + TPtr8 p(buffer,KBufferSize,KBufferSize);
1.118 + TInt n = 0;
1.119 + while (r==KErrNone)
1.120 + {
1.121 + r = Source.Read(p);
1.122 + if(r!=KErrNone || p.Size()==0)
1.123 + break;
1.124 + if (n==0)
1.125 + {
1.126 + // first block contains header
1.127 + if ((TUint)p.Size() < sizeof(E32ImageHeader))
1.128 + {
1.129 + r = KErrCorrupt;
1.130 + break;
1.131 + }
1.132 + E32ImageHeader* h = (E32ImageHeader*)buffer;
1.133 + r = SetCap(h);
1.134 + }
1.135 + if (r==KErrNone)
1.136 + r = Destination.Write(p);
1.137 + ++n;
1.138 + }
1.139 +
1.140 + delete buffer;
1.141 +
1.142 + Source.Close();
1.143 + Destination.Close();
1.144 +
1.145 + return r;
1.146 + }
1.147 +
1.148 +#endif
1.149 +
1.150 +_LIT(KDefaultSourcePath,"z:\\sys\\bin\\");
1.151 +_LIT(KDefaultDestinationPath,"?:\\sys\\bin\\");
1.152 +_LIT(KSIDOption,"-SID");
1.153 +_LIT(KVIDOption,"-VID");
1.154 +
1.155 +TInt ParseCommandLine()
1.156 + {
1.157 + TBuf<256> c;
1.158 + User::CommandLine(c);
1.159 +
1.160 + // Get exe name
1.161 + TLex l(c);
1.162 + if(SourceName.SetNoWild(l.NextToken(),0,&KDefaultSourcePath)!=KErrNone)
1.163 + return KErrArgument;
1.164 +
1.165 + // Get capability
1.166 + TLex cl(l.NextToken());
1.167 + if(cl.Val((TInt64&)Capability,EHex)!=KErrNone)
1.168 + return KErrArgument;
1.169 +
1.170 + // Mask out unsupported capabilities
1.171 + TCapabilitySet all;
1.172 + all.SetAllSupported();
1.173 + ((TCapabilitySet&)Capability).Intersection(all);
1.174 +
1.175 + // We always update capabilities in the headers
1.176 + CapabilitySet = ETrue;
1.177 +
1.178 + // Get options
1.179 + SecureIdSet = EFalse;
1.180 + VendorIdSet = EFalse;
1.181 + TPtrC nextToken;
1.182 + for (;;)
1.183 + {
1.184 + nextToken.Set(l.NextToken());
1.185 + if (nextToken == KSIDOption)
1.186 + {
1.187 + // SID specified
1.188 + nextToken.Set(l.NextToken());
1.189 + if (nextToken == KNullDesC)
1.190 + return KErrArgument;
1.191 + TLex sl(nextToken);
1.192 + if(sl.Val(SecureId.iId,EHex)!=KErrNone)
1.193 + return KErrArgument;
1.194 + SecureIdSet = ETrue;
1.195 + }
1.196 + else if (nextToken == KVIDOption)
1.197 + {
1.198 + // VID specified
1.199 + nextToken.Set(l.NextToken());
1.200 + if (nextToken == KNullDesC)
1.201 + return KErrArgument;
1.202 + TLex sl(nextToken);
1.203 + if(sl.Val(VendorId.iId,EHex)!=KErrNone)
1.204 + return KErrArgument;
1.205 + VendorIdSet = ETrue;
1.206 + }
1.207 + else
1.208 + break;
1.209 + }
1.210 +
1.211 + // Get target path
1.212 + TPtrC s(SourceName.NameAndExt());
1.213 + TBuf<sizeof(KDefaultDestinationPath)> defaultDestinationPath(KDefaultDestinationPath);
1.214 + defaultDestinationPath[0] = (TUint8) RFs::GetSystemDriveChar();
1.215 +
1.216 + if(DestinationName.SetNoWild(nextToken,&s,&defaultDestinationPath)!=KErrNone)
1.217 + return KErrArgument;
1.218 +
1.219 + // Check we used all the arguments
1.220 + if (l.NextToken() != KNullDesC)
1.221 + return KErrArgument;
1.222 +
1.223 + return KErrNone;
1.224 + }
1.225 +
1.226 +
1.227 +TInt E32Main()
1.228 + {
1.229 + TInt r;
1.230 +
1.231 + // Turn off lazy dll unloading
1.232 + RLoader l;
1.233 + if ((r=l.Connect())!=KErrNone)
1.234 + return r;
1.235 + r = l.CancelLazyDllUnload();
1.236 + l.Close();
1.237 + if (r!=KErrNone)
1.238 + return r;
1.239 +
1.240 + r = ParseCommandLine();
1.241 + if(r!=KErrNone)
1.242 + return r;
1.243 + r = Fs.Connect();
1.244 + if(r!=KErrNone)
1.245 + return r;
1.246 + r = Fs.MkDirAll(DestinationName.FullName());
1.247 + if(r==KErrNone || r==KErrAlreadyExists)
1.248 + r = DoIt();
1.249 + Fs.Close();
1.250 + return r;
1.251 + }