Access Windows Registry in C++ with CRegKey - c++

I tried to access the Windows Registry with this Code:
CRegKey key;
LPTSTR szBuffer = new TCHAR[50];
ULONG cchBuffer = 257;
key.Open(HKEY_CURRENT_USER, L"HARDWARE", KEY_READ);
ULONG chars;
CString str;
if (key.QueryStringValue(L"Test", 0, &chars) == ERROR_SUCCESS)
{
key.QueryStringValue(L"Test", str.GetBuffer(chars), &chars);
str.ReleaseBuffer();
}
key.Close();
It returned an Error of the Microsoft Visual C++ Runtime Library:
Debug Assertation Failed!
Program: ...
File: C:\Program Files\Microsoft Visual Studio
11.0\VC\ATLMFC\INCLUDE\altbase.h Line: 6146
Expression: m_hkey != 0
For information Blah blah
After pressing Ignore it crashes.
I'm not sure what compiler is used because I (think I have) configured Qt Creator to use Visual C++ but the output Directory os called ..._._MinGW_Qt_SDK_DEBUG
What to do now?

I don't have a Windows machine nearby, but I think that there is no subkey named HARDWARE into HKEY_CURRENT_USER: it is into HKEY_LOCAL_MACHINE.
That, added to the fact that you are not checking the Open call for errors suggests that what you really want to do is:
key.Open(HKEY_LOCAL_MACHINE, L"HARDWARE", KEY_READ);
Anyway, it is always a good idea to handle the error, just in case.

Related

Visual Studio (Resetting C++ project)

I've never used C++ in Visual Studio but do some work with C# and VB.
I have a simple x86 C++ project that loads a 32bit DLL then uses a function from it.
It was working fine, then I changed some settings (SDK version, toolset, C++ language standard) and now I get "The specified module could not be found." when I try and load the DLL.
I've reset C++ in the "Import and export settings wizard" and then reinstalled all of Visual Studio but I can't seem to find a way to get the project back to working with this DLL. Dumpbin shows me that all the dependencies it needs are in SYSWOW64 :/
I've made copies of the DLL and put them everywhere I can think of, but I get the same problem. It loads with C# but I have some memory access issues passing strings to one of the functions.
Anyone had an issue like this before?
//Get current exe path and add DLL filename.
char cDLLPath[MAX_PATH + 1];
TCHAR bufCurrentDirectory[MAX_PATH + 1] = { 0 };
DWORD dwNumCharacters = ::GetCurrentDirectory(MAX_PATH, bufCurrentDirectory);
if (dwNumCharacters == 0)
{
printf("Error getting executable path\n");
exit(0);
}
snprintf(cDLLPath, MAX_PATH + 1, "%s\\MyDLL.dll", bufCurrentDirectory);
HINSTANCE myDll = LoadLibrary((LPCWSTR)cDLLPath);
//MyDLL is always NULL, error message is always "The specified module could not be found."
I've removed the path, tried current working folder, moved it to c:\windows\system32 etc
This function tells me the DLL path\filename are correct.
BOOL file_exists(const fs::path& file_path, fs::file_status s = fs::file_status{})
{
if (fs::status_known(s) ? fs::exists(s) : fs::exists(file_path)) return true;
else return false;
}
-Pook

C++ ShellExecute specifically not opening LNK files

