SetupDiEnumDeviceInterfaces error 259 for display - c++

I am trying to retrieve a set of display related interfaces and seem always to get the 259 error. Since I am very unexperienced with WinApi I could need some hints :)
#include <atlstr.h>
#include <SetupApi.h>
#pragma comment(lib, "setupapi.lib")
#include <stdio.h>
#include <windows.h>
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>
const GUID GUID_CLASS_MONITOR = {0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18};
const GUID GUID_DEVINTERFACE_MONITOR = {0xe6f07b5f, 0xee97, 0x4a90, 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7};
int main( int argc, char *argv[ ] )
{
HDEVINFO hDevInfo;
SP_DEVICE_INTERFACE_DATA ifData;
ifData.cbSize = sizeof(ifData);
DWORD dwError;
hDevInfo = SetupDiGetClassDevs(NULL /*&GUID_CLASS_MONITOR*/, NULL, NULL, DIGCF_ALLCLASSES);
dwError = GetLastError();
BOOL bRtn = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_CLASS_MONITOR, 0, &ifData); // GUID_DEVINTERFACE_MONITOR did not work either
dwError = GetLastError();
return 0;
}
I cannot see what I am doing wrong SetupDiGetClassDevs has no errors but everything I try regarding SetupDiEnumDeviceInterfaces returns 259.
I've been trying both device setup as well the device interface GUID with no luck.
Edit: Clarification: bRtn returns 0 which means that SetupDiEnumDeviceInterfaces has failed. The 259 error means no more items but my system has two screens attached and since I am calling SetupDiGetClassDevs with no GUID I have expected to get at least my two screen items.
Edit: Added cbSize as suggested

Do you know that ifData.cbSize must be set properly before you call SetupDiEnumDeviceInterfaces?
(http://msdn.microsoft.com/en-us/library/windows/hardware/ff551015(v=vs.85).aspx)
The caller must set DeviceInterfaceData.cbSize to sizeof(SP_DEVICE_INTERFACE_DATA) before calling this function.
(http://msdn.microsoft.com/en-us/library/windows/hardware/ff552342(v=vs.85).aspx)
A SetupAPI function that takes an instance of the SP_DEVICE_INTERFACE_DATA structure as a parameter verifies whether the cbSize member of the supplied structure is equal to the size, in bytes, of the structure.
You did not show setting this value in your code.

For some reason the answer I found by try and error is not intuitive for me but it seems to work.
As I am unable to retrieve the device setup GUID but I had to add DIGCF_DEVICEINTERFACE with conjunction to device interface GUID GUID_DEVINTERFACE_MONITOR to be able to retrieve the interfaces.
Thanks for the hints as missing cbSize would have resulted in another error too :/

Related

How to compile and link a minimal .NET C++ program using mingw

I'm trying to compile a minimal example of .NET C++ code (just calling CLRCreateInstance and starting a CLR runtime host). I'm not using Visual Studio, but mingw. I installed the Windows 10 SDK with .NET goodies, and I have the header and lib files correctly installed in Program Files. However, I cannot get g++ to link my program:
$ g++ -o clr.exe -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Include\um" -L"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Lib\um\x64" -lmscoree clr.cpp
C:\Users\XXX\AppData\Local\Temp\cciBbZmZ.o:clr.cpp:(.text+0x3d): undefined reference to `_GUID const& __mingw_uuidof<ICLRMetaHost>()'
C:\Users\XXX\AppData\Local\Temp\cciBbZmZ.o:clr.cpp:(.text+0x4f): undefined reference to `CLRCreateInstance'
C:\Users\XXX\AppData\Local\Temp\cciBbZmZ.o:clr.cpp:(.text+0x78): undefined reference to `_GUID const& __mingw_uuidof<ICLRRuntimeInfo>()'
C:\Users\XXX\AppData\Local\Temp\cciBbZmZ.o:clr.cpp:(.text+0xb3): undefined reference to `_GUID const& __mingw_uuidof<ICLRRuntimeHost>()'
collect2.exe: error: ld returned 1 exit status
the program is:
#include <iostream>
#include <Windows.h>
#include <metahost.h>
#include <mscoree.h>
#pragma comment(lib, "mscoree.lib")
int main()
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
// build runtime
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
IID_PPV_ARGS(&pClrRuntimeHost));
// start runtime
hr = pClrRuntimeHost->Start();
hr = pClrRuntimeHost->Stop();
}
I finally made it work with the following two corrections:
I switched from vanilla MinGW to an msys2 packaged one. This solved the undefined reference to CLRCreateInstance, which I don't know why was failing with the vanilla MinGW. This basically consisted in downloading msys2 and running pacman -S mingw-w64-x86_64-gcc.
Thanks to this question I was able to solve the other three undefined references. I'm still not sure how all these COM things work, so unfortunately I'm not sure if this is the right way to solve the problem, or if I just introduced a fatal error but well... I went into mscoree.h and metahost.h in .NET SDK install dir, and looked for the things the linker was complaining about.
For example, in mscoree.h I found:
EXTERN_GUID(IID_ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);
so I went to my clr.cpp file and added:
__CRT_UUID_DECL(ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);
which seems to work just fine. Did the same for the other two, and my code got into this, which compiled and run without errors:
#include <Windows.h>
#include <metahost.h>
#include <mscoree.h>
#include <cstdio>
__CRT_UUID_DECL(ICLRMetaHost, 0xD332DB9E, 0xB9B3, 0x4125, 0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16);
__CRT_UUID_DECL(ICLRRuntimeInfo, 0xBD39D1D2, 0xBA2F, 0x486a, 0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91);
__CRT_UUID_DECL(ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);
int main(int argc, char *argv[])
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
// build runtime
if (CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost)) != S_OK) {
printf("[x] Error: CLRCreateInstance(..)\n");
return 2;
}
if (pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo)) != S_OK) {
printf("[x] Error: GetRuntime(..)\n");
return 2;
}
if (pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pClrRuntimeHost)) != S_OK) {
printf("[x] Error: GetInterface(..)\n");
return 2;
}
// start runtime
if (pClrRuntimeHost->Start() != S_OK) {
printf("[x] Error: Start(..)\n");
return 2;
}
// start runtime
if (pClrRuntimeHost->Stop() != S_OK) {
printf("[x] Error: Stop(..)\n");
return 2;
}
printf("success!\n");
return 0;
}

