ActiveX/OCX can't read from disk - activex

I just need some ideas/hints that push me into the right direction. Since the whole story is a bit more complicated I make it short: I have an OCX that itself uses a more complex DLL. When running this ActiveX it seems disk read operations fail (but I'm not 100% sure if this is the reason) and the underlying DLL causes crashes on some strange positions in code.
So my question: are there any special permissions/manifest information/whatever needed for such an ActiveX when running it with Windows 7?
Thanks!

OK, solved, is was a problem of incompatible libraries that caused a crash on a strange position in code.

Related

Porting embedded Dll from eVC to VS2008 causes not finding dll

I am trying to port an unmanaged C++ Dll from one embedded device to another and am facing some strange problems which I think must have something to do with memorymanagement and/or compilers. I am not posting much code but describe what I tried as I have tried too many different things to post all code and I think the problem must be somewhere deeper within.
The first device is running WinCE 5.0 and is compiled using embedded Visual C++ 4.0.
The second device is running Windows Embedded Compact 7 (I will call it WinCE 7 for simplicity) and is compiled using VS2008. Both devices have their own SDKs designed for the boards.
On the first device the Dll is running without any problems, but on the second device the with ne new SDK compiled Dll is not working. Having a C# applikation on the second device I tryed PInvoke to access the dll but on the PInvoke line in Debug Mode got the error message:
Can't find PInvoke DLL NAME.dll
After some research I learnd this error can have differend causes:
Missing dependencies of the native library you are calling into.
The native assmebly was compiled for the wrong subsystem (i.e. desktop, not CE)
The native assembly was compiled for the wrong processor (i.e. x86 and not ARM)
Not enough virtual memory for the DLL to load.
I used peinfo to check the dll. All dependencies are being found on the device, it is compiled for WinCE 7 and the processor type is right. (I would have been surprised if not, using the right SDK) So there still is number 4: not enough virtual memory. But WinCE5 is limited to 32MB virtual memory and running while WinCE7 can have up to 2GB?
So I started to try some things to narrow the error in and will tell you my results.
First I took my dll compiled for the first device and tryed to use it on the second device. Surprisingly the .net application can find and PInvoke this one. But some functions inside the Dll don't seem to be running right so I guess I have to use the right SDK. But having the right code for both dll I know the exports must be right. I am aware the two compilers use different c++ name mangling styles so that is not the problem, too.
Next I wrote a simple c++ application on VS2008 using the new SDK to Load the Dll from there. On the first device the application runs this way but now on my remote Display on running on the second device I get the Error Message:
Unable to import library NAME.dll ! Program will exit.
At least now I know it has nothing to do with .net and PInvoke. But further on I made a simple new dll using VS2008 and the new SDK and ne .net application is able to PInvoke it. So there must be something in the code that doesn't like to be Loaded. :-/
After some hours of searching through the code I realised the system doesn't like some global variables. I know global variables are bad and I would be glad if they wouldn't be there, but I have not started the code and over the years they got more and more before me dealing with it, so they would be very hard to erase right now.
These globals are instances of classes. Some of them seem to be bad, some others seem to be ok. Confusingly they all are instances of classes and I don't know why there are good and bad ones. When I comment out the bad globals, the application is able to PInvoke the Dll. One of the bad globals is enough to make to applikation not find the Dll.
Why is it like this using VS2008 with WinCE 7 but not using eVC4.0 with WinCE 5? And what is the problem with the globals? How can I solve this problem? At best the same code should be working for both compilers but first I need some ideas, what is wrong with the second compiler.
I have found the solution to my Dll loading problem. The two systems have a different behaviour on #pragma pack. So eventually there was missalignment while loading the dll what made the dll crash. Because of the globals it was in the loading process of the dll, so the error message did not say something about missalignment but the standard "Can't find PInvoke DLL".

Esent crashes with Windows 8 on a Delphi project

I've been using ESENT for my projects quite extensively and I really love how easy and fast it works. And stable too!!
But I have a HUGE problem with Windows 8!!! Regardless of how I link to the esent.dll (dynamically or statically) whenever I call something other than JetSetSystemParameter, the dll is crashing, takig my app down the cliff.
Unfortunately I still can't get it running. My code had no problem running with Windows 7 or older. But with Windows 8 I get esent.dll crashing when I try to create an instance (floating point invalid operation).
I tried all possible calling conventions. This is definitely NOT the problem. I tried some more and discovered this weird situation: 1. I created a demo application using VS 2012 and JetCreateInstance worked just fine. 2. Exactly the same code in Delphi XE3 will send esent.dll crashing. 3. I created a DLL using VS 2012, exporting the method that worked perfectly in the above demo app, thinking it's a Delphi bug. 4. And then I loaded the DLL in a demo Delphi project (tried with 6, XE2 and XE3). Called the method and BOOM. Same crash.
Now my assumption is that Microsoft won't allow?!? any other developer environment to work correctly with the esent.dll. Is this possible???
The error, a floating point invalid operation, makes the problem sound as though it is related to the floating point control word.
By default Delphi unmasks floating point exceptions. So when code asks the floating point unit to perform operations that result in errors, the FPU signals which is then converted to an exception.
But most other Windows development environments mask these exceptions on the FPU. Such code is written under the assumption that the execution environment has FPU exceptions masked. But if you call a DLL from Delphi, the execution environment will have unmasked FPU exceptions, breaking that assumption. I suspect that if you mask FPU exceptions then your problems will disappear.
To test if this is the problem, you can simply add this to your code, executed early in its life:
Set8087CW($027F);
This will mask all exceptions and set the FPU control word to the default Windows setting.
In the longer term you may wish to mask exceptions before each call to this DLL, and then restore the FPU control word when the call to the DLL returns.
That is a slightly dangerous game using the libraries that are supplied with Delphi since Set8087CW is not threadsafe due to its use of the global variable Default8087CW. If you wish to read more about that issue, I refer you to QC#107411.

Getting External Exception C0000006 in D2006 app - how can I force delphi to load the whole executable?

I get this occasionally when exiting my app - my app is running the EXE over a network. I understand it's a page fault when part of the EXE is loaded on demand.
I have also observed it in the OnDrawCell method of a TDrawGrid, so I'm mystified how that might have caused a page load. Also, the exception kept happening.
So my questions:
Can Error C0000006 result from other causes? I have made fairly major changes to the way the app manages memory, though nothing out of the ordinary, and I'm confident the code is behaving.
How can you make the app load all of itself into memory on startup (in Delphi 2006 - I understand there are directives for later versions of Delphi).
TIA
The directive $SetPEFlags seems to be part of Delphi 2006, at least Hallvard talks about it in this article in the context of D2006. Have a look here on how to use it.
We experience this too. The system puts some of the executable pages out to swap and then fails to page it back some time later. It appears to be related to network connections being restored after sleep.
The only viable solution that we have found is to locate executables on the local machine.
This exception C0000006 also often occurs if your software is run from a network drive. To prevent that problem you can combine the flag
{$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP}
with the following flag:
IMAGE_FILE_NET_RUN_FROM_SWAP = $0800;
{$SetPEFlags $0C00}

Stack Overflow error on one PC, no errors on the other?

The problem is this:
I have a project developed in Delphi XE on my laptop. When I run it on my desktop PC, I get a "stack overflow" exception on this line (I also used Writeln() on different parts of the code and just this line is the source of the problem):
S_List.LoadFromFile('Test.txt');
(S_List is a local TStringList which is created before this line)
But, when I run the same exact project on my laptop, it works without any errors or exceptions at all. The problem can't be the method itself, because when I change the whole part and write it again using 'TStreamReader', the same exception occurs. This time on StreamReader.ReadLine(). Also, I changed the file location, name, .... Problem still occurs.
It seems like a file system problem, but I don't have the slightest idea how this happens.
Any ideas? Can it be because of a virus or a malware?
P.S: Both (laptop and PC) have Win7 and Delphi XE. Also, both have 2GB RAM.
Edit: Just to be clear, my main goal for asking this question is not finding where the exception lies (that can't happen by giving 1 line of code, can it?). But, instead, how come this error is NOT consistant in different hardwares? What reason can that have? Also, how can I find what causes this inconsistency?
My guess, and guessing is all we can do, is that you have an uninitialised local variable. Or an object that you access after having freed it. I'm not sure how that leads to your stack overflow but almost anything is possible with such a scenario. As well as madExcept you should be using FastMM with full debug settings.
When someone has difficulty diagnosing an exception in a specific environment with a Delphi application I strongly suggest madExcept. It's free for non-commercial use, very easy to setup, and VERY helpful. Install it, enable it for your project, build a debug build, and deploy it to the problem machine. When the exception occurs, you should get a very detailed call stack of where the issue happened.
I would check this:
Is the test file identical on both computers
Do you have the same locale settings on both computers
If Delphi XE has components source, debug TStringList source, maybe there is a bug
As Nathanial suggested, use madExcept or similar library
Create simple program that will just allocate TStringList and load test file. If this works, bug is somewhere else in your code, if this fails bug is probably in TStringList
Check for duplicate DCU's and if possible do a full build of installed libraries and the application to see if the error persists.

Delphi 2010 BSOD Errors

We ported an application from Delphi 7 over to Delphi 2010 and have had customers encountering intermittent BSOD (blue screen of death) errors while running under Windows XP. The errors are very sporadic and have been very hard to track down. FYI : We are using the built-in memory manager from Delphi 2010.
Our first thought was a hardware issue but upgrading system drivers failed to fix the problem.
Has anyone else encountered BSOD issues under XP with Delphi 2010 generated applications? If so, do you have any suggestions on how we might correct this problem?
Thanks for your assistance!
There's nothing in the Delphi core libraries that can cause a BSOD directly. As David pointed out, Delphi programs run in user space. However, if they're sending invalid data to a kernel-space driver, that's a different matter.
You said D7-D2010 update, and the first thing that occurs to me there is the string revamp. Delphi's standard string type has been changed from AnsiString (1 byte per char) to UnicodeString (2 bytes per char) and if you're sending the wrong type of string to a driver or system routine somewhere it might cause strange behavior.
First thing I'd do is run a full build and watch for "implicit conversion" warnings from the compiler. This means that you're mixing string types. Find these and fix them and see if that helps.
Also, if you have any import units for external libraries, and they use APIs that take a string (or more likely a PChar) parameter, make sure they're converted to PAnsiChar. Delphi's already taken care of this for the Windows API stuff used in windows.pas, but if you've got any of your own you need to take care of it yourself.
BSOD can be analyzed opening the crash dump with WinDbg or other tool able to process crash dumps. Even a "minidump" will give enough informations to try to understand where and hopefully why a BSDO occurs. WinDbg can be downloaded freely, and you don't need to install it on the target machine, you can ask your customers to ship the crash dumps to you, and you can analize them offline. Anyway generating a BSOD from user mode code is usually very difficult - but there are ways to crash a system. What kind of error the BSOD displays?
Update: if the error is PAGE_FAULT_IN_NONPAGED_AREA this link explains what happened: http://technet.microsoft.com/en-us/library/cc957625.aspx. It usually a memory-related issue, and it may be that D2010 using more memory than older version may end up to trigger it. Could you run a memtest on those machines (http://www.memtest.org/)?
Ntkrlnpa.exe is not a driver, is the image containing the OS executive and kernel code (the version with PAE support). Using winDbg and the crash dump it is possibile to obtain the call stack leading to the crash.

Resources