secureswitools/swisistools/source/sisxlibrary/utility.cpp
changeset 0 ba25891c3a9e
child 24 5cc91383ab1e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/swisistools/source/sisxlibrary/utility.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,507 @@
+/*
+* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+*
+*/
+
+
+/**
+ @file 
+ @internalComponent
+ @released
+*/
+
+#include "utility.h"
+#include "exception.h"
+#include "utility_interface.h"
+#include "utils.h"
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <fstream>
+#include <algorithm>
+
+std::wostream* SISLogger::iStream = NULL;
+
+void SISLogger::SetStream(std::wostream& aStream)
+	{
+	iStream = &aStream;
+	}
+
+void SISLogger::Log(const std::wstring& aString)
+	{
+	if(NULL != iStream)
+		{
+		(*iStream) << aString;
+		}
+	}
+
+
+std::string wstring2string (const std::wstring& aWide)
+	{
+	int max = ConvertWideCharToMultiByte(aWide.c_str(),aWide.length(),0,0);
+	std::string reply;
+	if (max > 0 )
+		{
+		char* buffer = new char [max];
+		try
+			{
+			ConvertWideCharToMultiByte(aWide.c_str(),aWide.length(),buffer,max);
+			reply = std::string (buffer, max);
+			}
+		catch (...)
+			{
+			}
+		delete [] buffer;
+		}
+	return reply;
+	}
+
+std::wstring string2wstring (const std::string& aNarrow)
+	{
+	int max = ConvertMultiByteToWideChar(aNarrow.c_str(),aNarrow.length(),0,0, CP_OEMCP);
+	std::wstring reply;
+	if (max > 0 )
+		{
+		wchar_t* buffer = new wchar_t [max];
+		try
+			{
+			ConvertMultiByteToWideChar(aNarrow.c_str(),aNarrow.length(),buffer,max,CP_OEMCP);
+			reply = std::wstring (buffer, max);
+			}
+		catch (...)
+			{
+			}
+		delete [] buffer;
+		}
+	return reply;
+	}
+
+void EnsureExtended (std::wstring& aName, const std::wstring& aDefaultExtension)
+	{
+	assert (! aName.empty ());
+	assert (! aDefaultExtension.empty ());
+	std::wstring::size_type posSlash (aName.rfind ('\\'));
+	if (posSlash == std::wstring::npos)
+		{
+		posSlash = 0;
+		}
+	std::wstring::size_type posDot (aName.find (posSlash, '.'));
+	if (posDot == std::wstring::npos)
+		{
+		aName += aDefaultExtension;
+		}
+	}
+
+bool ValidateFileName (std::wstring& aName, const bool aMustExist)
+	{
+	assert (! aName.empty ());
+	if (aName.size () < 3)
+		{
+		return false;
+		}
+	std::wstring filename (aName);
+	bool isUNC ((filename.at (0) == L'/') && (filename.at (1) == L'/'));
+	bool isRelative (! isUNC && ((filename.at (1) != L':')));
+
+	if (! isRelative)
+		{
+		if (! isUNC && (filename.at (2) != L'/')) 
+			{
+			return false;
+			}
+		}
+	else
+		{
+		const int maxlen = PATHMAX * 8;	/*	The value of PATHMAX assumes short name FAT environment,
+												not long names and / or NTFS, UNC, URL, etc. etc.. Using a
+												larger value significantly reduces the chances of failure
+												when the application is deep in a subdirectory tree. Windows
+												calls require fixed length buffers. 
+											*/
+		wchar_t	directorybuffer [maxlen];
+		std::wstring cwd (_wgetcwd (directorybuffer, maxlen));
+		if (cwd.empty ()) 
+			{
+			return false;
+			}
+		if (cwd.size () > 3) 
+			{
+			cwd += KSisDirectorySeparator;	// trailing backslash is returned inconsistently according to docs for getcwd
+			}
+		filename = cwd + filename;
+		}
+
+	if (aMustExist)
+		{
+		DWORD attributes (GetFileAttributesW (filename.c_str ()));
+		if (attributes == RESULT) 
+			{
+			return false;
+			}
+		}
+	aName = filename;
+	return true;
+	}
+
+
+bool ValidateDirectory (std::wstring& aName, const bool aMustExist)
+	{
+	if (! ValidateFileName (aName, aMustExist)) 
+		{
+		return false;
+		}
+	if (aName.at (aName.size () - 1) != L'/') 
+		{
+		aName += L'/';
+		}
+	return true;
+	}
+
+bool ValidateFileName (std::wstring& aName, const bool aMustExist, const std::wstring& aDefaultExtension)
+	{
+	assert (! aName.empty ());
+	assert (! aDefaultExtension.empty ());
+	std::wstring filename (aName);
+	EnsureExtended (filename, aDefaultExtension);
+	if (! ValidateFileName (filename, aMustExist)) 
+		{
+		return false;
+		}
+	aName = filename;
+	return true;
+	}
+
+TUint32 IdentifyUCKeyword (const SKeyword aKeyword [], std::wstring aIdentifier, const std::wstring& aContext)
+	{
+	for (std::wstring::size_type letter = 0; letter < aIdentifier.size (); letter++)
+		{
+		aIdentifier [letter] = toupper (aIdentifier [letter]);
+		}
+	for (const SKeyword* index = &aKeyword [0]; index -> iName != NULL; index++)
+		{
+		if (aIdentifier.compare (index -> iName) == 0) 
+			{
+			return index -> iId;
+			}
+		}
+	throw CSISException (CSISException::ESyntax, aContext + aIdentifier);
+	}
+
+
+CSISFieldRoot::TFieldSize Alignment (const CSISFieldRoot::TFieldSize aOriginal)
+	{
+	const CSISFieldRoot::TFieldSize coarseness (4);
+	CSISFieldRoot::TFieldSize modulus (aOriginal % coarseness);
+	return (modulus == 0) ? 0 : (coarseness - modulus);
+	}
+
+
+CSISFieldRoot::TFieldSize AlignedSize (const CSISFieldRoot::TFieldSize aOriginal)
+	{
+	return aOriginal + Alignment (aOriginal);
+	}
+
+
+
+void ReadFiller (TSISStream& aFile)
+	{
+	CSISFieldRoot::TFieldSize diff (Alignment (aFile.tell ()));
+	assert (diff >= 0);
+	if (diff)
+		{
+		TUint8 junk;
+		for (CSISFieldRoot::TFieldSize index = 0; index < diff; index++) 
+			{
+			aFile >> junk;
+			}
+		}
+	}
+
+
+void WriteFiller (TSISStream& aFile)  
+	{
+	TSISStream::pos_type pos (aFile.tell ());
+	if (pos >= 0)
+		{
+		CSISFieldRoot::TFieldSize diff (Alignment (pos));
+		if (diff)
+			{
+			TUint8 padding = 0;
+			for (CSISFieldRoot::TFieldSize index = 0; index < diff; index++) 
+				{
+				aFile << padding;
+				}
+			}
+		}
+	}
+
+HANDLE OpenFileAndGetSize (const std::wstring& aName, TUint64* aSize)
+	{
+	HANDLE file = MakeSISOpenFile(aName.c_str(),GENERIC_READ,OPEN_EXISTING);
+	CSISException::ThrowIf ((INVALID_HANDLE_VALUE == file), 
+							CSISException::EFileProblem, std::wstring (L"cannot open ") + aName);
+	if (aSize)
+		{
+		DWORD dwHigh = 0;
+		DWORD dwLow = ::GetFileSize(file,&dwHigh);
+		TUint64 size = (dwHigh << 32) | dwLow;
+		*aSize = static_cast <TUint64> (size);
+		}
+	return file;
+	}
+
+
+void ReadAndCloseFile (HANDLE aFile, const TUint64 aSize, TUint8* aBuffer)
+	{
+	size_t got = 0;
+	::ReadFile(aFile,aBuffer,aSize,(DWORD*)&got,0);
+	::CloseHandle(aFile);
+	CSISException::ThrowIf (got != static_cast <size_t> (aSize), 
+							CSISException::EFileProblem, 
+							"cannot read file");
+	}
+
+
+int SearchSortedUCTable (const SIdentifierTable aTable [], const std::wstring& aIdentifier)
+	{
+	for (int index = 0; aTable [index].iName; index++)
+		{
+		int comparision = aIdentifier.compare (aTable [index].iName);
+		if (comparision == 0)
+			{
+			return index;
+			}
+		if (comparision < 0)
+			{
+			break;
+			}
+		}
+	return -1;
+	}
+
+
+LPSTR MakeMBCSString(LPCWSTR uniStr, UINT codePage, DWORD& length)
+// Convert a UNICODE string to a multi-byte string
+	{
+	LPSTR mbStr;
+	// get num unicode chars required
+	DWORD len = ConvertWideCharToMultiByte(uniStr, length, NULL, 0);
+	mbStr = new CHAR[len+1];
+	if (!mbStr) throw ErrNotEnoughMemory;
+	// convert
+	ConvertWideCharToMultiByte(uniStr, length, mbStr, len);
+	mbStr[len]='\0';
+	length=len;
+
+	return mbStr;
+	}
+
+
+char* Copy2TmpFile(const wchar_t *fName, TFileType fType)
+{
+	char *tmpName, *tmpFileName=NULL;
+	int numread = 0;
+
+	tmpName = GetTempFile();
+		
+	if(tmpName == NULL)
+		return NULL;
+
+	tmpFileName = new char[strlen(tmpName)+5];
+	strcpy(tmpFileName, tmpName);
+
+	if(fType == CERTFILE)
+		{
+		tmpFileName = strcat(tmpFileName, ".cer");
+		}	
+	else if(fType == KEYFILE)
+		{
+		tmpFileName = strcat(tmpFileName, ".key");
+		}
+	else
+		{
+		tmpFileName = strcat(tmpFileName, ".dat");
+		}
+
+		TransferFileData(fName,tmpFileName);
+		return tmpFileName;
+
+		if(tmpFileName != NULL)
+			delete tmpFileName;
+
+	return NULL;
+}
+
+/**
+ * Returns the size of the first occurance of an invalid directory separator.
+ * @param aPath Path to be validated.
+ * @param aIndex index from which the search begin. On function return this 
+ * 				index will point to the illegal directory separator. 
+ * @return 0 if path is valid. Else the number of character to be replaced.
+ * e.g. \sys\bin\ should be replaced with /sys/bin/
+ * and \\sys\\bin\\ should be replaced with /sys/bin/
+ */ 
+int FirstInvalidDirSeparatorSize(std::wstring& aPath, std::wstring::size_type& aIndex)
+	{
+	// If path semantics is correct (as needed by sisx library)
+	// then the function will return 0
+	int ret = 0; 
+	int pos = 0;
+	if((pos = aPath.find(L"\\\\", aIndex)) != std::wstring::npos)
+		{
+		ret = 2;
+		}
+	else if((pos = aPath.find(L"\\", aIndex)) != std::wstring::npos)
+		{
+		ret = 1;
+		}
+	aIndex = pos;
+	return ret;
+	}
+
+
+std::wstring FixPathDelimiters( const std::wstring& aString )
+    {
+    std::wstring ret = aString;
+	
+    std::wstring::size_type idx = 0;
+    int len = 0;
+	while(len = FirstInvalidDirSeparatorSize(ret, idx))
+        {
+		ret.replace( idx, len, KSisDirectorySeparator );
+        }
+    return ret;
+    }
+
+int GetFileType(std::wstring& aFileName)
+	{
+    int len = ConvertWideCharToMultiByte(aFileName.c_str(), -1, NULL, 0);
+    char* fileName = new char[len + 1];
+    ConvertWideCharToMultiByte(aFileName.c_str(), -1, fileName, len);
+
+    std::ifstream fs(fileName, std::ios::binary | std::ios::in);
+    fs.seekg(0, std::ios::end);
+    len = fs.tellg();
+    fs.seekg(0, std::ios::beg);
+    unsigned char* buffer = new unsigned char[len];
+    fs.read((char*)buffer, len);
+    fs.close();
+    
+    int type = EFileUnknown;
+    
+    const TUint32* data32 = reinterpret_cast<const TUint32*>(buffer);
+    
+	if (len <= sizeof(TUint32)*0x04)
+		{
+		delete[] buffer;
+		return type;
+		}
+	
+	if(IsExeData(buffer, len))
+		{
+		type = EFileExe;
+		}
+	else if(IsDllData(buffer, len))
+		{
+		type = EFileDll;
+		}
+ 
+	if(IsEmulatorExecutableData(buffer, len))
+		{
+		type |= EFileEmulatorExe;
+		}
+
+    return type;
+	}
+
+bool IsExecutableData(const unsigned char* aContent, TUint32 aLength) 
+	{
+	if (aLength <= sizeof(TUint32)*0x05)
+		{
+		return false;
+		}
+	const TUint32* data32 = reinterpret_cast<const TUint32*>(aContent);
+	bool isExecutable = false;
+
+	if (	IsExeData(aContent, aLength) || 
+			IsDllData(aContent, aLength) || 
+			IsEmulatorExecutableData(aContent, aLength))
+		{
+		isExecutable = true;
+		} 
+	
+	return isExecutable;
+	}
+
+bool IsEmulatorExecutableData(const unsigned char* aContent, TUint32 aLength)
+	{
+	bool isEmulatorExe = false;
+
+	// winscw binary
+	if (aLength > 2 && aContent[0] == 'M' && aContent[1] == 'Z')
+		{
+		isEmulatorExe = true;
+		}
+
+	return isEmulatorExe;
+	}
+
+
+bool IsExeData(const unsigned char* aContent, TUint32 aLength)
+	{
+	return (GetExecutableType(aContent, aLength) == KExecutableImageUid)? true: false;
+	}
+
+bool IsDllData(const unsigned char* aContent, TUint32 aLength)
+	{
+	return (GetExecutableType(aContent, aLength) == KDynamicLibraryUid)? true: false;
+	}
+
+
+TInt32 GetExecutableType(const unsigned char* aContent, TUint32 aLength)
+	{
+	const TUint32* data32 = reinterpret_cast<const TUint32*>(aContent);
+	if(aLength < sizeof(TUint32)*0x05)
+		{
+		return 0;
+		}
+	
+	TInt32 type = 0;
+
+	if(data32[0x04] == KFileHeaderSignature)
+		{
+		type = data32[0];
+		}
+	else if (IsEmulatorExecutableData(aContent, aLength))
+		{
+		const char symbian[] = ".SYMBIAN";
+		const int  len2      = sizeof(symbian)-1;
+		const unsigned char* index = std::search(aContent, aContent+aLength, symbian, symbian+len2);
+
+		if ( (index + KHeaderUidLength < aContent+aLength) && (index != aContent+aLength) )
+			{
+			index += KHeaderUidLength;
+			TInt32 offset = *(TInt32*)index;
+
+			if (offset < aLength)
+				{
+				const TUint32* x = (TUint32*)(aContent+offset);
+				type = x[0];
+				}
+			}
+		}
+
+	return type;
+	}