--- /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;
+ }