123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- /*
- Copyright (c) 2012, Simon Howard
- Permission to use, copy, modify, and/or distribute this software
- for any purpose with or without fee is hereby granted, provided
- that the above copyright notice and this permission notice appear
- in all copies.
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- //
- // Architecture-specific files for compilation on Windows.
- // A work in progress.
- //
- #include "lha_arch.h"
- #if LHA_ARCH == LHA_ARCH_WINDOWS
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <fcntl.h>
- #include <io.h>
- #include <stdlib.h>
- #include <stdint.h>
- static uint64_t unix_epoch_offset = 0;
- int lha_arch_vasprintf(char **result, char *fmt, va_list args)
- {
- int len;
- len = vsnprintf(NULL, 0, fmt, args);
- if (len >= 0) {
- *result = malloc(len + 1);
- if (*result != NULL) {
- return vsprintf(*result, fmt, args);
- }
- }
- *result = NULL;
- return -1;
- }
- void lha_arch_set_binary(FILE *handle)
- {
- _setmode(_fileno(handle), _O_BINARY);
- }
- int lha_arch_mkdir(char *path, unsigned int unix_mode)
- {
- return CreateDirectoryA(path, NULL) != 0;
- }
- int lha_arch_chown(char *filename, int unix_uid, int unix_gid)
- {
- return 1;
- }
- int lha_arch_chmod(char *filename, int unix_perms)
- {
- return 1;
- }
- static int set_timestamps(char *filename,
- FILETIME *creation_time,
- FILETIME *modification_time,
- FILETIME *access_time)
- {
- HANDLE file;
- int result;
- // Open file handle to the file to change.
- // The FILE_FLAG_BACKUP_SEMANTICS flag is needed so that we
- // can obtain handles to directories as well as files.
- file = CreateFileA(filename,
- FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
- if (file == INVALID_HANDLE_VALUE) {
- return 0;
- }
- // Set the timestamp and close the file handle.
- result = SetFileTime(file, creation_time,
- access_time, modification_time);
- CloseHandle(file);
- return result != 0;
- }
- int lha_arch_set_windows_timestamps(char *filename,
- uint64_t creation_time,
- uint64_t modification_time,
- uint64_t access_time)
- {
- FILETIME _creation_time;
- FILETIME _modification_time;
- FILETIME _access_time;
- _creation_time.dwHighDateTime
- = (uint32_t) ((creation_time >> 32) & 0xffffffff);
- _creation_time.dwLowDateTime
- = (uint32_t) (creation_time & 0xffffffff);
- _modification_time.dwHighDateTime
- = (uint32_t) ((modification_time >> 32) & 0xffffffff);
- _modification_time.dwLowDateTime
- = (uint32_t) (modification_time & 0xffffffff);
- _access_time.dwHighDateTime
- = (uint32_t) ((access_time >> 32) & 0xffffffff);
- _access_time.dwLowDateTime
- = (uint32_t) (access_time & 0xffffffff);
- return set_timestamps(filename, &_creation_time,
- &_modification_time, &_access_time);
- }
- int lha_arch_utime(char *filename, unsigned int timestamp)
- {
- SYSTEMTIME unix_epoch;
- FILETIME filetime;
- uint64_t ts_scaled;
- // Calculate offset between Windows FILETIME Jan 1, 1601 epoch
- // and Unix Jan 1, 1970 offset.
- if (unix_epoch_offset == 0) {
- unix_epoch.wYear = 1970;
- unix_epoch.wMonth = 1;
- unix_epoch.wDayOfWeek = 4; // Thursday
- unix_epoch.wDay = 1;
- unix_epoch.wHour = 0; // 00:00:00.0
- unix_epoch.wMinute = 0;
- unix_epoch.wSecond = 0;
- unix_epoch.wMilliseconds = 0;
- SystemTimeToFileTime(&unix_epoch, &filetime);
- unix_epoch_offset = ((uint64_t) filetime.dwHighDateTime << 32)
- + filetime.dwLowDateTime;
- }
- // Convert to Unix FILETIME.
- ts_scaled = (uint64_t) timestamp * 10000000 + unix_epoch_offset;
- filetime.dwHighDateTime = (uint32_t) ((ts_scaled >> 32) & 0xffffffff);
- filetime.dwLowDateTime = (uint32_t) (ts_scaled & 0xffffffff);
- // Set all timestamps to the same value:
- return set_timestamps(filename, &filetime, &filetime, &filetime);
- }
- FILE *lha_arch_fopen(char *filename, int unix_uid, int unix_gid, int unix_perms)
- {
- return fopen(filename, "wb");
- }
- LHAFileType lha_arch_exists(char *filename)
- {
- WIN32_FILE_ATTRIBUTE_DATA file_attr;
- // Read file attributes to determine the type of the file.
- // If this fails, assume the file does not exist.
- if (GetFileAttributesExA(filename, GetFileExInfoStandard,
- &file_attr)) {
- if ((file_attr.dwFileAttributes
- & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- return LHA_FILE_DIRECTORY;
- } else {
- return LHA_FILE_FILE;
- }
- }
- return LHA_FILE_NONE;
- }
- int lha_arch_symlink(char *path, char *target)
- {
- // No-op.
- return 1;
- }
- #endif /* LHA_ARCH_WINDOWS */
|