Ошибка вызывающая функция rtsc enum sub keys and values in registry key

I am trying to write a Windows application that gives me back all the subkeys and values given a certain key. I've written code that appears to work as far as providing subkeys within the given key...

I am trying to write a Windows application that gives me back all the subkeys and values given a certain key. I’ve written code that appears to work as far as providing subkeys within the given key, but doesn’t work at properly enumerating the values; it successfully enumerates subkeys without values and returns the results in kind of tabbed tree arrangement. However, when enumerating values, the program gives back a random value for each value present (the same random value each time), and then crashes afterwards with a debug error.

It’s intended output is basically:

(1) KEY
    (1) SUBKEY
    (1) SUBKEYWITHINSUBKEY
        Code: value1data
        Code: value2data
        Code: value3data
(2) SUBKEY
    (1) SUBKEYWITHINSUBKEY
(3) SUBKEY

…and so on.

The output I get instead is something like:

(1) KEY
(1) SUBKEY
    (1) SUBKEYWITHINSUBKEY
        Code: someValue
        Code: someValue
        Code: someValue

(…and then the crash)

This is followed with the following error:
«Debug Error! «Run-Time Check Failure #2 — Stack around the variable ‘valNameLen’ was corrupted.»

The code is a bit messy currently (I’m a Windows API newbie), but if anyone could show me what I’m doing wrong, or critique my coding style in anyway they feel fit, that would be great.

Thanks!

-R

/*
Windows Registry Subkey Enumeration Example
Based on example found at code-blue.org
*/

#include <windows.h>
#include <stdio.h>

void EnumerateValues(HKEY hKey, DWORD numValues)
{
 DWORD dwIndex = 0;
    LPSTR valueName = new CHAR[64];
 DWORD valNameLen;
 DWORD dataType;
 DWORD data;
 DWORD dataSize;

    for (int i = 0; i < numValues; i++)
 {
  RegEnumValue(hKey,
     dwIndex,
     valueName,
     &valNameLen,
     NULL,
     &dataType,
     (BYTE*)&data,
     &dataSize);

  dwIndex++;

        printf("Code: 0x%08Xn", data);
 }
}


void EnumerateSubKeys(HKEY RootKey, char* subKey, unsigned int tabs = 0) 
{
 HKEY hKey;
    DWORD cSubKeys;        //Used to store the number of Subkeys
    DWORD maxSubkeyLen;    //Longest Subkey name length
    DWORD cValues;        //Used to store the number of Subkeys
    DWORD maxValueLen;    //Longest Subkey name length
    DWORD retCode;        //Return values of calls

 RegOpenKeyEx(RootKey, subKey, 0, KEY_ALL_ACCESS, &hKey);

    RegQueryInfoKey(hKey,            // key handle
                    NULL,            // buffer for class name
                    NULL,            // size of class string
                    NULL,            // reserved
                    &cSubKeys,        // number of subkeys
                    &maxSubkeyLen,    // longest subkey length
                    NULL,            // longest class string 
                    &cValues,        // number of values for this key 
                    &maxValueLen,    // longest value name 
                    NULL,            // longest value data 
                    NULL,            // security descriptor 
                    NULL);            // last write time

    if(cSubKeys>0)
 {
        char currentSubkey[MAX_PATH];

        for(int i=0;i < cSubKeys;i++){
   DWORD currentSubLen=MAX_PATH;

            retCode=RegEnumKeyEx(hKey,    // Handle to an open/predefined key
            i,                // Index of the subkey to retrieve.
            currentSubkey,            // buffer to receives the name of the subkey
            &currentSubLen,            // size of that buffer
            NULL,                // Reserved
            NULL,                // buffer for class string 
            NULL,                // size of that buffer
            NULL);                // last write time

            if(retCode==ERROR_SUCCESS)
   {
                for (int i = 0; i < tabs; i++)
                    printf("t");
                printf("(%d) %sn", i+1, currentSubkey);

                char* subKeyPath = new char[currentSubLen + strlen(subKey)];
                sprintf(subKeyPath, "%s\%s", subKey, currentSubkey);
    EnumerateSubKeys(RootKey, subKeyPath, (tabs + 1));
   }
  }
 }
    else
 {
  EnumerateValues(hKey, cValues);
 }

 RegCloseKey(hKey); 
}


int main()
{
    EnumerateSubKeys(HKEY_CURRENT_USER,"SOFTWARE\MyKeyToSearchIn");
    return 0;
}

