Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-03

WinINet STDCALL callback crash

7 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Unknown author

Ludo,

Thank you very much for your most informative posting. I have spent the week trying to implement the msdn examples in pure Pascal and in Pascal-DLL hybrids. Success in non-threaded asynchrosity eludes me though.

Your example (http://www.lazarus.freepascal.org/index.php?topic=18506.15#msg105226) using URLMON's URLDownloadToFile works perfectly. However, the example is synchronous whilst we need asynchronous. Research indicates that URLOpenPullStream is the more relevant function in our case (because we download asynchronously to both memory streams and files, depending on what flags the user sets and can track the progress of the download). The problem is that URLOpenPullStream and URLDownloadToFile (which I am using as an intermediate coding step) both require a variable of a type that implements the IBindStatusCallback interface, which in turn requires declaration of the IBinding interface. I have tried doing so without success; I share my code below.

Is there a way to access the UrlMon.dll's definition of IBindStatus and IBinding so that these interfaces are available within Lazarus? Currently, the only option I see is to define these interfaces myself. Alternatively, is there an example of a Lazarus definition of these interfaces?

FYI, after the program segfaults, the assembler window points within urlmon!ZonesReInit

Thank you for any help you might provide.

Matthew

-------------------------------Top (Global) Level-------------------------------------------------------

INTERFACE
TYPE
	PIUnknown = ^IUnknown;
	BINDINFO = RECORD
	  cbSize: ULONGLONG;
	  szExtraInfo: LPWSTR;
	  stgmedData: STGMEDIUM;
	  grfBindInfoF: DWORD;
	  dwBindVerb: DWORD;
	  szCustomVerb: LPWSTR;
	  cbStgmedData: DWORD;
	  dwOptions: DWORD;
	  dwOptionsFlags: DWORD;
	  dwCodePage: DWORD;
	  securityAttributes: SECURITY_ATTRIBUTES;
	  iid1: GUID;
	  pUnk: PIUnknown;
	  dwReserved: DWORD;
	END;
	IBinding = INTERFACE (IUnknown)
		FUNCTION Abort(): HRESULT;
		FUNCTION GetBindResult(VAR pclsidProtocol: CLSID; VAR pdwResult: CLSID;
														VAR pszResult: LPOLESTR; VAR pdwReserved: DWORD): HRESULT;
		FUNCTION GetPriority(VAR pnPriority: LongInt): HRESULT;
		FUNCTION Resume(): HRESULT;
		FUNCTION SetPriority(nPriority: LongInt): HRESULT;
		FUNCTION Suspend(): HRESULT;
	END;
	PIBinding = ^IBinding;
  IBindStatusCallback = INTERFACE(IUnknown)
		{ // IUnknown members }
		Function QueryInterface(constref iid: tguid; out obj): longint stdcall; //Object Pascal--needs modification
		{ //Function IUnknown.QueryInterface(constref iid: tguid; VAR obj: Object): longint stdcall; //possible modification }
		Function _AddRef: longint stdcall;
		Function _Release: longint stdcall;
		FUNCTION GetBindInfo(VAR grfBINDF: DWORD; VAR bindinfo: BINDINFO): HRESULT; STDCALL;
		FUNCTION GetPriority(VAR pnPriority: LongInt): HRESULT; STDCALL;
		FUNCTION OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; pformatetc: PFORMATETC; pstgmed: PSTGMEDIUM): HRESULT; STDCALL;
		PROCEDURE OnLowResource(); STDCALL;
		FUNCTION OnObjectAvailable(riid: REFIID; punk: PIUnknown): HRESULT; STDCALL;
		FUNCTION OnProgress(ulProgress: ULONGLONG; ulProgressMax: ULONGLONG; ulStatusCode: ULONGLONG; szStatusText: LPCWSTR): HRESULT; STDCALL;
		FUNCTION OnStartBinding(dwReserved: DWORD; pib: PIBinding): HRESULT; STDCALL;
		FUNCTION OnStopBinding(hresult1: HRESULT; szError: LPCWSTR): HRESULT; STDCALL;
	END;
{----------------------- IBindStatusCallback stuff -----------------------}
		TBindStatusCallback = CLASS(IBindStatusCallback)
			PUBLIC
				{ // IUnknown members }
				Function QueryInterface(constref iid: tguid; out obj): longint stdcall; //Object Pascal--needs modification
				{ //Function IUnknown.QueryInterface(constref iid: tguid; VAR obj: Object): longint stdcall; //possible modification }
				Function _AddRef: longint stdcall;
				Function _Release: longint stdcall;
				{ IBindStatusCallback members }
				FUNCTION GetBindInfo(VAR grfBINDF: DWORD; VAR bindinfo: BINDINFO): HRESULT; STDCALL;
				FUNCTION GetPriority(VAR pnPriority: LongInt): HRESULT; STDCALL;
				FUNCTION OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; pformatetc: PFORMATETC; pstgmed: PSTGMEDIUM): HRESULT; STDCALL;
				PROCEDURE OnLowResource(); STDCALL;
				FUNCTION OnObjectAvailable(riid: REFIID; punk: PIUnknown): HRESULT; STDCALL;
				FUNCTION OnProgress(ulProgress: ULONGLONG; ulProgressMax: ULONGLONG; ulStatusCode: ULONGLONG; szStatusText: LPCWSTR): HRESULT; STDCALL;
				FUNCTION OnStartBinding(dwReserved: DWORD; pib: PIBinding): HRESULT; STDCALL;
				FUNCTION OnStopBinding(hresult1: HRESULT; szError: LPCWSTR): HRESULT; STDCALL;
			END;
VAR
		gBindStatusCallback: TBINDSTATUSCALLBACK; {TBINDSTATUSCALLBACK;}
IMPLEMENTATION
FUNCTION TBindStatusCallback.QueryInterface(constref iid: tguid; out obj): longint stdcall;
BEGIN
	QueryInterface := E_NOTIMPL;
END;
FUNCTION TBindStatusCallback._AddRef: longint stdcall;
BEGIN
	_AddRef := E_NOTIMPL;
END;
Function TBindStatusCallback._Release: longint stdcall;
BEGIN
	_Release := E_NOTIMPL;
END;
FUNCTION TBindStatusCallback.GetBindInfo(VAR grfBINDF: DWORD; VAR bindinfo: BINDINFO): HRESULT; STDCALL;
BEGIN
	GetBindInfo := E_NOTIMPL;
END;
FUNCTION TBindStatusCallback.GetPriority(VAR pnPriority: LongInt): HRESULT; STDCALL;
BEGIN
	GetPriority := E_NOTIMPL;
END;
FUNCTION TBindStatusCallback.OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; pformatetc: PFORMATETC; pstgmed: PSTGMEDIUM): HRESULT; STDCALL;
		VAR
			breakpoint: INT;
BEGIN
	breakpoint := 4;
END;
PROCEDURE TBindStatusCallback.OnLowResource(); STDCALL;
BEGIN
	;
END;
FUNCTION TBindStatusCallback.OnObjectAvailable(riid: REFIID; punk: PIUnknown): HRESULT; STDCALL;
BEGIN
	OnObjectAvailable := E_NOTIMPL;
END;
FUNCTION TBindStatusCallback.OnProgress(ulProgress: ULONGLONG; ulProgressMax: ULONGLONG; ulStatusCode: ULONGLONG; szStatusText: LPCWSTR): HRESULT; STDCALL;
		VAR
			breakpoint: INT;
BEGIN
	breakpoint := 5;
END;
FUNCTION TBindStatusCallback.OnStartBinding(dwReserved: DWORD; pib: PIBinding): HRESULT; STDCALL;
BEGIN
	OnStartBinding := E_NOTIMPL;
END;
FUNCTION TBindStatusCallback.OnStopBinding(hresult1: HRESULT; szError: LPCWSTR): HRESULT; STDCALL;
BEGIN
	OnStopBinding := E_NOTIMPL;
END;
	PROCEDURE DownloadURL (theURLString: Str;
				outputStream: TMemoryStream;
				toFile: TFile;
				outputFile, name, pass: Str);
        BEGIN
		dest:='C:\Windows\temp\data.txt';
		IF URLDownloadToFile(NIL, PChar(theURLString), PChar(Dest), 0, @gBindStatusCallback)=0 THEN
       END;
Earlier message 46 lines
-----Original Message----- From: "Ludo Brands" Sent: Sunday, February 24, 2013 5:04am To: Subject: Re: [Lazarus] WinINet STDCALL callback crash On 02/23/2013 09:49 PM, wrote: > Hello Lazarus Community, > > I am implementing asynchronous file download using WinINet's STDCALL callback. However, when the callback function recursively calls itself, it generates a crash around fpc_popaddrstack. I hypothesize that Pascal does not understand how to handle callbacks that use the stdcall convention (which I must use since the callback interfaces with the Win32 API and is itself set via the Win32 WinINet procedure InternetSetStatusCallback). > > I was wondering if anyone might graciously offer guidance on how to implement asynchronous download to file using the Win32 API or associated libraries only. Note that I have tried WinHTTP and a different implementation of WinINet using InternetConnect/InternetOpenRequest/InternetSendRequest/InternetReadFile). In the previous two implementations I have encountered the same segmentation fault around fpc_popaddrstack. Based on my experience with the below code and other STDCALL implementations, I do not think that Free Pascal can handle the case where a STDCALL function interrupts itself recursively. In the STDCALL convention, the callee is responsible for cleaning up the stack upon function exit. However, because the function in question (HttpCallback) has been interrupted by a second call to it from the Windows API, it has not had a chance to clean up the stack (because it has not had a chance to exit and thereby execute the epilogue code that cleans up the stack). The conditio n that causes the callback to interrupt itself is when InternetReadFile errors out with ERROR_IO_PENDING. In this circumstance, InternetReadFile also sends back an INTERNET_STATUS_REQUEST_COMPLETE message which interrupts the currently executing HttpCallback function. > > To state the exact circumstance of the crash: when not stepping through, InternetReadFile below errors out frequently with ERROR_IO_PENDING. This is fine except that InternetReadFile ALSO recursively triggers the callback, which after the second recursive call causes a crash. > > My current code is as follows. I've added inline comments around the parts that seem to crash. Thank you very much for any asssistance you can provide. > You are trying to read the complete HTTP reply inside the callback which will not work. ERROR_IO_PENDING just means that the data for the next buffer is not there yet. The callback function is called for every buffer you receive from the server and you should have only one InternetReadFile per INTERNET_STATUS_REQUEST_COMPLETE. So when the HTTP reply takes many buffers you will get many callbacks and in every callback you are supposed to read the buffer received with one single InternetReadFile, Take a look at this example on how to set up async processing: http://msdn.microsoft.com/en-us/library/windows/desktop/cc185684(v=vs.85).aspx. You'll notice the AcquireRequestHandle function that uses a EnterCriticalSection to lock the context. In your code you are not locking anything and your "recursive" entry in the callback is just using the same context which is the probable cause of your crash. STDCALL callbacks are used commonly in Freepascal and are not a problem at all. If you just want to download an url to file the easy way using the windows framework take a look at this post http://www.lazarus.freepascal.org/index.php?topic=18506.15#msg105226 Ludo --

Reply by email

Ludo Brands
to Unknown author
Show quoted text 12 lines
Ludo, Thank you very much for your most informative posting. I have spent the week trying to implement the msdn examples in pure Pascal and in Pascal-DLL hybrids. Success in non-threaded asynchrosity eludes me though. Your example (http://www.lazarus.freepascal.org/index.php?topic=18506.15#msg105226) using URLMON's URLDownloadToFile works perfectly. However, the example is synchronous whilst we need asynchronous. Research indicates that URLOpenPullStream is the more relevant function in our case (because we download asynchronously to both memory streams and files, depending on what flags the user sets and can track the progress of the download). The problem is that URLOpenPullStream and URLDownloadToFile (which I am using as an intermediate coding step) both require a variable of a type that implements the IBindStatusCallback interface, which in turn requires declaration of the IBinding interface. I have tried doing so without success; I share my code below. Is there a way to access the UrlMon.dll's definition of IBindStatus and IBinding so that these interfaces are available within Lazarus? Currently, the only option I see is to define these interfaces myself. Alternatively, is there an example of a Lazarus definition of these interfaces? FYI, after the program segfaults, the assembler window points within urlmon!ZonesReInit Thank you for any help you might provide.

This is definitely the most difficult route to async you are trying to walk;) Delphi has an unit to support urlmon that defines all these interfaces but I still have to see a stable and reliable piece of code that manages to use URLOpenPullStream. Also quite some knowledge on COM interfaces is need to try to get that working. For example QueryInterface := E_NOTIMPL; is a no go in interfaces.

Why don't you use a standard async library such as lNet (http://wiki.freepascal.org/lNet, http://lnet.wordpress.com/)? It has a lazarus package that will install amongst others the TLHTTPClientComponent that has already the necessary events. The library comes with a httpclienttest example application that show you how to use the component.
There is also Indy (http://wiki.freepascal.org/Indy_with_Lazarus) which is async although that library is much bigger and compatibility with lazarus is not that good as well as its portability to other platforms.

Ludo

Reply by email

Unknown author

Sven,

Thank you very much for your threading example below. I have used the model several times to build threaded implementations. However, I still get frequent, random segfaults when calling Windows functions. My current attempt, as simple as I can make it, is below. About 50% of the time, the first command in the execute procedure works fine; the other times it causes a crash. Might you or any others have suggestions on why this is?

Thank you,
Matthew

<pre>

TYPE
		DownloadThread = CLASS(TThread)
			PROCEDURE EXECUTE; OVERRIDE;
			PUBLIC
				theURL, theDest: AnsiString;
			PUBLIC
				CONSTRUCTOR Create(URLString: Str; dest: Str);
		END;
VAR //global
		gTheURLString: Str;
		dest: Str;
IMPLEMENTATION
	CONSTRUCTOR DownloadThread.Create(URLString: Str; dest: Str);
	BEGIN
		theURL := URLString;
		theDest := dest;
	  FreeOnTerminate := True;
	  inherited Create(False);
	END;
	PROCEDURE DownloadThread.execute;
	{ OVERRIDE }
	VAR
	  hInet: HINTERNET;
	  hURL: HINTERNET;
	  Buffer: array[0..1023] of Byte;
	  BufferLen, amt: cardinal;
	  f: file;
	  success: BOOLEAN;
	  appTitle: PChar;
	BEGIN
		appTitle := 'Lazarus App with Threading';
	  try
		  hInet := InternetOpen(appTitle, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
	    hURL := InternetOpenUrl(hInet, PChar(theURL), nil, 0, INTERNET_FLAG_RELOAD, 0);
	    try
	      FileMode := fmOpenWrite;
	      AssignFile(f, theDest);
	      try
	        Rewrite(f, 1);
	        amt := SizeOf(Buffer);
	        repeat
	          success := InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
	          BlockWrite(f, Buffer[0], BufferLen, amt);
	          if Terminated then
	            Exit;
	        until BufferLen = 0;
	      finally
	        CloseFile(f);
	      end;
	    finally
	      InternetCloseHandle(hURL);
	    end;
	  FINALLY
	    InternetCloseHandle(hInet);
	  END;
	END;

....main program...

DownloadThread.Create(gTheURLString, dest);

</pre>

Earlier message 74 lines
-----Original Message----- From: "Sven Barth" Sent: Monday, February 25, 2013 11:51am To: Subject: Re: [Lazarus] WinINet STDCALL callback crash On 25.02.2013 17:42, wrote: > Ludo, Hans-Peter, > > Many thanks for your insights. > > Ludo, I am reviewing the msdn code example you posted; I have read quite a few but don't remember seeing that one. > > Hans-Peter, our project has so far been able to avoid the additional complexity posed by threads. It would be with reluctance that we would turn to threading; however, if experimenting with Ludo's post content (see below) does not work, then would will use threads. Might you know of an example implementation or code for asynchronous HTTP and/or FTP downloads? In principle you could do it as follows: === example begin === type TDownloader = class(TThread) public type TCallback = procedure(aSender: TDownloader; aData: TStream) of object; private fCallback: TCallback; fUrl: String; protected procedure Execute; override; public constructor Create(const aUrl: String; aCallback: TCallback); end; constructor TDownloader.Create(const aUrl: String; aCallback: TCallback); begin // check that aCallback and aUrl are given and set up local variables // ... FreeOnTerminate := True; inherited Create(False); end; procedure TDownloader.Execute; var ms: TMemoryStream; begin ms := TMemoryStream.Create; try // here you use what ever synchronous API you want and store it's result in ms // when all data is received fCallback(Self, ms); finally ms.Free; end; end; // somewhere else TDownloader.Create('http://example.org/whatever', @MyCallback); // fire and forget === example end === Note: if you want to be able to cancel the download (which could be done by calling the thread's "Terminate" method which sets "Terminated" to "True") you should not set "FreeOnTerminate" to "True", check for "Terminated" in the thread's "Execute" method and capture the instance returned by "TDownloader.Create". Regards, Sven --

Reply by email

Benito van der Zander
to Unknown author
However, I still get frequent, random segfaults when calling Windows functions. My current attempt, as simple as I can make it, is below. About 50% of the time, the first command in the execute procedure works fine; the other times it causes a crash.

An actually crash or just a segfault message in the debugger?

I have been using wininet in a similar way for years, and it throws an error quite often, when run from within Lazarus.
But when called normally, without Lazarus everything works fine. I think wininet and debuggers just do not play well together...

Benito

Show quoted text 168 lines
Sven, Thank you very much for your threading example below. I have used the model several times to build threaded implementations. However, I still get frequent, random segfaults when calling Windows functions. My current attempt, as simple as I can make it, is below. About 50% of the time, the first command in the execute procedure works fine; the other times it causes a crash. Might you or any others have suggestions on why this is? Thank you, Matthew <pre> TYPE DownloadThread = CLASS(TThread) PROCEDURE EXECUTE; OVERRIDE; PUBLIC theURL, theDest: AnsiString; PUBLIC CONSTRUCTOR Create(URLString: Str; dest: Str); END; VAR //global gTheURLString: Str; dest: Str; IMPLEMENTATION CONSTRUCTOR DownloadThread.Create(URLString: Str; dest: Str); BEGIN theURL := URLString; theDest := dest; FreeOnTerminate := True; inherited Create(False); END; PROCEDURE DownloadThread.execute; { OVERRIDE } VAR hInet: HINTERNET; hURL: HINTERNET; Buffer: array[0..1023] of Byte; BufferLen, amt: cardinal; f: file; success: BOOLEAN; appTitle: PChar; BEGIN appTitle := 'Lazarus App with Threading'; try hInet := InternetOpen(appTitle, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); hURL := InternetOpenUrl(hInet, PChar(theURL), nil, 0, INTERNET_FLAG_RELOAD, 0); try FileMode := fmOpenWrite; AssignFile(f, theDest); try Rewrite(f, 1); amt := SizeOf(Buffer); repeat success := InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen); BlockWrite(f, Buffer[0], BufferLen, amt); if Terminated then Exit; until BufferLen = 0; finally CloseFile(f); end; finally InternetCloseHandle(hURL); end; FINALLY InternetCloseHandle(hInet); END; END; ....main program... DownloadThread.Create(gTheURLString, dest); </pre> -----Original Message----- From: "Sven Barth" Sent: Monday, February 25, 2013 11:51am To: Subject: Re: [Lazarus] WinINet STDCALL callback crash On 25.02.2013 17:42, wrote: > Ludo, Hans-Peter, > > Many thanks for your insights. > > Ludo, I am reviewing the msdn code example you posted; I have read quite a few but don't remember seeing that one. > > Hans-Peter, our project has so far been able to avoid the additional complexity posed by threads. It would be with reluctance that we would turn to threading; however, if experimenting with Ludo's post content (see below) does not work, then would will use threads. Might you know of an example implementation or code for asynchronous HTTP and/or FTP downloads? In principle you could do it as follows: === example begin === type TDownloader = class(TThread) public type TCallback = procedure(aSender: TDownloader; aData: TStream) of object; private fCallback: TCallback; fUrl: String; protected procedure Execute; override; public constructor Create(const aUrl: String; aCallback: TCallback); end; constructor TDownloader.Create(const aUrl: String; aCallback: TCallback); begin // check that aCallback and aUrl are given and set up local variables // ... FreeOnTerminate := True; inherited Create(False); end; procedure TDownloader.Execute; var ms: TMemoryStream; begin ms := TMemoryStream.Create; try // here you use what ever synchronous API you want and store it's result in ms // when all data is received fCallback(Self, ms); finally ms.Free; end; end; // somewhere else TDownloader.Create('http://example.org/whatever', @MyCallback); // fire and forget === example end === Note: if you want to be able to cancel the download (which could be done by calling the thread's "Terminate" method which sets "Terminated" to "True") you should not set "FreeOnTerminate" to "True", check for "Terminated" in the thread's "Execute" method and capture the instance returned by "TDownloader.Create". Regards, Sven -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Ludo Brands
to Benito van der Zander
Benito van der Zander wrote 12 lines
> However, I still get frequent, random segfaults when calling Windows > functions. My current attempt, as simple as I can make it, is below. > About 50% of the time, the first command in the execute procedure > works fine; the other times it causes a crash. An actually crash or just a segfault message in the debugger? I have been using wininet in a similar way for years, and it throws an error quite often, when run from within Lazarus. But when called normally, without Lazarus everything works fine. I think wininet and debuggers just do not play well together...

Or is it a SIGFPE? There are known similar problems with FPC and dll's crashing with floating point errors. With SetExceptionMask (unit math) you can mask these exceptions.

If you run on Win64 then SEH can cause crashes with dll's. Latest FPC from trunk (2.7.1) enables SEH on win64 by default.

Why don't you use a sync library such as synapse
(http://synapse.ararat.cz/doku.php) in your thread? In httpsend you'll find function HttpGetBinary(const URL: string; const Response: TStream): Boolean; Create a FileStream, call HttpGetBinary and close the stream, done. No external dependencies.

Also don't change FileMode in a thread. FileMode is global. This is not the cause of the crash you are seeing but could cause weird problems later on.

Ludo

Reply by email

Benito van der Zander
to Ludo Brands
If you run on Win64 then SEH can cause crashes with dll's. Latest FPC from trunk (2.7.1) enables SEH on win64 by default.

What kind of crashes? If compiled for win64, or run there? But the crashes in 2.6 would be unrelated, wouldn't they?

Why don't you use a sync library such as synapse (http://synapse.ararat.cz/doku.php) in your thread?

These kinds of libraries never work so well with https. You need to install openssl, set the ssl version manually when the detection fails sometimes,
and afair it never checks if the ssl certificate is actually valid. wininet checks it against the certificates allowed on the machine.

Benito

Ludo Brands wrote 37 lines
On 03/14/2013 12:09 AM, Benito van der Zander wrote: >> However, I still get frequent, random segfaults when calling Windows >> functions. My current attempt, as simple as I can make it, is below. >> About 50% of the time, the first command in the execute procedure >> works fine; the other times it causes a crash. > An actually crash or just a segfault message in the debugger? > > I have been using wininet in a similar way for years, and it throws an > error quite often, when run from within Lazarus. > But when called normally, without Lazarus everything works fine. > I think wininet and debuggers just do not play well together... > > Or is it a SIGFPE? There are known similar problems with FPC and dll's crashing with floating point errors. With SetExceptionMask (unit math) you can mask these exceptions. If you run on Win64 then SEH can cause crashes with dll's. Latest FPC from trunk (2.7.1) enables SEH on win64 by default. Why don't you use a sync library such as synapse (http://synapse.ararat.cz/doku.php) in your thread? In httpsend you'll find function HttpGetBinary(const URL: string; const Response: TStream): Boolean; Create a FileStream, call HttpGetBinary and close the stream, done. No external dependencies. Also don't change FileMode in a thread. FileMode is global. This is not the cause of the crash you are seeing but could cause weird problems later on. Ludo -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Ludo Brands
to Benito van der Zander
Benito van der Zander wrote
> If you run on Win64 then SEH can cause crashes with dll's. Latest FPC > from trunk (2.7.1) enables SEH on win64 by default. What kind of crashes? If compiled for win64, or run there?

Google for site:bugs.freepascal.org SEH win64 to get a list. FPC for WIn64 used a different exception handling which resulted in getting exceptions generated in dll's which where supposed to be caught inside the dll. Exceptions it didn't know what to do with.

But the crashes in 2.6 would be unrelated, wouldn't they?

Any exception generated in a non FPC dll code could crash your FPC win64 application with 2.6.0. Since the exception points to a call to external code, you just don't know.

Show quoted text 6 lines
> Why don't you use a sync library such as synapse > (http://synapse.ararat.cz/doku.php) in your thread? These kinds of libraries never work so well with https. You need to install openssl, set the ssl version manually when the detection fails sometimes, and afair it never checks if the ssl certificate is actually valid.

I personally contributed the code for certificate checking to synapse more than a year ago ;)
Yes you need a list of root CA's such as the mozilla one because openssl doesn't come with a list. But at least you get the opportunity to use an updated one. I can't remember when Microsoft updated the root CA list for XP.

wininet checks it against the certificates allowed on the machine.

Don't get me wrong. If wininet is working for you, so much the better. Only when it goes wrong, as in OP's case, there is only so much you can do with a closed source library.

Ludo

Reply by email