I am using UrlToDownloadFile function, but it doesn't download the file. No error shown in compiler (using VStudio 2012)
Here is the code:
#include <Windows.h>
#include "urlmon.h"
#pragma lib "urlmon.lib"
using namespace std;
void dwFile();
int _tmain(int argc, _TCHAR* argv[])
{
dwFile ();
return 0;
}
void dwFile ()
{
LPCSTR url = ("http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf");
LPCSTR fPath = ("C:\\Users\\Andyy\\Desktop\\test\\n3337.pdf");
HRESULT URLDownloadToFile ((NULL, url, fPath, 0, NULL));
}
Your code is not doing any error handling, and your string handling is wrong. Use this instead:
#include <Windows.h>
#include "urlmon.h"
#pragma lib "urlmon.lib"
using namespace std;
void dwFile();
int _tmain(int argc, _TCHAR* argv[])
{
dwFile ();
return 0;
}
void dwFile ()
{
LPCTSTR url = TEXT("http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf");
LPCTSTR fPath = TEXT("C:\\Users\\Andyy\\Desktop\\test\\n3337.pdf");
HRESULT hr = URLDownloadToFile (NULL, url, fPath, 0, NULL);
if (FAILED(hr))
{
// do something ...
}
/* or more preffered:
LPCWSTR url = L"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf";
LPCWSTR fPath = L"C:\\Users\\Andyy\\Desktop\\test\\n3337.pdf");
HRESULT hr = URLDownloadToFileW (NULL, url, fPath, 0, NULL);
if (FAILED(hr))
{
// do something ...
}
*/
}
Do note the following comment in the documentation:
URLDownloadToFile returns S_OK even if the file cannot be created and the download is canceled. If the szFileName parameter contains a file path, ensure that the destination directory exists before calling URLDownloadToFile. For best control over the download and its progress, an IBindStatusCallback interface is recommended.
Related
How control path to pinned application to taskbar with Qt
Since I myself have been searching with a lot of effort for a way to customize the program path to an application pinned to the taskbar, I wanted to post here my solution related to Qt.
Problem was, that I link the starter in a set of programs (starter/updater, main) when pinning the main program.
EventFilterPinnable.h
#pragma once
#include <QAbstractNativeEventFilter>
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#include <propsys.h>
#include <propkey.h>
#include <propvarutil.h>
HRESULT PropertyStoreSetStringValue(IPropertyStore* propertyStore, REFPROPERTYKEY pkey, PCWSTR value)
{
PROPVARIANT propVariant;
HRESULT hr = InitPropVariantFromString(value, &propVariant);
if(SUCCEEDED(hr))
{
hr = propertyStore->SetValue(pkey, propVariant);
PropVariantClear(&propVariant);
}
return hr;
}
HRESULT MakeWindowPinnable(HWND hwnd, PCWSTR userModelId, PCWSTR relaunchCommand, PCWSTR relaunchDisplayName, PCWSTR relaunchIcon = NULL)
{
IPropertyStore* propertyStore;
HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&propertyStore));
if(SUCCEEDED(hr))
{
PropertyStoreSetStringValue(propertyStore, PKEY_AppUserModel_ID, userModelId);
PropertyStoreSetStringValue(propertyStore, PKEY_AppUserModel_RelaunchCommand, relaunchCommand);
PropertyStoreSetStringValue(propertyStore, PKEY_AppUserModel_RelaunchDisplayNameResource, relaunchDisplayName);
if(relaunchIcon != NULL)
{
PropertyStoreSetStringValue(propertyStore, PKEY_AppUserModel_RelaunchIconResource, relaunchIcon);
}
propertyStore->Release();
}
return hr;
}
void OnCreate(HWND hwnd)
{
std::wstring sAppId = L"unique.app.id";
std::wstring sAppRelaunchCommand = L"\"C:\\Program Files\\Path with spaces\\Starter.exe\" -a argument1";
std::wstring sAppRelaunchDisplayName = L"Name of progam";
std::wstring sAppRelaunchIcon = L"\"C:\\Program Files\\Path with spaces\\Icon.ico\"";
MakeWindowPinnable(hwnd, sAppId.c_str(), sAppRelaunchCommand.c_str(), sAppRelaunchDisplayName.c_str(), sAppRelaunchIcon.c_str());
}
class EventFilterPinnable : public QAbstractNativeEventFilter
{
public:
EventFilterPinnable() {}
bool nativeEventFilter(const QByteArray& eventType, void* message, long* /*res*/) override
{
if(eventType == "windows_generic_MSG") {
MSG* msg = static_cast<MSG*>(message);
HWND hwnd = msg->hwnd;
if (msg->message==WM_CREATE)
{
OnCreate(hwnd);
}
}
return false;
}
};
in main.cpp simply add
QApplication app(argc, argv);
app.installNativeEventFilter(new EventFilterPinnable());
....
app.exec();
I recently coded an injector where as long as the dll is in the same directory as the exe injector it will inject but even when the dLL is in the same path it still returns with the error file not found.
Very new to c++ so not exactly sure how to fix it, only this I know that the problem must lie in the dll_name
The c++ code is listed here
#include <Windows.h>
#include <string>
#include <thread>
#include <libloaderapi.h>
using namespace std;
void get_proc_id(const char* window_title, DWORD &process_id)
{
GetWindowThreadProcessId(FindWindow(NULL, window_title), &process_id); // Find Process ID by using title of window
}
void error(const char* error_title, const char* error_message)
{
MessageBox(NULL, error_message, error_title, NULL);
exit(-1);
//if error occurs output false
}
bool file_exists(string file_name) // Makes sure file exists
{
struct stat buffer;
return (stat(file_name.c_str(), &buffer) == 0);
//Information goes through buffer if = 0 , it worked
//Creates random buffer of stat sturc doesnt matter what goes in - making sure function is successful, gets info about file and checks if it workeed
}
int main()
{
DWORD proc_id = NULL;
char dll_path[MAX_PATH];
const char* dll_name = "TestDll2.dll"; //Name of Dll
const char* window_title = "Untitled - Paint"; //Must Match Title Name
if (!file_exists(dll_name));
{
error("file_exists", "File does not exist");
}
if (!GetFullPathName(dll_name, MAX_PATH, dll_path, nullptr))
{
error("GetFullPathName", "Failed to get full file path");
}
get_proc_id(window_title, proc_id);
if (proc_id == NULL)
{
error("get_proc_id", "Failed to get process ID");
}
HANDLE h_process = OpenProcess(PROCESS_ALL_ACCESS, NULL, proc_id);
if (!h_process)
{
error("OpenProcess", "Failed to open handle to process");
}
void* allocated_memory = VirtualAllocEx(h_process, nullptr, MAX_PATH, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); //Calling Virutal Allocation, passing handle to process - reserving memory by going thru reserve and need to commit to it so we can write
if (!allocated_memory)
{
error("VirtualAllocEx", "Failed to allocate memory");
}
if (!WriteProcessMemory(h_process, allocated_memory, dll_path, MAX_PATH, nullptr)) // Write DLL path into the target program
{
error("WriteProcessMemory", "Failed to write process memory");
}
//If above works we call loadlibarya which is where the dll is stored
HANDLE h_thread = CreateRemoteThread(h_process, nullptr, NULL, LPTHREAD_START_ROUTINE(LoadLibraryA), allocated_memory, NULL, nullptr);
if (!h_thread)
{
error("CreateRemoteThread", "Failed to create remote thread");
}
CloseHandle(h_process);
VirtualFreeEx(h_process, allocated_memory, NULL, MEM_RELEASE);
MessageBox(0, "Successfully Injected!", "Sucess", 0);
} ```
Try to use C++ STL function or Windows native API:
#include <string>
#include <filesystem>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
bool IsExists(const std::string &FilePathName)
{
return std::filesystem::exists(FilePathName);
}
bool IsExists(const std::string &FilePathName)
{
return PathFileExistsA(FilePathName.c_str());
}
The file is being searched in the current directory, not in the directory of the exe file. These might not be the same. You have to find the path to the exe file in order to search for files in its directory. On Windows you could do something like this:
#include <psapi.h>
// ....
HANDLE Handle = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, GetCurrentProcessId() );
if ( Handle ) {
TCHAR buffer[MAX_PATH];
if ( GetModuleFileNameEx( Handle, 0, buffer, MAX_PATH ) ) {
std::filesystem::path exePath( buffer ); // TODO this might need encoding conversion
auto exeDir = exePath.parent_path();
auto dllPath = exeDir / "TestDll2.dll";
if ( std::filesystem::exists( dllPath ) ) {
// ...
}
}
}
You can also try GetProcessImageFileName if GetModuleFileNameEx does not work. Apparently it does not work in 32-bit applications on a 64-bit system (see comments in this answer).
I'm trying to get the elements in the desktop (icon shortcuts) using winapi, but for some reason I'm getting nothing. Am I doing it wrong? (I'm very new to this)
BOOL CALLBACK EnumChildWindows(HWND hwnd,LPARAM lParam) {
char str[256];
GetWindowTextA(hwnd, str, 200);
OutputDebugStringA(str);
return true;
}
Inside wWinMain:
HWND hDesktop = GetDesktopWindow();
EnumChildWindows(hDesktop, 0);
You used the EnumChildWindows function by mistake:
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) {
char str[256]{};
GetWindowTextA(hwnd, str, 200);
OutputDebugStringA(str);
return true;
}
int main(int argc, const char* argv[])
{
HWND hDesktop = GetDesktopWindow();
EnumChildWindows(hDesktop, EnumChildProc, 0);
return 0;
}
You need to set a callback function and call it with EnumChildWindows.
Of course, this cannot get the name of the "desktop shortcut", what you get is the name of all child windows.
If you want to get the name and location of the desktop shortcut, you need to use COM related, here is an example:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <ShlObj.h>
#include <atlbase.h>
int main(int argc, char** argv)
{
CComPtr<IShellWindows> spShellWindows;
CComPtr<IShellBrowser> spBrowser;
CComPtr<IDispatch> spDispatch;
CComPtr<IShellView> spShellView;
CComPtr<IFolderView> spView;
CComPtr<IShellFolder> spFolder;
CComPtr<IEnumIDList> spEnum;
CComHeapPtr<ITEMID_CHILD> spidl;
CComVariant vtLoc(CLSID_ShellWindows);
CComVariant vtEmpty;
STRRET str;
int count = 0;
HRESULT hr;
long lhWnd;
// INITIALIZE COM
CoInitialize(NULL);
// GET ShellWindows INTERFACE
hr = spShellWindows.CoCreateInstance(CLSID_ShellWindows);
// FIND WINDOW
hr = spShellWindows->FindWindowSW(
&vtLoc, &vtEmpty, SWC_DESKTOP, &lhWnd, SWFO_NEEDDISPATCH, &spDispatch);
// GET DISPATCH INTERFACE
CComQIPtr<IServiceProvider>(spDispatch)->
QueryService(SID_STopLevelBrowser, IID_PPV_ARGS(&spBrowser));
spBrowser->QueryActiveShellView(&spShellView);
spShellView->QueryInterface(IID_PPV_ARGS(&spView));
hr = spView->GetFolder(IID_PPV_ARGS(&spFolder));
// GET ENUMERATOR
spView->Items(SVGIO_ALLVIEW, IID_PPV_ARGS(&spEnum)); // get enumerator
// ENUMERATE ALL DESKTOP ITEMS
for (; spEnum->Next(1, &spidl, nullptr) == S_OK; spidl.Free()) {
// GET/PRINT ICON NAME AND POSITION
char* name;
POINT pt;
spFolder->GetDisplayNameOf(spidl, SHGDN_NORMAL, &str);
StrRetToStrA(&str, spidl, &name);
spView->GetItemPosition(spidl, &pt);
printf("%5d %5d \"%s\"\n", pt.x, pt.y, name);
}
CoUninitialize(); // release COM
exit(0);
}
I'm having a problem with creating a shortcut using C++.
The .lnk file is created, but the target has a nonsense path.
Can you explain why this code is not creating a correct shortcut? Can someone could help me fix my code?
Here is the code
// RepChrome.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "winnls.h"
#include "shobjidl.h"
#include "objbase.h"
#include "objidl.h"
#include "shlguid.h"
#include <shlobj.h>
HRESULT CreateLink(LPCWSTR lpszPathObj1, LPCSTR lpszPathLink, LPCWSTR lpszDesc,LPCWSTR lpszarg)
{
HRESULT hres;
IShellLink* psl;
// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
// Set the path to the shortcut target and add the description.
psl->SetPath(lpszPathObj1);
psl->SetArguments(lpszarg);
psl->SetDescription(lpszDesc);
// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
// Add code here to check return value from MultiByteWideChar
// for success.
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
return hres;
}
int _tmain(int argc, _TCHAR* argv[])
{
char sp[MAX_PATH] = { 0 };
WCHAR p[MAX_PATH]= { 0 };
WCHAR deskPath[MAX_PATH] = { 0 };
SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, deskPath);
sprintf_s( sp,sizeof(deskPath),"%s\\My Program.lnk",deskPath);
WCHAR path[MAX_PATH] = { 0 };
SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
swprintf_s( p,sizeof(path),L"%s\\My Program\\start.exe",path);
CreateLink(p, sp, L"",L"");
return 0;
}
When calling sprintf_s(), %s expects a char* string, but you are giving it a wchar* string instead. Also, you are passing in the wrong value for the second parameter of sprintf_s() and swprintf_s().
You really should not be using any char data in this code at all, especially since you are just converting it to wchar anyway, so you should use all wchar strings only. Change the lpszPathLink parameter to LPCWSTR, change the sp buffer to WCHAR[], and change sprintf_s() to swprintf_s().
Also, since all of the values you are using for the link are WCHAR anyway, you should use IShellLinkW directly instead of the TCHAR-based IShellLink.
Also, CreateLink() requires CoInitialize/Ex() to have been called beforehand, but it is NOT being called in this code.
Try this instead:
// RepChrome.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "winnls.h"
#include "shobjidl.h"
#include "objbase.h"
#include "objidl.h"
#include "shlguid.h"
#include <shlobj.h>
HRESULT CreateLink(LPCWSTR lpszPathObj1, LPCWSTR lpszPathLink, LPCWSTR lpszDesc, LPCWSTR lpszarg)
{
HRESULT hres;
IShellLinkW* psl;
// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&psl));
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
// Set the path to the shortcut target and add the description.
psl->SetPath(lpszPathObj1);
psl->SetArguments(lpszarg);
psl->SetDescription(lpszDesc);
// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_PPV_ARGS(&ppf));
if (SUCCEEDED(hres))
{
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(lpszPathLink, TRUE);
ppf->Release();
}
psl->Release();
}
return hres;
}
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
WCHAR sp[MAX_PATH] = { 0 };
WCHAR p[MAX_PATH] = { 0 };
WCHAR deskPath[MAX_PATH] = { 0 };
SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, deskPath);
swprintf_s( sp, _countof(sp), L"%s\\My Program.lnk", deskPath);
WCHAR path[MAX_PATH] = { 0 };
SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
swprintf_s( p, _countof(p), L"%s\\My Program\\start.exe", path);
CreateLink(p, sp, L"",L"");
CoUninitialize();
return 0;
}
my Code keeps filling the RAM, if it cant reach the file to download.(network disabled to test)
How can I stop downloading after timeout?
here is the main part for downloading:
int WINAPI WinMain(HINSTANCE instanceHandle, HINSTANCE, char*, int)
{
using namespace std;
std::wstring loadme = targetfolder;
loadme += L"\\filename.txt";
std::wstring url1(L"fileurl");
HRESULT hr1 = URLDownloadToFile(NULL, (url1.c_str()), (loadme.c_str()), 0, NULL); //Download-Start
}
You can use WinINet functions to check if internet is available, check if url link is available, and report progress. Needs "wininet.lib"
WinINet Reference
#include <windows.h>
#include <wininet.h>
#include <fstream>
void geturl(const wchar_t *url)
{
std::ofstream file("c:\\test\\test.htm");
HINTERNET hopen = InternetOpen(L"myAppName",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
if (hopen)
{
HINTERNET hurl = InternetOpenUrl(hopen,url,NULL,0,INTERNET_FLAG_DONT_CACHE,0);
if (hurl)
{
DWORD received;
const int bufsize = 1024;
char buf[bufsize];
while (InternetReadFile(hurl, buf, bufsize, &received))
{
//progress...
if (!received) break;
file.write(buf, received);
}
InternetCloseHandle(hurl);
}
InternetCloseHandle(hopen);
}
}