Page 3 of 4

Posted: Mon Jan 21, 2008 4:50 pm
by SFSxOI
Updated the sample app code in posts above, included the ability to select specific recorder for multiple recorder computers. Yes, still the same ugly and bloated GUI but with the drive selection added and a few things re-arranged.

Posted: Tue Jan 22, 2008 12:07 am
by SFSxOI
Updating the example app again in this post, but its changed somewhat from the one a few posts above. The below example adds some very basic common 'gotcha' error trapping things by using some filtering of common conditions that exist instead of using error code trapping. In the example below in some of the procedures I use the IMAPIv2 constants to filter for if certain conditions exist like no CD in the drive or if a disc is actually eraseable. I also added the MS default file system recommendations if no file system is selected, one of which is #FsiFileSystemUDF and the other is letting IMAPI decide the best file system to use by the use of the 'ChooseImageDefaults' method.

Code: Select all

; IMAPIv2 sample app for Vista and winXP SP2 v 1.6 - 22 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_0
  #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
  #Text_6
  #Text_7
  #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
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

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

pp.variant 
pp\vt = #VT_BSTR

Index = var_iso2
strISOFile$ = var_iso1

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_unkx)
    If media_unkx = #IMAPI_MEDIA_TYPE_UNKNOWN
      MessageRequester("Information", "Unknown media type or no media in recorder! (Load a disc maybe?)", 0)
      Recorder\EjectMedia()
      KillThread(tidid)
    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)
  Else
    MessageRequester("Information", "Cannot write to disc. Is the disc empty?", 0)
    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(@mediaType)

If mediaType = #IMAPI_MEDIA_TYPE_UNKNOWN
  MessageRequester("Information", "Unknown media type or no media in recorder! (Load a disc maybe?)", 0)
  Recorder\EjectMedia()
  KillThread(tide)
Else
  If mediaType = #IMAPI_MEDIA_TYPE_CDROM
    MessageRequester("Information", "Media in recorder is not eraseable! Load an eraseable disc maybe?", 0)
    Recorder\EjectMedia()
    KillThread(tide)
  EndIf
EndIf 

