Jump to content

Remy Lebeau

Members
  • Content Count

    3000
  • Joined

  • Last visited

  • Days Won

    135

Everything posted by Remy Lebeau

  1. Remy Lebeau

    Check if database table string field is empty or NULL??

    IsNullOrEmpty() is a method of TStringHelper, so you have to call it on a string instance, eg: if MyTable.FieldByName('MyField').AsString.IsNullOrEmpty then Which is really no better than simply testing for an empty string (since AsString can't return a null string): if MyTable.FieldByName('MyField').AsString = '' then However, since Delphi strings don't differentiate between null and empty (they are both a nil pointer), if you really need to differentiate then you will have to use TField.IsNull instead, eg: if MyTable.FieldByName('MyField').IsNull then // is null ... else if MyTable.FieldByName('MyField').AsString = '' then // is empty ... else // is not null or empty ...
  2. Remy Lebeau

    New Installation of Rad Studio 10.2 (Tokyo)

    Are you using the Feature installer (Web) or the Offline installer (ISO)?
  3. Remy Lebeau

    Audio via TCP/IP

    Note that TCP is usually not a good choice for streaming media, due to delays caused by latency, integrity checks, acks, etc. TCP is good to use when you need to ensure the receiver actually gets everything that is sent. But since real-time streaming media doesn't usually require that, dropped packets here and there are usually tolerable, so UDP is used instead, typically with a streaming media protocol on top of it, like RTP, etc.
  4. Remy Lebeau

    How to Send HTTP data in Delphi

    Delphi ships with Indy pre-installed, which has a TIdHTTP component. Modern versions of Delphi also have native THTTPClient/TNetHTTPClient components, too. But either way, you can't just send arbitrary data to the ESP without understanding what it is actually expecting. Do you have any documentation on what exactly it actually wants clients to send it? What do the required URLs look like? What input parameters are they expecting? Are they query-string parameters, or post-body parameters? Etc
  5. Remy Lebeau

    Patch a private virtual method

    The OS is not involved in this process. Instantiating an object is simply a matter of allocating a memory block to hold the data members, and then calling the class constructor on that memory block to initialize the data members. Any methods called on an object (including the constructor and destructor) is simply a matter of making a normal function call with a pointer to the object as a (hidden) parameter so the code knows which object is being act on. There are no copies of the method instructions being made. There is only 1 copy in memory that all objects share. Calling the same method on multiple objects will execute the same code instructions just with a different object parameter. It will fail if the patched method tries to access any data members that don't actually belong to the actual object that the method is being called on.
  6. Remy Lebeau

    CreateProcess causing some strange Access Violations

    Using the Addr() intrinsic in that way will give you the memory address of the _TaskDialogIndirect variable itself, not the memory address that the variable holds. Try inspecting just _TaskDialogIndirect by itself, or at least cast it to a Pointer.
  7. Remy Lebeau

    CreateProcess causing some strange Access Violations

    It is not an implementation detail, it is documented behavior: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
  8. Remy Lebeau

    CreateProcess causing some strange Access Violations

    That means you are trying to call a function through a nil function pointer. Did you check to see whether _TaskDialogIndirect is nil or not?
  9. Remy Lebeau

    CreateProcess causing some strange Access Violations

    Incorrect, it is the 2nd argument that must be writable. And only in the Unicode version.
  10. Remy Lebeau

    Centered message?

    There is also ShowMessagePos() for that purpose.
  11. Remy Lebeau

    DL a file from the web

    INVALID_HANDLE_VALUE is not null (0), it is -1. Some APIs return 0 on failure, some return -1 instead. Be careful mixing them up. See Why are HANDLE return values so inconsistent?
  12. Remy Lebeau

    DL a file from the web

    The point I was trying to make is that, if InternetOpen() fails, the value of HFile is left indeterminate, so calling InternetCloseHandle() on it is undefined behavior. Also, InternetCloseHandle() is not documented as accepting null handles, so if either InternetOpen() or InternetOpenUrl() fails, calling InternetCloseHandle() on the failed handle is also undefined behavior. So, best to call InternetCloseHandle() only on successfully opened handles. Which means, using multiple try..finally blocks. Calling GetLastError() multiple times mixed in other system calls risks having the error code wiped out in between the calls. Best to save the error code to a variable as soon as possible, and then use the variable where needed. Yes. Which is why one should generally use WriteBuffer() instead, which will raise if not all bytes are written.
  13. Remy Lebeau

    DL a file from the web

    This code has many small mistakes. Too many try's. Undefined behavior calling InternetCloseHandle() on invalid handles if either InternetOpen() or InternetOpenUrl() fail. Misuse of GetLastError(). Not reporting an error if InternetReadFile() fails. Not making sure FBuffer actually writes all of the bytes it is given.
  14. Remy Lebeau

    Patch a private virtual method

    Not a copy, but the original. All object instances of a class have their own copies of data members, but they all share a single set of code, vtables, etc in memory. So, patching a method of a class will affect all object instances of that class. Not sure I understand what you are asking.
  15. Remy Lebeau

    DL a file from the web

    It raises an exception on error. However, internally it uses Windows' Urlmon.URLDownloadToFile() function, which is notoriously buggy, and crappy at reporting errors.
  16. No. First, not even considering threads yet, TApplication is simply not designed to run multiple instances at a time. There are globals that it uses internally which it assumes it has exclusive access to, and will not share well with other instances. Also, there is plenty of code inside of the VCL that assumes there is only 1 global TApplication object, and won't even consider the existence of other instances. Second, considering threads, the VCL is simply not thread-safe to begin with. It is not designed to be used in multiple threads at a time. VCL controls are expected to be used only in the main UI thread which runs the single global TApplication object. Also, the VCL runs on top of the Win32 API, and API window handles have an affinity to the thread that creates them, which restricts which threads are allowed to access them. And VCL controls simply don't react well when those window handles get messed up when accessed across thread boundaries. Don't do it. That is a very bad design choice. Handle all of your UI needs in the default main UI thread only. You can use multiple worker threads to handle your business logic however you want, and you can create a separate TForm to associate with each worker thread if that is what you need. Just make sure that any data you share across threads is adequately protected from concurrent access, and that you have worker threads synchronize with the main UI thread whenever they need to access the UI.
  17. Those are not valid Delphi declarations. Those are valid Delphi declarations (well, almost - Write() needs a semicolon instead of a comma between Buffer and Count). They work the same as they do in C++. Most likely, you are simply passing in the wrong values, so you end up reading/writing data from the wrong memory addresses. Hard to say since you did not show the code you are having trouble with. In Delphi, an untyped 'const'/`var' parameter is just a reference to a memory address, so you can pass in whatever variable you want and the compiler will pass in the memory address of that variable. In C++, the closest equivalent to that is a '(const) void*' pointer, using the '&' operator to get the address of a variable. So, in Delphi, to read/write data from/to an array, for instance, you would pass in the 1st element of the array, and the compiler will pass in the memory address of that element. On the other hand, if you have a pointer to memory, you would have to dereference the pointer so the parameter can receive the memory address of the thing being pointed at. Here is a few examples using different types of memory: var Value: Integer; ComPort.Read(Value, SizeOf(Value)); ComPort.Write(Value, SizeOf(Value)); var Buffer: array[0..255] of Byte; ComPort.Read(Buffer[0], SizeOf(Buffer)); // or: ComPort.Read(Buffer, SizeOf(Buffer)); ComPort.Write(Buffer[0], SizeOf(Buffer)); // or: ComPort.Write(Buffer, SizeOf(Buffer)); var Buffer: array of Byte; SetLength(Buffer, ...); ComPort.Read(Buffer[0], Length(Buffer)); // or: ComPort.Read(PByte(Buffer)^, Length(Buffer)); ComPort.Write(Buffer[0], Length(Buffer)); // or: ComPort.Write(PByte(Buffer)^, Length(Buffer)); var Str: AnsiString; SetLength(Str, ...); ComPort.Read(Str[0], Length(Str)); // or: ComPort.Read(PAnsiChar(Str)^, Length(Str)); ComPort.Write(Str[0], Length(Str)); // or: ComPort.Write(PAnsiChar(Str)^, Length(Str)); var UStr: UnicodeString; SetLength(UStr, ...); ComPort.Read(UStr[0], Length(UStr) * SizeOf(WideChar)); // or: ComPort.Read(PWideChar(Str)^, Length(UStr) * SizeOf(WideChar)); ComPort.Write(UStr[0], Length(UStr) * SizeOf(WideChar)); // or: ComPort.Write(PWideChar(Str)^, Length(UStr) * SizeOf(WideChar)); type PMyRec = ^TMyRec; TMyRec = record Value: Integer; ... end; var Ptr: PMyRec; NumBytes: Integer; NumBytes := SizeOf(TMyRec) * ...; GetMem(Ptr, NumBytes); ComPort.Read(Ptr^, NumBytes); ComPort.Write(Ptr^, NumBytes); FreeMem(Ptr); Those are compiler intrinsic functions, they have special handling for parameters that you don't normally get with user-defined functions.
  18. Remy Lebeau

    TTreeview to JSON VCL?

    Duplicate:
  19. Remy Lebeau

    Write process memory

    There is no link (not that it matters, I didn't ask for the code, I asked you to clarify your question). That doesn't clarify anything. My earlier question still stands.
  20. Remy Lebeau

    Write process memory

    I'm not sure what you are asking for exactly. Are you asking for someone to make a GUI frontend for your code? Or, do you want to write to memory of an external GUI program? Writing to a process's memory is the title of this discussion thread, but your code is not attempting to do that. So your question seems to be about something else entirely. Please clarify.
  21. Remy Lebeau

    Creating HTTPS connection with Indy TIdHTTPserver

    As the browser's error message says, your server's certificate doesn't prove that 127.0.0.1 and mycomputer are the same entity, so the browser fails the handshake. Did you try connecting to https://mycomputer:4567 instead? The certificate you have is registered to a hostname, so that hostname must be specified in the URL used to access the server. See: Is it possible to have SSL certificate for IP address, not domain name?
  22. The response is sending you back an HTML page with Javascript on it. Is it possible that the Javascript is manipulating the page in a way that affects the HTTP requests? This goes back to my earlier comments. Stop focusing on the HTML, you need to pay closer attention to the raw HTTP traffic instead. You need to use your browser's built-in debugger to see what requests are actually being sent, and what responses are actually being received. Then you can just replicate those in your code as needed. Until you can get that raw traffic that, I can't help you any further. The POST request is sending back the same cookie that the GET response contained: From GET Response: Set-Cookie: ASPSESSIONIDQWRQBQCS=JM.................CL; secure; path=/ In POST request: Cookie: ASPSESSIONIDQWRQBQCS=JM.............CL The POST response is then sending back a new cookie: Set-Cookie: ASPSESSIONIDQWRQBQCS=MM............BP; secure; path=/ That is perfectly normal and acceptable. It is the same cookie name, just a different value. The server is well within its right to change the value of a cookie between requests. In this case, the cookie contains state information, and clearly that state is changing.
  23. TThread internally checks its Terminated property before calling Execute(). When you destroy a TThread that hasn't finished yet, the TThread destructor calls Terminate() and WaitFor() on itself. So, if you destroy a TThread before it even begins running, Execute() won't be called. That is nothing new, TThread has behaved this way for many years.
  24. Yes, leave the double-quotes off. A space character will be encoded as '%20' during transmission, eg: 'del=my%20delete' Because you didn't send the correct 'del' value, the server script probably didn't understand that you were asking for a delete operation. Again, before you can code the requests properly, you first need to study and understand what a web browser sends for each request. I'm not at a computer right now, so I can't look at that file. I'll have to look at it later.
  25. Remy Lebeau

    Attach to Process along with Stepping through Code

    Then ignore the Remote Debugger and the .rsm file (turn off remote debug symbols). All you need is the .tds file alongside the .exe file.
×