Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / Win API / June 2007



Tip: Looking for answers? Try searching our database.

Problem with DeviceIoControl in VB

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
John Kick - 20 Jun 2007 20:47 GMT
Hi,

I have a strange problem using DeviceIoControl api in my program.
One form is controlling the DVD player by using MSWEBDVD.dll and the other
form is just the form that I can place on a secondary monitor (e.g. a
beamer).
The problem is that running the code within the VB6 (SP6) IDE that
everything works fine, but when compiled an starting the resulting exe-file,
the program stops running, it terminates, whemn calling DeviceIoControl api.
Anybody who can explain me what I am doing wrong? I build in some
messageboxes and kept on changing, but nothing really helps.

Here is the code fore the form that controls (sorry everything is in Dutch
language, but I added some comment):

Private Sub cmdCloseApp_Click()

If bDISK_PRESENT = True Then
   frmDVDbeamer.dvd1.Stop
End If

End

End Sub

Private Sub cmdEject_Click()

If bDISK_PRESENT = False Then
   Exit Sub
End If

frmDVDbeamer.dvd1.Stop
frmDVDbeamer.dvd1.Eject
frmDVDbeamer.pboxdvd.Visible = False
End Sub

Public Sub cmdFullScreen_Click()

If bDISK_PRESENT = False Then
   Exit Sub
End If

If bFullScr = False Then
   frmDVDbeamer.dvd1.Left = 0
   frmDVDbeamer.dvd1.Width = frmDVDbeamer.Width
   frmDVDbeamer.dvd1.Height = frmDVDbeamer.Height
   frmDVDbeamer.dvd1.Top = frmDVDbeamer.pboxdvd.Top
   frmDVDbeamer.dvd1.FullScreenMode = True
   bFullScr = True

   DoEvents
End If

End Sub

Private Sub cmdOpenDVD_Click()
Dim DVDok As Boolean, strDVD As String

DVDok = False

On Error GoTo NoDVD
'MsgBox "Zoek drive letter"  'search drive type
strDVDdrive = FirstCDDrive & ":"
'MsgBox "Bepaal drive type"  'detect drive type
strDVD = GetDriveTypeEx(strDVDdrive)
DoEvents

If strDVD <> "DVD" Then
   'MsgBox "DVD drive gevonden"  'drive found
   DVDok = True
End If

If DVDok = False Then Exit Sub

DoEvents

'DVD scherm aan, maar besturing houden / Switch on DVD screen, but keep
focus

'MsgBox "Scherm activeren"  'activate screen
frmDVDbeamer.Show
DoEvents

frmDVDbeamer.dvd1.DVDDirectory = UCase(strDVDdrive & "\video_ts")
DoEvents

frmDVDstuur.cmdFullScreen.Enabled = True
frmDVDstuur.cmdPause.Enabled = True
frmDVDstuur.cmdPlay.Enabled = True
frmDVDstuur.cmdPrevChapter.Enabled = True
frmDVDstuur.cmdNextChapter.Enabled = True
frmDVDstuur.cmdStop.Enabled = True
frmDVDstuur.cmdReplay.Enabled = True

Exit Sub

NoDVD:
MsgBox "Plaats een DVD in de speler a.u.b.", vbOKOnly, App.Title  'Please
place DV in drive

bDISK_PRESENT = False

End Sub

Private Sub cmdPrevChapter_Click()

If bDISK_PRESENT = False Then
   Exit Sub
End If

frmDVDbeamer.dvd1.PlayPrevChapter
End Sub

Private Sub cmdPlay_Click()

If bDISK_PRESENT = False Then
   MsgBox "Geen disk in de drive aanwezig."  'no disk in drive
   Exit Sub
End If

If Screens = 1 Then
   'MsgBox "Film in DUBBELSCHERM modus"  'double screen mode
ElseIf Screens = 0 Then
   'MsgBox "Film in ENKELSCHERM modus"  'single screen mode
Else
   'MsgBox "FOUT in schermmodus", vbCritical + vbOKOnly  'error in screen
mode
End If

frmDVDbeamer.pboxdvd.Visible = True
frmDVDbeamer.dvd1.Play

DoEvents

frmDVDstuur.cmdFullScreen_Click
DoEvents

End Sub

Private Sub cmdStop_Click()

If bDISK_PRESENT = False Then
   Exit Sub
End If

frmDVDbeamer.dvd1.Stop
frmDVDbeamer.pboxdvd.Visible = False

