VirtualBox

Changeset 44942 in vbox for trunk


Ignore:
Timestamp:
Mar 6, 2013 10:13:56 PM (12 years ago)
Author:
vboxsync
Message:

Storage/tstVDIo: Switch to VDScript interpreter

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/testcase/tstVDIo.cpp

    r44529 r44942  
    3838#include "VDIoRnd.h"
    3939
     40#include "VDScript.h"
     41
    4042/**
    4143 * A virtual file backed by memory.
     
    214216} VDIOTEST, *PVDIOTEST;
    215217
    216 /**
    217  * Argument types.
    218  */
    219 typedef enum VDSCRIPTARGTYPE
    220 {
    221     /** Argument is a string. */
    222     VDSCRIPTARGTYPE_STRING = 0,
    223     /** Argument is a 64bit unsigned number. */
    224     VDSCRIPTARGTYPE_UNSIGNED_NUMBER,
    225     /** Argument is a 64bit signed number. */
    226     VDSCRIPTARGTYPE_SIGNED_NUMBER,
    227     /** Arugment is a unsigned 64bit range */
    228     VDSCRIPTARGTYPE_UNSIGNED_RANGE,
    229     /** Arugment is a boolean. */
    230     VDSCRIPTARGTYPE_BOOL
    231 } VDSCRIPTARGTYPE;
    232 
    233 /**
    234  * Script argument.
    235  */
    236 typedef struct VDSCRIPTARG
    237 {
    238     /** Argument identifier. */
    239     char            chId;
    240     /** Type of the argument. */
    241     VDSCRIPTARGTYPE enmType;
    242     /** Type depndent data. */
    243     union
    244     {
    245         /** String. */
    246         const char *pcszString;
    247         /** Bool. */
    248         bool        fFlag;
    249         /** unsigned number. */
    250         uint64_t    u64;
    251         /** Signed number. */
    252         int64_t     i64;
    253         /** Unsigned range. */
    254         struct
    255         {
    256             uint64_t Start;
    257             uint64_t End;
    258         } Range;
    259     } u;
    260 } VDSCRIPTARG, *PVDSCRIPTARG;
    261 
    262 /** Script action handler. */
    263 typedef DECLCALLBACK(int) FNVDSCRIPTACTION(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    264 /** Pointer to a script action handler. */
    265 typedef FNVDSCRIPTACTION *PFNVDSCRIPTACTION;
    266 
    267 /**
    268  * Script argument descriptor.
    269  */
    270 typedef struct VDSCRIPTARGDESC
    271 {
    272     /** Name of the arugment. */
    273     const char      *pcszName;
    274     /** Identifier for the argument. */
    275     char            chId;
    276     /** Type of the argument. */
    277     VDSCRIPTARGTYPE enmType;
    278     /** Flags  */
    279     uint32_t        fFlags;
    280 } VDSCRIPTARGDESC, *PVDSCRIPTARGDESC;
    281 /** Pointer to a const script argument descriptor. */
    282 typedef const VDSCRIPTARGDESC *PCVDSCRIPTARGDESC;
    283 
    284 /** Flag whether the argument is mandatory. */
    285 #define VDSCRIPTARGDESC_FLAG_MANDATORY   RT_BIT(0)
    286 /** Flag whether the number can have a size suffix (K|M|G) */
    287 #define VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX RT_BIT(1)
    288 
    289 /**
    290  * Script action.
    291  */
    292 typedef struct VDSCRIPTACTION
    293 {
    294     /** Action name. */
    295     const char              *pcszAction;
    296     /** Pointer to the arguments. */
    297     const PCVDSCRIPTARGDESC paArgDesc;
    298     /** Number of arugments in the array. */
    299     unsigned                cArgDescs;
    300     /** Pointer to the action handler. */
    301     PFNVDSCRIPTACTION       pfnHandler;
    302 } VDSCRIPTACTION, *PVDSCRIPTACTION;
    303 
    304 typedef const VDSCRIPTACTION *PCVDSCRIPTACTION;
    305 
    306 static DECLCALLBACK(int) vdScriptHandlerCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    307 static DECLCALLBACK(int) vdScriptHandlerOpen(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    308 static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    309 static DECLCALLBACK(int) vdScriptHandlerFlush(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    310 static DECLCALLBACK(int) vdScriptHandlerMerge(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    311 static DECLCALLBACK(int) vdScriptHandlerCompact(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    312 static DECLCALLBACK(int) vdScriptHandlerDiscard(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    313 static DECLCALLBACK(int) vdScriptHandlerCopy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    314 static DECLCALLBACK(int) vdScriptHandlerClose(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    315 static DECLCALLBACK(int) vdScriptHandlerPrintFileSize(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    316 static DECLCALLBACK(int) vdScriptHandlerIoLogReplay(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    317 static DECLCALLBACK(int) vdScriptHandlerIoRngCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    318 static DECLCALLBACK(int) vdScriptHandlerIoRngDestroy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    319 static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromNumber(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    320 static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    321 static DECLCALLBACK(int) vdScriptHandlerIoPatternDestroy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    322 static DECLCALLBACK(int) vdScriptHandlerSleep(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    323 static DECLCALLBACK(int) vdScriptHandlerDumpFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    324 static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    325 static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    326 static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    327 static DECLCALLBACK(int) vdScriptHandlerDumpDiskInfo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    328 static DECLCALLBACK(int) vdScriptHandlerPrintMsg(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    329 static DECLCALLBACK(int) vdScriptHandlerShowStatistics(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    330 static DECLCALLBACK(int) vdScriptHandlerResetStatistics(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    331 static DECLCALLBACK(int) vdScriptHandlerResize(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
     218static DECLCALLBACK(int) vdScriptHandlerCreate(PVDSCRIPTARG paScriptArgs, void *pvUser);
     219static DECLCALLBACK(int) vdScriptHandlerOpen(PVDSCRIPTARG paScriptArgs, void *pvUser);
     220static DECLCALLBACK(int) vdScriptHandlerIo(PVDSCRIPTARG paScriptArgs, void *pvUser);
     221static DECLCALLBACK(int) vdScriptHandlerFlush(PVDSCRIPTARG paScriptArgs, void *pvUser);
     222static DECLCALLBACK(int) vdScriptHandlerMerge(PVDSCRIPTARG paScriptArgs, void *pvUser);
     223static DECLCALLBACK(int) vdScriptHandlerCompact(PVDSCRIPTARG paScriptArgs, void *pvUser);
     224static DECLCALLBACK(int) vdScriptHandlerDiscard(PVDSCRIPTARG paScriptArgs, void *pvUser);
     225static DECLCALLBACK(int) vdScriptHandlerCopy(PVDSCRIPTARG paScriptArgs, void *pvUser);
     226static DECLCALLBACK(int) vdScriptHandlerClose(PVDSCRIPTARG paScriptArgs, void *pvUser);
     227static DECLCALLBACK(int) vdScriptHandlerPrintFileSize(PVDSCRIPTARG paScriptArgs, void *pvUser);
     228static DECLCALLBACK(int) vdScriptHandlerIoLogReplay(PVDSCRIPTARG paScriptArgs, void *pvUser);
     229static DECLCALLBACK(int) vdScriptHandlerIoRngCreate(PVDSCRIPTARG paScriptArgs, void *pvUser);
     230static DECLCALLBACK(int) vdScriptHandlerIoRngDestroy(PVDSCRIPTARG paScriptArgs, void *pvUser);
     231static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromNumber(PVDSCRIPTARG paScriptArgs, void *pvUser);
     232static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromFile(PVDSCRIPTARG paScriptArgs, void *pvUser);
     233static DECLCALLBACK(int) vdScriptHandlerIoPatternDestroy(PVDSCRIPTARG paScriptArgs, void *pvUser);
     234static DECLCALLBACK(int) vdScriptHandlerSleep(PVDSCRIPTARG paScriptArgs, void *pvUser);
     235static DECLCALLBACK(int) vdScriptHandlerDumpFile(PVDSCRIPTARG paScriptArgs, void *pvUser);
     236static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDSCRIPTARG paScriptArgs, void *pvUser);
     237static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDSCRIPTARG paScriptArgs, void *pvUser);
     238static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDSCRIPTARG paScriptArgs, void *pvUser);
     239static DECLCALLBACK(int) vdScriptHandlerDumpDiskInfo(PVDSCRIPTARG paScriptArgs, void *pvUser);
     240static DECLCALLBACK(int) vdScriptHandlerPrintMsg(PVDSCRIPTARG paScriptArgs, void *pvUser);
     241static DECLCALLBACK(int) vdScriptHandlerShowStatistics(PVDSCRIPTARG paScriptArgs, void *pvUser);
     242static DECLCALLBACK(int) vdScriptHandlerResetStatistics(PVDSCRIPTARG paScriptArgs, void *pvUser);
     243static DECLCALLBACK(int) vdScriptHandlerResize(PVDSCRIPTARG paScriptArgs, void *pvUser);
    332244
    333245/* create action */
    334 const VDSCRIPTARGDESC g_aArgCreate[] =
    335 {
    336     /* pcszName    chId enmType                          fFlags */
    337     {"disk",        'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    338     {"mode",        'm', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    339     {"name",        'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    340     {"type",        't', VDSCRIPTARGTYPE_STRING,          0},
    341     {"backend",     'b', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    342     {"size",        's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    343     {"ignoreflush", 'f', VDSCRIPTARGTYPE_BOOL,            0}
     246const VDSCRIPTTYPE g_aArgCreate[] =
     247{
     248    VDSCRIPTTYPE_STRING,
     249    VDSCRIPTTYPE_STRING,
     250    VDSCRIPTTYPE_STRING,
     251    VDSCRIPTTYPE_STRING,
     252    VDSCRIPTTYPE_STRING,
     253    VDSCRIPTTYPE_UINT64,
     254    VDSCRIPTTYPE_BOOL
    344255};
    345256
    346257/* open action */
    347 const VDSCRIPTARGDESC g_aArgOpen[] =
    348 {
    349     /* pcszName    chId enmType                          fFlags */
    350     {"disk",        'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    351     {"name",        'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    352     {"backend",     'b', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    353     {"async",       'a', VDSCRIPTARGTYPE_BOOL,            0},
    354     {"shareable",   's', VDSCRIPTARGTYPE_BOOL,            0},
    355     {"readonly",    'r', VDSCRIPTARGTYPE_BOOL,            0},
    356     {"discard",     'i', VDSCRIPTARGTYPE_BOOL,            0},
    357     {"ignoreflush", 'f', VDSCRIPTARGTYPE_BOOL,            0},
     258const VDSCRIPTTYPE g_aArgOpen[] =
     259{
     260    VDSCRIPTTYPE_STRING, /* disk */
     261    VDSCRIPTTYPE_STRING, /* name */
     262    VDSCRIPTTYPE_STRING, /* backend */
     263    VDSCRIPTTYPE_BOOL,   /* async */
     264    VDSCRIPTTYPE_BOOL,   /* shareable */
     265    VDSCRIPTTYPE_BOOL,   /* readonly */
     266    VDSCRIPTTYPE_BOOL,   /* discard */
     267    VDSCRIPTTYPE_BOOL    /* ignoreflush */
    358268};
    359269
    360270/* I/O action */
    361 const VDSCRIPTARGDESC g_aArgIo[] =
    362 {
    363     /* pcszName    chId enmType                          fFlags */
    364     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    365     {"async",      'a', VDSCRIPTARGTYPE_BOOL,            0},
    366     {"max-reqs",   'l', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0},
    367     {"mode",       'm', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    368     {"size",       's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    369     {"blocksize",  'b', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    370     {"off",        'o', VDSCRIPTARGTYPE_UNSIGNED_RANGE,  VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    371     {"writes",     'w', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
    372     {"pattern",    'p', VDSCRIPTARGTYPE_STRING,          0},
     271const VDSCRIPTTYPE g_aArgIo[] =
     272{
     273    VDSCRIPTTYPE_STRING, /* disk */
     274    VDSCRIPTTYPE_BOOL,   /* async */
     275    VDSCRIPTTYPE_UINT32, /* max-reqs */
     276    VDSCRIPTTYPE_STRING, /* mode */
     277    VDSCRIPTTYPE_UINT64, /* size */
     278    VDSCRIPTTYPE_UINT64, /* blocksize */
     279    VDSCRIPTTYPE_UINT64, /* offStart */
     280    VDSCRIPTTYPE_UINT64, /* offEnd */
     281    VDSCRIPTTYPE_UINT32, /* writes */
     282    VDSCRIPTTYPE_STRING  /* pattern */
    373283};
    374284
    375285/* flush action */
    376 const VDSCRIPTARGDESC g_aArgFlush[] =
    377 {
    378     /* pcszName    chId enmType                          fFlags */
    379     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    380     {"async",      'a', VDSCRIPTARGTYPE_BOOL,            0}
     286const VDSCRIPTTYPE g_aArgFlush[] =
     287{
     288    VDSCRIPTTYPE_STRING, /* disk */
     289    VDSCRIPTTYPE_BOOL    /* async */
    381290};
    382291
    383292/* merge action */
    384 const VDSCRIPTARGDESC g_aArgMerge[] =
    385 {
    386     /* pcszName    chId enmType                          fFlags */
    387     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    388     {"from",       'f', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
    389     {"to",         't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
     293const VDSCRIPTTYPE g_aArgMerge[] =
     294{
     295    VDSCRIPTTYPE_STRING, /* disk */
     296    VDSCRIPTTYPE_UINT32, /* from */
     297    VDSCRIPTTYPE_UINT32  /* to */
    390298};
    391299
    392300/* Compact a disk */
    393 const VDSCRIPTARGDESC g_aArgCompact[] =
    394 {
    395     /* pcszName    chId enmType                          fFlags */
    396     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    397     {"image",      'i', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
     301const VDSCRIPTTYPE g_aArgCompact[] =
     302{
     303    VDSCRIPTTYPE_STRING, /* disk */
     304    VDSCRIPTTYPE_UINT32  /* image */
    398305};
    399306
    400307/* Discard a part of a disk */
    401 const VDSCRIPTARGDESC g_aArgDiscard[] =
    402 {
    403     /* pcszName    chId enmType                          fFlags */
    404     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    405     {"async",      'a', VDSCRIPTARGTYPE_BOOL,            0},
    406     {"ranges",     'r', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}
     308const VDSCRIPTTYPE g_aArgDiscard[] =
     309{
     310    VDSCRIPTTYPE_STRING, /* disk */
     311    VDSCRIPTTYPE_BOOL,   /* async */
     312    VDSCRIPTTYPE_STRING  /* ranges */
    407313};
    408314
    409315/* Compact a disk */
    410 const VDSCRIPTARGDESC g_aArgCopy[] =
    411 {
    412     /* pcszName    chId enmType                          fFlags */
    413     {"diskfrom",   's', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    414     {"diskto",     'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    415     {"imagefrom",  'i', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
    416     {"backend",    'b', VDSCRIPTARGTYPE_STRING,          0},
    417     {"filename",   'f', VDSCRIPTARGTYPE_STRING,          0},
    418     {"movebyrename", 'm', VDSCRIPTARGTYPE_BOOL,          0},
    419     {"size",       'z', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0},
    420     {"fromsame",   'o', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0},
    421     {"tosame",     't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0}
     316const VDSCRIPTTYPE g_aArgCopy[] =
     317{
     318    VDSCRIPTTYPE_STRING, /* diskfrom */
     319    VDSCRIPTTYPE_STRING, /* diskto */
     320    VDSCRIPTTYPE_UINT32, /* imagefrom */
     321    VDSCRIPTTYPE_STRING, /* backend */
     322    VDSCRIPTTYPE_STRING, /* filename */
     323    VDSCRIPTTYPE_BOOL,   /* movebyrename */
     324    VDSCRIPTTYPE_UINT64, /* size */
     325    VDSCRIPTTYPE_UINT32, /* fromsame */
     326    VDSCRIPTTYPE_UINT32  /* tosame */
    422327};
    423328
    424329/* close action */
    425 const VDSCRIPTARGDESC g_aArgClose[] =
    426 {
    427     /* pcszName    chId enmType                          fFlags */
    428     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    429     {"mode",       'm', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    430     {"delete",     'r', VDSCRIPTARGTYPE_BOOL,            VDSCRIPTARGDESC_FLAG_MANDATORY}
     330const VDSCRIPTTYPE g_aArgClose[] =
     331{
     332    VDSCRIPTTYPE_STRING, /* disk */
     333    VDSCRIPTTYPE_STRING, /* mode */
     334    VDSCRIPTTYPE_BOOL    /* delete */
    431335};
    432336
    433337/* print file size action */
    434 const VDSCRIPTARGDESC g_aArgPrintFileSize[] =
    435 {
    436     /* pcszName    chId enmType                          fFlags */
    437     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    438     {"image",      'i', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY}
     338const VDSCRIPTTYPE g_aArgPrintFileSize[] =
     339{
     340    VDSCRIPTTYPE_STRING, /* disk */
     341    VDSCRIPTTYPE_UINT32 /* image */
    439342};
    440343
    441344/* print file size action */
    442 const VDSCRIPTARGDESC g_aArgIoLogReplay[] =
    443 {
    444     /* pcszName    chId enmType                          fFlags */
    445     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    446     {"iolog",      'i', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}
     345const VDSCRIPTTYPE g_aArgIoLogReplay[] =
     346{
     347    VDSCRIPTTYPE_STRING, /* disk */
     348    VDSCRIPTTYPE_STRING  /* iolog */
    447349};
    448350
    449351/* I/O RNG create action */
    450 const VDSCRIPTARGDESC g_aArgIoRngCreate[] =
    451 {
    452     /* pcszName    chId enmType                          fFlags */
    453     {"size",       'd', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    454     {"mode",       'm', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    455     {"seed",       's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0}
     352const VDSCRIPTTYPE g_aArgIoRngCreate[] =
     353{
     354    VDSCRIPTTYPE_UINT32, /* size */
     355    VDSCRIPTTYPE_STRING, /* mode */
     356    VDSCRIPTTYPE_UINT32, /* seed */
    456357};
    457358
    458359/* I/O pattern create action */
    459 const VDSCRIPTARGDESC g_aArgIoPatternCreateFromNumber[] =
    460 {
    461     /* pcszName    chId enmType                          fFlags */
    462     {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    463     {"size",       's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    464     {"pattern",    'p', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
     360const VDSCRIPTTYPE g_aArgIoPatternCreateFromNumber[] =
     361{
     362    VDSCRIPTTYPE_STRING, /* name */
     363    VDSCRIPTTYPE_UINT32, /* size */
     364    VDSCRIPTTYPE_UINT32  /* pattern */
    465365};
    466366
    467367/* I/O pattern create action */
    468 const VDSCRIPTARGDESC g_aArgIoPatternCreateFromFile[] =
    469 {
    470     /* pcszName    chId enmType                          fFlags */
    471     {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    472     {"file",       'f', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     368const VDSCRIPTTYPE g_aArgIoPatternCreateFromFile[] =
     369{
     370    VDSCRIPTTYPE_STRING, /* name */
     371    VDSCRIPTTYPE_STRING  /* file */
    473372};
    474373
    475374/* I/O pattern destroy action */
    476 const VDSCRIPTARGDESC g_aArgIoPatternDestroy[] =
    477 {
    478     /* pcszName    chId enmType                          fFlags */
    479     {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
     375const VDSCRIPTTYPE g_aArgIoPatternDestroy[] =
     376{
     377    VDSCRIPTTYPE_STRING  /* name */
    480378};
    481379
    482380/* Sleep */
    483 const VDSCRIPTARGDESC g_aArgSleep[] =
    484 {
    485     /* pcszName    chId enmType                          fFlags */
    486     {"time",       't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY}
     381const VDSCRIPTTYPE g_aArgSleep[] =
     382{
     383    VDSCRIPTTYPE_UINT32  /* time */
    487384};
    488385
    489386/* Dump memory file */
    490 const VDSCRIPTARGDESC g_aArgDumpFile[] =
    491 {
    492     /* pcszName    chId enmType                          fFlags */
    493     {"file",       'f', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    494     {"path",       'p', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
     387const VDSCRIPTTYPE g_aArgDumpFile[] =
     388{
     389    VDSCRIPTTYPE_STRING, /* file */
     390    VDSCRIPTTYPE_STRING  /* path */
    495391};
    496392
    497393/* Create virtual disk handle */
    498 const VDSCRIPTARGDESC g_aArgCreateDisk[] =
    499 {
    500     /* pcszName    chId enmType                          fFlags */
    501     {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    502     {"verify",     'v', VDSCRIPTARGTYPE_BOOL,            0}
     394const VDSCRIPTTYPE g_aArgCreateDisk[] =
     395{
     396    VDSCRIPTTYPE_STRING, /* name */
     397    VDSCRIPTTYPE_BOOL    /* verify */
    503398};
    504399
    505400/* Create virtual disk handle */
    506 const VDSCRIPTARGDESC g_aArgDestroyDisk[] =
    507 {
    508     /* pcszName    chId enmType                          fFlags */
    509     {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
     401const VDSCRIPTTYPE g_aArgDestroyDisk[] =
     402{
     403    VDSCRIPTTYPE_STRING  /* name */
    510404};
    511405
    512406/* Compare virtual disks */
    513 const VDSCRIPTARGDESC g_aArgCompareDisks[] =
    514 {
    515     /* pcszName    chId enmType                          fFlags */
    516     {"disk1",      '1', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    517     {"disk2",      '2', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
     407const VDSCRIPTTYPE g_aArgCompareDisks[] =
     408{
     409    VDSCRIPTTYPE_STRING, /* disk1 */
     410    VDSCRIPTTYPE_STRING  /* disk2 */
    518411};
    519412
    520413/* Dump disk info */
    521 const VDSCRIPTARGDESC g_aArgDumpDiskInfo[] =
    522 {
    523     /* pcszName    chId enmType                          fFlags */
    524     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     414const VDSCRIPTTYPE g_aArgDumpDiskInfo[] =
     415{
     416    VDSCRIPTTYPE_STRING  /* disk */
    525417};
    526418
    527419/* Print message */
    528 const VDSCRIPTARGDESC g_aArgPrintMsg[] =
    529 {
    530     /* pcszName    chId enmType                          fFlags */
    531     {"msg",        'm', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     420const VDSCRIPTTYPE g_aArgPrintMsg[] =
     421{
     422    VDSCRIPTTYPE_STRING  /* msg */
    532423};
    533424
    534425/* Show statistics */
    535 const VDSCRIPTARGDESC g_aArgShowStatistics[] =
    536 {
    537     /* pcszName    chId enmType                          fFlags */
    538     {"file",       'f', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     426const VDSCRIPTTYPE g_aArgShowStatistics[] =
     427{
     428    VDSCRIPTTYPE_STRING  /* file */
    539429};
    540430
    541431/* Reset statistics */
    542 const VDSCRIPTARGDESC g_aArgResetStatistics[] =
    543 {
    544     /* pcszName    chId enmType                          fFlags */
    545     {"file",       'f', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     432const VDSCRIPTTYPE g_aArgResetStatistics[] =
     433{
     434    VDSCRIPTTYPE_STRING  /* file */
    546435};
    547436
    548437/* Resize disk. */
    549 const VDSCRIPTARGDESC g_aArgResize[] =
    550 {
    551     /* pcszName    chId enmType                          fFlags */
    552     {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    553     {"size",       's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX}
     438const VDSCRIPTTYPE g_aArgResize[] =
     439{
     440    VDSCRIPTTYPE_STRING, /* disk */
     441    VDSCRIPTTYPE_UINT64  /* size */
    554442};
    555443
    556444
    557 const VDSCRIPTACTION g_aScriptActions[] =
    558 {
    559     /* pcszAction                  paArgDesc                          cArgDescs                                      pfnHandler */
    560     {"create",                     g_aArgCreate,                      RT_ELEMENTS(g_aArgCreate),                     vdScriptHandlerCreate},
    561     {"open",                       g_aArgOpen,                        RT_ELEMENTS(g_aArgOpen),                       vdScriptHandlerOpen},
    562     {"io",                         g_aArgIo,                          RT_ELEMENTS(g_aArgIo),                         vdScriptHandlerIo},
    563     {"flush",                      g_aArgFlush,                       RT_ELEMENTS(g_aArgFlush),                      vdScriptHandlerFlush},
    564     {"close",                      g_aArgClose,                       RT_ELEMENTS(g_aArgClose),                      vdScriptHandlerClose},
    565     {"printfilesize",              g_aArgPrintFileSize,               RT_ELEMENTS(g_aArgPrintFileSize),              vdScriptHandlerPrintFileSize},
    566     {"ioreplay",                   g_aArgIoLogReplay,                 RT_ELEMENTS(g_aArgIoLogReplay),                vdScriptHandlerIoLogReplay},
    567     {"merge",                      g_aArgMerge,                       RT_ELEMENTS(g_aArgMerge),                      vdScriptHandlerMerge},
    568     {"compact",                    g_aArgCompact,                     RT_ELEMENTS(g_aArgCompact),                    vdScriptHandlerCompact},
    569     {"discard",                    g_aArgDiscard,                     RT_ELEMENTS(g_aArgDiscard),                    vdScriptHandlerDiscard},
    570     {"copy",                       g_aArgCopy,                        RT_ELEMENTS(g_aArgCopy),                       vdScriptHandlerCopy},
    571     {"iorngcreate",                g_aArgIoRngCreate,                 RT_ELEMENTS(g_aArgIoRngCreate),                vdScriptHandlerIoRngCreate},
    572     {"iorngdestroy",               NULL,                              0,                                             vdScriptHandlerIoRngDestroy},
    573     {"iopatterncreatefromnumber",  g_aArgIoPatternCreateFromNumber,   RT_ELEMENTS(g_aArgIoPatternCreateFromNumber),  vdScriptHandlerIoPatternCreateFromNumber},
    574     {"iopatterncreatefromfile",    g_aArgIoPatternCreateFromFile,     RT_ELEMENTS(g_aArgIoPatternCreateFromFile),    vdScriptHandlerIoPatternCreateFromFile},
    575     {"iopatterndestroy",           g_aArgIoPatternDestroy,            RT_ELEMENTS(g_aArgIoPatternDestroy),           vdScriptHandlerIoPatternDestroy},
    576     {"sleep",                      g_aArgSleep,                       RT_ELEMENTS(g_aArgSleep),                      vdScriptHandlerSleep},
    577     {"dumpfile",                   g_aArgDumpFile,                    RT_ELEMENTS(g_aArgDumpFile),                   vdScriptHandlerDumpFile},
    578     {"createdisk",                 g_aArgCreateDisk,                  RT_ELEMENTS(g_aArgCreateDisk),                 vdScriptHandlerCreateDisk},
    579     {"destroydisk",                g_aArgDestroyDisk,                 RT_ELEMENTS(g_aArgDestroyDisk),                vdScriptHandlerDestroyDisk},
    580     {"comparedisks",               g_aArgCompareDisks,                RT_ELEMENTS(g_aArgCompareDisks),               vdScriptHandlerCompareDisks},
    581     {"dumpdiskinfo",               g_aArgDumpDiskInfo,                RT_ELEMENTS(g_aArgDumpDiskInfo),               vdScriptHandlerDumpDiskInfo},
    582     {"print",                      g_aArgPrintMsg,                    RT_ELEMENTS(g_aArgPrintMsg),                   vdScriptHandlerPrintMsg},
    583     {"showstatistics",             g_aArgShowStatistics,              RT_ELEMENTS(g_aArgShowStatistics),             vdScriptHandlerShowStatistics},
    584     {"resetstatistics",            g_aArgResetStatistics,             RT_ELEMENTS(g_aArgResetStatistics),            vdScriptHandlerResetStatistics},
    585     {"resize",                     g_aArgResize,                      RT_ELEMENTS(g_aArgResize),                     vdScriptHandlerResize},
     445const VDSCRIPTCALLBACK g_aScriptActions[] =
     446{
     447    /* pcszFnName                  enmTypeReturn      paArgDesc                          cArgDescs                                      pfnHandler */
     448    {"create",                     VDSCRIPTTYPE_VOID, g_aArgCreate,                      RT_ELEMENTS(g_aArgCreate),                     vdScriptHandlerCreate},
     449    {"open",                       VDSCRIPTTYPE_VOID, g_aArgOpen,                        RT_ELEMENTS(g_aArgOpen),                       vdScriptHandlerOpen},
     450    {"io",                         VDSCRIPTTYPE_VOID, g_aArgIo,                          RT_ELEMENTS(g_aArgIo),                         vdScriptHandlerIo},
     451    {"flush",                      VDSCRIPTTYPE_VOID, g_aArgFlush,                       RT_ELEMENTS(g_aArgFlush),                      vdScriptHandlerFlush},
     452    {"close",                      VDSCRIPTTYPE_VOID, g_aArgClose,                       RT_ELEMENTS(g_aArgClose),                      vdScriptHandlerClose},
     453    {"printfilesize",              VDSCRIPTTYPE_VOID, g_aArgPrintFileSize,               RT_ELEMENTS(g_aArgPrintFileSize),              vdScriptHandlerPrintFileSize},
     454    {"ioreplay",                   VDSCRIPTTYPE_VOID, g_aArgIoLogReplay,                 RT_ELEMENTS(g_aArgIoLogReplay),                vdScriptHandlerIoLogReplay},
     455    {"merge",                      VDSCRIPTTYPE_VOID, g_aArgMerge,                       RT_ELEMENTS(g_aArgMerge),                      vdScriptHandlerMerge},
     456    {"compact",                    VDSCRIPTTYPE_VOID, g_aArgCompact,                     RT_ELEMENTS(g_aArgCompact),                    vdScriptHandlerCompact},
     457    {"discard",                    VDSCRIPTTYPE_VOID, g_aArgDiscard,                     RT_ELEMENTS(g_aArgDiscard),                    vdScriptHandlerDiscard},
     458    {"copy",                       VDSCRIPTTYPE_VOID, g_aArgCopy,                        RT_ELEMENTS(g_aArgCopy),                       vdScriptHandlerCopy},
     459    {"iorngcreate",                VDSCRIPTTYPE_VOID, g_aArgIoRngCreate,                 RT_ELEMENTS(g_aArgIoRngCreate),                vdScriptHandlerIoRngCreate},
     460    {"iorngdestroy",               VDSCRIPTTYPE_VOID, NULL,                              0,                                             vdScriptHandlerIoRngDestroy},
     461    {"iopatterncreatefromnumber",  VDSCRIPTTYPE_VOID, g_aArgIoPatternCreateFromNumber,   RT_ELEMENTS(g_aArgIoPatternCreateFromNumber),  vdScriptHandlerIoPatternCreateFromNumber},
     462    {"iopatterncreatefromfile",    VDSCRIPTTYPE_VOID, g_aArgIoPatternCreateFromFile,     RT_ELEMENTS(g_aArgIoPatternCreateFromFile),    vdScriptHandlerIoPatternCreateFromFile},
     463    {"iopatterndestroy",           VDSCRIPTTYPE_VOID, g_aArgIoPatternDestroy,            RT_ELEMENTS(g_aArgIoPatternDestroy),           vdScriptHandlerIoPatternDestroy},
     464    {"sleep",                      VDSCRIPTTYPE_VOID, g_aArgSleep,                       RT_ELEMENTS(g_aArgSleep),                      vdScriptHandlerSleep},
     465    {"dumpfile",                   VDSCRIPTTYPE_VOID, g_aArgDumpFile,                    RT_ELEMENTS(g_aArgDumpFile),                   vdScriptHandlerDumpFile},
     466    {"createdisk",                 VDSCRIPTTYPE_VOID, g_aArgCreateDisk,                  RT_ELEMENTS(g_aArgCreateDisk),                 vdScriptHandlerCreateDisk},
     467    {"destroydisk",                VDSCRIPTTYPE_VOID, g_aArgDestroyDisk,                 RT_ELEMENTS(g_aArgDestroyDisk),                vdScriptHandlerDestroyDisk},
     468    {"comparedisks",               VDSCRIPTTYPE_VOID, g_aArgCompareDisks,                RT_ELEMENTS(g_aArgCompareDisks),               vdScriptHandlerCompareDisks},
     469    {"dumpdiskinfo",               VDSCRIPTTYPE_VOID, g_aArgDumpDiskInfo,                RT_ELEMENTS(g_aArgDumpDiskInfo),               vdScriptHandlerDumpDiskInfo},
     470    {"print",                      VDSCRIPTTYPE_VOID, g_aArgPrintMsg,                    RT_ELEMENTS(g_aArgPrintMsg),                   vdScriptHandlerPrintMsg},
     471    {"showstatistics",             VDSCRIPTTYPE_VOID, g_aArgShowStatistics,              RT_ELEMENTS(g_aArgShowStatistics),             vdScriptHandlerShowStatistics},
     472    {"resetstatistics",            VDSCRIPTTYPE_VOID, g_aArgResetStatistics,             RT_ELEMENTS(g_aArgResetStatistics),            vdScriptHandlerResetStatistics},
     473    {"resize",                     VDSCRIPTTYPE_VOID, g_aArgResize,                      RT_ELEMENTS(g_aArgResize),                     vdScriptHandlerResize},
    586474};
    587475
    588476const unsigned g_cScriptActions = RT_ELEMENTS(g_aScriptActions);
     477
     478static DECLCALLBACK(int) vdScriptCallbackPrint(PVDSCRIPTARG paScriptArgs, void *pvUser)
     479{
     480    RTPrintf(paScriptArgs[0].psz);
     481    return VINF_SUCCESS;
     482}
    589483
    590484static void tstVDError(void *pvUser, int rc, RT_SRC_POS_DECL,
     
    617511static int tstVDIoPatternGetBuffer(PVDPATTERN pPattern, void **ppv, size_t cb);
    618512
    619 static DECLCALLBACK(int) vdScriptHandlerCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    620 {
    621     int rc = VINF_SUCCESS;
     513static DECLCALLBACK(int) vdScriptHandlerCreate(PVDSCRIPTARG paScriptArgs, void *pvUser)
     514{
     515    int rc = VINF_SUCCESS;
     516    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    622517    uint64_t cbSize = 0;
    623518    const char *pcszBackend = NULL;
     
    629524    bool fIgnoreFlush = false;
    630525
    631     for (unsigned i = 0; i < cScriptArgs; i++)
    632     {
    633         switch (paScriptArgs[i].chId)
    634         {
    635             case 'd':
    636             {
    637                 pcszDisk = paScriptArgs[i].u.pcszString;
    638                 break;
    639             }
    640             case 'm':
    641             {
    642                 if (!RTStrICmp(paScriptArgs[i].u.pcszString, "base"))
    643                     fBase = true;
    644                 else if (!RTStrICmp(paScriptArgs[i].u.pcszString, "diff"))
    645                     fBase = false;
    646                 else
    647                 {
    648                     RTPrintf("Invalid image mode '%s' given\n", paScriptArgs[i].u.pcszString);
    649                     rc = VERR_INVALID_PARAMETER;
    650                 }
    651                 break;
    652             }
    653             case 'n':
    654             {
    655                 pcszImage = paScriptArgs[i].u.pcszString;
    656                 break;
    657             }
    658             case 'b':
    659             {
    660                 pcszBackend = paScriptArgs[i].u.pcszString;
    661                 break;
    662             }
    663             case 's':
    664             {
    665                 cbSize = paScriptArgs[i].u.u64;
    666                 break;
    667             }
    668             case 't':
    669             {
    670                 if (!RTStrICmp(paScriptArgs[i].u.pcszString, "fixed"))
    671                     fDynamic = false;
    672                 else if (!RTStrICmp(paScriptArgs[i].u.pcszString, "dynamic"))
    673                     fDynamic = true;
    674                 else
    675                 {
    676                     RTPrintf("Invalid image type '%s' given\n", paScriptArgs[i].u.pcszString);
    677                     rc = VERR_INVALID_PARAMETER;
    678                 }
    679                 break;
    680             }
    681             case 'f':
    682             {
    683                 fIgnoreFlush = paScriptArgs[i].u.fFlag;
    684                 break;
    685             }
    686             default:
    687                 AssertMsgFailed(("Invalid argument given!\n"));
    688         }
    689 
    690         if (RT_FAILURE(rc))
    691             break;
    692     }
     526    pcszDisk = paScriptArgs[0].psz;
     527    if (!RTStrICmp(paScriptArgs[1].psz, "base"))
     528        fBase = true;
     529    else if (!RTStrICmp(paScriptArgs[1].psz, "diff"))
     530        fBase = false;
     531    else
     532    {
     533        RTPrintf("Invalid image mode '%s' given\n", paScriptArgs[1].psz);
     534        rc = VERR_INVALID_PARAMETER;
     535    }
     536    pcszImage = paScriptArgs[2].psz;
     537    if (!RTStrICmp(paScriptArgs[3].psz, "fixed"))
     538        fDynamic = false;
     539    else if (!RTStrICmp(paScriptArgs[3].psz, "dynamic"))
     540        fDynamic = true;
     541    else
     542    {
     543        RTPrintf("Invalid image type '%s' given\n", paScriptArgs[3].psz);
     544        rc = VERR_INVALID_PARAMETER;
     545    }
     546    pcszBackend = paScriptArgs[4].psz;
     547    cbSize = paScriptArgs[5].u64;
     548    fIgnoreFlush = paScriptArgs[6].f;
    693549
    694550    if (RT_SUCCESS(rc))
     
    721577}
    722578
    723 static DECLCALLBACK(int) vdScriptHandlerOpen(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    724 {
    725     int rc = VINF_SUCCESS;
     579static DECLCALLBACK(int) vdScriptHandlerOpen(PVDSCRIPTARG paScriptArgs, void *pvUser)
     580{
     581    int rc = VINF_SUCCESS;
     582    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    726583    const char *pcszBackend = NULL;
    727584    const char *pcszImage = NULL;
     
    734591    bool fIgnoreFlush = false;
    735592
    736     for (unsigned i = 0; i < cScriptArgs; i++)
    737     {
    738         switch (paScriptArgs[i].chId)
    739         {
    740             case 'd':
    741             {
    742                 pcszDisk = paScriptArgs[i].u.pcszString;
    743                 break;
    744             }
    745             case 'n':
    746             {
    747                 pcszImage = paScriptArgs[i].u.pcszString;
    748                 break;
    749             }
    750             case 'b':
    751             {
    752                 pcszBackend = paScriptArgs[i].u.pcszString;
    753                 break;
    754             }
    755             case 's':
    756             {
    757                 fShareable = paScriptArgs[i].u.fFlag;
    758                 break;
    759             }
    760             case 'r':
    761             {
    762                 fReadonly = paScriptArgs[i].u.fFlag;
    763                 break;
    764             }
    765             case 'a':
    766             {
    767                 fAsyncIo = paScriptArgs[i].u.fFlag;
    768                 break;
    769             }
    770             case 'i':
    771             {
    772                 fDiscard = paScriptArgs[i].u.fFlag;
    773                 break;
    774             }
    775             default:
    776                 AssertMsgFailed(("Invalid argument given!\n"));
    777         }
    778 
    779         if (RT_FAILURE(rc))
    780             break;
    781     }
     593    pcszDisk = paScriptArgs[0].psz;
     594    pcszImage = paScriptArgs[1].psz;
     595    pcszBackend = paScriptArgs[2].psz;
     596    fShareable = paScriptArgs[3].f;
     597    fReadonly = paScriptArgs[4].f;
     598    fAsyncIo = paScriptArgs[5].f;
     599    fDiscard = paScriptArgs[6].f;
    782600
    783601    if (RT_SUCCESS(rc))
     
    808626}
    809627
    810 static DECLCALLBACK(int) vdScriptHandlerIo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    811 {
    812     int rc = VINF_SUCCESS;
     628static DECLCALLBACK(int) vdScriptHandlerIo(PVDSCRIPTARG paScriptArgs, void *pvUser)
     629{
     630    int rc = VINF_SUCCESS;
     631    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    813632    bool fAsync = false;
    814633    bool fRandomAcc = false;
     
    826645    PVDPATTERN pPattern = NULL;
    827646
    828     for (unsigned i = 0; i < cScriptArgs; i++)
    829     {
    830         switch (paScriptArgs[i].chId)
    831         {
    832             case 'd':
    833             {
    834                 pcszDisk = paScriptArgs[i].u.pcszString;
    835                 break;
    836             }
    837             case 'a':
    838             {
    839                 fAsync = paScriptArgs[i].u.fFlag;
    840                 break;
    841             }
    842             case 'l':
    843             {
    844                 cMaxReqs = paScriptArgs[i].u.u64;
    845                 break;
    846             }
    847             case 'm':
    848             {
    849                 if (!RTStrICmp(paScriptArgs[i].u.pcszString, "seq"))
    850                     fRandomAcc = false;
    851                 else if (!RTStrICmp(paScriptArgs[i].u.pcszString, "rnd"))
    852                     fRandomAcc = true;
    853                 else
    854                 {
    855                     RTPrintf("Invalid access mode '%s'\n", paScriptArgs[i].u.pcszString);
    856                     rc = VERR_INVALID_PARAMETER;
    857                 }
    858                 break;
    859             }
    860             case 's':
    861             {
    862                 cbIo = paScriptArgs[i].u.u64;
    863                 break;
    864             }
    865             case 'b':
    866             {
    867                 cbBlkSize = paScriptArgs[i].u.u64;
    868                 break;
    869             }
    870             case 'o':
    871             {
    872                 offStart = paScriptArgs[i].u.Range.Start;
    873                 offEnd = paScriptArgs[i].u.Range.End;
    874                 break;
    875             }
    876             case 'w':
    877             {
    878                 uWriteChance = (uint8_t)paScriptArgs[i].u.u64;
    879                 break;
    880             }
    881             case 'p':
    882             {
    883                 pcszPattern = paScriptArgs[i].u.pcszString;
    884                 break;
    885             }
    886             default:
    887                 AssertMsgFailed(("Invalid argument given!\n"));
    888         }
    889 
    890         if (RT_FAILURE(rc))
    891             break;
    892     }
     647    pcszDisk = paScriptArgs[0].psz;
     648    fAsync   = paScriptArgs[1].f;
     649    cMaxReqs = paScriptArgs[2].u64;
     650    if (!RTStrICmp(paScriptArgs[3].psz, "seq"))
     651        fRandomAcc = false;
     652    else if (!RTStrICmp(paScriptArgs[3].psz, "rnd"))
     653        fRandomAcc = true;
     654    else
     655    {
     656        RTPrintf("Invalid access mode '%s'\n", paScriptArgs[3].psz);
     657        rc = VERR_INVALID_PARAMETER;
     658    }
     659    cbBlkSize = paScriptArgs[4].u64;
     660    offStart = paScriptArgs[5].u64;
     661    offEnd = paScriptArgs[6].u64;
     662    cbIo = paScriptArgs[7].u64;
     663    uWriteChance = (uint8_t)paScriptArgs[8].u64;
     664    pcszPattern = paScriptArgs[9].psz;
    893665
    894666    if (   RT_SUCCESS(rc)
     
    919691
    920692    if (   RT_SUCCESS(rc)
    921         && pcszPattern)
     693        && RTStrCmp(pcszPattern, "none"))
    922694    {
    923695        pPattern = tstVDIoGetPatternByName(pGlob, pcszPattern);
     
    1156928}
    1157929
    1158 static DECLCALLBACK(int) vdScriptHandlerFlush(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1159 {
    1160     int rc = VINF_SUCCESS;
     930static DECLCALLBACK(int) vdScriptHandlerFlush(PVDSCRIPTARG paScriptArgs, void *pvUser)
     931{
     932    int rc = VINF_SUCCESS;
     933    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    1161934    bool fAsync = false;
    1162935    const char *pcszDisk = NULL;
    1163936    PVDDISK pDisk = NULL;
    1164937
    1165     for (unsigned i = 0; i < cScriptArgs; i++)
    1166     {
    1167         switch (paScriptArgs[i].chId)
    1168         {
    1169             case 'd':
    1170             {
    1171                 pcszDisk = paScriptArgs[i].u.pcszString;
    1172                 break;
    1173             }
    1174             case 'a':
    1175             {
    1176                 fAsync = paScriptArgs[i].u.fFlag;
    1177                 break;
    1178             }
    1179 
    1180             default:
    1181                 AssertMsgFailed(("Invalid argument given!\n"));
    1182         }
    1183 
    1184         if (RT_FAILURE(rc))
    1185             break;
    1186     }
     938    pcszDisk = paScriptArgs[0].psz;
     939    fAsync   = paScriptArgs[1].f;
    1187940
    1188941    if (RT_SUCCESS(rc))
     
    1222975}
    1223976
    1224 static DECLCALLBACK(int) vdScriptHandlerMerge(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1225 {
    1226     int rc = VINF_SUCCESS;
     977static DECLCALLBACK(int) vdScriptHandlerMerge(PVDSCRIPTARG paScriptArgs, void *pvUser)
     978{
     979    int rc = VINF_SUCCESS;
     980    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    1227981    const char *pcszDisk = NULL;
    1228982    PVDDISK pDisk = NULL;
     
    1230984    unsigned nImageTo = 0;
    1231985
    1232     for (unsigned i = 0; i < cScriptArgs; i++)
    1233     {
    1234         switch (paScriptArgs[i].chId)
    1235         {
    1236             case 'd':
    1237             {
    1238                 pcszDisk = paScriptArgs[i].u.pcszString;
    1239                 break;
    1240             }
    1241             case 'f':
    1242             {
    1243                 nImageFrom = (unsigned)paScriptArgs[i].u.u64;
    1244                 break;
    1245             }
    1246             case 't':
    1247             {
    1248                 nImageTo = (unsigned)paScriptArgs[i].u.u64;
    1249                 break;
    1250             }
    1251 
    1252             default:
    1253                 AssertMsgFailed(("Invalid argument given!\n"));
    1254         }
    1255 
    1256         if (RT_FAILURE(rc))
    1257             break;
    1258     }
    1259 
    1260     if (RT_SUCCESS(rc))
    1261     {
    1262         pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
    1263         if (!pDisk)
    1264             rc = VERR_NOT_FOUND;
    1265         else
    1266         {
    1267             /** @todo: Provide progress interface to test that cancelation
    1268              * doesn't corrupt the data.
    1269              */
    1270             rc = VDMerge(pDisk->pVD, nImageFrom, nImageTo, NULL);
    1271         }
    1272     }
    1273 
    1274     return rc;
    1275 }
    1276 
    1277 static DECLCALLBACK(int) vdScriptHandlerCompact(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1278 {
    1279     int rc = VINF_SUCCESS;
     986    pcszDisk   = paScriptArgs[0].psz;
     987    nImageFrom = paScriptArgs[1].u32;
     988    nImageTo   = paScriptArgs[2].u32;
     989
     990    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     991    if (!pDisk)
     992        rc = VERR_NOT_FOUND;
     993    else
     994    {
     995        /** @todo: Provide progress interface to test that cancelation
     996         * doesn't corrupt the data.
     997         */
     998        rc = VDMerge(pDisk->pVD, nImageFrom, nImageTo, NULL);
     999    }
     1000
     1001    return rc;
     1002}
     1003
     1004static DECLCALLBACK(int) vdScriptHandlerCompact(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1005{
     1006    int rc = VINF_SUCCESS;
     1007    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    12801008    const char *pcszDisk = NULL;
    12811009    PVDDISK pDisk = NULL;
    12821010    unsigned nImage = 0;
    12831011
    1284     for (unsigned i = 0; i < cScriptArgs; i++)
    1285     {
    1286         switch (paScriptArgs[i].chId)
    1287         {
    1288             case 'd':
    1289             {
    1290                 pcszDisk = paScriptArgs[i].u.pcszString;
    1291                 break;
    1292             }
    1293             case 'i':
    1294             {
    1295                 nImage = (unsigned)paScriptArgs[i].u.u64;
    1296                 break;
    1297             }
    1298 
    1299             default:
    1300                 AssertMsgFailed(("Invalid argument given!\n"));
    1301         }
    1302 
    1303         if (RT_FAILURE(rc))
    1304             break;
    1305     }
    1306 
    1307     if (RT_SUCCESS(rc))
    1308     {
    1309         pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
    1310         if (!pDisk)
    1311             rc = VERR_NOT_FOUND;
    1312         else
    1313         {
    1314             /** @todo: Provide progress interface to test that cancelation
    1315              * doesn't corrupt the data.
    1316              */
    1317             rc = VDCompact(pDisk->pVD, nImage, NULL);
    1318         }
    1319     }
    1320 
    1321     return rc;
    1322 }
    1323 
    1324 static DECLCALLBACK(int) vdScriptHandlerDiscard(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1325 {
    1326     int rc = VINF_SUCCESS;
     1012    pcszDisk = paScriptArgs[0].psz;
     1013    nImage   = paScriptArgs[1].u32;
     1014
     1015    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     1016    if (!pDisk)
     1017        rc = VERR_NOT_FOUND;
     1018    else
     1019    {
     1020        /** @todo: Provide progress interface to test that cancelation
     1021         * doesn't corrupt the data.
     1022         */
     1023        rc = VDCompact(pDisk->pVD, nImage, NULL);
     1024    }
     1025
     1026    return rc;
     1027}
     1028
     1029static DECLCALLBACK(int) vdScriptHandlerDiscard(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1030{
     1031    int rc = VINF_SUCCESS;
     1032    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    13271033    const char *pcszDisk = NULL;
    13281034    PVDDISK pDisk = NULL;
     
    13301036    const char *pcszRanges = NULL;
    13311037
    1332     for (unsigned i = 0; i < cScriptArgs; i++)
    1333     {
    1334         switch (paScriptArgs[i].chId)
    1335         {
    1336             case 'd':
    1337             {
    1338                 pcszDisk = paScriptArgs[i].u.pcszString;
    1339                 break;
    1340             }
    1341             case 'a':
    1342             {
    1343                 fAsync = paScriptArgs[i].u.fFlag;
    1344                 break;
    1345             }
    1346             case 'r':
    1347             {
    1348                 pcszRanges = paScriptArgs[i].u.pcszString;
    1349                 break;
    1350             }
    1351             default:
    1352                 AssertMsgFailed(("Invalid argument given!\n"));
    1353         }
    1354     }
     1038    pcszDisk   = paScriptArgs[0].psz;
     1039    fAsync     = paScriptArgs[1].f;
     1040    pcszRanges = paScriptArgs[2].psz;
    13551041
    13561042    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     
    15581244}
    15591245
    1560 static DECLCALLBACK(int) vdScriptHandlerCopy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1561 {
    1562     int rc = VINF_SUCCESS;
     1246static DECLCALLBACK(int) vdScriptHandlerCopy(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1247{
     1248    int rc = VINF_SUCCESS;
     1249    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    15631250    const char *pcszDiskFrom = NULL;
    15641251    const char *pcszDiskTo = NULL;
     
    15731260    unsigned nImageToSame = VD_IMAGE_CONTENT_UNKNOWN;
    15741261
    1575     for (unsigned i = 0; i < cScriptArgs; i++)
    1576     {
    1577         switch (paScriptArgs[i].chId)
    1578         {
    1579             case 's':
    1580             {
    1581                 pcszDiskFrom = paScriptArgs[i].u.pcszString;
    1582                 break;
    1583             }
    1584             case 'd':
    1585             {
    1586                 pcszDiskTo = paScriptArgs[i].u.pcszString;
    1587                 break;
    1588             }
    1589             case 'i':
    1590             {
    1591                 nImageFrom = (unsigned)paScriptArgs[i].u.u64;
    1592                 break;
    1593             }
    1594             case 'b':
    1595             {
    1596                 pcszBackend = paScriptArgs[i].u.pcszString;
    1597                 break;
    1598             }
    1599             case 'f':
    1600             {
    1601                 pcszFilename = paScriptArgs[i].u.pcszString;
    1602                 break;
    1603             }
    1604             case 'm':
    1605             {
    1606                 fMoveByRename = paScriptArgs[i].u.fFlag;
    1607                 break;
    1608             }
    1609             case 'z':
    1610             {
    1611                 cbSize = paScriptArgs[i].u.u64;
    1612                 break;
    1613             }
    1614             case 'o':
    1615             {
    1616                 nImageFromSame = (unsigned)paScriptArgs[i].u.u64;
    1617                 break;
    1618             }
    1619             case 't':
    1620             {
    1621                 nImageToSame = (unsigned)paScriptArgs[i].u.u64;
    1622                 break;
    1623             }
    1624 
    1625             default:
    1626                 AssertMsgFailed(("Invalid argument given!\n"));
    1627         }
    1628 
    1629         if (RT_FAILURE(rc))
    1630             break;
    1631     }
    1632 
    1633     if (RT_SUCCESS(rc))
    1634     {
    1635         pDiskFrom = tstVDIoGetDiskByName(pGlob, pcszDiskFrom);
    1636         pDiskTo = tstVDIoGetDiskByName(pGlob, pcszDiskTo);
    1637         if (!pDiskFrom || !pDiskTo)
    1638             rc = VERR_NOT_FOUND;
    1639         else
    1640         {
    1641             /** @todo: Provide progress interface to test that cancelation
    1642              * works as intended.
    1643              */
    1644             rc = VDCopyEx(pDiskFrom->pVD, nImageFrom, pDiskTo->pVD, pcszBackend, pcszFilename,
    1645                           fMoveByRename, cbSize, nImageFromSame, nImageToSame,
    1646                           VD_IMAGE_FLAGS_NONE, NULL, VD_OPEN_FLAGS_ASYNC_IO,
    1647                           NULL, pGlob->pInterfacesImages, NULL);
    1648         }
    1649     }
    1650 
    1651     return rc;
    1652 }
    1653 
    1654 static DECLCALLBACK(int) vdScriptHandlerClose(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1655 {
    1656     int rc = VINF_SUCCESS;
     1262    pcszDiskFrom   = paScriptArgs[0].psz;
     1263    pcszDiskTo     = paScriptArgs[1].psz;
     1264    nImageFrom     = paScriptArgs[2].u32;
     1265    pcszBackend    = paScriptArgs[3].psz;
     1266    pcszFilename   = paScriptArgs[4].psz;
     1267    fMoveByRename  = paScriptArgs[5].f;
     1268    cbSize         = paScriptArgs[6].u64;
     1269    nImageFromSame = paScriptArgs[7].u32;
     1270    nImageToSame   = paScriptArgs[8].u32;
     1271
     1272    pDiskFrom = tstVDIoGetDiskByName(pGlob, pcszDiskFrom);
     1273    pDiskTo = tstVDIoGetDiskByName(pGlob, pcszDiskTo);
     1274    if (!pDiskFrom || !pDiskTo)
     1275        rc = VERR_NOT_FOUND;
     1276    else
     1277    {
     1278        /** @todo: Provide progress interface to test that cancelation
     1279         * works as intended.
     1280         */
     1281        rc = VDCopyEx(pDiskFrom->pVD, nImageFrom, pDiskTo->pVD, pcszBackend, pcszFilename,
     1282                      fMoveByRename, cbSize, nImageFromSame, nImageToSame,
     1283                      VD_IMAGE_FLAGS_NONE, NULL, VD_OPEN_FLAGS_ASYNC_IO,
     1284                      NULL, pGlob->pInterfacesImages, NULL);
     1285    }
     1286
     1287    return rc;
     1288}
     1289
     1290static DECLCALLBACK(int) vdScriptHandlerClose(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1291{
     1292    int rc = VINF_SUCCESS;
     1293    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    16571294    bool fAll = false;
    16581295    bool fDelete = false;
     
    16601297    PVDDISK pDisk = NULL;
    16611298
    1662     for (unsigned i = 0; i < cScriptArgs; i++)
    1663     {
    1664         switch (paScriptArgs[i].chId)
    1665         {
    1666             case 'd':
    1667             {
    1668                 pcszDisk = paScriptArgs[i].u.pcszString;
    1669                 break;
    1670             }
    1671             case 'm':
    1672             {
    1673                 if (!RTStrICmp(paScriptArgs[i].u.pcszString, "all"))
    1674                     fAll = true;
    1675                 else if (!RTStrICmp(paScriptArgs[i].u.pcszString, "single"))
    1676                     fAll = false;
    1677                 else
    1678                 {
    1679                     RTPrintf("Invalid mode '%s' given\n", paScriptArgs[i].u.pcszString);
    1680                     rc = VERR_INVALID_PARAMETER;
    1681                 }
    1682                 break;
    1683             }
    1684             case 'r':
    1685             {
    1686                 fDelete = paScriptArgs[i].u.fFlag;
    1687                 break;
    1688             }
    1689             default:
    1690                 AssertMsgFailed(("Invalid argument given!\n"));
    1691         }
    1692 
    1693         if (RT_FAILURE(rc))
    1694             break;
    1695     }
    1696 
    1697     if (   RT_SUCCESS(rc)
    1698         && fAll
     1299    pcszDisk = paScriptArgs[0].psz;
     1300    if (!RTStrICmp(paScriptArgs[1].psz, "all"))
     1301        fAll = true;
     1302    else if (!RTStrICmp(paScriptArgs[1].psz, "single"))
     1303        fAll = false;
     1304    else
     1305    {
     1306        RTPrintf("Invalid mode '%s' given\n", paScriptArgs[1].psz);
     1307        rc = VERR_INVALID_PARAMETER;
     1308    }
     1309    fDelete = paScriptArgs[2].f;
     1310
     1311    if (   fAll
    16991312        && fDelete)
    17001313    {
     
    17201333
    17211334
    1722 static DECLCALLBACK(int) vdScriptHandlerPrintFileSize(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1723 {
    1724     int rc = VINF_SUCCESS;
     1335static DECLCALLBACK(int) vdScriptHandlerPrintFileSize(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1336{
     1337    int rc = VINF_SUCCESS;
     1338    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    17251339    const char *pcszDisk = NULL;
    17261340    PVDDISK pDisk = NULL;
    17271341    unsigned nImage = 0;
    17281342
    1729     for (unsigned i = 0; i < cScriptArgs; i++)
    1730     {
    1731         switch (paScriptArgs[i].chId)
    1732         {
    1733             case 'd':
    1734             {
    1735                 pcszDisk = paScriptArgs[i].u.pcszString;
    1736                 break;
    1737             }
    1738             case 'i':
    1739             {
    1740                 nImage = (unsigned)paScriptArgs[i].u.u64;
    1741                 break;
    1742             }
    1743             default:
    1744                 AssertMsgFailed(("Invalid argument given!\n"));
    1745         }
    1746     }
     1343    pcszDisk = paScriptArgs[0].psz;
     1344    nImage   = paScriptArgs[1].u32;
    17471345
    17481346    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     
    17561354
    17571355
    1758 static DECLCALLBACK(int) vdScriptHandlerIoLogReplay(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1759 {
    1760     int rc = VINF_SUCCESS;
     1356static DECLCALLBACK(int) vdScriptHandlerIoLogReplay(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1357{
     1358    int rc = VINF_SUCCESS;
     1359    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    17611360    const char *pcszDisk = NULL;
    17621361    PVDDISK pDisk = NULL;
    17631362    const char *pcszIoLog = NULL;
    17641363
    1765     for (unsigned i = 0; i < cScriptArgs; i++)
    1766     {
    1767         switch (paScriptArgs[i].chId)
    1768         {
    1769             case 'd':
    1770             {
    1771                 pcszDisk = paScriptArgs[i].u.pcszString;
    1772                 break;
    1773             }
    1774             case 'i':
    1775             {
    1776                 pcszIoLog = paScriptArgs[i].u.pcszString;
    1777                 break;
    1778             }
    1779             default:
    1780                 AssertMsgFailed(("Invalid argument given!\n"));
    1781         }
    1782     }
     1364    pcszDisk  = paScriptArgs[0].psz;
     1365    pcszIoLog = paScriptArgs[1].psz;
    17831366
    17841367    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     
    19231506
    19241507
    1925 static DECLCALLBACK(int) vdScriptHandlerIoRngCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1926 {
    1927     int rc = VINF_SUCCESS;
     1508static DECLCALLBACK(int) vdScriptHandlerIoRngCreate(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1509{
     1510    int rc = VINF_SUCCESS;
     1511    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    19281512    size_t cbPattern = 0;
    19291513    uint64_t uSeed = 0;
    19301514    const char *pcszSeeder = NULL;
    19311515
    1932     for (unsigned i = 0; i < cScriptArgs; i++)
    1933     {
    1934         switch (paScriptArgs[i].chId)
    1935         {
    1936             case 'd':
    1937             {
    1938                 cbPattern = paScriptArgs[i].u.u64;
    1939                 break;
    1940             }
    1941             case 's':
    1942             {
    1943                 uSeed = paScriptArgs[i].u.u64;
    1944                 break;
    1945             }
    1946             case 'm':
    1947             {
    1948                 pcszSeeder = paScriptArgs[i].u.pcszString;
    1949                 break;
    1950             }
    1951             default:
    1952                 AssertMsgFailed(("Invalid argument given!\n"));
    1953         }
    1954     }
     1516    cbPattern  = paScriptArgs[0].u64;
     1517    pcszSeeder = paScriptArgs[1].psz;
     1518    uSeed      = paScriptArgs[2].u64;
    19551519
    19561520    if (pGlob->pIoRnd)
     
    19851549}
    19861550
    1987 static DECLCALLBACK(int) vdScriptHandlerIoRngDestroy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    1988 {
     1551static DECLCALLBACK(int) vdScriptHandlerIoRngDestroy(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1552{
     1553    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
     1554
    19891555    if (pGlob->pIoRnd)
    19901556    {
     
    19981564}
    19991565
    2000 static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromNumber(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2001 {
    2002     int rc = VINF_SUCCESS;
     1566static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromNumber(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1567{
     1568    int rc = VINF_SUCCESS;
     1569    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    20031570    size_t cbPattern = 0;
    20041571    const char *pcszName = NULL;
    20051572    uint64_t u64Pattern = 0;
    20061573
    2007     for (unsigned i = 0; i < cScriptArgs; i++)
    2008     {
    2009         switch (paScriptArgs[i].chId)
    2010         {
    2011             case 'n':
    2012             {
    2013                 pcszName  = paScriptArgs[i].u.pcszString;
    2014                 break;
    2015             }
    2016             case 's':
    2017             {
    2018                 cbPattern = paScriptArgs[i].u.u64;
    2019                 break;
    2020             }
    2021             case 'p':
    2022             {
    2023                 u64Pattern = paScriptArgs[i].u.u64;
    2024                 break;
    2025             }
    2026             default:
    2027                 AssertMsgFailed(("Invalid argument given!\n"));
    2028         }
    2029     }
     1574    pcszName   = paScriptArgs[0].psz;
     1575    cbPattern  = paScriptArgs[1].u64;
     1576    u64Pattern = paScriptArgs[2].u64;
    20301577
    20311578    PVDPATTERN pPattern = tstVDIoGetPatternByName(pGlob, pcszName);
     
    20571604}
    20581605
    2059 static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2060 {
    2061     int rc = VINF_SUCCESS;
     1606static DECLCALLBACK(int) vdScriptHandlerIoPatternCreateFromFile(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1607{
     1608    int rc = VINF_SUCCESS;
     1609    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    20621610    const char *pcszName = NULL;
    20631611    const char *pcszFile = NULL;
    20641612
    2065     for (unsigned i = 0; i < cScriptArgs; i++)
    2066     {
    2067         switch (paScriptArgs[i].chId)
    2068         {
    2069             case 'n':
    2070             {
    2071                 pcszName = paScriptArgs[i].u.pcszString;
    2072                 break;
    2073             }
    2074             case 'f':
    2075             {
    2076                 pcszFile = paScriptArgs[i].u.pcszString;
    2077                 break;
    2078             }
    2079             default:
    2080                 AssertMsgFailed(("Invalid argument given!\n"));
    2081         }
    2082     }
     1613    pcszName = paScriptArgs[0].psz;
     1614    pcszFile = paScriptArgs[1].psz;
    20831615
    20841616    PVDPATTERN pPattern = tstVDIoGetPatternByName(pGlob, pcszName);
     
    21191651}
    21201652
    2121 static DECLCALLBACK(int) vdScriptHandlerIoPatternDestroy(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2122 {
    2123     int rc = VINF_SUCCESS;
     1653static DECLCALLBACK(int) vdScriptHandlerIoPatternDestroy(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1654{
     1655    int rc = VINF_SUCCESS;
     1656    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    21241657    const char *pcszName = NULL;
    21251658
    2126     for (unsigned i = 0; i < cScriptArgs; i++)
    2127     {
    2128         switch (paScriptArgs[i].chId)
    2129         {
    2130             case 'n':
    2131             {
    2132                 pcszName  = paScriptArgs[i].u.pcszString;
    2133                 break;
    2134             }
    2135             default:
    2136                 AssertMsgFailed(("Invalid argument given!\n"));
    2137         }
    2138     }
     1659    pcszName = paScriptArgs[0].psz;
    21391660
    21401661    PVDPATTERN pPattern = tstVDIoGetPatternByName(pGlob, pcszName);
     
    21521673}
    21531674
    2154 static DECLCALLBACK(int) vdScriptHandlerSleep(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2155 {
    2156     int rc = VINF_SUCCESS;
    2157     uint64_t cMillies = 0;
    2158 
    2159     for (unsigned i = 0; i < cScriptArgs; i++)
    2160     {
    2161         switch (paScriptArgs[i].chId)
    2162         {
    2163             case 't':
    2164             {
    2165                 cMillies = paScriptArgs[i].u.u64;
    2166                 break;
    2167             }
    2168             default:
    2169                 AssertMsgFailed(("Invalid argument given!\n"));
    2170         }
    2171     }
     1675static DECLCALLBACK(int) vdScriptHandlerSleep(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1676{
     1677    int rc = VINF_SUCCESS;
     1678    uint64_t cMillies = paScriptArgs[0].u64;
    21721679
    21731680    rc = RTThreadSleep(cMillies);
     
    21751682}
    21761683
    2177 static DECLCALLBACK(int) vdScriptHandlerDumpFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2178 {
    2179     int rc = VINF_SUCCESS;
     1684static DECLCALLBACK(int) vdScriptHandlerDumpFile(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1685{
     1686    int rc = VINF_SUCCESS;
     1687    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    21801688    const char *pcszFile = NULL;
    21811689    const char *pcszPathToDump = NULL;
    21821690
    2183     for (unsigned i = 0; i < cScriptArgs; i++)
    2184     {
    2185         switch (paScriptArgs[i].chId)
    2186         {
    2187             case 'f':
    2188             {
    2189                 pcszFile = paScriptArgs[i].u.pcszString;
    2190                 break;
    2191             }
    2192             case 'p':
    2193             {
    2194                 pcszPathToDump = paScriptArgs[i].u.pcszString;
    2195                 break;
    2196             }
    2197             default:
    2198                 AssertMsgFailed(("Invalid argument given!\n"));
    2199         }
    2200     }
     1691    pcszFile       = paScriptArgs[0].psz;
     1692    pcszPathToDump = paScriptArgs[1].psz;
    22011693
    22021694    /* Check for the file. */
     
    22231715}
    22241716
    2225 static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2226 {
    2227     int rc = VINF_SUCCESS;
     1717static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1718{
     1719    int rc = VINF_SUCCESS;
     1720    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    22281721    const char *pcszDisk = NULL;
    22291722    PVDDISK pDisk = NULL;
    22301723    bool fVerify = false;
    22311724
    2232     for (unsigned i = 0; i < cScriptArgs; i++)
    2233     {
    2234         switch (paScriptArgs[i].chId)
    2235         {
    2236             case 'n':
    2237             {
    2238                 pcszDisk = paScriptArgs[i].u.pcszString;
    2239                 break;
    2240             }
    2241             case 'v':
    2242             {
    2243                 fVerify = paScriptArgs[i].u.fFlag;
    2244                 break;
    2245             }
    2246             default:
    2247                 AssertMsgFailed(("Invalid argument given!\n"));
    2248         }
    2249     }
     1725    pcszDisk = paScriptArgs[0].psz;
     1726    fVerify  = paScriptArgs[1].f;
    22501727
    22511728    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     
    23021779}
    23031780
    2304 static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2305 {
    2306     int rc = VINF_SUCCESS;
     1781static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1782{
     1783    int rc = VINF_SUCCESS;
     1784    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    23071785    const char *pcszDisk = NULL;
    23081786    PVDDISK pDisk = NULL;
    23091787
    2310     for (unsigned i = 0; i < cScriptArgs; i++)
    2311     {
    2312         switch (paScriptArgs[i].chId)
    2313         {
    2314             case 'n':
    2315             {
    2316                 pcszDisk = paScriptArgs[i].u.pcszString;
    2317                 break;
    2318             }
    2319             default:
    2320                 AssertMsgFailed(("Invalid argument given!\n"));
    2321         }
    2322     }
     1788    pcszDisk = paScriptArgs[0].psz;
    23231789
    23241790    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     
    23411807}
    23421808
    2343 static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2344 {
    2345     int rc = VINF_SUCCESS;
     1809static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1810{
     1811    int rc = VINF_SUCCESS;
     1812    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    23461813    const char *pcszDisk1 = NULL;
    23471814    PVDDISK pDisk1 = NULL;
     
    23491816    PVDDISK pDisk2 = NULL;
    23501817
    2351     for (unsigned i = 0; i < cScriptArgs; i++)
    2352     {
    2353         switch (paScriptArgs[i].chId)
    2354         {
    2355             case '1':
    2356             {
    2357                 pcszDisk1 = paScriptArgs[i].u.pcszString;
    2358                 break;
    2359             }
    2360             case '2':
    2361             {
    2362                 pcszDisk2 = paScriptArgs[i].u.pcszString;
    2363                 break;
    2364             }
    2365             default:
    2366                 AssertMsgFailed(("Invalid argument given!\n"));
    2367         }
    2368     }
     1818    pcszDisk1 = paScriptArgs[0].psz;
     1819    pcszDisk2 = paScriptArgs[1].psz;
    23691820
    23701821    pDisk1 = tstVDIoGetDiskByName(pGlob, pcszDisk1);
     
    24321883}
    24331884
    2434 static DECLCALLBACK(int) vdScriptHandlerDumpDiskInfo(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2435 {
    2436     int rc = VINF_SUCCESS;
     1885static DECLCALLBACK(int) vdScriptHandlerDumpDiskInfo(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1886{
     1887    int rc = VINF_SUCCESS;
     1888    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    24371889    const char *pcszDisk = NULL;
    24381890    PVDDISK pDisk = NULL;
    24391891
    2440     for (unsigned i = 0; i < cScriptArgs; i++)
    2441     {
    2442         switch (paScriptArgs[i].chId)
    2443         {
    2444             case 'd':
    2445             {
    2446                 pcszDisk = paScriptArgs[i].u.pcszString;
    2447                 break;
    2448             }
    2449             default:
    2450                 AssertMsgFailed(("Invalid argument given!\n"));
    2451         }
    2452     }
     1892    pcszDisk = paScriptArgs[0].psz;
    24531893
    24541894    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     
    24621902}
    24631903
    2464 static DECLCALLBACK(int) vdScriptHandlerPrintMsg(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2465 {
    2466     RTPrintf("%s\n", paScriptArgs[0].u.pcszString);
     1904static DECLCALLBACK(int) vdScriptHandlerPrintMsg(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1905{
     1906    RTPrintf("%s\n", paScriptArgs[0].psz);
    24671907    return VINF_SUCCESS;
    24681908}
    24691909
    2470 static DECLCALLBACK(int) vdScriptHandlerShowStatistics(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2471 {
    2472     int rc = VINF_SUCCESS;
    2473     const char *pcszFile = NULL;
    2474 
    2475     for (unsigned i = 0; i < cScriptArgs; i++)
    2476     {
    2477         switch (paScriptArgs[i].chId)
    2478         {
    2479             case 'f':
    2480             {
    2481                 pcszFile = paScriptArgs[i].u.pcszString;
    2482                 break;
    2483             }
    2484             default:
    2485                 AssertMsgFailed(("Invalid argument given!\n"));
    2486         }
    2487     }
     1910static DECLCALLBACK(int) vdScriptHandlerShowStatistics(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1911{
     1912    int rc = VINF_SUCCESS;
     1913    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
     1914    const char *pcszFile = paScriptArgs[0].psz;
    24881915
    24891916    /* Check for the file. */
     
    25141941}
    25151942
    2516 static DECLCALLBACK(int) vdScriptHandlerResetStatistics(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2517 {
    2518     int rc = VINF_SUCCESS;
    2519     const char *pcszFile = NULL;
    2520 
    2521     for (unsigned i = 0; i < cScriptArgs; i++)
    2522     {
    2523         switch (paScriptArgs[i].chId)
    2524         {
    2525             case 'f':
    2526             {
    2527                 pcszFile = paScriptArgs[i].u.pcszString;
    2528                 break;
    2529             }
    2530             default:
    2531                 AssertMsgFailed(("Invalid argument given!\n"));
    2532         }
    2533     }
     1943static DECLCALLBACK(int) vdScriptHandlerResetStatistics(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1944{
     1945    int rc = VINF_SUCCESS;
     1946    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
     1947    const char *pcszFile = paScriptArgs[0].psz;
    25341948
    25351949    /* Check for the file. */
     
    25611975}
    25621976
    2563 static DECLCALLBACK(int) vdScriptHandlerResize(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    2564 {
    2565     int rc = VINF_SUCCESS;
    2566     const char *pcszDisk = NULL;
     1977static DECLCALLBACK(int) vdScriptHandlerResize(PVDSCRIPTARG paScriptArgs, void *pvUser)
     1978{
     1979    int rc = VINF_SUCCESS;
     1980    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
     1981    const char *pcszDisk = paScriptArgs[0].psz;
    25671982    uint64_t cbDiskNew = 0;
    25681983    PVDDISK pDisk = NULL;
    2569 
    2570     for (unsigned i = 0; i < cScriptArgs; i++)
    2571     {
    2572         switch (paScriptArgs[i].chId)
    2573         {
    2574             case 'd':
    2575             {
    2576                 pcszDisk = paScriptArgs[i].u.pcszString;
    2577                 break;
    2578             }
    2579             case 's':
    2580             {
    2581                 cbDiskNew = paScriptArgs[i].u.u64;
    2582                 break;
    2583             }
    2584             default:
    2585                 AssertMsgFailed(("Invalid argument given!\n"));
    2586         }
    2587     }
    25881984
    25891985    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     
    32182614
    32192615/**
    3220  * Skips the characters until the given character is reached.
    3221  *
    3222  * @returns Start of the string with the given character
    3223  *          or NULL if the string ended before.
    3224  *
    3225  * @param psz The string to skip.
    3226  * @param ch  The character.
    3227  */
    3228 static char *tstVDIoScriptSkipUntil(char *psz, char ch)
    3229 {
    3230     while (   *psz != '\0'
    3231            && *psz != ch)
    3232         psz++;
    3233 
    3234     return psz;
    3235 }
    3236 
    3237 /**
    3238  * Skips the spaces of the current string.
    3239  *
    3240  * @returns Start of the string with a non space character
    3241  *          or NULL if the string ended before.
    3242  *
    3243  * @param psz The string to skip.
    3244  */
    3245 static char *tstVDIoScriptSkipSpace(char *psz)
    3246 {
    3247     while (   *psz != '\0'
    3248            && RT_C_IS_SPACE(*psz))
    3249         psz++;
    3250 
    3251     return psz;
    3252 }
    3253 
    3254 /**
    3255  * Skips all characters until a space is reached of the current
    3256  * string.
    3257  *
    3258  * @returns Start of the string with a space character
    3259  *          or NULL if the string ended before.
    3260  *
    3261  * @param psz The string to skip.
    3262  */
    3263 static char *tstVDIoScriptSkipNonSpace(char *psz)
    3264 {
    3265     while (   *psz != '\0'
    3266            && !RT_C_IS_SPACE(*psz))
    3267         psz++;
    3268 
    3269     return psz;
    3270 }
    3271 
    3272 /**
    3273  * Returns true if the first character of the given string
    3274  * contains a character marking a line end (comment or \0
    3275  * terminator).
    3276  *
    3277  * @returns true if the line contains no more characters of
    3278  *          interest and false otherwise.
    3279  *
    3280  * @param psz    The string to check for.
    3281  */
    3282 static bool tstVDIoIsLineEnd(const char *psz)
    3283 {
    3284     return *psz == '\0' || *psz == '#';
    3285 }
    3286 
    3287 /**
    3288  * Parses one argument name, value pair.
    3289  *
    3290  * @returns IPRT status code.
    3291  *
    3292  * @param pVDScriptAction    Script action.
    3293  * @param pcszName           Argument name.
    3294  * @param pcszValue          Argument value.
    3295  * @param pScriptArg         Where to fill in the parsed
    3296  *                           argument.
    3297  * @param pfMandatory        Where to store whether the argument
    3298  *                           is mandatory.
    3299  */
    3300 static int tstVDIoScriptArgumentParse(PCVDSCRIPTACTION pVDScriptAction, const char *pcszName,
    3301                                       const char *pcszValue, PVDSCRIPTARG pScriptArg, bool *pfMandatory)
    3302 {
    3303     int rc = VERR_NOT_FOUND;
    3304 
    3305     for (unsigned i = 0; i < pVDScriptAction->cArgDescs; i++)
    3306     {
    3307         if (!RTStrCmp(pVDScriptAction->paArgDesc[i].pcszName, pcszName))
    3308         {
    3309             rc = VINF_SUCCESS;
    3310 
    3311             switch (pVDScriptAction->paArgDesc[i].enmType)
    3312             {
    3313                 case VDSCRIPTARGTYPE_BOOL:
    3314                 {
    3315                     pScriptArg->enmType = VDSCRIPTARGTYPE_BOOL;
    3316                     if (!RTStrICmp(pcszValue, "yes") || !RTStrICmp(pcszValue, "on"))
    3317                         pScriptArg->u.fFlag = true;
    3318                     else if (!RTStrICmp(pcszValue, "no") || !RTStrICmp(pcszValue, "off"))
    3319                         pScriptArg->u.fFlag = false;
    3320                     else
    3321                     {
    3322                         RTPrintf("Boolean argument malformed '%s'\n", pcszValue);
    3323                         rc = VERR_INVALID_PARAMETER;
    3324                     }
    3325                     break;
    3326                 }
    3327                 case VDSCRIPTARGTYPE_SIGNED_NUMBER:
    3328                 {
    3329                     pScriptArg->enmType = VDSCRIPTARGTYPE_SIGNED_NUMBER;
    3330                     AssertMsgFailed(("todo\n"));
    3331                     break;
    3332                 }
    3333                 case VDSCRIPTARGTYPE_STRING:
    3334                 {
    3335                     pScriptArg->enmType = VDSCRIPTARGTYPE_STRING;
    3336                     pScriptArg->u.pcszString = pcszValue;
    3337                     break;
    3338                 }
    3339                 case VDSCRIPTARGTYPE_UNSIGNED_NUMBER:
    3340                 {
    3341                     char *pszSuffix = NULL;
    3342 
    3343                     pScriptArg->enmType = VDSCRIPTARGTYPE_UNSIGNED_NUMBER;
    3344                     rc = RTStrToUInt64Ex(pcszValue, &pszSuffix, 10, &pScriptArg->u.u64);
    3345                     if (rc == VWRN_TRAILING_CHARS)
    3346                     {
    3347                         switch (*pszSuffix)
    3348                         {
    3349                             case 'k':
    3350                             case 'K':
    3351                             {
    3352                                 pScriptArg->u.u64 *= _1K;
    3353                                 break;
    3354                             }
    3355                             case 'm':
    3356                             case 'M':
    3357                             {
    3358                                 pScriptArg->u.u64 *= _1M;
    3359                                 break;
    3360                             }
    3361                             case 'g':
    3362                             case 'G':
    3363                             {
    3364                                 pScriptArg->u.u64 *= _1G;
    3365                                 break;
    3366                             }
    3367                             case 't':
    3368                             case 'T':
    3369                             {
    3370                                 pScriptArg->u.u64 *= (uint64_t)1024 * _1G;
    3371                                 break;
    3372                             }
    3373                             default:
    3374                             {
    3375                                 RTPrintf("Invalid size suffix '%s'\n", pszSuffix);
    3376                                 rc = VERR_INVALID_PARAMETER;
    3377                             }
    3378                         }
    3379                         if (rc != VERR_INVALID_PARAMETER)
    3380                             rc = VINF_SUCCESS;
    3381                     }
    3382 
    3383                     break;
    3384                 }
    3385                 case VDSCRIPTARGTYPE_UNSIGNED_RANGE:
    3386                 {
    3387                     char *pszSuffix = NULL;
    3388 
    3389                     pScriptArg->enmType = VDSCRIPTARGTYPE_UNSIGNED_RANGE;
    3390                     rc = RTStrToUInt64Ex(pcszValue, &pszSuffix, 10, &pScriptArg->u.Range.Start);
    3391                     if (rc == VWRN_TRAILING_CHARS)
    3392                     {
    3393                         if (*pszSuffix != '-')
    3394                         {
    3395                             switch (*pszSuffix)
    3396                             {
    3397                                 case 'k':
    3398                                 case 'K':
    3399                                 {
    3400                                     pScriptArg->u.u64 *= _1K;
    3401                                     break;
    3402                                 }
    3403                                 case 'm':
    3404                                 case 'M':
    3405                                 {
    3406                                     pScriptArg->u.u64 *= _1M;
    3407                                     break;
    3408                                 }
    3409                                 case 'g':
    3410                                 case 'G':
    3411                                 {
    3412                                     pScriptArg->u.u64 *= _1G;
    3413                                     break;
    3414                                 }
    3415                                 default:
    3416                                 {
    3417                                     RTPrintf("Invalid size suffix '%s'\n", pszSuffix);
    3418                                     rc = VERR_INVALID_PARAMETER;
    3419                                 }
    3420                             }
    3421                             if (RT_SUCCESS(rc))
    3422                                 pszSuffix++;
    3423                         }
    3424 
    3425                         if (*pszSuffix == '-')
    3426                         {
    3427                             pszSuffix++;
    3428                             rc = RTStrToUInt64Ex(pszSuffix, &pszSuffix, 10, &pScriptArg->u.Range.End);
    3429                             if (rc == VWRN_TRAILING_CHARS)
    3430                             {
    3431                                 switch (*pszSuffix)
    3432                                 {
    3433                                     case 'k':
    3434                                     case 'K':
    3435                                     {
    3436                                         pScriptArg->u.Range.End *= _1K;
    3437                                         break;
    3438                                     }
    3439                                     case 'm':
    3440                                     case 'M':
    3441                                     {
    3442                                         pScriptArg->u.Range.End *= _1M;
    3443                                         break;
    3444                                     }
    3445                                     case 'g':
    3446                                     case 'G':
    3447                                     {
    3448                                         pScriptArg->u.Range.End *= _1G;
    3449                                         break;
    3450                                     }
    3451                                     default:
    3452                                     {
    3453                                         RTPrintf("Invalid size suffix '%s'\n", pszSuffix);
    3454                                         rc = VERR_INVALID_PARAMETER;
    3455                                     }
    3456                                 }
    3457                             }
    3458                         }
    3459                         else
    3460                             rc = VERR_INVALID_PARAMETER;
    3461                     }
    3462                     else
    3463                         rc = VERR_INVALID_PARAMETER;
    3464 
    3465                     if (rc == VERR_INVALID_PARAMETER)
    3466                         RTPrintf("Invalid range format\n");
    3467                     break;
    3468                 }
    3469                 default:
    3470                     AssertMsgFailed(("Invalid script argument type\n"));
    3471             }
    3472 
    3473             if (RT_SUCCESS(rc))
    3474             {
    3475                 pScriptArg->chId = pVDScriptAction->paArgDesc[i].chId;
    3476                 *pfMandatory = !!(pVDScriptAction->paArgDesc[i].fFlags & VDSCRIPTARGDESC_FLAG_MANDATORY);
    3477             }
    3478             break;
    3479         }
    3480     }
    3481 
    3482     if (rc == VERR_NOT_FOUND)
    3483         RTPrintf("Argument '%s' not found\n", pcszName);
    3484 
    3485     return rc;
    3486 }
    3487 
    3488 /**
    3489  * Parses the arguments of a action in the script.
    3490  *
    3491  * @returns IPRT status code.
    3492  *
    3493  * @param psz                Argument string.
    3494  * @param pVDScriptAction    The script action to parses
    3495  *                           arguments for.
    3496  * @param paScriptArgs       Where to store the arguments.
    3497  * @param pcScriptArgs       Where to store the actual number of
    3498  *                           arguments parsed.
    3499  */
    3500 static int tstVDIoScriptArgumentListParse(char *psz, PCVDSCRIPTACTION pVDScriptAction, PVDSCRIPTARG paScriptArgs, unsigned *pcScriptArgs)
    3501 {
    3502     int rc = VINF_SUCCESS;
    3503     unsigned cMandatoryArgsReq = 0;
    3504     unsigned cScriptArgs = 0;
    3505 
    3506     /* Count the number of mandatory arguments first. */
    3507     for (unsigned i = 0; i < pVDScriptAction->cArgDescs; i++)
    3508         if (pVDScriptAction->paArgDesc[i].fFlags & VDSCRIPTARGDESC_FLAG_MANDATORY)
    3509             cMandatoryArgsReq++;
    3510 
    3511     /* One argument is given in the form name=value. */
    3512     *pcScriptArgs = 0;
    3513 
    3514     while (    psz
    3515            && !tstVDIoIsLineEnd(psz))
    3516     {
    3517         const char *pcszName = psz;
    3518 
    3519         psz = tstVDIoScriptSkipUntil(psz, '=');
    3520         if (!tstVDIoIsLineEnd(psz))
    3521         {
    3522             *psz = '\0'; /* Overwrite */
    3523             psz++;
    3524             const char *pcszValue = psz;
    3525 
    3526             psz = tstVDIoScriptSkipNonSpace(psz);
    3527             if (!tstVDIoIsLineEnd(psz))
    3528             {
    3529                 *psz = '\0'; /* Overwrite */
    3530                 psz++;
    3531                 psz = tstVDIoScriptSkipSpace(psz);
    3532             }
    3533 
    3534             pcszValue = tstVDIoScriptSkipSpace((char *)pcszValue);
    3535             if (*pcszValue == '\0')
    3536             {
    3537                 RTPrintf("Value missing for argument '%s'\n", pcszName);
    3538                 rc = VERR_INVALID_STATE;
    3539                 break;
    3540             }
    3541 
    3542             /* We have the name and value pair now. */
    3543             bool fMandatory = false; /* Shut up gcc */
    3544             rc = tstVDIoScriptArgumentParse(pVDScriptAction, pcszName, pcszValue, &paScriptArgs[cScriptArgs], &fMandatory);
    3545             if (RT_SUCCESS(rc))
    3546             {
    3547                 if (fMandatory)
    3548                     cMandatoryArgsReq--;
    3549                 cScriptArgs++;
    3550             }
    3551         }
    3552         else
    3553         {
    3554             RTPrintf("Argument in invalid form\n");
    3555             rc = VERR_INVALID_STATE;
    3556             break;
    3557         }
    3558     }
    3559 
    3560     if (   RT_SUCCESS(rc)
    3561         && cMandatoryArgsReq)
    3562     {
    3563         /* No arguments anymore but there are still mandatory arguments left. */
    3564         RTPrintf("There are %u arguments missing for script action '%s\n", pVDScriptAction->pcszAction);
    3565         rc = VERR_INVALID_STATE;
    3566     }
    3567 
    3568     if (RT_SUCCESS(rc))
    3569         *pcScriptArgs = cScriptArgs;
    3570 
    3571     return rc;
    3572 }
    3573 
    3574 /**
    3575  * Executes the script pointed to by the given stream.
    3576  *
    3577  * @returns IPRT status code.
    3578  *
    3579  * @param pStrm    The stream handle of the script.
    3580  * @param pGlob    Global test data.
    3581  */
    3582 static int tstVDIoScriptExecute(PRTSTREAM pStrm, PVDTESTGLOB pGlob)
    3583 {
    3584     int rc = VINF_SUCCESS;
    3585     char abBuffer[0x1000]; /* Current assumption that a line is never longer than 4096 bytes. */
    3586     PVDSCRIPTARG paScriptArgs = NULL;
    3587     unsigned cScriptArgsMax = 0;
    3588 
    3589     do
    3590     {
    3591         memset(abBuffer, 0, sizeof(abBuffer));
    3592         rc = RTStrmGetLine(pStrm, abBuffer, sizeof(abBuffer));
    3593         if (RT_SUCCESS(rc))
    3594         {
    3595             const char *pcszAction = NULL;
    3596             char *psz = abBuffer;
    3597 
    3598             /* Skip space */
    3599             psz = tstVDIoScriptSkipSpace(psz);
    3600             if (!tstVDIoIsLineEnd(psz))
    3601             {
    3602                 PCVDSCRIPTACTION pVDScriptAction = NULL;
    3603 
    3604                 /* Get the action name. */
    3605                 pcszAction = psz;
    3606 
    3607                 psz = tstVDIoScriptSkipNonSpace(psz);
    3608                 if (!tstVDIoIsLineEnd(psz))
    3609                 {
    3610                     Assert(RT_C_IS_SPACE(*psz));
    3611                     *psz++ = '\0';
    3612                 }
    3613 
    3614                 /* Find the action. */
    3615                 for (unsigned i = 0; i < g_cScriptActions; i++)
    3616                 {
    3617                     if (!RTStrCmp(pcszAction, g_aScriptActions[i].pcszAction))
    3618                     {
    3619                         pVDScriptAction = &g_aScriptActions[i];
    3620                         break;
    3621                     }
    3622                 }
    3623 
    3624                 if (pVDScriptAction)
    3625                 {
    3626                     /* Parse arguments. */
    3627                     if (cScriptArgsMax < pVDScriptAction->cArgDescs)
    3628                     {
    3629                         /* Increase arguments array. */
    3630                         if (paScriptArgs)
    3631                             RTMemFree(paScriptArgs);
    3632 
    3633                         cScriptArgsMax = pVDScriptAction->cArgDescs;
    3634                         paScriptArgs = (PVDSCRIPTARG)RTMemAllocZ(cScriptArgsMax * sizeof(VDSCRIPTARG));
    3635                     }
    3636 
    3637                     if (paScriptArgs)
    3638                     {
    3639                         unsigned cScriptArgs;
    3640 
    3641                         rc = tstVDIoScriptArgumentListParse(psz, pVDScriptAction, paScriptArgs, &cScriptArgs);
    3642                         if (RT_SUCCESS(rc))
    3643                         {
    3644                             /* Execute the handler. */
    3645                             rc = pVDScriptAction->pfnHandler(pGlob, paScriptArgs, cScriptArgs);
    3646                         }
    3647                     }
    3648                     else
    3649                     {
    3650                         RTPrintf("Out of memory while allocating argument array for script action %s\n", pcszAction);
    3651                         rc = VERR_NO_MEMORY;
    3652                     }
    3653                 }
    3654                 else
    3655                 {
    3656                     RTPrintf("Script action %s is not known\n", pcszAction);
    3657                     rc = VERR_NOT_FOUND;
    3658                 }
    3659             }
    3660             /* else empty line, just continue */
    3661         }
    3662     } while(RT_SUCCESS(rc));
    3663 
    3664     if (rc == VERR_EOF)
    3665     {
    3666         RTPrintf("Successfully executed I/O script\n");
    3667         rc = VINF_SUCCESS;
    3668     }
    3669     return rc;
    3670 }
    3671 
    3672 /**
    3673  * Executes the given I/O script.
     2616 * Executes the given I/O script using the new scripting engine.
    36742617 *
    36752618 * @returns nothing.
     
    36802623{
    36812624    int rc = VINF_SUCCESS;
    3682     PRTSTREAM pScriptStrm; /**< Stream of the script file. */
    36832625    VDTESTGLOB GlobTest;   /**< Global test data. */
     2626    void *pvFile = NULL;
     2627    size_t cbFile = 0;
    36842628
    36852629    memset(&GlobTest, 0, sizeof(VDTESTGLOB));
     
    36882632    RTListInit(&GlobTest.ListPatterns);
    36892633
    3690     rc = RTStrmOpen(pcszFilename, "r", &pScriptStrm);
     2634    rc = RTFileReadAll(pcszFilename, &pvFile, &cbFile);
    36912635    if (RT_SUCCESS(rc))
    36922636    {
     2637        char *pszScript = RTStrDupN((char *)pvFile, cbFile);
     2638        RTFileReadAllFree(pvFile, cbFile);
     2639
     2640        AssertPtr(pszScript);
    36932641        /* Init global test data. */
    36942642        GlobTest.VDIfError.pfnError     = tstVDError;
     
    37222670        if (RT_SUCCESS(rc))
    37232671        {
    3724             /* Execute the script. */
    3725             rc = tstVDIoScriptExecute(pScriptStrm, &GlobTest);
    3726             if (RT_FAILURE(rc))
     2672            VDSCRIPTCTX hScriptCtx = NULL;
     2673            rc = VDScriptCtxCreate(&hScriptCtx);
     2674            if (RT_SUCCESS(rc))
    37272675            {
    3728                 RTPrintf("Executing the script stream failed rc=%Rrc\n", rc);
     2676                rc = VDScriptCtxCallbacksRegister(hScriptCtx, g_aScriptActions, g_cScriptActions, &GlobTest);
     2677                AssertRC(rc);
     2678
     2679                rc = VDScriptCtxLoadScript(hScriptCtx, pszScript);
     2680                if (RT_FAILURE(rc))
     2681                {
     2682                    RTPrintf("Loading the script failed rc=%Rrc\n", rc);
     2683                }
     2684                else
     2685                    rc = VDScriptCtxCallFn(hScriptCtx, "main", NULL, 0);
     2686                VDScriptCtxDestroy(hScriptCtx);
    37292687            }
    37302688            VDIoBackendMemDestroy(GlobTest.pIoBackend);
     
    37322690        else
    37332691            RTPrintf("Creating the I/O backend failed rc=%Rrc\n");
    3734 
    3735         RTStrmClose(pScriptStrm);
    37362692    }
    37372693    else
Note: See TracChangeset for help on using the changeset viewer.

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