secureswitools/swisistools/source/sisxlibrary/utility.cpp
changeset 0 ba25891c3a9e
child 24 5cc91383ab1e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 /**
       
    20  @file 
       
    21  @internalComponent
       
    22  @released
       
    23 */
       
    24 
       
    25 #include "utility.h"
       
    26 #include "exception.h"
       
    27 #include "utility_interface.h"
       
    28 #include "utils.h"
       
    29 #include <stdio.h>
       
    30 #include <assert.h>
       
    31 #include <stdlib.h>
       
    32 #include <fstream>
       
    33 #include <algorithm>
       
    34 
       
    35 std::wostream* SISLogger::iStream = NULL;
       
    36 
       
    37 void SISLogger::SetStream(std::wostream& aStream)
       
    38 	{
       
    39 	iStream = &aStream;
       
    40 	}
       
    41 
       
    42 void SISLogger::Log(const std::wstring& aString)
       
    43 	{
       
    44 	if(NULL != iStream)
       
    45 		{
       
    46 		(*iStream) << aString;
       
    47 		}
       
    48 	}
       
    49 
       
    50 
       
    51 std::string wstring2string (const std::wstring& aWide)
       
    52 	{
       
    53 	int max = ConvertWideCharToMultiByte(aWide.c_str(),aWide.length(),0,0);
       
    54 	std::string reply;
       
    55 	if (max > 0 )
       
    56 		{
       
    57 		char* buffer = new char [max];
       
    58 		try
       
    59 			{
       
    60 			ConvertWideCharToMultiByte(aWide.c_str(),aWide.length(),buffer,max);
       
    61 			reply = std::string (buffer, max);
       
    62 			}
       
    63 		catch (...)
       
    64 			{
       
    65 			}
       
    66 		delete [] buffer;
       
    67 		}
       
    68 	return reply;
       
    69 	}
       
    70 
       
    71 std::wstring string2wstring (const std::string& aNarrow)
       
    72 	{
       
    73 	int max = ConvertMultiByteToWideChar(aNarrow.c_str(),aNarrow.length(),0,0, CP_OEMCP);
       
    74 	std::wstring reply;
       
    75 	if (max > 0 )
       
    76 		{
       
    77 		wchar_t* buffer = new wchar_t [max];
       
    78 		try
       
    79 			{
       
    80 			ConvertMultiByteToWideChar(aNarrow.c_str(),aNarrow.length(),buffer,max,CP_OEMCP);
       
    81 			reply = std::wstring (buffer, max);
       
    82 			}
       
    83 		catch (...)
       
    84 			{
       
    85 			}
       
    86 		delete [] buffer;
       
    87 		}
       
    88 	return reply;
       
    89 	}
       
    90 
       
    91 void EnsureExtended (std::wstring& aName, const std::wstring& aDefaultExtension)
       
    92 	{
       
    93 	assert (! aName.empty ());
       
    94 	assert (! aDefaultExtension.empty ());
       
    95 	std::wstring::size_type posSlash (aName.rfind ('\\'));
       
    96 	if (posSlash == std::wstring::npos)
       
    97 		{
       
    98 		posSlash = 0;
       
    99 		}
       
   100 	std::wstring::size_type posDot (aName.find (posSlash, '.'));
       
   101 	if (posDot == std::wstring::npos)
       
   102 		{
       
   103 		aName += aDefaultExtension;
       
   104 		}
       
   105 	}
       
   106 
       
   107 bool ValidateFileName (std::wstring& aName, const bool aMustExist)
       
   108 	{
       
   109 	assert (! aName.empty ());
       
   110 	if (aName.size () < 3)
       
   111 		{
       
   112 		return false;
       
   113 		}
       
   114 	std::wstring filename (aName);
       
   115 	bool isUNC ((filename.at (0) == L'/') && (filename.at (1) == L'/'));
       
   116 	bool isRelative (! isUNC && ((filename.at (1) != L':')));
       
   117 
       
   118 	if (! isRelative)
       
   119 		{
       
   120 		if (! isUNC && (filename.at (2) != L'/')) 
       
   121 			{
       
   122 			return false;
       
   123 			}
       
   124 		}
       
   125 	else
       
   126 		{
       
   127 		const int maxlen = PATHMAX * 8;	/*	The value of PATHMAX assumes short name FAT environment,
       
   128 												not long names and / or NTFS, UNC, URL, etc. etc.. Using a
       
   129 												larger value significantly reduces the chances of failure
       
   130 												when the application is deep in a subdirectory tree. Windows
       
   131 												calls require fixed length buffers. 
       
   132 											*/
       
   133 		wchar_t	directorybuffer [maxlen];
       
   134 		std::wstring cwd (_wgetcwd (directorybuffer, maxlen));
       
   135 		if (cwd.empty ()) 
       
   136 			{
       
   137 			return false;
       
   138 			}
       
   139 		if (cwd.size () > 3) 
       
   140 			{
       
   141 			cwd += KSisDirectorySeparator;	// trailing backslash is returned inconsistently according to docs for getcwd
       
   142 			}
       
   143 		filename = cwd + filename;
       
   144 		}
       
   145 
       
   146 	if (aMustExist)
       
   147 		{
       
   148 		DWORD attributes (GetFileAttributesW (filename.c_str ()));
       
   149 		if (attributes == RESULT) 
       
   150 			{
       
   151 			return false;
       
   152 			}
       
   153 		}
       
   154 	aName = filename;
       
   155 	return true;
       
   156 	}
       
   157 
       
   158 
       
   159 bool ValidateDirectory (std::wstring& aName, const bool aMustExist)
       
   160 	{
       
   161 	if (! ValidateFileName (aName, aMustExist)) 
       
   162 		{
       
   163 		return false;
       
   164 		}
       
   165 	if (aName.at (aName.size () - 1) != L'/') 
       
   166 		{
       
   167 		aName += L'/';
       
   168 		}
       
   169 	return true;
       
   170 	}
       
   171 
       
   172 bool ValidateFileName (std::wstring& aName, const bool aMustExist, const std::wstring& aDefaultExtension)
       
   173 	{
       
   174 	assert (! aName.empty ());
       
   175 	assert (! aDefaultExtension.empty ());
       
   176 	std::wstring filename (aName);
       
   177 	EnsureExtended (filename, aDefaultExtension);
       
   178 	if (! ValidateFileName (filename, aMustExist)) 
       
   179 		{
       
   180 		return false;
       
   181 		}
       
   182 	aName = filename;
       
   183 	return true;
       
   184 	}
       
   185 
       
   186 TUint32 IdentifyUCKeyword (const SKeyword aKeyword [], std::wstring aIdentifier, const std::wstring& aContext)
       
   187 	{
       
   188 	for (std::wstring::size_type letter = 0; letter < aIdentifier.size (); letter++)
       
   189 		{
       
   190 		aIdentifier [letter] = toupper (aIdentifier [letter]);
       
   191 		}
       
   192 	for (const SKeyword* index = &aKeyword [0]; index -> iName != NULL; index++)
       
   193 		{
       
   194 		if (aIdentifier.compare (index -> iName) == 0) 
       
   195 			{
       
   196 			return index -> iId;
       
   197 			}
       
   198 		}
       
   199 	throw CSISException (CSISException::ESyntax, aContext + aIdentifier);
       
   200 	}
       
   201 
       
   202 
       
   203 CSISFieldRoot::TFieldSize Alignment (const CSISFieldRoot::TFieldSize aOriginal)
       
   204 	{
       
   205 	const CSISFieldRoot::TFieldSize coarseness (4);
       
   206 	CSISFieldRoot::TFieldSize modulus (aOriginal % coarseness);
       
   207 	return (modulus == 0) ? 0 : (coarseness - modulus);
       
   208 	}
       
   209 
       
   210 
       
   211 CSISFieldRoot::TFieldSize AlignedSize (const CSISFieldRoot::TFieldSize aOriginal)
       
   212 	{
       
   213 	return aOriginal + Alignment (aOriginal);
       
   214 	}
       
   215 
       
   216 
       
   217 
       
   218 void ReadFiller (TSISStream& aFile)
       
   219 	{
       
   220 	CSISFieldRoot::TFieldSize diff (Alignment (aFile.tell ()));
       
   221 	assert (diff >= 0);
       
   222 	if (diff)
       
   223 		{
       
   224 		TUint8 junk;
       
   225 		for (CSISFieldRoot::TFieldSize index = 0; index < diff; index++) 
       
   226 			{
       
   227 			aFile >> junk;
       
   228 			}
       
   229 		}
       
   230 	}
       
   231 
       
   232 
       
   233 void WriteFiller (TSISStream& aFile)  
       
   234 	{
       
   235 	TSISStream::pos_type pos (aFile.tell ());
       
   236 	if (pos >= 0)
       
   237 		{
       
   238 		CSISFieldRoot::TFieldSize diff (Alignment (pos));
       
   239 		if (diff)
       
   240 			{
       
   241 			TUint8 padding = 0;
       
   242 			for (CSISFieldRoot::TFieldSize index = 0; index < diff; index++) 
       
   243 				{
       
   244 				aFile << padding;
       
   245 				}
       
   246 			}
       
   247 		}
       
   248 	}
       
   249 
       
   250 HANDLE OpenFileAndGetSize (const std::wstring& aName, TUint64* aSize)
       
   251 	{
       
   252 	HANDLE file = MakeSISOpenFile(aName.c_str(),GENERIC_READ,OPEN_EXISTING);
       
   253 	CSISException::ThrowIf ((INVALID_HANDLE_VALUE == file), 
       
   254 							CSISException::EFileProblem, std::wstring (L"cannot open ") + aName);
       
   255 	if (aSize)
       
   256 		{
       
   257 		DWORD dwHigh = 0;
       
   258 		DWORD dwLow = ::GetFileSize(file,&dwHigh);
       
   259 		TUint64 size = (dwHigh << 32) | dwLow;
       
   260 		*aSize = static_cast <TUint64> (size);
       
   261 		}
       
   262 	return file;
       
   263 	}
       
   264 
       
   265 
       
   266 void ReadAndCloseFile (HANDLE aFile, const TUint64 aSize, TUint8* aBuffer)
       
   267 	{
       
   268 	size_t got = 0;
       
   269 	::ReadFile(aFile,aBuffer,aSize,(DWORD*)&got,0);
       
   270 	::CloseHandle(aFile);
       
   271 	CSISException::ThrowIf (got != static_cast <size_t> (aSize), 
       
   272 							CSISException::EFileProblem, 
       
   273 							"cannot read file");
       
   274 	}
       
   275 
       
   276 
       
   277 int SearchSortedUCTable (const SIdentifierTable aTable [], const std::wstring& aIdentifier)
       
   278 	{
       
   279 	for (int index = 0; aTable [index].iName; index++)
       
   280 		{
       
   281 		int comparision = aIdentifier.compare (aTable [index].iName);
       
   282 		if (comparision == 0)
       
   283 			{
       
   284 			return index;
       
   285 			}
       
   286 		if (comparision < 0)
       
   287 			{
       
   288 			break;
       
   289 			}
       
   290 		}
       
   291 	return -1;
       
   292 	}
       
   293 
       
   294 
       
   295 LPSTR MakeMBCSString(LPCWSTR uniStr, UINT codePage, DWORD& length)
       
   296 // Convert a UNICODE string to a multi-byte string
       
   297 	{
       
   298 	LPSTR mbStr;
       
   299 	// get num unicode chars required
       
   300 	DWORD len = ConvertWideCharToMultiByte(uniStr, length, NULL, 0);
       
   301 	mbStr = new CHAR[len+1];
       
   302 	if (!mbStr) throw ErrNotEnoughMemory;
       
   303 	// convert
       
   304 	ConvertWideCharToMultiByte(uniStr, length, mbStr, len);
       
   305 	mbStr[len]='\0';
       
   306 	length=len;
       
   307 
       
   308 	return mbStr;
       
   309 	}
       
   310 
       
   311 
       
   312 char* Copy2TmpFile(const wchar_t *fName, TFileType fType)
       
   313 {
       
   314 	char *tmpName, *tmpFileName=NULL;
       
   315 	int numread = 0;
       
   316 
       
   317 	tmpName = GetTempFile();
       
   318 		
       
   319 	if(tmpName == NULL)
       
   320 		return NULL;
       
   321 
       
   322 	tmpFileName = new char[strlen(tmpName)+5];
       
   323 	strcpy(tmpFileName, tmpName);
       
   324 
       
   325 	if(fType == CERTFILE)
       
   326 		{
       
   327 		tmpFileName = strcat(tmpFileName, ".cer");
       
   328 		}	
       
   329 	else if(fType == KEYFILE)
       
   330 		{
       
   331 		tmpFileName = strcat(tmpFileName, ".key");
       
   332 		}
       
   333 	else
       
   334 		{
       
   335 		tmpFileName = strcat(tmpFileName, ".dat");
       
   336 		}
       
   337 
       
   338 		TransferFileData(fName,tmpFileName);
       
   339 		return tmpFileName;
       
   340 
       
   341 		if(tmpFileName != NULL)
       
   342 			delete tmpFileName;
       
   343 
       
   344 	return NULL;
       
   345 }
       
   346 
       
   347 /**
       
   348  * Returns the size of the first occurance of an invalid directory separator.
       
   349  * @param aPath Path to be validated.
       
   350  * @param aIndex index from which the search begin. On function return this 
       
   351  * 				index will point to the illegal directory separator. 
       
   352  * @return 0 if path is valid. Else the number of character to be replaced.
       
   353  * e.g. \sys\bin\ should be replaced with /sys/bin/
       
   354  * and \\sys\\bin\\ should be replaced with /sys/bin/
       
   355  */ 
       
   356 int FirstInvalidDirSeparatorSize(std::wstring& aPath, std::wstring::size_type& aIndex)
       
   357 	{
       
   358 	// If path semantics is correct (as needed by sisx library)
       
   359 	// then the function will return 0
       
   360 	int ret = 0; 
       
   361 	int pos = 0;
       
   362 	if((pos = aPath.find(L"\\\\", aIndex)) != std::wstring::npos)
       
   363 		{
       
   364 		ret = 2;
       
   365 		}
       
   366 	else if((pos = aPath.find(L"\\", aIndex)) != std::wstring::npos)
       
   367 		{
       
   368 		ret = 1;
       
   369 		}
       
   370 	aIndex = pos;
       
   371 	return ret;
       
   372 	}
       
   373 
       
   374 
       
   375 std::wstring FixPathDelimiters( const std::wstring& aString )
       
   376     {
       
   377     std::wstring ret = aString;
       
   378 	
       
   379     std::wstring::size_type idx = 0;
       
   380     int len = 0;
       
   381 	while(len = FirstInvalidDirSeparatorSize(ret, idx))
       
   382         {
       
   383 		ret.replace( idx, len, KSisDirectorySeparator );
       
   384         }
       
   385     return ret;
       
   386     }
       
   387 
       
   388 int GetFileType(std::wstring& aFileName)
       
   389 	{
       
   390     int len = ConvertWideCharToMultiByte(aFileName.c_str(), -1, NULL, 0);
       
   391     char* fileName = new char[len + 1];
       
   392     ConvertWideCharToMultiByte(aFileName.c_str(), -1, fileName, len);
       
   393 
       
   394     std::ifstream fs(fileName, std::ios::binary | std::ios::in);
       
   395     fs.seekg(0, std::ios::end);
       
   396     len = fs.tellg();
       
   397     fs.seekg(0, std::ios::beg);
       
   398     unsigned char* buffer = new unsigned char[len];
       
   399     fs.read((char*)buffer, len);
       
   400     fs.close();
       
   401     
       
   402     int type = EFileUnknown;
       
   403     
       
   404     const TUint32* data32 = reinterpret_cast<const TUint32*>(buffer);
       
   405     
       
   406 	if (len <= sizeof(TUint32)*0x04)
       
   407 		{
       
   408 		delete[] buffer;
       
   409 		return type;
       
   410 		}
       
   411 	
       
   412 	if(IsExeData(buffer, len))
       
   413 		{
       
   414 		type = EFileExe;
       
   415 		}
       
   416 	else if(IsDllData(buffer, len))
       
   417 		{
       
   418 		type = EFileDll;
       
   419 		}
       
   420  
       
   421 	if(IsEmulatorExecutableData(buffer, len))
       
   422 		{
       
   423 		type |= EFileEmulatorExe;
       
   424 		}
       
   425 
       
   426     return type;
       
   427 	}
       
   428 
       
   429 bool IsExecutableData(const unsigned char* aContent, TUint32 aLength) 
       
   430 	{
       
   431 	if (aLength <= sizeof(TUint32)*0x05)
       
   432 		{
       
   433 		return false;
       
   434 		}
       
   435 	const TUint32* data32 = reinterpret_cast<const TUint32*>(aContent);
       
   436 	bool isExecutable = false;
       
   437 
       
   438 	if (	IsExeData(aContent, aLength) || 
       
   439 			IsDllData(aContent, aLength) || 
       
   440 			IsEmulatorExecutableData(aContent, aLength))
       
   441 		{
       
   442 		isExecutable = true;
       
   443 		} 
       
   444 	
       
   445 	return isExecutable;
       
   446 	}
       
   447 
       
   448 bool IsEmulatorExecutableData(const unsigned char* aContent, TUint32 aLength)
       
   449 	{
       
   450 	bool isEmulatorExe = false;
       
   451 
       
   452 	// winscw binary
       
   453 	if (aLength > 2 && aContent[0] == 'M' && aContent[1] == 'Z')
       
   454 		{
       
   455 		isEmulatorExe = true;
       
   456 		}
       
   457 
       
   458 	return isEmulatorExe;
       
   459 	}
       
   460 
       
   461 
       
   462 bool IsExeData(const unsigned char* aContent, TUint32 aLength)
       
   463 	{
       
   464 	return (GetExecutableType(aContent, aLength) == KExecutableImageUid)? true: false;
       
   465 	}
       
   466 
       
   467 bool IsDllData(const unsigned char* aContent, TUint32 aLength)
       
   468 	{
       
   469 	return (GetExecutableType(aContent, aLength) == KDynamicLibraryUid)? true: false;
       
   470 	}
       
   471 
       
   472 
       
   473 TInt32 GetExecutableType(const unsigned char* aContent, TUint32 aLength)
       
   474 	{
       
   475 	const TUint32* data32 = reinterpret_cast<const TUint32*>(aContent);
       
   476 	if(aLength < sizeof(TUint32)*0x05)
       
   477 		{
       
   478 		return 0;
       
   479 		}
       
   480 	
       
   481 	TInt32 type = 0;
       
   482 
       
   483 	if(data32[0x04] == KFileHeaderSignature)
       
   484 		{
       
   485 		type = data32[0];
       
   486 		}
       
   487 	else if (IsEmulatorExecutableData(aContent, aLength))
       
   488 		{
       
   489 		const char symbian[] = ".SYMBIAN";
       
   490 		const int  len2      = sizeof(symbian)-1;
       
   491 		const unsigned char* index = std::search(aContent, aContent+aLength, symbian, symbian+len2);
       
   492 
       
   493 		if ( (index + KHeaderUidLength < aContent+aLength) && (index != aContent+aLength) )
       
   494 			{
       
   495 			index += KHeaderUidLength;
       
   496 			TInt32 offset = *(TInt32*)index;
       
   497 
       
   498 			if (offset < aLength)
       
   499 				{
       
   500 				const TUint32* x = (TUint32*)(aContent+offset);
       
   501 				type = x[0];
       
   502 				}
       
   503 			}
       
   504 		}
       
   505 
       
   506 	return type;
       
   507 	}