Problem with DeviceIoControl in VB
|
|
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
|
|
|