Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions cmd/service_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ package cmd
import (
"errors"
"fmt"
"os"
"path/filepath"
"runtime"

Expand Down Expand Up @@ -70,18 +69,18 @@ var installCmd = &cobra.Command{
Example: "cloudfuse service install",
FlagErrorHandling: cobra.ExitOnError,
RunE: func(cmd *cobra.Command, args []string) error {
programPath := filepath.Join("C:", "Program Files", "Cloudfuse", "windows-startup.exe")
startupPath := filepath.Join(os.Getenv("APPDATA"), "Microsoft", "Windows", "Start Menu", "Programs", "Startup", StartupName)
err := makeLink(programPath, startupPath)
// Create the registry for WinFsp
err := winservice.CreateWinFspRegistry()
if err != nil {
return fmt.Errorf("unable to create startup link [%s]", err.Error())
return fmt.Errorf("Failed to add Windows registry for WinFSP support. Here's why: [%v]", err)
}

// Create the registry for WinFsp
err = winservice.CreateWinFspRegistry()
Comment thread
jfantinhardesty marked this conversation as resolved.
// Add our startup process to the registry
programPath := filepath.Join("C:", "Program Files", "Cloudfuse", "windows-startup.exe")
err = winservice.AddRegistryValue(`SOFTWARE\Microsoft\Windows\CurrentVersion\Run`, "Cloudfuse", programPath)
if err != nil {
return fmt.Errorf("error adding Windows registry for WinFSP support [%s]", err.Error())
return fmt.Errorf("Failed to add startup registry value. Here's why: %v", err)
}

return nil
},
}
Expand All @@ -94,16 +93,15 @@ var uninstallCmd = &cobra.Command{
Example: "cloudfuse service uninstall",
FlagErrorHandling: cobra.ExitOnError,
RunE: func(cmd *cobra.Command, args []string) error {
startupPath := filepath.Join(os.Getenv("APPDATA"), "Microsoft", "Windows", "Start Menu", "Programs", "Startup", StartupName)
err := os.Remove(startupPath)
// Remove the cloudfuse startup registry entry
err := winservice.RemoveRegistryValue(`SOFTWARE\Microsoft\Windows\CurrentVersion\Run`, "Cloudfuse")
if err != nil {
return fmt.Errorf("failed to delete startup process [%s]", err.Error())
return fmt.Errorf("Failed to remove cloudfuse remount service from Windows startup registry. Here's why: %v", err)
}

// Remove the registry for WinFsp
err = winservice.RemoveWinFspRegistry()
if err != nil {
return fmt.Errorf("error removing Windows registry from WinFSP [%s]", err.Error())
return fmt.Errorf("Failed to remove cloudfuse entry from WinFSP registry. Here's why: %v", err)
}

return nil
Expand Down
92 changes: 32 additions & 60 deletions internal/winservice/registry_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,12 @@ package winservice
import (
"os"

"github.com/Seagate/cloudfuse/common/log"

"golang.org/x/sys/windows/registry"
)

// Windows Registry Paths
const (
cfRegistry = `SOFTWARE\Seagate\Cloudfuse\`
instanceRegistry = cfRegistry + `Instances\`
winFspRegistry = `SOFTWARE\WOW6432Node\WinFsp\Services\`
winFspRegistry = `SOFTWARE\WOW6432Node\WinFsp\Services\`
)

// WinFsp registry constants. JobControl is specified to be 1 by default in WinFsp. The security
Expand All @@ -50,11 +46,6 @@ const (
security = `D:P(A;;RPWPLC;;;WD)`
)

type KeyData struct {
MountPath string
ConfigFile string
}

// Specific mount command used in cloudfuse. This is the command that is executed when WinFsp launches our service.
// %1-%5 are strings that are added when mounting where:
// %1 is the mount directory
Expand All @@ -64,53 +55,6 @@ type KeyData struct {
// %5 is the passphrase if the config file is encrypted
const mountCmd = `mount %1 --config-file=%2 -o uid=%3,gid=%4 --passphrase=%5 --foreground=true`

func ReadRegistryInstanceEntry(name string) (KeyData, error) {
registryPath := instanceRegistry + name

key, err := registry.OpenKey(registry.LOCAL_MACHINE, registryPath, registry.ALL_ACCESS)
if err != nil {
log.Err("Unable to read instance names from Windows Registry: %v", err.Error())
return KeyData{}, err
}
defer key.Close()

var d KeyData
d.MountPath = name

d.ConfigFile, _, err = key.GetStringValue("ConfigFile")
if err != nil {
log.Err("Unable to read key ConfigFile from instance in Windows Registry: %v", err.Error())
return KeyData{}, err
}

return d, nil
}

// readRegistryEntry reads the cloudfuse registry and returns all the instances to be mounted.
func readRegistryEntry() ([]KeyData, error) {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, instanceRegistry, registry.ALL_ACCESS)
if err != nil {
log.Err("Unable to read instance names from Windows Registry: %v", err.Error())
return nil, err
}
defer key.Close()

keys, err := key.ReadSubKeyNames(-1)
if err != nil {
log.Err("Unable to read subkey names from Windows Registry: %v", err.Error())
return nil, err
}

var data []KeyData

for _, k := range keys {
d, _ := ReadRegistryInstanceEntry(k)
data = append(data, d)
}

return data, nil
}

// CreateWinFspRegistry creates an entry in the registry for WinFsp
// so the WinFsp launch tool can launch our mounts.
func CreateWinFspRegistry() error {
Expand All @@ -124,6 +68,7 @@ func CreateWinFspRegistry() error {
if err != nil {
return err
}
defer key.Close()

err = key.SetStringValue("Executable", executablePath)
if err != nil {
Expand Down Expand Up @@ -157,9 +102,36 @@ func RemoveWinFspRegistry() error {
return nil
}

// RemoveRegistryMount removes the entire cloudfuse registry
func RemoveAllRegistryMount() error {
err := registry.DeleteKey(registry.LOCAL_MACHINE, cfRegistry)
func AddRegistryValue(keyName string, valueName string, value string) error {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, keyName, registry.SET_VALUE)
if err != nil {
return err
}
defer key.Close()
err = key.SetStringValue(valueName, value)
if err != nil {
return err
}

return nil
}

func RemoveRegistryValue(keyName string, valueName string) error {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, keyName, registry.SET_VALUE|registry.QUERY_VALUE)
if err != nil {
return err
}
defer key.Close()

// Check if the value exists before trying to delete it.
_, _, err = key.GetStringValue(valueName)
if err != nil {
// the entry already doesn't exist - no need to report an error
return nil
}

// Delete the registry value
err = key.DeleteValue(valueName)
if err != nil {
return err
}
Expand Down
Loading