End Sub

Private Sub cmdPause_Click()

If bDISK_PRESENT = False Then
   Exit Sub
End If

frmDVDbeamer.dvd1.Pause
DoEvents

frmDVDbeamer.dvd1.SetFocus

End Sub

Private Sub cmdNextChapter_Click()

If bDISK_PRESENT = False Then
   Exit Sub
End If

frmDVDbeamer.dvd1.PlayNextChapter
End Sub

Private Sub cmdReplay_Click()
If bDISK_PRESENT = False Then
   Exit Sub
End If

frmDVDbeamer.dvd1.ReplayChapter

End Sub

Private Sub Form_Load()
' set buttons in place
Me.cmdPlay.Left = Me.cmdPrevChapter.Left + Me.cmdPrevChapter.Width + 5
Me.cmdPause.Left = Me.cmdPlay.Left + Me.cmdPlay.Width + 5
Me.cmdStop.Left = Me.cmdPause.Left + Me.cmdPause.Width + 5
Me.cmdNextChapter.Left = Me.cmdStop.Left + Me.cmdStop.Width + 5
Me.cmdReplay.Left = Me.cmdStop.Left + Me.cmdStop.Width + 5

bDISK_PRESENT = False

End Sub

Private Sub Form_Unload(Cancel As Integer)

All_Form_Unload

End Sub

Private Sub opt1_Click()

Screens = 0
'MsgBox "Enkelscherm"  'single scrteen

End Sub

Private Sub opt2_Click()

Screens = 1
'MsgBox "Dubbelscherm"  'double screen

End Sub

Sub All_Form_Unload()

OntladenAlleForms

End Sub

And here the second form that displays the running DVD:

Private Sub Form_Load()

frmDVDbeamer.Width = 1024 * 15
frmDVDbeamer.Height = 768 * 15
If Screens = 1 Then
   frmDVDbeamer.Move Screen.Width - 1 + 1, 0, 1024 * 15, 768 * 15
End If

frmDVDbeamer.Top = 0
frmDVDbeamer.pboxdvd.Left = 0
frmDVDbeamer.pboxdvd.Width = frmDVDbeamer.Width
frmDVDbeamer.pboxdvd.Height = frmDVDbeamer.Height
frmDVDbeamer.pboxdvd.Top = frmDVDbeamer.Top
frmDVDbeamer.Label1.Left = 0
frmDVDbeamer.Label1.Top = frmDVDbeamer.pboxdvd.Top
frmDVDbeamer.Label1.Width = frmDVDbeamer.pboxdvd.Width
frmDVDbeamer.Label1.Height = frmDVDbeamer.pboxdvd.Height

frmDVDbeamer.pboxdvd.Visible = False

If bDISK_PRESENT = False Then
   Exit Sub
End If

frmDVDbeamer.dvd1.FullScreenMode = True

End Sub

Thanks in advance,
John
Thorsten Albers - 20 Jun 2007 21:03 GMT
John Kick <john@kickfakeadr.com> schrieb im Beitrag
<46798425$0$9458$e4fe514c@dreader32.news.xs4all.nl>...
> I have a strange problem using DeviceIoControl api in my program.

If you think you have a problem with DeviceIoControl() you should post the
code which uses that function. In the code shown in your posting I can't
find any instance of it...

Signature

----------------------------------------------------------------------
THORSTEN ALBERS                       Universität Freiburg
                                               albers@
                                                      uni-freiburg.de
----------------------------------------------------------------------

John Kick - 20 Jun 2007 23:29 GMT
Ooops,
I forgot rthe modules..

Here they are:
' take a drive letter and display a MsgBox with the type of the medium in
the
' drive
' (you can delete the msgbox to achieve a silent function)

