Prevent 'd3d9.dll' function 'D3D9SetMode' calling 'ChangeDisplaySettingsExA' - c++

I am using a third party .dll which wraps around the DirectX d3d9.dll, modifying the original .dll's execution. A well known example of this type of setup is used by Fraps.
I am creating a Fullscreen exclusive device in multihead mode (D3DCREATE_ADAPTERGROUP_DEVICE).
I am running up against a problem where the .dll wrapper exits my program when a particular function is called from D3D9SetMode.
Here is a partial call stack generated by WinDbg from breaking when ChangeDisplaySettingsExA function is called:
0018e748 7024712d USER32!ChangeDisplaySettingsExA
0018e828 7024702e d3d9!D3D9SetMode+0xec
0018e858 70246fab d3d9!DdSetModeLH+0x83
0018e954 7024760b d3d9!CSwapChain::SetSwapChainDisplayMode+0x5ca
0018e9a4 702492b0 d3d9!CSwapChain::DoneExclusiveMode+0xc7
0018e9c8 702491fc d3d9!CEnum::DoneExclusiveMode+0x5d
0018ea18 7024904a d3d9!handleActivateApp+0x12f
0018ea40 763862fa d3d9!WindowProc+0x30f
...
I have worked out the WM_ACTIVATE is the last message to be processed before this occurs.
I have tried building against the DirectX9 February 2005 and 2007 SDK's (d3dx9_24.dll and d3dx9_32.dll respectively) - they both have the same problem.
I suspect there is a flag or setup scenario to prevent the call to ChangeDisplaySettingsExA. I have tried D3DCREATE_NOWINDOWCHANGES on device creation without any success.
Any links, information, ideas?

Related

How to solve a function acting differently based on callsite?

