Error reading character of string - Access violation error C++ - c++

I working with a Kinect v2 related project in C++ while I cannot use Depth Frame (BYTE*) outside the function.
It works for first some minutes I think by luck so.
Then I got errors like:
Error reading characters of string
and Access violation error and no symbols loaded for kinect20.dll at some point of time.
Here is the method I am calling the values.
BYTE* bodyIndex = new BYTE[512*424]; // initialization
HRESULT frameGet(){
//Initialization method if success
hr = pDepthFrame->AccessUnderlyingBuffer(&m_nDepthBufferSize, &bodyIndex); //Kinect dll method
prints(depth[300]); // Prints the value every time
return hr;
}
HRESULT getDepthFrame(){
if frameGet is success
prints(bodyIndex[300]); // throws error reading character of string
return hr;
}
Can anyone please explain how I can access the bodyIndex data everytime.
I didnt get any response when posted the full code so need the logic how c++ works.
If assumption is right the depth data got cleaned up after sometimes by kinectdll so it reflects.
I tried with memcpy the error still there.
Thanks in advance.

According to https://msdn.microsoft.com/en-us/library/microsoft.kinect.kinect.idepthframe.accessunderlyingbuffer.aspx
you don't need to allocate the memory.
Gets a pointer to the depth frame data.
public:
HRESULT AccessUnderlyingBuffer(
UINT *capacity,
UINT16 **buffer
)
buffer Type: UINT16 [out] When this method returns, contains the
pointer to the depth frame data.
If I understand the spec correctly you have always call AccessUnderlyingBuffer() before access to it.

Related

WPD API Detect if Device is a Phone?

EDIT: Full source code was requested. Below is a barebones implementation in order to replicate the bug. Content enumeration is removed, however the crash ocurrs on the first object call anyway. In this case, the WPD_DEVICE_OBJECT_ID object.
LINK TO CPP (Bug begins at line 103)
LINK TO QMAKE.PRO (I'm using Qt)
In my project I use the WPD API to read the contents of a mobile device. I followed the API to a tee and have successfully implemented content enumeration.
However, if a USB drive is connected, the WPD API will also sometimes detect that as a device. My program will go ahead and begin content enumeration anyway. I don't want that. I only want to enumerate mobile devices.
The problem is that during content enumeration, when my program attempts to retrieve a property of an object on the USB drive, it crashes. Here are the crash details:
Problem Event Name: BEX
Application Name: UniversalMC.exe
Application Version: 0.0.0.0
Application Timestamp: 5906a8a3
Fault Module Name: MSVCR100.dll
Fault Module Version: 10.0.40219.325
Fault Module Timestamp: 4df2be1e
Exception Offset: 0008af3e
Exception Code: c0000417
Exception Data: 00000000
OS Version: 6.1.7601.2.1.0.768.3
Locale ID: 1033
Additional Information 1: 185e
Additional Information 2: 185ef2beb7eb77a8e39d1dada57d0d11
Additional Information 3: a852
Additional Information 4: a85222a7fc0721be22726bd2ca6bc946
The crash occurs on this call:
hr = pObjectProperties->GetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, &objectName);
hr returns FAILED and then my program crashes.
After some research I've found that exception code c0000417 means a buffer overflow occurred? Correct me if I'm wrong but, is this a vulnerability in the WPD API? If so, how could I detect ahead of time that this device is not a mobile device?
Thanks for your time!
I ended up paying someone to help me pinpoint the issue.
The problem was that the root object (WPD_DEVICE_OBJECT_ID) would not return an object name no matter what (Not true for all devices).
The solution was to simply begin content enumeration FROM the root object and only check the names of its children. In my original implementation, I assumed every object has a name, but apparently that is not the case. The root object is the exception.
Here is a snippet:
CComPtr<IEnumPortableDeviceObjectIDs> pEnumObjectIDs;
// Print the object identifier being used as the parent during enumeration.
//qDebug("%ws\n",pszObjectID);
// Get an IEnumPortableDeviceObjectIDs interface by calling EnumObjects with the
// specified parent object identifier.
hr = pContent->EnumObjects(0, // Flags are unused
WPD_DEVICE_OBJECT_ID, // Starting from the passed in object
NULL, // Filter is unused
&pEnumObjectIDs);
// Enumerate content starting from the "DEVICE" object.
if (SUCCEEDED(hr))
{
// Loop calling Next() while S_OK is being returned.
while(hr == S_OK)
{
DWORD cFetched = 0;
PWSTR szObjectIDArray[NUM_OBJECTS_TO_REQUEST] = {0};
hr = pEnumObjectIDs->Next(NUM_OBJECTS_TO_REQUEST, // Number of objects to request on each NEXT call
szObjectIDArray, // Array of PWSTR array which will be populated on each NEXT call
&cFetched); // Number of objects written to the PWSTR array
if (SUCCEEDED(hr))
{
// Traverse the results of the Next() operation and recursively enumerate
// Remember to free all returned object identifiers using CoTaskMemFree()
for (DWORD dwIndex = 0; dwIndex < cFetched; dwIndex++)
{
//RECURSIVE CONTENT ENUMERATION CONTINUES HERE
//OBJECT NAME CHECKING CONTINUES IN THE RECURSIVE FUNCTION
// Free allocated PWSTRs after the recursive enumeration call has completed.
CoTaskMemFree(szObjectIDArray[dwIndex]);
szObjectIDArray[dwIndex] = NULL;
}
}
}
}
The solution is exactly what the sample project shows to do, however, I made the mistake of checking the name of the root object. So don't do that.
Get the object name if there is no "original file name"
hr = pObjectProperties->GetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, &objectName);
if(FAILED(hr)) {
hr = pObjectProperties->GetStringValue(WPD_OBJECT_NAME, &objectName);
}

