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, ®CUS) == ERROR_SUCCESS) + return; + HKEY regCUSC; + if (!::RegOpenKeyEx(regCUS, "Classes", 0, KEY_READ, ®CUSC) == ERROR_SUCCESS) { + ::RegCloseKey(regCUS); + return; + } + + HKEY regROOT; + bool regROOTwrite = false; + TString iconloc(buf); + iconloc += ",-101"; + + if (::RegOpenKeyEx(regCUSC, "ROOTDEV.ROOT", 0, KEY_READ, ®ROOT) != ERROR_SUCCESS) { + ::RegCloseKey(regCUSC); + if (::RegOpenKeyEx(regCUS, "Classes", 0, KEY_READ | KEY_WRITE, ®CUSC) == ERROR_SUCCESS && + ::RegCreateKeyEx(regCUSC, "ROOTDEV.ROOT", 0, NULL, 0, KEY_READ | KEY_WRITE, + NULL, ®ROOT, NULL) == ERROR_SUCCESS) { + regROOTwrite = true; + } + } else { + HKEY regROOTIcon; + if (::RegOpenKeyEx(regROOT, "DefaultIcon", 0, KEY_READ, ®ROOTIcon) == 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, ®CUSC) != ERROR_SUCCESS) { + // error opening key for writing: + regROOTwrite = false; + } else { + if (::RegOpenKeyEx(regCUSC, "ROOTDEV.ROOT", 0, KEY_WRITE, ®ROOT) != 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, ®ROOTIcon, 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, ®ROOTshell, NULL) == ERROR_SUCCESS) { + HKEY regShellOpen; + if (::RegCreateKeyEx(regROOTshell, "open", 0, NULL, 0, KEY_READ | KEY_WRITE, + NULL, ®ShellOpen, NULL) == ERROR_SUCCESS) { + HKEY regShellOpenCmd; + if (::RegCreateKeyEx(regShellOpen, "command", 0, NULL, 0, KEY_READ | KEY_WRITE, + NULL, ®ShellOpenCmd, 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, ®ROOT, 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); +}