diff -r 000000000000 -r bde4ae8d615e os/security/securityanddataprivacytools/securitytools/certapp/utils/utils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/security/securityanddataprivacytools/securitytools/certapp/utils/utils.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,176 @@ +/* +* Copyright (c) 2008-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: +* +*/ + + +#include <fstream> +#include "utils.h" +#include "logger.h" + +#ifndef __LINUX__ +#include <windows.h> +#endif + +typedef unsigned char TUint8; +typedef unsigned int TUint; + +#ifdef __LINUX__ +void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName) +{ + aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::in); +} + +void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName) +{ + aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out); +} + +#else + +WCHAR *WindowsUtf8ToUtf16(const char *aUtf8) +{ + int utf8Len = strlen(aUtf8) + 1; // We want to copy the terminator to the new string + int utf16Space = MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, 0, 0); + if(utf16Space <= 0) + { + dbg << Log::Indent() << "Failed to convert UTF-8 '" << aUtf8 << "' to UTF16" << Log::Endl(); + FatalError(); + return 0; + } + // prog << Log::Indent() << "utf16Space " << utf16Space << Log::Endl(); + WCHAR *utf16 = new WCHAR[utf16Space]; + (void) MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, utf16, utf16Space); +#if 0 + prog << Log::Indent() << "Raw UTF16 name is (chars " << utf16Space << ")" << Log::Endl(); + for(int i=0; i<utf16Space*2; ++i) + { + prog << TUint(((TUint8 *)utf16)[i]) << Log::Endl(); + } +#endif + return utf16; +} + +CHAR *WindowsUtf16ToUtf8(const WCHAR *aUtf16) +{ + int utf16Len = wcslen(aUtf16) + 1; // We want to copy the terminator to the new string + int utf8Space = WideCharToMultiByte(CP_UTF8, 0, aUtf16, utf16Len, 0, 0, 0, 0); + if(utf8Space <= 0) + { + dbg << Log::Indent() << "Failed to convert UTF16 string to UTF8" << Log::Endl(); + FatalError(); + return 0; + } + //prog << Log::Indent() << "utf8Space " << utf8Space << Log::Endl(); + CHAR *utf8 = new CHAR[utf8Space]; + (void) WideCharToMultiByte(CP_UTF8, 0, aUtf16, utf16Len, utf8, utf8Space, 0, 0); + +#if 0 + prog << Log::Indent() << "Raw UTF8 name is (chars " << utf8Space << ")" << Log::Endl(); + for(int i=0; i<utf8Space; ++i) + { + prog << TUint(((TUint8 *)utf8)[i]) << Log::Endl(); + } +#endif + return utf8; +} + +WCHAR *WindowsRetrieveDosName(const WCHAR *aLongName) +{ + // Convert to a short DOS file name. File MUST already exist! + // len will be space required for string and terminator + DWORD len = GetShortPathNameW((WCHAR *)aLongName, 0, 0); + if( len <= 0 ) + { + prog << Log::Indent() << "Failed to find existing file and retrieve short name" << Log::Endl(); + return 0; + } + + //prog << Log::Indent() << "space required for short name is " << len << Log::Endl(); + WCHAR *shortName = new WCHAR[len]; + (void) GetShortPathNameW(aLongName, shortName, len); + return shortName; +} + +void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName) +{ + // Unfortunately the windows C++ STL library will not open files specified via a UTF-8 filename. + // The workaround is to convert the UTF-8 name to the short DOS compatible name and open that instead + + // First convert the UTF-8 name to UTF-16 for use with the windows APIs + WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName); + + // Obtain short DOS compatible name for file + WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name); + if(utf16NameDos == 0) + { + aFStream.setstate(std::ios_base::badbit); + delete [] utf16Name; + return; + } + + char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos); + + aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::in); + + delete [] utf8NameDos; + delete [] utf16NameDos; + delete [] utf16Name; + return; +} + +void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName) +{ + // Unfortunately the windows C++ STL library will not open files specified via a UTF-8 filename. + // The workaround is to make sure the file already exists and then convert the UTF-8 name to the short DOS compatible name + // and open that instead + + // First convert the UTF-8 name to UTF-16 for use with the windows APIs + WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName); + + // Make sure the file exists + HANDLE fh = CreateFileW((WCHAR *)utf16Name, GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ); + if(fh == INVALID_HANDLE_VALUE) + { + dbg << Log::Indent() << "Failed to create file '" << aUtf8FileName << "'" << Log::Endl(); + aFStream.setstate(std::ios_base::badbit); + delete [] utf16Name; + return; + } + // Close handle + CloseHandle(fh); + + + // Obtain short DOS compatible name for file + WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name); + if(utf16NameDos == 0) + { + aFStream.setstate(std::ios_base::badbit); + delete [] utf16Name; + return; + } + + char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos); + + aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out); + + delete [] utf8NameDos; + delete [] utf16NameDos; + delete [] utf16Name; + return; +} +#endif + +// End of file