Turning HResult into actual errorcode, Delphi - delphi

At a certain moment an EOleSysError occurs and the errorcode of that exception is an HRESULT.
Is there a way where I can turn that HResult back into an errorcode or string?

A HRESULT already is an error code. Its meaning depends on the call that was made. In COM, HRESULTs are returned, because exceptions are not allowed. To work around that, it is common to call OleCheck, which checks a HRESULT and raises and exception if it is a value other than S_OK. That is the EOleSysError you are getting. :)
Note however, that HRESULT is already an error code. HRESULT is just an integer. The name is misleading, because the H suggests it is a handle, but it is not.
So there isn't any more information than you have now. The HRESULT value, combined with the documentation of the API you are calling, should give you all the details you need.

Related

delphi read from TMemorystream without position change

i have a TMemory stream that is filled from a proccess, i need to read an other part of it real time.when i use this code :
for i := 0 to j do
begin
FOutputStream.position:=i * 194
stream4.CopyFrom(FOutputStream, 194 );
end;
it return wrong data because the writer process change the position.
so i decided to use Memory property
stream4.CopyFrom( PByte(FOutputStream.Memory)[ i * 194 ] , 194) );
but i got this error
[DCC Error] Unit1.pas(640): E2010 Incompatible types: 'TStream' and
'Byte'
how can i handle this error?
You cannot use CopyFrom directly in this case, because that requires a stream, and you have a pointer.
You could solve this by creating a stream object that wrapped the memory owned by another memory stream. However that is needlessly complex. You merely need to call WriteBuffer.
stream4.WriteBuffer(PByte(FOutputStream.Memory)[i * 194] , 194);
I presume that you know this, but since you are operating from different threads when reading from and writing to the memory stream, you need to make sure that these actions account for any potential thread safety issues.

How to get the Error Code of CDO.Message

I wrote my routines for using CDO.Message. It's working long time ago.
But now, in some site they installed a certificate and then the priorly working version is making errors with all calls.
I used simple variants to hold the CDO.Message COM object.
When I used Send method(?) it returns a HResult.
But it's interesting, because the HResult is unusable for get the error code, because the Send is seems to be a real method which makes Exception on problems.
So the result code is -1 if I set to this value before.
I tried to get the last error code with GetLastError. But this is 0.
I can catch the Exception, but it contains only the error message what is:
"The transport failed to connect to the server"
The VB codes can get the error code which could provide extra information about the problem (or not).
Do you know about a technic to get the error code value from Delphi XE3?
It would be better if we had some source code at hand. Specifically the Delphi declaration of the COM interface.
My guess is that the method is declared as safecall. What this means is that the compiler understands that the method is actually stdcall returning HRESULT, and re-writes the parameters to match. If the true COM method returns an HRESULT other than S_OK then the compiler writes code to check for that and convert the error into an exception.
The exception that is raised will be EOleSysError and that has the property ErrorCode which contains the HRESULT that you are looking for.
So, you need to:
Add an exception handler to catch EOleSysError.
Read the ErrorCode property of the EOleSysError exception instance that you catch.
This is all a little bit round the houses. If you'd prefer to avoid exception handling, then you can always re-write the COM interface declaration to be a true stdcall method returning an HRESULT.

How do I find the address of an EXC_BAD_ACCESS exception?

