/[winpt]/trunk/Src/wptFileCBS.cpp
ViewVC logotype

Contents of /trunk/Src/wptFileCBS.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 464 - (show annotations)
Tue Oct 9 09:27:57 2012 UTC (12 years, 4 months ago) by twoaday
File size: 4786 byte(s)


1 /* wptFileCBS.cpp - Customized I/O callbacks for GPGME
2 * Copyright (C) 2005, 2006 Timo Schulz
3 * Copyright (C) 2005 g10 Code GmbH
4 *
5 * This file is part of WinPT.
6 *
7 * WinPT is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * WinPT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17 #ifdef HAVE_CONFIG_H
18 #include <config.h>
19 #endif
20
21 #include <windows.h>
22 #include <stdio.h>
23 #include <errno.h>
24
25 #include "wptCommonCtl.h"
26 #include "wptGPG.h"
27 #include "wptFileManager.h"
28 #include "wptErrors.h"
29 #include "wptTypes.h"
30 #include "wptW32API.h"
31 #include "wptUTF8.h"
32
33 void progress_callback (void *opaque, const char *what, int type,
34 int off, int max);
35
36
37 /* Predefined read callback. */
38 static ssize_t
39 read_cb (void *handle, void *buffer, size_t size)
40 {
41 file_data_t cb = (file_data_t)handle;
42 struct progress_filter_s *pfx = (struct progress_filter_s *)cb->cb_value;
43 DWORD nread = 0;
44
45 if (cb->error)
46 return -1;
47
48 if (!ReadFile (cb->handle, buffer, size, &nread, NULL)) {
49 cb->error = (int)GetLastError ();
50 log_debug ("read_cb: ReadFile() error=%d\r\n", cb->error);
51 return -1;
52 }
53
54
55 /* UTF8 klude: Remove byte order marker */
56 if (nread > 3 && cb->off == 0 && !memcmp(buffer, UTF8_BOM, 3)) {
57 BYTE *buf = (BYTE*)buffer;
58 memmove(buf, buf + 3, nread - 3);
59 nread -= 3;
60 }
61
62 /* XXX: there is a sync problem with the progress dialog. */
63 if (pfx != NULL)
64 progress_callback (pfx, NULL, 0, cb->off, cb->size);
65 cb->off += nread;
66 return (long)nread;
67 }
68
69
70 /* Predefined write callback. */
71 static ssize_t
72 write_cb (void *handle, const void *buffer, size_t size)
73 {
74 file_data_t cb = (file_data_t)handle;
75 DWORD nwritten;
76
77 if (cb->error)
78 return -1;
79
80 if (!cb->handle) {
81 SECURITY_ATTRIBUTES sec_attr;
82
83 memset (&sec_attr, 0, sizeof (sec_attr));
84 sec_attr.bInheritHandle = FALSE;
85 sec_attr.nLength = sizeof (sec_attr);
86 cb->handle = CreateFile (cb->name, GENERIC_WRITE, FILE_SHARE_WRITE,
87 &sec_attr, CREATE_ALWAYS, 0, NULL);
88 if (cb->handle == INVALID_HANDLE_VALUE) {
89 cb->error = (int)GetLastError ();
90 log_debug ("write_cb: CreateFile() error=%d\r\n", cb->error);
91 return -1;
92 }
93 }
94
95 if (!WriteFile (cb->handle, buffer, size, &nwritten, NULL)) {
96 cb->error = (int)GetLastError ();
97 log_debug ("write_cb: WriteFile() error=%d\r\n", cb->error);
98 return -1;
99 }
100 return (long)nwritten;
101 }
102
103
104 /* Create a new data -> file association with a static callback.
105 @fname is the file which is associated to the object.
106 @r_cb is the context which holds all information.
107 @for_read is 1 if the file is opened for read only.
108 Return value: 0 on success. */
109 gpgme_error_t
110 gpg_file_data_new (const char *fname, int flags, file_data_t *r_cb)
111
112 {
113 gpgme_error_t err;
114 file_data_t cb;
115 HANDLE fd = NULL;
116 SECURITY_ATTRIBUTES sec_attr;
117
118 *r_cb = NULL; /* reset */
119 memset (&sec_attr, 0, sizeof (sec_attr));
120 sec_attr.bInheritHandle = FALSE;
121 sec_attr.nLength = sizeof (sec_attr);
122 if (flags & F_DATA_READ) {
123 fd = CreateFile (fname, GENERIC_READ, FILE_SHARE_READ,
124 &sec_attr, OPEN_EXISTING, 0, NULL);
125 if (fd == INVALID_HANDLE_VALUE) {
126 log_debug ("gpg_file_data_new: CreateFile() error=%d\r\n",
127 (int)GetLastError ());
128 return gpgme_err_code_from_errno (ENOENT);
129 }
130 }
131 cb = new file_data_s;
132 if (!cb)
133 BUG (NULL);
134 memset (cb, 0, sizeof *cb);
135 cb->name = m_strdup (fname);
136 cb->cbs.read = read_cb;
137 cb->cbs.write = write_cb;
138 if (flags & F_DATA_READ) {
139 cb->handle = fd;
140 cb->size = GetFileSize (fd, NULL);
141 cb->off = 0;
142 }
143
144 err = gpgme_data_new_from_cbs (&cb->dat, &cb->cbs, cb);
145 if (!err)
146 *r_cb = cb;
147 else {
148 CloseHandle (fd);
149 free_if_alloc (cb);
150 }
151
152 return err;
153 }
154
155
156 /* Set the progress callback for the given object @ctx. */
157 void
158 gpg_file_data_set_cb (file_data_t ctx, struct progress_filter_s *pfx)
159 {
160 ctx->cb_value = (void*)pfx;
161 }
162
163
164 /* Set the file pointer to the begin again. */
165 void
166 gpg_file_data_rewind (file_data_t ctx)
167 {
168 SetFilePointer (ctx->handle, 0, NULL, FILE_BEGIN);
169 }
170
171
172 /* Release the context in @cb.
173 Close all internal handles if possible. */
174 void
175 gpg_file_data_release (file_data_t cb)
176 {
177 if (!cb)
178 return;
179 if (cb->handle) {
180 CloseHandle (cb->handle);
181 cb->handle = NULL;
182 }
183 if (cb->dat) {
184 gpgme_data_release (cb->dat);
185 cb->dat = NULL;
186 }
187 free_if_alloc (cb->name);
188 free_if_alloc (cb);
189 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26