Using new to allocate memory for unsigned char array fails

I'm trying to load a tga file in c++ code that I got from google searching, but the part that allocates memory fails. The beginning of my "LoadTarga" method includes these variables:
int imageSize;
unsigned char* targaImage;
Later on in the method the imageSize variable gets set to 262144 and I use that number to set the size of the array:
// Calculate the size of the 32 bit image data.
imageSize = width * height * 4;
// Allocate memory for the targa image data.
targaImage = new unsigned char[imageSize];
if (!targaImage)
{
MessageBox(hwnd, L"LoadTarga - failed to allocate memory for the targa image data", L"Error", MB_OK);
return false;
}
The problem is that the body of the if statement executes and I have no idea why the memory allocation failed. As far as I know it should work - I know the code compiles and runs up to this point and I haven't seen anything yet in google that would show a proper alternative.
What should I change in my code to make it allocate memory correctly?
Important Update:
Rob L's comments and suggestions were very useful (though I didn't try _heapchk since I solved the issue before I tried using it)
Trying each of fritzone's ideas meant the program ran past the "if (!targaImage)" point without trouble. The code that sets "targaImage and the if statement checks if memory was allocated correctly has been replaced with this:
try
{
targaImage = new unsigned char[imageSize];
}
catch (std::bad_alloc& ba)
{
std::cerr << "bad_alloc caught: " << ba.what() << '\n';
return false;
}
However I got a new problem with the very next bit of code:
count = (unsigned int)fread(targaImage, 1, imageSize, filePtr);
if (count != imageSize)
{
MessageBox(hwnd, L"LoadTarga - failed to read in the targa image data", L"Error", MB_OK);
return false;
}
Count was giving me a value of "250394" which is different to imageSize's value of "262144". I couldn't figure out why this was and doing a bit of searching (though I must admit, not much searching) on how "fread" works didn't yield info.
I decided to cancel my search and try the answer code on the tutorial site here http://www.rastertek.com/dx11s2tut05.html (scroll to the bottom of the page where it says "Source Code and Data Files" and download the zip. However creating a new project, putting in the source files and image file didn't work as I got a new error. At this point I thought maybe the way I converted the image file from to tga might have been incorrect.
So rather than spend a whole lot of time debugging the answer code I put the image file from the answer into my own project. I noted that the size of mine was MUCH smaller than the answer (245KB compared to 1025 KB) )so maybe if I use the answer code's image my code would run fine. Turns out I was right! Now the image is stretched sideways for some reason but my original query appears to have been solved.
Thanks Rob L and fritzone for your help!
You are NOT using the form of new which returns a null pointer in case of error, so it makes no sense for checking the return value. Instead you should be aware of catching a std::bad_alloc. The null pointer returning new for you has the syntax: new (std::nothrow) unsigned char[imageSize];
Please see: http://www.cplusplus.com/reference/new/operator%20new[]/
Nothing in your sample looks wrong. It is pretty unlikely that a modern Windows system will run out of memory allocating 256k just once. Perhaps your allocator is being called in a loop and allocating more than you think, or the value of imagesize is wrong. Look in the debugger.
Another possibility is that your heap is corrupt. Calling _heapchk() can help diagnose that.
Check the "memory peak working set" in windows tasks manager and ensure how much memory you are really trying to allocate.

