Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

743 lines
14 KiB

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
void DoUsage()
{
printf("Usage: kiwi inputfile\n");
}
typedef struct _TOKEN_ID {
WCHAR *String;
UINT Value;
} TOKEN_ID;
#define NO_MATCH 0
#define LOGFONT_W 1
#define LOGFONT_A 2
#define GET_TEXT_EXTENT_POINT 3
#define GET_RESOLUTION 4
#define GET_TEXT_FACE 5
#define GET_TEXT_EXTENTEX_POINT 6
#define GET_CHAR_WIDTH 7
#define GET_CHAR_ABC_WIDTHS 8
#define GET_CHARACTER_PLACEMENT 9
#define GET_GLYPHOUTLINE 10
#define GET_KERNINGPAIRS 11
TOKEN_ID Tokens[] = { {L"[LOGFONTW]",LOGFONT_W},
{L"[LOGFONTA]",LOGFONT_A},
{L"[GETTEXTEXTENTPOINT]",GET_TEXT_EXTENT_POINT},
{L"[GETRESOLUTION]",GET_RESOLUTION},
{L"[GETTEXTFACE]",GET_TEXT_FACE},
{L"[GETTEXTEXTENTEXPOINT]",GET_TEXT_EXTENTEX_POINT},
{L"[GETCHARWIDTH]",GET_CHAR_WIDTH},
{L"[GETCHARABCWIDTHS]",GET_CHAR_ABC_WIDTHS},
{L"[GETCHARACTERPLACEMENT]",GET_CHARACTER_PLACEMENT},
{L"[GETGLYPHOUTLINE]",GET_GLYPHOUTLINE},
{L"[GETKERNINGPAIRS]",GET_KERNINGPAIRS}};
UINT StringToToken(WCHAR *String)
{
int i;
for(i = 0; i < sizeof(Tokens) / sizeof(TOKEN_ID); i++)
{
if(!wcsicmp(String,Tokens[i].String))
{
return(Tokens[i].Value);
}
}
return(NO_MATCH);
}
void SkipComment(FILE *File)
{
unsigned char Value;
while(((Value = (unsigned char) getc(File)) == ' ') ||
(Value == 0x10));
if(Value == ';')
{
while(!feof(File) && (Value = (unsigned char) getc(File)) && Value != 0xA);
}
else
{
ungetc(Value,File);
}
}
BOOL ReadByteFromLine(FILE *File, PBYTE Result)
{
ULONG Value;
SkipComment(File);
if(fscanf(File,"%d", &Value) != 1)
{
return(FALSE);
}
else
{
*Result = (BYTE) Value;
}
return(TRUE);
}
BOOL ReadIntFromLine(FILE *File, int *Result)
{
INT Value;
BOOL IsHex = FALSE;
char HexCheck;
SkipComment(File);
while(!feof(File) && (((HexCheck = (char) getc(File)) == ' ') ||
(HexCheck == 0xA) || (HexCheck == 0xD)));
if(feof(File))
{
return(FALSE);
}
if(toupper(HexCheck) == 'X')
{
IsHex = TRUE;
}
else
{
ungetc(HexCheck,File);
}
if(fscanf(File,(IsHex) ? "%x" : "%d", &Value) != 1)
{
return(FALSE);
}
else
{
*Result = Value;
}
return(TRUE);
}
BOOL ReadUnicodeStringFromLine(FILE *File, WCHAR *ResultString)
{
int Value;
WCHAR *String = ResultString;
SkipComment(File);
while(!feof(File) && (((Value = (char) getc(File)) == ' ') ||
(Value == 0xA) || (Value == 0xD)));
if(feof(File))
{
return(FALSE);
}
// string is in the form \xxx\xxx where xxx are hex values for
// unicode codepoints
if(Value == '\\')
{
while(Value == '\\')
{
WCHAR CodePoint = 0;
while(!feof(File) && (Value = getc(File)) && isxdigit(Value))
{
if(isdigit(Value))
{
Value = Value - '0';
}
else
{
Value = _toupper(Value);
Value = Value - 'A' + 10;
}
CodePoint = CodePoint * 16 + Value;
}
*String++ = CodePoint;
}
*String++ = 0;
}
else if(Value == '"')
{
// trying to match a string in the form "....."
while(!feof(File) && (Value = getc(File)) && Value != '"')
{
*String++ = (WCHAR) Value;
}
*String++ = 0;
}
else
{
ungetc(Value,File);
while(!feof(File) && (Value = getc(File)) && Value != ' ' &&
Value != 0xA && Value != 0xD)
{
*String++ = (WCHAR) Value;
}
*String++ = 0;
ungetc(Value,File);
}
return(wcslen(ResultString) != 0);
}
BOOL ReadStringFromLine(FILE *File, char *ResultString)
{
WCHAR SignExtendedStringBuffer[255],*StringCounter;
if(ReadUnicodeStringFromLine(File,SignExtendedStringBuffer))
{
StringCounter = SignExtendedStringBuffer;
while(*StringCounter)
{
*ResultString++ = (char) *StringCounter++;
}
*ResultString = 0;
return(TRUE);
}
return(FALSE);
}
BOOL DoLogfont(FILE *File, HFONT *CurrentFont, BOOL Unicode)
{
LOGFONTW LogfontW;
LOGFONTA LogfontA;
LOGFONTW *Logfont;
if(Unicode)
{
Logfont = &LogfontW;
}
else
{
Logfont = (LOGFONTW*) &LogfontA;
}
if(!ReadIntFromLine(File,(int*) &Logfont->lfHeight) ||
!ReadIntFromLine(File,(int*) &Logfont->lfWidth) ||
!ReadIntFromLine(File,(int*) &Logfont->lfEscapement) ||
!ReadIntFromLine(File,(int*) &Logfont->lfOrientation) ||
!ReadIntFromLine(File,(int*) &Logfont->lfWeight) ||
!ReadByteFromLine(File,&Logfont->lfItalic) ||
!ReadByteFromLine(File,&Logfont->lfUnderline) ||
!ReadByteFromLine(File,&Logfont->lfStrikeOut) ||
!ReadByteFromLine(File,&Logfont->lfCharSet) ||
!ReadByteFromLine(File,&Logfont->lfOutPrecision) ||
!ReadByteFromLine(File,&Logfont->lfClipPrecision) ||
!ReadByteFromLine(File,&Logfont->lfQuality) ||
!ReadByteFromLine(File,&Logfont->lfPitchAndFamily))
{
return(FALSE);
}
if(Unicode)
{
if(!ReadUnicodeStringFromLine(File,(WCHAR*) LogfontW.lfFaceName))
{
return(FALSE);
}
*CurrentFont = CreateFontIndirectW(&LogfontW);
}
else
{
if(!ReadStringFromLine(File,(char*) LogfontA.lfFaceName))
{
return(FALSE);
}
*CurrentFont = CreateFontIndirectA(&LogfontA);
}
return(TRUE);
}
BOOL DoGetTextExtentPoint(FILE *File, HDC CurrentDC)
{
char StringBuffer[255];
if(ReadStringFromLine(File,StringBuffer))
{
SIZE Size;
GetTextExtentPointA(CurrentDC,
StringBuffer,
strlen(StringBuffer),
&Size);
printf("GetTextExtentPoint: %d %d\n", Size.cx, Size.cy);
return(TRUE);
}
return(FALSE);
}
BOOL DoGetTextExtentExPoint(FILE *File, HDC CurrentDC)
{
char StringBuffer[255];
int MaxExtent;
if(ReadStringFromLine(File,StringBuffer) &&
ReadIntFromLine(File,&MaxExtent))
{
SIZE Size;
INT Fit;
INT *DxArray = (INT*) LocalAlloc(LMEM_FIXED, strlen(StringBuffer)*sizeof(INT));
if(DxArray)
{
GetTextExtentExPointA(CurrentDC,
StringBuffer,
strlen(StringBuffer),
MaxExtent,
&Fit,
DxArray,
&Size);
printf("GetTextExtentExPoint: %d %d %d { ", Size.cx, Size.cy, Fit);
int i;
for(i = 0; i < Fit; i++)
{
printf("%d ", DxArray[i]);
}
printf("}\n");
LocalFree(DxArray);
return(TRUE);
}
else
{
printf("GetTextExtentExPoint: out of memory\n");
}
}
return(FALSE);
}
BOOL DoGetCharWidth(FILE *File, HDC CurrentDC, BOOL ThirtyTwo)
{
INT First, Last, Widths[256];
if(ReadIntFromLine(File,&First) &&
ReadIntFromLine(File,&Last))
{
printf(ThirtyTwo ? "GetCharWidth32: " : "GetCharWidth: ");
if((ThirtyTwo) ? GetCharWidth32(CurrentDC,First,Last,Widths) :
GetCharWidth(CurrentDC,First,Last,Widths))
{
INT i;
for(i = 0; i < Last-First; i++)
{
printf("%d ", Widths[i]);
}
printf("\n");
}
else
{
printf("call failed\n");
}
return(TRUE);
}
return(FALSE);
}
BOOL DoGetKerningPairs(FILE *File, HDC CurrentDC)
{
UINT NumPairs;
NumPairs = GetKerningPairs(CurrentDC, 0, NULL);
printf("GetKerningPairs: ");
if(NumPairs)
{
KERNINGPAIR *KerningBuffer;
KerningBuffer = (KERNINGPAIR*) LocalAlloc(LMEM_FIXED, sizeof(KERNINGPAIR) * NumPairs);
if(KerningBuffer)
{
if(GetKerningPairs(CurrentDC, NumPairs, KerningBuffer) == NumPairs)
{
UINT j;
printf("%d\n", NumPairs);
for(j = 0; j < NumPairs; j++)
{
printf("(%x,%x,%x)\n", KerningBuffer[j].wFirst, KerningBuffer[j].wSecond,
KerningBuffer[j].iKernAmount);
}
printf("\n");
}
else
{
printf("failed\n");
}
LocalFree(KerningBuffer);
}
else
{
printf("mem alloc failed\n");
}
}
else
{
printf("failed\n");
}
return(TRUE);
}
BOOL DoGetCharAbcWidths(FILE *File, HDC CurrentDC)
{
INT First, Last;
ABC AbcWidths[256];
if(ReadIntFromLine(File,&First) &&
ReadIntFromLine(File,&Last))
{
printf("GetCharAbcWidth: ");
if(GetCharABCWidths(CurrentDC,First,Last,AbcWidths))
{
INT i;
for(i = 0; i < Last-First; i++)
{
printf("(%d %d %d) ", AbcWidths[i].abcA, AbcWidths[i].abcB, AbcWidths[i].abcC);
}
printf("\n");
}
else
{
printf("call failed\n");
}
return(TRUE);
}
return(FALSE);
}
BOOL DoGetCharacterPlacement(FILE *File, HDC CurrentDC)
{
char StringBuffer[255];
int MaxExtent;
UINT Flags;
if(ReadStringFromLine(File,StringBuffer) &&
ReadIntFromLine(File,&MaxExtent) &&
ReadIntFromLine(File,(INT*)&Flags))
{
GCP_RESULTSA Results;
PVOID ResultsBuffer;
UINT StringSize = strlen(StringBuffer);
UINT BufferSize = ( sizeof(char) + // lpOutString
sizeof(UINT) + // lpOrder
sizeof(INT) + // lpDX
sizeof(INT) + // lpCaretPos
sizeof(char) + // lpClass
sizeof(WCHAR) // lpGlyphs
) * StringSize + sizeof(char); // extra char for null in lpOutString;
ResultsBuffer = LocalAlloc(LPTR, BufferSize);
if(ResultsBuffer)
{
int i;
DWORD ReturnValue;
Results.lStructSize = sizeof(Results);
Results.lpOutString = (LPSTR) ResultsBuffer;
Results.lpOrder = (UINT*) &Results.lpOutString[StringSize+1];
Results.lpDx = (INT*) &Results.lpOrder[StringSize];
Results.lpCaretPos = &Results.lpDx[StringSize];
Results.lpClass = (LPSTR) &Results.lpCaretPos[StringSize];
Results.lpGlyphs = (WCHAR*) &Results.lpClass[StringSize];
Results.nGlyphs = StringSize;
// if the flags specify GCP_JUSTIFY_IN then read in the DX array
if(Flags & GCP_JUSTIFYIN)
{
UINT j;
for(j = 0; j < StringSize; j++)
{
if(!ReadIntFromLine(File,&Results.lpDx[j]))
{
LocalFree(ResultsBuffer);
return(FALSE);
}
}
}
ReturnValue = GetCharacterPlacementA(CurrentDC,
StringBuffer,
StringSize,
MaxExtent,
&Results,
Flags);
printf("GetCharacterPlacement: %d %d %x\n", Results.nGlyphs, Results.nMaxFit, ReturnValue);
if(ReturnValue)
{
printf(" lpOutString : %s\n", Results.lpOutString);
printf(" lpOrder : ");
for(i = 0; i < Results.nMaxFit; i++)
{
printf("%d ", Results.lpOrder[i]);
}
printf("\n lpCaretPos : ");
for(i = 0; i < Results.nMaxFit; i++)
{
printf("%d ", Results.lpCaretPos[i]);
}
printf("\n lpClass : ");
for(i = 0; i < Results.nMaxFit; i++)
{
printf("%d ", Results.lpClass[i]);
}
printf("\n lpDx : ");
for(i = 0; i < (int) Results.nGlyphs; i++)
{
printf("%d ", Results.lpDx[i]);
}
printf("\n lpGlyphs : ");
for(i = 0; i < (int) Results.nGlyphs; i++)
{
printf("%d ", Results.lpGlyphs[i]);
}
}
printf("\n");
LocalFree(ResultsBuffer);
}
return(TRUE);
}
return(FALSE);
}
BOOL DoGetGlyphOutline(FILE *File, HDC CurrentDC)
{
UINT Glyph;
if(ReadIntFromLine(File,(INT*) &Glyph))
{
char OutlineBuffer[2048];
int NumBytes;
GLYPHMETRICS Metrics;
MAT2 Matrix;
memset((void*)&Matrix, 0, sizeof(Matrix));
Matrix.eM11.value = Matrix.eM22.value = 1;
printf("GetGlyphOutline: ");
if(NumBytes = GetGlyphOutline(CurrentDC, Glyph, GGO_NATIVE, &Metrics,
2048, OutlineBuffer, &Matrix))
{
int i;
for(i = 0; i < NumBytes; i++)
{
printf("%x ", OutlineBuffer[i]);
}
printf("\n");
}
else
{
printf("failed \n");
}
return(TRUE);
}
else
{
return(FALSE);
}
}
void main(int argc, char *argv[])
{
FILE *InputFile;
if(argc < 2 || argc > 3)
{
DoUsage();
exit;
}
if((InputFile = fopen(argv[1], "r")) == (FILE*) -1)
{
printf("Unable to open file %s\n", argv[1]);
exit;
}
HFONT CurrentFont = NULL;
HFONT OldFont = NULL;
HDC CurrentDC = CreateDC("Display", NULL, NULL, NULL);
BOOL ValidInput = TRUE;
do
{
WCHAR StringBuffer[255];
if(!ReadUnicodeStringFromLine(InputFile,StringBuffer))
{
break;
}
switch(StringToToken(StringBuffer))
{
case LOGFONT_W:
if(CurrentFont)
{
SelectObject(CurrentDC, OldFont);
DeleteObject(CurrentFont);
}
if(ValidInput = DoLogfont(InputFile,&CurrentFont,TRUE))
{
OldFont = SelectObject(CurrentDC, CurrentFont);
}
break;
case LOGFONT_A:
if(CurrentFont)
{
SelectObject(CurrentDC, OldFont);
DeleteObject(CurrentFont);
}
if(ValidInput = DoLogfont(InputFile,&CurrentFont,FALSE))
{
OldFont = SelectObject(CurrentDC, CurrentFont);
}
break;
case GET_TEXT_EXTENT_POINT:
ValidInput = DoGetTextExtentPoint(InputFile, CurrentDC);
break;
case GET_TEXT_EXTENTEX_POINT:
ValidInput = DoGetTextExtentExPoint(InputFile, CurrentDC);
break;
case GET_TEXT_FACE:
{
char *TextFace;
int Count,Count2;
Count = GetTextFace(CurrentDC, 0, 0);
if(Count && (TextFace = (char*) LocalAlloc(LMEM_FIXED,Count+1)))
{
Count2 = GetTextFace(CurrentDC,Count,TextFace);
printf("%s %d %d\n", TextFace, Count, Count2);
LocalFree(TextFace);
}
break;
}
case GET_RESOLUTION:
{
DWORD Resolution;
Resolution = GetDeviceCaps(CurrentDC, LOGPIXELSX);
printf("%x ", Resolution);
Resolution = GetDeviceCaps(CurrentDC, LOGPIXELSY);
printf("%x\n", Resolution);
break;
}
case GET_CHAR_WIDTH:
ValidInput = DoGetCharWidth(InputFile, CurrentDC, FALSE);
break;
case GET_CHAR_ABC_WIDTHS:
ValidInput = DoGetCharAbcWidths(InputFile, CurrentDC);
break;
case GET_CHARACTER_PLACEMENT:
ValidInput = DoGetCharacterPlacement(InputFile, CurrentDC);
break;
case GET_GLYPHOUTLINE:
ValidInput = DoGetGlyphOutline(InputFile, CurrentDC);
break;
case GET_KERNINGPAIRS:
ValidInput = DoGetKerningPairs(InputFile, CurrentDC);
break;
case NO_MATCH:
ValidInput = FALSE;
break;
}
}while(ValidInput);
if(!ValidInput)
{
printf("ERROR encountered in file\n");
}
fclose(InputFile);
}