I'm answering both to Vincent and Marc in this mail:

To Vincent:
No luck with -gh and -dMSG_DEBUG :\.
-gh is not reliable, since after windows exceptions, a lot of access violations occour, so a lot of data isn't deallocated because of exceptions being raised.
Tracing messages (or using -dTRACE) isn't very helpful either :\

To Marc:
In lazarus on win64 there is no manifest, since there are no resources at all: IIRC windres is used on win32 to embed resources into executables, but there is no windres on win64. In fact lazarus doesn't have any resource (i watched into it with CFF Explorer - http://www.ntcore.com/exsuite.php)
so no icons, no manifests.

But your observation made me study a bit this assemblies/manifest thing (I thought those "manifests" were something needed to have an xp look, but they are a way more powerful and complex thing) and
I think our problem is somewhat related to this thing.

So, let's explain what is this manifest/assembly/sxs thing.
Microsoft introduced this "side by side" assembly thing in Windows XP to try to reduce dll hell. It works this way: traditionally, if you upgraded a shared dll, programs that were built to use a previous version of this dll could have problems. To solve this, multiple versions of dlls and other executable things can be installed, and programs can specify which version they were
designed to use.
These "assemblies" are stored in subfolders of \windows\winsxs directory.
Programs can specify which assemblies (and what version) they depend of, in the manifest file. This can be a regular file which must reside in program directory and must be named as myprogram.exe.manifest (so for lazarus it could be lazarus.exe.manifest), or it can be embedded
as a resource into the executable.
Classical example is comctl32.dll. Windows xp loads by default comctl32.dll version 5.something (classical windows gui), but if program specifies another version in the manifest file, that
version is loaded.
E.g., lazarus on win32 has this manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
   version="1.0.0.0"
   processorArchitecture="X86"
   name="Lazarus"
   type="win32"
/>
<description>GUI RAD for FreePascal</description>
<dependency>
   <dependentAssembly>
       <assemblyIdentity
           type="win32"
           name="Microsoft.Windows.Common-Controls"
           version="6.0.0.0"
           processorArchitecture="X86"
           publicKeyToken="6595b64144ccf1df"
           language="*"
       />
   </dependentAssembly>
</dependency>
</assembly>

so the library that is loaded is
C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2982_x-ww_ac3f9c03\comctl32.dll
and the library manifest is in
C:\WINDOWS\WinSxS\Manifests\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2982_x-ww_ac3f9c03.Manifest

(actually the lazarus manifest specifies version 6.0.0.0, but version 6.0.2600.2982 is loaded since it's
a minor bugfix release of 6.0.0.0)


Now, things get more complicated.
In fact, it is possible for a program to dinamically change the version of the assembly it's bound to. Here comes the concept of "activation context": the active activation context contains informations about what version of what piece of code is bound to the program and so on. Basically, it's like if the application context contains the information that is put inside the manifest file. A program can change the current activation context, by creating new activation contexts, pushing them on the activation context stack and then popping them to restore the previous ones. Now, problems can arise: suppose my program calls functions from dll A, version 1.0, and from dll B, and that dll B calls too functions from dll A, but it expects A version 2.0: this is possible, since my program and dll B can have different activation contexts. But if dll B calls a callback in my program, it gets called with B activation context instead of my program one, and bad things can happen. I must admit I'm not sure I understand correctly (:D), but it should be something like this.

Now, our problem seems to be related to this activation context thing: windbg gives me this stack trace:
Child-SP          RetAddr           Call Site
00000000`0006f2d0 00000000`78c444cb ntdll!RtlActivateActivationContextUnsafeFast+0x92
00000000`0006f3a0 00000000`78c44be2 USER32!UserCallDlgProcCheckWow+0xc2
00000000`0006f480 00000000`78c5238d USER32!DefDlgProcWorker+0xf6
00000000`0006f510 00000000`78ef39ff USER32!_fnDWORD+0x2d
00000000`0006f570 00000000`78c4982a ntdll!KiUserCallbackDispatcherContinue
00000000`0006f5f8 00000000`78c5cd0c USER32!ZwUserShowWindow+0xa
00000000`0006f600 00000000`78c468af USER32!DialogBox2+0x399
00000000`0006f6a0 00000000`78c400bb USER32!InternalDialogBox+0x225
00000000`0006f720 00000000`015c43aa USER32!DialogBoxParamW+0x7f
00000000`0006f780 00000000`0173297a SHELL32!SHFusionDialogBoxParam+0xd9
00000000`0006f7f0 00000000`005a5f80 SHELL32!SHBrowseForFolderA+0x15a

with the exception being

(a94.b48): Unknown exception - code c0150014 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll!RtlActivateActivationContextUnsafeFast+0x92:
00000000`78f2a966 4881c4c8000000   add     rsp,0xc8

There are 5 of these exceptions, all at ntdll!RtlActivateActivationContextUnsafeFast+0x92 (but
with different call traces).
After these 5 exceptions, a lot of Access Violations occours, the first one being in sys_freemem_fixed i think (without debugger I tried to watch the linker map), but I think
they are not important since they should be caused by the previous ones.

So, from the name of the function it seems a activation context related problem. But I can't understand what is. I tried to print the current activation context in some parts of the lcl, and it looks like it's always the default one, apart in the callback called by
SHBrowseForFolder (as I expected).
I tried to write a manifest and use comctl32.dll version 6 (since it's the only library stored in winsxs to be loaded by my test program) - nothing changed. I tried to use version 5 and I noticed a lesser number of access violations on the console, while in windbg it was the same. I tried to activate the default activation context in the callback called by SHBroseForFolder - nothing. Tried the same in the Windproc procedure - nothing, and before and after calling SHBrowseForFolder - nothing, but in fact I tried these things only because of desperation, not because I believed they
were useful.

Some references:
Main introduction to manifests, assemblies and so on:
http://msdn2.microsoft.com/en-gb/library/aa375193.aspx

In particular, some subsections might be of interest:
Side by side assemblies references: http://msdn2.microsoft.com/en-gb/library/aa376414.aspx Using callbacks from hosted components: http://msdn2.microsoft.com/en-gb/library/aa376615.aspx

This blog might also be of interest:
http://blogs.msdn.com/jonwis/
In particular, these topics:
C++ object for activating and Deactivating Contexts
Fixing Activation Context Pollution
What's that awful directory name under Windows\WinSxS?

bye,
Giulio.
_________________________________________________________________
    To unsubscribe: mail [EMAIL PROTECTED] with
               "unsubscribe" as the Subject
  archives at http://www.lazarus.freepascal.org/mailarchives

Reply via email to