-
Content Count
3007 -
Joined
-
Last visited
-
Days Won
135
Everything posted by Remy Lebeau
-
The only time that Indy's TIdHTTPServer sends a 404 automatically is if you call AResponseInfo.SmartServeFile() on a file that doesn't exist. Otherwise, it sends a 404 only if you explicitly set AResponseInfo.ResponseNo to 404 yourself. So, are you doing either of those in your OnCommandOther event handler? If not, then are you sure the 404 response is coming from TIdHTPServer, and not maybe from a firewall/router in front of your server that could be intercepting the request and replying to it before TIdHTTPServer sees it? What do the actual response headers look like? There is simply not enough info to diagnose your problem.
-
0xEEDFADE is a Delphi exception. That's a good sign, it means it was thrown deliberately, not something unexpected like an Access Violation, etc. The 2nd IDE instance that is debugging the 1st instance should be able to show you what the exception actually is. 0xC000041D is STATUS_FATAL_USER_CALLBACK_EXCEPTION. That is not a good sign. Of course, it could also just be a side effect of the 1st error. Do you have the same problem if you load the component package dynamically at runtime via LoadPackage()? Or does the error happen strictly during install only?
-
TTrayIcon (Hidden main window and second form)
Remy Lebeau replied to PawelPepe's topic in General Help
Are you merely hiding and reshowing Form2 on each message? Or are you fully destroying and recreating it? FYI, Application.ShowMainForm only affects the startup of Application.Run(), so once the app is up and running then setting ShowMainForm has no effect. Also, hiding/showing the Application.Handle is only useful in this case if Application.MainFormOnTaskbar is false, which is not the default in modern Delphi projects. -
Are you sure it is YOUR program that has the file open? Did you verify that, such has with a tool like SysInternals Process Explorer? Maybe the file is open by the OS, or an antivirus/antimalware, etc.
-
What does that have to do with the IDE? Those components are for dragging things at runtime only. What is the actual PROBLEM you are having? WHAT are you trying to drag, FROM where, TO where? You are not explaining yourself very well.
-
Changes in System.sysutils.pas were not reflecting in other unit in Delphi 11
Remy Lebeau replied to sp0987's topic in General Help
That function returns a pointer to a trampoline. You must use that pointer when your hook function wants to call the original function. https://github.com/MahdiSafsafi/DDetours/wiki#interceptcreate For example: var TrampolineGetLocalTime: procedure(var st: TSystemTime); stdcall; procedure myNewLocalTime(var st: TSystemTime); stdcall; begin ... TrampolineGetLocalTime(st); ... end; TrampolineGetLocalTime := InterceptCreate(@Windows.GetLocalTime, @myNewLocalTime, ...); This is demonstrated in the DDetours documentation: https://github.com/MahdiSafsafi/DDetours/wiki#hooking-winapi-function -
Changes in System.sysutils.pas were not reflecting in other unit in Delphi 11
Remy Lebeau replied to sp0987's topic in General Help
That is not how a detour works. If you just save the original function address then you would call back into yourself, as you fear. The original function is still called everywhere, the detour simply modifies the first few bytes of the function to jump to your new function. So creating a detour requires saving the original bytes being modified so the new function can still execute them before jumping back into the original function past the modified bytes to continue the work normally. This is known as a "trampoline". However, in the case of a DLL function, it is simpler to just modify the PE imports table at runtime to redirect the entry of the target function to simply point at a different function, thus bypassing the original function completely. All calls go directly to the new function. In which case, yes, you would need to save the address of the original function so you can call it normally when needed. Since we don't know what your createNewDetour() is actually doing, it's important to know which technique is actually being used. -
Changes in System.sysutils.pas were not reflecting in other unit in Delphi 11
Remy Lebeau replied to sp0987's topic in General Help
Yes. You would write a replacement function in your code, and then detour the original DLL function, and then all calls to the DLL function will go through your replacement function instead. A detour doesn't care whether the original function resides in a DLL or not. It is all in the same address space of the calling process. Yes. -
"EIdSocketError" on S3 file upload - Delphi 7
Remy Lebeau replied to adeptusgb's topic in Network, Cloud and Web
Then you should have gotten an exception like EIdOSSLCouldNotLoadSSLLibrary from TIdHTTP when it failed to load the necessary TLS functions from the DLLs. -
"EIdSocketError" on S3 file upload - Delphi 7
Remy Lebeau replied to adeptusgb's topic in Network, Cloud and Web
url should be SignedURL instead. Is it an actual EAccessViolation, or some other exception? I see nothing in the code you have shown that should be causing an EAccessViolation. What is the complete error message? There should be more detail about the exact socket error that actually occurred. Sure, since you are disabling use of TLS. You can't connect to an HTTPS url without TLS. Other then the url issue mentioned above, the rest of the code looks fine. Do you have OpenSSL v1.0.2 DLLs installed alongside your app? More likely, either you are posting to the wrong URL, or there is a problem with the TLS handshake. Have you tried using a packet sniffer, like Wireshark, to look at the raw TCP data for any differences between the postman handshake and the TIdHTTP handshake? If the handshake is working, have you tried comparing Postman's HTTP request to TIdHTTP's HTTP request for differences? -
Changes in System.sysutils.pas were not reflecting in other unit in Delphi 11
Remy Lebeau replied to sp0987's topic in General Help
If you modify a unit's interface, you have to recompile everything that uses that unit. If you add functionality to a unit's implementation, you can't access it from other units without exposing it in the interface. Catch-22. Best option is to not modify system/rtl units except for non-interface bug fixes. If you need custom functionality, best to just implement it in your own unit. -
How I can know the procedure that was executed before another procedure ?
Remy Lebeau replied to William23668's topic in Delphi IDE and APIs
Are you compiling your project in Release mode instead of Debug mode? Or with debug info disabled? Have you tried doing a diff between your project file and a working project file? -
TProgressBar (and by extension, the underlying Win32 control) has never had an option to display text. That would require subclassing the ProgressBar to augment its drawing manually.
-
NULL iterators in C++ Builder - 32 bit vs. 64 bit
Remy Lebeau replied to Arvid P.'s topic in General Help
The original code you showed makes sense if the calling code is using this kind of pattern: first(); while (next()) { // do something with getPresent() ... } Whereas my 2nd example would need this kind of pattern instead: if (First()) { do { // do something with getPresent() ... } while (Next()); } -
crNo DOES map to a system cursor - IDC_NO: Why it is not transparent, who knows. Ask Microsoft.
-
I think you mean a design-time package. Why are you recompiling the VCL? Don't do that. Your project is clearly not setup correctly. Start over with a fresh project, and add your existing project source files to it. And make sure your design-time package (not a runtime package!) has the DesignIDE package listed in its requires clause. You should not be compiling DesignIntf.pas directly.
-
NULL iterators in C++ Builder - 32 bit vs. 64 bit
Remy Lebeau replied to Arvid P.'s topic in General Help
That is absolutely the wrong thing to do. There is no such concept as a "null iterator" in the standard library. An iterator has to always point at something valid, whether it is the 1st item in a container/range, the end of a container/range, or anything in between. For what you are attempting, you would need to wrap the iterator inside a std::optional (or equivalent, like Roger Cigol suggested), eg: std::optional<std::list<MyType*>::const_iterator> mp1MyType; void MyTypes::first() { mp1MyType = std::nullopt(); } bool MyTypes::next() { if ( !mp1MyType.has_value() ) mp1MyType = mLstMyTypes.begin(); else ++(*mp1MyType); if ( *mp1MyType == mLstMyTypes.end() ) { mp1MyType = std::nullopt(); return false; } return true; } MyType* MyTypes::getPresent() const { return mp1MyType.has_value() ? *(*mp1MyType) : nullptr; } But, why are you waiting until next() is called to move the iterator to the 1st item? Why can't you do it in first() instead? Seems like first() should return a bool indicating whether the iterator is valid, just like next() does, eg: std::list<MyType*>::const_iterator mp1MyType; bool MyTypes::first() { mp1MyType = mLstMyTypes.begin(); return ( mp1MyType != mLstMyTypes.end() ); } bool MyTypes::next() { if ( mp1MyType != mLstMyTypes.end() ) { ++mp1MyType; if ( mp1MyType != mLstMyTypes.end() ) return true; } return false; } MyType* MyTypes::getPresent() const { return ( mp1MyType != mLstMyTypes.end() ) ? *mp1MyType : nullptr; } -
Again, without seeing the actual code, it is hard to answer definitively. Ideally, you would just set a flag that your server's OnExecute event handler can look for periodically and close the connection of the calling thread so it can terminate gracefully. But, if you absolutely had to close the connection quickly, then calling Binding.CloseSocket() from outside the server should suffice (like I said, modern Indy already does that, but maybe your older version is not), provided you are not swallowing any subsequent exceptions that may arise.
-
Just because you are on a budget doesn't mean you should use outdated tools. Especially tools that can be obtained for free. What you describe sounds like the TCP server threads are not shutting down correctly. There couple be a number of reasons for that to happen. For instance: Are you catching and discarding the exceptions? If so, don't discard them. Rethrow them and let the server handle them. Are you shutting down the server in the main thread, and syncing with the main thread in your server events? If so, that is a guaranteed deadlock. Either shutdown the server from a worker thread so the main thread is free to continue processing sync requests. Or simply get rid of the syncs during shutdown. Is the client creating a new connection for each poll? Or reusing connections? Simply closing the sockets may not be enough. The server has to be allowed to process the closures so it can terminate its worker threads. Besides, TIdTCPServer already calls CloseSocket() internally during its shutdown. At least it does in recent years - it USED to call Disconnect() instead, but that proved to cause problems with OpenSSL connections across thread boundaries. Hard to say without seeing your actual code to see why it is not shutting down correctly. Possibly. Again, hard to say without knowing the root cause first. Define "safely". Is there a particular problem you are thinking of? Known issues are documented in the Update instructions, ie: https://github.com/IndySockets/Indy/wiki/Updating-Indy#delphicbuilderradstudio-101-berlin-and-later
-
memory; Memory not freed in Linux but freed in Windows
Remy Lebeau replied to michel.seicon's topic in Cross-platform
Unfortunately, that is not how Delphi's memory manager works, on any OS. Freed memory is held onto and reused, it is rarely returned to the OS until the app is exited. You should consider re-writing your code to make better use of memory buffers so they are (re-)allocated and freed less often. That is not true. Memory management and fragmentation are important issues to be aware of on Windows too, or any OS for that matter. -
File opening error C++ builder CE trivial program
Remy Lebeau replied to BruceV's topic in General Help
You probably need to recreate the project and make sure the VCL library is enabled. That wasn't the point of the exercise, though. It was to get more details about why the file is not opening correctly. But, if CreateFile() succeeds and std::ifstream fails, then there has to be another factor at play that is not being accounted for. -
Waiting for anonymous methods to complete
Remy Lebeau replied to brk303's topic in RTL and Delphi Object Pascal
You have a race condition. You are incrementing the counter at the point where the work is actually performed, but if the work is merely queued but the work thread hasn't actually started the work yet, then the counter may not have been incremented yet by the time you compare it in your destructor. You need to increment the counter at the point where the work is being queued, not where it is acted on. You didn't say which platform(s) you are targeting, On Windows for instance, a better strategy would be to put the thread's handles into an array, and then you can use (Msg)WaitForMultipleObjects() to wait for the handles to be signaled when the threads are fully terminated. However, you mention anonymous threads, so be aware that TThread.CreateAnonymousThread() sets TThread.FreeOnTerminate=true, which doesn't mix well with waiting on thread handles. So you would have to manually set FreeOnTerminate=false when starting the anonymous threads, and then free the threads yourself when they are finished running. -
NULL iterators in C++ Builder - 32 bit vs. 64 bit
Remy Lebeau replied to Arvid P.'s topic in General Help
Can you show the actual code? Standard iterators are not initializable/comparable with NULL values. So your code is likely wrong to begin with and just happened to work before due to implementation details of the old standard library, but the new standard library is exposing your bugs. You need to fix your buggy code to use iterators correctly. But it's hard to explain what you need to change until we see what you are actually doing. -
TCP Port Check with timeout
Remy Lebeau replied to chmichael's topic in ICS - Internet Component Suite
You are leaking the socket handle if connect() fails. You have to close the handle if socket() succeeds, regardless of whether connect() succeeds. You can't reduce (or even set) the timeout on a blocking connect(). You have to use a non-blocking connect() and then use select() or equivalent to implement the timeout. AFAIK, you can't disable SACK on a per-socket basis. You have to use the Registry or command-line netsh utility to disable it globally: https://superuser.com/questions/1808254/how-to-disable-tcp-sack-in-windows-xp https://www.linkedin.com/advice/3/how-can-tcp-selective-acknowledgment-sack-improve-heatc -
The standard FMX TMemo simply does not support HTML (or even basic text formatting in general). You will have to use a 3rd party control (or make your own from scratch) to display rich/formatted text.