I've been following a DirectInput tutorial and am having trouble printing a list of DirectInput device product names to a Windows console.
I'm using VS19's C++ compiler and am compiling with UNICODE defined. Since tszProductName is of type TCHAR which resolves to WCHAR I followed this stack overflow answer to allow the windows console to print unicode while also avoiding mixing wcout with cout in the same program.
Before I made those changes nothing was printed. Now the console prints '쳌' repeatedly for each device name. I tried switching from Unicode to Multibyte and going back to cout to no avail. Here is the code in question.
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma comment (lib,"dinput8.lib")
#pragma comment (lib,"dxguid.lib")
#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
#include <locale.h>
#include <clocale>
#include <io.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
IDirectInput8* dev;
std::vector<LPDIRECTINPUTDEVICE8> gameControllers;
BOOL CALLBACK enumGameControllers(LPCDIDEVICEINSTANCE devInst, LPVOID pvRef) {
LPDIRECTINPUTDEVICE8 gameController;
if (FAILED(dev->CreateDevice(devInst->guidInstance, &gameController, NULL)))
return DIENUM_CONTINUE;
else {
gameControllers.push_back(gameController);
return DIENUM_CONTINUE;
}
}
int wmain(int argc, wchar_t* argv[]) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
char* a = setlocale(LC_ALL, "en-US.UTF8");
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
CONSOLE_FONT_INFOEX fontInfo;
fontInfo.cbSize = sizeof(fontInfo);
fontInfo.FontFamily = 20;
fontInfo.FontWeight = 400;
fontInfo.nFont = 0;
const wchar_t myFont[] = L"Lucida Console";
fontInfo.dwFontSize = { 8, 16 };
std::copy(myFont, myFont + _countof(myFont), fontInfo.FaceName);
SetCurrentConsoleFontEx(hConsole, false, &fontInfo);
if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&dev, NULL))) {
std::wcout << L"Critical error: Unable to create the main DirectInput 8 COM object!\n";
return 1;
}
if (FAILED(dev->EnumDevices(DI8DEVCLASS_GAMECTRL, &enumGameControllers, NULL, DIEDFL_ATTACHEDONLY))) {
std::wcout << L"Critical error: Unable to enumerate input devices!\n";
return 1;
}
if (gameControllers.empty()) {
std::wcout << L"No peripherals found\n";
return 1;
}
int count = 1;
std::wcout << L"Number of devices: " << gameControllers.size() << std::endl;
for (LPDIRECTINPUTDEVICE8 i : gameControllers) {
DIDEVICEINSTANCE deviceInfo;
i->GetDeviceInfo(&deviceInfo);
std::wcout << L"Device Number " << count << L": ";
std::wcout << deviceInfo.tszProductName << std::endl;
if (FAILED(i->SetCooperativeLevel(GetConsoleWindow(), DISCL_BACKGROUND | DISCL_EXCLUSIVE))) {
std::wcout << L"Cooperative level could not be set\n";
return 1;
}
++count;
}
return 0;
}
Thanks in advance for any suggestions and/or solutions.
DIDEVICEINSTANCE deviceInfo;
i->GetDeviceInfo(&deviceInfo);
Problems with this code are that:
DIDEVICEINSTANCE::dwSize is not initialized as required, and
the return value of IDirectInputDevice8::GetDeviceInfo is not checked for errors.
Change to the following, instead.
DIDEVICEINSTANCE deviceInfo = { sizeof(DIDEVICEINSTANCE) };
if(i->GetDeviceInfo(&deviceInfo) != DI_OK) { /* call failed, handle error */ }
Related
I am trying to create a simple word highlighter for browsers (Chrome and Firefox) and I would like my program to use the process name (chrome.exe or firefox.exe) and then get their process ID.
I've found code that lets me get the process ID, but it requires a user to type the process name manually:
#include "pch.h"
#include <iostream>
#include <string>
#include <windows.h>
#include <tlhelp32.h>
DWORD FindProcessId(const std::wstring& processName);
int main()
{
std::wstring processName;
std::wcout << "Enter the process name: ";
std::getline(std::wcin, processName);
DWORD processID = FindProcessId(processName);
if (processID == 0)
std::wcout << "Could not find " << processName.c_str() << std::endl;
else
std::wcout << "Process ID is " << processID << std::endl;
system("PAUSE");
return 0;
}
DWORD FindProcessId(const std::wstring& processName)
{
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (processesSnapshot == INVALID_HANDLE_VALUE)
return 0;
Process32First(processesSnapshot, &processInfo);
if (!processName.compare(processInfo.szExeFile))
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while (Process32Next(processesSnapshot, &processInfo))
{
if (!processName.compare(processInfo.szExeFile))
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
Now, is there a way to manipulate this code for it to get the process ID automatically by checking whether the user is running firefox.exe or chrome.exe?
And after getting the process ID, how do I make my program understand that it needs to focus on said ID?
Now, is there a way to manipulate this code for it to get the process ID automatically by checking whether the user is running firefox.exe or chrome.exe?
#include <iostream>
#include <string>
#include <windows.h>
#include <tlhelp32.h>
DWORD FindProcessId(const std::wstring& processName);
int main()
{
std::wstring fifi = L"firefox.exe";
std::wstring gogo = L"chrome.exe";
auto fifi_proc_id = FindProcessId(fifi);
auto gogo_proc_id = FindProcessId(gogo);
if(fifi_proc_id && gogo_proc_id) {
// both runnin O.O what now?
}
else if(fifi_proc_id) {
// firefox running ... do stuff
}
else if(gogo_proc_id) {
// chrome running ... do stuff
}
else {
// none of both :(
}
}
And after getting the process ID, how do I make my program understand that it needs to focus on said ID?
I am sorry, but I don't know what you mean by "make my program understand that it needs to focus on said ID".
My program checks for uppercase letters in German language.
#include <iostream>
#include <boost/algorithm/string/classification.hpp>
#include <boost/locale.hpp>
using namespace std;
int main()
{
locale::global(locale("Germany_german"));
//locale::global(locale("de_DE.UTF-8")); //Also tried "de_DE.UTF-8", but does not work
string str1 = "über";
cout << boolalpha << any_of(str1.begin(), str1.end(), boost::algorithm::is_upper()) << endl;
string str2 = "Ää";
cout << boolalpha << any_of(str2.begin(), str2.end(), boost::algorithm::is_upper()) << endl;
return 0;
}
program crashes with error on console
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
I don't know what that exact locale string is, "de_DE.UTF-8" doesn't work as well.
Is there any way I can get exact locale name strings for all locales supported by OS. May be there is a list somewhere in header files, but I don't see anything <locale> header.
I wrote a program to print all supported locale names.
#include <Windows.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <ostream>
#include <iterator>
using namespace std;
vector<wstring> locals;
BOOL CALLBACK MyFuncLocaleEx(LPWSTR pStr, DWORD dwFlags, LPARAM lparam)
{
locals.push_back(pStr);
return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
EnumSystemLocalesEx(MyFuncLocaleEx, LOCALE_ALL, NULL, NULL);
for (vector<wstring>::const_iterator str = locals.begin(); str != locals.end(); ++str)
wcout << *str << endl;
wcout << "Total " << locals.size() << " locals found." << endl;
return 0;
}
Works great.
...
de
de-AT
de-CH
de-DE
de-DE_phoneb
de-LI
de-LU
...
Total 429 locals found.
#user1 The following might do the same as your elegant code. I can't test it because of the C1189 compiler error.
#include <Winnls.h>
#include <iostream>
#include <ostream>
using namespace std;
int size = 0;
BOOL CALLBACK MyFuncLocaleEx(LPWSTR pStr, DWORD dwFlags, LPARAM lparam) {
size++;
wcout << *pStr << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
EnumSystemLocalesEx(MyFuncLocaleEx, LOCALE_ALL, NULL, NULL);
wcout << "Total " << size << " locales found." << endl;
return 0;
}
I need to open a certain named pipe so I can fuzz test it, however my test code does not have access to the same data used to generate the name of the named pipe. However I can recognize the name of the pipe and then use that name to open up the pipe for fuzzing.
I used this forum post to start enumerating names of the handles on the system:
http://forum.sysinternals.com/howto-enumerate-handles_topic18892.html
However it seems that won't work with named pipes for some reason.
TL;DR: What API(s) do I need to use to list the names of all named pipes in the current process on Windows?
This will enumerate all named pipes in the system, or at the very least put you a step in the right direction.
This works in MinGW when built with -fpermissive. It should work with similar settings in MSVC.
#ifndef _WIN32_WINNT
// Windows XP
#define _WIN32_WINNT 0x0501
#endif
#include <Windows.h>
#include <Psapi.h>
// mycreatepipeex.c is at http://www.davehart.net/remote/PipeEx.c
// I created a simple header based on that.
#include "mycreatepipeex.h"
#include <iostream>
#include <cstdio>
#include <errno.h>
void EnumeratePipes()
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
#define TARGET_PREFIX "//./pipe/"
const char *target = TARGET_PREFIX "*";
memset(&FindFileData, 0, sizeof(FindFileData));
hFind = FindFirstFileA(target, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
std::cerr << "FindFirstFileA() failed: " << GetLastError() << std::endl;
return;
}
else
{
do
{
std::cout << "Pipe: " << TARGET_PREFIX << FindFileData.cFileName << std::endl;
}
while (FindNextFile(hFind, &FindFileData));
FindClose(hFind);
}
#undef TARGET_PREFIX
return;
}
int main(int argc, char**argv)
{
HANDLE read = INVALID_HANDLE_VALUE;
HANDLE write = INVALID_HANDLE_VALUE;
unsigned char pipe_name[MAX_PATH+1];
BOOL success = MyCreatePipeEx(&read, &write, NULL, 0, 0, 0, pipe_name);
EnumeratePipes();
if ( success == FALSE )
{
std::cerr << "MyCreatePipeEx() failed: " << GetLastError() << std::endl;
return 1;
}
FILE *f = fopen((const char*)pipe_name, "rwb");
if ( f == NULL )
{
std::cerr << "fopen(\"" << pipe_name << "\") failed: " << (int)errno << std::endl;
}
CloseHandle(read);
CloseHandle(write);
return 0;
}
So, I've now fought with this for 2 days, still the same error.
I've been on over 300 results with google, still same FAILURE. It shows up as HEX all the time or it doesn't work at all.
This is not using any external librarys and no .net framework.
100% non-dependent.
I've tried over 30 methods.
TCHAR szExeFileName[MAX_PATH];
GetModuleFileName(NULL, szExeFileName, MAX_PATH);
^ Doesn't work; returns hex.
The code is in a void.
#include "SharedHeader.h"
#include <Psapi.h>
#include "CommandLine_Pres.h"
#include <TlHelp32.h>
using namespace std;
void filePath()
{
// Figure out file path of current file
char cCurrentPath[FILENAME_MAX];
if(!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
{
cout << "error" << endl;
}
cCurrentPath[sizeof(cCurrentPath) -1] = '\0';
cout << cCurrentPath << endl;
// Get process id, filename
//cout << GetCommandLine();
int procId = GetCurrentProcessId();
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
/*
DOES NOT WORK BELOW [debug]
HANDLE Handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,GetCurrentProcessId());
if(Handle)
{
TCHAR Buffer[MAX_PATH];
if(GetModuleFileNameEx(Handle, 0, Buffer, MAX_PATH))
{
}
else
{
}
CloseHandle(Handle);
}*/
}
To get the address of the current running process you can use:
#include <iostream>
int main(int argc, char** argv)
{
std::cout << argv[0] << std::endl;
getchar();
return 0;
}
or:
#include <iostream>
#include <windows.h>
int main()
{
char szExeFileName[MAX_PATH];
GetModuleFileName(NULL, szExeFileName, MAX_PATH);
std::cout << szExeFileName;
getchar();
return 0;
}
This is my code:
#include <Windows.h>
#include <ShlObj.h>
#include <iostream>
using namespace std;
int main()
{
LPTSTR myPath = NULL;
SHGetSpecialFolderPath(0, myPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
if(myPath != NULL)
cout << "It returns something" << endl;
else
cout << "It returns nothing" << endl;
system("PAUSE");
return 0;
}
But myPath returns nothing. I just want to obtain the Desktop path. I'm on Windows 7 64 bits.
You need to give it room to put the data into:
T_CHAR myPath[ MAX_PATH ];
SHGetSpecialFolderPath(0, myPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);