| package hcsshim |
| |
| import ( |
| "fmt" |
| "syscall" |
| "unsafe" |
| |
| "github.com/Sirupsen/logrus" |
| ) |
| |
| func GetLayerMountPath(info DriverInfo, id string) (string, error) { |
| title := "hcsshim::GetLayerMountPath " |
| logrus.Debugf(title+"Flavour %s ID %s", info.Flavour, id) |
| |
| // Load the DLL and get a handle to the procedure we need |
| dll, proc, err := loadAndFind(procGetLayerMountPath) |
| if dll != nil { |
| defer dll.Release() |
| } |
| if err != nil { |
| return "", err |
| } |
| |
| // Convert id to uint16 pointer for calling the procedure |
| idp, err := syscall.UTF16PtrFromString(id) |
| if err != nil { |
| err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err) |
| logrus.Error(err) |
| return "", err |
| } |
| |
| // Convert info to API calling convention |
| infop, err := convertDriverInfo(info) |
| if err != nil { |
| err = fmt.Errorf(title+" - Failed conversion info struct %s", err) |
| logrus.Error(err) |
| return "", err |
| } |
| |
| var mountPathLength uint64 |
| mountPathLength = 0 |
| |
| // Call the procedure itself. |
| logrus.Debugf("Calling proc (1)") |
| r1, _, _ := proc.Call( |
| uintptr(unsafe.Pointer(&infop)), |
| uintptr(unsafe.Pointer(idp)), |
| uintptr(unsafe.Pointer(&mountPathLength)), |
| uintptr(unsafe.Pointer(nil))) |
| |
| if r1 != 0 { |
| err = fmt.Errorf(title+" - First Win32 API call returned error r1=%d err=%s id=%s flavour=%d", |
| r1, syscall.Errno(r1), id, info.Flavour) |
| logrus.Error(err) |
| return "", err |
| } |
| |
| // Allocate a mount path of the returned length. |
| if mountPathLength == 0 { |
| return "", nil |
| } |
| mountPathp := make([]uint16, mountPathLength) |
| mountPathp[0] = 0 |
| |
| // Call the procedure again |
| logrus.Debugf("Calling proc (2)") |
| r1, _, _ = proc.Call( |
| uintptr(unsafe.Pointer(&infop)), |
| uintptr(unsafe.Pointer(idp)), |
| uintptr(unsafe.Pointer(&mountPathLength)), |
| uintptr(unsafe.Pointer(&mountPathp[0]))) |
| |
| use(unsafe.Pointer(&mountPathLength)) |
| use(unsafe.Pointer(&infop)) |
| use(unsafe.Pointer(idp)) |
| |
| if r1 != 0 { |
| err = fmt.Errorf(title+" - Second Win32 API call returned error r1=%d err=%s id=%s flavour=%d", |
| r1, syscall.Errno(r1), id, info.Flavour) |
| logrus.Error(err) |
| return "", err |
| } |
| |
| path := syscall.UTF16ToString(mountPathp[0:]) |
| logrus.Debugf(title+" - succeeded id=%s flavour=%d path=%s", id, info.Flavour, path) |
| return path, nil |
| } |