public void typeKey(
     double sec,
     final int charCode,
     final int keyCode,
     final boolean alt,
     final boolean ctrl,
     final boolean shift,
     final int delay,
     final boolean async) {
   if (!isSecure(sec)) return;
   // called by doh.robot._keyPress
   // see it for details
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           try {
             log("> typeKey Robot " + charCode + ", " + keyCode + ", " + async);
             KeyPressThread thread =
                 new KeyPressThread(
                     charCode, keyCode, alt, ctrl, shift, delay, async ? null : previousThread);
             previousThread = async ? previousThread : thread;
             thread.start();
             log("< typeKey Robot");
           } catch (Exception e) {
             log("Error calling typeKey");
             e.printStackTrace();
           }
           return null;
         }
       });
 }
 public void moveMouse(double sec, final int x1, final int y1, final int d, final int duration) {
   // called by doh.robot.mouseMove
   // see it for details
   // a nice name like "mouseMove" is reserved in Java
   if (!isSecure(sec)) return;
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           int x = x1 + docScreenX;
           int y = y1 + docScreenY;
           if (x > docScreenXMax || y > docScreenYMax) {
             // TODO: try to scroll view
             log("Request to mouseMove denied");
             return null;
           }
           int delay = d;
           log("> mouseMove Robot " + x + ", " + y);
           MouseMoveThread thread = new MouseMoveThread(x, y, delay, duration, previousThread);
           previousThread = thread;
           thread.start();
           log("< mouseMove Robot");
           return null;
         }
       });
 }
Beispiel #3
0
 /**
  * Gets most recent focus owner component associated with the given window. It does that without
  * calling Window.getMostRecentFocusOwner since it provides its own logic contradicting with
  * setDefautlFocus. Instead, it calls KeyboardFocusManager directly.
  */
 private Component getMostRecentFocusOwnerForWindow(Window w) {
   Method meth =
       AccessController.doPrivileged(
           new PrivilegedAction<Method>() {
             @Override
             public Method run() {
               Method meth = null;
               try {
                 meth =
                     KeyboardFocusManager.class.getDeclaredMethod(
                         "getMostRecentFocusOwner", new Class<?>[] {Window.class});
                 meth.setAccessible(true);
               } catch (Exception e) {
                 // Must never happen
                 e.printStackTrace();
               }
               return meth;
             }
           });
   if (meth != null) {
     // Meth refers static method
     try {
       return (Component) meth.invoke(null, new Object[] {w});
     } catch (Exception e) {
       // Must never happen
       e.printStackTrace();
     }
   }
   // Will get here if exception was thrown or meth is null
   return w.getMostRecentFocusOwner();
 }
