windows-nt/Source/XPSP1/NT/base/ntsetup/opktools/setupmgr/oc/scsi.c
2020-09-26 16:20:57 +08:00

797 lines
22 KiB
C

//----------------------------------------------------------------------------
//
// Copyright (c) 1997-1999 Microsoft Corporation
// All rights reserved.
//
// File Name:
// scsi.c
//
// Description:
// This file contains the dialog procedure for the SCSI files.
// (IDD_SCSI).
//
//----------------------------------------------------------------------------
#include "pch.h"
#include "resource.h"
#define MAX_SCSI_SELECTIONS 1024
#define MAX_SCSI_NAME_LEN 256
#define SCSI_FILE_EXTENSION _T("oem")
#define ALL_FILE_EXTENSION _T("*")
static TCHAR* StrScsiFiles;
static TCHAR* StrAllFiles;
static TCHAR g_szScsiFileFilter[MAX_PATH + 1];
static TCHAR g_szAllFileFilter[MAX_PATH + 1];
//
// This var keeps track of the path to the txtsetup.oem
//
static TCHAR szTxtSetupOemLocation[MAX_PATH];
//
// This var keeps track of if the user has loaded a new txtsetup.oem so we
// know when we need to copy more files over.
//
static BOOL bHasLoadedTxtSetupOem = FALSE;
VOID LoadOriginalSettingsLowHalScsi(HWND hwnd,
LPTSTR lpFileName,
QUEUENUM dwWhichQueue);
static VOID LoadScsiFromTxtsetupOem( IN HWND hwnd,
IN TCHAR *szTxtSetupOemPath );
//----------------------------------------------------------------------------
//
// Function: OnScsiInitDialog
//
// Purpose:
//
// Arguments: HWND hwnd - handle to the dialog box
//
// Returns: VOID
//
//----------------------------------------------------------------------------
static VOID
OnScsiInitDialog( IN HWND hwnd )
{
HRESULT hrPrintf;
//
// Load the resource strings
//
StrScsiFiles = MyLoadString( IDS_SCSI_FILES );
StrAllFiles = MyLoadString( IDS_ALL_FILES );
//
// Build the text file filter string
//
//
// The question marks (?) are just placehoders for where the NULL char
// will be inserted.
//
hrPrintf=StringCchPrintf( g_szScsiFileFilter,AS(g_szScsiFileFilter),
_T("%s (*.oem)?*.oem?%s (*.*)?*.*?"),
StrScsiFiles,
StrAllFiles );
ConvertQuestionsToNull( g_szScsiFileFilter );
hrPrintf=StringCchPrintf( g_szAllFileFilter, AS(g_szAllFileFilter),
_T("%s (*.*)?*.*?"),
StrAllFiles );
ConvertQuestionsToNull( g_szAllFileFilter );
}
//----------------------------------------------------------------------------
//
// Function: OnScsiSetActive
//
// Purpose:
//
// Arguments: HWND hwnd - handle to the dialog box
//
// Returns: VOID
//
//----------------------------------------------------------------------------
static VOID
OnScsiSetActive( IN HWND hwnd ) {
INT_PTR i;
INT_PTR iListBoxCount;
TCHAR szListBoxEntryText[MAX_STRING_LEN];
//
// If we are editing a script and haven't loaded the txtsetup.oem, then
// populate the list box with the entries in the txtsetup.oem
//
if( ! WizGlobals.bNewScript && ! bHasLoadedTxtSetupOem ) {
//
// The OEM files path must be valid if we are going to use it to
// read files.
//
AssertMsg( WizGlobals.OemFilesPath[0] != _T('\0'),
"OEM files path is blank");
//
// Populate the list box with the SCSI entries in txtsetup.oem
//
ConcatenatePaths( szTxtSetupOemLocation,
WizGlobals.OemFilesPath,
_T("Textmode"),
NULL );
LoadScsiFromTxtsetupOem( hwnd, szTxtSetupOemLocation );
//
// Select those entries in the MassStorageDrivers namelist
//
iListBoxCount = SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_GETCOUNT,
0,
0 );
//
// For each entry in the list box, see if its name is in the namelist
// and if it is, then select it.
//
for( i = 0; i < iListBoxCount; i++ ) {
SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_GETTEXT,
i,
(LPARAM) szListBoxEntryText );
if( FindNameInNameList( &GenSettings.MassStorageDrivers,
szListBoxEntryText ) != -1 ) {
SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_SETSEL,
TRUE,
i );
}
}
}
PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK | PSWIZB_NEXT);
}
//----------------------------------------------------------------------------
//
// Function: LoadScsiFromTxtsetupOem
//
// Purpose: Reads the txtsetup.oem in the specified parameter and load the
// SCSI choices into the list box.
//
// Arguments: hwnd - handle to the dialog box
// szTxtSetupOemPath - path to the txtsetup.oem
//
// Returns: VOID
//
//----------------------------------------------------------------------------
static VOID
LoadScsiFromTxtsetupOem( IN HWND hwnd,
IN TCHAR *szTxtSetupOemPath ) {
INT_PTR iIndex;
BOOL bKeepReading;
TCHAR szTxtSetupOemPathAndFilename[MAX_PATH] = _T("");
TCHAR szScsiDriverName[MAX_SCSI_NAME_LEN] = _T("");
TCHAR szScsiFriendlyName[MAX_SCSI_NAME_LEN] = _T("");
HINF hScsiOem;
INFCONTEXT ScsiOemContext = { 0 };
ConcatenatePaths( szTxtSetupOemPathAndFilename,
szTxtSetupOemPath,
OEM_TXTSETUP_NAME,
NULL );
hScsiOem = SetupOpenInfFile( szTxtSetupOemPathAndFilename,
NULL,
INF_STYLE_OLDNT | INF_STYLE_WIN4,
NULL );
if( hScsiOem == INVALID_HANDLE_VALUE ) {
// ISSUE-2002/02/28-stelo- alert an error that we couldn't open the file
return;
}
ScsiOemContext.Inf = hScsiOem;
ScsiOemContext.CurrentInf = hScsiOem;
bKeepReading = SetupFindFirstLine( hScsiOem,
_T("SCSI"),
NULL,
&ScsiOemContext );
//
// For each SCSI entry, add its friendly-name to the list box
//
while( bKeepReading ) {
TCHAR *pScsiDriverName;
SetupGetStringField( &ScsiOemContext,
0,
szScsiDriverName,
MAX_SCSI_NAME_LEN,
NULL );
SetupGetStringField( &ScsiOemContext,
1,
szScsiFriendlyName,
MAX_SCSI_NAME_LEN,
NULL );
//
// Don't allow the adding of a blank name (protection against a bad input file)
//
if( szScsiFriendlyName[0] != _T('\0') ) {
iIndex = SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_ADDSTRING,
0,
(LPARAM) szScsiFriendlyName );
pScsiDriverName = (TCHAR*) malloc( sizeof(szScsiDriverName) );
if (pScsiDriverName == NULL)
TerminateTheWizard(IDS_ERROR_OUTOFMEMORY);
lstrcpyn( pScsiDriverName, szScsiDriverName, AS(szScsiDriverName));
SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_SETITEMDATA,
iIndex,
(LPARAM) pScsiDriverName );
}
//
// move to the next line of the .oem file
//
bKeepReading = SetupFindNextLine( &ScsiOemContext, &ScsiOemContext );
}
SetupCloseInfFile( hScsiOem );
bHasLoadedTxtSetupOem = TRUE;
}
//----------------------------------------------------------------------------
//
// Function: ClearScsiListBox
//
// Purpose: Deallocates memory for all the elements in the SCSI list box and
// clears it.
//
// Arguments: HWND hwnd - handle to the dialog box
//
// Returns: VOID
//
//----------------------------------------------------------------------------
static VOID
ClearScsiListBox( IN HWND hwnd ) {
INT_PTR i;
INT_PTR iListBoxCount;
TCHAR *pData;
iListBoxCount = SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_GETCOUNT,
0,
0 );
for( i = 0; i < iListBoxCount; i++ ) {
pData = (TCHAR *) SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_GETITEMDATA,
i,
0 );
if( pData ) {
free( pData );
}
}
SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_RESETCONTENT,
0,
0 );
}
//----------------------------------------------------------------------------
//
// Function: OnBrowseLoadDriver
//
// Purpose: Creates a browse window for the user to select an OEM driver and
// populates the SCSI list box with the appropriate values
//
// NOTE: the malloc call in here is arguably a bug (memory leak). I
// malloc the memory but never free it. Every malloc they do will be
// <= MAX_PATH and realistically they won't do that many. Once they do
// a load, if they do another load, I free the old memory (see
// ClearScsiListBox) and allocate new memory. So, for the last load
// they do, the memory never gets freed. To do it right,
// we would free the memory at the end of the program but NT does this for
// us anyways when the process gets killed. (so no need to free)
//
// Arguments: HWND hwnd - handle to the dialog box
//
// Returns: VOID
//
//----------------------------------------------------------------------------
static VOID
OnBrowseLoadDriver( IN HWND hwnd ) {
INT iIndex;
BOOL bKeepReading;
BOOL bFileNotFound = TRUE;
TCHAR szTxtSetupOemLocationAndFilename[MAX_PATH] = _T("");
TCHAR szScsiFriendlyName[MAX_SCSI_NAME_LEN] = _T("");
HINF hScsiOem = NULL;
INFCONTEXT ScsiOemContext = { 0 };
TCHAR PathBuffer[MAX_PATH];
INT iRet;
LPTSTR pFileName;
GetCurrentDirectory( MAX_PATH, PathBuffer );
ConcatenatePaths( szTxtSetupOemLocationAndFilename,
szTxtSetupOemLocation,
OEM_TXTSETUP_NAME,
NULL );
//
// Keep asking for a file until we either get a txtsetup.oem or the user
// presses cancel.
//
while( bFileNotFound ) {
iRet = ShowBrowseFolder( hwnd,
g_szScsiFileFilter,
SCSI_FILE_EXTENSION,
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
PathBuffer,
szTxtSetupOemLocationAndFilename );
if ( ! iRet )
return; // user pressed cancel on the dialog
pFileName = MyGetFullPath( szTxtSetupOemLocationAndFilename );
if( pFileName && (LSTRCMPI( pFileName, OEM_TXTSETUP_NAME ) == 0) ) {
bFileNotFound = FALSE; // we have found the file
}
else {
// ISSUE-2002/02/28-stelo-
/*
ReportErrorId(hwnd,
MSGTYPE_ERR | MSGTYPE_WIN32,
,
GenSettings.lpszLogoBitmap, szLogoDestination);
*/
}
}
ClearScsiListBox( hwnd );
//
// Trim the file name off szTxtSetupOemLocationAndFilename so it only
// provides the path to the txtsetup.oem
//
{
TCHAR *p = szTxtSetupOemLocationAndFilename;
while( p != pFileName )
{
p++;
}
*p = _T('\0');
}
lstrcpyn( szTxtSetupOemLocation, szTxtSetupOemLocationAndFilename, AS(szTxtSetupOemLocation) );
//
// Read in from the file OEM file they specified in the browse box and
// add the friendly-name entries to the list box
//
LoadScsiFromTxtsetupOem( hwnd, szTxtSetupOemLocation );
}
//----------------------------------------------------------------------------
//
// Function: CopyFileToDistShare
//
// Purpose: Given a path and file name to one file, it copies that file to
// the given destination path. If the file already exists on the
// destination, then do not make the copy. If the source file name does
// not exist then Browse for it.
//
// Arguments:
// HWND hwnd - handle to the dialog box
// LPTSTR szSrcPath - path file to copy
// LPTSTR szSrcFileName - filename to copy
// LPTSTR szDestPath - path of where file is to be copied
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID
CopyFileToDistShare( IN HWND hwnd,
IN LPTSTR szSrcPath,
IN LPTSTR szSrcFileName,
IN LPTSTR szDestPath ) {
INT iRet;
TCHAR szSrcPathAndName[MAX_PATH] = _T("");
TCHAR szDestPathAndName[MAX_PATH] = _T("");
ConcatenatePaths( szSrcPathAndName,
szSrcPath,
szSrcFileName,
NULL );
ConcatenatePaths( szDestPathAndName,
szDestPath,
szSrcFileName,
NULL );
if( ! DoesFileExist( szSrcPathAndName ) )
{
TCHAR* pFileName;
BOOL bFileFound = FALSE;
do
{
ReportErrorId( hwnd,
MSGTYPE_ERR,
IDS_ERR_SPECIFY_FILE,
szSrcFileName );
iRet = ShowBrowseFolder( hwnd,
g_szAllFileFilter,
ALL_FILE_EXTENSION,
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
szSrcPath,
szSrcPathAndName );
// ISSUE-2002/02/28-stelo- if they press cancel should I warn them that they have to
// copy the file manually?
if ( ! iRet )
return; // user pressed cancel on the dialog
pFileName = MyGetFullPath( szSrcPathAndName );
if( pFileName && ( lstrcmpi( pFileName, szSrcFileName ) == 0 ) ) {
bFileFound = TRUE; // we have found the file
}
} while( ! bFileFound );
}
CopyFile( szSrcPathAndName, szDestPathAndName, TRUE );
SetFileAttributes( szDestPathAndName, FILE_ATTRIBUTE_NORMAL );
}
//----------------------------------------------------------------------------
//
// Function: OnWizNextScsi
//
// Purpose: For every selection in the SCSI list box, copy the files over to
// the distribution share and stores the driver and filenames so they can
// be written out.
//
// Arguments: IN HWND hwnd - handle to the dialog box
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID
OnWizNextScsi( IN HWND hwnd ) {
INT_PTR i;
INT_PTR iNumberSelected;
BOOL bKeepReading;
UINT rgiScsiSelections[MAX_SCSI_SELECTIONS];
TCHAR *pDriverName;
TCHAR szDriverSectionName[MAX_INILINE_LEN];
TCHAR szScsiDriverName[MAX_SCSI_NAME_LEN];
TCHAR szTextmodePath[MAX_PATH] = _T("");
TCHAR szOemFilePathAndName[MAX_PATH] = _T("");
HINF hScsiOem;
INFCONTEXT ScsiOemContext = { 0 };
//
// If they never loaded a txtsetup.oem, then there is no work to do
//
if( bHasLoadedTxtSetupOem == FALSE ) {
return;
}
iNumberSelected = SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_GETSELITEMS,
MAX_SCSI_SELECTIONS,
(LPARAM) rgiScsiSelections );
//
// Prepare to add the new drivers
//
ResetNameList( &GenSettings.MassStorageDrivers );
ConcatenatePaths( szTextmodePath,
WizGlobals.OemFilesPath,
_T("Textmode"),
NULL );
if ( ! EnsureDirExists( szTextmodePath ) )
{
ReportErrorId( hwnd,
MSGTYPE_ERR | MSGTYPE_WIN32,
IDS_ERR_CREATE_FOLDER,
szTextmodePath );
return;
}
ConcatenatePaths( szOemFilePathAndName,
szTxtSetupOemLocation,
OEM_TXTSETUP_NAME,
NULL );
//
// Read the txtsetup.oem file into the txtsetup queue
//
LoadOriginalSettingsLowHalScsi(hwnd,
szOemFilePathAndName,
SETTING_QUEUE_TXTSETUP_OEM);
hScsiOem = SetupOpenInfFile( szOemFilePathAndName,
NULL,
INF_STYLE_OLDNT | INF_STYLE_WIN4,
NULL );
if( hScsiOem == INVALID_HANDLE_VALUE ) {
// ISSUE-2002/02/28-stelo- need to somehow alert an error
return;
}
for( i = 0; i < iNumberSelected; i++ ) {
SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_GETTEXT,
rgiScsiSelections[i],
(LPARAM) szScsiDriverName );
AddNameToNameList( &GenSettings.MassStorageDrivers,
szScsiDriverName );
ScsiOemContext.Inf = hScsiOem;
ScsiOemContext.CurrentInf = hScsiOem;
pDriverName = (TCHAR *) SendDlgItemMessage( hwnd,
IDC_LB_SCSI,
LB_GETITEMDATA,
rgiScsiSelections[i],
0 );
//
// Build up the section name
//
lstrcpyn( szDriverSectionName, _T("Files.SCSI."), AS(szDriverSectionName));
lstrcatn( szDriverSectionName, pDriverName, MAX_INILINE_LEN );
bKeepReading = SetupFindFirstLine( hScsiOem,
szDriverSectionName,
NULL,
&ScsiOemContext );
//
// For the [File.SCSI.x] entry, add its filenames to the OemScsiFiles
// namelist and copy the files to the $oem$ dir
//
while( bKeepReading ) {
SetupGetStringField( &ScsiOemContext,
2,
szScsiDriverName,
MAX_SCSI_NAME_LEN,
NULL );
//
// Don't allow the adding of a blank name (protection against a bad
// input file)
//
if( szScsiDriverName[0] != _T('\0') ) {
//
// Only copy the file if we haven't copied it already, this
// could happen if 2 friendly-name drivers are selected and they
// both use the same file.
//
if( FindNameInNameList( &GenSettings.OemScsiFiles,
szScsiDriverName ) == NOT_FOUND ) {
AddNameToNameList( &GenSettings.OemScsiFiles,
szScsiDriverName );
CopyFileToDistShare( hwnd,
szTxtSetupOemLocation,
szScsiDriverName,
szTextmodePath );
}
}
//
// move to the next line of the .oem file
//
bKeepReading = SetupFindNextLine( &ScsiOemContext, &ScsiOemContext );
}
}
SetupCloseInfFile( hScsiOem );
}
//----------------------------------------------------------------------------
//
// Function: DlgScsiPage
//
// Purpose: Dialog procedure for the SCSI driver page (Mass Storage devices).
//
// Arguments: standard Win32 dialog proc arguments
//
// Returns: standard Win32 dialog proc return value -- whether the message
// was handled or not
//
//----------------------------------------------------------------------------
INT_PTR CALLBACK
DlgScsiPage( IN HWND hwnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam )
{
BOOL bStatus = TRUE;
switch( uMsg )
{
case WM_INITDIALOG:
{
OnScsiInitDialog( hwnd );
break;
}
case WM_COMMAND: {
switch ( LOWORD(wParam) )
{
case IDC_BUT_LOAD_DRIVER:
if ( HIWORD(wParam) == BN_CLICKED )
OnBrowseLoadDriver( hwnd );
break;
default:
bStatus = FALSE;
break;
}
break;
}
case WM_NOTIFY: {
LPNMHDR pnmh = (LPNMHDR)lParam;
switch( pnmh->code ) {
case PSN_QUERYCANCEL:
CancelTheWizard(hwnd); break;
case PSN_SETACTIVE: {
OnScsiSetActive( hwnd );
break;
}
case PSN_WIZBACK:
break;
case PSN_WIZNEXT:
OnWizNextScsi( hwnd );
break;
default:
break;
}
break;
}
default:
bStatus = FALSE;
break;
}
return( bStatus );
}