src/Pure/System/cygwin.scala
author wenzelm
Sun, 28 Jun 2009 15:39:51 +0200
changeset 31826 7f311da87d5a
parent 31499 4345173ee386
child 34043 7129fab1fe4f
permissions -rwxr-xr-x
some more Cygwin checks;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
31499
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/System/cygwin.scala
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     3
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     4
Accessing the Cygwin installation.
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     5
*/
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     6
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     7
package isabelle
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     8
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
     9
import java.lang.reflect.Method
31826
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    10
import java.io.File
31499
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    11
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    12
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    13
object Cygwin
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    14
{
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    15
  /* registry access */
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    16
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    17
  // Some black magic involving private WindowsPreferences from Sun, cf.
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    18
  // http://www.docjar.com/html/api/java/util/prefs/WindowsPreferences.java.html
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    19
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    20
  private val WindowsPreferences = Class.forName("java.util.prefs.WindowsPreferences")
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    21
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    22
  private val HKEY_CURRENT_USER = 0x80000001
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    23
  private val HKEY_LOCAL_MACHINE = 0x80000002
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    24
  private val KEY_READ = 0x20019
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    25
  private val NATIVE_HANDLE = 0
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    26
  private val ERROR_CODE = 1
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    27
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    28
  private def C_string(s: String): Array[Byte] =
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    29
    (s + "\0").getBytes("US-ASCII")
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    30
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    31
  private def J_string(bs: Array[Byte]): String =
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    32
    new String(bs, 0, bs.length - 1, "US-ASCII")
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    33
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    34
  private val INT = Integer.TYPE
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    35
  private val BYTES = (new Array[Byte](0)).getClass
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    36
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    37
  private def open_key(handle: Int, subkey: Array[Byte], mask: Int): Array[Int] =
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    38
  {
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    39
    val m = WindowsPreferences.getDeclaredMethod("WindowsRegOpenKey", INT, BYTES, INT)
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    40
    m.setAccessible(true)
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    41
    m.invoke(null, handle.asInstanceOf[Object], subkey.asInstanceOf[Object],
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    42
      mask.asInstanceOf[Object]).asInstanceOf[Array[Int]]
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    43
  }
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    44
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    45
  private def close_key(handle: Int): Int =
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    46
  {
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    47
    val m = WindowsPreferences.getDeclaredMethod("WindowsRegCloseKey", INT)
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    48
    m.setAccessible(true)
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    49
    m.invoke(null, handle.asInstanceOf[Object]).asInstanceOf[Int]
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    50
  }
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    51
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    52
  private def query(handle: Int, name: Array[Byte]) =
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    53
  {
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    54
    val m = WindowsPreferences.getDeclaredMethod("WindowsRegQueryValueEx", INT, BYTES)
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    55
    m.setAccessible(true)
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    56
    m.invoke(null, handle.asInstanceOf[Object], name.asInstanceOf[Object]).
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    57
      asInstanceOf[Array[Byte]]
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    58
  }
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    59
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    60
  def query_registry(sys: Boolean, path: String, name: String): Option[String] =
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    61
  {
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    62
    val handle = if (sys) HKEY_LOCAL_MACHINE else HKEY_CURRENT_USER
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    63
    val result = open_key(handle, C_string(path), KEY_READ)
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    64
    if (result(ERROR_CODE) != 0) None
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    65
    else {
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    66
      val res = query(result(NATIVE_HANDLE), C_string(name))
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    67
      if (res == null) None
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    68
      else Some(J_string(res))
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    69
    }
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    70
  }
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    71
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    72
  def query_registry(path: String, name: String): Option[String] =
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    73
    query_registry(false, path, name) orElse
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    74
      query_registry(true, path, name)
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    75
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    76
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    77
  /* Cygwin installation */
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    78
31826
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    79
  // old-style mount points (Cygwin 1.5)
31499
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    80
  private val CYGWIN_MOUNTS = "Software\\Cygnus Solutions\\Cygwin\\mounts v2"
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    81
31826
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    82
  // new-style setup (Cygwin 1.7)
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    83
  private val CYGWIN_SETUP1 = "Software\\Cygwin\\setup"
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    84
  private val CYGWIN_SETUP2 = "Software\\Wow6432Node\\Cygwin\\setup"  // !?
31499
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
    85
31826
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    86
  def config(): (String, String) =
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    87
  {
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    88
    query_registry(CYGWIN_SETUP1, "rootdir") match {
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    89
      case Some(root) => (root, "/cygdrive")
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    90
      case None =>
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    91
        val root =
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    92
          query_registry(CYGWIN_MOUNTS + "\\/", "native") getOrElse "C:\\cygwin"
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    93
        val cygdrive =
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    94
          query_registry(CYGWIN_MOUNTS, "cygdrive prefix") getOrElse "cygdrive"
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    95
        (root, cygdrive)
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    96
    }
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    97
  }
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    98
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
    99
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
   100
  /* basic sanity check */
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
   101
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
   102
  def check(root: String): Boolean =
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
   103
    new File(root + "\\bin\\bash.exe").isFile &&
7f311da87d5a some more Cygwin checks;
wenzelm
parents: 31499
diff changeset
   104
    new File(root + "\\bin\\env.exe").isFile
31499
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
   105
}
4345173ee386 Accessing the Cygwin installation.
wenzelm
parents:
diff changeset
   106