Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

255 lines
6.9 KiB

#include <windows.h>
#include "resource.h"
#define countof(a) (sizeof(a)/sizeof((a)[0]))
void InstallFonts(HINSTANCE hInst, LPCTSTR pcszIniPath);
void AddFont(HINSTANCE hInst, LPCTSTR pcszFontName, LPCTSTR pcszFontFile);
BOOL FileExists(LPCSTR lpcszFileName);
LPSTR AddPath(LPSTR lpszPath, LPCSTR lpcszFileName);
LPCSTR GetFileName(LPCSTR lpcszFilePath);
LPSTR FAR ANSIStrRChr(LPCSTR lpStart, WORD wMatch);
__inline BOOL ChrCmpA_inline(WORD w1, WORD wMatch);
int _stdcall ModuleEntry(void)
{
int i;
STARTUPINFO si;
LPSTR pszCmdLine = GetCommandLine();
if ( *pszCmdLine == '\"' ) {
/*
* Scan, and skip over, subsequent characters until
* another double-quote or a null is encountered.
*/
while ( *++pszCmdLine && (*pszCmdLine
!= '\"') );
/*
* If we stopped on a double-quote (usual case), skip
* over it.
*/
if ( *pszCmdLine == '\"' )
pszCmdLine++;
}
else {
while (*pszCmdLine > ' ')
pszCmdLine++;
}
/*
* Skip past any white space preceeding the second token.
*/
while (*pszCmdLine && (*pszCmdLine <= ' ')) {
pszCmdLine++;
}
si.dwFlags = 0;
GetStartupInfoA(&si);
i = WinMain(GetModuleHandle(NULL), NULL, pszCmdLine,
si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
ExitProcess(i);
return i; // We never comes here.
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
TCHAR szIniPath[MAX_PATH];
LPTSTR pszPtr;
TCHAR szTitle[MAX_PATH];
TCHAR szMsg[MAX_PATH];
TCHAR szError[MAX_PATH];
LoadString(hInst, IDS_TITLE, szTitle, countof(szTitle));
*szIniPath = '\0';
GetModuleFileName(NULL, szIniPath, countof(szIniPath));
if (*szIniPath == TEXT('\0'))
{
LoadString(hInst, IDS_INVALID_DIR, szError, countof(szError));
MessageBox(NULL, szError, szTitle, MB_OK | MB_SETFOREGROUND);
return 1;
}
if ((pszPtr = ANSIStrRChr(szIniPath,'\\')) != NULL)
pszPtr++;
else
pszPtr = szIniPath;
lstrcpy(pszPtr, TEXT("ieakfont.ini"));
if (!FileExists(szIniPath))
{
LoadString(hInst, IDS_INVALID_INIFILE, szMsg, countof(szMsg));
wsprintf(szError, szMsg, szIniPath);
MessageBox(NULL, szError, szTitle, MB_OK | MB_SETFOREGROUND);
return 1;
}
InstallFonts(hInst, szIniPath);
return 1;
}
void InstallFonts(HINSTANCE hInst, LPCTSTR pcszIniPath)
{
int nFonts = 0;
TCHAR szFontDir[MAX_PATH];
// get the fonts directory
GetWindowsDirectory(szFontDir, countof(szFontDir));
AddPath(szFontDir, "FONTS");
// get the font filenames to be installed from the ini file
nFonts = GetPrivateProfileInt(TEXT("FONTS"), TEXT("NUMFONTS"), 0, pcszIniPath);
for (int nIndex = 0; nIndex < nFonts; nIndex++)
{
TCHAR szKey[10];
TCHAR szFontStr[MAX_PATH];
wsprintf(szKey, TEXT("FONT%d"), nIndex + 1);
if (GetPrivateProfileString(TEXT("FONTS"), szKey, TEXT(""), szFontStr, countof(szFontStr), pcszIniPath))
{
TCHAR szFontFile[MAX_PATH];
TCHAR szFontName[MAX_PATH];
lstrcpy(szFontFile, szFontDir);
AddPath(szFontFile, szFontStr);
wsprintf(szKey, TEXT("FONTNAME%d"), nIndex + 1);
GetPrivateProfileString(TEXT("FONTS"), szKey, szFontStr, szFontName, countof(szFontName), pcszIniPath);
// REVIEW: (a-saship) by the time this api call happens all parameters are validated and not empty.
// AddFont itself doesn't validate in-parameters.
AddFont(hInst, szFontName, szFontFile);
}
}
}
void AddFont(HINSTANCE hInst, LPCTSTR pcszFontName, LPCTSTR pcszFontFile)
{
TCHAR szTitle[MAX_PATH];
TCHAR szMsg[MAX_PATH];
TCHAR szError[MAX_PATH];
TCHAR szFontFileName[MAX_PATH];
TCHAR szKeyName[MAX_PATH];
HKEY hkFontsKey;
LoadString(hInst, IDS_TITLE, szTitle, countof(szTitle));
lstrcpy(szFontFileName, GetFileName(pcszFontFile));
if (!AddFontResource(pcszFontFile))
{
LoadString(hInst, IDS_ADDFONT_ERROR, szMsg, countof(szMsg));
wsprintf(szError, szMsg, szFontFileName);
MessageBox(NULL, szError, szTitle, MB_OK | MB_SETFOREGROUND);
return;
}
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0L);
// make it permanent by adding it to the registry
if ((GetVersion() & 0x80000000) == 0) // if NT
lstrcpy(szKeyName, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"));
else
lstrcpy(szKeyName, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Fonts"));
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkFontsKey, NULL) == ERROR_SUCCESS)
{
RegSetValueEx(hkFontsKey, pcszFontName, 0, REG_SZ, (CONST BYTE *) szFontFileName, lstrlen(szFontFileName) + 1);
RegCloseKey(hkFontsKey);
}
}
BOOL FileExists(LPCSTR lpcszFileName)
{
DWORD dwAttrib = GetFileAttributes(lpcszFileName);
if (dwAttrib == (DWORD) -1)
return FALSE;
return !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
LPSTR AddPath(LPSTR lpszPath, LPCSTR lpcszFileName)
{
LPSTR lpszPtr;
if (lpszPath == NULL)
return NULL;
lpszPtr = lpszPath + lstrlen(lpszPath);
if (lpszPtr > lpszPath && *CharPrev(lpszPath, lpszPtr) != '\\')
*lpszPtr++ = '\\';
if (lpcszFileName != NULL)
lstrcpy(lpszPtr, lpcszFileName);
else
*lpszPtr = '\0';
return lpszPath;
}
LPCSTR GetFileName(LPCSTR lpcszFilePath)
// Return the name of the file alone from lpcszFilePath
{
LPCSTR lpcszFileName = ANSIStrRChr(lpcszFilePath, '\\');
return (lpcszFileName == NULL ? lpcszFilePath : lpcszFileName + 1);
}
// copied from \\trango\slmadd\src\shell\shlwapi\strings.c
/*
* StrRChr - Find last occurrence of character in string
* Assumes lpStart points to start of null terminated string
* wMatch is the character to match
* returns ptr to the last occurrence of ch in str, NULL if not found.
*/
LPSTR FAR ANSIStrRChr(LPCSTR lpStart, WORD wMatch)
{
LPCSTR lpFound = NULL;
for ( ; *lpStart; lpStart = CharNext(lpStart))
{
// (ChrCmp returns FALSE when characters match)
if (!ChrCmpA_inline(*(UNALIGNED WORD FAR *)lpStart, wMatch))
lpFound = lpStart;
}
return ((LPSTR)lpFound);
}
// copied from \\trango\slmadd\src\shell\shlwapi\strings.c
/*
* ChrCmp - Case sensitive character comparison for DBCS
* Assumes w1, wMatch are characters to be compared
* Return FALSE if they match, TRUE if no match
*/
__inline BOOL ChrCmpA_inline(WORD w1, WORD wMatch)
{
/* Most of the time this won't match, so test it first for speed.
*/
if (LOBYTE(w1) == LOBYTE(wMatch))
{
if (IsDBCSLeadByte(LOBYTE(w1)))
{
return(w1 != wMatch);
}
return FALSE;
}
return TRUE;
}