Beispiel #4
0
  /*
   * Creates a thread to run the applet. This method is called
   * each time an applet is loaded and reloaded.
   */
  synchronized void createAppletThread() {
    // Create a thread group for the applet, and start a new
    // thread to load the applet.
    String nm = "applet-" + getCode();
    loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
    loader.grab(); // Keep this puppy around!

    // 4668479: Option to turn off codebase lookup in AppletClassLoader
    // during resource requests. [stanley.ho]
    String param = getParameter("codebase_lookup");

    if (param != null && param.equals("false")) loader.setCodebaseLookup(false);
    else loader.setCodebaseLookup(true);

    ThreadGroup appletGroup = loader.getThreadGroup();
    handler = new Thread(appletGroup, this, "thread " + nm, 0, false);
    // set the context class loader for this thread
    AccessController.doPrivileged(
        new PrivilegedAction<Object>() {
          @Override
          public Object run() {
            handler.setContextClassLoader(loader);
            return null;
          }
        });
    handler.start();
  }
    public void componentShown(ComponentEvent evt) {
      // sets the security manager to fix a bug in liveconnect in Safari on Mac
      if (key != -1) {
        return;
      }
      window = (JSObject) JSObject.getWindow(applet());

      AccessController.doPrivileged(
          new PrivilegedAction() {
            public Object run() {
              log("> init Robot");
              try {
                SecurityManager oldsecurity = System.getSecurityManager();
                boolean isOpera = false;
                try {
                  isOpera = (System.getProperty("browser").equals("Opera.plugin"));
                } catch (Exception e) {
                }
                try {
                  securitymanager = oldsecurity;
                  securitymanager.checkTopLevelWindow(null);
                  // xdomain
                  if (charMap == null) {
                    if (!confirm(
                        "DOH has detected that the current Web page is attempting to access DOH, but belongs to a different domain than the one you agreed to let DOH automate. If you did not intend to start a new DOH test by visiting this Web page, press Cancel now and leave the Web page. Otherwise, press OK to trust this domain to automate DOH tests.")) {
                      stop();
                      return null;
                    }
                  }
                  log("Found old security manager");
                } catch (Exception e) {
                  e.printStackTrace();
                  log("Making new security manager");
                  securitymanager = new RobotSecurityManager(isOpera, oldsecurity);
                  securitymanager.checkTopLevelWindow(null);
                  System.setSecurityManager(securitymanager);
                }
                // instantiate the Robot
                robot = new Robot();
              } catch (Exception e) {
                log("Error calling _init_: " + e.getMessage());
                key = -2;
                e.printStackTrace();
              }
              log("< init Robot");
              return null;
            }
          });
      if (key == -2) {
        // applet not trusted
        // start the test without it
        window.eval("doh.robot._appletDead=true;doh.run();");
      } else {
        // now that the applet has really started, let doh know it's ok to use it
        log("_initRobot");
        dohrobot = (JSObject) window.eval("doh.robot");
        dohrobot.call("_initRobot", new Object[] {applet()});
      }
    }
 public void log(final String s) {
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           System.out.println((new Date()).toString() + ": " + s);
           return null;
         }
       });
 }
 private void alert(final String s) {
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           window.eval("top.alert(\"" + s + "\");");
           return null;
         }
       });
 }
 private boolean confirm(final String s) {
   return ((Boolean)
           AccessController.doPrivileged(
               new PrivilegedAction() {
                 public Object run() {
                   return ((Boolean) window.eval("top.confirm(\"" + s + "\");"));
                 }
               }))
       .booleanValue();
 }
 public void wheelMouse(double sec, final int amount, final int delay, final int duration) {
   // called by doh.robot.mouseWheel
   // see it for details
   if (!isSecure(sec)) return;
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           MouseWheelThread thread = new MouseWheelThread(amount, delay, duration, previousThread);
           previousThread = thread;
           thread.start();
           return null;
         }
       });
 }
Beispiel #10
0
    /** Handles mouse dragged event */
    public void mouseDragged(MouseEvent ev) {
      Window w = (Window) ev.getSource();

      if (isMovingWindow) {
        Point windowPt;
        try {
          windowPt = (Point) AccessController.doPrivileged(getLocationAction);
          windowPt.x = windowPt.x - dragOffsetX;
          windowPt.y = windowPt.y - dragOffsetY;
          w.setLocation(windowPt);
          windowMoved = true;
        } catch (PrivilegedActionException e) {
        }
      }
    }
 public void downKey(double sec, final int charCode, final int keyCode, final int delay) {
   // called by doh.robot.keyUp
   // see it for details
   // a nice name like "keyDown" is reserved in Java
   if (!isSecure(sec)) return;
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           log("> downKey Robot " + charCode + ", " + keyCode);
           KeyDownThread thread = new KeyDownThread(charCode, keyCode, delay, previousThread);
           previousThread = thread;
           thread.start();
           log("< downKey Robot");
           return null;
         }
       });
 }
 // java.awt.Applet methods
 public void stop() {
   window = null;
   // only secure code run once
   if (key != -2) {
     // prevent further execution of secure functions
     key = -2;
     // Java calls this when you close the window.
     // It plays nice and restores the old security manager.
     AccessController.doPrivileged(
         new PrivilegedAction() {
           public Object run() {
             log("Stop");
             securitymanager.checkTopLevelWindow(null);
             log("Security manager reset");
             return null;
           }
         });
   }
 }
