//+------------------------------------------------------------------ // // 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 #include #include #include #include #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(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); } }