J3 Limited
 
Google
WWW J3Ltd
 
Using CAB Files In MS IE

 CAB files are used by Microsoft to package files into a compressed archive file whose name usually ends with .cab (just like zip files, but done the Microsoft way).

A set of java classes can be packaged into a cab file. This allows a lengthy code installation to be performed once only. On subsequent browser visits the user’s JVM detects that the classes are already downloaded. Therefore the applet can start immediately. This technique has been successfully used to develop a set of applets which use Sun’s Swing java classes (around 1Meg download), on an ISDN based intratnet as well as local area networks.

Microsoft Internet Explorer versions 3.x upwards understand cab files. cab file names can be referred to in object tags, or applet tags. This is a feature well worth knowing when developing Java software for MSIE.

This technique also opens up Java’s printing abilities to an applet writer. A signed applet can (depending on the user’s security settings) print, read and write files on the user’s hard disk.

Background Information

There now follows a brief explanation of how MSIE’s JVM locates class files.

On any Windows installation there is a directory within the Winnt or Windows directory. This directory’s name is Java. This is where Microsoft’s JVM looks for class files.

MS's Java Subdirectories:

  • Classes: holds the Java core & Microsoft classes, sometimes found in a file called classes.zip.
  • Lib: this is where we will download our class files. Files placed here are on the class path, and usually MS JVM looks here for files, before going down the TCP/IP route. Fresh installations of Internet Explorer do not have this directory, installing a cab file creates the directory if need be.
  • Packages: the use of this directory is not currently known.
  • Trustlib: OLE Object Java wrapper classes are usually placed here, for example AxctiveX control Java wrappers

By placing often used (and stable) class files in the lib subdirectory, we can speed up applet download times. The JVM checks the directory for any classes required before trying to download them.

All that remains is to explain how to package java classes so that they end up in the user’s java\lib directory.

How To...

Here's a quick explanation of how to generate cab files and put them on a web page.

Don't worry if it's confusing, it's probably meant to be that way.

Get The CAB SDK

First you need to make sure you have the correct cab manufacturing utilities. The cab sdk is freely available on Microsoft’s web site (somewhere). Alternatively MSDN subscribers will have the sdk on one of the CD’s (somewhere). Old SDK versions don’t handle long file names correctly. I have found that extract.exe versions 1.00.0601 upwards function correctly. To see the version you have, open a dos prompt in the bin directory where the cab sdk is installed and type extract.

As an aside, windows installs an old version in the windows/winnt directory, which does not handle long file names. You can copy extract from the cab sdk to your windows directory to avoid confusion.

Wrap The Classes In A CAB Archive

