-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathwin_snapshot.go
125 lines (93 loc) · 3.05 KB
/
win_snapshot.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//go:build windows
// +build windows
package main
import (
"fmt"
"os"
"os/user"
"path/filepath"
vss "github.com/jeromehadorn/vss"
)
func SymlinkSnapshot(symlinkPath string, id string, deviceObjectPath string) (string, error) {
snapshotSymLinkFolder := symlinkPath + "\\" + id + "\\"
snapshotSymLinkFolder = filepath.Clean(snapshotSymLinkFolder)
os.RemoveAll(snapshotSymLinkFolder)
if err := os.MkdirAll(snapshotSymLinkFolder, 0700); err != nil {
return "", fmt.Errorf("failed to create snapshot symlink folder for snapshot: %s, err: %s", id, err)
}
os.Remove(snapshotSymLinkFolder)
fmt.Println("Symlink from: ", deviceObjectPath, " to: ", snapshotSymLinkFolder)
if err := os.Symlink(deviceObjectPath, snapshotSymLinkFolder); err != nil {
return "", fmt.Errorf("failed to create symlink from: %s to: %s, error: %s", deviceObjectPath, snapshotSymLinkFolder, err)
}
return snapshotSymLinkFolder, nil
}
func getAppDataFolder() (string, error) {
// Get information about the current user
currentUser, err := user.Current()
if err != nil {
return "", err
}
// Construct the path to the application data folder
appDataFolder := filepath.Join(currentUser.HomeDir, "AppData", "Roaming", "PBSBackupGO")
// Create the folder if it doesn't exist
err = os.MkdirAll(appDataFolder, os.ModePerm)
if err != nil {
return "", err
}
return appDataFolder, nil
}
func createVSSSnapshot(path string) string {
path, _ = filepath.Abs(path)
volName := filepath.VolumeName(path)
volName += "\\"
subPath := path[len(volName):] //Strp C:\, 3 chars or whatever it is
appDataFolder, err := getAppDataFolder()
if err != nil {
fmt.Println("Error:", err)
return path
}
sn := vss.Snapshotter{}
snapid, err := os.ReadFile(filepath.Join(appDataFolder, "temp_snapshot_id.txt"))
if err == nil {
snapid_str := string(snapid)
fmt.Printf("Found leftover snapshot, deleting it...\n")
sn.DeleteSnapshot(snapid_str)
os.Remove(filepath.Join(appDataFolder, "temp_snapshot_id.txt"))
}
fmt.Printf("Creating VSS Snapshot...")
snapshot, err := sn.CreateSnapshot(volName, 180, true)
if err != nil {
panic(err)
}
fmt.Printf("Snapshot created: %s\n", snapshot.Id)
f, err := os.Create(filepath.Join(appDataFolder, "temp_snapshot_id.txt"))
if err != nil {
sn.DeleteSnapshot(snapshot.Id)
panic(err)
}
f.WriteString(snapshot.Id)
f.Close()
_, err = SymlinkSnapshot(filepath.Join(appDataFolder, "VSS"), snapshot.Id, snapshot.DeviceObjectPath)
if err != nil {
sn.DeleteSnapshot(snapshot.Id)
os.Remove(filepath.Join(appDataFolder, "temp_snapshot_id.txt"))
panic(err)
}
return filepath.Join(appDataFolder, "VSS", snapshot.Id, subPath)
}
func VSSCleanup() {
appDataFolder, err := getAppDataFolder()
if err != nil {
fmt.Println("Error:", err)
return
}
sn := vss.Snapshotter{}
snapid, err := os.ReadFile(filepath.Join(appDataFolder, "temp_snapshot_id.txt"))
if err == nil {
snapid_str := string(snapid)
fmt.Printf("Found leftover snapshot, deleting it...\n")
sn.DeleteSnapshot(snapid_str)
os.Remove(filepath.Join(appDataFolder, "temp_snapshot_id.txt"))
}
}