@@ -4,12 +4,13 @@ package sftp
44
55import (
66 "fmt"
7+ "io"
78 "io/fs"
89 "os"
910 "path"
1011 "path/filepath"
11- "syscall"
12- "time "
12+
13+ "golang.org/x/sys/windows "
1314)
1415
1516func (s * Server ) toLocalPath (p string ) string {
@@ -45,16 +46,13 @@ func (s *Server) toLocalPath(p string) string {
4546 return lp
4647}
4748
48- var kernel32 , _ = syscall .LoadLibrary ("kernel32.dll" )
49- var getLogicalDrivesHandle , _ = syscall .GetProcAddress (kernel32 , "GetLogicalDrives" )
50-
5149func bitsToDrives (bitmap uint32 ) []string {
52- var drive rune = 'A '
50+ var drive rune = 'a '
5351 var drives []string
5452
5553 for bitmap != 0 {
5654 if bitmap & 1 == 1 {
57- drives = append (drives , string (drive ))
55+ drives = append (drives , string (drive )+ ":" )
5856 }
5957 drive ++
6058 bitmap >>= 1
@@ -64,56 +62,63 @@ func bitsToDrives(bitmap uint32) []string {
6462}
6563
6664func getDrives () ([]string , error ) {
67- if ret , _ , callErr := syscall .Syscall (uintptr (getLogicalDrivesHandle ), 0 , 0 , 0 , 0 ); callErr != 0 {
68- return nil , fmt .Errorf ("GetLogicalDrives: %w" , callErr )
69- } else {
70- drives := bitsToDrives (uint32 (ret ))
71- return drives , nil
65+ mask , err := windows .GetLogicalDrives ()
66+ if err != nil {
67+ return nil , fmt .Errorf ("GetLogicalDrives: %w" , err )
7268 }
69+ return bitsToDrives (mask ), nil
7370}
7471
75- type dummyDriveStat struct {
72+ type driveInfo struct {
73+ fs.FileInfo
7674 name string
7775}
7876
79- func (s * dummyDriveStat ) Name () string {
80- return s .name
81- }
82- func (s * dummyDriveStat ) Size () int64 {
83- return 1024
84- }
85- func (s * dummyDriveStat ) Mode () os.FileMode {
86- return os .FileMode (0755 )
87- }
88- func (s * dummyDriveStat ) ModTime () time.Time {
89- return time .Now ()
90- }
91- func (s * dummyDriveStat ) IsDir () bool {
92- return true
93- }
94- func (s * dummyDriveStat ) Sys () any {
95- return nil
77+ func (i * driveInfo ) Name () string {
78+ return i .name // since the Name() returned from a os.Stat("C:\\") is "\\"
9679}
9780
98- type WinRoot struct {
81+ type winRoot struct {
9982 dummyFile
83+ doneDirs int
10084}
10185
102- func (f * WinRoot ) Readdir (int ) ([]os.FileInfo , error ) {
86+ func (f * winRoot ) Readdir (n int ) ([]os.FileInfo , error ) {
10387 drives , err := getDrives ()
10488 if err != nil {
10589 return nil , err
10690 }
107- infos := []os. FileInfo {}
108- for _ , drive := range drives {
109- infos = append ( infos , & dummyDriveStat { drive })
91+
92+ if f . doneDirs >= len ( drives ) {
93+ return nil , io . EOF
11094 }
95+ drives = drives [f .doneDirs :]
96+
97+ var infos []os.FileInfo
98+ for i , drive := range drives {
99+ if i >= n {
100+ break
101+ }
102+
103+ fi , err := os .Stat (drive )
104+ if err != nil {
105+ return nil , err
106+ }
107+
108+ di := & driveInfo {
109+ FileInfo : fi ,
110+ name : drive ,
111+ }
112+ infos = append (infos , di )
113+ }
114+
115+ f .doneDirs += len (infos )
111116 return infos , nil
112117}
113118
114- func openFileLike (path string , flag int , mode fs.FileMode ) (FileLike , error ) {
119+ func openfile (path string , flag int , mode fs.FileMode ) (file , error ) {
115120 if path == "/" {
116- return & WinRoot {}, nil
121+ return & winRoot {}, nil
117122 }
118123 return os .OpenFile (path , flag , mode )
119124}
0 commit comments