windows-nt/Source/XPSP1/NT/base/ntsetup/books/ntbooks.c
2020-09-26 16:20:57 +08:00

712 lines
15 KiB
C

/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
books.c
Abstract:
Main module for on-line reference books installation/invocation.
Author:
Ted Miller (tedm) 5-Jan-1995
Revision History:
--*/
#include "books.h"
#include <setupapi.h>
#include <stdlib.h>
WCHAR TagFile[MAX_PATH];
WCHAR CdRomName[250];
//
// Module handle
//
HANDLE hInst;
//
// Handle of main icon.
//
HICON MainIcon;
//
// Command line parameters
//
ForceProduct CmdLineForce = ForceNone;
BOOL CmdLineForcePrompt = FALSE;
typedef struct _PROMPTDIALOGPARAMS {
PWSTR MainMessage;
PWSTR InitialLocation;
PWSTR FinalLocation;
} PROMPTDIALOGPARAMS, *PPROMPTDIALOGPARAMS;
INT_PTR
CALLBACK
DlgProcPrompt(
IN HWND hdlg,
IN UINT msg,
IN WPARAM wParam,
IN LPARAM lParam
);
VOID
FixupNames(
VOID
);
VOID
DoBooks(
IN WCHAR CdRomDrive,
IN PWSTR PreviousLocation
);
BOOL
ParseArgs(
IN int argc,
IN char *argv[]
);
VOID
Usage(
VOID
);
int
__cdecl
main(
IN int argc,
IN char *argv[]
)
{
PWSTR BooksLocation;
WCHAR CdRomDrive;
WCHAR Path[MAX_PATH];
hInst = GetModuleHandle(NULL);
MainIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_MAIN));
if(!ParseArgs(argc,argv)) {
Usage();
}
FixupNames();
//
// Get BooksLocation profile value.
//
BooksLocation = MyGetProfileValue(BooksProfileLocation,L"");
if (!BooksLocation[0] && !CmdLineForcePrompt) {
//
// Look for the Help file in its normal location and make
// sure it's present. If it is, set BooksLocation.
//
WCHAR pwcsHelpPath[_MAX_PATH];
if (GetWindowsDirectory(pwcsHelpPath, _MAX_PATH)) {
lstrcat(pwcsHelpPath, L"\\Help");
if (DoesFileExist(pwcsHelpPath))
BooksLocation = DupString(pwcsHelpPath);
}
}
if(BooksLocation[0] && !CmdLineForcePrompt) {
//
// BooksLocation has been set previously. This is no guarantee that
// the location is currently accessible. Check to see if the help file
// is available. If not we will prompt the user.
//
if(CheckHelpfilePresent(BooksLocation)) {
//
// The help file is accessible. Fire up winhelp.
//
FireUpWinhelp(0,BooksLocation);
} else {
//
// The help file is not currently accessible.
//
DoBooks(LocateCdRomDrive(),BooksLocation);
}
} else {
//
// Books location was not specified already.
// In this case look for a cd-rom drive.
//
if(CdRomDrive = LocateCdRomDrive()) {
//
// Form the path of the helpfile on the CD
//
Path[0] = CdRomDrive;
Path[1] = L':';
Path[2] = 0;
lstrcat(Path,PathOfBooksFilesOnCd);
//
// Found a cd-rom drive. Look for the relevent nt cd in there
// and make sure the help file is there too just for good measure.
//
if(!CmdLineForcePrompt
&& IsCdRomInDrive(CdRomDrive,TagFile)
&& CheckHelpfilePresent(Path))
{
//
// The nt cd-rom is in there. Fire up winhelp.
//
FireUpWinhelp(CdRomDrive,PathOfBooksFilesOnCd);
} else {
//
// Prompt for the nt cd-rom, or an alternate location.
//
DoBooks(CdRomDrive,NULL);
}
} else {
//
// No cd-rom drive; prompt for an alternate location.
//
DoBooks(0,NULL);
}
}
return 0;
}
VOID
Usage(
VOID
)
{
MyError(NULL,IDS_USAGE,TRUE);
}
BOOL
ParseArgs(
IN int argc,
IN char *argv[]
)
{
int i;
for(argc--,i=1; argc; argc--,i++) {
if((argv[i][0] == '-') || (argv[i][0] == '/')) {
switch(argv[i][1]) {
case 's':
case 'S':
//
// accept /s or /server
//
if(!argv[i][2]) {
CmdLineForce = ForceServer;
} else {
if(lstrcmpiA(argv[i]+1,"server")) {
return(FALSE);
}
CmdLineForce = ForceServer;
}
break;
case 'w':
case 'W':
//
// accept /w or /workstation
//
if(!argv[i][2]) {
CmdLineForce = ForceWorkstation;
} else {
if(lstrcmpiA(argv[i]+1,"workstation")) {
return(FALSE);
}
CmdLineForce = ForceWorkstation;
}
break;
case 'n':
case 'N':
//
// Ignore remembered location (ie, *N*ew location)
//
if(argv[i][2]) {
return(FALSE);
} else {
CmdLineForcePrompt = TRUE;
}
break;
default:
return(FALSE);
}
} else {
//
// All args are switches
//
return(FALSE);
}
}
return(TRUE);
}
VOID
DoBooks(
IN WCHAR CdRomDrive,
IN PWSTR PreviousLocation
)
{
DWORD Id;
INT_PTR DialogReturn;
WCHAR CurrentDirectory[MAX_PATH];
// UINT DriveType;
PROMPTDIALOGPARAMS Params;
//
// The dialog looks slightly different depending on
// whether there is a CD-ROM drive in the system.
//
// If there is we say something like "insert the cdrom in
// the drive or give an alternate location." If there is not
// we say something like "tell us where the files are."
//
//retry:
if(PreviousLocation) {
Id = CdRomDrive ? MSG_PROMPT_CD : MSG_PROMPT_NO_CD;
Params.InitialLocation = PreviousLocation;
} else {
Id = CdRomDrive ? MSG_PROMPT_CD_FIRST : MSG_PROMPT_NO_CD_FIRST;
if(CdRomDrive) {
wsprintf(CurrentDirectory,L"%c:%s",CdRomDrive,PathOfBooksFilesOnCd);
} else {
GetCurrentDirectory(
sizeof(CurrentDirectory)/sizeof(CurrentDirectory[0]),
CurrentDirectory
);
}
Params.InitialLocation = CurrentDirectory;
}
Params.MainMessage = RetreiveMessage(Id,PreviousLocation,CdRomName);
DialogReturn = DialogBoxParam(
hInst,
MAKEINTRESOURCE(DLG_PROMPT),
NULL,
DlgProcPrompt,
(LPARAM)&Params
);
MyFree(Params.MainMessage);
if(DialogReturn) {
//
// Removed the copy stuff for now, as it's not done yet
// and not likely to be completed any time soon.
//
#if 0
//
// If the path is a UNC path this should be 0 (drive type unknown)
// so the test below will work just fine
//
DriveType = MyGetDriveType(Params.FinalLocation[0]);
//
// If there is no previous location and the files are
// not on a local hard drive offer to install them on
// the hard drive.
//
// Treat removable drives like hard drives, because it's unlikely
// the files are on a floppy and removable hard drives come back as
// DRIVE_REMOVABLE, not DRIVE_FIXED.
//
if(!PreviousLocation && (DriveType != DRIVE_FIXED) && (DriveType != DRIVE_REMOVABLE)) {
if(!DoInstall(&Params.FinalLocation)) {
MyFree(Params.FinalLocation);
PreviousLocation = NULL;
goto retry;
}
}
#endif
FireUpWinhelp(0,Params.FinalLocation);
}
}
VOID
FixupNames(
VOID
)
{
HKEY hKey;
LONG l;
DWORD DataType;
WCHAR Data[128];
DWORD DataSize;
BOOL IsServer;
BOOL b;
UINT SourceId;
HINF Inf;
//
// Figure out if this is a server or workstation and fix up
// the global cd-rom name and tagfile variables accordingly.
//
// Open HKLM\System\CCS\Control\ProductOptions and check ProductType value.
// If it's 'winnt' then this is a workststion. Otherwise assume server.
//
switch(CmdLineForce) {
case ForceServer:
IsServer = TRUE;
break;
case ForceWorkstation:
IsServer = FALSE;
break;
case ForceNone:
default:
IsServer= FALSE;
l = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Control\\ProductOptions",
0,
KEY_READ,
&hKey
);
if(l == NO_ERROR) {
DataSize = sizeof(Data)/sizeof(Data[0]);
l = RegQueryValueEx(
hKey,
L"ProductType",
0,
&DataType,
(LPBYTE)Data,
&DataSize
);
RegCloseKey(hKey);
if((l == NO_ERROR) && (DataType == REG_SZ) && lstrcmpi(Data,L"winnt")) {
IsServer = TRUE;
}
}
break;
}
if(IsServer) {
HelpFileName = L"WINDOWS.CHM";
BooksProfileLocation = L"ServerBooksLocation";
} else {
HelpFileName = L"WINDOWS.CHM";
BooksProfileLocation = L"WorkstationBooksLocation";
}
//
// Get information about the NT CD-ROM. We assume that the books files
// are on the same CD as the basic system, which also must have
// ntoskrnl.exe on it.
//
b = FALSE;
Inf = SetupOpenMasterInf();
if(Inf != INVALID_HANDLE_VALUE) {
if(SetupGetSourceFileLocation(Inf,NULL,L"NTOSKRNL.EXE",&SourceId,NULL,0,NULL)) {
b = SetupGetSourceInfo(
Inf,
SourceId,
SRCINFO_TAGFILE,
TagFile,
sizeof(TagFile)/sizeof(WCHAR),
NULL
);
if(b) {
b = SetupGetSourceInfo(
Inf,
SourceId,
SRCINFO_DESCRIPTION,
CdRomName,
sizeof(CdRomName)/sizeof(WCHAR),
NULL
);
}
}
SetupCloseInfFile(Inf);
}
if(!b) {
MyError(NULL,IDS_LAYOUT_INF_DAMAGED,TRUE);
}
}
////////////////////////////////////////////////////////
PWSTR PropertyName = L"__mydlgparams";
BOOL
PromptDialogOk(
IN HWND hdlg
)
{
WCHAR Location[MAX_PATH];
UINT Length;
PPROMPTDIALOGPARAMS DlgParams;
DlgParams = (PPROMPTDIALOGPARAMS)GetProp(hdlg,PropertyName);
//
// Get the text the user has typed into the edit control
// as the location of the files.
//
Length = GetDlgItemText(hdlg,IDC_LOCATION,Location,MAX_PATH);
//
// Remove trailing backslash if any.
//
if(Length && (Location[Length-1] == L'\\')) {
Location[Length-1] = 0;
}
//
// See whether the online books help file is at that location.
//
if(CheckHelpfilePresent(Location)) {
DlgParams->FinalLocation = DupString(Location);
return(TRUE);
}
//
// See whether the online books help file is in the subdirectory
// where it would be on the CD.
//
lstrcat(Location,PathOfBooksFilesOnCd);
if(CheckHelpfilePresent(Location)) {
DlgParams->FinalLocation = DupString(Location);
return(TRUE);
}
return(FALSE);
}
BOOL
PromptDialogBrowse(
IN HWND hdlg
)
{
BOOL b;
OPENFILENAME on;
WCHAR Filter[256];
WCHAR Location[MAX_PATH];
PWSTR Title;
WCHAR InitialDir[MAX_PATH];
PWSTR p;
DWORD len;
p = MyLoadString(IDS_FILETYPE_NAME);
lstrcpy(Filter,p);
MyFree(p);
len = lstrlen(Filter)+1;
lstrcpy(Filter+len,HelpFileName);
len += lstrlen(HelpFileName) + 1;
Filter[len] = 0;
lstrcpy(Location,HelpFileName);
Title = MyLoadString(IDS_BROWSE_TITLE);
GetDlgItemText(hdlg,IDC_LOCATION,InitialDir,MAX_PATH);
on.lStructSize = sizeof(on);
on.hwndOwner = hdlg;
on.hInstance = hInst;
on.lpstrFilter = Filter;
on.lpstrCustomFilter = NULL;
on.nMaxCustFilter = 0;
on.nFilterIndex = 1;
on.lpstrFile = Location;
on.nMaxFile = MAX_PATH;
on.lpstrFileTitle = NULL;
on.nMaxFileTitle = 0;
on.lpstrInitialDir = InitialDir;
on.lpstrTitle = Title;
on.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
on.nFileOffset = 0;
on.nFileExtension = 0;
on.lpstrDefExt = L"HLP";
on.lCustData = 0;
on.lpfnHook = NULL;
on.lpTemplateName = NULL;
b = GetOpenFileName(&on);
MyFree(Title);
if(b) {
//
// User said ok. The full path of the help file is in
// Location. Ignore the actual filename; the path is
// what we want.
//
Location[on.nFileOffset ? on.nFileOffset-1 : 0] = 0;
//
// Set the text in the edit cntrol so the dialog
// can fetch it later.
//
SetDlgItemText(hdlg,IDC_LOCATION,Location);
}
return b;
}
INT_PTR
CALLBACK
DlgProcPrompt(
IN HWND hdlg,
IN UINT msg,
IN WPARAM wParam,
IN LPARAM lParam
)
{
PPROMPTDIALOGPARAMS DlgParams;
switch(msg) {
case WM_INITDIALOG:
CenterDialogOnScreen(hdlg);
DlgParams = (PPROMPTDIALOGPARAMS)lParam;
//
// Set the main text message.
//
SetDlgItemText(hdlg,IDT_MAIN_CAPTION,DlgParams->MainMessage);
//
// Set the text in the edit control and select all of it.
// Also set focus to that control.
//
SetDlgItemText(hdlg,IDC_LOCATION,DlgParams->InitialLocation);
SendDlgItemMessage(hdlg,IDC_LOCATION,EM_SETSEL,0,(LPARAM)(-1));
SendDlgItemMessage(hdlg,IDC_LOCATION,EM_LIMITTEXT,MAX_PATH-1,0);
SetFocus(GetDlgItem(hdlg,IDC_LOCATION));
//
// Remember the init params
//
if(!SetProp(hdlg,PropertyName,(HANDLE)lParam)) {
OutOfMemory();
}
//
// Tell windows we set the focus.
//
return(FALSE);
case WM_COMMAND:
switch(HIWORD(wParam)) {
case BN_CLICKED:
switch(LOWORD(wParam)) {
case IDB_BROWSE:
if(!PromptDialogBrowse(hdlg)) {
break;
}
// FALL THROUGH IF BROWSE WAS SUCCESSFUL
case IDOK:
if(PromptDialogOk(hdlg)) {
EndDialog(hdlg,TRUE);
} else {
MyError(hdlg,IDS_BAD_LOCATION,FALSE);
}
return(FALSE);
case IDCANCEL:
EndDialog(hdlg,FALSE);
return(FALSE);
}
break;
}
break;
case WM_QUERYDRAGICON:
return(MainIcon != NULL);
default:
return(FALSE);
}
return(TRUE);
}