Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

Invalid/Foreign characters in value fetched from registry


Best Answer MSIYER , 09 May 2013 - 11:22

Yes Stefan, this Installscript function is a wrapper over Win32 API.

But the issue was more complicated than originally thought. I am going to share what I found in the hope that this solves someone else's problem too:

 
The value fetched from the registry by Installshield installer was written by a Win32 application. It has the following line of code:

RegSetValueEx(hKey, LEICA_PATH, 0, REG_SZ, (const unsigned 
char*)m_reqLeicaPath.GetBuffer(m_reqLeicaPath.GetLength()), 
m_reqLeicaPath.GetLength());

The RegSetValueEx function has the following signature:

LONG WINAPI RegSetValueEx(

  _In_        HKEY hKey,

  _In_opt_    LPCTSTR lpValueName,

  _Reserved_  DWORD Reserved,

  _In_        DWORD dwType,

  _In_        const BYTE *lpData,

  _In_        DWORD cbData

);

The MSDN reference for RegSetValueEx says the following about DWORD cbData:

cbData [in]

The size of the information pointed to by the lpData parameter, in bytes. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character or characters.

 

The actual cbData value that the application was passing was :

m_reqLeicaPath.GetLength()

The m_reqLeicaPath variable is a CString and the CString::GetLength() returns the byte count of the string without taking into account the terminating null of a string.

 

The correct cbData should have been:

(m_reqLeicaPath.GetLength() + 1)

RegSetValueEx specifically requires the byte count to include one/two bytes for null character depending on ANSI/UNICODE settings.

 

Thus the value being stored in the registry was not proper. The way it would be retrieved will also be not proper.

 

I am killing the application's bugs. I have also decided to clean up the string based on the backslash guarantee.

 

Go to the full post


4 replies to this topic

MSIYER

MSIYER
  • Full Members
  • 90 posts

Posted 07 May 2013 - 15:43

Hi,

 

I have an installer created using Installshield 2012 that depends greatly on the value of a Registry key written by some other application developed in-house.

I use RegDBGetKeyValueEx Installscript API to fetch the value.

 

This value is a directory path guaranteed to have a trailing backslash.

This value serves as the TARGETDIR for my installer.

 

The issue is that I often see a foreign character (Chinese, Japanese or Korean) appended to the backslash.

This causes my TARGETDIR to contain the foreign character. This pollutes my installation.

 

I feel this is some bug with Installscript API which wrongly translates the Registry value.

 

Please provide some inputs so that I may find the root-cause of the issue.


Edited by MSIYER, 07 May 2013 - 15:47.


Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 08 May 2013 - 14:51

I think that this InstallScript function is more or less a wrapper around the Windows API. Does the same problem happen with other registry entries or is therer something "special" with this entry?

As a workaround you could cut off the string after the last backslash.



MSIYER

MSIYER
  • Full Members
  • 90 posts

Posted 09 May 2013 - 11:22   Best Answer

Yes Stefan, this Installscript function is a wrapper over Win32 API.

But the issue was more complicated than originally thought. I am going to share what I found in the hope that this solves someone else's problem too:

 
The value fetched from the registry by Installshield installer was written by a Win32 application. It has the following line of code:

RegSetValueEx(hKey, LEICA_PATH, 0, REG_SZ, (const unsigned 
char*)m_reqLeicaPath.GetBuffer(m_reqLeicaPath.GetLength()), 
m_reqLeicaPath.GetLength());

The RegSetValueEx function has the following signature:

LONG WINAPI RegSetValueEx(

  _In_        HKEY hKey,

  _In_opt_    LPCTSTR lpValueName,

  _Reserved_  DWORD Reserved,

  _In_        DWORD dwType,

  _In_        const BYTE *lpData,

  _In_        DWORD cbData

);

The MSDN reference for RegSetValueEx says the following about DWORD cbData:

cbData [in]

The size of the information pointed to by the lpData parameter, in bytes. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character or characters.

 

The actual cbData value that the application was passing was :

m_reqLeicaPath.GetLength()

The m_reqLeicaPath variable is a CString and the CString::GetLength() returns the byte count of the string without taking into account the terminating null of a string.

 

The correct cbData should have been:

(m_reqLeicaPath.GetLength() + 1)

RegSetValueEx specifically requires the byte count to include one/two bytes for null character depending on ANSI/UNICODE settings.

 

Thus the value being stored in the registry was not proper. The way it would be retrieved will also be not proper.

 

I am killing the application's bugs. I have also decided to clean up the string based on the backslash guarantee.

 



Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 10 May 2013 - 20:00

That wasn't easy to find... good work.



MSIYER

MSIYER
  • Full Members
  • 90 posts

Posted 13 May 2013 - 10:38

I got some help from StackOverflow. The difficult part was identifying the application that was writing these entries and getting hold of the exact code.

Once that was done, one guy at StackOverflow, who had faced a similar issue earlier, pointed me in the right direction.

http://stackoverflow...d-from-registry