issues with FindFirstFile API call

C

Comcast Newsgroups

Hello everyone,



I am programming in Visual Studio 2002, VB.net. I typically stick to
version 1.0 of the framework for compatibility reasons. Recently, I ran
into an issue that I couldn't solve with the framework. I am working with
file paths that exceed that MAX_PATH ANSI limitation in the framework. I
have to Windows API Unicode functions.



I am having an issue with the FindFirstFile API function. I am using it to
determine whether a file or directory exists. Interestingly, if I pass a
directory with a "*" wildcard at the end, the function does return a handle
to the directory. For example, \\?\C:\temp\* returns a valid handle. If I
pass a file, such as \\?\C:\temp\test.xls, I cannot obtain a handle, and the
FindFirstFile returns INVALID_HANDLE_VALUE.



I have the FindFirstFile function declared as follows:



<DllImport("kernel32", EntryPoint:="FindFirstFileW",
CharSet:=CharSet.Unicode, SetLastError:=True, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Shared Function FindFirstFile(ByVal lpFileName As String, <Out()> ByVal
lpFindFileData As WIN32_FIND_DATA) As IntPtr



WIN32_FIND_DATA is wrapped in a Class and so is FILETIME. This allows me
to pass both types as references to the API function, which I don't believe
I can do with structures.



<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Public Class WIN32_FIND_DATA'

Private Const MAX_PATH As Integer = 1024
Public dwFileAttributes As Long
Public ftCreationTime As FILETIME
Public ftLastAccessTime As FILETIME
Public ftLastWriteTime As FILETIME
Public nFileSizeHigh As Long
Public nFileSizeLow As Long
Public dwReserved0 As Long
Public dwReserved1 As Long
<VBFixedString(MAX_PATH), MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=MAX_PATH)> Public cFileName As String ' MAX_PATH - full filename
<VBFixedString(14), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=14)>
Public cAlternateFileName As String ' Dos Name

.........

End Class

I then create a new object of WIN32_FIND_DATA class, and pass it to the
FindFirstFile function, with a string path of the file as such:

lFileHdl = FindFirstFile("\\?\" & sFile, lpFindFileData)

lFileHdl is of type IntPtr and is always -1, unless I pass a Directory with
a "*" wildcard at the end. I know the file exists.

Can anyone shine some light on this?

Thank you in advance,

dmitry
 
K

Karl E. Peterson

Comcast Newsgroups said:
I am programming in Visual Studio 2002, VB.net.

Please *remove* the ClassicVB group (m.p.vb.winapi) from replies and follow-ups!

fu2: m.p.dotnet.*
 
H

Herfried K. Wagner [MVP]

Comcast Newsgroups said:
<DllImport("kernel32", EntryPoint:="FindFirstFileW",
CharSet:=CharSet.Unicode, SetLastError:=True, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Shared Function FindFirstFile(ByVal lpFileName As String, <Out()> ByVal
lpFindFileData As WIN32_FIND_DATA) As IntPtr

WIN32_FIND_DATA is wrapped in a Class and so is FILETIME. This allows me
to pass both types as references to the API function, which I don't
believe I can do with structures.

You could use structures too. Then you'd have to pass the parameter 'ByRef'
instead of 'ByVal'.
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Public Class WIN32_FIND_DATA'

Private Const MAX_PATH As Integer = 1024
Public dwFileAttributes As Long
Public ftCreationTime As FILETIME
Public ftLastAccessTime As FILETIME
Public ftLastWriteTime As FILETIME
Public nFileSizeHigh As Long
Public nFileSizeLow As Long
Public dwReserved0 As Long
Public dwReserved1 As Long

Your data types are wrong here. 'DWORD' is 'Int32' ('Integer') in VB.NET.
'Long' is a 64-bit type, whereas it has been a 32-bit type in VB6.
 
C

Comcast Newsgroups

Herfried,

Thank you for your reply. I tried what you had suggested and changed by
datatypes to Int32 (I also tried Integer, just in case). I still can't get
a handle to a file. I am still fine with getting a handle to a directory.
Is it possible that WIN32_FIND_DATA structure changes when dealing with the
Unicode version of FindFirstFile? I am unable to find any documentation of
such, with the exception that WIN32_FIND_DATA is WIN32_FIND_DATAW when
dealing with Unicode.

Thanks,

Dmitry
 
M

Mattias Sjögren

WIN32_FIND_DATA is wrapped in a Class and so is FILETIME.

FILETIME must be a structure for it to work correctly. You can use the
one defined in the System.Runtime.InteropServices.ComTypes namespace.


Mattias
 
D

Dmitry Akselrod

Mattias,

Thank you for your suggestion. I tried using the FILETIME structure you
suggested. It hadn't changed the results, unfortunately. I can still get
a handle to a directory, just not a file. This is just weird.

Thanks,
dmitry
 
T

Thorsten Albers

Dmitry Akselrod said:
Thank you for your suggestion. I tried using the FILETIME structure you
suggested. It hadn't changed the results, unfortunately. I can still get
a handle to a directory, just not a file. This is just weird.

You were asked to remove the ClassicVB group (microsoft.public.vb.winapi)
from your list of newsgroups. Please do so! This newsgroup
microsoft.public.vb.winapi is related to Windows API programming with MS
Visual Basic 6.0 which has very few things in common with MS Visual
Basic.NET. In this newsgroup we are >>not<< discussing subjectes related to
the MS VB.NET!

--
 
H

Herfried K. Wagner [MVP]

Thorsten,

Thorsten Albers said:
You were asked to remove the ClassicVB group (microsoft.public.vb.winapi)
from your list of newsgroups. Please do so! This newsgroup
microsoft.public.vb.winapi is related to Windows API programming with MS
Visual Basic 6.0 which has very few things in common with MS Visual
Basic.NET. In this newsgroup we are >>not<< discussing subjectes related
to
the MS VB.NET!

Well, may I ask why you are posting that to the VB.NET group too (no, I do
not expect an answer...)?

;-)
 
M

Mattias Sjögren

Thank you for your suggestion. I tried using the FILETIME structure you
suggested. It hadn't changed the results, unfortunately. I can still get
a handle to a directory, just not a file. This is just weird.

What does Marshal.GetLastWin32Error() return?


Mattias
 
D

Dmitry Akselrod

Mattias,

Thanks again, Marshal.GetLastWin32Error retuns Error # 3. I have a Debug
statement that fires right after the statement where I attempt to obtain a
handle to the file I am searching for.

Last Win32 Error #: 3 Description: The system cannot find the path
specified.
Dmitry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top