开发者

Issue with RegConnectRegistry connecting to 64 bit machines

开发者 https://www.devze.com 2022-12-22 11:40 出处:网络
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 at

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 开发者_C百科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);
    }
}


This is not really an answer, but a suggestion. Even though you are only querying the registry (not writing), I'm wondering if you are producing some kind of dead-lock with the multiple threads.

Lacking a Windows development or testing environment, take this suggestion for what its worth: perhaps you could use mutexes around the registry calls... that may relieve any deadlock situation, if that is indeed the problem.

Good luck.


I think it must be an environmental issue. I just tried this from 32-bit Windows XP Professional to 64-bit Windows 7 Ultimate and it worked fine. Occasionally on a thread or two a call to RegQueryValueEx would fail with either ERROR_BUSY or ERROR_NOT_READY, but I never experienced any long delays. In case anybody else tries to test this, I ran into a snag; the account you are using must be a member of the Performance Monitor Users group in order to remotely access HKEY_PERFORMANCE_DATA. Also ensure the Remote Registry Service is running.

0

精彩评论

暂无评论...
验证码 换一张
取 消