Bizarre behavior of RegQueryValueEx(), please advise.
-
Have you checked the registry to make sure the values are stored correctly? Have you run it with the debugger to ensure the value names are correct?
Yes, I have. That was done 10 years ago. I've been using this registry storage approach since 2004. There is nothing to debug, the application has always worked flawlessly - until the number of values exceeded certain computer-specific limit, which is much lower than the officially documented one.
-
I have created a simple program to add 150 values to a key, and then read them out, in sequence or randomly. In every case I get the correct value returned. There must be something else in your code that causes the error.
-
Yes, I have. That was done 10 years ago. I've been using this registry storage approach since 2004. There is nothing to debug, the application has always worked flawlessly - until the number of values exceeded certain computer-specific limit, which is much lower than the officially documented one.
That something worked for 10 years does not mean that it is flawless. It is also not an argument to skip debugging. You could use below code to verify whether it is a limit or not. If there's a limit, below code should run into the same problem.
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;namespace ConsoleApplication5
{
class Program
{
static UIntPtr HKEY_CURRENT_USER = new UIntPtr(0x80000001u);
const int LOOPS = 200;enum RegistryRights: int { ReadKey = 131097, WriteKey = 131078 } \[DllImport("advapi32.dll", CharSet = CharSet.Auto)\] public static extern int RegOpenKeyEx( UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult); \[DllImport("advapi32.dll", SetLastError = true)\] static extern uint RegQueryValueEx( UIntPtr hKey, string lpValueName, int lpReserved, ref uint lpType, IntPtr lpData, ref uint lpcbData); \[DllImport("advapi32.dll", SetLastError = true)\] public static extern int RegCloseKey( UIntPtr hKey); private static string ReadRegKey(UIntPtr rootKey, string keyPath, string valueName) { UIntPtr hKey = UIntPtr.Zero; string keyValue = ""; if (RegOpenKeyEx(rootKey, keyPath, (int)0, (int)RegistryRights.ReadKey, out hKey) == 0) { uint size = 1024; uint type = 0; IntPtr pResult = IntPtr.Zero; pResult = Marshal.AllocHGlobal((int)size); if (RegQueryValueEx(hKey, valueName, 0, ref type, pResult, ref size) == 0) keyValue = Convert.ToString(Marshal.ReadByte(pResult)); // takes only first byte, for test Marshal.FreeHGlobal(pResult); RegCloseKey(hKey); } return keyValue; } static void Prepare() { byte\[\] bytes = new byte\[88\]; for (byte b = 0; b < 88; b++) bytes\[b\] = b; RegistryKey rkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default); RegistryKey tkey = rkey.OpenSubKey("Test", true); for (byte i = 0; i < LOOPS; i++) {
-
Yes, I have. That was done 10 years ago. I've been using this registry storage approach since 2004. There is nothing to debug, the application has always worked flawlessly - until the number of values exceeded certain computer-specific limit, which is much lower than the officially documented one.
SMD111 wrote:
the application has always worked flawlessly - until
Then it hasn't worked flawlessly. You really need to do some serious debugging to find out why this is happening. Rather than just assuming that it's a Microsoft error, you should look deeper into your code.
-
That something worked for 10 years does not mean that it is flawless. It is also not an argument to skip debugging. You could use below code to verify whether it is a limit or not. If there's a limit, below code should run into the same problem.
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;namespace ConsoleApplication5
{
class Program
{
static UIntPtr HKEY_CURRENT_USER = new UIntPtr(0x80000001u);
const int LOOPS = 200;enum RegistryRights: int { ReadKey = 131097, WriteKey = 131078 } \[DllImport("advapi32.dll", CharSet = CharSet.Auto)\] public static extern int RegOpenKeyEx( UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult); \[DllImport("advapi32.dll", SetLastError = true)\] static extern uint RegQueryValueEx( UIntPtr hKey, string lpValueName, int lpReserved, ref uint lpType, IntPtr lpData, ref uint lpcbData); \[DllImport("advapi32.dll", SetLastError = true)\] public static extern int RegCloseKey( UIntPtr hKey); private static string ReadRegKey(UIntPtr rootKey, string keyPath, string valueName) { UIntPtr hKey = UIntPtr.Zero; string keyValue = ""; if (RegOpenKeyEx(rootKey, keyPath, (int)0, (int)RegistryRights.ReadKey, out hKey) == 0) { uint size = 1024; uint type = 0; IntPtr pResult = IntPtr.Zero; pResult = Marshal.AllocHGlobal((int)size); if (RegQueryValueEx(hKey, valueName, 0, ref type, pResult, ref size) == 0) keyValue = Convert.ToString(Marshal.ReadByte(pResult)); // takes only first byte, for test Marshal.FreeHGlobal(pResult); RegCloseKey(hKey); } return keyValue; } static void Prepare() { byte\[\] bytes = new byte\[88\]; for (byte b = 0; b < 88; b++) bytes\[b\] = b; RegistryKey rkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default); RegistryKey tkey = rkey.OpenSubKey("Test", true); for (byte i = 0; i < LOOPS; i++) {
-
I have included the essential code example with my original post. You are welcome to comment on it or let me know if I should give more details.
-
-
That something worked for 10 years does not mean that it is flawless. It is also not an argument to skip debugging. You could use below code to verify whether it is a limit or not. If there's a limit, below code should run into the same problem.
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;namespace ConsoleApplication5
{
class Program
{
static UIntPtr HKEY_CURRENT_USER = new UIntPtr(0x80000001u);
const int LOOPS = 200;enum RegistryRights: int { ReadKey = 131097, WriteKey = 131078 } \[DllImport("advapi32.dll", CharSet = CharSet.Auto)\] public static extern int RegOpenKeyEx( UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult); \[DllImport("advapi32.dll", SetLastError = true)\] static extern uint RegQueryValueEx( UIntPtr hKey, string lpValueName, int lpReserved, ref uint lpType, IntPtr lpData, ref uint lpcbData); \[DllImport("advapi32.dll", SetLastError = true)\] public static extern int RegCloseKey( UIntPtr hKey); private static string ReadRegKey(UIntPtr rootKey, string keyPath, string valueName) { UIntPtr hKey = UIntPtr.Zero; string keyValue = ""; if (RegOpenKeyEx(rootKey, keyPath, (int)0, (int)RegistryRights.ReadKey, out hKey) == 0) { uint size = 1024; uint type = 0; IntPtr pResult = IntPtr.Zero; pResult = Marshal.AllocHGlobal((int)size); if (RegQueryValueEx(hKey, valueName, 0, ref type, pResult, ref size) == 0) keyValue = Convert.ToString(Marshal.ReadByte(pResult)); // takes only first byte, for test Marshal.FreeHGlobal(pResult); RegCloseKey(hKey); } return keyValue; } static void Prepare() { byte\[\] bytes = new byte\[88\]; for (byte b = 0; b < 88; b++) bytes\[b\] = b; RegistryKey rkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default); RegistryKey tkey = rkey.OpenSubKey("Test", true); for (byte i = 0; i < LOOPS; i++) {
Thank you for the code example. I cannot compile it because I use plain C, such as in Microsoft Windows Help (Win32 Online Help, version 1.00.178) or on MSDN pages, or such as this one: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911%28v=vs.85%29.aspx[^]
-
SMD111 wrote:
the application has always worked flawlessly - until
Then it hasn't worked flawlessly. You really need to do some serious debugging to find out why this is happening. Rather than just assuming that it's a Microsoft error, you should look deeper into your code.
Quote:
You really need to do some serious debugging to find out why this is happening.
Why do you assume I have not done “some serious debugging”? Please teach me how to debug a single RTL function call that does not generate an error.
Quote:
Rather than just assuming that it's a Microsoft error…
Do you work for Microsoft? You see, I came to this forum in order to share with people some very strange findings, in order to get somebody interested in finding what is really going on, and not to get a write-off along the lines “It works on my computer!” If you don’t have interest in this problem, you don’t have to post to this thread, I thank you very much for looking into this.
Quote:
you should look deeper into your code
You have my code, above.
-
Yes, but it does not tell us anything much that helps to identify why it is not working. [edit] Removed redundant comment. [/edit]
-
I have included the essential code example with my original post. You are welcome to comment on it or let me know if I should give more details.
Try your code again, but isolate it in a console-app. Have it fill the array, save it, and read it as the C# example I posted. Have it output the first byte. That way it should be easy to determine whether something is wrong with the code you posted, or whether it is going wrong in another place. If it is something in the QueryValueEx call, then it should be reproducable with a few lines of code.
Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]
-
-
Quote:
You really need to do some serious debugging to find out why this is happening.
Why do you assume I have not done “some serious debugging”? Please teach me how to debug a single RTL function call that does not generate an error.
Quote:
Rather than just assuming that it's a Microsoft error…
Do you work for Microsoft? You see, I came to this forum in order to share with people some very strange findings, in order to get somebody interested in finding what is really going on, and not to get a write-off along the lines “It works on my computer!” If you don’t have interest in this problem, you don’t have to post to this thread, I thank you very much for looking into this.
Quote:
you should look deeper into your code
You have my code, above.
SMD111 wrote:
Why do you assume I have not done “some serious debugging”?
I assume nothing; I respond only to the information you have provided.
SMD111 wrote:
Do you work for Microsoft?
No, but experience has taught me that in situations such as this it is most likely a user error.
SMD111 wrote:
If you don’t have interest in this problem
I do have interest, which is why I wrote a program to try and identify why this situation occurs.
SMD111 wrote:
You have my code, above.
Which, as I said elsewhere, tells us very little.
-
Thank you for the code example. I cannot compile it because I use plain C, such as in Microsoft Windows Help (Win32 Online Help, version 1.00.178) or on MSDN pages, or such as this one: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911%28v=vs.85%29.aspx[^]
SMD111 wrote:
I cannot compile it because I use plain C,
Download a compiler? Translating it to C would not help very much in proving that the api-call works as intended. Or in another wording, I'm simply trying to prove that
SELECT
is not broken. If I can prove that, then the error must be somewhere else in the code.Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]
-
SMD111 wrote:
I cannot compile it because I use plain C,
Download a compiler? Translating it to C would not help very much in proving that the api-call works as intended. Or in another wording, I'm simply trying to prove that
SELECT
is not broken. If I can prove that, then the error must be somewhere else in the code.Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]
Eddy Vluggen wrote:
Download a compiler? Translating it to C would not help very much in proving that the api-call works as intended.
I do not understand what you are saying. C is a low-level language that shows how things exactly work (well, assembler would be better still, but I don't have time to write an asm example of RegQuerryValueEx() use). After all, according to MSDN article[^],
Quote:
The Win32 API (also known as the Windows API) is a C-based framework for creating Windows applications.
Quote:
This API is designed for use by C/C++ programmers.
This is a Windows API forum, right? It looks like we are speaking different languages ;) Perhaps the problem I observe is not related to the use of API but to some Windows system internals, such as user policies management... Maybe I should re-post my question in a different forum. Whatever it is, I'll let you know if I find an answer.
-
Eddy Vluggen wrote:
Download a compiler? Translating it to C would not help very much in proving that the api-call works as intended.
I do not understand what you are saying. C is a low-level language that shows how things exactly work (well, assembler would be better still, but I don't have time to write an asm example of RegQuerryValueEx() use). After all, according to MSDN article[^],
Quote:
The Win32 API (also known as the Windows API) is a C-based framework for creating Windows applications.
Quote:
This API is designed for use by C/C++ programmers.
This is a Windows API forum, right? It looks like we are speaking different languages ;) Perhaps the problem I observe is not related to the use of API but to some Windows system internals, such as user policies management... Maybe I should re-post my question in a different forum. Whatever it is, I'll let you know if I find an answer.
SMD111 wrote:
C is a low-level language that shows how things exactly work
For the things you write, yes. It does not show the internals of the WinAPI, and you can call those functions from higher level languages. If there are policies playing along (or other settings or stuff like a corrupted register), then the problem should re-occur in whatever language you use to call the API.
SMD111 wrote:
This is a Windows API forum, right? It looks like we are speaking different languages ;)
I assumed English, my bad.
Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]