Issue with RegConnectRegistry connecting to 64 bit machines

Posted by RA on Stack Overflow See other posts from Stack Overflow or by RA
Published on 2010-03-08T15:50:50Z Indexed on 2010/03/27 8:53 UTC
Read the original article Hit count: 333

Filed under:
|
|

I'm seeing a weird thing when connecting to the performance registry on 64 bit editions of Windows. The whole program stalls and callstacks becomes unreadable. After a long timeout, the connection attempts aborts and everything goes back to normal.

The only solution is to make sure that only one thread at the time queries the remote registry, unless the remote machine is a 32 bit Windows XP, 2003, 2000 , then you can use as many threads as you like.

Have anyone a technical explanation why this might be happening ? I've spent 2-3 days searching the web without coming up with anything.

Here is a test program, run it first with one thread (connecting to a 64 bit Windows), then remove the comment in tmain and run it with 4 threads. Running it with one thread works as expected, running with 4, returns ERROR_BUSY (dwRet == 170) after stalling for a while.

Remember to set a remote machine correctly in RegConnectRegistry before running the program.

#define TOTALBYTES    8192
#define BYTEINCREMENT 4096

void PerfmonThread(void *pData)
{
    DWORD BufferSize = TOTALBYTES;
    DWORD cbData;
    DWORD dwRet;

    PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );
    cbData = BufferSize;

    printf("\nRetrieving the data...");

    HKEY hKey;
    DWORD dwAccessRet = RegConnectRegistry(L"REMOTE_MACHINE",HKEY_PERFORMANCE_DATA,&hKey);

    dwRet = RegQueryValueEx( hKey,L"global",NULL,NULL,(LPBYTE) PerfData, &cbData );
    while( dwRet == ERROR_MORE_DATA )
    {
        // Get a buffer that is big enough.

        BufferSize += BYTEINCREMENT;
        PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
        cbData = BufferSize;

        printf(".");
        dwRet = RegQueryValueEx( hKey,L"global",NULL,NULL,(LPBYTE) PerfData,&cbData );
    }
    if( dwRet == ERROR_SUCCESS )
        printf("\n\nFinal buffer size is %d\n", BufferSize);
    else 
        printf("\nRegQueryValueEx failed (%d)\n", dwRet);

    RegCloseKey(hKey);
}

int _tmain(int argc, _TCHAR* argv[])
{
    _beginthread(PerfmonThread,0,NULL);
/*  _beginthread(PerfmonThread,0,NULL);
    _beginthread(PerfmonThread,0,NULL);
    _beginthread(PerfmonThread,0,NULL);
*/

    while(1)
    {

        Sleep(2000);
    }
}

© Stack Overflow or respective owner

Related posts about win32

Related posts about remote-registry