Member Avatar

9 Years Ago

Hello all,

I am trying to get a bunch of sub-keys and values from the registry in vb 2010 and i remember in vb6 this was quite easy. Can anyone share code to help? Or a link where I can go? I’ve been searching for nearly 8 hours on line and can’t find anything I can use. The microsoft sites don’t really help and most of the articles I find are for vb 7, or vb 6. Any help would be appreciated.

./x86


Recommended Answers

Here’s an MSDN article on accessing the registry with vb 2010

Jump to Post

Something like this will iterate through all the values of a specific key:

        Dim key As Microsoft.Win32.RegistryKey = My.Computer.Registry.CurrentUser.OpenSubKey("Software")
        For Each ValueName In key.GetValueNames
            Debug.WriteLine(key.GetValue(ValueName))
        Next

Jump to Post

All 7 Replies

Member Avatar

9 Years Ago

Here’s an MSDN article on accessing the registry with vb 2010

Member Avatar

9 Years Ago

tinstaafl,

I know how to read and write to the registry. I’m lost as to how to create the loop needed to iterate through the keys. Do you have any information on this?


Reverend Jim

4,218



Hi, I’m Jim, one of DaniWeb’s moderators.



Moderator



Featured Poster


9 Years Ago

The following lists all of the subkeys under HKCUSoftware

Dim key As Microsoft.Win32.RegistryKey = My.Computer.Registry.CurrentUser.OpenSubKey("Software")

For Each subkey In key.GetSubKeyNames
    Debug.WriteLine(subkey.ToString)
Next

Edited

9 Years Ago
by Reverend Jim

Member Avatar

9 Years Ago

Reverend Jim,

This is very close to what I’m trying to do. I have been at it for a while trying to mod the code to get it to get the values. Do you think you can help me with this portion? What I’m looking to do is obtain the string value of a key. And, if you can… Do you know any good books that reference the win32 api in vb.net 2010?

./x86

Member Avatar

9 Years Ago

Something like this will iterate through all the values of a specific key:

        Dim key As Microsoft.Win32.RegistryKey = My.Computer.Registry.CurrentUser.OpenSubKey("Software")
        For Each ValueName In key.GetValueNames
            Debug.WriteLine(key.GetValue(ValueName))
        Next

Edited

9 Years Ago
by tinstaafl


Reverend Jim

4,218



Hi, I’m Jim, one of DaniWeb’s moderators.



Moderator



Featured Poster


9 Years Ago

I don’t know about a book but the win32 API is documented online here

Member Avatar

9 Years Ago

Rock on. I appreciate it. The code works well. I also appreciate the resource.


Reply to this topic

Be a part of the DaniWeb community

