Linker issue with EnumPrinters Sample - c++

First of all, I understand there are many topics on this function, but I did not find any about this particular problem, sorry if I am repeating...
I have been working on a program in C++ that works with printers and I need to get the list of printers in the system.
I am using the EnumPrinters API and I am getting a compile error I don't understand.
This is my code:
#include <iostream>
#include <windows.h>
#include <winspool.h>
using namespace std;
int main()
{
PRINTER_INFO_5 pi;
PBYTE buffer[99];
DWORD bufferSize = 0;
DWORD bufferNeeded = 0;
DWORD Entries = 0;
bool r;
r = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 5, NULL, bufferSize, &bufferNeeded, &Entries);
if (!r)
{ cout << "No printer found" << endl; }
else { cout << "Found printers" << endl; }
}
When I try to compile (codeBlocks typical installation w/ gcc), I get this error:
C:\Programação\C++\lab\main.cpp 18 undefined reference to 'EnumPrintersA#28'
I think this may be a linker problem, but I don't know how to solve it...
Thank you!
SOLVED!
After some help I found out that the problem was that I wasn't importing the correct library. I thought including the header would be enough.
I needed to follow these steps (using 'winspool' instead of 'gdi32').
By the way, adding 'winspool.lib' did not solve it. Use 'winspool' instead (no '.lib')

Your linker is missing a .lib-file. If you lookup EnumPrinters at the MSDN documentation, you will see which library you have to add (somewhere at the bottom of the page, right before the comments).
In this case it's Winspool.lib. For gcc, add the commandline option: -lwinspool.

Related

C++ recursive_directory_iterator miss some files

I'm trying to get all files in directory through c++17 on my visual studio 2017 but I've just encountered a really weird problem. If I specify directory like this I can get all files without any problem:
for (auto& p : std::filesystem::recursive_directory_iterator("C:\\Users\\r00t\\AppData\\Roaming\\Mozilla")) {
if (std::filesystem::is_regular_file(p.path())) {
std::cout << p.path() << std::endl;
}
}
But I need all file list on APPDATA, and I'm trying to get path with getenv() function and when using it "recursive_directory_iterator" function skipping files:
for (auto& p : std::filesystem::recursive_directory_iterator(getenv("APPDATA"))) {
if (std::filesystem::is_regular_file(p.path())) {
std::cout << p.path() << std::endl;
}
}
Is that because of using getenv() function? Some folders that skipping when using getenv;
Mozilla
TeamWiever
NVIDIA
and so on ..
Btw, I'm using C++ last 5 days and definitely don't have any clue what causes for that behavior. Please help me, right now I'm stuck.
EDIT :
for (auto& p : std::filesystem::directory_iterator(getenv("APPDATA"))) {
std::string targetFolder = p.path().string();
for (auto& targetFolderFiles : std::filesystem::recursive_directory_iterator(targetFolder)) {
if (std::filesystem::is_regular_file(targetFolderFiles.path())) {
std::cout << targetFolderFiles.path() << std::endl;
}
}
}
This is also not working, seems like i must put string into function like this:
recursive_directory_iterator("C:\\Users\\r00t\\AppData\\Roaming\\Mozilla")
otherwise definitely not working, LOL ??
EDIT - PROBLEM FIXED
Using experimental library is working with C++14 compiler like as expected.
#include <experimental/filesystem>
Now i can able to get all files without problem.Seems like this is problem about C++17 and filesystem library ..
Thanks for all support guys.
getenv() returns a char* or NULL. <filesystem> is probably operating with wchar_t* strings since you are on Windows. Use SHGetKnownFolderPath(...) to query for where special folders are.
What happens when you run your program is probably that you hit some character that can't be displayed with your current locale ("C" if not set explicitly) so it sets your outstream in fail mode. You can however set your locale to UTF-16LE to remedy this. It works with /std:c++17 and the standard <filesystem> header:
#include <Shlobj.h> // SHGetKnownFolderPath
#include <clocale> // std::setlocale
#include <io.h> // _setmode
#include <fcntl.h> // _O_U16TEXT
Code Page Identifiers
const char CP_UTF_16LE[] = ".1200";
setlocale(LC_ALL, CP_UTF_16LE);
_setmode
_setmode(_fileno(stdout), _O_U16TEXT);
With that in place, the path you get from SHGetKnownFolderPath should work:
PWSTR the_path;
if(SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT, NULL, &the_path) == S_OK) {
for(auto& p : std::filesystem::recursive_directory_iterator(the_path)) {
std::wcout << p.path() << L"\n";
// you can also detect if the outstream is in fail mode:
if (std::wcout.fail()) {
std::wcout.clear(); // ... and clear the fail mode
std::wcout << L" (wcout was fail mode)\n";
}
}
CoTaskMemFree(the_path);
}
You may also find the list of Default Known Folders in Windows useful.