Public Function GetDriveTypeEx(DriveLetter As String) As DriveType
   Dim OS As String
   OS = GetOsVersion()
   'MsgBox "Windows versie is: " & OS
   'validate input parameter
   If Len(Trim$(DriveLetter)) <> 2 And Right$(Trim$(DriveLetter), _
       1) <> ":" Then
       MsgBox "Please enter the drive letter and a colon."
   Else
       GetDriveTypeEx = GetDriveType(Trim$(DriveLetter))
       DoEvents
       'Select Case GetDriveTypeEx
       '    Case DVD
       '        MsgBox "Drive is a DVD"
       '    Case CDROM
       '        MsgBox "Drive is a CDROM"
       '    Case DVDORCDROM
       '        MsgBox "Drive is a DVD or CDROM"
       '    Case FIXED
       '        MsgBox "Drive is a FIXED"
       '    Case RAMDISK
       '        MsgBox "Drive is a RAMDISK"
       '    Case REMOTE
       '        MsgBox "Drive is a REMOTE"
       '    Case REMOVABLE
       '        MsgBox "Drive is a EMOVABLE"
       '    Case NO_ROOT_DIR
       '        MsgBox "Drive is a INVALID ROOT DIR"
       '    Case UNKNOWN
       '        MsgBox "Drive is a UNKNOWN"
       'End Select
       'only works in WinXP and 2K and higher
       'use default get drive type result if not xp or 2K
       If (GetDriveTypeEx = DVDORCDROM Or GetDriveTypeEx = DVD) And (OS =
"Win2K" Or OS = "WinXP" Or OS = "Vista") Then
           Dim mediaTypes As GET_MEDIA_TYPES
           Dim status As Long
           Dim returned As Long
           Dim hDevice As Long
           Dim mynull As Long
           '//
           '// Get the Media type.
           '//
           'get a handle to the device
           'hDevice = CreateFile("\\.\" & UCase$(Trim$(DriveLetter)), _
           '    GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or
FILE_SHARE_WRITE, _
           '    mynull, OPEN_EXISTING, 0, mynull)
           hDevice = CreateFile("\\?\" & UCase$(Trim$(DriveLetter)), _
               GENERIC_READ, FILE_SHARE_READ, _
               mynull, OPEN_EXISTING, 0, mynull)
           DoEvents
           'get the media types IO call
           MsgBox "Resultaat CreateFile: " & hDevice & " op \\?\" &
UCase$(Trim$(DriveLetter))
           If hDevice <> INVALID_HANDLE_VALUE Then
'DeviceIoControl(hFile,IOCTL_STORAGE_GET_MEDIA_TYPES_EX,0,0,&m_gmt,sizeof(m_gmt),&dwRet,0)
               'status = DeviceIoControl(hDevice, _
               '    IOCTL_STORAGE_GET_MEDIA_TYPES_EX, mynull, 0,
mediaTypes, _
               '    2048, returned, ByVal 0)
               DoEvents
               MsgBox "Check drive type"
               status = DeviceIoControl(hDevice, _
                   IOCTL_STORAGE_GET_MEDIA_TYPES_EX, mynull, 0, mediaTypes,
_
                   2048, returned, ByVal 0)
               DoEvents
               MsgBox "Status: " & status
               If status = 0 Then
                   MsgBox "DRIVER ERROR"
                   GetDriveTypeEx = UNKNOWN
                   Exit Function
               Else
                   If mediaTypes.DeviceType = FILE_DEVICE_CD_ROM Then
                       'MsgBox "CDROM"
                       GetDriveTypeEx = CDROM
                   ElseIf mediaTypes.DeviceType = FILE_DEVICE_DVD Then
                       'MsgBox "DVD"
                       GetDriveTypeEx = DVD
                   Else
                      MsgBox "Onbekende optische drive"
                   End If
               End If
               CloseHandle hDevice
           Else
               'MsgBox "FILE ERROR" & " " & hDevice
               GetDriveTypeEx = DVD
           End If
       Else
           'process other drive types
           'remove if message box is not desired
           Select Case GetDriveTypeEx
               Case DVDORCDROM
                   MsgBox "DVD or CDROM"
               Case FIXED
                   MsgBox "FIXED"
               Case RAMDISK
                   MsgBox "RAMDISK"
               Case REMOTE
                   MsgBox "REMOTE"
               Case REMOVABLE
                   MsgBox "REMOVABLE"
               Case NO_ROOT_DIR
                   MsgBox "INVALID ROOT DIR"
               Case UNKNOWN
                   MsgBox "UNKNOWN"
           End Select
       End If
   End If
End Function

' return a string that identifies the OS version

Public Function GetOsVersion() As String
   ' Return name of operating system
   Dim lret As Long
   Dim osverinfo As OSVERSIONINFO

   osverinfo.dwOSVersionInfoSize = Len(osverinfo)

   lret = GetVersionEx(osverinfo)
   DoEvents

   If lret = 0 Then
       GetOsVersion = "unknown"
   Else
       Select Case osverinfo.dwPlatformId & "/" & osverinfo.dwMajorVersion
