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.
 
 
 
 
 
 

552 lines
16 KiB

// formerly pffobj.cxx
#include "precomp.hpp"
INT APIENTRY EngPlusMultiByteToWideChar(
UINT CodePage,
LPWSTR WideCharString,
INT BytesInWideCharString,
LPSTR MultiByteString,
INT BytesInMultiByteString
)
{
return MultiByteToWideChar(CodePage, 0,
MultiByteString,BytesInMultiByteString,
WideCharString, BytesInWideCharString/sizeof(WCHAR)
);
// returns zero on error
}
INT APIENTRY EngWideCharToMultiByte(
UINT CodePage,
LPWSTR WideCharString,
INT BytesInWideCharString,
LPSTR MultiByteString,
INT BytesInMultiByteString
)
{
return WideCharToMultiByte(
CodePage, 0,
WideCharString, BytesInWideCharString,
MultiByteString,BytesInMultiByteString,
NULL, NULL
);
}
VOID APIENTRY EngGetCurrentCodePage(
PUSHORT pOemCodePage,
PUSHORT pAnsiCodePage
)
{
*pAnsiCodePage = (USHORT) GetACP();
*pOemCodePage = (USHORT) GetOEMCP();
}
VOID APIENTRY EngUnmapFontFileFD(
ULONG_PTR iFile
)
{
FONTFILEVIEW *pffv = (FONTFILEVIEW *)iFile;
pffv->mapCount--;
if ((pffv->mapCount == 0) && pffv->pvView)
{
if (pffv->pwszPath)
{
UnmapViewOfFile(pffv->pvView);
pffv->pvView = NULL;
}
}
}
BOOL APIENTRY EngMapFontFileFD(
ULONG_PTR iFile,
PULONG *ppjBuf,
ULONG *pcjBuf
)
{
FONTFILEVIEW *pffv = (FONTFILEVIEW *)iFile;
BOOL bRet = FALSE;
if (pffv->mapCount)
{
pffv->mapCount++;
if (ppjBuf)
{
*ppjBuf = (PULONG)pffv->pvView;
}
if (pcjBuf)
{
*pcjBuf = pffv->cjView;
}
return TRUE;
}
if (pffv->pwszPath)
{
HANDLE hFile;
if (Globals::IsNt)
{
hFile = CreateFileW(pffv->pwszPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
}
else // Windows 9x - non-Unicode
{
AnsiStrFromUnicode ansiPath(pffv->pwszPath);
if (ansiPath.IsValid())
{
hFile = CreateFileA(ansiPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
} else {
hFile = INVALID_HANDLE_VALUE;
}
}
if (hFile != INVALID_HANDLE_VALUE)
{
ULARGE_INTEGER lastWriteTime;
if (GetFileTime(hFile, NULL, NULL, (FILETIME *) &lastWriteTime.QuadPart) &&
lastWriteTime.QuadPart == pffv->LastWriteTime.QuadPart)
{
*pcjBuf = GetFileSize(hFile, NULL);
if (*pcjBuf != -1)
{
HANDLE hFileMapping = CreateFileMappingA(hFile, 0, PAGE_READONLY, 0, 0, NULL); // "mappingobject");
if (hFileMapping)
{
*ppjBuf = (PULONG)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (*ppjBuf)
{
bRet = TRUE;
pffv->pvView = *ppjBuf;
pffv->cjView = *pcjBuf;
pffv->mapCount = 1;
}
CloseHandle(hFileMapping);
}
}
}
CloseHandle(hFile);
}
}
return bRet;
}
GpFontFile *LoadFontMemImage(
WCHAR* fontImageName,
BYTE* fontMemoryImage,
INT fontImageSize
)
{
ULONG cwc = UnicodeStringLength(fontImageName) + 1;
FONTFILEVIEW *pffv;
if ((pffv = (FONTFILEVIEW *)GpMalloc(sizeof(FONTFILEVIEW))) == NULL)
return NULL;
else
{
PVOID pvImage;
if ((pvImage = (PVOID)GpMalloc(fontImageSize)) == NULL)
{
GpFree(pffv);
return NULL;
}
GpMemcpy(pvImage, fontMemoryImage, fontImageSize);
pffv->LastWriteTime.QuadPart = 0;
pffv->pvView = pvImage;
pffv->cjView = fontImageSize;
pffv->mapCount = 1;
pffv->pwszPath = NULL;
return (LoadFontInternal(fontImageName, cwc, pffv, TRUE));
}
}
GpFontFile *LoadFontFile(WCHAR *awcPath)
{
// convert font file name to fully qualified path
ULONG cwc = UnicodeStringLength(awcPath) + 1; // for term. zero
FONTFILEVIEW *pffv;
HANDLE hFile;
if ((pffv = (FONTFILEVIEW *)GpMalloc(sizeof(FONTFILEVIEW))) == NULL)
{
return NULL;
}
pffv->LastWriteTime.QuadPart = 0;
pffv->pvView = NULL;
pffv->cjView = 0;
pffv->mapCount = 0;
pffv->pwszPath = awcPath;
if (Globals::IsNt)
{
hFile = CreateFileW(pffv->pwszPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
}
else // Windows 9x - non-Unicode
{
AnsiStrFromUnicode ansiPath(pffv->pwszPath);
if (ansiPath.IsValid())
{
hFile = CreateFileA(ansiPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
} else {
hFile = INVALID_HANDLE_VALUE;
}
}
if (hFile != INVALID_HANDLE_VALUE)
{
if (!(pffv->cjView = GetFileSize(hFile, NULL)))
{
CloseHandle(hFile);
goto error;
}
if (!GetFileTime(hFile, NULL, NULL, (FILETIME *) &pffv->LastWriteTime.QuadPart))
{
CloseHandle(hFile);
goto error;
}
CloseHandle(hFile);
return (LoadFontInternal(awcPath, cwc, pffv, FALSE));
}
error:
GpFree(pffv);
return NULL;
}
GpFontFile *LoadFontInternal(
WCHAR * awcPath,
ULONG cwc,
FONTFILEVIEW * pffv,
BOOL bMem
)
{
GpFontFile *pFontFile = NULL;
ULONG_PTR hffNew = ttfdSemLoadFontFile(// 1, // #OF FILES
(ULONG_PTR *)&pffv,
(ULONG) Globals::LanguageID // for english US
);
if (hffNew)
{
ULONG cFonts = ttfdQueryNumFaces(hffNew);
if (cFonts && cFonts != FD_ERROR)
{
ULONG cjFontFile = offsetof(GpFontFile, aulData) +
cFonts * sizeof(GpFontFace) +
cFonts * sizeof(ULONG_PTR) +
cwc * sizeof(WCHAR);
pFontFile = (GpFontFile *)GpMalloc(cjFontFile);
if (!pFontFile)
{
ttfdSemUnloadFontFile(hffNew);
if (pffv->pwszPath == NULL)
GpFree(pffv->pvView);
GpFree(pffv);
return NULL;
}
pFontFile->SizeOfThis = cjFontFile;
// Connect GpFontFile's sharing the same hash bucket
pFontFile->SetNext(NULL);
pFontFile->SetPrev(NULL);
// Point family names to appropriate memory
pFontFile->AllocateNameHolders(
(WCHAR **)(
(BYTE *)pFontFile +
offsetof(GpFontFile, aulData) +
cFonts * sizeof(GpFontFace)), cFonts);
// pwszPathname_ points to the Unicode upper case path
// name of the associated font file which is stored at the
// end of the data structure.
pFontFile->pwszPathname_ = (WCHAR *)((BYTE *)pFontFile +
offsetof(GpFontFile, aulData) +
cFonts * sizeof(ULONG_PTR) +
cFonts * sizeof(GpFontFace));
UnicodeStringCopy(pFontFile->pwszPathname_, awcPath);
pFontFile->cwc = cwc; // total for all strings
// state
pFontFile->flState = 0; // state (ready to die?)
pFontFile->cLoaded = 1;
pFontFile->cRealizedFace = 0; // total number of RFONTs
pFontFile->bRemoved = FALSE; // number of referring FontFamily objects
// RFONT list
pFontFile->prfaceList = NULL; // pointer to head of doubly linked list
// driver information
pFontFile->hff = hffNew; // font driver handle to font file, RETURNED by DrvLoadGpFontFile
// identifies the font driver, it could be a printer driver as well
// ULONG ulCheckSum; // checksum info used for UFI's
// fonts in this file (and filename slimed in)
pFontFile->cFonts = cFonts; // number of fonts (same as chpfe)
pFontFile->pfv = pffv; // FILEVIEW structure, passed to DrvLoadFontFile
if (pFontFile->pfv->pwszPath) // not a memory image
{
pFontFile->pfv->pwszPath = pFontFile->pwszPathname_;
}
// loop over pfe's, init the data:
GpFontFace *pfe = (GpFontFace *)pFontFile->aulData;
for (ULONG iFont = 0; iFont < cFonts; iFont++)
{
pfe[iFont].pff = pFontFile; // pointer to physical font file object
pfe[iFont].iFont = iFont + 1; // index of the font for IFI or device, 1 based
pfe[iFont].flPFE = 0; //!!! REVIEW carefully
if ((pfe[iFont].pifi = ttfdQueryFont(hffNew, (iFont + 1), &pfe[iFont].idifi)) == NULL )
{
VERBOSE(("Error setting pifi for entry %d.", iFont));
ttfdSemUnloadFontFile(hffNew);
GpFree(pFontFile);
if (pffv->pwszPath == NULL)
GpFree(pffv->pvView);
GpFree(pffv);
return NULL;
}
pfe[iFont].NumGlyphs = 0;
pfe[iFont].NumGlyphs = pfe[iFont].pifi->cig;
pfe[iFont].cGpFontFamilyRef = 0;
pfe[iFont].lfCharset = DEFAULT_CHARSET;
pfe[iFont].SetSymbol(FALSE);
if (pfe[iFont].InitializeImagerTables() == FALSE)
{
VERBOSE(("Error initializing imager tables for entry %d.", iFont));
ttfdSemUnloadFontFile(hffNew);
GpFree(pFontFile);
if (pffv->pwszPath == NULL)
GpFree(pffv->pvView);
GpFree(pffv);
return NULL;
}
// Set the font family name from the first font entry
pFontFile->SetFamilyName(iFont, ((WCHAR *)(((BYTE*) pfe[iFont].pifi) + pfe[iFont].pifi->dpwszFamilyName)));
}
}
}
if (pFontFile == NULL)
{
if (pffv->pwszPath == NULL)
GpFree(pffv->pvView);
GpFree(pffv);
}
return pFontFile;
}
VOID UnloadFontFile(GpFontFile *pFontFile)
{
return;
}
/******************************Public*Routine******************************\
* bMakePathNameW (PWSZ pwszDst, PWSZ pwszSrc, PWSZ *ppwszFilePart)
*
* Converts the filename pszSrc into a fully qualified pathname pszDst.
* The parameter pszDst must point to a WCHAR buffer at least
* MAX_PATH*sizeof(WCHAR) bytes in size.
*
* An attempt is made find the file first in the new win95 directory
* %windows%\fonts (which also is the first directory in secure font path,
* if one is defined) and then we do the old fashioned windows stuff
* where SearchPathW searches directories in usual order
*
* ppwszFilePart is set to point to the last component of the pathname (i.e.,
* the filename part) in pwszDst. If this is null it is ignored.
*
* Returns:
* TRUE if sucessful, FALSE if an error occurs.
*
* History:
* Mon 02-Oct-1995 -by- Bodin Dresevic [BodinD]
* update: added font path stuff
* 30-Sep-1991 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
extern "C" int __cdecl
HackStrncmp(
const char *str1,
const char *str2,
size_t count
) ;
BOOL MakePathName(
WCHAR *dst, WCHAR *src
)
{
WCHAR* pwszF;
ULONG path_length = 0; // essential to initialize
if (OSInfo::IsNT)
{
// ASSERTGDI(Globals::FontsDir, "gpwcFontsDir not initialized\n");
// if relative path
if ( (src[0] != L'\\') && !((src[1] == L':') && (src[2] == L'\\')) )
{
// find out if the font file is in %windir%\fonts
path_length = SearchPathW(
Globals::FontsDirW,
src,
NULL,
MAX_PATH,
dst,
&pwszF);
#ifdef DEBUG_PATH
TERSE(("SPW1: pwszSrc = %ws", src));
if (path_length)
TERSE(("SPW1: pwszDst = %ws", dst));
#endif // DEBUG_PATH
}
// Search for file using default windows path and return full pathname.
// We will only do so if we did not already find the font in the
// %windir%\fonts directory or if pswzSrc points to the full path
// in which case search path is ignored
if (path_length == 0)
{
path_length = SearchPathW (
NULL,
src,
NULL,
MAX_PATH,
dst,
&pwszF);
#ifdef DEBUG_PATH
TERSE(("SPW2: pwszSrc = %ws", src));
if (path_length)
TERSE(("SPW2: pwszDst = %ws", dst));
#endif // DEBUG_PATH
}
} else {
/* Windows 9x */
CHAR* pwszFA;
CHAR srcA[MAX_PATH];
CHAR dstA[MAX_PATH];
CHAR file_partA[MAX_PATH];
memset(srcA, 0, sizeof(srcA));
memset(dstA, 0, sizeof(dstA));
memset(file_partA, 0, sizeof(file_partA));
WideCharToMultiByte(CP_ACP, 0, src, UnicodeStringLength(src), srcA, MAX_PATH, 0, 0);
// ASSERTGDI(Globals::FontsDir, "gpwcFontsDir not initialized\n");
// if relative path
if ( (srcA[0] != '\\') && !((srcA[1] == ':') && (srcA[2] == '\\')) )
{
// find out if the font file is in %windir%\fonts
path_length = SearchPathA(
Globals::FontsDirA,
srcA,
NULL,
MAX_PATH,
dstA,
(char**)&pwszFA);
}
// Search for file using default windows path and return full pathname.
// We will only do so if we did not already find the font in the
// %windir%\fonts directory or if pswzSrc points to the full path
// in which case search path is ignored
if (path_length == 0)
{
path_length = SearchPathA (
NULL,
srcA,
NULL,
MAX_PATH,
dstA,
&pwszFA);
#ifdef DEBUG_PATH
TERSE(("SPW2: pwszSrc = %ws", src));
if (path_length)
TERSE(("SPW2: pwszDst = %ws", dst));
#endif // DEBUG_PATH
}
MultiByteToWideChar(CP_ACP, 0, dstA, strlen(dstA), dst, MAX_PATH);
dst[path_length] = 0; /* null termination */
}
// If search was successful return TRUE:
return (path_length != 0);
}