From 1612baca9203c3029b6818e40ceb9f195a7da205 Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Tue, 31 May 2016 19:27:07 +0000 Subject: [PATCH] gui: /rest/system/browse with no arguments returns drives on Windows (ref #3201) GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3203 --- cmd/syncthing/gui.go | 8 +++++++ lib/osutil/drives_unix.go | 13 ++++++++++ lib/osutil/drives_windows.go | 46 ++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 lib/osutil/drives_unix.go create mode 100644 lib/osutil/drives_windows.go diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index 2cf441c2..a47712e2 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -1173,6 +1173,14 @@ func (s *apiService) getPeerCompletion(w http.ResponseWriter, r *http.Request) { func (s *apiService) getSystemBrowse(w http.ResponseWriter, r *http.Request) { qs := r.URL.Query() current := qs.Get("current") + if current == "" && runtime.GOOS == "windows" { + if drives, err := osutil.GetDriveLetters(); err == nil { + sendJSON(w, drives) + } else { + http.Error(w, err.Error(), 500) + } + return + } search, _ := osutil.ExpandTilde(current) pathSeparator := string(os.PathSeparator) if strings.HasSuffix(current, pathSeparator) && !strings.HasSuffix(search, pathSeparator) { diff --git a/lib/osutil/drives_unix.go b/lib/osutil/drives_unix.go new file mode 100644 index 00000000..03f20347 --- /dev/null +++ b/lib/osutil/drives_unix.go @@ -0,0 +1,13 @@ +// Copyright (C) 2016 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +// +build !windows + +package osutil + +func GetDriveLetters() ([]string, error) { + return nil, nil +} diff --git a/lib/osutil/drives_windows.go b/lib/osutil/drives_windows.go new file mode 100644 index 00000000..868b30a1 --- /dev/null +++ b/lib/osutil/drives_windows.go @@ -0,0 +1,46 @@ +// Copyright (C) 2016 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +// +build windows + +package osutil + +import ( + "bytes" + "fmt" + "syscall" + "unsafe" +) + +func GetDriveLetters() ([]string, error) { + kernel32, err := syscall.LoadDLL("kernel32.dll") + if err != nil { + return nil, err + } + getLogicalDriveStringsHandle, err := kernel32.FindProc("GetLogicalDriveStringsA") + if err != nil { + return nil, err + } + + buffer := [1024]byte{} + bufferSize := uint32(len(buffer)) + + hr, _, _ := getLogicalDriveStringsHandle.Call(uintptr(unsafe.Pointer(&bufferSize)), uintptr(unsafe.Pointer(&buffer))) + if hr == 0 { + return nil, fmt.Errorf("Syscall failed") + } + + var drives []string + parts := bytes.Split(buffer[:], []byte{0}) + for _, part := range parts { + if len(part) == 0 { + break + } + drives = append(drives, string(part)) + } + + return drives, nil +}