& _
           "/" & osverinfo.dwMinorVersion
           'switched off some cases, not relevant
           'Case "1/4/0"
               'GetOsVersion = "Win95"
           'Case "1/4/10"
               'GetOsVersion = "Win98"
           'Case "1/4/90"
               'GetOsVersion = "WinME"
           'Case "2/3/51"
               'GetOsVersion = "WinNT351"
           Case "2/4/0"
               GetOsVersion = "WinNT4"
           Case "2/5/0"
               GetOsVersion = "Win2K"
           Case "2/5/1"
               GetOsVersion = "WinXP"
           Case "2/6/0"
               GetOsVersion = "Vista"
           Case Else
               GetOsVersion = "Windows versie niet ondersteund"
       End Select
   End If
End Function

and the start module:
Public Const DRIVE_DVD = 7
Public Const DRIVE_RAMDISK = 6
Public Const DRIVE_CDROM = 5
Public Const DRIVE_REMOTE = 4
Public Const DRIVE_FIXED = 3
Public Const DRIVE_REMOVABLE = 2
Public Const DRIVE_NO_ROOT_DIR = 1
Public Const DRIVE_UNKNOWN = 0

Public Const IOCTL_STORAGE_GET_MEDIA_TYPES_EX As Long = &H2D0C04
Public Const GENERIC_READ As Long = &H80000000
Public Const GENERIC_WRITE As Long = &H40000000
Public Const FILE_SHARE_READ As Long = &H1
Public Const FILE_SHARE_WRITE As Long = &H2
Public Const OPEN_EXISTING As Long = 3
Public Const INVALID_HANDLE_VALUE As Long = -1
Public Const ERROR_ACCESS_DENIED As Long = 5&
Public Const ERROR_NOT_READY As Long = 21&
Public Const FILE_ATTRIBUTE_NORMAL As Long = &H80
Public Const FILE_FLAG_NO_BUFFERING As Long = &H20000000

Public Const FILE_DEVICE_CD_ROM As Long = &H2
Public Const FILE_DEVICE_DVD As Long = &H33

Public Declare Function GetDriveType Lib "kernel32.dll" Alias
"GetDriveTypeA" _
   (ByVal nDrive As String) As Long
Public Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
   (lbVersionInfirmation As OSVERSIONINFO) As Long

Public Type OSVERSIONINFO
   dwOSVersionInfoSize As Long
   dwMajorVersion As Long
   dwMinorVersion As Long
   dwBuildNumber As Long
   dwPlatformId As Long
   szCSDVersion As String * 128
End Type

Public Enum STORAGE_MEDIA_TYPE
   DDS_4mm = &H20           '// Tape - DAT DDS1,2,... (all vendors)
   MiniQic                   '// Tape - miniQIC Tape
   Travan                    '// Tape - Travan TR-1,2,3,...
   QIC                       '// Tape - QIC
   MP_8mm                    '// Tape - 8mm Exabyte Metal Particle
   AME_8mm                   '// Tape - 8mm Exabyte Advanced Metal Evap
   AIT1_8mm                  '// Tape - 8mm Sony AIT
   DLT '                       // Tape - DLT Compact IIIxt, IV
   NCTP '                      // Tape - Philips NCTP
   IBM_3480 '                  // Tape - IBM 3480
   IBM_3490E '                 // Tape - IBM 3490E
   IBM_Magstar_3590 '          // Tape - IBM Magstar 3590
   IBM_Magstar_MP '            // Tape - IBM Magstar MP
   STK_DATA_D3 '               // Tape - STK Data D3
   SONY_DTF '                  // Tape - Sony DTF
   DV_6mm '                    // Tape - 6mm Digital Video
   DMI '                       // Tape - Exabyte DMI and compatibles
   SONY_D2 '                   // Tape - Sony D2S and D2L
   CLEANER_CARTRIDGE '         // Cleaner - All Drive types that support
Drive
                               ' Cleaners
   CD_ROM '                    // Opt_Disk - CD
   CD_R '                      // Opt_Disk - CD-Recordable (Write Once)
   CD_RW '                     // Opt_Disk - CD-Rewriteable
   DVD_ROM '                   // Opt_Disk - DVD-ROM
   DVD_R '                     // Opt_Disk - DVD-Recordable (Write Once)
   DVD_RW '                    // Opt_Disk - DVD-Rewriteable
   MO_3_RW '                   // Opt_Disk - 3.5" Rewriteable MO Disk
   MO_5_WO '                   // Opt_Disk - MO 5.25" Write Once
   MO_5_RW '                   // Opt_Disk - MO 5.25" Rewriteable (not
