First, some clarification of terms. By finalize, I don't mean closing a session; I mean writing a lead-out to a CD or DVD in such a way that information can no longer be added to it via the usual means (Roxio, Nero, Windows Explorer, etc.)
I've done a fair amount of research on this. There are some open-source programs like InfraRecorder from which we could draw some inspiration, but they all seem to involve rather elaborate reams of C++ code using IMAPI, which seems like a very low-level way to do things. None of the developers on our team have the C++ or IMAPI expertise to support such a code base.
The most promising resource on the internet appears to be this one, but it doesn't seem to include a finalize function. Here is the code that "writes an image":
public void WriteImage(BurnVerificationLevel verification, bool finalize, bool eject)
{
if (!_recorderLoaded)
throw new InvalidOperationException("LoadMedia must be called first.");
MsftDiscRecorder2 recorder = null;
MsftDiscFormat2Data discFormatData = null;
try
{
recorder = new MsftDiscRecorder2();
recorder.InitializeDiscRecorder(_recorders.SelectedItem.InternalUniqueId);
discFormatData = new MsftDiscFormat2Data
{
Recorder = recorder,
ClientName = ClientName,
ForceMediaToBeClosed = finalize
};
//
// Set the verification level
//
var burnVerification = (IBurnVerification)discFormatData;
burnVerification.BurnVerificationLevel = IMAPI_BURN_VERIFICATION_LEVEL.IMAPI_BURN_VERIFICATION_NONE;
//
// Check if media is blank, (for RW media)
//
object[] multisessionInterfaces = null;
if (!discFormatData.MediaHeuristicallyBlank)
multisessionInterfaces = discFormatData.MultisessionInterfaces;
//
// Create the file system
//
IStream fileSystem;
_CreateImage(recorder, multisessionInterfaces, out fileSystem);
discFormatData.Update += _discFormatWrite_Update;
//
// Write the data
//
try
{
discFormatData.Write(fileSystem);
}
finally
{
if (fileSystem != null) Marshal.FinalReleaseComObject(fileSystem);
}
discFormatData.Update -= _discFormatWrite_Update;
if (eject) recorder.EjectMedia();
}
finally
{
_isWriting = false;
if (discFormatData != null) Marshal.ReleaseComObject(discFormatData);
if (recorder != null) Marshal.ReleaseComObject(recorder);
}
}
The critical section of code seems to be this one:
discFormatData = new MsftDiscFormat2Data
{
Recorder = recorder,
ClientName = ClientName,
ForceMediaToBeClosed = finalize // <-- Here
};
But this isn't a finalize function; it's a function that burns actual data onto a disk. Do you have to actually create a new session to perform a finalization on an existing disk?