Done. The list of DLLs now are sentences of Rexx' words. An avoidable disadvantage is that embedded spaces in relative DLL file names no longer are supported. So you can install TB as "C:\Internet Apps\thunderbird\thunderbird.exe", but you cannot use the full file spec "C:\Internet Apps\thunderbird\original dlls\NSS.DLL". Because, according to Rexx, "original" and "dlls\NSS.DLL" are 2 words (and 2 files), due to the blank character. This problem doesn't exist at the moment.
If one has no clue what the number of Rexx words of "original dlls\nss.dll" is: REXXTRY.CMD SAY Words('original dlls\nss.dll')
The output for INSTURBO.CMD must be 1. One Rexx "word" (per one DLL file). As stated above: the problem doesn't exist now.
Untested: installing SM (and TB?) uses icon files distributed via the original ZIP file.
Fully untested: Mozilla, because typically the OS will install that legacy browser and the only update should be the new, recommended MOZTURBO.EXE. No DLLs loaded high, no MOZILLA.EXE objects created.
Main changes were announced earlier. New DLLs can be appended as words in the section of line numbers 30-40 (generic, FF, SM and TB, SM only). Read-only file attribute unset and set for all qualifying read-only DLLs, albeit without error checking (a.o. SysFileTree not running out of memory, no fatal error message when restoring read-only failed). And (default = no) creating a folder and objects inside that folder. The Turbo objects can be created there too.
BTW, if RPM or whatever installs HIGHMEM.EXE in a PATH directory, then it's quite likely that it will be found quite fast indeed. The search order is first ABOVE512.EXE (just because I've got that) and next HIGHMEM.EXE. If the user doesn't type the full path, then the slowest time will be having no ABOVE512.EXE and having a Z:\ZZZZZ\Microsoft Cloud\Huge Network drive\Family\The wife\Tools\HIGHMEM.EXE file.
Possible tests, excluding user-I/O:
Check the relative DLL file names (not changed).
Check if the icons are right for SM/TB (as used in INSTURBO.CMD's FILESPEC=xxx\yyy.ico).
Copy (MOZILLA.EXE,) MOZTURBO.EXE and INSTURBO.CMD to x:\TEST. This should only create the 3 turbo-related objects.
Unzip FF/SM/TB in x:\TEST, copy xxTURBO.EXE and INSTURBO.CMD to the 3 main directories. Optionally mark or unmark DLLs as read-only, and execute the 3 INSTURBO.CMDs.
Basic FF test, starting with installing a FFTURBO.ZIP package in the main FF directory and making sure that some DLL's are(n't) marked as read-only:
Check if the command "THUNDERBIRD.EXE -mail" makes sense. If not, change its "CALL SysCreateObject ..." to "IF product='SM' THEN CALL SysCreateObect ...".
inflating: CHANGES
inflating: ffturbo.exe
inflating: LICENSE
inflating: readme
[R:\meuk\firefox]attrib +r mozsqlt3.dll
[R:\meuk\firefox]attrib +r xul.dll
[R:\meuk\firefox]attrib -r lgpllibs.dll
[R:\meuk\firefox]insturbo.cmd
Product found: FF
FFTURBO.EXE found.
Do you want to use memory above 512 MiB for DLLs (default, recommended),
which doesn't require having more than 512 MiB of RAM installed (Y/n)?
All expected DLLs found.
Please enter the full path to ABOVE512.EXE or HIGHMEM.EXE, or press nothing
but <ENTER> to try to find it:
ABOVE512.EXE or HIGHMEM.EXE not found in current directory nor PATH.
Searching...
Scanning drive C:
Scanning drive D:
Found: D:\Utilities\Above512\ABOVE512.exe
DLL unmarked as a read-only file.
module : XUL.DLL
object 0 : base 0x00010000, size 0x036e3e20, flags 0x00012005
readable, !writeable, executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, himem
object 1 : base 0x03700000, size 0x0009b5f0, flags 0x00002003
readable, writeable, !executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, !himem
object 2 : base 0x00000000, size 0x00002324, flags 0x00002039
readable, !writeable, !executable, resource, discardable, shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, !himem
DLL marked as a read-only file again.
module : LGPLLIBS.DLL
object 0 : base 0x00010000, size 0x00069c80, flags 0x00012005
readable, !writeable, executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, himem
object 1 : base 0x00080000, size 0x00017e10, flags 0x00002003
readable, writeable, !executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, !himem
DLL unmarked as a read-only file.
module : MOZSQLT3.DLL
object 0 : base 0x00010000, size 0x000a7110, flags 0x00012005
readable, !writeable, executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, himem
object 1 : base 0x000c0000, size 0x00001bf0, flags 0x00002003
readable, writeable, !executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, !himem
DLL marked as a read-only file again.
module : browser\components\BRWSRCMP.DLL
object 0 : base 0x00010000, size 0x00076990, flags 0x00012005
readable, !writeable, executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, himem
object 1 : base 0x00090000, size 0x00017f50, flags 0x00002003
readable, writeable, !executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, !himem
module : gmp-clearkey\0.1\CLEARKEY.DLL
object 0 : base 0x00010000, size 0x00061f50, flags 0x00012005
readable, !writeable, executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, himem
object 1 : base 0x00080000, size 0x00017d10, flags 0x00002003
readable, writeable, !executable, !resource, !discardable, !shared,
!preload, !invalid, swappable, !16:16 alias, !conforming,
32bit, !IOPL, !himem
Object created: Firefox Turbo
Object created: Firefox Turbo (unload)
WPS shadow object of Firefox Turbo created in the startup folder.
Do you want to try to create WPS objects for Firefox (y/N)? y
Folder Firefox created.
Press <ENTER>...
/* InsTurbo.CMD */
CALL RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
CALL SysLoadFuncs
/* Find Mozilla product in the current directory */
SAY
product=''
IF Stream('MOZILLA.EXE','C','QUERY EXISTS')<>'' THEN product='Mozilla'
IF Stream('THUNDERBIRD.EXE','C','QUERY EXISTS')<>'' THEN product='TB'
IF Stream('FIREFOX.EXE','C','QUERY EXISTS')<>'' THEN product='FF'
IF Stream('SEAMONKEY.EXE','C','QUERY EXISTS')<>'' THEN product='SM'
IF product='' THEN DO
SAY 'Error, cannot find any main Mozilla executable in the current directory:'
SAY ' ' Directory()
SAY
CALL CharOut '','Press <ENTER>... '
PULL .
EXIT
END
SAY 'Product found:' product
IF product='Mozilla' THEN product='MOZ'
/* Compile a list of DLLs, with one space between relative full DLL file specs */
dlls=''
IF Length(product)=2 THEN DO
/* DLLs shared by all non-legacy products */
dlls='XUL.DLL LGPLLIBS.DLL MOZSQLT3.DLL'
/* Additional DLLs exclusive for FF only */
IF product='FF' THEN dlls=dlls 'browser\components\BRWSRCMP.DLL gmp-clearkey\0.1\CLEARKEY.DLL'
/* Additional DLLs exclusive for both SM and TB */
IF product='SM' | product='TB' THEN dlls=dlls 'LDAP60.DLL LDIF60.DLL PRLDAP60.DLL'
/* Additional DLLs exclusive for SM only */
IF product='SM' THEN dlls=dlls 'components\SUITE.DLL'
END
dll.0=Words(dlls)
DO i=1 TO dll.0
dll.i=Word(dlls,i)
END i
/* Find the matching TURBO.EXE in the same current directory */
turbo=product||'TURBO.EXE'
IF Stream(turbo,'C','QUERY EXISTS')='' THEN DO
SAY 'Error, cannot find' turbo 'in the current directory:' Directory()
SAY
CALL CharOut '','Press <ENTER>... '
PULL .
EXIT
END
SAY turbo 'found.'
/* Load DLLs high, if the product is not the legacy Mozilla? */
loadhigh=0
IF Length(product)=2 THEN DO
SAY
SAY 'Do you want to use memory above 512 MiB for DLLs (default, recommended),'
CALL CharOut '',"which doesn't require having more than 512 MiB of RAM installed (Y/n)? "
PULL answer
answer=Strip(answer)
IF answer='' THEN answer='Y'
IF Left(answer,1)='Y' THEN loadhigh=1
SAY
END
/* Load high */
IF loadhigh=1 THEN DO
DO i=1 TO dll.0
IF Stream(dll.i,'C','QUERY EXISTS')='' THEN DO
SAY
SAY 'Error: cannot find' dll.i
SAY
CALL CharOut '','Press <ENTER>... '
PULL .
EXIT
END
END i
SAY 'All expected DLLs found.'
SAY
/* Try to find ABOVE512.EXE or HIGHMEM.EXE, if the answer was (Y)es */
file='ABOVE512.EXE'
high=Stream(file,'C','QUERY EXISTS')
IF high='' THEN high=Stream('HIGHMEM.EXE','C','QUERY EXISTS')
IF high='' THEN high=SysSearchPath('PATH',file)
IF high='' THEN high=SysSearchPath('PATH','HIGHMEM.EXE')
IF high='' THEN DO
SAY 'Please enter the full path to' file 'or HIGHMEM.EXE, or press nothing'
CALL CharOut '','but <ENTER> to try to find it: '
PARSE PULL high
SAY
IF Strip(high)<>'' THEN DO
IF Right(high,1)<>'\' THEN high=high||'\'
high=high||file
IF Stream(high,'C','QUERY EXISTS')='' THEN DO
SAY 'Error: cannot find file' high
SAY
CALL CharOut '','Press <ENTER>... '
PULL .
EXIT
END
END
END
IF Strip(high)='' THEN DO
SAY file 'or HIGHMEM.EXE not found in current directory nor PATH.'
SAY 'Searching...'
drives=SysDriveMap('A:')
IF drives='' THEN DO
SAY
SAY 'Error: no drives found.'
SAY
CALL CharOut '','Press <ENTER>... '
PULL .
EXIT
END
drive.0=Words(drives)
DO i=1 TO drive.0
okay.i=0
IF SysDriveInfo(Word(drives,i))<>'' THEN okay.i=1
END i
DO i=1 TO drive.0
IF okay.i=0 THEN ITERATE i
IF high='' THEN DO
SAY 'Scanning drive' Word(drives,i)
pattern1=Word(drives,i)||'\'||file
pattern2=Word(drives,i)||'\HIGHMEM.EXE'
CALL SysFileTree pattern1,'hit.','FOS'
IF hit.0=0 THEN CALL SysFileTree pattern2,'hit.','FOS'
IF hit.0>0 THEN DO
high=hit.1
SAY
SAY 'Found:' high
END
END
END i
END
IF high='' THEN DO
SAY
SAY 'Error:' file 'nor HIGHMEM.EXE found.'
SAY
CALL CharOut '','Press <ENTER>... '
PULL .
EXIT
END
DO i=1 TO dll.0
/* Is the DLL read-only? */
restore=0
CALL SysFileTree dll.i,'readonly.','F','***+*'
/* If so, then (try to) toggle the setting */
IF readonly.0=1 THEN DO
restore=1
CALL SysFileTree dll.i,'readonly.','F',,'***-*'
CALL SysFileTree dll.i,'readonly.','F','***-*'
IF readonly.0>0 THEN SAY dll 'unmarked as a read-only file.'
END
arguments=dll.i '-c'
IF Translate(FileSpec('N',high))='HIGHMEM.EXE' THEN arguments='-c' dll.i
'@'||high arguments
/* (Try to) restore the read-only setting, if possibly changed */
IF restore=1 THEN DO
CALL SysFileTree dll.i,'readonly.','F',,'***+*'
CALL SysFileTree dll.i,'readonly.','F','***+*'
IF readonly.0>0 THEN SAY dll 'marked as a read-only file again.'
END
END i
END
here=Translate(Directory())
name=''
IF product='FF' THEN name='Firefox'
IF product='MOZ' THEN name='Mozilla'
IF product='SM' THEN name='SeaMonkey'
IF product='TB' THEN name='Thunderbird'
name2=name 'Turbo'
SAY
IF SysCreateObject('WPProgram',name2,'<WP_DESKTOP>','EXENAME=CMD.EXE;PARAMETERS=/c detach' here||'\'||turbo '-l;STARTUPDIR='||here||';MINIMIZED=YES;OBJECTID=<TURBO_'||product||'>','R') THEN DO
SAY 'Object created:' name2
IF SysCreateObject('WPProgram',name2 '(unload)','<WP_DESKTOP>','EXENAME='||here||'\'||turbo||';PARAMETERS=-u;STARTUPDIR='||here||';MINIMIZED=YES;OBJECTID=<TURBO_'||product||'_UNLOAD>','R') THEN DO
SAY 'Object created:' name2 '(unload)'
IF SysCreateShadow('<TURBO_'||product||'>','<WP_START>') THEN DO
SAY'WPS shadow object of' name2 'created in the startup folder.'
SAY
answer='N'
IF Length(product)=2 THEN DO
CALL CharOut '','Do you want to try to create WPS objects for' name||' (y/N)? '
PULL answer
answer=Strip(answer)
END
IF answer='' THEN answer='N'
IF Left(answer,1)='Y' THEN DO
SAY
folderid='<'||product||'_FOLDER>'
IF SysCreateObject('WPFolder',name,'<WP_DESKTOP>','OBJECTID='||folderid,'R') THEN DO
SAY 'Folder' name 'created.'
IF product='FF' THEN exename=here||'\'||'FIREFOX.EXE'
IF product='SM' THEN exename=here||'\'||'SEAMONKEY.EXE'
IF product='TB' THEN exename=here||'\'||'THUNDERBIRD.EXE'
CALL SysCreateObject 'WPProgram',name 'Profile Manager',folderid,'EXENAME='||exename||';PARAMETERS=-ProfileManager;STARTUPDIR='||here
CALL SysCreateObject 'WPProgram',name 'Read Me',folderid,'EXENAME=E.EXE;PARAMETERS='||here||'README.OS2;STARTUPDIR='||here
CALL SysCreateObject 'WPProgram',name 'Safe Mode',folderid,'EXENAME='||exename||';PARAMETERS=-safe-mode;STARTUPDIR='||here
IF product='SM' | product='TB' THEN DO
CALL SysCreateObject 'WPProgram',name 'Composer',folderid,'EXENAME='||exename||';PARAMETERS=-edit;STARTUPDIR='||here,';ICONFILE='||here||'\chrome\icons\default\editorWindow.ico'
CALL SysCreateObject 'WPProgram',name 'Mail',folderid,'EXENAME='||exename||';PARAMETERS=-mail;STARTUPDIR='||here,';ICONFILE='||here||'\chrome\icons\default\messengerWindow.ico'
CALL SysCreateObject 'WPProgram',name 'News',folderid,'EXENAME='||exename||';PARAMETERS=-news;STARTUPDIR='||here,';ICONFILE='||here||'\chrome\icons\default\messengerWindow.ico'
CALL SysCreateObject 'WPProgram',name 'Send Mail',folderid,'EXENAME='||exename||';PARAMETERS=-compose mailto:[mailto:];STARTUPDIR='||here,';ICONFILE='||here||'\chrome\icons\default\msgcomposeWindow.ico'
END
/* Main EXE last, so it's selected by default when the folder is opened in icon view */
CALL SysCreateObject 'WPProgram',name,folderid,'EXENAME='||exename||';STARTUPDIR='||here
END
SAY
END
CALL CharOut '','Press <ENTER>... '
PULL .
EXIT
END
END
END
SAY 'Error: cannot create all 3 WPS objects.'
SAY
CALL CharOut '','Press <ENTER>... '
PULL .
EXIT