e32tools/e32lib/setcap/setcap.cpp
changeset 0 044383f39525
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/e32tools/e32lib/setcap/setcap.cpp	Tue Oct 27 16:36:35 2009 +0000
@@ -0,0 +1,184 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32utils\setcap\setcap.cpp
+// 
+//
+
+#include "setcap.h"
+
+#include <e32std.h>
+
+GLDEF_D TBool CapabilitySet;
+GLDEF_D SCapabilitySet Capability;
+GLDEF_D TBool SecureIdSet;
+GLDEF_D TSecureId SecureId;
+GLDEF_D TBool VendorIdSet;
+GLDEF_D TVendorId VendorId;
+
+#ifdef __TOOLS__
+#define		Mem		HMem
+#include "h_utl.h"
+#endif //__TOOLS__
+
+#if !defined(__EPOC32__) && !defined(__LINUX__)
+
+GLDEF_C TInt SetCap(HANDLE hFile)
+	{
+	DWORD ret;
+	TText8 checkedUidBuf[sizeof(TCheckedUid)];
+	ReadFile(hFile,checkedUidBuf,sizeof(TCheckedUid),&ret,NULL);
+	if (ret!=sizeof(TCheckedUid))
+		goto close;
+
+	//Look at PE file for UID section
+	{
+	const TInt KPeHeaderAddrAddr=0x3c;
+	const TInt KPeHeaderAddrSize=0x01;
+	const TInt KNumberOfSectionsOffset=0x06;
+	const TInt KNumberOfSectionsSize=0x02;
+	const TInt KSectionTableOffset=0xf8;
+	const TInt KSectionHeaderSize=0x28;
+	const TInt KSectionNameLength=0x08;
+	const TInt KPtrToRawDataOffset=0x14;
+	const TInt KPtrToRawDataSize=0x04;
+	const TText8 peText[4]={'P','E',0,0};
+	const TText8 uidText[8]={'.','S','Y','M','B','I','A','N'};
+		
+	//Read address of start of PE header
+	if (SetFilePointer(hFile,KPeHeaderAddrAddr,0,FILE_BEGIN)==0xFFFFFFFF)
+		goto close;
+	TInt peAddr=0;
+	ReadFile(hFile,&peAddr,KPeHeaderAddrSize,&ret,NULL);
+	if (ret!=KPeHeaderAddrSize)
+		goto close;
+		
+	//Check it really is the start of PE header
+	if (SetFilePointer(hFile,peAddr,0,FILE_BEGIN)==0xFFFFFFFF)
+		goto close;
+	TText8 text[4];
+	ReadFile(hFile,text,4,&ret,NULL);
+	if (*(TInt32*)text!=*(TInt32*)peText)
+		goto close;
+		
+	//Read number of sections
+	if (SetFilePointer(hFile,peAddr+KNumberOfSectionsOffset,0,FILE_BEGIN)==0xFFFFFFFF)
+		goto close;
+	TInt sections=0;
+	ReadFile(hFile,&sections,KNumberOfSectionsSize,&ret,NULL);
+	if (ret!=KNumberOfSectionsSize)
+		goto close;
+
+	//Go through section headers looking for UID section
+	if (SetFilePointer(hFile,peAddr+KSectionTableOffset,0,FILE_BEGIN)==0xFFFFFFFF)
+		goto close;
+	TInt i=0;
+	for(;i<sections;i++)
+		{
+		TText8 name[KSectionNameLength];
+		ReadFile(hFile,name,KSectionNameLength,&ret,NULL);
+		if (ret!=KSectionNameLength)
+			goto close;
+		if (*(TInt64*)name==*(TInt64*)uidText)
+			break;
+		if (SetFilePointer(hFile,KSectionHeaderSize-KSectionNameLength,0,FILE_CURRENT)==0xFFFFFFFF)
+			goto close;
+		}
+	if (i==sections)
+		goto close;
+
+	//Read RVA/Offset
+	if (SetFilePointer(hFile,KPtrToRawDataOffset-KSectionNameLength,0,FILE_CURRENT)==0xFFFFFFFF)
+		goto close;
+	TInt uidOffset;
+	ReadFile(hFile,&uidOffset,KPtrToRawDataSize,&ret,NULL);
+	if (ret!=KPtrToRawDataSize)
+		goto close;
+
+	//SYMBIAN Header
+	if (SetFilePointer(hFile,uidOffset,0,FILE_BEGIN)==0xFFFFFFFF)
+		goto close;
+
+	TEmulatorImageHeader header;
+
+	ReadFile(hFile,&header,sizeof(header),&ret,NULL);
+	if (ret!=sizeof(header))
+		goto close;
+
+	// set new capabilities
+	if (CapabilitySet)
+		{
+		header.iS.iCaps = Capability;
+		}
+
+	// set new secure id and vendor id if specified
+	if (SecureIdSet)
+		{
+		header.iS.iSecureId = SecureId.iId;
+		}
+	if (VendorIdSet)
+		{
+		header.iS.iVendorId = VendorId.iId;
+		}
+
+	// save header values
+	Capability = header.iS.iCaps;
+	SecureId.iId = header.iS.iSecureId;
+	VendorId.iId = header.iS.iVendorId;
+
+	if (SetFilePointer(hFile,uidOffset,0,FILE_BEGIN)==0xFFFFFFFF)
+		goto close;
+
+	BOOL b = WriteFile(hFile,&header,sizeof(header),&ret,NULL);
+	if (b==FALSE)
+		goto close;
+
+	CloseHandle(hFile);
+	return KErrNone;
+	}
+close:
+	CloseHandle(hFile);
+	return KErrGeneral;
+	}
+
+#endif //__EPOC32__
+
+#ifndef __WINS__
+
+GLDEF_C TInt SetCap(E32ImageHeader* h)
+	{
+	TUint hdrfmt = h->HeaderFormat();
+	if (hdrfmt < KImageHdrFmt_V)
+		return KErrNotSupported;
+	E32ImageHeaderV* v = (E32ImageHeaderV*)h;
+	if (CapabilitySet)
+		v->iS.iCaps = Capability;
+	if (SecureIdSet)
+		v->iS.iSecureId = SecureId.iId;
+	if (VendorIdSet)
+		v->iS.iVendorId = VendorId.iId;	
+
+	// save header values
+	Capability = v->iS.iCaps;
+	SecureId.iId = v->iS.iSecureId;
+	VendorId.iId = v->iS.iVendorId;
+
+	// regenerate CRC
+	v->iHeaderCrc = KImageCrcInitialiser;
+	TUint32 crc = 0;
+	Mem::Crc32(crc, v, v->TotalSize());
+	v->iHeaderCrc = crc;
+	return KErrNone;
+	}
+
+#endif //__WINS__