Ftp rekursiv durchsuchen (FtpFindNextFile)



  • Hallo,

    hab hier ein Problem mit meine Methode, die ein TTreeview mit
    der Verzeichnisstruktur eines FTP Servers füllen soll.
    Problem liegt darin, dass beim ersten rekursiven aufruf
    hSearch = NULL wird (Zeile 11).

    Jemand eine Idee?

    bool TFtpService::FillTreeView(String FtpPfad, TTreeView *TreeView, TTreeNode *Node )
    {
       /* Objekte für die suche */
       WIN32_FIND_DATA FileData;    // Die Gefundenen Dateien
       HANDLE hSearch;              // Handel zum suchen
       String GesamterPfad;         // Pfad + Dateiname
    
       bool SearchDone = false;
    
       hSearch = FtpFindFirstFile(hFTPSession,
                                  FtpPfad.c_str(),
                                  &FileData,
                                  INTERNET_FLAG_RELOAD,
                                  0);
    
       /* wenn keine Suchergbnisse vorliegen, verlasse die Schleife */
       if (hSearch == INVALID_HANDLE_VALUE || hSearch == NULL)
           SearchDone = true;
    
       /* solange was gefunden wurde, starte eine neue suche wenn es ein Ordner ist */
       while(!SearchDone)
       {
          /* wenn es ein Ordner ist, Starte in diesem eine neue suche */
          if(FileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
          {
             /* Zeiger auf neuen Knoten anlegen und
                diesen auf ein neues Child vom Treeview zeigen lassen*/
             TTreeNode *NewNode = TreeView->Items->AddChild(Node, FileData.cFileName);
             //NewNode->ImageIndex = 0;
    
             // In dem gefundenem Ordner eine neue Suche starten
             FillTreeView(FtpPfad + FileData.cFileName + "/", TreeView, NewNode);
          }
          else
          {
             // gefundene Datei in Knoten schreiben
             TreeView->Items->AddChild(Node, FileData.cFileName);//->ImageIndex = 1;
          }
    
          // Liegt ein weiteres Suchergebnis vor?
          if(!InternetFindNextFile( hSearch, &FileData ) )
          {
             if (GetLastError() == ERROR_NO_MORE_FILES)
             {
                SearchDone = true;
             }
             else
             {
                SearchDone = true;
             }
          }
       }
       FindClose(hSearch);
    }
    

    Edit:
    Ich weiß auch nicht genau wie ich jetzt die Errorcodes auslesen könnte.

    Edit 2:
    evtl falsches forum?



  • Hallo

    ja, las dich ins WinAPI-Forum verschieben.

    Zum Thema Fehlerausweertung steht hier untrer Return Value auch das nötige.

    bis bald
    akari



  • Ok, hab hier was gefunden:
    http://windowssdk.msdn.microsoft.com/en-us/library/ms736452.aspx

    Die Funktion:

    BOOL InternetGetLastResponseInfo(
    LPDWORD lpdwError,
    LPTSTR lpszBuffer,
    LPDWORD lpdwBufferLength
    );

    Als Erklärung für lpdwError steht dort folgendes:
    [out] Pointer to a variable that receives an error message pertaining to the operation that failed.

    lpdwError bekomme ich doch mit:
    http://windowssdk.msdn.microsoft.com/en-us/library/ms679360.aspx
    DWORD GetLastError(void)

    Dann sollte ich doch so den Error auslesen können:

    char Buffer[1024];
    InternetGetLastResponseInfo(GetLastError(), Buffer, 1024);

    Allerdings sagt er mir, das die konvertierung von unsigned long nach unsigned long * nicht möglich sei?.

    Bitte helfen.

    danke 😉



  • Dieser Thread wurde von Moderator/in Jansen aus dem Forum VCL/CLX (Borland C++ Builder) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • d0x schrieb:

    Allerdings sagt er mir, das die konvertierung von unsigned long nach unsigned long * nicht möglich sei?.

    Das bekommste mit dem Referenz-Operator hin...:

    char Buffer[1024];
    unsigned long ulErrorCode = GetLastError();
    InternetGetLastResponseInfo(&ulErrorCode , Buffer, 1024);
    

    Aber ich versteh die Funktion irg.wie anders:

    TCHAR szMessage[1024];
    DWORD dwErrorCode;
    if(InternetGetLastResponseInfo(&dwErrorCode, szMessage, sizeof(szMessage) / sizeof(TCHAR)))
         MessageBox(NULL, szMessage, NULL, MB_OK | MB_ICONERROR);
    

    So würd ich es machen 🤡 .



  • Danke für die Antwort.

    Leider sagt mir der Compiler bei deiner Lösung:

    "Konvertierung von 'unsigned int' nach 'unsigned long *' nicht möglich".

    Damit meint er die Adressübergabe von &dwErrorCode.

    Hm, ich weiß net warum aber das hier klappt:

    void GetServerResponse()
    {
        DWORD dwInfo;
        DWORD dwLength;
        char *pszResponse = NULL;
    
        InternetGetLastResponseInfo(&dwInfo, NULL, &dwLength);
        if(dwLength)
        {
            if((pszResponse = (char *)LocalAlloc(LPTR, dwLength)))
                if(InternetGetLastResponseInfo(&dwInfo, (LPTSTR)pszResponse, &dwLength))
                {
    // message verarbeiten mit cout oder ähnliches
                }
                else
                    // fehler fprintf(LogFile, "Fehler: %i\n", GetLastError());
        }
        else
            // fehler fprintf(LogFile, "Fehler: %i\n", GetLastError());
    
        LocalFree(pszResponse);
    }
    

    Hab das so hier im Forum gefunden.

    Allerdings bringt das mich net weiter. Die erhoffte fehlermeldung kommt nicht 😞

    Beim ersten rekursiven aufruf geht nachwievor mein handle hSearch auf NULL.


Anmelden zum Antworten