Beispiel #13
0
 /** Get a class loader. Create in a restricted context */
 synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) {
   AppletClassLoader c = classloaders.get(key);
   if (c == null) {
     AccessControlContext acc = getAccessControlContext(codebase);
     c =
         AccessController.doPrivileged(
             new PrivilegedAction<AppletClassLoader>() {
               @Override
               public AppletClassLoader run() {
                 AppletClassLoader ac = createClassLoader(codebase);
                 /* Should the creation of the classloader be
                  * within the class synchronized block?  Since
                  * this class is used by the plugin, take care
                  * to avoid deadlocks, or specialize
                  * AppletPanel within the plugin.  It may take
                  * an arbitrary amount of time to create a
                  * class loader (involving getting Jar files
                  * etc.) and may block unrelated applets from
                  * finishing createAppletThread (due to the
                  * class synchronization). If
                  * createAppletThread does not finish quickly,
                  * the applet cannot process other messages,
                  * particularly messages such as destroy
                  * (which timeout when called from the browser).
                  */
                 synchronized (getClass()) {
                   AppletClassLoader res = classloaders.get(key);
                   if (res == null) {
                     classloaders.put(key, ac);
                     return ac;
                   } else {
                     return res;
                   }
                 }
               }
             },
             acc);
   }
   return c;
 }
 public void releaseMouse(
     double sec, final boolean left, final boolean middle, final boolean right, final int delay) {
   if (!isSecure(sec)) return;
   // called by doh.robot.mouseRelease
   // see it for details
   // a nice name like "mouseRelease" is reserved in Java
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           log("> mouseRelease Robot " + left + ", " + middle + ", " + right);
           MouseReleaseThread thread =
               new MouseReleaseThread(
                   (left ? InputEvent.BUTTON1_MASK : 0)
                       + (middle ? InputEvent.BUTTON2_MASK : 0)
                       + (right ? InputEvent.BUTTON3_MASK : 0),
                   delay,
                   previousThread);
           previousThread = thread;
           thread.start();
           log("< mouseRelease Robot");
           return null;
         }
       });
 }
