mirror of https://github.com/lianthony/NT4.0
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.
504 lines
11 KiB
504 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
intl.c
|
|
|
|
Abstract:
|
|
|
|
Module with code for NLS-related stuff.
|
|
This module is designed to be used with intl.inf and font.inf
|
|
by control panel applets.
|
|
|
|
Author:
|
|
|
|
Ted Miller (tedm) 15-Aug-1995
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "setupp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
//
|
|
// This structure and the callback function below are used to set the
|
|
// hidden attribute bit on certain font files. That bit causes the font folder
|
|
// app to not autoinstall these files.
|
|
//
|
|
typedef struct _FONTQCONTEXT {
|
|
PVOID SetupQueueContext;
|
|
HINF FontInf;
|
|
} FONTQCONTEXT, *PFONTQCONTEXT;
|
|
|
|
PCWSTR szHiddenFontFiles = L"HiddenFontFiles";
|
|
|
|
UINT
|
|
pSetupFontQueueCallback(
|
|
IN PFONTQCONTEXT Context,
|
|
IN UINT Notification,
|
|
IN UINT Param1,
|
|
IN UINT Param2
|
|
)
|
|
{
|
|
PFILEPATHS FilePaths;
|
|
PWCHAR p;
|
|
INFCONTEXT InfContext;
|
|
|
|
//
|
|
// If a file is finished being copied, set its attributes
|
|
// to include the hidden attribute if necessary.
|
|
//
|
|
if((Notification == SPFILENOTIFY_ENDCOPY)
|
|
&& (FilePaths = (PFILEPATHS)Param1)
|
|
&& (FilePaths->Win32Error == NO_ERROR)
|
|
&& (p = wcsrchr(FilePaths->Target,L'\\'))
|
|
&& SetupFindFirstLine(Context->FontInf,szHiddenFontFiles,p+1,&InfContext)) {
|
|
|
|
SetFileAttributes(FilePaths->Target,FILE_ATTRIBUTE_HIDDEN);
|
|
}
|
|
|
|
return(SetupDefaultQueueCallback(Context->SetupQueueContext,Notification,Param1,Param2));
|
|
}
|
|
|
|
|
|
VOID
|
|
pSetupMarkHiddenFonts(
|
|
VOID
|
|
)
|
|
{
|
|
HINF hInf;
|
|
INFCONTEXT InfContext;
|
|
BOOL b;
|
|
WCHAR Path[MAX_PATH];
|
|
PWCHAR p;
|
|
PCWSTR q;
|
|
int Space;
|
|
|
|
hInf = SetupOpenInfFile(L"FONT.INF",NULL,INF_STYLE_WIN4,NULL);
|
|
if(hInf != INVALID_HANDLE_VALUE) {
|
|
|
|
GetWindowsDirectory(Path,MAX_PATH);
|
|
lstrcat(Path,L"\\FONTS\\");
|
|
p = Path + lstrlen(Path);
|
|
Space = MAX_PATH - (p - Path);
|
|
|
|
if(SetupFindFirstLine(hInf,szHiddenFontFiles,NULL,&InfContext)) {
|
|
|
|
do {
|
|
if(q = pSetupGetField(&InfContext,0)) {
|
|
|
|
lstrcpyn(p,q,Space);
|
|
if(FileExists(Path,NULL)) {
|
|
SetFileAttributes(Path,FILE_ATTRIBUTE_HIDDEN);
|
|
}
|
|
}
|
|
|
|
} while(SetupFindNextLine(&InfContext,&InfContext));
|
|
}
|
|
|
|
SetupCloseInfFile(hInf);
|
|
}
|
|
}
|
|
|
|
|
|
DWORD
|
|
pSetupNLSInstallFonts(
|
|
IN HWND Window,
|
|
IN HINF InfHandle,
|
|
IN PCWSTR OemCodepage,
|
|
IN PCWSTR FontSize,
|
|
IN HSPFILEQ FileQueue
|
|
)
|
|
{
|
|
BOOL b;
|
|
WCHAR SectionName[64];
|
|
|
|
//
|
|
// Form section name.
|
|
//
|
|
wsprintf(SectionName,L"Font.CP%s.%s",OemCodepage,FontSize);
|
|
|
|
if(FileQueue) {
|
|
//
|
|
// First pass: just enqueue files for copy.
|
|
//
|
|
b = SetupInstallFilesFromInfSection(
|
|
InfHandle,
|
|
NULL,
|
|
FileQueue,
|
|
SectionName,
|
|
NULL,
|
|
SP_COPY_NEWER
|
|
);
|
|
} else {
|
|
//
|
|
// Second pass: do registry munging, etc.
|
|
//
|
|
b = SetupInstallFromInfSection(
|
|
Window,
|
|
InfHandle,
|
|
SectionName,
|
|
SPINST_ALL & ~SPINST_FILES,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
return(b ? NO_ERROR : GetLastError());
|
|
}
|
|
|
|
|
|
DWORD
|
|
pSetupNLSLoadInfs(
|
|
OUT HINF *FontInfHandle,
|
|
OUT HINF *IntlInfHandle OPTIONAL
|
|
)
|
|
{
|
|
HINF fontInfHandle;
|
|
HINF intlInfHandle;
|
|
DWORD d;
|
|
|
|
fontInfHandle = SetupOpenInfFile(L"font.inf",NULL,INF_STYLE_WIN4,NULL);
|
|
if(fontInfHandle == INVALID_HANDLE_VALUE) {
|
|
d = GetLastError();
|
|
goto c0;
|
|
}
|
|
|
|
if(!SetupOpenAppendInfFile(NULL,fontInfHandle,NULL)) {
|
|
d = GetLastError();
|
|
goto c1;
|
|
}
|
|
|
|
if(IntlInfHandle) {
|
|
intlInfHandle = SetupOpenInfFile(L"intl.inf",NULL,INF_STYLE_WIN4,NULL);
|
|
if(intlInfHandle == INVALID_HANDLE_VALUE) {
|
|
d = GetLastError();
|
|
goto c1;
|
|
}
|
|
|
|
if(!SetupOpenAppendInfFile(NULL,intlInfHandle,NULL)) {
|
|
d = GetLastError();
|
|
goto c2;
|
|
}
|
|
|
|
*IntlInfHandle = intlInfHandle;
|
|
}
|
|
|
|
*FontInfHandle = fontInfHandle;
|
|
return(NO_ERROR);
|
|
|
|
c2:
|
|
SetupCloseInfFile(intlInfHandle);
|
|
c1:
|
|
SetupCloseInfFile(fontInfHandle);
|
|
c0:
|
|
return(d);
|
|
}
|
|
|
|
|
|
DWORD
|
|
SetupChangeLocale(
|
|
IN HWND Window,
|
|
IN LCID NewLocale
|
|
)
|
|
{
|
|
DWORD d;
|
|
BOOL b;
|
|
HINF IntlInfHandle;
|
|
INFCONTEXT InfContext;
|
|
WCHAR Codepage[24];
|
|
WCHAR NewLocaleString[24];
|
|
FONTQCONTEXT QueueContext;
|
|
HSPFILEQ FileQueue;
|
|
PCWSTR SizeSpec;
|
|
HDC hdc;
|
|
PCWSTR p;
|
|
|
|
|
|
SizeSpec = L"96";
|
|
if(hdc = CreateDC(L"DISPLAY",NULL,NULL,NULL)) {
|
|
if(GetDeviceCaps(hdc,LOGPIXELSY) > 108) {
|
|
SizeSpec = L"120";
|
|
}
|
|
|
|
DeleteDC(hdc);
|
|
}
|
|
|
|
//
|
|
// Load inf files.
|
|
//
|
|
d = pSetupNLSLoadInfs(&QueueContext.FontInf,&IntlInfHandle);
|
|
if(d != NO_ERROR) {
|
|
goto c0;
|
|
}
|
|
|
|
//
|
|
// Get oem codepage for the locale. This is also a sanity check
|
|
// to see that the locale is supported.
|
|
//
|
|
wsprintf(NewLocaleString,L"%.8x",NewLocale);
|
|
if(!SetupFindFirstLine(IntlInfHandle,L"Locales",NewLocaleString,&InfContext)) {
|
|
d = ERROR_INVALID_PARAMETER;
|
|
goto c1;
|
|
}
|
|
|
|
p = pSetupGetField(&InfContext,2);
|
|
if(!p) {
|
|
d = ERROR_INVALID_PARAMETER;
|
|
goto c1;
|
|
}
|
|
//
|
|
// Copy into local storage since p points into internal structures
|
|
// that could move as we call INF APIs
|
|
//
|
|
lstrcpyn(Codepage,p,sizeof(Codepage)/sizeof(Codepage[0]));
|
|
|
|
//
|
|
// Create a setup file queue and initialize default Setup copy queue
|
|
// callback context.
|
|
//
|
|
FileQueue = SetupOpenFileQueue();
|
|
if(!FileQueue || (FileQueue == INVALID_HANDLE_VALUE)) {
|
|
d = ERROR_OUTOFMEMORY;
|
|
goto c1;
|
|
}
|
|
|
|
QueueContext.SetupQueueContext = SetupInitDefaultQueueCallback(Window);
|
|
if(!QueueContext.SetupQueueContext) {
|
|
d = ERROR_OUTOFMEMORY;
|
|
goto c2;
|
|
}
|
|
|
|
//
|
|
// Enqueue locale-related files for copy.
|
|
//
|
|
b = SetupInstallFilesFromInfSection(
|
|
IntlInfHandle,
|
|
NULL,
|
|
FileQueue,
|
|
NewLocaleString,
|
|
NULL,
|
|
SP_COPY_NEWER
|
|
);
|
|
|
|
if(!b) {
|
|
d = GetLastError();
|
|
goto c3;
|
|
}
|
|
|
|
//
|
|
// Enqueue font-related files for copy.
|
|
//
|
|
d = pSetupNLSInstallFonts(Window,QueueContext.FontInf,Codepage,SizeSpec,FileQueue);
|
|
if(d != NO_ERROR) {
|
|
goto c3;
|
|
}
|
|
|
|
//
|
|
// Determine whether the queue actually needs to be committed.
|
|
//
|
|
b = SetupScanFileQueue(
|
|
FileQueue,
|
|
SPQ_SCAN_FILE_VALIDITY | SPQ_SCAN_INFORM_USER,
|
|
Window,
|
|
NULL,
|
|
NULL,
|
|
&d
|
|
);
|
|
|
|
if(!b) {
|
|
d = GetLastError();
|
|
goto c3;
|
|
}
|
|
|
|
//
|
|
// d = 0: User wants new files or some files were missing;
|
|
// Must commit queue.
|
|
//
|
|
// d = 1: User wants to use existing files and queue is empty;
|
|
// Can skip committing queue.
|
|
//
|
|
// d = 2: User wants to use existing files but del/ren queues not empty.
|
|
// Must commit queue. The copy queue will have been emptied,
|
|
// so only del/ren functions will be performed.
|
|
//
|
|
if(d == 1) {
|
|
|
|
b = TRUE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Copy enqueued files.
|
|
//
|
|
b = SetupCommitFileQueue(
|
|
Window,
|
|
FileQueue,
|
|
pSetupFontQueueCallback,
|
|
&QueueContext
|
|
);
|
|
}
|
|
|
|
if(!b) {
|
|
d = GetLastError();
|
|
goto c3;
|
|
}
|
|
|
|
//
|
|
// Complete installation of locale stuff.
|
|
//
|
|
b = SetupInstallFromInfSection(
|
|
Window,
|
|
IntlInfHandle,
|
|
NewLocaleString,
|
|
SPINST_ALL & ~SPINST_FILES,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if(!b) {
|
|
d = GetLastError();
|
|
goto c3;
|
|
}
|
|
|
|
//
|
|
// Perform font magic associated with the new locale's codepage(s).
|
|
//
|
|
d = pSetupNLSInstallFonts(Window,QueueContext.FontInf,Codepage,SizeSpec,NULL);
|
|
|
|
c3:
|
|
SetupTermDefaultQueueCallback(QueueContext.SetupQueueContext);
|
|
c2:
|
|
SetupCloseFileQueue(FileQueue);
|
|
c1:
|
|
SetupCloseInfFile(QueueContext.FontInf);
|
|
SetupCloseInfFile(IntlInfHandle);
|
|
c0:
|
|
return(d);
|
|
}
|
|
|
|
|
|
DWORD
|
|
SetupChangeFontSize(
|
|
IN HWND Window,
|
|
IN PCWSTR SizeSpec
|
|
)
|
|
{
|
|
DWORD d;
|
|
WCHAR cp[24];
|
|
FONTQCONTEXT QueueContext;
|
|
HSPFILEQ FileQueue;
|
|
BOOL b;
|
|
|
|
//
|
|
// BUGBUG do we really want the current OEM CP?
|
|
//
|
|
wsprintf(cp,L"%u",GetOEMCP());
|
|
|
|
//
|
|
// Load NLS inf.
|
|
//
|
|
d = pSetupNLSLoadInfs(&QueueContext.FontInf,NULL);
|
|
if(d != NO_ERROR) {
|
|
goto c0;
|
|
}
|
|
|
|
//
|
|
// Create queue and initialize default callback routine.
|
|
//
|
|
FileQueue = SetupOpenFileQueue();
|
|
if(!FileQueue || (FileQueue == INVALID_HANDLE_VALUE)) {
|
|
d = ERROR_OUTOFMEMORY;
|
|
goto c1;
|
|
}
|
|
|
|
QueueContext.SetupQueueContext = SetupInitDefaultQueueCallback(Window);
|
|
if(!QueueContext.SetupQueueContext) {
|
|
d = ERROR_OUTOFMEMORY;
|
|
goto c2;
|
|
}
|
|
|
|
//
|
|
// First pass: copy files.
|
|
//
|
|
d = pSetupNLSInstallFonts(Window,QueueContext.FontInf,cp,SizeSpec,FileQueue);
|
|
if(d != NO_ERROR) {
|
|
goto c3;
|
|
}
|
|
|
|
//
|
|
// Determine whether the queue actually needs to be committed.
|
|
//
|
|
b = SetupScanFileQueue(
|
|
FileQueue,
|
|
SPQ_SCAN_FILE_VALIDITY | SPQ_SCAN_INFORM_USER,
|
|
Window,
|
|
NULL,
|
|
NULL,
|
|
&d
|
|
);
|
|
|
|
if(!b) {
|
|
d = GetLastError();
|
|
goto c3;
|
|
}
|
|
|
|
//
|
|
// d = 0: User wants new files or some files were missing;
|
|
// Must commit queue.
|
|
//
|
|
// d = 1: User wants to use existing files and queue is empty;
|
|
// Can skip committing queue.
|
|
//
|
|
// d = 2: User wants to use existing files but del/ren queues not empty.
|
|
// Must commit queue. The copy queue will have been emptied,
|
|
// so only del/ren functions will be performed.
|
|
//
|
|
if(d == 1) {
|
|
|
|
b = TRUE;
|
|
|
|
} else {
|
|
|
|
b = SetupCommitFileQueue(
|
|
Window,
|
|
FileQueue,
|
|
pSetupFontQueueCallback,
|
|
&QueueContext
|
|
);
|
|
}
|
|
|
|
if(!b) {
|
|
d = GetLastError();
|
|
goto c3;
|
|
}
|
|
|
|
//
|
|
// Second pass: perform registry munging, etc.
|
|
//
|
|
d = pSetupNLSInstallFonts(Window,QueueContext.FontInf,cp,SizeSpec,NULL);
|
|
|
|
c3:
|
|
SetupTermDefaultQueueCallback(QueueContext.SetupQueueContext);
|
|
c2:
|
|
SetupCloseFileQueue(FileQueue);
|
|
c1:
|
|
SetupCloseInfFile(QueueContext.FontInf);
|
|
c0:
|
|
return(d);
|
|
}
|
|
|