Its really hard going to code to save the ip settings(RegSetValueEx()) from cpp(By registry editing of WinCe).
Its issue about encoding of string(which I parse to BYTE* and if I use hardcoded string,parsed it to same BYTE* it supports)
Anybody can support for coding, will be good.Otherwise , please show me the different routes if you can.
(Like batch file(setting ip with ipconfig) to execute from cpp).
HKEY hKey;
int res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Comm\\ENET1\\Parms\\TcpIp", 0, KEY_WRITE, &hKey);
const BYTE* data = (BYTE*)text;
long ret = RegSetValueEx(hKey,L"IpAddress",0,REG_MULTI_SZ,data,16);
RegCloseKey(HKEY_LOCAL_MACHINE);
It should save ip on WinCe from cpp.
By batch file executing from cpp.
Registry editing from cpp.
Or any other method.
Related
I'm trying reading the Registry data from a value named Scoop in HKLM\Software\Wow6432Node\Company\Software\Settings:
This key and value already exist prior to installing my software.
My software contains its own 32-bit service. So when my software is installed, the service (running under SYSTEM), attempts to read this value.
However, within the service, RegQueryValueEx returns "2" (ERROR_FILE_NOT_FOUND). Yet, when I run services.msc and restart my service, RegQueryValueEx returns "0" (ERROR_SUCCESS). RegOpenKeyEx always returns ERROR_SUCCESS, but RegQueryValueEx is returning 2 at installation.
My code:
HANDLE hKey = NULL;
WCHAR *sPath = L"SOFTWARE\\Company\\Software\\Settings";
RegOpenKeyExW(HKEY_LOCAL_MACHINE, sPath, 0, KEY_WOW64_32KEY | KEY_QUERY_VALUE, &hKey);
DWORD dwSize = 0;
DWORD dwType = 0;
WCHAR sZeroLengthString[4] = {0};
// get the buffer size needed, including null terminating characters.
dwRV = RegQueryValueExW(hKey, L"Scoop", NULL, &dwType, (LPBYTE) sZeroLengthString, &dwSize);
The instalation is being run under a domain admin account.
I can't for the life of me figure out why RegQueryValueEx is returning 2 at install, but is fine restarting with services.msc. The manifest of the service is set to highestAvailable, and there are no special permissions on the Registry key, just the standard...SYSTEM does have Full Control.
Do not access the Wow6432Node key directly at all, pretend it doesn't even exist. Access the non-redirected key normally, using the appropriate KEY_WOW64_(32|64)KEY flag to handle the redirection based on which view your want to access. This is even stated in the documentation:
Registry Redirector
Redirected keys are mapped to physical locations under Wow6432Node. For example, HKEY_LOCAL_MACHINE\Software is redirected to HKEY_LOCAL_MACHINE\Software\Wow6432Node. However, the physical location of redirected keys should be considered reserved by the system. Applications should not access a key's physical location directly, because this location may change. For more information, see Accessing an Alternate Registry View.
Wow6432Node is an implementation detail of the WOW64 emulator for 32bit processes. So, don't rely on it. Simply drop Wow6432Node from your sPath since you are explicitly accessing the 32bit Registry view:
HANDLE hKey = NULL;
LPCWSTR sPath = L"SOFTWARE\\Company\\Software\\Settings";
RegOpenKeyExW(HKEY_LOCAL_MACHINE, sPath, 0, KEY_WOW64_32KEY | KEY_QUERY_VALUE, &hKey);
DWORD dwSize = 0;
DWORD dwType = 0;
WCHAR sZeroLengthString[4] = {0};
// get the buffer size needed, including null terminating characters.
dwRV = RegQueryValueExW(hKey, L"Scoop", NULL, &dwType, (LPBYTE) sZeroLengthString, &dwSize);
I'm working on an utility to hook various bits of the Windows API used by different applications. The aim of the project is, at the moment to make any application portable by redirecting filesystem and registry calls to custom locations using easyhook and boost (specifically the property_tree library).
I'm currently working on the registry part of the project and I have successfully created analogues to the RegCreateKey(ExA/ExW/A/W), RegOpenKey(ExA/ExW/A/W) and RegCloseKey functions and they work fine (i made a virtual handle system to create and translate hKey handles). They work by basically translating everything to strings and saving them in a boost property tree (and then writing the tree to an .info file).
I started working on the RegSetValue and RegQueryValue functions, the ones that actually handle the data and encountered a major problem. Below are the two functions. Note that these are called by easyhook with the same parameters of the original winapi call.
LSTATUS WINAPI myRegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData)
{
boost::property_tree::ptree VirtualRegistry;
boost::property_tree::read_info("VirtualRegistry.info", VirtualRegistry);
VirtualRegistry.put(boost::property_tree::ptree::path_type(std::string(GetPathFromHandleA(hKey) + '\\' + lpValueName), '\\'), reinterpret_cast<const char*>(lpData));
boost::property_tree::write_info("VirtualRegistry.info", VirtualRegistry);
return ERROR_SUCCESS;
}
This works fine for REG_SZ calls but other types of data are not saved correctly.
LSTATUS WINAPI myRegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
{
boost::property_tree::ptree VirtualRegistry;
boost::property_tree::read_info("VirtualRegistry.info", VirtualRegistry);
try
{
*lpData = reinterpret_cast<const BYTE*>VirtualRegistry.get_child(boost::property_tree::ptree::path_type(std::string(GetPathFromHandleA(hKey) + "\\" + lpValueName), '\\')).data();
return ERROR_SUCCESS;
}
catch (const boost::property_tree::ptree_bad_path& e1)
{
std::cout << "\n" << "ENTRY NOT FOUND" << "\n";
return ERROR_FILE_NOT_FOUND;
}
}
This does not work. The reinterpret cast on line 6 is invalid and it won't compile.
The problem is the way my functions handle different types of data. A registry call can have many different value types and the way I wrote myRegSetValue only seems to work for REG_SZ. I will also have to save the value type when writing the call to the file but that does not solve the problem.
So my question is, is there any way of saving the raw data of a call, as a string, without having to cast it as a string, so that it works for all types of data, and then reading it back from the file from a string back to raw data and passing it to the application?
I guess I could write a separate interpreter for each key type but i would really rather not because it would be very hacky and also would break applications that do not use the registry API correctly and store invalid values in the registry (like, for example, the Unity game Sunless Sea).
Thank you, I hope I explained this in enough detail.
It appears that the real problem is already the implementation of myRegSetValueExA. When you get lpData, you can't assume that it points to data that will remain valid. You must store not the pointer, but the pointed-to data.
That's also why cbData is necessary; you need to know how much data to store. You can't rely on strlen since the type might not be REG_SZ.
Note that your assumption about This works fine for REG_SZ is true only because VirtualRegistry.put(std::string key, const char* value) is a convenient overload which calls strlen(buf) for you.
The solution is to create explicitly std::string data(static_cast<const char*>(lpData), cbData) and use that in the put. To retrieve it, you use .get<std::string>(key) instead of get_child(key).data().
I am trying to write a DWORD value to the registry programmatically in C++.
I've done a bit of searching and I have found that this question has been asked before. I've tried to follow their solution but have come up with a really frustrating issue which, as far as I know, have not been addressed by their solution.
This is my code:
HKEY hKey;
LPCWSTR sKeyPath;
int iResult;
sKeyPath = L"Software\\ABI\\";
iResult = RegOpenKeyEx(HKEY_CURRENT_USER, sKeyPath, NULL, KEY_ALL_ACCESS, &hKey);
DWORD value = 0x00000003;
iResult = RegSetValueEx(hKey, L"Test", NULL, REG_DWORD, (const BYTE*)value, sizeof(value));
RegCloseKey(hKey);
I've done some basic debugging and found that the value of iResult is 998 after I call RegSetValueEx. I am sure that this key is present in the windows registry because I created it manually with regedit.exe for testing purposes. The value of the DWORD "Test" is initially 0x00000009 and is unchanged after I run my program.
I am not sure where I am wrong.
Any help would be appreciated.
P.S. I've not managed to find any helpful site on the net for error 998. The only reference I found mentions that that's the worst error you can get when handling registry.
P.P.S. By the way, I'm running this program on Windows 8. I don't think that changes anything but I've had experiences with Windows 8 having some weird security issues before.
You need to pass the address of value:
iResult = RegSetValueEx(hKey,
L"Test",
NULL,
REG_DWORD,
(const BYTE*)&value, // Change made here.
sizeof(value));
The error code 998 means:
Invalid access to memory location.
When the address of value is not passed its actual value (3) is being used as a memory address, causing the failure.
I wrote a small program which frequently opens small, user text files and until now haven't encountered any problems with read/write access or any sorts of conflict. The files are selected in another piece of software which I have no control over, and are passed to me as a string.
When attempting to open a file from a mapped network drive I am getting a "The system cannot find the path specified" error (GetLastError() = 3).
The call is shown below, *iNCfileName = "z:\\Validation\\Sample Files\\1_1-4 120MM.CC", where Z: is a mapped folder on our domain.
iNCfile = CreateFile( iNCfileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if ( iNCfile == INVALID_HANDLE_VALUE )
{
string msg; // lots of better ways to get this printed ... but ...
dw = GetLastError();
msg = iNCfileName;
msg += ": ";
msg += _com_error(dw).ErrorMessage();
print_error(dw , (char*)msg.c_str() );
return 102;
}
The file opens from my program if I copy it to the local hard drive. It also opens in notepad from the mapped drive.
Could this be a problem between the "Z:\whatever.txt" mapped representation and the true file name (\mydomain\Validation\S....??)?
If so, how can I convert from one to the other in a programmatic way (assume I won't know the domain/share names ahead of time)?
If it makes any difference I use VS2010 and the application executes on a Win XP machine.
Related: my follow up question
I've encountered this before. When using a path like \\DOMAIN\PATH\FILE.TXT I had to first call WNetAddConnection2().
Here is my code (of course you can exclude the NULL members):
NETRESOURCE nr = {0}; //new structure for network resource
nr.dwType = RESOURCETYPE_ANY; //generic resource (any type allowed)
nr.lpLocalName = NULL; //does not use a device
nr.lpRemoteName = "\\\\DOMAIN\\PATH\\FOLDER"; //For me, this pointed to an account's documents folder, and from there I could use a subfolder
nr.lpProvider = NULL; //no provider
DWORD ret = WNetAddConnection2 (&nr, NULL, NULL, CONNECT_TEMPORARY); //add connection
Don't forget the header and library.
I just had the same issue; trying to create a file using API CreateFileW under a mapped drive ( Z:\folder ) did not worked; howerver, after researching this subject i tried to create the file using the real path ( \\Shared_computer_name\folder\ ) immediately worked successfully.
Now I have to work a function to retrieve the real name of a mapped drive, to use it when necessary... just found WNetGetUniversalName, have to make it to work.
Ineed to open this key" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\"
and get the "VerSpecificRootDir" value using c++ ....How can i do this
I have no knowledge abt it can any one help me in this regard..
After Getting All The Support I did it as
unsigned long type=REG_SZ, size=1024;
char res[1024]="";
HKEY hk;
long n = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Microsoft\\Microsoft SQL Server\\100"),
0,KEY_QUERY_VALUE, &hk );
if ( n == ERROR_SUCCESS )
{
printf("OK \n");
RegQueryValueEx(hk,L"VerSpecificRootDir",NULL,&type,(LPBYTE)&res[0],&size);
RegCloseKey(hk);
}
But in this i am not getting the value of "VerSpecificDirectory" what i have missed let me know?? what is wrong in this code....
You can use the Windows function SHRegGetValue like this:
TCHAR buffer[260];
DWORD bufferSize = sizeof(buffer);
SHRegGetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Microsoft SQL Server\\100", "VerSpecificRootDir", SRRF_RT_REG_SZ, NULL, buffer, &bufferSize);
After calling the function, buffer will contain a null-terminated string of the directory. Might want to check the return value for errors too.
#include <windows.h>
HKEY hKey;
int buffersize = 1024;
char *buffer = new char[buffersize];
RegOpenKeyEx (HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Microsoft SQL Server\\100",NULL,KEY_READ,&hKey);
RegQueryValueEx(hKey,"VerSpecificRootDir",NULL,NULL,(LPBYTE) buffer, buffersize);
std::cout << buffer;
RegCloseKey (hKey);
I currently only know how to do that by using the Qt framework:
QSettings settings("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\");
QString dir = settings.value("VerSpecificRootDir");
Qt is free and allows you to use simple and very good documented c++ APIs instead of the mixed and up Windows APIs. Sorry - that sounds for advertising... but I formerly struggled with the very bad designed Windows API and than found Qt, which allows me to develop faster and (a cool benefit) for multiple platforms without having to adapt my code.
Regards,
Chris
You can sure use ATL::CRegKey. It has all the functionality you need.
http://msdn.microsoft.com/en-us/library/xka57xy4(VS.80).aspx
Registry API was available (for ~15 years) from Windows 95 onwards. It's all well documented on MSDN ; and if you care to Google so many examples.