779 lines
22 KiB
C++
779 lines
22 KiB
C++
|
/****************************************************************************
|
||
|
|
||
|
Copyright (c) Microsoft Corporation 1997
|
||
|
All rights reserved
|
||
|
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include "pch.h"
|
||
|
|
||
|
#include <windowsx.h>
|
||
|
#include <setupapi.h>
|
||
|
#include <advpub.h>
|
||
|
#include <regstr.h>
|
||
|
#include <lm.h>
|
||
|
|
||
|
#include "utils.h"
|
||
|
|
||
|
DEFINE_MODULE("Main");
|
||
|
|
||
|
// Globals
|
||
|
HINSTANCE g_hinstance = NULL;
|
||
|
|
||
|
#define SMALL_BUFFER_SIZE 256
|
||
|
#define MAX_FILES_SIZE 512
|
||
|
#define STRING_BUFFER_SIZE 65535
|
||
|
|
||
|
static TCHAR g_szServerName[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szRemoteBoot[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szBootFilename[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szBootIniOptions[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szClientName[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szMAC[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szInstallation[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szClientDomain[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szAdminUser[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szAdminPasswd[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
static TCHAR g_szWinntTemplate[ SMALL_BUFFER_SIZE ] = { 0 };
|
||
|
|
||
|
|
||
|
// search and replace structure
|
||
|
typedef struct {
|
||
|
LPTSTR pszToken;
|
||
|
LPTSTR pszString;
|
||
|
} SAR, * LPSAR;
|
||
|
|
||
|
//
|
||
|
// Searches and replaces text.
|
||
|
//
|
||
|
// NOTE: There is no check for writing beyond the buffer even though
|
||
|
// I passed the paramater.
|
||
|
//
|
||
|
void
|
||
|
SearchAndReplace(
|
||
|
LPSAR psarList,
|
||
|
LPTSTR pszString,
|
||
|
DWORD dwSize )
|
||
|
{
|
||
|
LPTSTR psz = pszString;
|
||
|
|
||
|
if ( !psarList || !pszString )
|
||
|
return;
|
||
|
|
||
|
while ( *psz )
|
||
|
{
|
||
|
if ( *psz == TEXT('%') )
|
||
|
{
|
||
|
LPSAR psar = psarList;
|
||
|
|
||
|
psz++; // move forward
|
||
|
|
||
|
while( psar->pszToken )
|
||
|
{
|
||
|
int iCmp;
|
||
|
DWORD dwString = lstrlen( psar->pszString );
|
||
|
DWORD dwToken = lstrlen( psar->pszToken );
|
||
|
LPTSTR pszTemp = psz + dwToken;
|
||
|
TCHAR ch = *pszTemp;
|
||
|
*pszTemp = 0;
|
||
|
|
||
|
iCmp = lstrcmpi( psz, psar->pszToken );
|
||
|
|
||
|
*pszTemp = ch;
|
||
|
|
||
|
if ( !iCmp )
|
||
|
{ // match, so replace
|
||
|
psz--; // move back
|
||
|
|
||
|
if ( 2 + dwToken < dwString )
|
||
|
{
|
||
|
DWORD dwLen = lstrlen( &psz[ 2 + dwToken ] ) + 1;
|
||
|
MoveMemory( &psz[ dwString ], &psz[ 2 + dwToken ], dwLen * sizeof(TCHAR));
|
||
|
}
|
||
|
|
||
|
CopyMemory( psz, psar->pszString, dwString * sizeof(TCHAR) );
|
||
|
|
||
|
if ( 2 + dwToken > dwString )
|
||
|
{
|
||
|
lstrcpy( &psz[ dwString ], &psz[ 2 + dwToken ] );
|
||
|
}
|
||
|
|
||
|
psz++; // move forward
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
psar++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
psz++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Munge the registry
|
||
|
//
|
||
|
LONG
|
||
|
MungeRegistry(
|
||
|
LPCTSTR pszPath,
|
||
|
LPCTSTR pszKey,
|
||
|
LPTSTR pszResult,
|
||
|
LPDWORD pdwSize )
|
||
|
{
|
||
|
HKEY hkeyComputer;
|
||
|
LONG lResult;
|
||
|
|
||
|
lResult = RegOpenKey( HKEY_LOCAL_MACHINE,
|
||
|
pszPath,
|
||
|
&hkeyComputer );
|
||
|
if ( lResult != ERROR_SUCCESS )
|
||
|
goto Finish;
|
||
|
|
||
|
lResult = RegQueryValueEx( hkeyComputer,
|
||
|
pszKey,
|
||
|
NULL, // reserved
|
||
|
NULL, // type
|
||
|
(LPBYTE) pszResult,
|
||
|
pdwSize );
|
||
|
|
||
|
RegCloseKey( hkeyComputer );
|
||
|
|
||
|
Finish:
|
||
|
return lResult;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Munges the registry for the computer name
|
||
|
//
|
||
|
LONG
|
||
|
RetrieveComputerName( void )
|
||
|
{
|
||
|
DWORD dwSize = sizeof( g_szServerName );
|
||
|
return MungeRegistry( REGSTR_PATH_COMPUTRNAME,
|
||
|
REGSTR_VAL_COMPUTERNAME,
|
||
|
g_szServerName,
|
||
|
&dwSize );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Populates the Installation ComboBox
|
||
|
//
|
||
|
HRESULT
|
||
|
PopulateInstallationComboBox(
|
||
|
HWND hDlg )
|
||
|
{
|
||
|
BOOL fKeepSearching = TRUE;
|
||
|
HRESULT hr = S_OK;
|
||
|
TCHAR szPath[ MAX_PATH ];
|
||
|
DWORD dwLen;
|
||
|
WIN32_FIND_DATA fd;
|
||
|
HANDLE handle;
|
||
|
HWND hwndCB = GetDlgItem( hDlg, IDC_CB_INSTALLATION );
|
||
|
LPSHARE_INFO_2 psi = NULL;
|
||
|
|
||
|
NetShareGetInfo( NULL, // this machine
|
||
|
g_szRemoteBoot,
|
||
|
2, // share level 2
|
||
|
(LPBYTE *) &psi );
|
||
|
|
||
|
// create the directory
|
||
|
lstrcpy( szPath, psi->shi2_path );
|
||
|
dwLen = lstrlen( szPath );
|
||
|
szPath[ dwLen++ ] = TEXT('\\');
|
||
|
LoadString( g_hinstance, IDS_SETUP, &szPath[ dwLen ], ARRAYSIZE( szPath ) - dwLen );
|
||
|
dwLen = lstrlen( szPath );
|
||
|
lstrcpy( &szPath[ dwLen ], TEXT("\\*") );
|
||
|
|
||
|
handle = FindFirstFile( szPath, &fd );
|
||
|
if ( handle == INVALID_HANDLE_VALUE )
|
||
|
goto Cleanup;
|
||
|
|
||
|
while ( fKeepSearching)
|
||
|
{
|
||
|
if ( fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY &&
|
||
|
lstrcmp( fd.cFileName, TEXT(".") ) && // ignore
|
||
|
lstrcmp( fd.cFileName, TEXT("..") ) ) // ignore
|
||
|
{
|
||
|
ComboBox_AddString( hwndCB, fd.cFileName );
|
||
|
}
|
||
|
|
||
|
fKeepSearching = FindNextFile( handle, &fd );
|
||
|
}
|
||
|
|
||
|
ComboBox_SetCurSel( hwndCB, 0 );
|
||
|
|
||
|
Cleanup:
|
||
|
if ( handle != INVALID_HANDLE_VALUE)
|
||
|
FindClose( handle );
|
||
|
|
||
|
if ( psi )
|
||
|
NetApiBufferFree( psi );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
//
|
||
|
// Populates the Configuration ComboBox
|
||
|
//
|
||
|
HRESULT
|
||
|
PopulateConfigurationComboBox(
|
||
|
HWND hDlg )
|
||
|
{
|
||
|
BOOL fKeepSearching = TRUE;
|
||
|
HRESULT hr = S_OK;
|
||
|
TCHAR szPath[ MAX_PATH ];
|
||
|
DWORD dwLen;
|
||
|
WIN32_FIND_DATA fd;
|
||
|
HANDLE handle;
|
||
|
HWND hwndCB = GetDlgItem( hDlg, IDC_CB_WINNTSIF );
|
||
|
LPSHARE_INFO_2 psi = NULL;
|
||
|
int iSel;
|
||
|
|
||
|
ComboBox_ResetContent( hwndCB );
|
||
|
|
||
|
NetShareGetInfo( NULL, // this machine
|
||
|
g_szRemoteBoot,
|
||
|
2, // share level 2
|
||
|
(LPBYTE *) &psi );
|
||
|
|
||
|
// create the directory
|
||
|
lstrcpy( szPath, psi->shi2_path );
|
||
|
dwLen = lstrlen( szPath );
|
||
|
szPath[ dwLen++ ] = TEXT('\\');
|
||
|
LoadString( g_hinstance, IDS_TEMPLATES, &szPath[ dwLen ], ARRAYSIZE( szPath ) - dwLen );
|
||
|
dwLen = lstrlen( szPath );
|
||
|
szPath[ dwLen++ ] = TEXT('\\');
|
||
|
LoadString( g_hinstance, IDS_INTELPATH, &szPath[ dwLen ], ARRAYSIZE( szPath ) - dwLen );
|
||
|
dwLen = lstrlen( szPath );
|
||
|
szPath[ dwLen++ ] = TEXT('\\');
|
||
|
LoadString( g_hinstance, IDS_WINNTTEMPLATEFILES, &szPath[ dwLen ], ARRAYSIZE( szPath ) - dwLen );
|
||
|
|
||
|
handle = FindFirstFile( szPath, &fd );
|
||
|
if ( handle == INVALID_HANDLE_VALUE )
|
||
|
goto Cleanup;
|
||
|
|
||
|
while ( fKeepSearching)
|
||
|
{
|
||
|
// whack it at the period
|
||
|
LPTSTR psz = fd.cFileName;
|
||
|
while ( *psz )
|
||
|
{
|
||
|
if ( *psz == TEXT('.') )
|
||
|
{
|
||
|
*psz = 0;
|
||
|
break;
|
||
|
}
|
||
|
psz++;
|
||
|
}
|
||
|
|
||
|
ComboBox_AddString( hwndCB, fd.cFileName );
|
||
|
fKeepSearching = FindNextFile( handle, &fd );
|
||
|
}
|
||
|
|
||
|
ComboBox_SetCurSel( hwndCB, 0 );
|
||
|
|
||
|
Cleanup:
|
||
|
if ( handle != INVALID_HANDLE_VALUE)
|
||
|
FindClose( handle );
|
||
|
|
||
|
if ( psi )
|
||
|
NetApiBufferFree( psi );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
BOOL CALLBACK
|
||
|
ClientDlgProc(
|
||
|
HWND hDlg,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam )
|
||
|
{
|
||
|
NMHDR FAR *lpnmhdr;
|
||
|
DWORD dw;
|
||
|
|
||
|
switch ( uMsg )
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
CenterDialog( hDlg );
|
||
|
SetDlgItemText( hDlg, IDC_E_SERVER, g_szServerName );
|
||
|
SetDlgItemText( hDlg, IDC_E_REMOTEBOOT, g_szRemoteBoot );
|
||
|
SetDlgItemText( hDlg, IDC_E_BOOTFILENAME, g_szBootFilename );
|
||
|
SetDlgItemText( hDlg, IDC_E_BOOTINIOPTIONS, g_szBootIniOptions);
|
||
|
PopulateInstallationComboBox( hDlg );
|
||
|
PopulateConfigurationComboBox( hDlg );
|
||
|
Edit_LimitText( GetDlgItem( hDlg, IDC_E_MAC ), 12 );
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
{
|
||
|
switch ( LOWORD( wParam ) )
|
||
|
{
|
||
|
case IDOK:
|
||
|
{
|
||
|
DWORD dwLen;
|
||
|
TCHAR sz[ SMALL_BUFFER_SIZE ];
|
||
|
GetDlgItemText( hDlg, IDC_E_SERVER, g_szServerName, ARRAYSIZE( g_szServerName ));
|
||
|
GetDlgItemText( hDlg, IDC_E_REMOTEBOOT, g_szRemoteBoot, ARRAYSIZE( g_szRemoteBoot ));
|
||
|
GetDlgItemText( hDlg, IDC_E_BOOTFILENAME, g_szBootFilename, ARRAYSIZE( g_szBootFilename ));
|
||
|
GetDlgItemText( hDlg, IDC_E_BOOTINIOPTIONS, g_szBootIniOptions, ARRAYSIZE( g_szBootIniOptions ));
|
||
|
GetDlgItemText( hDlg, IDC_E_MAC, g_szMAC, ARRAYSIZE( g_szMAC ));
|
||
|
GetDlgItemText( hDlg, IDC_E_MACHINENAME, g_szClientName, ARRAYSIZE( g_szClientName ));
|
||
|
GetDlgItemText( hDlg, IDC_CB_INSTALLATION, g_szInstallation, ARRAYSIZE( g_szInstallation ));
|
||
|
GetDlgItemText( hDlg, IDC_E_CLIENTDOMAIN, g_szClientDomain, ARRAYSIZE( g_szClientDomain ));
|
||
|
GetDlgItemText( hDlg, IDC_E_ADMINUSER, g_szAdminUser, ARRAYSIZE( g_szAdminUser ));
|
||
|
GetDlgItemText( hDlg, IDC_E_ADMINPASSWD, g_szAdminPasswd, ARRAYSIZE( g_szAdminPasswd ));
|
||
|
GetDlgItemText( hDlg, IDC_CB_WINNTSIF, g_szWinntTemplate, ARRAYSIZE( g_szWinntTemplate ));
|
||
|
|
||
|
// add that extension
|
||
|
dw = LoadString( g_hinstance, IDS_WINNTTEMPLATEFILES, sz, ARRAYSIZE( sz ));
|
||
|
Assert( dw );
|
||
|
dwLen = lstrlen( g_szWinntTemplate );
|
||
|
lstrcpy( &g_szWinntTemplate[ dwLen ], &sz[ 1 ] );
|
||
|
|
||
|
EndDialog( hDlg, IDOK );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDCANCEL:
|
||
|
EndDialog( hDlg, IDCANCEL );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// change semicolon delinated list to double-null list
|
||
|
//
|
||
|
void
|
||
|
SemiColonToDoubleNullList( LPTSTR pszList )
|
||
|
{
|
||
|
while ( *pszList )
|
||
|
{
|
||
|
if ( *pszList == TEXT(';') )
|
||
|
{
|
||
|
*pszList = 0;
|
||
|
}
|
||
|
|
||
|
pszList++;
|
||
|
}
|
||
|
pszList++;
|
||
|
*pszList = 0; // double the null.
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Adds files to the Queue to be copied. It returns the number of files added
|
||
|
// to the Queue.
|
||
|
//
|
||
|
DWORD
|
||
|
CopyFilesAddToQueue(
|
||
|
HSPFILEQ Queue, // setup Queue
|
||
|
LPTSTR pszSource,
|
||
|
LPTSTR pszDest,
|
||
|
LPTSTR pszFiles, // Double-null terminated file list
|
||
|
LPTSTR pszSubpath ) // optional sub-path
|
||
|
{
|
||
|
DWORD dwCount = 0;
|
||
|
LPTSTR psz = pszFiles;
|
||
|
|
||
|
while ( *pszFiles )
|
||
|
{
|
||
|
DWORD dwLen;
|
||
|
|
||
|
// check for comma which indicates rename
|
||
|
psz = pszFiles;
|
||
|
while (*psz && *psz != TEXT(','))
|
||
|
psz++;
|
||
|
|
||
|
if ( *psz == TEXT(',') )
|
||
|
{
|
||
|
*psz= 0; // terminate
|
||
|
psz++;
|
||
|
}
|
||
|
else
|
||
|
{ // sources name is dest name
|
||
|
psz = pszFiles;
|
||
|
}
|
||
|
|
||
|
SetupQueueCopy(
|
||
|
Queue,
|
||
|
pszSource,
|
||
|
NULL,
|
||
|
pszFiles,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
pszDest,
|
||
|
psz,
|
||
|
SP_COPY_NEWER | SP_COPY_NOOVERWRITE | SP_COPY_WARNIFSKIP );
|
||
|
|
||
|
// get next file
|
||
|
pszFiles = psz + lstrlen( psz ) + 1;
|
||
|
dwCount++;
|
||
|
}
|
||
|
|
||
|
return dwCount;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
HRESULT
|
||
|
SetupClient( )
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
TCHAR szImage[ MAX_PATH ];
|
||
|
TCHAR szSetup[ MAX_PATH ];
|
||
|
TCHAR szTemplates[ MAX_PATH ];
|
||
|
TCHAR szBootIni[ MAX_PATH ];
|
||
|
TCHAR szString[ MAX_PATH ];
|
||
|
TCHAR szDosNetFilename[ MAX_PATH ];
|
||
|
TCHAR szWinntSif[ MAX_PATH ];
|
||
|
DWORD dwLen;
|
||
|
DWORD dw;
|
||
|
HSPFILEQ Queue;
|
||
|
PVOID pContext;
|
||
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
|
HKEY hkeyBINL;
|
||
|
HKEY hkeyMAC;
|
||
|
LPTSTR pszFiles = (LPTSTR) TraceAlloc( GMEM_FIXED, MAX_FILES_SIZE );
|
||
|
LPTSTR psz = NULL;
|
||
|
LPSHARE_INFO_2 psi = NULL;
|
||
|
LPVOID args[ 6 ];
|
||
|
SAR sExpand[] = {
|
||
|
{ TEXT("BINLSERVER"), g_szServerName },
|
||
|
{ TEXT("INSTALLATION"), g_szInstallation },
|
||
|
{ TEXT("CLIENTNAME"), g_szClientName },
|
||
|
{ TEXT("REMOTEBOOT"), g_szRemoteBoot },
|
||
|
{ TEXT("CLIENTDOMAIN"), g_szClientDomain },
|
||
|
{ TEXT("ADMINUSER"), g_szAdminUser },
|
||
|
{ TEXT("ADMINPASSWD"), g_szAdminPasswd },
|
||
|
{ NULL, NULL } // end of list
|
||
|
};
|
||
|
char chString[ STRING_BUFFER_SIZE ];
|
||
|
|
||
|
NetShareGetInfo( NULL, // this machine
|
||
|
g_szRemoteBoot,
|
||
|
2, // share level 2
|
||
|
(LPBYTE *) &psi );
|
||
|
|
||
|
// create the directory
|
||
|
lstrcpy( szImage, psi->shi2_path );
|
||
|
dwLen = lstrlen( szImage );
|
||
|
szImage[ dwLen++ ] = TEXT('\\');
|
||
|
dw = LoadString( g_hinstance, IDS_IMAGES, &szImage[ dwLen ], ARRAYSIZE( szImage ) - dwLen );
|
||
|
Assert( dw );
|
||
|
dwLen = lstrlen( szImage );
|
||
|
szImage[ dwLen++ ] = TEXT('\\');
|
||
|
lstrcpy( &szImage[ dwLen ], g_szClientName );
|
||
|
|
||
|
CreateDirectory( szImage, NULL );
|
||
|
|
||
|
// setup path
|
||
|
lstrcpy( szSetup, psi->shi2_path );
|
||
|
dwLen = lstrlen( szSetup );
|
||
|
szSetup[ dwLen++ ] = TEXT('\\');
|
||
|
dw = LoadString( g_hinstance, IDS_SETUP, &szSetup[ dwLen ], ARRAYSIZE( szSetup ) - dwLen );
|
||
|
Assert( dw );
|
||
|
dwLen = lstrlen( szSetup );
|
||
|
szSetup[ dwLen++ ] = TEXT('\\');
|
||
|
lstrcpy( &szSetup[ dwLen ], g_szInstallation );
|
||
|
dwLen = lstrlen( szSetup );
|
||
|
szSetup[ dwLen++ ] = TEXT('\\');
|
||
|
dw = LoadString( g_hinstance, IDS_INTELPATH, &szSetup[ dwLen ], ARRAYSIZE( szSetup ) - dwLen );
|
||
|
Assert( dw );
|
||
|
|
||
|
// Create DOSNET.INF filepath
|
||
|
lstrcpy( szDosNetFilename, szSetup );
|
||
|
dwLen = lstrlen( szDosNetFilename );
|
||
|
szDosNetFilename[ dwLen ] = TEXT('\\');
|
||
|
dwLen++;
|
||
|
dw = LoadString( g_hinstance, IDS_DOSNETINFFILENAME,
|
||
|
&szDosNetFilename[ dwLen ], ARRAYSIZE( szDosNetFilename ) - dwLen );
|
||
|
Assert( dw );
|
||
|
|
||
|
Queue = SetupOpenFileQueue( );
|
||
|
|
||
|
// Retrieve the list of files from the INF and add to Queue
|
||
|
GetPrivateProfileSection( TEXT("RootBootFiles"), pszFiles, MAX_FILES_SIZE,
|
||
|
szDosNetFilename );
|
||
|
CopyFilesAddToQueue( Queue, szSetup, szImage, pszFiles, NULL );
|
||
|
|
||
|
// add additional files from resources
|
||
|
dw = LoadString( g_hinstance, IDS_FILESTOBECOPIED, pszFiles, MAX_FILES_SIZE );
|
||
|
Assert( dw );
|
||
|
SemiColonToDoubleNullList( pszFiles );
|
||
|
CopyFilesAddToQueue( Queue, szSetup, szImage, pszFiles, NULL );
|
||
|
|
||
|
// copy winnt.sif template
|
||
|
lstrcpy( szTemplates, psi->shi2_path );
|
||
|
dwLen = lstrlen( szTemplates );
|
||
|
szTemplates[ dwLen++ ] = TEXT('\\');
|
||
|
dw = LoadString( g_hinstance, IDS_TEMPLATES, &szTemplates[ dwLen ], ARRAYSIZE( szTemplates ) - dwLen );
|
||
|
Assert( dw );
|
||
|
dwLen = lstrlen( szTemplates );
|
||
|
szTemplates[ dwLen++ ] = TEXT('\\');
|
||
|
dw = LoadString( g_hinstance, IDS_INTELPATH, &szTemplates[ dwLen ], ARRAYSIZE( szTemplates ) - dwLen );
|
||
|
Assert( dw );
|
||
|
|
||
|
lstrcpy( pszFiles, g_szWinntTemplate );
|
||
|
dwLen = lstrlen( pszFiles );
|
||
|
pszFiles[ dwLen++ ] = TEXT(',');
|
||
|
dw = LoadString( g_hinstance, IDS_WINNTSIF, &pszFiles[ dwLen ], MAX_PATH );
|
||
|
Assert( dw );
|
||
|
SemiColonToDoubleNullList( pszFiles );
|
||
|
CopyFilesAddToQueue( Queue, szTemplates, szImage, pszFiles, NULL );
|
||
|
|
||
|
TraceFree( pszFiles );
|
||
|
|
||
|
pContext = SetupInitDefaultQueueCallback( NULL );
|
||
|
|
||
|
if (!SetupCommitFileQueue( NULL, Queue, SetupDefaultQueueCallback,
|
||
|
pContext ) )
|
||
|
goto Cleanup;
|
||
|
|
||
|
dw = LoadString( g_hinstance, IDS_REG_BINL_PARAMETER, szString, ARRAYSIZE( szString ));
|
||
|
Assert( dw );
|
||
|
if ( ERROR_SUCCESS ==
|
||
|
RegOpenKey( HKEY_LOCAL_MACHINE, szString, &hkeyBINL ) )
|
||
|
{
|
||
|
if ( ERROR_SUCCESS ==
|
||
|
RegCreateKey( hkeyBINL, g_szMAC, &hkeyMAC ) )
|
||
|
{
|
||
|
dw = LoadString( g_hinstance, IDS_IMAGES, szString, ARRAYSIZE( dw ));
|
||
|
Assert( dw );
|
||
|
dwLen = lstrlen( szString );
|
||
|
szString[ dwLen++ ] = TEXT('\\');
|
||
|
lstrcpy( &szString[ dwLen ], g_szClientName );
|
||
|
dwLen = lstrlen( szString );
|
||
|
szString[ dwLen++ ] = TEXT('\\');
|
||
|
lstrcpy( &szString[ dwLen ], g_szBootFilename );
|
||
|
dwLen = ( lstrlen( szString ) + 1 ) * sizeof(TCHAR);
|
||
|
|
||
|
RegSetValueEx( hkeyMAC, TEXT("BootFileName"), 0, REG_SZ, (LPBYTE) szString, dwLen );
|
||
|
|
||
|
dwLen = ( lstrlen( g_szServerName ) + 1 ) * sizeof(TCHAR);
|
||
|
RegSetValueEx( hkeyMAC, TEXT("HostName"), 0, REG_SZ, (LPBYTE) g_szServerName, dwLen );
|
||
|
|
||
|
RegCloseKey( hkeyMAC );
|
||
|
}
|
||
|
RegCloseKey( hkeyBINL );
|
||
|
}
|
||
|
|
||
|
// create MAC Address file
|
||
|
lstrcpy( szString, szImage );
|
||
|
dwLen = lstrlen( szString );
|
||
|
szString[ dwLen++ ] = TEXT('\\');
|
||
|
lstrcpy( &szString[ dwLen ], g_szMAC );
|
||
|
|
||
|
hFile = CreateFile( szString,
|
||
|
GENERIC_WRITE,
|
||
|
FILE_SHARE_READ,
|
||
|
NULL, // security attribs
|
||
|
CREATE_ALWAYS,
|
||
|
FILE_ATTRIBUTE_NORMAL, // maybe FILE_ATTRIBUTE_HIDDEN
|
||
|
NULL ); // template
|
||
|
CloseHandle( hFile );
|
||
|
|
||
|
lstrcpy( szBootIni, szImage );
|
||
|
dwLen = lstrlen( szBootIni );
|
||
|
szBootIni[ dwLen++ ] = TEXT('\\');
|
||
|
dw = LoadString( g_hinstance, IDS_BOOTINI, &szBootIni[ dwLen ], ARRAYSIZE( szBootIni ) - dwLen );
|
||
|
Assert( dw );
|
||
|
|
||
|
hFile = CreateFile( szBootIni,
|
||
|
GENERIC_WRITE,
|
||
|
FILE_SHARE_READ,
|
||
|
NULL, // security attribs
|
||
|
CREATE_ALWAYS,
|
||
|
FILE_ATTRIBUTE_NORMAL, // maybe FILE_ATTRIBUTE_HIDDEN
|
||
|
NULL ); // template
|
||
|
if ( hFile == INVALID_HANDLE_VALUE )
|
||
|
goto Cleanup;
|
||
|
|
||
|
dw = LoadString( g_hinstance, IDS_BOOTLOADER, szString, ARRAYSIZE( szString ));
|
||
|
Assert( dw );
|
||
|
|
||
|
args[0] = (LPVOID) &g_szServerName;
|
||
|
args[1] = (LPVOID) &g_szRemoteBoot;
|
||
|
args[2] = (LPVOID) &g_szClientName;
|
||
|
args[3] = (LPVOID) &g_szInstallation;
|
||
|
args[4] = (LPVOID) &g_szBootIniOptions;
|
||
|
|
||
|
FormatMessage(
|
||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING |
|
||
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||
|
szString,
|
||
|
NULL, // message id - n/a
|
||
|
NULL, // language - use system
|
||
|
(LPTSTR) &psz,
|
||
|
0, // minimum length
|
||
|
(char **) &args );
|
||
|
DebugMemoryAddAddress( psz );
|
||
|
|
||
|
WideCharToMultiByte( CP_ACP, 0, psz, -1, chString, ARRAYSIZE( chString ), NULL, NULL );
|
||
|
|
||
|
dwLen = lstrlenA( chString );
|
||
|
WriteFile( hFile, chString, dwLen, &dw, NULL );
|
||
|
|
||
|
CloseHandle( hFile );
|
||
|
TraceFree( psz );
|
||
|
|
||
|
// process WINNT.SIF
|
||
|
lstrcpy( szWinntSif, szImage );
|
||
|
dwLen = lstrlen( szWinntSif );
|
||
|
szWinntSif[ dwLen++ ] = TEXT('\\');
|
||
|
dw = LoadString( g_hinstance, IDS_WINNTSIF, &szWinntSif[ dwLen ], ARRAYSIZE( szWinntSif ) - dwLen );
|
||
|
Assert( dw );
|
||
|
|
||
|
hFile = CreateFile( szWinntSif,
|
||
|
GENERIC_READ,
|
||
|
FILE_SHARE_READ,
|
||
|
NULL, // security attribs
|
||
|
OPEN_EXISTING,
|
||
|
FILE_ATTRIBUTE_NORMAL, // maybe FILE_ATTRIBUTE_HIDDEN
|
||
|
NULL ); // template
|
||
|
if ( hFile == INVALID_HANDLE_VALUE )
|
||
|
goto Cleanup;
|
||
|
|
||
|
ReadFile( hFile, chString, ARRAYSIZE( chString ), &dw, NULL );
|
||
|
Assert( dw != ARRAYSIZE( chString ));
|
||
|
|
||
|
CloseHandle( hFile );
|
||
|
|
||
|
psz = (LPTSTR) TraceAlloc( GMEM_FIXED, ARRAYSIZE( chString ));
|
||
|
MultiByteToWideChar( CP_ACP, 0, chString, -1, psz, ARRAYSIZE( chString ));
|
||
|
|
||
|
SearchAndReplace( sExpand, psz, ARRAYSIZE( chString ));
|
||
|
|
||
|
hFile = CreateFile( szWinntSif,
|
||
|
GENERIC_WRITE,
|
||
|
FILE_SHARE_READ,
|
||
|
NULL, // security attribs
|
||
|
CREATE_ALWAYS,
|
||
|
FILE_ATTRIBUTE_NORMAL, // maybe FILE_ATTRIBUTE_HIDDEN
|
||
|
NULL ); // template
|
||
|
if ( hFile == INVALID_HANDLE_VALUE )
|
||
|
goto Cleanup;
|
||
|
|
||
|
WideCharToMultiByte( CP_ACP, 0, psz, -1, chString, ARRAYSIZE( chString ), NULL, NULL );
|
||
|
|
||
|
dwLen = lstrlenA( chString );
|
||
|
WriteFile( hFile, chString, dwLen, &dw, NULL );
|
||
|
|
||
|
CloseHandle( hFile );
|
||
|
TraceFree( psz );
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
Cleanup:
|
||
|
|
||
|
if ( Queue )
|
||
|
SetupCloseFileQueue( Queue );
|
||
|
|
||
|
if ( psi )
|
||
|
NetApiBufferFree( psi );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// WinMain()
|
||
|
//
|
||
|
int APIENTRY
|
||
|
WinMain(
|
||
|
HINSTANCE hInstance,
|
||
|
HINSTANCE hPrevInstance,
|
||
|
LPSTR lpCmdLine,
|
||
|
int nCmdShow)
|
||
|
{
|
||
|
HANDLE hMutex;
|
||
|
HRESULT hr = S_OK;
|
||
|
DWORD dw;
|
||
|
|
||
|
g_hinstance = hInstance;
|
||
|
|
||
|
INITIALIZE_TRACE_MEMORY;
|
||
|
|
||
|
// Initialize
|
||
|
RetrieveComputerName( );
|
||
|
dw = LoadString( g_hinstance, IDS_REMOTEBOOT, g_szRemoteBoot, ARRAYSIZE( g_szRemoteBoot ));
|
||
|
Assert( dw );
|
||
|
dw = LoadString( g_hinstance, IDS_BOOTFILENAME, g_szBootFilename, ARRAYSIZE( g_szBootFilename ));
|
||
|
Assert( dw );
|
||
|
dw = LoadString( g_hinstance, IDS_BOOTINIOPTIONS, g_szBootIniOptions, ARRAYSIZE( g_szBootIniOptions ));
|
||
|
Assert( dw );
|
||
|
|
||
|
if ( IDOK == DialogBox( g_hinstance, MAKEINTRESOURCE( IDD_CLIENT ), NULL, ClientDlgProc ) )
|
||
|
{
|
||
|
if ( lstrlen( g_szMAC ) != 12 )
|
||
|
goto Cleanup;
|
||
|
|
||
|
if ( !lstrlen( g_szClientName ) )
|
||
|
goto Cleanup;
|
||
|
|
||
|
hr = SetupClient( );
|
||
|
}
|
||
|
|
||
|
Cleanup:
|
||
|
UNINITIALIZE_TRACE_MEMORY;
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
// stolen from the CRT, used to shrink our code
|
||
|
int _stdcall ModuleEntry(void)
|
||
|
{
|
||
|
int i;
|
||
|
STARTUPINFOA si;
|
||
|
LPSTR pszCmdLine = GetCommandLineA();
|
||
|
|
||
|
|
||
|
if ( *pszCmdLine == '\"' )
|
||
|
{
|
||
|
/*
|
||
|
* Scan, and skip over, subsequent characters until
|
||
|
* another double-quote or a null is encountered.
|
||
|
*/
|
||
|
while ( *++pszCmdLine && (*pszCmdLine != '\"') );
|
||
|
/*
|
||
|
* If we stopped on a double-quote (usual case), skip
|
||
|
* over it.
|
||
|
*/
|
||
|
if ( *pszCmdLine == '\"' )
|
||
|
pszCmdLine++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
while (*pszCmdLine > ' ')
|
||
|
pszCmdLine++;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Skip past any white space preceeding the second token.
|
||
|
*/
|
||
|
while (*pszCmdLine && (*pszCmdLine <= ' '))
|
||
|
{
|
||
|
pszCmdLine++;
|
||
|
}
|
||
|
|
||
|
si.dwFlags = 0;
|
||
|
GetStartupInfoA(&si);
|
||
|
|
||
|
i = WinMain(GetModuleHandle(NULL), NULL, pszCmdLine,
|
||
|
si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
|
||
|
ExitProcess(i);
|
||
|
return i; // We never come here.
|
||
|
}
|