user-0 提问: 请问下C语言读取注册表的规则是怎么样的，附图。觉得很奇怪

回复:
user: user-1
content: Getting the System Version The following example uses the GetVersionEx, GetSystemMetrics, and GetNativeSystemInfo functions to determine the version information of the currently running operating system. The code outputs the information to the console.  Relying on version information is not the best way to test for a feature. Instead, refer to the documentation for the feature of interest. For more information on common techniques for feature detection, see Operating System Version.  If you must require a particular operating system, be sure to use it as a minimum supported version, rather than design the test for the one operating system. This way, your detection code will continue to work on future versions of Windows.   #include <windows.h> #include <tchar.h> #include <stdio.h>  #define BUFSIZE 80  typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);  int __cdecl _tmain() {    OSVERSIONINFOEX osvi;    SYSTEM_INFO si;    PGNSI pGNSI;    BOOL bOsVersionInfoEx;     ZeroMemory(&si, sizeof(SYSTEM_INFO));    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));     // Try calling GetVersionEx using the OSVERSIONINFOEX structure.    // If that fails, try using the OSVERSIONINFO structure.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);     if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )    {       osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);       if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )           return FALSE;    }     // Call GetNativeSystemInfo if supported    // or GetSystemInfo otherwise.     pGNSI = (PGNSI) GetProcAddress(       GetModuleHandle(TEXT("kernel32.dll")),        "GetNativeSystemInfo");    if(NULL != pGNSI)       pGNSI(&si);    else GetSystemInfo(&si);     switch (osvi.dwPlatformId)    {       // Test for the Windows NT product family.        case VER_PLATFORM_WIN32_NT:        // Test for the specific product.        if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )       {          if( osvi.wProductType == VER_NT_WORKSTATION )              printf ("Windows Vista ");          else printf ("Windows Server \"Longhorn\" " );       }        if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )       {          if( GetSystemMetrics(SM_SERVERR2) )             printf( "Microsoft Windows Server 2003 \"R2\" ");          else if( osvi.wProductType == VER_NT_WORKSTATION &&             si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)          {             printf( "Microsoft Windows XP Professional x64 Edition ");          }          else printf ("Microsoft Windows Server 2003, ");       }        if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )          printf ("Microsoft Windows XP ");        if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )          printf ("Microsoft Windows 2000 ");        if ( osvi.dwMajorVersion <= 4 )          printf ("Microsoft Windows NT ");        // Test for specific product on Windows NT 4.0 SP6 and later.       if( bOsVersionInfoEx )       {          // Test for the workstation type.          if ( osvi.wProductType == VER_NT_WORKSTATION &&               si.wProcessorArchitecture!=PROCESSOR_ARCHITECTURE_AMD64)          {             if( osvi.dwMajorVersion == 4 )                printf ( "Workstation 4.0 " );             else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )                printf ( "Home Edition " );             else printf ( "Professional " );          }           // Test for the server type.          else if ( osvi.wProductType == VER_NT_SERVER ||                     osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )          {             if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==2)             {                if ( si.wProcessorArchitecture ==                     PROCESSOR_ARCHITECTURE_IA64 )                {                    if( osvi.wSuiteMask & VER_SUITE_DATACENTER )                       printf ( "Datacenter Edition "                                "for Itanium-based Systems" );                    else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )                       printf ( "Enterprise Edition "                                "for Itanium-based Systems" );                }                 else if ( si.wProcessorArchitecture ==                          PROCESSOR_ARCHITECTURE_AMD64 )                {                    if( osvi.wSuiteMask & VER_SUITE_DATACENTER )                       printf ( "Datacenter x64 Edition " );                    else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )                       printf ( "Enterprise x64 Edition " );                    else printf( "Standard x64 Edition " );                }                 else                {                    if( osvi.wSuiteMask & VER_SUITE_DATACENTER )                       printf ( "Datacenter Edition " );                    else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )                       printf ( "Enterprise Edition " );                    else if ( osvi.wSuiteMask & VER_SUITE_BLADE )                       printf ( "Web Edition " );                    else printf ( "Standard Edition " );                }             }             else if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0)             {                if( osvi.wSuiteMask & VER_SUITE_DATACENTER )                   printf ( "Datacenter Server " );                else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )                   printf ( "Advanced Server " );                else printf ( "Server " );             }             else  // Windows NT 4.0              {                if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )                   printf ("Server 4.0, Enterprise Edition " );                else printf ( "Server 4.0 " );             }          }       }       // Test for specific product on Windows NT 4.0 SP5 and earlier       else         {          HKEY hKey;          TCHAR szProductType[BUFSIZE];          DWORD dwBufLen=BUFSIZE*sizeof(TCHAR);          LONG lRet;           lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,             TEXT("SYSTEM\\CurrentControlSet\\Control\\"                  "ProductOptions"), 0, KEY_QUERY_VALUE, &hKey );          if( lRet != ERROR_SUCCESS )             return FALSE;           lRet = RegQueryValueEx( hKey, TEXT("ProductType"),             NULL, NULL, (LPBYTE) szProductType, &dwBufLen);          RegCloseKey( hKey );           if( (lRet != ERROR_SUCCESS) ||              (dwBufLen > BUFSIZE*sizeof(TCHAR)) )             return FALSE;           if ( lstrcmpi( TEXT("WINNT"), szProductType) == 0 )             printf( "Workstation " );          if ( lstrcmpi( TEXT("LANMANNT"), szProductType) == 0 )             printf( "Server " );          if ( lstrcmpi( TEXT("SERVERNT"), szProductType) == 0 )             printf( "Advanced Server " );          printf( "%d.%d ", osvi.dwMajorVersion, osvi.dwMinorVersion );       }        // Display service pack (if any) and build number.        if( osvi.dwMajorVersion == 4 &&            lstrcmpi( osvi.szCSDVersion, TEXT("Service Pack 6") ) == 0 )       {           HKEY hKey;          LONG lRet;           // Test for SP6 versus SP6a.          lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,             TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\"                  "Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey );          if( lRet == ERROR_SUCCESS )             printf( "Service Pack 6a (Build %d)\n",              osvi.dwBuildNumber & 0xFFFF );                   else // Windows NT 4.0 prior to SP6a          {             _tprintf( TEXT("%s (Build %d)\n"),                osvi.szCSDVersion,                osvi.dwBuildNumber & 0xFFFF);          }           RegCloseKey( hKey );       }       else // not Windows NT 4.0        {          _tprintf( TEXT("%s (Build %d)\n"),             osvi.szCSDVersion,             osvi.dwBuildNumber & 0xFFFF);       }        break;        // Test for the Windows Me/98/95.       case VER_PLATFORM_WIN32_WINDOWS:        if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)       {           printf ("Microsoft Windows 95 ");           if (osvi.szCSDVersion[1]=='C' || osvi.szCSDVersion[1]=='B')              printf("OSR2 " );       }         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)       {           printf ("Microsoft Windows 98 ");           if ( osvi.szCSDVersion[1]=='A' || osvi.szCSDVersion[1]=='B')              printf("SE " );       }         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)       {           printf ("Microsoft Windows Millennium Edition\n");       }        break;        case VER_PLATFORM_WIN32s:        printf ("Microsoft Win32s\n");       break;    }    return TRUE;  }

