3

I have the following Visual Basic 6.0 function which writes an ANSI string to a new file over FTP. I would like it to write the file as UTF-16LE. Is there any good way to do that within this following method?

Public Sub writeToFile(ByVal FTPServer As String _
                 , ByVal userName As String _
                 , ByVal password As String _
                 , ByVal contents As String _
                 , ByVal destinationFile As String)

    Dim hFile As Long
    Dim lCount As Long

    inetOpen
    inetConnect FTPServer, userName, password
    hFile = apiFtpOpenFile(m_hFTP, destinationFile, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY, 0&)
    If hFile = 0 Then
        Err.Raise EWMFTPErrorCodes.wmFTPSendError, , internetError
    End If

    If apiInternetWriteFile(hFile, contents, Len(contents), lCount) = 0 Then
        Err.Raise EWMFTPErrorCodes.wmFTPSendError, , internetError
    End If

    apiInternetCloseHandle hFile
End Sub

I haven't done Visual Basic 6.0 in about 10 years, so I'm shaky at best. Any input would be greatly appreciated.

Here is the apiInternetWriteFile declaration;

Private Declare Function apiInternetWriteFile Lib "wininet.dll" Alias "InternetWriteFile" ( _
                         ByVal hFile As Long _
                       , ByVal lpBuffer As String _
                       , ByVal dwNumberOfBytesToWrite As Long _
                       , ByRef lpdwNumberOfBytesWritten As Long) As Long
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
cc0
  • 1,960
  • 7
  • 40
  • 57

1 Answers1

2

We need to see the declaration for apiInternetWriteFile. I'm pretty sure it's a Declare into an API call, maybe something in WinINet.dll. My guess is that you need to:

  • Change the Declare so it expects a ByVal Long for the 2nd argument
  • EDIT to get a BOM at the start, try Contents = ChrW(&HFEFF&) & Contents. Or possibly FFEF, not sure of the endianness.
  • Pass StrPtr(contents) for the 2nd argument
  • Pass Len(contents)*2 for the 3rd argument (length in bytes)

That will pass a Unicode UTF-16 string as the contents argument

MarkJ
  • 30,070
  • 5
  • 68
  • 111
  • Doh, I thought that worked perfectly, the file size is now double. However it does not have the UTF-16LE BOM (ff fe). Any suggestion on how to go about that? – cc0 Mar 31 '11 at 10:53
  • 1
    See my edit, please post back to let us know whether it works & I'll edit accordingly. – MarkJ Mar 31 '11 at 11:26
  • LE is FFFE, and your edit does put the BOM in there, but the text becomes all jibberish. Something is askew. I was trying to convert the string to byte array, then concatenate with a BOM byte array. Then I had the suggestion of using an ADO Stream object, which seems even better. Although if you could find a simple solution to this, I would love to see it. – cc0 Mar 31 '11 at 12:00
  • 2
    Have you tried ChrW$(&HFEFF&) yet? This function takes a positive Long value, not a signed Integer. If you think about what "little endian" means it should be obvious this is correct. – Bob77 Mar 31 '11 at 14:43
  • Wow, perfect. That worked like a charm. Thank you! Could you explain the two "&"s inside the paranthesis there? – cc0 Mar 31 '11 at 18:16
  • 1
    &H indicates the start of a hex integer literal, and the trailing & makes it a Long (4 byte signed integer) rather than the default Integer (2 byte signed integer). Without the trailing & suggested by Bob, my original code was passing a **negative value** to ChrW and you weren't getting the correct BOM. – MarkJ Mar 31 '11 at 20:27
  • 2
    When I want a Long value in hex I'm in the habit of always typing it as &H0xxxxx& if I use less than 8 hex digits. The IDE will trim leading 0s and drop the trailing & if redundant once you move from the statement. Been burnt too many times I suppose, so I watch for the change as a visual check. – Bob77 Mar 31 '11 at 20:34