A client contacted us and said that he could not install EurekaLog. More precisely: EurekaLog is installed, but subsequent launch of the
IDE raises an error:
Can't load package C:\Program Files (x86)\Neos Eureka S.r.l\EurekaLog 7\Packages\Studio25\EurekaLogExpert250.bpl. Access is denied.
Moreover, the client claimed that the file exists, there is
access to it, reinstalling EurekaLog does not help.
Additionally, it was found that the code from the EurekaLogExpert250.bpl
package actually does not receive control (is not executed).
The
IDE uses the same LoadPackage function from the SysUtils
unit that you (your code) use. The
IDE does not execute any secret code. The LoadPackage function is implemented as follows: function LoadPackage(const Name: string; AValidatePackage: TValidatePackageProc): HMODULE; begin Result := SafeLoadLibrary(Name); if Result = 0 then raise EPackageError.CreateResFmt(@sErrorLoadingPackage, [Name, SysErrorMessage(GetLastError)]); // ----- try InitializePackage(Result, AValidatePackage); except FreeLibrary(Result); raise; end; end; where the InitializePackage function is implemented as: procedure InitializePackage(Module: HMODULE; AValidatePackage: TValidatePackageProc); type TPackageLoad = procedure; var PackageLoad: TPackageLoad; begin CheckForDuplicateUnits(Module, AValidatePackage); @PackageLoad := GetProcAddress(Module, 'Initialize'); //Do not localize if Assigned(PackageLoad) then PackageLoad else raise EPackageError.CreateFmt(sInvalidPackageFile, [GetModuleName(Module)]); end; As you can see: the only place where an
exception with an error code from the
OS (5 = ERROR_ACCESS_DENIED) can be raised when loading a
package is the marked line. This means that an
Access Denied error when loading a
package can only occur if the call to the LoadLibrary function fails.
Therefore, the client was asked to create a new empty
VCL application with the following test code: procedure TForm1.Button1Click(Sender: TObject); var Lib: HMODULE; begin Lib := LoadPackage('C:\Program Files (x86)\Neos Eureka S.r.l\EurekaLog 7\Packages\Studio25\EurekaLogExpert250.bpl'); if Lib = 0 then RaiseLastOSError else MessageBox(0, 'The
package was loaded!', 'Test', 0); end; As it turns out, the test application loads the
package successfully.
To be sure that the
IDE was not executing any additional hidden code, we asked the client to create a new
Design-Time package with a new
unit containing only the test code:
unit Unit1; procedure Register; implementation uses Windows, SysUtils; procedure Register; var Lib: HMODULE; begin Lib := LoadPackage('C:\Program Files (x86)\Neos Eureka S.r.l\EurekaLog 7\Packages\Studio25\EurekaLogExpert250.bpl'); if Lib = 0 then RaiseLastOSError else MessageBox(0, 'The
package was loaded!', 'Test', 0); end; end. And when the client tried to load this test
package, the
IDE again gave an error message.
Let's make an intermediate result:
- The test application successfully loads the package;
- The test package (and IDE) cannot load the package.
This strongly suggests that the problem is not with the
package, but with the
IDE itself.
We also tried the following: - Launch the IDE (without EurekaLog);
- Open the Run / Load Process menu item;
- Specify bds.exe as the target process for debugging;
- Launch the second instance of the IDE. In this case: the first instance will be the debugger, and the second will be the debugged one;
- In the process being debugged: try to add/load the EurekaLogExpert250.bpl package;
- In the debugger: monitor for exceptions that occur.
This algorithm did not provide any new information. In the debugger: we saw that in the process being debugged, the LoadLibrary function returns 0, which leads to an error being raised - as we assumed above.
Since both we and the client had already checked the
access rights to the file EurekaLogExpert250.bpl a hundred times and saw no problems, we had to do something else.
The EurekaLog
Expert250.bpl
package is a
Design-Time package. It depends on the
Run-Time package EurekaLog
Core250.bpl. This means that if the LoadLibrary function loads the EurekaLogExpert250.bpl
package, it will see that the EurekaLogExpert250.bpl
package references the EurekaLogCore250.bpl file and will try to load it too. And if a problem arose while loading the EurekaLog
Core250.bpl
package, it will bubble up to the top level and will be returned to the caller by the LoadLibrary function.
Therefore, the client also checked the file EurekaLogCore250.bpl (located in the C:\Windows\System32 folder) and found no problems.
Next, we asked the client to use Microsoft/SysInternals Process Monitor tool to monitor how the
IDE was accessing files. It was necessary to launch the
IDE, open the adding component dialog, then launch the Process Monitor tool and specify the "Process Name=
bds.exe => include" filter. Then try to add the
package, see the error message and save the resulting report.
In the resulting report, we ran a search for the "Eureka" word and immediately saw that the
bds.exe was able to open and read the EurekaLogExpert250.bpl file - which further confirms that there is nothing wrong with the EurekaLogExpert250.bpl file.
But the lines immediately below confused us: Process Monitor reported that the
bds.exe is trying to
access the EurekaLogCore250.bpl from
IDE's \bin folder. This is strange because modern versions of EurekaLog do not touch
IDE's \bin folder.
(Very) old versions of EurekaLog installed the ecc32.exe file in IDE's \bin folder. We had to remove this behavior because
Modern versions of the IDE may throw an integrity/license verification error if there are third-party files in IDE's \bin folder:Question: I’ve installed and registered C++ Builder or Delphi, yet when it starts I am brought to a web page with the error “Product or License Validation Error”. How can I fix this?
Answer: By far the most common cause for this error is having files or applications not provided by Embarcadero that are copied into the bin folder below where RAD Studio is installed. Only files provided by Embarcadero may reside in the bin folder.
Therefore, modern versions of EurekaLog do not copy any files to IDE's \bin folder.
But when we tried to check the
access rights to the \bin\EurekaLogCore250.bpl file, we... did not find such file!
As it turns out: the \bin\EurekaLogCore250.bpl is, in fact, a directory! The mystery is solved!
So, the following happened:
- The IDE calls the LoadPackage function to load the package;
- The LoadPackage function calls the LoadLibrary function to load the EurekaLogExpert250.bpl file;
- The LoadLibrary function (successfully) opens and reads the EurekaLogExpert250.bpl file;
- The LoadLibrary function sees that the EurekaLogExpert250.bpl file contains a link/reference to the EurekaLogCore250.bpl file;
- The LoadLibrary function tries to load the EurekaLogCore250.bpl file;
- The LoadLibrary function uses
standard operating system's library search rules and sees that EurekaLogCore250.bpl is located right here: in IDE's \bin folder;
- The LoadLibrary function tries to load EurekaLogCore250.bpl from IDE's \bin folder;
- The LoadLibrary function returns error 5 (Access Denied) because the EurekaLogCore250.bpl folder in IDE's \bin folder does not have the "EXECUTE" access right".
And, indeed, everything worked after deleting the EurekaLogCore250.bpl folder from
IDE's \bin folder.
But where did the EurekaLogCore250.bpl folder in
IDE's \bin folder came from? I don't know. The EurekaLog installer is made using InnoSetup. Of course, the InnoSetup installation file for EurekaLog has no idea about IDEs you have installed and folders in which they are installed. And therefore the InnoSetup installation file for EurekaLog will not be able to create any folder there - simply because it does not know where it is.
Registration of EurekaLog in the
IDE is carried out by the standalone registration program: .exe file compiled in Delphi from our source code. The problem is that in our source code for EurekaLog registration does not have a single call to MkDir or ForceDirectories functions: the EurekaLog registration application does not create directories, it copies files and enters data about them into Windows registry.
Even if the EurekaLogCore250.bpl in
IDE's \bin folder was created by our installer: why is it a directory and not a file? And why is it alone? Why are there no EurekaLogExpert250.bpl and EurekaLogComponent250.bpl - after all, these three files go together.
So far it looks like
someone has created a EurekaLogCore250.bpl directory in
IDE's \bin folder. Perhaps it was some kind of
IDE expert?
If you are our client, if you saw this error and know who creates the EurekaLogCore250.bpl directory in
IDE's \bin folder - please
let us know.
Weiterlesen...