LIMDOW)
   MO_5_LIMDOW '               // Opt_Disk - MO 5.25" Rewriteable (LIMDOW)
   PC_5_WO '                   // Opt_Disk - Phase Change 5.25" Write Once
           ' Optical
   PC_5_RW '                   // Opt_Disk - Phase Change 5.25" Rewriteable
   PD_5_RW '                   // Opt_Disk - PhaseChange Dual Rewriteable
   ABL_5_WO '                  // Opt_Disk - Ablative 5.25" Write Once
Optical
   PINNACLE_APEX_5_RW '        // Opt_Disk - Pinnacle Apex 4.6GB
Rewriteable
                      ' Optical
   SONY_12_WO '                // Opt_Disk - Sony 12" Write Once
   PHILIPS_12_WO '             // Opt_Disk - Philips/LMS 12" Write Once
   HITACHI_12_WO '             // Opt_Disk - Hitachi 12" Write Once
   CYGNET_12_WO '              // Opt_Disk - Cygnet/ATG 12" Write Once
   KODAK_14_WO '               // Opt_Disk - Kodak 14" Write Once
   MO_NFR_525 '                // Opt_Disk - Near Field Recording
(Terastor)
   NIKON_12_RW '               // Opt_Disk - Nikon 12" Rewriteable
   IOMEGA_ZIP '                // Mag_Disk - Iomega Zip
   IOMEGA_JAZ '                // Mag_Disk - Iomega Jaz
   SYQUEST_EZ135 '             // Mag_Disk - Syquest EZ135
   SYQUEST_EZFLYER '           // Mag_Disk - Syquest EzFlyer
   SYQUEST_SYJET '             // Mag_Disk - Syquest SyJet
   AVATAR_F2 '                 // Mag_Disk - 2.5" Floppy
   MP2_8mm '                   // Tape - 8mm Hitachi
   DST_S '                     // Ampex DST Small Tapes
   DST_M '                     // Ampex DST Medium Tapes
   DST_L '                     // Ampex DST Large Tapes
   VXATape_1 '                 // Ecrix 8mm Tape
   VXATape_2 '                 // Ecrix 8mm Tape
   STK_9840 '                  // STK 9840
   LTO_Ultrium '               // IBM, HP, Seagate LTO Ultrium
   LTO_Accelis '               // IBM, HP, Seagate LTO Accelis
   DVD_RAM '                   // Opt_Disk - DVD-RAM
   AIT_8mm '                   // AIT2 or higher
   ADR_1 '                     // OnStream ADR Mediatypes
   ADR_2 '                     // Indicates an on-stream ADR media type
device
   STK_9940 '                  // STK 9940
End Enum

Public Type DEVICE_MEDIA_INFO
   Cylinders As Double
   MediaType As STORAGE_MEDIA_TYPE
   TracksPerCylinder As Long
   SectorsPerTrack As Long
   BytesPerSector As Long
   NumberMediaSides As Long
   MediaCharacteristics As Long
End Type

Public Type GET_MEDIA_TYPES
  DeviceType As Long
  MediaInfoCount As Long
  MediaInfo(0) As DEVICE_MEDIA_INFO
End Type

Public Enum DriveType
   UNKNOWN = 0
   NO_ROOT_DIR '1
   REMOVABLE   '2
   FIXED       '3
   REMOTE      '4
   DVDORCDROM  '5
   RAMDISK     '6
   DVD         '7
   CDROM       '8
End Enum

Public Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As
Long, _
   ByVal dwIoControlCode As Long, lpInBuffer As Any, _
   ByVal nInBufferSize As Long, lpOutBuffer As Any, _
   ByVal nOutBufferSize As Long, lpBytesReturned As Long, _
   lpOverlapped As Any) As Long
Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal
_
   lpFileName As String, ByVal dwDesiredAccess As Long, _
   ByVal dwShareMode As Long, lpSecurityAttributes As Long, _
   ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long,
_
   ByVal hTemplateFile As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long)
As _
   Long

Public Screens As Integer
Public strDVDdrive As String, bDISK_PRESENT As Boolean
Public strTimeTotal As String
Public bFullScr As Boolean

Public Sub Main()
   Screens = 1
   bFullScr = False

   frmDVDstuur.Show

End Sub

