I have a VB6 app which gets a file path and must check if this path points to an actual file, as opposed to an LPT device, pipe, etc. I'm using the APIs CreateFile, GetFileType, and then CloseHandle.
Although this code works, when I attach a debugger to the program, the debugger breaks on an exception, saying that CloseHandle is trying to close a non-existing handle (or, sometimes, saying "invalid argument"). This happens even though I check (as you can see from the code) that the handle <> INVALID_HANDLE_VALUE.
I have two questions.
First, I think I need to change the call to CreateFile, from
handle = CreateFile(FilePath, 0, 0, ByVal 0&, OPEN_EXISTING, 0&, 0&)
...to
handle = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, FILE_ATTRIBUTES_ENUM.FA_NORMAL, 0&)
am I correct about this? I'm only using CreateFile to get the handle to pass over to GetFileType. I'm not actually doing anything with this file.
Second, why could this be happening? I'm checking if handle <> INVALID_HANDLE_VALUE, but still getting this error!
The results of the a dump are attached after the code.
Private Const OPEN_EXISTING As Long = 3
Private Const FILE_SHARE_READ As Long = &H1
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Const FILE_TYPE_DISK As Long = &H1
Private Const FILE_TYPE_CHAR As Long = &H2
Private Const FILE_TYPE_PIPE As Long = &H3
Private Const FILE_TYPE_REMOTE As Long = &H8000
Private Const FILE_TYPE_UNKNOWN As Long = &H0
Private Declare Function CloseHandle_API Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long
Private 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
Private Declare Function GetFileType_API Lib "kernel32" Alias "GetFileType" (ByVal hFile As Long) As Long
Private Function IsAnActualFile(FilePath As String, fileType As Long) As Boolean
On Error GoTo errHandle
Dim handle As Long
Dim lpSecurityAttributes As Long
lpSecurityAttributes = 0
handle = CreateFile(FilePath, 0, 0, ByVal 0&, OPEN_EXISTING, 0&, 0&)
If handle <> INVALID_HANDLE_VALUE Then
fileType = GetFileType_API(handle)
If fileType = FILE_TYPE_DISK Then
IsAnActualFile = True
End If
CloseHandle_API handle
End If
errHandle:
If handle <> INVALID_HANDLE_VALUE Then CloseHandle_API handle
End Function
Here is the dump:
0:000> kb
ChildEBP RetAddr Args to Child
0018edf0 74ebc463 000038ec 000038ec 0018ee10 ntdll!NtClose+0x12
0018ee00 75141418 000038ec 00000001 0018ee68 KERNELBASE!CloseHandle+0x2d
0018ee10 1107ee38 000038ec 0018f32c 00000000 kernel32!CloseHandleImplementation+0x3f
0018ee68 1107d3ef 19cb5968 0018f32c 0018f158 MyProgram!Document::IsAnActualFile+0xb8