github.com/iikira/iikira-go-utils@v0.0.0-20230610031953-f2cb11cde33a/utils/prealloc/prealloc_windows.go (about) 1 package prealloc 2 3 import ( 4 "golang.org/x/sys/windows" 5 "log" 6 "syscall" 7 ) 8 9 var ( 10 kernel32 = syscall.NewLazyDLL("kernel32.dll") 11 procSetFileValidData = kernel32.NewProc("SetFileValidData") 12 ) 13 14 func initPrivilege() error { 15 current, err := windows.GetCurrentProcess() 16 if err != nil { 17 return &PreAllocError{ 18 ProcName: "GetCurrentProcess", 19 Err: err, 20 } 21 } 22 23 var hToken windows.Token 24 err = windows.OpenProcessToken(current, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &hToken) 25 if err != nil { 26 return &PreAllocError{ 27 ProcName: "OpenProcessToken", 28 Err: err, 29 } 30 } 31 32 var ( 33 seManageVolumeName, _ = windows.UTF16PtrFromString("SeManageVolumePrivilege") 34 tp = windows.Tokenprivileges{ 35 PrivilegeCount: 1, 36 Privileges: [1]windows.LUIDAndAttributes{ 37 windows.LUIDAndAttributes{ 38 Luid: windows.LUID{}, 39 Attributes: windows.SE_PRIVILEGE_ENABLED, 40 }, 41 }, 42 } 43 ) 44 err = windows.LookupPrivilegeValue(nil, seManageVolumeName, &tp.Privileges[0].Luid) 45 if err != nil { 46 return &PreAllocError{ 47 ProcName: "LookupPrivilegeValue", 48 Err: err, 49 } 50 } 51 52 err = windows.AdjustTokenPrivileges(hToken, false, &tp, 0, nil, nil) 53 if err != nil { 54 return &PreAllocError{ 55 ProcName: "AdjustTokenPrivileges", 56 Err: err, 57 } 58 } 59 60 return nil 61 } 62 63 // 初始化权限 64 func init() { 65 err := initPrivilege() 66 if err != nil { 67 log.Printf("prealloc: init privileges error: %s\n", err) // 打印警告 68 } 69 } 70 71 // PreAlloc 预分配文件空间 72 func PreAlloc(fd uintptr, length int64) error { 73 err := syscall.Ftruncate(syscall.Handle(fd), length) 74 if err != nil { 75 return &PreAllocError{ 76 ProcName: "Ftruncate", 77 Err: err, 78 } 79 } 80 81 r1, _, err := procSetFileValidData.Call(fd, uintptr(length)) 82 if r1 == 0 { 83 return &PreAllocError{ 84 ProcName: "SetFileValidData", 85 Err: err, 86 } 87 } 88 89 return nil 90 }