Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

477 lines
12 KiB

/*++
Copyright (c) 1985 - 1999, Microsoft Corporation
Module Name:
eudc.c
Abstract:
Author:
KazuM Apr.19.1996
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#if defined(FE_SB)
NTSTATUS
CreateEUDC(
PCONSOLE_INFORMATION Console
)
{
PEUDC_INFORMATION EudcInfo;
EudcInfo = ConsoleHeapAlloc(EUDC_TAG, sizeof(EUDC_INFORMATION));
if (EudcInfo == NULL) {
return STATUS_NO_MEMORY;
}
EudcInfo->LocalVDMEudcMode = FALSE;
EudcInfo->LocalKeisenEudcMode = FALSE;
EudcInfo->hDCLocalEudc = NULL;
EudcInfo->hBmpLocalEudc = NULL;
EudcInfo->EudcFontCacheInformation = NULL;
EudcInfo->LocalEudcSize.X = DEFAULT_EUDCSIZE;
EudcInfo->LocalEudcSize.Y = DEFAULT_EUDCSIZE;
RtlZeroMemory(&EudcInfo->EudcRange,sizeof(EudcInfo->EudcRange));
EudcInfo->EudcRangeSize = GetSystemEUDCRangeW(EudcInfo->EudcRange, EUDC_RANGE_SIZE);
if (EudcInfo->EudcRangeSize)
EudcInfo->EudcRangeSize--; // remove terminator
Console->EudcInformation = (PVOID)EudcInfo;
return STATUS_SUCCESS;
}
VOID
DeleteEUDC(
PCONSOLE_INFORMATION Console
)
{
PEUDC_INFORMATION EudcInfo = Console->EudcInformation;
if (EudcInfo->hDCLocalEudc) {
ReleaseDC(NULL, EudcInfo->hDCLocalEudc);
DeleteObject(EudcInfo->hBmpLocalEudc);
}
}
NTSTATUS
RegisterLocalEUDC(
IN PCONSOLE_INFORMATION Console,
IN WCHAR wChar,
IN COORD FontSize,
IN PCHAR FontFace
)
{
NTSTATUS Status;
PCHAR TmpBuff;
DWORD BuffSize;
PEUDC_INFORMATION EudcInfo = Console->EudcInformation;
if (EudcInfo->EudcFontCacheInformation == NULL) {
Status = (NTSTATUS)CreateFontCache(&(PFONT_CACHE_INFORMATION)EudcInfo->EudcFontCacheInformation);
if (!NT_SUCCESS(Status)) {
RIPMSG1(RIP_WARNING, "RegisterLocalEUDC: failed in CreateFontCache, Status is %08x", Status);
return Status;
}
}
BuffSize = CalcBitmapBufferSize(FontSize, BYTE_ALIGN);
TmpBuff = FontFace;
while(BuffSize--)
*TmpBuff++ = ~(*TmpBuff);
return (NTSTATUS)SetFontImage(EudcInfo->EudcFontCacheInformation,
wChar,
FontSize,
BYTE_ALIGN,
FontFace
);
}
VOID
FreeLocalEUDC(
IN PCONSOLE_INFORMATION Console
)
{
PEUDC_INFORMATION EudcInfo = Console->EudcInformation;
if (EudcInfo->EudcFontCacheInformation != NULL) {
DestroyFontCache((PFONT_CACHE_INFORMATION)EudcInfo->EudcFontCacheInformation);
}
ConsoleHeapFree(Console->EudcInformation);
}
VOID
GetFitLocalEUDCFont(
IN PCONSOLE_INFORMATION Console,
IN WCHAR wChar
)
{
NTSTATUS Status;
COORD FontSize;
VOID *FontFace;
DWORD BuffSize;
PEUDC_INFORMATION EudcInfo;
PFONT_CACHE_INFORMATION FontCacheInfo;
EudcInfo = (PEUDC_INFORMATION)Console->EudcInformation;
FontCacheInfo = (PFONT_CACHE_INFORMATION)EudcInfo->EudcFontCacheInformation;
FontSize = CON_FONTSIZE(Console);
if (IsConsoleFullWidth(Console->hDC,Console->OutputCP,wChar)) {
FontSize.X *= 2;
}
if ((EudcInfo->LocalEudcSize.X != FontSize.X) ||
(EudcInfo->LocalEudcSize.Y != FontSize.Y) ) {
ReleaseDC(NULL, EudcInfo->hDCLocalEudc);
DeleteObject(EudcInfo->hBmpLocalEudc);
EudcInfo->hDCLocalEudc = CreateCompatibleDC(Console->hDC);
EudcInfo->hBmpLocalEudc = CreateBitmap(FontSize.X, FontSize.Y, BITMAP_PLANES, BITMAP_BITS_PIXEL, NULL);
SelectObject(EudcInfo->hDCLocalEudc, EudcInfo->hBmpLocalEudc);
EudcInfo->LocalEudcSize.X = FontSize.X;
EudcInfo->LocalEudcSize.Y = FontSize.Y;
}
BuffSize = CalcBitmapBufferSize(FontSize,WORD_ALIGN);
FontFace = ConsoleHeapAlloc(TMP_DBCS_TAG, BuffSize);
if (FontFace == NULL) {
RIPMSG0(RIP_WARNING, "GetFitLocalEUDCFont: failed to allocate FontFace.");
return;
}
Status = (NTSTATUS)GetFontImage(FontCacheInfo,
wChar,
FontSize,
WORD_ALIGN,
FontFace
);
if (! NT_SUCCESS(Status)) {
if ((Console->Flags & CONSOLE_VDM_REGISTERED) &&
FontSize.X == DefaultFontSize.X * 2 &&
FontSize.Y == DefaultFontSize.Y &&
FontSize.X == VDM_EUDC_FONT_SIZE_X &&
FontSize.Y - 2 == VDM_EUDC_FONT_SIZE_Y ) {
COORD TmpFontSize = FontSize;
TmpFontSize.Y -= 2;
RtlFillMemory((PVOID)FontFace,BuffSize,0xff);
Status = (NTSTATUS)GetFontImage(FontCacheInfo,
wChar,
TmpFontSize,
WORD_ALIGN,
FontFace
);
if (! NT_SUCCESS(Status)) {
Status = (NTSTATUS)GetStretchedFontImage(FontCacheInfo,
wChar,
FontSize,
WORD_ALIGN,
FontFace
);
if (! NT_SUCCESS(Status)) {
ASSERT(FALSE);
ConsoleHeapFree(FontFace);
return;
}
}
}
else {
Status = (NTSTATUS)GetStretchedFontImage(FontCacheInfo,
wChar,
FontSize,
WORD_ALIGN,
FontFace
);
if (! NT_SUCCESS(Status)) {
ASSERT(FALSE);
ConsoleHeapFree(FontFace);
return;
}
}
Status = (NTSTATUS)SetFontImage(FontCacheInfo,
wChar,
FontSize,
WORD_ALIGN,
FontFace
);
if (! NT_SUCCESS(Status)) {
ASSERT(FALSE);
ConsoleHeapFree(FontFace);
return;
}
}
SetBitmapBits(EudcInfo->hBmpLocalEudc, BuffSize, (PBYTE)FontFace);
ConsoleHeapFree(FontFace);
}
BOOL
IsEudcRange(
IN PCONSOLE_INFORMATION Console,
IN WCHAR ch
)
{
PEUDC_INFORMATION EudcInfo;
int i;
EudcInfo = (PEUDC_INFORMATION)Console->EudcInformation;
for (i=0; i < EudcInfo->EudcRangeSize; i+=2)
{
if (EudcInfo->EudcRange[i] <= ch && ch <= EudcInfo->EudcRange[i+1])
return TRUE;
}
return FALSE;
}
BOOL
CheckEudcRangeInString(
IN PCONSOLE_INFORMATION Console,
IN PWCHAR string,
IN SHORT len,
OUT SHORT *find_pos
)
{
SHORT i;
for (i = 0; i < len; i++,string++)
{
if (IsEudcRange(Console, *string))
{
*find_pos = i;
return TRUE;
}
}
return FALSE;
}
LPWSTR
SkipWhite(
LPWSTR lpch
)
{
if( lpch == NULL )
return( NULL );
for ( ; ; lpch++ )
{
switch (*lpch)
{
case L' ':
case L'\t':
case L'\r':
case L'\n':
break;
default:
return(lpch);
}
}
}
WORD
ConvertStringToHex(
LPWSTR lpch,
LPWSTR *endptr
)
{
WCHAR ch;
WORD val = 0;
while ( (ch=*lpch) != L'\0')
{
if (L'0' <= ch && ch <= L'9')
val = (val << 4) + (ch - L'0');
else if (L'A' <= ch && ch <= L'F')
val = (val << 4) + (ch - L'A' + 10);
else if (L'a' <= ch && ch <= L'f')
val = (val << 4) + (ch - L'a' + 10);
else
break;
lpch++;
}
if (endptr)
*endptr = lpch;
return val;
}
WORD
ConvertStringToDec(
LPWSTR lpch,
LPWSTR *endptr
)
{
WCHAR ch;
WORD val = 0;
while ( (ch=*lpch) != L'\0')
{
if (L'0' <= ch && ch <= L'9')
val = (val * 10) + (ch - L'0');
else
break;
lpch++;
}
if (endptr)
*endptr = lpch;
return val;
}
INT
GetSystemEUDCRangeW(
WORD *pwEUDCCharTable,
UINT cjSize)
{
NTSTATUS Status;
HKEY hkRegistry;
UNICODE_STRING SystemACPString;
WCHAR awcACP[10];
WCHAR awchBuffer[512];
INT iEntry = 0;
/*
* Check parameter
*
* If pwEUDCWideCharTable == NULL && cjSize == 0
* We have to return the needed buffer size to store data
*/
if ((pwEUDCCharTable == NULL && cjSize != 0) ||
(pwEUDCCharTable != NULL && cjSize == 0)) {
return 0;
}
/*
* Open registry key.
*/
Status = MyRegOpenKey(NULL,
MACHINE_REGISTRY_EUDC,
&hkRegistry);
if (!NT_SUCCESS(Status)) {
RIPMSG2(RIP_WARNING,
"GetSystemEUDCRangeW: RegOpenKeyExW(%ws) failed, error = 0x%x",
MACHINE_REGISTRY_EUDC,
GetLastError());
return 0;
}
/*
* Convert ACP to Unicode string.
*/
SystemACPString.Length = 0;
SystemACPString.MaximumLength = ARRAY_SIZE(awcACP);
SystemACPString.Buffer = awcACP;
RtlIntegerToUnicodeString(WINDOWSCP, 10, &SystemACPString);
/*
* Read registry data.
*/
Status = MyRegQueryValue(hkRegistry,
awcACP,
sizeof(awchBuffer), (PBYTE)&awchBuffer);
if (!NT_SUCCESS(Status)) {
RIPMSG2(RIP_VERBOSE,
"GetSystemEUDCRangeW: NtQueryValueKey(%ws) failed, error = 0x%x",
awcACP,
GetLastError());
} else {
LPWSTR pwszBuf = awchBuffer;
/*
* Parse the data.
*/
while (pwszBuf != NULL && *pwszBuf != UNICODE_NULL) {
WORD ch1,ch2;
/*
* Get Start Range value.
*/
pwszBuf = SkipWhite(pwszBuf);
ch1 = ConvertStringToHex(pwszBuf, &pwszBuf);
pwszBuf = SkipWhite(pwszBuf);
if (*pwszBuf != L'-') {
RIPMSG0(RIP_WARNING, "GetSystemEUDCRangeW: Invalid format");
iEntry = 0;
goto Error;
}
/*
* Get End Range value.
*/
pwszBuf = SkipWhite(pwszBuf + 1);
ch2 = ConvertStringToHex(pwszBuf, &pwszBuf);
/*
* Confirm the data sort order is correct.
*/
if (ch1 > ch2) {
RIPMSG0(RIP_WARNING, "GetSystemEUDCRangeW: Sort order is incorrect");
iEntry = 0;
goto Error;
}
/*
* Move pointer to next.
*/
pwszBuf = SkipWhite(pwszBuf);
if (*pwszBuf == L',') {
pwszBuf = SkipWhite(pwszBuf + 1);
}
/*
* Above, if pwszBuf is NULL, we've reached the EOD.
*/
iEntry++;
/*
* If caller buffer is large enough to store the data, store it.
* Even if that's not the case, we have to continue to parse the
* data to compute the number of entry.
*/
/*
* 3 - Because we have to store NULL as a mark of EOD.
*/
if (cjSize >= 3) {
*pwEUDCCharTable++ = ch1;
*pwEUDCCharTable++ = ch2;
cjSize -= 2;
}
}
*pwEUDCCharTable = UNICODE_NULL;
iEntry = iEntry * 2 + 1;
}
Error:
/*
* Close registry handle.
*/
UserAssert(hkRegistry != NULL);
NtClose(hkRegistry);
return iEntry;
}
#endif