Some Service interface are not supported in the MFGetService helper function

I'm trying to get a pointer to the IDirect3DSurface9 and I use the the helper function MFGetService and I pass MR_BUFFER_SERVICE to the second parameter.While linking,I received a "unresolved external symbol _MR_BUFFER_SERVICE" error.
I looked up the definition of MR_BUFFER_SERVICE in evr.h and found a macro describing it:
DEFINE_GUID(MR_BUFFER_SERVICE,
0xa562248c,
0x9ac6,
0x4ffc,
0x9f, 0xba, 0x3a, 0xf8, 0xf8, 0xad, 0x1a, 0x4d
);
And then I decided to make this GUID on my own and passed to the MFGetService, but then I get the error code E_NOINTERFACE while debugging.
//Here are the GUID struct I made:
const GUID FAR MR_BUFFER_SERVICE = { 0xa562248c,0x9ac6,0x4ffc, {0x9f, 0xba, 0x3a, 0xf8, 0xf8, 0xad, 0x1a, 0x4d} };
//The main code of getting a pointer to IDirect3DSurface9:
IDirect3DSurface9 *d3dsurface9;
IMFMediaBuffer* pBuffer = NULL;
hr = MFCreateMemoryBuffer(1024 * 10, &pBuffer);
if (FAILED(hr))
{
MessageBox(NULL, L"fail in creating Media Buffer", NULL, NULL);
}
hr = MFGetService(pBuffer, MR_BUFFER_SERVICE,
IID_PPV_ARGS(&d3dsurface9));
if (FAILED(hr))
{
MessageBox(NULL, L"failed in getting IDirect3DSurface9", NULL, NULL);
}
Linker error is to be resolved by additionally linking strmiids.lib
#pragma comment(lib, "strmiids.lib")
MR_BUFFER_SERVICE is not available from generic system memory backed buffers you create by MFCreateMemoryBuffer. This service is only available from buffers which are wrapping respective D3D9 surface, esp. created with MFCreateDXSurfaceBuffer function.
The details are documented here: DirectX Surface Buffer.

Finding and replacing pattern in memory