Beispiel #15
0
  /**
   * get the context for the AppletClassLoader we are creating. the context is granted permission to
   * create the class loader, connnect to the codebase, and whatever else the policy grants to all
   * codebases.
   */
  private AccessControlContext getAccessControlContext(final URL codebase) {

    PermissionCollection perms =
        AccessController.doPrivileged(
            new PrivilegedAction<PermissionCollection>() {
              @Override
              public PermissionCollection run() {
                Policy p = java.security.Policy.getPolicy();
                if (p != null) {
                  return p.getPermissions(
                      new CodeSource(null, (java.security.cert.Certificate[]) null));
                } else {
                  return null;
                }
              }
            });

    if (perms == null) perms = new Permissions();

    // XXX: this is needed to be able to create the classloader itself!

    perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);

    Permission p;
    java.net.URLConnection urlConnection = null;
    try {
      urlConnection = codebase.openConnection();
      p = urlConnection.getPermission();
    } catch (java.io.IOException ioe) {
      p = null;
    }

    if (p != null) perms.add(p);

    if (p instanceof FilePermission) {

      String path = p.getName();

      int endIndex = path.lastIndexOf(File.separatorChar);

      if (endIndex != -1) {
        path = path.substring(0, endIndex + 1);

        if (path.endsWith(File.separator)) {
          path += "-";
        }
        perms.add(new FilePermission(path, SecurityConstants.FILE_READ_ACTION));
      }
    } else {
      URL locUrl = codebase;
      if (urlConnection instanceof JarURLConnection) {
        locUrl = ((JarURLConnection) urlConnection).getJarFileURL();
      }
      String host = locUrl.getHost();
      if (host != null && (host.length() > 0))
        perms.add(new SocketPermission(host, SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION));
    }

    ProtectionDomain domain =
        new ProtectionDomain(
            new CodeSource(codebase, (java.security.cert.Certificate[]) null), perms);
    AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] {domain});

    return acc;
  }
  public void _initKeyboard(double sec) {
    log("> initKeyboard");
    // javascript entry point to discover the keyboard
    if (!isSecure(sec)) return;
    if (charMap != null) {
      dohrobot.call("_onKeyboard", new Object[] {});
      return;
    }

    AccessController.doPrivileged(
        new PrivilegedAction() {
          public Object run() {
            charMap = new HashMap();
            KeyEvent event = new KeyEvent(applet(), 0, 0, 0, KeyEvent.VK_SPACE, ' ');
            charMap.put(new Integer(32), event);
            try {
              // a-zA-Z0-9 + 29 others
              vkKeys = new Vector();
              for (char i = 'a'; i <= 'z'; i++) {
                vkKeys.add(
                    new Integer(
                        KeyEvent.class
                            .getField("VK_" + Character.toUpperCase((char) i))
                            .getInt(null)));
              }
              for (char i = '0'; i <= '9'; i++) {
                vkKeys.add(
                    new Integer(
                        KeyEvent.class
                            .getField("VK_" + Character.toUpperCase((char) i))
                            .getInt(null)));
              }
              int[] mykeys =
                  new int[] {
                    KeyEvent.VK_COMMA,
                    KeyEvent.VK_MINUS,
                    KeyEvent.VK_PERIOD,
                    KeyEvent.VK_SLASH,
                    KeyEvent.VK_SEMICOLON,
                    KeyEvent.VK_LEFT_PARENTHESIS,
                    KeyEvent.VK_NUMBER_SIGN,
                    KeyEvent.VK_PLUS,
                    KeyEvent.VK_RIGHT_PARENTHESIS,
                    KeyEvent.VK_UNDERSCORE,
                    KeyEvent.VK_EXCLAMATION_MARK,
                    KeyEvent.VK_DOLLAR,
                    KeyEvent.VK_CIRCUMFLEX,
                    KeyEvent.VK_AMPERSAND,
                    KeyEvent.VK_ASTERISK,
                    KeyEvent.VK_QUOTEDBL,
                    KeyEvent.VK_LESS,
                    KeyEvent.VK_GREATER,
                    KeyEvent.VK_BRACELEFT,
                    KeyEvent.VK_BRACERIGHT,
                    KeyEvent.VK_COLON,
                    KeyEvent.VK_BACK_QUOTE,
                    KeyEvent.VK_QUOTE,
                    KeyEvent.VK_OPEN_BRACKET,
                    KeyEvent.VK_BACK_SLASH,
                    KeyEvent.VK_CLOSE_BRACKET,
                    KeyEvent.VK_EQUALS
                  };
              for (int i = 0; i < mykeys.length; i++) {
                vkKeys.add(new Integer(mykeys[i]));
              }
            } catch (Exception e) {
              e.printStackTrace();
            }
            Thread thread =
                new Thread() {
                  public void run() {
                    robot.setAutoDelay(0);
                    log("< initKeyboard");
                    pressNext();
                  }
                };
            thread.start();
            return null;
          }
        });
  }
