From 8ae18dbdd38d692a91d9cb8fe1543e3f6052913a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Mal=C3=BD?= Date: Thu, 26 Mar 2015 21:37:10 +0100 Subject: [PATCH] Implement MTH files reading on Windows --- VS2013/libHPCS/libHPCS.sln | 17 ++++++ VS2013/libHPCS/libHPCS.vcxproj | 75 +++++++++++++++++++++++++- libhpcs.c | 97 ++++++++++++++++++++++++++++++---- libhpcs_p.h | 14 +++-- 4 files changed, 187 insertions(+), 16 deletions(-) diff --git a/VS2013/libHPCS/libHPCS.sln b/VS2013/libHPCS/libHPCS.sln index a2f60ad..e07e896 100644 --- a/VS2013/libHPCS/libHPCS.sln +++ b/VS2013/libHPCS/libHPCS.sln @@ -5,16 +5,33 @@ VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libHPCS", "libHPCS.vcxproj", "{5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_tool", "..\test_tool\test_tool.vcxproj", "{3F415811-5359-48A6-9729-34BB4A3D7DDA}" + ProjectSection(ProjectDependencies) = postProject + {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6} = {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug with test_tool|Win32 = Debug with test_tool|Win32 Debug|Win32 = Debug|Win32 + Release with test_tool|Win32 = Release with test_tool|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}.Debug with test_tool|Win32.ActiveCfg = Debug with test_tool|Win32 + {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}.Debug with test_tool|Win32.Build.0 = Debug with test_tool|Win32 {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}.Debug|Win32.ActiveCfg = Debug|Win32 {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}.Debug|Win32.Build.0 = Debug|Win32 + {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}.Release with test_tool|Win32.ActiveCfg = Release with test_tool|Win32 + {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}.Release with test_tool|Win32.Build.0 = Release with test_tool|Win32 {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}.Release|Win32.ActiveCfg = Release|Win32 {5B9F8B15-85D5-4D5F-8F22-BB576E4CD4B6}.Release|Win32.Build.0 = Release|Win32 + {3F415811-5359-48A6-9729-34BB4A3D7DDA}.Debug with test_tool|Win32.ActiveCfg = Debug with test_tool|Win32 + {3F415811-5359-48A6-9729-34BB4A3D7DDA}.Debug with test_tool|Win32.Build.0 = Debug with test_tool|Win32 + {3F415811-5359-48A6-9729-34BB4A3D7DDA}.Debug|Win32.ActiveCfg = Debug|Win32 + {3F415811-5359-48A6-9729-34BB4A3D7DDA}.Release with test_tool|Win32.ActiveCfg = Release with test_tool|Win32 + {3F415811-5359-48A6-9729-34BB4A3D7DDA}.Release with test_tool|Win32.Build.0 = Release with test_tool|Win32 + {3F415811-5359-48A6-9729-34BB4A3D7DDA}.Release|Win32.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VS2013/libHPCS/libHPCS.vcxproj b/VS2013/libHPCS/libHPCS.vcxproj index b898445..02d7137 100644 --- a/VS2013/libHPCS/libHPCS.vcxproj +++ b/VS2013/libHPCS/libHPCS.vcxproj @@ -1,10 +1,18 @@  + + Debug with test_tool + Win32 + Debug Win32 + + Release with test_tool + Win32 + Release Win32 @@ -19,7 +27,13 @@ DynamicLibrary true - v120 + v120_xp + Unicode + + + DynamicLibrary + true + v120_xp Unicode @@ -29,22 +43,41 @@ true MultiByte + + DynamicLibrary + false + v120_xp + true + MultiByte + + + + + + + true + + true + false + + false + @@ -57,6 +90,24 @@ Windows true + Shlwapi.lib;%(AdditionalDependencies) + 2.0 + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBHPCS_EXPORTS;_HPCS_LITTLE_ENDIAN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + Windows + true + Shlwapi.lib;%(AdditionalDependencies) + 2.0 @@ -75,6 +126,28 @@ true true true + Shlwapi.lib;%(AdditionalDependencies) + 2.0 + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBHPCS_EXPORTS;_HPCS_LITTLE_ENDIAN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + Shlwapi.lib;%(AdditionalDependencies) + 2.0 diff --git a/libhpcs.c b/libhpcs.c index 7dd5226..33d69ff 100644 --- a/libhpcs.c +++ b/libhpcs.c @@ -2,7 +2,16 @@ #include "libhpcs_p.h" #ifdef _WIN32 -/* Blank for now */ +#include +#ifndef _WIN32_WINNT_WIN8 +#define _WIN32_WINNT_WIN8 0x0602 +#endif +#if _WIN32_WINNT > _WIN32_WINNT_WIN8 +#include +#else +#include +#endif +#include #else #include #endif @@ -787,22 +796,90 @@ static enum HPCS_ParseCode read_string_at_offset(FILE* datafile, const HPCS_offs /** Platform-specific functions */ #ifdef _WIN32 -static enum HPCS_ParseCode __win32_next_native_line(HPCS_UFH fh, HPCS_NChar* line, int32_t length) +static enum HPCS_ParseCode __win32_next_native_line(FILE* fh, WCHAR* line, int32_t length) { - /* Not implemented */ - return PARSE_E_CANT_READ; + if (fgetws(line, length, fh) == NULL) + return PARSE_E_CANT_READ; + + return PARSE_OK; } -static HPCS_UFH __win32_open_data_file(const char* filename) +static FILE* __win32_open_data_file(const char* filename) { - /* Not implemented */ - return NULL; + FILE* fh; + WCHAR* w_filename; + int w_size; + + /* Get the required size */ + w_size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, filename, -1, NULL, 0); + if (w_size == 0) { + PR_DEBUGF("Count MultiByteToWideChar() error: %x\n", GetLastError()); + return NULL; + } + w_filename = calloc(w_size, sizeof(WCHAR)); + if (w_filename == NULL) + return NULL; + + if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, filename, -1, w_filename, w_size) == 0) { + PR_DEBUGF("Convert MultiByteToWideChar() error: %x\n", GetLastError()); + free(w_filename); + return NULL; + } + fh = _wfopen(w_filename, L"r, ccs=UNICODE"); + + free(w_filename); + return fh; +} + +static enum HPCS_ParseCode __win32_parse_native_method_info_line(char** name, char** value, WCHAR* line) +{ + WCHAR* w_name; + WCHAR* w_value; + WCHAR* w_newline; + enum HPCS_ParseCode ret; + + w_name = wcstok(line, EQUALITY_SIGN); + if (w_name == NULL) + return PARSE_E_NOT_FOUND; + w_value = wcstok(NULL, EQUALITY_SIGN); + if (w_value == NULL) + return PARSE_E_NOT_FOUND; + + /* Remove trailing \n from w_value, if any */ + w_newline = StrStrW(w_value, CR_LF); + if (w_newline != NULL) + *w_newline = (WCHAR)0; + + ret = __win32_wchar_to_utf8(name, w_name); + if (ret != PARSE_OK) + return ret; + ret = __win32_wchar_to_utf8(value, w_value); + if (ret != PARSE_OK) + return ret; + + return PARSE_OK; } -static enum HPCS_ParseCode __win32_parse_native_method_info_line(char** name, char** value, UChar* line) +static enum HPCS_ParseCode __win32_wchar_to_utf8(char** target, const WCHAR* s) { - /* Not implemented */ - return PARSE_E_CANT_READ; + int mb_size; + + mb_size = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL); + if (mb_size == 0) { + PR_DEBUGF("Count WideCharToMultiByte() error: 0x%x\n", GetLastError()); + return PARSE_E_INTERNAL; + } + *target = malloc(mb_size); + if (*target == NULL) + return PARSE_E_NO_MEM; + + if (WideCharToMultiByte(CP_UTF8, 0, s, -1, *target, mb_size, NULL, NULL) == 0) { + free(*target); + PR_DEBUGF("Convert WideCharToMultiByte() error: 0x%x\n", GetLastError()); + return PARSE_E_INTERNAL; + } + + return PARSE_OK; } #else static void __unix_hpcs_initialize() diff --git a/libhpcs_p.h b/libhpcs_p.h index 43f96d1..0aa5fad 100644 --- a/libhpcs_p.h +++ b/libhpcs_p.h @@ -12,7 +12,9 @@ typedef int bool; #include #ifdef _WIN32 -#error "Not defined yet!" +#include +#define HPCS_NChar WCHAR +#define HPCS_UFH FILE* #else #include #include @@ -33,6 +35,7 @@ enum HPCS_ParseCode { PARSE_E_CANT_READ, PARSE_E_NOT_FOUND, PARSE_E_INV_PARAM, + PARSE_E_INTERNAL, PARSE_W_NO_DATA }; @@ -117,9 +120,9 @@ const char* HPCS_E_UNKNOWN_TYPE_STR = "The specified file contains an unknown ty const char* HPCS_E__UNKNOWN_EC_STR = "Unknown error code."; #ifdef _WIN32 -#error "Not implemented yet" +WCHAR EQUALITY_SIGN[] = { 0x003D, 0x0000 }; +WCHAR CR_LF[] = { 0x000A, 0x0000 }; /* Windows hides the actual end-of-line which is {0x000D, 0x000A} from us */ #else -/* ICU strings declarations */ UChar* EQUALITY_SIGN; UChar* CR_LF; #endif @@ -144,9 +147,10 @@ static enum HPCS_ParseCode read_string_at_offset(FILE* datafile, const HPCS_offs /** Platform-specific functions */ #ifdef _WIN32 -static enum HPCS_ParseCode __win32_next_native_line(HPCS_UFH, HPCS_NChar* line, int32_t length); +static enum HPCS_ParseCode __win32_next_native_line(FILE* fh, WCHAR* line, int32_t length); static HPCS_UFH __win32_open_data_file(const char* filename); -static enum HPCS_ParseCode __win32_parse_native_method_info_line(char** name, char** value, HPCS_NChar* line); +static enum HPCS_ParseCode __win32_parse_native_method_info_line(char** name, char** value, WCHAR* line); +static enum HPCS_ParseCode __win32_wchar_to_utf8(char** target, const WCHAR* s); #else static void __attribute((constructor)) __unix_hpcs_initialize(); static void __attribute((destructor)) __unix_hpcs_destroy(); -- 2.43.5