I ran into some strange behavior while upgrading a compiler from VS 2010 Ultimate to VS 2013 Professional. The operating system is Windows 7 Professional.
Using GetLastError(), I tracked the problem down to a DescribePixelFormat(...) call. Before it, there is no error. Immediately after it, I get error 1150 (which is apparently "The specified program requires a newer version of Windows.").
Edit: The code looks like this:
HWND window = CreateWindowEx(...);
HDC device_context = GetDC(window);
DWORD error_before = GetLastError(); //is 0
int count = DescribePixelFormat(device_context, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
DWORD error_after = GetLastError(); //is 1150
The problem only occurs in Release x64 mode, and the same code worked fine with VS 2010. Could this have something to do with VS 2013 thinking it needs Win 8 or something? What's going on here?
Your code that calls GetLastError is incorrect. The documentation of DescribePixelFormat says:
Return value
If the function succeeds, the return value is the maximum pixel format
index of the device context. In addition, the function sets the
members of the PIXELFORMATDESCRIPTOR structure pointed to by ppfd
according to the specified pixel format.
If the function fails, the return value is zero. To get extended error
information, call GetLastError.
In other words, you need to check the return value of the DescribePixelFormat function. You are not doing that. Only in the case where DescribePixelFormat returns zero does the value returned by GetLastError have any meaning.
Related
There is an article on MSDN talking about QueryPerformanceCounter:
Acquiring high-resolution time stamps
Towards the bottom is an FAQ section with an interesting question:
Under what circumstances does QueryPerformanceFrequency return FALSE, or QueryPerformanceCounter return zero?
This won't occur on any system that runs Windows XP or later.
That answer is correct, except that it is wrong. There are circumstances where QueryPerformanceFrequency will return false.
I will be self answering this.
Under what circumstances does QueryPerformanceFrequency return FALSE, or QueryPerformanceCounter return zero?
This won't occur on any system that runs Windows XP or later.
That is correct, perhaps with the slight change in phrasing:
This can occur on any system that runs Windows XP or later.
There are circumstances where QueryPerformanceFrequency returns false. You can Google for people experiencing the problem.
i had the problem today (on Windows 7):
Int64 freq;
//...
QueryPerformanceFrequency(#freq);
The function call fails (returns false), and GetLastError returns:
ERROR_NOACCESS
998 (0x3E6)
Invalid access to memory location.
Alignment Matters
The issue happens if your Int64 memory address is not double-word (4-byte) aligned. For example, if you use a compiler that defaults to Byte or Word alignment for objects, or structures, or class member variables. In this case, QueryPerformanceCounter will return false.
Note: It's entirely possible that QueryPerformanceCounter only happens to work with double-word (4-byte) alignment, and might actually require quad-word (8-byte) alignment. The Windows x64 calling convention documentation is silent on the subject.
It is also possible that the CPU hardware is silently fixing up 4-byte alignment to 8-byte alignment, where it won't do the same for 1, 2, 3, 5, 6, or 7 byte alignment. It is also possible that this new drive system, if operable, could render the Red October undetectable to our SOSUS warning nets in the Atlantic.
tl;dr
Under what circumstances does QueryPerformanceFrequency return FALSE, or QueryPerformanceCounter return zero?
The function can fail with error code ERROR_NOACCESS (Invalid access to memory location) if the variable to not double-word (8-byte) aligned.
Bonus Chatter
The documentation:
Return value
If the installed hardware supports a high-resolution performance counter, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError. On systems that run Windows XP or later, the function will always succeed and will thus never return zero.
I've been playing around with CryptoAPI and everything was fine.
I've imported .PFX to the certificate store, got context, got CSP handle. Every function I've been using I've checked for the mistakes with GetLastError function. But when I'd called CryptGetUserKey with three arguments which are hCryptProv, dwKeySpec and pointer to UserKey, I got an error, but GetLastError call didn't show me anything but a random value like 2148073485 that means nothing I suppose.
How can I find out what is wrong?
OS - Windows 7 32b HP;
Programming language - C++;
IDE - MSVS2013 Ultimate.
GetLastError call didn't show me anything but a random value like 2148073485 that means nothing I suppose.
You fail WINAPI forever. It took me like five seconds to launch Calc.exe and convert it to hex: 8009000D, which looks like a perfectly valid error HRESULT.
Let's take some time to analyze it a bit more:
8 is ERROR.
9 is not 7, meaning it's not a regular Win32 error. A search in Visual C++ headers tells me 9 is FACILITY_SSPI.
If I search 8009000D in Visual C++ headers, I get this line:
#define NTE_NO_KEY _HRESULT_TYPEDEF_(0x8009000DL) There, you have it, it's your error: NTE_NO_KEY.
MSDN is rather unhelpful, but Google shows some other questions about the NTE_NO_KEY error, such as this.
I'm trying to call IOCTL_BTH_GET_LOCAL_INFO using DeviceIoControl, which I believe it can be done (accordingly to Bluetooth Profile Driver IOCTLs).
I'm on a Windows 7 x64 using Visual Studio 2012 (probably with default configuration).
The handle have a valid value (I removed the validation code) but DeviceIoControl always returns ERROR_INVALID_USER_BUFFER (error 1784).
Here's the code:
int main() {
BTH_LOCAL_RADIO_INFO buffer;
BOOL fStatus;
HANDLE h;
DWORD returned = 0;
h = CreateFile(
TEXT("\\\\.\\BthPan"),
GENERIC_READ | GENERIC_WRITE ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
fStatus = DeviceIoControl(
h,
IOCTL_BTH_GET_LOCAL_INFO,
NULL, 0,
(LPVOID)&buffer, sizeof(BTH_LOCAL_RADIO_INFO),
&returned,
(LPOVERLAPPED) NULL
);
(...)
After some research I tried the following solutions:
Changing the structure pack alignment to 1/4/8 byte (with VS options);
Using values which are 8-byte aligned (later I've found out that
this was already happening, even with data types smaller than 8 bytes). After a while I've read somewhere that DeviceIoControl deals with misaligment for you, so probably no need to worry about that.
All of the solutions above have failed. What do you think it is? VS have a bunch of configurations for Win32, but that never gave me a problem before (first time with IOCTL though).
I've seen some of that code on 32feet.NET, so probably it's just an error of mine (I can't see any difference).
You're sending IOCTL_BTH_GET_LOCAL_INFO to the wrong device (Bluetooth Personal Area Network instead of Bluetooth Radio).
So I suggest you to use BluetoothFindFirstRadio, BluetoothFindNextRadio and BluetoothFindRadioClose to simply iterate through local Bluetooth radios, rather than to guess the correct DOS Device Names for them.
I have an MFC-driven dialog-based application created with MSVS2005. Here is my problem step by step. I have button on my dialog and corresponding click-handler with code like this:
int* i = 0;
*i = 3;
I'm running debug version of program and when I click on the button, Visual Studio catches focus and alerts "Access violation writing location" exception, program cannot recover from the error and all I can do is to stop debugging. And this is the right behavior.
Now I add some OpenGL initialization code in the OnInitDialog() method:
HDC DC = GetDC(GetSafeHwnd());
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat = ChoosePixelFormat(DC, &pfd);
SetPixelFormat(DC, pixelformat, &pfd);
HGLRC hrc = wglCreateContext(DC);
ASSERT(hrc != NULL);
wglMakeCurrent(DC, hrc);
Of course this is not exactly what I do, it is the simplified version of my code. Well now the strange things begin to happen: all initialization is fine, there are no errors in OnInitDialog(), but when I click the button... no exception is thrown. Nothing happens. At all. If I set a break-point at the *i = 3; and press F11 on it, the handler-function halts immediately and focus is returned to the application, which continue to work well. I can click button again and the same thing will happen.
It seems like someone had handled occurred exception of access violation and silently returned execution into main application message-receiving cycle.
If I comment the line wglMakeCurrent(DC, hrc);, all works fine as before, exception is thrown and Visual Studio catches it and shows window with error message and program must be terminated afterwards.
I experience this problem under Windows 7 64-bit, NVIDIA GeForce 8800 with latest drivers (of 11.01.2010) available at website installed. My colleague has Windows Vista 32-bit and has no such problem - exception is thrown and application crashes in both cases.
Well, hope good guys will help me :)
PS The problem originally where posted under this topic.
Ok, I found out some more information about this. In my case it's windows 7 that installs KiUserCallbackExceptionHandler as exception handler, before calling my WndProc and giving me execution control. This is done by ntdll!KiUserCallbackDispatcher. I suspect that this is a security measure taken by Microsoft to prevent hacking into SEH.
The solution is to wrap your wndproc (or hookproc) with a try/except frame so you can catch the exception before Windows does.
Thanks to Skywing at http://www.nynaeve.net/
We've contacted nVidia about this
issue, but they say it's not their
bug, but rather the Microsoft's. Could
you please tell how you located the
exception handler? And do you have
some additional information, e.g. some
feedbacks from Microsoft?
I used the "!exchain"-command in WinDbg to get this information.
Rather than wrapping the WndProc or hooking all WndProcs, you could use Vectored Exception Handling:
http://msdn.microsoft.com/en-us/library/ms679274.aspx
First, both behaviors are correct. Dereferencing a null pointer is "undefined behavior", not a guaranteed access violation.
First, find out whether this is related to exception throwing or only to accessing memory location zero (try a different exception).
If you configure Visual Studio to stop on first-chance access violations, does it break?
Call VirtualQuery(NULL, ...) before and after glMakeCurrent and compare. Maybe the nVidia OpenGL drivers VirtualAlloc page zero (a bad idea, but not impossible or illegal).
I found this question when I was looking at a similar problem. Our problem turned out to be silent consumption of exceptions when running a 32-bit application on 64-bit Windows.
http://connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-messages
There’s a fix available from Microsoft, though deploying it is somewhat challenging if you have multiple target platforms:
http://support.microsoft.com/kb/976038
Here's an article on the subject describing the behavior:
http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/
This thread on stack overflow also describes the problem I was experiencing:
Exceptions silently caught by Windows, how to handle manually?
I'm printing using CreateDC, passing in a valid DEVMODE structure and getting NULL returned which indicates an error but GetLastError returns 0.
m_hDC = ::CreateDC(L"WINSPOOL", PrinterName, NULL, pDevMode);
if (m_hDC == NULL)
{
throw Exception(GetLastError(), __LINE__, _T(__FILE__));
}
This is working for all of my customers apart from one, any ideas?
This turned out to be a problem with the thunking spooler api's.
The software is a 32 bit Windows service running on a 64 bit system.
It seems that only one user/session can print at a time from a 32 bit process, the next user has to wait for splwow64.exe to timeout (or kill it) before they can print.
It is covered in a technote from MS.
Are you sure that pDevMode is valid? You could try using a NULL pointer here in case the DEVMODE is the issue.