Prechádzať zdrojové kódy

gui: /rest/system/browse with no arguments returns drives on Windows (ref #3201)

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3203
Audrius Butkevicius 9 rokov pred
rodič
commit
1612baca92

+ 8 - 0
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) {

+ 13 - 0
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
+}

+ 46 - 0
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
+}