Readprocessmemory in C++ won't read

I have been coding for a few years now, but in 2016 I took a couple years off. Now I decided to come back, so I wanted to play around with some reverse engineering.
I played around with a game called Black Ops 1: Zombies. I found the memory addresses, then I went into C++ to code a simple cheat for unlimited ammo (This is offline), but it didn't work, so tried using ReadProcessMemory instead to see if it gives the correct ammo. The console started printing out "0". I thought there might been something with the code so I looked up some of my older source code, and the code was the same, tried installing VS 2015 instead in case the compiler is the problem, still nothing, tried GNCC compiler, still nothing. Tried using it on my second computer and it worked. I tried disabling Anti-Virus and windows defender but still nothing.
Here is the source code if it means anything:
#include <iostream>
#include <Windows.h>
using namespace std;
DWORD Address = 0x180A6C8;
DWORD pID;
int points;
int main()
{
while (true)
{
HWND hWnd = FindWindowA(0, ("Call of Duty®: BlackOps"));
GetWindowThreadProcessId(hWnd, &pID);
HANDLE pHandle = OpenProcess(PROCESS_VM_READ, FALSE, pID);
ReadProcessMemory(pHandle, (LPVOID)Address, &points, sizeof(points), 0);
cout << points << endl;
Sleep(100);
}
}
A.) Can you read the Address in Cheat Engine etc
B.) Does it require a base address (e.g "client.dll")? If so get the module base address of the required module.

Console Printing of string and wstring in C++

I can see there are many questions related to strings and wide strings. But as none of them gives me information I am looking for... I am posting a new question.
I have this code...
std::string myName("vikrant");
std::cout<<myName<<std::endl;
std::wstring myNameHindi = L"मुरुगन";
std::wcout<<myNameHindi<<"-----"<<myNameHindi.size()<<std::endl;
std::wcout<<L"मुरुगन"<<std::endl;
std::string myNameHindiS = "मुरुगन";
std::cout<<myNameHindiS<<"-----"<<myNameHindiS.size()<<std::endl;
when I compile & run this code on my RHEL box(... (connected through ssh, running gcc 4.1.2) I get this o/p (please note middle two lines are not printing properly)
vikrant
.A0A(-----6
.A0A(
मुरुगन-----18
While on my apple laptop and one of FreeBSD(through ssh) box I dont get o/p from w_* code. I just get first and last cout executed
vikrant
मुरुगन-----18
My understanding was that if not specified these strings will be treated as UTF 8. and if string can handle it wstring will handle as well. Is there something wrong in that approach?
Some addon questions are...
is it just a display problem? or wstring is not reliable on linux?
Any additional information may help as well.
EASIEST WAY
Here is what are you looking for, #include <clocale> and for example, to have Turkish, just simply type setlocale(LC_ALL,"Turkish"); to your code.
You can also just leave it as setlocale(LC_ALL,""); it will use your local language.
#include <iostream>
#include <clocale>
int main(){
setlocale(LC_ALL,"Turkish");
std::cout << "I can type any Turkish character like ÖöÇ窺İiĞğÜüİ, anything.\n" << std::endl;
system("pause");
return 0;
}
SOME OTHER WEIRD WAY TO DO IT
This is a really weird way to do it but it will also work.
#include <iostream>
int main()
{
std::string characters="IiĞğÇçÜüŞşÖö";
int i;
for ( i=0; i<characters.length(); ++i ){
characters[i]=(characters[i]==-2) ? 159:characters[i]; //ş
characters[i]=(characters[i]==-3) ? 141:characters[i]; //ı
characters[i]=(characters[i]==-4) ? 129:characters[i]; //ü
characters[i]=(characters[i]==-10) ? 148:characters[i]; //ö
characters[i]=(characters[i]==-16) ? 167:characters[i]; //ğ
characters[i]=(characters[i]==-25) ? 135:characters[i]; //ç
characters[i]=(characters[i]==-34) ? 158:characters[i]; //Ş
characters[i]=(characters[i]==-35) ? 152:characters[i]; //İ
characters[i]=(characters[i]==-36) ? 154:characters[i]; //Ü
characters[i]=(characters[i]==-42) ? 153:characters[i]; //Ö
characters[i]=(characters[i]==-48) ? 166:characters[i]; //Ğ
characters[i]=(characters[i]==-57) ? 128:characters[i]; //Ç
std::cout << characters[i] << " ";
}
}

In Embedded Octave C++ how do I execute a script file? ("error: invalid call to script")

I am writing a c++ oct-file that I would like to use as a link between my c++ code and scripts that were written in Octave. I can build and execute with no problems, and as long as I am doing simple things, it seems to work. I can even call functions in a script file with feval()! I just can't seem to figure out how to execute an entire script file..
If I try this simple program, I get an error, but I'm not sure why
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/toplev.h> // for do_octave_atexit
#include <iostream>
#include <string>
using namespace std;
void runscript(const string &file) {
cout << "attempting to run: " << file << endl;
int parse_status = 0;
eval_string(file, false, parse_status);
cout << "parse_status: " << parse_status << endl;
eval_string(file, false, parse_status, 0); // I'm not sure what the difference here is or
// what the value 0 means, I can't find any documentation on
// what `hargout` is.. See Note {1} below
cout << "parse_status: " << parse_status << endl;
}
int main(int argc, char **argv) {
// Set-up
char *oct_argv[3] = {(char*)"embedded", (char*)"-q", (char*)"--interactive"};
octave_main(3, oct_argv, true);
// Attempt to run script
runscript("Script1");
runscript("Script1.m");
// `a` should be defined after running Script1.m..
octave_value_list a = get_top_level_value("a", false);
do_octave_atexit ();
return 0;
}
Script1.m is very simple and looks like this:
a = 1000;
a
When I run, I always get this output:
attempting to run: Script1
error: invalid call to script /Users/Daly/Documents/School/EECS/Labs/GitHub/deep/Octave/ Script1.m
parse_status: 0
parse_status: 0
attempting to run: Script1.m
parse_status: 0
parse_status: 0
error: get_top_level_value: undefined symbol 'a'
It only ever complains about the invalid call the first time, no matter how many times I try to eval_string or in what order.
Notes: {1} After searching for error: invalid call to script, I found this source code which at line 00155 raises this exact error if nargout isn't 0, so I thought they might be related?
But anyway, maybe this isn't the right way to be going about it. What is the correct way to execute an entire octave script from an octave-embedded c++ program? Thanks!
You should be using the function source_file() rather than eval_string(). Take a look into the parser.h file which unfortunately doesn't have a lot of comments. The names are quite self-explanatory so you shouldn't have a lot of problems.
Also, you're pretty much trying to reimplement Octave's source function. If you really want to implement it again, look into the oct-parse.cc file (generated during the build process with flex and bison).

SystemParametersInfo returns 0

#include <iostream>
#include <windows.h>
using namespace std;
int main(){
LPWSTR test = L"C:/aizen.png";
int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, test, SPIF_UPDATEINIFILE);
if(result)
cout << "Wallpaper set!";
else
cout << "NOOOOO!" << result;
cin >> result;
return 0;
}
Very simple code, but result returns 0. What am I doing wrong?
Do what the documentation says, and call GetLastError to find out the reason behind the error.
Some possible causes spring to mind:
SystemParametersInfo does not like forward slashes as separators.
The system doesn't like .png files for wallpaper.
The file doesn't exist.
You have an ANSI/Unicode encoding mismatch.
You don't have rights to modify the wallpaper.
Really, the list is endless. So let the system tell you.
Note that the documentation says:
When the SPI_SETDESKWALLPAPER flag is used, SystemParametersInfo always returns TRUE.
But this is a great big fat lie. It's trivially easy to call the function, pass SPI_SETDESKWALLPAPER, and receive FALSE in return.
Don't know with the information we have.
This return value indicates that the call failed. You'll need to call GetLastError() for information about why.