blob: 0b79e63f0803d97f2f0dc24571920f2775a94288 [file] [log] [blame]
Andrew Molyneux516cab02014-12-24 20:07:05 +00001/*
2zip_source_win32a.c -- create data source from Windows file (ANSI)
3Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
4
5This file is part of libzip, a library to manipulate ZIP archives.
6The authors can be contacted at <libzip@nih.at>
7
8Redistribution and use in source and binary forms, with or without
9modification, are permitted provided that the following conditions
10are met:
111. Redistributions of source code must retain the above copyright
12notice, this list of conditions and the following disclaimer.
132. Redistributions in binary form must reproduce the above copyright
14notice, this list of conditions and the following disclaimer in
15the documentation and/or other materials provided with the
16distribution.
173. The names of the authors may not be used to endorse or promote
18products derived from this software without specific prior
19written permission.
20
21THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*/
33
34
35#include <errno.h>
36#include <stdio.h>
Andrew Molyneux516cab02014-12-24 20:07:05 +000037
Andrew Molyneux516cab02014-12-24 20:07:05 +000038#include "zipint.h"
Andrew Molyneuxc6a581a2015-02-07 14:00:05 +000039#include "zipwin32.h"
Andrew Molyneux516cab02014-12-24 20:07:05 +000040
41static void * _win32_strdup_a(const void *str);
42static HANDLE _win32_open_a(_zip_source_win32_read_file_t *ctx);
Andrew Molyneuxbf871b52015-02-20 08:14:22 +000043static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
Andrew Molyneux516cab02014-12-24 20:07:05 +000044static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx);
Andrew Molyneuxcb815c42014-12-24 21:24:58 +000045static int _win32_remove_a(const void *fname);
Andrew Molyneux516cab02014-12-24 20:07:05 +000046
Andrew Molyneux516cab02014-12-24 20:07:05 +000047static _zip_source_win32_file_ops_t win32_ops_a = {
48 .op_strdup = _win32_strdup_a,
49 .op_open = _win32_open_a,
50 .op_create_temp = _win32_create_temp_a,
51 .op_rename_temp = _win32_rename_temp_a,
Andrew Molyneuxcb815c42014-12-24 21:24:58 +000052 .op_remove = _win32_remove_a
Andrew Molyneux516cab02014-12-24 20:07:05 +000053};
54
55ZIP_EXTERN zip_source_t *
56zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len)
57{
58 if (za == NULL)
59 return NULL;
60
61 return zip_source_win32a_create(fname, start, len, &za->error);
62}
63
64
65ZIP_EXTERN zip_source_t *
66zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
67{
68 if (fname == NULL || length < -1) {
69 zip_error_set(error, ZIP_ER_INVAL, 0);
70 return NULL;
71 }
72
73 return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_a, error);
74}
75
76
Thomas Klausner892fb3b2015-01-27 15:00:57 +010077static void *
Andrew Molyneux516cab02014-12-24 20:07:05 +000078_win32_strdup_a(const void *str)
79{
80 return strdup((const char *)str);
81}
82
83
Thomas Klausner892fb3b2015-01-27 15:00:57 +010084static HANDLE
Andrew Molyneux516cab02014-12-24 20:07:05 +000085_win32_open_a(_zip_source_win32_read_file_t *ctx)
86{
Andrew Molyneux99e167f2015-02-22 13:28:53 +000087 return CreateFileA(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Andrew Molyneux516cab02014-12-24 20:07:05 +000088}
89
90
Thomas Klausner892fb3b2015-01-27 15:00:57 +010091static HANDLE
Andrew Molyneuxbf871b52015-02-20 08:14:22 +000092_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
Andrew Molyneux516cab02014-12-24 20:07:05 +000093{
94 int len;
95
96 len = strlen((const char *)ctx->fname) + 10;
97 if (*temp == NULL) {
Andrew Molyneuxf97c6612014-12-24 22:02:36 +000098 if ((*temp = malloc(sizeof(char) * len)) == NULL) {
Andrew Molyneux516cab02014-12-24 20:07:05 +000099 zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
100 return INVALID_HANDLE_VALUE;
101 }
102 }
103 if (sprintf((char *)*temp, "%s.%08x", (const char *)ctx->fname, value) != len - 1) {
104 return INVALID_HANDLE_VALUE;
105 }
106
Andrew Molyneuxbf871b52015-02-20 08:14:22 +0000107 return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
Andrew Molyneux516cab02014-12-24 20:07:05 +0000108}
109
110
Thomas Klausner892fb3b2015-01-27 15:00:57 +0100111static int
Andrew Molyneux516cab02014-12-24 20:07:05 +0000112_win32_rename_temp_a(_zip_source_win32_read_file_t *ctx)
113{
Andrew Molyneux73d4a302014-12-24 22:00:37 +0000114 if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
Andrew Molyneux516cab02014-12-24 20:07:05 +0000115 return -1;
Andrew Molyneux516cab02014-12-24 20:07:05 +0000116 return 0;
117}
118
119
Thomas Klausner892fb3b2015-01-27 15:00:57 +0100120static int
Andrew Molyneuxcb815c42014-12-24 21:24:58 +0000121_win32_remove_a(const void *fname)
Andrew Molyneux516cab02014-12-24 20:07:05 +0000122{
Andrew Molyneuxcb815c42014-12-24 21:24:58 +0000123 DeleteFileA((const char *)fname);
Andrew Molyneux516cab02014-12-24 20:07:05 +0000124 return 0;
125}