📄 pgpunicodewin32.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
pgpUnicodeWin32.c - Unicode conversion calls for Win32
$Id: pgpUnicodeWin32.c,v 1.14 2002/10/10 06:48:34 sdas Exp $
____________________________________________________________________________*/
#include <windows.h>
#include <shlwapi.h>
#include "pgpUnicodeWin32.h"
#include "pgpUnicode.h"
#include "pgpPubTypes.h"
#define kPGPBufferSize 256
// the prototype for the MultiByteToWideChar call
typedef int (WINAPI *MultiByteToWideCharProc) (
UINT CodePage,
DWORD dwFlags,
LPCSTR lpMultiByteStr,
int cchMultiByte,
LPWSTR lpWideCharStr,
int cchWideChar);
// the prototype for the WideCharToMultiByte call
typedef int (WINAPI *WideCharToMultiByteProc) (
UINT CodePage,
DWORD dwFlags,
LPWSTR lpWideCharStr,
int cchWideChar,
LPCSTR lpMultiByteStr,
int cchMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar);
static BOOL bIsInitialized = FALSE;
static MultiByteToWideCharProc s_fpMultiByteToWideChar = NULL;
static WideCharToMultiByteProc s_fpWideCharToMultiByte = NULL;
// ______________________________________________
//
// load the needed libraries
static void
sInitializeWin32UnicodeLibraries ()
{
HINSTANCE hLib=NULL;
OSVERSIONINFO osid={0};
if (bIsInitialized)
return;
osid.dwOSVersionInfoSize = sizeof ( osid );
GetVersionEx (&osid);
if (osid.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
// On Win9x we have to use the "Microsoft Layer for Unicode"
// add-in DLL, "UnicoWS.dll". We have this dll in the product
// installation directory - so we need to know where we are
// installed so we can load this correctly.
char *pszFileName = NULL, szFilePath[MAX_PATH+11] = {0};
DWORD dwLen = MAX_PATH;
LONG lRet = 0;
HKEY hKey = NULL;
//PGP_REGISTRYKEY, PGP_INSTALLPATHVALUE values hard coded here
lRet = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\PGP Corporation\\PGP",
0, KEY_READ, &hKey);
if ((lRet == ERROR_SUCCESS) && (NULL != hKey))
{
lRet = RegQueryValueEx (hKey, "InstallPath",
0, NULL, (LPBYTE)szFilePath, &dwLen);
if (lRet == ERROR_SUCCESS)
{
//append mslu dll at the end
strncat (szFilePath, "unicows.dll", 11);
//load the MSLU dll from pgp installation directory
hLib = LoadLibrary (szFilePath);
}
RegCloseKey (hKey);
hKey = NULL;
}
if (NULL == hLib)
{
if (!(hLib = LoadLibrary ("Kernel32.dll")))
return;
}
}
else
{
if (!(hLib = LoadLibrary ("Kernel32.dll")))
return;
}
s_fpMultiByteToWideChar =
(MultiByteToWideCharProc)GetProcAddress (hLib, "MultiByteToWideChar");
s_fpWideCharToMultiByte =
(WideCharToMultiByteProc)GetProcAddress (hLib, "WideCharToMultiByte");
//if both functions were successfully located by us
if((NULL != s_fpMultiByteToWideChar) && (NULL != s_fpWideCharToMultiByte))
bIsInitialized = TRUE;//we are initialized
else
{
//cleanup what we have done so far
if(NULL != hLib)
{
FreeLibrary(hLib);
hLib=NULL;
}
}
}
/* ______________________________________________
*
* convert an ASCIIZ string in local code page to
* UTF-8 encoded Unicode string.
* NB: don't call with the same buffer specified as
* both pszASCII and pszUTF8. The UTF-8 representation
* may be longer than the ASCII, thus corrupting it
* before it if fully converted.
*/
PGPError
pgpLocalStringToUTF8 (
PGPUInt32 uFlags,
PGPUInt32 uCodePage,
const char* pszASCII,
PGPUInt32 uLenASCII,
char* pszUTF8,
PGPUInt32 uMaxLenUTF8,
PGPUInt32* puLenUTF8)
{
PGPError err = kPGPError_NoUnicodeEquivalent;
if (!bIsInitialized)
sInitializeWin32UnicodeLibraries ();
if (s_fpMultiByteToWideChar)
{
// use the Win32 APIs
PGPUInt32 u, uIn, uOut, uToConvert, uOutPos;
PGPInt32 iLenWide;
PGPUInt16 wsz[kPGPBufferSize];
uToConvert = uLenASCII;
uOutPos = 0;
while ((uToConvert > 0) && (uOutPos < uMaxLenUTF8))
{
// convert string in local code page format to UCS-2
uIn = min (uToConvert, kPGPBufferSize);
if (uFlags & kPGPUnicodeFlag_Secure)
{
for (u=0; u<uIn; u++)
{
s_fpMultiByteToWideChar (uCodePage,
MB_ERR_INVALID_CHARS,
&pszASCII[u], 1, &wsz[u], kPGPBufferSize);
}
iLenWide = uIn;
}
else
{
iLenWide = s_fpMultiByteToWideChar (uCodePage,
MB_ERR_INVALID_CHARS,
pszASCII, uIn, wsz, kPGPBufferSize);
}
if (iLenWide > 0)
{
// now convert UCS-2 format to UTF-8
pgpUCS2StringToUTF8 (wsz, iLenWide,
&pszUTF8[uOutPos], uMaxLenUTF8-uOutPos, &uOut);
if (uOut > 0)
err = kPGPError_NoErr;
else
err = kPGPError_BufferTooSmall;
}
pszASCII += uIn;
uToConvert -= uIn;
uOutPos += uOut;
}
// wipe buffer
if (uFlags & kPGPUnicodeFlag_Secure)
ZeroMemory (wsz, sizeof(wsz));
*puLenUTF8 = uOutPos;
if (*puLenUTF8 > uMaxLenUTF8-1)
*puLenUTF8 = uMaxLenUTF8-1;
}
else
{
// we failed to link to the required conversion functions
// so just copy the input to the output
*puLenUTF8 = min (uMaxLenUTF8-1, uLenASCII);
strncpy (pszUTF8, pszASCII, *puLenUTF8);
err = kPGPError_NoErr;
}
// always NULL-terminate
pszUTF8[*puLenUTF8] = '\0';
return err;
}
/* ______________________________________________
*
* convert a UTF-8 Unicode string to local code page
* It is OK to specify the same buffer as both input
* and output (as far as I know).
*/
PGPError
pgpUTF8StringToLocal (
PGPUInt32 uFlags,
PGPUInt32 uCodePage,
const char* pszUTF8,
PGPUInt32 uLenUTF8,
char* pszASCII,
PGPUInt32 uMaxLenASCII,
PGPUInt32* puLenASCII)
{
PGPError err = kPGPError_BufferTooSmall;
if (!bIsInitialized)
sInitializeWin32UnicodeLibraries ();
if (s_fpMultiByteToWideChar)
{
// use the Win32 APIs
PGPUInt32 uIn, uOut, uToConvert, uOutPos;
PGPUInt32 u, uLenWide;
PGPUInt16 wsz[kPGPBufferSize];
uToConvert = uLenUTF8;
uOutPos = 0;
while ((uToConvert > 0) && (uOutPos < uMaxLenASCII))
{
// convert string in local code page format to UCS-2
uIn = pgpUTF8StringToUCS2 (pszUTF8, uToConvert,
wsz, kPGPBufferSize, &uLenWide);
if (uLenWide > 0)
{
// convert UCS-2 string to local code page
if (uFlags & kPGPUnicodeFlag_Secure)
{
// break up the string into characters and
// convert one at a time in order to avoid
// passing passphrase to system function.
for (u=0; u<uLenWide; u++)
{
uOut = s_fpWideCharToMultiByte (uCodePage, 0,
&wsz[u], 1,
&pszASCII[uOutPos], uMaxLenASCII-uOutPos,
NULL, NULL);
uOutPos += uOut;
}
uOut = 0;
}
else
{
// use system call to convert intact string.
// this is not secure since we are passing the
// intact string to the system function.
uOut = s_fpWideCharToMultiByte (uCodePage, 0,
wsz, uLenWide,
&pszASCII[uOutPos], uMaxLenASCII-uOutPos,
NULL, NULL);
}
if (uOut > 0)
err = kPGPError_NoErr;
else
err = kPGPError_BufferTooSmall;
}
else
{
// We couldn't convert from UTF-8, so we just copy
// the string. This handles the case where other
// implementations created userid strings with
// proprietary high-ASCII chars.
uOutPos = min (uMaxLenASCII-1, uLenUTF8);
strncpy (pszASCII, pszUTF8, uOutPos);
err = kPGPError_NoErr;
break;
}
pszUTF8 += uIn;
uToConvert -= uIn;
uOutPos += uOut;
}
// wipe buffer
if (uFlags & kPGPUnicodeFlag_Secure)
ZeroMemory (wsz, sizeof(wsz));
*puLenASCII = uOutPos;
if (*puLenASCII > uMaxLenASCII-1)
*puLenASCII = uMaxLenASCII-1;
}
else
{
// we failed to link to the required conversion functions
// so just copy the input to the output
*puLenASCII = min (uMaxLenASCII-1, uLenUTF8);
strncpy (pszASCII, pszUTF8, *puLenASCII);
err = kPGPError_NoErr;
}
// always NULL-terminate
pszASCII[*puLenASCII] = '\0';
return err;
}
/* ______________________________________________
*
* convert a Local string to UCS-2.
*/
void
pgpLocalStringToUCS2 (
PGPUInt32 uFlags,
PGPUInt32 uCodePage,
const char* pszLocal,
PGPUInt32 uLenLocal,
PGPUInt16* wszWide,
PGPUInt32 uMaxLenWide,
PGPUInt32* puLenOut)
{
PGPUInt32 u, uToDo;
if (!bIsInitialized)
sInitializeWin32UnicodeLibraries ();
if (s_fpMultiByteToWideChar)
{
if (uFlags & kPGPUnicodeFlag_Secure)
{
// break up the string into characters and
// convert one at a time in order to avoid
// passing passphrase to system function.
// note that we assume input string is one byte
// per character, which it should be for a "local"
// string.
uToDo = min (uLenLocal, uMaxLenWide);
for (u=0; u<uToDo; u++)
{
s_fpMultiByteToWideChar (uCodePage,
MB_ERR_INVALID_CHARS,
&pszLocal[u], 1, &wszWide[u], 1);
}
*puLenOut = uToDo;
}
else
{
*puLenOut = s_fpMultiByteToWideChar (uCodePage,
MB_ERR_INVALID_CHARS,
pszLocal, uLenLocal, wszWide, uMaxLenWide);
}
}
else
{
// we failed to link to the required conversion functions
// so just copy the input to the output
uToDo = min (uLenLocal, uMaxLenWide);
for (u=0; u<uToDo; u++)
wszWide[u] = pszLocal[u];
*puLenOut = uToDo;
}
}
/* ______________________________________________
*
* get current Code Page for window
*/
PGPUInt32
pgpGetCodePageFromWindow (
void* hwnd)
{
CHARSETINFO cs;
HDC hdc;
hdc = GetDC ((HWND)hwnd);
if (hdc)
{
TranslateCharsetInfo (
(DWORD*)(GetTextCharset (hdc)), &cs, TCI_SRCCHARSET);
ReleaseDC ((HWND)hwnd, hdc);
return cs.ciACP;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -