'* $Revision:   1.14  $
'* $Logfile:   H:/proj/rns/vcs/install/setup.inv  $

CONST TRUE = 1
CONST FALSE = 0

'**************************************************************************
'*******************************  Windows API's  **************************
'**************************************************************************
GLOBAL hSetup AS INTEGER
GLOBAL fFrameInit AS INTEGER
GLOBAL fInstallInit AS INTEGER

CONST SM_CXSCREEN = 0
CONST SM_CYSCREEN = 1

CONST WF_80x87    = 1024
CONST WF_CPU186   =  128
CONST WF_CPU286   =    2
CONST WF_CPU386   =    4
CONST WF_CPU486   =    8
CONST WF_STANDARD =   16
CONST WF_ENHANCED =   32
CONST WF_WINNT    = &H4000


'' DoMsgBox Flags

CONST MB_OK          = 0
CONST MB_ICONHAND    = 16
CONST MB_TASKMODAL   = 8192


DECLARE FUNCTION DoMsgBox LIB "mscomstf.dll" (lpText$,lpCaption$,wType%) As INTEGER
DECLARE FUNCTION GetWindowsDirectory LIB "kernel" (szBuf$, cbBuf%) AS INTEGER
DECLARE FUNCTION GetSystemDirectory LIB "kernel" (szBuf$, cbBuf%) AS INTEGER
DECLARE FUNCTION GetProfileString LIB "kernel" (szSect$, szKey$, szDefault$, szBuf$, cbBuf%) AS INTEGER
DECLARE FUNCTION GetVersion LIB "kernel" AS INTEGER
DECLARE FUNCTION GetSystemMetrics LIB "user" (nIndex%) AS INTEGER
DECLARE FUNCTION GetWinFlags LIB "kernel" AS LONG




'**************************************************************************
'****************************** Setup Constants ***************************
'**************************************************************************


''Command Option Flags

CONST cmoVital       = 1
CONST cmoCopy        = 2
CONST cmoUndo        = 4
CONST cmoRoot        = 8
CONST cmoDecompress  = 16
CONST cmoTimeStamp   = 32
CONST cmoReadOnly    = 64
CONST cmoBackup      = 128
CONST cmoForce       = 256
CONST cmoRemove      = 512
CONST cmoOverwrite   = 1024
CONST cmoAppend      = 2048
CONST cmoPrepend     = 4096
CONST cmoNone        = 0
CONST cmoAll         = 65535


''File Exist Modes

CONST femExists     = 0
CONST femRead       = 1
CONST femWrite      = 2
CONST femReadWrite  = 3


''Read-Only Return Code

CONST ynrcNo         = 0
CONST ynrcYes        = 1
CONST ynrcErr1       = 2
CONST ynrcErr2       = 3
CONST ynrcErr3       = 4
CONST ynrcErr4       = 5
CONST ynrcErr5       = 6
CONST ynrcErr6       = 7
CONST ynrcErr7       = 8
CONST ynrcErr8       = 9
CONST ynrcErr9       = 10


''General Return Codes

CONST grcOkay       = 0
CONST grcNotOkay    = 1
CONST grcUserQuit   = 48


''Ranges

''CONST cbSymValMax = 8192
CONST cbSymValMax = 512
    ''REVIEW: symbol table will allow strings up to 8192 bytes
    '' but we get Out of String Space wattdrvr error if we alloc
    '' STRING$() that big. (See GetSymbolValue and GetListItem)
    '' We should look into using dynamic far alloc instead of
    '' STRING$ for large buffers.
    '' NOTE: 8192 works okay with runtime wattdrvr, however.


''ON ERROR Error Codes
CONST STFERR      = 1024   ''setup system error
CONST STFQUIT     = 1025   ''user quit

CONST scmOff      = 0
CONST scmOnIgnore = 1
CONST scmOnFatal  = 2


'**************************************************************************
'********************************  Setup API's  ***************************
'**************************************************************************

'' common

DECLARE FUNCTION FOpenInf LIB "mscomstf.dll" (szFile$, fCheck%, fCheckSyms%) AS INTEGER
DECLARE FUNCTION HShowWaitCursor LIB "msshlstf.dll" AS INTEGER
DECLARE FUNCTION FRestoreCursor  LIB "msshlstf.dll" (hPrev%) AS INTEGER

	
''shell

DECLARE FUNCTION FSetBitmap LIB "msshlstf.dll" (szDll$, Bitmap%) AS INTEGER
DECLARE FUNCTION FSetAbout LIB "msshlstf.dll" (szAbout1$, szAbout2$) AS INTEGER
DECLARE FUNCTION FDoDialog LIB "msuilstf.dll" (hwnd%, szDll$, Dlg%, szDlgProc$, HelpDlg%, szHelpProc$) AS INTEGER
DECLARE FUNCTION FKillNDialogs LIB "msuilstf.dll" (n%) AS INTEGER
DECLARE SUB SetWindowText LIB "User" (hwnd%, lpString$)
DECLARE FUNCTION FSetSymbolValue LIB "msshlstf.dll" (szSymbol$, szValue$) AS INTEGER
DECLARE FUNCTION FRemoveSymbol LIB "mscomstf.dll" (szSym$) AS INTEGER
DECLARE FUNCTION CbGetSymbolValue LIB "mscomstf.dll" (szSymbol$, szValue$, Length%) AS INTEGER
DECLARE FUNCTION UsGetListLength LIB "mscomstf.dll" (szSymbol$) AS INTEGER
DECLARE FUNCTION CbGetListItem LIB "mscomstf.dll" (szListSymbol$, n%, szListItem$, cbMax%) AS INTEGER
DECLARE FUNCTION FAddListItem LIB "mscomstf.dll" (szListSymbol$, szListItem$) AS INTEGER
DECLARE FUNCTION FReplaceListItem LIB "mscomstf.dll" (szListSymbol$, n%, szListItem$) AS INTEGER


''shell

DECLARE FUNCTION InitializeFrame LIB "msshlstf.dll" (szCmdLine$) AS INTEGER
DECLARE FUNCTION HwndFrame LIB "msshlstf.dll" AS INTEGER
DECLARE FUNCTION HinstFrame LIB "msshlstf.dll" AS INTEGER



''install

DECLARE FUNCTION FCreateDir LIB "msinsstf.dll" (szDir$, cmo%) AS INTEGER
DECLARE FUNCTION FAddSectionFilesToCopyList LIB "mscomstf.dll" (szSect$, szSrc$, szDest$) AS INTEGER
DECLARE FUNCTION FAddSectionKeyFileToCopyList LIB "mscomstf.dll" (szSect$, szKey$, szSrc$, szDest$) AS INTEGER
DECLARE FUNCTION GrcCopyFilesInCopyList LIB "msinsstf.dll" (hInstance%) AS INTEGER
DECLARE FUNCTION FCreateIniKeyValue LIB "msinsstf.dll" (szFile$, szSect$, szKey$, szValue$, cmo%) AS INTEGER
DECLARE FUNCTION FCreateProgManGroup LIB "msinsstf.dll" (szGroup$, szPath$, cmo%) AS INTEGER
DECLARE FUNCTION FCreateProgManItem LIB "msinsstf.dll" (szGroup$, szItem$, szCmd$, cmo%) AS INTEGER
DECLARE FUNCTION FShowProgManGroup LIB "msinsstf.dll" (szGroup$, szCmd$, cmo%) AS INTEGER
DECLARE SUB      ResetCopyList LIB "msinsstf.dll"
DECLARE FUNCTION LcbGetCopyListCost LIB "msinsstf.dll" (szExtraList$, szCostList$, szNeedList$) AS LONG
DECLARE FUNCTION FCopyOneFile LIB "msinsstf.dll" (szSrc$, szDest$, cmo%, fAppend%) AS INTEGER
DECLARE FUNCTION YnrcBackupFile LIB "msinsstf.dll" (szFullPath$, szBackup$, cmo%) AS INTEGER
DECLARE FUNCTION YnrcRemoveFile LIB "msinsstf.dll" (szFullPathSrc$, cmo%) AS INTEGER
DECLARE FUNCTION FInitializeInstall LIB "msinsstf.dll" (hinst%, hwndFrame%) AS INTEGER
DECLARE FUNCTION FIsDirWritable LIB "msinsstf.dll" (szDir$) AS INTEGER
DECLARE FUNCTION SetSizeCheckMode LIB "msinsstf.dll" (scmMode%) AS INTEGER
DECLARE FUNCTION FCreateSysIniKeyValue LIB "msinsstf.dll" (szFile$, szSect$, szKey$, szValue$, cmo%) AS INTEGER
DECLARE FUNCTION FSetRestartDir LIB "msinsstf.dll" (szDir$) AS INTEGER
DECLARE FUNCTION FRestartListEmpty LIB "msinsstf.dll" AS INTEGER
DECLARE FUNCTION FExitExecRestart LIB "msinsstf.dll" AS INTEGER
DECLARE FUNCTION CbGetIniKeyString LIB "msdetstf.dll" (szFile$, szSect$, szKey$, szBuf$, cbBuf%) AS INTEGER


'*************************************************************************
'****************  Setup Basic Wrapper Declarations  *********************
'*************************************************************************


''shell

DECLARE SUB SetBitmap(szDll$, Bitmap%)
DECLARE SUB SetAbout(szAbout1$, szAbout2$)
DECLARE FUNCTION UIStartDlg(szDll$, Dlg%, szDlgProc$, HelpDlg%, szHelpProc$) AS STRING
DECLARE SUB UIPop (n%)
DECLARE SUB UIPopAll
DECLARE SUB SetTitle (sz$)
DECLARE SUB ReadInfFile (szFile$)
DECLARE SUB SetSymbolValue (szSymbol$, szValue$)
DECLARE SUB RemoveSymbol (szSym$)
DECLARE FUNCTION GetListLength(szSymbol$) AS INTEGER
DECLARE FUNCTION GetSymbolValue (szSymbol$) AS STRING
DECLARE FUNCTION GetListItem(szSymbol$, n%) AS STRING
DECLARE SUB AddListItem(szSymbol$, szItem$)
DECLARE SUB ReplaceListItem(szSymbol$, n%, szItem$)

DECLARE FUNCTION InitFrame (szCmdLine$) AS INTEGER
DECLARE FUNCTION InitSetup (szCmdLine$) AS INTEGER

DECLARE FUNCTION ShowWaitCursor AS INTEGER
DECLARE SUB RestoreCursor (hPrev%)


''install


DECLARE SUB CreateDir (szDir$, cmo%)
DECLARE SUB AddSectionFilesToCopyList (szSect$, szSrc$, szDest$)
DECLARE SUB AddSectionKeyFileToCopyList (szSect$, szKey$, szSrc$, szDest$)
DECLARE SUB MakeListFromSectionFilename (szSym$, szSect$)
DECLARE SUB CopyFilesInCopyList
DECLARE SUB CreateIniKeyValue (szFile$, szSect$, szKey$, szValue$, cmo%)
DECLARE SUB CreateProgmanGroup (szGroup$, szPath$, cmo%)
DECLARE SUB CreateProgmanItem (szGroup$, szItem$, szCmd$, szOther$, cmo%)
DECLARE SUB ShowProgmanGroup (szGroup$, Cmd%, cmo%)
DECLARE SUB ClearCopyList
DECLARE FUNCTION GetCopyListCost (szExtraList$, szCostList$, szNeedList$) AS LONG
DECLARE SUB CopyFile (szFullPathSrc$, szFullPathDst$, cmo%, fAppend%)
DECLARE SUB RemoveFile (szFullPathSrc$, cmo%)
DECLARE SUB RenameFile (szFullPath$, szBackup$)
DECLARE SUB InitInstall
DECLARE SUB OpenLogFile (szFile$, fAppend%)
DECLARE SUB CloseLogFile
DECLARE SUB WriteToLogFile (szStr$)
DECLARE FUNCTION IsDirWritable (szDir$) AS INTEGER
DECLARE FUNCTION FMakeListInfSectionField LIB "mscomstf.dll" (szSym$, szSect$, iField%) AS INTEGER
DECLARE SUB CreateSysIniKeyValue (szFile$, szSect$, szKey$, szValue$, cmo%)
DECLARE FUNCTION GetNthFieldFromIniString (szLine$, iField%) AS STRING
DECLARE SUB SetRestartDir(szDir$)
DECLARE FUNCTION RestartListEmpty AS INTEGER
DECLARE FUNCTION ExitExecRestart AS INTEGER


'' Windows system detect

DECLARE FUNCTION GetWindowsDir  AS STRING
DECLARE FUNCTION GetWindowsSysDir AS STRING
DECLARE FUNCTION GetScreenWidth AS INTEGER
DECLARE FUNCTION GetScreenHeight AS INTEGER
DECLARE FUNCTION GetWindowsMajorVersion AS INTEGER
DECLARE FUNCTION GetWindowsMinorVersion AS INTEGER
DECLARE FUNCTION GetWindowsMode AS INTEGER
DECLARE FUNCTION GetIniKeyString (szFile$, szSect$, szKey$) AS STRING

'*************************************************************************
'*****************  Setup Basic Wrapper Definitions  *********************
'*************************************************************************
FUNCTION InitSetup(szCmdLine$) STATIC AS INTEGER
    fFrameInit = 0
    fInstallInit = 0

    IF hSetup > 0 THEN
    END IF

    i% = InitFrame(szCmdLine$)
    fFrameInit = 1

    InitInstall
    fInstallInit = 1

    InitSetup = i%
END FUNCTION


'**************************************************************************
FUNCTION InitFrame(szCmdLine$) STATIC AS INTEGER
    IF hSetup > 0 THEN
    ELSE
        i% = InitializeFrame(szCmdLine$)
        IF i% = -1 THEN
            END   '' NOT an error - Usage (/?) or Command line copy operation
        ELSEIF i% = 0 THEN
            END
        ELSE
            InitFrame = i%
        END IF
    END IF
END FUNCTION


'*************************************************************************
SUB InitInstall STATIC
    IF hSetup > 0 THEN
    ELSEIF FInitializeInstall(HinstFrame(), HwndFrame()) = 0 THEN
        END
    END IF
END SUB


'**************************************************************************
SUB SetBitmap(szDll$, Bitmap%) STATIC
    IF FSetBitmap(szDll$, Bitmap%) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'**************************************************************************
SUB SetAbout(szAbout1$, szAbout2$) STATIC
    IF FSetAbout(szAbout1$, szAbout2$) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB SetTitle(sz$) STATIC
    SetWindowText HwndFrame(), sz$
END SUB


'*************************************************************************
SUB ReadInfFile (szFile$) STATIC
    IF FOpenInf(szFile$, 1, 0) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
FUNCTION UIStartDlg(szDll$, Dlg%, szDlgProc$, HelpDlg%, szHelpProc$) STATIC AS STRING
    IF FDoDialog(HwndFrame(), szDll$, Dlg%, szDlgProc$, HelpDlg%, szHelpProc$) = 0 THEN
        ERROR STFERR
    ELSE
        UIStartDlg = GetSymbolValue("DLGEVENT")
    END IF
END FUNCTION


'*************************************************************************
SUB UIPop (n%) STATIC
    IF FKillNDialogs(n%) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB UIPopAll STATIC
    IF FKillNDialogs(65535) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
FUNCTION GetSymbolValue(szSymbol$) STATIC AS STRING
    szValue$ = string$(cbSymValMax,32)
    Length% = CbGetSymbolValue(szSymbol$, szValue$, cbSymValMax)
    GetSymbolValue = szValue$
    IF Length% >= cbSymValMax THEN
        res% = DoMsgBox("Buffer Overflow", "MS-Setup Error", MB_ICONHAND+MB_OK)
        ERROR STFERR
    END IF
    IF szSymbol$ = "" THEN
        ERROR STFERR
    END IF
    szValue$ = ""
END FUNCTION


'*************************************************************************
FUNCTION GetListLength(szSymbol$) STATIC AS INTEGER
    GetListLength = UsGetListLength(szSymbol$)
    IF szSymbol$ = "" THEN
        ERROR STFERR
    END IF
END FUNCTION


'*************************************************************************
FUNCTION GetListItem(szListSymbol$, nItem%) STATIC AS STRING
    szListItem$ = string$(cbSymValMax,32)
    Length% = CbGetListItem(szListSymbol$, nItem%, szListItem$, cbSymValMax)
    GetListItem = szListItem$
    IF Length% >= cbSymValMax THEN
        res% = DoMsgBox("Buffer Overflow", "MS-Setup Error", MB_ICONHAND+MB_OK)
        ERROR STFERR
    END IF
    IF szListSymbol$ = "" THEN
        ERROR STFERR
    END IF
    if nItem% <= 0 or nItem% > GetListLength(szListSymbol$) then
        ERROR STFERR
    end if
    szListItem$ = ""
END FUNCTION


'*************************************************************************
SUB AddListItem(szSymbol$, szItem$) STATIC
    IF FAddListItem(szSymbol$, szItem$) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB ReplaceListItem(szSymbol$, n%, szItem$) STATIC
    IF FReplaceListItem(szSymbol$, n%, szItem$) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB SetSymbolValue(szSymbol$, szValue$) STATIC
    IF FSetSymbolValue(szSymbol$, szValue$) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB RemoveSymbol(szSym$) STATIC
    IF FRemoveSymbol(szSym$) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
FUNCTION ShowWaitCursor STATIC AS INTEGER
    ShowWaitCursor = HShowWaitCursor
END FUNCTION


'*************************************************************************
SUB RestoreCursor (hPrev%) STATIC
    i% = FRestoreCursor(hPrev%)
    IF i% = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB CreateDir (szDir$, cmo%) STATIC
    IF FCreateDir(szDir$, cmo%) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB CreateProgmanGroup (szGroup$, szPath$, cmo%) STATIC
    IF FCreateProgManGroup(szGroup$, szPath$, cmo%) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB ShowProgmanGroup (szGroup$, Cmd%, cmo%) STATIC
    IF FShowProgManGroup(szGroup$, STR$(Cmd%), cmo%) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB ClearCopyList STATIC
    ResetCopyList
END SUB


'*************************************************************************
FUNCTION GetCopyListCost (szExtraList$, szCostList$, szNeedList$) STATIC AS LONG
    lNeed& = LcbGetCopyListCost (szExtraList$, szCostList$, szNeedList$)
    IF lNeed& < 0 THEN
        ERROR STFERR
    END IF
    GetCopyListCost = lNeed&
END FUNCTION


'*************************************************************************
SUB CreateProgmanItem (szGroup$, szItem$, szCmd$, szOther$, cmo%) STATIC
    szItemNew$ = szItem$
    IF szOther$ <> "" THEN
        szItemNew$ = szItem$ + "," + szOther$
    END IF
    IF FCreateProgManItem(szGroup$, szItemNew$, szCmd$, cmo%) = 0 THEN
        ERROR STFERR
    END IF
    szItemNew$ = ""
END SUB


'*************************************************************************
SUB CopyFilesInCopyList STATIC
    grc% = GrcCopyFilesInCopyList (HinstFrame())

    IF grc% = grcUserQuit THEN
        ERROR STFQUIT
    ELSEIF grc% > 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB CopyFile (szFullPathSrc$, szFullPathDst$, cmo%, fAppend%) STATIC
    IF  FCopyOneFile(szFullPathSrc$, szFullPathDst$, (cmo OR cmoCopy), fAppend%) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB RemoveFile (szFullPathSrc$, cmo%) STATIC
    IF  YnrcRemoveFile(szFullPathSrc$, cmo%) = ynrcNo THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB RenameFile (szFullPath$, szBackup$) STATIC
    IF YnrcBackupFile(szFullPath$, szBackup$, cmoNone) = ynrcNo THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB AddSectionFilesToCopyList (szSect$, szSrc$, szDest$) STATIC
    IF FAddSectionFilesToCopyList (szSect$, szSrc$, szDest$) = 0 THEN
        ERROR STFERR
    END IF
END SUB

'*************************************************************************
SUB AddSectionKeyFileToCopyList (szSect$, szKey$, szSrc$, szDest$) STATIC
'$ifdef DEBUG
    if FValidInfSect(szSect$) = 0 then
        n% = 1
    elseif szKey$ = "" then
        n% = 2
    elseif FValidFATDir(szSrc$) = 0 then
        n% = 3
    elseif FValidFATDir(szDest$) = 0 then
        n% = 4
    else
        n% = 0
    end if
    if n% > 0 then
        BadArgErr n%, "AddSectionKeyFileToCopyList", szSect$+", "+szKey$+", "+szSrc$+", "+szDest$
    end if
'$endif ''DEBUG

    IF FAddSectionKeyFileToCopyList (szSect$, szKey$, szSrc$, szDest$) = 0 THEN
'$ifdef DEBUG
        StfApiErr saeFail, "AddSectionKeyFileToCopyList", szSect$+", "+szKey$+", "+szSrc$+", "+szDest$
'$endif ''DEBUG
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
SUB MakeListFromSectionFilename (szSym$, szSect$) STATIC
    IF FMakeListInfSectionField(szSym$, szSect$, 1) = 0 THEN
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
FUNCTION IsDirWritable (szDir$) STATIC AS INTEGER
    IsDirWritable = FIsDirWritable(szDir$)
END FUNCTION

	
'*************************************************************************
FUNCTION GetWindowsMajorVersion STATIC AS INTEGER
    GetWindowsMajorVersion = GetVersion() MOD 256
END FUNCTION


'*************************************************************************
FUNCTION GetWindowsMinorVersion STATIC AS INTEGER
    GetWindowsMinorVersion = GetVersion() / 256
