Get information about device using SetupAPI - c++

I have a printer connected with USB port and I want to get some information about it. I am using SetupDiEnumDeviceInfo function from setupapi to get information. I am doing everything as it is described in MSDN.
#include <string>
#include <windows.h>
#include <vector>
#include <iostream>
#include <setupapi.h>
#include <winerror.h>
#pragma comment (lib, "SetupAPI.lib")
static GUID GUID_DEVCLASS_PORTS = { 0x4d36e978, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 };
int main()
{
SP_DEVINFO_DATA devInfoData;
HDEVINFO deviceInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, 0, 0, DIGCF_PRESENT);
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DWORD nDevice = 0;
if (SetupDiEnumDeviceInfo(deviceInfo, nDevice, &devInfoData))
{
}
return 0;
}
The problem is that I am always getting false result.
GetLastError() function retruns 259.
What am I doing wrong?

this is my sample. I add the devguid.h, and use GUID_DEVCLASS_USB.
#include <string>
#include <windows.h>
#include <setupapi.h>
#include <devguid.h>
#pragma comment (lib, "SetupAPI.lib")
int main()
{
int res = 0;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData = { sizeof(DeviceInfoData) };
// get device class information handle
hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_USB, 0, 0, DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
res = GetLastError();
return res;
}
// enumerute device information
DWORD required_size = 0;
for (int i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)
{
DWORD DataT;
char friendly_name[2046] = { 0 };
DWORD buffersize = 2046;
DWORD req_bufsize = 0;
// get device description information
if (!SetupDiGetDeviceRegistryPropertyA(hDevInfo, &DeviceInfoData, SPDRP_CLASSGUID, &DataT, (PBYTE)friendly_name, buffersize, &req_bufsize))
{
res = GetLastError();
continue;
}
char temp[512] = { 0 };
sprintf_s(temp, 512, "USB device %d: %s", i, friendly_name);
puts(temp);
}
return 0;
}

Related

ReadProcessMemory always giving 0 when ran! C++

