no instance of overloaded function "strstr" matches the argument list - c++

E0304 no instance of overloaded function "strstr" matches the argument list
I'm getting this error when try to compile, how can i fix this? post the code cus it's better to understand then photo.
So this is the error that i'm getting i don't have any idea what is causing this and how to fix.
int MakeWindows();
int CloseWindows();
int WINAPI WinMain(_In_HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
HW_PROFILE_INFO hwProfileInfo;
const char* cHWID = "{1234-5678-9669-1337}"; //
if (GetCurrentHwProfile(&hwProfileInfo) != NULL) }
printf("Hardware ID: %s\n", hwProfileInfo.szHwProfileGuid);
if (strstr(hwProfileInfo.szHwProfileGuid, cHWID)) {
printf("Your hardware ID was successful\n\n");
Sleep(3069);
system("CLS");
}
else {
printf("Your Hardware ID was denied;\n");
Sleep(1000);
TerminateProcess(GetCurrentProcess(), NULL);
}
}
else {
return 0;
}
};

strstr wants a char* as its first arg. szHwProfileGuid is going to be a wide string. You need wccstr
So try :
const wcchar* cHWID = L"{1234-5678-9669-1337}";

The problem stems from your project being compiled as Unicode ('wide' characters, usually wchar_t types or defined in Windows as WCHAR), and you also using single-byte characters (char or CHAR), for example in your call to strstr().
(As you're seeing here, the two don't cooperate nicely!)
The Windows API defines two versions of many of its structures (and therefore the respective functions that use them), one to accommodate each character type. In your code example, HW_PROFILE_INFO is actually defined as HW_PROFILE_INFOW for the wide-character version of the API, and you're invoking GetCurrentHwProfileW(). This is fine and by design, since your build is instrumented as a Unicode build.
There are a few ways you could fix this; here's a simple method (your original code with two slight modifications):
int MakeWindows();
int CloseWindows();
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
HW_PROFILE_INFOA hwProfileInfo; // <== Change # 1
const char* cHWID = "{1234-5678-9669-1337}"; //
if (GetCurrentHwProfileA(&hwProfileInfo) != NULL) } // <== Change # 2
printf("Hardware ID: %s\n", hwProfileInfo.szHwProfileGuid);
if (strstr(hwProfileInfo.szHwProfileGuid, cHWID)) {
printf("Your hardware ID was successful\n\n");
Sleep(3069);
system("CLS");
}
else {
printf("Your Hardware ID was denied;\n");
Sleep(1000);
TerminateProcess(GetCurrentProcess(), NULL);
}
}
else {
return 0;
}
};
This set of simple changes has you explicitly using the single-byte versions of the WINAPI functions, keeping your call to strstr() consistent for its two arguments.
(I'll mention again that this is only one way to fix this problem, and the "best" solution may be subjective. :))

Related

WinMain() not receiving enough args if opened by double-clicking the file

I used to be able to double-click files of my custom extension and open it via my C++ exe program (right click-> open with -> my program). The program was correctly receiving args.
Its WinMain() was receiving several args: the first argument was path to exe and the second argument was the path to the clicked file.
However, I no longer seem to be able to receive the second argument, it always launches my program with 1 argument: the path to this program.
Could it be because of the Windows Update I did today? Using Windows 10 and Visual Studio (same happens if compiled in Debug or in Release)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
int nArgs;
LPWSTR *szArglist = CommandLineToArgvW(GetCommandLine(), &nArgs); //GetCommandLine() is a #define located inside processenv.h
//Now nArgs is your argc and szarglist is your argv
//first arg is path to exe, second arg is path to clicked file.
if(nArgs<=1){ LocalFree(szArglist); return EXIT_FAILURE; } //not enough args (1 or less)
LocalFree(szArglist);
return EXIT_SUCCESS;
}
It was because of how I was fetching the arguments.
I was using CommandLineToArgvW(), but when I instead started to use __argv and __argc it started working. Found this answer here
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
if(__argc<=1){ return EXIT_FAILURE; } //not enough args (1 or less)
/*use __argv[1] to fetch your second argument (in my case it's filepath) */
return EXIT_SUCCESS;
}

Get processID using part of WINDOW heading

i use the following program in c++ ,in Visual C++ 6.0, to inform me with message box when the MS Paint program is opened. It uses the exact name of the WINDOW of MS Paint,which is "Untitled - Paint" . However now i need to make the program inform me with message box when i know only a part of the name of the actual WINDOW , for example , if the window is "Abcdefgh - Paint" and i set the string name in this way - std::wstring windowName(L"Paint"); - the program to work again. Using the following 3 rows of code the program works fine when the actual WINDOW name is the exact name of the MS Paint window:
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
But it will not work if the string windowName is just part of the name, i mean if it is "Paint".
Can someone show me how to do this? I thought to take a list of the names of all opened WINDOWS and to compare them with my part of the real name, i mean to search match of the substring "Paint" in their names, but i don't know how to get all opened windows.
Also, this is very important, my computer is old and i am using Visual C++ 6.0, so i can not use all the evolution features of C++ and the program environments nowadays, i mean , i can not use code which is compiled correctly in .NET but does not compiles in Visual C++ 6.0.
Thanks
#include "stdafx.h"
#include < iostream>
#include < string>
#include < windows.h>
#include < sstream>
#include < ctime>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
std::wstring windowName(L"Untitled - Paint");
while(true)
{
Sleep(1000*5);
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
int tday = now->tm_mday;
int tmin = now->tm_min;
int thour = now->tm_hour;
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
char probaintstr[20];
sprintf(probaintstr,"%d",*processID);
if(strlen(probaintstr) <=5 )
{
Sleep(1000*10);
MessageBox(NULL,"niama go Notepad ili Wordpad","zaglavie",MB_OK);
}
else {
}
}
return 0;
}
You can use EnumWindows, for example
BOOL CALLBACK enumWindow(HWND hwnd, LPARAM lp)
{
std::string str(512, 0);
int len = GetWindowText(hwnd, &str[0], str.size());
if (str.find("Paint") != std::string::npos)
{
MessageBox(0, str.c_str(), 0, 0);
}
return true;
}
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
EnumWindows(enumWindow, 0);
return 0;
}
Or you can use FindWindowEx and look for classname. The classname for MS Paint is "MSPaintApp". You can find this information from "Spy" utility for windows.
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
for (HWND hwnd = NULL;;)
{
hwnd = FindWindowExA(NULL, hwnd, "MSPaintApp", 0);
if (!hwnd)
break;
std::string str(512, 0);
int len = GetWindowText(hwnd, &str[0], 512);
str.resize(len);
if (str.find("Paint") != std::string::npos)
MessageBox(0, str.c_str(), 0, 0);
}
return 0;
}
For process id you don't need to allocate memory. Just use a reference:
DWORD processID;
GetWindowThreadProcessId(windowHandle, &processID);