I've been struggling with this for the better part of a day, rewriting every which way and referencing documentation and even other people's code, but no matter what I do, I can't seem to get my code to work.
A thread in my process is attempting to search the memory of another thread. I'm looking to fix something in a specific module, but I'm furthermore not sure how to or if it's worth narrowing down my search, so right now it's just searching the entire process--and possibly itself? Who knows?
Whenever I latch on a debugger, I can find this set of bytes just fine (equivalent to mov rsi, rax; test dil, 1; jz short loc_...), but for the life of me I can't at all seem to find it.
I found that I did rarely find it, which definitely means that for some reason my search appears to be accessing... well, irrelevant things, and probably finding this purely by chance. I've absorbed so many names and concepts in a single day I think it just isn't sitting right in my head. What's going wrong here?
Addon.cpp
#include <iostream>
#include "Addon.h"
#include <sstream>
#include <vector>
int pattern[] = { 0x48, 0x8B, 0xF0, 0x40, 0xF6, 0xC7, 0x01, 0x74, 0x3E };
int replace[] = { 0x48, 0x8B, 0xF0, 0x40, 0xF6, 0xC7, 0x00, 0x75, 0x3E };
DWORD WINAPI background(LPVOID lpParam)
{
HANDLE h = GetCurrentProcess();
while (true) //for now
{
MEMORY_BASIC_INFORMATION mbi;
unsigned char* p = NULL;
for (p = NULL; VirtualQueryEx(h, p, &mbi, sizeof(mbi)) == sizeof(mbi); p += mbi.RegionSize)
{
std::vector<char> buffer;
if (mbi.State == MEM_COMMIT && mbi.Type == MEM_MAPPED || mbi.Type == MEM_PRIVATE)
{
SIZE_T bytes_read;
buffer.resize(mbi.RegionSize);
ReadProcessMemory(h, p, &buffer[0], mbi.RegionSize, &bytes_read);
buffer.resize(bytes_read);
}
std::vector<char> new_tail(buffer.end() - 9, buffer.end());
for (char t : old_tail)
buffer.push_back(t);
old_tail = new_tail;
if (std::search(buffer.begin(), buffer.end(), std::begin(pattern), std::end(pattern) != buffer.end())
{
MessageBoxA(NULL, "Found", "Found", NULL);
}
}
}
return 0;
}
Added other files on request.
Addon.h
#pragma once
#include <iostream>
#include "windows.h"
#ifdef ADDON_EXPORTS
#define ADDON_API __declspec(dllexport)
#else
#define ADDON_API __declspec(dllimport)
#endif
DWORD WINAPI background(LPVOID lpParam);
dllmain.cpp
#include "windows.h"
#include <string>
#include <tchar.h>
#include "Addon.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DWORD thread;
CreateThread(NULL, 0, background, 0, 0, &thread);
if (thread == NULL)
{
MessageBoxA(NULL, "Failed to start crash fix", "Error", MB_ICONERROR);
}
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
The problem was in the definition of pattern (and replace). It was defined as int, whereas it should be char. As Ted Lyngmo said, 'sometimes the answer stares you right in the good eye.'

Why CoCreateInstance can't create an instance of my component?

I am learning COM through the book "Inside COM" of Dale Rogerson. I try to register my component in the registry and then through this info create an instance of my component in the code of my client. But I see ::FormatMessage function writes this: Class not registered. So, ::CoCreateInstance can't create an instance of my component.
My REG-file:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\CLSID\{68584B56-9224-4DCC-AD35-1070CC9B8FDE}]
#="bush_component_01"
[HKEY_CLASSES_ROOT\CLSID\{68584B56-9224-4DCC-AD35-1070CC9B8FDE}\InprocServer32]
#="D:\\projects\\com_sandbox_solution_01\\Debug\\bush_component_01.dll"
[HKEY_CLASSES_ROOT\CLSID\{EB4BFC91-6A6E-43D1-B4CD-7A5DF24DB8D8}]
#="IID_IX"
[HKEY_CLASSES_ROOT\CLSID\{EB4BFC91-6A6E-43D1-B4CD-7A5DF24DB8D8}\InprocServer32]
#="D:\\projects\\com_sandbox_solution_01\\Debug\\bush_component_01.dll"
Piece of code of my client:
...
// GUID of my DLL (it registered in registry (look at my REG-code above))
// {68584B56-9224-4DCC-AD35-1070CC9B8FDE}
static const CLSID CLSID_component_01 =
{ 0x68584b56, 0x9224, 0x4dcc, { 0xad, 0x35, 0x10, 0x70, 0xcc, 0x9b, 0x8f, 0xde } };
// GUID of my some interface (it registered in registry (look at my REG-code above))
// {EB4BFC91-6A6E-43D1-B4CD-7A5DF24DB8D8}
static const IID IID_IX =
{ 0xeb4bfc91, 0x6a6e, 0x43d1, { 0xb4, 0xcd, 0x7a, 0x5d, 0xf2, 0x4d, 0xb8, 0xd8 } };
...
// Code of my client:
::CoInitialize(nullptr);
IUnknown* comp = nullptr;
HRESULT hcri = ::CoCreateInstance(CLSID_component_01, nullptr,
CLSCTX_INPROC_SERVER, IID_IX, (void**)&comp);
if (FAILED(hcri)){
void* msg = nullptr;
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr, hcri, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0,
nullptr);
trace("***** TRACE *****");
trace((LPTSTR)msg);
trace("****************");
keep_window_open();
return 1;
}
// But ::FormatMessage function writes this: Class not registered
Why does it happen?
In 64-bit Windows 32-bit applications should use Wow6432Node registry subkey (in terms of 64-bit regedit).
Unfortunately 32-bit book does not cover that.

