Page 2 of 4

Posted: Wed Jan 16, 2008 4:42 pm
by harff182
OK, sometimes even a dummy like me gets a flash of inspiration:

Code: Select all

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 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.p-bstr)
  get_VendorId(value)
  get_ProductId(value)
  get_ProductRevision(value)
  ;get_VolumeName(value.p-bstr)
  get_VolumeName(value)
  get_VolumePathNames(value) ;??
  ;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)
EndInterface

Interface IDiscFormat2 Extends IDispatch
  IsRecorderSupported(recorder.l, value.l)
  IsCurrentMediaSupported(recorder.l, value.l)
  get_MediaPhysicallyBlank(value.l)
  get_MediaHeuristicallyBlank(value.l)
  get_SupportedMediaTypes(value.l)
EndInterface

Interface IDiscFormat2Erase Extends IDiscFormat2
  put_Recorder(value)
  get_Recorder(value)
  put_FullErase(value)
  get_FullErase(value)
  get_CurrentPhysicalMediaType(value)
  put_ClientName(value.p-bstr)
  get_ClientName(value)
  EraseMedia()
EndInterface

ProcedureDLL.s Uni2Ansi(unicodestr.l) ; Converts Unicode to normal (Ansi) string
  lenA = WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, 0, 0, 0, 0);
  ansistr.s = Space(lenA)
  If (lenA > 0)
    WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, @ansistr, lenA, 0, 0);
  EndIf
  ProcedureReturn ansistr
EndProcedure

pp.variant
pp\vt = #VT_BSTR

CoInitialize_(0)
CoCreateInstance_(?CLSID_MsftDiscMaster2,0,1,?IID_IDiscMaster2,@DiscMaster.IDiscMaster2)
DiscMaster\get_Count(@count)


For x = 0 To count

  If x = count
    Break
  EndIf
  
  DiscMaster\get_Item(x,@pp\bstrval)
   
  CoCreateInstance_(?CLSID_MsftDiscRecorder2,0,1,?IID_IDiscRecorder2,@Recorder.IDiscRecorder2)
  Recorder\InitializeDiscRecorder(pp\bstrval)
   
  CoCreateInstance_(?CLSID_MsftDiscFormat2Erase,0,1,?IID_IDiscFormat2Erase,@Format.IDiscFormat2Erase)
  Format\put_Recorder(Recorder)
  
  DiscMaster\get_Item(x,@pp\bstrval)
  Recorder\InitializeDiscRecorder(pp\bstrval)
  Debug "drive:       " +Str(x) +" is ID: " +Uni2Ansi(pp\bstrval)
  
  Recorder\get_VendorId(@pp\bstrval)
  Debug "vendor:      " +Uni2Ansi(pp\bstrval)
  
  Recorder\get_ProductId(@pp\bstrval)
  Debug "ProductID:   "+Uni2Ansi(pp\bstrval)
  
  Recorder\get_ProductRevision(@pp\bstrval)
  Debug "Revision:    "+Uni2Ansi(pp\bstrval)
  
  Recorder\get_VolumeName(@pp\bstrval)
  Debug "VolumeName:  " +Uni2Ansi(pp\bstrval)
  
  Recorder\get_VolumePathNames(@pp\bstrval) ;;;<<<<< this doesn't work yet, gotta work out a SAFEARRAY thing first
  Debug "VplPathNames " +Uni2Ansi(pp\bstrval)
   
  Debug " "
    
  med_type = Format\get_CurrentPhysicalMediaType(@mediaType)
           
    Case #IMAPI_MEDIA_TYPE_UNKNOWN
    Debug "Media Type is Unknown or no media loaded"
     
    Case #IMAPI_MEDIA_TYPE_CDROM
    Debug "Media Type is a CD-ROM (or burned CD-R)"
     
    Case #IMAPI_MEDIA_TYPE_CDR
    Debug "Media Type is CD-R"
     
    Case #IMAPI_MEDIA_TYPE_CDRW
    Debug "Media Type is CD-R/W"
     
    Case #IMAPI_MEDIA_TYPE_DVDROM
    Debug "Media Type is a DVD-ROM (or a burned DVD-R)"
     
    Case #IMAPI_MEDIA_TYPE_DVDRAM
    Debug "Media Type is DVD-RAM"
     
    Case #IMAPI_MEDIA_TYPE_DVDPLUSR
    Debug "Media Type is DVD+R"
     
    Case #IMAPI_MEDIA_TYPE_DVDPLUSRW
    Debug "Media Type is DVD+RW"
     
    Case #IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER
    Debug "Media Type is DVD+R DL"
    
    Case #IMAPI_MEDIA_TYPE_DVDDASHR
    Debug "Media Type is DVD-R"
    
    Case #IMAPI_MEDIA_TYPE_DVDDASHRW
    Debug "Media Type is DVD-RW"
    
    Case #IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER
    Debug "Media Type is DVD-R DL"
    
    Case #IMAPI_MEDIA_TYPE_DISK
    Debug "Media Type is Disk"
    
    Case #IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER
    Debug "Media Type is DVD+RW DL"
    
    Case #IMAPI_MEDIA_TYPE_HDDVDROM
    Debug "Media Type is HD DVD-ROM"
    
    Case #IMAPI_MEDIA_TYPE_HDDVDR
    Debug "Media Type is HD DVD-R"
    
    Case #IMAPI_MEDIA_TYPE_HDDVDRAM
    Debug "Media Type is HD DVD-RAM"
    
    Case #IMAPI_MEDIA_TYPE_BDROM
    Debug "Media Type is BD-ROM"
    
    Case #IMAPI_MEDIA_TYPE_BDR
    Debug "Media Type is BD-R"
    
    Case #IMAPI_MEDIA_TYPE_BDRE
    Debug "Media Type is BD-RE"
   
  EndSelect
  Debug ""
Next x

DiscMaster\Release()
Recorder\Release()   
Format\Release()

CoUninitialize_()
       
End


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 

with this output:
Debugger wrote:drive: 0 is ID: \\?\ide#cdromhl-dt-st_dvdram_gsa-4163b_______________a106____#334b354333313242313020322020202020202020#{53f56308-b6bf-11d0-94f2-00a0c91efb8b}
vendor: HL-DT-ST
ProductID: DVDRAM GSA-4163B
Revision: A106
VolumeName: \\?\Volume{fcfbbcce-478a-11dc-bd62-806d6172696f}\
VolPathNames ?

Media Type is DVD-ROM

drive: 1 is ID: \\?\ide#cdromtsstcorp_cd#dvdw_sh-s182d_______________sb06____#5&39971a7a&0&0.1.0#{53f56308-b6bf-11d0-94f2-00a0c91efb8b}
vendor: TSSTcorp
ProductID: CD/DVDW SH-S182D
Revision: SB06
VolumeName: \\?\Volume{fcfbbccd-478a-11dc-bd62-806d6172696f}\
VolPathNames ?

Media Type is CD-R/W


@SFSxOI
I left in all commented parts, since I don't know, what you still need to go on.
Maybe you also find a way to show "real" VolumeName of the medium, e.g. "imapi_test" beside the VolumePathNames :wink:

Big thanks 'til here... scholly

Posted: Wed Jan 16, 2008 10:16 pm
by SFSxOI
I do have another way using WMI but my goal here is to use only IMAPI if at all possible, so the line:

Code: Select all

Recorder\get_VolumePathNames(@pp\bstrval) ;;;<<<<< this doesn't work yet, gotta work out a SAFEARRAY thing first 
dosn;t work yet because it's associated with SAFEARRAY and i'm still trying to work that out. Hopefully I will have it done soon. Been doing a lot of research and learned a lot, but SAFEARRAY is a PITA! :)

Posted: Wed Jan 16, 2008 10:38 pm
by harff182
Have you had a search in the German Forum ?

You may find somthing interresting starting there:

http://www.purebasic.fr/german/viewtopic.php?t=7410
http://www.purebasic.fr/german/viewtopi ... 26&start=7
http://www.purebasic.fr/german/viewtopi ... 1&start=39

hth... scholly

Posted: Thu Jan 17, 2008 5:24 am
by SFSxOI
removed code from this post - see below

Posted: Thu Jan 17, 2008 4:21 pm
by harff182
SFSxOI wrote: BTW, I don't see how the code you posted works, there is no SELECT for the case and what you posted does not work correctly here.
Your also using old code, see the more recent version below.
hm... no idea where I lost that SELECT :?
And it might be a good idea, to put some kind of version-info as comment into every new code ;)

Code: Select all

; IMAPI2-usage by SFSxOI
; using Windows Vista Ultimate and PB 4.??
; Version 1.05 (17 Jan 2008 5:24:34)
SFSxOI wrote:This code works here just fine for 2 drives on Windows Vista Ultimate:
Sorry I can't understand why. Can you please post your debug-output ?
SFSxOI wrote:harff, you can see the changes from the original by the commented out functions. Try it out and see if it works oK now.
As always, the Uni2Ansi() is missing. What Version of PB are you using ?
Using the variable "count" insted of "x" forces "drive: 2 is ID:....", but I don't have a third optical !
And all output for both DVD-writers are identical, even though they and the media inside are not !

BTW, you're not from Europe, are you? Times of working with PB seem very different for the both of us :?

[Edit 1, at 17 Jan 2008 22:14:00 GMT +1]
Back to 'work':


I had to change the code the following way to make it work like I expect it to work with XPHome SP2, PB 4.10 an two DVD-Writers:

Code: Select all

; IMAPI2-usage by SFSxOI
; using Windows Vista Ultimate and PB 4.??
; Version 17 Jan 2008 5:24:34)
;
; changed by harff182 
; for XP Home SP2 and PB 4.10
; at 17 Jan 2008 22:08:00 GMT +1


Enumeration ; _#IMAPI_PROFILE_TYPE
  #IMAPI_PROFILE_TYPE_INVALID = 0
  #IMAPI_PROFILE_TYPE_NON_REMOVABLE_DISK = 1
  #IMAPI_PROFILE_TYPE_REMOVABLE_DISK = 2
  #IMAPI_PROFILE_TYPE_MO_ERASABLE = 3
  #IMAPI_PROFILE_TYPE_MO_WRITE_ONCE = 4
  #IMAPI_PROFILE_TYPE_AS_MO = 5
  #IMAPI_PROFILE_TYPE_CDROM = 8
  #IMAPI_PROFILE_TYPE_CD_RECORDABLE = 9
  #IMAPI_PROFILE_TYPE_CD_REWRITABLE = 10
  #IMAPI_PROFILE_TYPE_DVDROM = 16
  #IMAPI_PROFILE_TYPE_DVD_DASH_RECORDABLE = 17
  #IMAPI_PROFILE_TYPE_DVD_RAM = 18
  #IMAPI_PROFILE_TYPE_DVD_DASH_REWRITABLE = 19
  #IMAPI_PROFILE_TYPE_DVD_DASH_RW_SEQUENTIAL = 20
  #IMAPI_PROFILE_TYPE_DVD_DASH_R_DUAL_SEQUENTIAL = 21
  #IMAPI_PROFILE_TYPE_DVD_DASH_R_DUAL_LAYER_JUMP = 22
  #IMAPI_PROFILE_TYPE_DVD_PLUS_RW = 26
  #IMAPI_PROFILE_TYPE_DVD_PLUS_R = 27
  #IMAPI_PROFILE_TYPE_DVD_PLUS_RW_DUAL = 42
  #IMAPI_PROFILE_TYPE_DVD_PLUS_R_DUAL = 43
  #IMAPI_PROFILE_TYPE_BD_ROM = 64
  #IMAPI_PROFILE_TYPE_BD_R_SEQUENTIAL = 65
  #IMAPI_PROFILE_TYPE_BD_R_RANDOM_RECORDING = 66
  #IMAPI_PROFILE_TYPE_BD_REWRITABLE = 67
  #IMAPI_PROFILE_TYPE_HD_DVD_ROM = 80
  #IMAPI_PROFILE_TYPE_HD_DVD_RECORDABLE = 81
  #IMAPI_PROFILE_TYPE_HD_DVD_RAM = 82
  #IMAPI_PROFILE_TYPE_NON_STANDARD = 65535
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 = 10
  #IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER = 11
  #IMAPI_MEDIA_TYPE_DISK = 12
  #IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER = 13
  #IMAPI_MEDIA_TYPE_HDDVDROM = 14
  #IMAPI_MEDIA_TYPE_HDDVDR = 15
  #IMAPI_MEDIA_TYPE_HDDVDRAM = 16
  #IMAPI_MEDIA_TYPE_BDROM = 17
  #IMAPI_MEDIA_TYPE_BDR = 18
  #IMAPI_MEDIA_TYPE_BDRE = 19
  #IMAPI_MEDIA_TYPE_MAX = 19
EndEnumeration

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_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)
  get_VendorId(value)
  get_ProductId(value)
  get_ProductRevision(value)
  get_VolumeName(value)
  get_VolumePathNames(value) ;??
  ;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)
EndInterface

Interface IDiscFormat2 Extends IDispatch
  IsRecorderSupported(recorder.l, value.l)
  IsCurrentMediaSupported(recorder.l, value.l)
  get_MediaPhysicallyBlank(value.l)
  get_MediaHeuristicallyBlank(value.l)
  get_SupportedMediaTypes(value.l)
EndInterface

Interface IDiscFormat2Erase Extends IDiscFormat2
  put_Recorder(value)
  get_Recorder(value)
  put_FullErase(value)
  get_FullErase(value)
  get_CurrentPhysicalMediaType(value)
  put_ClientName(value.p-bstr)
  get_ClientName(value)
  EraseMedia()
EndInterface

Structure SAFEARRAYBOUND
  cElements.L  ; # of elements in the array dimension
  lLbound.L    ; Lower bounds of the array dimension
EndStructure

Structure SAFEARRAY
  cDims.W
  fFeatures.W
  cbElements.L
  cLocks.L
  pvData.L
  rgsabound.SAFEARRAYBOUND[60]
EndStructure

Procedure.S GetVariantString(*Variant.VARIANT)
  Protected String.S = ""

  If VariantChangeType_(*Variant, *Variant, 0, #VT_BSTR) = #S_OK
    String = PeekS(*Variant\bstrVal, -1, #PB_Unicode)
    VariantClear_(*Variant)
  Else
    Debug "VariantChangeType() failed!"
  EndIf

  ProcedureReturn String 
EndProcedure

ProcedureDLL.s ax_Uni2Ansi(unicodestr.l) ; Converts Unicode to normal (Ansi) string
  lenA = WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, 0, 0, 0, 0);
  ansistr.s = Space(lenA)
  If (lenA > 0)
    WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, @ansistr, lenA, 0, 0);
  EndIf
  ProcedureReturn ansistr
EndProcedure

pp.variant
pp\vt = #VT_BSTR

Variant.VARIANT
*VariantArray.SAFEARRAY
     
CoInitialize_(0)
CoCreateInstance_(?CLSID_MsftDiscMaster2,0,1,?IID_IDiscMaster2,@DiscMaster.IDiscMaster2)
DiscMaster\get_Count(@count)
;DiscMaster\get_Item(Index,@pp\bstrval)
   
