00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "precomp.h"
00022
#pragma hdrstop
00023
#include <setupbat.h>
00024
00025 CONST WCHAR
pwszType1Key[] =
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Type 1 Installer\\Type 1 Fonts";
00026 CONST WCHAR
pwszSweepType1Key[] =
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Type 1 Installer\\LastType1Sweep";
00027 CONST WCHAR
pwszUpdType1Key[] =
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Type 1 Installer\\Upgraded Type1";
00028
00029 CONST WCHAR
pwszFontsKey[] =
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
00030 CONST WCHAR
pwszSweepKey[] =
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\LastFontSweep";
00031 CONST WCHAR
pwszFontDrivers[] =
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Font Drivers";
00032
00033 #define LAST_SWEEP_TIME L"LastSweepTime"
00034 #define UPGRADED_TYPE1 L"UpgradedType1"
00035
00036 #define DWORDALIGN(X) (((X) + 3) & ~3)
00037
00038 WCHAR *
gpwcSystemDir;
00039 WCHAR *
gpwcFontsDir;
00040 BOOL gbWin31Upgrade;
00041
00042
00043 BOOL bCheckIfDualBootingWithWin31()
00044 {
00045 WCHAR
Buffer[32];
00046 WCHAR awcWindowsDir[
MAX_PATH];
00047
DWORD dwRet;
00048
UINT cwchWinPath = GetSystemWindowsDirectoryW(awcWindowsDir,
MAX_PATH);
00049
00050
00051
00052
if (awcWindowsDir[cwchWinPath - 1] ==
L'\\')
00053 {
00054 cwchWinPath -= 1;
00055 }
00056 awcWindowsDir[cwchWinPath] =
L'\0';
00057
00058 lstrcatW(awcWindowsDir,
L"\\system32\\");
00059 lstrcatW(awcWindowsDir, WINNT_GUI_FILE_W);
00060
00061 dwRet = GetPrivateProfileStringW(
00062 WINNT_DATA_W,
00063 WINNT_D_WIN31UPGRADE_W,
00064 WINNT_A_NO_W,
00065
Buffer,
00066
sizeof(
Buffer)/
sizeof(WCHAR),
00067 awcWindowsDir
00068 );
00069
00070
#if DBGSWEEP
00071
DbgPrint(
"\n dwRet = %ld, win31upgrade = %ws\n\n", dwRet,
Buffer);
00072
#endif
00073
00074
return (
BOOL)(dwRet ? (!lstrcmpiW(
Buffer,WINNT_A_YES)) : 0);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 VOID vNullTermWideString (WCHAR *pwcDest, WCHAR *pwcSrc, ULONG ulLength)
00090 {
00091 ULONG index;
00092
00093
for (index = 0; index < ulLength; index++) {
00094 *pwcDest++ = *pwcSrc++;
00095 }
00096 *pwcDest =
'\0';
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 BOOL bCheckFontEntry(WCHAR *pwcName, WCHAR *pwcExtension)
00113 {
00114
BOOL bRet =
FALSE;
00115 LONG cwc = (LONG)wcslen(pwcName) - (LONG)wcslen(pwcExtension);
00116
if (cwc > 0)
00117 {
00118 bRet = !_wcsicmp(&pwcName[cwc], pwcExtension);
00119 }
00120
return bRet;
00121
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 #define EXT_TRUETYPE L"(TrueType)"
00135 #define EXT_FOT L".FOT"
00136
00137
00138 VOID vProcessFontEntry(
00139 HKEY hkey,
00140 WCHAR *pwcValueName,
00141 ULONG ulValueNameLength,
00142 WCHAR *pwcFileName,
00143 ULONG ulFileNameLength
00144 )
00145 {
00146
NTSTATUS Status;
00147 UNICODE_STRING UnicodeString;
00148
BOOL bFot =
FALSE;
00149 WCHAR awcTTF[
MAX_PATH];
00150 WCHAR awcTmpBuf[
MAX_PATH];
00151 WCHAR *pwcTTF;
00152 FLONG fl, fl2;
00153 FLONG flEmbed;
00154
DWORD dwPidTid;
00155 WCHAR awcValueName[
MAX_PATH];
00156 WCHAR awcFileName[
MAX_PATH];
00157
00158
00159
00160 ulValueNameLength =
min(
MAX_PATH - 1, ulValueNameLength);
00161
vNullTermWideString (awcValueName, pwcValueName, ulValueNameLength);
00162
00163
00164 ulFileNameLength =
min(
MAX_PATH - 1, ulFileNameLength);
00165
vNullTermWideString (awcFileName, pwcFileName, ulFileNameLength);
00166
00167
if (
bCheckFontEntry(awcValueName,
EXT_TRUETYPE))
00168 {
00169
00170
00171
if (bFot =
bCheckFontEntry(awcFileName,
EXT_FOT))
00172 {
00173
00174
00175
00176
00177
00178
00179
if (bMakePathNameW(awcTmpBuf, awcFileName,
NULL, &fl2))
00180 {
00181
if (cGetTTFFromFOT(awcTmpBuf,
MAX_PATH, awcTTF, &fl, &flEmbed, &dwPidTid,
TRUE) &&
00182 !(fl & FONT_ISNOT_FOT))
00183 {
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
if (bFot && !
gbWin31Upgrade)
00199 {
00200 UserVerify(DeleteFileW(awcTmpBuf));
00201 }
00202
00203
if ((fl & (FONT_IN_FONTS_DIR | FONT_IN_SYSTEM_DIR)) == 0)
00204 {
00205
00206
00207
00208 pwcTTF = awcTTF;
00209 }
00210
else
00211 {
00212
00213
00214
00215 pwcTTF = &awcTTF[wcslen(awcTTF) - 1];
00216
while ((pwcTTF >= awcTTF) && (*pwcTTF !=
L'\\') && (*pwcTTF !=
L':'))
00217 pwcTTF--;
00218 pwcTTF++;
00219
00220
if (fl & FONT_IN_SYSTEM_DIR)
00221 {
00222
00223
00224
00225 wcscpy(awcTmpBuf,
gpwcFontsDir);
00226 lstrcatW(awcTmpBuf,
L"\\");
00227 lstrcatW(awcTmpBuf, pwcTTF);
00228
00229
00230
00231
00232
00233 RIPMSG2(RIP_VERBOSE,
"Moving %ws to %ws", awcTTF, awcTmpBuf);
00234
if (!
gbWin31Upgrade)
00235 {
00236 UserVerify(MoveFileW(awcTTF, awcTmpBuf));
00237 }
00238
else
00239 {
00240
00241
00242 UserVerify(CopyFileW(awcTTF, awcTmpBuf,
TRUE));
00243 }
00244 }
00245 }
00246
00247 RIPMSG2(RIP_VERBOSE,
"writing to the registry:\n %ws=%ws", pwcValueName, pwcTTF);
00248
RtlInitUnicodeString(&UnicodeString, awcValueName);
00249
Status =
NtSetValueKey(hkey,
00250 &UnicodeString,
00251 0,
00252 REG_SZ,
00253 pwcTTF,
00254 (wcslen(pwcTTF)+1) *
sizeof(WCHAR));
00255 UserAssert(
NT_SUCCESS(
Status));
00256 }
00257
#if DBG
00258
else
00259 {
00260 RIPMSG1(RIP_WARNING,
"Could not locate ttf pointed to by %ws", awcTmpBuf);
00261 }
00262
#endif
00263
}
00264
#if DBG
00265
else
00266 {
00267 RIPMSG1(RIP_WARNING,
"Could not locate .fot: %ws", awcFileName);
00268 }
00269
#endif
00270
}
00271 }
00272
else
00273 {
00274
00275
00276
00277
00278
00279
if (bMakePathNameW(awcTTF, awcFileName,
NULL, &fl))
00280 {
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
if (fl & (FONT_IN_SYSTEM_DIR | FONT_IN_FONTS_DIR))
00291 {
00292
00293
00294
00295 pwcTTF = &awcTTF[wcslen(awcTTF) - 1];
00296
while ((pwcTTF >= awcTTF) && (*pwcTTF !=
L'\\') && (*pwcTTF !=
L':'))
00297 pwcTTF--;
00298 pwcTTF++;
00299
00300
if (fl & FONT_IN_SYSTEM_DIR)
00301 {
00302
00303
00304
00305 wcscpy(awcTmpBuf,
gpwcFontsDir);
00306 lstrcatW(awcTmpBuf,
L"\\");
00307 lstrcatW(awcTmpBuf, pwcTTF);
00308
00309
00310
00311
00312
00313
00314 RIPMSG2(RIP_VERBOSE,
"Moving %ws to %ws", awcTTF, awcTmpBuf);
00315
if (!
gbWin31Upgrade)
00316 {
00317 UserVerify(MoveFileW(awcTTF, awcTmpBuf));
00318 }
00319
else
00320 {
00321
00322
00323 UserVerify(CopyFileW(awcTTF, awcTmpBuf,
TRUE));
00324 }
00325 }
00326
00327
00328
00329
00330
if (!(fl & FONT_RELATIVE_PATH))
00331 {
00332 RIPMSG2(RIP_VERBOSE,
"writing to the registry:\n %ws=%ws", pwcValueName, pwcTTF);
00333
RtlInitUnicodeString(&UnicodeString, awcValueName);
00334
Status =
NtSetValueKey(hkey,
00335 &UnicodeString,
00336 0,
00337 REG_SZ,
00338 pwcTTF,
00339 (wcslen(pwcTTF)+1) *
sizeof(WCHAR));
00340 UserAssert(
NT_SUCCESS(
Status));
00341 }
00342 }
00343 }
00344 }
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 VOID vMoveFileFromSystemToFontsDir(WCHAR *pwcFile)
00361 {
00362 WCHAR awcTmpBuf[
MAX_PATH];
00363 WCHAR awcTmp[
MAX_PATH];
00364 FLONG fl;
00365 WCHAR *pwcTmp;
00366
00367
#if DBG
00368
BOOL bOk;
00369
#endif
00370
00371
if (bMakePathNameW(awcTmp, pwcFile,
NULL, &fl))
00372 {
00373
00374
00375
00376
00377
if
00378 (
00379 (fl & (FONT_IN_SYSTEM_DIR | FONT_RELATIVE_PATH)) ==
00380 (FONT_IN_SYSTEM_DIR | FONT_RELATIVE_PATH)
00381 )
00382 {
00383
00384
00385
00386 pwcTmp = &awcTmp[wcslen(awcTmp) - 1];
00387
while ((pwcTmp >= awcTmp) && (*pwcTmp !=
L'\\') && (*pwcTmp !=
L':'))
00388 pwcTmp--;
00389
00390
if (pwcTmp > awcTmp)
00391 pwcTmp++;
00392
00393
00394
00395
00396 wcscpy(awcTmpBuf,
gpwcFontsDir);
00397 lstrcatW(awcTmpBuf,
L"\\");
00398 lstrcatW(awcTmpBuf, pwcTmp);
00399
00400
00401
00402
00403
00404
#if DBG
00405
bOk =
00406
#endif
00407
MoveFileW(awcTmp, awcTmpBuf);
00408
00409 RIPMSG3(RIP_VERBOSE,
00410
"move %ws to %ws %s",
00411 awcTmp,
00412 awcTmpBuf,
00413 (bOk) ?
"succeeded" :
"failed");
00414 }
00415
#if DBG
00416
else
00417 {
00418 RIPMSG2(RIP_WARNING,
00419
"File %ws not in system directory, fl = 0x%lx\n",
00420 awcTmp, fl);
00421 }
00422
#endif
00423
00424 }
00425
#if DBG
00426
else
00427 {
00428 RIPMSG1(RIP_WARNING,
"Could not locate %ws", pwcFile);
00429 }
00430
#endif
00431
}
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 VOID vProcessType1FontEntry(
00451 HKEY hkey,
00452 WCHAR *pwcValueName,
00453 ULONG ulValueNameLength,
00454 WCHAR *pwcValueData,
00455 ULONG ulValueDataLength
00456 )
00457 {
00458 WCHAR *pwcPFM, *pwcPFB;
00459
00460 UNREFERENCED_PARAMETER(hkey);
00461 UNREFERENCED_PARAMETER(pwcValueName);
00462 UNREFERENCED_PARAMETER(ulValueNameLength);
00463 UNREFERENCED_PARAMETER(ulValueDataLength);
00464
00465
00466
00467
if ((pwcValueData[0] !=
L'\0') && (pwcValueData[1] ==
L'\0'))
00468 {
00469 pwcPFM = &pwcValueData[2];
00470 pwcPFB = pwcPFM + wcslen(pwcPFM) + 1;
00471
00472
vMoveFileFromSystemToFontsDir(pwcPFM);
00473
vMoveFileFromSystemToFontsDir(pwcPFB);
00474 }
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 VOID vAddType1Font(
00490 WCHAR *pwcValueData,
00491 DWORD dwFlags
00492 )
00493 {
00494 WCHAR *pwcPFM, *pwcPFB, *pwcMMM;
00495
00496
#if DBG
00497
int iRet;
00498
#endif
00499
00500
00501
00502
if ((pwcValueData[0] !=
L'\0') && (pwcValueData[1] ==
L'\0'))
00503 {
00504 pwcPFM = &pwcValueData[2];
00505 pwcPFB = pwcPFM + wcslen(pwcPFM) + 1;
00506 pwcMMM = pwcPFB + wcslen(pwcPFB) + 1;
00507
00508
00509
00510 pwcPFB[-1] = PATH_SEPARATOR;
00511
00512
00513
00514
if (pwcMMM[0] !=
L'\0')
00515 pwcMMM[-1] = PATH_SEPARATOR;
00516
00517
#if DBG
00518
iRet =
00519
#endif
00520
00521 GdiAddFontResourceW(pwcPFM,
dwFlags,
NULL);
00522
00523
#if DBGSWEEP
00524
DbgPrint(
"%ld = GdiAddFontResourceW(%ws, 0x%lx);\n",
00525 iRet, pwcPFM,
dwFlags);
00526
#endif
00527
}
00528 }
00529
00530
00531 VOID vAddRemoteType1Font(
00532 HKEY hkey,
00533 WCHAR *pwcValueName,
00534 ULONG ulValueNameLength,
00535 WCHAR *pwcValueData,
00536 ULONG ulValueDataLength
00537 )
00538 {
00539 UNREFERENCED_PARAMETER(hkey);
00540 UNREFERENCED_PARAMETER(pwcValueName);
00541 UNREFERENCED_PARAMETER(ulValueNameLength);
00542 UNREFERENCED_PARAMETER(ulValueDataLength);
00543
vAddType1Font(pwcValueData, AFRW_ADD_REMOTE_FONT);
00544 }
00545
00546 VOID vAddLocalType1Font(
00547 HKEY hkey,
00548 WCHAR *pwcValueName,
00549 ULONG ulValueNameLength,
00550 WCHAR *pwcValueData,
00551 ULONG ulValueDataLength
00552 )
00553 {
00554 UNREFERENCED_PARAMETER(hkey);
00555 UNREFERENCED_PARAMETER(pwcValueName);
00556 UNREFERENCED_PARAMETER(ulValueNameLength);
00557 UNREFERENCED_PARAMETER(ulValueDataLength);
00558
vAddType1Font(pwcValueData, AFRW_ADD_LOCAL_FONT);
00559 }
00560
00561
00562 typedef VOID (*
PFNENTRY)(HKEY hkey, WCHAR *, ULONG, WCHAR *, ULONG);
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 VOID vSweepFonts(
00578 PCWSTR pwszFontListKey,
00579 PCWSTR pwszFontSweepKey,
00580 PFNENTRY pfnProcessFontEntry,
00581 BOOL bForceEnum
00582 )
00583 {
00584
DWORD cjMaxValueName;
00585
DWORD iFont;
00586
NTSTATUS Status;
00587 UNICODE_STRING UnicodeString;
00588 OBJECT_ATTRIBUTES ObjA;
00589 KEY_FULL_INFORMATION KeyInfo;
00590
DWORD dwReturnLength;
00591
00592 PKEY_VALUE_FULL_INFORMATION KeyValueInfo;
00593
BYTE *pjValueData;
00594
00595 HKEY hkey =
NULL;
00596
struct {
00597 KEY_VALUE_PARTIAL_INFORMATION;
00598 LARGE_INTEGER;
00599 } SweepValueInfo;
00600 LARGE_INTEGER LastSweepTime;
00601
BOOL bSweep =
FALSE;
00602
00603 HKEY hkeyLastSweep;
00604
DWORD cjData;
00605
00606
if (!bForceEnum)
00607 {
00608
00609
00610
00611
00612
RtlInitUnicodeString(&UnicodeString, pwszFontSweepKey);
00613 InitializeObjectAttributes(&ObjA,
00614 &UnicodeString,
00615 OBJ_CASE_INSENSITIVE,
00616
NULL,
00617
NULL);
00618
Status =
NtOpenKey(&hkeyLastSweep,
00619 KEY_READ | KEY_WRITE,
00620 &ObjA);
00621
00622
if (!
NT_SUCCESS(
Status))
00623 {
00624
DWORD dwDisposition;
00625
00626
00627
00628
00629 bSweep =
TRUE;
00630
00631
00632
00633
00634
Status =
NtCreateKey(&hkeyLastSweep,
00635 KEY_WRITE,
00636 &ObjA,
00637 0,
00638
NULL,
00639 REG_OPTION_NON_VOLATILE,
00640 &dwDisposition);
00641
00642
if (!
NT_SUCCESS(
Status))
00643
return;
00644 }
00645
else
00646 {
00647
RtlInitUnicodeString(&UnicodeString,
LAST_SWEEP_TIME);
00648
Status =
NtQueryValueKey(hkeyLastSweep,
00649 &UnicodeString,
00650 KeyValuePartialInformation,
00651 &SweepValueInfo,
00652
sizeof(SweepValueInfo),
00653 &dwReturnLength);
00654
if (!
NT_SUCCESS(
Status))
00655 {
00656 bSweep =
TRUE;
00657 }
00658
else
00659 {
00660 UserAssert(SweepValueInfo.Type == REG_BINARY);
00661 UserAssert(SweepValueInfo.DataLength ==
sizeof(LastSweepTime));
00662 RtlCopyMemory(&LastSweepTime, &SweepValueInfo.Data,
sizeof(LastSweepTime));
00663 }
00664 }
00665 }
00666
else
00667 {
00668 bSweep =
TRUE;
00669 }
00670
00671
00672
00673
00674
00675
RtlInitUnicodeString(&UnicodeString, pwszFontListKey);
00676 InitializeObjectAttributes(&ObjA,
00677 &UnicodeString,
00678 OBJ_CASE_INSENSITIVE,
00679
NULL,
00680
NULL);
00681
Status =
NtOpenKey(&hkey,
00682 KEY_READ | KEY_WRITE,
00683 &ObjA);
00684
00685
if (
NT_SUCCESS(
Status))
00686 {
00687
00688
00689
Status =
NtQueryKey(hkey,
00690 KeyFullInformation,
00691 &KeyInfo,
00692
sizeof(KeyInfo),
00693 &dwReturnLength);
00694
00695
if (
NT_SUCCESS(
Status) && KeyInfo.Values)
00696 {
00697 UserAssert(!(KeyInfo.ClassLength | KeyInfo.SubKeys | KeyInfo.MaxNameLen | KeyInfo.MaxClassLen));
00698
00699
00700
00701
00702
if (!bSweep)
00703 {
00704
if (KeyInfo.LastWriteTime.QuadPart != LastSweepTime.QuadPart ) {
00705 bSweep =
TRUE;
00706 }
00707 }
00708
00709
00710
00711
if (bSweep &&
00712 bInitSystemAndFontsDirectoriesW(&
gpwcSystemDir, &
gpwcFontsDir))
00713 {
00714
00715
00716 cjMaxValueName =
DWORDALIGN(KeyInfo.MaxValueNameLen +
sizeof(WCHAR));
00717
00718
00719
00720
00721 KeyInfo.MaxValueDataLen =
DWORDALIGN(KeyInfo.MaxValueDataLen);
00722 cjData = cjMaxValueName +
00723 KeyInfo.MaxValueDataLen ;
00724
00725
if (KeyValueInfo =
UserLocalAlloc(0,
sizeof(*KeyValueInfo) + cjData))
00726 {
00727
for (iFont = 0; iFont < KeyInfo.Values; iFont++)
00728 {
00729
Status =
NtEnumerateValueKey(
00730 hkey,
00731 iFont,
00732 KeyValueFullInformation,
00733 KeyValueInfo,
00734
sizeof(*KeyValueInfo) + cjData,
00735 &dwReturnLength);
00736
00737
if (
NT_SUCCESS(
Status))
00738 {
00739 UserAssert(KeyValueInfo->NameLength <= KeyInfo.MaxValueNameLen);
00740 UserAssert(KeyValueInfo->DataLength <= KeyInfo.MaxValueDataLen);
00741 UserAssert((KeyValueInfo->Type == REG_SZ) || (KeyValueInfo->Type == REG_MULTI_SZ));
00742
00743
00744
00745 pjValueData = (
BYTE *)KeyValueInfo + KeyValueInfo->DataOffset;
00746
00747
00748
00749
00750
00751 (*pfnProcessFontEntry)(hkey,
00752 KeyValueInfo->Name,
00753 KeyValueInfo->NameLength /
sizeof(WCHAR),
00754 (WCHAR *)pjValueData,
00755 KeyValueInfo->DataLength /
sizeof(WCHAR));
00756 }
00757 }
00758
00759
if (!bForceEnum)
00760 {
00761
00762
00763
00764
Status =
NtQueryKey(hkey,
00765 KeyFullInformation,
00766 &KeyInfo,
00767
sizeof(KeyInfo),
00768 &dwReturnLength);
00769 UserAssert(
NT_SUCCESS(
Status));
00770
00771
00772
00773
RtlInitUnicodeString(&UnicodeString,
LAST_SWEEP_TIME);
00774
Status =
NtSetValueKey(hkeyLastSweep,
00775 &UnicodeString,
00776 0,
00777 REG_BINARY,
00778 &KeyInfo.LastWriteTime,
00779
sizeof(KeyInfo.LastWriteTime));
00780 UserAssert(
NT_SUCCESS(
Status));
00781 }
00782
00783
00784
00785
UserLocalFree(KeyValueInfo);
00786 }
00787 }
00788 }
00789
NtClose(hkey);
00790 }
00791
00792
if (!bForceEnum)
00793 {
00794
NtClose(hkeyLastSweep);
00795 }
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 BOOL bLoadableFontDrivers()
00819 {
00820
NTSTATUS Status;
00821 UNICODE_STRING UnicodeString;
00822 OBJECT_ATTRIBUTES ObjA;
00823 KEY_FULL_INFORMATION KeyInfo;
00824
DWORD dwReturnLength;
00825 HKEY hkey =
NULL;
00826
BOOL bRet =
FALSE;
00827
00828
00829
00830
00831
00832
00833
00834
RtlInitUnicodeString(&UnicodeString,
pwszFontDrivers);
00835 InitializeObjectAttributes(&ObjA,
00836 &UnicodeString,
00837 OBJ_CASE_INSENSITIVE,
00838
NULL,
00839
NULL);
00840
Status =
NtOpenKey(&hkey,
00841 KEY_READ,
00842 &ObjA);
00843
00844
if (
NT_SUCCESS(
Status))
00845 {
00846
00847
00848
Status =
NtQueryKey(hkey,
00849 KeyFullInformation,
00850 &KeyInfo,
00851
sizeof(KeyInfo),
00852 &dwReturnLength);
00853
00854
if (
NT_SUCCESS(
Status) && KeyInfo.Values)
00855 {
00856 UserAssert(!(KeyInfo.ClassLength | KeyInfo.SubKeys | KeyInfo.MaxNameLen | KeyInfo.MaxClassLen));
00857
00858
00859
00860 bRet =
TRUE;
00861 }
00862
00863
NtClose(hkey);
00864 }
00865
return bRet;
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
BOOL bCheckAndDeleteTTF
00882 (
00883 HKEY hkey,
00884 PKEY_FULL_INFORMATION pKeyInfo,
00885 PKEY_VALUE_FULL_INFORMATION KeyValueInfo,
00886 PKEY_VALUE_BASIC_INFORMATION KeyValueBasicInfo,
00887
DWORD cjData
00888 )
00889 {
00890
NTSTATUS Status;
00891 UNICODE_STRING UnicodeString;
00892
DWORD dwReturnLength;
00893 ULONG iFont;
00894 WCHAR awcTmp[
MAX_PATH], *pFontName, *pType1Name, *pwcFile;
00895
BOOL bDelTTFfile, bRet =
TRUE;
00896 FLONG fl;
00897 WCHAR awcType1Name[
MAX_PATH];
00898 WCHAR awcFontName[
MAX_PATH];
00899 WCHAR awcFile[
MAX_PATH];
00900
00901
00902
for (iFont = 0; iFont < pKeyInfo->Values; iFont++)
00903 {
00904 RtlZeroMemory(KeyValueInfo->Name, cjData);
00905
Status =
NtEnumerateValueKey(
00906 hkey,
00907 iFont,
00908 KeyValueFullInformation,
00909 KeyValueInfo,
00910
sizeof(*KeyValueInfo) + cjData,
00911 &dwReturnLength);
00912
00913
if (
NT_SUCCESS(
Status))
00914 {
00915 UserAssert(KeyValueInfo->NameLength <= pKeyInfo->MaxValueNameLen);
00916 UserAssert(KeyValueInfo->DataLength <= pKeyInfo->MaxValueDataLen);
00917 UserAssert(KeyValueInfo->Type == REG_SZ);
00918
00919 bDelTTFfile =
FALSE;
00920
00921
00922
vNullTermWideString (awcType1Name,
00923 KeyValueBasicInfo->Name,
00924 KeyValueBasicInfo->NameLength /
sizeof(WCHAR));
00925
vNullTermWideString (awcFontName,
00926 KeyValueInfo->Name,
00927 KeyValueInfo->NameLength /
sizeof(WCHAR));
00928
vNullTermWideString (awcFile,
00929 (WCHAR *) ((
BYTE *)KeyValueInfo + KeyValueInfo->DataOffset),
00930 KeyValueInfo->DataLength /
sizeof(WCHAR));
00931 pType1Name = awcType1Name;
00932 pFontName = awcFontName;
00933 pwcFile = awcFile;
00934
00935
while((*pType1Name) && (*pType1Name++ == *pFontName++))
00936 ;
00937
00938
00939
00940
if ((*pType1Name == 0) && (*pFontName++ ==
L' '))
00941 {
00942 WCHAR *pTrueType =
L"(TrueType)";
00943
00944
while(*pTrueType && (*pTrueType++ == *pFontName++))
00945 ;
00946
if (*pTrueType == 0)
00947 {
00948 bDelTTFfile =
TRUE;
00949 }
00950 }
00951
00952
if (bDelTTFfile)
00953 {
00954
00955
if (bRet = bMakePathNameW(awcTmp, pwcFile,
NULL, &fl))
00956 {
00957 UserVerify((bRet = DeleteFileW(awcTmp)));
00958 }
00959
00960
00961 *pFontName = 0;
00962
RtlInitUnicodeString(&UnicodeString, awcFontName);
00963
Status =
NtDeleteValueKey(hkey, (PUNICODE_STRING)&UnicodeString);
00964
00965
00966
if (
NT_SUCCESS(
Status))
00967 pKeyInfo->Values--;
00968
else
00969 bRet =
FALSE;
00970
00971
break;
00972 }
00973 }
00974
else
00975 {
00976 bRet =
FALSE;
00977
break;
00978 }
00979 }
00980
00981
return bRet;
00982 }
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996 BOOL bCleanConvertedTTFs()
00997 {
00998 UNICODE_STRING UnicodeString;
00999 OBJECT_ATTRIBUTES ObjA;
01000
NTSTATUS Status;
01001 HKEY hkeyFonts =
NULL, hkeyType1 =
NULL;
01002
DWORD dwReturnLength;
01003
DWORD iFontT1, cjData;
01004
DWORD cjMaxValueNameT1, cjMaxValueNameFonts;
01005
BOOL bRet =
FALSE, bError =
FALSE;
01006
01007 KEY_FULL_INFORMATION KeyInfoType1, KeyInfoFonts;
01008 PKEY_VALUE_BASIC_INFORMATION KeyValueBasicInfo;
01009 PKEY_VALUE_FULL_INFORMATION KeyValueInfo;
01010
01011
01012
01013
RtlInitUnicodeString(&UnicodeString,
pwszType1Key);
01014 InitializeObjectAttributes(&ObjA,
01015 &UnicodeString,
01016 OBJ_CASE_INSENSITIVE,
01017
NULL,
01018
NULL);
01019
01020
Status =
NtOpenKey(&hkeyType1,
01021 KEY_READ | KEY_WRITE,
01022 &ObjA);
01023
01024
if (
NT_SUCCESS(
Status))
01025 {
01026
Status =
NtQueryKey(hkeyType1,
01027 KeyFullInformation,
01028 &KeyInfoType1,
01029
sizeof(KeyInfoType1),
01030 &dwReturnLength);
01031
01032
if (
NT_SUCCESS(
Status) && KeyInfoType1.Values)
01033 {
01034 UserAssert(!(KeyInfoType1.ClassLength | KeyInfoType1.SubKeys |
01035 KeyInfoType1.MaxNameLen | KeyInfoType1.MaxClassLen));
01036
01037 cjMaxValueNameT1 =
DWORDALIGN(KeyInfoType1.MaxValueNameLen +
sizeof(WCHAR));
01038
01039
01040
if (KeyValueBasicInfo =
UserLocalAlloc(0,
sizeof(*KeyValueBasicInfo) + cjMaxValueNameT1))
01041 {
01042
RtlInitUnicodeString(&UnicodeString,
pwszFontsKey);
01043 InitializeObjectAttributes(&ObjA,
01044 &UnicodeString,
01045 OBJ_CASE_INSENSITIVE,
01046
NULL,
01047
NULL);
01048
Status =
NtOpenKey(&hkeyFonts,
01049 KEY_READ | KEY_WRITE,
01050 &ObjA);
01051
01052
if (
NT_SUCCESS(
Status))
01053 {
01054
Status =
NtQueryKey(hkeyFonts,
01055 KeyFullInformation,
01056 &KeyInfoFonts,
01057
sizeof(KeyInfoFonts),
01058 &dwReturnLength);
01059
01060
if (
NT_SUCCESS(
Status) && KeyInfoFonts.Values)
01061 {
01062 UserAssert(!(KeyInfoFonts.ClassLength | KeyInfoFonts.SubKeys |
01063 KeyInfoFonts.MaxNameLen | KeyInfoFonts.MaxClassLen));
01064
01065 cjMaxValueNameFonts =
DWORDALIGN(KeyInfoFonts.MaxValueNameLen +
sizeof(WCHAR));
01066 KeyInfoFonts.MaxValueDataLen =
DWORDALIGN(KeyInfoFonts.MaxValueDataLen);
01067 cjData = cjMaxValueNameFonts + KeyInfoFonts.MaxValueDataLen;
01068
01069
01070
if (KeyValueInfo =
UserLocalAlloc(0,
sizeof(*KeyValueInfo) + cjData))
01071 {
01072
01073
for (iFontT1 = 0; iFontT1 < KeyInfoType1.Values; iFontT1++)
01074 {
01075 RtlZeroMemory(KeyValueBasicInfo->Name, cjMaxValueNameT1);
01076
Status =
NtEnumerateValueKey(
01077 hkeyType1,
01078 iFontT1,
01079 KeyValueBasicInformation,
01080 KeyValueBasicInfo,
01081
sizeof(*KeyValueBasicInfo) + cjMaxValueNameT1,
01082 &dwReturnLength);
01083
01084
if (
NT_SUCCESS(
Status))
01085 {
01086 UserAssert(KeyValueBasicInfo->NameLength <= KeyInfoType1.MaxValueNameLen);
01087 UserAssert(KeyValueBasicInfo->Type == REG_MULTI_SZ);
01088
01089
01090
01091
01092
01093 bRet =
bCheckAndDeleteTTF(hkeyFonts, &KeyInfoFonts, KeyValueInfo,
01094 KeyValueBasicInfo, cjData);
01095
if (!bRet)
01096 {
01097 bError =
TRUE;
01098 }
01099 }
01100 }
01101
UserLocalFree(KeyValueInfo);
01102
01103
if (KeyInfoType1.Values == 0)
01104 {
01105 bRet =
TRUE;
01106 }
01107 }
01108 }
01109
NtClose(hkeyFonts);
01110 }
01111
UserLocalFree(KeyValueBasicInfo);
01112 }
01113 }
01114
NtClose(hkeyType1);
01115 }
01116
01117
return (bRet && !bError);
01118 }
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 VOID vCleanConvertedTTFs()
01133 {
01134
BOOL bNeedUpgrade =
FALSE;
01135 UNICODE_STRING UnicodeString;
01136 OBJECT_ATTRIBUTES ObjA;
01137
DWORD dwReturnLength;
01138
NTSTATUS Status;
01139 HKEY hkeyUpgradeType1 =
NULL;
01140
01141
struct {
01142 KEY_VALUE_PARTIAL_INFORMATION;
01143 LARGE_INTEGER;
01144 } UpgradeValueInfo;
01145
DWORD UpgradeValue = 0;
01146
01147
RtlInitUnicodeString(&UnicodeString,
pwszUpdType1Key);
01148 InitializeObjectAttributes(&ObjA,
01149 &UnicodeString,
01150 OBJ_CASE_INSENSITIVE,
01151
NULL,
01152
NULL);
01153
01154
Status =
NtOpenKey(&hkeyUpgradeType1,
01155 KEY_READ | KEY_WRITE,
01156 &ObjA);
01157
01158
if (!
NT_SUCCESS(
Status))
01159 {
01160
01161
01162
01163
DWORD dwDisposition;
01164
01165
Status =
NtCreateKey(&hkeyUpgradeType1,
01166 KEY_WRITE,
01167 &ObjA,
01168 0,
01169
NULL,
01170 REG_OPTION_NON_VOLATILE,
01171 &dwDisposition);
01172
if (
NT_SUCCESS(
Status))
01173 {
01174 bNeedUpgrade =
TRUE;
01175 }
01176 }
01177
else
01178 {
01179
RtlInitUnicodeString(&UnicodeString,
UPGRADED_TYPE1);
01180
Status =
NtQueryValueKey(hkeyUpgradeType1,
01181 &UnicodeString,
01182 KeyValuePartialInformation,
01183 &UpgradeValueInfo,
01184
sizeof(UpgradeValueInfo),
01185 &dwReturnLength);
01186
01187
if (
NT_SUCCESS(
Status))
01188 {
01189 UserAssert(UpgradeValueInfo.Type == REG_DWORD);
01190 UserAssert(UpgradeValueInfo.DataLength ==
sizeof(UpgradeValue));
01191 RtlCopyMemory(&UpgradeValue, &UpgradeValueInfo.Data,
sizeof(UpgradeValue));
01192
01193
01194
if (UpgradeValue == 0)
01195 {
01196 bNeedUpgrade =
TRUE;
01197 }
01198 }
01199 }
01200
01201
if (bNeedUpgrade)
01202 {
01203
if (
bCleanConvertedTTFs())
01204 {
01205 UpgradeValue = 1;
01206 }
01207
01208
RtlInitUnicodeString(&UnicodeString,
UPGRADED_TYPE1);
01209
Status =
NtSetValueKey(hkeyUpgradeType1,
01210 &UnicodeString,
01211 0,
01212 REG_DWORD,
01213 &UpgradeValue,
01214
sizeof(UpgradeValue));
01215 UserAssert(
NT_SUCCESS(
Status));
01216 }
01217
01218
if (hkeyUpgradeType1)
01219 {
01220
NtClose(hkeyUpgradeType1);
01221 }
01222 }
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 VOID vFontSweep()
01238 {
01239
01240
01241
gbWin31Upgrade =
bCheckIfDualBootingWithWin31();
01242
01243
01244
01245
01246
vCleanConvertedTTFs();
01247
01248
01249
01250
vSweepFonts(
pwszFontsKey,
pwszSweepKey,
vProcessFontEntry,
FALSE);
01251
01252
01253
01254
vSweepFonts(
pwszType1Key,
pwszSweepType1Key,
vProcessType1FontEntry,
FALSE);
01255
01256
01257
01258
01259
if (
gpwcSystemDir)
01260 {
01261 LocalFree(
gpwcSystemDir);
01262
gpwcSystemDir =
NULL;
01263 }
01264
01265 }
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277 VOID vLoadT1Fonts(PFNENTRY pfnProcessFontEntry)
01278 {
01279
01280
if (
bLoadableFontDrivers())
01281 {
01282
#if DBGSWEEP
01283
DbgPrint(
"vLoadT1Fonts(0x%lx) was called\n", pfnProcessFontEntry);
01284
#endif
01285
01286
01287
vSweepFonts(
pwszType1Key,
pwszSweepType1Key, pfnProcessFontEntry,
TRUE);
01288
01289
01290
01291
01292
if (
gpwcSystemDir)
01293 {
01294 LocalFree(
gpwcSystemDir);
01295
gpwcSystemDir =
NULL;
01296 }
01297 }
01298 }
01299
01300 VOID vLoadLocalT1Fonts()
01301 {
01302
vLoadT1Fonts(
vAddLocalType1Font);
01303 }
01304
01305 VOID vLoadRemoteT1Fonts()
01306 {
01307
vLoadT1Fonts(
vAddRemoteType1Font);
01308 }