VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/RawHDDCore.cpp@ 28125

Last change on this file since 28125 was 27808, checked in by vboxsync, 15 years ago

VBoxHDD: First part of the async I/O support

  • The async I/O interface is not presented to the backend directly anymore but goes through a new interface in VBoxHDD doing the request management
  • Implemented everything to make the old coe work again
  • Async I/O completely disabled for now because it is not working atm (the old code for VMDK was removed)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.4 KB
Line 
1/* $Id: RawHDDCore.cpp 27808 2010-03-29 20:52:56Z vboxsync $ */
2/** @file
3 * RawHDDCore - Raw Disk image, Core Code.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#define LOG_GROUP LOG_GROUP_VD_RAW
26#include <VBox/VBoxHDD-Plugin.h>
27#include <VBox/err.h>
28
29#include <VBox/log.h>
30#include <iprt/assert.h>
31#include <iprt/alloc.h>
32#include <iprt/file.h>
33
34
35/*******************************************************************************
36* Constants And Macros, Structures and Typedefs *
37*******************************************************************************/
38
39/**
40 * Raw image data structure.
41 */
42typedef struct RAWIMAGE
43{
44 /** Base image name. */
45 const char *pszFilename;
46#ifndef VBOX_WITH_NEW_IO_CODE
47 /** File descriptor. */
48 RTFILE File;
49#else
50 /** Storage handle. */
51 PVDIOSTORAGE pStorage;
52 /** I/O interface. */
53 PVDINTERFACE pInterfaceIO;
54 /** Async I/O interface callbacks. */
55 PVDINTERFACEIO pInterfaceIOCallbacks;
56#endif
57
58 /** Pointer to the per-disk VD interface list. */
59 PVDINTERFACE pVDIfsDisk;
60
61 /** Error callback. */
62 PVDINTERFACE pInterfaceError;
63 /** Opaque data for error callback. */
64 PVDINTERFACEERROR pInterfaceErrorCallbacks;
65
66 /** Open flags passed by VBoxHD layer. */
67 unsigned uOpenFlags;
68 /** Image flags defined during creation or determined during open. */
69 unsigned uImageFlags;
70 /** Total size of the image. */
71 uint64_t cbSize;
72 /** Physical geometry of this image. */
73 PDMMEDIAGEOMETRY PCHSGeometry;
74 /** Logical geometry of this image. */
75 PDMMEDIAGEOMETRY LCHSGeometry;
76
77} RAWIMAGE, *PRAWIMAGE;
78
79/*******************************************************************************
80* Static Variables *
81*******************************************************************************/
82
83/** NULL-terminated array of supported file extensions. */
84static const char *const s_apszRawFileExtensions[] =
85{
86 /** @todo At the monment this backend doesn't claim any extensions, but it might
87 * be useful to add a few later. However this needs careful testing, as the
88 * CheckIfValid function never returns success. */
89 NULL
90};
91
92/*******************************************************************************
93* Internal Functions *
94*******************************************************************************/
95
96static int rawFlushImage(PRAWIMAGE pImage);
97static void rawFreeImage(PRAWIMAGE pImage, bool fDelete);
98
99
100/**
101 * Internal: signal an error to the frontend.
102 */
103DECLINLINE(int) rawError(PRAWIMAGE pImage, int rc, RT_SRC_POS_DECL,
104 const char *pszFormat, ...)
105{
106 va_list va;
107 va_start(va, pszFormat);
108 if (pImage->pInterfaceError)
109 pImage->pInterfaceErrorCallbacks->pfnError(pImage->pInterfaceError->pvUser, rc, RT_SRC_POS_ARGS,
110 pszFormat, va);
111 va_end(va);
112 return rc;
113}
114
115static int rawFileOpen(PRAWIMAGE pImage, bool fReadonly, bool fCreate)
116{
117 int rc = VINF_SUCCESS;
118
119 AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n"));
120
121#ifndef VBOX_WITH_NEW_IO_CODE
122 uint32_t fOpen = fReadonly ? RTFILE_O_READ | RTFILE_O_DENY_NONE
123 : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE;
124
125 if (fCreate)
126 fOpen |= RTFILE_O_CREATE;
127 else
128 fOpen |= RTFILE_O_OPEN;
129
130 rc = RTFileOpen(&pImage->File, pImage->pszFilename, fOpen);
131#else
132 unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0;
133
134 if (fCreate)
135 uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE;
136
137 rc = pImage->pInterfaceIOCallbacks->pfnOpen(pImage->pInterfaceIO->pvUser,
138 pImage->pszFilename,
139 uOpenFlags,
140 &pImage->pStorage);
141#endif
142
143 return rc;
144}
145
146static int rawFileClose(PRAWIMAGE pImage)
147{
148 int rc = VINF_SUCCESS;
149
150#ifndef VBOX_WITH_NEW_IO_CODE
151 if (pImage->File != NIL_RTFILE)
152 rc = RTFileClose(pImage->File);
153
154 pImage->File = NIL_RTFILE;
155#else
156 if (pImage->pStorage)
157 rc = pImage->pInterfaceIOCallbacks->pfnClose(pImage->pInterfaceIO->pvUser,
158 pImage->pStorage);
159
160 pImage->pStorage = NULL;
161#endif
162
163 return rc;
164}
165
166static int rawFileFlushSync(PRAWIMAGE pImage)
167{
168 int rc = VINF_SUCCESS;
169
170#ifndef VBOX_WITH_NEW_IO_CODE
171 rc = RTFileFlush(pImage->File);
172#else
173 rc = pImage->pInterfaceIOCallbacks->pfnFlushSync(pImage->pInterfaceIO->pvUser,
174 pImage->pStorage);
175#endif
176
177 return rc;
178}
179
180static int rawFileGetSize(PRAWIMAGE pImage, uint64_t *pcbSize)
181{
182 int rc = VINF_SUCCESS;
183
184#ifndef VBOX_WITH_NEW_IO_CODE
185 rc = RTFileGetSize(pImage->File, pcbSize);
186#else
187 rc = pImage->pInterfaceIOCallbacks->pfnGetSize(pImage->pInterfaceIO->pvUser,
188 pImage->pStorage,
189 pcbSize);
190#endif
191
192 return rc;
193
194}
195
196static int rawFileSetSize(PRAWIMAGE pImage, uint64_t cbSize)
197{
198 int rc = VINF_SUCCESS;
199
200#ifndef VBOX_WITH_NEW_IO_CODE
201 rc = RTFileSetSize(pImage->File, cbSize);
202#else
203 rc = pImage->pInterfaceIOCallbacks->pfnSetSize(pImage->pInterfaceIO->pvUser,
204 pImage->pStorage,
205 cbSize);
206#endif
207
208 return rc;
209}
210
211
212static int rawFileWriteSync(PRAWIMAGE pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten)
213{
214 int rc = VINF_SUCCESS;
215
216#ifndef VBOX_WITH_NEW_IO_CODE
217 rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten);
218#else
219 rc = pImage->pInterfaceIOCallbacks->pfnWriteSync(pImage->pInterfaceIO->pvUser,
220 pImage->pStorage,
221 off, cbWrite, pcvBuf,
222 pcbWritten);
223#endif
224
225 return rc;
226}
227
228static int rawFileReadSync(PRAWIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead)
229{
230 int rc = VINF_SUCCESS;
231
232#ifndef VBOX_WITH_NEW_IO_CODE
233 rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead);
234#else
235 rc = pImage->pInterfaceIOCallbacks->pfnReadSync(pImage->pInterfaceIO->pvUser,
236 pImage->pStorage,
237 off, cbRead, pvBuf,
238 pcbRead);
239#endif
240
241 return rc;
242}
243
244static bool rawFileOpened(PRAWIMAGE pImage)
245{
246#ifndef VBOX_WITH_NEW_IO_CODE
247 return pImage->File != NIL_RTFILE;
248#else
249 return pImage->pStorage != NULL;
250#endif
251}
252
253/**
254 * Internal: Open an image, constructing all necessary data structures.
255 */
256static int rawOpenImage(PRAWIMAGE pImage, unsigned uOpenFlags)
257{
258 int rc;
259
260 if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO)
261 return VERR_NOT_SUPPORTED;
262
263 pImage->uOpenFlags = uOpenFlags;
264
265 pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR);
266 if (pImage->pInterfaceError)
267 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
268
269#ifdef VBOX_WITH_NEW_IO_CODE
270 /* Try to get I/O interface. */
271 pImage->pInterfaceIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_IO);
272 AssertPtr(pImage->pInterfaceIO);
273 pImage->pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->pInterfaceIO);
274 AssertPtr(pImage->pInterfaceIOCallbacks);
275#endif
276
277 /*
278 * Open the image.
279 */
280 rc = rawFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false);
281 if (RT_FAILURE(rc))
282 {
283 /* Do NOT signal an appropriate error here, as the VD layer has the
284 * choice of retrying the open if it failed. */
285 goto out;
286 }
287
288 rc = rawFileGetSize(pImage, &pImage->cbSize);
289 if (RT_FAILURE(rc))
290 goto out;
291 if (pImage->cbSize % 512)
292 {
293 rc = VERR_VD_RAW_INVALID_HEADER;
294 goto out;
295 }
296 pImage->uImageFlags |= VD_IMAGE_FLAGS_FIXED;
297
298out:
299 if (RT_FAILURE(rc))
300 rawFreeImage(pImage, false);
301 return rc;
302}
303
304/**
305 * Internal: Create a raw image.
306 */
307static int rawCreateImage(PRAWIMAGE pImage, uint64_t cbSize,
308 unsigned uImageFlags, const char *pszComment,
309 PCPDMMEDIAGEOMETRY pPCHSGeometry,
310 PCPDMMEDIAGEOMETRY pLCHSGeometry,
311 PFNVDPROGRESS pfnProgress, void *pvUser,
312 unsigned uPercentStart, unsigned uPercentSpan)
313{
314 int rc;
315 RTFOFF cbFree = 0;
316 uint64_t uOff;
317 size_t cbBuf = 128 * _1K;
318 void *pvBuf = NULL;
319
320 if (uImageFlags & VD_IMAGE_FLAGS_DIFF)
321 {
322 rc = rawError(pImage, VERR_VD_RAW_INVALID_TYPE, RT_SRC_POS, N_("Raw: cannot create diff image '%s'"), pImage->pszFilename);
323 goto out;
324 }
325 uImageFlags |= VD_IMAGE_FLAGS_FIXED;
326
327 pImage->uImageFlags = uImageFlags;
328 pImage->PCHSGeometry = *pPCHSGeometry;
329 pImage->LCHSGeometry = *pLCHSGeometry;
330
331 pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR);
332 if (pImage->pInterfaceError)
333 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
334
335#ifdef VBOX_WITH_NEW_IO_CODE
336 /* Try to get async I/O interface. */
337 pImage->pInterfaceIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_IO);
338 AssertPtr(pImage->pInterfaceIO);
339 pImage->pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->pInterfaceIO);
340 AssertPtr(pImage->pInterfaceIOCallbacks);
341#endif
342
343 /* Create image file. */
344 rc = rawFileOpen(pImage, false, true);
345 if (RT_FAILURE(rc))
346 {
347 rc = rawError(pImage, rc, RT_SRC_POS, N_("Raw: cannot create image '%s'"), pImage->pszFilename);
348 goto out;
349 }
350
351 /* Check the free space on the disk and leave early if there is not
352 * sufficient space available. */
353 rc = RTFsQuerySizes(pImage->pszFilename, NULL, &cbFree, NULL, NULL);
354 if (RT_SUCCESS(rc) /* ignore errors */ && ((uint64_t)cbFree < cbSize))
355 {
356 rc = rawError(pImage, VERR_DISK_FULL, RT_SRC_POS, N_("Raw: disk would overflow creating image '%s'"), pImage->pszFilename);
357 goto out;
358 }
359
360 /* Allocate & commit whole file if fixed image, it must be more
361 * effective than expanding file by write operations. */
362 rc = rawFileSetSize(pImage, cbSize);
363 if (RT_FAILURE(rc))
364 {
365 rc = rawError(pImage, rc, RT_SRC_POS, N_("Raw: setting image size failed for '%s'"), pImage->pszFilename);
366 goto out;
367 }
368
369 /* Fill image with zeroes. We do this for every fixed-size image since on
370 * some systems (for example Windows Vista), it takes ages to write a block
371 * near the end of a sparse file and the guest could complain about an ATA
372 * timeout. */
373 pvBuf = RTMemTmpAllocZ(cbBuf);
374 if (!pvBuf)
375 {
376 rc = VERR_NO_MEMORY;
377 goto out;
378 }
379
380 uOff = 0;
381 /* Write data to all image blocks. */
382 while (uOff < cbSize)
383 {
384 unsigned cbChunk = (unsigned)RT_MIN(cbSize, cbBuf);
385
386 rc = rawFileWriteSync(pImage, uOff, pvBuf, cbChunk, NULL);
387 if (RT_FAILURE(rc))
388 {
389 rc = rawError(pImage, rc, RT_SRC_POS, N_("Raw: writing block failed for '%s'"), pImage->pszFilename);
390 goto out;
391 }
392
393 uOff += cbChunk;
394
395 if (pfnProgress)
396 {
397 rc = pfnProgress(pvUser,
398 uPercentStart + uOff * uPercentSpan * 98 / (cbSize * 100));
399 if (RT_FAILURE(rc))
400 goto out;
401 }
402 }
403 RTMemTmpFree(pvBuf);
404
405 if (RT_SUCCESS(rc) && pfnProgress)
406 pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100);
407
408 pImage->cbSize = cbSize;
409
410 rc = rawFlushImage(pImage);
411
412out:
413 if (RT_SUCCESS(rc) && pfnProgress)
414 pfnProgress(pvUser, uPercentStart + uPercentSpan);
415
416 if (RT_FAILURE(rc))
417 rawFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
418 return rc;
419}
420
421/**
422 * Internal. Free all allocated space for representing an image, and optionally
423 * delete the image from disk.
424 */
425static void rawFreeImage(PRAWIMAGE pImage, bool fDelete)
426{
427 Assert(pImage);
428
429 if (rawFileOpened(pImage))
430 {
431 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
432 rawFlushImage(pImage);
433 rawFileClose(pImage);
434 }
435 if (fDelete && pImage->pszFilename)
436 RTFileDelete(pImage->pszFilename);
437}
438
439/**
440 * Internal. Flush image data to disk.
441 */
442static int rawFlushImage(PRAWIMAGE pImage)
443{
444 int rc = VINF_SUCCESS;
445
446 if ( rawFileOpened(pImage)
447 && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
448 rc = rawFileFlushSync(pImage);
449
450 return rc;
451}
452
453
454/** @copydoc VBOXHDDBACKEND::pfnCheckIfValid */
455static int rawCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk)
456{
457 LogFlowFunc(("pszFilename=\"%s\"\n", pszFilename));
458 int rc = VINF_SUCCESS;
459
460 if ( !VALID_PTR(pszFilename)
461 || !*pszFilename)
462 {
463 rc = VERR_INVALID_PARAMETER;
464 goto out;
465 }
466
467 /* Always return failure, to avoid opening everything as a raw image. */
468 rc = VERR_VD_RAW_INVALID_HEADER;
469
470out:
471 LogFlowFunc(("returns %Rrc\n", rc));
472 return rc;
473}
474
475/** @copydoc VBOXHDDBACKEND::pfnOpen */
476static int rawOpen(const char *pszFilename, unsigned uOpenFlags,
477 PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
478 void **ppBackendData)
479{
480 LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p ppBackendData=%#p\n", pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, ppBackendData));
481 int rc;
482 PRAWIMAGE pImage;
483
484 /* Check open flags. All valid flags are supported. */
485 if (uOpenFlags & ~VD_OPEN_FLAGS_MASK)
486 {
487 rc = VERR_INVALID_PARAMETER;
488 goto out;
489 }
490
491 /* Check remaining arguments. */
492 if ( !VALID_PTR(pszFilename)
493 || !*pszFilename)
494 {
495 rc = VERR_INVALID_PARAMETER;
496 goto out;
497 }
498
499
500 pImage = (PRAWIMAGE)RTMemAllocZ(sizeof(RAWIMAGE));
501 if (!pImage)
502 {
503 rc = VERR_NO_MEMORY;
504 goto out;
505 }
506 pImage->pszFilename = pszFilename;
507#ifndef VBOX_WITH_NEW_IO_CODE
508 pImage->File = NIL_RTFILE;
509#else
510 pImage->pStorage = NULL;
511#endif
512 pImage->pVDIfsDisk = pVDIfsDisk;
513
514 rc = rawOpenImage(pImage, uOpenFlags);
515 if (RT_SUCCESS(rc))
516 *ppBackendData = pImage;
517 else
518 RTMemFree(pImage);
519
520out:
521 LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData));
522 return rc;
523}
524
525/** @copydoc VBOXHDDBACKEND::pfnCreate */
526static int rawCreate(const char *pszFilename, uint64_t cbSize,
527 unsigned uImageFlags, const char *pszComment,
528 PCPDMMEDIAGEOMETRY pPCHSGeometry,
529 PCPDMMEDIAGEOMETRY pLCHSGeometry, PCRTUUID pUuid,
530 unsigned uOpenFlags, unsigned uPercentStart,
531 unsigned uPercentSpan, PVDINTERFACE pVDIfsDisk,
532 PVDINTERFACE pVDIfsImage, PVDINTERFACE pVDIfsOperation,
533 void **ppBackendData)
534{
535 LogFlowFunc(("pszFilename=\"%s\" cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p ppBackendData=%#p", pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData));
536 int rc;
537 PRAWIMAGE pImage;
538
539 PFNVDPROGRESS pfnProgress = NULL;
540 void *pvUser = NULL;
541 PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation,
542 VDINTERFACETYPE_PROGRESS);
543 PVDINTERFACEPROGRESS pCbProgress = NULL;
544 if (pIfProgress)
545 {
546 pCbProgress = VDGetInterfaceProgress(pIfProgress);
547 if (pCbProgress)
548 pfnProgress = pCbProgress->pfnProgress;
549 pvUser = pIfProgress->pvUser;
550 }
551
552 /* Check open flags. All valid flags are supported. */
553 if (uOpenFlags & ~VD_OPEN_FLAGS_MASK)
554 {
555 rc = VERR_INVALID_PARAMETER;
556 goto out;
557 }
558
559 /* Check remaining arguments. */
560 if ( !VALID_PTR(pszFilename)
561 || !*pszFilename
562 || !VALID_PTR(pPCHSGeometry)
563 || !VALID_PTR(pLCHSGeometry))
564 {
565 rc = VERR_INVALID_PARAMETER;
566 goto out;
567 }
568
569 pImage = (PRAWIMAGE)RTMemAllocZ(sizeof(RAWIMAGE));
570 if (!pImage)
571 {
572 rc = VERR_NO_MEMORY;
573 goto out;
574 }
575 pImage->pszFilename = pszFilename;
576#ifndef VBOX_WITH_NEW_IO_CODE
577 pImage->File = NIL_RTFILE;
578#else
579 pImage->pStorage = NULL;
580#endif
581 pImage->pVDIfsDisk = pVDIfsDisk;
582
583 rc = rawCreateImage(pImage, cbSize, uImageFlags, pszComment,
584 pPCHSGeometry, pLCHSGeometry,
585 pfnProgress, pvUser, uPercentStart, uPercentSpan);
586 if (RT_SUCCESS(rc))
587 {
588 /* So far the image is opened in read/write mode. Make sure the
589 * image is opened in read-only mode if the caller requested that. */
590 if (uOpenFlags & VD_OPEN_FLAGS_READONLY)
591 {
592 rawFreeImage(pImage, false);
593 rc = rawOpenImage(pImage, uOpenFlags);
594 if (RT_FAILURE(rc))
595 {
596 RTMemFree(pImage);
597 goto out;
598 }
599 }
600 *ppBackendData = pImage;
601 }
602 else
603 RTMemFree(pImage);
604
605out:
606 LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData));
607 return rc;
608}
609
610/** @copydoc VBOXHDDBACKEND::pfnRename */
611static int rawRename(void *pBackendData, const char *pszFilename)
612{
613 LogFlowFunc(("pBackendData=%#p pszFilename=%#p\n", pBackendData, pszFilename));
614 int rc = VERR_NOT_IMPLEMENTED;
615
616 LogFlowFunc(("returns %Rrc\n", rc));
617 return rc;
618}
619
620/** @copydoc VBOXHDDBACKEND::pfnClose */
621static int rawClose(void *pBackendData, bool fDelete)
622{
623 LogFlowFunc(("pBackendData=%#p fDelete=%d\n", pBackendData, fDelete));
624 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
625 int rc = VINF_SUCCESS;
626
627 /* Freeing a never allocated image (e.g. because the open failed) is
628 * not signalled as an error. After all nothing bad happens. */
629 if (pImage)
630 {
631 rawFreeImage(pImage, fDelete);
632 RTMemFree(pImage);
633 }
634
635 LogFlowFunc(("returns %Rrc\n", rc));
636 return rc;
637}
638
639/** @copydoc VBOXHDDBACKEND::pfnRead */
640static int rawRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
641 size_t cbToRead, size_t *pcbActuallyRead)
642{
643 LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToRead=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbToRead, pcbActuallyRead));
644 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
645 int rc;
646
647 Assert(pImage);
648 Assert(uOffset % 512 == 0);
649 Assert(cbToRead % 512 == 0);
650
651 if ( uOffset + cbToRead > pImage->cbSize
652 || cbToRead == 0)
653 {
654 rc = VERR_INVALID_PARAMETER;
655 goto out;
656 }
657
658 rc = rawFileReadSync(pImage, uOffset, pvBuf, cbToRead, NULL);
659 *pcbActuallyRead = cbToRead;
660
661out:
662 LogFlowFunc(("returns %Rrc\n", rc));
663 return rc;
664}
665
666/** @copydoc VBOXHDDBACKEND::pfnWrite */
667static int rawWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf,
668 size_t cbToWrite, size_t *pcbWriteProcess,
669 size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite)
670{
671 LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToWrite=%zu pcbWriteProcess=%#p pcbPreRead=%#p pcbPostRead=%#p\n", pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess, pcbPreRead, pcbPostRead));
672 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
673 int rc;
674
675 Assert(pImage);
676 Assert(uOffset % 512 == 0);
677 Assert(cbToWrite % 512 == 0);
678
679 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
680 {
681 rc = VERR_VD_IMAGE_READ_ONLY;
682 goto out;
683 }
684
685 if ( uOffset + cbToWrite > pImage->cbSize
686 || cbToWrite == 0)
687 {
688 rc = VERR_INVALID_PARAMETER;
689 goto out;
690 }
691
692 rc = rawFileWriteSync(pImage, uOffset, pvBuf, cbToWrite, NULL);
693 if (pcbWriteProcess)
694 *pcbWriteProcess = cbToWrite;
695
696out:
697 LogFlowFunc(("returns %Rrc\n", rc));
698 return rc;
699}
700
701/** @copydoc VBOXHDDBACKEND::pfnFlush */
702static int rawFlush(void *pBackendData)
703{
704 LogFlowFunc(("pBackendData=%#p\n", pBackendData));
705 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
706 int rc;
707
708 rc = rawFlushImage(pImage);
709 LogFlowFunc(("returns %Rrc\n", rc));
710 return rc;
711}
712
713/** @copydoc VBOXHDDBACKEND::pfnGetVersion */
714static unsigned rawGetVersion(void *pBackendData)
715{
716 LogFlowFunc(("pBackendData=%#p\n", pBackendData));
717 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
718
719 Assert(pImage);
720
721 if (pImage)
722 return 1;
723 else
724 return 0;
725}
726
727/** @copydoc VBOXHDDBACKEND::pfnGetSize */
728static uint64_t rawGetSize(void *pBackendData)
729{
730 LogFlowFunc(("pBackendData=%#p\n", pBackendData));
731 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
732
733 Assert(pImage);
734
735 if (pImage)
736 return pImage->cbSize;
737 else
738 return 0;
739}
740
741/** @copydoc VBOXHDDBACKEND::pfnGetFileSize */
742static uint64_t rawGetFileSize(void *pBackendData)
743{
744 LogFlowFunc(("pBackendData=%#p\n", pBackendData));
745 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
746 uint64_t cb = 0;
747
748 Assert(pImage);
749
750 if (pImage)
751 {
752 uint64_t cbFile;
753 if (rawFileOpened(pImage))
754 {
755 int rc = rawFileGetSize(pImage, &cbFile);
756 if (RT_SUCCESS(rc))
757 cb += cbFile;
758 }
759 }
760
761 LogFlowFunc(("returns %lld\n", cb));
762 return cb;
763}
764
765/** @copydoc VBOXHDDBACKEND::pfnGetPCHSGeometry */
766static int rawGetPCHSGeometry(void *pBackendData,
767 PPDMMEDIAGEOMETRY pPCHSGeometry)
768{
769 LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p\n", pBackendData, pPCHSGeometry));
770 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
771 int rc;
772
773 Assert(pImage);
774
775 if (pImage)
776 {
777 if (pImage->PCHSGeometry.cCylinders)
778 {
779 *pPCHSGeometry = pImage->PCHSGeometry;
780 rc = VINF_SUCCESS;
781 }
782 else
783 rc = VERR_VD_GEOMETRY_NOT_SET;
784 }
785 else
786 rc = VERR_VD_NOT_OPENED;
787
788 LogFlowFunc(("returns %Rrc (PCHS=%u/%u/%u)\n", rc, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
789 return rc;
790}
791
792/** @copydoc VBOXHDDBACKEND::pfnSetPCHSGeometry */
793static int rawSetPCHSGeometry(void *pBackendData,
794 PCPDMMEDIAGEOMETRY pPCHSGeometry)
795{
796 LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n", pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
797 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
798 int rc;
799
800 Assert(pImage);
801
802 if (pImage)
803 {
804 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
805 {
806 rc = VERR_VD_IMAGE_READ_ONLY;
807 goto out;
808 }
809
810 pImage->PCHSGeometry = *pPCHSGeometry;
811 rc = VINF_SUCCESS;
812 }
813 else
814 rc = VERR_VD_NOT_OPENED;
815
816out:
817 LogFlowFunc(("returns %Rrc\n", rc));
818 return rc;
819}
820
821/** @copydoc VBOXHDDBACKEND::pfnGetLCHSGeometry */
822static int rawGetLCHSGeometry(void *pBackendData,
823 PPDMMEDIAGEOMETRY pLCHSGeometry)
824{
825 LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry));
826 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
827 int rc;
828
829 Assert(pImage);
830
831 if (pImage)
832 {
833 if (pImage->LCHSGeometry.cCylinders)
834 {
835 *pLCHSGeometry = pImage->LCHSGeometry;
836 rc = VINF_SUCCESS;
837 }
838 else
839 rc = VERR_VD_GEOMETRY_NOT_SET;
840 }
841 else
842 rc = VERR_VD_NOT_OPENED;
843
844 LogFlowFunc(("returns %Rrc (LCHS=%u/%u/%u)\n", rc, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
845 return rc;
846}
847
848/** @copydoc VBOXHDDBACKEND::pfnSetLCHSGeometry */
849static int rawSetLCHSGeometry(void *pBackendData,
850 PCPDMMEDIAGEOMETRY pLCHSGeometry)
851{
852 LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData, pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
853 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
854 int rc;
855
856 Assert(pImage);
857
858 if (pImage)
859 {
860 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
861 {
862 rc = VERR_VD_IMAGE_READ_ONLY;
863 goto out;
864 }
865
866 pImage->LCHSGeometry = *pLCHSGeometry;
867 rc = VINF_SUCCESS;
868 }
869 else
870 rc = VERR_VD_NOT_OPENED;
871
872out:
873 LogFlowFunc(("returns %Rrc\n", rc));
874 return rc;
875}
876
877/** @copydoc VBOXHDDBACKEND::pfnGetImageFlags */
878static unsigned rawGetImageFlags(void *pBackendData)
879{
880 LogFlowFunc(("pBackendData=%#p\n", pBackendData));
881 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
882 unsigned uImageFlags;
883
884 Assert(pImage);
885
886 if (pImage)
887 uImageFlags = pImage->uImageFlags;
888 else
889 uImageFlags = 0;
890
891 LogFlowFunc(("returns %#x\n", uImageFlags));
892 return uImageFlags;
893}
894
895/** @copydoc VBOXHDDBACKEND::pfnGetOpenFlags */
896static unsigned rawGetOpenFlags(void *pBackendData)
897{
898 LogFlowFunc(("pBackendData=%#p\n", pBackendData));
899 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
900 unsigned uOpenFlags;
901
902 Assert(pImage);
903
904 if (pImage)
905 uOpenFlags = pImage->uOpenFlags;
906 else
907 uOpenFlags = 0;
908
909 LogFlowFunc(("returns %#x\n", uOpenFlags));
910 return uOpenFlags;
911}
912
913/** @copydoc VBOXHDDBACKEND::pfnSetOpenFlags */
914static int rawSetOpenFlags(void *pBackendData, unsigned uOpenFlags)
915{
916 LogFlowFunc(("pBackendData=%#p\n uOpenFlags=%#x", pBackendData, uOpenFlags));
917 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
918 int rc;
919
920 /* Image must be opened and the new flags must be valid. Just readonly and
921 * info flags are supported. */
922 if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO)))
923 {
924 rc = VERR_INVALID_PARAMETER;
925 goto out;
926 }
927
928 /* Implement this operation via reopening the image. */
929 rawFreeImage(pImage, false);
930 rc = rawOpenImage(pImage, uOpenFlags);
931
932out:
933 LogFlowFunc(("returns %Rrc\n", rc));
934 return rc;
935}
936
937/** @copydoc VBOXHDDBACKEND::pfnGetComment */
938static int rawGetComment(void *pBackendData, char *pszComment,
939 size_t cbComment)
940{
941 LogFlowFunc(("pBackendData=%#p pszComment=%#p cbComment=%zu\n", pBackendData, pszComment, cbComment));
942 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
943 int rc;
944
945 Assert(pImage);
946
947 if (pImage)
948 {
949 if (pszComment)
950 *pszComment = '\0';
951 rc = VINF_SUCCESS;
952 }
953 else
954 rc = VERR_VD_NOT_OPENED;
955
956 LogFlowFunc(("returns %Rrc comment='%s'\n", rc, pszComment));
957 return rc;
958}
959
960/** @copydoc VBOXHDDBACKEND::pfnSetComment */
961static int rawSetComment(void *pBackendData, const char *pszComment)
962{
963 LogFlowFunc(("pBackendData=%#p pszComment=\"%s\"\n", pBackendData, pszComment));
964 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
965 int rc;
966
967 Assert(pImage);
968
969 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
970 {
971 rc = VERR_VD_IMAGE_READ_ONLY;
972 goto out;
973 }
974
975 if (pImage)
976 rc = VERR_NOT_SUPPORTED;
977 else
978 rc = VERR_VD_NOT_OPENED;
979
980out:
981 LogFlowFunc(("returns %Rrc\n", rc));
982 return rc;
983}
984
985/** @copydoc VBOXHDDBACKEND::pfnGetUuid */
986static int rawGetUuid(void *pBackendData, PRTUUID pUuid)
987{
988 LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
989 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
990 int rc;
991
992 Assert(pImage);
993
994 if (pImage)
995 rc = VERR_NOT_SUPPORTED;
996 else
997 rc = VERR_VD_NOT_OPENED;
998
999 LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid));
1000 return rc;
1001}
1002
1003/** @copydoc VBOXHDDBACKEND::pfnSetUuid */
1004static int rawSetUuid(void *pBackendData, PCRTUUID pUuid)
1005{
1006 LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
1007 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
1008 int rc;
1009
1010 LogFlowFunc(("%RTuuid\n", pUuid));
1011 Assert(pImage);
1012
1013 if (pImage)
1014 {
1015 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
1016 rc = VERR_NOT_SUPPORTED;
1017 else
1018 rc = VERR_VD_IMAGE_READ_ONLY;
1019 }
1020 else
1021 rc = VERR_VD_NOT_OPENED;
1022
1023 LogFlowFunc(("returns %Rrc\n", rc));
1024 return rc;
1025}
1026
1027/** @copydoc VBOXHDDBACKEND::pfnGetModificationUuid */
1028static int rawGetModificationUuid(void *pBackendData, PRTUUID pUuid)
1029{
1030 LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
1031 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
1032 int rc;
1033
1034 Assert(pImage);
1035
1036 if (pImage)
1037 rc = VERR_NOT_SUPPORTED;
1038 else
1039 rc = VERR_VD_NOT_OPENED;
1040
1041 LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid));
1042 return rc;
1043}
1044
1045/** @copydoc VBOXHDDBACKEND::pfnSetModificationUuid */
1046static int rawSetModificationUuid(void *pBackendData, PCRTUUID pUuid)
1047{
1048 LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
1049 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
1050 int rc;
1051
1052 Assert(pImage);
1053
1054 if (pImage)
1055 {
1056 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
1057 rc = VERR_NOT_SUPPORTED;
1058 else
1059 rc = VERR_VD_IMAGE_READ_ONLY;
1060 }
1061 else
1062 rc = VERR_VD_NOT_OPENED;
1063
1064 LogFlowFunc(("returns %Rrc\n", rc));
1065 return rc;
1066}
1067
1068/** @copydoc VBOXHDDBACKEND::pfnGetParentUuid */
1069static int rawGetParentUuid(void *pBackendData, PRTUUID pUuid)
1070{
1071 LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
1072 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
1073 int rc;
1074
1075 Assert(pImage);
1076
1077 if (pImage)
1078 rc = VERR_NOT_SUPPORTED;
1079 else
1080 rc = VERR_VD_NOT_OPENED;
1081
1082 LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid));
1083 return rc;
1084}
1085
1086/** @copydoc VBOXHDDBACKEND::pfnSetParentUuid */
1087static int rawSetParentUuid(void *pBackendData, PCRTUUID pUuid)
1088{
1089 LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
1090 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
1091 int rc;
1092
1093 Assert(pImage);
1094
1095 if (pImage)
1096 {
1097 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
1098 rc = VERR_NOT_SUPPORTED;
1099 else
1100 rc = VERR_VD_IMAGE_READ_ONLY;
1101 }
1102 else
1103 rc = VERR_VD_NOT_OPENED;
1104
1105 LogFlowFunc(("returns %Rrc\n", rc));
1106 return rc;
1107}
1108
1109/** @copydoc VBOXHDDBACKEND::pfnGetParentModificationUuid */
1110static int rawGetParentModificationUuid(void *pBackendData, PRTUUID pUuid)
1111{
1112 LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
1113 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
1114 int rc;
1115
1116 Assert(pImage);
1117
1118 if (pImage)
1119 rc = VERR_NOT_SUPPORTED;
1120 else
1121 rc = VERR_VD_NOT_OPENED;
1122
1123 LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid));
1124 return rc;
1125}
1126
1127/** @copydoc VBOXHDDBACKEND::pfnSetParentModificationUuid */
1128static int rawSetParentModificationUuid(void *pBackendData, PCRTUUID pUuid)
1129{
1130 LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
1131 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
1132 int rc;
1133
1134 Assert(pImage);
1135
1136 if (pImage)
1137 {
1138 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
1139 rc = VERR_NOT_SUPPORTED;
1140 else
1141 rc = VERR_VD_IMAGE_READ_ONLY;
1142 }
1143 else
1144 rc = VERR_VD_NOT_OPENED;
1145
1146 LogFlowFunc(("returns %Rrc\n", rc));
1147 return rc;
1148}
1149
1150/** @copydoc VBOXHDDBACKEND::pfnDump */
1151static void rawDump(void *pBackendData)
1152{
1153 PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
1154
1155 Assert(pImage);
1156 if (pImage)
1157 {
1158 pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%llu\n",
1159 pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors,
1160 pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors,
1161 pImage->cbSize / 512);
1162 }
1163}
1164
1165static int rawGetTimeStamp(void *pvBackendData, PRTTIMESPEC pTimeStamp)
1166{
1167 int rc = VERR_NOT_IMPLEMENTED;
1168 LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
1169 return rc;
1170}
1171
1172static int rawGetParentTimeStamp(void *pvBackendData, PRTTIMESPEC pTimeStamp)
1173{
1174 int rc = VERR_NOT_IMPLEMENTED;
1175 LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
1176 return rc;
1177}
1178
1179static int rawSetParentTimeStamp(void *pvBackendData, PCRTTIMESPEC pTimeStamp)
1180{
1181 int rc = VERR_NOT_IMPLEMENTED;
1182 LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
1183 return rc;
1184}
1185
1186static int rawGetParentFilename(void *pvBackendData, char **ppszParentFilename)
1187{
1188 int rc = VERR_NOT_IMPLEMENTED;
1189 LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
1190 return rc;
1191}
1192
1193static int rawSetParentFilename(void *pvBackendData, const char *pszParentFilename)
1194{
1195 int rc = VERR_NOT_IMPLEMENTED;
1196 LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
1197 return rc;
1198}
1199
1200static bool rawIsAsyncIOSupported(void *pvBackendData)
1201{
1202 return false;
1203}
1204
1205static int rawAsyncRead(void *pvBackendData, uint64_t uOffset, size_t cbRead,
1206 PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
1207{
1208 int rc = VERR_NOT_IMPLEMENTED;
1209 LogFlowFunc(("returns %Rrc\n", rc));
1210 return rc;
1211}
1212
1213static int rawAsyncWrite(void *pvBackendData, uint64_t uOffset, size_t cbWrite,
1214 PVDIOCTX pIoCtx,
1215 size_t *pcbWriteProcess, size_t *pcbPreRead,
1216 size_t *pcbPostRead, unsigned fWrite)
1217{
1218 int rc = VERR_NOT_IMPLEMENTED;
1219 LogFlowFunc(("returns %Rrc\n", rc));
1220 return rc;
1221}
1222
1223static int rawAsyncFlush(void *pvBackendData, PVDIOCTX pIoCtx)
1224{
1225 int rc = VERR_NOT_IMPLEMENTED;
1226 LogFlowFunc(("returns %Rrc\n", rc));
1227 return rc;
1228}
1229
1230VBOXHDDBACKEND g_RawBackend =
1231{
1232 /* pszBackendName */
1233 "raw",
1234 /* cbSize */
1235 sizeof(VBOXHDDBACKEND),
1236 /* uBackendCaps */
1237 VD_CAP_CREATE_FIXED | VD_CAP_FILE,
1238 /* papszFileExtensions */
1239 s_apszRawFileExtensions,
1240 /* paConfigInfo */
1241 NULL,
1242 /* hPlugin */
1243 NIL_RTLDRMOD,
1244 /* pfnCheckIfValid */
1245 rawCheckIfValid,
1246 /* pfnOpen */
1247 rawOpen,
1248 /* pfnCreate */
1249 rawCreate,
1250 /* pfnRename */
1251 rawRename,
1252 /* pfnClose */
1253 rawClose,
1254 /* pfnRead */
1255 rawRead,
1256 /* pfnWrite */
1257 rawWrite,
1258 /* pfnFlush */
1259 rawFlush,
1260 /* pfnGetVersion */
1261 rawGetVersion,
1262 /* pfnGetSize */
1263 rawGetSize,
1264 /* pfnGetFileSize */
1265 rawGetFileSize,
1266 /* pfnGetPCHSGeometry */
1267 rawGetPCHSGeometry,
1268 /* pfnSetPCHSGeometry */
1269 rawSetPCHSGeometry,
1270 /* pfnGetLCHSGeometry */
1271 rawGetLCHSGeometry,
1272 /* pfnSetLCHSGeometry */
1273 rawSetLCHSGeometry,
1274 /* pfnGetImageFlags */
1275 rawGetImageFlags,
1276 /* pfnGetOpenFlags */
1277 rawGetOpenFlags,
1278 /* pfnSetOpenFlags */
1279 rawSetOpenFlags,
1280 /* pfnGetComment */
1281 rawGetComment,
1282 /* pfnSetComment */
1283 rawSetComment,
1284 /* pfnGetUuid */
1285 rawGetUuid,
1286 /* pfnSetUuid */
1287 rawSetUuid,
1288 /* pfnGetModificationUuid */
1289 rawGetModificationUuid,
1290 /* pfnSetModificationUuid */
1291 rawSetModificationUuid,
1292 /* pfnGetParentUuid */
1293 rawGetParentUuid,
1294 /* pfnSetParentUuid */
1295 rawSetParentUuid,
1296 /* pfnGetParentModificationUuid */
1297 rawGetParentModificationUuid,
1298 /* pfnSetParentModificationUuid */
1299 rawSetParentModificationUuid,
1300 /* pfnDump */
1301 rawDump,
1302 /* pfnGetTimeStamp */
1303 rawGetTimeStamp,
1304 /* pfnGetParentTimeStamp */
1305 rawGetParentTimeStamp,
1306 /* pfnSetParentTimeStamp */
1307 rawSetParentTimeStamp,
1308 /* pfnGetParentFilename */
1309 rawGetParentFilename,
1310 /* pfnSetParentFilename */
1311 rawSetParentFilename,
1312 /* pfnIsAsyncIOSupported */
1313 rawIsAsyncIOSupported,
1314 /* pfnAsyncRead */
1315 rawAsyncRead,
1316 /* pfnAsyncWrite */
1317 rawAsyncWrite,
1318 /* pfnAsyncFlush */
1319 rawAsyncFlush,
1320 /* pfnComposeLocation */
1321 genericFileComposeLocation,
1322 /* pfnComposeName */
1323 genericFileComposeName,
1324 /* pfnCompact */
1325 NULL
1326};
1327
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette