os/security/securityanddataprivacytools/securitytools/certapp/utils/utils.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2008-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 #include <fstream>
    20 #include "utils.h"
    21 #include "logger.h"
    22 
    23 #ifndef __LINUX__
    24 #include <windows.h>
    25 #endif
    26 
    27 typedef unsigned char TUint8;
    28 typedef unsigned int TUint;
    29 
    30 #ifdef __LINUX__
    31 void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName)
    32 {
    33 	aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::in);
    34 }
    35 
    36 void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName)
    37 {
    38 	aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
    39 }
    40 
    41 #else
    42 
    43 WCHAR *WindowsUtf8ToUtf16(const char *aUtf8)
    44 {
    45 	int utf8Len = strlen(aUtf8) + 1; // We want to copy the terminator to the new string
    46 	int utf16Space = MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, 0, 0);
    47 	if(utf16Space <= 0)
    48 		{
    49 		dbg << Log::Indent() << "Failed to convert UTF-8 '" << aUtf8 << "' to UTF16" << Log::Endl();
    50 		FatalError();
    51 		return 0;
    52 		}
    53 	// prog << Log::Indent() << "utf16Space " << utf16Space << Log::Endl();
    54 	WCHAR *utf16 = new WCHAR[utf16Space];
    55 	(void) MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, utf16, utf16Space);
    56 #if 0
    57 	prog << Log::Indent() << "Raw UTF16 name is (chars " << utf16Space << ")" << Log::Endl();
    58 	for(int i=0; i<utf16Space*2; ++i)
    59 		{
    60 		prog << TUint(((TUint8 *)utf16)[i]) << Log::Endl();
    61 		}
    62 #endif
    63 	return utf16;
    64 }
    65 
    66 CHAR *WindowsUtf16ToUtf8(const WCHAR *aUtf16)
    67 {
    68 	int utf16Len = wcslen(aUtf16) + 1; // We want to copy the terminator to the new string
    69 	int utf8Space = WideCharToMultiByte(CP_UTF8, 0, aUtf16, utf16Len, 0, 0, 0, 0);
    70 	if(utf8Space <= 0)
    71 		{
    72 		dbg << Log::Indent() << "Failed to convert UTF16 string to UTF8" << Log::Endl();
    73 		FatalError();
    74 		return 0;
    75 		}
    76 	//prog << Log::Indent() << "utf8Space " << utf8Space << Log::Endl();
    77 	CHAR *utf8 = new CHAR[utf8Space];
    78 	(void) WideCharToMultiByte(CP_UTF8, 0, aUtf16, utf16Len, utf8, utf8Space, 0, 0);
    79 
    80 #if 0
    81 	prog << Log::Indent() << "Raw UTF8 name is (chars " << utf8Space << ")" << Log::Endl();
    82 	for(int i=0; i<utf8Space; ++i)
    83 		{
    84 		prog << TUint(((TUint8 *)utf8)[i]) << Log::Endl();
    85 		}
    86 #endif
    87 	return utf8;
    88 }
    89 
    90 WCHAR *WindowsRetrieveDosName(const WCHAR *aLongName)
    91 {
    92 	// Convert to a short DOS file name. File MUST already exist!
    93 	// len will be space required for string and terminator
    94 	DWORD len = GetShortPathNameW((WCHAR *)aLongName, 0, 0);
    95 	if( len <= 0 )
    96 		{
    97 		prog << Log::Indent() << "Failed to find existing file and retrieve short name" << Log::Endl();
    98 		return 0;
    99 		}
   100 	
   101 	//prog << Log::Indent() << "space required for short name is " << len << Log::Endl();
   102 	WCHAR *shortName = new WCHAR[len];
   103 	(void) GetShortPathNameW(aLongName, shortName, len);
   104 	return shortName;
   105 }
   106 
   107 void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName)
   108 {
   109 	// Unfortunately the windows C++ STL library will not open files specified via a UTF-8 filename.
   110 	// The workaround is to convert the UTF-8 name to the short DOS compatible name and open that instead
   111 
   112 	// First convert the UTF-8 name to UTF-16 for use with the windows APIs
   113 	WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName);
   114 
   115 	// Obtain short DOS compatible name for file
   116 	WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name);
   117 	if(utf16NameDos == 0)
   118 		{
   119 		aFStream.setstate(std::ios_base::badbit);
   120 		delete [] utf16Name;
   121 		return;
   122 		}
   123 
   124 	char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos);
   125 
   126 	aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::in);
   127 
   128 	delete [] utf8NameDos;
   129 	delete [] utf16NameDos;
   130 	delete [] utf16Name;
   131 	return;
   132 }
   133 
   134 void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName)
   135 {
   136 	// Unfortunately the windows C++ STL library will not open files specified via a UTF-8 filename.
   137 	// The workaround is to make sure the file already exists and then convert the UTF-8 name to the short DOS compatible name 
   138 	// and open that instead
   139 
   140 	// First convert the UTF-8 name to UTF-16 for use with the windows APIs
   141 	WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName);
   142 
   143 	// Make sure the file exists
   144 	HANDLE fh = CreateFileW((WCHAR *)utf16Name, GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,  CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
   145 	if(fh == INVALID_HANDLE_VALUE)
   146 		{
   147 		dbg << Log::Indent() << "Failed to create file '" << aUtf8FileName << "'" << Log::Endl();
   148 		aFStream.setstate(std::ios_base::badbit);
   149 		delete [] utf16Name;
   150 		return;
   151 		}
   152 	// Close handle
   153 	CloseHandle(fh);
   154 
   155 
   156 	// Obtain short DOS compatible name for file
   157 	WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name);
   158 	if(utf16NameDos == 0)
   159 		{
   160 		aFStream.setstate(std::ios_base::badbit);
   161 		delete [] utf16Name;
   162 		return;
   163 		}
   164 
   165 	char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos);
   166 
   167 	aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
   168 
   169 	delete [] utf8NameDos;
   170 	delete [] utf16NameDos;
   171 	delete [] utf16Name;
   172 	return;
   173 }
   174 #endif
   175 
   176 // End of file