github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/dokan/dokan.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package dokan 6 7 import ( 8 "github.com/keybase/client/go/kbfs/dokan/winacl" 9 ) 10 11 // MountHandle holds a reference to a mounted filesystem. 12 type MountHandle struct { 13 errChan chan error 14 // Dir is the path of this mount. 15 Dir string 16 } 17 18 // Mount mounts a FileSystem with the given Config. 19 // Mount returns when the filesystem has been mounted or there is an error. 20 func Mount(cfg *Config) (*MountHandle, error) { 21 err := loadDokanDLL(cfg) 22 if err != nil { 23 return nil, err 24 } 25 var ec = make(chan error, 2) 26 var slot = fsTableStore(cfg.FileSystem, ec) 27 flags := cfg.MountFlags 28 go func() { 29 ctx := allocCtx(slot) 30 defer ctx.Free() 31 ec <- ctx.Run(cfg.Path, flags) 32 close(ec) 33 }() 34 // This gets a send from either 35 // 1) DokanMain from ctx.Run returns an error before mount 36 // 2) After the filesystem is mounted from handling the Mounted callback. 37 // Thus either the filesystem was mounted ok or it was not mounted 38 // and an err is not nil. DokanMain does not return errors after the 39 // mount, but if such errors occured they can be catched by BlockTillDone. 40 err = <-ec 41 if err != nil { 42 return nil, err 43 } 44 return &MountHandle{ec, cfg.Path}, nil 45 } 46 47 // Close unmounts the filesystem. Can be used to interrupt a 48 // running filesystem - usually not needed if BlockTillDone 49 // is used. 50 func (m *MountHandle) Close() error { 51 return Unmount(m.Dir) 52 } 53 54 // BlockTillDone blocks till Dokan is done. 55 func (m *MountHandle) BlockTillDone() error { 56 // Two cases: 57 // 1) Mount got send from Mounted hook (nil) and we wait for the ctx.Run case 58 // 2) Mount got send from Mount (which errored) and closed the channel 59 err := <-m.errChan 60 return err 61 } 62 63 // Unmount a drive mounted by Dokan. 64 func Unmount(path string) error { 65 return unmount(path) 66 } 67 68 // Path converts the path to UTF-8 running in O(n). 69 func (fi *FileInfo) Path() string { 70 return lpcwstrToString(fi.rawPath) 71 } 72 73 // IsDeleteOnClose should be checked from Cleanup. 74 func (fi *FileInfo) IsDeleteOnClose() bool { 75 return fi.ptr.DeleteOnClose != 0 76 } 77 78 // IsRequestorUserSidEqualTo returns true if the argument is equal 79 // to the sid of the user associated with the filesystem request. 80 func (fi *FileInfo) IsRequestorUserSidEqualTo(sid *winacl.SID) bool { 81 return fi.isRequestorUserSidEqualTo(sid) 82 } 83 84 // NumberOfFileHandles returns the number of open file handles for 85 // this filesystem. 86 func (fi *FileInfo) NumberOfFileHandles() uint32 { 87 return fsTableGetFileCount(uint32(fi.ptr.DokanOptions.GlobalContext)) 88 }