Compare commits

...

2 commits

Author SHA1 Message Date
4e54fbf753 WIP work on windows support
Some checks failed
Run Unit Tests / build-and-run-unit-tests (push) Failing after 1s
2024-07-05 17:59:04 +09:00
3f74beefdc WIP Windows impl. 2024-07-05 15:00:50 +09:00

View file

@ -31,6 +31,12 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#elif SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_WINDOWS
#include <windows.h>
#include <fileapi.h>
#include <winnt.h>
#include <winioctl.h>
#include <wchar.h>
#endif #endif
#include "data_structures/hash_map.h" #include "data_structures/hash_map.h"
@ -61,7 +67,11 @@ unsigned int simple_archiver_parser_internal_filename_idx(
} else if ((flags & 3) == 1) { } else if ((flags & 3) == 1) {
if (filename[idx] == 0) { if (filename[idx] == 0) {
return known_good_idx; return known_good_idx;
#if SIMPLE_ARCHIVER_PLATFORM != SIMPLE_ARCHIVER_PLATFORM_WINDOWS
} else if (filename[idx] == '/') { } else if (filename[idx] == '/') {
#else
} else if (filename[idx] == '\\') {
#endif
flags |= 2; flags |= 2;
} else { } else {
return idx - 1; return idx - 1;
@ -69,7 +79,11 @@ unsigned int simple_archiver_parser_internal_filename_idx(
} else if ((flags & 3) == 3) { } else if ((flags & 3) == 3) {
if (filename[idx] == 0) { if (filename[idx] == 0) {
return known_good_idx; return known_good_idx;
#if SIMPLE_ARCHIVER_PLATFORM != SIMPLE_ARCHIVER_PLATFORM_WINDOWS
} else if (filename[idx] == '/') { } else if (filename[idx] == '/') {
#else
} else if (filename[idx] == '\\') {
#endif
continue; continue;
} else if (filename[idx] == '.') { } else if (filename[idx] == '.') {
flags &= 0xFFFFFFFC; flags &= 0xFFFFFFFC;
@ -103,6 +117,34 @@ void simple_archiver_parser_internal_remove_end_slash(char *filename) {
} }
} }
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) { void simple_archiver_internal_free_file_info_fn(void *data) {
SDArchiverFileInfo *file_info = data; SDArchiverFileInfo *file_info = data;
if (file_info) { if (file_info) {
@ -390,7 +432,7 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames(
file_info->link_dest = NULL; file_info->link_dest = NULL;
} }
simple_archiver_list_add( simple_archiver_list_add(
files_list, file_info, files_list, file_info
simple_archiver_internal_free_file_info_fn); simple_archiver_internal_free_file_info_fn);
simple_archiver_hash_map_insert( simple_archiver_hash_map_insert(
&hash_map, &hash_map_sentinel, combined_path, &hash_map, &hash_map_sentinel, combined_path,
@ -418,6 +460,76 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames(
// Unhandled type. TODO handle this. // 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 #endif
// Remove leading "./" entries from files_list. // Remove leading "./" entries from files_list.