os/kernelhwsrv/kerneltest/e32utils/setcap/main.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32utils\setcap\main.cpp
    15 // SETCAP.EXE
    16 // Makes a copy of an executable file and gives it the specified capabilities.
    17 // It may also, optionally, modify the Secure or Vendor IDs.
    18 // This runs under the Symbian OS - it is not a native PC utility.
    19 // Command line syntax:
    20 // SETCAP source_exe capability [-SID secureId] [-VID vendorId] [destination_path]
    21 // source_exe         Name and path of an executable file (default path is Z:\SYS\BIN\)
    22 // capability         Hexadecimal value for capabilities
    23 // secureId			 Optional hexadecimal value of secure ID
    24 // vendorId			 Optional hexadecimal value of vendor ID
    25 // destination_path   Optional name and path to copy the exe to
    26 // (defaults to C:\SYS\BIN\source_exe_name)
    27 // Notes
    28 // 1.  The 'capability' command line argument is the hexadecimal value of the
    29 // capabilities when they are represented as a bit-field. E.g. the 3 capabilities
    30 // LocalServices, ReadUserData and WriteUserData would together have a value of:
    31 // (1<<ECapabilityLocalServices) | (<<ECapabilityReadUserData) | (1<<ECapabilityWriteUserData)
    32 // Which in hexadecimal is '1c000'
    33 // If the value supplied includes capabilities which aren't supported by the current
    34 // OS version, then these are ignored and not added to the file.
    35 // 2.  If the source executable is in ROM it must be a RAM executable image, not an
    36 // execute-in-place image. I.e. its entry in an OBY file must start with "data=" and
    37 // not "file=".
    38 // For OBY files generated automatically by "ABLD ROMFILE" this needs to be achieved by
    39 // using lines similar to the following in the executables MMP file:
    40 // ROMTARGET    // Empty ROM path means don't include normal execute-in-place file
    41 // RAMTARGET \sys\bin\    // Target path (in ROM) for RAM executable image
    42 // 3.  The Symbian OS only allows one binary file with a given name; the name doesn't
    43 // include file path or extension. This means if SETCAP is used to make a copy of a
    44 // binary which is already loaded then the copy will not get loaded when used with
    45 // RProcess::Create(), instead the already loaded version will be used. To avoid this,
    46 // use SETCAP to give the copy a different name. E.g. "SETCAP test.exe 1234 test2.exe"
    47 // 
    48 //
    49 
    50 /**
    51  @file
    52 */
    53 
    54 #include "setcap.h"
    55 
    56 #include <f32file.h>
    57 
    58 TParse SourceName;
    59 TParse DestinationName;
    60 RFs Fs;
    61 
    62 #ifdef __WINS__
    63 
    64 TInt DoIt()
    65 	{
    66 	TInt  r;
    67 
    68 	TBuf<MAX_PATH> sName;
    69 	r = MapEmulatedFileName(sName, SourceName.NameAndExt());
    70 	if(r!=KErrNone)
    71 		return r;
    72 
    73 	TBuf<MAX_PATH> dName;
    74 	r = MapEmulatedFileName(dName, DestinationName.FullName());
    75 	if(r!=KErrNone)
    76 		return r;
    77 
    78 	if(!Emulator::CopyFile((LPCTSTR)sName.PtrZ(),(LPCTSTR)dName.PtrZ(),FALSE))
    79 		return KErrGeneral;
    80 
    81 	HANDLE hFile=Emulator::CreateFile((LPCTSTR)dName.PtrZ(),GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
    82 	if (hFile==INVALID_HANDLE_VALUE)
    83 		return KErrArgument;
    84 
    85 	return SetCap(hFile);
    86 	}
    87 
    88 #else // Not WINS
    89 
    90 #include <f32file.h>
    91 
    92 RFile Source;
    93 RFile Destination;
    94 
    95 TInt DoIt()
    96 	{
    97 	TInt r;
    98 
    99 	r=Source.Open(Fs,SourceName.FullName(),EFileRead);
   100 	if(r!=KErrNone)
   101 		return r;
   102 
   103 	r = Destination.Replace(Fs,DestinationName.FullName(),EFileWrite);
   104 	if(r!=KErrNone)
   105 		return r;
   106 
   107 	TUint8* buffer;
   108 	const TInt KBufferSize = 0x10000;
   109 
   110 	buffer = (TUint8*)User::Alloc(KBufferSize);
   111 	if(!buffer)
   112 		return KErrNoMemory;
   113 
   114 	TPtr8 p(buffer,KBufferSize,KBufferSize);
   115 	TInt n = 0;
   116 	while (r==KErrNone)
   117 		{
   118 		r = Source.Read(p);
   119 		if(r!=KErrNone || p.Size()==0)
   120 			break;
   121 		if (n==0)
   122 			{
   123 			// first block contains header
   124 			if ((TUint)p.Size() < sizeof(E32ImageHeader))
   125 				{
   126 				r = KErrCorrupt;
   127 				break;
   128 				}
   129 			E32ImageHeader* h = (E32ImageHeader*)buffer;
   130 			r = SetCap(h);
   131 			}
   132 		if (r==KErrNone)
   133 			r = Destination.Write(p);
   134 		++n;
   135 		}
   136 
   137 	delete buffer;
   138 
   139 	Source.Close();
   140 	Destination.Close();
   141 
   142 	return r;
   143 	}
   144 
   145 #endif
   146 
   147 _LIT(KDefaultSourcePath,"z:\\sys\\bin\\");
   148 _LIT(KDefaultDestinationPath,"?:\\sys\\bin\\");
   149 _LIT(KSIDOption,"-SID");
   150 _LIT(KVIDOption,"-VID");
   151 
   152 TInt ParseCommandLine()
   153 	{
   154 	TBuf<256> c;
   155 	User::CommandLine(c);
   156 
   157 	// Get exe name
   158 	TLex l(c);
   159 	if(SourceName.SetNoWild(l.NextToken(),0,&KDefaultSourcePath)!=KErrNone)
   160 		return KErrArgument;
   161 
   162 	// Get capability
   163 	TLex cl(l.NextToken());
   164 	if(cl.Val((TInt64&)Capability,EHex)!=KErrNone)
   165 		return KErrArgument;
   166 
   167 	// Mask out unsupported capabilities
   168 	TCapabilitySet all;
   169 	all.SetAllSupported();
   170 	((TCapabilitySet&)Capability).Intersection(all);
   171 
   172 	// We always update capabilities in the headers
   173 	CapabilitySet = ETrue;
   174 
   175 	// Get options
   176 	SecureIdSet = EFalse;
   177 	VendorIdSet = EFalse;
   178 	TPtrC nextToken;
   179 	for (;;)
   180 		{
   181 		nextToken.Set(l.NextToken());
   182 		if (nextToken == KSIDOption)
   183 			{
   184 			// SID specified
   185 			nextToken.Set(l.NextToken());
   186 			if (nextToken == KNullDesC)
   187 				return KErrArgument;				
   188 			TLex sl(nextToken);
   189 			if(sl.Val(SecureId.iId,EHex)!=KErrNone)
   190 				return KErrArgument;
   191 			SecureIdSet = ETrue;
   192 			}
   193 		else if (nextToken == KVIDOption)
   194 			{
   195 			// VID specified
   196 			nextToken.Set(l.NextToken());
   197 			if (nextToken == KNullDesC)
   198 				return KErrArgument;				
   199 			TLex sl(nextToken);
   200 			if(sl.Val(VendorId.iId,EHex)!=KErrNone)
   201 				return KErrArgument;
   202 			VendorIdSet = ETrue;
   203 			}
   204 		else
   205 			break;
   206 		}
   207 				
   208 	// Get target path
   209 	TPtrC s(SourceName.NameAndExt());
   210 	TBuf<sizeof(KDefaultDestinationPath)> defaultDestinationPath(KDefaultDestinationPath);
   211 	defaultDestinationPath[0] = (TUint8) RFs::GetSystemDriveChar();
   212 	
   213 	if(DestinationName.SetNoWild(nextToken,&s,&defaultDestinationPath)!=KErrNone)
   214 		return KErrArgument;
   215 
   216 	// Check we used all the arguments
   217 	if (l.NextToken() != KNullDesC)
   218 		return KErrArgument;
   219 
   220 	return KErrNone;
   221 	}
   222 
   223 
   224 TInt E32Main()
   225 	{
   226 	TInt r;
   227 
   228 	 // Turn off lazy dll unloading
   229 	RLoader l;
   230 	if ((r=l.Connect())!=KErrNone)
   231 		return r;
   232 	r = l.CancelLazyDllUnload();
   233 	l.Close();
   234 	if (r!=KErrNone)
   235 		return r;
   236 	
   237 	r = ParseCommandLine();
   238 	if(r!=KErrNone)
   239 		return r;
   240 	r = Fs.Connect();
   241 	if(r!=KErrNone)
   242 		return r;
   243 	r = Fs.MkDirAll(DestinationName.FullName());
   244 	if(r==KErrNone || r==KErrAlreadyExists)
   245 		r = DoIt();
   246 	Fs.Close();
   247 	return r;
   248 	}