4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * A simple but more realistic read-only file server.
39 #error "build error: winexample2.c should only be used on Windows"
49 #include <sys/types.h>
54 #define NBDKIT_API_VERSION 2
55 #include <nbdkit-plugin.h>
57 static char *filename
= NULL
;
59 /* A debug flag which can be set on the command line using
60 * '-D example2.extra=1' to enable very verbose debugging to help
61 * developers. Use the debug flags for extra debugging which would
62 * only be useful for the original developers of the plugin. For
63 * ordinary debugging, just use nbdkit_debug and enable messages with
64 * the -v flag on the command line.
66 NBDKIT_DLL_PUBLIC
int example2_debug_extra
= 0;
69 example2_unload (void)
74 /* If you want to display extra information about the plugin when
75 * the user does ‘nbdkit example2 --dump-plugin’ then you can print
76 * ‘key=value’ lines here.
79 example2_dump_plugin (void)
81 printf ("example2_extra=hello\n");
84 /* Called for each key=value passed on the command line. This plugin
85 * only accepts file=<filename>, which is required.
88 example2_config (const char *key
, const char *value
)
90 if (strcmp (key
, "file") == 0) {
91 /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
92 filename
= nbdkit_realpath (value
);
97 nbdkit_error ("unknown parameter '%s'", key
);
104 /* Check the user did pass a file=<FILENAME> parameter. */
106 example2_config_complete (void)
108 if (filename
== NULL
) {
109 nbdkit_error ("you must supply the file=<FILENAME> parameter "
110 "after the plugin name on the command line");
117 #define example2_config_help \
118 "file=<FILENAME> (required) The filename to serve."
120 /* The per-connection handle. */
121 struct example2_handle
{
125 /* Create the per-connection handle.
127 * Because this plugin can only serve readonly, we can ignore the
128 * 'readonly' parameter.
131 example2_open (int readonly
)
133 struct example2_handle
*h
;
135 h
= malloc (sizeof *h
);
137 nbdkit_error ("malloc: error %lu", GetLastError ());
141 h
->fh
= CreateFile (filename
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
142 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
143 if (h
->fh
== INVALID_HANDLE_VALUE
) {
144 nbdkit_error ("CreateFile: %s: error %lu", filename
, GetLastError ());
152 /* Free up the per-connection handle. */
154 example2_close (void *handle
)
156 struct example2_handle
*h
= handle
;
162 /* In fact NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS would work here.
163 * However for the benefit of people who blindly cut and paste code
164 * without bothering to read any documentation, leave this at a safe
167 #define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
169 /* Get the file size. */
171 example2_get_size (void *handle
)
173 struct example2_handle
*h
= handle
;
174 LARGE_INTEGER size
= { 0 };
176 if (!GetFileSizeEx (h
->fh
, &size
)) {
177 nbdkit_error ("%s: GetFileSizeEx: error %lu", filename
, GetLastError ());
181 /* Use the debug flags for extra debugging which would only be
182 * useful for the original developers of the plugin. For ordinary
183 * debugging, just use nbdkit_debug and enable messages with the -v
184 * flag on the command line. This is a contrived example of how to
187 if (example2_debug_extra
)
188 nbdkit_debug ("extra debugging: size = %I64d", (long long)size
.QuadPart
);
190 return size
.QuadPart
;
193 /* Read data from the file. */
195 example2_pread (void *handle
, void *buf
, uint32_t count
, uint64_t offset
,
198 struct example2_handle
*h
= handle
;
202 memset (&ovl
, 0, sizeof ovl
);
203 ovl
.Offset
= offset
& 0xffffffff;
204 ovl
.OffsetHigh
= offset
>> 32;
206 /* XXX Will fail weirdly if count is larger than 32 bits. */
207 if (!ReadFile (h
->fh
, buf
, count
, &r
, &ovl
)) {
208 nbdkit_error ("%s: ReadFile: error %lu", filename
, GetLastError ());
215 static struct nbdkit_plugin plugin
= {
217 .version
= PACKAGE_VERSION
,
218 .unload
= example2_unload
,
219 .dump_plugin
= example2_dump_plugin
,
220 .config
= example2_config
,
221 .config_complete
= example2_config_complete
,
222 .config_help
= example2_config_help
,
223 .open
= example2_open
,
224 .close
= example2_close
,
225 .get_size
= example2_get_size
,
226 .pread
= example2_pread
,
229 NBDKIT_REGISTER_PLUGIN (plugin
)