Jump to content

Remy Lebeau

Members
  • Content Count

    2337
  • Joined

  • Last visited

  • Days Won

    95

Everything posted by Remy Lebeau

  1. Remy Lebeau

    Binary data in String?

    Most likely, that code predated the shift to Unicode in Delphi 2009. No, it doesn't. It has the potential to corrupt the data. This is exactly why you SHOULD NOT put binary data into a UnicodeString. Doesn't work. It fills only 1/2 of the UnicodeString's memory with the non-textual binary (because SizeOf(WideChar) is 2, so the SetLength() is allocating twice the number of bytes as were read in), then converts the entire UnicodeString (including the unused bytes) from UTF-16 to ANSI producing complete garbage, and then writes that garbage as-is to file. So yes, the same number of bytes MAY be written as were read in (but that is not guaranteed), but those bytes are useless. That code is copying the binary as-is into an AnsiString of equal byte size, converting that AnsiString to a UTF-16 UnicodeString using the user's default locale, then converting that UnicodeString from UTF-16 back to ANSI using the same locale. Depending on the particular locale used, that MAY be a lossy conversion, you MIGHT end up with the same bytes that you started with, or you MIGHT NOT. This has nothing to do with pointers. You are simply performing 2 separate data conversions (binary/ANSI -> UTF-16 -> binary/ANSI ) that just HAPPEN to produce the same results as the input IN YOUR ENVIRONMENT.
  2. Remy Lebeau

    TIDHTTPServer not receiving POST

    Then there is no reason why TIdHTTPServer should not be calling the events. So, you are just going to have to debug into the server's code to find out where it is hanging. Are the OnHeadersAvailable, OnCreatePostStream, OnParseAuthentication, and OnCreateSession events being called? In the log you showed, there is an extra > before the Content-Length header. Is that really present in the request, or is that just a typo when posting the log here? Then I strongly suggest you add them.
  3. Remy Lebeau

    TIDHTTPServer not receiving POST

    Clearly the server IS receiving the POST request, you can see it in your log file. But if the OnCommand... events are not being called, it usually means the request is incomplete, ie if TIdHTTPServer is waiting for more data that is not received. Note the log also shows the TCP connection being disconnected at the same time the request is received. So, the client is likely dropping the connection on its end before sending the full 1523 bytes that it claimed to be sending. BTW, 10.6.1 is not the latest version of Indy, the current version is 10.6.2.
  4. I second VMWare, but I've always just used the free version, never the paid version.
  5. Remy Lebeau

    Error parsing winmail.dat

    Type 72 is PT_CLSID, not sure what attribute 32768 ($8000) is. TIdCoderTNEF does not implement either one at this time. There are a LOT of MAPI properties that are not implemented yet. TIdCoderTnef is mainly concerned with extracting things that make sense to apply to a TIdMessage. I can look into maybe having TIdCoderTnef just skip unknown fields instead of raising an exception on them. Or maybe exposing an event so user code can decide what to do with them.
  6. Remy Lebeau

    Is there any way to install delphi 10.4 package into Delphi 10.3?

    Package binaries are specific to each compiler version. 10.3 can only use packages that have been compiled for 10.3, etc. If you have the source code for the 10.4 package, you will have to compile it using 10.3's compiler.
  7. Remy Lebeau

    Outlook Server Execution Failed

    What does this have to do with Indy? You are getting an ActiveX/COM error, not a socket error. Either Outlook is not installed, or it is malfunctioning, or your app simply doesn't have permission to run it.
  8. Remy Lebeau

    Do bug fix patches really require active subscription?

    https://www.embarcadero.com/update-subscription
  9. Remy Lebeau

    Find exception location from MAP file?

    Last time I tried that (last year), I couldn't get it to work. So I had to write my own stack tracing code from scratch, which "works" but it doesn't display function names yet, only memory addresses relative to the process' base address. And that project has since been EOL'ed, so I can't go back and update it.
  10. Remy Lebeau

    Prevent Alt or Ctrl + Print Screen

    On Windows 7 and later, you can use SetWindowDisplayAffinity() to specify that you want your Form window to only appear on a monitor display. That will omit (black) it out in screen captures, etc.
  11. Remy Lebeau

    Show a FMX form inside a dll from a VCL application

    Not safely, no. Is it legal to have a cross-process parent/child or owner/owned window relationship?
  12. Remy Lebeau

    Find exception location from MAP file?

    The *preferred* base addresses are in the map file, as well as in exe/dll PE headers, but it is not guaranteed that exe/dll modules will actually use those base addresses at runtime (typically, they will, but the OS is free to move them somewhere else). You can use the Win32 GetModuleHandle() function, or the RTL's SysInti.HInstance, to get the actual base address at runtime.
  13. There are 3rd party Object Inspectors available, if you search around. Or, you could write your own editor using the VCL's TValueListEditor component and some manual RTTI logic.
  14. That article is written for saving a single component to a file, not for saving multiple components. I would suggest saving the TForm itself rather than each of its child components individually.
  15. Why? The C code clearly names the parameter "num_elements", so it stands to reason that it expects an "element count", not a "byte count". A dynamic array is already a pointer, so you don't need to index into the array, PInteger(data) will suffice.
  16. Remy Lebeau

    Choose a Folder dialog

    No. IFDEF your code to call the relevant OS APIs directly (SHBrowseForFolder()/IFileOpenDialog on Windows, etc). Or else just make your own dialog/Form that iterates the filesystem (ie, via the System.IOUtils.TDirectory class) and display the contents as needed.
  17. No, it is worse than that. TThread.Synchronize() puts the specified method pointer into a global thread-safe queue, along with a waitable event, then posts a signal to the main UI thread letting it know the queue is pending, and then waits on the queued event to be signaled. The main UI thread periodically iterates the queue (whenever it receives the posted signal, as well as whenever the main message loop enters an idle state, or user code calls Classes.CheckSynchronize() directly). All of the queued methods are called in order, and their events are signaled to unblock their waiting threads.
  18. Remy Lebeau

    TFileStream fmShare modes

    Sharing flags are used with the Mode parameter, not the Rights parameter. Creation and Sharing flags can be OR'ed together in the Mode parameter, eg: Result := TFileStream.Create(FileName, fmOpenReadWrite or fmShareDenyNone{, 0}); That was true in the old days when fmCreate was defined as $FFFF and thus could not be mixed with any other flags, but that is no longer the case. When the Rights parameter was introduced (which is not used on Windows when fmCreate is used), fmCreate was redefined as $FF00 so it can now be mixed with sharing flags, eg: fs := TFileStream.Create(FileName, fmCreate or fmShareDenyNone{, 0}); If no sharing mode is specified, fmShareCompat is the default, except in the specific case of the old fmCreate value ($FFFF) being used, in which case the default is fmShareExclusive instead for backwards compatibility. But either way, on Windows, fmShareCompat and fmShareExclusive mean the same thing - there is no sharing enabled on the file.
  19. No, when ABinding is bound to a wildcard IP like '::0'. Internally, TIdUDPServer uses recvfrom() to read packets, and the information you want is simply not available from recvfrom(). You would need to use recvmsg()/WSARecvMsg() instead (ie, via Indy's TIdStack.ReceiveMsg() method), which requires the IP_PKTINFO/IPV6_RECVPKINFO option be enabled on the socket for recvmsg() to report the receiving adapter's info on each packet read. TIdUDPServer does not support recvmsg(), though. You would have to alter its source code and recompile. Otherwise, you could use TIdUDPClient instead and run your own reading logic with it (despite their names, TIdUDPClient and TIdUDPServer are not true client/server components since UDP is connectionless, so their roles are a little more blurry than with TCP. You can use TIdUDPClient as a server, and TIdUDPServer as a client). Otherwise, you could simply enumerate the local IPs (ie via Indy's TIdStack.GetLocalAddressList() method) and create a separate Binding for each IP individually, and then ABinding.IP will have a meaningful value in the OnUDPRead event. This does mean that TIdUDPServer would need to allocate multiple sockets, though. No. Sending data out from a bound socket will use the IP of the adapter that the socket is bound to. If the socket is bound to a wildcard IP, then the OS will pick which adapter to use, based on its own routing tables for the destination IP. If you want to send out from a specific adapter, you need to either create and bind a separate socket (ie TIdUDPClient) to that adapter, and then send using that socket. use sendmsg()/WSASendMsg() (which Indy does not have a wrapper for), passing in a msghdr struct containing an IP_PKTINFO/IPV6_PKTINFO control message that specifies the desired source IP and interface index. See Setting the source IP for a UDP socket
  20. Almost. It would be more accurate to say that it binds to all local network adapters for the Binding's specified IPVersion. The IPVersion is set to IPv4 by default (see the ID_DEFAULT_IP_VERSION constant in IdGlobal.pas). You would need 2 separate Binding objects to bind to all IPv4 and IPv6 adapters at the same time, as TIdUDPServer would have to create separate IPv4 and IPv6 listening sockets (Indy does not support dual-stack sockets at this time: ticket #29). For example: IdUDPServer.DefaultPort := ...; with IdUDPServer.Bindings.Add do begin IP := ...; IPVersion := Id_IPv4; end; with IdUDPServer.Bindings.Add do begin IP := ...; IPVersion := Id_IPv6; end; If you don't create any Bindings at all, TIdUDPServer will create 1 or 2 default Binding objects for you, depending on whether the underlying platform allows separate IPv4+IPv6 sockets to be bound on all adapters on the same port at the same time (not all do, ie Linux and Android do not, but Windows does). The above IP is an IPv6 address, so I'm guessing you have not created an IPv6 Binding to listen on. You can't bind an IPv4-only socket to IPv6 adapters, and vice versa.
  21. Remy Lebeau

    Issues with Sleep(1) called in a loop

    And also: https://stackoverflow.com/questions/9518106/winapi-sleep-function-call-sleeps-for-longer-than-expected
  22. Remy Lebeau

    SetLength TBytes Memory Leak

    The call stack in that log also looks a little off. System._DynArraySetLength() does not call System._LStrFromPWCharLen(), and System._LStrFromPWCharLen() does not call System.DynArraySetLength(). System._DynArraySetLength() calls System.DynArraySetLength() directly. So, even though the code shown does call System._LStrFromPWCharLen() (on the RawByteString type-cast), that call should not be on the call stack anymore when System._ReallocMem() is called.
  23. Remy Lebeau

    Timer game delphi 7

    This would be easier: seconds:=seconds mod 60;
  24. Remy Lebeau

    GMail Inbox

    Sorry, I don't know what that means. UIDs are unique within a given folder, but not necessarily across folders. Multiple folders can refer to the same message. And UIDs are persistent only so long as the folder's UIDValidity value doesn't change. If you save a UID across sessions, you have to check if the folder's UIDValidity has changed before you can use the UID again. When you select a folder with TIdIMAP4.SelectMailBox(), its current UIDValidity value is stored in the TIdIMAP4.MailBox.UIDValidity property. Refer to RFC 3501 section 2.3.1.1 for more details. TIdIMAP4.SearchMailBox() returns message numbers, not UIDs. If you want UIDs, use TIdIMAP4.UIDSearchMailBox() instead. Otherwise, you can extract a UID from the result of TIdIMAP4.RetrieveHeader(), or pass message numbers from TIdIMAP4.SearchMailBox() to TIdIMAP4.GetUID().
  25. Remy Lebeau

    GMail Inbox

    Looks like you have extra spaces surrounding the 189. Do you get the same error if you remove them? Also, I found this, might be useful: How to remove a label from an email message from Gmail by using the IMAP protocol?
×