IMAPIv2 for Vista

Share your advanced PureBasic knowledge/code with the community.
Michael Korolev
User
User
Posts: 53
Joined: Wed Nov 01, 2006 3:02 pm
Location: Russia/Krasnoyarsk
Contact:

Post by Michael Korolev »

Michael Korolev wrote:sfs_Get_VariantString() function is absent everywhere: in Droopy and in include file :?:
harff182
Enthusiast
Enthusiast
Posts: 105
Joined: Thu Dec 08, 2005 4:58 pm
Location: Duesseldorf, Germany

Post by harff182 »

Well, I thought, you only needed something to learn, not full functional code, sorry :oops:

First about "sfs_" and "ax_":
I always put prefixes and mostly an URL to procs from other people, that helped me, to not get confused or problems with procs in additional libs my apps sometimes need.

Now some working code:

Code: Select all

;based on code from SFSxOI: http://www.purebasic.fr/english/viewtopic.php?t=30535

Procedure.S   sfs_Get_VariantString(*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

Procedure.s    ax_Uni2Ansi(unicodestr.l) 
  ;user: aXend
  ;forum: http://www.purebasic.fr/english/viewtopic.php?t=16569
  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 

Procedure.l   ugs_get_IMAPImediaType(driveletter.s)
DisableDebugger
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_Item(index,value) 
  get_Count(a.l)
  get_IsSupportedEnvironment(value.l)
EndInterface

Interface IDiscRecorder2 Extends IDispatch
  EjectMedia()
  CloseTray()
  AcquireExclusiveAccess(a.l,b.s)
  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_DeviceCanLoadMedia(a.l)
  get_LegacyDeviceNumber(a.l)
  get_SupportedFeaturePages(a)
  get_CurrentFeaturePages(a)
  get_SupportedProfiles(a)
  get_CurrentProfiles(a)
  get_SupportedModePages(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

pp.variant
pp\vt = #VT_BSTR

Variant.VARIANT
*VariantArray.SAFEARRAY
thisletter.s = ""
     
CoInitialize_(0)
CoCreateInstance_(?CLSID_MsftDiscMaster2,0,1,?IID_IDiscMaster2,@DiscMaster.IDiscMaster2)
DiscMaster\get_Count(@count)

Debug driveletter
For imapidrives = 0 To count

  Debug " "
  
  DiscMaster\get_Item(imapidrives,@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)  
  

  Recorder\InitializeDiscRecorder(pp\bstrval)  
  Debug "drive:   " +Str(imapidrives) +"   is ID:       " +ax_Uni2Ansi(pp\bstrval)   

  Recorder\get_ProductId(@pp\bstrval)
  Debug "ProductID:              "+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

    thisletter = sfs_Get_VariantString(*Variant)
    Debug "Your Drive Path is:   " +thisletter
  
    med_type = Format\get_CurrentPhysicalMediaType(@mediaType)
    Debug mediatype
  
  Next i
  If thisletter = UCase(driveletter)
    Break
  EndIf
  
  Debug ""
   
Next imapidrives

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

CoUninitialize_()
       
DataSection
  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_MsftDiscFormat2Erase:
    Data.l $2735412B
    Data.w $7F64,$5B0F
    Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E

  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_IDiscFormat2Erase:
    Data.l $27354156
    Data.w $8F64,$5B0F
    Data.b $8F,$00,$5D,$77,$AF,$BE,$26,$1E
EndDataSection
EnableDebugger
ProcedureReturn mediatype

EndProcedure;ugs_get_IMAPImediaType(driveletter.s)

cdvdLW.s = "z:\"
Debug "LW to check: "+cdvdLW

thismediatype = ugs_get_IMAPImediaType(cdvdLW)
Debug thismediatype
Select thismediaType 
   
  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

End
Does it work for you (Michael Korolev) now ?
Sorry 4 my poor English, it's the only one I learned 40 years ago...
since 17.12.08: XPHome(SP3) + PB 4.30
Michael Korolev
User
User
Posts: 53
Joined: Wed Nov 01, 2006 3:02 pm
Location: Russia/Krasnoyarsk
Contact:

Post by Michael Korolev »

Damn, IMAPI is too difficult for me :? . No, Invalid memory access in line 11 :(
harff182
Enthusiast
Enthusiast
Posts: 105
Joined: Thu Dec 08, 2005 4:58 pm
Location: Duesseldorf, Germany

Post by harff182 »

Line 11 ???
That's "endif" :o in Procedure.S sfs_Get_VariantString(*Variant.VARIANT) which is originally from SFSxOI, AFAIR.
Michael Korolev wrote:Damn, IMAPI is too difficult for me
I don't think so.
I don't understand most of his code, but I followed him changing it and it was not that difficult to ripp off the part I needed to get the media-infos.

------------------
If you don't get around with IMAPI, have a look at this thread, where Sparkie tried to help.
The results are not as correct as the IMAPI-way, but may probably satisfy you.

------------------
BTW: What versions of Windows and PureBasic are you using?
Last edited by harff182 on Sun Jul 13, 2008 4:03 pm, edited 1 time in total.
Sorry 4 my poor English, it's the only one I learned 40 years ago...
since 17.12.08: XPHome(SP3) + PB 4.30
Michael Korolev
User
User
Posts: 53
Joined: Wed Nov 01, 2006 3:02 pm
Location: Russia/Krasnoyarsk
Contact:

Post by Michael Korolev »

I know. But line 11. I testing on Win Vista SP1. Checked with PureBasic 4.02 and 4.20
harff182
Enthusiast
Enthusiast
Posts: 105
Joined: Thu Dec 08, 2005 4:58 pm
Location: Duesseldorf, Germany

Post by harff182 »

Please use the right driveletter for your system instead of my "z:\" and tell the result.
In the German forum I got response, that the code works on Vista Ultimate 64 SP1 with the right driveletters while my "z:\" gave an error like yours.
Sorry 4 my poor English, it's the only one I learned 40 years ago...
since 17.12.08: XPHome(SP3) + PB 4.30
Michael Korolev
User
User
Posts: 53
Joined: Wed Nov 01, 2006 3:02 pm
Location: Russia/Krasnoyarsk
Contact:

Post by Michael Korolev »

Works! I didn't know that I need to define drive letter, I thought, this code enumerating them all :D. How I can thank you!?

One thing is confusing that to know a drive letter I need to write 278 strings! I afraid to look at this code in C++ :shock:

So, user need to have minimun WinXP SP2 with special update (IMAPI v2)?
harff182
Enthusiast
Enthusiast
Posts: 105
Joined: Thu Dec 08, 2005 4:58 pm
Location: Duesseldorf, Germany

Post by harff182 »

Michael Korolev wrote:Works! I didn't know that I need to define drive letter, I thought, this code enumerating them all :D
Well, at first I just posted the proc, which should have indicated, that it is only called for one drive.
And than I quickly build around the rest for working code. Sometimes (especially on weekends) I'm as lazy as possible :lol:
Michael Korolev wrote:How I can thank you!?
Just try to share knowledge here, when you feel to be able to help and don't hesitate coz of not so good English. There's always a way to explain and sometimes code tells more than thousand words :lol:
Michael Korolev wrote:So, user need to have minimun WinXP SP2 with special update (IMAPI v2)?
AFAIK: Yes.
But I remember someone posting about problems, when SP3 is installed over SP2 without doing that IMAPI-update first.
Michael Korolev wrote:One thing is confusing that to know a drive letter I need to write 278 strings!
Why? And Which 278 strings?

Code: Select all

; German forum: http://www.purebasic.fr/german/viewtopic.php?t=1895&highlight=
; Author: DataMiner (updated for PB 4.00 by Andre)
; Date: 05. February 2005
; OS: Windows
; Demo: No

Define.l Serial, type, i 
Define.s Lfwrk, FileSystem, VolName 

For i=65 To 90 
  Lfwrk=Chr(i)+":" 
  type =GetDriveType_(Lfwrk) 
  FileSystem = Space(256) 
  VolName= Space(256) 
  GetVolumeInformation_(@Lfwrk, @VolName, 255, @Serial, 0, 0, @FileSystem, 255) 
  Select type 
    Case 0 
      Debug Lfwrk+" The drive type cannot be determined." 
    Case 2 
      Debug Lfwrk+" = DRIVE_REMOVABLE, "+VolName+", "+FileSystem+", "+  Hex(Serial) 
    Case 3 
      Debug Lfwrk+" = DRIVE_FIXED, "+VolName+", "+FileSystem+", "+  Hex(Serial) 
    Case 4 
      Debug Lfwrk+" = DRIVE_REMOTE, "+VolName+", "+FileSystem+", "+  Hex(Serial) 
    Case 5 
      Debug Lfwrk+" = DRIVE_CDROM, "+VolName+", "+FileSystem+", "+  Hex(Serial) 
    Case 6 
      Debug Lfwrk+" = DRIVE_RAMDISK,   "+VolName+", "+FileSystem+", "+  Hex(Serial) 
  EndSelect 
Next
In case 5 you can call the proc to determine the media-type :lol:
Sorry 4 my poor English, it's the only one I learned 40 years ago...
since 17.12.08: XPHome(SP3) + PB 4.30
User avatar
Le Soldat Inconnu
Enthusiast
Enthusiast
Posts: 306
Joined: Wed Jul 09, 2003 11:33 am
Location: France

Post by Le Soldat Inconnu »

when i compile code, it's always crash on "DiscMaster\get_Count(@count)" or think like this one.
What i do wrong ?
LSI
harff182
Enthusiast
Enthusiast
Posts: 105
Joined: Thu Dec 08, 2005 4:58 pm
Location: Duesseldorf, Germany

Post by harff182 »

Please give some more information:

- which code crashes
- which OS and Service-Pack
- did you install the mentioned "IMAPI"-patch
- which PB-Version exactly
Sorry 4 my poor English, it's the only one I learned 40 years ago...
since 17.12.08: XPHome(SP3) + PB 4.30
User avatar
Le Soldat Inconnu
Enthusiast
Enthusiast
Posts: 306
Joined: Wed Jul 09, 2003 11:33 am
Location: France

Post by Le Soldat Inconnu »

This code :
Posted: Sun Jul 13, 2008 11:12

On top of this page

Windows XP SP2, pb4.20

But i don't have this :
the mentioned "IMAPI"-patch

I think i skip this information, sorry :oops:
What is this and where find this ?
Thanks
LSI
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Le Soldat Inconnu wrote:... But i don't have this :
the mentioned "IMAPI"-patch

I think i skip this information, sorry :oops:
What is this and where find this ?
I think this is it : http://www.microsoft.com/downloads/deta ... laylang=en
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
harff182
Enthusiast
Enthusiast
Posts: 105
Joined: Thu Dec 08, 2005 4:58 pm
Location: Duesseldorf, Germany

Post by harff182 »

Yes, gnozal was too fastImage
And don't use my "z:\" but the letter of your drive :lol:
Sorry 4 my poor English, it's the only one I learned 40 years ago...
since 17.12.08: XPHome(SP3) + PB 4.30
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

harff182 wrote: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
Can't you just check to see whether the DiscMaster object is created successfully or not? If it fails, you can't do much anyway, so you could ask the user to ensure they have installed the patch.

It's possible that the name of the DLL could change, or that someone could implement the IDiscMaster interface using an alternative underlying object.

PS, I've just found this thread as I need to identify whether a CD drive has some blank media in it or not. So this is all excellent work as it saves me the effort :)

Thanks.
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Post Reply