diff --git a/src/parser.c b/src/parser.c index c14f2aa..b321810 100644 --- a/src/parser.c +++ b/src/parser.c @@ -31,6 +31,12 @@ #include #include #include +#elif SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_WINDOWS +#include +#include +#include +#include +#include #endif #include "data_structures/hash_map.h" @@ -61,7 +67,11 @@ unsigned int simple_archiver_parser_internal_filename_idx( } 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; @@ -69,7 +79,11 @@ unsigned int simple_archiver_parser_internal_filename_idx( } 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; @@ -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) { SDArchiverFileInfo *file_info = data; if (file_info) { @@ -418,6 +460,72 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames( // 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.