All the required Java class files can be placed in a new cab file by writing a small bat file, for example:

  • D:
    cd \CurrentProjects\Java\Output
    C:\PROGRA~1\CABSDK\bin\CABARC.EXE -p -r N innercab.cab *.*
    • -p: this option preserves path (directory) information. It is worth noting that the starting path is the current path, as specified in the file list. If C:\Work\Java\Output\*.* were given as the list of files to archive, the preserved file locations would start at Work\Java\Output.
    • -r: ask the cabarc utility to recursively scan subdirectories, and add the files found to the archive.
    • N cabFileName: this option specifies the cabfile to generate. In this example we specify innercab.cab, you should really specify a name more condusive to your project’s purpose.

    The cab file generated can be used in an applet tag :

    • <applet code=myClass.class cabbase=innercab.cab>

    The above can reduce download times, codebase could be used for other browsers (using a compressed jar file for example). This method places the class files in the browser’s cache. We want to install them on the user’s machine to make the installation more parmanent. The next step explains how to do this.

    Wrap The Cab File In Another Cab File

    We now have a cabfile in the current directory (C:\Work\Java\Output) called innercab.cab. The next step is to make this file a sort of versioned object (ActiveX Object) we can place on a web page. In order to do this the following steps must be taken:

    1. A GUID is generated, and its value noted
    2. An inf file is edited. Microsoft provides a template, which requires slight modifications, let this file be called example.inf (it should end with a .inf bit). This file holds:
      • A version number, you can assign your own value here.
      • GUID.
      • The location of one of the Java class files.
      • The directory where the files are extracted (Lib or Trustlib).
    3. Generate a cab file, which holds the cab file generated previously, and example.inf.
    4. Optionally sign the generated cab file. Signing it ensures the user only sees the download dialog 1st time around.

    A GUID is a universally unique identifier generated based on some clever random number generators which use the host’s network card id as a seed.

    Creating a GUID can be done in one of two ways: use the program guidgen.exe, which comes with visual studio tools (also available free in Microsoft’s SDK for Java www.microsoft.com/java ), or take an existing GUID and perform some random changes on it. The former method is preferable, the latter easier.

    To sum up, a new cab file needs to be generated. This new archive holds two files: the previously generated cab file (innercab.cab), and an inf file which tells MSIE where to extract the innercab’s files.

    Below is an example inf (information) file. Copy the outlined section and save it to a file of your choice, then modify the red bits as indicated later. Note that line breaks are important!

    You can download the example file here if you wish.


    Start of Information File


    ; Template for example.inf
    ; Copyright 1996, Microsoft Corporation
    ; Version 1.1, 26 July 1996
    ; This inf file controls the user's installation of your Java
    ; classes. It is important to get all of this correct.
    ; This is separated into sections; be sure to make the >
    ; necessary changes in each one.
    [hook1]
    ; In this line, replace CabFileName.cab with the CAB file name
    ; you chose when filling in the template for ClassPck.ddf,
    ; at .Set CabinetNameTemplate=
    run=extrac32.exe /e /a /y /l %49000% innercab.cab
    [hook2]
    ; Change the name of master.inf to the name you are assigning this
    ; file. Leave the second line alone.
    InfFile=master.inf
    InfSection=RegistryData
    [Strings]
    ; Running uuidgen in the SDK generates the ClassId you need to fill
    ; in here. This classId also goes in the OBJECT tag.
    ; Don't forget the set braces!
    ClassId="{F017E5E1-5A74-11d0-AB71-0020BF49B04D}"
    ; Put the name by which your packages should be referred to
    ; (i.e. "Bob's Text Viewer") here.
    PackageName="J3 CAB Example Classes"
    [AddRegSection]
    ; Leave this line.
    HKLM,"SOFTWARE\Classes\CLSID\%ClassId%",,,"%PackageName%"
    ; Replace <aa...> with the version number (like 1,0,0,1) of this
    ; version of your library. This is so that when you want to update
    ; your libraries, you can change the version rather then the classId
    ; and the problems that go with that. If the version number here
    ; and in the OBJECT tag match the version already stored on the
    ; user's machine, it will not download the classes again, which
    ; also saves time and energy.
    HKLM,"SOFTWARE\Classes\CLSID\%ClassId%\InstalledVersion",,,"1,0,0,0"
    ; Here, replace <filename> with the name of one of the class files in
    ; your package, including the virtual path (specified in classpck.ddf)
    ; to that file. This will make sure that the classes exist on the
    ; user's system; if they don't, they will be downloaded, regardless
    ; of version numbers.
    HKLM,"Software\Classes\CLSID\%ClassId%\InstalledVersion","Path",,"%49000%\j3\com\someJavaClass.class"
    ; Leave these keys alone.
    HKLM,"SOFTWARE\Classes\CLSID\%ClassId%\InProcServer32",,,"%11%\MSJAVA.DLL"
    HKLM,"SOFTWARE\Classes\CLSID\%ClassId%\InProcServer32","NoJavaClass",,""
    HKLM,"SOFTWARE\Classes\CLSID\%ClassId%\InProcServer32","ThreadingModel",,"Both"
    ; Under most circumstances, you should leave the next two keys alone.
    ; Only change them if
    ; 1) You have not expanded the classes into their subdirectories on
    ; the user's machine, but have instead stored them in an uncompressed
    ; .ZIP file; in that case, change the appropriate value
    ; to "%49000%\<ZipFileName>".
    ;
    ; 2) You have decided to install the files onto another, hard-coded
    ; directory of your choice. This is not recommended, for you will
    ; clutter up the user's directories and have to make other changes.
    ; If you do so, though, change the appropriate value to the absolute
    ; pathname to that directory, and change it in the run= line above.
    ; Also note that the "visible in scope" problem explained in the README
    ; for .ZIP files also applies here.
    ;
    ; If you use one of these, you will use exactly one.
    ; The difference between Lib and TrustLib is described in the README.
    HKLM,"SOFTWARE\Classes\CLSID\%ClassId%\InProcServer32","Lib",,"%49000%"
    ;HKLM,"SOFTWARE\Classes\CLSID\%ClassId%\InProcServer32","TrustLib",,"%49000%"
    ; ***************************************************************
    ; THE NEXT SECTION IS TO BE CHANGED IF YOU WANT TO INSTALL
    ; NATIVE CODE (DLLS, ETC.) ON THE USER'S MACHINE. PLEASE BE
    ; RESPONSIBLE ABOUT THIS USE.
    ; ***************************************************************
    ; This template assumes you are installing all items into the
    ; <windir>\system directory, and that they are all in 8.3 form.
    ; If you need something more complex, update the INF appropriately.
    ; Leave these three lines.
    [RegistryData]
    AddReg=AddRegSection
    CustomDestination=MyCustomDestination
    ;; If you are installing native code, you will want to uncomment all
    ;; the lines in the remainder of this section, except for the ones
    ;; that are descriptive (and have two semicolons).
    ; CopyFiles=OtherFiles
    ;[DestinationDirs]
    ;OtherFiles=11
    ;[OtherFiles]
    ;; List the name of each file (delimited by returns) here.
    ;; Just list the local name--no need for paths, etc. Example:
    ;; foo1.dll,,,32
    ;; foo2.dll,,,32
    ;[SourceDisksFiles]
    ;; For each name listed in the above section, you will want to put
    ;; <filename>=1 on this list. So it would look like
    ;; foo1.dll=1
    ;; foo2.dll=1
    ;[SourceDisksNames]
    ;1=%PackageName%,"",0
    ; **************************************************************
    ; END OF NATIVE CODE SECTION
    ; **************************************************************
    [PackageDestination49000]
    ; This value should only change if you have decided to place your
    ; classes in the TrustedClasspath. In that case, you
    ; will change "LibsDirectory" to "TrustedLibsDirectory".
    ; The reasons to do this are explained in the README.
    "HKLM","Software\Microsoft\Java VM","LibsDirectory","",""
    ; *************************************************
    ; THE REMAINDER OF THIS FILE SHOULD NOT BE CHANGED.
    ; *************************************************
    [Setup Hooks]
    hook1=hook1
    hook2=hook2
    [Version]
    signature="$CHICAGO$"
    AdvancedINF=2.0
    [DefaultInstall]
    CustomDestination=MyCustomDestination
    AddReg=AddRegSection
    [MyCustomDestination]
    49000=PackageDestination49000,23

    End Of Information File


    Explanation Of highlighted Entries

    The red bits in the previous section outline what you need to change in the sample file.

    run=extrac32.exe /e /a /y /l %49000% innercab.cab

    change innercab.cab to the name of the cab file which holds all your java class files.

    ClassId="{F017E5E1-5A74-11d0-AB71-0020BF49B04D}"

    Change this hexadecimal GUID to your randomly generated GUID for this project.

    PackageName="J3 CAB Example Classes"

    Specify your project’s verbose name in the double quotes.

    HKLM,"SOFTWARE\Classes\CLSID\%ClassId%\InstalledVersion",,,"1,0,0,0"

    Give your project a version number, this number is stored on the system. When you provide enhancements/bug fixes you can increment this version number. This number is also present in the object tag on the web page which references this cab ActiveX object. The browser uses this tag to determine if it has the correct version installed. If not it will try to download an updated version.

    In short just remember to update this inf file number as well as the number in the web page’s object tag (explained later) to ensure users get timely updates installed on their system.

    HKLM,"Software\Classes\CLSID\%ClassId%\InstalledVersion","Path",,"%49000%\j3\com\someJavaClass.class"

    Here you specify a class file name (pick a class, any class in your innercab.cab). It’s a second line of defence used by Microsoft, in case things get corrupted. If the above file is not present, MSIE will download the cab again.

    HKLM,"SOFTWARE\Classes\CLSID\%ClassId%\InProcServer32","Lib",,"%49000%"

    Just make sure the above line is OK, and has not got a ‘;’ before it. As explained in the comments, you can either download the files into the user’s "LIB" directory, or TRUSTLIB. This article focusses on installing standard java class files which should be in the LIB directory.

    For the curious among you, the TRUSTLIB directory is used to place ActveX control wrapper classes. These allow Java classes to call ActiveX control methods in an ActiveX control (more of this if enough of you readers ask me to explain this).

    "HKLM","Software\Microsoft\Java VM","LibsDirectory","",""

    Ditto, just to make sure .

    Generate The Final Cab File

    The next step is to generate a cab file, which holds the example.inf file, and the initial cab file generated (innercab.cab).

    C:
    cd \work\Java\Output
    C:\PROGRA~1\CABSDK\bin\CABARC.EXE -s 6144 N master.cab master.inf innercab.cab

    The above commands change to the directory where the files to be archived are placed. Cabarc is given the following parameters:

    • -s 6144: reserves 6144 bytes for a digital signature
    • N final.cab: specifies the name of the cab file to generate.
    • example.inf innercab.cab: the two files to place in the cab file

    Sign The Cab File (Optional)

    This step allows the following:

    • The second time the cab object tag is encountered, the installation is not performed
    • The user does not see a digital certificate confirmation dialog the second time around. Depending on the security settings, the user may not even see it first time around.
    • It should stop anybody but the CIA and hackers from tampering with your archive =:-o

    The tool to sign a cab file is also provided by Microsoft’s developper tools, and in the Java SDK (www.microsoft.com/java).

    Unfortunately you need to get hold of a key. It’s no longer free for individuals, companies have to pay even more (www.verisign.com ).

    To sign the above generated cab file you perform the following steps, whilst online to the internet:

    "Signcode.exe final.cab –spc C:\Progra~1\Signcode\mycredentials.spc –v C:\Progra~1\Signcode\verisign.key –t http://timestamp.verisign.com/scripts/timstamp.dll"

    My shoestring budget does not allow for spending anything but time. Hence it is not possible to explain the intricacies of the above line. This step is optional though.

    Place An Object Tag On One Of Your Web Pages

    Here is an example web page:

    <html><OBJECT CLASSID="CLSID: F017E5E1-5A74-11d0-AB71-0020BF49B04D" CODEBASE="final.cab"#Version=1,0,0,0">
    </OBJECT>
    <head>
    <title>J3 Fantastic Cab File Demo</title>
    </head>
    <body>
    <applet
    code=com.j3.someJavaApplet.class name=MeDemo width=100% height=90% >
    </applet>
    </body>
    </html>

    The Object Tag:

    • The object tag is responsible for installing the java classes to the user’s computer. The tag need not be on the same page as the applet, but this ensures the user will have the files installed.
    • The GUID for the object is specified, this allows MSIE to check it has the object already installed without downloading the cab.
    • The cab file name is specified, so that MSIE can download the file, if it needs to.
    • A version number is given. This number is also entered in the cab file. This allows MSIE to determine if the user has an old, and out of date cab installed.

    The Applet Tag:

    • The code entry specifies the applet class to run. The object tag will have installed it on the user’s machine.

    Conclusion

    This completes the discussion of cab files in MSIE. We have covered the following important topics:

    • How to wrap java classes in a cab file
    • How to wrap a cab file in another cab file to permanently install the files on the user’s machine
    • How to use the Object and Applet HTML tags to use the archived java classes.

    This technique is really aimed at intranet and extranet software development. The general public is not always prepared to accept software from untrusted sources. This is because signed applets are not subject to the Java sandbox security.

      Copyright 2000 J3 LtdPermission is granted to reproduce material on this page, on the condition that a reference to "WWW.J3Ltd.com" is given as the source of the material.