For x = 0 To count

  CoCreateInstance_(?CLSID_MsftDiscRecorder2,0,1,?IID_IDiscRecorder2,@Recorder.IDiscRecorder2)
  ;Recorder\InitializeDiscRecorder(pp\bstrval)
   
  CoCreateInstance_(?CLSID_MsftDiscFormat2Erase,0,1,?IID_IDiscFormat2Erase,@Format.IDiscFormat2Erase)
  Format\put_ClientName("hello")
  ;Format\put_Recorder(Recorder)

  If x = count
    Break
  EndIf
  ;Recorder\InitializeDiscRecorder(pp\bstrval)
  DiscMaster\get_Item(x,@pp\bstrval)
  Recorder\InitializeDiscRecorder(pp\bstrval)
  Format\put_Recorder(Recorder)
  Debug "drive:   " +Str(x) +"   is ID:    " +ax_Uni2Ansi(pp\bstrval)
  med_type = Format\get_CurrentPhysicalMediaType(@mediaType)
       
  Select mediaType ;med_type_pick
   
  Case #IMAPI_MEDIA_TYPE_UNKNOWN
  Debug "Media Type is Unknown or no media loaded"
     
  Case #IMAPI_MEDIA_TYPE_CDROM
  Debug "Media Type is a CD-ROM (or burned CD-R)"
     
    Case #IMAPI_MEDIA_TYPE_CDR
    Debug "Media Type is blank CD-R"
     
    Case #IMAPI_MEDIA_TYPE_CDRW
    Debug "Media Type is CD-R/W"
     
    Case #IMAPI_MEDIA_TYPE_DVDROM
    Debug "Media Type is a DVD-ROM (or a burned DVD-R)"
    
    Case #IMAPI_MEDIA_TYPE_DVDRAM
    Debug "Media Type is DVD-RAM"
     
    Case #IMAPI_MEDIA_TYPE_DVDPLUSR
    Debug "Media Type is DVD+R"
    
    Case #IMAPI_MEDIA_TYPE_DVDPLUSRW
    Debug "Media Type is DVD+RW"
     
    Case #IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER
    Debug "Media Type is DVD+R DL"
    
    Case #IMAPI_MEDIA_TYPE_DVDDASHR
    Debug "Media Type is blank DVD-R"
    
    Case #IMAPI_MEDIA_TYPE_DVDDASHRW
    Debug "Media Type is DVD-RW"
    
    Case #IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER
    Debug "Media Type is DVD-R DL"
   
    Case #IMAPI_MEDIA_TYPE_DISK
    Debug "Media Type is Disk"
   
    Case #IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER
    Debug "Media Type is DVD+RW DL"
    
    Case #IMAPI_MEDIA_TYPE_HDDVDROM
    Debug "Media Type is HD DVD-ROM"
    
    Case #IMAPI_MEDIA_TYPE_HDDVDR
    Debug "Media Type is HD DVD-R"
  
    Case #IMAPI_MEDIA_TYPE_HDDVDRAM
    Debug "Media Type is HD DVD-RAM"
    
    Case #IMAPI_MEDIA_TYPE_BDROM
    Debug "Media Type is BD-ROM"
    
    Case #IMAPI_MEDIA_TYPE_BDR
    Debug "Media Type is BD-R"
    
    Case #IMAPI_MEDIA_TYPE_BDRE
    Debug "Media Type is BD-RE"
   
  EndSelect
   
  Recorder\get_VendorId(@pp\bstrval)
  Debug ax_Uni2Ansi(pp\bstrval)
  
  Recorder\get_ProductId(@pp\bstrval)
  Debug ax_Uni2Ansi(pp\bstrval)
  
  Recorder\get_ProductRevision(@pp\bstrval)
  Debug ax_Uni2Ansi(pp\bstrval)
  
  Recorder\get_VolumeName(@pp\bstrval)
  Debug ax_Uni2Ansi(pp\bstrval)
   
  Recorder\get_VolumePathNames(@value.SAFEARRAY)
  Variant\parray = PeekL(value)
  *VariantArray = Variant\parray
  For i = 1 To *VariantArray\rgsabound[0]\cElements
    *Variant = *VariantArray\pvData + (i - 1) * 16
    Debug "Your Drive Path is:   " +GetVariantString(*Variant)
  Next i
   
  DiscMaster\get_IsSupportedEnvironment(@value_support)
   
  Select value_support
   
    Case #VARIANT_TRUE
    Debug "Environment is supported!"
     
    Case #VARIANT_FALSE
    Debug "Environment IS NOT supported!"
         
  EndSelect
   
  Recorder\get_DeviceCanLoadMedia(@CanLoad)
   
  Select CanLoad
   
    Case #VARIANT_TRUE
    Debug "Device can eject and reload media!"
     
    Case #VARIANT_FALSE
    Debug "Device CAN NOT eject and reload media!"
         
  EndSelect
   
  Recorder\get_LegacyDeviceNumber(@legacy_num)
  Debug "Legacy number is:    " +Str(legacy_num)
   
  Format\IsRecorderSupported(Recorder, @record_support)
   
  Select record_support
   
    Case #VARIANT_TRUE
    Debug "Recorder is a supported IMAPI drive"
     
    Case #VARIANT_FALSE
    Debug "Recorder IS NOT A SUPPORTED IMAPI drive"
         
  EndSelect
   
  Recorder\get_ActiveDiscRecorder(@pp\bstrval)
  Debug ax_Uni2Ansi(pp\bstrval)
   
  Recorder\get_SupportedProfiles(@val.SAFEARRAY)
  Variant\parray = PeekL(val)
  *VariantArray = Variant\parray
  Debug ""
  Debug "**************Drive Profiles*****************"
  For i = 1 To *VariantArray\rgsabound[0]\cElements
    *Variant = *VariantArray\pvData + (i - 1) * 16
       
    profiles_x.l = Val(GetVariantString(*Variant))
     
    Select profiles_x
         
      Case #IMAPI_PROFILE_TYPE_INVALID
      Debug "The profile is not valid."
  
      Case #IMAPI_PROFILE_TYPE_NON_REMOVABLE_DISK
      Debug "The disk is not removable media"
  
      Case #IMAPI_PROFILE_TYPE_REMOVABLE_DISK
      Debug "The disk is removable media"
  
      Case #IMAPI_PROFILE_TYPE_MO_ERASABLE
      Debug "An Magneto-Optical Erasable drive"
  
      Case #IMAPI_PROFILE_TYPE_MO_WRITE_ONCE
      Debug "A write once optical drive."
  
      Case #IMAPI_PROFILE_TYPE_AS_MO
      Debug "An advance storage Magneto-Optical drive."
  
      Case #IMAPI_PROFILE_TYPE_CDROM
      Debug "A CD-ROM drive."
  
      Case #IMAPI_PROFILE_TYPE_CD_RECORDABLE
      Debug "A CD-R drive."
  
      Case #IMAPI_PROFILE_TYPE_CD_REWRITABLE
      Debug "A CD-RW or CD+RW drive."
  
      Case #IMAPI_PROFILE_TYPE_DVDROM
      Debug "A DVD-ROM drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_DASH_RECORDABLE
      Debug "A DVD-R sequential recording drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_RAM
      Debug "A DVD-RAM drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_DASH_REWRITABLE
      Debug "A DVD-RW restricted overwrite drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_DASH_RW_SEQUENTIAL
      Debug "A DVD-RW sequential recording drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_DASH_R_DUAL_SEQUENTIAL
      Debug "A DVD-R dual layer sequential recording drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_DASH_R_DUAL_LAYER_JUMP
      Debug "A DVD-R dual layer jump recording drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_PLUS_RW
      Debug "A DVD+RW drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_PLUS_R
      Debug "A DVD+R drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_PLUS_RW_DUAL
      Debug "A DVD+RW dual layer drive."
  
      Case #IMAPI_PROFILE_TYPE_DVD_PLUS_R_DUAL
      Debug "A DVD+R dual layer drive."
  
      Case #IMAPI_PROFILE_TYPE_BD_ROM
      Debug "A Blu-ray read only drive."
  
      Case #IMAPI_PROFILE_TYPE_BD_R_SEQUENTIAL
      Debug "A write once Blu-ray drive with sequential recording."
  
      Case #IMAPI_PROFILE_TYPE_BD_R_RANDOM_RECORDING
      Debug "A write once Blu-ray drive with random-access recording capability."
  
      Case #IMAPI_PROFILE_TYPE_BD_REWRITABLE
      Debug "A rewritable Blu-ray drive."
  
      Case #IMAPI_PROFILE_TYPE_HD_DVD_ROM
      Debug "A read only high density DVD."
  
      Case #IMAPI_PROFILE_TYPE_HD_DVD_RECORDABLE
      Debug "A write once high density DVD."
  
      Case #IMAPI_PROFILE_TYPE_HD_DVD_RAM
      Debug "A high density DVD with random access positioning."
  
      Case #IMAPI_PROFILE_TYPE_NON_STANDARD
      Debug "Nonstandard drive."
         
    EndSelect
 
  Next i
  Debug ""
  Debug "-------------------------------------- Next DVD-Writer ---------------------------"
  Debug ""
Next x

DiscMaster\Release()
Recorder\Release()   
Format\Release()

CoUninitialize_()
       
End


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 
The debugger-output, as I expected it to be:

Code: Select all

drive:   0   is ID:    \\?\ide#cdromhl-dt-st_dvdram_gsa-4163b_______________a106____#334b354333313242313020322020202020202020#{53f56308-b6bf-11d0-94f2-00a0c91efb8b}
Media Type is DVD+R
HL-DT-ST
DVDRAM GSA-4163B
A106
\\?\Volume{fcfbbcce-478a-11dc-bd62-806d6172696f}\
Your Drive Path is:   Y:\
Environment is supported!
Device can eject and reload media!
Legacy number is:    1
Recorder is a supported IMAPI drive
\\?\ide#cdromhl-dt-st_dvdram_gsa-4163b_______________a106____#334b354333313242313020322020202020202020#{53f56308-b6bf-11d0-94f2-00a0c91efb8b}

**************Drive Profiles*****************
A DVD-RAM drive.
A DVD-R sequential recording drive.
A DVD-RW sequential recording drive.
A DVD-RW restricted overwrite drive.
A DVD+RW drive.
A DVD+R drive.
A DVD+R dual layer drive.
A DVD-ROM drive.
A CD-R drive.
A CD-RW or CD+RW drive.
A CD-ROM drive.
The disk is removable media

-------------------------------------- Next DVD-Writer ---------------------------

drive:   1   is ID:    \\?\ide#cdromtsstcorp_cd#dvdw_sh-s182d_______________sb06____#5&39971a7a&0&0.1.0#{53f56308-b6bf-11d0-94f2-00a0c91efb8b}
Media Type is CD-R/W
TSSTcorp
CD/DVDW SH-S182D
SB06
\\?\Volume{fcfbbccd-478a-11dc-bd62-806d6172696f}\
Your Drive Path is:   Z:\
Environment is supported!
Device can eject and reload media!
Legacy number is:    0
Recorder is a supported IMAPI drive
\\?\ide#cdromtsstcorp_cd#dvdw_sh-s182d_______________sb06____#5&39971a7a&0&0.1.0#{53f56308-b6bf-11d0-94f2-00a0c91efb8b}

**************Drive Profiles*****************
A DVD-R dual layer sequential recording drive.
A DVD-R dual layer jump recording drive.
A DVD+R dual layer drive.
A DVD+R drive.
A DVD+RW drive.
A DVD-RW sequential recording drive.
A DVD-RW restricted overwrite drive.
A DVD-RAM drive.
A DVD-R sequential recording drive.
A DVD-ROM drive.
A CD-RW or CD+RW drive.
A CD-R drive.
A CD-ROM drive.
The disk is removable media

-------------------------------------- Next DVD-Writer ---------------------------
expexting your debug-output... scholly

Posted: Thu Jan 17, 2008 11:34 pm
by SFSxOI
code in this post removed, see posts below this one for working examples.

Posted: Fri Jan 18, 2008 1:36 am
by harff182
SFSxOI wrote:ARGHHHHHHhhhhhh! Of course your right. I'm stupid. I was testing the code that you see below which is working for me with multiple drives...but...I was posting code that was always a version behind what was currently working...'
:lol: :twisted: :lol: :twisted: :lol: :twisted: :lol: :twisted: :lol: :twisted: :lol: :twisted:
So I think you'll be :D to read, that this code works on my installation, too, without visible problems.

Time to have some sleep... scholly

Posted: Fri Jan 18, 2008 9:10 pm
by SFSxOI
here is an include file for IMAPIv2 in case you perfer to use it and below that is our refined code using the imapi2_include.pbi file. Some of the things in the include are not used in the code, this is just the overall include i'm using as I develop this a little more.