In How do I recover from EXC_BAD_ACCESS?, I figured out how to recover from an EXC_BAD_ACCESS, but I had the badly accessed pointer stored in a global. Obviously, this won't scale. When I run the code in the iOS Simulator (i386), I can see faultvaddr register in the Exception State Registers section of the debugger when inside my catch_exception_raise function. However, its value isn't the same or close to pointer returned from vm_allocate. Is there a way to get this value dynamically?
Given the catch_exception_raise function below, how would I discover the address that caused the EXC_BAD_ACCESS?
kern_return_t
catch_exception_raise(mach_port_t exception_port,
mach_port_t thread,
mach_port_t task,
exception_type_t exception,
exception_data_t code_vector,
mach_msg_type_number_t code_count)
{
fprintf(stderr, "catch_exception_raise %d\n", exception);
return KERN_SUCCESS;
}
There is a great amount of detail on that in the OS X and iOS Internals book (http://www.newosxbook.com). Listing 11-21 (ibid) in the book actually shows sample code to do so. In a nutshell, you've two options:
A) look at the exception itself from the exception data - convert the state to an arm_thread_state, something like so:
struct arm_thread_state *atsh = &exc.old_state;
printf ("CPSR is %p, PC is %p, etc.\n", atsh->cpsr, atsh->pc);
Or
B) call thread_get_state to the thread port (since you have that right there as argument #2), and get pc (the instruction pointer) or any of the other registers
EDIT
I'm not sure how to make A) work, but the following works (found here) for B) on the 32-bit iOS Simulator. I'm not sure what the arm register equivalent is for __faultvaddr, so you'd have to figure that out before trying arm.
// types from thread_status.h
x86_exception_state32_t x86_exception_state32;
mach_msg_type_number_t sc = x86_EXCEPTION_STATE32_COUNT;
thread_get_state(thread,
x86_EXCEPTION_STATE32,
(thread_state_t)&x86_exception_state32,
&sc);

D3DXGetImageInfoFromFile produces Access violation writing location error

I have a piece of code written below and I'm stuck with it. I've done it before with a different compiler and right now I'm moving into the Visual C++. Every time this function tries to get called this error pops out:
Unhandled exception at 0x0076e124 in SeaQuest.exe: 0xC0000005:
Access violation writing location 0xccccccd0.
Besides, I've written the D3DXGetImageInfoFromFileA's syntax correctly.
class Texture
{
private:
D3DXIMAGE_INFO m_ImageInfo;
public:
bool GetImageInfo(char* filename);
};
bool Texture::GetImageInfo(char* filename)
{
if((D3DXGetImageInfoFromFileA(filename, &m_ImageInfo)) != D3D_OK)
return false;
}
I've also tracked the DirectX debug output but it doesn't show anything.
UPDATE
Now I've defined a D3DXIMAGE_INFO local variable in the implementation of GetImageInfo and have it addressed instead of m_ImageInfo. It works!. I don't know what is the problem with my private member that the Access violation writing rises for that. Hope someone guide me.
ANSWER
I was using Texture class as a pointer variable in another class and the reason was to not instantiating the pointer to a new Texture class or I could use a non pointer variable then copy class into it but losing the benefits of referencing. 0xC0000005 is near to 0 so it means there is a NULL pointer that it's trying to get addressed. I'll keep it in mind hope you will too!

IntPtr causing memory leak?

This function is in a loop. When I run the program, the line with IntPtr is giving me memory problems, I've put delete[], but it still doesn't solve the memory problem, can anyone help please? thanks
void showImage(IplImage *img,System::Windows::Forms::PictureBox^ picturebox)
{
IntPtr ip(new unsigned char[img->widthStep*img->height]); // this line causing memory usage to keep going up very fast
//memcpy(ip.ToPointer(),img->imageData,img->widthStep*img->height);
//picturebox->Image = gcnew Bitmap(img->width,img->height, img->widthStep, System:rawing::Imaging::PixelFormat::Format24bppRgb, ip);
delete[] ip;
}
This is C++\CLI
It is rather sad that this code compiles, but that is by design. The delete operator applied to a managed type doesn't actually free any memory. It calls the IDisposable::Dispose() method on the passed object. It is rather sad that this even works, the IntPtr gets boxed to turn it into an object and then checked to see if it implements the IDisposable interface. It doesn't of course, nothing happens.
You have to pass the pointer that you got back from the new operator. Don't forget to do this in a finally block so an exception cannot cause a leak.
Btw, there are more complications in the code that you commented. The Bitmap constructor you use requires you to keep the IntPtr valid, you cannot release the memory until the Bitmap is no longer used. So using delete isn't actually valid. Consider using Bitmap.LockBits() instead to get a pointer to a Bitmap that manages its own memory. And watch out for stride.

Resources