Results 1 to 6 of 6

Thread: [RESOLVED] Unicode problem: read binary file at spesific position with unicode path

  1. #1

    Thread Starter
    Member
    Join Date
    Dec 2009
    Posts
    33

    Resolved [RESOLVED] Unicode problem: read binary file at spesific position with unicode path

    i have a code like this:

    Code:
    Public Function GetBin(ByVal lpFileName As String, ByVal lpByteCount As Long, Optional ByVal StartByte As Long = 0) As String
    On Error Resume Next
    Dim Bin() As Byte
    Dim ByteSum As Long
    Dim i As Long
    
    ReDim Bin(lpByteCount) As Byte
    
    Open lpFileName For Binary As #1
        If StartByte = 0 Then
            Get #1, , Bin
        Else
            Get #1, StartByte, Bin
        End If
    Close #1
    
    For i = 0 To lpByteCount
        ByteSum = ByteSum + Bin(i)
    Next i
    
    GetBin = ByteSum
    
    End Function
    which can read spesific bytes within spesific position.
    the problem is:

    how to make it supports unicode path?

    or..
    is there any replacement for this function??
    Last edited by astralist; Jan 10th, 2010 at 07:38 AM.

  2. #2
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: [HELP] Unicode problem: read binary file at spesific position with unicode path

    Can you help an idiot here by explaining what you mean by unicode path? Is lpFileName not unicode anyway?
    W o t . S i g

  3. #3
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: [HELP] Unicode problem: read binary file at spesific position with unicode path

    This probably refers to either files where the path is longer than MAXPATH (around 260) and/or where the full path name contains characters that can't be mapped from a VB6 (Unicode) String to the ANSI codepage for the current locale.

    Almost everything VB6 does with its native I/O statements involves such translation to ANSI so that VB6 programs can still work on Win9X machines where Unicode was not natively supported.

    To work with files using Unicode paths you usually have to resort to the wide-char ("Unicode") versions of system API calls with names ending in W instead of A. You would then generally have to prefix pathnames with "\\?\" as well, which tells the system you are supplying a Unicode path.

    VB6's Open statement will accept names starting with "\\?\" but I don't think this means that unmappable characters or paths exceeding MAXPATH will actually work. Lots of other VB6 I/O functions (such as Dir$() and GetAttr()) may fail if you feed them a "\\?\" path too.


    A long-winded way of saying I think the OP wants to use paths containing some characters that don't map to his default ANSI codepage. I could be wrong about this, and I suppose it is also possible that characters which do successfully map but exceed &H7F after mapping fail too (accented letters, etc.).

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [HELP] Unicode problem: read binary file at spesific position with unicode path

    CreateFileW, ReadFile & WriteFile APIs are unicode compatible. They have no problems with unicode path or file names. Once you have a file handle (CreateFileW), you can read the bytes into your array. Here's an example I use quite often, tweak to taste.

    Note: I added the bUnicode variable in function below but never do that in my projects. I cache the value to a form-level variable in form load so the routines always know whether to use unicode or ansi APIs elsewhere in the project. Besides, caching it once is a bit faster vs testing every time.

    Edited: For the GetFileHandle to work, the passed file name must be valid, it can't contain a path/filename like ?????. So if you are offering your customers an option to select a file, use a unicode version of the common dialog. A fair substitute example can be found in my signature below.
    Code:
    Private Function GetFileHandle(FileName As String, bRead As Boolean) As Long
    
        ' Function uses APIs to read/create files with unicode support
    
        Const GENERIC_READ As Long = &H80000000
        Const OPEN_EXISTING = &H3
        Const FILE_SHARE_READ = &H1
        Const GENERIC_WRITE As Long = &H40000000
        Const FILE_SHARE_WRITE As Long = &H2
        Const CREATE_ALWAYS As Long = 2
        Const FILE_ATTRIBUTE_ARCHIVE As Long = &H20
        Const FILE_ATTRIBUTE_HIDDEN As Long = &H2
        Const FILE_ATTRIBUTE_READONLY As Long = &H1
        Const FILE_ATTRIBUTE_SYSTEM As Long = &H4
        Const FILE_ATTRIBUTE_NORMAL = &H80&
        
        Dim Flags As Long, Access As Long
        Dim Disposition As Long, Share As Long, hFile As Long
    
        Dim bUnicode As Boolean
        bUnicode = Not (IsWindowUnicode(GetDesktopWindow) = 0&)
        
        If bRead Then
            Access = GENERIC_READ
            Share = FILE_SHARE_READ
            Disposition = OPEN_EXISTING
            Flags = FILE_ATTRIBUTE_ARCHIVE Or FILE_ATTRIBUTE_HIDDEN Or FILE_ATTRIBUTE_NORMAL _
                    Or FILE_ATTRIBUTE_READONLY Or FILE_ATTRIBUTE_SYSTEM
        Else
            Access = GENERIC_READ Or GENERIC_WRITE
            Share = 0&
            If bUnicode Then
                Flags = GetFileAttributesW(StrPtr(FileName))
                If (Flags And FILE_ATTRIBUTE_READONLY) Then
                    Flags = FILE_ATTRIBUTE_NORMAL
                    SetFileAttributesW StrPtr(FileName), Flags
                End If
            Else
                Flags = GetFileAttributes(FileName)
                If (Flags And FILE_ATTRIBUTE_READONLY) Then
                    Flags = FILE_ATTRIBUTE_NORMAL
                    SetFileAttributes FileName, Flags
                End If
            End If
            If Flags < 0& Then Flags = FILE_ATTRIBUTE_NORMAL
            ' CREATE_ALWAYS will delete previous file if necessary
            Disposition = CREATE_ALWAYS
        End If
        
        If bUnicode Then
            hFile = CreateFileW(StrPtr(FileName), Access, Share, ByVal 0&, Disposition, Flags, 0&)
            If hFile = 0& Then hFile = INVALID_HANDLE_VALUE
        Else
            hFile = CreateFile(FileName, Access, Share, ByVal 0&, Disposition, Flags, 0&)
            If hFile = 0& Then hFile = INVALID_HANDLE_VALUE
        End If
        
        GetFileHandle = hFile
    
    End Function
    
    ' changes to your routine
    Public Function GetBin(ByVal lpFileName As String, ByVal lpByteCount As Long, Optional ByVal StartByte As Long = 0) As String
    On Error Resume Next
    Dim Bin() As Byte
    Dim ByteSum As Long
    Dim i As Long
    Dim hFile As Long, lNrRead As Long
    
    hFile = GetFileHandle(lpFileName, True)
    If hFile = INVALID_HANDLE_VALUE Then
         MsgBox "Failed to access the passed file name"
    Else
         ReDim Bin(lpByteCount) As Byte
    
         SetFilePointer hFile, 0&, 0&, ByVal 0& ' beginning of file
         ReadFile hFile, Bin(0), lpByteCount, lNrRead, ByVal 0&
         CloseHandle hFile
         If lpByteCount < lNrRead Then
             MsgBox "Not all data was read."
             ' Reasons: 1) StartByte > FileLength, 2) lbByteCount+StartByte > FileLength, 3) other
         Else
            For i = 0 To lpByteCount
                ByteSum = ByteSum + Bin(i)
            Next i
            GetBin = ByteSum
         End If
    End If
    End Function
    Here are the API declarations. To get more details about the APIs recommend reading about them on MSDN or AllAPI.net
    Code:
    Private Declare Function IsWindowUnicode Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
    Private Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByRef lpOverlapped As Any) As Long
    Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
    Private Declare Function CreateFileW Lib "kernel32" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
    Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
    Private Declare Function DeleteFileW Lib "kernel32.dll" (ByVal lpFileName As Long) As Long
    Private Declare Function DeleteFileA Lib "kernel32.dll" (ByVal lpFileName As String) As Long
    Private Declare Function SetFileAttributesW Lib "kernel32.dll" (ByVal lpFileName As Long, ByVal dwFileAttributes As Long) As Long
    Private Declare Function SetFileAttributes Lib "kernel32.dll" Alias "SetFileAttributesA" (ByVal lpFileName As String, ByVal dwFileAttributes As Long) As Long
    Private Declare Function GetFileAttributesW Lib "kernel32.dll" (ByVal lpFileName As Long) As Long
    Private Declare Function GetFileAttributes Lib "kernel32.dll" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
    Private Declare Function GetFileSize Lib "kernel32.dll" (ByVal hFile As Long, ByVal lpFileSizeHigh As Long) As Long
    Private Declare Function SetFilePointer Lib "kernel32.dll" (ByVal hFile As Long, ByVal lDistanceToMove As Long, ByRef lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Const INVALID_HANDLE_VALUE = -1&
    Last edited by LaVolpe; Dec 31st, 2009 at 07:15 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    Member
    Join Date
    Dec 2009
    Posts
    33

    Re: [HELP] Unicode problem: read binary file at spesific position with unicode path

    WOW!

    thanks a lot LaVolpe

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [HELP] Unicode problem: read binary file at spesific position with unicode path

    You are welcome. In order to use your optional StartByte parameter, suggest changing related line to:
    SetFilePointer hFile, startByte, 0&, ByVal 0&
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width