user: user-1
content: RegOpenKeyEx Function  Opens the specified registry key. Note that key names are not case sensitive.  To perform transacted registry operations on a key, call the RegOpenKeyTransacted function.   LONG WINAPI RegOpenKeyEx(   __in          HKEY hKey,   __in          LPCTSTR lpSubKey,   DWORD ulOptions,   __in          REGSAM samDesired,   __out         PHKEY phkResult );  Parameters hKey  A handle to an open registry key. This handle is returned by the RegCreateKeyEx or RegOpenKeyEx function, or it can be one of the following predefined keys:    HKEY_CLASSES_ROOT  HKEY_CURRENT_USER  HKEY_LOCAL_MACHINE  HKEY_USERS  Windows Me/98/95:  This parameter can also be the following key:   HKEY_DYN_DATA  lpSubKey  The name of the registry subkey to be opened.   Key names are not case sensitive.  If this parameter is NULL or a pointer to an empty string, the function will open a new handle to the key identified by the hKey parameter.  For more information, see Registry Element Size Limits.  ulOptions  This parameter is reserved and must be zero.  samDesired  A mask that specifies the desired access rights to the key. The function fails if the security descriptor of the key does not permit the requested access for the calling process. For more information, see Registry Key Security and Access Rights.  phkResult  A pointer to a variable that receives a handle to the opened key. If the key is not one of the predefined registry keys, call the RegCloseKey function after you have finished using the handle.  Return Value If the function succeeds, the return value is ERROR_SUCCESS.  If the function fails, the return value is a nonzero error code defined in Winerror.h. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.  Remarks Unlike the RegCreateKeyEx function, the RegOpenKeyEx function does not create the specified key if the key does not exist in the registry.  If your service or application impersonates different users, do not use this function with HKEY_CURRENT_USER. Instead, call the RegOpenCurrentUser function.  A single registry key can be opened only 65534 times. When attempting the 65535th open operation, this function fails with ERROR_NO_SYSTEM_RESOURCES.  Note that operations that access certain registry keys are redirected. For more information, see Registry Virtualization and 32-bit and 64-bit Application Data in the Registry.  Example Code  For an example, see Getting the System Version.  Requirements Client  Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.   Server  Requires Windows Server 2008, Windows Server 2003, Windows 2000 Server, or Windows NT Server.   Header  Declared in Winreg.h; include Windows.h.   Library  Use Advapi32.lib.   DLL  Requires Advapi32.dll.     Unicode  Implemented as RegOpenKeyExW (Unicode) and RegOpenKeyExA (ANSI).

user: user-2
content: 在读取前没有对dataSize赋值，所以RegQueryValueEx不知道你传入的buffer的长度，在调用query前，你要把dataSize置为20

user: user-0
content: 我都赋了admin同个键值，为什么读出来会出错呢?