(the .pbi includes most of what is needed for the basics for IMAPIv2. Some of the things i'm still working on)

Here is the include file:

Code: Select all

; imapi2_include.pbi v 1.6 - 26 Jan 2008
; for PureBasic using version 4.10
; by SFSxOI
; On XP sp2 you have To install KB932716 (Image Mastering API v2.0) first
;*************************************************************************************************
; credits: 
; folder To iso created by bingo - http://www.purebasic.fr/english/viewtopic.php?t=29757
; traumatic and Shardik for SAFEARRAY help: http://www.purebasic.fr/english/viewtopic.php?t=30583
; Microsoft
;*************************************************************************************************
; implementation notes:
; As noted with in-code-remarks

; ##########################################
; #         Imports                        #
; ##########################################
Import "shlwapi.lib" 
SHCreateStreamOnFileEx(pszFile.p-unicode,grfMode.l,dwAttributes.l,fCreate.b,pstmTemplate.l,ppstm.l); 
EndImport

; ##########################################
; #         Constants and Enumerations     #
; ##########################################

;////////////Constants////////////////

#STGM_SHARE_DENY_NONE = 64
#STGM_READ = 0
#STGM_WRITE = 1 
#STGM_CREATE = 4096 
#STATFLAG_NONAME = 0

;Number of bytes in a sector.
#IMAPI_SECTOR_SIZE = 2048
;Base rate of speed that a CD spins, measured in sectors per second.
#IMAPI_SECTORS_PER_SECOND_AT_1X_CD = 75
;Base
#IMAPI_SECTORS_PER_SECOND_AT_1X_DVD = 680

;///////////Enumerations/////////////

Enumeration ; _STORAGE_BUS_TYPE
  #BusTypeUnknown
  #BusTypeScsi
  #BusTypeAtapi
  #BusTypeAta
  #BusType1394
  #BusTypeSsa
  #BusTypeFibre
  #BusTypeUsb
  #BusTypeRAID
  #BusTypeiScsi
  #BusTypeSas
  #BusTypeSata
  #BusTypeSd
  #BusTypeMmc
  #BusTypeMax
  #BusTypeMaxReserved = 127
EndEnumeration

Enumeration ; _IMAPI_FORMAT2_DATA_WRITE_ACTION
  #IMAPI_FORMAT2_DATA_WRITE_ACTION_VALIDATING_MEDIA=0
  #IMAPI_FORMAT2_DATA_WRITE_ACTION_FORMATTING_MEDIA=1
  #IMAPI_FORMAT2_DATA_WRITE_ACTION_INITIALIZING_HARDWARE=2
  #IMAPI_FORMAT2_DATA_WRITE_ACTION_CALIBRATING_POWER=3
  #IMAPI_FORMAT2_DATA_WRITE_ACTION_WRITING_DATA=4
  #IMAPI_FORMAT2_DATA_WRITE_ACTION_FINALIZATION=5
  #IMAPI_FORMAT2_DATA_WRITE_ACTION_COMPLETED=6
EndEnumeration

Enumeration ; _IMAPI_FORMAT2_TAO_WRITE_ACTION
  #IMAPI_FORMAT2_TAO_WRITE_ACTION_UNKNOWN=0
  #IMAPI_FORMAT2_TAO_WRITE_ACTION_PREPARING=1
  #IMAPI_FORMAT2_TAO_WRITE_ACTION_WRITING=2
  #IMAPI_FORMAT2_TAO_WRITE_ACTION_FINISHING=3
EndEnumeration

Enumeration ; _IMAPI_FORMAT2_RAW_CD_WRITE_ACTION
  #IMAPI_FORMAT2_RAW_CD_WRITE_ACTION_UNKNOWN=0
  #IMAPI_FORMAT2_RAW_CD_WRITE_ACTION_PREPARING=1
  #IMAPI_FORMAT2_RAW_CD_WRITE_ACTION_WRITING=2
  #IMAPI_FORMAT2_RAW_CD_WRITE_ACTION_FINISHING=3
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=10
  #IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER=11
  #IMAPI_MEDIA_TYPE_DISK=12
  #IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER=13
  #IMAPI_MEDIA_TYPE_HDDVDROM=14
  #IMAPI_MEDIA_TYPE_HDDVDR=15
  #IMAPI_MEDIA_TYPE_HDDVDRAM=16
  #IMAPI_MEDIA_TYPE_BDROM=17
  #IMAPI_MEDIA_TYPE_BDR=18
  #IMAPI_MEDIA_TYPE_BDRE=19
  #IMAPI_MEDIA_TYPE_MAX=19
EndEnumeration

Enumeration ; _IMAPI_READ_TRACK_ADDRESS_TYPE
  #IMAPI_READ_TRACK_ADDRESS_TYPE_LBA=0
  #IMAPI_READ_TRACK_ADDRESS_TYPE_TRACK=1
  #IMAPI_READ_TRACK_ADDRESS_TYPE_SESSION=2
EndEnumeration

Enumeration ; _IMAPI_FEATURE_PAGE_TYPE
  #IMAPI_FEATURE_PAGE_TYPE_PROFILE_LIST=0
  #IMAPI_FEATURE_PAGE_TYPE_CORE=1
  #IMAPI_FEATURE_PAGE_TYPE_MORPHING=2
  #IMAPI_FEATURE_PAGE_TYPE_REMOVABLE_MEDIUM=3
  #IMAPI_FEATURE_PAGE_TYPE_WRITE_PROTECT=4
  #IMAPI_FEATURE_PAGE_TYPE_RANDOMLY_READABLE=16
  #IMAPI_FEATURE_PAGE_TYPE_CD_MULTIREAD=29
  #IMAPI_FEATURE_PAGE_TYPE_CD_READ=30
  #IMAPI_FEATURE_PAGE_TYPE_DVD_READ=31
  #IMAPI_FEATURE_PAGE_TYPE_RANDOMLY_WRITABLE=32
  #IMAPI_FEATURE_PAGE_TYPE_INCREMENTAL_STREAMING_WRITABLE=33
  #IMAPI_FEATURE_PAGE_TYPE_SECTOR_ERASABLE=34
  #IMAPI_FEATURE_PAGE_TYPE_FORMATTABLE=35
  #IMAPI_FEATURE_PAGE_TYPE_HARDWARE_DEFECT_MANAGEMENT=36
  #IMAPI_FEATURE_PAGE_TYPE_WRITE_ONCE=37
  #IMAPI_FEATURE_PAGE_TYPE_RESTRICTED_OVERWRITE=38
  #IMAPI_FEATURE_PAGE_TYPE_CDRW_CAV_WRITE=39
  #IMAPI_FEATURE_PAGE_TYPE_MRW=40
  #IMAPI_FEATURE_PAGE_TYPE_ENHANCED_DEFECT_REPORTING=41
  #IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_RW=42
  #IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R=43
  #IMAPI_FEATURE_PAGE_TYPE_RIGID_RESTRICTED_OVERWRITE=44
  #IMAPI_FEATURE_PAGE_TYPE_CD_TRACK_AT_ONCE=45
  #IMAPI_FEATURE_PAGE_TYPE_CD_MASTERING=46
  #IMAPI_FEATURE_PAGE_TYPE_DVD_DASH_WRITE=47
  #IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_READ=48
  #IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_R_WRITE=49
  #IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_RW_WRITE=50
  #IMAPI_FEATURE_PAGE_TYPE_LAYER_JUMP_RECORDING=51
  #IMAPI_FEATURE_PAGE_TYPE_CD_RW_MEDIA_WRITE_SUPPORT=55
  #IMAPI_FEATURE_PAGE_TYPE_BD_PSEUDO_OVERWRITE=56
  #IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R_DUAL_LAYER=59
  #IMAPI_FEATURE_PAGE_TYPE_BD_READ=64
  #IMAPI_FEATURE_PAGE_TYPE_BD_WRITE=65
  #IMAPI_FEATURE_PAGE_TYPE_HD_DVD_READ=80
  #IMAPI_FEATURE_PAGE_TYPE_HD_DVD_WRITE=81
  #IMAPI_FEATURE_PAGE_TYPE_POWER_MANAGEMENT=256
  #IMAPI_FEATURE_PAGE_TYPE_SMART=257
  #IMAPI_FEATURE_PAGE_TYPE_EMBEDDED_CHANGER=258
  #IMAPI_FEATURE_PAGE_TYPE_CD_ANALOG_PLAY=259
  #IMAPI_FEATURE_PAGE_TYPE_MICROCODE_UPDATE=260
  #IMAPI_FEATURE_PAGE_TYPE_TIMEOUT=261
  #IMAPI_FEATURE_PAGE_TYPE_DVD_CSS=262
  #IMAPI_FEATURE_PAGE_TYPE_REAL_TIME_STREAMING=263
  #IMAPI_FEATURE_PAGE_TYPE_LOGICAL_UNIT_SERIAL_NUMBER=264
  #IMAPI_FEATURE_PAGE_TYPE_MEDIA_SERIAL_NUMBER=265
  #IMAPI_FEATURE_PAGE_TYPE_DISC_CONTROL_BLOCKS=266
  #IMAPI_FEATURE_PAGE_TYPE_DVD_CPRM=267
  #IMAPI_FEATURE_PAGE_TYPE_FIRMWARE_INFORMATION=268
  #IMAPI_FEATURE_PAGE_TYPE_AACS=269
  #IMAPI_FEATURE_PAGE_TYPE_VCPS=272
EndEnumeration

Enumeration ; _IMAPI_MODE_PAGE_TYPE
  #IMAPI_MODE_PAGE_TYPE_READ_WRITE_ERROR_RECOVERY=1
  #IMAPI_MODE_PAGE_TYPE_MRW=3
  #IMAPI_MODE_PAGE_TYPE_WRITE_PARAMETERS=5
  #IMAPI_MODE_PAGE_TYPE_CACHING=8
  #IMAPI_MODE_PAGE_TYPE_INFORMATIONAL_EXCEPTIONS=28
  #IMAPI_MODE_PAGE_TYPE_TIMEOUT_AND_PROTECT=29
  #IMAPI_MODE_PAGE_TYPE_POWER_CONDITION=26
  #IMAPI_MODE_PAGE_TYPE_LEGACY_CAPABILITIES=42
EndEnumeration

Enumeration ; _IMAPI_MODE_PAGE_REQUEST_TYPE
  #IMAPI_MODE_PAGE_REQUEST_TYPE_CURRENT_VALUES=0
  #IMAPI_MODE_PAGE_REQUEST_TYPE_CHANGEABLE_VALUES=1
  #IMAPI_MODE_PAGE_REQUEST_TYPE_DEFAULT_VALUES=2
  #IMAPI_MODE_PAGE_REQUEST_TYPE_SAVED_VALUES=3
EndEnumeration

Enumeration ; _IMAPI_PROFILE_TYPE
  #IMAPI_PROFILE_TYPE_INVALID=0
  #IMAPI_PROFILE_TYPE_NON_REMOVABLE_DISK=1
  #IMAPI_PROFILE_TYPE_REMOVABLE_DISK=2
  #IMAPI_PROFILE_TYPE_MO_ERASABLE=3
  #IMAPI_PROFILE_TYPE_MO_WRITE_ONCE=4
  #IMAPI_PROFILE_TYPE_AS_MO=5
  #IMAPI_PROFILE_TYPE_CDROM=8
  #IMAPI_PROFILE_TYPE_CD_RECORDABLE=9
  #IMAPI_PROFILE_TYPE_CD_REWRITABLE=10
  #IMAPI_PROFILE_TYPE_DVDROM=16
  #IMAPI_PROFILE_TYPE_DVD_DASH_RECORDABLE=17
  #IMAPI_PROFILE_TYPE_DVD_RAM=18
  #IMAPI_PROFILE_TYPE_DVD_DASH_REWRITABLE=19
  #IMAPI_PROFILE_TYPE_DVD_DASH_RW_SEQUENTIAL=20
  #IMAPI_PROFILE_TYPE_DVD_DASH_R_DUAL_SEQUENTIAL=21
  #IMAPI_PROFILE_TYPE_DVD_DASH_R_DUAL_LAYER_JUMP=22
  #IMAPI_PROFILE_TYPE_DVD_PLUS_RW=26
  #IMAPI_PROFILE_TYPE_DVD_PLUS_R=27
  #IMAPI_PROFILE_TYPE_DDCDROM=32
  #IMAPI_PROFILE_TYPE_DDCD_RECORDABLE=33
  #IMAPI_PROFILE_TYPE_DDCD_REWRITABLE=34
  #IMAPI_PROFILE_TYPE_DVD_PLUS_RW_DUAL=42
  #IMAPI_PROFILE_TYPE_DVD_PLUS_R_DUAL=43
  #IMAPI_PROFILE_TYPE_BD_ROM=64
  #IMAPI_PROFILE_TYPE_BD_R_SEQUENTIAL=65
  #IMAPI_PROFILE_TYPE_BD_R_RANDOM_RECORDING=66
  #IMAPI_PROFILE_TYPE_BD_REWRITABLE=67
  #IMAPI_PROFILE_TYPE_HD_DVD_ROM=80
  #IMAPI_PROFILE_TYPE_HD_DVD_RECORDABLE=81
  #IMAPI_PROFILE_TYPE_HD_DVD_RAM=82
  #IMAPI_PROFILE_TYPE_NON_STANDARD=65535
EndEnumeration

Enumeration ; _IMAPI_FORMAT2_DATA_MEDIA_STATE
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_UNKNOWN=0
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_INFORMATIONAL_MASK=15
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MASK=64512
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_OVERWRITE_ONLY=1
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_RANDOMLY_WRITABLE=1
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_BLANK=2
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_APPENDABLE=4
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_FINAL_SESSION=8
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_DAMAGED=1024
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_ERASE_REQUIRED=2048
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_NON_EMPTY_SESSION=4096
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_WRITE_PROTECTED=8192
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_FINALIZED=16384
  #IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MEDIA=32768
EndEnumeration

Enumeration ; _IMAPI_MEDIA_WRITE_PROTECT_STATE
  #IMAPI_WRITEPROTECTED_UNTIL_POWERDOWN=1
  #IMAPI_WRITEPROTECTED_BY_CARTRIDGE=2
  #IMAPI_WRITEPROTECTED_BY_MEDIA_SPECIFIC_REASON=4
  #IMAPI_WRITEPROTECTED_BY_SOFTWARE_WRITE_PROTECT=8
  #IMAPI_WRITEPROTECTED_BY_DISC_CONTROL_BLOCK=16
  #IMAPI_WRITEPROTECTED_READ_ONLY_MEDIA=16384
EndEnumeration

Enumeration ; _IMAPI_FORMAT2_RAW_CD_DATA_SECTOR_TYPE
  #IMAPI_FORMAT2_RAW_CD_SUBCODE_PQ_ONLY=1
  #IMAPI_FORMAT2_RAW_CD_SUBCODE_IS_COOKED=2
  #IMAPI_FORMAT2_RAW_CD_SUBCODE_IS_RAW=3
EndEnumeration

Enumeration ; PlatformId
  #PlatformX86=0
  #PlatformPowerPC=1
  #PlatformMac=2
EndEnumeration

Enumeration ; EmulationType
  #EmulationNone=0
  #Emulation12MFloppy=1
  #Emulation144MFloppy=2
  #Emulation288MFloppy=3
  #EmulationHardDisk=4
EndEnumeration

Enumeration ; FsiFileSystems
  #FsiFileSystemNone=0
  #FsiFileSystemISO9660=1
  #FsiFileSystemJoliet=2
  #FsiFileSystemUDF=4
  #FsiFileSystemUnknown=1073741824
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=10
  #IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER=11
  #IMAPI_MEDIA_TYPE_DISK=12
  #IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER=13
  #IMAPI_MEDIA_TYPE_HDDVDROM=14
  #IMAPI_MEDIA_TYPE_HDDVDR=15
  #IMAPI_MEDIA_TYPE_HDDVDRAM=16
  #IMAPI_MEDIA_TYPE_BDROM=17
  #IMAPI_MEDIA_TYPE_BDR=18
  #IMAPI_MEDIA_TYPE_BDRE=19
  #IMAPI_MEDIA_TYPE_MAX=19
EndEnumeration

Enumeration ; FsiItemType
  #FsiItemNotFound=0
  #FsiItemDirectory=1
  #FsiItemFile=2
EndEnumeration

; ##########################################
; #               Interface                #
; ##########################################

CompilerIf Defined(IWriteEngine2EventArgs,#PB_Interface) = #False
Interface IWriteEngine2EventArgs Extends IDispatch; CD Write Engine
  get_StartLba(dispidMember.l)
  get_SectorCount(dispidMember.l)
  get_LastReadLba(dispidMember.l)
  get_LastWrittenLba(dispidMember.l)
  get_TotalSystemBuffer(dispidMember.l)
  get_UsedSystemBuffer(dispidMember.l)
  get_FreeSystemBuffer(dispidMember.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IDiscFormat2DataEventArgs,#PB_Interface) = #False
Interface IDiscFormat2DataEventArgs Extends IWriteEngine2EventArgs; Track-at-once Data Writer
  get_ElapsedTime(dispidMember.l)
  get_RemainingTime(dispidMember.l)
  get_TotalTime(dispidMember.q)
  get_CurrentAction(dispidMember.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IDiscFormat2TrackAtOnceEventArgs,#PB_Interface) = #False
Interface IDiscFormat2TrackAtOnceEventArgs Extends IWriteEngine2EventArgs; CD Track-at-once Audio Writer Event Arguments
  get_CurrentTrackNumber(dispidMember.l)
  get_CurrentAction(dispidMember.q)
  get_ElapsedTime(dispidMember.l)
  get_RemainingTime(dispidMember.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IDiscFormat2RawCDEventArgs,#PB_Interface) = #False
Interface IDiscFormat2RawCDEventArgs Extends IWriteEngine2EventArgs; CD Disc-At-Once RAW Writer Event Arguments
  get_CurrentAction(dispidMember.l)
  get_ElapsedTime(dispidMember.l)
  get_RemainingTime(dispidMember.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IWriteSpeedDescriptor,#PB_Interface) = #False
Interface IWriteSpeedDescriptor Extends IDispatch; A single optical drive Write Speed Configuration
  get_MediaType(dispidMember.l)
  get_RotationTypeIsPureCAV(dispidMember.l)
  get_WriteSpeed(dispidMember.l)
EndInterface
CompilerEndIf

CompilerIf Defined(DDiscMaster2Events,#PB_Interface) = #False
Interface DDiscMaster2Events Extends IDispatch; Provides notification of the arrival/removal of CD/DVD (optical) devices.
  NotifyDeviceAdded(*object.IDispatch,uniqueId.p-bstr)
  NotifyDeviceRemoved(*object.IDispatch,uniqueId.p-bstr)
EndInterface
CompilerEndIf

CompilerIf Defined(IBootOptions,#PB_Interface) = #False
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
CompilerEndIf

CompilerIf Defined(IDiscMaster2,#PB_Interface) = #False
Interface IDiscMaster2 Extends IDispatch ;<<<<<
  get__NewEnum(dispidMember.l)
  get_Item(index.l, value)
  get_Count(index.l)
  get_IsSupportedEnvironment(index.l)
EndInterface
CompilerEndIf

CompilerIf Defined(DWriteEngine2Events,#PB_Interface) = #False
Interface DWriteEngine2Events Extends IDispatch; Provides notification of the progress of the WriteEngine2 writing.
  Update(*object.IDispatch,*progress.IDispatch)
EndInterface
CompilerEndIf

CompilerIf Defined(DDiscFormat2EraseEvents,#PB_Interface) = #False
Interface DDiscFormat2EraseEvents Extends IDispatch ; Provides notification of media erase progress.
  Update(*object.IDispatch,elapsedSeconds.l,estimatedTotalSeconds.l)
EndInterface
CompilerEndIf

CompilerIf Defined(DDiscFormat2DataEvents,#PB_Interface) = #False
Interface DDiscFormat2DataEvents Extends IDispatch ; Data Writer 
  Update(*object.IDispatch,*progress.IDispatch)
EndInterface
CompilerEndIf

CompilerIf Defined(DDiscFormat2TrackAtOnceEvents,#PB_Interface) = #False
Interface DDiscFormat2TrackAtOnceEvents Extends IDispatch ; CD Track-at-Once Audio Writer Events <<<<<<<
  Update(*object.IDispatch,*progress.IDispatch)
EndInterface
CompilerEndIf

CompilerIf Defined(DDiscFormat2RawCDEvents,#PB_Interface) = #False
Interface DDiscFormat2RawCDEvents Extends IDispatch ; CD Disc-At-Once RAW Writer Events <<<<<<
  Update(*object.IDispatch,*progress.IDispatch)
EndInterface
CompilerEndIf

CompilerIf Defined(IDiscRecorder2,#PB_Interface) = #False
Interface IDiscRecorder2 Extends IDispatch ;
  EjectMedia()
  CloseTray()
  AcquireExclusiveAccess(force.w,__MIDL__IDiscRecorder20000.p-bstr)
  ReleaseExclusiveAccess()
  DisableMcn()
  EnableMcn()
  InitializeDiscRecorder(recorderUniqueId)
  get_ActiveDiscRecorder(recorderUniqueId.l)
  get_VendorId(recorderUniqueId.l)
  get_ProductId(recorderUniqueId.l)
  get_ProductRevision(recorderUniqueId.l)
  get_VolumeName(recorderUniqueId.l) 
  get_VolumePathNames(recorderUniqueId.l) ; value.SAFEARRAY
  get_DeviceCanLoadMedia(recorderUniqueId.l)
  get_LegacyDeviceNumber(recorderUniqueId.l)
  get_SupportedFeaturePages(recorderUniqueId.l) ; value.SAFEARRAY
  get_CurrentFeaturePages(recorderUniqueId.q) ; value.SAFEARRAY
  get_SupportedProfiles(recorderUniqueId.l) ; value.SAFEARRAY
  get_CurrentProfiles(recorderUniqueId.l) ; value.SAFEARRAY
  get_SupportedModePages(recorderUniqueId.l) ; value.SAFEARRAY
  get_ExclusiveAccessOwner(recorderUniqueId.l) 
EndInterface
CompilerEndIf

; IDiscRecorder2Ex information: Note - You cannot access this functionality from script, haven't tried in PB
; To get an instance of this Interface, create an instance of the IDiscRecorder2 Interface And then call the IDiscRecorder2\QueryInterface
; method To retrieve the IDiscRecorder2Ex Interface.
CompilerIf Defined(IDiscRecorder2Ex,#PB_Interface) = #False
Interface IDiscRecorder2Ex Extends IUnknown ; 
  SendCommandNoData(Cdb.l,CdbSize.l,SenseBuffer.l,Timeout.l)
  SendCommandSendDataToDevice(Cdb.l,CdbSize.l,SenseBuffer.l,Timeout.l,Buffer.l,BufferSize.l)
  SendCommandGetDataFromDevice(Cdb.l,CdbSize.l,SenseBuffer.l,Timeout.l,Buffer.l,BufferSize.l,BufferFetched.l)
  ReadDvdStructure(format.l,address.l,layer.l,agid.l,Data_.l,Count.l)
  SendDvdStructure(format.l,Data_.l,Count.l)
  GetAdapterDescriptor(Data_.l,byteSize.l)
  GetDeviceDescriptor(Data_.l,byteSize.l)
  GetDiscInformation(discInformation.l,byteSize.l)
  GetTrackInformation(address.l,addressType.l,trackInformation.l,byteSize.l)
  GetFeaturePage(requestedFeature.l,currentFeatureOnly.b,featureData.l,byteSize.l)
  GetModePage(requestedModePage.l,requestType.l,modePageData.l,byteSize.l)
  SetModePage(requestType.l,Data_.l,byteSize.l)
  GetSupportedFeaturePages(currentFeatureOnly.b,featureData.l,byteSize.l)
  GetSupportedProfiles(currentOnly.b,profileTypes.l,validProfiles.l)
  GetSupportedModePages(requestType.l,modePageTypes.l,validPages.l)
  GetByteAlignmentMask(value.l)
  GetMaximumNonPageAlignedTransferSize(value.l)
  GetMaximumPageAlignedTransferSize(value.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IWriteEngine2,#PB_Interface) = #False
Interface IWriteEngine2 Extends IDispatch ; Write Engine 
  WriteSection(Data_.l,startingBlockAddress.l,numberOfBlocks.l)
  CancelWrite()
  put_Recorder(Data_.l)
  get_Recorder(Data_.l)
  put_UseStreamingWrite12(Data_.w)
  get_UseStreamingWrite12(Data_.l)
  put_StartingSectorsPerSecond(Data_.l)
  get_StartingSectorsPerSecond(Data_.l)
  put_EndingSectorsPerSecond(Data_.l)
  get_EndingSectorsPerSecond(Data_.l)
  put_BytesPerSector(Data_.l)
  get_BytesPerSector(Data_.l)
  get_WriteInProgress(Data_.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IDiscFormat2,#PB_Interface) = #False
Interface IDiscFormat2 Extends IDispatch ;
  IsRecorderSupported(Recorder.l, value.l)
  IsCurrentMediaSupported(Recorder.l, value.l)
  get_MediaPhysicallyBlank(Recorder.l)
  get_MediaHeuristicallyBlank(Recorder.l)
  get_SupportedMediaTypes(Recorder.l) ;value.SAFEARRAY
EndInterface
CompilerEndIf

CompilerIf Defined(IDiscFormat2Erase,#PB_Interface) = #False
Interface IDiscFormat2Erase Extends IDiscFormat2 ; 
  put_Recorder(Recorder.l)
  get_Recorder(Recorder.l)
  put_FullErase(Recorder.w)
  get_FullErase(Recorder.l)
  get_CurrentPhysicalMediaType(Recorder.l)
  put_ClientName(Recorder.p-bstr)
  get_ClientName(Recorder.l)
  EraseMedia()
EndInterface
CompilerEndIf

CompilerIf Defined(IDiscFormat2Data,#PB_Interface) = #False
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) ; supportedSpeeds.SAFEARRAY 
  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
CompilerEndIf

CompilerIf Defined(IDiscFormat2TrackAtOnce,#PB_Interface) = #False
Interface IDiscFormat2TrackAtOnce Extends IDiscFormat2 ; CD Track-at-Once Audio Writer
  PrepareMedia()
  AddAudioTrack(Data_.l)
  CancelAddTrack()
  ReleaseMedia()
  SetWriteSpeed(RequestedSectorsPerSecond.l,RotationTypeIsPureCAV.w)
  put_Recorder(RequestedSectorsPerSecond.l)
  get_Recorder(RequestedSectorsPerSecond.l)
  put_BufferUnderrunFreeDisabled(RequestedSectorsPerSecond.w)
  get_BufferUnderrunFreeDisabled(RequestedSectorsPerSecond.l)
  get_NumberOfExistingTracks(RequestedSectorsPerSecond.l)
  get_TotalSectorsOnMedia(RequestedSectorsPerSecond.l)
  get_FreeSectorsOnMedia(RequestedSectorsPerSecond.l)
  get_UsedSectorsOnMedia(RequestedSectorsPerSecond.l)
  put_DoNotFinalizeMedia(RequestedSectorsPerSecond.w)
  get_DoNotFinalizeMedia(RequestedSectorsPerSecond.l)
  get_ExpectedTableOfContents(RequestedSectorsPerSecond.l)
  get_CurrentPhysicalMediaType(RequestedSectorsPerSecond.l)
  put_ClientName(RequestedSectorsPerSecond.p-bstr)
  get_ClientName(RequestedSectorsPerSecond.l)
  get_RequestedWriteSpeed(RequestedSectorsPerSecond.l)
  get_RequestedRotationTypeIsPureCAV(RequestedSectorsPerSecond.l)
  get_CurrentWriteSpeed(RequestedSectorsPerSecond.l)
  get_CurrentRotationTypeIsPureCAV(RequestedSectorsPerSecond.l)
  get_SupportedWriteSpeeds(RequestedSectorsPerSecond.l)
  get_SupportedWriteSpeedDescriptors(RequestedSectorsPerSecond.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IDiscFormat2RawCD,#PB_Interface) = #False
Interface IDiscFormat2RawCD Extends IDiscFormat2 ; CD Disc-At-Once RAW Writer
  PrepareMedia()
  WriteMedia(Data_.l)
  WriteMedia2(Data_.l,streamLeadInSectors.l)
  CancelWrite()
  ReleaseMedia()
  SetWriteSpeed(RequestedSectorsPerSecond.l,RotationTypeIsPureCAV.w)
  put_Recorder(RequestedSectorsPerSecond.l)
  get_Recorder(RequestedSectorsPerSecond.q)
  put_BufferUnderrunFreeDisabled(RequestedSectorsPerSecond.w)
  get_BufferUnderrunFreeDisabled(RequestedSectorsPerSecond.l)
  get_StartOfNextSession(RequestedSectorsPerSecond.l)
  get_LastPossibleStartOfLeadout(RequestedSectorsPerSecond.l)
  get_CurrentPhysicalMediaType(RequestedSectorsPerSecond.l)
  get_SupportedSectorTypes(RequestedSectorsPerSecond.l)
  put_RequestedSectorType(RequestedSectorsPerSecond.l)
  get_RequestedSectorType(RequestedSectorsPerSecond.l)
  put_ClientName(RequestedSectorsPerSecond.p-bstr)
  get_ClientName(RequestedSectorsPerSecond.l)
  get_RequestedWriteSpeed(RequestedSectorsPerSecond.l)
  get_RequestedRotationTypeIsPureCAV(RequestedSectorsPerSecond.l)
  get_CurrentWriteSpeed(RequestedSectorsPerSecond.q)
  get_CurrentRotationTypeIsPureCAV(RequestedSectorsPerSecond.l)
  get_SupportedWriteSpeeds(RequestedSectorsPerSecond.l)
  get_SupportedWriteSpeedDescriptors(RequestedSectorsPerSecond.l)
EndInterface
CompilerEndIf 

CompilerIf Defined(IFileSystemImage,#PB_Interface) = #False
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(discIdentifier.p-bstr)
  IdentifyFileSystemsOnDisc(discRecorder.l) 
  GetDefaultFileSystemForImport(fileSystems.l) 
  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
CompilerEndIf

; Information : IFileSystemImage2 - only available for Windows Vista SP1 and Windows Server 2008.
; write multiple boot entries or boot images required for the EFI/UEFI support. For example, boot media with boot straps for both Windows XP and Windows Vista.
; included here for future use and expansion
CompilerIf Defined(IFileSystemImage2,#PB_Interface) = #False
Interface IFileSystemImage2 Extends IFileSystemImage
  get_BootImageOptionsArray(pVal.l) ; out pVal.SAFEARRAY 
  put_BootImageOptionsArray(newVal.l) ; in newVal.SAFEARRAY
EndInterface
CompilerEndIf

CompilerIf Defined(IProgressItems,#PB_Interface) = #False
Interface IProgressItems Extends IDispatch; Progress item block mapping collection
  get__NewEnum(dispidMember.l)
  get_Item(Index.l)
  get_Count(Index.l)
  ProgressItemFromBlock(block.l)
  ProgressItemFromDescription(Description.p-bstr)
  get_EnumProgressItems(Description.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IProgressItem,#PB_Interface) = #False
Interface IProgressItem Extends IDispatch; FileSystemImageResult progress item
  get_Description(dispidMember.l)
  get_FirstBlock(dispidMember.l)
  get_LastBlock(dispidMember.l)
  get_BlockCount(dispidMember.q)
EndInterface
CompilerEndIf

CompilerIf Defined(IFileSystemImageResult,#PB_Interface) = #False
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
CompilerEndIf

CompilerIf Defined(IFsiItem,#PB_Interface) = #False
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
CompilerEndIf

CompilerIf Defined(IFsiDirectoryItem,#PB_Interface) = #False
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
CompilerEndIf

CompilerIf Defined(IFsiFileItem,#PB_Interface) = #False
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
CompilerEndIf

CompilerIf Defined(IMultisession,#PB_Interface) = #False
Interface IMultisession Extends IDispatch ; Generic multisession support interface.
  get_IsSupportedOnCurrentMediaState(value.l)
  put_InUse(value.w)
  get_InUse(value.l)
  get_ImportRecorder(value.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IMultisessionSequential,#PB_Interface) = #False
Interface IMultisessionSequential Extends IMultisession ; Sequential multisession support interface.
  get_IsFirstDataSession(value.l)
  get_StartAddressOfPreviousSession(value.l)
  get_LastWrittenAddressOfPreviousSession(value.l)
  get_NextWritableAddress(value.l)
  get_FreeSectorsOnMedia(value.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IStreamPseudoRandomBased,#PB_Interface) = #False
Interface IStreamPseudoRandomBased Extends IStream; Pseudo-random based IStream data (implementation dependent)
  put_Seed(value.l)
  get_Seed(value.l)
  put_ExtendedSeed(values.l,eCount.l)
  get_ExtendedSeed(values.l,eCount.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IStreamConcatenate,#PB_Interface) = #False
Interface IStreamConcatenate Extends IStream; Stream concatenation
  Initialize(stream1.l,stream2.l)
  Initialize2(streams.l,streamCount.l)
  Append(stream.l)
  Append2(streams.l,streamCount.l)
EndInterface
CompilerEndIf

CompilerIf Defined(IStreamInterleave,#PB_Interface) = #False
Interface IStreamInterleave Extends IStream; Stream interleave: each stream gets interleaveSize bytes, then cycles to the next stream
  Initialize(streams.l,interleaveSizes.l,streamCount.l)
EndInterface
CompilerEndIf

; ##########################################
; #               Structures               #
; ##########################################

CompilerIf Defined(_STORAGE_DEVICE_DESCRIPTOR,#PB_Structure) = #False
Structure _STORAGE_DEVICE_DESCRIPTOR
  Version.l
  Size.l
  DeviceType.b
  DeviceTypeModifier.b
  RemovableMedia.l
  CommandQueueing.l
  VendorIdOffset.l
  ProductIdOffset.l
  ProductRevisionOffset.l
  SerialNumberOffset.l
  BusType.l
  RawPropertiesLength.l 
  RawDeviceProperties.b[1]
EndStructure
CompilerEndIf

CompilerIf Defined(SAFEARRAYBOUND,#PB_Structure) = #False
Structure SAFEARRAYBOUND ; ; thanks to Shardik for this
  cElements.L  ; # of elements in the array dimension 
  lLbound.L    ; Lower bounds of the array dimension 
EndStructure
CompilerEndIf 

CompilerIf Defined(SAFEARRAY,#PB_Structure) = #False
Structure SAFEARRAY ; ; thanks to Shardik for this
  cDims.W 
  fFeatures.W 
  cbElements.L 
  cLocks.L 
  pvData.L 
  rgsabound.SAFEARRAYBOUND[60] 
EndStructure
CompilerEndIf

; since PB handles quad
CompilerIf Defined(_ULARGE_INTEGER,#PB_Structure) = #False
Structure _ULARGE_INTEGER
  QuadPart.q
EndStructure
CompilerEndIf
; since PB handles quad
CompilerIf Defined(_LARGE_INTEGER,#PB_Structure) = #False
Structure _LARGE_INTEGER
  QuadPart.q
EndStructure
CompilerEndIf
; see ; STATSTG and tagSTATSTG

CompilerIf Defined(tagCONNECTDATA,#PB_Structure) = #False
Structure tagCONNECTDATA
  *pUnk.IUnknown
  dwCookie.l
EndStructure
CompilerEndIf

; STATSTG as currently used
CompilerIf Defined(STATSTG,#PB_Structure) = #False
Structure STATSTG
  pwcsName.l 
  type.l 
  cbSize.q 
  mtime.FILETIME 
  ctime.FILETIME 
  atime.FILETIME
  grfMode.f 
  grfLocksSupported.l 
  clsid.GUID 
  grfStateBits.l 
  reserved.l
EndStructure
CompilerEndIf

; STATSTG as currently defined for Imapiv2 and in current SDK for imapiv2
CompilerIf Defined(tagSTATSTG,#PB_Structure) = #False
Structure tagSTATSTG
  pwcsName.l ; p-unicode
  type.l
  cbSize._ULARGE_INTEGER
  mtime.l
  ctime.l
  atime.l
  grfMode.l
  grfLocksSupported.l
  clsid.IWriteEngine2EventArgs
  grfStateBits.l
  reserved.l
EndStructure
CompilerEndIf
; STATSTG as currently defined for Imapiv2 and in current SDK for imapiv2 File System
;Structure tagSTATSTG
CompilerIf Defined(tagSTATSTG_FS,#PB_Structure) = #False
Structure tagSTATSTG_FS ; changed name to avoid conflict while testing
  pwcsName.l ; p-unicode
  type.l
  cbSize.l
  mtime.l
  ctime.l
  atime.l
  grfMode.l
  grfLocksSupported.l
  clsid.l
  grfStateBits.l
  reserved.l
EndStructure
CompilerEndIf

; ##########################################
; #         Helper/wrap/macro/procedures   #
; ##########################################

Procedure.s GetVariantString(*Variant.VARIANT) ; thanks to Shardik for this
  Protected String.S = "" 

  If VariantChangeType_(*Variant, *Variant, 0, #VT_BSTR) = #S_OK 
    String = PeekS(*Variant\bstrVal, -1, #PB_Unicode) 
    VariantClear_(*Variant) 
  Else 
    Debug "VariantChangeType() failed!" 
  EndIf 

  ProcedureReturn String  
EndProcedure

Procedure.s sfs_Uni2Ansi(Pointer) ; credit to the originator for this 
  Buffer.s=Space(512) 
  WideCharToMultiByte_(#CP_ACP,0,Pointer,-1,@Buffer,512,0,0) 
  ProcedureReturn Buffer 
EndProcedure 

Procedure DiscMaster_obj() ; call this to create IDiscMaster2 object called DiscMaster
Global DiscMaster.IDiscMaster2
CoCreateInstance_(?CLSID_MsftDiscMaster2,0,1,?IID_IDiscMaster2,@DiscMaster.IDiscMaster2)
ProcedureReturn
EndProcedure

Procedure Recorder_obj() ; call this to create IDiscRecorder2 called Recorder
Global Recorder.IDiscRecorder2
CoCreateInstance_(?CLSID_MsftDiscRecorder2,0,1,?IID_IDiscRecorder2,@Recorder.IDiscRecorder2)
ProcedureReturn
EndProcedure

Procedure Format2Erase_obj() ; call this to create IDiscFormat2Erase object called Format2Erase
Global Format2Erase.IDiscFormat2Erase
CoCreateInstance_(?CLSID_MsftDiscFormat2Erase,0,1,?IID_IDiscFormat2Erase,@Format2Erase.IDiscFormat2Erase)
ProcedureReturn
EndProcedure

Procedure FileSystemImgage_obj() ; call this to create IFileSystemImage object called FileSystemImgage
Global FileSystemImgage.IFileSystemImage
CoCreateInstance_(?CLSID_MsftFileSystemImage,0,1,?IID_IFileSystemImage,@FileSystemImgage.IFileSystemImage)
ProcedureReturn
EndProcedure

Procedure DataWriter_Format2Data_obj() ; call this to create IDiscFormat2Data called DataWriter_Format2Data
Global DataWriter_Format2Data.IDiscFormat2Data
CoCreateInstance_(?CLSID_MsftDiscFormat2Data,0,1,?IID_IDiscFormat2Data,@DataWriter_Format2Data.IDiscFormat2Data)
ProcedureReturn
EndProcedure

Procedure DiscFormat2RawCD_obj() ; call this to create IDiscFormat2RawCD object called DiscFormat2RawCD
Global DiscFormat2RawCD.IDiscFormat2RawCD
CoCreateInstance_(?CLSID_MsftDiscFormat2RawCD,0,1,?IID_IDiscFormat2RawCD,@DiscFormat2RawCD.IDiscFormat2RawCD)
ProcedureReturn
EndProcedure

Procedure Format2TrackAtOnce_obj() ; call this to create IDiscFormat2TrackAtOnce object called Format2TrackAtOnce
Global DiscFormat2RawCD.IDiscFormat2RawCD
CoCreateInstance_(?CLSID_MsftDiscFormat2TrackAtOnce,0,1,?IID_IDiscFormat2TrackAtOnce,@Format2TrackAtOnce.IDiscFormat2TrackAtOnce)
ProcedureReturn
EndProcedure

Procedure WriteEngine2_obj() ; call this to create IWriteEngine2 object called WriteEngine2
Global WriteEngine2.IWriteEngine2
CoCreateInstance_(?CLSID_MsftWriteEngine2,0,1,?IID_IWriteEngine2,@WriteEngine2.IWriteEngine2)
ProcedureReturn
EndProcedure

Procedure IBootOptions_obj() ; call this to create IBootOptions object called IBoot_Options
Global IBoot_Options.IBootOptions
CoCreateInstance_(?CLSID_BootOptions,0,1,?IID_IBootOptions,@IBoot_Options.IBootOptions)
ProcedureReturn
EndProcedure

Procedure StreamConcatenate_obj() ; call this to create IStreamConcatenate object called StreamConcatenate
Global StreamConcatenate.IStreamConcatenate
CoCreateInstance_(?CLSID_MsftStreamConcatenate,0,1,?IID_IStreamConcatenate,@StreamConcatenate.IStreamConcatenate)
ProcedureReturn
EndProcedure

Procedure StreamInterleave_obj() ; call this to create IStreamInterleave object called StreamInterleave
Global StreamInterleave.IStreamInterleave
CoCreateInstance_(?CLSID_MsftStreamInterleave,0,1,?IID_IStreamInterleave,@StreamInterleave.IStreamInterleave)
ProcedureReturn
EndProcedure

Procedure StreamPseudoRandomBased_obj() ; call this to create IStreamPseudoRandomBased object called StreamPseudoRandomBased
Global StreamPseudoRandomBased.IStreamPseudoRandomBased
CoCreateInstance_(?CLSID_MsftStreamPrng001,0,1,?IID_IStreamPseudoRandomBased,@StreamPseudoRandomBased.IStreamPseudoRandomBased)
ProcedureReturn
EndProcedure

Procedure DIROBJroot_obj() ; call this to create a FileSystemImgage\get_root IFsiDirectoryItem object called DIROBJ
Global DIROBJ.IFsiDirectoryItem
FileSystemImgage\get_root(@DIROBJ.IFsiDirectoryItem)
ProcedureReturn
EndProcedure

Procedure RESULT_image_obj() ; call this to create IFileSystemImageResult object called RESULT_image
Global RESULT_image.IFileSystemImageResult
FileSystemImgage\CreateResultImage(@RESULT_image.IFileSystemImageResult)
ProcedureReturn
EndProcedure

; Information: CreateBurnIStream()
; Creates a IStream object named dataStream.IStream For .iso file creation Or burning To CD\DVD.
; No parameters
Procedure CreateBurnIStream() ; call this to create dataStream.IStream stream object 
Global dataStream.IStream
CreateStreamOnHGlobal_(0,#True,@dataStream)
ProcedureReturn
EndProcedure

; Information: CreateIsoIStream(in_IsoName.s)
; Creates a IStream object named isoStream.IStream for your .iso file creation
; Produces in_IsoName.iso located at full path To where .iso is created on hard drive - i.e..."C:\myiso.iso" Or "C:\temp\myiso.iso"
; where:
; In = in_IsoName.s = full path To where .iso is To be created on hard drive - i.e..."C:\myiso.iso" or "C:\temp\myiso.iso"
Procedure CreateIsoIStream(in_IsoName.s) ; call this to create isoStream.IStream stream object
Global isoStream.IStream
SHCreateStreamOnFileEx(in_IsoName,#STGM_WRITE|#STGM_CREATE,0,0,0,@isoStream)
ProcedureReturn
EndProcedure

; Information: CreateBootFileIStream(in_BootFileName.s)
; Creates a IStream object named BootImg.IStream for your boot file image for use in creating bootable CD's/DVD's 
; where:
; in = in_BootFileName.s = full path To the boot file image to use for bootable CD\DVD creation, i.e..."C:\bootimg.bin" or "C:\temp\bootimg.bin"
Procedure CreateBootFileIStream(in_BootFileName.s) ; call this to create BootImg.IStream stream object
Global BootImg.IStream
SHCreateStreamOnFileEx(in_BootFileName,#STGM_READ|#STGM_SHARE_DENY_NONE,0,0,0,@BootImg)
ProcedureReturn
EndProcedure

; Information: CreateBurnIsoIStream(in_iso_burn_file_name.s)
; Creates a IStream object named IsoBurnStream.IStream used to burn a .iso to CD/DVD 
; where:
; in = in_iso_burn_file_name.s = full path To the .iso file to burn to CD\DVD, i.e..."C:\myiso.iso" or "C:\temp\myiso.iso"
Procedure CreateBurnIsoIStream(in_iso_burn_file_name.s) ; call this to create IsoBurnStream.IStream stream object
Global IsoBurnStream.IStream
SHCreateStreamOnFileEx(in_iso_burn_file_name,#STGM_READ|#STGM_SHARE_DENY_NONE,0,0,0,@IsoBurnStream)
ProcedureReturn
EndProcedure

;Information : Eject_Drive(indexx.l)
;In some cases and configurations all objects are released by the Format2Data\Write before any other objects can use the 
;Recorder object, the write function has exclusive access to the drive and is greedy about letting other functions use the objects.
;The Eject function also needs exclusive access but the write function doesn't like to share, as a result the procedure crashes.
;Call this To eject the drive media tray when you need the drive To open For you in one of these special circumstances.
;where:
;indexx.l = the drive index for the drive you need to eject
Procedure Eject_Drive(indexx.l)
pp.variant 
pp\vt = #VT_BSTR
Index.l = indexx.l
CoInitialize_(0)

  DiscMaster_obj()
  DiscMaster\get_Item(Index,@pp\bstrval)
  Recorder_obj()
  Recorder\InitializeDiscRecorder(pp\bstrval)
  DataWriter_Format2Data_obj()
  DataWriter_Format2Data\put_Recorder(Recorder)
  Recorder\EjectMedia()
  
  DiscMaster\Release()
  Recorder\Release()
DataWriter_Format2Data\Release()

CoUninitialize_()

EndProcedure

;Information : Close_Drive(indexx.l) - See information for Eject_Drive_Utility(indexx.l)
;where:
;indexx.l = the drive index for the drive you need to close
Procedure Close_Drive(indexx.l)
pp.variant 
pp\vt = #VT_BSTR
Index.l = indexx.l
CoInitialize_(0)

  DiscMaster_obj()
  DiscMaster\get_Item(Index,@pp\bstrval)
  Recorder_obj()
  Recorder\InitializeDiscRecorder(pp\bstrval)
  DataWriter_Format2Data_obj()
  DataWriter_Format2Data\put_Recorder(Recorder)
  Recorder\CloseTray()
  
  DiscMaster\Release()
  Recorder\Release()
DataWriter_Format2Data\Release()

CoUninitialize_()

EndProcedure

;Information : Check_media(media_unk)
;Checks for unknown media, no media, or unsupported media in drive - uses most common types
;where:
;in = output of IDiscFormat2Data\get_CurrentPhysicalMediaType(@value.l)
Procedure Check_Media(media_unk)  
  Select media_unk
      Case #IMAPI_MEDIA_TYPE_CDROM ; CD-ROM
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_CDR ; CD-R
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_CDRW ; CD-RW
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DVDROM ; DVD-ROM
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DVDRAM ; DVD-RAM
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DVDPLUSR ; DVD+R
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DVDPLUSRW ; DVD+RW
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER ; DVD+R dual layer
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DVDDASHR ; DVD-R
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DVDDASHRW ; DVD-RW
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER ; DVD-R dual layer
      media_type_decide.l = #True
      Case #IMAPI_MEDIA_TYPE_DISK ; Randomly writable
      media_type_decide.l = #True
      ; Media not present OR is unrecognized below here
      Case #IMAPI_MEDIA_TYPE_UNKNOWN 
      media_type_decide.l = #False
      Case #IMAPI_MEDIA_TYPE_HDDVDROM
      media_type_decide.l = #False
      Case #IMAPI_MEDIA_TYPE_BDROM
      media_type_decide.l = #False
  EndSelect
    
If media_type_decide.l = #False
ProcedureReturn #False
Else
ProcedureReturn #True
EndIf 
EndProcedure

; ##########################################
; #                 GUIDs                  #
; ##########################################

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
  CLSID_MsftDiscFormat2RawCD:
    Data.l $27354128
    Data.w $7F64,$5B0F
    Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
  CLSID_MsftDiscFormat2TrackAtOnce:
    Data.l $27354129
    Data.w $7F64,$5B0F
    Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
  CLSID_MsftWriteEngine2:
    Data.l $2735412C
    Data.w $7F64,$5B0F
    Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
  CLSID_MsftStreamConcatenate:
    Data.l $27354125
    Data.w $7F64,$5B0F
    Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
  CLSID_MsftStreamInterleave:
    Data.l $27354124
    Data.w $7F64,$5B0F
    Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
  CLSID_MsftStreamPrng001:
    Data.l $27354126
    Data.w $7F64,$5B0F
    Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
  CLSID_IMAPI2:
    Data.l $2735412F
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  CLSID_IMAPI2FS:
    Data.l $2C941FD0
    Data.w $975B,$59BE
    Data.b $A9,$60,$9A,$2A,$26,$28,$53,$A5
  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_IFileSystemImageResult:
    Data.l $2C941FD8 
    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
  IID_IWriteEngine2EventArgs:
    Data.l $27354136
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IDiscFormat2DataEventArgs:
    Data.l $2735413D
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IDiscFormat2TrackAtOnceEventArgs:
    Data.l $27354140
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IDiscFormat2RawCDEventArgs:
    Data.l $27354143
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IWriteSpeedDescriptor:
    Data.l $27354144
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_DDiscMaster2Events:
    Data.l $27354131
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_DWriteEngine2Events:
    Data.l $27354137
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_DDiscFormat2EraseEvents:
    Data.l $2735413A
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_DDiscFormat2DataEvents:
    Data.l $2735413C
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_DDiscFormat2TrackAtOnceEvents:
    Data.l $2735413F
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_DDiscFormat2RawCDEvents:
    Data.l $27354142
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IDiscRecorder2Ex:
    Data.l $27354132
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IWriteEngine2:
    Data.l $27354135
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IDiscFormat2:
    Data.l $27354152
    Data.w $8F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IDiscFormat2TrackAtOnce:
    Data.l $27354154
    Data.w $8F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IDiscFormat2RawCD:
    Data.l $27354155
    Data.w $8F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IMultisessionSequential:
    Data.l $27354151
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IMultisession:
    Data.l $27354150
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IProgressItems:
    Data.l $2C941FD7
    Data.w $975B,$59BE
    Data.b $A9,$60,$9A,$2A,$26,$28,$53,$A5
  IID_IProgressItem:
    Data.l $2C941FD5
    Data.w $975B,$59BE
    Data.b $A9,$60,$9A,$2A,$26,$28,$53,$A5
  IID_IStreamConcatenate:
    Data.l $27354146
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IStreamInterleave:
    Data.l $27354147
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
  IID_IStreamPseudoRandomBased:
    Data.l $27354145
    Data.w $7F64,$5B0F
    Data.b $8F,$0,$5D,$77,$AF,$BE,$26,$1E
EndDataSection

Posted: Fri Jan 18, 2008 11:19 pm
by harff182
ARGL......

you REALLY should include a Procedure.s sfs_Uni2Ansi(Pointer), or anybody, who wants to test and has not installed Droopys Lib will fail and give up.

And ALL 19 mediatypes, not only 9 will make those happy, who can use and check them ;)

Yes, I know, I can be a PITA, but your good code shouldn't fail unnecessarily.

Posted: Sat Jan 19, 2008 12:48 am
by SFSxOI
OK, i added the rest of the media types and the procedure. posted the edited code above.

You think its neater and cleaner to do something like this to create the objects:

Code: Select all

DiscMaster_obj()
rather then

Code: Select all

CoCreateInstance_(?CLSID_MsftDiscMaster2,0,1,?IID_IDiscMaster2,@DiscMaster.IDiscMaster2)
i think it looks neater and helps follow the code flow better...plus it makes it real easy to convert VB scripts too which do basically the same.

???
harff182 wrote:ARGL......

you REALLY should include a Procedure.s sfs_Uni2Ansi(Pointer), or anybody, who wants to test and has not installed Droopys Lib will fail and give up.

And ALL 19 mediatypes, not only 9 will make those happy, who can use and check them ;)

Yes, I know, I can be a PITA, but your good code shouldn't fail unnecessarily.

Posted: Sat Jan 19, 2008 1:25 pm
by harff182
SFSxOI wrote:You think its neater and cleaner to do something like this to create the objects
.....
i think it looks neater and helps follow the code flow better...
Agreed, even for me, who don't understand it all, it's now easy to follow, from which interface an output comes from ;)

And don't forget to increase the version-numbers from now on :twisted:

Posted: Sat Jan 19, 2008 11:58 pm
by SFSxOI
Updated the 'imapi2_include.pbi' include file a few posts above this one.

Here is a more complete example using more of the IMAPIv2 functions in a sample-application form. Yes, I know the GUI is ugly, but its not intended to be a final product and the GUI was created in haste to test the code more quickly, and besides i'm not an "artistic" person when it comes to GUI's - the user can create their own.

The below code uses the 'imapi2_include.pbi' include file from a few posts above this one.

Code: Select all

; IMAPIv2 sample app for Vista and winXP SP2 v 1.8 - 26 January 2008
; On XP sp2 you have To install KB932716 (Image Mastering API v2.0) first
;*************************************************************************************************
; credits: 
; folder To iso created by bingo - http://www.purebasic.fr/english/viewtopic.php?t=29757
; traumatic and Shardik for SAFEARRAY help: http://www.purebasic.fr/english/viewtopic.php?t=30583
; Microsoft
;*************************************************************************************************
; implementation notes:
; Windows Vista or WinXP SP2 with KB932716 (Image Mastering API v2.0) installed 
; Requires - imapi2_include.pbi

XIncludeFile "imapi2_include.pbi"
Global tidcd.l, tidiso.l, tide.l, tidid.l, recorder_index.l

Enumeration 1
  #Button_1
  #Button_2
  #Button_3
  #Button_4
  #Button_5
  #Button_6
  #CheckBox_1
  #CheckBox_2
  #CheckBox_3
  #CheckBox_4
  #CheckBox_5
  #CheckBox_6
  #CheckBox_7
  #CheckBox_8
  #CheckBox_9
  #CheckBox_10
  #CheckBox_11
  #CheckBox_12
  #Drive_Select
  #Exit
  #Frame3D_1
  #Frame3D_2
  #Frame3D_3
  #Frame3D_4
  #Frame3D_5
  #String_1
  #String_2
  #Text_1
  #Text_2
  #Text_3
  #Text_4
  #Text_5
  #Window_0
EndEnumeration

Structure THREADDATA_MAIN 
  item_main1.s 
  item_main2.s 
  item_main3.s
  item_main4.s
  item_main5.l
  item_main6.l
  item_main7.l
  item_main8.s
  item_main9.l
  item_main10.l
  item_main11.l
EndStructure

Structure THREADDATA_ISO 
  item_iso1.s 
  item_iso2.l
  item_iso3.l
EndStructure

Structure THREADDATA_ERS 
  item_ers1.l 
  item_ers2.l
EndStructure

Structure Drive_Path
  Index_ID.l
  Path_ID.s
  Vendor_ID.s
  Product_ID.s
EndStructure

Procedure GetDrive(get_drive.s)
Global NewList Drive_List.Drive_Path()

pp.variant 
pp\vt = #VT_BSTR

Variant.VARIANT 
*VariantArray.SAFEARRAY
CoInitialize_(0)
DiscMaster_obj()
DiscMaster\get_Count(@count)

For x = 0 To count
 
  If x = count
    Break
  EndIf
  
  Recorder_obj()
  DataWriter_Format2Data_obj()
    DiscMaster\get_Item(x,@pp\bstrval)
    Recorder\InitializeDiscRecorder(pp\bstrval)
    DataWriter_Format2Data\IsRecorderSupported(Recorder, @record_support)
  
  If record_support = #VARIANT_TRUE
      Recorder\get_VendorId(@pp\bstrval)
      VendorID$ = sfs_Uni2Ansi(pp\bstrval)
      Recorder\get_ProductId(@pp\bstrval)
      ProductId$ =  sfs_Uni2Ansi(pp\bstrval)
      
      Recorder\get_VolumePathNames(@value.SAFEARRAY)
      Variant\parray = PeekL(value)
      *VariantArray = Variant\parray
      For i = 1 To *VariantArray\rgsabound[0]\cElements 
        *Variant = *VariantArray\pvData + (i - 1) * 16
        Drive_Path$ = GetVariantString(*Variant)
      Next i
      
      AddElement(Drive_List())
      Drive_List()\Index_ID = x
      Drive_List()\Path_ID = Drive_Path$
      Drive_List()\Vendor_ID = VendorID$
      Drive_List()\Product_ID = ProductId$
      
      If get_drive <> "INITIAL"
        If Left(Drive_Path$,1) = get_drive
        index_drive.l = x
        Break
        EndIf
      EndIf 
    Else
    MessageRequester("Information", "Unable to find IMAPI recorder.", 0)
  EndIf
   
Next x

DiscMaster\Release()
Recorder\Release()
DataWriter_Format2Data\Release()

CoUninitialize_()

If get_drive <> "INITIAL"
    ProcedureReturn index_drive
  Else
    ProcedureReturn count
EndIf
EndProcedure

Procedure IsoToDisc(*td_iso.THREADDATA_ISO)
Protected var_iso1.s, var_iso2.l, var_iso3.l

  With *td_iso 
    var_iso1 = \item_iso1
    var_iso2 = \item_iso2
    var_iso3 = \item_iso3
  EndWith

pp.variant 
pp\vt = #VT_BSTR

strISOFile$ = var_iso1
Index = var_iso2

IsoBurnStream.IStream

CoInitialize_(0)

DiscMaster_obj()
DiscMaster\get_Item(Index,@pp\bstrval)

Recorder_obj()
Recorder\InitializeDiscRecorder(pp\bstrval)

DataWriter_Format2Data_obj()
DataWriter_Format2Data\put_Recorder(Recorder)

    DataWriter_Format2Data\get_CurrentPhysicalMediaType(@media_chk)
    
    mediacheck.l = Check_Media(media_chk)
    
    If mediacheck = #False                
      MessageRequester("Information", "Unknown media, no media, or unsupported media in recorder" +#CRLF$ +"Load a disc maybe?", 0)
      Recorder\EjectMedia()
      DiscMaster\Release()
      DataWriter_Format2Data\Release()
      Recorder\Release()
      KillThread(tidid)
    EndIf
    DataWriter_Format2Data\get_MediaHeuristicallyBlank(@hblank)
    DataWriter_Format2Data\get_MediaPhysicallyBlank(@blank)
    If blank = #VARIANT_FALSE And hblank = #VARIANT_FALSE
      MessageRequester("Information", "The disc is not blank! Please insert a blank disc and try again.", 0)
      Recorder\EjectMedia()
      DiscMaster\Release()
      DataWriter_Format2Data\Release()
      Recorder\Release()
      KillThread(tidid)
    EndIf
    
    DataWriter_Format2Data\IsCurrentMediaSupported(Recorder, @MediaSupported)
    If MediaSupported = #VARIANT_FALSE
    MessageRequester("Information", "Current media IS NOT supported.", 0)
    Recorder\EjectMedia()
    DiscMaster\Release()
    DataWriter_Format2Data\Release()
    Recorder\Release()   
    KillThread(tidcd)
    EndIf 

DataWriter_Format2Data\put_ClientName("PB_IMAPIv2")

CreateBurnIsoIStream(strISOFile$)

  If DataWriter_Format2Data\get_NextWritableAddress(Recorder) = #S_OK
    DataWriter_Format2Data\SetWriteSpeed($FFFFFFFF, #VARIANT_FALSE)
    DataWriter_Format2Data\Write(IsoBurnStream)
    MessageRequester("Information", "ISO was burned to recorder", 0)
    If var_iso3 = #True
    Eject_Drive(Index) ; see imapi2_include.pbi
    EndIf
  Else
    MessageRequester("Information", "Cannot write to disc. Is the disc empty?", 0)
    Eject_Drive(Index)
    DiscMaster\Release()
    DataWriter_Format2Data\Release()
    Recorder\Release()
    KillThread(tidid)
  EndIf
  
CoUninitialize_()

EndProcedure

Procedure EraseDisc(*td_ers.THREADDATA_ERS)
Protected var_ers1.l, var_ers2.l

  With *td_ers 
    var_ers1 = \item_ers1
    var_ers2 = \item_ers2
  EndWith

Index.l = var_ers2
pp.variant 
pp\vt = #VT_BSTR

CoInitialize_(0)

DiscMaster_obj()
DiscMaster\get_Item(Index,@pp\bstrval)

Recorder_obj()   
Recorder\InitializeDiscRecorder(pp\bstrval)

Format2Erase_obj()
Format2Erase\put_Recorder(Recorder)
Format2Erase\get_CurrentPhysicalMediaType(@media_chk)

mediacheck.l = Check_Media(media_chk)

If mediacheck = #False
  MessageRequester("Information", "Unknown media, no media, or unsupported media in recorder" +#CRLF$ +"or media is not eraseable" +#CRLF$ +"Load an eraseable disc maybe?", 0)
  Recorder\EjectMedia()
  DiscMaster\Release()
  Recorder\Release()   
  Format2Erase\Release()
  KillThread(tide)
EndIf

Format2Erase\put_ClientName("PB_IMAPIv2")
Format2Erase\put_FullErase(var_ers1)   
If Format2Erase\EraseMedia() = #S_OK
MessageRequester("Information", "Media erased.", 0)
Eject_Drive(Index)
EndIf

DiscMaster\Release()
Recorder\Release()   
Format2Erase\Release()


CoUninitialize_()
        
EndProcedure 

Procedure FolderToCD(*td_main.THREADDATA_MAIN)
Protected var_main1.s, var_main2.s, var_main3.s, var_main4.s, var_main5.l, var_main6.l, var_main7.l, var_main8.s, var_main9.l, var_main10.l, var_main11.l

  With *td_main 
    var_main1 = \item_main1 
    var_main2 = \item_main2 
    var_main3 = \item_main3
    var_main4 = \item_main4
    var_main5 = \item_main5
    var_main6 = \item_main6
    var_main7 = \item_main7
    var_main8 = \item_main8
    var_main9 = \item_main9
    var_main10 = \item_main10
    var_main11 = \item_main11
  EndWith

pp.variant 
pp\vt = #VT_BSTR

If var_main9 = #True
  file_boot$ = var_main8
EndIf

If var_main9 = #True And Len(file_boot$) <= 0
  MessageRequester("Information", "You elected to make a bootable CD\DVD but did not choose a boot file image." +#CRLF$ +"Select a boot image or un-check 'Include Boot Image'.", 0)
  KillThread(tidcd)
EndIf

Index = var_main11
Path$ = var_main3
Volume_Name$ = var_main2
Type_File_Sys.l = var_main5
BootImg.IStream
dataStream.IStream

CreateBurnIStream()

CoInitialize_(0)

  If DiscMaster_obj() = #S_OK
    If Recorder_obj() = #S_OK 
    DiscMaster\get_Item(Index,@pp\bstrval)
    Recorder\InitializeDiscRecorder(pp\bstrval)

      If var_main9 = #True And Len(file_boot$) > 0
        IBootOptions_obj()
        IBoot_Options\put_Manufacturer("Microsoft") 
        IBoot_Options\put_PlatformId(#PlatformX86)
        IBoot_Options\put_Emulation(#EmulationNone)
        CreateBootFileIStream(file_boot$)
        IBoot_Options\AssignBootImage(BootImg)
      EndIf
      
      If FileSystemImgage_obj() = #S_OK
      ; uncomment put_FreeMediaBlocks to fix size and comment SetMaxMediaBlocksFromDevice
        ;FileSystemImgage\put_FreeMediaBlocks($200000) ;about 4 GB size, max num blocks
        ; comment put_FreeMediaBlocks and uncomment SetMaxMediaBlocksFromDevice to have max blocks determined by IMAPI based on drive and media
        FileSystemImgage\SetMaxMediaBlocksFromDevice(Recorder)
      If Type_File_Sys = #FsiFileSystemNone
        FileSystemImgage\ChooseImageDefaults(Recorder)
      Else
        FileSystemImgage\put_FileSystemsToCreate(Type_File_Sys)
      EndIf
        FileSystemImgage\put_VolumeName(Volume_Name$)
        
        If var_main9 = #True And Len(file_boot$) > 0
          FileSystemImgage\put_BootImageOptions(IBoot_Options.IBootOptions)
        EndIf
        
        DIROBJroot_obj()
              
        If DataWriter_Format2Data_obj() = #S_OK
          DataWriter_Format2Data\put_Recorder(Recorder)
          
          ; check if Unknown media, no media, or unsupported/unrecognized media in drive
          DataWriter_Format2Data\get_CurrentPhysicalMediaType(@media_chk)
          mediacheck.l = Check_Media(media_chk)
                              
          If mediacheck = #False
            MessageRequester("Information", "Unknown media, no media, or unsupported media in recorder!" +#CRLF$ +"Load a disc maybe?", 0)
            Recorder\EjectMedia()
            FileSystemImgage\Release()
            DIROBJ\Release()
            DiscMaster\Release()
            Recorder\Release()   
            DataWriter_Format2Data\Release()
            KillThread(tidcd)
          EndIf
           
          
          DataWriter_Format2Data\IsCurrentMediaSupported(Recorder, @MediaSupported)
          If MediaSupported = #VARIANT_FALSE
          MessageRequester("Information", "Current media IS NOT supported.", 0)
          Recorder\EjectMedia()
          FileSystemImgage\Release()
          DIROBJ\Release()
          DiscMaster\Release()
          Recorder\Release()   
          DataWriter_Format2Data\Release()
          KillThread(tidcd)
          EndIf
                    
          DataWriter_Format2Data\put_ClientName("PB_IMAPIv2")
          DataWriter_Format2Data\SetWriteSpeed($FFFFFFFF, #VARIANT_FALSE)
          FileSystemImgage\ChooseImageDefaults(Recorder)
          DIROBJ\AddTree(Path$, var_main6)
          RESULT_image_obj()
          RESULT_image\get_ImageStream(@dataStream)
          DataWriter_Format2Data\put_ForceMediaToBeClosed(var_main10)
          
          DataWriter_Format2Data\write(dataStream)
 
        EndIf 
      EndIf
    EndIf
  EndIf

  If var_main7 = #True
    Recorder\EjectMedia()
  EndIf

FileSystemImgage\Release()
DIROBJ\Release()
DiscMaster\Release()
Recorder\Release()   
DataWriter_Format2Data\Release()

If var_main9 = #True And Len(file_boot$) > 0
  BootImg\Release()
EndIf 
dataStream\Release()

CoUninitialize_() 

EndProcedure

Procedure CreateISO(*td_main.THREADDATA_MAIN)
Protected var_main1.s, var_main2.s, var_main3.s, var_main4.s, var_main5.l, var_main6.l, var_main7.l, var_main8.s, var_main9.l, var_main10.l, var_main11.l

  With *td_main 
    var_main1 = \item_main1 
    var_main2 = \item_main2 
    var_main3 = \item_main3
    var_main4 = \item_main4
    var_main5 = \item_main5
    var_main6 = \item_main6
    var_main7 = \item_main7
    var_main8 = \item_main8
    var_main9 = \item_main9
    var_main10 = \item_main10
    var_main11 = \item_main11
  EndWith

isoStream.IStream 
dataStream.IStream
BootImg.IStream

If var_main9 = #True
  file_boot$ = var_main8
EndIf

If var_main9 = #True And Len(file_boot$) <= 0
  MessageRequester("Information", "You elected to make a bootable CD\DVD but did not choose a boot file image." +#CRLF$ +"Select a boot image or un-check 'Include Boot Image'.", 0)
  KillThread(tidiso)
EndIf  

Volume_Name$ = var_main2
isofile$ = var_main4 +var_main1 
foldertoiso$ = var_main3
Type_File_Sys.l = var_main5
CreateBurnIStream()
CreateIsoIStream(isofile$)

If var_main9 = #True And Len(file_boot$) > 0
  CreateBootFileIStream(file_boot$)
EndIf 
 
CoInitialize_(0) 
  
    If var_main9 = #True And Len(file_boot$) > 0
      If IBootOptions_obj() = #S_OK
        IBoot_Options\put_Manufacturer("Microsoft") 
        IBoot_Options\put_PlatformId(#PlatformX86)
        IBoot_Options\put_Emulation(#EmulationNone)
        IBoot_Options\AssignBootImage(BootImg)
      EndIf
    EndIf
        
    If FileSystemImgage_obj() = #S_OK
      FileSystemImgage\put_FreeMediaBlocks(0)
        If Type_File_Sys = #FsiFileSystemNone
          FileSystemImgage\put_FileSystemsToCreate(#FsiFileSystemUDF)
        Else
          FileSystemImgage\put_FileSystemsToCreate(Type_File_Sys)
        EndIf
      
      FileSystemImgage\put_VolumeName(Volume_Name$)
      If var_main9 = #True And Len(file_boot$) > 0 
        FileSystemImgage\put_BootImageOptions(IBoot_Options.IBootOptions)
      EndIf 
      
      DIROBJroot_obj()
      DIROBJ\AddTree(foldertoiso$, var_main6)
      DIROBJ\get_count(@dirinroot.l)
      RESULT_image_obj()
      RESULT_image\get_ImageStream(@dataStream)
      dataStream\Stat(st.STATSTG,#STATFLAG_NONAME)
      
      ret1.q
      ret2.q
      
      dataStream\copyto(isoStream,st\cbSize,@ret1,@ret2)
      FileSystemImgage\Release() 
    EndIf 
  
  If var_main9 = #True And Len(file_boot$) > 0
    IBoot_Options\Release()
  EndIf 

DIROBJ\Release() 
isoStream\Release() 
dataStream\Release() 

If var_main9 = #True And Len(file_boot$) > 0
  BootImg\Release()
EndIf

CoUninitialize_()
EndProcedure

If OpenWindow(#Window_0, 0, 0, 563, 390, "Folder Or ISO", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget| #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(#Window_0))
  GetDrive("INITIAL")
  imapi_drives.l = CountList(Drive_List())
  ButtonGadget(#Button_1,393, 40, 130, 30, "Select Source", #BS_HOLLOW|#BS_FLAT) : GadgetToolTip(#Button_1, "Click here to select the source folder.")
  ButtonGadget(#Button_2,393, 80, 130, 30, "Select ISO Destination", #BS_HOLLOW|#BS_FLAT) : GadgetToolTip(#Button_2, "Click here to select the destination of the .iso.")
  ButtonGadget(#Button_3,185, 270, 130, 30, "Select Boot Image", #BS_HOLLOW|#BS_FLAT) : GadgetToolTip(#Button_3, "Click here to select a boot image.")
  ButtonGadget(#Button_4,393, 250, 130, 30, "Create", #BS_HOLLOW|#BS_FLAT) : GadgetToolTip(#Button_4, "Click here to Create ISO.")
  ButtonGadget(#Button_5,25, 305, 90, 30, "Erase") : GadgetToolTip(#Button_5, "Click here to Erase.")
  ButtonGadget(#Button_6,393, 160, 130, 30, "Select ISO File") : GadgetToolTip(#Button_6, "Click here to select ISO file.")
  ButtonGadget(#Exit,393, 300,  130, 30, "Exit",#BS_HOLLOW|#BS_FLAT)
  
  CheckBoxGadget(#CheckBox_1, 30,  30, 90, 20, "ISO9660")
  CheckBoxGadget(#CheckBox_2, 30,  60, 90, 20, "UDF")
  CheckBoxGadget(#CheckBox_3, 30,  90, 90, 20, "Joliet")
  CheckBoxGadget(#CheckBox_4, 15,  145, 90, 20, "Add Only Files")
  CheckBoxGadget(#CheckBox_5, 15,  168, 95, 20, "Add Root Folder")
  CheckBoxGadget(#CheckBox_6, 15,  190, 98, 20, "Burn to CD/DVD")
  CheckBoxGadget(#CheckBox_7, 200,  180, 112, 20, "Eject disc after burn")
  CheckBoxGadget(#CheckBox_8, 150,  240, 110, 20, "Include boot image")
  CheckBoxGadget(#CheckBox_9, 420,  220, 85, 20, "Close the disc")
  CheckBoxGadget(#CheckBox_10, 30,  240, 90, 20, "Full Erase")
  CheckBoxGadget(#CheckBox_11, 30,  270, 90, 20, "Quick Erase")
  CheckBoxGadget(#CheckBox_12, 420,  130, 98, 20, "Burn ISO to Disc")
  
  ComboBoxGadget(#Drive_Select, 140, 145, 220, 100) : GadgetToolTip(#Drive_Select, "Select your CD\DVD recorder here with the pull down menu.")
  If imapi_drives => 1
      ForEach Drive_List()
        AddGadgetItem(#Drive_Select, -1,Drive_List()\Path_ID +"  " +Drive_List()\Vendor_ID +Drive_List()\Product_ID)
      Next
    SetGadgetState(#Drive_Select, 1)
    Else
    MessageRequester("Information", "No recordable drives found.", 0)
  EndIf
  
  Frame3DGadget(#Frame3D_1, 15, 10, 110, 130, "Select File System")
  Frame3DGadget(#Frame3D_2, 140, 10, 220, 110, "Enter ISO and Volume name")
  Frame3DGadget(#Frame3D_3, 375, 10, 170, 200, "Select Source and Destination")
  Frame3DGadget(#Frame3D_4, 140, 220, 220, 130, "Bootable CD/DVD Options")
  Frame3DGadget(#Frame3D_5, 15, 220, 110, 130, "CD/DVD Erase")
    
  StringGadget(#String_1,150,  30, 200, 20, "")
  StringGadget(#String_2,150,  80, 200, 20, "", #PB_String_UpperCase)
  ;IMAPI limits Volume ID length to 30 characters, if it contains only ASCII characters, and 16, if it contains Unicode characters.
  TextGadget(#Text_1, 150, 50, 200, 15, "Enter ISO name here..e.g..'MyIso'", #PB_Text_Center)
  TextGadget(#Text_2, 150, 100, 200, 15, "Enter Volume name here..e.g..'MyCD'", #PB_Text_Center)
  TextGadget(#Text_3, 20, 120, 100, 15, "(No check = System)")
  TextGadget(#Text_4, 150, 305, 150, 40, "Your boot image is:  ")
  TextGadget(#Text_5, 200, 130, 150, 30, "Select Recorder")

        Repeat
          Event = WaitWindowEvent()
          ventType = EventType()
          WindowID = EventWindow()
          GadgetID = EventGadget()
          
          Select Event
          
            Case #PB_Event_Gadget      
            
            Select EventGadget()
            
              Case #Drive_Select
                        Drive_String$ = GetGadgetText(#Drive_Select)
                        If Drive_String$ > ""
                        drive$ = Left(Drive_String$, 1)
                        recorder_index.l = GetDrive(drive$)
                        EndIf
            
              Case #String_1
                        SetGadgetColor(#String_1,#PB_Gadget_BackColor,RGB($FF, $FF, $00)) : Delay(1)
                        
              Case #String_2
                        SetGadgetColor(#String_2,#PB_Gadget_BackColor,RGB($FF, $FF, $00)) : Delay(1)
                        
              Case #CheckBox_1
                        iso_filesys.l = #FsiFileSystemISO9660
;                                                 
              Case #CheckBox_2
                        iso_filesys.l = #FsiFileSystemUDF
;                                                 
              Case #CheckBox_3
                        iso_filesys.l = #FsiFileSystemJoliet
;                                                 
              Case #CheckBox_4
                        SetGadgetState(#CheckBox_5, 0)
                                                
              Case #CheckBox_5
                        SetGadgetState(#CheckBox_4, 0)
                        
              Case #CheckBox_6
                         If GetGadgetState(#CheckBox_6) = 1
                         MessageRequester("Information", "Burn folder directly to CD/DVD selected", 0)
                         EndIf
                          
              Case #CheckBox_7
                        If GetGadgetState(#CheckBox_7) = 1
                        eject_yn.l = #True
                        Else
                        eject_yn.l = #False
                        EndIf
                        
              Case #CheckBox_8
                        If GetGadgetState(#CheckBox_8) = 1
                        MessageRequester("Information", "You have elected to make a bootable CD/DVD", 0)
                        EndIf
              
              Case #CheckBox_9
                        If GetGadgetState(#CheckBox_6) = 0
                        MessageRequester("Information", "You can only close a disc if burning directly to the disc." +#CRLF$ +"You can not close a disc if only creating an .iso file on the hard dive.", 0)
                        SetGadgetState(#CheckBox_9, 0)
                        EndIf
                        
              Case #CheckBox_10
                        SetGadgetState(#CheckBox_11, 0)
              
              Case #CheckBox_11
                        SetGadgetState(#CheckBox_10, 0)
                        
              Case #CheckBox_12
                        SetGadgetState(#CheckBox_1, 0)
                        SetGadgetState(#CheckBox_2, 0)
                        SetGadgetState(#CheckBox_3, 0)
                        SetGadgetState(#CheckBox_4, 0)
                        SetGadgetState(#CheckBox_5, 0)
                        SetGadgetState(#CheckBox_6, 0)
                        ;SetGadgetState(#CheckBox_7, 0)
                        SetGadgetState(#CheckBox_8, 0)
                        SetGadgetState(#CheckBox_9, 0)
                        SetGadgetState(#CheckBox_10, 0)
                        SetGadgetState(#CheckBox_11, 0)
              
              Case #Button_1
                        If GetGadgetState(#CheckBox_4) = 1
                          file_fold.l = #VARIANT_FALSE
                        EndIf
                        
                        If GetGadgetState(#CheckBox_5) = 1
                          file_fold.l = #VARIANT_TRUE
                        EndIf    
                        
                        InitialPath_Source$ = "C:\"
                        Path_Source$ = PathRequester("Please select your Source folder", InitialPath_Source$)
                        
                        If Path_Source$
                          MessageRequester("Information", "Your Source folder is:"+#CRLF$+Path_Source$, 0)
                        Else
                          MessageRequester("Information", "The request was canceled.", 0) 
                        EndIf

              Case #Button_2
                        If GetGadgetState(#CheckBox_6) = 0
                          InitialPath_Dest$ = "C:\"
                          Path_Dest$ = PathRequester("Please select your ISO Destination", InitialPath_Dest$)
                          If Path_Dest$
                            MessageRequester("Information", "Your Destination folder is:"+#CRLF$+Path_Dest$, 0)
                            Else
                            MessageRequester("Information", "The request was canceled.", 0) 
                          EndIf
                        EndIf
                        
                        If GetGadgetState(#CheckBox_6) = 1
                        Path_Dest$ = "CD/DVD Recorder"
                            MessageRequester("Information", "Destination is CD/DVD Recorder.", 0)
                        EndIf

              Case #Button_3
                         If GetGadgetState(#CheckBox_8) = 1
                           InitialPath_Img$ = "C:\"
                           boot_img$ = OpenFileRequester("Select a boot image", InitialPath_Img$, "*.*", 0)
                         Else
                          boot_img$ = ""
                         EndIf
                         
                         If GetGadgetState(#CheckBox_8) = 1 And Len(boot_img$) > 0
                           boot_img_file$ = GetFilePart(boot_img$)
                           SetGadgetText(#Text_4, "Your boot image is:   " +boot_img_file$)
                         EndIf
                                                    
              Case #Button_4
                        If GetGadgetState(#CheckBox_6) = 1
                          Path_Dest$ = "CD/DVD Burn"
                        ISO_Name$ = GetGadgetText(#String_1)
                          If ISO_Name$ = ""
                              ISO_name$ = "My_iso.iso" 
                              Else
                              ISO_name$ = ISO_Name$ +".iso"
                          EndIf
                          Vol_Name$ = GetGadgetText(#String_2)
                          If Vol_Name$ = ""
                            Vol_Name$ = "My_Folder"
                            Else
                            Vol_Name$ = Vol_Name$
                          EndIf
                        EndIf   
                        
                          If Len(Path_Source$) = 0 And Len(Path_Dest$) = 0 And GetGadgetState(#CheckBox_6) = 0
                          MessageRequester("Information", "Select a Source and Destination."+#CRLF$+Path_Dest$, 0)
                            Else
                              If Len(Path_Source$) = 0 And Len(Path_Dest$) > 0 And GetGadgetState(#CheckBox_6) = 0
                                MessageRequester("Information", "Select a Source folder."+#CRLF$+Path_Dest$, 0)
                              Else
                                If Len(Path_Source$) > 0 And Len(Path_Dest$) = 0 And GetGadgetState(#CheckBox_6) = 0
                                  MessageRequester("Information", "Select a Destination."+#CRLF$+Path_Dest$, 0)
                                Else
                                  If Len(Path_Source$) > 0 And Len(Path_Dest$) > 0 And GetGadgetState(#CheckBox_6) = 0
                                    ISO_Name$ = GetGadgetText(#String_1)
                                      If ISO_Name$ = ""
                                          ISO_name$ = "My_iso.iso" 
                                        Else
                                          ISO_name$ = ISO_Name$ +".iso"
                                      EndIf
                                          Vol_Name$ = GetGadgetText(#String_2)
                                      If Vol_Name$ = ""
                                          Vol_Name$ = "My_Folder_ISO"
                                        Else
                                          Vol_Name$ = Vol_Name$
                                      EndIf
                                  EndIf
                                EndIf
                              EndIf
                          EndIf 
                                    
                        If GetGadgetState(#CheckBox_8) = 1
                            boot_img_yn.l = #True
                          Else
                            boot_img_yn.l = #False
                        EndIf
                        
                        If GetGadgetState(#CheckBox_9) = 1
                          close_yn.l = #VARIANT_TRUE
                          Else
                          close_yn.l = #VARIANT_FALSE
                        EndIf
                        
                        ; If you're burning more than 2 GB of data to the DVD, you must set the File System to #FsiFileSystemUDF.
                        ; The renaming of long file names occur for ISO9660 file system per restriction of the file name length to 8+3 format. 
                        ; Use either UDF (preferred) Or ISO9660+Joliet To avoid renaming. 
                        ; If you don't have expetise in file systems call IFileSystemImage\ChooseImageDefaults(Recorder) to have IMAPI select the best file system for you.
                        
                        If GetGadgetState(#CheckBox_1) = 0 And GetGadgetState(#CheckBox_2) = 0 And GetGadgetState(#CheckBox_3) = 0
                          iso_filesys.l = #FsiFileSystemNone
                        EndIf
                        
                        If GetGadgetState(#CheckBox_1) = 1 And GetGadgetState(#CheckBox_2) = 1 And GetGadgetState(#CheckBox_3) = 1
                          iso_filesys.l = #FsiFileSystemISO9660 | #FsiFileSystemUDF | #FsiFileSystemJoliet
                        Else
                          iso_filesys.l = iso_filesys.l
                        EndIf
                        
                        If GetGadgetState(#CheckBox_1) = 1 And GetGadgetState(#CheckBox_2) = 1 And GetGadgetState(#CheckBox_3) = 0
                          iso_filesys.l = #FsiFileSystemISO9660 | #FsiFileSystemUDF
                        Else
                          iso_filesys.l = iso_filesys.l
                        EndIf
                        
                        If GetGadgetState(#CheckBox_1) = 1 And GetGadgetState(#CheckBox_2) = 0 And GetGadgetState(#CheckBox_3) = 1
                          iso_filesys.l = #FsiFileSystemISO9660 | #FsiFileSystemJoliet
                        Else
                          iso_filesys.l = iso_filesys.l
                        EndIf
                        
                        If GetGadgetState(#CheckBox_1) = 0 And GetGadgetState(#CheckBox_2) = 1 And GetGadgetState(#CheckBox_3) = 1
                          iso_filesys.l = #FsiFileSystemUDF | #FsiFileSystemJoliet
                        Else
                          iso_filesys.l = iso_filesys.l
                        EndIf
                        
                        If Len(ISO_Name$) > 0 And Len(Vol_Name$) > 0 And Len(Path_Source$) > 0 And Len(Path_Dest$) >0 And iso_filesys >= 0

                          var_main.THREADDATA_MAIN 
                          With var_main 
                            \item_main1 = ISO_Name$ 
                            \item_main2 = Vol_Name$ 
                            \item_main3 = Path_Source$
                            \item_main4 = Path_Dest$
                            \item_main5 = iso_filesys
                            \item_main6 = file_fold
                            \item_main7 = eject_yn
                            \item_main8 = boot_img$
                            \item_main9 = boot_img_yn
                            \item_main10 = close_yn
                            \item_main11 = recorder_index
                          EndWith
                          
                          If GetGadgetState(#CheckBox_6) = 1 And GetGadgetState(#CheckBox_4) = 1
                              tidcd = CreateThread(@FolderToCD(), var_main)
                            Else
                              If GetGadgetState(#CheckBox_6) = 1 And GetGadgetState(#CheckBox_5) = 1
                              tidcd = CreateThread(@FolderToCD(), var_main)
                              Else
                                If GetGadgetState(#CheckBox_6) = 1 And GetGadgetState(#CheckBox_4) = 0 And GetGadgetState(#CheckBox_5) = 0
                                  MessageRequester("Information", "You did not elect 'Add only Files' or 'Add Root Folder'.", 0)
                                EndIf
                              EndIf
                          EndIf
                          
                          If GetGadgetState(#CheckBox_6) = 0 And GetGadgetState(#CheckBox_4) = 1
                            tidiso = CreateThread(@CreateISO(), var_main)
                            Else
                              If GetGadgetState(#CheckBox_6) = 0 And GetGadgetState(#CheckBox_5) = 1
                                tidiso = CreateThread(@CreateISO(), var_main)
                              Else
                                If GetGadgetState(#CheckBox_6) = 0 And GetGadgetState(#CheckBox_4) = 0 And GetGadgetState(#CheckBox_5) = 0 
                                  MessageRequester("Information", "You did not elect 'Add only Files' or 'Add Root Folder'.", 0)
                                EndIf
                              EndIf
                          EndIf  
                        EndIf
                                      
              Case #Button_5
                        If GetGadgetState(#CheckBox_10) = 1
                            erase_x.l = #VARIANT_TRUE
                          Else
                            If GetGadgetState(#CheckBox_11) = 1
                            erase_x.l = #VARIANT_FALSE
                            EndIf
                        EndIf
                        
                          var_ers.THREADDATA_ERS 
                          With var_ers 
                            \item_ers1 = erase_x 
                            \item_ers2 = recorder_index 
                          EndWith
                          
                        tide = CreateThread(@EraseDisc(), var_ers)
                        
              Case #Button_6
                        If GetGadgetState(#CheckBox_12) = 1
                          InitialPath_Img$ = "C:\"
                          Pattern$ = "ISO (*.iso)|*.iso"
                          ISO_File$ = OpenFileRequester("Select an ISO File", InitialPath_Img$, Pattern$, 0)
                        EndIf
                        
                          var_iso.THREADDATA_ISO 
                          With var_iso 
                            \item_iso1 = ISO_File$ 
                            \item_iso2 = recorder_index
                            \item_iso3 = eject_yn
                          EndWith
                        
                        If Len(ISO_File$) <= 0
                          MessageRequester("Information", "You did not select an.iso image.", 0)
                        Else
                          tidid = CreateThread(@IsoToDisc(), var_iso)
                        EndIf 
              
              Case #Exit
              End
                       
            EndSelect
          EndSelect
        Until Event = #PB_Event_CloseWindow
EndIf

Posted: Sun Jan 20, 2008 12:44 am
by SFSxOI
And, another example, needs the 'imapi2_include.pbi' include from a few posts above this one. (this was previously posted in the post with the include file but its been updated a little for use with the include file)

Code: Select all

; Enumerate_CD_DVD_properties.pb v 1.1 - 19 Jan 2008
; for PureBasic using version 4.10
; by SFSxOI
; needs - imapi2_include.pbi

XIncludeFile "imapi2_include.pbi"

pp.variant 
pp\vt = #VT_BSTR

Variant.VARIANT 
*VariantArray.SAFEARRAY

CoInitialize_(0)

DiscMaster_obj() ; create a IDiscMaster2 object called DiscMaster
DiscMaster\get_Count(@count) ; use our IDiscMaster2 object to get the number of computer recorders
; get_Count always starts counting at 1

For x = 0 To count ; 0 to number of computer recorders
; the index for recorders always starts at 0, get_Count only gives the number of recorders and not the index of recorders
; this is why 'x = 0 To count' starts at 0 and not 1 'cause we want enumeration of the index of recorders not the number of recorders
; and x becomes the UniqueID of our recorders getting a different recorder each iteration thru the loop
; i.e...first time = recorder at index 0, second time thru = recorder at index 1..up to the number of recorders from 'count'
; below in the line 'DiscMaster\get_Item(x,@pp\bstrval)' we use 'x' which gives us the UniqueID out in pp\bstrval where 'x' = the recorder index,
; then we use 'Recorder\InitializeDiscRecorder(pp\bstrval)' to initialize that particular recorder so we can use it for our purpose
; first recoder is always index 0
  If x = count
  Break
  EndIf
  Recorder_obj() ; Create a IDiscRecorder2 object called Recorder
  Format2Erase_obj() ; Create a IDiscFormat2Erase object called Format2Erase
    DiscMaster\get_Item(x,@pp\bstrval)
    Recorder\InitializeDiscRecorder(pp\bstrval)
    Format2Erase\put_Recorder(Recorder)
    
    Debug "drive:   " +Str(x) +"   is ID:    " +sfs_Uni2Ansi(pp\bstrval)
    med_type = Format2Erase\get_CurrentPhysicalMediaType(@mediaType)
        
    Select mediaType
    
      Case #IMAPI_MEDIA_TYPE_UNKNOWN
      Debug "Media Type is unknown media type or the recorder is empty"
      
      Case #IMAPI_MEDIA_TYPE_CDROM
      Debug "Media Type is CD-ROM or CD-R/RW"
      
      Case #IMAPI_MEDIA_TYPE_CDR
      Debug "Media Type write once (CD-R) media"
      
      Case #IMAPI_MEDIA_TYPE_CDRW
      Debug "Media Type is rewritable (CD-RW) media"
      
      Case #IMAPI_MEDIA_TYPE_DVDROM
      Debug "Either the DVD drive or DVD media is read-only"
      
      Case #IMAPI_MEDIA_TYPE_DVDRAM
      Debug "Media Type is DVD-RAM"
      
      Case #IMAPI_MEDIA_TYPE_DVDPLUSR
      Debug "Media Type is write once media that supports the DVD plus format (DVD+R)"
      
      Case #IMAPI_MEDIA_TYPE_DVDPLUSRW
      Debug "Media Type is rewritable media that supports the DVD plus format (DVD+RW)"
      
      Case #IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER
      Debug "Media Type is write once dual layer media that supports the DVD plus format (DVD+R DL)"
      
      Case #IMAPI_MEDIA_TYPE_DVDDASHR
      Debug "Media Type is write once media DVD dash format (DVD-R)"
      
      Case #IMAPI_MEDIA_TYPE_DVDDASHRW
      Debug "Media Type is rewritable media that supports the DVD dash format (DVD-RW)"
      
      Case #IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER
      Debug "Media Type is write once media that supports the DVD dash format (DVD-R DL)"
      
      Case #IMAPI_MEDIA_TYPE_DISK
      Debug "Media Type supports random-access writes and identifies and avoids using damaged tracks"
      
      Case #IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER
      Debug "Media Type is rewritable dual layer media that supports the DVD plus format (DVD+RW DL)"
      
      Case #IMAPI_MEDIA_TYPE_HDDVDROM
      Debug "Media Type is high definition Read only DVD media (HD DVD-ROM)"
      
      Case #IMAPI_MEDIA_TYPE_HDDVDR
      Debug "Media Type is write once high definition media (HD DVD-R)"
      
      Case #IMAPI_MEDIA_TYPE_HDDVDRAM
      Debug "Media Type is random access high definition media (HD DVD-RAM)"
      
      Case #IMAPI_MEDIA_TYPE_BDROM
      Debug "Media Type is read only Blu-ray media (BD-ROM)"
      
      Case #IMAPI_MEDIA_TYPE_BDR
      Debug "Media Type is write once Blu-ray media (BD-R)"
      
      Case #IMAPI_MEDIA_TYPE_BDRE
      Debug "Media Type is rewritable Blu-ray media (BD-RE)"
      
      ; #IMAPI_MEDIA_TYPE_MAX=19 no media here, just the max limit
    
    EndSelect
    
    Recorder\get_VendorId(@pp\bstrval) 
    Debug sfs_Uni2Ansi(pp\bstrval)
    Recorder\get_ProductId(@pp\bstrval)
    Debug sfs_Uni2Ansi(pp\bstrval)
    Recorder\get_ProductRevision(@pp\bstrval)
    Debug sfs_Uni2Ansi(pp\bstrval)
    Recorder\get_VolumeName(@pp\bstrval)
    Debug sfs_Uni2Ansi(pp\bstrval)
    
    Recorder\get_VolumePathNames(@value.SAFEARRAY)
    Variant\parray = PeekL(value)
    *VariantArray = Variant\parray
    For i = 1 To *VariantArray\rgsabound[0]\cElements 
      *Variant = *VariantArray\pvData + (i - 1) * 16 
      Debug "Your Drive Path is:   " +GetVariantString(*Variant) 
    Next i 
    
    DiscMaster\get_IsSupportedEnvironment(@value_support)
    
    Select value_support
    
      Case #VARIANT_TRUE
      Debug "Environment is supported!"
      
      Case #VARIANT_FALSE
      Debug "Environment IS NOT supported!"
          
    EndSelect
    
    Recorder\get_DeviceCanLoadMedia(@CanLoad)
    
    Select CanLoad
    
      Case #VARIANT_TRUE
      Debug "Device can eject and reload media!"
      
      Case #VARIANT_FALSE
      Debug "Device CAN NOT eject and reload media!"
          
    EndSelect
    
    Recorder\get_LegacyDeviceNumber(@legacy_num)
    Debug "Legacy number is:    " +Str(legacy_num)
    
    Format2Erase\IsRecorderSupported(Recorder, @record_support)
    
    Select record_support
    
      Case #VARIANT_TRUE
      Debug "Recorder is a supported IMAPI drive"
      
      Case #VARIANT_FALSE
      Debug "Recorder IS NOT A SUPPORTED IMAPI drive"
      Default
        Debug "IMAPI support for this drive is unknown"
          
    EndSelect
    
    Recorder\get_ActiveDiscRecorder(@pp\bstrval)
    Debug "Active Recorder is:    " +sfs_Uni2Ansi(pp\bstrval)
    
    Recorder\get_SupportedProfiles(@val.SAFEARRAY)
    Variant\parray = PeekL(val)
    *VariantArray = Variant\parray
    Debug ""
    Debug "**************Drive Profiles*****************"
    For i = 1 To *VariantArray\rgsabound[0]\cElements 
      *Variant = *VariantArray\pvData + (i - 1) * 16
       
      profiles_x.l = Val(GetVariantString(*Variant))
      
        Select profiles_x
          
          Case #IMAPI_PROFILE_TYPE_INVALID
             Debug "The profile is not valid." 
          Case #IMAPI_PROFILE_TYPE_NON_REMOVABLE_DISK
            Debug "The disc is not removable media" 
          Case #IMAPI_PROFILE_TYPE_REMOVABLE_DISK
            Debug "The disc is removable media" 
          Case #IMAPI_PROFILE_TYPE_MO_ERASABLE
            Debug "An Magneto-Optical Erasable drive" 
          Case #IMAPI_PROFILE_TYPE_MO_WRITE_ONCE
            Debug "A write once optical drive."
          Case #IMAPI_PROFILE_TYPE_AS_MO
            Debug "An advance storage Magneto-Optical drive." 
          Case #IMAPI_PROFILE_TYPE_CDROM 
            Debug "A CD-ROM drive."
          Case #IMAPI_PROFILE_TYPE_CD_RECORDABLE
            Debug "A CD-R drive." 
          Case #IMAPI_PROFILE_TYPE_CD_REWRITABLE
            Debug "A CD-RW or CD+RW drive." 
          Case #IMAPI_PROFILE_TYPE_DVDROM
            Debug "A DVD-ROM drive."
          Case #IMAPI_PROFILE_TYPE_DVD_DASH_RECORDABLE
            Debug "A DVD-R sequential recording drive."
          Case #IMAPI_PROFILE_TYPE_DVD_RAM
            Debug "A DVD-RAM drive." 
          Case #IMAPI_PROFILE_TYPE_DVD_DASH_REWRITABLE
            Debug "A DVD-RW restricted overwrite drive." 
          Case #IMAPI_PROFILE_TYPE_DVD_DASH_RW_SEQUENTIAL
            Debug "A DVD-RW sequential recording drive." 
          Case #IMAPI_PROFILE_TYPE_DVD_DASH_R_DUAL_SEQUENTIAL
            Debug "A DVD-R dual layer sequential recording drive." 
          Case #IMAPI_PROFILE_TYPE_DVD_DASH_R_DUAL_LAYER_JUMP
            Debug "A DVD-R dual layer jump recording drive." 
          Case #IMAPI_PROFILE_TYPE_DVD_PLUS_RW
            Debug "A DVD+RW drive." 
          Case #IMAPI_PROFILE_TYPE_DVD_PLUS_R
            Debug "A DVD+R drive."
          Case #IMAPI_PROFILE_TYPE_DVD_PLUS_RW_DUAL
            Debug "A DVD+RW dual layer drive." 
          Case #IMAPI_PROFILE_TYPE_DVD_PLUS_R_DUAL
            Debug "A DVD+R dual layer drive."
          Case #IMAPI_PROFILE_TYPE_BD_ROM
            Debug "A Blu-ray read only drive." 
          Case #IMAPI_PROFILE_TYPE_BD_R_SEQUENTIAL
            Debug "A write once Blu-ray drive with sequential recording." 
          Case #IMAPI_PROFILE_TYPE_BD_R_RANDOM_RECORDING
            Debug "A write once Blu-ray drive with random-access recording capability." 
          Case #IMAPI_PROFILE_TYPE_BD_REWRITABLE
            Debug "A rewritable Blu-ray drive." 
          Case #IMAPI_PROFILE_TYPE_HD_DVD_ROM
            Debug "A read only high density DVD." 
          Case #IMAPI_PROFILE_TYPE_HD_DVD_RECORDABLE
            Debug "A write once high density DVD." 
          Case #IMAPI_PROFILE_TYPE_HD_DVD_RAM
            Debug "A high density DVD with random access positioning." 
          Case #IMAPI_PROFILE_TYPE_NON_STANDARD
            Debug "Nonstandard drive."
          Default
            Debug "No Supported Profiles"
         
        EndSelect
 
    Next i
    
    Recorder\get_SupportedModePages(@valx.SAFEARRAY)
    Variant\parray = PeekL(valx)
    *VariantArray = Variant\parray
    Debug ""
    Debug "**************Supported Mode pages*****************"
    For i = 1 To *VariantArray\rgsabound[0]\cElements 
      *Variant = *VariantArray\pvData + (i - 1) * 16
       
      modes_x.l = Val(GetVariantString(*Variant))
      
      Select modes_x
      
        Case #IMAPI_MODE_PAGE_TYPE_READ_WRITE_ERROR_RECOVERY
          Debug "The mode page specifies the error recovery parameters the drive uses during any command that performs a data read or write operation from the media." 
        Case #IMAPI_MODE_PAGE_TYPE_MRW
          Debug "The mode page provides a method by which the host may control the special features of a MRW CD-RW Drive." 
        Case #IMAPI_MODE_PAGE_TYPE_WRITE_PARAMETERS
          Debug "The mode page provides parameters that are often needed in the execution of commands that write to the media." 
        Case #IMAPI_MODE_PAGE_TYPE_CACHING
          Debug "The mode page contains parameters to enable or disable caching during read or write operations." 
        Case #IMAPI_MODE_PAGE_TYPE_INFORMATIONAL_EXCEPTIONS
          Debug "The mode page contains parameters for exception reporting mechanisms that result in specific sense code errors when failures are predicted. This mode page is related to the S.M.A.R.T. feature." 
        Case #IMAPI_MODE_PAGE_TYPE_TIMEOUT_AND_PROTECT
          Debug "The mode page contains command time-out values that are suggested by the device." 
        Case #IMAPI_MODE_PAGE_TYPE_POWER_CONDITION
          Debug "The mode page contains power management settings for the drive. The parameters define how long the logical unit delays before changing its internal power state."
        Case #IMAPI_MODE_PAGE_TYPE_LEGACY_CAPABILITIES
          Debug "The mode page contains legacy device capabilities. These are superseded by the feature pages returned through the GetConfiguration command."

      EndSelect

    Next i
    
    Recorder\get_CurrentFeaturePages(@valy.SAFEARRAY)
    Variant\parray = PeekL(valy)
    *VariantArray = Variant\parray
    Debug ""
    Debug "**************Current Feature pages*****************"
    For i = 1 To *VariantArray\rgsabound[0]\cElements 
      *Variant = *VariantArray\pvData + (i - 1) * 16
      feature_x.l = Val(GetVariantString(*Variant))
      
        Select feature_x
   
          Case #IMAPI_FEATURE_PAGE_TYPE_PROFILE_LIST
            Debug "Identifies profiles supported by the logical unit."
          Case #IMAPI_FEATURE_PAGE_TYPE_CORE
            Debug "Supports functionality common to all devices." 
          Case #IMAPI_FEATURE_PAGE_TYPE_MORPHING
            Debug "Has the ability to notify an initiator about operational changes and accept initiator requests to prevent operational changes." 
          Case #IMAPI_FEATURE_PAGE_TYPE_REMOVABLE_MEDIUM
            Debug "Has a medium that is removable."
          Case #IMAPI_FEATURE_PAGE_TYPE_WRITE_PROTECT
            Debug "Has changing capability for write protection status of the logical unit." 
          Case #IMAPI_FEATURE_PAGE_TYPE_RANDOMLY_READABLE
            Debug "Able to read data from logical blocks specified by Logical Block Addresses." 
          Case #IMAPI_FEATURE_PAGE_TYPE_CD_MULTIREAD
            Debug "Conforms to the OSTA Multi-Read specification 1.00, with the exception of CD Play capability (the CD Audio Feature is not required)." 
          Case #IMAPI_FEATURE_PAGE_TYPE_CD_READ
            Debug "Able to read CD specific information from the media and is able to read user data from all types of CD blocks."
          Case #IMAPI_FEATURE_PAGE_TYPE_DVD_READ
            Debug "Able to read DVD specific information from the media." 
          Case #IMAPI_FEATURE_PAGE_TYPE_RANDOMLY_WRITABLE
            Debug "Able to write data to logical blocks specified by Logical Block Addresses." 
          Case #IMAPI_FEATURE_PAGE_TYPE_INCREMENTAL_STREAMING_WRITABLE
            Debug "Able to write data to a contiguous region, and is able to append data to a limited number of locations on the media." 
          Case #IMAPI_FEATURE_PAGE_TYPE_SECTOR_ERASABLE
            Debug "Supports erasable media and media that requires an erase pass before overwrite, such as some magneto-optical technologies"
          Case #IMAPI_FEATURE_PAGE_TYPE_FORMATTABLE
            Debug "Can format media into logical blocks." 
          Case #IMAPI_FEATURE_PAGE_TYPE_HARDWARE_DEFECT_MANAGEMENT
            Debug "Has defect management available to provide a defect-free contiguous address space." 
          Case #IMAPI_FEATURE_PAGE_TYPE_WRITE_ONCE
            Debug "Has the ability to record to any previously unrecorded logical block."
          Case #IMAPI_FEATURE_PAGE_TYPE_RESTRICTED_OVERWRITE
            Debug "Has the ability to overwrite logical blocks only in fixed sets at a time." 
          Case #IMAPI_FEATURE_PAGE_TYPE_CDRW_CAV_WRITE
            Debug "Has the ability to write CD-RW media that is designed for CAV recording."
          Case #IMAPI_FEATURE_PAGE_TYPE_MRW
            Debug "Capable of reading a disc with the MRW format." 
          Case #IMAPI_FEATURE_PAGE_TYPE_ENHANCED_DEFECT_REPORTING
            Debug "Has the ability to perform media certification and recovered error reporting for logical unit assisted software defect management."
          Case #IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_RW
            Debug "Capable of reading a recorded DVD+RW disc."
          Case #IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R
            Debug "Capable of reading a recorded DVD+R disc." 
          Case #IMAPI_FEATURE_PAGE_TYPE_RIGID_RESTRICTED_OVERWRITE
            Debug "Has the ability to perform writing only on Blocking boundaries." 
          Case #IMAPI_FEATURE_PAGE_TYPE_CD_TRACK_AT_ONCE
            Debug "Able to write data to a CD track."
          Case #IMAPI_FEATURE_PAGE_TYPE_CD_MASTERING
            Debug "Able to write a CD in Session at Once mode or Raw mode." 
          Case #IMAPI_FEATURE_PAGE_TYPE_DVD_DASH_WRITE
            Debug "Has the ability to write data to DVD-R/-RW in Disc at Once mode." 
          Case #IMAPI_FEATURE_PAGE_TYPE_LAYER_JUMP_RECORDING
            Debug "Able to write data to contiguous regions that are allocated on multiple layers, and is able to append data to a limited number of locations on the media." 
          Case #IMAPI_FEATURE_PAGE_TYPE_CD_RW_MEDIA_WRITE_SUPPORT
            Debug "Has the ability to perform writing CD-RW media." 
          Case #IMAPI_FEATURE_PAGE_TYPE_BD_PSEUDO_OVERWRITE
            Debug "Provides Logical Block overwrite service on BD-R discs that are formatted as SRM+POW."
          Case #IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R_DUAL_LAYER
            Debug "Capable of reading a recorded DVD+R Double Layer disc" 
          Case #IMAPI_FEATURE_PAGE_TYPE_BD_READ
            Debug "Able to read control structures and user data from the Blu-ray disc."
          Case #IMAPI_FEATURE_PAGE_TYPE_BD_WRITE
            Debug "Able to write control structures and user data to certain Blu-ray discs." 
          Case #IMAPI_FEATURE_PAGE_TYPE_HD_DVD_READ
            Debug "Able to read HD DVD specific information from the media." 
          Case #IMAPI_FEATURE_PAGE_TYPE_HD_DVD_WRITE
            Debug "Has the ability to write to HD DVD-R/-RW media." 
          Case #IMAPI_FEATURE_PAGE_TYPE_POWER_MANAGEMENT
            Debug "Able to perform initiator and logical unit directed power management." 
          Case #IMAPI_FEATURE_PAGE_TYPE_SMART
            Debug "Able to perform Self-Monitoring Analysis and Reporting Technology (S.M.A.R.T.)."
          Case #IMAPI_FEATURE_PAGE_TYPE_EMBEDDED_CHANGER
            Debug "Able to move media from a storage area to a mechanism and back." 
          Case #IMAPI_FEATURE_PAGE_TYPE_CD_ANALOG_PLAY
            Debug "Able to play CD Audio data directly to an external output." 
          Case #IMAPI_FEATURE_PAGE_TYPE_MICROCODE_UPDATE
            Debug "Able to upgrade its internal microcode via the interface." 
          Case #IMAPI_FEATURE_PAGE_TYPE_TIMEOUT
            Debug "Able to always respond to commands within a set time period."
          Case #IMAPI_FEATURE_PAGE_TYPE_DVD_CSS
            Debug "Able to perform DVD CSS/CPPM authentication and key management. This feature also indicates that the logical unit supports CSS for DVD-Video and CPPM for DVD-Audio." 
          Case #IMAPI_FEATURE_PAGE_TYPE_REAL_TIME_STREAMING
            Debug "Able to perform reading and writing within initiator specified (and logical unit verified) performance ranges and supports the stream playback operation." 
          Case #IMAPI_FEATURE_PAGE_TYPE_LOGICAL_UNIT_SERIAL_NUMBER
            Debug "Has a unique serial number." 
          Case #IMAPI_FEATURE_PAGE_TYPE_MEDIA_SERIAL_NUMBER
            Debug "Capable of reading a media serial number of the currently installed media."
          Case #IMAPI_FEATURE_PAGE_TYPE_DISC_CONTROL_BLOCKS
            Debug "Able to read and/or write Disc Control Blocks from or to the media." 
          Case #IMAPI_FEATURE_PAGE_TYPE_DVD_CPRM
            Debug "Able to perform DVD CPRM and is able to perform CPRM authentication and key management."
          Case #IMAPI_FEATURE_PAGE_TYPE_FIRMWARE_INFORMATION
            Debug "Provides the date and time of the creation of the current firmware revision loaded on the device." 
          Case #IMAPI_FEATURE_PAGE_TYPE_AACS
            Debug "Supports AACS and is able to perform AACS authentication process."
          Case #IMAPI_FEATURE_PAGE_TYPE_VCPS
            Debug "Able To process disc Data structures that are specified in the VCPS."
          Default
            Debug "No Current Feature pages"
  
      EndSelect
    
    Next i 

Next x

DiscMaster\Release()
Recorder\Release()   
Format2Erase\Release()

CoUninitialize_()
        
End

Posted: Sun Jan 20, 2008 2:31 am
by harff182
FMPOV: well done :)

My next suggestion:

Resul$ = get_IncludeVersion()

With this function, it can be tested, whether a tester is using the right version of the Include or if he (at this moment me :oops: ) missed a new version ;)

Posted: Sun Jan 20, 2008 6:30 pm
by SFSxOI
thanks harff182

Updated the include file, edited a few posts up to the new version.

Added a few helper functions for creating streams, cleaned up a little, removed a stucture that wasn't needed, changed layout some to put enumerations and constants first for the helper functions.

Also updated the example application above to use the new include version, previous versions should continue to work tho and if not then look at the new include file for any changes to helper procedures used in the previous version but there shouldn't be any changes needed. Added a few checks in the new example app to prevent crashes when no files are selected when the user cancels selection. Yes, it still uses the same ugly bloated test GUI, so if someone wants to come up with a nice one that would be OK too.

had a question from someone about why I ran the procedures in a seperate thread, for example:

Code: Select all

tid = CreateThread(@FolderToCD(), var)

where tid = the thread ID
Simply, the reason i'm running the procedures in another thread; IMAPI is very greedy, it wants to consume as much of the thread resources as possible which means that any GUI will become un-responsive if its in the same thread, it does not share well with other things in the same thread. Running the procedures in a seperate thread prevents the GUI from becoming un-responsive, allows for callback procedures (which I have not added) for monitoring things like burn speed and progress, and allows IMAPI to be happy with what its doing which increases its effectiveness. Its also eaisier on system resources when it runs in its own thread. This is the same thing that commercially available applications do to keep IMAPI happy and their GUI's responsive.