END FUNCTION


'*************************************************************************
FUNCTION GetWindowsMode STATIC AS INTEGER
    GetWindowsMode = 0
    longTmp& = GetWinFlags()
    IF longTmp& AND WF_STANDARD THEN
        GetWindowsMode = 1
    ELSEIF longTmp& AND WF_ENHANCED THEN
        GetWindowsMode = 2
    END IF
END FUNCTION


'*************************************************************************
FUNCTION GetWindowsDir STATIC AS STRING
    szBuf$ = string$(256, 32)
    cbBuf% = GetWindowsDirectory(szBuf$, 256)

    IF cbBuf% = 0 THEN
        GetWindowsDir = ""
        ERROR STFERR
    ELSE
        IF cbBuf% > 255 THEN
            res% = DoMsgBox("Buffer Overflow", "MS-Setup Error", MB_ICONHAND+MB_OK)
            ERROR STFERR
        END IF
        szBuf$ = RTRIM$(szBuf$)
        IF MID$(szBuf$, 1, 1) = "\" THEN
            'szBuf$ = MID$(CURDIR$, 1, 2) + szBuf$
            szBuf$ = MID$(GetWindowsSysDir, 1, 2) + szBuf$
        ELSEIF MID$(szBuf$, 2, 1) <> ":" THEN
            szBuf$ = MID$(GetWindowsSysDir, 1, 3) + szBuf$
        END IF
        IF MID$(szBuf$, LEN(szBuf$), 1) <> "\" THEN
            szBuf$ = szBuf$ + "\"
        END IF
        GetWindowsDir = szBuf$
    END IF

    szBuf$ = ""
END FUNCTION


'*************************************************************************
FUNCTION GetWindowsSysDir STATIC AS STRING
    szBuf$ = string$(256, 32)
    cbBuf% = GetSystemDirectory(szBuf$, 256)

    IF cbBuf% = 0 THEN
        ERROR STFERR
    ELSE
        IF cbBuf% > 255 THEN
            res% = DoMsgBox("Buffer Overflow", "MS-Setup Error", MB_ICONHAND+MB_OK)
            ERROR STFERR
        END IF
        szBuf$ = RTRIM$(szBuf$)
        IF MID$(szBuf$, 1, 1) = "\" THEN
            szBuf$ = MID$(CURDIR$, 1, 2) + szBuf$
        ELSEIF MID$(szBuf$, 2, 1) <> ":" THEN
            szBuf$ = MID$(CURDIR$, 1, 3) + szBuf$
        END IF
        IF MID$(szBuf$, LEN(szBuf$), 1) <> "\" THEN
            szBuf$ = szBuf$ + "\"
        END IF
        GetWindowsSysDir = szBuf$
    END IF

    szBuf$ = ""
END FUNCTION


'*************************************************************************
FUNCTION GetScreenWidth STATIC AS INTEGER
    GetScreenWidth = GetSystemMetrics(SM_CXSCREEN)
END FUNCTION


'*************************************************************************
FUNCTION GetScreenHeight STATIC AS INTEGER
    GetScreenHeight = GetSystemMetrics(SM_CYSCREEN)
END FUNCTION


'*************************************************************************
SUB CreateSysIniKeyValue (szFile$, szSect$, szKey$, szValue$, cmo%) STATIC
'$ifdef DEBUG
    if FValidFATPath(szFile$) = 0 then
        n% = 1
    elseif FValidInfSect(szSect$) = 0 then
        n% = 2
    elseif szKey$ = "" then
        n% = 3
    else
        n% = 0
    end if
    if n% > 0 then
        BadArgErr n%, "CreateSysIniKeyValue", szFile$+", "+szSect$+", "+szKey$+", "+szValue$+", "+STR$(cmo%)
    end if
'$endif ''DEBUG

    IF FCreateSysIniKeyValue(szFile$, szSect$, szKey$, szValue$, cmo%) = 0 THEN
'$ifdef DEBUG
        StfApiErr saeFail, "CreateSysIniKeyValue", szFile$+", "+szSect$+", "+szKey$+", "+szValue$+", "+STR$(cmo%)
'$endif ''DEBUG
        ERROR STFERR
    END IF
END SUB

'*************************************************************************
FUNCTION GetNthFieldFromIniString (szLine$, iField%) STATIC AS STRING
    IF iField% < 1 THEN
'$ifdef DEBUG
        StfApiErr saeFail, "GetNthFieldFromIniString", szLine$+", "+STR$(iField%)
