IMAPIv2 for Vista
Posted: Sat Jan 12, 2008 12:12 am
Yet another IMAPIv2 thing for Vista (and XP SP2 if you have the KB update - see remarks in code). The commented items in the Interface's are some things i'm not sure of for full implementation so if anyone has suggestions or ideas....
Converted from msdn VB script example:
http://msdn2.microsoft.com/en-us/library/aa364817.aspx
With help from the code by bingo at:
http://www.purebasic.fr/english/viewtop ... iscmaster2
Anyway, here ya go:
Converted from msdn VB script example:
http://msdn2.microsoft.com/en-us/library/aa364817.aspx
With help from the code by bingo at:
http://www.purebasic.fr/english/viewtop ... iscmaster2
Anyway, here ya go:
Code: Select all
; see imapi2sample.cpp in sdk
; folder to .iso Vista and winXP SP2
; On XP sp2 you have To install KB932716 (Image Mastering API v2.0) firstVista And winXP SP2 With
; For testing edit the line:
;
; isofile.s = "c:\tmp\mein.iso"
; foldertoiso.s = "c:\temp\"
; folder To iso created by bingo - http://www.purebasic.fr/english/viewtopic.php?t=29757
Import "shlwapi.lib"
SHCreateStreamOnFileEx(pszFile.p-unicode,grfMode.l,dwAttributes.l,fCreate.b,pstmTemplate.l,ppstm.l);
EndImport
#STGM_SHARE_DENY_NONE=$00000040
#STGM_READ=$00000000
#STGM_WRITE = 1
#STGM_CREATE = $1000
#STATFLAG_NONAME = 0
#adFileTypeBinary = 1
Enumeration
#FsiFileSystemNone = 0
#FsiFileSystemISO9660 = 1
#FsiFileSystemJoliet = 2
#FsiFileSystemUDF = 4
;#FsiFileSystemUnknown = 1073741824
#FsiFileSystemUnknown = $40000000
EndEnumeration
Enumeration ; EmulationType
#EmulationNone = 0
#Emulation12MFloppy = 1
#Emulation144MFloppy = 2
#Emulation288MFloppy = 3
#EmulationHardDisk = 4
EndEnumeration
Enumeration ;_#IMAPI_MEDIA_PHYSICAL_TYPE
#IMAPI_MEDIA_TYPE_UNKNOWN = 0
#IMAPI_MEDIA_TYPE_CDROM = $1
#IMAPI_MEDIA_TYPE_CDR = $2
#IMAPI_MEDIA_TYPE_CDRW = $3
#IMAPI_MEDIA_TYPE_DVDROM = $4
#IMAPI_MEDIA_TYPE_DVDRAM = $5
#IMAPI_MEDIA_TYPE_DVDPLUSR = $6
#IMAPI_MEDIA_TYPE_DVDPLUSRW = $7
#IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER = $8
#IMAPI_MEDIA_TYPE_DVDDASHR = $9
#IMAPI_MEDIA_TYPE_DVDDASHRW = $a
#IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER = $b
#IMAPI_MEDIA_TYPE_DISK = $c
#IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER = $0D
#IMAPI_MEDIA_TYPE_HDDVDROM = $0E
#IMAPI_MEDIA_TYPE_HDDVDR = $0F
#IMAPI_MEDIA_TYPE_HDDVDRAM = $10
#IMAPI_MEDIA_TYPE_BDROM = $11
#IMAPI_MEDIA_TYPE_BDR = $12
#IMAPI_MEDIA_TYPE_BDRE = $13
#IMAPI_MEDIA_TYPE_MAX = $13
EndEnumeration
Interface IBootOptions Extends IDispatch
get_BootImage(dispidMember.l)
get_Manufacturer(dispidMember.l)
put_Manufacturer(dispidMember.p-bstr)
get_PlatformId(dispidMember.l)
put_PlatformId(dispidMember.l)
get_Emulation(dispidMember.l)
put_Emulation(dispidMember.l)
get_ImageSize(dispidMember.l)
AssignBootImage(newVal.l)
EndInterface
Interface IDiscMaster2 Extends IDispatch
get__NewEnum(a)
;get__NewEnum(ppunk.IEnumVARIANT) ; IEnumVARIANT** ppunk - need IEnumVARIANT??
get_Item(index,value) ; [in]LONG index, [out]BSTR* value
;get_Item(index) ; [in]LONG index, [out]BSTR* value
get_Count(a.l)
get_IsSupportedEnvironment(value.l)
EndInterface
Interface IDiscRecorder2 Extends IDispatch
EjectMedia()
CloseTray()
AcquireExclusiveAccess(a.l,b.s)
;AcquireExclusiveAccess(a.l,b.p-bstr) ;??
ReleaseExclusiveAccess()
DisableMcn()
EnableMcn()
InitializeDiscRecorder(a.l)
get_ActiveDiscRecorder(value.p-bstr)
get_VendorId(value)
get_ProductId(value.p-bstr)
get_ProductRevision(value.p-bstr)
get_VolumeName(value.p-bstr)
get_VolumePathNames(a) ;??
;get_VolumePathNames(value.SAFEARRAY) ; ???
get_DeviceCanLoadMedia(a.l)
get_LegacyDeviceNumber(a.l)
get_SupportedFeaturePages(a)
;get_SupportedFeaturePages(value.SAFEARRAY) ;??
get_CurrentFeaturePages(a)
;get_CurrentFeaturePages(value.SAFEARRAY) ;??
get_SupportedProfiles(a)
;get_SupportedProfiles(value.SAFEARRAY) ;??
get_CurrentProfiles(a)
;get_CurrentProfiles(value.SAFEARRAY) ;??
get_SupportedModePages(a)
;get_SupportedModePages(value.SAFEARRAY) ;??
;get_ExclusiveAccessOwner(a)
get_ExclusiveAccessOwner(value.p-bstr)
EndInterface
Interface IFileSystemImage Extends IDispatch
get_Root(dispidMember.l)
get_SessionStartBlock(dispidMember.l)
put_SessionStartBlock(dispidMember.l)
get_FreeMediaBlocks(dispidMember.l)
put_FreeMediaBlocks(dispidMember.l)
SetMaxMediaBlocksFromDevice(discRecorder.l)
get_UsedBlocks(discRecorder.l)
get_VolumeName(discRecorder.l)
put_VolumeName(discRecorder.p-bstr)
get_ImportedVolumeName(discRecorder.l)
get_BootImageOptions(discRecorder.l)
put_BootImageOptions(discRecorder.l)
get_FileCount(discRecorder.l)
get_DirectoryCount(discRecorder.l)
get_WorkingDirectory(discRecorder.l)
put_WorkingDirectory(discRecorder.p-bstr)
get_ChangePoint(discRecorder.l)
get_StrictFileSystemCompliance(discRecorder.l)
put_StrictFileSystemCompliance(discRecorder.w)
get_UseRestrictedCharacterSet(discRecorder.l)
put_UseRestrictedCharacterSet(discRecorder.w)
get_FileSystemsToCreate(discRecorder.l)
put_FileSystemsToCreate(discRecorder.l)
get_FileSystemsSupported(discRecorder.l)
put_UDFRevision(discRecorder.l)
get_UDFRevision(discRecorder.l)
get_UDFRevisionsSupported(discRecorder.l)
ChooseImageDefaults(discRecorder.l)
ChooseImageDefaultsForMediaType(value.l)
put_ISO9660InterchangeLevel(value.l)
get_ISO9660InterchangeLevel(value.l)
get_ISO9660InterchangeLevelsSupported(value.l)
CreateResultImage(a.l)
Exists(FullPath.p-bstr)
;CalculateDiscIdentifier() ;<<<<<<<<<<<<<<<<<
CalculateDiscIdentifier(discIdentifier.p-bstr)
IdentifyFileSystemsOnDisc(discRecorder.l)
GetDefaultFileSystemForImport(fileSystems.l)
;ImportFileSystem() ;<<<<<<<<<<<<<<<<<
ImportFileSystem(importedFileSystem.l)
ImportSpecificFileSystem(fileSystemToUse.l)
RollbackToChangePoint(ChangePoint.l)
LockInChangePoint()
CreateDirectoryItem(Name.p-bstr)
CreateFileItem(Name.p-bstr)
get_VolumeNameUDF(Name.l)
get_VolumeNameJoliet(Name.l)
get_VolumeNameISO9660(Name.l)
get_StageFiles(Name.l)
put_StageFiles(Name.w)
get_MultisessionInterfaces(Name.l)
put_MultisessionInterfaces(Name.l)
EndInterface
Interface IFileSystemImage2 Extends IFileSystemImage
get_BootImageOptionsArray(pVal.l)
put_BootImageOptionsArray(newVal.l)
EndInterface
Interface IFileSystemImageResult Extends IDispatch
get_ImageStream(dispidMember.l)
get_ProgressItems(dispidMember.l)
get_TotalBlocks(dispidMember.l)
get_BlockSize(dispidMember.l)
get_DiscId(dispidMember.l)
EndInterface
Interface IDiscFormat2 Extends IDispatch
IsRecorderSupported(recorder.l, value.l) ; [in]IDiscRecorder2* recorder, [out]VARIANT_BOOL* value
IsCurrentMediaSupported(recorder.l, value.l) ; [in]IDiscRecorder2* recorder, [out]VARIANT_BOOL* value
get_MediaPhysicallyBlank(value.l) ; [out]VARIANT_BOOL* value
get_MediaHeuristicallyBlank(value.l) ; [out]VARIANT_BOOL* value
get_SupportedMediaTypes(value.l) ; [out]SAFEARRAY* value
EndInterface
Interface IDiscFormat2Erase Extends IDiscFormat2
put_Recorder(value) ;[in]IDiscRecorder2* value - value = An IDiscRecorder2 Interface that identifies the recording device To use in the erase operation
get_Recorder(value) ; [out]IDiscRecorder2** value - value = An IDiscRecorder2 Interface that identifies the recording device To use in the erase operation
put_FullErase(value) ; [in]VARIANT_BOOL value - value = #VARIANT_TRUE to fully erase the disc by overwriting the entire medium at least once. Set #VARIANT_FALSE To
;overwrite the directory tracks, but Not entire disc. #VARIANT_FALSE requires less time To perform than the full erase option. The Default is VARIANT_FALSE.
get_FullErase(value) ;[out]VARIANT_BOOL* value - value = #VARIANT_TRUE if the erase operation fully erases the disc by overwriting the entire medium at least once.
; #VARIANT_FALSE If the erase operation overwrites the directory tracks, but Not the entire disc. This option requires less time To perform than the full erase option
;this is the quick erase
get_CurrentPhysicalMediaType(value) ; [out]IMAPI_MEDIA_PHYSICAL_TYPE* value - see the IMAPI_MEDIA_PHYSICAL_TYPE enumeration type
put_ClientName(value.p-bstr) ; [in]BSTR value
get_ClientName(value) ; [out]BSTR* value
EraseMedia()
EndInterface
Interface IDiscFormat2Data Extends IDiscFormat2
put_Recorder(Recorder.l)
get_Recorder(Recorder.l)
put_BufferUnderrunFreeDisabled(Recorder.w)
get_BufferUnderrunFreeDisabled(Recorder.l)
put_PostgapAlreadyInImage(Recorder.w)
get_PostgapAlreadyInImage(Recorder.l)
get_CurrentMediaStatus(Recorder.l)
get_WriteProtectStatus(Recorder.l)
get_TotalSectorsOnMedia(Recorder.l)
get_FreeSectorsOnMedia(Recorder.l)
get_NextWritableAddress(Recorder.l)
get_StartAddressOfPreviousSession(Recorder.l)
get_LastWrittenAddressOfPreviousSession(Recorder.l)
put_ForceMediaToBeClosed(Recorder.w)
get_ForceMediaToBeClosed(value.l)
put_DisableConsumerDvdCompatibilityMode(Recorder.w)
get_DisableConsumerDvdCompatibilityMode(Recorder.l)
get_CurrentPhysicalMediaType(Recorder.l)
put_ClientName(Recorder.p-bstr)
get_ClientName(Recorder.p-bstr)
get_RequestedWriteSpeed(Recorder.l)
get_RequestedRotationTypeIsPureCAV(Recorder.l)
get_CurrentWriteSpeed(Recorder.l)
get_CurrentRotationTypeIsPureCAV(Recorder.l)
get_SupportedWriteSpeeds(Recorder.l)
get_SupportedWriteSpeedDescriptors(Recorder.l)
put_ForceOverwrite(Recorder.w)
get_ForceOverwrite(Recorder.l)
get_MultisessionInterfaces(Recorder.l)
Write(Data_.l)
CancelWrite()
SetWriteSpeed(RequestedSectorsPerSecond.l,RotationTypeIsPureCAV.w)
EndInterface
Interface IFsiItem Extends IDispatch
get_Name(pVal.l)
get_FullPath(pVal.l)
get_CreationTime(pVal.l)
put_CreationTime(newVal.l)
get_LastAccessedTime(pVal.l)
put_LastAccessedTime(newval.l)
get_LastModifiedTime(pVal.l)
put_LastModifiedTime(newVal.l)
get_IsHidden(pVal.l)
put_IsHidden(newVal.l)
FileSystemName(fileSystem.l, pVal.l)
FileSystemPath(fileSystem.l, pVal.l)
EndInterface
Interface IFsiDirectoryItem Extends IFsiItem
get__NewEnum(fileSystem.l)
get_Item(path.p-bstr)
get_Count(path.l)
get_EnumFsiItems(path.l)
AddDirectory(path.p-bstr)
AddFile(path.p-bstr,fileData.l)
AddTree(sourceDirectory.p-bstr,includeBaseDirectory.w)
Add(Item.l)
Remove(path.p-bstr)
RemoveTree(path.p-bstr)
EndInterface
Interface IFsiFileItem Extends IFsiItem
get_DataSize(pVal.l)
get_DataSize32BitLow(pVal.l)
get_DataSize32BitHigh(pVal.l)
get_Data(pVal.l)
put_Data(newVal.l)
EndInterface
pp.variant
pp\vt = #VT_BSTR
Index = 0 ; only one drive at this time, first drive at index 0
Path$ = "C:\somefolder"
Volume_Name$ = "My_VOLUME_NAME"
Type_File_Sys.l = #FsiFileSystemJoliet
burnstream.IStream ; stream
CreateStreamOnHGlobal_(0,#True,@burnstream) ; create the stream
CoInitialize_(0)
;Create a DiscMaster2 object to connect to optical drives
If CoCreateInstance_(?CLSID_MsftDiscMaster2,0,1,?IID_IDiscMaster2,@DiscMaster.IDiscMaster2) = 0
; Create a DiscRecorder object for the specified burning device
If CoCreateInstance_(?CLSID_MsftDiscRecorder2,0,1,?IID_IDiscRecorder2,@Recorder.IDiscRecorder2) = 0
;pp\bstrval contains the uniqueId referenced at msdn example
DiscMaster\get_Item(Index,@pp\bstrval) ; we find our drive - enumerate for all drives
Recorder\InitializeDiscRecorder(pp\bstrval) ;init our selected drive
;Create a new file system image And retrieve root directory / create an image stream for a specified directory
If CoCreateInstance_(?CLSID_MsftFileSystemImage,0,1,?IID_IFileSystemImage,@FSIOBJ.IFileSystemImage) = 0
FSIOBJ\put_FreeMediaBlocks(0) ;infinite number of blocks = 0 - not in msdn example, I added
FSIOBJ\put_FileSystemsToCreate(Type_File_Sys) ; not in msdn example, I added
FSIOBJ\put_VolumeName(Volume_Name$) ; not in msdn example, I added
FSIOBJ\get_root(@DIROBJ.IFsiDirectoryItem)
;create the new disc format and set the recorder
If CoCreateInstance_(?CLSID_MsftDiscFormat2Data,0,1,?IID_IDiscFormat2Data,@dataWriter.IDiscFormat2Data) = 0
dataWriter\put_Recorder(Recorder) ; set the recorder
dataWriter\put_ClientName("IMAPIv2") ; the client name
dataWriter\SetWriteSpeed($FFFFFFFF, #VARIANT_FALSE) ; not in msdn example, I added
FSIOBJ\ChooseImageDefaults(Recorder)
; Add the directory and its contents to the file system
DIROBJ\AddTree(Path$, #VARIANT_FALSE) ; change #VARIANT_FALSE to #VARIANT_TRUE to include the root folder
; Create an image from the file system
FSIOBJ\CreateResultImage(@result.IFileSystemImageResult)
result\get_ImageStream(@burnstream)
;Write stream to disc using the specified recorder
;put_ForceMediaToBeClosed causes the CD\DVD to be closed
dataWriter\put_ForceMediaToBeClosed(#VARIANT_TRUE) ; this has to come before the write to tell it what to do when the burn is complete
dataWriter\write(burnstream)
EndIf
EndIf
EndIf
EndIf
Recorder\EjectMedia() ;eject the tray
; release stuff and clean up
FSIOBJ\Release()
DIROBJ\Release()
DiscMaster\Release()
Recorder\Release()
dataWriter\Release()
burnstream\Release()
CoUninitialize_()
End ; finished
DataSection
CLSID_BootOptions:
Data.l $2C941FCE
Data.w $975B,$59BE
Data.b $A9,$60,$9A,$2A,$26,$28,$53,$A5
CLSID_MsftFileSystemImage:
Data.l $2C941FC5
Data.w $975B,$59BE
Data.b $A9,$60,$9A,$2A,$26,$28,$53,$A5
CLSID_MsftDiscMaster2:
Data.l $2735412E
Data.w $7F64,$5B0F
Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
CLSID_MsftDiscRecorder2:
Data.l $2735412D
Data.w $7F64,$5B0F
Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
CLSID_MsftDiscFormat2Data:
Data.l $2735412A
Data.w $7F64,$5B0F
Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
CLSID_MsftDiscFormat2Erase:
Data.l $2735412B
Data.w $7F64,$5B0F
Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
IID_IBootOptions:
Data.l $2C941FD4
Data.w $975B,$59BE
Data.b $A9,$60,$9A,$2A,$26,$28,$53,$A5
IID_IFileSystemImage:
Data.l $2C941FE1
Data.w $975B,$59BE
Data.b $A9,$60,$9A,$2A,$26,$28,$53,$A5
IID_IDiscMaster2:
Data.l $27354130
Data.w $7F64,$5B0F
Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
IID_IDiscRecorder2:
Data.l $27354133
Data.w $7F64,$5B0F
Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
IID_IDiscFormat2Data:
Data.l $27354153
Data.w $9F64,$5B0F
Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
IID_IDiscFormat2Erase:
Data.l $27354156
Data.w $8F64,$5B0F
Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
EndDataSection