Beispiel #17
0
  /** Determine JDK level of an applet. */
  private void findAppletJDKLevel(Applet applet) {
    // To determine the JDK level of an applet, the
    // most reliable way is to check the major version
    // of the applet class file.

    // synchronized on applet class object, so calling from
    // different instances of the same applet will be
    // serialized.
    Class<?> appletClass = applet.getClass();

    synchronized (appletClass) {
      // Determine if the JDK level of an applet has been
      // checked before.
      Boolean jdk11Target = loader.isJDK11Target(appletClass);
      Boolean jdk12Target = loader.isJDK12Target(appletClass);

      // if applet JDK level has been checked before, retrieve
      // value and return.
      if (jdk11Target != null || jdk12Target != null) {
        jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue();
        jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue();
        return;
      }

      String name = appletClass.getName();

      // first convert any '.' to '/'
      name = name.replace('.', '/');

      // append .class
      final String resourceName = name + ".class";

      byte[] classHeader = new byte[8];

      try (InputStream is =
          AccessController.doPrivileged(
              (PrivilegedAction<InputStream>) () -> loader.getResourceAsStream(resourceName))) {

        // Read the first 8 bytes of the class file
        int byteRead = is.read(classHeader, 0, 8);

        // return if the header is not read in entirely
        // for some reasons.
        if (byteRead != 8) return;
      } catch (IOException e) {
        return;
      }

      // Check major version in class file header
      int major_version = readShort(classHeader, 6);

      // Major version in class file is as follows:
      //   45 - JDK 1.1
      //   46 - JDK 1.2
      //   47 - JDK 1.3
      //   48 - JDK 1.4
      //   49 - JDK 1.5
      if (major_version < 46) jdk11Applet = true;
      else if (major_version == 46) jdk12Applet = true;

      // Store applet JDK level in AppContext for later lookup,
      // e.g. page switch.
      loader.setJDK11Target(appletClass, jdk11Applet);
      loader.setJDK12Target(appletClass, jdk12Applet);
    }
  }
  private void _typeKey(
      final int cCode, final int kCode, final boolean a, final boolean c, final boolean s) {
    AccessController.doPrivileged(
        new PrivilegedAction() {
          public Object run() {
            int charCode = cCode;
            int keyCode = kCode;
            boolean alt = a;
            boolean ctrl = c;
            boolean shift = s;
            boolean altgraph = false;
            log("> _typeKey Robot " + charCode + ", " + keyCode);
            try {
              int keyboardCode = getVKCode(charCode, keyCode);
              if (charCode >= 32) {
                // if it is printable, then it lives in our hashmap
                KeyEvent event = (KeyEvent) charMap.get(new Integer(charCode));
                // see if we need to press shift to generate this
                // character
                if (!shift) {
                  shift = event.isShiftDown();
                }
                altgraph = event.isAltGraphDown();
                keyboardCode = event.getKeyCode();
              }

              // run through exemption list
              if (!isUnsafe(keyboardCode)) {
                if (shift) {
                  log("Pressing shift");
                  robot.keyPress(KeyEvent.VK_SHIFT);
                }
                if (alt) {
                  log("Pressing alt");
                  robot.keyPress(KeyEvent.VK_ALT);
                }
                if (altgraph) {
                  log("Pressing altgraph");
                  robot.keyPress(KeyEvent.VK_ALT_GRAPH);
                }
                if (ctrl) {
                  log("Pressing ctrl");
                  robot.keyPress(KeyEvent.VK_CONTROL);
                }
                if (keyboardCode != KeyEvent.VK_SHIFT
                    && keyboardCode != KeyEvent.VK_ALT
                    && keyboardCode != KeyEvent.VK_CONTROL) {
                  try {
                    robot.keyPress(keyboardCode);
                    robot.keyRelease(keyboardCode);
                  } catch (Exception e) {
                    log("Error while actually typing a key");
                    e.printStackTrace();
                  }
                }
                if (ctrl) {
                  robot.keyRelease(KeyEvent.VK_CONTROL);
                  ctrl = false;
                }
                if (alt) {
                  robot.keyRelease(KeyEvent.VK_ALT);
                  alt = false;
                }
                if (altgraph) {
                  robot.keyRelease(KeyEvent.VK_ALT_GRAPH);
                  altgraph = false;
                }
                if (shift) {
                  log("Releasing shift");
                  robot.keyRelease(KeyEvent.VK_SHIFT);
                  shift = false;
                }
              }
            } catch (Exception e) {
              log("Error in _typeKey");
              e.printStackTrace();
            }
            log("< _typeKey Robot");
            return null;
          }
        });
  }
    public void mouseDragged(MouseEvent ev) {
      Window w = (Window) ev.getSource();
      Point pt = ev.getPoint();

      if (isMovingWindow) {
        Point windowPt;
        try {
          windowPt = (Point) AccessController.doPrivileged(getLocationAction);
          windowPt.x = windowPt.x - dragOffsetX;
          windowPt.y = windowPt.y - dragOffsetY;
          w.setLocation(windowPt);
        } catch (PrivilegedActionException e) {
        }
      } else if (dragCursor != 0) {
        Rectangle r = w.getBounds();
        Rectangle startBounds = new Rectangle(r);
        Dimension min = w.getMinimumSize();

        switch (dragCursor) {
          case Cursor.E_RESIZE_CURSOR:
            adjust(r, min, 0, 0, pt.x + (dragWidth - dragOffsetX) - r.width, 0);
            break;
          case Cursor.S_RESIZE_CURSOR:
            adjust(r, min, 0, 0, 0, pt.y + (dragHeight - dragOffsetY) - r.height);
            break;
          case Cursor.N_RESIZE_CURSOR:
            adjust(r, min, 0, pt.y - dragOffsetY, 0, -(pt.y - dragOffsetY));
            break;
          case Cursor.W_RESIZE_CURSOR:
            adjust(r, min, pt.x - dragOffsetX, 0, -(pt.x - dragOffsetX), 0);
            break;
          case Cursor.NE_RESIZE_CURSOR:
            adjust(
                r,
                min,
                0,
                pt.y - dragOffsetY,
                pt.x + (dragWidth - dragOffsetX) - r.width,
                -(pt.y - dragOffsetY));
            break;
          case Cursor.SE_RESIZE_CURSOR:
            adjust(
                r,
                min,
                0,
                0,
                pt.x + (dragWidth - dragOffsetX) - r.width,
                pt.y + (dragHeight - dragOffsetY) - r.height);
            break;
          case Cursor.NW_RESIZE_CURSOR:
            adjust(
                r,
                min,
                pt.x - dragOffsetX,
                pt.y - dragOffsetY,
                -(pt.x - dragOffsetX),
                -(pt.y - dragOffsetY));
            break;
          case Cursor.SW_RESIZE_CURSOR:
            adjust(
                r,
                min,
                pt.x - dragOffsetX,
                0,
                -(pt.x - dragOffsetX),
                pt.y + (dragHeight - dragOffsetY) - r.height);
            break;
          default:
            break;
        }
        if (!r.equals(startBounds)) {
          w.setBounds(r);
          // Defer repaint/validate on mouseReleased unless dynamic
          // layout is active.
          if (Toolkit.getDefaultToolkit().isDynamicLayoutActive()) {
            w.validate();
            getRootPane().repaint();
          }
        }
      }
    }