Public Sub OntladenAlleForms()
Dim Form As Form

On Error Resume Next

For Each Form In Forms
   Unload Form
   Set Form = Nothing
Next Form

End Sub

' Return the first DVD drive letter.
' Return "" if we cannot find a CD drive.
Public Function FirstCDDrive() As String
Const ASC_A = 65
Const ASC_Z = ASC_A + 25

Dim i As Integer

   For i = ASC_A To ASC_Z
       If GetDriveType(Chr$(i) & ":\") = DRIVE_DVD Or GetDriveType(Chr$(i)
& ":\") = DRIVE_CDROM Then
           FirstCDDrive = Chr$(i)
           bDISK_PRESENT = True
           DoEvents
           'MsgBox "Drive aanwezig = " & Chr$(i)
           Exit For
       End If
   Next i
End Function

Hope this helps

John

> John Kick <john@kickfakeadr.com> schrieb im Beitrag
> <46798425$0$9458$e4fe514c@dreader32.news.xs4all.nl>...
[quoted text clipped - 3 lines]
> code which uses that function. In the code shown in your posting I can't
> find any instance of it...
Uwe Sieber - 21 Jun 2007 04:59 GMT
> Public Declare Function GetDriveType Lib "kernel32.dll"
>       Alias "GetDriveTypeA" (ByVal nDrive As String) As Long
[quoted text clipped - 12 lines]
>     CDROM       '8
> End Enum

Where do you have the information from that GetDriveType
might return a 7 or 8?

> hDevice = CreateFile("\\?\" & UCase$(Trim$(DriveLetter)), _
>              GENERIC_READ, FILE_SHARE_READ, _
>              mynull, OPEN_EXISTING, 0, mynull)

For calling DeviceIoControl for gathering informations only
usually a 0& for dwDesiredAccess is good enough.
With GENERIC_READ CreateFile may fail for restriced users.

> status = DeviceIoControl(hDevice,
>    IOCTL_STORAGE_GET_MEDIA_TYPES_EX, mynull, 0, mediaTypes, _
>    2048, returned, ByVal 0)

I'm no sure but I suspect that ByVal 0 will pass an integer
(2 Bytes) instead of the expected 4 Bytes. Use ByVal 0& instead.

Uwe
John Kick - 21 Jun 2007 10:36 GMT
Uwe, see reply in the text near your remarks.

> > Public Declare Function GetDriveType Lib "kernel32.dll"
> >       Alias "GetDriveTypeA" (ByVal nDrive As String) As Long
[quoted text clipped - 15 lines]
> Where do you have the information from that GetDriveType
> might return a 7 or 8?

I found a snippet of code on http://www.devx.com/vb2themax/Tip/19403
That's where most of my this code came from.

> > hDevice = CreateFile("\\?\" & UCase$(Trim$(DriveLetter)), _
> >              GENERIC_READ, FILE_SHARE_READ, _
[quoted text clipped - 3 lines]
> usually a 0& for dwDesiredAccess is good enough.
> With GENERIC_READ CreateFile may fail for restriced users.

I will try that. Another reaction tells that referenced values are not
handled correct by the API (see remarks of Sinna)

> > status = DeviceIoControl(hDevice,
> >    IOCTL_STORAGE_GET_MEDIA_TYPES_EX, mynull, 0, mediaTypes, _
> >    2048, returned, ByVal 0)
>
> I'm no sure but I suspect that ByVal 0 will pass an integer
> (2 Bytes) instead of the expected 4 Bytes. Use ByVal 0& instead.

I'll try it. If other problems appear, "I'll be back".

> Uwe

Thanks a lot!
John
John Kick - 21 Jun 2007 12:02 GMT
> Uwe, see reply in the text near your remarks.
>
[quoted text clipped - 45 lines]
> Thanks a lot!
> John
Using your advices, but still nut working. I tried the 0&, Byval 0& with
same result. I als tried the next change, but that results in a vlaue for
'returned' of zero, but running in IDE it returns 72.
           hDevice = CreateFile("\\?\" & UCase$(Trim$(DriveLetter)), _
               mynull, FILE_SHARE_READ, _
               mynull, OPEN_EXISTING, 0, mynull)

and
               status = DeviceIoControl(hDevice, _
                   IOCTL_STORAGE_GET_MEDIA_TYPES_EX, mynull, 0, mediaTypes,
_
                   2048, returned, mynull)

The variable 'status': I made it a boolean.

Another thing: running within the IDE the CreateFile gives mostly a high
value, above 1000 for the device handle. Running the EXE the handle mostly
has the value of 152. Could that be the problem?

Tia
John
Uwe Sieber - 21 Jun 2007 11:59 GMT
>> Uwe, see reply in the text near your remarks.
>>
[quoted text clipped - 18 lines]
>> I found a snippet of code on http://www.devx.com/vb2themax/Tip/19403
>> That's where most of my this code came from.

Ok, in a more readable fashion of the code I see now
that 7 and 8 are set later when GetDriveType returned
DRIVE_CDROM. It's ok.

>>>> hDevice = CreateFile("\\?\" & UCase$(Trim$(DriveLetter)), _
>>>>              GENERIC_READ, FILE_SHARE_READ, _
>>>>              mynull, OPEN_EXISTING, 0, mynull)

The problem is the useless mynull. It must be use with ByVal.
Just use ByVal 0& instead. Without ByVal VB puts the address
of the mynull variable on the stack where a 0 should be.

That it works without ByVal in the IDE is pure chance.

Uwe
John Kick - 21 Jun 2007 13:05 GMT
>>> Uwe, see reply in the text near your remarks.
>>>
[quoted text clipped - 34 lines]
>
> Uwe

I replaced all the mynull by ByVal 0& (in CreateFile and DeviceIOControl),
but program still stops after calling the DeviceIOControl api. It looks like
that the call terminates the running process, I do not get the MsgBox that
followes the DeviceIOControl.

Tia
John
Sinna - 22 Jun 2007 07:20 GMT
>> Uwe, see reply in the text near your remarks.

<snip>
>>>> hDevice = CreateFile("\\?\" & UCase$(Trim$(DriveLetter)), _
>>>>              GENERIC_READ, FILE_SHARE_READ, _
[quoted text clipped - 4 lines]
>> I will try that. Another reaction tells that referenced values are not
>> handled correct by the API (see remarks of Sinna)

<snip>
John,

You got my reaction wrong. I didn't say that referenced values are
handled incorrect by the API. The only thing I wanted to state was that
it's very important to pass the values in the correct way (ByVal or
ByRef). Calling the API in the IDE seems to be quite tolerant but once
compiled it has to be correct.
I've experienced this when calling the CopyMemory API for a VB User
Defined Type.

Sinna
Thorsten Albers - 21 Jun 2007 12:21 GMT
John Kick <john@kickfakeadr.com> schrieb im Beitrag
<4679aa33$0$6758$e4fe514c@dreader27.news.xs4all.nl>...
...
Dim mynull As Long
...
status = DeviceIoControl(hDevice, _
                        IOCTL_STORAGE_GET_MEDIA_TYPES_EX,
                        mynull,
                        0,
                        mediaTypes,
                        2048,
                        returned,
                        ByVal 0)

a)
 Dim mynull As Long

 ...
 mynull,
 ...

This allocates memory for a 4 byte value which is initialized by VB to 0,
and uses 'mynull' as a symbol for the pointer to the allocated memory. It
is >not< a NULL pointer!
To pass a NULL pointer for a parameter declared as 'ByRef ... As Any' use
e.g.
 ByVal 0&

b)
...
mediaTypes,
2048,
...

You never, never, never should give the size of a memory block as an
absolute value but let VB calculate the size for you, if possible:
...
mediaTypes,
Len(mediaTypes),
...

c)
...
ByVal 0)

Any number in VB not suffixed by a VB data type suffix gets handled as a 2
byte integer value. So, this will pass the >>2<< bytes 00 00 to
DeviceIoControl(). But since DeviceIoControl() for this parameter expects a
>>4<< byte memory pointer it reads 2 additional bytes from the stack the
value of which is undefined. They may be 00, but they don't need to be.
This is very likely to cause a crash or at least let DeviceIoControl()
fail. Change it to:
 ByVal 0&

> Public Type DEVICE_MEDIA_INFO
>     Cylinders As Double
[quoted text clipped - 5 lines]
>     MediaCharacteristics As Long
> End Type

> Public Type GET_MEDIA_TYPES
>    DeviceType As Long
>    MediaInfoCount As Long
>    MediaInfo(0) As DEVICE_MEDIA_INFO
> End Type

IOCTL_STORAGE_GET_MEDIA_TYPES_EX returns "information about the types of
media supported by a device". I.e. it possibly returns a GET_MEDIA_TYPES
struktur with >>more then 1<< DEVICE_MEDIA_INFO strukture.
Your deklaration of GET_MEDIA_TYPES is for a GET_MEDIA_TYPES struktur with
>>only 1<< DEVICE_MEDIA_INFO strukture!

