Re: Error 52 Bad file name or number on file read



Sorry Nick but if you're ending up with a mixture of ANSI and Unicode data
then you're doing something wrong. If you follow the rules then you should
only have textual data in one of the formats. Also, it's strongly
recommended to use byte arrays for ANSI data and not VB Strings since the
latter are always assumed to hold valid Unicode.

The following variation of your code works fine here, and returns proper
Unicode file names and directory names:

'--------------------------------
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW"
( _
ByVal lpFileName As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW"
( _
ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long)
As Long

Const MAX_PATH = 260
Const MAX_PATH_UNICODE = 2 * (MAX_PATH - 1)
Const INVALID_HANDLE_VALUE = -1

Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName(MAX_PATH_UNICODE) As Byte
cAlternate As String * 14
End Type

Public Function StripNulls(sText As String) As String
If (InStr(sText, Chr$(0)) > 0) Then
StripNulls = Left$(sText, InStr(sText, Chr$(0)) - 1)
Else
StripNulls = sText
End If
End Function

Private Sub Form_Load()
Dim tWFD As WIN32_FIND_DATA
Dim sPath As String, sDirName As String, hSearch As Long

sPath = "H:\HKF-Docs\*.*"
hSearch = FindFirstFile(StrPtr(sPath), tWFD)
If hSearch <> INVALID_HANDLE_VALUE Then
Do
' Convert byte array to Unicode string
sDirName = tWFD.cFileName
' Make sure there are no superfluous trailing Unicode NUL
characters
sDirName = StripNulls(sDirName)
' Ignore the current and encompassing directories.
If (sDirName <> ".") And (sDirName <> "..") Then
Debug.Print sDirName
End If
Loop While FindNextFile(hSearch, tWFD) <> 0
FindClose hSearch
End If
End Sub
'--------------------------------


Tony Proctor

"NickHK" <TungCheWah@xxxxxxxxxxx> wrote in message
news:OMVLkh0RGHA.5156@xxxxxxxxxxxxxxxxxxxxxxx

English W2K:
Although I am not the OP on this, the topic (if it was correct about the
non-ANSI characters in the filename/path) is something that has I've been
struggling with a while. So thanks for the incentive to look at it again.

FindFirstFile and Dir (which is a wrapper FindFirstFileA ??) both get
hosed,
not surprisingly.
But I have made some progress with help from
http://forums.devx.com/printthread.php?t=136183

Const HomeDir As String = "\\?\H:\HKF-Docs\" '\\?\ to allow longer path
than MAX_PATH
Const SearchStr As String ="*.*"

Private Declare Function FindFirstFile Lib "kernel32" Alias
"FindFirstFileW"
(ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW"
(ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As
Long)
As Long

Const MAX_PATH = 260
Const MAX_PATH_UNICODE = 2 * MAX_PATH - 1
Const INVALID_HANDLE_VALUE = -1

Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName (MAX_PATH_UNICODE) As Byte
cAlternate As String * 14
End Type


Dim WFD As WIN32_FIND_DATA
hSearch = FindFirstFile(StrConv(HomeDir & SearchStr, vbUnicode), WFD)
'Then if no error, strip Nulls from WFD.cFileName, compare against "." &
"..", then output
Find Next til done

Still have a problem stripping the NULLs if a mix of Unicode and ANSI
character, as the second byte of the ANSI is NULL and hence the string is
truncated prematurely.
e.g. 114 130 166 143 65 0 49 0 46 0 120 108 0 0 0 0 0 0
0
0 > 114 130 166 143 65
Do you have to test for null on the odd bytes only ?

NickHK


"J French" <erewhon@xxxxxxxxxx> wrote in message
news:4415666a.100403653@xxxxxxxxxxxxxxxxxxxxxxx
On Mon, 13 Mar 2006 16:19:24 +0800, "NickHK" <TungCheWah@xxxxxxxxxxx>
wrote:

I get that error trying this code on files with Chinese characters in
the
name or path.

Right - so we have a Unicrud file system and you are working in ANSI

Sounds like a trip down the Wide API Lane is needed

How are you locating the files to inspect, using Dir$() or
FindFirstFile() ?






.



Relevant Pages

  • Re: Did Borland doing well in Q4? Listen to the Earning CC
    ... AS an ANSI application you will need to change all "String" ... declarations to "ANSIString" (and Char to ANSIChar and PChar to ... Only THEN can you start thinking about how Unicode is best ... Even the specifically "ANSI" FS routines do not use ...
    (borland.public.delphi.non-technical)
  • Re: using structs like BROWSEINFO and OPENFILENAME (string members
    ... your discussion of unicode ... vs ansi reminded me to recheck my typelib and found a couple of errors. ... > is declared as string, the other is declared as long. ...
    (microsoft.public.vb.winapi)
  • Re: api call for tchar*
    ... > String passes an ANSI version while a ByRef passes a Unicode version. ... The row of characters is preceded by a Long ...
    (microsoft.public.vb.winapi)
  • Re: length checking...
    ... ANSI string. ... Win9x is dead, so all apps are becoming NT-only, which means - no reasons ... Unicode is much simpler then ANSI, and I would recommend Unicode for beginners ...
    (microsoft.public.development.device.drivers)
  • Re: CeGetFileAttributes always fails
    ... I'm not a VB programmer so I don't know how VB deals with UNICODE, ... > ftCreationTime As FILETIME ... > ByVal lpFileName As String) As Long ... > Dim hFind As Long ...
    (microsoft.public.pocketpc.developer)

Quantcast