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.

846 lines
24 KiB

  1. /***************************************************************************
  2. * MODULE: FontReg.c
  3. *
  4. * PURPOSE: This module does a very simple thing: Moves font information
  5. * from the [fonts] section of the WIN.INI into the registry.
  6. *
  7. * 1) If a font is in the \windows\system directory, it is moved
  8. * to \windows\fonts. (If it is already in the fonts directory
  9. * it is just left there.)
  10. *
  11. * 2) The information is written into the Registry at:
  12. * HKLM\Software\Microsoft\Windows\CurrentVersion\Fonts
  13. *
  14. * 3) The entry i removed from WIN.INI
  15. *
  16. *
  17. * NOTE: This program has NOT been checked in a DBCS environment.
  18. * Somethings will need to be changed, most notibly, checking for
  19. * a backslash in a path name.
  20. *
  21. *
  22. * REVISION LOG:
  23. * 10/17/94 Initial revision. Eric Robinson, ElseWare Corporation.
  24. * eric@elseware.com.
  25. *
  26. *
  27. ***************************************************************************/
  28. ////#include <windows.h>
  29. #include <excpt.h> // From windows.h.
  30. #include <stdarg.h>
  31. #include <windef.h>
  32. #include <winbase.h>
  33. #include <wingdi.h>
  34. #include <winuser.h>
  35. #include <winnls.h>
  36. #include <winreg.h>
  37. #include "ttf.h"
  38. HKEY hKeyFonts;
  39. char szWindowsDir[MAX_PATH];
  40. char szSystemDir[MAX_PATH];
  41. char szSharedDir[MAX_PATH];
  42. char szFontsDir[MAX_PATH];
  43. BOOL bNetworkInstall;
  44. BYTE Buffer[2048];
  45. typedef struct
  46. {
  47. DWORD dwVersion;
  48. DWORD dwFlags;
  49. UINT uDriveType;
  50. char *pszFilePart;
  51. char szIniName[MAX_PATH];
  52. char szFullPath[MAX_PATH];
  53. } FILEDETAILS, *PFILEDETAILS;
  54. //*****************************************************************************
  55. //************************** D P R I N T F ********************************
  56. //*****************************************************************************
  57. #ifdef DEBUG //************ DEBUG **************
  58. void msgprintf( LPCSTR pszMsg, ... )
  59. {
  60. char ach[256];
  61. wvsprintf(ach, pszMsg, ((char *)&pszMsg + sizeof(char *)));
  62. OutputDebugString(ach);
  63. }
  64. #define dprintf( args ) msgprintf args
  65. #else //*********** RETAIL *************
  66. #define dprintf( args )
  67. #endif
  68. //*****************************************************************************
  69. //****************** A P P E N D F I L E N A M E **********************
  70. //*****************************************************************************
  71. void AppendFileName( PSZ pszPath, PSZ pszFile )
  72. {
  73. int cbPath;
  74. cbPath = lstrlen(pszPath);
  75. if( pszPath[cbPath-1] != '\\' ) pszPath[cbPath++] = '\\';
  76. lstrcpy( pszPath+cbPath, pszFile );
  77. }
  78. //*****************************************************************************
  79. //************************* O P E N K E Y *******************************
  80. //*****************************************************************************
  81. #define szCurrentVersion "Software\\Microsoft\\Windows\\CurrentVersion"
  82. HKEY OpenKey( char *pszKey )
  83. {
  84. HKEY hKey;
  85. LONG lrc;
  86. DWORD dwBogus;
  87. char szSubKey[256];
  88. lstrcpy( szSubKey, szCurrentVersion );
  89. lstrcat( szSubKey, pszKey );
  90. dprintf(( " RegCreateKeyEx('%s')\n", szSubKey ));
  91. lrc = RegCreateKeyEx( HKEY_LOCAL_MACHINE, // hKey
  92. szSubKey, // lpszSubKey
  93. 0L, // dwReserved
  94. NULL, // lpszClass
  95. REG_OPTION_NON_VOLATILE, // fdwOptions
  96. KEY_ALL_ACCESS, // samDesired
  97. NULL, // lpSecurityAttributes
  98. &hKey, // phkResult
  99. &dwBogus ); // pdwDisposition
  100. if( lrc != ERROR_SUCCESS )
  101. {
  102. hKey = NULL;
  103. dprintf(( " Couldn't open registry key '%s'\n", szSubKey ));
  104. }
  105. return hKey;
  106. }
  107. //*****************************************************************************
  108. //**************** G E T F O N T S D I R E C T O R Y ******************
  109. //*****************************************************************************
  110. void GetFontsDirectory( void )
  111. {
  112. HKEY hKey;
  113. LONG lrc = ERROR_SUCCESS+1;
  114. DWORD cbShared;
  115. dprintf(( "Getting shared directory string from registry\r\n" ));
  116. hKey = OpenKey( "\\Setup" );
  117. if( hKey )
  118. {
  119. cbShared = MAX_PATH;
  120. lrc = RegQueryValueEx( hKey, // hKey
  121. "SharedDir", // lpszValueName
  122. NULL, // lpdwReserved
  123. NULL, // lpdwType
  124. szSharedDir, // lpbData
  125. &cbShared ); // lpcbData
  126. RegCloseKey( hKey );
  127. }
  128. if( lrc != ERROR_SUCCESS )
  129. {
  130. dprintf(( "RegQueryValue( SharedDir ) failed! Error = %d\r\n", lrc ));
  131. dprintf(( " Using path from GetWindowsDirectory\r\n" ));
  132. lstrcpy( szSharedDir, szWindowsDir );
  133. }
  134. dprintf(( " szSharedDir = '%s'\r\n", szSharedDir ));
  135. lstrcpy( szFontsDir, szSharedDir );
  136. AppendFileName( szFontsDir, "fonts" );
  137. dprintf(( " szFontsDir = '%s'\r\n", szFontsDir ));
  138. }
  139. //*****************************************************************************
  140. //************************* G E T D I R S *******************************
  141. //*****************************************************************************
  142. void GetDirs( void )
  143. {
  144. GetWindowsDirectory( szWindowsDir, MAX_PATH );
  145. GetSystemDirectory( szSystemDir, MAX_PATH );
  146. GetFontsDirectory();
  147. bNetworkInstall = (lstrcmpi( szSharedDir, szWindowsDir ) != 0);
  148. dprintf(( "GetDirs\r\n" ));
  149. dprintf(( " szWindowsDir = '%s'\r\n", szWindowsDir ));
  150. dprintf(( " szSystemDir = '%s'\r\n", szSystemDir ));
  151. dprintf(( " szSharedDir = '%s'\r\n", szSharedDir ));
  152. dprintf(( " szFontsDir = '%s'\r\n", szFontsDir ));
  153. dprintf(( " bNetworkInstall = %d\r\n", bNetworkInstall ));
  154. }
  155. //*****************************************************************************
  156. //******************** F I N D F O N T F I L E ************************
  157. //*****************************************************************************
  158. #define MODE_WIN31 1
  159. #define MODE_WIN95 2
  160. PSZ FindFontFile( PSZ pszFile, PSZ pszFullPath, DWORD dwMode )
  161. {
  162. DWORD dwrc;
  163. PSTR pszFilePart;
  164. dprintf(( "FindFontFile\r\n" ));
  165. pszFilePart = NULL;
  166. // Search fonts directory first if in win95 mode
  167. if( dwMode == MODE_WIN95 )
  168. {
  169. dprintf(( "Calling SearchPath( %s, %s )\r\n", szFontsDir, pszFile ));
  170. dwrc = SearchPath( szFontsDir, // Path to search for file
  171. pszFile, // Filename to search for
  172. NULL, // No extension
  173. MAX_PATH, // Size of output buffer
  174. pszFullPath, // Output buffer
  175. &pszFilePart ); // & of filename pointer
  176. dprintf(( " dwrc = %u\n", dwrc ));
  177. if( dwrc ) goto FFFReturn;
  178. }
  179. // Search win31 style
  180. dprintf(( "Calling SearchPath( NULL, %s )\r\n", pszFile ));
  181. dwrc = SearchPath( NULL, // Path to search for file
  182. pszFile, // Filename to search for
  183. NULL, // No extension
  184. MAX_PATH, // Size of output buffer
  185. pszFullPath, // Output buffer
  186. &pszFilePart ); // & of filename pointer
  187. dprintf(( " dwrc = %u\r\n", dwrc ));
  188. // If not found and in win31 mode, search in fonts folder
  189. if( !dwrc && dwMode == MODE_WIN31 )
  190. {
  191. dprintf(( "Calling SearchPath( %s, %s )\r\n", szFontsDir, pszFile ));
  192. dwrc = SearchPath( szFontsDir, // Path to search for file
  193. pszFile, // Filename to search for
  194. NULL, // No extension
  195. MAX_PATH, // Size of output buffer
  196. pszFullPath, // Output buffer
  197. &pszFilePart ); // & of filename pointer
  198. dprintf(( " dwrc = %u\n", dwrc ));
  199. }
  200. FFFReturn:
  201. return pszFilePart;
  202. }
  203. //*****************************************************************************
  204. //******************* G E T F I L E D E T A I L S *********************
  205. //*****************************************************************************
  206. #define IN_SYSTEM 0x0001
  207. #define IN_WINDOWS 0x0002
  208. #define IN_SHARED 0x0004
  209. #define IN_FONTS 0x0008
  210. #define IN_OTHER 0x0010
  211. #define FON_FILE 0x0100
  212. #define FOT_FILE 0x0200
  213. #define TTF_FILE 0x0400
  214. #define SZT2BANNER "This is a TrueType font, not a program.\r\r\n$"
  215. BOOL GetFileDetails( PSTR pszIniFile, PFILEDETAILS pfd, DWORD dwMode )
  216. {
  217. HANDLE hFile;
  218. char szDir[MAX_PATH];
  219. //----------------------- Crunch source filename ----------------------------
  220. pfd->dwFlags = 0;
  221. pfd->uDriveType = 0;
  222. pfd->dwVersion = 0;
  223. lstrcpy( pfd->szIniName, pszIniFile );
  224. dprintf(( "GetFileDetails\r\n" ));
  225. dprintf(( " pszIniFile = '%s'\r\n", pszIniFile ));
  226. dprintf(( " dwMode = 0x%.8lX\r\n", dwMode ));
  227. pfd->pszFilePart = FindFontFile( pszIniFile, pfd->szFullPath, dwMode );
  228. if( !pfd->pszFilePart )
  229. {
  230. dprintf(( " Couldn't find file\r\n" ));
  231. return FALSE;
  232. }
  233. dprintf(( " szFullPath = '%s'\r\n", pfd->szFullPath ));
  234. dprintf(( " pszFilePart = '%s'\r\n", pfd->pszFilePart ));
  235. //------------------ Figure out which directory its in ----------------------
  236. lstrcpy( szDir, pfd->szFullPath );
  237. szDir[pfd->pszFilePart-pfd->szFullPath-1] = '\0';
  238. dprintf(( " szDir = '%s'\r\n", szDir ));
  239. if( !lstrcmpi(szSystemDir,szDir) )
  240. pfd->dwFlags |= IN_SYSTEM;
  241. else if( !lstrcmpi(szWindowsDir,szDir) )
  242. pfd->dwFlags |= IN_WINDOWS;
  243. else if( !lstrcmpi(szSharedDir,szDir) )
  244. pfd->dwFlags |= IN_SHARED;
  245. else if( !lstrcmpi(szFontsDir,szDir) )
  246. pfd->dwFlags |= IN_FONTS;
  247. if( szDir[0] != '\\' )
  248. {
  249. szDir[3] = 0;
  250. dprintf(( "GetDriveType( %s )\r\n", szDir ));
  251. pfd->uDriveType = GetDriveType( szDir );
  252. }
  253. else
  254. pfd->uDriveType = DRIVE_REMOTE;
  255. dprintf(( " uDriveType = %d\r\n", pfd->uDriveType ));
  256. //----------------- Read in first chunk for examination ---------------------
  257. hFile = CreateFile( pfd->szFullPath,
  258. GENERIC_READ,
  259. FILE_SHARE_READ,
  260. NULL,
  261. OPEN_EXISTING,
  262. FILE_ATTRIBUTE_NORMAL,
  263. NULL );
  264. if( hFile != INVALID_HANDLE_VALUE )
  265. {
  266. DWORD dwRead;
  267. if( ReadFile( hFile, Buffer, sizeof(Buffer), &dwRead, NULL ) )
  268. {
  269. if( lstrcmp( &Buffer[78], SZT2BANNER ) == 0 ) // FOT check
  270. {
  271. dprintf(( " FOT file\r\n" ));
  272. pfd->dwFlags |= FOT_FILE;
  273. }
  274. else if( *(WORD *)&Buffer[0] == 0x5A4D ) // FON check
  275. {
  276. dprintf(( " FON file\r\n" ));
  277. pfd->dwFlags |= FON_FILE;
  278. }
  279. else // TTF check
  280. {
  281. int i, nOffsets;
  282. sfnt_OffsetTablePtr pOffsetTable;
  283. sfnt_DirectoryEntryPtr pDirEntry;
  284. sfnt_FontHeader FontHeader;
  285. dprintf(( " Checking for TTF file\r\n" ));
  286. pOffsetTable = (sfnt_OffsetTablePtr)Buffer;
  287. nOffsets = (int)SWAPW(pOffsetTable->numOffsets);
  288. dprintf(( " Version = 0x%.8X\r\n", SWAPL(pOffsetTable->version) ));
  289. dprintf(( " numOffsets = %d\r\n", nOffsets ));
  290. if( nOffsets < sizeof(Buffer)/sizeof(sfnt_DirectoryEntry) )
  291. {
  292. pDirEntry = (sfnt_DirectoryEntryPtr)pOffsetTable->table;
  293. for( i = 0; i < nOffsets; i++, pDirEntry++ )
  294. {
  295. #ifdef DEBUG
  296. DWORD dwTag[2];
  297. dwTag[0] = (DWORD)pDirEntry->tag;
  298. dwTag[1] = 0;
  299. dprintf(( " tag[%d] = '%s'\r\n", i, (PSZ)&dwTag[0] ));
  300. #endif
  301. if( pDirEntry->tag == tag_head )
  302. {
  303. dprintf(( "Found 'head' table\r\n" ));
  304. dprintf(( " offset = %d\r\n", SWAPL(pDirEntry->offset) ));
  305. dprintf(( " length = %d\r\n", SWAPL(pDirEntry->length) ));
  306. SetFilePointer( hFile, SWAPL(pDirEntry->offset), NULL, FILE_BEGIN );
  307. FontHeader.fontRevision = 0;
  308. ReadFile( hFile, &FontHeader, sizeof(FontHeader), &dwRead, NULL );
  309. dprintf(( " fontRevision = 0x%.8X\r\n", SWAPL(FontHeader.fontRevision) ));
  310. pfd->dwVersion = SWAPL(FontHeader.fontRevision);
  311. pfd->dwFlags |= TTF_FILE;
  312. break;
  313. }
  314. }
  315. }
  316. else
  317. {
  318. dprintf(( "OffsetTable.numOffsets is out of range!" ));
  319. }
  320. }
  321. }
  322. else
  323. {
  324. dprintf(( " ReadFile failed\r\n" ));
  325. }
  326. CloseHandle( hFile );
  327. }
  328. else
  329. {
  330. dprintf(( " CreateFile failed\r\n" ));
  331. }
  332. dprintf(( " dwFlags = 0x%.8lX\r\n", pfd->dwFlags ));
  333. return TRUE;
  334. }
  335. //*****************************************************************************
  336. //******************* D O R K O N R E G I S T R Y *********************
  337. //*****************************************************************************
  338. void DorkOnRegistry( PSZ pszDescription, PSZ pszRegFile )
  339. {
  340. LONG lrc;
  341. dprintf(( " Writing registry entry: '%s' '%s'\r\n", pszDescription, pszRegFile ));
  342. lrc = RegSetValueEx( hKeyFonts,
  343. pszDescription,
  344. 0,
  345. REG_SZ,
  346. pszRegFile,
  347. lstrlen(pszRegFile) );
  348. if( lrc != ERROR_SUCCESS )
  349. {
  350. dprintf(( "*** error writing to registry! rc = %d\r\n", GetLastError() ));
  351. }
  352. dprintf(( "<<< Calling AddFontResource(%s)\r\n", pszRegFile ));
  353. lrc = AddFontResource( pszRegFile );
  354. if( !lrc )
  355. {
  356. dprintf(( "*** AddFontResource(%s) failed!\r\n", pszRegFile ));
  357. }
  358. }
  359. //*****************************************************************************
  360. //******************** H A N D L E E X I S T I N G **********************
  361. //*****************************************************************************
  362. BOOL HandleExisting( char *pszCheck, PFILEDETAILS pfdSource )
  363. {
  364. FILEDETAILS fdExisting;
  365. dprintf(( "Looking for existing file'\r\n" ));
  366. dprintf(( " pszCheck = '%s'\r\n", pszCheck ));
  367. dprintf(( " Source file details\r\n" ));
  368. dprintf(( " szIniName = '%s'\r\n", pfdSource->szIniName ));
  369. dprintf(( " szFullPath = '%s'\r\n", pfdSource->szFullPath ));
  370. dprintf(( " szFilePart = '%s'\r\n", pfdSource->pszFilePart ));
  371. dprintf(( " dwFlags = 0x%.8X\r\n", pfdSource->dwFlags ));
  372. dprintf(( " dwVersion = 0x%.8X\r\n", pfdSource->dwVersion ));
  373. if( !GetFileDetails( pszCheck, &fdExisting, MODE_WIN95 ) ) return FALSE;
  374. dprintf(( " Existing file details\r\n" ));
  375. dprintf(( " szIniPath = '%s'\r\n", fdExisting.szIniName ));
  376. dprintf(( " szFullPath = '%s'\r\n", fdExisting.szFullPath ));
  377. dprintf(( " szFilePart = '%s'\r\n", fdExisting.pszFilePart ));
  378. dprintf(( " dwFlags = 0x%.8X\r\n", fdExisting.dwFlags ));
  379. dprintf(( " dwVersion = 0x%.8X\r\n", fdExisting.dwVersion ));
  380. if( fdExisting.dwVersion >= pfdSource->dwVersion )
  381. {
  382. dprintf(( "Existing file is newer or the same, killing ini entry\r\n" ));
  383. if( (pfdSource->dwFlags & (TTF_FILE+IN_SYSTEM)) == (TTF_FILE+IN_SYSTEM) )
  384. {
  385. dprintf(( "Deleting older source file '%s'\r\n", pfdSource->szFullPath ));
  386. if( !DeleteFile( pfdSource->szFullPath ) )
  387. {
  388. dprintf(( "*** couldn't delete '%s', le = #%d\r\n", pfdSource->szFullPath, GetLastError() ));
  389. }
  390. }
  391. else
  392. {
  393. dprintf(( "Ini file not SYSTEM dir, not deleting\r\n" ));
  394. }
  395. return TRUE; // return "source was older"
  396. }
  397. dprintf(( "Removing existing font resource\r\n" ));
  398. while( RemoveFontResource(fdExisting.szIniName) ); // Clear all instances
  399. while( RemoveFontResource(fdExisting.szFullPath) );
  400. while( RemoveFontResource(fdExisting.pszFilePart) );
  401. // If existing font is in fonts or system directory, delete it. But make
  402. // make sure that the file we're deleting isn't the source file.
  403. if( fdExisting.dwFlags & (IN_SYSTEM+IN_FONTS) &&
  404. lstrcmpi(fdExisting.szFullPath,pfdSource->szFullPath) != 0 )
  405. {
  406. dprintf(( "Deleting existing file '%s'\r\n", fdExisting.szFullPath ));
  407. if( !DeleteFile( fdExisting.szFullPath ) )
  408. {
  409. dprintf(( "*** error deleting '%s', le = #%d\r\n", fdExisting.szFullPath, GetLastError() ));
  410. }
  411. }
  412. return FALSE; // return "source was newer or not existing"
  413. }
  414. //*****************************************************************************
  415. //******************* P R O C E S S I N I L I N E *********************
  416. //*****************************************************************************
  417. void ProcessIniLine( PSZ pszDescription, PSZ pszIniFile )
  418. {
  419. FILEDETAILS fdSource;
  420. FILEDETAILS fdFOT;
  421. char szRegFile[MAX_PATH];
  422. dprintf(( "ProcessIniLine\r\n" ));
  423. dprintf(( " pszDescription = '%s'\r\n", pszDescription ));
  424. dprintf(( " pszIniFile = '%s'\r\n", pszIniFile ));
  425. fdSource.dwFlags = 0;
  426. fdFOT.dwFlags = 0;
  427. //-------------------- Get details on file in WIN.INI -----------------------
  428. GetFileDetails( pszIniFile, &fdSource, MODE_WIN31 );
  429. if( fdSource.dwFlags == 0 )
  430. {
  431. // This is bad, it means we couldn't find the font file referenced
  432. // in WIN.INI. That means that gdi probably won't find it either but
  433. // to be extra safe I'll just copy the ini file entry to the registry
  434. // so that we get the same bootup behavior as before.
  435. //// dprintf(( " Error getting file details, copying to registry\r\n" ));
  436. //// DorkOnRegistry( pszDescription, pszIniFile );
  437. dprintf(( " Couldn't find source file, nuking WIN.INI entry\r\n" ));
  438. WriteProfileString( "Fonts", pszDescription, NULL );
  439. return;
  440. }
  441. if( fdSource.dwFlags & FOT_FILE )
  442. {
  443. dprintf(( " its an FOT file, getting TTF information\r\n" ));
  444. fdFOT = fdSource;
  445. GetFileDetails( &Buffer[0x400], &fdSource, MODE_WIN31 );
  446. // If the ttf file for this fot file isn't found then simply
  447. // use the fot file. This will emulate win31 behavior.
  448. //
  449. // 03/25/95 - mikegi
  450. //
  451. // When the ttf file installed 'in place' on some sort of
  452. // removable disk, then we'll use the fot file. Do this
  453. // because we can't guarantee that the ttf file will be
  454. // available on subsequent boots.
  455. //
  456. // 04/20/95 - mikegi
  457. if( fdSource.dwFlags == 0 || // ttf file not found or
  458. fdSource.uDriveType != DRIVE_FIXED ) // is on non-fixed media
  459. {
  460. dprintf(( " couldn't find ttf file or its on removable media" ));
  461. dprintf(( " installing fot file" ));
  462. fdSource = fdFOT;
  463. fdFOT.dwFlags = 0;
  464. }
  465. }
  466. //-------------- See if entry already exists in the registry ----------------
  467. {
  468. LONG lrc;
  469. DWORD dwExisting;
  470. char szExisting[MAX_PATH];
  471. dprintf(( "Calling RegQueryValueEx('%s')\r\n", pszDescription ));
  472. dwExisting = sizeof(szExisting);
  473. lrc = RegQueryValueEx( hKeyFonts, pszDescription, NULL, NULL, szExisting, &dwExisting );
  474. dprintf(( " lrc = %d\r\n", lrc ));
  475. if( lrc == ERROR_SUCCESS )
  476. {
  477. dprintf(( "Entry already exists in registry\r\n" ));
  478. dprintf(( " szExisting = '%s'\r\n", szExisting ));
  479. if( HandleExisting(szExisting,&fdSource) ) goto CleanupSource;
  480. }
  481. }
  482. //--------------------- Copy file to fonts directory ------------------------
  483. if( fdSource.dwFlags & IN_SYSTEM )
  484. {
  485. dprintf(( " Copying source from SYSTEM directory to FONTS folder\r\n" ));
  486. if( !(fdSource.dwFlags & FON_FILE) )
  487. {
  488. lstrcpy( szRegFile, szFontsDir );
  489. AppendFileName( szRegFile, fdSource.pszFilePart );
  490. dprintf(( " Checking for existing file in FONTS folder\r\n" ));
  491. if( HandleExisting(szRegFile,&fdSource) )
  492. {
  493. // file exists in fonts dir, but no registry entry for it
  494. dprintf(( " already in FONTS directory, just adding registry entry" ));
  495. }
  496. else
  497. {
  498. dprintf(( " Moving file: '%s' to '%s'\r\n", fdSource.szFullPath, szRegFile ));
  499. if( !MoveFile( fdSource.szFullPath, szRegFile ) )
  500. {
  501. dprintf(( "*** MoveFile failed! rc = %d\r\n", GetLastError() ));
  502. }
  503. }
  504. }
  505. else
  506. {
  507. dprintf(( " leaving .FON in SYSTEM directory\r\n" ));
  508. }
  509. lstrcpy( szRegFile, fdSource.pszFilePart );
  510. }
  511. else if( fdSource.dwFlags & IN_FONTS )
  512. {
  513. dprintf(( " Leaving in FONTS dir: '%s'\r\n", fdSource.szFullPath ));
  514. lstrcpy( szRegFile, fdSource.pszFilePart );
  515. }
  516. else
  517. {
  518. dprintf(( " Installing file in place: '%s'\r\n", fdSource.szFullPath ));
  519. lstrcpy( szRegFile, fdSource.szFullPath );
  520. }
  521. DorkOnRegistry( pszDescription, szRegFile );
  522. //----------------------- Delete source FOT file ----------------------------
  523. CleanupSource:
  524. dprintf(( " Nuking WIN.INI entry: '%s'\r\n", pszDescription ));
  525. WriteProfileString( "Fonts", pszDescription, NULL );
  526. if( fdFOT.dwFlags & (FOT_FILE+IN_SYSTEM) == FOT_FILE+IN_SYSTEM )
  527. {
  528. dprintf(( " Deleting '%s'\r\n", fdFOT.szFullPath ));
  529. if( !DeleteFile( fdFOT.szFullPath ) )
  530. {
  531. dprintf(( "*** couldn't delete '%s', le = #%d\r\n", fdFOT.szFullPath, GetLastError() ));
  532. }
  533. }
  534. }
  535. //*****************************************************************************
  536. //*********************** G E T S E C T I O N ***************************
  537. //*****************************************************************************
  538. int GetSection( LPSTR lpFile, LPSTR lpSection, LPHANDLE hSection)
  539. {
  540. int nCount;
  541. int nSize;
  542. HANDLE hLocal, hTemp;
  543. char *pszSect;
  544. if( !( hLocal = LocalAlloc( LMEM_MOVEABLE, nSize=4096 ) ) )
  545. return( 0 );
  546. //
  547. // Now that a buffer exists, Enumerate all LHS of the section. If the
  548. // buffer overflows, reallocate it and try again.
  549. //
  550. do
  551. {
  552. pszSect = (PSTR) LocalLock( hLocal );
  553. if( lpFile )
  554. nCount = GetPrivateProfileString(lpSection, NULL, "", pszSect,
  555. nSize, lpFile);
  556. else
  557. nCount = GetProfileString(lpSection, NULL, "", pszSect, nSize);
  558. LocalUnlock(hLocal);
  559. if (nCount <= nSize-10)
  560. break;
  561. nSize += 2048;
  562. if (!(hLocal = LocalReAlloc(hTemp=hLocal, nSize, LMEM_MOVEABLE)))
  563. {
  564. LocalFree(hTemp);
  565. return(0);
  566. }
  567. } while (1) ;
  568. *hSection = hLocal;
  569. return (nCount);
  570. }
  571. //*****************************************************************************
  572. //****************** P R O C E S S I N I F I L E **********************
  573. //*****************************************************************************
  574. void ProcessIt( void )
  575. {
  576. char szFonts[] = "FONTS";
  577. PSTR pszItem;
  578. HANDLE hLocalBuf;
  579. PSTR pLocalBuf, pEnd;
  580. int nCount;
  581. char szPath[ MAX_PATH ];
  582. GetDirs();
  583. nCount = GetSection(NULL, szFonts, &hLocalBuf);
  584. if( !hLocalBuf ) return;
  585. pLocalBuf = (PSTR) LocalLock(hLocalBuf);
  586. pEnd = pLocalBuf+nCount;
  587. // Add all the fonts in the list, if they haven't been added already
  588. for( pszItem=pLocalBuf; pszItem<pEnd; pszItem+=lstrlen(pszItem)+1)
  589. {
  590. if( !*pszItem ) continue;
  591. GetProfileString(szFonts, pszItem, "", szPath, sizeof(szPath));
  592. if( *szPath )
  593. {
  594. ProcessIniLine( pszItem, szPath );
  595. }
  596. }
  597. LocalUnlock( hLocalBuf );
  598. LocalFree( hLocalBuf );
  599. }
  600. //*****************************************************************************
  601. //************************* W I N M A I N *******************************
  602. //*****************************************************************************
  603. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
  604. {
  605. LONG lrc;
  606. DWORD dwDisposition;
  607. lrc = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  608. "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts",
  609. 0,
  610. NULL,
  611. REG_OPTION_NON_VOLATILE,
  612. KEY_SET_VALUE,
  613. NULL,
  614. &hKeyFonts,
  615. &dwDisposition );
  616. if( lrc == ERROR_SUCCESS )
  617. {
  618. ProcessIt();
  619. dprintf(( " Flushing fonts key\r\n" ));
  620. RegFlushKey( hKeyFonts );
  621. RegCloseKey( hKeyFonts );
  622. }
  623. else
  624. {
  625. dprintf(( "*** RegCreateKeyEx failed! rc = %d\r\n", GetLastError() ));
  626. }
  627. return 0;
  628. }