views:

31

answers:

1

I have the following piece of code. This is written for getting the list of timezones from registry and populating into an array. This piece of code works fine in Win7 and Vista OS but not in WinXp and Win2k3.

The reason is because of the size of array getting overflown. I have defined only 100 elements. However there are more than 100 elements in the registry.

Now my question is why this does not fail in Vista or Win7 machines. Is there any difference in allocation of memory between Xp and Vista OS.

It crashes in the line while getting 100the element from registry

while( RegEnumKeyEx( Key, nTimezones, tzKeyNames[nTimezones].GetBuffer( size ), &size, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS )

Full code

 CString    sRegKey;
    HKEY    Key;
    HKEY    subKey;
    int     nTimezones = 0;
    CArray< CString, CString >  tzKeyNames;

tzOffset.SetSize( 100, 10 );
tzKeyNames.SetSize( 100, 10 );
tzDisplayNames.SetSize( 100, 10 );

OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
GetVersionEx(&osvi);

if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
sRegKey = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones");
}
else
{
sRegKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones");
}

if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, sRegKey, 0, KEY_READ , &Key ) == ERROR_SUCCESS )
{
    DWORD size;
    DWORD type = REG_SZ;
    TZINFO  tz;
    _TCHAR name[ 128 ];
    BYTE data[ 128 ];

    size = 128;
    while( RegEnumKeyEx( Key, nTimezones, tzKeyNames[nTimezones].GetBuffer( size ), &size, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS )
    {
        tzKeyNames[nTimezones].ReleaseBuffer();

        if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, sRegKey + _T("\\") + (LPCTSTR)tzKeyNames[nTimezones], 0, KEY_READ , &subKey ) == ERROR_SUCCESS )
        {
            size = 128;
            if( RegQueryValueEx( subKey, _T("Display"), NULL, &type, (unsigned char*)name, &size ) == ERROR_SUCCESS )
            {
                tzDisplayNames[nTimezones] = name;
            }

            size = 128;
            if( RegQueryValueEx( subKey, _T("TZI"), NULL, &type, data, &size ) == ERROR_SUCCESS )
            {
                memcpy( &tz, data, size );
                tzOffset[ nTimezones ] = (int)(( tz.Bias / -60.0 ) * 2.0 ) + 24;
            }
            RegCloseKey( subKey );      
        }
        nTimezones++;
    }
    RegCloseKey( Key );     
}
+1  A: 

Exception is raised when application tries to read/write a piece of memory that is not in it's address space. In one case after the array there was addressed memory, in other there wasn't. This is random. And yes, various allocation algorithm will lead to various results but this is only one element causing randomness. The results are also dependent on how many bytes are allocated and where they are allocated by your application, other applications and the OS itself.

// EDIT

tzKeyNames[nTimezones].ReleaseBuffer();

Probably the problem is not in reading after the array's end (it's usually within addressed space) but that some garbage was read. This garbage is used as a pointer, when dereferenced causes exception.

adf88