Solved

How to save an UTF-8 string as file name with CreateFileW API Function

Posted on 2006-11-02
2
1,025 Views
Last Modified: 2012-06-22
I am currently developing a upload component for web page, the html page uses UTF-8 encoding and uploads a file that named with simplified chinese characters. The vb6 component uses the MultiByteToWideChar API function to convert the data requested from Request object with UTF-8 (65001), then uses CreateTextW function to save file onto disk.

lngFileHandle = CreateFile(strFileName, GENERIC_WRITE, 0, ByVal 0&, CREATE_ALWAYS, 0, 0)

I've tried to use CreateFileA() function, but strFileName contained unicode chars which CreateFileA() did not recognise (shown as ?) and returned a "Bad file name or number" error.
Using CreateFileW(), it accepts the file name, but it does not recognise the encoding of strFileName and saves the file under the folder  where the vb project is running, this time the file name is made up of unknown characters.
I then use:
StrConv(strFileName, vbUnicode)
and got some of the simplified chinese characters right, and others became "?" or square blocks.
What I don't understand is that the byte array or string which passed into CreateFileW() is already in UTF-8 format, but still requires the StrConv() function to convert it into Unicode format to create a partially correct filename. Does Windows XP/2003 store file names in different format other than UTF-8?
Even if I pass a string without any encoding (e.g. "aaa"), CreateFileW() still creates the file with unreadable file name.
How can I save the file name in Unicode/UTF-8 format correctly without the need of StrConv()?

Thank you very much!

P.S. Please forgive me for my bad english.
0
Comment
Question by:guest321
2 Comments
 
LVL 22

Accepted Solution

by:
danaseaman earned 300 total points
ID: 17863452
Change Declare of CreateFileW so that strFileName is a Long. Then use StrPtr(strFileName) when you call it.
Something like this:

'in module

Option Explicit

'
' CreateFile constants
'
Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000
Private Const OPEN_EXISTING = 3
Private Const OPEN_ALWAYS As Long = 4
Private Const FILE_FLAG_BACKUP_SEMANTICS = &H2000000

Declare Function CreateFileA Lib "kernel32.dll" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByRef lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Declare Function CreateFileW Lib "kernel32.dll" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByRef lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long


Public Sub CreateFileTest(ByVal m_PathName As String)

   Dim hFile            As Long
   'hFile = CreateFileA(m_PathName, _
      GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, _
      ByVal 0&, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, 0)
     
    hFile = CreateFileW(StrPtr(m_PathName), _
      GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, _
      ByVal 0&, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, 0)
     
   Debug.Print "hFile", hFile
   CloseHandle hFile
End Sub

 
0
 

Author Comment

by:guest321
ID: 17865572
It works perfectly! Thank you very much!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Check Disk (CHKDSK) on all volumes and fix if needed. 8 177
Write data from SQL to CSV file - position 1 52
Vb.net 2008 2 56
Excel VBA combine two working workbooks 8 46
Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

929 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now