'$endif ''DEBUG
        ERROR STFERR
    END IF
    szStart$ = szLine$
    IF iField% <> 1 THEN
        FOR i% = 2 TO iField% STEP 1
            iNew% = INSTR(szStart$, ",")
            IF iNew% = 0 THEN
                GetNthFieldFromIniString = ""
                GOTO _GNFFIS_END
            END IF
            szStart$ = MID$(szStart$, (iNew% + 1))
        NEXT
    END IF

    iNew% = INSTR(szStart$, ",")
    IF iNew% <> 0 THEN
        szStart$ = MID$(szStart$, 1, (iNew% - 1))
    END IF

    GetNthFieldFromIniString = LTRIM$(RTRIM$(szStart$))

_GNFFIS_END:

END FUNCTION




'**************************************************************************
'*************************  Error Handlers  *******************************
'**************************************************************************


TRAP CleanupTrap From "MSSHLSTF.DLL"

End Trap

hSetup = InitSetup(COMMAND$)

ON ERROR GOTO QUIT


'**************************************************************************
'*************************  Setup Detect API's  ***************************
'**************************************************************************

''detect

DECLARE FUNCTION FIsValidDrive LIB "msdetstf.dll" (nDrive%) AS INTEGER
DECLARE FUNCTION FIsRemoteDrive LIB "msdetstf.dll" (nDrive%) AS INTEGER
DECLARE FUNCTION LcbFreeDrive LIB "msdetstf.dll" (nDrive%) AS LONG

DECLARE FUNCTION FDoesFileExist LIB "msdetstf.dll" (szFileName$, mode%) AS INTEGER
DECLARE FUNCTION LcbGetSizeOfFile LIB "msdetstf.dll" (szFile$) AS LONG
DECLARE FUNCTION FDirExists LIB "msdetstf.dll" (szDir$) AS INTEGER
DECLARE FUNCTION FIsDriverInConfig LIB "msdetstf.dll" (szDrv$) AS INTEGER
DECLARE FUNCTION CbGetEnvVariableValue LIB "msdetstf.dll" (szEnvVar$, szBuf$, cbBuf%) AS INTEGER
DECLARE FUNCTION WGetConfigLastDrive LIB "msdetstf.dll" AS INTEGER





'*************************************************************************
'****************  Detect Basic Wrapper Declarations  ********************
'*************************************************************************


'' detect

DECLARE FUNCTION IsDriveValid (szDrive$) AS INTEGER
DECLARE FUNCTION IsDriveNetwork (szDrive$) AS INTEGER
DECLARE FUNCTION GetFreeSpaceForDrive (szDrive$) AS LONG

DECLARE FUNCTION DoesFileExist (szFile$, mode%) AS INTEGER
DECLARE FUNCTION GetSizeOfFile (szFile$) AS LONG
DECLARE FUNCTION DoesDirExist (szDir$) AS INTEGER
DECLARE FUNCTION IsDriverInConfig (szDrv$) AS INTEGER
DECLARE FUNCTION GetEnvVariableValue (szEnvVar$) AS STRING
DECLARE FUNCTION GetConfigLastDrive AS STRING



'*************************************************************************
FUNCTION IsDriveValid (szDrive$) STATIC  AS INTEGER
    IsDriveValid = FIsValidDrive(ASC(UCASE$(szDrive$)) - ASC("A") + 1)
END FUNCTION


'*************************************************************************
FUNCTION IsDriveNetwork (szDrive$) STATIC  AS INTEGER
    IsDriveNetwork = FIsRemoteDrive(ASC(UCASE$(szDrive$)) - ASC("A") + 1)
END FUNCTION


'*************************************************************************
FUNCTION GetFreeSpaceForDrive (szDrive$) STATIC  AS LONG
    GetFreeSpaceForDrive = LcbFreeDrive(ASC(UCASE$(szDrive$)) - ASC("A") + 1)
END FUNCTION


'*************************************************************************
FUNCTION DoesFileExist (szFileName$, mode%) STATIC  AS INTEGER
    DoesFileExist = FDoesFileExist(szFileName$, mode%)
END FUNCTION


'*************************************************************************
FUNCTION GetSizeOfFile (szFile$) STATIC  AS LONG
    GetSizeOfFile = LcbGetSizeOfFile(szFile$)
END FUNCTION


'*************************************************************************
FUNCTION DoesDirExist (szDir$) STATIC  AS INTEGER
    DoesDirExist = FDirExists(szDir$)
