65.9K
CodeProject 正在变化。 阅读更多。
Home

修补我的 Windows Mobile 上的阿拉伯语区域设置

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2012年5月6日

CPOL

1分钟阅读

viewsIcon

19899

downloadIcon

255

将您的本地语言添加到 Windows 本地设置中,以支持 Unicode。

引言

如何让设备支持Unicode,通过修改系统中的coredll.dll内的InitLocale函数来实现,而不是在你的应用程序中修改。这样就可以在整个系统中设置你的阿拉伯语区域设置,从而能够保存阿拉伯语文件。如果没有这个设置,你将无法在文件中保存阿拉伯语,也无法保存笔记、约会或日历。

注意:我们已经将这种方法应用于所有设备制造商,例如HTC、华硕、InterMek等,因为这些设备最初没有阿拉伯语区域设置。

背景

大多数应用程序会尝试从区域设置读取一些信息,通过框架或MFC中的函数等。无论你使用哪种语言,所有框架都应该调用coredll.dll内的InitLocal函数,因此在这种情况下,你需要做的就是钩住这个函数。

Using the Code

如前所述,我们需要获取coredll.dllInitLocale函数的指针,并将其保存在fpInitlocale中,以便稍后使用。我们将在后面详细讨论这一点。

另外,我们需要使用CreateMutex,顺便说一下,了解互斥锁的含义会很有帮助。

CreateMutex:互斥锁是一种同步对象,用于协商单个进程中线程之间的互斥访问,以避免对公共资源(如全局变量)的并发修改。

/* some shared stuff that has to go */
HINSTANCE hinstCore = (HINSTANCE)GetModuleHandle(L"COREDLL");
FARPROC fpInitLocale = GetProcAddress(hinstCore,L"InitLocale");
HANDLE _nlsMutex=CreateMutex(NULL,0,L"NLSMUTEX");
HANDLE _nlsHeap=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,4,0,0x10000,L"NLSHEAP"); 

现在,要共享进程之间的内存,你必须使用CreateFileForMapping来使你的区域设置在所有进程之间共享。

HANDLE hNLSFile, hNLSMap, hNLSOrig;
/* create the new mapping with slightly different name */
hNLSFile = CreateFileForMapping(nlsFile,GENERIC_READ,0,0,OPEN_EXISTING,0,0);
hNLSMap = CreateFileMapping(hNLSFile,0,PAGE_READONLY,0,0,L"some nice string longer that 7 chars"); 
FSMAP *nls = HandleToMap(hNLSMap);
/* get original */
hNLSOrig = CreateFileMapping(INVALID_HANDLE_VALUE,0,PAGE_READONLY,0,0,L"NLSFILE"); 
LPVOID origView=MapViewOfFile(hNLSOrig,6,0,0,0);
FSMAP *orig = HandleToMap(hNLSOrig); 

这里的代码技巧是重命名原始名称(使其不可见),因为所有...

  • NLSFILE
  • NLSMUTEEX

...已经缓存到正在运行的进程中。

orig->name->name[0]='_'; /* change the first letter */
/* rename our file mapping to be NLSFILE :)*/
wcscpy(nls->name->name, L"NLSFILE");
/* rename NLSHEAP - it is cached in all coredll instances (all apps) */
FSMAP *nlsHeap= HandleToMap(hNLSOrig);
nlsHeap->name->name[0]='_';
/* rename NLSMUTEX - all coredll expect it to be available. force recreation */
MUTEX *m = HandleToMutex(_nlsMutex);
m->name->name[0]='_';  

现在,我们将遍历所有正在运行的进程,并用我们的NLSFILENLSMUTEX替换原始的那个。

PROCESSENTRY32 pe32;
HANDLE hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | 0x40000000 /*TH32CS_SNAPNOHEAPS*/, NULL);
pe32.dwSize=sizeof(pe32);
BOOL bb=Process32First(hSnap,&pe32);
while (bb) {
/* all processes - including NK.EXE */
CallInProcess(pe32.th32ProcessID, fpInitLocale, NULL);
pe32.dwSize=sizeof(pe32);
bb=Process32Next(hSnap, &pe32);
}
CloseToolhelp32Snapshot(hSnap); 

最后,要使用这段代码,请将nls.cpp添加到你的进程中,并调用这个函数。

PatchNLS("\windows\younls.nls"); 
© . All rights reserved.