Compare commits
3 commits
664dcfaa89
...
eb74f31204
Author | SHA1 | Date | |
---|---|---|---|
eb74f31204 | |||
fdd0e19b79 | |||
33bfdaca14 |
2 changed files with 118 additions and 4 deletions
|
@ -50,10 +50,16 @@ Following the file-count bytes, the following bytes are added for each file:
|
|||
4. The fourth byte.
|
||||
1. Currently unused.
|
||||
4. If this file is a symbolic link:
|
||||
1. 2 bytes is 16-bit unsigned integer "link target path" in big-endian. This
|
||||
does not include the NULL at the end of the string.
|
||||
2. X bytes of link-target-path (length defined by previous value). Is a
|
||||
NULL-terminated string.
|
||||
1. 2 bytes is 16-bit unsigned integer "link target absolute path" in
|
||||
big-endian. This does not include the NULL at the end of the string.
|
||||
2. X bytes of link-target-absolute-path (length defined by previous value).
|
||||
Is a NULL-terminated string. If the previous "size" value is 0, then
|
||||
this entry does not exist and should be skipped.
|
||||
3. 2 bytes is 16-bit unsigned integer "link target relative path" in
|
||||
big-endian. This does not include the NULL at the end of the string.
|
||||
4. X bytes of link-target-relative-path (length defined by previous value).
|
||||
Is a NULL-terminated string. If the previous "size" value is 0, then
|
||||
this entry does not exist and should be skipped.
|
||||
5. If this file is NOT a symbolic link:
|
||||
1. 8 bytes 64-bit unsigned integer "size of filename in this archive file".
|
||||
2. X bytes file data (length defined by previous value).
|
||||
|
|
108
src/parser.c
108
src/parser.c
|
@ -31,6 +31,12 @@
|
|||
#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"
|
||||
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue