⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpunicodewin32.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 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 + -