Jump to content

w0wbagger

Members
  • Content Count

    32
  • Joined

  • Last visited

Everything posted by w0wbagger

  1. I was finally able to compile and install ICS 9.3 for C++ Builder 12.2, and while I was able to compile and run the (delphi, .dproj) SslFTPServer demo, when I create a new C++ Builder project and place a TFTPServer (Not an TSslFTPServer) component on the form, I can connect to it using a regular ftp client, but the connection doesn't seem to "Return". That is, I can't enter a subsequent command like USER or PASS. Even though I've compiled the ics library with debug info, I can't seem to debug into overbyteicsftpSrv,pas just OverbyteicsWsockets.pas. I know there aren't a lot of C++ Builder users here, but I can't think of why something would compile and run with the libs I installed in C++ Builder as a .dproj, I can't build a simple C++ App (literally 1 component on a form). Might anyone have an idea? Thanks.
  2. w0wbagger

    ICS TFTPServer on C++ Builder 12.2

    Have to give up on this for now. TFTPServer and TSslFTPServer do not seem to work for me in C++ Builder. I can compile and run the .dproj demo (it works correctly), but cannot create the simplest native C++ Builder app with either component. It connects (triggers OnClientConnect), but then hangs. I can't seem to debug into the .pas source, so can't figure out why. The fact I can run the .dproj sample program okay would indicate to me that the .lib file is correct, and it must be something about how the .hpp files are generated that somehow screw it up? Anyway, if there's anyone else using C++ out there, I've sent Angus some updates for the package directory .proj files that make the library compilable. Maybe the other components work, but T(Ssl)FTPServer doesn't seem to, unfortunately. Here's what the ICSLogger captured: 21:54:04:484 054684F0 Listening 21:54:04:499 SslFtpServer1 started 21:54:13:060 054684F0 Do_FD_ACCEPT handle=1632 21:54:13:063 08B427E0 Client Connect Error - No Error (#0) -1 21:54:35:908 054684F0 SocketCloseCalled handle=1632 21:54:35:910 054684F0 TCustomWSocket.Shutdown 1 handle=1632 21:54:35:913 054684F0 ResetSslSession starting handle=-1 21:54:35:921 ResetSslSession SetShutDown FSsl handle=0 21:54:35:927 ResetSslSession FSslBio handle=0 21:54:35:928 ResetSslSession FNBio handle=0 21:54:35:929 ResetSslSession Fibio handle=0 21:54:35:929 ResetSslSession Close FSsl handle=0 21:54:35:940 054684F0 ResetSslSession Done 21:54:35:940 SslFtpServer1 stopped and here's the client side log: . 2024-10-13 21:54:13.059 Session upkeep . 2024-10-13 21:54:13.099 Connecting to 127.0.0.1 ... . 2024-10-13 21:54:13.099 Connection pending . 2024-10-13 21:54:13.099 Connected with 127.0.0.1. Waiting for welcome message... . 2024-10-13 21:54:28.748 Timeout detected. (control connection) . 2024-10-13 21:54:28.748 Connection closed . 2024-10-13 21:54:28.748 Connection failed. . 2024-10-13 21:54:28.748 Got reply 1004 to the command 1 * 2024-10-13 21:54:28.809 (EFatal) Connection failed. * 2024-10-13 21:54:28.809 Timeout detected. (control connection) * 2024-10-13 21:54:28.809 Connection failed.
  3. w0wbagger

    ICS TFTPServer on C++ Builder 12.2

    Thanks Angus, I'll try your suggestions now. The server never responds with the "Welcome" lines. it does trigger a "ConnectClient" event, (I can log this okay), but then never returns control to my ftp session to allow me to enter a USER command. Will let you know how I get on with your suggestions, thanks.
  4. w0wbagger

    ICS TFTPServer on C++ Builder 12.2

    It calls OnClientConnect, and I am able to enter some log entries there (although as I mentioned, Client->GetPeerAddr() returns '' in it). But then, nothing. My understanding of the component is it should then send a request for User/Pass, but it doesn't seem to get to this point. Is there some other trigger between connect and the Banner/request for User that I might trap to log? Here's what inspecting the Client * looks like in OnClientConnect. It looks...incomplete? ftpState is ftpcWaitingUserCode, but on the client side, control hasn't returned to me to enter USER or PASS. Does this suggest an issue at a lower-level function?
  5. w0wbagger

    ICS TFTPServer on C++ Builder 12.2

    I'll try. It's strange. I wrote two apps, one with the TFtpClient component, one with the TFtpServer component. If I use the *updated* client app with the *old* TFtpServer app (the one written with 8.7, the last time I was able to compile ICS in C++ Builder), it works fine. As soon as I try replacing the old TFtpServer App with the new one, it stops. I was logging ClientConnect in the new version, and noticed that when it's called, the PeerAddr is NULL. Something must have changed. I'll check the changelogs to see if I can pinpoint what's happened, but as of now, I'd say TFtpServer is not backwards compatible in C++ Builder, while TFtpClient still works correctly (8.7->9.3).. I'll try using an sslFTPServer component and see if I have any better luck, too. Just writing these in case anyone else is trying to get this working in C++ Builder.
  6. Hey folks, we've been dealing with this issue for more than a decade, and I'm only now finally asking if there's an elegant solution for updating my project files when we upgrade RAD Studio version. We use a few 3rd party libraries (Devart, DevExpress, ICS), and every time we upgrade, the library file names change (for example from libXXXR28 to libXXXR29). Generally, this means we have to find everywhere in our project file that the old library files are referred to and update them. Is there an easier way of doing this? If we just create a brand new project with all of the original source files, will it automatically add the .lib files the project requires? How *does* RAD Studio identify which of the installed .lib files are required in a project? Thanks in advance for any advice on how you migrate your projects to the most recent version of RAD Studio.
  7. w0wbagger

    ICS V9.1 announced

    Just installed 12.2 and pulled the most recent build, and nothing compiles/builds/installs properly in C++ Builder. I guess I'll have to start from scratch again trying to get this compiled and installed. Sorry, Angus. Does Embarcadero not offer any support for stuff like this? I'd think if they're willing to put a Delphi installation in GetIt, they'd be willing to help create a C++ installation, esp. given their work on C++ for this version of Rad Studio.
  8. w0wbagger

    ICS V9.1 announced

    I think we made more progress attempting to get 9.2 installed and working on C++ Builder 12, but we're not quite there yet. Something about the way it's linking means it doesn't create the .lib file. I'd start there first, instead of 9.1.
  9. w0wbagger

    ICS V9.2 announced

    Hey Angus, when I try to compile this new group (or individual projects) in C++ Builder v12.1, I'm getting an ilink32 error "Unable to open file "ICSCOMMONCBNEWRUN.LIB". It does not appear to be creating it? Specifically, I get this arcane error: c:\program files (x86)\embarcadero\studio\23.0\Bin\CodeGear.Cpp.Targets(4197,5): error : Fatal: Unable to open file 'ICSCOMMONCBNEWRUN.LIB' I'm going to compare the earlier ilink32 command (v9.1) to the ilink32 here and see what's different (I was able to build ICSCOMMONCBNEWRUN.LIB" in v9.1) Will keep you apprised.
  10. w0wbagger

    Upgrading to new RAD Studio vs. project Lib names

    Yeah, that was what I feared. If I strip the .libs back to absolutely nothing, do you know if there is a way to find the filename of the lib that contains the function that is preventing the linker from linking? [Obviously not for 3rd party libs, but maybe at least RAD Studio has a resource that says "function XX is in library YY, with filename ZZ"]? Thanks for your suggestions.
  11. w0wbagger

    Upgrading to new RAD Studio vs. project Lib names

    @Vincent Parrett, I'm using C++ Builder, and the issue for us really stems from the massive list of .lib files passed to ilink. We don't use runtime packages, so our project files have a big list of libs, the names of which are almost all changed for the new version of RAD studio. This program is at least two decades old, and each time we've upgraded from Borland C++ 6, to Codegear, to Embarcadero, we have to modify the .proj file. Was just wondering if there's an easy way to have RAD Studio add all .libs for all installed packages to a project file. There has to be a better way than what we've had to do over the years. Thanks for your response.
  12. Hey folks, it's clear that the installation projects that ship with v9.2 for C++ builder don't work. I'm trying to figure out how I can fix them so I can contribute them back to the community, but the 12.x projects seem completely at odds with the older ones. Even though the new project files are called ICSXXXXXCBNewRun and IcsXXXXXCBNewDesign, there are still references to icsCommonCB110Run and icsCommonCB110Design in the project files (specifically the "requires" sections). In addition, if I look at the IcsCommonCB110Run.cbproj (from v8.x) . the "Contains" section has a ton of .pas files. In IcsCommonCBNewRun.cbproj file, there are only 5 .dcr files, and no .pas files. Am I meant to install v8.X first (thereby creating the icsCommonCB110*.files), or are the project files for C++ Builder 9.2 just really incorrect? I've never installed/written components before, so am a little sketchy on how exactly this should be working. But I am noticing enormous inconsistencies between the 8.x and 9.2 projects. It would seem odd to me that I might have to install a prior version to then install a later version. Thanks for any guidance you can provide.
  13. Thanks Angus, after this e-mail I'll direct any questions to you via e-mail. I knew that nobody is supporting ICS for C++ which is why I thought I'd step up. Do you think I'm better off starting with the v8.X project files and modifying them (because they worked), or starting from the 9.x ones and attempting to figure out what's missing, because they seem fairly materially different (e.g. the icsCommonNewCBRun.cbproj is missing all the .pas files entirely)?
  14. w0wbagger

    ICS V9.2 announced

    Before I uninstall my (working) v8.70 installation in C++ Builder (Alexandria), has anyone tested installing this for C++ Builder? It doesn't show up when searching for C++ components in GetIt (only Delphi and ALL), so I'm thinking maybe not?
  15. w0wbagger

    ICS REST Server?

    Thank you, Angus, I'll do this.
  16. Hey folks, I successfully used the ICS REST client component a few months ago with some generous help from Angus, but have now been tasked with writing a REST server. This server would be able to take a number of different simultaneous requests for information as well as receive files and send files (essentially, like an FTP server but using HTTP as the transport mechanism). Is there any advantage in trying to do this via ICS (Is there a component for this? I see a TSimpleWebSrv.) , or should I just use the built-in HTTP App generator in C++ Builder?
  17. I've been using ICS for more than 15 years but have never used the RESTful or HTTP components (always just FTP), but finally have to use it. I'm trying not to use Indy, but installing and learning how to use ICSin C++ is tough (I don't know Pascal). So apologies if I ask some stupid questions here. There were a *lot* of problems trying to use the v8.7 components (had to comment out a lot of lines from OverbyteIcsWinCrypt.hpp, because the compiler generated pretty bad .hpp files, I guess), but I couldn't get 9.1 to install in C++ Builder, so sticking with the older version for now. I've written code to send an XML stream to an API site, and having issues with the status returned. If I understand how this all works, then when I send my POST, my program should continue doing things until the REST server responds with some message, either "Bad Request", or "Unauthorized", or "200 - everything is good with what you sent" or other documented response. But it seems that what actually happens is that once the data is sent, whether good or bad, RestClientRequestDone is fired immediately with ErrCode = 0, and says it was completed successfully. However, if there was an error, it does the above (says it was successful), but then the catch at the bottom traps the error returned by the API server ("Not Authorized", or "Bad Request"). Do I misunderstand when RestClientRequestDone fires? Does it fire before hearing anything back from the API Server? If I want to wait until that happens, what event should I be trapping? Thanks in advance for your help (and your patience!) Here's my pretty simple code: // I believe this should fire after the file/apikey have been sent, and the API server responds void __fastcall TfrmCAD::RestClientRequestDone(TObject *Sender, THttpRequest RqType, WORD ErrCode) { GRequestCompleted = true; if (ErrCode != 0) { ShowMessage("Error during HTTP request: " + IntToStr(ErrCode)); } else { ShowMessage("Request completed successfully.\nResponse: " + GResponseData); } } //--------------------------------------------------------------------------- // Function to send an XML file to an API using ICS TSslHttpRest void TfrmCAD::SendXMLFileToAPI(const String &xmlFileName) { if (!FileExists(xmlFileName)) { ShowMessage("File does not exist: " + xmlFileName); return; } // Prepare the HTTP client TSslHttpRest *RESTClient = new TSslHttpRest( this ); RESTClient->OnRestRequestDone = &RestClientRequestDone; RESTClient->URL = "APIURLHIDDEN"; // Load the XML file into a stream TFileStream *fileStream = new TFileStream(xmlFileName, fmOpenRead | fmShareDenyWrite); try { // Simplified approach, adjust accordingly RESTClient->SendStream = fileStream; RESTClient->ExtraHeaders->Add("x-api-key: APIKEYREDACTED"); GRequestCompleted = false; RESTClient->Post(); // Wait for the request to complete while (!GRequestCompleted) { Application->ProcessMessages(); } } catch (const Exception &e) { ShowMessage("Error sending file: " + e.Message); } // Clean up delete RESTClient; delete fileStream; }
  18. Understood. I'll take a look at ICSSnippets, which should get me to where I need to be. Thanks for your help. I'll try not to bother you again. FWIW, Chat-GPT is quite helpful in converting Pascal code to C++, for any other C++ programmers trying to make sense of Pascal code. I may even use it to convert some of the new sample code to C++ to include in a future release, if you think that would be helpful (after testing it fully, of course).
  19. Thank you, Angus. I'll unzip the 9.1 distribution and take a look at the ICSSnippets there. I thought the preferred method was to use non-blocking Async mode, so I've been trying to do that everywhere I use ICS components. Is there any downside to using Sync mode for a low-volume application?
  20. Thank you, Angus. I find it difficult to understand Pascal code, but I did what you said and I now have something that seems to be working. I pretty much directly translated, as best I could, the code from OverbyteIcsHttpRestTst.PAS. I don't think OverbyteIcsSnippets is part of what is shipped with 8.70? (Spent hours last night trying to install 9.1 on C++ builder, but was unable to get it to work). HOWEVER, I see in the OverbyteIcsHttpRestTst.PAS file that you have defined an Async Flag in the call to RestRequest. I have defined a function RESTClientRequestDone, and assigned it to RESTClient->OnRestRequestDone.. If I set Async to false, I get an immediate response to my RestRequest as 202 (file accepted), and then OnRestRequestDone fires and I can get a ton of good information about the request. This is true if I deliberately send the wrong API or an incorrect URL. The ErrCode is correct in that case and it catches the raw error data if something went awry. If I set Async to true, however, it fails with a Status code of 0, which as I understand it, is indeterminate. OnRestRequestDone still fires, but I get an HTTP 0. In both cases (Async true OR false), RESTClientRequestDone fires, but only in the non-Async version does it give me proper values. The only difference from "it works!" to "it doesn't work!" is the Async flag that I set in the call to RestRequest (see below). I just can't understand from the Pascal source what I might be doing incorrectly. It seems to work perfectly with Async = false, so I guess I can just run with that, but I would like to understand why Async mode blows up. Thanks for any light you can shed on this. Code follows: void __fastcall TfrmCAD::RESTClientRequestDone(TObject *Sender, THttpRequest RqType, WORD ErrCode) { TSslHttpRest *restClient = dynamic_cast<TSslHttpRest*>(Sender); if (restClient == nullptr) return; if (ErrCode != 0) { memoStatus->Lines->Add("Request failed: Error: " + restClient->RequestDoneErrorStr + " - " + IntToStr(restClient->StatusCode) + " " + restClient->ReasonPhrase); return; } memoStatus->Lines->Add("Request done, StatusCode " + IntToStr(restClient->StatusCode)); if (restClient->ContentType.Pos("text/") > 0 || restClient->ContentType.Pos("xml") > 0 || restClient->ContentType.Pos("json") > 0 || restClient->ContentType.Pos("java") > 0) { memoStatus->Lines->Add(String("Raw Response:"+restClient->ResponseRaw)); } else { memoStatus->Lines->Add("<Non-textual content received: " + restClient->ContentType + ">"); } // Clean up delete restClient; } //--------------------------------------------------------------------------- // Function to send an XML file to an API using ICS TSSlHttpRest void TfrmCAD::SendXMLFileToAPI(const String &xmlFileName, String& APIURL, String& APIKey) { if (!FileExists(xmlFileName)) { ShowMessage("File does not exist: " + xmlFileName); return; } // Set up the URL and SSL options TSslHttpRest *RESTClient = new TSslHttpRest( this ); RESTClient->OnRestRequestDone = &RESTClientRequestDone; RESTClient->URL = APIURL; RESTClient->SslCliSecurity = sslCliSecTls12; RESTClient->ContentTypePost = "application/xml"; // Add the API key to the request headers if (!chkSendEmptyHeader->Checked) { // I do this to test that errors are detected and reported correctly - this removes the api-key to test "not authorized". RESTClient->ExtraHeaders->Add("x-api-key: "+APIKey); } // Load the XML file into a string and start the asynchronous POST request int StatusCode; TFileStream *fileStream = new TFileStream(xmlFileName, fmOpenRead | fmShareDenyWrite); try { // Simplified approach, adjust accordingly RESTClient->SendStream = fileStream; StatusCode = RESTClient->RestRequest(httpPOST, APIURL, true, ""); // Works perfectly if Async = false, fails if Async = true; memoStatus->Lines->Add("ASync REST Request Started, StatusCode = "+IntToStr(StatusCode)); } catch (const Exception &e) { ShowMessage("Error preparing request: " + e.Message); } delete fileStream; } //--------------------------------------------------------------------------- void __fastcall TfrmCAD::btnSendXMLClick(TObject *Sender) { String xmlFileName = btnLoadXML->Text; if (!xmlFileName.IsEmpty()) { String apiKey = txtAPIKey->Text; String apiURL = txtAPIURL->Text; SendXMLFileToAPI(xmlFileName, apiURL, apiKey); } else { ShowMessage("No file selected."); } }
  21. w0wbagger

    ICS V9.1 announced

    I'm going to add what I've found here. The IcsVCLCBNewRun.cpp currently includes a #pragma link "IcsCommonCB110Run.a" and a #pragma link "IcsCommonCB110Run.lib" (I think?) these should be changed to "IcsCommonCBNewRun". IcsVCLCBNewDesign.cbproj has "IcsCommonCB110Run.bpi" under "Requires". I'm assuming that this should be removed and replaced with "IcsCommonCBNewRun.bpi". IcsVCLCBNewDesign.cbproj also has "IcsVCLCB110Run.bpi" under "Requires". I'm assuming also that his should also be removed and replaced with "IcsVCLCBNewRun.bpi" Made these changes but it still doesn't work. There are a lot of references to 110 in the various project files (vs 22.0). When I install the components in "IcsCommonCBNewDesign", no component tab gets generated, but if I look at the components from the "Components->Install Packages" screen, I see them all there. However, when I install the components from "IcsVCLCBNewDesign", it says they're installed, but there are no components showing when I click on the "Components" button from the "Components->Install Packages" screen when highlighting the VCL Design-Time Package. I'm at a bit of a loss, now.
  22. w0wbagger

    ICS V9.1 announced

    If I figure it out, I'm happy to e-mail any project file changes. I notice the difference between 8.xx installer and 9.1 installer is that the .pas files aren't included in the C++ project, and since it never opens them to compile them, (I believe) it doesn't create the .hpp files. The project file only includes the .dcr files. Again, I know nothing about the Pascal personality, so I'm going to just try adding the .PAS files to their respective projects and see if that works.
  23. w0wbagger

    ICS V9.1 announced

    Ah, I see that GetIt only installs ICS for the Delphi personality. They don't show up in the C++ Builder personality. That's new. The last time I used GetIt to install the components, they did show up in C++. Will try to figure out the manual install. Edit: I'm very unfamiliar with the Pascal personality. My understanding is that when you compile a Pascal file in C++ Builder, it automatically generates the .hpp file. Is the option not set in the project?
  24. w0wbagger

    ICS V9.1 announced

    This looks great, if I can get it working. Thank you, Angus. We use C++ Builder (Alexandria). GetIt installed everything fine, but I couldn't find the .hpp file for C++ Builder. Do they get created, or do I have to install manually? Thanks, Ian
  25. I have this same problem in C++ Builder. No idea what might be causing it. Restarting the IDE seems to solve it.
×