LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

problem burning multisession discs

I am attempting to write a LabWindows program that uses the IMAPI2 Active-X libraries to burn recordable CDs.  The program runs fine when I use a blank CD-R, but when I subsequently attempt to burn another session on the same disc, only the files from the first session are visible in Windows.  I can view the files from all the burn sessions using IsoBuster so I know they're present on the disc.

 

I'm using Windows 7 Pro, which should be compatible with all types of media for IMAPI2.  I know the discs are not the problem because using Windows Explorer to do the multisession burn works fine.

 

My code is attached.

 

Rich Ferrara

 

 

#include <userint.h>
#include <imapi2.h>
#include <imapi2error.h>
#include <imapi2fs.h>
#include <ansi_c.h>
#include <toolbox.h>
#include <imapi2fserror.h>
#include "imapi2ActiveX.h"
#include "imapi2FsActiveX.h"
#include "archives_defs.h"

// Master control object for all drives
static CAObjHandle discMaster;
    
// Arrays of drive handles and information (names, letters, media types)
static CAObjHandle *cdDriveHandles;
static char **cdDriveNames;
static char **cdDrivePaths;
static MediaType **cdDriveMedia;
static IMAPI2FSType_IStream cdImageStream;

// Number of recordable drives present in the system
static long numDrives;

int main(void)
{
    CmtThreadFunctionID threadId;
    int status;
    
    InitializeCdDrives();
    
    BurnCd(cdDriveHandles[0], IMAPI2FSConst_IMAPI_MEDIA_TYPE_CDR);
    
    MessagePopup("cd burn", "done");
    
    CleanUpCdDriveMemory();
    
    return 0;
}

int InitializeCdDrives(void)
{
    HRESULT result;
    SAFEARRAY *safeArrayPtr;
    CAObjHandle format;
    VARIANT *varArray;
    MediaType *media;
    size_t numElements;
    long index;
    int i;
    char *str;
    int error = E_CVIAUTO_NO_ERROR;
    
    // Read the number of CD/DVD drives in the system
    errChk(IMAPI2_NewIDiscMaster2 (NULL, 1, LOCALE_NEUTRAL, 0, &discMaster));
    errChk(IMAPI2_IDiscMaster2GetCount (discMaster, NULL, &numDrives));
    
    // Allocate memory to hold lists of CD/DVD drive information
    cdDriveNames   = malloc(numDrives * (int)sizeof(char *));
    cdDriveHandles = malloc(numDrives * (int)sizeof(CAObjHandle));
    cdDrivePaths   = malloc(numDrives * (int)sizeof(char *));
    cdDriveMedia   = malloc(numDrives * (int)sizeof(MediaType *));
    nullChk(cdDriveNames);
    nullChk(cdDriveHandles);
    nullChk(cdDrivePaths);
    nullChk(cdDriveMedia);
    
    for (index=0; index<numDrives; ++index)
    {
        // Read a CD drive device name
        errChk(IMAPI2_IDiscMaster2GetItem (discMaster, NULL, index, 
            &cdDriveNames[index]));
        
        // Set up a handle for this device
        errChk(IMAPI2_NewIDiscRecorder2 (NULL, 1, LOCALE_NEUTRAL, 0, 
            &cdDriveHandles[index]));
        errChk(IMAPI2_IDiscRecorder2InitializeDiscRecorder (
            cdDriveHandles[index], NULL, cdDriveNames[index]));
       
        // Get the device's drive letter
        errChk(IMAPI2_IDiscRecorder2GetVolumePathNames (cdDriveHandles[index],
            NULL, &safeArrayPtr)); 
        errChk(CA_SafeArrayTo1DArrayEx (&safeArrayPtr, CAVT_VARIANT, 0, &varArray, 
            &numElements));
        errChk(CA_VariantGetCString (&varArray[0], &cdDrivePaths[index]));
        CA_FreeMemory(varArray);
        
        // Get the media types supported by this device
        errChk(IMAPI2_NewIDiscFormat2Data (NULL, 1, LOCALE_NEUTRAL, 0,
            &format));
        errChk(IMAPI2_IDiscFormat2DataSetRecorder (format, NULL, 
            cdDriveHandles[index]));
        errChk(IMAPI2_IDiscFormat2DataGetSupportedMediaTypes (format, NULL, 
            &safeArrayPtr));
        errChk(CA_SafeArrayTo1DArrayEx (&safeArrayPtr, CAVT_VARIANT, 0, &varArray,
            &numElements));
        cdDriveMedia[index] = malloc(numElements * (int)sizeof(long));
        media = cdDriveMedia[index];
        for (i=0; i<numElements; ++i)
        {
            errChk(CA_VariantGetLong (&varArray[i], (long *)&media[i])); 
        }
        CA_FreeMemory(varArray);
    }
    
Error:
    return error;
}    
      
