//go:build windows

package main

import (
	"errors"
	"path/filepath"
	"syscall"
	"unsafe"
)

var kernel32Disk = syscall.NewLazyDLL("kernel32.dll")
var procGetDiskFreeSpaceExW = kernel32Disk.NewProc("GetDiskFreeSpaceExW")
var procGetFileAttributesW = kernel32Disk.NewProc("GetFileAttributesW")

func freeSpace(path string) (uint64, error) {
	p, _ := syscall.UTF16PtrFromString(path)
	var avail, total, free uint64
	r, _, e := procGetDiskFreeSpaceExW.Call(uintptr(unsafe.Pointer(p)), uintptr(unsafe.Pointer(&avail)), uintptr(unsafe.Pointer(&total)), uintptr(unsafe.Pointer(&free)))
	if r == 0 {
		return 0, e
	}
	return avail, nil
}
func rejectUnsafePath(root, p string) error {
	base, _ := filepath.Abs(root)
	cur, _ := filepath.Abs(p)
	for {
		u, _ := syscall.UTF16PtrFromString(cur)
		a, _, _ := procGetFileAttributesW.Call(uintptr(unsafe.Pointer(u)))
		if uint32(a) != 0xFFFFFFFF && uint32(a)&0x400 != 0 {
			return errors.New("reparse point is not allowed")
		}
		if samePath(cur, base) {
			break
		}
		next := filepath.Dir(cur)
		if next == cur {
			break
		}
		cur = next
	}
	return nil
}