We’re a friendly, industry-focused community of developers, IT pros, digital marketers,
and technology enthusiasts meeting, networking, learning, and sharing knowledge.

    bool CRegEdit::Open(const std::string & sSubKey, HKEY hKey)

    {  

        Close();

        m_sSubKey = sSubKey;

        m_hKey = ((hKey == 0) ? s_hDefaultHKEY : hKey);

        LONG nRegOpenRez = RegOpenKeyEx(m_hKey, m_sSubKey.c_str(), 0, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &m_hRegKey);

        if (nRegOpenRez != ERROR_SUCCESS)

        {

            HANDLE hToken;

            TOKEN_PRIVILEGES tkp;

            if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return false;

            if (LookupPrivilegeValue(NULL, SE_TAKE_OWNERSHIP_NAME , &tkp.Privileges[0].Luid))

            {      

                tkp.PrivilegeCount = 1;

                tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

                AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);

                RegOpenKeyEx(m_hKey, m_sSubKey.c_str(), 0, WRITE_OWNER, &m_hRegKey);

                PSID pSid;

                PSECURITY_DESCRIPTOR pSD;

                std::string sName = «MACHINE\SYSTEM\ControlSet001\Enum»; // …например

                GetNamedSecurityInfo((LPTSTR) sName.c_str(), SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION, &pSid, 0, 0, 0, &pSD);

                SetSecurityInfo(m_hRegKey, SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION, pSid, NULL, NULL, NULL);

                RegOpenKeyEx(m_hKey, m_sSubKey.c_str(), 0, WRITE_DAC, &m_hRegKey);

                //LocalFree(pSD); //? по идее нужно освобождать, но тогда всё вроде выполняется, но в доступе к ключу — отказ

                PACL pDacl;

                GetNamedSecurityInfo((LPTSTR) sName.c_str(), SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 0, 0, &pDacl, 0, &pSD);

                ACL_SIZE_INFORMATION asi;

                GetAclInformation(pDacl, &asi, sizeof(asi), AclSizeInformation);

                ACL_REVISION_INFORMATION ari;

                GetAclInformation(pDacl, &ari, sizeof(ari), AclRevisionInformation);

                BYTE NewDaclBuf[64000];

                PACL pNewDacl = (PACL)NewDaclBuf;

                InitializeAcl(pNewDacl, 64000, ari.AclRevision);

                AddAccessAllowedAceEx(pNewDacl, ACL_REVISION_DS, CONTAINER_INHERIT_ACE, GENERIC_ALL, pSid);

                for (DWORD i = 0; i < asi.AceCount; i++)

                {

                    void* pAce;

                    GetAce(pDacl, i, &pAce);

                    ACE_HEADER* pAceHeader = (ACE_HEADER*)pAce;

                    AddAce(pNewDacl, ari.AclRevision, MAXDWORD, pAce, pAceHeader->AceSize);

                }

                SetSecurityInfo(m_hRegKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL);

                RegCloseKey(m_hRegKey);

                nRegOpenRez = RegOpenKeyEx(m_hKey, m_sSubKey.c_str(), 0, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &m_hRegKey);

                LocalFree(pSD);

            }

        }

        return (nRegOpenRez == ERROR_SUCCESS);

    }

  • Remove From My Forums
  • Frage

  • I have a C# console app compiled with .Net 2.0 in 32 bit machine. This app run fine in 32bit machine. But when I run in x64 machine I get some issues.

    I figured out that the information about app was installed correctly on HKLMSOFTWAREWow6432NodeMyCompanyMyApp registry key.

    But in my code I have hard coded the following string «SOFTWAREMyCompanyMyApp»

    I thought that WOW64 could translate correctly from «SOFTWAREMyCompanyMyApp» to SOFTWAREWow6432NodeMyCompanyMyApp. I am using the class RegistryKey from the Framework. I know that all is correct because it works in 32bit but seems that I am missing something with x64. I got a look at Registry Redirection and Reflection but could not see a solution. Any idea?

    Thanks.

    www.byteshift.com

Antworten

  • The rules are pretty straightforward:

    • .NET app compiled for «x86»:

      • Always 32-bit

      • On 32-bit platforms, accesses 32-bit registry

      • On 64-bit platforms, accesses 32-bit registry (inside Wow6432Node)

        • 64-bit registry inaccessible (without doing something weird)

    • .NET app compiled for «x64»:
      • Always 64 bit

      • On 32-bit platforms, won’t run

      • On 64-bit platforms, accesses 64-bit registry (not inside Wow6432Node)

        • If you want to get to the 32-bit registry, you need to do something weird

    • .NET app compiled for «AnyCpu»

      • Either 32 or 64 bit depending on platform

      • On 32-bit platforms, accesses 32-bit registry

      • On 64-bit platforms, accesses 64-bit registry (not inside Wow6432Node)

        • If you want to get to the 32-bit registry, you need to do something weird

    «Something weird» technically requires passing a special flag to RegOpenKeyEx to obtain the alternate registry view.  .NET doesn’t expose any function that will do this nicely, so you’d have to drop to p/invoke to get there.

    Alternatively if you want to get to the 32-bit registry from a 64-bit/AnyCpu app, you can hardcode the «Wow6432Node» path in (since the 32 bit registry is visible from 64 bit, but not the reverse), but MS explicitly recommends against this.

Windows 7 Enterprise Windows 7 Professional Windows 7 Home Basic Windows 7 Home Premium Windows 7 Starter Windows 7 Ultimate Windows Server 2008 R2 Enterprise Windows Server 2008 R2 Datacenter Windows Server 2008 R2 for Itanium-Based Systems Windows Server 2008 R2 Foundation Windows Server 2008 R2 Standard Microsoft Windows XP Home Edition Microsoft Windows XP Professional Microsoft Windows XP Professional x64 Edition Microsoft Windows XP Tablet PC Edition Windows Server 2008 Datacenter Windows Server 2008 Enterprise Windows Server 2008 for Itanium-Based Systems Windows Server 2008 Foundation Windows Vista Business Windows Vista Enterprise Windows Vista Home Basic Windows Vista Home Premium Windows Vista Starter Windows Vista Ultimate Windows Server 2008 Datacenter without Hyper-V Windows Server 2008 Enterprise without Hyper-V Windows Server 2008 R2 Service Pack 1 Windows Server 2008 Service Pack 2 Windows Server 2008 Standard without Hyper-V Windows Vista Business 64-bit Edition Windows Vista Enterprise 64-bit Edition Windows Vista Home Basic 64-bit Edition Windows Vista Home Premium 64-bit Edition Windows Vista Service Pack 2 Windows Vista Ultimate 64-bit Edition Windows 7 Service Pack 1 More…Less

Notes

  • This article is intended for advanced users, administrators, and IT Professionals.

  • Importing Registration Entries (.reg) files is a feature of Regedit.exe and is not supported by Regedt32.exe. You can use Regedit.exe to make some changes to the registry on a Windows NT 4.0-based or Windows 2000-based computer, but some changes require Regedt32.exe. For example, you cannot add or change REG_EXPAND_SZ or REG_MULTI_SZ values with Regedit.exe on a Windows NT 4.0-based or Windows 2000-based computer. Regedt32.exe is the primary Registry Editor for Windows NT 4.0 and Windows 2000. If you must use Regedt32.exe, you cannot use Registration Entries (.reg) files to modify the registry. For more information about the differences between Regedit.exe and Regedt32.exe, click the following article number to view the article in the Microsoft Knowledge Base:

    141377 Differences between Regedit.exe and Regedt32.exe
     

IN THIS TASK

  • SUMMARY

    • Syntax of .Reg Files

    • Adding Registry Subkeys or Adding and Changing Registry Values

    • Deleting Registry Subkeys and Values

    • Renaming Registry Subkeys and Values

    • Distributing Registry Changes

Summary

Important This section, method, or task contains steps that tell you how to modify the registry. However, serious problems might occur if you modify the registry incorrectly. Therefore, make sure that you follow these steps carefully. For added protection, back up the registry before you modify it. Then, you can restore the registry if a problem occurs. For more information about how to back up and restore the registry, click the following article number to view the article in the Microsoft Knowledge Base:

322756 How to back up and restore the registry in Windows
This step-by-step article describes how to add, modify, or delete registry subkeys and values by using a Registration Entries (.reg) file. Regedit.exe uses .reg files to import and export registry subkeys and values. You can use these .reg files to remotely distribute registry changes to several Windows-based computers. When you run a .reg file, the file contents merge into the local registry. Therefore, you must distribute .reg files with caution.

back to the top

Syntax of .Reg Files

A .reg file has the following syntax:

RegistryEditorVersion
Blank line
[RegistryPath1]

«DataItemName1«=»DataType1:DataValue1«
DataItemName2«=»DataType2:DataValue2«
Blank line
[RegistryPath2]

«DataItemName3«=»DataType3:DataValue3«

where:

RegistryEditorVersion is either «Windows Registry Editor Version 5.00» for Windows 2000, Windows XP, and Windows Server 2003, or «REGEDIT4» for Windows 98 and Windows NT 4.0. The «REGEDIT4» header also works on Windows 2000-based, Windows XP-based, and Windows Server 2003-based computers.

Blank line is a blank line. This identifies the start of a new registry path. Each key or subkey is a new registry path. If you have several keys in your .reg file, blank lines can help you to examine and to troubleshoot the contents.

RegistryPathx is the path of the subkey that holds the first value you are importing. Enclose the path in square brackets, and separate each level of the hierarchy by a backslash. For example:

[HKEY_LOCAL_ MACHINESOFTWAREPoliciesMicrosoftWindowsSystem]
A .reg file can contain several registry paths. If the bottom of the hierarchy in the path statement does not exist in the registry, a new subkey is created. The contents of the registry files are sent to the registry in the order you enter them. Therefore, if you want to create a new subkey with another subkey below it, you must enter the lines in the correct order.

DataItemNamex is the name of the data item that you want to import. If a data item in your file does not exist in the registry, the .reg file adds it (with the value of the data item). If a data item does exist, the value in your .reg file overwrites the existing value. Quotation marks enclose the name of the data item. An equal sign (=) immediately follows the name of the data item.

