I am trying to do an application which shows machine name of the PC fetch from registry. It has to run in 64 bit window 7 machine.
But I can only manage to output the system error message.
In below code,
I always get value of value1str (using RegOpenKeyEx method) => as 0 (which is ERROR_SUCCESS)
and value2str (using RegQueryValueEx method) => as 2 (which is ERROR_FILE_NOT_FOUND)
Anyone knows how to display the real machine name?
Please help!
#define KEY_WOW64_64KEY (0x0100)
#include <iostream>
#include <string>
BEGIN_MESSAGE_MAP(CPOConLogApp, CWinApp)
END_MESSAGE_MAP()
CPOConLogApp::CPOConLogApp()
{
int value1;
int value2;
HKEY root = NULL;
CString value1Str,value2Str;
value1=RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName"), NULL, KEY_READ|KEY_WOW64_64KEY, &root);
value1Str.Format("%d",value1);
MessageBoxA ( NULL, value1Str, "Test", MB_OK );
LPBYTE data = NULL;
DWORD dwType;
DWORD dwSize;
data = new BYTE[dwType];
value2=RegQueryValueEx(HKEY_LOCAL_MACHINE,TEXT("Computer Name"), NULL, &dwType, data, &dwSize);
value2Str.Format("%d",value2);
MessageBoxA (NULL, value2Str , "Test", MB_OK );
}
Alternative solution:
Instead of trying to find where is the key in the Registry and how to read it, you can just rely on the API Microsoft provide.
To get the Computer NetBIOS name (initialized from registry at system startup) use GetComputerName like below.
#include <windows.h>
int main()
{
char buf[1024];
DWORD dwCompNameLen = 1024;
if (0 != GetComputerName(buf, &dwCompNameLen)) {
printf("name %s\n", buf);
}
return 0;
}
You can read the computer name from the below mentioned registry key,
System\CurrentControlSet\Control\ComputerName\ComputerName
I found out why always ERROR_FILE_NOT_FOUND value. I suppose to put last parameter of RegOpenKeyEx to the first parameter in RegQueryValueEx. It should be like this.
value2=RegQueryValueEx(root,TEXT("Computer Name"), NULL, &dwType, data, &dwSize);
If you want prompts the value of the registry, computer name in this case, use the below code.
value.Format("%s",pszBuffer);
MessageBoxA (NULL, value , "Test", MB_OK );
Related
I am trying to disable the Windows Defender using a C++ Win32API application.
To do that I need to write a D Word into the registry (DisableAntiSpyware = 1).
I always do that manually after installing a new Windows.
So here is my code, but its not working.
Maybe someone could tell me why or what is wrong with it. Thank you!
OK I've changed the code a bit, still not working...
case 1:
//::MessageBeep(MB_ICONERROR);
::MessageBox(hWnd, L"Button was Pressed",L"Button was clicked?",MB_OK);
LONG
SetRegValue
(
const wchar_t* path
, const wchar_t *name
, const BYTE *value
);
{
LONG status;
HKEY hKey;
DWORD value = 0x00000001;
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"\\SOFTWARE\\Policies\\Microsoft\\Windows Defender", 0, KEY_ALL_ACCESS, &hKey);
if ((status == ERROR_SUCCESS) && (hKey != NULL))
{
status = RegSetValueEx(hKey, L"test", 0, REG_DWORD, (const BYTE*)&value,sizeof(value));
RegCloseKey(hKey);
}
return status;
::MessageBeep(MB_ICONERROR);
}
}
}
break;
When opening a Registry key, you should request only the rights you actually need. So replace KEY_ALL_ACCESS with KEY_SET_VALUE instead, since all you are doing is writing a value. But even then, you might still need to run your app with elevated permissions in order to write to HKEY_LOCAL_MAHCINE, unless you give your user account write access to the Windows Defender key beforehand.
Also, if your code is compiled as 32bit and runs on a 64bit system, and it needs to write to the 64bit Registry, then you have to include the KEY_WOW64_64KEY flag otherwise you may be subject to Registry Reflection/Registry Redirection.
Try something more like this instead:
case 1:
{
::MessageBox(hWnd, L"Button was Pressed", L"Button was clicked?", MB_OK);
DWORD value = 1;
DWORD flags = KEY_SET_VALUE;
#if !defined(_WIN64)
BOOL bIsWow64Process = FALSE;
if (IsWow64Process(GetCurrentProcess(), &bIsWow64Process) && bIsWow64Process)
flags |= KEY_WOW64_64KEY;
#endif
HKEY hKey;
LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"\\SOFTWARE\\Policies\\Microsoft\\Windows Defender", 0, flags, &hKey);
if ((status == ERROR_SUCCESS) && (hKey != NULL))
{
status = RegSetValueEx(hKey, L"DisableAntiSpyware", 0, REG_DWORD, (const BYTE*)&value, sizeof(value));
RegCloseKey(hKey);
}
::MessageBeep(MB_ICONERROR);
}
break;
You can't write to any key under HKEY_LOCAL_MACHINE unless the program is running with elevated privileges, i.e. administrator mode. The call to RegOpenKeyEx or RegSetValueEx will fail.
We have had a piece of software in use for several years and just recently we have started receiving reports of issues. Investigating the reported issues revealed they are being caused because the software is no longer able to create a sub key in the registry instead it receives an access is denied error. The one common denominator between all users is that they are using Windows 10.
On windows 10 64 bit the software attempts to create the sub key:
HKU\{SID}\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Wow6432Node\{OUR_KEY}\{SUB_KEY}
On windows 10 32 bit the software attempts to create the sub key:
HKU\{SID}\Software\Classes\VirtualStore\MACHINE\SOFTWARE\{OUR_KEY}\{SUB_KEY}
Our key exists in the registry; the software runs with administrator privileges and executes the following code:
ORegistry
ORegistry::CreateSubKey( const OString& szSubKeyName )
{
ORegistry result( NULL );
if( m_hKey != NULL )
{
HKEY hRes;
wchar_t *wstr = szSubKeyName.toWChars();
LONG lRes = RegCreateKeyEx( m_hKey, wstr, 0, NULL, REG_OPTION_NON_VOLATILE, mSamDesired | KEY_WRITE, NULL, &hRes, NULL );
delete [] wstr;
if( lRes == ERROR_SUCCESS )
{
result = hRes;
}
else
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lRes,
0, // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Process any inserts in lpMsgBuf.
// ...
// Display the string.
ODebugOutput::log(&OString("Registry CreateSubKey Error: Subkey (%s) and windows error (%s)"), &szSubKeyName, &OString((LPCTSTR)lpMsgBuf));
//MessageBox( NULL, (LPCTSTR)lpMsgBuf, L"Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
}
return result;
We are unable to reproduce this issue so if no solution is known then reproduction steps would also be helpful.
Thanks for your help and time in advance.
I'm trying to find the path to Excel using the registry, and have tried to adapt some code I've found on the internet. I'm using 64-bit Win7 and have confirmed the key is there using regedit.
#include <windows.h>
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
HKEY hKey = 0;
char buf[255] = {0};
DWORD dwType = 0;
DWORD dwBufSize = sizeof(buf);
const char* subkey = "SOFTWARE\\Classes\\Excel.Application\\CLSID";
if( RegOpenKey(HKEY_LOCAL_MACHINE,subkey,&hKey) == ERROR_SUCCESS)
{
dwType = REG_SZ;
if( RegQueryValueEx(hKey,"default",0, &dwType, (BYTE*)buf, &dwBufSize) == ERROR_SUCCESS)
{
cout << "key value is '" << buf << "'\n";
}
else
cout << "can not query for key value\n";
RegCloseKey(hKey);
}
else
cout << "Can not open key\n";
cin.ignore();
return 0;
}
Does anyone know why this isn't working?
Thanks
James
Try changing the
RegQueryValueEx(hKey,"default",0, &dwType, (BYTE*)buf, &dwBufSize) == ERROR_SUCCESS)
with
RegQueryValueEx(hKey, NULL, 0, &dwType, (BYTE*)buf, &dwBufSize) == ERROR_SUCCESS)
If you want the "default" value, you should pass NULL or a empty string in the lpValueName field.
Also if your application is not 64-bit and you are running in a 64-bit OS, you should check the KEY_WOW64_64KEY flag on the RegOpenKeyEx function, to have access to the key you want.
Almost all Windows API functions, when the fail, set a more detailed error code that you can get by calling GetLastError() for more details. You should call that after a call to RegOpenKey() fails.
In your example, the RegOpenKey() is probably failing with an access denied error. RegOpenKey() open a registry key with full read/write/delete access. A standard user on Windows 7 doesn't have write or delete access on HKLM so RegOpenKey() will fail.
You should instead use RegOpenKeyEx() which will let you specify read-only access, as below.
RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, KEY_READ, &hKey)
PS. When asking a question like the one above you should be more descriptive on how the code is failing. In your example above you should include which line/function call is failing. For example "When I use this code, the call to RegOpenKey is failing.
I am Creating the Registry Key using following code:
LPCTSTR lpNDS= TEXT("SOFTWARE\\myKEY");
if(OK==ERROR_SUCCESS)
{
MessageBox ( NULL, "Success",
_T("SimpleShlExt"),
MB_ICONINFORMATION );
}
else
{
MessageBox ( NULL, "Failed" ,
_T("SimpleShlExt"),
MB_ICONINFORMATION );
}
LONG openRes = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
lpNDS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hRegKey,
NULL);
if (openRes!=ERROR_SUCCESS)
MessageBox ( NULL, "Registry Createion Failed",
_T("SimpleShlExt"),
MB_ICONINFORMATION );
Now I am writing up to the Key using:
CSimpleShlExt::WriteToRegistry(LPSTR lpRegKeyVal)
{
LONG setRes = RegSetValueEx (hRegKey, "NDS", 0, REG_SZ, (LPBYTE)lpRegKeyVal, strlen(lpRegKeyVal)+1);
CloseRegistryKey();
}
Now I am trying read the registry key value that I have created using WriteToRegistry function. I have tried with
RegOpenKeyEx(hRegKey,lpNDS,0,KEY_QUERY_VALUE,&hRegKey);
But this is failing.
Which function shall I use to read the value contained inside the key?
You can try something like :
TCHAR szValue[TEMP_STR_SIZE] = {0};
DWORD dwStorageSize = TEMP_STR_SIZE;
LPBYTE lpStorage = reinterpret_cast<LPBYTE>(szValue);
// In case of registry value retrieval failure
if (ERROR_SUCCESS != RegQueryValueEx(hRegKey, _T("NDS"), 0, 0, lpStorage, &dwStorageSize))
{
// Prompt error
}
Edit:
Just noticed there are no subkey, changed my sample code
Which function shall I use to read the value contained inside the key?
Try RegQueryValue and/or RegEnumValue. Read the documentation to see which one suits your needs the best.
I'm trying to create a new registry key in the windows registry using C++. Here is the code I have so far:
HKEY hKey;
LPCTSTR sk = TEXT("SOFTWARE\\OtherTestSoftware");
LONG openRes = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
sk,
0,
NULL,
REG_OPTION_BACKUP_RESTORE,
KEY_ALL_ACCESS,
NULL,
&hKey,
NULL);
if (openRes==ERROR_SUCCESS) {
printf("Success creating key.");
} else {
printf("Error creating key.");
}
LPCTSTR value = TEXT("OtherTestSoftwareKey");
LPCTSTR data = "OtherTestData\0";
LONG setRes = RegSetValueEx (hKey, value, 0, REG_SZ, (LPBYTE)data, strlen(data)+1);
if (setRes == ERROR_SUCCESS) {
printf("Success writing to Registry.");
} else {
printf("Error writing to Registry.");
}
//RegDeleteKey(hKey, sk);
LONG closeOut = RegCloseKey(hKey);
if (closeOut == ERROR_SUCCESS) {
printf("Success closing key.");
} else {
printf("Error closing key.");
}
I'm able to successfully open an existing key using a very similar code snippet (basically replace RegCreateKeyEx with RegOpenKeyEx). I would imagine that one or more of the arguments I'm passing into RegCreateKeyEx is causing the trouble. I'm honestly not sure where things might be getting fouled up since all of the error codes i've trapped show success. For reference, here is the function signature for RegCreateKeyEx:
/*
* LONG WINAPI RegCreateKeyEx(
__in HKEY hKey,
__in LPCTSTR lpSubKey,
__reserved DWORD Reserved,
__in_opt LPTSTR lpClass,
__in DWORD dwOptions,
__in REGSAM samDesired,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__out PHKEY phkResult,
__out_opt LPDWORD lpdwDisposition
);
*/
Any thoughts would be great!
thanks,
brian
I've been compiling my own personal Function Library for years. One part of this deals entirely with registry access, see the CreateRegistryKey function the Registry.Cpp file.
If you are interested, you can grab the entire library here.
As already mentioned, you've specified the REG_OPTION_BACKUP_RESTORE option in the call to RegCreateKeyEx, which means that you're opening the key in order to perform a backup or restore. Ordinarily, you would use REG_OPTION_NON_VOLATILE instead.
What operating system are you running? In Windows 2000/XP, the HKEY_LOCAL_MACHINE registry hive is not writeable by non-administrator users, so RegCreateKeyEx will fail with an access denied error (error 5). This also applies to Vista, if your application has a requestedExecutionLevel entry in its manifest. If you're running Vista, and your application doesn't specify a requestedExecutionLevel (or if it doesn't have a manifest at all), access to HKEY_LOCAL_MACHINE will be virtualised, so RegCreateKeyEx should succeed. See Registry Virtualization in Windows Vista in MSDN for more details.
There are some more problems with the code you've posted, which will only become apparent if you compile your project with UNICODE defined. This line:
LPCTSTR data = "OtherTestData\0";
should be
LPCTSTR data = TEXT("OtherTestData\0");
and this line:
LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ,
(LPBYTE)data, _tcslen(data)+1);
should be:
LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ,
(LPBYTE)data, (_tcslen(data)+1) * sizeof(TCHAR));
because the cbData parameter in RegSetValueEx is the length of the data in bytes, not characters.
I hope this helps!
The first clue is your use of REG_OPTION_BACKUP_RESTORE. You probably don't want to use that flag, as I believe it requires a special "backup" privilege that you need to enable beforehand. Normal applications won't want to do that.
Probably this is the reason why you can cannot create a new key, with your code.
These links might be of help.
http://www.codeguru.com/forum/archive/index.php/t-378884.html
http://www.codeguru.com/forum/archive/index.php/t-275250.html
As a sidenote, always try GetLastError() to get the error message.
I have not tested either of them.