diff --git a/core/utils/src/rootcint.cxx b/core/utils/src/rootcint.cxx
index eec9ee2e85e28772b97b25a9f2f2e6ca0c25b696..b62d1dbfd2ecb3b70bcbabdee6f3bb70656057b2 100644
--- a/core/utils/src/rootcint.cxx
+++ b/core/utils/src/rootcint.cxx
@@ -311,6 +311,8 @@ const char *help =
 #ifdef system
 #undef system
 #endif
+#include <windows.h>
+#include <Tlhelp32.h> // for MAX_MODULE_NAME32
 #include <process.h>
 #include <errno.h>
 #endif
@@ -507,6 +509,15 @@ const char *GetExePath()
          buf[ret] = 0;
          exepath = buf;
       }
+#endif
+#ifdef _WIN32
+   char *buf = new char[MAX_MODULE_NAME32 + 1];
+   ::GetModuleFileName(NULL, buf, MAX_MODULE_NAME32 + 1);
+   char* p = buf;
+   while ((p = strchr(p, '\\')))
+      *(p++) = '/';
+   exepath = buf;
+   delete buf;
 #endif
    }
    return exepath.c_str();
@@ -523,14 +534,20 @@ void SetRootSys()
       strcpy(ep, exepath);
       char *s;
       if ((s = strrchr(ep, '/'))) {
-         *s = 0;
-         if ((s = strrchr(ep, '/'))) {
+         // $ROOTSYS/bin/rootcint
+         int removesubdirs = 2;
+         if (!strncmp(s, "rootcint_tmp", 12))
+            // $ROOTSYS/core/utils/src/rootcint_tmp
+            removesubdirs = 4;
+         for (int i = 0; s && i < removesubdirs; ++i) {
             *s = 0;
-            char *env = new char[strlen(ep) + 10];
-            sprintf(env, "ROOTSYS=%s", ep);
-            putenv(env);
+            s = strrchr(ep, '/');
          }
+         if (s) *s = 0;
       }
+      char *env = new char[strlen(ep) + 10];
+      sprintf(env, "ROOTSYS=%s", ep);
+      putenv(env);
       delete [] ep;
    }
 }
@@ -615,8 +632,7 @@ string R__tmpnam()
 #endif
 }
 
-#ifdef WIN32
-#include "windows.h"
+#ifdef _WIN32
 //______________________________________________________________________________
 // defined in newlink.c
 extern "C" FILE *FOpenAndSleep(const char *filename, const char *mode);
diff --git a/core/winnt/src/TWinNTSystem.cxx b/core/winnt/src/TWinNTSystem.cxx
index 9ceed09f24e658487e6f2f12835ac893969e15c4..911169f3b54ea044b87887d661478daadaec5f74 100644
--- a/core/winnt/src/TWinNTSystem.cxx
+++ b/core/winnt/src/TWinNTSystem.cxx
@@ -747,6 +747,136 @@ namespace {
       return SUCCEEDED(hres);
    }
 
