zip_source_win32w.c [plain text]
#include <stdio.h>
#include "zipint.h"
#include "zipwin32.h"
static void * _win32_strdup_w(const void *str);
static HANDLE _win32_open_w(_zip_source_win32_read_file_t *ctx);
static HANDLE _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
static int _win32_rename_temp_w(_zip_source_win32_read_file_t *ctx);
static int _win32_remove_w(const void *fname);
static _zip_source_win32_file_ops_t win32_ops_w = {
_win32_strdup_w,
_win32_open_w,
_win32_create_temp_w,
_win32_rename_temp_w,
_win32_remove_w
};
ZIP_EXTERN zip_source_t *
zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len)
{
if (za == NULL)
return NULL;
return zip_source_win32w_create(fname, start, len, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
{
if (fname == NULL || length < -1) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_w, error);
}
static void *
_win32_strdup_w(const void *str)
{
return _wcsdup((const wchar_t *)str);
}
static HANDLE
_win32_open_w(_zip_source_win32_read_file_t *ctx)
{
return CreateFileW(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
static HANDLE
_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
{
int len;
len = wcslen((const wchar_t *)ctx->fname) + 10;
if (*temp == NULL) {
if ((*temp = malloc(sizeof(wchar_t) * len)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return INVALID_HANDLE_VALUE;
}
}
if (_snwprintf((wchar_t *)*temp, len, L"%s.%08x", (const wchar_t *)ctx->fname, value) != len - 1) {
return INVALID_HANDLE_VALUE;
}
return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
}
static int
_win32_rename_temp_w(_zip_source_win32_read_file_t *ctx)
{
if (!MoveFileExW(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
return -1;
return 0;
}
static int
_win32_remove_w(const void *fname)
{
DeleteFileW((const wchar_t *)fname);
return 0;
}