WinMain arguments

My issue is that the arguments are only retrieving the first letter in each of the parameters, for this i do not know why..
Could someone elaborate?
#include <Windows.h>
#include <string>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hpInstance, LPSTR nCmdLine, int iCmdShow){
LPWSTR *szArglist;
int nArgs = 0;
szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
std::string a;
for(int i=0; i<nArgs; i++){
a += (LPCSTR)szArglist[i];
}
MessageBox(NULL, (LPCSTR)a.c_str(), (LPCSTR)a.c_str(), MB_OK);
LocalFree(szArglist);
return 0;
}
I believe the issue lies within CommandLineToArgvW(GetCommandLineW(), &nArgs);
LPWSTR is typedefed to wchar_t *, szArglist is an array of wchar_t *s. A wide character is 2 bytes instead of of 1, so a letter might be represented as:
0x0038 0x0000
However, if you take those bytes and say 'hey, pretend I'm a char *, this looks like a C-string with one letter (0x0038), because the 2nd char (0x0000) is null, which in C style strings represents the end of the string.
The problem you have is that you are trying to fit wide characters (wchar_t) into a non-wide (char) string, which is a much more complicated opperation.
The solution: either use wstring/wchar_t everywhere (corresponding to LPWSTR/LPCWSTR), or use string/char everywhere (corresponding to LPSTR and LPCSTR I believe). Note that your project setting for 'use unicode' should match your decision. Try not to mix these!
Shouldn't this just be
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hpInstance, LPSTR nCmdLine, int iCmdShow)
{
MessageBoxA(NULL, nCmdLine, nCmdLine, MB_OK);
return 0;
}
or
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hpInstance, LPSTR nCmdLine, int iCmdShow)
{
MessageBoxW(NULL, GetCommandLineW(), GetCommandLineW(), MB_OK);
return 0;
}
?

c++ WinApi : GetClientRect fails

I am coding a screensaver program running on Windows.
In preview mode, Windows calls the program this way :
Screensaver.exe /p ParentWindowHandle
However, when I make this call in my program :
BOOL res = GetClientRect(parentWindowHandle, rect)
res is FALSE, rect is NULL and I get ERROR_INVALID_WINDOW_HANDLE with GetLastError()
GetWindowRect gives me the same results.
But, if I make a call to BOOL res = IsWindow(parentWindowHandle) instead, I get res == TRUE. Does this not mean I have a valid window handle ?
The code looks like this :
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
unsigned int handle = GetHandleFromCommandLine(pCmdLine); // Custom function (tested and approved :) )
HWND parentWindowHandle = (HWND) handle;
LPRECT rect = NULL;
BOOL res = GetClientRect(parentWindowHandle, rect);
// here, rect == NULL, res == FALSE and GetLastError() returns ERROR_INVALID_WINDOW_HANDLE
// ...
// ...
}
On 64-bit Windows, a window handle is 64 bits and cannot fit in an unsigned int, so your cast is producing a value that is an invalid window handle. You should modify your GetHandleFromCommandLine function so that it returns a proper HWND, not an unsigned int, and no type cast is necessary.
Also, GetClientRect returns the rectangle by storing it into the value pointed at by the second parameter. If you pass it NULL, it has nowhere to store that, so it will either crash or fail with an invalid parameter error. To avoid that, pass in the address of a local variable:
RECT rect;
GetClientRect(..., &rect);

detect if application running on virtual box

I went thrrough some links in stackoverflow. But code given here doesnt work for virtual box. I have also tried redpill but thats not working too. my application will run on both linux and windows(preferably).
Please let me know if anyone has any solution.
Edit: Preet Sangha's link not working as well
VBox 1.0 uses a different method. Check http://spth.virii.lu/eof2/articles/WarGame/vboxdetect.html
from http://www.gedzac.com/rrlf.dr.eof.eZine/articles/WarGame/vboxdetect.html
Check if the pseudo-device \\.\VBoxMiniRdrDN exists in the system (you need CreateFile())
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if(CreateFile("\\\\.\\VBoxMiniRdrDN",GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL) != INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"VBox detected!","Warning",MB_OK|MB_ICONWARNING);
}
else
{
MessageBox(NULL,"Not inside VBox","Info",MB_OK|MB_ICONINFORMATION);
}
}