+   void UpdateRegistry(TWinNTSystem* sys, char* buf /* size of buffer: MAX_MODULE_NAME32 + 1 */) {
+      // register ROOT as the .root file handler:
+      GetModuleFileName(0, buf, MAX_MODULE_NAME32 + 1);
+      if (strcmp(sys->TWinNTSystem::BaseName(buf), "root.exe"))
+         return;
+      HKEY regCUS;
+      if (!::RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &regCUS) == ERROR_SUCCESS)
+         return;
+      HKEY regCUSC;
+      if (!::RegOpenKeyEx(regCUS, "Classes", 0, KEY_READ, &regCUSC) == ERROR_SUCCESS) {
+         ::RegCloseKey(regCUS);
+         return;
+      }
+
+      HKEY regROOT;
+      bool regROOTwrite = false;
+      TString iconloc(buf);
+      iconloc += ",-101";
+
+      if (::RegOpenKeyEx(regCUSC, "ROOTDEV.ROOT", 0, KEY_READ, &regROOT) != ERROR_SUCCESS) {
+         ::RegCloseKey(regCUSC);
+         if (::RegOpenKeyEx(regCUS, "Classes", 0, KEY_READ | KEY_WRITE, &regCUSC) == ERROR_SUCCESS &&
+            ::RegCreateKeyEx(regCUSC, "ROOTDEV.ROOT", 0, NULL, 0, KEY_READ | KEY_WRITE,
+            NULL, &regROOT, NULL) == ERROR_SUCCESS) {
+            regROOTwrite = true;
+         }
+      } else {
+         HKEY regROOTIcon;
+         if (::RegOpenKeyEx(regROOT, "DefaultIcon", 0, KEY_READ, &regROOTIcon) == ERROR_SUCCESS) {
+            char bufIconLoc[1024];
+            DWORD dwType;
+            DWORD dwSize = sizeof(bufIconLoc);
+
+            if (::RegQueryValueEx(regROOTIcon, NULL, NULL, &dwType, (BYTE*)bufIconLoc, &dwSize))
+               regROOTwrite = (iconloc != bufIconLoc);
+            else
+               regROOTwrite = true;
+            ::RegCloseKey(regROOTIcon);
+         } else
+            regROOTwrite = true;
+         if (regROOTwrite) {
+            // re-open for writing
+            ::RegCloseKey(regCUSC);
+            ::RegCloseKey(regROOT);
+            if (::RegOpenKeyEx(regCUS, "Classes", 0, KEY_READ | KEY_WRITE, &regCUSC) != ERROR_SUCCESS) {
+               // error opening key for writing:
+               regROOTwrite = false;
+            } else {
+               if (::RegOpenKeyEx(regCUSC, "ROOTDEV.ROOT", 0, KEY_WRITE, &regROOT) != ERROR_SUCCESS) {
+                  // error opening key for writing:
+                  regROOTwrite = false;
+                  ::RegCloseKey(regCUSC);
+               }
+            }
+         }
+      }
+
+      // determine the fileopen.C file path:
+      TString fileopen;
+#ifndef ROOT_PREFIX
+      fileopen += sys->TWinNTSystem::DriveName(buf);
+      fileopen += ":";
+      fileopen += sys->TWinNTSystem::DirName(sys->TWinNTSystem::DirName(buf));
+      fileopen += "\\macros";
+#else
+      fileopen += ROOTMACRODIR;
+#endif
+      fileopen += "\\fileopen.C";
+
+      if (regROOTwrite) {
+         // only write to registry if fileopen.C is readable
+         regROOTwrite = (::_access(fileopen, kReadPermission) == 0);
+      }
+
+      if (!regROOTwrite) {
+         ::RegCloseKey(regROOT);
+         ::RegCloseKey(regCUSC);
+         ::RegCloseKey(regCUS);
+         return;
+      }
+
+      static const char apptitle[] = "ROOT data file";
+      ::RegSetValueEx(regROOT, NULL, 0, REG_SZ, (BYTE*)apptitle, sizeof(apptitle));
+      DWORD editflags = /*FTA_OpenIsSafe*/ 0x00010000; // trust downloaded files
+      ::RegSetValueEx(regROOT, "EditFlags", 0, REG_DWORD, (BYTE*)&editflags, sizeof(editflags));
+
+      HKEY regROOTIcon;
+      if (::RegCreateKeyEx(regROOT, "DefaultIcon", 0, NULL, 0, KEY_READ | KEY_WRITE,
+                           NULL, &regROOTIcon, NULL) == ERROR_SUCCESS) {
+         TString iconloc(buf);
+         iconloc += ",-101";
+         ::RegSetValueEx(regROOTIcon, NULL, 0, REG_SZ, (BYTE*)iconloc.Data(), iconloc.Length() + 1);
+         ::RegCloseKey(regROOTIcon);
+      }
+
+      // "open" verb
+      HKEY regROOTshell;
+      if (::RegCreateKeyEx(regROOT, "shell", 0, NULL, 0, KEY_READ | KEY_WRITE,
+                           NULL, &regROOTshell, NULL) == ERROR_SUCCESS) {
+         HKEY regShellOpen;
+         if (::RegCreateKeyEx(regROOTshell, "open", 0, NULL, 0, KEY_READ | KEY_WRITE,
+                              NULL, &regShellOpen, NULL) == ERROR_SUCCESS) {
+            HKEY regShellOpenCmd;
+            if (::RegCreateKeyEx(regShellOpen, "command", 0, NULL, 0, KEY_READ | KEY_WRITE,
+                                 NULL, &regShellOpenCmd, NULL) == ERROR_SUCCESS) {
+               TString cmd(buf);
+               cmd += " -l \"%1\" \"";
+               cmd += fileopen;
+               cmd += "\"";
+               ::RegSetValueEx(regShellOpenCmd, NULL, 0, REG_SZ, (BYTE*)cmd.Data(), cmd.Length() + 1);
+               ::RegCloseKey(regShellOpenCmd);
+            }
+            ::RegCloseKey(regShellOpen);
+         }
+         ::RegCloseKey(regROOTshell);
+      }
+      ::RegCloseKey(regROOT);
+
+      if (::RegCreateKeyEx(regCUSC, ".root", 0, NULL, 0, KEY_READ | KEY_WRITE,
+                           NULL, &regROOT, NULL) == ERROR_SUCCESS) {
+         static const char appname[] = "ROOTDEV.ROOT";
+         ::RegSetValueEx(regROOT, NULL, 0, REG_SZ, (BYTE*)appname, sizeof(appname));
+      }
+      ::RegCloseKey(regCUSC);
+      ::RegCloseKey(regCUS);
+
+      // tell Windows that the association was changed
+      ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
+   } // UpdateRegistry()
+
 } // end unnamed namespace
 
 
