Microsoft KB Archive/199929

From BetaArchive Wiki

Article ID: 199929

Article Last Modified on 1/23/2007



APPLIES TO

  • Microsoft Office XP Developer Edition
  • Microsoft Office 2000 Developer Edition
  • Microsoft Access 97 Standard Edition
  • Microsoft ActiveX Data Objects 2.0
  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic 6.0 Enterprise Edition



This article was previously published under Q199929

SYMPTOMS

When using the Data Access Objects (DAO), Remote Data Objects (RDO) or the ADO GetChunk method, on a long binary field of a Microsoft Access database, binary data may appear corrupt if the binary information previously stored was read from disk using a String (BSTR) variable instead of a Byte array. The problem occurs under one of the following conditions:

  • You recently upgraded your computer to Windows 98 or Windows NT version 4.0 SP4. Previously stored data now appears corrupt.


-or-

  • You are using a shared database. The corruption occurs when the binary data was stored by clients running on Windows 95 or Windows NT 4.0 SP3, and then extracted by clients running Windows 98 or Windows NT 4.0 SP4 or vice versa.


CAUSE

The problem is that the information stored to the database is mistakenly being converted to Unicode before being stored. The "corruption" occurs when reading the information from disk using the Visual Basic or Visual Basic for Applications Get statement.

By design, the Get statement relies on the data type of the variable to determine how the information should be read into Visual Basic. If you pass a String (BSTR) variable to the function, Visual Basic identifies the information as being a text string, and converts it to Unicode. However, since the data is binary and not text, this conversion corrupts the data before it is ever stored to the database.

Although binary data stored in Unicode format can be "decoded" in some cases, it requires that the Unicode symbol table used to map 1-byte ANSI characters to 2-byte Unicode characters be the same for both the conversion to and the conversion from Unicode. Due to the recent addition of the European Currency symbol, the symbol table for Windows 98 and Windows NT 4.0 SP4 is different from those used previously. These changes will have no effect on text strings, but can effect binary data mistakenly converted to Unicode.

RESOLUTION

NOTE: Binary data should never be converted to/from Unicode. To avoid the possibility of such conversions, do not use BSTRs when working with binary data. Instead use a Byte array. For example:

   Dim yBinaryData() As Byte

   Open "C:\MyFile.dat" For Binary As #1
      ReDim yBinaryData(LOF(1)) As Byte
      Get #1, , yBinaryData
   Close #1
   rs.Fields("MyData").AppendChunk yBinaryData
                

For databases with "corrupted" data already stored, you will need to extract the information on a Windows 98 or Windows NT 4.0 SP3 computer and restore it correctly using a byte array.

STATUS

This behavior is by design.

MORE INFORMATION

To reproduce the behavior you need a .bmp image file (or other binary file) and two computers, one running Windows 95 and another running Windows 98.

Steps to Reproduce Behavior

  1. Start Microsoft Access and create a new database.
  2. Create a new Table and add the following fields:

    Name Type
    ID (Primary Key) AutoNumber
    Picture OLE Object
  3. Save the Table as BinData.
  4. Create a new Module and enter the following sample code:

          Sub TestPicIn(sFileName As String)
             Dim db As Database
             Dim rs As Recordset
             Dim sData As String
             Dim nDataSize As Long
    
             Set db = CurrentDb()
             Set rs = db.OpenRecordset("BinData")
             rs.AddNew
                Open sFileName For Binary As #1
                  nDataSize = LOF(1)
                  sData = Space$(nDataSize)
                  Get #1, , sData
                Close #1
             rs!Picture.AppendChunk sData
             rs.Update
          End Sub
    
          Sub TestPicOut(sFileName As String)
             Dim db As Database
             Dim rs As Recordset
             Dim sData As String
             Dim nDataSize As Long
    
             Set db = CurrentDb()
             Set rs = db.OpenRecordset("BinData")
             If Not rs.EOF Then
                nDataSize = rs!Picture.FieldSize
                sData = rs!Picture.GetChunk(0, nDataSize)
    
                Open sFileName For Binary As #2
                  Put #2, , sData
                Close #2
             End If
          End Sub
                        
  5. Save the Module.
  6. On a Windows 95 computer, type the following in the module's Immediate window. Make sure the file exists at the specified location:

          TestPicIn "C:\Windows\Setup.bmp"
                        
  7. Copy the database to a Windows 98 or Windows NT SP4 computer, then open the database. Type the following in the module's Immediate window:

          TestPicOut "C:\Windows\Temp\TestPic.bmp"
                        

    RESULT: The image file is mistakenly converted to Unicode format before being stored to the database. Although it will "decode" correctly if extracted on the same Windows 95 computer that stored the image, when the data is extracted to a file on a Windows 98 computer, the image "decodes" incorrectly causing the new file to appear corrupt.


REFERENCES

For additional information about using GetChunk and AppendChunk, please see the following article in the Microsoft Knowledge Base:

153238 HOWTO: Use GetChunk and AppendChunk Methods of RDO Object


Keywords: kbautomation kbprb kbrdo KB199929