-Windows 7 64-bit
-Visual Studio 2013 (v120)
-Unicode Enabled
-Target Build- Debug 32-bit
I would like to build a launcher (for personal use) however I can't get ShellExecute to work with all file types or paths, specifically shortcuts (LNK). I've researched and tried the following in many combinations...
-I'm using escape sequences
-I'm adding the file extension (and tried without)
-I've included Windows.h
-Printed directory FindFirstFile / FindNextFile to explicitly ensure the path has no typos
-Tried using both a literal and variable as file path argument
-Tried running VS with admin privileges
-Tried ShellExecute, ShellExecuteA, ShellExecuteEx, and System (with appropriate character sets)
-Tried NULL, "runas" and, "open" for the verb
-Launches fine from Command Line or explorer using same path
-Tried using %USERPROFILE% macro instead of user name (returns 2)
-Seems to work with EXE and URLs
-Does not seem to work with any LNK across any path including C:\ directly
Suspected issue
-32bit/64bit discrepancy
-UAC / Privelages
-Character set
-File extension
-Anti virus interference (though AV isn't alerting me of any issues) and I've tested while silencing my AV
Here is one of the simplest programs I've tried...
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <atlstr.h>
int _tmain(int argc, _TCHAR* argv[])
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
// Variables below for testing as path argument
// Paths that end with LNK are the only ones that I can't get to launch
CStringW link("C:\\Users\\Home\\Documents\\Art\\blender.lnk"); // Doesn't work
CStringW target("C:\\Program Files\\Blender Foundation\\Blender\\blender.exe"); // Launches software as expected
CStringW url("https://stackoverflow.com"); // Launches browser with URL as expected
int error = reinterpret_cast<int>(ShellExecute(
NULL,
NULL,
L"C:\\Users\\Home\\Documents\\Art\\blender.lnk", // Using literal with LNK extension also does not work
NULL,
NULL,
SW_SHOWDEFAULT
));
// EVEN SYSTEM CAN NOT FIND THE PATH!!!
// system("C:\\Users\\Home\\Documents\\Art\\blender.lnk");
std::cout << error << std::endl; // Returns 3 "The specified path was not found.".
// Free COM
CoUninitialize();
return 0;
}
First, check that your .lnk file is in the path.
Then (and the most probable cause of your problem) check that your .lnk filename is created correctly. To make sure it is not like "blender.lnk.lnk"(I can reproduce your issue if I have set as this).
You can also try to parse the path of the link file manually by yourself.
Here is the sample:
void ShortcutToRealpath(LPWSTR pszString, LPSTR pdzString)
{
IShellLink *pShellLink;
HRESULT hRes;
::CoInitialize(NULL);
hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&pShellLink);
if (SUCCEEDED(hRes))
{
IPersistFile *ppf;
hRes = pShellLink->QueryInterface(IID_IPersistFile, (void **)&ppf);
if (SUCCEEDED(hRes))
{
hRes = ppf->Load(pszString, TRUE);
if (SUCCEEDED(hRes))
{
pShellLink->GetPath(pdzString, MAX_PATH, NULL, 0);
}
ppf->Release();
}
pShellLink->Release();
}
::CoUninitialize();
}
When I build as x86 Platform, the path will be parsed like:
That's the reason your program can't find the path.
And if I select x64:
Put your target file to the corresponding file.
EDIT:
After I test it with the MS tool Procmom.exe, I have found something others, if run as 32-bit, it will show :
The key value is C:\Program Files (x86) and if we run it as 64-bit, the key is reference to "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir" the key value is C:\Program Files. After I check the registry:
It seems that C:\Program Files is not visible by default to the 32-bit registry(I am not sure about the specific reason).
If you change the key ProgramFilesDir to C:\Program Files in 32-bit registry, the issue will be fixed.

VC++ Dll Not Working On Windows XP Sp3 When Using C++ Builder

I have created VC++ Dll in Visual Studio 2013.
extern "C" int __declspec(dllexport) __cdecl ConvertImageToText(char* dataPath, char* imageFilePath, char* captchaCode)
{
// to do
return 0;
}
I'm using in Borland C++ Builder 6 like that.
HMODULE dllHandle = LoadLibrary("Captcha.dll");
int (__cdecl *ConvertImageToText)(char*,char*,char*);
ConvertImageToText =(int (__cdecl *)(char*,char*,char*))GetProcAddress(dllHandle, "ConvertImageToText");
if (ConvertImageToText != NULL )
{
ConvertImageToText("","","");
}else
{
ShowMessage("ConvertImageToText pointer not found !");
}
it's working well in win7/8/8.1.there isn't any problem.
But can't find pointer of ConvertImageToText on windows xp sp3.
I have changed VC++ Dll Project "Platform Toolset" as "Visual Studio 2013 - Windows XP (v120_xp)".nothing not changed.
I have checked Visual C++ Redistributable packages.All installed
Any sugguestions ?
You need to implement proper error checking as described by the documentation.
Test the return value of LoadLibrary. A value of NULL indicates failure. If that is so, call GetLastError for extended error details.
E. Test the return value of GetProcAddress. A value of NULL indicates failure. If that is so, call GetLastError for extended error details.
Likely LoadLibrary is failing because your DLL is linked to a runtime that is not installed on the target machine, or because your DLL is linked to Win32 API functions that do not exist on XP.
If you cannot work it out from here you can use Dependency Walker for extra debugging. Use it in profile mode to debug the loader's attempt to load the DLL. That will reveal enough information to diagnose the problem.
I have installed that redist release. it worked.

c++ file datestamp change by ms sql xp called by trigger to allow refresh vb.net forms application

I'm using SQL2012 and VS2012.
I'd like to implement this solution for watching a file's date and time stamp which is updated by a dll when a trigger on a SQL table is fired.
Here is what I'm trying to do.
Which references a MSDN article
I’ve followed the instructions but got this:
Msg 17750, Level 16, State 0, Procedure xsp_UpdateSignalFile, Line 1
Could not load the DLL XSP.dll, or one of the DLLs it references. Reason: 193(%1 is not a valid Win32 application.).
I’m assuming because I’m using SQL2012 64-bit.
I downloaded the XSP.DLL source and looking at in the VS2012 but can’t get it to compile, even after finding myself a copy of opends60.lib
Error 4 error LNK2019: unresolved external symbol _srv_rpcparams referenced in function _xsp_UpdateSignalFile C:\Users\Administrator\Documents\xsp.dll\WickedCode0304\XSP\XSP.obj XSP
Can a C++ wizard help me compile this to 64bit or am I going wrong earlier?
It is saying it can't resolve some received params?
The .cpp file looks like this:
#include <windows.h>
#include <srv.h>
///////////////////////////////////////////////////////////////////////
// Entry point
extern "C" BOOL WINAPI DllMain (HINSTANCE hInstance, DWORD dwReason,
LPVOID lpReserved)
{
return TRUE;
}
///////////////////////////////////////////////////////////////////////
// Exported functions
extern "C" __declspec (dllexport)
ULONG __GetXpVersion ()
{
return ODS_VERSION;
}
extern "C" __declspec (dllexport)
SRVRETCODE xsp_UpdateSignalFile (SRV_PROC *srvproc)
{
//
// Make sure an input parameter is present.
//
if (srv_rpcparams (srvproc) == 0)
return -1;
//
// Extract the file name from the input parameter.
//
BYTE bType;
char file[256];
ULONG ulMaxLen = sizeof (file);
ULONG ulActualLen;
BOOL fNull;
if (srv_paraminfo (srvproc, 1, &bType, &ulMaxLen, &ulActualLen,
(BYTE*) file, &fNull) == FAIL)
return -1;
if (bType != SRVBIGCHAR && bType != SRVBIGVARCHAR)
return -1;
file[ulActualLen] = 0;
//
// Update the file's time stamp.
//
char path[288] = "C:\\AspNetSql\\";
lstrcat (path, file);
HANDLE hFile = CreateFile (path, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle (hFile);
return 0;
}
I got this working with using SQL Server 2008 SP3 Dev 64-bit and VS 2012 Ultimate running on Win 7 Pro 64-bit. Here's what I did:
Created a new Empty Project from the VC++templates in VS and added an empty C++ file.
Changed platform to x64 in the Configuration manager.
Changed the Configuration Type to Dynamic library (.dll) under Configuration Properties/General.
Installed the SQL x64 native client including the SQL Server Native Client SDK to get the opends60.lib. I'm not sure the SDK component is actually needed.
Added C:\Program Files\Microsoft SQL Server\90\SDK\Lib\x64 to Additional library directories in the Linker options. This was were the native client was installed.
Added opends60.lib to Additional dependencies in the Linker options.
Compiled without errors.
Created the output directory that the XSP.dll uses: C:\AspNetSql\.
Copied the XSP.dll to the directory created in step 8.
Installed the extended stored procedure using:
USE master
EXEC sp_addextendedproc 'xsp_UpdateSignalFile', 'C:\AspNetSql\XSP.dll'
GRANT EXECUTE ON xsp_UpdateSignalFile TO PUBLIC
Executed it using master..xsp_UpdateSignalFile 'Quotes.Quotations'and verified it worked by confirming that the file Quotes.Quotations was created in the output directory.
If you have any questions or want clarification on any step I can add screenshots or provide more information.

Visual C++ err: RegGetValueA could not be located

Attempting to write a simple registry-check script in Visual Studio 2010, running on XP SP3 x86.
No errs are thrown on build, but on debug the program exits with the following error:
The procedure entry point RegGetValueA
could not be located in the dynamic
link library ADVAPI32.dll
Here is the entire code of the program.
// #define _WIN32_WINNT 0x0501
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[])
{
long reg = RegQueryValueEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", NULL,NULL,NULL,NULL);
// if (reg!=ERROR_SUCCESS) MessageBox(0, "Error Opening Registry Key", "Error", 0);
return 0;
}
The comments in the code above where added based on an answer by wmeyer.
When uncommented, the code does not exit with that error, but throws a different error:
Debugging information for Test5.exe
cannot be found or does not match.
Binary was not built with debug
information. Do you want to continue
debugging?
If I continue, the MessageBox pops up with "Error Opening Registry Key".
I have tried replacing the RegQueryValueEx function with the following three other methods, one at a time.
I KNOW THAT TWO OF THEM ARE VISTA ONLY, but I wanted to see if the error would be different.
It wasn't.
long reg = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, hKey);
// Vista+ PHKEY hKey;
long reg = RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", hKey);
long reg = RegGetValue(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "", RRF_RT_ANY, NULL, NULL,NULL);
I've already lost hours trying to work out several other errors, such as "cannot convert parameter 1 from 'char' to 'LPCWSTR'" - which was solved by changing the configuration
and "Cannot find or open the PDB file", solved by changing the configuration.
So again, the question to be clear:
How do I deal with the error?
How did wmeyer's suggestion of adding a header to filter out Vista-only methods help, when the prog has no Vista methods to begin with? And why does the program still not work?
My computer definitely does have a advapi.dll file in Windows/syatem32.
EDIT:
Completely rewrote the question when the answers pointed out how unclear it was.
Originally I had assumed that Visual Studio 2010 is not backwards compatible with XP.
I've been forcefully told that is incorrect, but still can't get VS to work.
If you want your code to run in XP or an earlier system use RegQueryValueEx.
In any case, you should check the documentation first and then search Google. The Win32 API is very well documented, with details on retrieving data from the registry and supported OS information in every function's page, e.g. RegGetValue is supported in XP 64bit and later.
You should set _WIN32_WINNT to the Windows version you are targeting.
See here: http://msdn.microsoft.com/en-us/library/aa383745(v=vs.85).aspx#setting_winver_or__win32_winnt