summaryrefslogtreecommitdiffstats
path: root/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c')
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 9df9ddc..2dc2d92 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -542,11 +542,36 @@ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
{
static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
static int set;
+ BOOL ret;
+
if (!set) {
set = 1;
f = la_GetFunctionKernel32("CreateHardLinkW");
}
- return f == NULL ? 0 : (*f)(linkname, target, NULL);
+ if (!f)
+ return (0);
+ ret = (*f)(linkname, target, NULL);
+ if (!ret) {
+ /* Under windows 2000, it is necessary to remove
+ * the "\\?\" prefix. */
+#define IS_UNC(name) ((name[0] == L'U' || name[0] == L'u') && \
+ (name[1] == L'N' || name[1] == L'n') && \
+ (name[2] == L'C' || name[2] == L'c') && \
+ name[3] == L'\\')
+ if (!wcsncmp(linkname,L"\\\\?\\", 4)) {
+ linkname += 4;
+ if (IS_UNC(linkname))
+ linkname += 4;
+ }
+ if (!wcsncmp(target,L"\\\\?\\", 4)) {
+ target += 4;
+ if (IS_UNC(target))
+ target += 4;
+ }
+#undef IS_UNC
+ ret = (*f)(linkname, target, NULL);
+ }
+ return (ret);
}
static int
@@ -2207,6 +2232,7 @@ create_dir(struct archive_write_disk *a, wchar_t *path)
le->fixup |=TODO_MODE_BASE;
le->mode = mode_final;
}
+ free(full);
return (ARCHIVE_OK);
} else {
la_dosmaperr(GetLastError());