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.
 
 
 
 
 
 

2823 lines
72 KiB

/** FILE: font3.c ********** Module Header ********************************
*
* Control panel applet for Font configuration. This file holds code for
* the items concerning fonts.
*
* History:
* 12:30 on Tues 23 Apr 1991 -by- Steve Cathcart [stevecat]
* Took base code from Win 3.1 source
* 10:30 on Tues 04 Feb 1992 -by- Steve Cathcart [stevecat]
* Updated code to latest Win 3.1 sources
* 04 April 1994 -by- Steve Cathcart [stevecat]
* Added support for PostScript Type 1 fonts
*
* Copyright (C) 1990-1994 Microsoft Corporation
*
*************************************************************************/
//==========================================================================
// Include files
//==========================================================================
// C Runtime
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
// #include <fcntl.h>
// #include <io.h>
// #include <sys\types.h>
// #include <sys\stat.h>
// Application specific
#include "main.h"
#undef COLOR
#define CONST const
//typedef WCHAR *PWCHAR;
// Windows SDK
#ifdef JAPAN
#include <windows.h>
#endif // JAPAN
#include <wingdip.h> // For private GDI entry point: GetFontResourceInfo()
#include <commdlg.h>
#include <dlgs.h>
#include <shellapi.h>
#include <lzexpand.h>
#include "fontdefs.h"
//==========================================================================
// Local Definitions
//==========================================================================
#define ATTRDIRLIST 0xC010 /* include directories and drives in listbox */
#define ATTRFILELIST 0x0000
#define MAXFILE 20
#define CBEXTMAX 20
#define OF_ERR_FNF 2
#ifdef JAPAN // support install font from *.inf file
#define OEMSETUPINF TEXT("oemsetup.inf")
#define SETUPINF TEXT("setup.inf")
#define OEMSETUPINF_ID 1
#define SETUPINF_ID 2
#define INF_ID_MAX SETUPINF_ID
#define DISKS_SECTION TEXT("[disks]")
#define TRUETYPE_FONT_SECTION TEXT("[TrueType fonts]")
#define OUTLINE_ID TEXT(".outline")
#define BITMAP_ID TEXT(".bitmaps")
#define SOFTWARE_PREFIX TEXT("SOFTWARE\\")
#define SYS_PREFIX TEXT("SYS:")
#define TT_REG_KEY TEXT("Microsoft\\Windows NT\\CurrentVersion\\TrueType Bitmap support section\\Bitmap for ")
#define WIN_INI_KEY TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\win.ini")
#define BITMAP_FOR_KEY TEXT("Bitmap for ")
#define TRUETYPE_WITH_INF 0xc000
#endif // JAPAN
typedef int (*NEXTFONT)(WORD, void *, LPTSTR, LPTSTR, LPTSTR);
struct tagDlgFontInfo
{
INT iMagic;
INT iSize;
HWND hListDesc;
HWND hListFiles;
HWND hDlg;
LPOPENFILENAME lpOfn;
} ;
#define DFI_MAGIC (0x4b4c4243) // KLBC
#define DFI_SIZE (sizeof(struct tagDlgFontInfo)) // Structure size
//==========================================================================
// External Declarations
//==========================================================================
/* data */
extern SHORT nCurSel;
extern HWND hDlgProgress;
extern BOOL bCancelInstall;
extern TCHAR szFontsKey[];
// Registry location for installing PostScript printer font info
extern TCHAR szType1Key[];
/* functions */
extern void InitPSInstall ();
extern BOOL IsTrueType(LPBUFTYPE lpFile);
//==========================================================================
// Local Data Declarations
//==========================================================================
TCHAR szExtSave[CBEXTMAX+1] = TEXT("\0");
#ifdef JAPAN // support install font from *.inf file
BOOL bInstallingFontAtBackground = FALSE;
ATOM *pInfAtomKeyTable[3] = { NULL , NULL , NULL };
typedef struct
{
ATOM AtomDisksNum; // Disk Number atom;
ATOM AtomDisksDir; // Disk directory atom
ATOM AtomDisksDesc; // Disk Description atom;
ATOM AtomDisksId; // Disk Id atom;
} DISKS_INFO;
DISKS_INFO *pInfDisksInfo = NULL;
#endif // JAPAN
TCHAR szTTF[] = TEXT(".TTF");
TCHAR szFON[] = TEXT(".FON"); // Use this now.
TCHAR szPFM[] = TEXT(".PFM");
TCHAR szPFB[] = TEXT(".PFB");
TCHAR szPostScript[] = TEXT("Type 1");
//==========================================================================
// Local Function Prototypes
//==========================================================================
void AddFonts (HWND hwndFontDlg, BOOL bInPlace,
NEXTFONT lpfnNextFont, void *lpData);
VOID vAddDefaultExtension (TCHAR *, TCHAR *);
VOID ConvertExtension (LPTSTR pszFile, LPTSTR szExt);
BOOL IsNewExe (PBUFTYPE pFile);
//==========================================================================
// Functions
//==========================================================================
/////////////////////////////////////////////////////////////////////////////
//
// ConvertExtension
//
// Find the extension on a file and change it to szExt.
//
/////////////////////////////////////////////////////////////////////////////
void ConvertExtension(LPTSTR lpszFile, LPTSTR lpszExt)
{
LPTSTR lpch;
if (!(lpch=_tcsrchr (lpszFile, TEXT('\\'))))
lpch = lpszFile;
if (lpch=_tcschr (lpch, TEXT('.')))
*lpch = TEXT('\0');
lstrcat (lpszFile, lpszExt);
}
/////////////////////////////////////////////////////////////////////////////
//
// IsCompressed
//
// Leave this function as only ANSI because it just checks the header to
// determine if it is a compress file or not.
//
/////////////////////////////////////////////////////////////////////////////
BOOL IsCompressed(LPTSTR szFile)
{
static CHAR szCmpHdr[] = "SZDD\x88\xf0'3";
BOOL bRet = FALSE;
HANDLE fh;
CHAR buf[CharSizeOf(szCmpHdr)];
if ((fh = OpenFileWithShare(szFile, NULL, OF_READ)) == INVALID_HANDLE_VALUE)
return(FALSE);
buf[CharSizeOf(buf)-1] = '\0';
if (MyByteReadFile (fh, buf, CharSizeOf(buf)-1) && !lstrcmpA (buf, szCmpHdr))
bRet = TRUE;
MyCloseFile (fh);
return (bRet);
}
/////////////////////////////////////////////////////////////////////////////
//
// ValidFontFile
//
// in:
// lpszFile file name to validate
// out:
// lpszDesc on succes name of TT file or description from exehdr
// lpiFontType set to a value based on Font type 1 == TT, 2 == Type1
//
// NOTE: Assumes that lpszDesc is of size DESCMAX
//
// returns:
// TRUE success, FALSE failure
//
/////////////////////////////////////////////////////////////////////////////
BOOL ValidFontFile(LPTSTR lpszFile, LPTSTR lpszDesc, int *lpiFontType)
{
BOOL result;
DWORD dwBufSize;
TCHAR strbuf[PATHMAX];
BUFTYPE File;
BOOL bTrueType = FALSE;
*lpszDesc = (TCHAR) 0;
*lpiFontType = NOT_TT_OR_T1;
lstrcpy(File.name, lpszFile);
if (IsTrueType(&File))
{
*lpiFontType = TRUETYPE_FONT;
wsprintf(lpszDesc, TEXT("%s (%s)"), File.desc, szTrueType);
return TRUE;
}
if (IsPSFont (NULL, lpszFile, lpszDesc, NULL, NULL, NULL, lpiFontType))
return TRUE;
result = FALSE;
if (AddFontResource (lpszFile))
{
// See if this is a TrueType font file
dwBufSize = sizeof(BOOL);
GetCurrentDirectory(PATHMAX, strbuf);
BackslashTerm(strbuf);
lstrcat(strbuf, lpszFile);
result = GetFontResourceInfoW (strbuf,
&dwBufSize,
&bTrueType,
GFRI_ISTRUETYPE);
if (bTrueType)
*lpiFontType = TRUETYPE_FONT;
if (result)
{
dwBufSize = DESCMAX;
result = GetFontResourceInfoW (strbuf,
&dwBufSize,
lpszDesc,
GFRI_DESCRIPTION);
if (result && bTrueType)
{
wsprintf(lpszDesc, TEXT("%s (%s)"), (LPTSTR)lpszDesc,
(LPTSTR)szTrueType);
}
}
RemoveFontResource (lpszFile);
}
return (result);
}
/////////////////////////////////////////////////////////////////////////////
//
// UniqueFilename
//
// Guarantee a unique filename in a directory. Do not overwrite existing
// files.
//
/////////////////////////////////////////////////////////////////////////////
BOOL UniqueFilename (LPTSTR lpszDst, LPTSTR lpszSrc, LPTSTR lpszDir)
{
TCHAR szFullPath[PATHMAX];
LPTSTR lpszFile, lpszSrcExt, lpszDstExt;
WORD digit = 0;
lstrcpy (szFullPath, lpszDir);
lstrcpy (lpszFile = BackslashTerm(szFullPath), lpszSrc);
if (!(lpszSrcExt = _tcschr(lpszSrc, TEXT('.'))))
lpszSrcExt = szDot;
if (OpenFileWithShare (szFullPath, NULL, OF_EXIST) == INVALID_HANDLE_VALUE)
goto AllDone;
if (!(lpszDstExt=_tcschr(lpszFile, TEXT('.'))))
lpszDstExt = lpszFile + lstrlen(lpszFile);
while (lpszDstExt-lpszFile < 7)
*lpszDstExt++ = TEXT('_');
do
{
TCHAR szTemp[8];
wsprintf(szTemp, TEXT("%X"), digit++);
if (digit++ > 0x4000)
return (FALSE);
lstrcpy (lpszFile + 8 - lstrlen(szTemp), szTemp);
lstrcat (lpszFile, lpszSrcExt);
}
while (OpenFileWithShare (szFullPath, NULL, OF_EXIST) != INVALID_HANDLE_VALUE);
AllDone:
lstrcpy (lpszDst, lpszFile);
return(TRUE);
}
/////////////////////////////////////////////////////////////////////////////
//
// AddFonts
//
// We now have a callback, so that this function is called before the
// browse dialog is dismissed, so that we don't have to do everything twice
//
// This routine allows for installing the font files from their native
// directory and either copying them to the FONTS dir, or leaving them
// "InPlace".
//
/////////////////////////////////////////////////////////////////////////////
void AddFonts(HWND hwndFontDlg, BOOL bInPlace,
NEXTFONT lpfnNextFont, void *lpData)
{
TCHAR szDesc[DESCMAX];
TCHAR szDir[PATHMAX];
TCHAR szTemp[PATHMAX];
TCHAR szTemp2[PATHMAX];
TCHAR szSrcName[PATHMAX];
TCHAR szDstName[PATHMAX];
LPTSTR lpszDstDir;
BOOL bTrueType;
BOOL bDeletePSEntry;
LPTSTR lpszDstName;
BOOL bThisOneInPlace;
HWND hListFonts;
HWND hAddFonts;
WORD wSrcDirLen, wCount;
WORD wMsg;
int rc;
int iFontType;
int ifType;
int iTotalFonts;
#ifdef JAPAN // support install font from *.inf
int InfId = 0 , PrevInfId = 0;
HANDLE hFile = INVALID_HANDLE_VALUE;
TCHAR szInfPath[PATHMAX];
TUCHAR *pbInf = NULL;
long lFileSize;
#endif // JAPAN
BOOL bInShared = FALSE;
BOOL bFontsInstalled = FALSE;
BOOL bUpdateWinIni;
struct tagDlgFontInfo *lpDlgFontInfo;
LONG lRet;
HKEY hkey;
DWORD dwType;
#ifdef JAPAN
// We are installing font
bInstallingFontAtBackground = TRUE;
#endif // JAPAN
szDir[0] = TEXT('.');
szDir[1] = TEXT('\\');
szDir[2] = TEXT('\0');
wSrcDirLen = 2;
hListFonts = GetDlgItem (hwndFontDlg, LBOX_INSTALLED);
SendMessage (hListFonts, LB_SETSEL, 0, -1L);
BackslashTerm (szSharedDir);
lpDlgFontInfo = (struct tagDlgFontInfo *) lpData;
//
// Set local variables depending on who called AddFonts
//
if ((lpDlgFontInfo->iMagic == DFI_MAGIC) &&
(lpDlgFontInfo->iSize == DFI_SIZE))
{
hAddFonts = lpDlgFontInfo->hDlg;
//
// How many fonts do we have to install?
//
iTotalFonts = SendMessage (lpDlgFontInfo->hListDesc, LB_GETSELCOUNT, 0, 0);
}
else
{
HDROP *phdrop;
phdrop = (HDROP *) lpData;
hAddFonts = hwndFontDlg;
//
// How many fonts do we have to install?
//
iTotalFonts = DragQueryFile (*phdrop, 0xffffffff, NULL, 0);
}
//
// Safeguards against causing Access violations in case bad
// values are returned.
//
if (!IsWindow (hAddFonts))
hAddFonts = hwndFontDlg;
if (!iTotalFonts)
iTotalFonts = 1;
bCancelInstall = FALSE;
//
// Performance optimization - open the "fonts" registry key up
// early and keep it open so "Set" operations are must faster
// than using the "WriteProfileString" apis.
//
lRet = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
szFontsKey,
0,
KEY_READ | KEY_WRITE,
&hkey);
//
// I know "goto" statements are not 'cool' but because of the size
// of the install loops, it is actually easier to maintain this way.
//
if (lRet != ERROR_SUCCESS)
{
MyMessageBox (hwndFontDlg, MYFONT+50, MYFONT+20,
MB_OK | MB_ICONEXCLAMATION, (LPTSTR)NULL);
return;
}
//
// Init Type1 font installation and Progress dialog
//
InitPSInstall ();
InitProgress (hAddFonts);
for (wCount=0; ; ++wCount)
{
//
// Check for user cancellation of installation
//
if (bCancelInstall)
break;
//
// Get next font to install
//
iFontType = (*lpfnNextFont)(wCount, lpData, szDstName,
szSrcName, szDesc);
bTrueType = (iFontType == TRUETYPE_FONT);
bUpdateWinIni = TRUE;
ifType = IF_OTHER;
bDeletePSEntry = FALSE;
//
// Check that a file name was given
//
if (!*szSrcName)
break;
//
// Update the overall progress dialog
//
UpdateProgress (iTotalFonts, wCount+1, wCount * 100 / iTotalFonts);
//
// If they gave us a new dir, then check if it is remote
//
// NOTE: The first call to NextFont routine returns the source
// directory in szDstName. On subsequent calls this is NULL
// and our local szDir string holds the value.
//
if (*szDstName && (BackslashTerm (szDstName), lstrcmp (szDstName, szDir)))
{
lstrcpy (szDir, szDstName);
wSrcDirLen = lstrlen (szDir);
if (bInPlace)
{
switch (GetDriveType (szDir))
{
case DRIVE_REMOTE:
case DRIVE_REMOVABLE:
case DRIVE_CDROM:
case DRIVE_RAMDISK:
if (MyMessageBox (hwndFontDlg, ERRORS+6, INITS+1,
MB_YESNO|MB_ICONEXCLAMATION) != IDYES)
goto NoMoreFonts;
}
}
bInShared = !_tcsicmp (szDir, szSharedDir);
}
CharUpper (szSrcName);
lstrcpy (szDstName, szDir);
lstrcat (szDstName, szSrcName);
if (!*szDesc)
{
//
// Check if its a valid font file
//
if (!ValidFontFile(szDstName, szDesc, &iFontType))
{
bTrueType = (iFontType == TRUETYPE_FONT);
//
// This is an invalid font
//
if (MyMessageBox(hwndFontDlg, bTrueType ? MYFONT+12 : MYFONT+11,
MYFONT+7, MB_OKCANCEL|MB_ICONEXCLAMATION,
(LPTSTR)(*szDesc?szDesc:szSrcName)) == IDCANCEL)
goto NoMoreFonts;
goto NextSelection;
}
}
if ((iFontType == TYPE1_FONT) || (iFontType == TYPE1_FONT_NC))
{
//
// szDstName has the full source file name
//
bThisOneInPlace = bInPlace || bInShared;
if (bThisOneInPlace && !bInShared)
lpszDstDir = szNull;
else
lpszDstDir = szSharedDir;
//
// For installations involving the conversion of the Type1
// font to TrueType:
//
// "szDstName" has the destination name of the
// installed TrueType font file.
// "szDesc" is munged to contain "(TrueType)".
//
switch (InstallT1Font (hAddFonts,
hListFonts, // Installed fonts lbox
!bThisOneInPlace, // Copy TT file?
bInShared, // Files in Shared Dir?
szDstName, // PFM File & Directory
szDesc)) // Font description
{
case TYPE1_INSTALL_TT_AND_MPS:
//
// The PS font was converted to TrueType and a matching
// PostScript font is ALREADY installed.
//
bDeletePSEntry = TRUE;
//
// fall thru....
case TYPE1_INSTALL_TT_AND_PS:
//
// The PS font was converted to TrueType and the matching
// PostScript font was installed.
//
ifType = IF_TYPE1_TT;
//
// fall thru....
case TYPE1_INSTALL_TT_ONLY:
//
//
// The PS font was converted to TrueType and the matching
// PostScript font was NOT installed and a matching PS
// font was NOT found.
//
// Setup variables to finish installation of converted
// TrueType font file.
//
// NOTE: In this case "ifType" already equals IF_OTHER
//
bUpdateWinIni =
bTrueType = TRUE;
//
// Reset install progress for TT version of font
//
ResetProgress ();
Progress2 (0, szDesc);
goto FinishTTInstall;
case TYPE1_INSTALL_PS_AND_MTT:
//
// The PostScript font was installed and we found a matching
// TrueType font that was already installed. All Listbox
// manipulation was done in InstallT1Font routine.
//
// fall thru....
case TYPE1_INSTALL_PS_ONLY:
//
// Only the PostScript font was installed. All Listbox
// manipulation was done in InstallT1Font routine.
//
bUpdateWinIni = FALSE;
goto FinishType1Install;
case TYPE1_INSTALL_IDYES:
case TYPE1_INSTALL_IDOK:
case TYPE1_INSTALL_IDNO:
//
// The font was not installed, but the User wanted to
// continue installation. Continue installation with
// the next font.
//
// The font was not installed due to an error somewhere
// and the User pressed OK in the MessageBox
//
// OR
//
// The User selected NO in the InstallPSDlg routine.
//
bUpdateWinIni = FALSE;
goto NextSelection;
case TYPE1_INSTALL_IDCANCEL:
goto NoMoreFonts;
default:
//
// CANCEL and NOMEM (user already warned)
//
goto NoMoreFonts;
}
//
// On leaving this conditional many variables must be set up
// correctly to proceed with installation of a TrueType font.
//
// szDesc - fontname description for listbox display
// ifType - itemdata to attach to TT lbox entry
// szSrcName - filename of source font
// szDstName - final destination filename
// lpszDstDir - points to destination path string
// bTrueType - TRUE if Type1 file converted to TT
// bUpdateWinIni - FALSE if Type1 file not converted to TT
// and used separatly to determine if [fonts]
// section of win.ini (registry) should be
// updated.
//
}
//
// Start install progress for this font
//
ResetProgress ();
Progress2 (0, szDesc);
#ifdef JAPAN // support install font from *.inf
/*
The routines , if the file is *.inf
Jul.14.1993 -By- Hideyuki Nagase [hideyukn]
*/
if( ( InfId = GetIdFontInf( szSrcName ) ) != 0 )
{
ATOM Atom;
BOOL bRet;
INT iRet;
int ii;
TUCHAR *pbStart , *pbEnd , *pbNow;
TUCHAR szKey[DESCMAX] , szAtom[DESCMAX];
/*
Open and Read *.inf file into memory
*/
if( PrevInfId != InfId )
{
if( hFile != INVALID_HANDLE_VALUE )
CloseInfFile( hFile , pbInf );
hFile = OpenInfFile( szDstName , &pbInf , &lFileSize );
if( hFile == INVALID_HANDLE_VALUE )
{
InfId = 0;
goto NextSelection;
}
}
/*
Make a back up inf path
We need path only , NO need filename
This string should be termed with backslash
*/
lstrcpy( szInfPath , szDstName );
*( _tcsrchr( szInfPath , TEXT('\\') ) + 1 ) = TEXT('\0');
/*
Get Atom table Index
*/
ii = 0x0fff & bTrueType;
/*
Get string that associated this atom
*/
Atom = GetInfAtom( pInfAtomKeyTable[InfId] + ii , szAtom , DESCMAX );
if( Atom == 0 )
goto NextSelection;
/*
Prepare to Build font file
*/
/* Create outline data Section Name */
szKey[0] = TEXT('[');
szKey[1] = TEXT('\0');
lstrcat( szKey , szAtom );
lstrcat( szKey , OUTLINE_ID );
lstrcat( szKey , TEXT("]") );
/* Setup disks infomation */
/*
if *.inf file is different from previous one, we have to re build
disk info table
*/
if( PrevInfId != InfId )
{
int nDisks , ii;
/* Free previous one */
if( pInfDisksInfo != NULL )
FreeInfDisksTable( pInfDisksInfo );
/* Search [disks] section */
pbNow = GetInfSectionPointer( DISKS_SECTION , pbInf , lFileSize );
/* Get the number of this section */
nDisks = GetInfSectionMemberCount( pbNow );
/* Allocate disk info table */
pInfDisksInfo = AllocateInfDisksTable( nDisks );
for( ii = 0 ; ii < nDisks ; ii ++ )
{
TUCHAR szToken[DESCMAX];
/* Get Disk Number */
GetInfLeftValue( pbNow , szToken , DESCMAX );
pInfDisksInfo[ii].AtomDisksNum = AddAtom( szToken );
/* Get directory */
pbNow = GetInfRightValuePointer( pbNow );
pbNow = GetToken( pbNow , szToken , DESCMAX );
pInfDisksInfo[ii].AtomDisksDir = AddAtom( szToken );
/* Get disks description */
pbNow = GetToken( pbNow , szToken , DESCMAX );
pInfDisksInfo[ii].AtomDisksDesc = AddAtom( szToken );
/* Get disks id */
pbNow = GetToken( pbNow , szToken , DESCMAX );
pInfDisksInfo[ii].AtomDisksId = AddAtom( szToken );
/* Move to Next Line */
pbNow = GetNextLineToken( pbNow );
}
}
/* *** Let's install outline data *** */
/*
Search Section
*/
pbNow = GetInfSectionPointer( szKey , pbInf , lFileSize );
if( pbNow == NULL )
goto NextSelection;
/*
Check the member of this section ( outline section data member should be only 1 )
*/
if( GetInfSectionMemberCount( pbNow ) != 1 )
goto NextSelection;
/* Copy file name to szDstName */
lstrcpy( szDstName , szSharedDir );
lpszDstName = szDstName + lstrlen(szDstName);
/* Copy Left value ( left value presents file name after binding */
GetInfLeftValue( pbNow , lpszDstName , PATHMAX - lstrlen(szDstName) );
/* szSrcName should be keep FontFile name ( without path ) */
GetInfLeftValue( pbNow , szSrcName , PATHMAX );
/* Get right value */
pbStart = GetInfRightValuePointer( pbNow );
/*
Install TrueType font
*/
iRet = BuildAndOrCopyFont
(
hwndFontDlg , // Base windows handle
szDstName , // Distination Filename and Path
szInfPath , // Inf file directory ( Def.inst path )
pbStart // File Build Info
);
switch( iRet )
{
case TT_INSTALL_SUCCESS :
goto StartBitmapInstall;
case TT_INSTALL_ALREADY :
goto StartBitmapInstall;
// goto EndBitmapInstall;
case TT_INSTALL_CANCEL :
case TT_INSTALL_FAIL :
default :
goto NextSelection;
}
/* *** Let's install bitmap font data *** */
StartBitmapInstall:
/* Create bitmap data Section Name */
szKey[0] = TEXT('[');
szKey[1] = TEXT('\0');
lstrcat( szKey , szAtom );
lstrcat( szKey , BITMAP_ID );
lstrcat( szKey , TEXT("]") );
/*
Search section
*/
pbNow = GetInfSectionPointer( szKey , pbInf , lFileSize );
/* If bitmap font section is not exit , we need to process following */
if( pbNow == NULL )
goto EndBitmapInstall;
/* Install bitmap font */
bRet = bInstallBitmapFont
(
hwndFontDlg , // Base window handle
szSrcName , // Truetype font file name
szSharedDir , // Distination Install path
szInfPath , // Inf file directory ( def. inst.path )
pbNow // File Build Info
);
if( bRet != TRUE )
{
TUCHAR szString[256];
LoadString( hModule , MYFONT+31 , szString , CharSizeOf(szString) );
if( IDYES
!=
MessageBox( hwndFontDlg , szString , NULL ,
MB_YESNO | MB_ICONEXCLAMATION )
)
{
/* User cancel all font of this installation */
/* Delete font files */
DeleteFile (szDstName); /* Outline font */
DeleteBitmapFont (hwndFontDlg, szDstName, TRUE); /* Bitmap font */
goto NextSelection;
}
else
{
/* User cancel only bitmap font of installation */
DeleteBitmapFont (hwndFontDlg, szDstName, TRUE); /* Bitmap font */
}
}
EndBitmapInstall:
bInPlace = TRUE;
}
#endif // JAPAN
//////////////////////////////////////////////////////////////////////
// Check if font is already loaded on the system
//////////////////////////////////////////////////////////////////////
//
// If the description string from the Font file, exactly matches
// that of one we already have in Win.Ini, the font is already
// installed in the system.
//
lRet = RegQueryValueEx (hkey, szDesc, 0, &dwType, 0, 0);
if (lRet == ERROR_SUCCESS)
{
//
// "Font is already loaded"
//
int iTemp = MyMessageBox (hwndFontDlg,
MYFONT+21,
INITS+1,
MB_OKCANCEL | MB_ICONEXCLAMATION,
(LPTSTR)szDesc);
if (iTemp == IDCANCEL)
goto NoMoreFonts;
goto NextSelection;
}
//////////////////////////////////////////////////////////////////////
// If USER asked us NOT to copy file to "fonts" directory AND it
// is a compressed file, ask them if we should copy it anyway
//////////////////////////////////////////////////////////////////////
if (bThisOneInPlace = bInPlace || bInShared)
{
if (IsCompressed(szDstName))
{
if (bInPlace)
{
//
// "Font is compressed"
//
switch (MyMessageBox(hwndFontDlg, ERRORS+9, INITS+1,
MB_YESNOCANCEL|MB_ICONEXCLAMATION, (LPTSTR)szDesc))
{
case IDCANCEL:
goto NoMoreFonts;
case IDNO:
goto NextSelection;
default:
//
// This is IDYES or NOMEM
//
break;
}
}
bThisOneInPlace = FALSE;
}
}
#ifdef WIN31_WAY
#ifdef NOTTINPLACE
if (bThisOneInPlace && (GetModuleHandle(szSrcName)>=(HANDLE)1 ||
(!bInShared && bTrueType)))
#else
if (bThisOneInPlace && !bTrueType && !bInShared &&
GetModuleHandle(szSrcName)>(HANDLE)1)
#endif
#endif // WIN31_WAY
// NT way - supports TT directly, can't do a GetModuleHandle on TT
// or "compressed" or .fon files
//
// if (bThisOneInPlace && !bTrueType && !bInShared)
//
if (bThisOneInPlace && (iFontType == NOT_TT_OR_T1) && !bInShared)
{
/* BUG: We still need to write win.ini line
*/
if (bInShared)
goto NextSelection;
/* "Cannot use font in place; do you want to install in
* the shared dir?"
*/
bThisOneInPlace = FALSE;
}
//
// szDstName should already have the full source file name
//
if (bThisOneInPlace)
{
if (bTrueType && !bInShared)
{
lpszDstDir = szNull;
}
else
{
lstrcpy(szDstName, szSrcName);
lpszDstDir = szDir;
}
}
else
{
//////////////////////////////////////////////////////////////////
// COPY files to "fonts" directory
//////////////////////////////////////////////////////////////////
LPTSTR pszFiles[2];
/* Let LZ tell us what the name should have been
*/
GetExpandedName (szDstName, szDstName);
lstrcpy (szDstName, szDstName+wSrcDirLen);
// [stevecat] Test code to FORCE the destination filename extension
// 5/27/92 of TrueType files to .TTF for the COPY operation
//
// NOTE: This is because the LZ A algorithm does not correctly restore
// the trailing 'F' char for when the file is uncompressed.
if (bTrueType)
ConvertExtension(szDstName, szTTF);
if (!(UniqueFilename (szDstName, szDstName, szSharedDir)))
{
if (MyMessageBox (hwndFontDlg, MYFONT+19, MYFONT+7,
MB_OKCANCEL | MB_ICONEXCLAMATION, (LPTSTR)szDesc) ==IDCANCEL)
goto NoMoreFonts;
goto NextSelection;
}
lpszDstDir = szSharedDir;
pszFiles[0] = szSrcName;
pszFiles[1] = szDstName;
lstrcpy (szDirOfSrc, szDir);
// Build Destination file pathname
lstrcpy (szTemp2, szDstName);
lstrcpy (szDstName, szSharedDir);
pszFiles[1] = lstrcat (szDstName, szTemp2);
// Build Source file pathname
lstrcpy (szTemp, szSrcName);
lstrcpy (szSrcName, szDir);
pszFiles[0] = lstrcat (szSrcName, szTemp);
if ((rc = Copy (hwndFontDlg, pszFiles[0], pszFiles[1])) <= 0)
{
switch (rc)
{
// On these two return codes, the USER has effectively
// "Cancelled" the copy operation for the fonts
case COPY_CANCEL:
case COPY_DRIVEOPEN:
goto NoMoreFonts;
case COPY_SELF:
wMsg = ERRORS+10;
break;
case COPY_NOCREATE:
wMsg = ERRORS+13;
break;
case COPY_NODISKSPACE:
wMsg = ERRORS+12;
break;
case COPY_NOMEMORY:
wMsg = ERRORS+11;
break;
default:
wMsg = ERRORS+14;
break;
}
if (MyMessageBox (hwndFontDlg, wMsg, INITS+1,
MB_OKCANCEL | MB_ICONEXCLAMATION,
szDstName, szSrcName) == IDCANCEL)
{
goto NoMoreFonts;
}
else
{
goto NextSelection;
}
}
// Reset names to just bare Filenames
lstrcpy (szSrcName, szTemp);
lstrcpy (szDstName, szTemp2);
}
//////////////////////////////////////////////////////////////////////
// If it is a TrueType font, generate a *.FOT file
//////////////////////////////////////////////////////////////////////
FinishTTInstall:
if (bTrueType)
{
HDC hDC;
//
// Update install progress for this font - about half done
// since TrueType file has been copied, if necessary.
//
Progress2 (50, szDesc);
hDC = GetDC (NULL);
lstrcpy(szTemp, szSharedDir);
ConvertExtension(szSrcName, szFOT);
// Special GDI patch ??? - may not be needed by NT WIN GDI
if (*lpszDstDir)
*(BackslashTerm (lpszDstDir)-1) = TEXT('\0');
if (!UniqueFilename (lpszDstName=BackslashTerm(szTemp),
szSrcName, szSharedDir) ||
!CreateScalableFontResource (0, szTemp,
szDstName,
lpszDstDir))
{
ReleaseDC (NULL, hDC);
// Fix directory back with trailing backslash
if (*lpszDstDir)
BackslashTerm (lpszDstDir);
if (!bThisOneInPlace)
{
lstrcpy (szTemp, szSharedDir);
lstrcpy (BackslashTerm (szTemp), szDstName);
DeleteFile (szTemp);
}
if (MyMessageBox (hwndFontDlg,
TTEnabled() ? MYFONT+16 : MYFONT+22,
INITS+1,
MB_OKCANCEL | MB_ICONEXCLAMATION, szDesc)
== IDCANCEL)
goto NoMoreFonts;
goto NextSelection;
}
// Fix directory back with trailing backslash
if (*lpszDstDir)
BackslashTerm (lpszDstDir);
ReleaseDC(NULL, hDC);
}
else
{
lpszDstName = szDstName;
lstrcpy(szTemp, lpszDstDir);
lstrcpy(BackslashTerm(szTemp), szDstName);
}
//////////////////////////////////////////////////////////////////////
// Add the font resource
//////////////////////////////////////////////////////////////////////
if (!AddFontResource(szTemp))
{
ErrorPath:
//
// Delete installed font file(s)
//
if (bTrueType || !bThisOneInPlace)
{
DeleteFile (szTemp);
if (bTrueType && !bThisOneInPlace)
{
lstrcpy (szTemp, szSharedDir);
lstrcpy (BackslashTerm (szTemp), szDstName);
DeleteFile (szTemp);
}
}
//
// Report error adding font resource
//
if (MyMessageBox (hwndFontDlg, MYFONT+19, MYFONT+20,
MB_OKCANCEL | MB_ICONEXCLAMATION,
(LPTSTR)szDesc) == IDCANCEL)
goto NoMoreFonts;
goto NextSelection;
}
//////////////////////////////////////////////////////////////////////
// Write string to win.ini and add font to Parent window listbox
//////////////////////////////////////////////////////////////////////
if (bUpdateWinIni)
{
TCHAR *pwszData = (bInShared || !bInPlace) ? lpszDstName : szTemp;
lRet = RegSetValueEx (hkey, szDesc, 0, REG_SZ, (BYTE*) pwszData,
(DWORD) (sizeof(TCHAR) * (lstrlen(pwszData) + 1)));
if (lRet == ERROR_NOT_ENOUGH_MEMORY)
{
//
// Report registry out of memory error when adding
// fonts to system. Tell user to increase registry
// quota using system applet and then try re-installing
// fonts later (after reboot).
//
MyMessageBox (hwndFontDlg, ERRORS+8, MYFONT+20,
MB_OK | MB_ICONEXCLAMATION,
(LPTSTR)NULL);
goto NoMoreFonts;
}
else if (lRet != ERROR_SUCCESS)
{
//
// For any other error - like FONTS keys being
// write protected, remove font and report error
//
RemoveFontResource (szTemp);
goto ErrorPath;
}
}
//
// Update install progress for this font
//
Progress2 (100, szDesc);
rc = SendMessage (hListFonts, LB_ADDSTRING, 0, (LONG)(LPTSTR)szDesc);
//
// Attach font type to each listed font
//
SendMessage (hListFonts, LB_SETITEMDATA, rc, ifType);
SendMessage (hListFonts, LB_SETSEL, 1, rc);
//
// If a matching PostScript version of the font was found, delete
// the Listbox entry for it since we have just added a TrueType
// entry with type IF_TYPE1_TT for that font.
//
if (bDeletePSEntry)
{
//
// Change font description to have "(PostScript)" now
//
RemoveDecoration (szDesc, TRUE);
wsprintf (szDesc, TEXT("%s (%s)"), szDesc, szPostScript);
rc= SendMessage (hListFonts, LB_FINDSTRINGEXACT, (WPARAM) -1,
(LONG)szDesc);
if (rc != LB_ERR)
SendMessage (hListFonts, LB_DELETESTRING, rc, 0L);
}
UpdateWindow (hListFonts);
FinishType1Install:
bFontsInstalled = TRUE;
NextSelection:
#ifdef JAPAN // support install font from *.inf
/* keep current *.inf id */
PrevInfId = InfId;
#endif // JAPAN
;
}
NoMoreFonts:
RegCloseKey(hkey);
//
// Update the overall progress dialog - show a 100% message
//
UpdateProgress (iTotalFonts, iTotalFonts, 100);
Sleep (1000);
TermProgress ();
TermPSInstall ();
#ifdef JAPAN // support install font from *.inf
/* Close Inf file */
if (hFile != INVALID_HANDLE_VALUE )
CloseInfFile( hFile , pbInf );
/* Delete Font Description atom */
for (InfId = 0 ; InfId < INF_ID_MAX ; InfId ++ )
FreeInfAtomTable( pInfAtomKeyTable[InfId] );
#endif // JAPAN
if (bFontsInstalled)
{
SendWinIniChange (szFonts);
SetDlgItemText (hwndFontDlg, IDOK, pszClose);
nCurSel = -1;
FontSelChange (hwndFontDlg);
}
#ifdef JAPAN
// We done install font
bInstallingFontAtBackground = FALSE;
#endif // JAPAN
}
/////////////////////////////////////////////////////////////////////////////
//
// NextDropFont
//
// drag drop file install. with SHIFT key pressed we do in place.
//
/////////////////////////////////////////////////////////////////////////////
BOOL NextDropFont (WORD wCount, HANDLE *lphDrop,
LPTSTR szDir, LPTSTR szFile, LPTSTR szDesc)
{
LPTSTR lpTemp;
/* Return no file if there is an error; always return no description
*/
*szFile = *szDesc = TEXT('\0');
if (!DragQueryFile (*lphDrop, wCount, szDir, PATHMAX))
return(0);
if (!(lpTemp = _tcsrchr (szDir, TEXT('\\'))))
return(0);
/* Get the file name, and terminate the dir name
*/
++lpTemp;
lstrcpy (szFile, lpTemp);
*lpTemp = TEXT('\0');
/* The return value means nothing since there is no description
*/
return(0);
}
/////////////////////////////////////////////////////////////////////////////
//
// FontsDropped
//
/////////////////////////////////////////////////////////////////////////////
void FontsDropped (HWND hwnd, HANDLE hDrop)
{
AddFonts (hwnd, GetKeyState(VK_SHIFT)<0, (void *) NextDropFont, (void *) &hDrop);
DragFinish (hDrop);
}
/////////////////////////////////////////////////////////////////////////////
//
// FilesToDescs
//
/////////////////////////////////////////////////////////////////////////////
int nFontsToGo = 0;
int nNumFonts;
HWND hWndAddFonts = NULL;
int nSelItem = -1;
VOID FilesToDescs(VOID)
{
int nItem;
TCHAR szFileName[MAXFILE];
TCHAR szDesc[DESCMAX];
// TCHAR szTemp[DESCMAX];
TCHAR szFontsRead[PATHMAX];
int iFontType;
MSG msg;
HWND hListFiles, hListDesc, hStat, hwndAll;
#ifdef JAPAN // support install font from *.inf
int InfId = 0;
// If we are installing font in background,
// We have to avoid enter this routine
if( bInstallingFontAtBackground )
return;
#endif // JAPAN
if (!hWndAddFonts || !nFontsToGo)
return;
hListFiles = GetDlgItem(hWndAddFonts, lst1);
hListDesc = GetDlgItem(hWndAddFonts, ctlLast+1);
hStat = GetDlgItem(hWndAddFonts, ctlLast+3);
hwndAll = GetDlgItem(hWndAddFonts, psh16);
if (nFontsToGo < 0)
{
if (GetFocus()==hListDesc || GetFocus()==hwndAll)
SendMessage(hWndAddFonts, WM_NEXTDLGCTL,
(DWORD) GetDlgItem(hWndAddFonts, lst2), 1L);
EnableWindow(hListDesc, FALSE);
EnableWindow(hwndAll, FALSE);
SendMessage(hListDesc, LB_RESETCONTENT, 0, 0L);
UpdateWindow(hListDesc);
SendMessage(hStat, WM_SETTEXT, 0, (LONG)(LPTSTR)szNull);
if (!(nNumFonts=nFontsToGo=(int)SendMessage(hListFiles, LB_GETCOUNT,
0, 0L)))
goto ThereAreNoFonts;
SendMessage(hListDesc, WM_SETREDRAW, 0, 0L);
}
LoadString (hModule, MYFONT+23, szFontsRead, CharSizeOf(szFontsRead));
/* We want to read at least one
*/
goto ReadNext;
for ( ; nFontsToGo; )
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
return;
ReadNext:
if (SendMessage(hListFiles, LB_GETTEXT, --nFontsToGo,
(LONG)(LPTSTR)szFileName) == LB_ERR)
continue;
wsprintf(szDesc, szFontsRead,
(int)((long)(nNumFonts-nFontsToGo)*100/nNumFonts));
SendMessage(hStat, WM_SETTEXT, 0, (LONG)(LPTSTR)szDesc);
#ifdef JAPAN // support Install font from *.inf
/*
The routines if the file is *.inf
14.Jul.1993 -By- Hideyuki Nagase [hideyukn]
*/
/*
Check the file that is given by File List box is oemsetup.inf or setup.inf
*/
if ( ( InfId = GetIdFontInf(szFileName) ) != 0 )
{
HANDLE hInfFile;
BOOL bRet;
int nFontCount , ii;
long lFileSize;
unsigned short usStatus;
TUCHAR *pbInf = NULL , *pbNow = NULL;
/*
Open *.Inf file and read it to memory
*/
hInfFile = OpenInfFile( szFileName , &pbInf , &lFileSize );
if( hInfFile == INVALID_HANDLE_VALUE )
continue;
/*
Search TrueType font section
*/
pbNow = GetInfSectionPointer( TRUETYPE_FONT_SECTION , pbInf , lFileSize );
if( pbNow == NULL )
{
CloseInfFile( hInfFile , pbInf );
continue;
}
/*
Now bpNow point the top member in specified section
*/
/*
Set number of font in *.inf
*/
nFontCount = GetInfSectionMemberCount( pbNow );
/*
Free old Inf Atoms
*/
FreeInfAtomTable( pInfAtomKeyTable[InfId] );
pInfAtomKeyTable[InfId] = NULL;
/*
Allocate Atom key table
*/
pInfAtomKeyTable[InfId] = AllocateInfAtomTable( nFontCount );
if( pInfAtomKeyTable == NULL ) continue;
/* Read Description */
for( ii = 0 ; ii < nFontCount ; ii ++ )
{
/*
Is current pointer valid ?
*/
if( pbNow == NULL )
break;
/*
Get Description string
*/
bRet = GetInfDescription( pbNow , szDesc , DESCMAX );
if( !bRet )
break;
/*
Send description string to List box
*/
nItem = (int)SendMessage( hListDesc , LB_ADDSTRING , 0 , (LONG)(LPSTR)szDesc );
if( nItem == LB_ERR )
continue;
/*
Send Item data to List box
*/
usStatus = TRUETYPE_WITH_INF | ( 0x0fff & ii );
SendMessage( hListDesc , LB_SETITEMDATA , nItem ,
MAKELONG( nFontsToGo , usStatus ) );
/*
Keep key value ( left value ) into atom table
*/
SetInfAtom( pInfAtomKeyTable[InfId] + ii , pbNow );
/*
Move to Next Line
*/
pbNow = GetNextLineToken( pbNow );
}
/*
Close Inf File
*/
CloseInfFile( hInfFile , pbInf );
}
else
{
#endif // JAPAN
if (!ValidFontFile (szFileName, szDesc, &iFontType) || !szDesc[0])
continue;
if ((nItem = (int)SendMessage (hListDesc, LB_ADDSTRING, 0,
(LONG)szDesc)) == LB_ERR)
continue;
// [stevecat] What is this for?? Double reads of same file? A hack to
// cover-up double processing of same font?
// if ((SendMessage(hListDesc, LB_GETTEXT, nItem-1, (LONG)(LPSTR)szTemp)
// !=LB_ERR && !strcmp(szTemp, szDesc)) ||
// (SendMessage(hListDesc, LB_GETTEXT, nItem+1, (LONG)(LPSTR)szTemp)
// !=LB_ERR && !strcmp(szTemp, szDesc)))
// SendMessage(hListDesc, LB_DELETESTRING, nItem, 0L);
SendMessage(hListDesc, LB_SETITEMDATA, nItem,
MAKELONG(nFontsToGo, iFontType));
#ifdef JAPAN // support Install font from *.inf
}
#endif // JAPAN
}
SendMessage(hStat, WM_SETTEXT, 0, (LONG)(LPTSTR)szNull);
if ((int)SendMessage(hListDesc, LB_GETCOUNT, 0, 0L) > 0)
{
EnableWindow(hListDesc, TRUE);
EnableWindow(hwndAll, TRUE);
}
else
{
ThereAreNoFonts:
LoadString (hModule, MYFONT+29, szFontsRead, CharSizeOf(szFontsRead));
SendMessage (hListDesc, LB_ADDSTRING, 0, (LONG)szFontsRead);
}
SendMessage(hListDesc, WM_SETREDRAW, 1, 0L);
InvalidateRect(hListDesc, NULL, TRUE);
}
/////////////////////////////////////////////////////////////////////////////
//
// NextDlgFont
//
/////////////////////////////////////////////////////////////////////////////
int NextDlgFont (WORD wCount, struct tagDlgFontInfo *lpDlgFontInfo,
LPTSTR szDir, LPTSTR szFile, LPTSTR szDesc)
{
int nSel;
DWORD dwSel;
LPTSTR lpTemp;
/* If we bug out early, then return with no file (meaning the end)
*/
*szDir = *szFile = *szDesc = TEXT('\0');
/* Check that some file is still selected
*/
if (!(WORD)SendMessage(lpDlgFontInfo->hListDesc, LB_GETSELITEMS, 1,
(LONG)(LPTSTR)&nSel))
return(0);
/* Fill in the directory if this is the first time through
*/
if (wCount == 0)
{
lstrcpy(szDir, lpDlgFontInfo->lpOfn->lpstrFile);
if (!(lpTemp = _tcsrchr(szDir, TEXT('\\'))))
return(0);
lpTemp[1] = TEXT('\0');
}
/* Unselect the first selected file, and get its desc, filename,
* and return whether it is truetype
*/
SendMessage (lpDlgFontInfo->hListDesc, LB_SETSEL, 0, (LONG)nSel);
SendMessage (lpDlgFontInfo->hListDesc, LB_GETTEXT, nSel, (LONG)szDesc);
dwSel = SendMessage (lpDlgFontInfo->hListDesc, LB_GETITEMDATA, nSel, 0L);
SendMessage (lpDlgFontInfo->hListFiles, LB_GETTEXT, LOWORD(dwSel),
(LONG)szFile);
return((int)HIWORD(dwSel));
}
/////////////////////////////////////////////////////////////////////////////
//
// FontHookProc
//
// Hooks into common dialog to allow size of selected files to be displayed.
//
/////////////////////////////////////////////////////////////////////////////
BOOL APIENTRY FontHookProc(HWND hDlg, UINT iMessage, WPARAM wParam, LONG lParam)
{
HWND hListFiles, hListDesc;
int nCount;
switch (iMessage)
{
case WM_INITDIALOG:
hWndAddFonts = hDlg;
CheckDlgButton(hDlg, chx2, TRUE);
nFontsToGo = -1;
break;
case WM_DESTROY:
hWndAddFonts = NULL;
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ctlLast+1:
switch (HIWORD(wParam))
{
case LBN_DBLCLK:
PostMessage(hDlg, WM_COMMAND, MAKELONG(IDOK, BN_CLICKED),
(LONG) GetDlgItem(hDlg, IDOK));
break;
case LBN_SELCHANGE:
DescToFiles:
hListFiles = GetDlgItem(hDlg, lst1);
hListDesc = GetDlgItem(hDlg, ctlLast+1);
if (SendMessage(hListDesc, LB_GETSELCOUNT, 0, 0L) > 0)
{
/* Just select the first file if there is any selection
*/
SendMessage(hListDesc, LB_GETSELITEMS, 1,
(LONG)(LPTSTR)&nCount);
nCount = (int)SendMessage(hListDesc, LB_GETITEMDATA,
nCount, 0L);
SendMessage(hListFiles, LB_SETCURSEL, LOWORD(nCount), 0L);
}
else
{
/* Select no files and clear the edit field
*/
SendMessage(hListFiles, LB_SETCURSEL, (WPARAM)(LONG)-1, 0L);
SendDlgItemMessage(hDlg, edt1, WM_SETTEXT, 0,
(LONG)(LPTSTR)szNull);
}
SendMessage(hDlg, WM_COMMAND, MAKELONG(lst1, LBN_SELCHANGE),
(LONG) hListFiles);
}
break;
case psh16: // select all
SendDlgItemMessage(hDlg, ctlLast+1, LB_SETSEL, TRUE, -1L);
goto DescToFiles;
case lst2:
if (HIWORD(wParam) == LBN_DBLCLK)
nFontsToGo = -1;
break;
case cmb2:
switch (HIWORD(wParam))
{
case CBN_DROPDOWN:
nSelItem = (int)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0L);
break;
case CBN_CLOSEUP:
if (nSelItem != (int)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0L))
nFontsToGo = -1;
nSelItem = -1;
break;
case CBN_SELCHANGE:
if (nSelItem == -1)
nFontsToGo = -1;
break;
}
break;
case IDOK:
case IDCANCEL:
case IDABORT:
nFontsToGo = -1;
break;
}
break;
default:
if (iMessage == wBrowseDoneMessage)
{
HWND hFontDlg;
struct tagDlgFontInfo DlgFontInfo;
DlgFontInfo.lpOfn = (LPOPENFILENAME)lParam;
EnableWindow (hFontDlg=DlgFontInfo.lpOfn->hwndOwner, TRUE);
SetFocus (hFontDlg);
DlgFontInfo.hListFiles = GetDlgItem (hDlg, lst1);
DlgFontInfo.hListDesc = GetDlgItem (hDlg, ctlLast+1);
DlgFontInfo.hDlg = hDlg;
DlgFontInfo.iMagic = DFI_MAGIC;
DlgFontInfo.iSize = DFI_SIZE;
//
// This is in NT 3.5 release, but causes a problem with
// returning focus back to Font dialog boxes if a user
// switches apps during installation. So, now I no longer
// hide it.
//
// ShowWindow(hDlg, SW_HIDE);
//
// force buttons to repaint
//
UpdateWindow (hFontDlg);
AddFonts (hFontDlg, !IsDlgButtonChecked (hDlg, chx2),
(void *) NextDlgFont, (void *) &DlgFontInfo);
}
else if (iMessage == wHelpMessage)
{
CPHelp (hDlg);
return TRUE;
}
break;
}
return FALSE; // commdlg, do your thing
}
#ifdef JAPAN // support install font from *.inf file
/*
Support routines for font instollation from inf file
Jul.14.1993 -By- Hideyuki Nagase [hideyukn]
*/
DISKS_INFO *
AllocateInfDisksTable
(
int nCount
)
{
DISKS_INFO *pDisks;
pDisks = LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT , sizeof( DISKS_INFO ) * ( nCount + 1 ) );
return pDisks;
}
void
FreeInfDisksTable
(
DISKS_INFO *pDisks
)
{
DISKS_INFO *pDisksTop = pDisks;
if( pDisks == NULL ) return;
while( pDisks->AtomDisksNum != 0 )
{
DeleteAtom( pDisks->AtomDisksNum );
DeleteAtom( pDisks->AtomDisksDir );
DeleteAtom( pDisks->AtomDisksDesc );
DeleteAtom( pDisks->AtomDisksId );
pDisks ++;
}
LocalFree( pDisksTop );
}
INT
SearchInfDisksAtom
(
DISKS_INFO *pDisks ,
ATOM AtomNum
)
{
DISKS_INFO *pDisksTop = pDisks;
INT ii = 0;
if( pDisks == NULL ) return( -1 );
while( pDisks->AtomDisksNum != 0 )
{
if( pDisks->AtomDisksNum == AtomNum )
return( ii );
pDisks ++;
ii ++;
}
return( -1 );
}
ATOM *
AllocateInfAtomTable
(
int nCount
)
{
ATOM *pAtom;
pAtom = LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT , sizeof( ATOM ) * ( nCount + 1 ) );
return( pAtom );
}
void
FreeInfAtomTable
(
ATOM *pAtom
)
{
if( pAtom == NULL ) return;
while( *pAtom != 0 )
{
DeleteAtom( *pAtom );
pAtom ++;
}
}
int
GetIdFontInf
(
TUCHAR *szFileName
)
{
if( szFileName == NULL ) return 0;
if( lstrcmpi( szFileName , OEMSETUPINF ) == 0 )
return OEMSETUPINF_ID;
if( lstrcmpi( szFileName , SETUPINF ) == 0 )
return SETUPINF_ID;
return 0;
}
HANDLE
OpenInfFile
(
TUCHAR *szFileName ,
TUCHAR **ppbInfData ,
long *plFileSize
)
{
HANDLE hInfFile;
long lFileSize;
TUCHAR *pbInf;
TUCHAR aszInfPath[ MAX_PATH ];
/*
Get the directory where oemsetup.inf is in
*/
if( _tcschr( szFileName , TEXT('\\') ) == NULL )
{
GetCurrentDirectory( MAX_PATH , aszInfPath );
BackslashTerm( aszInfPath );
lstrcat( aszInfPath , szFileName );
}
else
{
lstrcpy( aszInfPath , szFileName );
}
/*
Open it
*/
hInfFile = MyOpenFile( aszInfPath , NULL, OF_READ );
if( hInfFile == INVALID_HANDLE_VALUE )
return INVALID_HANDLE_VALUE;
/*
Get file size
*/
/* Move to EOF */
lFileSize = MyFileSeek( hInfFile , 0L , 2 );
/* Back to top */
MyFileSeek( hInfFile , 0L , 0 );
/*
Allocate memory to keep inf file data
*/
pbInf = LocalAlloc( LMEM_FIXED , ByteCountOf(lFileSize + 2) );
if( pbInf == NULL )
{
MyCloseFile( hInfFile );
return INVALID_HANDLE_VALUE;
}
/*
Read file into memory
*/
MyAnsiReadFile( hInfFile , CP_OEMCP, pbInf , lFileSize );
*(pbInf + lFileSize + 1) = TEXT('\n');
*(pbInf + lFileSize + 2) = TEXT('\0');
/*
Prepare to return
*/
MyCloseFile( hInfFile );
*ppbInfData = pbInf;
*plFileSize = lFileSize;
return( hInfFile );
}
void
CloseInfFile
(
HANDLE hInfFile ,
TUCHAR *pbInfData
)
{
UNREFERENCED_PARAMETER( hInfFile );
if( pbInfData != NULL ) LocalFree( pbInfData );
}
TUCHAR *
SkipWhite
(
TUCHAR *lpch
)
{
if( lpch == NULL ) return( NULL );
for ( ; ; lpch=CharNext(lpch))
{
switch (*lpch)
{
case TEXT(' '):
case TEXT('\t'):
case TEXT('\r'):
case TEXT('\n'):
break;
default:
return(lpch);
}
}
}
TUCHAR *
BackWhite
(
TUCHAR *lpch ,
TUCHAR *lpchTop
)
{
if( lpch == NULL ) return( NULL );
for ( ; ; lpch=CharPrev(lpchTop,lpch))
{
switch (*lpch)
{
case TEXT(' '):
case TEXT('\t'):
case TEXT('\r'):
case TEXT('\n'):
break;
default:
return(lpch);
}
}
}
BOOL
IsSection
(
TUCHAR *lpch
)
{
if( lpch == NULL ) return FALSE;
if( *lpch == TEXT('[') ) return TRUE;
return FALSE;
}
BOOL
IsInfMember
(
TUCHAR *lpch
)
{
TUCHAR *LineEnd;
LineEnd = _tcschr( lpch , TEXT('\n') );
if( LineEnd == NULL ) return( FALSE );
while( lpch <= LineEnd )
if( *lpch++ == TEXT('=') ) return( TRUE );
return( FALSE );
}
TUCHAR *
GoNextLine
(
TUCHAR *lpch
)
{
return( _tcschr( lpch , TEXT('\n') ) );
}
TUCHAR *
GetNextLineToken
(
TUCHAR *lpch
)
{
lpch = GoNextLine( lpch );
if( lpch != NULL )
lpch = SkipWhite( lpch );
return lpch;
}
TUCHAR *
GetInfRightValuePointer
(
TUCHAR *lpch
)
{
lpch = _tcschr( lpch , TEXT('=') );
lpch ++;
return( SkipWhite( lpch ) );
}
TUCHAR *
GetInfLeftValue
(
TUCHAR *lpch ,
TUCHAR *szBuffer ,
int limit
)
{
TUCHAR *lpchTop = lpch;
lpch = _tcschr( lpch , TEXT('=') );
lpch --;
lpch = BackWhite( lpch , lpchTop );
while( lpchTop <= lpch && --limit )
*szBuffer ++ = *lpchTop ++;
*szBuffer = TEXT('\0');
return( lpch );
}
TUCHAR *
GetToken
(
TUCHAR *lpchTop ,
TUCHAR *lpBuffer ,
int iBufferSize
)
{
TUCHAR *lpch;
lpch = SkipWhite( lpchTop );
while( iBufferSize )
{
switch( *lpch )
{
// case TEXT(' ') :
case TEXT(':') :
case TEXT('=') :
case TEXT(',') :
case TEXT('\t') :
case TEXT('\r') :
case TEXT('\n') :
*lpBuffer = TEXT('\0');
lpch++;
return( lpch );
case TEXT('"') :
++lpch;
while( *lpch != TEXT('"') && *lpch != TEXT('\n') &&
*lpch != TEXT('\r') && *lpch != TEXT('\0') && --iBufferSize )
{
*lpBuffer ++ = *lpch ++;
}
lpch ++;
break;
default :
if( *lpch != TEXT(' ') )
{
*lpBuffer ++ = *lpch;
--iBufferSize;
}
lpch ++;
}
}
}
TUCHAR *
GetInfSectionPointer
(
TUCHAR *SectionName ,
TUCHAR *InfData ,
long lInfDataSize
)
{
TUCHAR *SectionFind;
TUCHAR *SectionTop;
SectionFind = _tcsstr( InfData , SectionName );
if( SectionFind == NULL ) return NULL;
SectionTop = GetNextLineToken( SectionFind );
return SectionTop;
}
int
GetInfSectionMemberCount
(
TUCHAR *SectionTopMember
)
{
int nCount = 0;
TUCHAR *lpch = SectionTopMember;
while( lpch != NULL && IsInfMember( lpch ) )
{
nCount ++;
lpch = GetNextLineToken( lpch );
}
return( nCount );
}
BOOL
GetInfDescription
(
TUCHAR *pbNow ,
TUCHAR *szBuffer ,
long limit
)
{
pbNow = GetInfRightValuePointer( pbNow );
if( *pbNow != TEXT('"') ) return FALSE;
GetToken( pbNow , szBuffer , limit );
return TRUE;
}
void
SetInfAtom
(
ATOM *pInfAtom ,
TUCHAR *ValueTop
)
{
TUCHAR szKey[DESCMAX];
GetToken( ValueTop , szKey , DESCMAX );
*pInfAtom = AddAtom( szKey );
}
ATOM
GetInfAtom
(
ATOM *pInfAtom ,
TUCHAR *szBuffer ,
int iBufferSize
)
{
return( GetAtomName( *pInfAtom , szBuffer , iBufferSize ) );
}
BOOL
GetInstallFontPath
(
HWND hDlg ,
TUCHAR *DiskNum ,
TUCHAR *szTempFile ,
TUCHAR *szFileName
)
{
TUCHAR szText[256];
TUCHAR szDesc[DESCMAX];
ATOM AtomNum;
int ii;
AtomNum = FindAtom( DiskNum );
ii = SearchInfDisksAtom( pInfDisksInfo , AtomNum );
if( ii == -1 ) return ( FALSE );
GetAtomName( pInfDisksInfo[ii].AtomDisksDesc , szDesc , DESCMAX );
/* Propably szTempFile pointed file name, we need only path */
*( _tcsrchr( szTempFile , TEXT('\\') ) ) = TEXT('\0');
return( OpenInstallFontDialog( hDlg , szDesc , szFileName , szTempFile ) );
}
#define TT_INSTALL_SUCCESS 0x01
#define TT_INSTALL_FAIL 0x02
#define TT_INSTALL_ALREADY 0x03
#define TT_INSTALL_CANCEL 0x04
INT
BuildAndOrCopyFont
(
HWND hDlg ,
TUCHAR *szDstName , // Distination Filename and Path
TUCHAR *szInfPath , // Inf file path
TUCHAR *pbStart , // File Build Info
)
{
HANDLE hFile , hFileMaster;
TUCHAR szTempFile[ MAX_PATH ];
int ii;
/*
At first, Check we have builded file , or Not.
*/
hFileMaster = MyOpenFile( szDstName , NULL, OF_READ );
/* If exist , we return with TRUE */
if( hFileMaster != INVALID_HANDLE_VALUE )
{
MyCloseFile( hFileMaster );
return( TT_INSTALL_ALREADY );
}
/* Create Distination File */
hFileMaster = MyOpenFile( szDstName , NULL, OF_CREATE );
if( hFileMaster == INVALID_HANDLE_VALUE )
return( TT_INSTALL_FAIL );
/* We Build up distination file path according to information in inf */
/* Set default install path */
lstrcpy( szTempFile , szInfPath );
/* Build File */
for( ; ; )
{
TUCHAR DisksId[DESCMAX];
TUCHAR DisksFile[MAX_PATH];
TUCHAR *ExpandedData;
long lLzFileSize;
if( pbStart == NULL || *pbStart == TEXT('\n') || *pbStart == TEXT('\r') )
break;
/* Get Disks Id and Source filename */
pbStart = GetToken( pbStart , DisksId , DESCMAX );
pbStart = GetToken( pbStart , DisksFile , MAX_PATH );
/* Build install file path */
lstrcat( szTempFile , DisksFile );
/* open it */
while( ( hFile = MyOpenFile( szTempFile , NULL, OF_READ ) ) == INVALID_HANDLE_VALUE )
{
if( GetInstallFontPath( hDlg , DisksId , szTempFile , DisksFile ) == FALSE )
{
MyCloseFile( hFileMaster );
DeleteFile( szDstName );
return( TT_INSTALL_CANCEL );
}
if( szTempFile[lstrlen(szTempFile) - 1] != TEXT('\\') )
{
lstrcat( szTempFile , TEXT("\\") );
}
lstrcat( szTempFile , DisksFile );
/* Update background rect in install dlg of insert disk dlg */
UpdateWindow( GetParent( hDlg ) );
UpdateWindow( hDlg );
HourGlass( TRUE );
}
/* Get file size */
lLzFileSize = MyFileSeek( hFile , 0 , 2 );
MyFileSeek( hFile , 0 , 0 );
/* Allocate memory to keep file data */
ExpandedData = LocalAlloc( LMEM_FIXED , ByteCountOf(lLzFileSize) );
if( ExpandedData == NULL ) return( TT_INSTALL_FAIL );
/* Read the data and write down it to file */
MyByteReadFile( hFile , (LPVOID) ExpandedData , lLzFileSize );
MyByteWriteFile( hFileMaster , (LPVOID) ExpandedData , lLzFileSize );
LocalFree( ExpandedData );
MyCloseFile( hFile );
/* Cut file name , we need only path nexttime */
*( _tcsrchr( szTempFile , TEXT('\\') ) + 1 ) = TEXT('\0');
}
MyCloseFile( hFileMaster );
return( TT_INSTALL_SUCCESS );
}
BOOL
bInstallBitmapFont
(
HWND hDlg ,
TUCHAR *szTTFont ,
TUCHAR *szDstPath ,
TUCHAR *szInfPath ,
TUCHAR *pbSectionTop
)
{
HKEY hKey , hKeyMap;
INT nBitmapFont;
INT iRet;
DWORD dwRet;
TUCHAR *pbInf = pbSectionTop;
TUCHAR *pbNow;
TUCHAR szKey[ MAX_PATH ];
TUCHAR szSrcFont[ MAX_PATH ];
TUCHAR szDstFont[ MAX_PATH ];
TUCHAR szToken[ MAX_PATH ];
TUCHAR char szData[ MAX_PATH ];
lstrcpy( szSrcFont , szInfPath );
lstrcpy( szDstFont , szDstPath );
/*
Compute the member count in this bitmap section
*/
nBitmapFont = GetInfSectionMemberCount( pbSectionTop );
/*
At least, Bitmap font section has to have 2 member.
One font and "Mode=" description
*/
if( nBitmapFont < 2 )
return( FALSE );
/* Create Ini file mapping */
lstrcpy( szKey , BITMAP_FOR_KEY );
lstrcat( szKey , szTTFont );
lstrcpy( szData , SYS_PREFIX );
lstrcat( szData , TT_REG_KEY );
lstrcat( szData , szTTFont );
RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
WIN_INI_KEY ,
0 ,
KEY_ALL_ACCESS ,
&hKeyMap
);
RegSetValueEx( hKeyMap ,
szKey ,
0 ,
REG_SZ ,
szData ,
ByteCountOf(lstrlen(szData) + 1)
);
RegCloseKey( hKeyMap );
/* Create key */
lstrcpy( szKey , SOFTWARE_PREFIX );
lstrcat( szKey , TT_REG_KEY );
lstrcat( szKey , szTTFont );
RegCreateKeyEx( HKEY_LOCAL_MACHINE ,
szKey ,
0 ,
NULL ,
0 ,
KEY_ALL_ACCESS ,
NULL ,
&hKey ,
&dwRet
);
/* Install bitmap font */
while( nBitmapFont-- )
{
pbNow = pbInf;
/* Get distination font file name */
pbNow = GetInfLeftValue( pbNow , szToken , MAX_PATH );
pbNow = GetInfRightValuePointer( pbNow );
/* Check the key is "Mode" ? */
if( lstrcmpi( szToken , TEXT("Mode") ) == 0 )
{
pbNow = GetToken( pbNow , szData , MAX_PATH );
/* Write Mode information into registry */
RegSetValueEx( hKey ,
szToken ,
0 ,
REG_SZ ,
szData ,
ByteCountOf(lstrlen(szData) + 1)
);
/* Move to Next Line for next loop */
pbInf = GetNextLineToken( pbInf );
continue;
}
/* Build path */
lstrcat( szDstFont , szToken );
/* Get font size */
pbNow = GetToken( pbNow , szData , MAX_PATH );
/* Now , pbNow point the information of Build font file */
iRet = BuildAndOrCopyFont
(
hDlg ,
szDstFont ,
szSrcFont ,
pbNow
);
switch( iRet )
{
case TT_INSTALL_SUCCESS :
case TT_INSTALL_ALREADY :
{
/* Write registry */
RegSetValueEx( hKey ,
szData ,
0 ,
REG_SZ ,
szToken ,
ByteCountOf(lstrlen(szToken) + 1)
);
break;
}
case TT_INSTALL_FAIL :
case TT_INSTALL_CANCEL :
goto ErrorExit;
}
/* Init DstPath for Next loop */
*( _tcsrchr( szDstFont , TEXT('\\') ) + 1 ) = TEXT('\0');
/* Move to Pointer for Next loop */
pbInf = GetNextLineToken( pbInf );
}
RegCloseKey( hKey );
return( TRUE );
ErrorExit:
RegCloseKey( hKey );
return( FALSE );
}
VOID
DeleteBitmapFont
(
HWND hDlg ,
TUCHAR *szPathAndName ,
BOOL bErase
)
{
HKEY hKey;
LONG lRet;
TUCHAR *szNow;
TUCHAR szPath[ MAX_PATH ];
TUCHAR szFile[ MAX_PATH ];
TUCHAR szKey[ MAX_PATH ];
TUCHAR szValue[ MAX_PATH ];
TUCHAR szData[ MAX_PATH ];
DWORD dwValue , dwData , dwType;
DWORD dwIndex;
lstrcpy( szPath , szPathAndName );
szNow = _tcsrchr( szPath , TEXT('\\') );
if( szNow == NULL ) return;
/* keep TT font file name */
lstrcpy( szFile , szNow + 1 );
/* Cut file name */
*( szNow + 1 ) = TEXT('\0');
/* We have to remove the data in registry and delete file */
/* *** delete mapping data *** */
/* Create value name */
lstrcpy( szValue , BITMAP_FOR_KEY );
lstrcat( szValue , szFile );
RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
WIN_INI_KEY ,
0 ,
KEY_ALL_ACCESS ,
&hKey
);
/* If this key is not exist, bitmap font was not installed , yet */
if (hKey != ERROR_SUCCESS)
return;
RegDeleteValue( hKey ,
szValue
);
RegCloseKey( hKey );
/* *** delete bitmap support data *** */
/* Create key name */
lstrcpy( szKey , SOFTWARE_PREFIX );
lstrcat( szKey , TT_REG_KEY );
lstrcat( szKey , szFile );
RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
szKey ,
0 ,
KEY_ALL_ACCESS ,
&hKey
);
/* If this key does not exist, bitmap font was not installed yet */
if (hKey != ERROR_SUCCESS)
return;
/* Init for loop */
dwIndex = 0;
/* Enum Registry value */
dwValue = MAX_PATH;
dwData = MAX_PATH;
lRet = RegEnumValue( hKey ,
dwIndex ,
szValue ,
&dwValue ,
0 ,
&dwType ,
szData ,
&dwData
);
while( lRet == ERROR_SUCCESS )
{
/* Check this value is Mode or not */
if( bErase && lstrcmpi( szValue , TEXT("Mode") ) != 0 )
{
/* if it not "Mode" , Delete bitmap font file */
/* Build path */
lstrcat( szPath , szData );
/* Delete file */
DeleteFile( szPath );
/* Cut file name from path */
*( _tcsrchr( szPath , TEXT('\\') ) + 1 ) = TEXT('\0');
}
dwIndex ++;
dwValue = MAX_PATH;
dwData = MAX_PATH;
lRet = RegEnumValue( hKey ,
dwIndex ,
szValue ,
&dwValue ,
0 ,
&dwType ,
szData ,
&dwData
);
}
RegCloseKey( hKey );
/* *** Delete registey key *** */
RegDeleteKey( HKEY_LOCAL_MACHINE ,
szKey
);
}
#endif // JAPAN