VirtualBox

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

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

VBoxHDD: async I/O updates. Mostly complete except for bug fixes

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