For Windows 8 application certification, there are (among other) these requirements:
3.2 Your app must be compiled using the /SafeSEH flag to ensure safe exceptions handling
3.3 Your app must be compiled using the /NXCOMPAT flag to prevent data execution
3.4 Your app must be compiled using the /DYNAMICBASE flag for address space layout randomization (ASLR)
I wasn't able to find out how to enable either of these in C++Builder XE.
For /NXCOMPAT and /DYNAMICBASE, one can use editbin.exe from VS or peflags.exe from Cygwin. Though I would feel more confident about possible side-effects, if there was native way to enable these.
Anyway, I'm totally at loss regarding /SafeSEH.
First, /SafeSEH only applies to x86, not x64 or ARM. It requires that your compiler generate additional tables indicating the function addresses that are considered valid exception handlers for security reasons. There's a slim chance you could do this yourself, but it would require that you look at the fs:0 exception handling chain in your compiled assembly code and enumerate all addresses that are ever pushed on that chain, then describe them as documented here: http://msdn.microsoft.com/en-us/library/9a89h429(v=VS.80).aspx. There's a (slim) chance that your code doesn't actually have any handlers, and they're all in the C++Builder's runtime (might make it easy if the runtime is a separate DLL).
You should try to convince C++Builder to update their compiler to support SafeSEH. It's been around in the Windows platform since XP SP2, and plugs a pretty nasty security hole (exception handler addresses exist on the stack in x86, just waiting for a buffer overflow to put any random address there to be executed)
For the issue related to /NXCOMPAT and /DYNAMICBASE, I have created a request for the C++ Builder linker to support these flags here: https://quality.embarcadero.com/browse/RSP-13072
Using editbin.exe from Visual C++ is hardly an ideal solution, and their linker needs to support these flags natively.
UPDATE: An additional request has been created here for the C++ Builder / Delphi runtime files (DLLs/BPLs) to be distributed with these flags already set, so as to avoid having to use EDITBIN from Visual C++ to set them yourself: https://quality.embarcadero.com/browse/RSP-13231
Related
We have developed a DLL in Delphi 10 that we use in some legacy Delphi 6 applications. The new functionality in the DLL is only for a few clients and is therefore not required to roll out to all our clients. If we try to deploy the Delphi 6 application without the DLL we get the error "The code execution cannot proceed because xxx.dll was not found.". We get the error the moment the app starts to run. Is there a way to prevent this error if the DLL does not exist? In our Delphi 6 code we already use FileExists(xxx.dll) to see if we should make the functionality in the DLL available therefore we don't have the risk that the application will crash if the dll is not present.
We would also be keen to learn where/when the Delphi 6 app checks if the DLL exists because it happens before the Application.Initialize, which is the first line of code in the DPR file.
This type of failure is caused by statically (aka : implicitly) linking the DLL. There is no option if you have chosen to use static linking - the DLL must be present on the system trying to run the application.
There are two ways to allow the DLL to be optionally present.
One is to rewrite the affected sections of code to use dynamic linking (aka : explicit ) for your DLLs instead of static linking. For Delphi 6, this is unfortunately your only option.
The other, an option if you are targeting Windows only and if you are compiling with Delphi 2010 or greater, is to use delayed loading by decorating your import declarations with the delayed directive:
function GetSomething: Integer; external 'somelibrary.dll' delayed;
This is really just syntactic sugar resting on top of what is otherwise dynamic loading, but it does provide an easier path to migrate statically linked code to a dynamic linked model without needing an extensive rewrite.
From Embarcadero :
The delayed directive is useful in the case where the imported routines do not exist on the target operating system on which the application is run. Statically imported routines require that the operating system find and load the library when the application is started. If the routine is not found in the loaded library, or the library does not exist, the Operating System halts the execution of the application. Using the delayed directive enables you to check, at run time, whether the Operating System supports the required APIs; only then you can call the imported routines.
Note: Trying to call a delayed routine that cannot be resolved results in a run-time error (or an exception, if the SysUtils unit is loaded).
In either case, delayed or dynamic loading, you would need to catch the failure to resolve the DLL and gracefully deny users access to whatever functions the DLL provides.
I distribute a Win32 Delphi application that uses ADVAPI32.DLL to call some encryption and decryption routines. It works great on modern versions of Windows, but a few customers use some very old versions of Windows, like Windows Vista and unpatched Windows 7. For those customers, the version of ADVAPI32.Dll is obsolete and sometimes causes decryption errors.
I know that advapi32.dll is a "known" system DLL, and as such it cannot be loaded locally (I mean, from my app folder instead of System32), so how can I solve this issue? I tried using a renamed local copy of the DLL but that didnt work either...
First and foremost, you are not legally allowed to redistribute advapi32.dll. Second, you cannot reliably run newer system DLLs on old systems, they come with dependencies and you need to provide the updated dependencies. Many system DLLs have special protection mechanisms preventing from loading an incorrect one as part of elementary DLL hijacking prevention security mechanisms. And finally, CryptDecrypt and friends, as well as other similar functions are working perfectly fine in Vista and Windows 7. If you encounter issues, is either a bug in your code, or you are simply not respecting the stated restrictions of Crypto API for said platforms. So better post the code you use, and the error you get on those older systems.
Even if you are able to load a different version of advapi32.dll, there is no guarantee that it will actually work on the target systems.
The advapi32.dll is only an interface dll that provides the "public API". Internally it delegates much functionality to the windows kernel, so if this interface changes or the kernel of the target system does not implement a function, your app will crash. You should think of advapi32.dllmore as an interface than an implementation - you call methods provided by it but it may do different things on different platforms that provide a version of the dll.
On Windows Nano Server the advapi32.dll is only a forwarding dll that delegates API calls to other DLLs ("OneCore" API).
In our program we are using a web service to pull back data from a third party into our program.
Ever since we updated to Delphi XE from Delphi 2009, Windows server 2003 users are receiving the following error message when making a SOAP call to the web service.
msvcrt.dll on Server 2003 does not have the procedure _ftol2_sse which is now being called for some reason..
I know this procedure was not being called when we had our source code on Delphi 2009 because I don't get this error on Windows server 2003 when running those builds.
Is this feasible? Could a change in the IDE affect which dll procedures are being called? Does anyone have any insight or ideas on how I might track down or fix this error?
Thanks
This is the third similar question you have asked on this topic. I'll attempt to give you some background information and help you work out what is going on.
First of all it's important to know that msvcrt.dll is a system component. It is not the MSVC runtime. It is supplied as part of Windows. Back in the bad old days, in the mid-90s, a lot of devlopers assumed that the MSVC6 runtime was always available. And they neglected to install that runtime as part of their program's installation. This occasionally caused trouble when the install program happened to find a machine without MSVC6.
The MSVC team moved to differently named runtime DLLs, msvcrt70.dll, msvcrt80.dll and so on. And they educated the developers that installing the MSVC runtime should be part of all MSVC application's installation programs.
But the Windows team wanted to help out legacy apps that had installers that assumed MSVC6 runtime was available. So they took the MSVC6 runtime under their control and started shipping it with Windows. I think this started around the time of Windows 2000 or XP.
The point I am trying to make is that msvcrt.dll is a system DLL over which you have no control. In your previous questions you have described your attempts to modify that DLL. Don't do that.
Now, from what I can glean, the version of msvcrt.dll that shipped with 2003 server does not export a function named _ftol2_sse. Hardly surprising since SSE floating point was not widely available back in the days of 2003 server. Clearly something in your system is resulting in an attempt to import _ftol2_sse.
You should be able to work out what is provoking this by using Dependency Walker. Use the functions on the Profile menu to start your application and study closely the logs. You should be able to see the chain of events that lead to an attempt to link to _ftol2_sse.
I'd be surprised if any of the Windows code linked to msvcrt.dll. That library is provided purely as a prop for legacy apps that link against MSVC6. But you never know.
Also try loading your executable in Dependency Walker. Look at the list of imported DLLs. Check to see if msvcrt.dll is in the list. If so, see what functions your executable imports, and if _ftol2_sse is in that list. If so then you'll be able to find it somewhere in the Delphi source code.
From the various similar sounding reports on the web I suspect that the problem you face is benign. Many of the people reporting the same issue can OK the dialogs and have their program continue without problem. This suggests that you can simply suppress the error reporting and so solve your problem. Use the SetErrorMode function to do so. You want to include the SEM_FAILCRITICALERRORS flag.
Be aware that SetErrorMode has a rather perverse interface. Almost all code that I have ever seen uses it incorrectly. Including the code in the Delphi RTL, and so many of the commonly used Delphi third party libraries. Raymond Chen, as usual, explains how to use it correctly.
Could switching compilers provoke the behaviour change? Certainly they could. Either the library code that you are using is implemented differently. Or perhaps the error mode is somehow different at the crucial moment.
Delphi with 64 bit compilation is now in Beta, but only invited beta-testers will get their hands on this version.
What should be tested by the beta testers?
Embarcadero will probably provide a tester's guide for the beta testers. But, here are some ideas:
Memory allocation, alignment, heap and stack. 32-bit could use up to 4GB (well, 3.5) of address space on a 64-bit version of Windows with the /LARGEADDRESSAWARE switch: Delphi64 should be able to use much more. Try allocating 8, 16, and 32 GB. (Even if you have less RAM, the allocation should work since it's a virtual address space.) Now read and write values into it a certain spots: check your allocation and pointers all work. Have a look at what Process Explorer reports for the app. Inspect your stack: it runs top-down, unlike the heap - what does it looks like, what addresses is it using? What does the 16-byte alignment look like? Is that alignment kept for all internal Pascal functions, or only those that call external code? In the 32-bit VCL, there were some bits of code that weren't safe for addresses larger than 2GB. Have those been fixed? Does anything break when it's allocated in, say, the 53rd GB of your program's address space? (Try allocating a huge amount, and then dynamically creating forms, controls etc - they'll probably be created with high addresses.) Does the memory manager fragment? How fast are memory moves and copies?
Compiler warnings. (This one is important.) Upgrade your programs - compile them without changes, and see what warnings / errors you get; fix any; and then fix bugs that occur even though you weren't warned. What issues did you encounter? Should the compiler have warned you, but didn't? Do you get warnings when truncating a pointer when casting to an integer? What about more complex issues: if you use the Single floating-point type, what happens? Warning, or is it silently represented as a double? What if you pass in a parameter to a method that's a different size - for example, PostMessage and you pass in a 32-bit-sized value to the handle parameter - will the compiler be smart enough to guess that if the size is wrong, your code might be wrong, even though it's often valid to pass a smaller type to a larger parameter? Under what circumstances should it do so? (Another thing: what if you pass a 64-bit pointer to a 32-bit type in a method expecting a pointer to a 64-bit type - the type safety should yell loudly, but does it? A use case for that is reading blocks from a binary file, something that could easily cause problems with the wrong-sized types.) ...etc.
Compiler warnings are probably one of the most useful tools for people who upgrade, so the compiler should produce as many as possible, in as many situations as possible, with as few false positives as possible. Remember Delphi is used by a wide range of programmers - you may know what a warning means or recognize bad code even if the compiler is silent, but anything that will help novices (or good programmers having a bad day) is important.
Custom controls & WinAPI. You probably have a few customs controls or bits of code that make heavy use of Windows APIs instead of the VCL. Are there any Windows API-specific issues?
Language compatibility. Does the old file IO code work - AssignFile, etc? RTTI? If you have an event signature with an Integer type, and an event handler is auto-created by the IDE, is it generated as Integer or a size-specific integer type depending on the platform that's currently set? What if the event is NativeInt, what then? (I've seen bugs in event handler method signature generation before, though only on the C++ side.)
Different types of application. We can assume GUI programs have been tested well. What about console and service applications?
C++Builder compatible file generation. C++Builder won't be 64-bit in XE2, but hopefully will in XE3. Delphi can produce ..hpp and .obj files for Pascal code, though. What happens in for a 64-bit platform? Can you produce those files, even though they're useless? Does the compiler generate C++-specific warnings in 64-bit mode, or does it give up and not let you do it? In 32-bit mode, is there anything you can do for 64-bit compatibility that will generate a warning building the C++ header?
Linker. Can you link .lib and .obj files created with other compilers? (I'd expect .lib yes, .obj no.) Does the linker use COFF or OMF for 64-bit - have they changed? This thread implies an ELF format. Has it changed for 32-bit too? Does this affect the DCU format, will we still get ultra-fast compiling / linking?
COM and 64-bit plugins. Are there any marshalling issues? Can you build a 64-bit plugin for Explorer now?
Calling conventions. Safecall's supposed to be the only 'calling convention' (if safecall counts...) that's still different - does it still work? Function and procedure pointers, and closures (object method pointers): do they work? What do they look like in the debug inspector? Given all calling conventions are now the same, if you mix calling conventions in your method declaration and your calling pointer, what happens? Is there any legacy stuff around that will break or does it transparently work? Does it now give you an (erroneous) warning that the types are incompatible?
Floating point math. The Delphi 64 preview said floating point would be double only. Can Delphi handle long doubles? Are there any compatibility routines for handling the old Real (48 bits, I think??) type? Does the compiler generate SSE or SSE2 code or a mix, and how good is it?
Performance. This is their first go at a 64-bit compiler; it will probably be refined over the next few releases. But are there any obvious performance problems, with:
compiling; linking; IDE insight?
Generated code: are your programs faster or slower? Is FP math faster or slower? Does inline work, and does it generate any unnecessary header/footer bits around inlined methods?
Debugging. This is probably easiest to test through the whole process of testing everything else, but how well does the 64-bit debugger work? Does it have all functionality of the 32-bit one? Do IDE debug visualiser plugins still work? What if you debug a non-Delphi 64-bit program or attach to a process, instead of running normally?
Misc Is Delphi itself compiled as a 64-bit program? If not, why not? (Are they "eating their own dogfood"?) Code inspect the new VCL (assuming the preview comes with VCL source.) What have they done to make the VCL 32/64 compatible? Are there any errors, or if you already know 64-bit code well from other IDEs, are there better approaches they could take instead?
...etc. I could keep typing for hours, but I think that's a good start though :)
I'm sure Embarcadero will provide some testing guidance. For what it's worth this is what I'd test; Mostly because it's the stuff I care about:
Small console application should work.
Allows me to allocate a 4Gb flat hunk of memory. Don't really need that, but it will be the first thing my console application tries, right after WriteLn('I''m using all 64 bits!!!!');
Can create 64bit DLL and the DLL can be imported and used from other environment.
Do some simple things and look at the generated assembler, just for kicks.
Can create Firebird 64bit compatible UDF's
I'd probably try compiling my "utility" units, because they do an fair amount of pointer manipulation, see how they work.
If the VCL works I'd put it through it's paces: create small form, put a button on it, ShowMessage.
Generally speaking the only thing I really need 64bit Delphi for is Firebird 64bit UDFs. That's minor and can be "fixed" using FPC. I assume the best testing will be done by people that actually need 64 bit delphi. And those people don't need testing suggestions.
The base foundation stuff would come first, to ensure that Delphi 64 can be used for what Delphi 32 can't be used:
compiler correctness: first and foremost, no internal errors, no incorrect code-gen
ability to compile to 64bit DLLs and stability of those
stress the memory manager: with large objects, fragmented allocation, multi-threaded allocations, etc.
multi-threading: is it stable? is it efficient? does it scale? that for core RTL functions and units, and not forgetting the reference-counted types.
floating point: does the compiler deliver proper SSE? are the maths functions properly implemented and correct? what happens if you stress the SSE register set with complex expressions?
And as a bonus, ability to accept 64bit object files from the usual C++ compilers.
Non visual stuff ... I think. There is already success from some beta testers that already ported their libraries. I don't know the preview but from the information I don't have I would assume more complex non visual scenarios currently make sense. Anyone who knows it better please correct me ...
I think the preview first allows you to setup a migration strategy, this would be my intention. The VCL ... intended to work on one code base and maybe backport your code to purepascal instead of assembler.
Mike
I'm writing delphi app which should have capability of loading plugins. I'm using JvPluginManager as plugin system/manager ;) Now, in the new plugin wizard they say it's better to use .bpl type plugins instead of .dll plugins ... What are the pros of this solution versus dll type plugins?
So far I've found only cons of this solution:
I have to put all the common interface units in separate package so that while loading plugins it won't throw any error about the other package containing common unit
if, let's say, one of plugin developers decides to uses some well-known unit (like synapse), which doesn't have runtime package by default, and the second plugin developer does the same, than bump... it's crash here ...
So, what are actually the pros of using bpls instead of dlls compiled with runtime packages?
Thanks in advance
Another disadvantage to BPL's. When you switch Delphi versions you will have to re-distribute new plugins. After many attempts at attempting to find the perfect plugin system, I ended up with COM and I have never regretted that decision. In a commercial application which has had the plugin requirement for over 8 years, the application has continued to move forward and yet some of the plugins that were released with the first iteration still exist in their ORIGINAL form.
If you choose this method, do yourself a favor and start with a simple interface and then add new interfaces upon it. You don't want to ever change your base interface, so keep it simple and sweet.
As Alexander said, a BPL is basically a DLL. But there are some conditions (from a not-so-short summary I made: http://wiki.freepascal.org/packages ):
A unit can only exist once in BPL's +Exe. This avoids duplication of state (twice the heapmanager and other global vars of system etc, VMT tables etc)
.BPL's can only USE other .BPLs.
This means that dynamic types like ansistring and IS/AS work properly over BPL interfaces.
Initialization/finalization are separate procedure and their initialization order is strictly controlled. For static dynamic loading this is simpler, for dynamic loading (plugin-like) all dependancies on units are checked .
Everything is essentially one big program, which means that the BPL's must be compiled with the same compiler version and RTL and depends on the versions other dependancies. It might be harder to make .BPL's to plugin to an existing EXE, since the Delphi version must match.
This also means that you must deliver .dcp's for (non Delphi) .BPLs the plugin .BPLs depend on
In short: if the plugin architecture is open, make it a DLL. Otherwise people have to have the exact same Delphi version to write plugins.
Hybrid is also possible. An higher level .BPL interface for functionality you factor out into .BPL yourself and selected devels, and a rock bottom procedure DLL interface for the rest.
A third option is using DLLs, but ordain Sharemem. Strings will work, multiple Delphi versions will work. Objects can work but are unsafe (e.g. I guess e.g. D2009 with an earlier version wouldn't work). Even other language users might be able to allocate over COM, not entirely excluding non Delphi.
Your first con is also a pro. If you replicate shared code in each dll the dlls get bigger and bigger. Even when using dlls you can prevent this by moving shared code in a separate dll.
Pros:
Types are shared. No TFont is not a TFont problem
Memory manager is shared. Strings and classes can be used as parameter between plugins without problems.
Cons:
Plugins can be built using Delphi or BCB only.
Plugins should use the same Delphi or BCB version.
Have you considerd using COM? COM makes it possible to share types, strings and classes and the plugins can be written in many programming languages.
I'm not familiar of JvPluginManager, but it depends on how you're going to use BPLs.
Basically, BPL - is just a usual DLL, but its initialization/finalization work is stripped from DllMain to separate functions: 'Initialize'/'Finalize'.
So, if you're going to use BPL like usual DLL, there are no cons that I'm aware of, only pros: there will be no more troubles with DllMain. That's all. The only difference.
But BPL in Delphi also provide a convient way to share code. This means great advantages (common memory manager, no duplicated code, etc, etc). So usual BPL does a lot more than "being just a DLL".
But this also means, that now your plugin system is limited to Delphi only (well, may be C++ Builder too). I.e. both plugins and exe MUST be compiled in the very same compiler to run smoothly.
If this is acceptable for you (i.e. no MS Visual Studio, no, sir, never) - then go ahead, you can use all power of BPLs.
P.S. But upgrading such BPLs plugins can be also a nightmare, if you do not design interface side carefully. In certain worst cases, you may need to recompile everything.
P.P.S. Like I said: I have no idea, how it is applied to plugins, created by JvPluginManager.
Avoid blp approach as you will have to ship a big bag of bpl with you software and thus, distribution will become bulky.
why do we use Delphi to compile small stand alone programs that just RUN anywhere without any runtime dependency. Using bpls means defeating this very purpose.
I don't know as to how comfortable you are with DLLs, but I would suggest you to use DLLs.
This will give other developers (who
may get interested in your software)
a chance to use any development
language (as long as that language
can spit out dll) to write their own
plugins that can be used in your
developed software.
Another thing is that you will be
saved from Delphi's vcl version
dependency tyranny. A major weak
point of Delphi till date.