func TestDirectoryJunction(t *testing.T) { var tests = []dirLinkTest{ { // Create link similar to what mklink does, by inserting \??\ at the front of absolute target. name: "standard", mklink: func(link, target string) error { var t reparseData t.addSubstituteName(`\??\` + target) t.addPrintName(target) return createMountPoint(link, &t) }, }, { // Do as junction utility https://technet.microsoft.com/en-au/sysinternals/bb896768.aspx does - set PrintNameLength to 0. name: "have_blank_print_name", mklink: func(link, target string) error { var t reparseData t.addSubstituteName(`\??\` + target) t.addPrintName("") return createMountPoint(link, &t) }, }, } output, _ := osexec.Command("cmd", "/c", "mklink", "/?").Output() mklinkSupportsJunctionLinks := strings.Contains(string(output), " /J ") if mklinkSupportsJunctionLinks { tests = append(tests, dirLinkTest{ name: "use_mklink_cmd", mklink: func(link, target string) error { output, err := osexec.Command("cmd", "/c", "mklink", "/J", link, target).CombinedOutput() if err != nil { t.Errorf("failed to run mklink %v %v: %v %q", link, target, err, output) } return nil }, }, ) } else { t.Log(`skipping "use_mklink_cmd" test, mklink does not supports directory junctions`) } testDirLinks(t, tests) }
func TestDirectorySymbolicLink(t *testing.T) { var tests []dirLinkTest output, _ := osexec.Command("cmd", "/c", "mklink", "/?").Output() mklinkSupportsDirectorySymbolicLinks := strings.Contains(string(output), " /D ") if mklinkSupportsDirectorySymbolicLinks { tests = append(tests, dirLinkTest{ name: "use_mklink_cmd", mklink: func(link, target string) error { output, err := osexec.Command("cmd", "/c", "mklink", "/D", link, target).CombinedOutput() if err != nil { t.Errorf("failed to run mklink %v %v: %v %q", link, target, err, output) } return nil }, }, ) } else { t.Log(`skipping "use_mklink_cmd" test, mklink does not supports directory symbolic links`) } // The rest of these test requires SeCreateSymbolicLinkPrivilege to be held. runtime.LockOSThread() defer runtime.UnlockOSThread() err := windows.ImpersonateSelf(windows.SecurityImpersonation) if err != nil { t.Fatal(err) } defer windows.RevertToSelf() err = enableCurrentThreadPrivilege("SeCreateSymbolicLinkPrivilege") if err != nil { t.Skipf(`skipping some tests, could not enable "SeCreateSymbolicLinkPrivilege": %v`, err) } tests = append(tests, dirLinkTest{ name: "use_os_pkg", mklink: func(link, target string) error { return os.Symlink(target, link) }, }, dirLinkTest{ // Create link similar to what mklink does, by inserting \??\ at the front of absolute target. name: "standard", mklink: func(link, target string) error { var t reparseData t.addPrintName(target) t.addSubstituteName(`\??\` + target) return createSymbolicLink(link, &t, false) }, }, dirLinkTest{ name: "relative", mklink: func(link, target string) error { var t reparseData t.addSubstituteNameNoNUL(filepath.Base(target)) t.addPrintNameNoNUL(filepath.Base(target)) return createSymbolicLink(link, &t, true) }, }, ) testDirLinks(t, tests) }