#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#elif SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_WINDOWS
+#include <fileapi.h>
+#include <wchar.h>
+#include <windows.h>
+#include <winioctl.h>
+#include <winnt.h>
#endif
#include "data_structures/hash_map.h"
} else if ((flags & 3) == 1) {
if (filename[idx] == 0) {
return known_good_idx;
+#if SIMPLE_ARCHIVER_PLATFORM != SIMPLE_ARCHIVER_PLATFORM_WINDOWS
} else if (filename[idx] == '/') {
+#else
+ } else if (filename[idx] == '\\') {
+#endif
flags |= 2;
} else {
return idx - 1;
} else if ((flags & 3) == 3) {
if (filename[idx] == 0) {
return known_good_idx;
+#if SIMPLE_ARCHIVER_PLATFORM != SIMPLE_ARCHIVER_PLATFORM_WINDOWS
} else if (filename[idx] == '/') {
+#else
+ } else if (filename[idx] == '\\') {
+#endif
continue;
} else if (filename[idx] == '.') {
flags &= 0xFFFFFFFC;
}
}
+char *simple_archiver_internal_forward_to_backward_slash(const char *string) {
+ unsigned int len = strlen(string) + 1;
+ char *backward_slash_string = malloc(len);
+ strncpy(backward_slash_string, string, len);
+
+ for (unsigned int idx = 0; idx < len; ++idx) {
+ if (backward_slash_string[idx] == '/') {
+ backward_slash_string[idx] = '\\';
+ }
+ }
+
+ return backward_slash_string;
+}
+
+char *simple_archiver_internal_backward_to_forward_slash(const char *string) {
+ unsigned int len = strlen(string) + 1;
+ char *forward_slash_string = malloc(len);
+ strncpy(forward_slash_string, string, len);
+
+ for (unsigned int idx = 0; idx < len; ++idx) {
+ if (forward_slash_string[idx] == '\\') {
+ forward_slash_string[idx] = '/';
+ }
+ }
+
+ return forward_slash_string;
+}
+
void simple_archiver_internal_free_file_info_fn(void *data) {
SDArchiverFileInfo *file_info = data;
if (file_info) {
// Unhandled type. TODO handle this.
}
}
+#elif SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_WINDOWS
+ for (char **iter = parsed->working_files; iter && *iter; ++iter) {
+ DWORD file_stats = GetFileAttributesA(*iter);
+ if (file_stats == INVALID_FILE_ATTRIBUTES) {
+ printf("Failed to get attributes for %s\n", *iter);
+ continue;
+ } else if ((file_stats & FILE_ATTRIBUTE_DIRECTORY) == 0) {
+ // Is not a directory.
+ if ((file_stats & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
+ // Is not a symbolic link. Is probably a regular file.
+ printf("%s is probably a regular file.\n", *iter);
+ } else {
+ // Check if "reparse point" is a symbolic link.
+ WIN32_FIND_DATAA find_data;
+ HANDLE find_handle = FindFirstFileA(*iter, &find_data);
+ if (find_handle == INVALID_HANDLE_VALUE) {
+ printf("Unable to verify if %s is a symbolic link!\n", *iter);
+ continue;
+ }
+ printf("Filename in find data structure is \"%s\".\n",
+ find_data.cFileName);
+ if (find_data.dwReserved0 != IO_REPARSE_TAG_SYMLINK) {
+ puts("NOTICE: result of FindFirstFileA does not have symlink tag!");
+ // printf("%s is not a symbolic link but is a reparse point (tag is
+ // %#lx).\n", *iter, find_data.dwReserved0);
+ // FindClose(find_handle);
+ // continue;
+ }
+ FindClose(find_handle);
+ // Is a symbolic link.
+ printf("%s is a symbolic link.\n", *iter);
+ HANDLE symlink_handle =
+ CreateFileA(*iter, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL);
+ if (symlink_handle == INVALID_HANDLE_VALUE) {
+ puts("Failed to get handle on symbolic link!");
+ continue;
+ }
+
+ REPARSE_GUID_DATA_BUFFER output;
+ printf("Size of REPARSE_GUID_DATA_BUFFER is %llu\n",
+ sizeof(REPARSE_GUID_DATA_BUFFER));
+ DWORD count;
+ OVERLAPPED overlapped;
+ if (DeviceIoControl(symlink_handle, FSCTL_GET_REPARSE_POINT, NULL, 0,
+ &output, sizeof(REPARSE_GUID_DATA_BUFFER), &count,
+ &overlapped) == 0) {
+ DWORD error = GetLastError();
+ printf("Failed to get info on symlink handle (%lu %#lx)!\n", error,
+ error);
+ CloseHandle(symlink_handle);
+ continue;
+ }
+ printf("link destination count is %lu.\n", count);
+ // printf("First bytes:\n %#hhx %#hhx %#hhx %#hhx %#hhx %#hhx %#hhx
+ // %#hhx\n", output[0], output[1], output[2], output[3], output[4],
+ // output[5], output[6], output[7]);
+
+ // printf("Link to: %s\n", output.SymbolicLinkReparseBuffer.);
+ CloseHandle(symlink_handle);
+ }
+ } else {
+ // Is a directory.
+ printf("%s is a directory.\n", *iter);
+ }
+ }
#endif
// Remove leading "./" entries from files_list.