Jump to content

Remy Lebeau

Members
  • Content Count

    2684
  • Joined

  • Last visited

  • Days Won

    113

Everything posted by Remy Lebeau

  1. Remy Lebeau

    Windows PATH length limit?

    In theory, up to 32K: What is the maximum length of an environment variable? The actual PATH environment variable itself is not limited to that length, but in practice, various tools that set the path, and various APIs that use the path, are limited. https://superuser.com/questions/1385854/how-do-i-bypass-restrictions-on-the-length-of-the-path-variable https://www.askwoody.com/forums/topic/what-is-the-real-path-length-limit-in-windows-10/ https://learn.microsoft.com/en-US/troubleshoot/windows-client/shell-experience/command-line-string-limitation That last one theorizes that the PATH could be as much as 8K, not 2K. So, the limitation is not so much on the variable itself, but on how it's used.
  2. Remy Lebeau

    Delphi Clipboard - WM_CLIPBOARDUPDATE (sent, but no changes)

    Yes, it does. That is showing you that the sequence number isn't changing,which means the clipboard content is not changing. You are just getting spurulous messages. So check the sequence number on each message and if it hasn't changed value since the last time you called it then ignore the message.
  3. Remy Lebeau

    Delphi Clipboard - WM_CLIPBOARDUPDATE (sent, but no changes)

    Try using GetClipboardSequenceNumber() on each message to check if the clipboard content has actually changed. Also, the OnCreate/OnDestroy events are not the best place to register/remove your listener. Those events are tied to the lifetime of the Form object, not its HWND window, which may be recreated dynamically during the Form's lifetime. You should instead override the Form's virtual CreateWnd() and DestroyWnd() methods.
  4. Remy Lebeau

    FindFirst (Delphi) vs Dir * /s

    There are 2 other mistakes in the FindFirst code - It is counting all of the files AND the subdirectories (despite MikeZ87's claim to the contrary) AND the '.' and '..' entries. Every time FileSearch() is called, it is searching the C:\ root again and again. It is not searching the DirName that is passed in. Try this instead: var MyTotal : Int64; //This gets set to 0 in the button.click code when FileSearch is initially run. procedure TForm1.ButtonClick(Sender: TObject); begin MyTotal := 0; FileSearch('C:'); end; procedure TForm1.FileSearch(dirName: string); var searchResult: TSearchRec; begin dirName := IncludeTrailingPathDelimiter(dirName); if FindFirst(dirName + '*', faAnyFile, searchResult) = 0 then begin // <-- NOT THE ROOT! try repeat if (searchResult.Attr and faDirectory) = 0 then begin Inc(MyTotal); // <-- MOVE HERE! //... end else if (searchResult.Name <> '.') and (searchResult.Name <> '..') then begin FileSearch(dirName + searchResult.Name); end; until FindNext(searchResult) <> 0; finally FindClose(searchResult); end; end; end; That being said, I would suggest a slight modification - make FileSearch() be a function that returns the file count, rather than modifying a class member, eg: procedure TForm1.ButtonClick(Sender: TObject); var TotalFiles : Int64; begin TotalFiles := FileSearch('C:'); // use TotalFiles as needed... end; function TForm1.FileSearch(dirName: string): Int64; var searchResult: TSearchRec; begin Result := 0; dirName := IncludeTrailingPathDelimiter(dirName); if FindFirst(dirName + '*', faAnyFile, searchResult) = 0 then begin try repeat if (searchResult.Attr and faDirectory) = 0 then begin Inc(Result); //... end else if (searchResult.Name <> '.') and (searchResult.Name <> '..') then begin Inc(Result, FileSearch(dirName + searchResult.Name)); end; until FindNext(searchResult) <> 0; finally FindClose(searchResult); end; end; end;
  5. Remy Lebeau

    random 404 errors

    Did you check the Apache logs for problems? You can enable SSL/TLS in TIdHTTPServer. But no, Indy does not natively support an up-to-date version of OpenSSL yet, only up to 1.0.2u, but that does support TLS 1.2. However, there are other 3rd party options for using newer TLS versions with Indy. And, nothing stops you from writing a custom TIdSSLIOHandlerSocketBase-derived class to interact with whatever TLS library you want. So, it is not an ideal situation, but it is not a show-stopper, either. What you showed is not an HTTP 404 error. It sounds like a communication problem between the proxy and the TIdHTTPServer. Then you are just going to have to keep debugging and logging until you can figure out what reproduces it. It should be fine, provided the ports are being blocked by either the firewall or the OS.
  6. Remy Lebeau

    random 404 errors

    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.
  7. Remy Lebeau

    Access violation installing a component

    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?
  8. Remy Lebeau

    TTrayIcon (Hidden main window and second form)

    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.
  9. Remy Lebeau

    how to delete TFDTable after open

    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.
  10. Remy Lebeau

    Drag and DPR

    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.
  11. 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
  12. 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.
  13. 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.
  14. Remy Lebeau

    "EIdSocketError" on S3 file upload - Delphi 7

    Then you should have gotten an exception like EIdOSSLCouldNotLoadSSLLibrary from TIdHTTP when it failed to load the necessary TLS functions from the DLLs.
  15. Remy Lebeau

    "EIdSocketError" on S3 file upload - Delphi 7

    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?
  16. 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.
  17. 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?
  18. Remy Lebeau

    Show percentage in VCL TProgressBar

    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.
  19. Remy Lebeau

    NULL iterators in C++ Builder - 32 bit vs. 64 bit

    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()); }
  20. Remy Lebeau

    Cursor "crNo"

    crNo DOES map to a system cursor - IDC_NO: Why it is not transparent, who knows. Ask Microsoft.
  21. Remy Lebeau

    New to delphi

    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.
  22. Remy Lebeau

    NULL iterators in C++ Builder - 32 bit vs. 64 bit

    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; }
  23. Remy Lebeau

    Indy version question

    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.
  24. Remy Lebeau

    Indy version question

    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
  25. Remy Lebeau

    Memory not freed in Linux but freed in Windows

    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.
×