diff --git a/cmd/clef/main.go b/cmd/clef/main.go index 802e118e70..088701eeee 100644 --- a/cmd/clef/main.go +++ b/cmd/clef/main.go @@ -533,7 +533,12 @@ func DefaultConfigDir() string { if runtime.GOOS == "darwin" { return filepath.Join(home, "Library", "Signer") } else if runtime.GOOS == "windows" { - return filepath.Join(home, "AppData", "Roaming", "Signer") + appdata := os.Getenv("APPDATA") + if appdata != "" { + return filepath.Join(appdata, "Signer") + } else { + return filepath.Join(home, "AppData", "Roaming", "Signer") + } } else { return filepath.Join(home, ".clef") } diff --git a/eth/config.go b/eth/config.go index f71b8dfee4..aca9b5e68b 100644 --- a/eth/config.go +++ b/eth/config.go @@ -68,8 +68,15 @@ func init() { home = user.HomeDir } } - if runtime.GOOS == "windows" { - DefaultConfig.Ethash.DatasetDir = filepath.Join(home, "AppData", "Ethash") + if runtime.GOOS == "darwin" { + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, "Library", "Ethash") + } else if runtime.GOOS == "windows" { + localappdata := os.Getenv("LOCALAPPDATA") + if localappdata != "" { + DefaultConfig.Ethash.DatasetDir = filepath.Join(localappdata, "Ethash") + } else { + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, "AppData", "Local", "Ethash") + } } else { DefaultConfig.Ethash.DatasetDir = filepath.Join(home, ".ethash") } diff --git a/node/defaults.go b/node/defaults.go index cea4997cb4..73b262429d 100644 --- a/node/defaults.go +++ b/node/defaults.go @@ -58,11 +58,20 @@ func DefaultDataDir() string { // Try to place the data folder in the user's home dir home := homeDir() if home != "" { - if runtime.GOOS == "darwin" { + switch runtime.GOOS { + case "darwin": return filepath.Join(home, "Library", "Ethereum") - } else if runtime.GOOS == "windows" { - return filepath.Join(home, "AppData", "Roaming", "Ethereum") - } else { + case "windows": + // We used to put everything in %HOME%\AppData\Roaming, but this caused + // problems with non-typical setups. If this fallback location exists and + // is non-empty, use it, otherwise DTRT and check %LOCALAPPDATA%. + fallback := filepath.Join(home, "AppData", "Roaming", "Ethereum") + appdata := windowsAppData() + if appdata == "" || isNonEmptyDir(fallback) { + return fallback + } + return filepath.Join(appdata, "Ethereum") + default: return filepath.Join(home, ".ethereum") } } @@ -70,6 +79,26 @@ func DefaultDataDir() string { return "" } +func windowsAppData() string { + if v := os.Getenv("LOCALAPPDATA"); v != "" { + return v // Vista+ + } + if v := os.Getenv("APPDATA"); v != "" { + return filepath.Join(v, "Local") + } + return "" +} + +func isNonEmptyDir(dir string) bool { + f, err := os.Open(dir) + if err != nil { + return false + } + names, _ := f.Readdir(1) + f.Close() + return len(names) > 0 +} + func homeDir() string { if home := os.Getenv("HOME"); home != "" { return home