home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- Module name: Setup.C
- Programmer : Jeffrey M. Richter.
- *****************************************************************************/
-
- #include "..\nowindws.h"
- #undef NOATOM
- #undef NOCTLMGR
- #undef NOKERNEL
- #undef NOLFILEIO
- #undef NOLSTRING
- #undef NOMB
- #undef NOMEMMGR
- #undef NOMINMAX
- #undef NOMSG
- #undef NOOPENFILE
- #undef NORESOURCE
- #undef NOSHOWWINDOW
- #undef NOSYSMETRICS
- #undef NOUSER
- #undef NOWINMESSAGES
- #undef NOWINOFFSETS
- #undef NOWINSTYLES
- #include <windows.h>
- #include <dde.h>
-
- #include <dos.h>
- #include <direct.h>
- #include <string.h>
-
- #include "Setup.H"
- #include "SetupInf.H"
- #include "..\Meter.04\Meter.H"
-
- BOOL NEAR PASCAL CreateDstDirTree (HWND hDlgStatus);
- BOOL NEAR PASCAL CopyAllFiles (HWND hDlgStatus);
- BOOL NEAR PASCAL CreatePMInfo (HANDLE hInstance);
- #define WasCancelled(hDlg) (!IsWindowEnabled(GetDlgItem(hDlg, IDCANCEL)))
-
- char _szAppName[] = "Setup";
- HANDLE _hInstance;
- char _szSrcDir[MAXDIR] = "x:\\"; // Where SETUP.EXE was run from.
- char _szDstDir[MAXDIR];
-
- int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int nCmdShow) {
- int nResult;
- HWND hDlgStatus;
- FARPROC fpStatDlgProc, fpProc;
- HANDLE hLibMeter;
- DWORD dwDiskSpaceNeeded, dwFreeDiskSpace;
- struct diskfree_t DiskFreeSpace;
- char szBuf[100];
-
- // Don't let another instance of this application execute.
- if (hPrevInstance != NULL) return(0);
-
- // Prepare the DDE Client window class so that we can use it later.
- if (!RegisterDDEClient(hInstance)) return(0);
-
- // Initialize the default source path so that it uses the same drive
- // letter that the SETUP.EXE application was executed from.
- GetModuleFileName(hInstance, _szSrcDir, sizeof(_szSrcDir));
- *(_fstrrchr(_szSrcDir, '\\') + 1) = 0;
-
- _hInstance = hInstance;
-
- // Check that the METER.DLL is available at the beginning.
- wsprintf(szBuf, "%sMETER.DLL", (LPSTR) _szSrcDir);
- hLibMeter = LoadLibrary(szBuf);
- if (hLibMeter < 32) {
- MsgBox(hInstance, NULL, IDS_NOMETERLIB, _szAppName,
- MB_ICONINFORMATION | MB_OK | MB_TASKMODAL);
- return(0);
- }
-
- // Read the SETUP.INF file into memory.
- wsprintf(szBuf, "%s%sSETUP.INF", (LPSTR) _szSrcDir, (LPSTR)
- ((*(_fstrrchr(_szSrcDir, '\\') + 1) == 0) ? "" : "\\"));
-
- nResult = (SIM_INITIALIZE_ERROR) SetupInfoSys(SIM_INITIALIZE, 0, szBuf);
- if (nResult != SIM_INIT_NOERROR) {
- MsgBox(hInstance, NULL,
- (nResult == SIM_INIT_NOMEM) ? IDS_NOMEMORY : IDS_NOSETUPINFOFILE,
- _szAppName, MB_ICONINFORMATION | MB_OK | MB_TASKMODAL,
- (LPSTR) szBuf);
- FreeLibrary(hLibMeter);
- return(0);
- }
-
- // Get the amount of memory (in K) that is needed for the installation.
- dwDiskSpaceNeeded = SetupInfoSys(SIM_GETSPACENEEDED, 0, 0);
-
- // Create the Status dialog box.
- fpStatDlgProc = MakeProcInstance(StatusDlgProc, hInstance);
- hDlgStatus = CreateDialog(hInstance, MAKEINTRESOURCE(DLG_STATUS),
- NULL, fpStatDlgProc);
-
- do {
- // Welcome user to setup program and prompt for destination directory.
- fpProc = MakeProcInstance(WelcomeDlgProc, hInstance);
- nResult = DialogBox(hInstance, MAKEINTRESOURCE(DLG_WELCOME),
- NULL, fpProc);
- FreeProcInstance(fpProc);
- if (nResult == IDCANCEL) break;
-
- // check if there is sufficient disk space on the destination drive.
- _dos_getdiskfree(_szDstDir[0] - 'A' + 1, &DiskFreeSpace);
- dwFreeDiskSpace = ((DWORD) DiskFreeSpace.avail_clusters *
- (DWORD) DiskFreeSpace.sectors_per_cluster *
- (DWORD) DiskFreeSpace.bytes_per_sector) / 1024UL;
-
- if (dwFreeDiskSpace < dwDiskSpaceNeeded) {
- MsgBox(hInstance, NULL, IDS_NODISKSPACE, _szAppName,
- MB_OK | MB_ICONINFORMATION | MB_TASKMODAL,
- _szDstDir[0], dwFreeDiskSpace, dwDiskSpaceNeeded);
- continue;
- }
-
- // Try to create the destination directory tree.
- ShowWindow(hDlgStatus, SW_SHOW);
- UpdateWindow(hDlgStatus);
- nResult = CreateDstDirTree(hDlgStatus);
- ShowWindow(hDlgStatus, SW_HIDE);
-
- if (nResult == FALSE) {
- // If the directory tree cannot be created, force loop to repeat.
- dwFreeDiskSpace = 0;
- }
-
- } while (dwFreeDiskSpace < dwDiskSpaceNeeded);
-
- if (nResult == IDCANCEL) {
- DestroyWindow(hDlgStatus);
- FreeProcInstance(fpStatDlgProc);
- FreeLibrary(hLibMeter);
- return(0);
- }
-
- // Make the destination directory the current directory.
- chdir(_szDstDir);
-
- // Try to copy the files.
- ShowWindow(hDlgStatus, SW_SHOW);
- UpdateWindow(hDlgStatus);
- nResult = CopyAllFiles(hDlgStatus);
- ShowWindow(hDlgStatus, SW_HIDE);
-
- // Cleanup the things that we no longer need.
- DestroyWindow(hDlgStatus);
- FreeProcInstance(fpStatDlgProc);
- FreeLibrary(hLibMeter);
-
- if (nResult == FALSE) {
- // Installation not complete.
- MsgBox(hInstance, NULL, IDS_SETUPNOGOOD, _szAppName,
- MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
- return(0);
- }
-
- MsgBox(hInstance, NULL,
- CreatePMInfo(hInstance) ? IDS_PMADDOK : IDS_PMADDNOGOOD,
- _szAppName, MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
- return(0);
- }
-
-
- // ********** Functions for Creating the destination directory tree **********
- BOOL NEAR PASCAL CreateDstDirTree (HWND hDlgStatus) {
- int nResult, nMaxDirs, nDirNum;
- char szBuf[MAXDIR]; MSG Msg;
-
- SetDlgItemText(hDlgStatus, ID_STATLINE1, "Creating destination directory tree...");
- nMaxDirs = (int) SetupInfoSys(SIM_GETNUMDIRS, 0, 0);
- SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE, 0, 0);
- SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSINJOB, nMaxDirs + 1, 0);
- SetDlgItemText(hDlgStatus, ID_STATLINE2, _szDstDir);
-
- // Create the destination directory.
- nResult = chdir(_szDstDir);
- if (nResult != 0) {
- nResult = mkdir(_szDstDir);
- if (nResult != 0) {
- MsgBox(_hInstance, hDlgStatus, IDS_CANTMAKEDIR, _szAppName,
- MB_ICONINFORMATION | MB_OK, (LPSTR) _szDstDir);
- return(FALSE);
- } else chdir(_szDstDir);
- }
- SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE, 1, 0);
-
- // Create any subdirectories under the destination directory.
- for (nDirNum = 0; nDirNum < nMaxDirs; nDirNum++) {
- // Let some other applications execute.
- while (PeekMessage(&Msg, NULL, NULL, NULL, PM_REMOVE)) {
- TranslateMessage(&Msg);
- DispatchMessage(&Msg);
- }
-
- if (WasCancelled(hDlgStatus)) {
- nResult = IDCANCEL;
- break;
- }
-
- wsprintf(szBuf, "%s%s", (LPSTR) _szDstDir,
- (LPSTR) ((*(_fstrrchr(_szDstDir, '\\') + 1) == 0) ? "" : "\\"));
- SetupInfoSys(SIM_GETDIR, nDirNum, _fstrchr(szBuf, 0));
- SetDlgItemText(hDlgStatus, ID_STATLINE2, szBuf);
-
- nResult = chdir(szBuf);
- if (nResult != 0) {
- nResult = mkdir(szBuf);
- if (nResult != 0) {
- MsgBox(_hInstance, hDlgStatus, IDS_CANTMAKEDIR, _szAppName,
- MB_ICONINFORMATION | MB_OK, (LPSTR) szBuf);
- nResult = IDCANCEL;
- break;
- } else chdir(szBuf);
- }
- nResult = IDOK;
- SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE, nDirNum + 2, 0);
- }
- return(nResult != IDCANCEL);
- }
-
-
- // ******************* Functions for Copying Files ***************************
-
- typedef enum {
- CFE_NOERROR,
- CFE_NOMEMORY,
- CFE_CANTOPENSRC,
- CFE_CANTOPENDST,
- } COPYFILE_ERROR;
-
-
- COPYFILE_ERROR NEAR PASCAL CopyFile (LPSTR szSrcPath, LPSTR szDstPath) {
- const WORD wBufferSize = 65535u;
- int nSrcFile, nDstFile;
- WORD wBytesRead, wDate, wTime;
- OFSTRUCT ofSrc, ofDst;
- LPSTR lpBuffer;
- GLOBALHANDLE hMem;
-
- nSrcFile = OpenFile(szSrcPath, &ofSrc, OF_READ);
- if (nSrcFile == -1) return(CFE_CANTOPENSRC);
-
- hMem = GlobalAlloc(GMEM_MOVEABLE, wBufferSize);
- if (hMem == NULL) {
- _lclose(nSrcFile);
- return(CFE_NOMEMORY);
- }
-
- nDstFile = OpenFile(szDstPath, &ofDst, OF_CREATE | OF_WRITE);
- if (nDstFile == -1) {
- _lclose(nSrcFile);
- GlobalFree(hMem);
- return(CFE_CANTOPENDST);
- }
-
- lpBuffer = GlobalLock(hMem);
- do {
- wBytesRead = _lread(nSrcFile, lpBuffer, wBufferSize);
- _lwrite(nDstFile, lpBuffer, wBytesRead);
- } while (wBytesRead == wBufferSize);
- GlobalUnlock(hMem);
-
- // Make the destination file have the same time stamp as the source file.
- _dos_getftime(nSrcFile, &wDate, &wTime);
- _dos_setftime(nDstFile, wDate, wTime);
- _lclose(nDstFile);
-
- GlobalFree(hMem);
- _lclose(nSrcFile);
- return(CFE_NOERROR);
- }
-
-
-
-
- BOOL NEAR PASCAL CopyAllFiles (HWND hDlgStatus) {
- int nMaxFiles, nFileNum, nResult; COPYFILE_ERROR CFE;
- char szSrcPath[MAXPATH], szDstPath[MAXPATH], szFileName[MAXFILENAME];
- char szFileDesc[MAXFILEDESC], szDir[MAXDIRDESC], szDiskDesc[MAXDISKDESC];
- MSG Msg; FARPROC fpProc;
-
- HANDLE hDlgRes;
-
- // Get the handle of the "InsertDisk" dialog box from the EXEcutable file.
- hDlgRes = FindResource(_hInstance, MAKEINTRESOURCE(DLG_INSERTDISK), RT_DIALOG);
-
- // Get the memory handle of the "InsertDisk" dialog box in memory.
- // The block is already in memory because the dialog box is marked as
- // PRELOAD FIXED.
- hDlgRes = LoadResource(_hInstance, hDlgRes);
-
- // Force the memory block to be locked down. This prohibits Windows
- // from discarding the dialog box template from memory.
- LockResource(hDlgRes);
-
- SetDlgItemText(hDlgStatus, ID_STATLINE1, "Copying files...");
- nMaxFiles = (int) SetupInfoSys(SIM_GETNUMFILES, 0, 0);
- SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE, 0, 0);
- SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSINJOB, nMaxFiles, 0);
-
- fpProc = MakeProcInstance(InsertDiskDlgProc, _hInstance);
- for (nFileNum = 0; nFileNum < nMaxFiles; nFileNum++) {
- SetupInfoSys(SIM_GETFILEDESC, nFileNum, szFileDesc);
- SetupInfoSys(SIM_GETFILENAME, nFileNum, szFileName);
- SetupInfoSys(SIM_GETFILEDIR, nFileNum, szDir);
- SetupInfoSys(SIM_GETFILEDISK, nFileNum, szDiskDesc);
- SetDlgItemText(hDlgStatus, ID_STATLINE2, szFileDesc);
-
- wsprintf(szDstPath, "%s%s%s\\%s", (LPSTR) _szDstDir, (LPSTR)
- ((*(_fstrrchr(_szDstDir, '\\') + 1) == 0) ? "" : "\\"),
- (LPSTR) szDir, (LPSTR) szFileName);
-
- do {
- // Let other applications execute.
- while (PeekMessage(&Msg, NULL, NULL, NULL, PM_REMOVE)) {
- TranslateMessage(&Msg);
- DispatchMessage(&Msg);
- }
-
- if (WasCancelled(hDlgStatus)) {
- nResult = IDCANCEL;
- break;
- }
-
- wsprintf(szSrcPath, "%s%s%s\\%s", (LPSTR) _szSrcDir, (LPSTR)
- ((*(_fstrrchr(_szSrcDir, '\\') + 1) == 0) ? "" : "\\"),
- (LPSTR) szDir, (LPSTR) szFileName);
-
- nResult = IDOK;
- if (!SetupInfoSys(SIM_ISFILECOMPRESSED, nFileNum, 0)) {
- CFE = CopyFile(szSrcPath, szDstPath);
-
- switch (CFE) {
-
- case CFE_NOERROR:
- nResult = IDOK;
- break;
-
- case CFE_NOMEMORY:
- nResult = MsgBox(_hInstance, hDlgStatus, IDS_NOMEMORYCOPY,
- _szAppName, MB_ICONINFORMATION | MB_RETRYCANCEL);
- break;
-
- case CFE_CANTOPENSRC:
- nResult = DialogBoxParam(_hInstance,
- MAKEINTRESOURCE(DLG_INSERTDISK), hDlgStatus, fpProc,
- (LONG) (LPSTR) szDiskDesc);
-
- // Normally, Windows would have discarded the dialog box
- // template from memory after the dialog box had been
- // created. By forcing the memory block to be locked by the
- // call to LockResource() above, the template will NOT be
- // discarded. If the template were discarded, the next time
- // this dialog box needed to be created Windows would have
- // to load the template from the EXEcutable file. However,
- // the SETUP.EXE file is probably not on the diskette that
- // is currently in the drive. This would cause the program
- // to behave erratically.
- break;
-
- case CFE_CANTOPENDST:
- nResult = MsgBox(_hInstance, hDlgStatus, IDS_CANTOPENDST,
- _szAppName, MB_ICONINFORMATION | MB_RETRYCANCEL);
- break;
- }
- } else {
- // Use decompression function to copy the file.
- }
-
- // Make sure that the user really wants to cancel Setup.
- if (nResult == IDCANCEL) {
- nResult = MsgBox(_hInstance, hDlgStatus, IDS_QUERYABORT,
- _szAppName, MB_ICONQUESTION | MB_YESNO);
- if (nResult == IDYES) {
- nResult = IDCANCEL;
- break;
- }
- }
-
- } while (nResult != IDCANCEL && CFE != CFE_NOERROR);
- if (nResult == IDCANCEL) break;
-
- SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE,
- nFileNum + 1, 0);
- }
-
- // The dialog box template is no longer necessary to keep around so
- // it may be unlocked and removed from memory.
- UnlockResource(hDlgRes);
- FreeResource(hDlgRes);
-
- FreeProcInstance(fpProc);
- return(nResult != IDCANCEL);
- }
-
- // *********************** Miscellaneous Function ****************************
- int FAR cdecl MsgBox (HANDLE hInstance, HWND hWnd, WORD wID,
- LPSTR szCaption, WORD wType, ...) {
- char szResString[200], szText[200];
- void FAR *VarArgList = (WORD FAR *) &wType + 1;
- LoadString(hInstance, wID, szResString, sizeof(szResString) - 1);
- wvsprintf(szText, szResString, VarArgList);
- return(MessageBox(hWnd, szText, szCaption, wType));
- }