os/kernelhwsrv/kerneltest/e32utils/setcap/main.cpp
changeset 0 bde4ae8d615e
     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 +	}