END FUNCTION


'*************************************************************************
FUNCTION IsDriverInConfig (szDrv$) STATIC  AS INTEGER
'$ifdef DEBUG
    if szDrv$ = "" then
        BadArgErr 1, "IsDriverInConfig", szDrv$
    end if
'$endif ''DEBUG
    IsDriverInConfig = FIsDriverInConfig(szDrv$)
END FUNCTION


'*************************************************************************
FUNCTION GetEnvVariableValue (szEnvVar$) STATIC  AS STRING
'$ifdef DEBUG
    if szEnvVar$ = "" then
        BadArgErr 1, "GetEnvVariableValue", szEnvVar$
    end if
'$endif ''DEBUG
    cb% = 1024
    szBuf$ = STRING$(cb%, 32)
    cbRet% = CbGetEnvVariableValue(szEnvVar$, szBuf$, cb%)
    GetEnvVariableValue = szBuf$
'$ifdef DEBUG
    IF cbRet% >= cb% THEN
        StfApiErr saeOvfl, "GetEnvVariableValue", szEnvVar$
        ERROR STFERR
    END IF
'$endif ''DEBUG
    szBuf$ = ""
END FUNCTION

'*************************************************************************


'*************************************************************************
FUNCTION GetConfigLastDrive STATIC  AS STRING
    chRet% = WGetConfigLastDrive
    if chRet% = 0 then
        GetConfigLastDrive = ""
    else
        GetConfigLastDrive = CHR$(chRet%)
    end if
END FUNCTION

'*************************************************************************
SUB CreateIniKeyValue (szFile$, szSect$, szKey$, szValue$, cmo%) STATIC
'$ifdef DEBUG
    if FValidIniFile(szFile$) = 0 then
        n% = 1
    elseif FValidInfSect(szSect$) = 0 then
        n% = 2
    else
        n% = 0
    end if
    if n% > 0 then
        BadArgErr n%, "CreateIniKeyValue", szFile$+", "+szSect$+", "+szKey$+", "+szValue$+", "+STR$(cmo%)
    end if
'$endif ''DEBUG

    IF FCreateIniKeyValue(szFile$, szSect$, szKey$, szValue$, cmo%) = 0 THEN
'$ifdef DEBUG
        StfApiErr saeFail, "CreateIniKeyValue", szFile$+", "+szSect$+", "+szKey$+", "+szValue$+", "+STR$(cmo%)
'$endif ''DEBUG
        ERROR STFERR
    END IF
END SUB

'*************************************************************************
SUB SetRestartDir (szDir$) STATIC
'$ifdef DEBUG
    if FValidFATDir(szDir$) = 0 then
        BadArgErr 1, "SetRestartDir", szDir$
    end if
'$endif ''DEBUG
    IF FSetRestartDir(szDir$) = 0 THEN
'$ifdef DEBUG
        StfApiErr saeFail, "SetRestartDir", szDir$
'$endif ''DEBUG
        ERROR STFERR
    END IF
END SUB


'*************************************************************************
FUNCTION RestartListEmpty STATIC AS INTEGER
    IF FRestartListEmpty() = 0 THEN
        RestartListEmpty = 0
    ELSE
        RestartListEmpty = 1
    END IF
END FUNCTION


'*************************************************************************
FUNCTION ExitExecRestart STATIC AS INTEGER
    ExitExecRestart = FExitExecRestart
END FUNCTION


'*************************************************************************
FUNCTION GetIniKeyString (szFile$, szSect$, szKey$) STATIC  AS STRING
'$ifdef DEBUG
    if FValidIniFile(szFile$) = 0 then
        n% = 1
    elseif szKey$ = "" then
        n% = 3
    else
        n% = 0
    end if
    if n% > 0 then
        BadArgErr n%, "GetIniKeyString", szFile$+", "+szSect$+", "+szKey$
    end if
'$endif ''DEBUG

    cb% = 512
    szBuf$ = STRING$(cb%, 32)
    cbRet% = CbGetIniKeyString(szFile$, szSect$, szKey$, szBuf$, cb%)
    GetIniKeyString = szBuf$
'$ifdef DEBUG
    IF cbRet% >= cb% THEN
        StfApiErr saeOvfl, "GetIniKeyString", szFile$+", "+szSect$+", "+szKey$
        ERROR STFERR
    END IF
'$endif ''DEBUG
    szBuf$ = ""
END FUNCTION


