CP_THREAD_ACP与CP_ACP
在使用MultiByteToWideChar的时候,大部分都知道上述两个参数,MSDN上的解释也是简单到极致。通常我们会选择使用CP_ACP,但是总有人会在没有真正明白它们之间的区别前使用CP_THREAD_ACP。
上周收到一个日方的Bug报告。Bug的上下文基本是这样的:有一个功能是记录设备信息一览的,并可以将这些信息输出到一个文件(格式有很多)。这个文件可以手动实时获取,也可以设置日期和时间定时获取。
Bug的现象是:在英语和日语的环境下,一切都OK。但是在俄语下定时获取文件的功能失效,手动获取确实OK的。
我们模拟俄语的环境是在非俄语的OS下,改变控制面板中的“地域”中的信息为俄语,包括User Locale和System Locale还有位置。
int usize = ::MultiByteToWideChar(CP_THREAD_ACP, 0, name, (int)strlen(name) + 1, NULL, 0); wchar_t *unicode = new wchar_t[usize];
if(NULL != unicode)
{
ZeroMemory(unicode, usize * sizeof(wchar_t)); // Convert
::MultiByteToWideChar(CP_THREAD_ACP, 0, name, (int)strlen(name), unicode, usize); // Make Key-source
unsigned char key_message[DM_MAX_SIZE_OF_PARAMS]; memcpy( key_message, SNMPV3_HASH_KEY, strlen(SNMPV3_HASH_KEY) );
memcpy( key_message + strlen(SNMPV3_HASH_KEY),
unicode, usize * sizeof(wchar_t) );
memcpy( key_message + strlen(SNMPV3_HASH_KEY) + usize * sizeof(wchar_t),
hash, SIZE_OF_MESSAGE_DIGEST ); // Make hash
md5.MakeMD5(key_message,
strlen(SNMPV3_HASH_KEY) + usize * sizeof(wchar_t) + SIZE_OF_MESSAGE_DIGEST,
key_data);
if( NULL != key ) memcpy( key, key_data, SIZE_OF_MESSAGE_DIGEST ); delete[] unicode;
}
上面的代码片段是我摘自过程中的出现问题的一段。
后来经过分析,执行写文件的功能是在一个单独的F.exe中做的,而F.exe调用了S.dll中的函数,上述代码就是处于S.dll中。定时写文件的功能是因为主程序有个服务,当时间到达后由服务创建F.exe来执行功能。
在主程序中,手动执行保存文件动作是,进入S.dll中的Thread Locale是和System Locale相同的,为0x0419,即俄语。所以执行MultiByteToWideChar没问题,也就能产生正确的Key用于解密。但是在定时的情况下,由服务创建F.exe进程进入S.dll时,Thread Locale是0x0411,即日语(OS为日语),System Locale还是0x0419。这种情况下,使用MultiByteToWideChar转换的字符串会是乱码,最终也就导致了程序的异常。
在此有个不明白的地方是,为什么由服务启动F.exe进程,执行进程的主线程的Thread Local会是0x0411。正常情况下启动F.exe(通过主程序Create或手动启动),Thread Locale和System Locale都是相同的。CreateProcess中也没有办法来设置Thread Locale让主线程运行在指定的Locale下。
这个也说明了另外一个问题,通过过更改地域信息区模拟其他语言环境还是会存在一些缺陷。上面代码如果是运行在俄语的OS下我想是不会出现这样的问题。
Conclusion
在我们不确定线程的code page时,使用CP_THREAD_ACP并不是一个好主意。因为我们没有办法确定Thread Locale和System Locale是一致的,也就是System Locale和User Locale之间可能会存在不一致性。这篇文章可以做个参考。
CP_THREAD_ACP与CP_ACP的更多相关文章
- Windows上的字符转换之CP_ACP和CP_OEMCP
原文地址:http://blog.sina.com.cn/s/blog_53c1950a010158mw.html Windows API函数MultiByteToWideChar用于多字节编码字符串 ...
- CP_ACP : CP_OEMCP
// filesystem windows_file_codecvt.cpp -----------------------------------------// // Copyright Bema ...
- 关于多字节、宽字节、WideCharToMultiByte和MultiByteToWideChar函数的详解
所谓的短字符,就是用8bit来表示的字符,典型的应用是ASCII码. 而宽字符,顾名思义,就是用16bit表示的字符,典型的有UNICODE. **************************** ...
- MULTIBYTETOWIDECHAR的与WIDECHARTOMULTIBYTE的参数详解及相互转换
第一个就是宽字符到多字节字符转换函数,函数原型如下: int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPCWSTR lpWideChar ...
- 函数 MultiByteToWideChar() 详解
函数原型: int MultiByteToWideChar( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cchMultiByte ...
- 函数WideCharToMultiByte() 详解
函数原型: int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPWSTR lpWideCharStr, int cchWideChar, ...
- MultiByteToWideChar和WideCharToMultiByte用法详解
今天写ini文件的时候发现的问题: TCHAR temp[]; //strcpy_s(temp, request.newVersion); MultiByteToWideChar(CP_ACP, , ...
- php连接Access数据库的三种方法
http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2009/1115/3524.html 虽然不是一个类但先放这儿吧 最近想把一个asp的网站改成 ...
- 使用Win32 API 查找文件
头文件:#include <windows.h> //FindFirstFile() 获得指定目录的第一个文件 HANDLE FindFirstFile( LPCTSTR lpFileNa ...
随机推荐
- SQL Server(函数) 关键字的使用 三
三, 函数关键字 -- 使用介绍 28, Function的使用(Function的内建 SQL函数)? 内建 SQL 函数的语法是: SELECT function(列) FROM 表) 29, a ...
- js调用本地 exe
js方法 function Run(strPath) //only for ie { try { var objShell = new ActiveXObject("wscript.sh ...
- Sql 解释
SQL(Structured Query Language) 结构化查询语言,虽然是查询语言,也是一种编程语言,但是执行查询操作. 根据数据的操作对象,可以将SQL语句分为几类. DDL(Data D ...
- ZOJ 2392 The Counting Problem(模拟)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1368 题目大意:计算从S到T中所有的数,其中0,1,2,3,4,5, ...
- Java 与 Python 的对比
最近在学习Python, 现在写一个Python程序和Java程序进行对一下比,以此展示各自不同的特点.这个程序的功能是计算([n, m) )之间的闰年. Python程序如下: def fu ...
- RX学习笔记:在FreeCodeCamp的学习
FreeCodeCamp https://www.freecodecamp.com 2016-07-03 前几日在Github浏览时,偶然看到一个叫FreeCodeCamp的开源项目,进去该网站之后感 ...
- HTML5 基础
1.HTML5 简介 HTML5 是最新的 HTML 标准,他是万维网的核心语言.标准通用标记语言下的一个应用“超文本标记语言”. HTML 的上一个标准 HTML4.01 诞生于 1999年,他的第 ...
- PHP常见算法-面试篇(1)
1.冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将 ...
- SQL技术内幕一
范式:关系模型的规范化规则. Codd提出的三个数据库范式: 1. 第一范式 第一范式要求表中的每一行都是必须是唯一的.因为关系型数据库是基于集合论的,而集合的定义中,要求每一个元素都是唯一的(在关系 ...
- 1-了解Python
为什么使用python: 软件质量: 可读写.一致性.软件质量 支持软件开发的高级重用机制 提供开发者的效率: 代码只有java或C++的1/5~1/3 无须编译链接,提高了程序原的效率 程序的可移植 ...