Beispiel #20
0
  /** Does install of JRE */
  public static void install() {

    // Hide the JNLP Clients installer window and show own
    Config.getInstallService().hideStatusWindow();
    showInstallerWindow();

    // Make sure the destination exists.
    String path = Config.getInstallService().getInstallPath();
    if (Config.isWindowsInstall()) {
      String defaultLocation = "C:\\Program Files\\Java\\j2re" + Config.getJavaVersion() + "\\";
      File defaultDir = new File(defaultLocation);
      if (!defaultDir.exists()) {
        defaultDir.mkdirs();
      }
      if (defaultDir.exists() && defaultDir.canWrite()) {
        path = defaultLocation; // use default if you can
      }
    }

    File installDir = new File(path);

    if (!installDir.exists()) {
      installDir.mkdirs();
      if (!installDir.exists()) {
        // The installFailed string is only for debugging. No localization needed
        installFailed("couldntCreateDirectory", null);
        return;
      }
    }

    // Show license if neccesary
    enableStep(STEP_LICENSE);
    if (!showLicensing()) {
      // The installFailed string is only for debugging. No localization needed
      installFailed("Licensing was not accepted", null);
    }
    ;

    // Make sure that the data JAR is downloaded
    enableStep(STEP_DOWNLOAD);
    if (!downloadInstallerComponent()) {
      // The installFailed string is only for debugging. No localization needed
      installFailed("Unable to download data component", null);
    }

    String nativeLibName = Config.getNativeLibName();
    File installerFile = null;

    try {
      // Load native library into process if found
      if (nativeLibName != null && !Config.isSolarisInstall()) {
        System.loadLibrary(nativeLibName);
      }

      // Unpack installer
      enableStep(STEP_UNPACK);
      String installResource = Config.getInstallerResource();
      Config.trace("Installer resource: " + installResource);
      installerFile = unpackInstaller(installResource);

      // To clean-up downloaded files
      Config.trace("Unpacked installer to: " + installerFile);
      if (installerFile == null) {
        // The installFailed string is only for debugging. No localization needed
        installFailed("Could not unpack installer components", null);
        return;
      }

      enableStep(STEP_INSTALL);
      setStepText(STEP_INSTALL, Config.getWindowStepWait(STEP_INSTALL));

      boolean success = false;
      if (Config.isSolarisInstall()) {
        success = runSolarisInstaller(path, installerFile);
      } else {
        success = runWindowsInstaller(path, installerFile);
      }

      if (!success) {
        // The installFailed string is only for debugging. No localization needed
        installFailed("Could not run installer", null);
        return;
      }
    } catch (UnsatisfiedLinkError ule) {
      // The installFailed string is only for debugging. No localization needed
      installFailed("Unable to load library: " + nativeLibName, null);
      return;
    } finally {
      if (installerFile != null) {
        installerFile.delete();
      }
    }

    setStepText(STEP_INSTALL, Config.getWindowStep(STEP_INSTALL));
    enableStep(STEP_DONE);

    String execPath = path + Config.getJavaPath();
    Config.trace(execPath);

    /** Remove installer JAR from cache */
    removeInstallerComponent();

    // If we're running anything after 1.0.1 or not on Windows, just call
    // finishedInstall.  Otherwise, deny ExitVM permission so that we can
    // return here and do a reboot.  We have to do this because we need to
    // call ExtensionInstallerService.finishedInstall(), which registers
    // that our extension (the JRE) is installed.  Unfortunately pre-1.2 it
    // also does not understand that we are requesting a reboot, and calls
    // System.exit().  So for pre 1.2 we want to deny the permission to
    // exit the VM so we can return here and perform a reboot.
    boolean ispre12 = false;
    String version = Config.getJavaWSVersion();
    // get first tuple
    String v = version.substring(version.indexOf('-') + 1);
    int i2 = v.indexOf('.');
    int v1 = Integer.parseInt(v.substring(0, i2));
    // get second tuple
    v = v.substring(i2 + 1);
    i2 = v.indexOf('.');
    if (i2 == -1) i2 = v.indexOf('-');
    if (i2 == -1) i2 = v.indexOf('[');
    if (i2 == -1) i2 = v.length();
    int v2 = Integer.parseInt(v.substring(0, i2));
    // are we pre 1.2?
    if (v1 < 1 || (v1 == 1 && v2 < 2)) ispre12 = true;

    if (Config.isWindowsInstall() && ispre12 && Config.isHopper()) {
      // deny ExitVM permission then call finishedInstall
      ProtectionDomain pd = (new Object()).getClass().getProtectionDomain();
      CodeSource cs = pd.getCodeSource();
      AllPermissionExceptExitVM perm = new AllPermissionExceptExitVM();
      PermissionCollection newpc = perm.newPermissionCollection();
      newpc.add(perm);

      // run finishedInstall within the new context which excluded
      // just the ExitVM permission
      ProtectionDomain newpd = new ProtectionDomain(cs, newpc);
      AccessControlContext newacc = new AccessControlContext(new ProtectionDomain[] {newpd});
      final String fExecPath = execPath;
      try {
        AccessController.doPrivileged(
            new PrivilegedExceptionAction() {
              public Object run() throws SecurityException {
                finishedInstall(fExecPath);
                return null;
              }
            },
            newacc);
      } catch (PrivilegedActionException pae) {
        // swallow the exception because we want ExitVM to fail silent
      } catch (SecurityException se) {
        // swallow the exception because we want ExitVM to fail silent
      }
    } else {
      // just call finished Install
      finishedInstall(execPath);
    }

    if (Config.isWindowsInstall() && WindowsInstaller.IsRebootNecessary()) {
      // reboot
      if (!WindowsInstaller.askUserForReboot()) System.exit(0);
    } else {
      System.exit(0);
    }
  }