I am writing a cheat for a game that I play sometimes, there is no anticheat. I have the value and pointers and offsets in Cheat Engine.
I have been using stuff from different places, mostly copy paste and put together (this is my first cheat, lagswitching doesn't count).
When I run it, it gives the Module base address + the pointer which was 0x7ff732b3bc80, then I already know the offsets. But the value it reads is 0 from the address 0x7ff732b3bc80 + the offsets 0xC60, 0x68, 0x58, 0x8, 0x0, 0x88, 0x14. I put these into Cheat Engine and receive the results of the value I am looking for, which is the Y coordinate. I will show a picture of that below.
This seems to be from the error 299 that it is not showing up.
Please help, this is not an online game I promise ;). I need to learn somehow.
#ifdef _UNICODE
#ifndef UNICODE
#define UNICODE
#endif
#endif
#include <windows.h>
#include <memory.h>
#include <tlhelp32.h>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32W modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32FirstW(hSnap, &modEntry))
{
do
{
if (!_wcsicmp(modEntry.szModule, modName))
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32NextW(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
DWORD GetProcId()
{
PROCESSENTRY32 pe32;
HANDLE hSnapshot = NULL;
DWORD pid = 0;
pe32.dwSize = sizeof( PROCESSENTRY32 );
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( Process32First( hSnapshot, &pe32 ) )
{
do{
if( strcmp( pe32.szExeFile, "*****.exe" ) == 0 )
{
pid = pe32.th32ProcessID;
break;
}
}while( Process32Next( hSnapshot, &pe32 ) );
}
if( hSnapshot != INVALID_HANDLE_VALUE )
CloseHandle( hSnapshot );
return pid;
}
uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, vector<unsigned int> offsets)
{
uintptr_t addr = ptr;
for (unsigned int i = 0; i < offsets.size(); ++i)
{
ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
addr += offsets[1];
}
return addr;
}
int main()
{
DWORD ProcId = GetProcId();
cout<<ProcId << endl;
float CoordY = 0;
uintptr_t ModuleBase = GetModuleBaseAddress(ProcId, L"****[enter image description here][1].exe");
uintptr_t PointerAddr = ModuleBase + 0x0195BC80;
cout << "DynamicPointerAddress: " << "0x" << hex << PointerAddr << endl;
HANDLE hProcess = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcId);
vector<unsigned int> Offsets = {0xC60, 0x68, 0x58, 0x8, 0x0, 0x88, 0x14};
uintptr_t CoordAddress = FindDMAAddy(hProcess, PointerAddr, Offsets);
ReadProcessMemory(hProcess, (BYTE*)CoordAddress, &CoordY, sizeof(float), nullptr);
cout<<CoordY;
Sleep(10000);
}
And this is what Cheat Engine says:
*Edit 1: Value of the hProcess opening is 0xc0.
**Edit 2: Value of ReadProccessMemory() is 0.
**Edit 3: Thanks to someone in the comment's I have narrowd the error to Error 299 on ReadProcessMemory. If anyone has any way I could fix this please share. I have tried several online methods. And the program I am reading from is 64 bit.
I am running as admin.

InternetOpenUrl Unhandled exception [duplicate]

This is a shortened version of my code:
#include <iostream>
#include <urlmon.h>
#include <wininet.h>
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "wininet.lib")
void data();
void test(std::string received) {
data();
Sleep(1);
}
void data() {
- >>HINTERNET connect = InternetOpen(L"MyBrowser", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET OpenAddress = InternetOpenUrl(connect, L"web page", NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION, 0);
char dataReceived[5000];
std::string received;
DWORD NumberOfBytesRead = 0;
while (InternetReadFile(OpenAddress, dataReceived, 5000, &NumberOfBytesRead) && NumberOfBytesRead)
{
received += std::string(dataReceived);
}
- >>InternetCloseHandle(connect);
InternetCloseHandle(OpenAddress);
test(received);
}
int main() {
data();
}
Please tell me how to normally move the selected lines (- >>) outside the function to run them once?
Change data() and test() to take an HINTERNET as a parameter, and then main() can create the HINTERNET to pass in, eg:
#include <iostream>
#include <urlmon.h>
#include <wininet.h>
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "wininet.lib")
void data(HINTERNET connect);
void test(HINTERNET connect, std::string received) {
data(connect);
Sleep(1);
}
void data(HINTERNET connect) {
HINTERNET OpenAddress = InternetOpenUrl(connect, L"web page", NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION, 0);
char dataReceived[5000];
std::string received;
DWORD NumberOfBytesRead = 0;
while (InternetReadFile(OpenAddress, dataReceived, 5000, &NumberOfBytesRead) && NumberOfBytesRead)
{
received += std::string(dataReceived);
}
InternetCloseHandle(OpenAddress);
test(connect, received);
}
int main() {
HINTERNET connect = InternetOpen(L"MyBrowser", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
data(connect);
InternetCloseHandle(connect);
}

Move HINTERNET connect outside the procedure

This is a shortened version of my code:
#include <iostream>
#include <urlmon.h>
#include <wininet.h>
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "wininet.lib")
void data();
void test(std::string received) {
data();
Sleep(1);
}
void data() {
- >>HINTERNET connect = InternetOpen(L"MyBrowser", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET OpenAddress = InternetOpenUrl(connect, L"web page", NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION, 0);
char dataReceived[5000];
std::string received;
DWORD NumberOfBytesRead = 0;
while (InternetReadFile(OpenAddress, dataReceived, 5000, &NumberOfBytesRead) && NumberOfBytesRead)
{
received += std::string(dataReceived);
}
- >>InternetCloseHandle(connect);
InternetCloseHandle(OpenAddress);
test(received);
}
int main() {
data();
}
Please tell me how to normally move the selected lines (- >>) outside the function to run them once?
Change data() and test() to take an HINTERNET as a parameter, and then main() can create the HINTERNET to pass in, eg:
#include <iostream>
#include <urlmon.h>
#include <wininet.h>
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "wininet.lib")
void data(HINTERNET connect);
void test(HINTERNET connect, std::string received) {
data(connect);
Sleep(1);
}
void data(HINTERNET connect) {
HINTERNET OpenAddress = InternetOpenUrl(connect, L"web page", NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION, 0);
char dataReceived[5000];
std::string received;
DWORD NumberOfBytesRead = 0;
while (InternetReadFile(OpenAddress, dataReceived, 5000, &NumberOfBytesRead) && NumberOfBytesRead)
{
received += std::string(dataReceived);
}
InternetCloseHandle(OpenAddress);
test(connect, received);
}
int main() {
HINTERNET connect = InternetOpen(L"MyBrowser", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
data(connect);
InternetCloseHandle(connect);
}

Get process description

As you know there is some difference between a process name and it's description, for example the dwm.exe process's description is Desktop Window Manager
I can check the name of the processes with this code:
#include <windows.h>
#include <TlHelp32.h>
#include <Winternl.h>
typedef NTSTATUS (NTAPI *NTQUERYINFORMATIONPROCESS)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
int main()
{
PEB Peb = {0};
DWORD dwSize = 0;
DWORD dwPID = 0;
HANDLE hProcess = NULL;
HANDLE hProcessSnap = NULL;
WCHAR PsPath[MAX_PATH] = {0};
WCHAR wszProcName[20] = L"dwm.exe"; //Desktop Window Manager
PROCESSENTRY32 PsEntry32 = {0};
PROCESS_BASIC_INFORMATION PsBasicInfo = {0};
RTL_USER_PROCESS_PARAMETERS RtlUserPsParams = {0};
NTQUERYINFORMATIONPROCESS NtFunction = NULL;
if((hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
PsEntry32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hProcessSnap, &PsEntry32))
{
CloseHandle(hProcessSnap);
return FALSE;
}
do
{
if(lstrcmpiW(PsEntry32.szExeFile, wszProcName) == 0)
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PsEntry32.th32ProcessID);
if(hProcess != INVALID_HANDLE_VALUE)
{
NtFunction = (NTQUERYINFORMATIONPROCESS)GetProcAddress(LoadLibraryW(L"ntdll.dll"), "NtQueryInformationProcess");
if(NtFunction)
{
if(NtFunction(hProcess, ProcessBasicInformation, &PsBasicInfo, sizeof(PROCESS_BASIC_INFORMATION), &dwSize) == ERROR_SUCCESS)
{
ReadProcessMemory(hProcess, PsBasicInfo.PebBaseAddress, &Peb, sizeof(PEB), (SIZE_T*)&dwSize);
ReadProcessMemory(hProcess, Peb.ProcessParameters, &RtlUserPsParams, sizeof(RTL_USER_PROCESS_PARAMETERS), (SIZE_T*)&dwSize);
ReadProcessMemory(hProcess, RtlUserPsParams.ImagePathName.Buffer, PsPath, RtlUserPsParams.ImagePathName.Length, (SIZE_T*)&dwSize);
dwPID = PsEntry32.th32ProcessID;
}
}
CloseHandle(hProcess);
}
}
}while(Process32Next(hProcessSnap, &PsEntry32));
CloseHandle(hProcessSnap);
}
return 0;
}
now I want to check the processes description
Is it possible to get all processes description one by one and check them?
I use ToolHelp32Snapshot() to get the module path instead of your PEB method, following that I:
GetFileVersionInfoSizeA() to get the size of the version structure
GetFileVersionInfoA() to pull the data from that structure into a local char array.
VerQueryValue() with "\VarFileInfo\Translation" to get the language code pages
Then I loop through the different language code pages to create the subblock string required for the next query.
Then I use VerQueryValue() with the correct language code page inserted inside the sub block and store the result into another char array.
Then we print this string to console.
#include <iostream>
#include <string>
#include <Windows.h>
#include <TlHelp32.h>
#include <strsafe.h>
#pragma comment(lib,"Version.lib")
std::string GetModulePath(std::string moduleName, DWORD procId)
{
std::string path;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry{};
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (!_stricmp(modEntry.szModule, moduleName.c_str()))
{
path = modEntry.szExePath;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return path;
}
std::string GetFilePath(std::string procName)
{
std::string path;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_stricmp(procEntry.szExeFile, procName.c_str()))
{
path = GetModulePath(procName, procEntry.th32ProcessID);
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return path;
}
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
};
int main()
{
std::string path = GetFilePath("notepad++.exe");
DWORD verSize = GetFileVersionInfoSizeA(path.c_str(), 0);
char* data = new char[verSize]{ 0 };
GetFileVersionInfoA(path.c_str(), 0, verSize, data);
UINT length;
LANGANDCODEPAGE* lpTranslate;
VerQueryValue(data, "\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &length);
char SubBlock[50]{ 0 };
for (unsigned int i = 0; i < (length / sizeof(struct LANGANDCODEPAGE)); i++)
{
HRESULT result = StringCchPrintf(SubBlock, 50,
TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
char* description = new char[0x100]{ 0 };
UINT length2;
VerQueryValue(data, SubBlock, (LPVOID*)&description, &length2);
std::cout << description << "\n";
}
getchar();
return 0;
}
Must run as administrator, and only tested on x86.

Hwid to clipboard

So this is what i am trying todo i am trying to copy serial number to clipboard but it doesnt work is there anything i did wrong if yes then plz help me i would like to have this working becouse its something for a project of me that i am selling
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include "windows.h"
namespace std {}
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR volumeName[MAX_PATH + 1] = { 0 };
TCHAR fileSystemName[MAX_PATH + 1] = { 0 };
DWORD serialNumber = 0;
DWORD maxComponentLen = 0;
DWORD fileSystemFlags = 0;
if (GetVolumeInformation(
_T("C:\\"),
volumeName,
ARRAYSIZE(volumeName),
& serialNumber,
& maxComponentLen,
& fileSystemFlags,
fileSystemName,
ARRAYSIZE(fileSystemName)))
{
_tprintf(_T("Serial Number: %lu\n"), serialNumber);
GlobalUnlock(GetVolumeInformation);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(1, GetVolumeInformation);
CloseClipboard();
MessageBoxA(NULL, "HWID COPYED.", "HWID", NULL);
std::cout << std::endl << "Press any key to continue...";
getchar();
}
}
You should avoid using the T macros (the macros starting with _T and _t). Microsoft still uses these macros in some of its documentations for historical reasons, but it's useless and confusing. I don't know if you are using ANSI or Unicode (Unicode is recommended).
If you only need the serial number from GetVolumeInformation then you can set the other variables to NULL, see documentation.
Once you get the serial number, convert it to text. Then copy the text to clipboard. Below is ANSI example:
void copy(const char* text)
{
int len = strlen(text) + 1;
HGLOBAL hmem = GlobalAlloc(GMEM_MOVEABLE, len);
char* buffer = (char*)GlobalLock(hmem);
strcpy_s(buffer, len, text);
GlobalUnlock(hmem);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_TEXT, hmem);
CloseClipboard();
}
int _tmain()
{
DWORD serialNumber = 0;
if (GetVolumeInformation(
_T("C:\\"),
NULL,
0,
&serialNumber,
NULL,
0,
NULL,
0))
{
std::cout << serialNumber << std::endl;
char buf[100];
sprintf_s(buf, 100, "%d", serialNumber);
copy(buf);
MessageBoxA(NULL, buf, "HWID", NULL);
}
return 0;
}