Accessing buffer using C++-AMP

Could somebody please help me understand exactly the step that is not working here?
I am trying to use C++-AMP to do parallel-for loops, however despite having no trouble or errors going through my process, I can't get my final data.
I want to pull out my data by means of mapping it
m_pDeviceContext->Map(pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
{
blah
}
But I've worked on this for days on end without even a single inch of progress.
Here is everything I do with C++-AMP:
Constructor: I initialise my variables because I have to
: m_AcceleratorView(concurrency::direct3d::create_accelerator_view(reinterpret_cast<IUnknown *>(_pDevice)))
, m_myArray(_uiNumElement, m_AcceleratorView)
I copy my initial data into the C++-AMP array
concurrency::copy(Data.begin(), m_myArray);
I do stuff to the data
concurrency::parallel_for_each(...) restrict(amp)
{
blah
}
All of this seems fine, I run into no errors.
However the next step I want to do is pull the data from the buffer, which doesn't seem to work:
ID3D11Buffer* pBuffer = reinterpret_cast<ID3D11Buffer *>(concurrency::direct3d::get_buffer(m_myArray));
When I map this data (deviceContext->Map) the data inside is 0x00000000
What step am I forgetting that will allow me to read this data? Even when I try to set the CPU read/write access type I get an error, and I didn't even see any of my references do it that way either:
m_Accelerator.set_default_cpu_access_type(concurrency::access_type::access_type_read_write);
This creates an error to say "accelerator does not support zero copy"
Can anyone please help me and tell me why I can't read my buffer, and how to fix it?
The following code should work for this. You should also check that the DX device you and the C++AMP accelerator are associated with the same hardware.
HRESULT hr = S_OK;
array<int, 1> arr(1024);
CComPtr<ID3D11Buffer> buffer;
IUnknown* unkBuf = get_buffer(arr);
hr = unkBuf->QueryInterface(__uuidof(ID3D11Buffer), reinterpret_cast<LPVOID*>(&buffer));
This question has an answer that shows you how to do the opposite.
Reading Buffer Data using C++ AMP

WinInet InternetReadFile returns 0x8007007a (The data area passed to a system call is too small)

I have an issue with WinInet's InternetReadFile (C++).
In some rare cases the function fails and GetLastError returns the mentioned error 0x8007007a (which according to ErrorLookup corresponds to "The data area passed to a system call is too small").
I have a few questions regarding this:
Why does this happen in some rare cases but in other cases works
fine (I'm talking of course about always downloading the same ~15MB
zip file) ?
Is this really related to the buffer size passed to the API call ? I am using a const buffer size of 1024 BYTES for this call. Should I use a bigger buffer size ? If so, how can I know what is the "right" buffer size ?
What can I do to recover during run time if I do get this error ?
Adding a code snippet (note that this will not work as is because some init code is necessary):
#define HTTP_RESPONSE_BUFFER_SIZE 1024
std::vector<char> responseBuffer;
DWORD dwResponseBytesRead = 0;
do
{
const size_t oldBufferSize = responseBuffer.size();
responseBuffer.resize(oldBufferSize + HTTP_RESPONSE_BUFFER_SIZE);
// Now we read again to the last place we stopped
// writing in the previous iteration.
dwResponseBytesRead = 0;
BOOL bInternetReadFile = ::InternetReadFile(hOpenRequest, // hFile. Retrieved from a previous call to ::HttpOpenRequest
(LPVOID)&responseBuffer[oldBufferSize], // lpBuffer.
HTTP_RESPONSE_BUFFER_SIZE, // dwNumberOfBytesToRead.
&dwResponseBytesRead); // lpdwNumberOfBytesRead.
if(!bInternetReadFile)
{
// Do clean up and exit.
DWORD dwErr = ::GetLastError(); // This, in some cases, will return: 0x7a
HRESULT hr = HRESULT_FROM_WIN32(dwErr); // This, in some cases, will return: 0x8007007a
return;
}
// Adjust the buffer according to the actual number of bytes read.
responseBuffer.resize(oldBufferSize + dwResponseBytesRead);
}
while(dwResponseBytesRead != 0);
It is a documented error for InternetReadFile:
WinINet attempts to write the HTML to the lpBuffer buffer a line at a time. If the application's buffer is too small to fit at least one line of generated HTML, the error code ERROR_INSUFFICIENT_BUFFER is returned as an indication to the application that it needs a larger buffer.
So you are supposed to handle this error by increasing the buffer size. Just double the size, repeatedly if necessary.
There are some discrepancies in question. It isn't clear that you are reading an HTML file for one, 15MB seems excessive. Another is that this error should repeat well. But most troubling is the error code value, it is wrapped in an HRESULT, the kind of error code that a COM component would return. You should be getting a Windows error code back from GetLastError(), just 0x7a and not 0x8007007a.
Do make sure that your error checking is correct. Only ever call GetLastError() when InternetReadFile() returned FALSE. If that checks out (always post a snippet please) then do consider that this error is actually generated upstream, perhaps the firewall or flaky anti-malware.

How can I determine why a call to IXMLDOMDocument::load() fails?

I am trying to debug what appears to be an XML parsing issue in my code. I have isolated it down to the following code snippet:
HRESULT
CXmlDocument::Load(IStream* Stream)
{
CComVariant xmlSource(static_cast<IUnknown*>(Stream));
VARIANT_BOOL isSuccessful;
* HRESULT hr = m_pXmlDoc->load(xmlSource, &isSuccessful);
return (hr == S_FALSE) ? E_FAIL : hr;
}
Note: m_pXmlDoc is of the type CComPtr<IXMLDOMDocument>.
It appears that the call to IXMLDOMDocument::load() (marked with the *) is failing - IOW, it is returning S_FALSE.
I am not able to step into load() to determine why it is failing, as it is a COM call.
The MSDN page for this method doesn't seem to be giving a lot of insight.
I have a few hunches:
The XML is not well-formed
The XML file is too large (approximately 120MB)
It is a memory-related issue (the process size gets to > 2GB at the time of failure)
NB: A registry key has been set to allow the process size to be this large, as the largest valid process size for WinXP, AFAIK, is 2GB).
Any ideas as to why this call could be failing?
The following code will fetch the specific parser error from the DOM and it's location in the source XML.
CComPtr<IXMLDOMParseError> pError;
CComBSTR sReason, sSource;
long nLine = 0, nColumn = 0;
m_pXmlDoc->get_parseError(&pError);
if(pError)
{
pError->get_reason(&sReason);
pError->get_srcText(&sSource);
pError->get_line(&nLine);
pError->get_linepos(&nColumn);
}
sReason will be filled with the error message. sSource will contain the errorneous source line in the XML. nLine and nColumn should get set to the line number and column of the error, although in practice these two aren't always set reliably (iirc, this is especially true of validation errors, rather than parser/well-formedness ones).
If the XML file is opened by another Task or Proccess the Load() method
can't load the file but it doesn't state that the loading has failed.
I consider this behaviour as a bug.
So you have to check the Property documentElement - if it is null, load() has failed, too.