@@ -797,12 +927,13 @@ fGUIThreadHandle(0), fGUIThreadId(0)
       fBeepFreq     = gEnv->GetValue("Root.System.BeepFreq", 0);
    }
 
+   char *buf = new char[MAX_MODULE_NAME32 + 1];
+
 #ifndef ROOTPREFIX
    // set ROOTSYS
    HMODULE hModCore = ::GetModuleHandle("libCore.dll");
    if (hModCore) {
-      char buf[MAX_MODULE_NAME32 + 1];
-      ::GetModuleFileName(hModCore, buf, sizeof(buf));
+      ::GetModuleFileName(hModCore, buf, MAX_MODULE_NAME32 + 1);
       char* pLibName = strstr(buf, "libCore.dll");
       if (pLibName) {
          --pLibName; // skip trailing \\ or /
@@ -813,6 +944,10 @@ fGUIThreadHandle(0), fGUIThreadId(0)
       }
    }
 #endif
+
+   UpdateRegistry(this, buf);
+
+   delete [] buf;
 }
 
 //______________________________________________________________________________
@@ -1963,7 +2098,7 @@ TList *TWinNTSystem::GetVolumes(Option_t *opt) const
       *szFs='\0';
       sDrive.Form("%c:", (curdrive + 'A' - 1));
       sType.Form("Unknown Drive (%s)", sDrive.Data());
-      GetVolumeInformation(Form("%s\\", sDrive.Data()), NULL, 0, NULL, NULL, 
+      GetVolumeInformation(Form("%s\\", sDrive.Data()), NULL, 0, NULL, NULL,
                            NULL, (LPSTR)szFs, 32);
       type = ::GetDriveType(sDrive.Data());
       switch (type) {
@@ -1992,7 +2127,7 @@ TList *TWinNTSystem::GetVolumes(Option_t *opt) const
       _getcwd(curdir, _MAX_PATH);
       // If we can switch to the drive, it exists
       // but skip floppy drives...
-      UINT nOldErrorMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); 
+      UINT nOldErrorMode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
       for( drive = 3; drive <= 26; ++drive ) {
          if( !_chdrive( drive ) ) {
             *szFs='\0';
diff --git a/macros/fileopen.C b/macros/fileopen.C
new file mode 100644
index 0000000000000000000000000000000000000000..21091479d2ebd3a2070036348f02dc60a1132199
--- /dev/null
+++ b/macros/fileopen.C
@@ -0,0 +1,11 @@
+// @(#)etc:$Id: $
+// Author: Axel Naumann, 2008-05-22
+//
+// This script gets executed when double-clicking a ROOT file (currently only on Windows).
+// The file that got double clicked and opened is accessible as _file0.
+void fileopen() 
+{
+   new TBrowser;
+   // or, to only browse the file:
+   // new TBrowser(_file0);
+}