Format2Erase\put_ClientName("PB_IMAPIv2")
Format2Erase\put_FullErase(var_ers1)   
Format2Erase\EraseMedia()

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)
          
          DataWriter_Format2Data\get_CurrentPhysicalMediaType(@media_unkx)
          If media_unkx = #IMAPI_MEDIA_TYPE_UNKNOWN
            MessageRequester("Information", "Unknown or no media in recorder! (Load a disc maybe?)", 0)
            Recorder\EjectMedia()
            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 = 1
    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(#Exit,393, 300,  130, 30, "Exit",#BS_HOLLOW|#BS_FLAT)
  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.")
  
  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")
  
  ComboBoxGadget(#Drive_0, 140, 145, 220, 100) : GadgetToolTip(#Drive_0, "Select your CD\DVD recorder here with the pull down menu.")
  If imapi_drives => 1
      ForEach Drive_List()
        AddGadgetItem(#Drive_0, -1,Drive_List()\Path_ID +"  " +Drive_List()\Vendor_ID +Drive_List()\Product_ID)
      Next
    SetGadgetState(#Drive_0, 1)
    Else
    MessageRequester("Information", "No recordable drives found.", 0)
  EndIf
   
  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")
    
  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_6, 150, 305, 150, 40, "Your boot image is:  ")
  TextGadget(#Text_7, 200, 130, 150, 30, "Select Recorder")
  
  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")
  
        Repeat
          Event = WaitWindowEvent()
          ventType = EventType()
          WindowID = EventWindow()
          GadgetID = EventGadget()
          
          Select Event
          
            Case #PB_Event_Gadget      
            
            Select EventGadget()
            
              Case #Drive_0
                        Drive_String$ = GetGadgetText(#Drive_0)
                        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 = 1
                        Else
                        eject_yn.l = 0
                        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_6, "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 
                          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: Tue Jan 22, 2008 11:50 pm
by SFSxOI
Updated include file a few posts back - minor typos corrected, nothing serious.

Updated sample application with fresh cleaned up code and basic event/error trapping, implemented running in seperate threads for erase and burning iso to disc, removed some testing stuff. Still same ugly GUI but you can make your own to suit you.


also, one more change - added a 'Break' in the 'GetDrive(get_drive.s)' procedure :

Code: Select all

If get_drive <> "INITIAL" 
        If Left(Drive_Path$,1) = get_drive 
        index_drive.l = x 
        Break ;<<<<added
        EndIf 
      EndIf 
to break out of loop the first time the drive is found, wasn't doing it before and was possibility that index could be wrong for the drive in some cases with some dual function drives. Hard to explain, before would select the drive the first time but if drive was really a legacy-type (in relation to Vista) dual function type drive (some drives) and a second drive (or more) was also installed and selected for further use and then the first drive was selected again, sometimes the index would be wrong for the drive by detecting the other dual-use part of the drive as a different drive when in reality it was actually the same drive. The 'Break' seemed to have fixed that little intermittant problem. I think it was something to do with the way the drive reported the first time as a seperate drive when the IMAPIv2 initialization tried to initialize the drive the first time and the feature pages in the drive were not refeshed or curent for the dual use until after the drive was used the first time, only happened on WindowsXP SP2 systems. Not sure exactly, was hard to pin down and the break was a gamble put in during trouble shooting and seems to have worked so I left it in. Someone suggested to me that it might have something to do with the upper and lower filters in the registry from other burning software installs, its a known big problem according to MS, but I wasn't able to verify the registry filter thing.

Posted: Wed Jan 23, 2008 11:19 pm
by SFSxOI
Updated the include file. Changes are these:

added in: imapi2_include.pbi
(in Case someone actually uses the GetAdapterDescriptor Or GetDeviceDescriptor functions And likes To be tortured :) )
Enumeration _STORAGE_BUS_TYPE To support IDiscRecorder2Ex Interface\GetAdapterDescriptor And GetDeviceDescriptor function
Structure _STORAGE_DEVICE_DESCRIPTOR To support IDiscRecorder2Ex Interface\GetAdapterDescriptor And GetDeviceDescriptor function

Also added three constants For Sectors/sec And Sectors/size

Also added two utility procedures To support special Case\configurations involving 'Recorder object\write()' function
Procedure Eject_Drive(indexx.l) <<< see the .pbi For information
Procedure Close_Drive(indexx.l) <<< see the .pbi For information

Also updated the example application to use the new Eject_Drive utility procedure in the updated .pbi.

Posted: Sat Jan 26, 2008 12:20 pm
by SFSxOI
Updated the include file and the sample application

In imapi2_include.pbi - version 1.6, 26 Jan 2008

added (by request): helper Procedure Check_Media(media_unk)

In the sample application (still With the ugly GUI :) ) - version 1.8, 26 Jan 2008

added: the use of the Check_Media(media_chk) Procedure To check For unknown media, no media, Or unsupported media in drive

Fixed reported issue with sample app: Problem With recording an .iso To disc And detecting blank media And overwriting the existing Data when disc had Data recorded under IMAPI v1 leading To loss of Data on disc due To blank media detection failure without warning. Under certain conditions If a DVD RW Or CD RW media had been peviously multisession Or disc was more then half full Or Data existed that was recorded under IMAPIv1, when an .iso recording was attempted the detection of blank media would fail in some cases And the existing Data would be overwritten leading To loss of Data. Added a double check To solve the issue. Added get_MediaHeuristicallyBlank(@hblank) in combination With get_MediaPhysicallyBlank(@blank) which solved the problem.
Now Data is Not overwritten And the warning now includes these certain conditions and prevents data loss from happening by giving a reliable warning that the disc is not empty and killing the .iso record thread forcing the user to respond to the warning (message - click OK), ejecting the media tray, and user has to start over and will not let user (as sample app is now) record an .iso on media that is not truely blank.

Re: IMAPIv2 for Vista

Posted: Thu Apr 03, 2008 8:37 pm
by harff182
SFSxOI wrote:Yet another IMAPIv2 thing for Vista (and XP SP2 if you have the KB932716 update - see remarks in code).
While everything works fine on my machine, a friend of mine tried my app without having installed this KB932716 update.
Is there a possibility, that my app checks, whether IMAPI2 is available?

tia... scholly

Posted: Fri Apr 04, 2008 3:51 pm
by SFSxOI
hmmm, ya know i briefly thought about that around the beginning of this but didn't really consider it in the overall project because its not un-common to need a user to meet certain requirements to use certain software. I suppose you could do some sort of file version check or something.

Posted: Fri Apr 04, 2008 11:04 pm
by harff182
I hoped, there would be something like Get_IMAPIVersion_(), but now I will try something like

Code: Select all

If OpenLibrary(#PB_Any, "imapi2.dll") = 0
  MessageRequester("Error","Problems with Imapi V2, consult the docs")
EndIf

Posted: Sat Apr 05, 2008 8:47 pm
by SFSxOI
You might be on to something tho with that little snippett. You could test the version of the .dll to determine Imapi V2 is present or actually there is nothing wrong with just seeing the .dll is present for imapiv2 although I think I would test the version myself to make sure ImapiV2 is actually the one being used in the system because its possible that some installed software could cause a previous version to be in use even if the v 2 dll is present on the system physically.

Posted: Sat Apr 05, 2008 10:19 pm
by harff182
The snippet above is the only way I found to do a check - I'm still a PB-beginner, so I may overlook another way :oops:

Posted: Sat Jul 12, 2008 11:49 am
by Michael Korolev
Hi. Is there way to know media type using not only imapi v2? How I can link media type info with drive letter? Piece of code will be helpful )

Posted: Sat Jul 12, 2008 11:29 pm
by harff182
Michael Korolev wrote:Is there way to know media type using not only imapi v2?
Using imapi is the only reliable way I found so far
Michael Korolev wrote: How I can link media type info with drive letter? Piece of code will be helpful

Code: Select all

 removed because of confusion - see my next post for working code ;)

Posted: Sat Jul 12, 2008 11:43 pm
by Michael Korolev
ax_Uni2Ansi() is not a function and bla-bla-bla.. when I declared it, this appeared: sfs_Get_VariantString() is not a function, e.t.c.

Posted: Sat Jul 12, 2008 11:58 pm
by SFSxOI
its in the include file, or install the droppy library and change it to Uni2Ansi (remove the ax_)
Michael Korolev wrote:ax_Uni2Ansi() is not a function and bla-bla-bla.. when I declared it, this appeared: sfs_Get_VariantString() is not a function, e.t.c.

Posted: Sun Jul 13, 2008 12:24 am
by Michael Korolev
sfs_Get_VariantString() function is absent everywhere, in Droopy and in include file :?: