Problem with RegConnectRegistry connecting 64-bit machines

I see a strange thing when connecting to the performance registry on 64-bit versions of Windows. The entire program of kiosks and stop tables becomes unreadable. After a long timeout, the connection attempt is interrupted, and everything returns to normal.

The only solution is to make sure that only one thread is requesting the remote registry, unless the remote computer is a 32-bit version of Windows XP, 2003, 2000, then you can use as many threads as you want.

Does anyone have a technical explanation why this could happen? I spent 2-3 days on the Internet without inventing anything.

Here is a test program, first run it with a single thread (connecting to 64-bit Windows), then delete the comment in tmain and run it with 4 threads. Starting with a single thread works, as expected, with 4, returns ERROR_BUSY (dwRet == 170) after stopping for a while.

Remember to install the remote computer correctly in RegConnectRegistry before starting 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);
    }
}
+3
source share
2 answers

In fact, this is not an answer, but a proposal. Despite the fact that you only request the registry (do not write), I wonder if you are doing some kind of deadlock with multiple threads.

Windows , , : , ... , .

.

+1

, . 32- Windows XP Professional 64- Windows 7 Ultimate, . RegQueryValueEx ERROR_BUSY ERROR_NOT_READY, . - , ; HKEY_PERFORMANCE_DATA. , .

+1

Source: https://habr.com/ru/post/1735952/


All Articles