How to use windows DLL (late bound) methods in C++?

I've basically been trying to get this working for the last couple of days, but all of my attempts and all the examples/suggestions found online have failed. I'm trying to use Microsoft's "setupapi.dll" methods in implementing my own .dll to access a peripheral device I have created.
Right now I'm simply trying to use the method "SetupDiGetClassDevs" found in "setupapi.dll" to retrieve a list of attached HID devices on my computer. I've tried everything from "AfxLoadLibrary" to "__declspec(dllimport)" and pretty much everything else I've found online to no avail.
I've found working examples in C# but have not found anything that even compiles in C++. I am running Microsoft visual C++ 2010 express on Windows 7 64-bit if that makes a difference (ideally I'd want it to be OS independent - at least across more recent versions of windows). Any code samples that can successfully import/use this method would be greatly appreciated. (Also don't forget to mention any configuration settings/resource files/etc as I need to figure out a holistic process to make this work.)
UPDATE!!!:
so i finally got my code to compile using a combination of suggestions from the responses given here + some more googling. my current code is as follows (and fyi the main issue here was that an "L" had to be prefixed to the .dll in quotes):
GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};
HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFACE_DATA;
SP_DEVINFO_DATA DevInfoData;
DWORD InterfaceIndex = 0;
DWORD StatusLastError = 0;
DWORD dwRegType;
DWORD dwRegSize;
DWORD StructureSize = 0;
PBYTE PropertyValueBuffer;
bool MatchFound = false;
DWORD ErrorStatus;
BOOL BoolStatus = FALSE;
DWORD LoopCounter = 0;
HINSTANCE dllHandle = LoadLibrary(L"setupapi.dll");
if(dllHandle)
{
typedef HDEVINFO (WINAPI *pFUNC)(LPGUID, PCTSTR, HWND, DWORD);
pFUNC SetupDiGetClassDevs = (pFUNC) GetProcAddress(dllHandle,
#ifdef UNICODE
"SetupDiGetClassDevsW"
#else
"SetupDiGetClassDevsA"
#endif
);
if(SetupDiGetClassDevs)
hDevInfo = SetupDiGetClassDevsW(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
FreeLibrary(dllHandle);
unfortunately i wasn't able to get this working using the "safeloadlibrary" function remy mentioned. and my impression from other forums is that the standard "loadlibrary" function is non-ideal. so i'd like to know what is needed to implement it (header files, etc) or if there is another better way to do this. apparently there are also some issues that may arise using "loadlibrary" in a DLL (particularly in DLLMain entry point) but given my lack of experience using .dll's i'm not really sure what they are.
Your code fails because you are passing the wrong function name to GetProcAddress(). Like most API functions that have string parameters, SetupDiGetClassDevs() has separate Ansi and Unicode flavors available (SetupDiGetClassDevsA() and SetupDiGetClassDevsW(), respectively), and the API header files transparently hide this detail from you. So you need to adjust your string value according to which flavor you actually want to use, eg:
HINSTANCE dllHandle = SafeLoadLibrary("setupapi.dll");
if (dllHandle)
{
typedef HDEVINFO WINAPI (*pFUNC)(LPGUID, PCTSTR, HWND, DWORD);
pFUNC SetupDiGetClassDevs = (pFUNC) GetProcAddress(dllHandle,
#ifdef UNICODE
"SetupDiGetClassDevsW"
#else
"SetupDiGetClassDevsA"
#endif
);
if (SetupDiGetClassDevs)
hDevInfo = SetupDiGetClassDevs(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
FreeLibrary(dllHandle);
}
Here is a simply trick to make the mapping easier to work with if you have multiple functions to load dynamically:
#if defined(UNICODE)
#define _MAP_WINNAME_STR(n) n "W"
#else
#define _MAP_WINNAME_STR(n) n "A"
#endif
pFUNC SetupDiGetClassDevs = (pFUNC) GetProcAddress(dllHandle, _MAP_WINNAME_STR("SetupDiGetClassDevs"));