I have an application that opens many windows. Sometimes, I get wglCreateContext() returns 0 and GetLastError() returns 0xc007001f.
It happens on Intel graphic cards only.
Did someone see it? Someone knows what it is?
You can decompose the error code into its parts. 0xC makes it a fatal error, 007 produces facility code 7 which is the winapi. Which makes the last four digits Windows error 31:
//
// MessageId: ERROR_GEN_FAILURE
//
// MessageText:
//
// A device attached to the system is not functioning.
//
#define ERROR_GEN_FAILURE 31L
Which makes it a pretty basic device driver kind of problem, assuming you passed a correct device context handle to wglCreateContext(). The kind that typically requires a video driver update and ensuring that the right kind of OpenGL driver is installed. Nothing you can do to fix of course, this is a problem that the user needs to tackle.
I believe error 0xc007001f is when SetPixelFormat() fails. Which means, you are trying to use some feature in the pixel format that isn't supported by that card. If I'm not mistaken, Intel graphics cards barely support OpenGL (only [EDIT: 2.1]).
Also you can use FormatMessage to get string for error description:
DWORD err = GetLastError();
char* msg;
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, err, 0, (LPCSTR)&msg, 0, 0);
MessageBoxA(0, msg, "Error", 0);
LocalFree(msg);
Related
I have C++ code (works well with VS6 up to VS2017) that enumerates USB devices and retrieves several properties. I recently added SPDRP_DEVTYPE:
SetupDiGetDeviceRegistryProperty(hDevInfo, &DevData, SPDRP_DEVTYPE, 0L, (BYTE*) &dwData, 4, 0);
The call returns with 'false' and GetLastError() then returns 13 ("The data is invalid"). The same happens when trying to query for SPDRP_CHARACTERISTICS.
Most other PropertyKey values I have tried work well (for example, SPDRP_CAPABILITIES, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, SPDRP_FRIENDLYNAME, and so on) but these two keep failing.
Running the EXE as administrator does not change anything. I tested on Windows 7 (32/64) and on Windows 10.
In addition, I tried to open the device with CreateFile (which succeeds) and then use DeviceIoControl(), but every call to DeviceIoControl fails with Error 50 "not supported"
Any idea why these calls are not working?
I have been using the FormatMessage function within the Windows API to generate message strings from system error codes. I noticed that for some error codes the full message doesn't appear to be created.
Take this sample program as an example:
int main()
{
wchar_t * buffer = nullptr;
FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
ERROR_SYSTEM_PROCESS_TERMINATED,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&buffer),
0,
nullptr);
std::wcout << buffer << std::endl;
return 0;
}
According to MSDN I should see the following:
{Fatal System Error}
The %hs system process terminated unexpectedly with a status of 0x%08x (0x%08x 0x%08x). The system has been shut down.
However, in the sample program I will see:
{Fatal System Error}
The %hs system process terminated unexpectedly with a status of 0x
I noticed that ERROR_UNHANDLED_EXCEPTION also doesn't create the full message (when compared to the list on MSDN). Both of the expected messages contain 0x%08 placeholders, but the message ends after 0x.
From what I can see, other error messages appear to match the lists on MSDN (i.e. the issue appears to be restricted to ERROR_UNHANDLED_EXCEPTION and ERROR_SYSTEM_PROCESS_TERMINATED).
Credit to engf-010 - you get the same if you use the Error Lookup tool in Visual Studio (Tools - Error Lookup). The error codes are 574 and 591.
Does anyone know why these messages are being cropped?
Is there anyway to get the full message?
The messages you mention (ERROR_UNHANDLED_EXCEPTION and ERROR_SYSTEM_PROCESS_TERMINATED) have printf-style inserts (%08x). However, FormatMessage uses %0 to terminate a message.
My guess is that there's another avenue where these messages are returned by the system with the printf-style placeholders already populated; these messages, in their raw form, are not meant to be handled by FormatMessage.
Given that these messages contain the text (Fatal System Error) or (Application Error), it is not altogether surprising that Windows handles these message specially.
I am trying to get a test page printed from the Windows Driver Kit (WDK) 8.1 Samples (the bitmap sample). Since I did not get any print output, I placed a "GetLastError" call after each call to 'DrvWriteSpoolBuf":
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, (void*)&(pOemPDEV->bmFileHeader), sizeof(BITMAPFILEHEADER));
DWORD pdwReturn = GetLastError();
if (pdwReturn != ERROR_SUCCESS)
ERR("OEMEndDoc: Error printing=%ld\n", pdwReturn);
I received Error 183 !!! From System Error Codes:
ERROR_ALREADY_EXISTS
183 (0xB7)
Cannot create a file when that file already exists.
Alternate version of call above
DWORD res = pOemPDEV->pOEMHelp->DrvWriteSpoolBuf(pDevObj, &(pOemPDEV->bmFileHeader), sizeof(BITMAPFILEHEADER), &dwWritten);
I get res=E_FAIL
(apology for using bold - comments seem to overlook this result though)
How can I get such an error from printing ? (either to LPT1 or FILE: port)
I have tested the code by saving to a bitmap the exact contents I am trying to send to he spooler, the bitmap was created correctly.
...I apologize for not including more code, it is available at the link I posted above... Windows Driver Kit (WDK) 8.1 Samples
Windows Driver Kit (WDK) 8.1 Samples\OEM Printer Customization Plug-in Samples\C++\bitmap
It seems that, because of a function that was implemented and not disabled, there were two different methods to process image data... I was not aware that each sent their output to the spooler (generating the ERROR_ALREADY_EXISTS... is my guess)
(more precisely, while I did not implement FilterGraphics, but only ImageProcessing, I also should have returned S_FALSE for FilterGraphics in the GetImplementedMethod)
Using the following code, more or less copy-pasted from the MSDN example of
GetAdaptersAddresses, I get the return value 122, which means ERROR_INSUFFICIENT_BUFFER (according to this system error code list).
ULONG outBufLen = 150000; // Tried for different (large) values here...
PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
DWORD dwRetVal = GetAdaptersAddresses(AF_INET, 0, NULL, pAddresses, &outBufLen);
// ....
free(pAddresses);
The documentation of GetAdaptersAddresses does not list ERROR_INSUFFICIENT_BUFFER as one of the expected return values. (It lists ERROR_BUFFER_OVERFLOW, which should adjust outBufLen to the needed value, but that remains unchanged).
Using GetAdaptersInfo instead leads to the same symptoms.
This error does not occur on my development machine, but on one virtual and one real clean Windows 7 x86 SP1 installation (added the VC++ redistributables).
As a c++ newbie, am I doing something wrong? What could cause this error and how to fix it? =)
First of all, you can - as others suggested - do two calls, to find out required buffer size, and then do the query itself. Especially if you are seeing the error, your first try would be to ask API what size it expected.
Second, you need to know that this API is not quite safe in 32-bit processes consuming high amounts of memory, so that buffers span into higher 2GB of address space. API might start acting in a weird way, either due to its own bug, or a bug in an underlying layer. See details on this on MS Connect here: GetAdaptersAddresses API incorrectly returns no adapters for a process with high memory consumption.
The fact that error code is not "one of the expected return values" tells for the versions that the error comes from an underlying layer and this API just passes it up on internal failure. As a clue, having disabled some network adapter on the system, you might get rid of the error.
Visual Studio deployed a library named "IPHLPAPI.dll" together with my project which caused the problem. Deleting this file solved it.
Why this was the case is subject to further research =)
First, a buffer is a block of memory.
So insufficient could mean that you haven't given it enough memory somehow. Our could be a block of memory which you don't have access to. Maybe the address doesn't even exist.
Look at this:
ERROR_INSUFFICIENT_BUFFER
122 (0x7A)
The data area passed to a system call is too small.
This sounds really like the buffer hasn't got enough allocated memory. Or similar.
Maybe the
outBufLen
has to be a specific length, maybe the size of the memory block. Because sometimes it doesn't check for the 'name' but tries to compare for each of the variables size. This idea came from the High Level Shader Language.
So i would try to look a bit more on the:
ULONG outBufLen = 150000; // Tried for different (large) values here...
PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
Good luck!
To know the exact buffer size required, you can just pass NULL into pAddresses and size will be set to the required size. You may want to rewrite your code slightly to make that work;
DWORD rv, size = 0;
PIP_ADAPTER_ADDRESSES adapter_addresses;
rv = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &size);
if (rv != ERROR_BUFFER_OVERFLOW)
return false; // ERROR
adapter_addresses = (PIP_ADAPTER_ADDRESSES)malloc(size);
rv = GetAdaptersAddresses(AF_INET, 0, NULL, adapter_addresses, &size);
if (rv != ERROR_SUCCESS) {
free(adapter_addresses);
return false; // ERROR
}
How to get the unique number (serial number/ID) for Processor (CPU), SCSI, Display, and IDE using C++ program other than WMI and asm code?
Since you mention WMI, I assume you are working on Windows. Lookup GetVolumeInformation().
On Windows you can get CPU info from the environment variable *PROCESSOR_** , you can parse the volume serial number from vol, the MAC address from route print
If you want to make it cross-platform (and if this is for software licensing) then an open source platform like Linux raises the problem to a whole new level anyway and requires a different approach. However you can still get a lot of the info by parsing the output from standard tools.
You really should consider WMI. In the old days, the BIOS would have been helpful but its all been replaced by the HAL.
CodeProject is always worth searching in cases like this.
How To Get Hardware Information
The below is the code I use to retrieve the hard drive serial for a game, so that cheaters are permanently banned (and they can't get back in without getting a new drive!):
string GetMachineID()
{
// LPCTSTR szHD = "C:\\"; // ERROR
string ss;
ss = "Err_StringIsNull";
UCHAR szFileSys[255],
szVolNameBuff[255];
DWORD dwSerial;
DWORD dwMFL;
DWORD dwSysFlags;
int error = 0;
bool success = GetVolumeInformation(LPCTSTR("C:\\"), (LPTSTR)szVolNameBuff,
255, &dwSerial,
&dwMFL, &dwSysFlags,
(LPTSTR)szFileSys,
255);
if (!success) {
ss = "Err_Not_Elevated";
}
std::stringstream errorStream;
errorStream << dwSerial;
return string(errorStream.str().c_str());
}
Although there is a potential bug whereupon if Windows is installed onto a drive other than C:\, this is an easy fix.