diff --git a/src/parser.c b/src/parser.c index 9419f4c..d7e8c11 100644 --- a/src/parser.c +++ b/src/parser.c @@ -32,9 +32,11 @@ #include #include #elif SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_WINDOWS -#include +#include #include #include +#include +#include #endif #include "data_structures/hash_map.h" @@ -430,7 +432,7 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames( file_info->link_dest = NULL; } simple_archiver_list_add( - files_list, file_info, + files_list, file_info simple_archiver_internal_free_file_info_fn); simple_archiver_hash_map_insert( &hash_map, &hash_map_sentinel, combined_path, @@ -459,7 +461,75 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames( } } #elif SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_WINDOWS -/* DWORD file_stats = GetFileAttributesA(*/ + 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.