API EnumOutputs fails DXGI_ERROR_NOT_FOUND on Win8/Windows 8 - windows

Was having an odd situation with our product being too bright on win8 compared to win7. So tried PNTriangles11 DX SDK example and got the same results. This was after testing the behavior at BestBuy and 24 systems all behaved the same way, all failed calling EnumOutputs. It did not matter if desktop, laptop, all in one, or tablet.
Where our directx charting product looked like... also shows our WPF charting component and even more variation in brightness caused by this same failure issue.
So this led to researching and I find that I can reproduce on Win7 by adding below...
HRESULT CD3D11Enumeration::EnumerateOutputs( CD3D11EnumAdapterInfo* pAdapterInfo )
{
HRESULT hr;
IDXGIOutput* pOutput;
for( int iOutput = 0; ; ++iOutput )
{
pOutput = NULL;
hr = pAdapterInfo->m_pAdapter->EnumOutputs( iOutput, &pOutput );
// FORCE FAILURE ON WIN7 FOR TESTING PURPOSES
hr = DXGI_ERROR_NOT_FOUND;
if( DXGI_ERROR_NOT_FOUND == hr )
{
return S_OK;
}
else if( FAILED( hr ) )
{
return hr; //Something bad happened.
}
else //Success!
{
CD3D11EnumOutputInfo* pOutputInfo = new CD3D11EnumOutputInfo;
if( !pOutputInfo
Though to get the sdk example to run now on Win8 and Win7 you also need to modify (adding the test for non zero hAdapterMonitor...
// Check to see if the window needs to be resized.
// Handle cases where the window is minimized and maxmimized as well.
bool bNeedToResize = false;
if(hAdapterMonitor && DXUTGetIsWindowedFromDS( pNewDeviceSettings ) &&
!bKeepCurrentWindowSize )
{
UINT nClientWidth;
UINT nClientHeight;
if( IsIconic( DXUTGetHWNDDeviceWindowed() ) )
{
The above allows you to tinker with the issue on win7 as a way to develop for win8.
So my question is, what is the best solution to handling EnumOutputs failing on Win8. And or what other changes to DXUT do you find useful.
Microsoft is working on this, and I will post their response, hopefully shortly, but a discussion of this topic is needed as so many dxut inspired software projects or those using EnumOutputs are failing on Win8.
ANSWER 1: Microsoft did get back to me with an initial response to get PNTriangles11 working on Win8. They pointed me to the change within DXUTApplyDefaultDeviceSettings(DXUTDeviceSettings *modifySettings) where...
modifySettings->d3d11.sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
has to be changed to...
modifySettings->d3d11.sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
but the simple workaround for DXUTChangeDevice is still needed: a test for non zero hAdapterMonitor...
bool bNeedToResize = false;
if(hAdapterMonitor && DXUTGetIsWindowedFromDS( pNewDeviceSettings ) && !bKeepCurrentWindowSize )
{
UINT nClientWidth;
UINT nClientHeight;
if( ::IsIconic( DXUTGetHWNDDeviceWindowed() ) )
{
// Window is currently minimized. To tell if it needs to resize,
Still waiting for an explanation from Microsoft why EnumOutputs failed on all 24 systems I tested at BestBuy.

Related

Walking the NTFS Change Journal on Windows 10

I'm trying to read the NTFS Change Journal but I've noticed that all the example code I can find fails on Windows 10, even though it works on Windows 7.
For example, Microsofts own example Walking a Buffer of Change Journal Records works on Windows 7 but when I run the same code on Windows 10 I get an error 87 (The parameter is incorrect) when I call DeviceIoControl with FSCTL_READ_USN_JOURNAL (Note that the earlier call to DeviceIoControl with FSCTL_QUERY_USN_JOURNAL completes successfully and return valid data.).
I've even taken the EXE compiled and working on Windows 7 and copied it to the Windows 10 machine and it still fails, so I believe that Windows 10 may be more strict on parameter validation or something like that?
I am running the code as Administrator, so that's not the issue.
I can't find any other references to this problem, but I get the same issue if I take other peoples example code and attempt to run it on Windows 10.
Edit:
The code itself:
#include <Windows.h>
#include <WinIoCtl.h>
#include <stdio.h>
#define BUF_LEN 4096
void main()
{
HANDLE hVol;
CHAR Buffer[BUF_LEN];
USN_JOURNAL_DATA JournalData;
READ_USN_JOURNAL_DATA ReadData = {0, 0xFFFFFFFF, FALSE, 0, 0};
PUSN_RECORD UsnRecord;
DWORD dwBytes;
DWORD dwRetBytes;
int I;
hVol = CreateFile( TEXT("\\\\.\\c:"),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hVol == INVALID_HANDLE_VALUE )
{
printf("CreateFile failed (%d)\n", GetLastError());
return;
}
if( !DeviceIoControl( hVol,
FSCTL_QUERY_USN_JOURNAL,
NULL,
0,
&JournalData,
sizeof(JournalData),
&dwBytes,
NULL) )
{
printf( "Query journal failed (%d)\n", GetLastError());
return;
}
ReadData.UsnJournalID = JournalData.UsnJournalID;
printf( "Journal ID: %I64x\n", JournalData.UsnJournalID );
printf( "FirstUsn: %I64x\n\n", JournalData.FirstUsn );
for(I=0; I<=10; I++)
{
memset( Buffer, 0, BUF_LEN );
if( !DeviceIoControl( hVol,
FSCTL_READ_USN_JOURNAL,
&ReadData,
sizeof(ReadData),
&Buffer,
BUF_LEN,
&dwBytes,
NULL) )
{
printf( "Read journal failed (%d)\n", GetLastError());
return;
}
dwRetBytes = dwBytes - sizeof(USN);
// Find the first record
UsnRecord = (PUSN_RECORD)(((PUCHAR)Buffer) + sizeof(USN));
printf( "****************************************\n");
// This loop could go on for a long time, given the current buffer size.
while( dwRetBytes > 0 )
{
printf( "USN: %I64x\n", UsnRecord->Usn );
printf("File name: %.*S\n",
UsnRecord->FileNameLength/2,
UsnRecord->FileName );
printf( "Reason: %x\n", UsnRecord->Reason );
printf( "\n" );
dwRetBytes -= UsnRecord->RecordLength;
// Find the next record
UsnRecord = (PUSN_RECORD)(((PCHAR)UsnRecord) +
UsnRecord->RecordLength);
}
// Update starting USN for next call
ReadData.StartUsn = *(USN *)&Buffer;
}
CloseHandle(hVol);
}
I've managed to work out what the problem is.
The example Microsoft code creates a local variable defined as READ_USN_JOURNAL_DATA, which is defined as:
#if (NTDDI_VERSION >= NTDDI_WIN8)
typedef READ_USN_JOURNAL_DATA_V1 READ_USN_JOURNAL_DATA, *PREAD_USN_JOURNAL_DATA;
#else
typedef READ_USN_JOURNAL_DATA_V0 READ_USN_JOURNAL_DATA, *PREAD_USN_JOURNAL_DATA;
#endif
On my systems (Both the Win10 and Win7 systems) this evaluates to READ_USN_JOURNAL_DATA_V1.
Looking at the difference betweem READ_USN_JOURNAL_DATA_V0 and READ_USN_JOURNAL_DATA_V1 we can see that V0 is defined as:
typedef struct {
USN StartUsn;
DWORD ReasonMask;
DWORD ReturnOnlyOnClose;
DWORDLONG Timeout;
DWORDLONG BytesToWaitFor;
DWORDLONG UsnJournalID;
} READ_USN_JOURNAL_DATA_V0, *PREAD_USN_JOURNAL_DATA_V0;
and the V1 version is defined as:
typedef struct {
USN StartUsn;
DWORD ReasonMask;
DWORD ReturnOnlyOnClose;
DWORDLONG Timeout;
DWORDLONG BytesToWaitFor;
DWORDLONG UsnJournalID;
WORD MinMajorVersion;
WORD MaxMajorVersion;
} READ_USN_JOURNAL_DATA_V1, *PREAD_USN_JOURNAL_DATA_V1;
Note the new Min and Max Major version members.
So, the Microsoft code is defining a local variable called ReadData that is actually a V1 structure, yet it appears to fill in the data assuming it's a V0 structure. i.e. it doesn't set the Min and Max elements.
It appears that Win7 is fine with this but Win10 rejects it and returns error 87 (The parameter is incorrect).
Sure enough if I explicitly define the ReadData variable to be a READ_USN_JOURNAL_DATA_V0 then the code works on Win7 and Win10, whereas if I explicitly define it as a READ_USN_JOURNAL_DATA_V1 then it continues to work on Win7 but not on Win10.
The strange thing is that the API documentation for READ_USN_JOURNAL_DATA_V1 structure states that it's only supported from Windows 8 on, so it's odd that it works on Windows 7 at all. I guess it's just interpreting it as a READ_USN_JOURNAL_DATA_V0 structure given that V1 version is an extension of the V0 structure. If so then it must be ignoring the size parameter that is passed into DeviceIOControl.
Anyway, all working now. I hope someone finds this a useful reference in the future.
I came across this exact same issue with the sample code as the OP. At the start of the sample code, you will see a partial initialization of the structure at the point of declaration. A little later in the code, right before the offending call, there is a line that assigns the UsnJournalID into the read data structure.
For Windows 10, though, the other two members of the V1 structure are not initialized. I initialized them right after the UsnJournalID's initialization with:
#if (NTDDI_VERSION >= NTDDI_WIN8)
ReadData.MinMajorVersion = JournalData.MinSupportedMajorVersion;
ReadData.MaxMajorVersion = JournalData.MaxSupportedMajorVersion;
#endif
When I ran my code after doing this, it worked correctly without the error code. I remember reading in the Volume Management API discussion that the Min and Max versions needed to be set. I forgot exactly where, because I've been reading and testing this stuff for a couple days.
Anyway, I hope that clarifies the issue for anyone coming after me.
Replace the READ_USN_JOURNAL_DATA structure with READ_USN_JOURNAL_DATA_V0 data structure and initialize it.
This worked for me
READ_USN_JOURNAL_DATA_V0 ReadData;
ZeroMemory(&ReadData, sizeof(ReadData));
ReadData.ReasonMask = 0xFFFFFFFF;

How to detect a specific System Tray Popup/Tooltip

I need to detect a specific Windows System Tray Tooltip/Popup (USB Device Not Recognized). I don't seem to be having much luck polling with FindWindow. Is there a hook or something that will show me each one that pops up?
I have managed it doing the following:
HWND HMyTooltip = NULL, HNew = FindWindow( "tooltips_class32", NULL );
// Cycle through all visible tooltip windows looking for the one we want
while (HNew && !HMyTooltip)
{
if (IsWindowVisible(HNew))
{
HMyTooltip = HNew;
// If you want to find a particular tooltip, check the text (Note: GetWindowText doesn't work)
SendMessage( HMyTooltip, WM_GETTEXT, ARRAYSIZE(Title), (LPARAM)Title );
if (_strnicmp( Title, "USB Device Not Recognised", 22 ) != 0)
HMyTooltip = NULL;
}
HNew = GetWindow( HNew, GW_HWNDNEXT );
}

X11/Xlib: Window always on top

A window should stay on top of all other windows. Is this somehow possible with plain x11/xlib? Googling for "Always on top" and "x11" / "xlib" didn't return anything useful.
I'd avoid toolkits like GTK+, if somehow possible.
I'm using Ubuntu with gnome desktop. In the window menu, there's an option "Always On Top". Is this provided by the X server or the window manager? If the second is the case, is there a general function that can be called for nearly any wm? Or how to do this in an "X11-generic" way?
Edit: I implemented fizzer's answer, now having following code:
XSelectInput(this->display, this->window,
ButtonPressMask |
StructureNotifyMask |
ExposureMask |
KeyPressMask |
PropertyChangeMask |
VisibilityChangeMask );
// ...
// In a loop:
if (XPending(this->display) >= 0)
{
XNextEvent(this->display, &ev);
switch(ev.type) {
// ...
case VisibilityNotify:
XRaiseWindow(this->display, this->window);
XFlush(this->display);
break;
// ...
}
}
But the eventhandling and raising nearly never gets executed even my mask is correct?!
#define _NET_WM_STATE_REMOVE 0 // remove/unset property
#define _NET_WM_STATE_ADD 1 // add/set property
#define _NET_WM_STATE_TOGGLE 2 // toggle property
Bool MakeAlwaysOnTop(Display* display, Window root, Window mywin)
{
Atom wmStateAbove = XInternAtom( display, "_NET_WM_STATE_ABOVE", 1 );
if( wmStateAbove != None ) {
printf( "_NET_WM_STATE_ABOVE has atom of %ld\n", (long)wmStateAbove );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE_ABOVE !\n" );
return False;
}
Atom wmNetWmState = XInternAtom( display, "_NET_WM_STATE", 1 );
if( wmNetWmState != None ) {
printf( "_NET_WM_STATE has atom of %ld\n", (long)wmNetWmState );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE !\n" );
return False;
}
// set window always on top hint
if( wmStateAbove != None )
{
XClientMessageEvent xclient;
memset( &xclient, 0, sizeof (xclient) );
//
//window = the respective client window
//message_type = _NET_WM_STATE
//format = 32
//data.l[0] = the action, as listed below
//data.l[1] = first property to alter
//data.l[2] = second property to alter
//data.l[3] = source indication (0-unk,1-normal app,2-pager)
//other data.l[] elements = 0
//
xclient.type = ClientMessage;
xclient.window = mywin; // GDK_WINDOW_XID(window);
xclient.message_type = wmNetWmState; //gdk_x11_get_xatom_by_name_for_display( display, "_NET_WM_STATE" );
xclient.format = 32;
xclient.data.l[0] = _NET_WM_STATE_ADD; // add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
xclient.data.l[1] = wmStateAbove; //gdk_x11_atom_to_xatom_for_display (display, state1);
xclient.data.l[2] = 0; //gdk_x11_atom_to_xatom_for_display (display, state2);
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
//gdk_wmspec_change_state( FALSE, window,
// gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
// GDK_NONE );
XSendEvent( display,
//mywin - wrong, not app window, send to root window!
root, // <-- DefaultRootWindow( display )
False,
SubstructureRedirectMask | SubstructureNotifyMask,
(XEvent *)&xclient );
XFlush(display);
return True;
}
return False;
}
You don't want to use XRaiseWindow() to try to stay on top. Some window managers will ignore it entirely. For those that don't, consider what happens if more than one app tries to do this. Boom! That's why the window manager is in charge of stacking windows, not the app.
The way you do this is to use the protocols defined in the Extended Window Manager Hints (EWMH), see: http://www.freedesktop.org/wiki/Specifications/wm-spec
Specifically here you want _NET_WM_STATE_ABOVE which is how the "Always on Top" menu item works.
If you aren't using a toolkit you'll want to get used to scavenging in toolkit source code to figure out how to do things. In this case you could look at the function gdk_window_set_keep_above() in GTK+'s X11 backend. That will show how to use the _NET_WM_STATE_ABOVE hint.
I wrote something like this in Xlib many years ago. It's a few lines of code. When your window is partially obscured you get a VisibilityNotify event, then call XRaiseWindow. Watch out for the case where two of your 'always on top' windows overlap.
Use Actual Title Buttons (http://www.actualtools.com/titlebuttons/) for example. It allows to stay any windows always on top , roll up, make transparency and etc..

Grabbing the backbuffer with DirectX 7

I'm trying to write a small chunk of code to grab the backbuffer into an array of pixels. I've barely used directX before as I'm more of a OpenGL fan.
My wish is to actually replace some code in a project that grabs the backbuffer using BitBlt and DC which is very slow.
This is supposed to work on all computers and that's why I chose directx7.
My question is.. how would I do that?
Thank you.
What I do is to use a helper class to do the lock /unlock as below. Then you use it like so :
mBackBuffer->Flip( DDFLIP_WAIT );
{
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ReadLock r( mBackBuffer, ddsd, NULL /* for whole surface */ );
if ( r )
{
// ddsd.lpSurface contains the void* pointer to the bytes
// ddsd.lPitch contains the byte count of each horizontal line
}
} // ReadLock unlocks when it goes out of scope
class ReadLock
{
public:
ReadLock(IDirectDrawSurface7* surface, DDSURFACEDESC2& ddsd, LPRECT pRect = 0 ) : surface_(surface), mpRect( pRect ), hr( S_OK )
{
hr = surface_->Lock( mpRect, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK | DDLOCK_WAIT | DDLOCK_READONLY, 0 );
}
HRESULT getResult() const { return hr; }
bool operator!() const { return FAILED( hr ); }
operator bool() const { return SUCCEEDED( hr ); }
~ReadLock()
{
if ( surface_ && SUCCEEDED( hr ) )
surface_->Unlock(mpRect);
}
private:
HRESULT hr;
RECT* mpRect;
IDirectDrawSurface7* surface_;
};
TBH DirectX 9 will work even with ancient cards. You don't have all the features available but you have a a SHED load more usable information out there. Although I think you might be a bit knackered on Win 95/9/me support and win 2K. Bear in mind NT4 never had a decent version of DirectX.
Alas I don't have the DX7 docs anywhere handy but I'm pretty sure you could just get the back buffer surface and then lock it to get at the data. Though you need to bear in mind just how slow grabbing the back buffer can be, especially on old cards. Copying the back buffer from local video memory to system memory across the PCI or AGP bus is incredibly slow.
What exactly are you trying to achieve? There must be better ways to achieve what you are after doing ...

Windows - Prevent crashes "Checking for a solution..." and "Restarting the program..."

This may not be a purely programming related question, but I come across this often during development. When my app crashes and I choose to kill it, Windows automatically throws up a "Checking for a solution..." dialog box. When I hit the cancel button on that I get another dialog box that says "Restarting the program..." Is there a way to prevent this behavior? When I stop an app I'd prefer if it were silently killed. I'm using Windows 7 if the platform is important.
Although Microsoft recommends using a newer replacement API available only on Windows Vista and later, there is an API which works for all versions of Windows from XP onward: AddERExcludedApplication(). This function takes the module name without path information (e.g., "myprogram.exe") for which error reporting is to be disabled.
The new method available only Windows Vista and later is to call WerAddExcludedApplication() function. This API allows you to specify whether it should change the HKEY_CURRENT_USER registry hive, or the HKEY_LOCAL_MACHINE registry hive. Be sure to set this for the HKCU if the HKLM set fails, such as:
typedef BOOL (*ADD_MER_EXCLUDED_APP_XP) (PCWSTR);
typedef BOOL (*ADD_MER_EXCLUDED_APP_VISTA) (PCWSTR, BOOL);
bool disable_microsoft_error_reporting(PCWSTR wz_app)
{
const WCHAR * const WZ_MER_DLL_XP = L"faultrep.dll";
const char * const SZ_MER_PROC_XP = "AddERExcludedApplicationW";
const WCHAR * const WZ_MER_DLL_VISTA = L"wer.dll";
const char * const SZ_MER_PROC_VISTA = "WerAddExcludedApplicationW";
const int WER_EXCLUDE_FOR_ALL_USERS = TRUE;
const int WER_EXCLUDE_FOR_THIS_USER = FALSE;
HANDLE hlib_error_reports_xp = NULL;
HANDLE hlib_error_reports_vista = NULL;
ADD_MER_EXCLUDED_APP_XP add_mer_excluded_app_xp = NULL;
ADD_MER_EXCLUDED_APP_VISTA add_mer_excluded_app_vista = NULL;
bool success = false;
// First, attempt the API that has been around since XP.
hlib_error_reports_xp = LoadLibrary(WZ_MER_DLL_XP);
if (hlib_error_reports_xp)
{
add_mer_excluded_app_xp = (ADD_MER_EXCLUDED_APP_XP)GetProcAddress(hlib_error_reports_xp, SZ_MER_PROC_XP);
if (add_mer_excluded_app_xp)
success = add_mer_excluded_app_xp(wz_app);
FreeLibrary(hlib_error_reports_xp);
hlib_error_reports_xp = NULL;
add_mer_excluded_app_xp = NULL;
if (success)
return true;
}
// That did not succeed. Attempt the Vista API.
hlib_error_reports_vista = LoadLibrary(WZ_MER_DLL_VISTA);
if (hlib_error_reports_vista)
{
add_mer_excluded_app_vista = (ADD_MER_EXCLUDED_APP_VISTA)GetProcAddress(hlib_error_reports_vista, SZ_MER_PROC_VISTA);
if (add_mer_excluded_app_vista)
{
success = (S_OK == add_mer_excluded_app_vista(wz_app, WER_EXCLUDE_FOR_ALL_USERS));
if (!success)
success = (S_OK == add_mer_excluded_app_vista(wz_app, WER_EXCLUDE_FOR_THIS_USER));
}
FreeLibrary(hlib_error_reports_vista);
hlib_error_reports_vista = NULL;
add_mer_excluded_app_vista = NULL;
if (success)
return true;
}
// Nothing worked. Fail.
return false;
}
To further curtail the execution of the WER components, imeplement an unhandled exception filter and pass it to: SetUnhandledExceptionFilter() function. To shunt WER, your filter must never return EXCEPTION_CONTINUE_SEARCH or EXCEPTION_EXECUTE_HANDLER.
One of the drawbacks of implementing the SetUnhandledExceptionFilter() function is that it interferes with Just-in-time debugging.
You mention you want the app to be "silently killed." In that case:
LONG WINAPI global_exception_filter(struct _EXCEPTION_POINTERS *exception_info)
{
ExitProcess(0xDEDD000D);
}
int WINAPI WinMain(
HINSTANCE _hinstance,
HINSTANCE hinstance_prev,
LPSTR sz_cmd_line,
int cmd_show
)
{
SetUnhandledExceptionFilter(global_exception_filter);
/* ... */
}
Will cause the application to immediately vanish upon unhandled exception. N.B., the exit code to return is a matter of taste.
Check out the answers on these questions:
How do I disable the ‘Debug / Close Application’ dialog on Windows Vista?
Hide Error Report window
I realize that others have answered with ways to work around this, but...
Let's not forget that the best way to protect against this is to write a program that doesn't crash. :-) You shouldn't be seeing this if you are using memory correctly and not hanging the GUI thread.
Altering the behavior of an application crash is a great way to introduce subtle and deadly bugs. See also this blog post from Microsoft's Raymond Chen.
Take a look at the Windows Error Reporting APIs.

Resources