windows-nt/Source/XPSP1/NT/sdktools/unicows/godot/util.c
2020-09-26 16:20:57 +08:00

328 lines
7.9 KiB
C

/*++
Copyright (c) 2000-2001, Microsoft Corporation All rights reserved.
Module Name:
util.c
Abstract:
Several utility functions we need are thrown in here for kicks.
MiniAtoI
CpgFromLocale
CbPerChOfCpg
GetKernelHandle
GetUserHandle
GetAdvapiHandle
GetRasHandle
GetOtherRasHandle
GetComDlgHandle
cchUnicodeMultiSz
cbAnsiMultiSz
Revision History:
17 Mar 2001 v-michka Created.
--*/
#include "precomp.h"
// forward declares
void LoadLibrarySafe(HMODULE * phMod, char * Library);
// our remembered handles for various DLLs we dynamically load from
// CONSIDER: Maybe we could free up the one handle we have for each
// library? We cannot do this in DllMain according to PSDK
// docs, but maybe it is worth doing if we are being
// unloaded anyway by the caller?
static HMODULE m_hModGB18030 = 0;
static HMODULE m_hModComDlg = 0;
static HMODULE m_hModOtherRas = 0;
static HMODULE m_hModRas = 0;
static HMODULE m_hModAdvapi = 0;
static HMODULE m_hModUser = 0;
static HMODULE m_hModKernel = 0;
static HMODULE m_hModSensapi = 0;
static HMODULE m_hModOleAcc = 0;
/*-------------------------------
CpgFromLocale
Given a locale, returns the appropriate codepage to use
for conversions
-------------------------------*/
UINT CpgFromLocale(LCID Locale)
{
char lpLCData[6]; // Max of this param, per PSDK docs
if (GetLocaleInfoA(Locale, LOCALE_IDEFAULTANSICODEPAGE, lpLCData, 6))
return(MiniAtoI(lpLCData));
return(g_acp);
}
/*-------------------------------
CpgOemFromLocale
Given a locale, returns the appropriate OEM codepage to use
for conversions
-------------------------------*/
UINT CpgOemFromLocale(LCID Locale)
{
char lpLCData[6]; // Max of this param, per PSDK docs
if (GetLocaleInfoA(Locale, LOCALE_IDEFAULTCODEPAGE, lpLCData, 6))
return(MiniAtoI(lpLCData));
return(g_oemcp);
}
#pragma intrinsic (strlen)
/*-------------------------------
MiniAtoI
Our baby version of the atoi function. Since we know that we always have
full digits with no white space, we can be nicer about this than the
VC runtime version is (since they have so many special cases).
-------------------------------*/
UINT MiniAtoI(const char * lpsz)
{
size_t cch = (lpsz ? strlen(lpsz) : 0);
UINT RetVal = 0;
UINT mod = 1;
UINT ich;
char ch;
for(ich = 1 ; ich <= cch ; ich++)
{
ch = lpsz[cch - ich];
RetVal += ((ch - '0') * mod);
mod *= 10;
}
return(RetVal);
}
/*-------------------------------
CbPerChOfCpg
Given a code page, returns the maximum number of bytes
that can be needed for a single character.
-------------------------------*/
UINT CbPerChOfCpg(UINT cpg)
{
CPINFO cpi;
if(GetCPInfo(cpg, &cpi))
return(cpi.MaxCharSize);
// We should not fail here, but if we do, default to requiring a big
// buffer, just to be safe.
return(2);
}
/*-------------------------------
CpgFromHdc
Given a device context handle, returns the code page to
use. This is something that a lot of GDI functions do.
-------------------------------*/
UINT CpgFromHdc(HDC hdc)
{
int chs;
CHARSETINFO csi;
chs = GetTextCharset(hdc);
if(TranslateCharsetInfo(&(DWORD)chs, &csi, TCI_SRCCHARSET))
return(csi.ciACP);
else
return(g_acp);
}
/*-------------------------------
GetUserHandle
-------------------------------*/
HMODULE GetUserHandle(void)
{
if (!m_hModUser)
{
m_hModUser = GetModuleHandleA("user32");
if (!m_hModUser)
LoadLibrarySafe(&m_hModUser, "user32");
}
return(m_hModUser);
}
/*-------------------------------
GetComDlgHandle
-------------------------------*/
HMODULE GetComDlgHandle(void)
{
if (!m_hModComDlg)
LoadLibrarySafe(&m_hModComDlg, "comdlg32.dll");
return m_hModComDlg;
}
/*-------------------------------
GetGB18030Handle
-------------------------------*/
HMODULE GetGB18030Handle(void)
{
if (!m_hModGB18030)
LoadLibrarySafe(&m_hModGB18030, "c_gb18030.dll");
return m_hModGB18030;
}
/*-------------------------------
GetKernelProc
We do not need to call LoadLibrary since we are sure it is
loaded (it is loaded into every process!)
-------------------------------*/
FARPROC GetKernelProc(LPCSTR Function)
{
if (!m_hModKernel)
m_hModKernel = GetModuleHandleA("kernel32");
return(GetProcAddress(m_hModKernel, Function));
}
/*-------------------------------
GetUserProc
-------------------------------*/
FARPROC GetUserProc(LPCSTR Function)
{
return(GetProcAddress(GetUserHandle(), Function));
}
/*-------------------------------
GetAdvapiProc
-------------------------------*/
FARPROC GetAdvapiProc(LPCSTR Function)
{
if (!m_hModAdvapi)
{
m_hModAdvapi = GetModuleHandleA("advapi32");
if (!m_hModAdvapi)
LoadLibrarySafe(&m_hModAdvapi, "advapi32");
}
return(GetProcAddress(m_hModAdvapi, Function));
}
/*-------------------------------
GetOleAccProc
-------------------------------*/
FARPROC GetOleAccProc(LPCSTR Function)
{
if (!m_hModOleAcc)
LoadLibrarySafe(&m_hModOleAcc, "oleacc.dll");
return(GetProcAddress(m_hModOleAcc, Function));
}
/*-------------------------------
GetSensApiProc
-------------------------------*/
FARPROC GetSensApiProc(LPCSTR Function)
{
if (!m_hModSensapi)
LoadLibrarySafe(&m_hModSensapi, "sensapi.dll");
return(GetProcAddress(m_hModSensapi, Function));
}
/*-------------------------------
GetRasProc
All RAS procs are in some DLL but we do not know
which one; therefore, we use this wrapper to get
the procs
-------------------------------*/
FARPROC GetRasProc(LPCSTR Function)
{
FARPROC RetVal;
if (!m_hModRas)
LoadLibrarySafe(&m_hModRas, "rasapi32.dll");
RetVal = GetProcAddress(m_hModRas, Function);
if(RetVal==0)
{
if (!m_hModOtherRas)
LoadLibrarySafe(&m_hModOtherRas, "rnaph.dll");
RetVal = GetProcAddress(m_hModOtherRas, Function);
}
return(RetVal);
}
/*-------------------------------
LoadLibrarySafe
Keeps us from ever LoadLibrarying more than one
time in multithreaded scenarios.
-------------------------------*/
void LoadLibrarySafe(HMODULE * phMod, char * Library)
{
HMODULE hModT = LoadLibraryA(Library);
if(InterlockedExchange((LPLONG)&(*phMod), (LONG)hModT) != 0)
{
// Some other thread beat us to it, lets unload our instance
FreeLibrary(hModT);
}
}
//----------------------------------------------------------------------------
// There are strings which are blocks of strings end to end with a trailing '\0'
// to indicate the true end. These strings are used with the REG_MULTI_SZ
// option of the Reg... routines and the lpstrFilter field of the OPENFILENAME
// structure used in the GetOpenFileName and GetSaveFileName routines. To help
// in converting these strings here are two routines which calculate the size
// of the Unicode and ANSI versions (including all '\0's!):
// Stolen from VSANSI
//----------------------------------------------------------------
// Return size of WCHAR string list in WCHARs.
size_t cchUnicodeMultiSz(LPCWSTR lpsz)
{
LPCWSTR pch = lpsz;
for (;;)
{
if (*pch)
pch++;
else
{
pch++;
if (!*pch)
break;
}
}
return 1 + (pch - lpsz);
}
//----------------------------------------------------------------
// Return size of ANSI string list in bytes.
size_t cbAnsiMultiSz(LPCSTR lpsz)
{
LPCSTR pch = lpsz;
for (;;)
{
if (*pch)
pch++;
else
{
pch++;
// Break if we've reached the double Null
if (!*pch)
break;
}
}
return 1 + (pch - lpsz);
}