int BurnCd(CAObjHandle drive, MediaType media)
{
    IMAPI2FSObj_IFileSystemImageResult resultImage;
    IMAPI2FSObj_IFsiDirectoryItem root;
    enum IMAPI2FSEnum_FsiFileSystems fileSystem;
    CAObjHandle discFormat;
    CAObjHandle image;
    SAFEARRAY *multiSession = NULL;
    VBOOL blank;
    int error = E_CVIAUTO_NO_ERROR;
    
    // Lock the disc drive
    errChk(IMAPI2_IDiscRecorder2AcquireExclusiveAccess (drive, NULL, 
        VTRUE, "RDP-PLATE"));
    
    // Set up the CD file system
    errChk(IMAPI2_NewIDiscFormat2Data (NULL, 1, LOCALE_NEUTRAL, 0, 
        &discFormat));
    errChk(IMAPI2_IDiscFormat2DataSetRecorder (discFormat, NULL, drive));
    errChk(IMAPI2_IDiscFormat2DataSetClientName (discFormat, NULL, 
        "RDP-PLATE"));

    // Set up the disc file system
    errChk(IMAPI2FS_NewIFileSystemImage3 (NULL, 1, LOCALE_NEUTRAL, 0, 
        &image));
   
    // Is the disc blank?   
    errChk(IMAPI2_IDiscFormat2GetMediaPhysicallyBlank (discFormat, NULL,
        &blank));

    if (blank == VTRUE)
    {
        // Set up a new blank file system
        errChk(IMAPI2FS_IFileSystemImage3ChooseImageDefaults (image, 
            NULL, drive));
    }
    else
    {
        // Retrieve the folder structure already on the disc
        errChk(IMAPI2_IDiscFormat2DataGetMultisessionInterfaces (discFormat,
            NULL, &multiSession));
        errChk(IMAPI2FS_IFileSystemImage3SetMultisessionInterfaces (
            image, NULL, multiSession));
        errChk(IMAPI2FS_IFileSystemImage3ImportFileSystem (
            image, NULL, &fileSystem));
    }
    
    // Get the image root
    errChk(IMAPI2FS_IFileSystemImage3GetRoot (image, NULL, &root));

    // Add files
    errChk(IMAPI2FS_IFsiDirectoryItemAddTree (root, NULL, "c:\\rich\\fizz", 
        VTRUE));
    
    // Create the result image and stream
    errChk(IMAPI2FS_IFileSystemImage3CreateResultImage (image, NULL, 
        &resultImage));
    errChk(IMAPI2FS_IFileSystemImageResultGetImageStream (resultImage, 
        NULL, &cdImageStream));
    
    // Burn the disc
    errChk(IMAPI2_IDiscFormat2DataWrite (discFormat, NULL, cdImageStream));
    
    // Unlock the disc drive
    errChk(IMAPI2_IDiscRecorder2ReleaseExclusiveAccess (drive, NULL));
    
Error:
    printf ("cd burn status = %x\n", error);
    return error;
}

void CleanUpCdDriveMemory(void)
{
    int index;
    
    for (index=0; index<numDrives; ++index)
    {
        free(cdDriveMedia[index]);
    }
    free(cdDriveMedia);
    free(cdDrivePaths);
    free(cdDriveHandles);
    free(cdDriveNames);
}

 

 

0 Kudos
Message 1 of 4
(3,533 Views)

Hello richferrara,

 

Unfortunately NI did not release this library, but I would definitely advise you to contact whoever did release this library and ask them for some example code or guidance.  As well, I would check google for some example code in C. 

 

Thanks and good luck!

 

Regards,

Shawn S. | NIC
Instrument Driver/IVI PSE
National Instruments
0 Kudos
Message 2 of 4
(3,516 Views)

Do you know who released it?

0 Kudos
Message 3 of 4
(3,514 Views)

Hello again richferrara,

 

I believe this will help you further: 

 

Image Mastering API by Microsoft

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366450%28v=vs.85%29.aspx

 

Thanks and good luck!

Regards,

Shawn S. | NIC
Instrument Driver/IVI PSE
National Instruments
0 Kudos
Message 4 of 4
(3,512 Views)