Not sure how to word the title so feel free to rename, but the issue I'm having is that I've got a function that works in one project, but fails in another. Below is rough pseudocode to show that one call in LibraryProject works, whereas the call in GameProject doesn't.
In ChildClass::do_stuff, the win32_window HWND is valid, whereas the second one, failed_win32_window is null and glfw throws an error saying it isn't initialized, despite it already having been initialized (since the first glfw call was successful and I've manually stepped through to verify it was):
GLFWError #65537 Happen, The GLFW library is not initialized
Here's pseudocode showing the two projects, and the files. GLFW is set initialized properly since if I do all my glfw logic within LibraryProject, the window shows up as normal.
//LibraryProject
////library_header.h
class ParentClass {
GLFW* _mainWindow; //filled in elsewhere in the real code
HWND getWin32Window() { return glfwGetWin32Window(_mainWindow); }
}
//GameProject
////game_header.h
#include "library_header.h" //from other Project
class ChildClass : public ParentClass {
void do_stuff() {
HWND win32_window = this->getWin32Window(); //this works because it goes down into LibraryProject.dll's module
HWND failed_win32_window = glfwGetWin32Window(_mainWindow); //but literally the same call here doesn't because it happens within GameProject.exe
}
}
////game_body.cpp
void function_called_elsewhere_in_game() {
//called from GameProject.exe
auto child = ChildClass();
child.do_stuff();
}
I'm not sure if this is an issue with glfw and my setup, or just my misunderstanding how projects and dependencies work.
Things I've tried:
Downloading the latest glfw3
Rebuilding the entire solution
Toggling with References and Linking Dependency Inputs
Things to note:
This is happening in the main thread, nothing else is using glfw at the same time. Its 100% reproducible too.
glfw3.lib is always being created in my GameProject output folder, based on the one inside LibraryProject
Stepping through the disassembly for each of the two glfwGetWin32Window calls has different addresses in disassembly, leading me to believe they're two different copies of the same library, but I'm not sure.
This is not an issue with cocos2d, the game engine I'm using as starting a blank project and calling glfwGetWin32Window(..) returns a valid pointer, even in GameProject, so there's something that I'm doing wrong, but I don't know what.
Images showing off the actual behaviour. magnolia_cocos_proj is GameProject and is the exe I'm running, and libcocos2d is LibraryProject I'm using as a DLL (I'm unfamiliar with the details of how linking and dlls work).
win32_window has valid value
definition of getWin32Window() to be 100% sure. Notice the module is in libcocos2d.dll now.
after going over the second line, the error throws and the second window is null
As I understood from "glfw3.lib is always being created" you use static linking. Static linking of a lib to different dll and exe lead to duplicating of all static memory of the lib. You should use a dynamic library for GLFW in the case. It's glfw3dll.lib.
There are two main cases why this error could appear:
GLFWError #65537 Happen, The GLFW library is not initialised
Case One :
The mentioned error occurs if a GLFW function was called that mustn't be called unless the library is initialised. So, you need to initialise GLFW before calling any function that requires initialisation.
Read an API introduction for reference. Use if-else statement for handling glfwInit() and errors.
Reading Moving from GLFW 2 to 3 is also useful.
Case Two :
This error quite often occurs in the case you have previous versions of GLFW installed on your machine. GLFW3 doesn't like running along with previous version installed. So, delete all the GLFW libraries and linkers and reinstall the latest GLFW 3 from scratch.
Hope this helps.

ACPI _PS0 failing with UNINITIALIZED_ARG

I have a touchscreen controller (which is an I2C slave) that I need to enable via APCI. This should be done by calling the _PS0 ACPI method. I call this method by using AcpiEvaluateObject with no arguments and no return values.
AcpiEvaluateObject(nullptr, (ACPI_STRING)"\\_SB.I2C4._PS0", nullptr, nullptr); // returns AE_OK
AcpiEvaluateObject(nullptr, (ACPI_STRING)"\\_SB.I2C4.TCS2._PS0", nullptr, nullptr); // returns AE_AML_UNINITIALIZED_ARG
When calling this method on the parent object (I2C4), everything goes fine but calling it on the touch screen controller (TCS2), it fails. What also makes me wonder is that it returns AE_AML_UNINITIALIZED_ARG even though it doesn't take any args (according to the DSDT).
Calling the _CRS method on the same object also works without any problems. I also looked into the Linux kernel source how they change ACPI power states and they use the exact same mechanism. It boils down to the use of acpi_evaluate_object in acpi_dev_pm_explicit_set which also seems to work on the touchscreen device.
I'm not using Linux, but Genode and the Acpica library.
what am I missing to successfully enable the touchscreen device via ACPI? Is there something the Linux kernel is initializing implicitly (I couldn't find something like this)?

Loading OpenGL > 1.1 functions Windows

I'm having trouble setting up OpenGL with MSVS 2013. I'm aware that the opengl32.dll on my Windows
platform located at C:\Windows\System32 is an implementation of OpenGL 1.1.
What I'm trying to do is to load the newer OpenGL > 1.1 functions such as glBindBuffer and glBufferData. I have read that it's possible getting a pointer to the function using wglGetProcAddress. When using this function the returned pointer is always null, all the original functions in the dll using GetProcAddress(OpenGL32DLL, "...") work perfectly except the newer functions don't seem to load.
I'm hoping anybody here can help me go through my setup and point out what I did wrong or if I have missed something.
So here we go:
I have downloaded OpenGL Extensions Viewer 4.4 which points out I'm able to perfectly run upto OpenGL 2.1 which
should be more than enough to use or load glBindBuffer and glBufferData.
I downloaded Microsoft SDKs/v7.1 which includes the headers: gl/glu.h and gl/gl.h; I also downloaded the GLEXT extensions API
from here and linked the glext.lib + included the headers.
Files in the Linker:
C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\OpenGL32.Lib
C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\GlU32.Lib
C:\Users\user\Desktop\glext\lib\glext.lib
The CPP files included:
C:\Program Files\Microsoft SDKs\Windows\v7.1\Include -> GL.h, GLU.h
C:\Users\user\Desktop\glext\include -> glcorearb.h, glext.h, wglext.h
Instead of handling all these details yourself, I suggest you just grab yourself a copy of GLEW ( http://glew.sourceforge.net/ ) which handles all of this for you in a standard way. I currently use it on several published products without issues.
In your example, you'd be able to do the following:
if (GL_ARB_multi_bind) {
//glBindBuffer is available.
}
(Of course, after a call to glewInit(), possibly with glewExperimental = TRUE; - see documentation for details.)
When using this function the returned pointer is always null, all the original functions in the dll using GetProcAddress(OpenGL32DLL, "...") work perfectly except the newer functions don't seem to load.
Do you have a valid OpenGL context created and made current on the calling thread? In Windows extension functions are technically per-context, i.e. you have to get the pointers to the functions for each OpenGL context you create and make sure to use the right function pointers with the right context.
This of course also means that you must have a OpenGL context to begin with. The usual sequence of setting up an OpenGL context in Windows is:
pseudocode
struct glctx {
HGLRC rc
// dictionary for explanation purposes
// one would normally just have a bunch of
// structure elements here
functionpointer[string:name] extensionfunction
}
if not window_with_desired_pixelformat_exists: {
wnd := create_a_window
pixelformat := select_pixelformat
wnd→set_pixelformat pixelformat
}
dc := wnd→getDC
glctx ctx
ctx→rc := wglCreateContext(dc)
wglMakeCurrent(dc, ctx→rc);
foreach(fname in extensionfunctions_names): {
ctx→extensionfunction[name] = wglGetProcAddress(name)
}
I think that the problem is that there is no current context while calling wglGetProcAddress.
Function pointers can be specific for a precise pixel format, determined by tge context creation procedure.

ShellExtension AddPages isn't called

I am trying to implement a PropertySheetHandler shell extension, without much luck.
For some reason, the ContextMenu handlers are successfully called (Initialize() and QueryContextMenu()) but AddPages() is not called.
I have implemented the IShellPropSheetExt interface (AddPages() and ReplacePages()) and have the following declared:
BEGIN_COM_MAP(CShellExtension)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
COM_INTERFACE_ENTRY(IShellPropSheetExt)
END_COM_MAP()
Also, in the Registry I added the following entry:
HKEY_CLASSES_ROOT\*\shellex\PropertySheetHandlers\MyPropSheet
And of course also added to the CLSID:
HKEY_CLASSES_ROOT\CLSID\{CC669AD3-9F45-4C29-ADF7-F2F58E2DB2E9}\InprocServer32
With the DLL path and ThreadingModel Apartment (also tried Both).
What am I missing?
I also ran Process Monitor, and I can see my DLL is found, yet no call to Initialize or AddPages is made upon file properties.

Why do I receive a SIGSEGV signal while using the Aria robotics API?

I am using the Aria C++ programming libs for mobile robots (http://robots.mobilerobots.com/wiki/ARIA). I am new to this API so I wanted to start with a simple action class derived from ArAction. Now I tried to develop a small test program (an ArAction) in order to
control a simulated p3dx robot via MobileSim. Development takes place under Ubuntu 10.10, using gcc 4.4.5. Making (compiling) my code works fine, without errors. I can also set the desired speed for example in my ArAction's fire() method, and the simulation is also working as desired.
But, unfortunately, I can't use the ArRobot object attached to the ArAction I am overriding. The problem is that none of the member functions of the ArRobot object seems to work. For example, calling getVel() or getCompass() always returns a zero value. And when I call the hasFrontBumpers() method the program even crashes with the error message "Aria: Received signal 'SIGSEGV'. Exiting.". As soon as I remove this method call and recompile the error is also gone again...
Here is the relevant code that leads to the crash:
ArActionDesired * forward::fire(ArActionDesired d)
{
desiredState.reset();
ArRobot *r = getRobot();
if(r == NULL)
{
printf("ArRobot = NULL\n");
deactivate();
return &desiredState;
}
printf("ok, ArRobot is not NULL, check for bumpers...\n");
r->hasFrontBumpers(); // <-- this leads to the SIGSEV-based "crash"
return &desiredState;
}
Any ideas what I am missing here -- is it a problem with my coding, or with the simulation environment? Thanks in advance for your help!
Kind regards, Matthias
ok, found it out now -- for the records: the Aria libs in version 2.7.2 are based on gcc-3 and libstdc++ 5, but Ubuntu 10.10 (which I am using) is shipped with gcc-4 and libstdc++ 6 per default. So I had to manually install the older versions of both packages, now my code is running fine...
cheers!
Calling hasFrontBumpers() for a p3dx from the fire() works fine for me on a similar Linux platform. If something is wrong, it is not in this method but in the initialization of the system. A reason for the non-moving robot could be that robot.enableMotors() hasn't been called.