DataTypex is the data type for the registry value and immediately follows the equal sign. For all the data types other than REG_SZ (a string value), a colon immediately follows the data type. If the data type is REG_SZ , do not include the data type value or colon. In this case, Regedit.exe assumes REG_SZ for the data type. The following table lists the typical registry data types:

Data Type

DataType in .reg

REG_BINARY

hexadecimal

REG_DWORD

dword

REG_EXPAND_SZ

hexadecimal(2)

REG_MULTI_SZ

hexadecimal(7)

For more information about registry data types, click the following article number to view the article in the Microsoft Knowledge Base:

256986 Description of the Microsoft Windows registry
 
DataValuex immediately follows the colon (or the equal sign with REG_SZ) and must be in the appropriate format (for example, string or hexadecimal). Use hexadecimal format for binary data items.

Note You can enter several data item lines for the same registry path.

Note the registry file should contain a blank line at the bottom of the file.

back to the top

Adding Registry Subkeys or Adding and Changing Registry Values

To add a registry subkey or add or change a registry value, make the appropriate changes in the registry, and then export the appropriate subkey or subkeys. Exported registry subkeys are automatically saved as .reg files. To make changes to the registry and export your changes to a .reg file, follow these steps:

  1. Click Start, click Run, type regedit in the Open box, and then click OK.

  2. Locate and then click the subkey that holds the registry item or items that you want to change.

  3. Click File, and then click Export.

    This step backs up the subkey before you make any changes. You can import this file back into the registry later if your changes cause a problem.

  4. In the File name box, type a file name to use to save the .reg file with the original registry items, and then click Save.

    Note Use a file name that reminds you of the contents, such as a reference to the name of the subkey.

  5. In the right pane, add or modify the registry items you want.

  6. Repeat steps 3 and 4 to export the subkey again, but use a different file name for the .reg file. You can use this .reg file to make your registry changes on another computer.

  7. Test your changes on the local computer. If they cause a problem, double-click the file that holds the backup of the original registry data to return the registry to its original state. If the changes work as expected, you can distribute the .reg you created in step 6 to other computers by using the methods in the «Distributing Registry Changes» section of this article.

back to the top

Deleting Registry Keys and Values

To delete a registry key with a .reg file, put a hyphen (-) in front of the RegistryPath in the .reg file. For example, to delete the Test subkey from the following registry key:

HKEY_LOCAL_MACHINESoftware
put a hyphen in front of the following registry key in the .reg file:

HKEY_LOCAL_MACHINESoftwareTest
The following example has a .reg file that can perform this task.

[-HKEY_LOCAL_MACHINESoftwareTest]
To delete a registry value with a .reg file, put a hyphen (-) after the equals sign following the DataItemName in the .reg file. For example, to delete the TestValue registry value from the following registry key:

HKEY_LOCAL_MACHINESoftwareTest
put a hyphen after the «TestValue»= in the .reg file. The following example has a .reg file that can perform this task.

HKEY_LOCAL_MACHINESoftwareTest

«TestValue»=-
To create the .reg file, use Regedit.exe to export the registry key that you want to delete, and then use Notepad to edit the .reg file and insert the hyphen.

back to the top

Renaming Registry Keys and Values

To rename a key or value, delete the key or value, and then create a new key or value with the new name.

Distributing Registry Changes

You can send a .reg file to users in an e-mail message, put a .reg file on a network share and direct users to the network share to run it, or you can add a command to the users’ logon scripts to automatically import the .reg file when they log on. When users run the .reg file, they receive the following messages:

Registry Editor
Are you sure you want to add the information in path of .reg file to the registry?
If the user clicks Yes, the user receives the following message:

Registry Editor
Information in path of .reg file has been successfully entered into the registry.
Regedit.exe supports a /s command-line switch to not display these messages. For example, to silently run the .reg file (with the /s switch) from a login script batch file, use the following syntax:

regedit.exe /s path of .reg file
You can also use Group Policy or System Policy to distribute registry changes across your network. For additional information, visit the following Microsoft Web site:

Need more help?

Понравилась статья? Поделить с друзьями:
  • Ошибка вызова сервиса фиас ппдгр
  • Ошибка вызова сервиса передачи получения данных фсс unmarshalling error
  • Ошибка вызова сервиса передачи получения данных сообщение не соответствует формату xml encryption
  • Ошибка вызова сервиса передачи получения данных ошибка дешифрования сообщения
  • Ошибка вызова сервиса передачи получения данных premature end of file фсс