home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1996 September
/
PCWK996.iso
/
demo
/
wgelectr
/
emul51
/
setup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-26
|
18KB
|
529 lines
/****************************************************************************
Module name: Setup.C
Programmer : Nils E Thorell & Michael Quirk
*****************************************************************************/
/* #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 */
#pragma warn -pro
#define PATHS "Paths"
#include <windows.h>
#include <dde.h>
#include <dir.h>
#include <dos.h>
#include <direct.h>
#include <string.h>
#include <io.h> // Borland
#include <ctype.h>
#include "Setup.H"
#include "SetupInf.H"
#include "setuppm.h"
#include "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];
void MyDelay(int ms)
{
DWORD stop_time = GetTickCount() + ms; // in milliseconds ..
while(GetTickCount() < stop_time)
;
}
#pragma argsused
int PASCAL WinMain (HANDLE hInst, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
int nResult,i;
HWND hDlgStatus;
FARPROC fpStatDlgProc, fpProc, fpLoadDlgProc;
HANDLE hLibMeter;
DWORD dwDiskSpaceNeeded, dwFreeDiskSpace;
// struct diskfree_t DiskFreeSpace; Microsoft only!
struct dfree 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(hInst)) return(0);
// Initialize the default source path so that it uses the same drive
// letter that the SETUP.EXE application was executed from.
GetModuleFileName(hInst, _szSrcDir, sizeof(_szSrcDir)); *(_fstrrchr(_szSrcDir, '\\') + 1) = 0;
hInstance = hInst;
// 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 != IDOK) {
if(nResult != IDCANCEL)
MsgBox(hInstance, NULL, IDS_CANTSTART, _szAppName, MB_OK);
break;
}
// check if there is sufficient disk space on the destination drive.
//_dos_getdiskfree(_szDstDir[0] - 'A' + 1, &DiskFreeSpace);
getdfree(_szDstDir[0] - 'A' + 1, &DiskFreeSpace);
//dwFreeDiskSpace = ((DWORD) DiskFreeSpace.avail_clusters *
// (DWORD) DiskFreeSpace.sectors_per_cluster *
// (DWORD) DiskFreeSpace.bytes_per_sector) / 1024UL;
dwFreeDiskSpace = ((DWORD) DiskFreeSpace.df_avail *
(DWORD) DiskFreeSpace.df_sclus *
(DWORD) DiskFreeSpace.df_bsec) / 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;
}
i = CreatePMInfo(hInstance) ? IDS_PMADDOK : IDS_PMADDNOGOOD;
MsgBox(hInstance,NULL,i,_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;
/* new variables for multi-level directory create */
char tmp[80], destin[80];
int ix, totallen,i;
struct ffblk TEST; /* for findfirst() function */
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) {
for(i = 0; i < 80 ; i++) tmp[i] = '\0';
strcpy(destin,_szDstDir);
totallen = strlen(destin);
i = ix = 0;
do{
if(ix > 3 && destin[ix] == '\\'){
if((i = findfirst(tmp,&TEST,FA_DIREC)) != 0){
if((nResult = mkdir(tmp)) !=0)
break;
}
tmp[ix] = destin[ix];
} else
tmp[ix] = destin[ix];
if(destin[ix] == '\0' || ix == totallen){
if((i = findfirst(tmp,&TEST,FA_DIREC)) != 0){
if((nResult = mkdir(tmp)) !=0)
break;
}
i = 1;
}
ix++;
}while(ix <= totallen && i == 0);
}
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);
MyDelay(600);
// 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);
MyDelay(300);
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);
}
MyDelay(400);
return nResult != IDCANCEL;
}
// ******************* Functions for Copying Files ***************************
typedef enum {
CFE_NOERROR,
CFE_NOMEMORY,
CFE_CANTOPENSRC,
CFE_CANTOPENDST,
} COPYFILE_ERROR;
#pragma argsused
COPYFILE_ERROR NEAR PASCAL CopyFile (LPSTR szSrcPath, LPSTR szDstPath) {
const WORD wBufferSize = 65535u;
int nSrcFile, nDstFile;
WORD wBytesRead, wDate, wTime;
struct ftime ft; // Borland
OFSTRUCT ofSrc, ofDst;
LPSTR lpBuffer;
GLOBALHANDLE hMem;
char ffname[16];
char UserDir[80];
char fileName[100];
char whosINI = 0, OverWrite = 1;
char *testptr;
static char *PathName[] = {"LoadFilePath","SourceFilePath","EmulatorPath"};
if((testptr = strstr(szSrcPath,".INI"))){
if((testptr = strstr(szSrcPath,"EMUL300"))) whosINI = 1;
if((testptr = strstr(szSrcPath,"BDM300"))) whosINI = 2;
if((testptr = strstr(szSrcPath,"EMUL16"))) whosINI = 3;
if((testptr = strstr(szSrcPath,"BDM16"))) whosINI = 4;
if((testptr = strstr(szSrcPath,"DEMO300"))) whosINI = 5;
if((testptr = strstr(szSrcPath,"DEMO16"))) whosINI = 6;
if((testptr = strstr(szSrcPath,"EMUL196"))) whosINI = 7;
if((testptr = strstr(szSrcPath,"EMUL51"))) whosINI = 8;
if((testptr = strstr(szSrcPath,"DEMO51"))) whosINI = 9;
if((nDstFile = OpenFile(szDstPath, &ofDst, OF_READ)) == -1)
OverWrite = 1;
else {
OverWrite = 0;
_lclose(nDstFile);
}
} else
whosINI = 0;
if(OverWrite){
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);
getftime(nSrcFile,&ft); // Borland
setftime(nDstFile,&ft); // Borland
_lclose(nDstFile);
GlobalFree(hMem);
_lclose(nSrcFile);
if(whosINI){
if(whosINI == 1) strcpy(ffname,"EMUL300.INI");
if(whosINI == 2) strcpy(ffname,"BDM300.INI");
if(whosINI == 3) strcpy(ffname,"EMUL16.INI");
if(whosINI == 4) strcpy(ffname,"BDM16.INI");
if(whosINI == 5) strcpy(ffname,"DEMO300.INI");
if(whosINI == 6) strcpy(ffname,"DEMO16.INI");
if(whosINI == 7) strcpy(ffname,"EMUL196.INI");
if(whosINI == 8) strcpy(ffname,"EMUL51.INI");
if(whosINI == 9) strcpy(ffname,"DEMO51.INI");
strcpy(UserDir,_szDstDir);
strcpy(fileName,_szDstDir);
if(UserDir[strlen(UserDir)] != '\\'){
strcat(UserDir,"\\");
strcat(fileName,"\\");
}
strcat(fileName,ffname);
if(whosINI == 7)
strcat(UserDir,",.OMF");
else if(whosINI < 7 )
strcat(UserDir,",.OBJ");
else
strcat(UserDir,",.*");
WritePrivateProfileString(PATHS,(LPSTR)PathName[0],UserDir,fileName);
if(UserDir[strlen(UserDir)] == '*')
UserDir[strlen(UserDir)-2] = '\0';
else
UserDir[strlen(UserDir)-3] = '\0';
strcat(UserDir,"C");
WritePrivateProfileString(PATHS,(LPSTR)PathName[1],UserDir,fileName);
if(UserDir[strlen(UserDir)] == '*')
UserDir[strlen(UserDir)-2] = '\0';
else
UserDir[strlen(UserDir)-3] = '\0';
if(whosINI == 8 || whosINI == 9)
strcat(UserDir,"STR.SYM\0");
WritePrivateProfileString(PATHS,(LPSTR)PathName[2],UserDir,fileName);
}
}
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];
char szTargetDir[MAXPATH];
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);
// if the target directory is "\WINDOWS" and the file extention
// is ".INI" then the actual WINDOWS home directory.
/*
if(stricmp(szDir,"\\WINDOWS") == 0 && (strstr(szFileName,".INI") || strstr(szFileName,".ini"))) {
char szWindowsDir[MAXDIR];
SetupInfoSys(SIM_GETWINDIR,0, szWindowsDir);
wsprintf(szDstPath, "%s\\%s",(LPSTR)szWindowsDir,(LPSTR)szFileName);
} else */
wsprintf(szDstPath, "%s%s%s\\%s", (LPSTR) _szDstDir, (LPSTR) ((*(_fstrrchr(_szDstDir, '\\') + 1) == 0) ? "" : "\\"), (LPSTR) szDir, (LPSTR) szFileName);
wsprintf(szTargetDir, "%s%s%s\\", (LPSTR) _szDstDir, (LPSTR) ((*(_fstrrchr(_szDstDir, '\\') + 1) == 0) ? "" : "\\"), (LPSTR) szDir);
SetupInfoSys(SIM_GETFILEDISK, nFileNum, szDiskDesc);
SetDlgItemText(hDlgStatus, ID_STATLINE2, szFileDesc);
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) ? "" : "\\"), szDir[0] == '\\'? (LPSTR)(szDir+1):(LPSTR)szDir, (LPSTR) szFileName);
nResult = IDOK;
if (!SetupInfoSys(SIM_ISFILECOMPRESSED, nFileNum, 0)) {
SetDlgItemText(hDlgStatus, ID_STATLINE1, "Copying files...");
switch(CFE = CopyFile(szSrcPath, szDstPath)) {
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)/* szSrcPath */ 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.
SetDlgItemText(hDlgStatus, ID_STATLINE1, "Expanding file during copy...");
switch(CFE = Xpandmain(szSrcPath,(LPSTR) szTargetDir)){
case CFE_NOERROR: nResult = IDOK; break;
case CFE_CANTOPENSRC:
nResult = DialogBoxParam(hInstance, MAKEINTRESOURCE(DLG_INSERTDISK), hDlgStatus, fpProc, (LONG) (LPSTR)/* szSrcPath */ szDiskDesc);
break;
case CFE_CANTOPENDST:
nResult = MsgBox(hInstance, hDlgStatus,IDS_CANTOPENDST, _szAppName, MB_ICONINFORMATION | MB_RETRYCANCEL);
break;
}
}
// 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);
}