The usual procedure in such cases is (schematically):
1. Call to DeviceIoControl() with no pointer to output buffer (NULL) and
zero output buffer length (0).
 -> DeviceIoControl() returns the output buffer size needed.
2. ReDim abData(0 To <Needed buffer size - >) As Byte
3. Call to DeviceIoControl() with pointer to and size of abData().
 -> DeviceIoControl() fills abData() with the data requested.
4. Read the data from abData() to the respective struktures (use
RtlMoveMemory()).

Signature

----------------------------------------------------------------------
THORSTEN ALBERS                       Universität Freiburg
                                               albers@
                                                      uni-freiburg.de
----------------------------------------------------------------------

John Kick - 21 Jun 2007 13:24 GMT
> John Kick <john@kickfakeadr.com> schrieb im Beitrag
> <4679aa33$0$6758$e4fe514c@dreader27.news.xs4all.nl>...
[quoted text clipped - 23 lines]
> e.g.
>  ByVal 0&

Ok, I've done that

> b)
> ...
[quoted text clipped - 8 lines]
> Len(mediaTypes),
> ...

This is not working, the program stops immediately.

> c)
> ...
[quoted text clipped - 9 lines]
> fail. Change it to:
>  ByVal 0&

Changed to Byval 0&

>> Public Type DEVICE_MEDIA_INFO
>>     Cylinders As Double
[quoted text clipped - 27 lines]
> 4. Read the data from abData() to the respective struktures (use
> RtlMoveMemory()).

Can you give an example?
And how does DeviceIOControl returns the needed buffer size? like
BUFLEN=DeviceIOControl(....)?

Tia,
John
Thorsten Albers - 21 Jun 2007 20:48 GMT
John Kick <john@kickfakeadr.com> schrieb im Beitrag
<467a6dff$0$8328$e4fe514c@dreader28.news.xs4all.nl>...
> > b)
> > ...
[quoted text clipped - 9 lines]
> > ...
> This is not working, the program stops immediately.

The program surely doesn't stop because of this! The reason for it to stopp
is another one.

> Can you give an example?

Sorry, not now due to lack of time.

> And how does DeviceIOControl returns the needed buffer size? like
> BUFLEN=DeviceIOControl(....)?

Read the documentation! The value returned by DeviceIoControl() is a
boolean value which either is TRUE (<> 0) or FALSE (0). If the procedure as
described in my previous posting is supported by the driver of the used
device, DeviceIoControl() returns the output buffer size needed in
'lpBytesReturned'.

Signature

----------------------------------------------------------------------
THORSTEN ALBERS                       Universität Freiburg
                                               albers@
                                                      uni-freiburg.de
----------------------------------------------------------------------

John Kick - 22 Jun 2007 11:41 GMT
> John Kick <john@kickfakeadr.com> schrieb im Beitrag
> <467a6dff$0$8328$e4fe514c@dreader28.news.xs4all.nl>...
[quoted text clipped - 29 lines]
> device, DeviceIoControl() returns the output buffer size needed in
> 'lpBytesReturned'.

Thanks, I presume I misread that.

I'll try the suggestion.

John
John - 25 Jun 2007 14:08 GMT
> John Kick <john@kickfakeadr.com> schrieb im Beitrag
> <467a6dff$0$8328$e4fe514c@dreader28.news.xs4all.nl>...
[quoted text clipped - 27 lines]
> device, DeviceIoControl() returns the output buffer size needed in
> 'lpBytesReturned'.

Thorsten,
Vielen dank/Thanks a lot,

My program is working now exactly as ment to work, I now can go on with
adding functionality to the program.

Grtnx
John
Sinna - 21 Jun 2007 07:33 GMT
> Hi,
>
[quoted text clipped - 249 lines]
>
>  

In most cases it's a problem with the way you call the API.
Recently I had a same issue: in the IDE is runs like a charm, when
compiled: BANG!
Finally I found out I had to pass a variable by value instead of by
reference.

Sinna
John Kick - 21 Jun 2007 10:30 GMT
>> Hi,
>>
[quoted text clipped - 256 lines]
>
> Sinna

Thanks for the tip, I will try that.

John
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.