Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

649 lines
17 KiB

//+------------------------------------------------------------------
//
// Project: Windows NT4 DS Client Setup Wizard
//
// Purpose: Installs the Windows NT4 DS Client Files
//
// File: dscsetup.cpp
//
// History: March 1998 Zeyong Xu Created
// Jan 2000 Jeff Jones (JeffJon) Modified
// - changed to be an NT setup
//
//------------------------------------------------------------------
#include <windows.h>
#include <prsht.h>
#include <setupapi.h>
#include <tchar.h>
#include <stdlib.h>
#include "resource.h"
#include "dscsetup.h"
#include "wizard.h"
#include "doinst.h"
SInstallVariables g_sInstVar;
// DllMain Entry
BOOL APIENTRY DllMain( HINSTANCE hInstance,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an exported function.
DWORD WINAPI DoDscSetup(LPCSTR lpCmdLine)
{
// initialize the variables of installation
InitVariables();
ParseCmdline(const_cast<PSTR>(lpCmdLine));
//
// Go through setup if we are installing with anything but
// the /a flag
//
if (g_sInstVar.m_bSysDlls || g_sInstVar.m_bWabInst)
{
// create objects
if(!CreateObjects())
return SETUP_ERROR;
// Launch setup wizard
if(!DSCSetupWizard())
{
TCHAR szMessage[MAX_MESSAGE + 1];
TCHAR szTitle[MAX_TITLE + 1];
LoadString(g_sInstVar.m_hInstance,
IDS_ERROR_WIZARD,
szMessage,
MAX_MESSAGE);
LoadString(g_sInstVar.m_hInstance,
IDS_ERROR_TITLE,
szTitle,
MAX_TITLE);
// display a error message - Failure to load Setup Wizard
MessageBox(NULL,
szMessage, // address of text in message box
szTitle, // address of title of message box
MB_OK | MB_TOPMOST | MB_ICONERROR); // style of message box
g_sInstVar.m_nSetupResult = SETUP_ERROR;
}
// destroy objects
DestroyObjects();
if(g_sInstVar.m_nSetupResult == SETUP_SUCCESS &&
!g_sInstVar.m_bQuietMode
#ifdef MERRILL_LYNCH
&& !g_sInstVar.m_bNoReboot
#endif
)
{
// prompt reboot
SetupPromptReboot(NULL, // optional, handle to a file queue
NULL, // parent window of this dialog box
FALSE); // optional, do not prompt user);
}
else if(g_sInstVar.m_nSetupResult == SETUP_SUCCESS &&
g_sInstVar.m_bQuietMode
#ifdef MERRILL_LYNCH
&& !g_sInstVar.m_bNoReboot
#endif
)
{
HANDLE htoken = INVALID_HANDLE_VALUE;
do
{
// twiddle our process privileges to enable SE_SHUTDOWN_NAME
HRESULT hr = OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&htoken);
if (FAILED(hr))
{
break;
}
LUID luid;
memset(&luid, 0, sizeof(luid));
hr = LookupPrivilegeValue(0, SE_SHUTDOWN_NAME, &luid);
if (FAILED(hr))
{
break;
}
TOKEN_PRIVILEGES privs;
memset(&privs, 0, sizeof(privs));
privs.PrivilegeCount = 1;
privs.Privileges[0].Luid = luid;
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
hr = AdjustTokenPrivileges(htoken, 0, &privs, 0, 0, 0);
if (FAILED(hr))
{
break;
}
hr = ExitWindowsEx(EWX_REBOOT, 0);
if (FAILED(hr))
{
break;
}
}
while (0);
if (htoken != INVALID_HANDLE_VALUE)
{
CloseHandle(htoken);
}
}
}
else
{
//
// Setup was run with the /a flag. This means we
// don't want to show the UI and let the adsix86.inf
// handle the install for us
//
if (!LaunchProcess(STR_INSTALL_ADSIWREMOVE))
{
g_sInstVar.m_nSetupResult = SETUP_ERROR;
}
}
return g_sInstVar.m_nSetupResult;
}
VOID ParseCmdline(LPSTR lpCmdLine)
{
PCTSTR ptszTok = _tcstok(lpCmdLine, _T(" "));
do
{
if (ptszTok != NULL)
{
if (_tcsicmp(ptszTok, _T("/q")) == 0)
{
g_sInstVar.m_bQuietMode = TRUE;
}
if (_tcsicmp(ptszTok, _T("/a")) == 0)
{
g_sInstVar.m_bWabInst = FALSE;
g_sInstVar.m_bSysDlls = FALSE;
}
if (_tcsicmp(ptszTok, _T("/d")) == 0)
{
g_sInstVar.m_bWabInst = FALSE;
}
#ifdef MERRILL_LYNCH
if (_tcsicmp(ptszTok, _T("/n")) == 0)
{
g_sInstVar.m_bNoReboot = TRUE;
}
#endif
}
ptszTok = _tcstok(NULL, _T(" "));
} while (ptszTok != NULL);
}
// initialize the variables of installation
VOID InitVariables()
{
g_sInstVar.m_hInstance = GetModuleHandle(STR_DLL_NAME);
g_sInstVar.m_hInstallThread = NULL;
g_sInstVar.m_uTimerID = 0;
g_sInstVar.m_hBigBoldFont = NULL;
g_sInstVar.m_hProgress = NULL;
g_sInstVar.m_hFileNameItem = NULL;
g_sInstVar.m_bDCOMInstalled = FALSE;
g_sInstVar.m_bQuietMode = FALSE;
g_sInstVar.m_bWabInst = TRUE;
g_sInstVar.m_bSysDlls = TRUE;
#ifdef MERRILL_LYNCH
g_sInstVar.m_bNoReboot = FALSE;
#endif
g_sInstVar.m_nSetupResult = SETUP_SUCCESS;
// get source path
GetModuleFileName(g_sInstVar.m_hInstance,
g_sInstVar.m_szSourcePath,
MAX_PATH);
*(_tcsrchr(g_sInstVar.m_szSourcePath, CHAR_BACKSLASH) + 1) = TEXT('\0'); // Strip setup.exe off path
}
// start setup wizard
BOOL DSCSetupWizard()
{
PROPSHEETHEADER psh;
PROPSHEETPAGE psPage[SIZE_WIZARD_PAGE];
int i = 0;
//
// Setup the Welcome page
//
i=0;
ZeroMemory(&psPage[i],sizeof(PROPSHEETPAGE));
psPage[i].dwSize = sizeof(PROPSHEETPAGE);
psPage[i].dwFlags = PSP_USETITLE | PSP_HIDEHEADER;
psPage[i].hInstance = g_sInstVar.m_hInstance;
psPage[i].pszTemplate = MAKEINTRESOURCE(IDD_WELCOME);
psPage[i].pfnDlgProc = (DLGPROC) WelcomeDialogProc;
psPage[i].lParam = (LPARAM) 0;
psPage[i].pszTitle = MAKEINTRESOURCE(IDS_WIZARD_TITLE);
/* ntbug#337931: remove license page
//
// Setup the License Page
//
i++;
ZeroMemory(&psPage[i],sizeof(PROPSHEETPAGE));
psPage[i].dwSize = sizeof(PROPSHEETPAGE);
psPage[i].dwFlags = PSP_USETITLE |
PSP_USEHEADERTITLE |
PSP_USEHEADERSUBTITLE;
psPage[i].hInstance = g_sInstVar.m_hInstance;
psPage[i].pszTemplate = MAKEINTRESOURCE(IDD_LICENSE);
psPage[i].pfnDlgProc = (DLGPROC) LicenseDialogProc;
psPage[i].lParam = (LPARAM) 0;
psPage[i].pszTitle = MAKEINTRESOURCE(IDS_WIZARD_TITLE);
psPage[i].pszHeaderTitle = MAKEINTRESOURCE(IDS_HEADERTITLE_LICENSE);
psPage[i].pszHeaderSubTitle = MAKEINTRESOURCE(IDS_HEADERSUBTITLE_LICENSE);
*/
//
// Setup the Select Page
//
i++;
ZeroMemory(&psPage[i],sizeof(PROPSHEETPAGE));
psPage[i].dwSize = sizeof(PROPSHEETPAGE);
psPage[i].dwFlags = PSP_USETITLE |
PSP_USEHEADERTITLE |
PSP_USEHEADERSUBTITLE;
psPage[i].hInstance = g_sInstVar.m_hInstance;
psPage[i].pszTemplate = MAKEINTRESOURCE(IDD_CONFIRM);
psPage[i].pfnDlgProc = (DLGPROC) ConfirmDialogProc;
psPage[i].lParam = (LPARAM) 0;
psPage[i].pszTitle = MAKEINTRESOURCE(IDS_WIZARD_TITLE);
psPage[i].pszHeaderTitle = MAKEINTRESOURCE(IDS_HEADERTITLE_CONFIRM);
psPage[i].pszHeaderSubTitle = MAKEINTRESOURCE(IDS_HEADERSUBTITLE_CONFIRM);
//
// Setup the Confirm Page
//
i++;
ZeroMemory(&psPage[i],sizeof(PROPSHEETPAGE));
psPage[i].dwSize = sizeof(PROPSHEETPAGE);
psPage[i].dwFlags = PSP_USETITLE |
PSP_USEHEADERTITLE |
PSP_USEHEADERSUBTITLE;
psPage[i].hInstance = g_sInstVar.m_hInstance;
psPage[i].pszTemplate = MAKEINTRESOURCE(IDD_INSTALL);
psPage[i].pfnDlgProc = (DLGPROC) InstallDialogProc;
psPage[i].lParam = (LPARAM) 0;
psPage[i].pszTitle = MAKEINTRESOURCE(IDS_WIZARD_TITLE);
psPage[i].pszHeaderTitle = MAKEINTRESOURCE(IDS_HEADERTITLE_INSTALL);
psPage[i].pszHeaderSubTitle = MAKEINTRESOURCE(IDS_HEADERSUBTITLE_INSTALL);
//
// Setup the Completion page
//
i++;
ZeroMemory(&psPage[i],sizeof(PROPSHEETPAGE));
psPage[i].dwSize = sizeof(PROPSHEETPAGE);
psPage[i].dwFlags = PSP_USETITLE | PSP_HIDEHEADER;
psPage[i].hInstance = g_sInstVar.m_hInstance;
psPage[i].pszTemplate = MAKEINTRESOURCE(IDD_COMPLETION);
psPage[i].pfnDlgProc = (DLGPROC) CompletionDialogProc;
psPage[i].lParam = (LPARAM) 0;
psPage[i].pszTitle = MAKEINTRESOURCE(IDS_WIZARD_TITLE);
//
// Setup the wizard
//
ZeroMemory(&psh,sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
// Windows 98 with 16 color display mode crashes when PSH_STRETCHWATERMARK flag is on.
psh.dwFlags = PSH_USEICONID |
PSH_PROPSHEETPAGE |
PSH_WIZARD97 |
PSH_WATERMARK |
PSH_HEADER; // | PSH_STRETCHWATERMARK;
psh.pszIcon = MAKEINTRESOURCE(IDI_ICON_APP);
psh.hInstance = g_sInstVar.m_hInstance;
psh.pszCaption = MAKEINTRESOURCE(IDS_WIZARD_TITLE);;
psh.nStartPage = 0;
psh.nPages = SIZE_WIZARD_PAGE;
psh.ppsp = (LPCPROPSHEETPAGE) &psPage;
//
// Run the wizard
//
if(g_sInstVar.m_bQuietMode)
{
if(!CheckDiskSpace())
return FALSE;
psh.nStartPage = 2;
}
else
psh.nStartPage = 0;
if( PropertySheet(&psh) < 0 ) // failure to load wizard
{
return FALSE;
}
//
// Because SetWindowLongPtr(hWnd, DWL_MSGRESULT, IDD_COMPLETION)
// doesn't work on Win95 (when users click Cancel, the wizard can't
// be routed to the Completion page), I added the following code to
// open the Completion page
//
if(!g_sInstVar.m_bQuietMode)
{
psh.nStartPage = 3;
if( PropertySheet(&psh) < 0 ) // failure to load wizard
{
return FALSE;
}
}
return TRUE;
}
// check for DCOM installed
void CheckDCOMInstalled()
{
HKEY hSubKey;
// check if IE 4.0 has been installed
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT,
STR_DCOM_REGKEY,
0,
KEY_READ,
&hSubKey) )
{
g_sInstVar.m_bDCOMInstalled = TRUE;
RegCloseKey(hSubKey);
}
}
// gets Disk Free space
DWORD64 SetupGetDiskFreeSpace()
{
DWORD dwSectorsPerCluster;
DWORD dwBytesPerSector;
DWORD dwNumberOfFreeClusters;
DWORD dwTotalNumberOfClusters;
DWORD64 d64FreeSpace = 0;
TCHAR szPathName[MAX_PATH + 1]; // address of root path
if(GetSystemDirectory(szPathName, // address of buffer for system directory
MAX_PATH)) // size of directory buffer);
{
if ( szPathName[1] == TEXT(':'))
{
// this is a drive letter
// assume it is of for d:backslash
szPathName[3] = TEXT('\0');
//get free space, GetDiskFreeSpaceEx() don't support in older Win95
if (GetDiskFreeSpace(szPathName, // address of root path
&dwSectorsPerCluster, // address of sectors per cluster
&dwBytesPerSector, // address of bytes per sector
&dwNumberOfFreeClusters, // address of number of free clusters
&dwTotalNumberOfClusters)) // address of total number of clusters
{
// calc total size
d64FreeSpace = DWORD64(dwSectorsPerCluster)
* dwBytesPerSector
* dwNumberOfFreeClusters;
}
}
}
return d64FreeSpace;
}
// check if DSClient has been installed
BOOL CheckDSClientInstalled()
{
HKEY hSubKey;
BOOL bResult = FALSE;
// open reg key of DS Client
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
STR_DSCLIENT_REGKEY,
0,
KEY_ALL_ACCESS,
&hSubKey) )
{
bResult = TRUE;
RegCloseKey(hSubKey);
}
return bResult;
}
/* ntbug#337931: remove license page
// load "License Agreement" text from license file
BOOL LoadLicenseFile(HWND hDlg)
{
BOOL bReturn = FALSE;
TCHAR szTitle[MAX_TITLE + 1];
TCHAR szTempBuffer[MAX_MESSAGE + 1];
TCHAR szLicenseFile[MAX_PATH + 1];
TCHAR szReturnTextBuffer[MAX_MESSAGE + 1];
LPTSTR lpszLicenseText = NULL;
HANDLE hFile;
DWORD dwNumberOfBytesRead, dwFileSize;
//
// Determine where we are installing from
// and specific the license file there
//
lstrcpy(szLicenseFile, g_sInstVar.m_szSourcePath);
lstrcat(szLicenseFile, STR_LICENSEFILE);
// Open License file
hFile = CreateFile(szLicenseFile, // pointer to name of the file
GENERIC_READ, // access (read-write) mode
FILE_SHARE_READ, // share mode
NULL, // pointer to security descriptor
OPEN_EXISTING, // how to create
FILE_ATTRIBUTE_NORMAL, // file attributes
NULL); // handle to file with attributes to copy
if(INVALID_HANDLE_VALUE != hFile)
{
// Read License file into string
// setup memory, get file size in bytes
dwFileSize = GetFileSize (hFile, NULL) ;
if (dwFileSize != 0xFFFFFFFF)
{
// this program is for Win98/95, it will work in MBCS not UNICODE
// this code is for ANSI US version, license.txt file uses the single byte character set(ANSI)
// if doing locolization, license.txt file should use the double byte character set(DBCS/MBCS)
lpszLicenseText = (LPTSTR) calloc (dwFileSize + sizeof(TCHAR),
sizeof(BYTE));
}
if(lpszLicenseText)
{
//read file
if (ReadFile(hFile, // handle of file to read
lpszLicenseText, // address of buffer that receives data
dwFileSize, // number of bytes to read
&dwNumberOfBytesRead, // address of number of bytes read
NULL)) // address of structure for data
{
// display license on dialog
SetDlgItemText(hDlg, IDC_LICENSE_TEXT, lpszLicenseText);
bReturn = TRUE;
}
// so free the memory
free(lpszLicenseText);
}
//close file handle
CloseHandle(hFile);
}
if(!bReturn)
{
// load string
LoadString(g_sInstVar.m_hInstance,
IDS_ERROR_TITLE,
szTitle,
MAX_TITLE);
LoadString(g_sInstVar.m_hInstance,
IDS_ERROR_LICENSEFILE,
szTempBuffer,
MAX_MESSAGE);
wsprintf(szReturnTextBuffer,
TEXT("%s %s"),
szTempBuffer,
szLicenseFile);
MessageBox(hDlg,
szReturnTextBuffer,
szTitle,
MB_OK | MB_TOPMOST | MB_ICONERROR);
}
return bReturn;
}
*/
// check disk space
BOOL CheckDiskSpace()
{
BOOL bResult = TRUE;
TCHAR szString[MAX_MESSAGE + MAX_TITLE + 1];
TCHAR szTitle[MAX_TITLE + 1];
TCHAR szMessage[MAX_MESSAGE + 1];
if(SIZE_TOTAL*MB_TO_BYTE > SetupGetDiskFreeSpace())
{
// load string
LoadString(g_sInstVar.m_hInstance,
IDS_ERROR_NODISKSPACE,
szMessage,
MAX_MESSAGE);
LoadString(g_sInstVar.m_hInstance,
IDS_ERROR_TITLE,
szTitle,
MAX_TITLE);
wsprintf(szString,
TEXT("%s %d MB."),
szMessage,
SIZE_TOTAL);
MessageBox(NULL,
szString,
szTitle,
MB_OK | MB_TOPMOST | MB_ICONERROR);
bResult = FALSE;
}
return bResult;
}
// create objects
BOOL CreateObjects()
{
try
{
// initialize the synchronizing object
InitializeCriticalSection(&g_sInstVar.m_oCriticalSection);
}
catch(...)
{
return FALSE;
}
// create a 12 pt big font
CreateBigFont();
return TRUE;
}
// destroy objects
VOID DestroyObjects()
{
// wait to finish the runing setup process
if(g_sInstVar.m_hInstallThread)
{
// wait the installation thread to finish
WaitForSingleObject(g_sInstVar.m_hInstallThread,INFINITE);
CloseHandle(g_sInstVar.m_hInstallThread);
}
// delete the synchronizing object
DeleteCriticalSection(&g_sInstVar.m_oCriticalSection);
//Frees up the space used by loading the fonts
if( g_sInstVar.m_hBigBoldFont )
{
DeleteObject( g_sInstVar.m_hBigBoldFont );
}
}
//create a big font for dialog title
VOID CreateBigFont()
{
NONCLIENTMETRICS ncm;
LOGFONT BigBoldLogFont;
HDC hdc;
// Create the fonts we need based on the dialog font
ZeroMemory(&ncm,sizeof(NONCLIENTMETRICS));
ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
BigBoldLogFont = ncm.lfMessageFont;
BigBoldLogFont.lfWeight = FW_BOLD;
hdc = GetDC(NULL);
if( hdc )
{
BigBoldLogFont.lfHeight = 0 -
(GetDeviceCaps(hdc,LOGPIXELSY) *
SIZE_TITLE_FONT /
72);
g_sInstVar.m_hBigBoldFont = CreateFontIndirect(&BigBoldLogFont);
ReleaseDC(NULL,hdc);
}
}