Share via


Sesiones FTP

WinINet permite a las aplicaciones navegar y manipular directorios y archivos en un servidor ftp. Dado que los servidores proxy cern no admiten FTP, las aplicaciones que usan un proxy CERN exclusivamente deben usar la función InternetOpenUrl . Para obtener más información sobre cómo usar InternetOpenUrl, consulte Acceso directo a direcciones URL.

Para iniciar una sesión FTP, use InternetConnect para crear el identificador de sesión.

WinINet permite realizar las siguientes acciones en un servidor FTP:

  • Navegue entre directorios.
  • Enumerar, crear, quitar y cambiar el nombre de los directorios.
  • Cambie el nombre, cargue, descargue y elimine archivos.

La navegación la proporcionan las funciones FtpGetCurrentDirectory y FtpSetCurrentDirectory . Estas funciones usan el identificador de sesión creado por una llamada anterior a InternetConnect para determinar en qué directorio está actualmente la aplicación o para cambiar a otro subdirectorio.

La enumeración de directorios se realiza mediante las funciones FtpFindFirstFile e InternetFindNextFile . FtpFindFirstFile usa el identificador de sesión creado por InternetConnect para buscar el primer archivo que coincida con los criterios de búsqueda especificados y devuelve un identificador para continuar con la enumeración de directorios. InternetFindNextFile usa el identificador devuelto por FtpFindFirstFile para devolver el siguiente archivo que coincida con los criterios de búsqueda originales. La aplicación debe seguir llamando a InternetFindNextFile hasta que no haya más archivos en el directorio.

Use la función FtpCreateDirectory para crear nuevos directorios. Esta función usa el identificador de sesión creado por InternetConnect y crea el directorio especificado por la cadena que se pasa a la función. La cadena puede contener un nombre de directorio relativo al directorio actual o una ruta de acceso de directorio completa.

Para cambiar el nombre de archivos o directorios, la aplicación puede llamar a FtpRenameFile. Esta función reemplaza el nombre original por el nuevo nombre pasado a la función. El nombre del archivo o directorio puede ser relativo al directorio actual o a un nombre completo.

Para cargar o colocar archivos en un servidor FTP, la aplicación puede usar FtpPutFile o FtpOpenFile (junto con InternetWriteFile). FtpPutFile se puede usar si el archivo ya existe localmente, mientras que FtpOpenFile e InternetWriteFile se pueden usar si es necesario escribir datos en un archivo en el servidor FTP.

Para descargar u obtener archivos, la aplicación puede usar FtpGetFile o FtpOpenFile (con InternetReadFile). FtpGetFile se usa para recuperar un archivo de un servidor FTP y almacenarlo localmente, mientras que FtpOpenFile e InternetReadFile se pueden usar para controlar dónde va la información descargada (por ejemplo, la aplicación podría mostrar la información en un cuadro de edición).

Elimine archivos en un servidor FTP mediante la función FtpDeleteFile . Esta función quita un nombre de archivo relativo al directorio actual o a un nombre de archivo completo del servidor FTP. FtpDeleteFile requiere un identificador de sesión devuelto por InternetConnect.

Identificadores de función FTP

Para funcionar correctamente, las funciones FTP requieren determinados tipos de identificadores HINTERNET . Estos identificadores se deben crear en un orden específico, empezando por el identificador raíz creado por InternetOpen. InternetConnect puede crear un identificador de sesión FTP.

En el diagrama siguiente se muestran las funciones que dependen del identificador de sesión FTP devuelto por InternetConnect. Los cuadros sombreados representan funciones que devuelven identificadores HINTERNET , mientras que los cuadros sin formato representan funciones que usan el identificador HINTERNET creado por la función en la que dependen.

funciones ftp dependientes del identificador de sesión ftp devuelto por Internetconnect

En el diagrama siguiente se muestran las dos funciones que devuelven identificadores HINTERNET y las funciones que dependen de ellas. Los cuadros sombreados representan funciones que devuelven identificadores HINTERNET , mientras que los cuadros sin formato representan funciones que usan el identificador HINTERNET creado por la función en la que dependen.

funciones ftp que devuelven identificadores de hinternet

Para obtener más información, vea HINTERNET Handles(Identificadores de HINTERNET).

Uso de las funciones de WinINet para sesiones FTP

Las siguientes funciones se usan durante las sesiones FTP. Estos servidores proxy cern no reconocen estas funciones. Las aplicaciones que deben funcionar a través de servidores proxy cern deben usar InternetOpenUrl y acceder directamente a los recursos. Para más información sobre el acceso directo a los recursos, consulte Acceso directo a direcciones URL directamente.

Función Descripción
FtpCreateDirectory Crea un nuevo directorio en el servidor. Esta función requiere un identificador creado por InternetConnect.
FtpDeleteFile Elimina un archivo del servidor. Esta función requiere un identificador creado por InternetConnect.
FtpFindFirstFile Inicia la enumeración de archivos o la búsqueda de archivos en el directorio actual. Esta función requiere un identificador creado por InternetConnect.
FtpGetCurrentDirectory Devuelve el directorio actual del cliente en el servidor. Esta función requiere un identificador creado por InternetConnect.
FtpGetFile Recupera un archivo del servidor. Esta función requiere un identificador creado por InternetConnect.
FtpOpenFile Inicia el acceso a un archivo en el servidor para leer o escribir. Esta función requiere un identificador creado por InternetConnect.
FtpPutFile Escribe un archivo en el servidor. Esta función requiere un identificador creado por InternetConnect.
FtpRemoveDirectory Elimina un directorio en el servidor. Esta función requiere un identificador creado por InternetConnect.
FtpRenameFile Cambia el nombre de un archivo en el servidor. Esta función requiere un identificador creado por InternetConnect.
FtpSetCurrentDirectory Cambia el directorio actual del cliente en el servidor. Esta función requiere un identificador creado por InternetConnect.
InternetWriteFile Escribe datos en un archivo abierto en el servidor. Esta función requiere un identificador creado por FtpOpenFile.

 

Iniciar una sesión FTP

La aplicación establece una sesión FTP llamando a InternetConnect en un identificador creado por InternetOpen. InternetConnect necesita el nombre del servidor, el número de puerto, el nombre de usuario, la contraseña y el tipo de servicio (que se deben establecer en INTERNET_SERVICE_FTP). Para la semántica de FTP pasiva, la aplicación también debe establecer la marca de INTERNET_FLAG_PASSIVE .

Los valores INTERNET_DEFAULT_FTP_PORT y INTERNET_INVALID_PORT_NUMBER se pueden usar para el número de puerto. INTERNET_DEFAULT_FTP_PORT usa el puerto FTP predeterminado, pero el tipo de servicio debe establecerse. INTERNET_INVALID_PORT_NUMBER usa el valor predeterminado para el tipo de servicio indicado.

Los valores del nombre de usuario y la contraseña se pueden establecer en NULL. Si ambos valores se establecen en NULL, InternetConnect usa "anónimo" para el nombre de usuario y la dirección de correo electrónico del usuario para la contraseña. Si solo la contraseña se establece en NULL, el nombre de usuario pasado a InternetConnect se usa para el nombre de usuario y se usa una cadena vacía para la contraseña. Si ninguno de los valores es NULL, se usa el nombre de usuario y la contraseña proporcionados a InternetConnect .

Enumerar directorios

La enumeración de un directorio en un servidor FTP requiere la creación de un identificador por FtpFindFirstFile. Este identificador es una rama del identificador de sesión creado por InternetConnect. FtpFindFirstFile busca el primer archivo o directorio en el servidor y lo devuelve en una estructura WIN32_FIND_DATA . Use InternetFindNextFile hasta que devuelva ERROR_NO_MORE_FILES. Este método busca todos los archivos y directorios subsiguientes en el servidor. Para obtener más información sobre InternetFindNextFile, vea Buscar el siguiente archivo.

Para determinar si el archivo recuperado por FtpFindFirstFile o InternetFindNextFile es un directorio, compruebe el miembro dwFileAttributes de la estructura WIN32_FIND_DATA para ver si es igual a FILE_ATTRIBUTE_DIRECTORY.

Si la aplicación realiza cambios en el servidor FTP o si el servidor FTP cambia con frecuencia, las marcas INTERNET_FLAG_NO_CACHE_WRITE y INTERNET_FLAG_RELOAD deben establecerse en FtpFindFirstFile. Estas marcas garantizan que la información del directorio que se recupera del servidor FTP esté actualizada.

Una vez completada la enumeración de directorios, la aplicación debe realizar una llamada a InternetCloseHandle en el identificador creado por FtpFindFirstFile. Hasta que se cierre ese identificador, la aplicación no puede volver a llamar a FtpFindFirstFile en el identificador de sesión creado por InternetConnect. Si se realiza una llamada a FtpFindFirstFile en el mismo identificador de sesión antes de cerrar la llamada anterior a la misma función, se produce un error en la función y se devuelve ERROR_FTP_TRANSFER_IN_PROGRESS.

En el ejemplo siguiente se enumera el contenido de un directorio FTP en un control de cuadro de lista. El parámetro hConnection es un identificador devuelto por la función InternetConnect después de establecer una sesión FTP. El código fuente de ejemplo de la función InternetErrorOut a la que se hace referencia en este ejemplo se puede encontrar en el tema Control de errores.

#include <windows.h>
#include <strsafe.h>
#include <wininet.h>

#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "user32.lib")

#define  FTP_FUNCTIONS_BUFFER_SIZE          MAX_PATH+8

BOOL WINAPI DisplayFtpDir(
                           HWND hDlg,
                           HINTERNET hConnection,
                           DWORD dwFindFlags,
                           int nListBoxId )
{
  WIN32_FIND_DATA dirInfo;
  HINTERNET       hFind;
  DWORD           dwError;
  BOOL            retVal = FALSE;
  TCHAR           szMsgBuffer[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR           szFName[FTP_FUNCTIONS_BUFFER_SIZE];
  
  SendDlgItemMessage( hDlg, nListBoxId, LB_RESETCONTENT, 0, 0 );
  hFind = FtpFindFirstFile( hConnection, TEXT( "*.*" ), 
                            &dirInfo, dwFindFlags, 0 );
  if ( hFind == NULL )
  {
    dwError = GetLastError( );
    if( dwError == ERROR_NO_MORE_FILES )
    {
      StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
        TEXT( "No files found at FTP location specified." ) );
      retVal = TRUE;
      goto DisplayDirError_1;
    }
    StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
      TEXT( "FtpFindFirstFile failed." ) );
    goto DisplayDirError_1;
  }

  do
  {
    if( FAILED( StringCchCopy( szFName, FTP_FUNCTIONS_BUFFER_SIZE,
                  dirInfo.cFileName ) ) ||
        ( ( dirInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) &&
        ( FAILED( StringCchCat( szFName, FTP_FUNCTIONS_BUFFER_SIZE,
         TEXT( " <DIR> " ) ) ) ) ) )
    {
      StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
        TEXT( "Failed to copy a file or directory name." ) );
      retVal = FALSE;
      goto DisplayDirError_2;
    }
    SendDlgItemMessage( hDlg, nListBoxId, LB_ADDSTRING, 
                        0, (LPARAM) szFName );
  } while( InternetFindNextFile( hFind, (LPVOID) &dirInfo ) );

  if( ( dwError = GetLastError( ) ) == ERROR_NO_MORE_FILES )
  {
    InternetCloseHandle(hFind);
    return( TRUE );
  }
  StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
    TEXT( "FtpFindNextFile failed." ) );

DisplayDirError_2:
  InternetCloseHandle( hFind );
DisplayDirError_1:
  MessageBox( hDlg,
    (LPCTSTR) szMsgBuffer,
    TEXT( "DisplayFtpDir( ) Problem" ),
    MB_OK | MB_ICONERROR );
  return( retVal );
}

Las funciones FtpGetCurrentDirectory y FtpSetCurrentDirectory controlan la navegación por directorios.

FtpGetCurrentDirectory devuelve el directorio actual de la aplicación en el servidor FTP. Se incluye la ruta de acceso del directorio raíz en el servidor FTP.

FtpSetCurrentDirectory cambia el directorio de trabajo en el servidor. La información del directorio que se pasa a FtpSetCurrentDirectory puede ser un nombre de ruta de acceso parcial o completo en relación con el directorio actual. Por ejemplo, si la aplicación está actualmente en el directorio "public/info" y la ruta de acceso es "ftp/example", FtpSetCurrentDirectory cambia el directorio actual a "public/info/ftp/example".

En el ejemplo siguiente se usa el identificador de sesión FTP hConnection, que devuelve InternetConnect. El nuevo nombre de directorio se toma del cuadro de edición del cuadro de diálogo primario cuyo IDC se pasa en el parámetro nDirNameId . Antes de realizar el cambio de directorio, la función recupera el directorio actual y lo almacena en el mismo cuadro de edición. El código souce de la función DisplayFtpDir denominada al final se muestra arriba.

BOOL WINAPI ChangeFtpDir( HWND hDlg, 
                          HINTERNET hConnection,
                          int nDirNameId, 
                          int nListBoxId )
{
  DWORD dwSize;
  TCHAR szNewDirName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szOldDirName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR* szFailedFunctionName;

  dwSize = FTP_FUNCTIONS_BUFFER_SIZE;

  if( !GetDlgItemText( hDlg, nDirNameId, szNewDirName, dwSize ) )
  {
    szFailedFunctionName = TEXT( "GetDlgItemText" );
    goto ChangeFtpDirError;
  }

  if ( !FtpGetCurrentDirectory( hConnection, szOldDirName, &dwSize ))
  {
    szFailedFunctionName = TEXT( "FtpGetCurrentDirectory" );
    goto ChangeFtpDirError;
  }

  if( !SetDlgItemText( hDlg, nDirNameId, szOldDirName ) )
  {
    szFailedFunctionName = TEXT( "SetDlgItemText" );
    goto ChangeFtpDirError;
  }

  if( !FtpSetCurrentDirectory( hConnection, szNewDirName ) )
  {
    szFailedFunctionName = TEXT( "FtpSetCurrentDirectory" );
    goto ChangeFtpDirError;
  }
  return( DisplayFtpDir( hDlg, hConnection, 0, nListBoxId ) );

ChangeFtpDirError:
  InternetErrorOut( hDlg, GetLastError( ), szFailedFunctionName );
  DisplayFtpDir( hDlg, hConnection, INTERNET_FLAG_RELOAD, nListBoxId);
  return( FALSE );
}

Manipular directorios en un servidor FTP

WinINet proporciona la capacidad de crear y quitar directorios en un servidor FTP al que la aplicación tiene los privilegios necesarios. Si la aplicación debe iniciar sesión en un servidor con un nombre de usuario y una contraseña específicos, los valores se pueden usar en InternetConnect al crear el identificador de sesión ftp.

La función FtpCreateDirectory toma un identificador de sesión FTP válido y una cadena terminada en null que contiene una ruta de acceso completa o un nombre relativo al directorio actual y crea un directorio en el servidor FTP.

En el ejemplo siguiente se muestran dos llamadas independientes a FtpCreateDirectory. En ambos ejemplos, hFtpSession es el identificador de sesión creado por la función InternetConnect y el directorio raíz es el directorio actual.

/* Creates the directory "test" in the current (root) directory. */
FtpCreateDirectory( hFtpSession, "test" );

/* Creates the directory "example" in the test directory. */
FtpCreateDirectory( hFtpSession, "\\test\\example" );

La función FtpRemoveDirectory toma un identificador de sesión y una cadena terminada en null que contiene una ruta de acceso completa o un nombre relativo al directorio actual y quita ese directorio del servidor FTP.

En el ejemplo siguiente se muestran dos llamadas de ejemplo a FtpRemoveDirectory. En ambas llamadas, hFtpSession es el identificador de sesión creado por la función InternetConnect y el directorio raíz es el directorio actual. Hay un directorio denominado "test" en el directorio raíz y un directorio denominado "example" en el directorio "test".

/* Removes the "example" directory (plus any files/directories it contains) from the "test" directory. */
FtpRemoveDirectory(hFtpSession,"\\test\\example");

/* Removes the "test" directory (plus any files/directories it contains) from the root directory. */
FtpRemoveDirectory(hFtpSession, "test");
FtpRemoveDirectory(hFtpSession,TEXT("\\test\\example"));
/* Removes the "example" directory and any files or 
directories contained in it from the "test" directory. */

FtpRemoveDirectory(hFtpSession, TEXT("test"));
/* Removes the "test" directory and any files or 
directories contained in it from the root directory. */

En el ejemplo siguiente se crea un directorio en el servidor FTP. El nuevo nombre de directorio se toma del cuadro de edición del cuadro de diálogo primario cuyo IDC se pasa en el parámetro nDirNameId . InternetConnection creó el identificador hConnection después de establecer una sesión FTP. El código fuente de la función DisplayFtpDir a la que se llama al final se muestra anteriormente.

BOOL WINAPI CreateFtpDir( HWND hDlg, HINTERNET hConnection,
                          int nDirNameId, int nListBoxId )
{
  TCHAR szNewDirName[FTP_FUNCTIONS_BUFFER_SIZE];

  if( !GetDlgItemText( hDlg, nDirNameId, 
                       szNewDirName, 
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Error: Directory Name Must Be Specified" ),
                TEXT( "Create FTP Directory" ), 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpCreateDirectory( hConnection, szNewDirName ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), 
                      TEXT( "FtpCreateDirectory" ) );
    return( FALSE );
  }

  return( DisplayFtpDir( hDlg, hConnection, 
                         INTERNET_FLAG_RELOAD, 
                         nListBoxId ) );
}

En el ejemplo siguiente se elimina un directorio del servidor FTP. El nombre del directorio que se va a eliminar se toma del cuadro de edición del cuadro de diálogo primario cuyo IDC se pasa al parámetro nDirNameId . InternetConnection creó el identificador hConnection después de establecer una sesión FTP. El código fuente de la función DisplayFtpDir a la que se llama al final se muestra anteriormente.

BOOL WINAPI RemoveFtpDir( HWND hDlg, HINTERNET hConnection,
                          int nDirNameId, int nListBoxId )
{
  TCHAR szDelDirName[FTP_FUNCTIONS_BUFFER_SIZE];

  if( !GetDlgItemText( hDlg, nDirNameId, szDelDirName, 
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Error: Directory Name Must Be Specified" ),
                TEXT( "Remove FTP Directory" ), 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpRemoveDirectory( hConnection, szDelDirName ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), 
                      TEXT( "FtpRemoveDirectory" ) );
    return( FALSE );
  }

  return( DisplayFtpDir( hDlg, hConnection, 
                         INTERNET_FLAG_RELOAD, nListBoxId ) );
}

Obtener archivos en un servidor FTP

Hay tres métodos para recuperar archivos de un servidor FTP:

Para obtener más información sobre el uso de la función InternetReadFile , vea Leer archivos.

Si la dirección URL del archivo está disponible, la aplicación puede llamar a InternetOpenUrl para conectarse a esa dirección URL y, a continuación, usar InternetReadFile para controlar la descarga del archivo. Esto permite que la aplicación tenga un control más estricto sobre la descarga y es ideal para situaciones en las que no es necesario realizar otras operaciones en el servidor FTP. Para obtener más información sobre cómo acceder directamente a los recursos, consulte Acceso directo a direcciones URL.

Si la aplicación ha establecido un identificador de sesión FTP para el servidor con InternetConnect, la aplicación puede llamar a FtpOpenFile con el nombre de archivo existente y con un nuevo nombre para el archivo almacenado localmente. Después, la aplicación puede usar InternetReadFile para descargar el archivo. Esto permite que la aplicación tenga un control más estricto sobre la descarga y mantenga la conexión con el servidor FTP, por lo que se pueden ejecutar más comandos.

Si la aplicación no necesita un control estricto sobre la descarga, la aplicación puede usar FtpGetFile con el identificador de sesión FTP, el nombre de archivo remoto y el nombre de archivo local para recuperar el archivo. FtpGetFile realiza toda la contabilidad y sobrecarga asociada a la lectura de un archivo desde un servidor FTP y la almacena localmente.

En el ejemplo siguiente se recupera un archivo de un servidor FTP y se guarda localmente. El nombre del archivo en el servidor FTP se toma del cuadro de edición del cuadro de diálogo primario cuyo IDC se pasa en el parámetro nFtpFileNameId y el nombre local en el que se guarda el archivo se toma del cuadro de edición cuyo IDC se pasa en el parámetro nLocalFileNameId . InternetConnection creó el identificador hConnection después de establecer una sesión FTP.

BOOL WINAPI GetFtpFile( HWND hDlg, HINTERNET hConnection,
                        int nFtpFileNameId, int nLocalFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szLocalFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  DWORD dwTransferType;
  TCHAR szBoxTitle[] = TEXT( "Download FTP File" );
  TCHAR szAsciiQuery[] =
    TEXT("Do you want to download as ASCII text?(Default is binary)");
  TCHAR szAsciiDone[] = 
    TEXT( "ASCII Transfer completed successfully..." );
  TCHAR szBinaryDone[] = 
    TEXT( "Binary Transfer completed successfully..." );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nLocalFileNameId, szLocalFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Target File or Destination File Missing" ),
                szBoxTitle, 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  dwTransferType = ( MessageBox( hDlg, 
                                 szAsciiQuery, 
                                 szBoxTitle, 
                                 MB_YESNO ) == IDYES ) ?
                   FTP_TRANSFER_TYPE_ASCII : FTP_TRANSFER_TYPE_BINARY;
  dwTransferType |= INTERNET_FLAG_RELOAD;

  if( !FtpGetFile( hConnection, szFtpFileName, szLocalFileName, FALSE,
                   FILE_ATTRIBUTE_NORMAL, dwTransferType, 0 ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), TEXT( "FtpGetFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg,( dwTransferType == 
                      (FTP_TRANSFER_TYPE_ASCII | INTERNET_FLAG_RELOAD)) ?
                      szAsciiDone : szBinaryDone, szBoxTitle, MB_OK );
  return( TRUE );
}

Colocar archivos en un servidor FTP

Hay dos métodos para colocar un archivo en un servidor FTP:

Una aplicación que debe enviar datos a un servidor FTP, pero no tiene un archivo local que contenga todos los datos, debe usar FtpOpenFile para crear y abrir un archivo en el servidor ftp. A continuación, la aplicación puede usar InternetWriteFile para cargar la información en el archivo.

Si el archivo ya existe localmente, la aplicación puede usar FtpPutFile para cargar el archivo en el servidor FTP. FtpPutFile realiza toda la sobrecarga que va con la carga de un archivo local en un servidor FTP remoto.

En el ejemplo siguiente se copia un archivo local en el servidor FTP. El nombre local del archivo se toma del cuadro de edición del cuadro de diálogo primario cuyo IDC se pasa en el parámetro nLocalFileNameId y el nombre bajo el que se guarda el archivo en el servidor FTP se toma del cuadro de edición cuyo IDC se pasa en el parámetro nFtpFileNameId . InternetConnection creó el identificador hConnection después de establecer una sesión FTP.

BOOL WINAPI PutFtpFile( HWND hDlg, HINTERNET hConnection,
                        int nFtpFileNameId, int nLocalFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szLocalFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  DWORD dwTransferType;
  TCHAR szBoxTitle[] = TEXT( "Upload FTP File" );
  TCHAR szASCIIQuery[] =
    TEXT("Do you want to upload as ASCII text? (Default is binary)");
  TCHAR szAsciiDone[] = 
    TEXT( "ASCII Transfer completed successfully..." );
  TCHAR szBinaryDone[] = 
    TEXT( "Binary Transfer completed successfully..." );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nLocalFileNameId, szLocalFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT("Target File or Destination File Missing"),
                szBoxTitle, 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  dwTransferType =
    ( MessageBox( hDlg, 
                  szASCIIQuery, 
                  szBoxTitle, 
                  MB_YESNO ) == IDYES ) ?
    FTP_TRANSFER_TYPE_ASCII : FTP_TRANSFER_TYPE_BINARY;

  if( !FtpPutFile( hConnection, 
                   szLocalFileName, 
                   szFtpFileName, 
                   dwTransferType, 
                   0 ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), TEXT( "FtpGetFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg,
              ( dwTransferType == FTP_TRANSFER_TYPE_ASCII ) ?
                szAsciiDone : szBinaryDone, szBoxTitle, MB_OK );
  return( TRUE );  // Remember to refresh directory listing
}

Eliminar archivos de un servidor FTP

Para eliminar un archivo de un servidor FTP, use la función FtpDeleteFile . La aplicación que llama debe tener los privilegios necesarios para eliminar un archivo del servidor FTP.

En el ejemplo siguiente se elimina un archivo del servidor FTP. El nombre del archivo que se va a eliminar se toma del cuadro de edición del cuadro de diálogo primario cuyo IDC se pasa al parámetro nFtpFileNameId . InternetConnection creó el identificador hConnection después de establecer una sesión FTP. Puesto que esta función no actualiza los listados de archivos ni la presentación de directorios, el proceso de llamada debe hacerlo después de la eliminación correcta.

BOOL WINAPI DeleteFtpFile( HWND hDlg, HINTERNET hConnection,
                           int nFtpFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szBoxTitle[] = TEXT( "Delete FTP File" );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, TEXT( "File Name Must Be Specified!" ),
                szBoxTitle, MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpDeleteFile( hConnection, szFtpFileName ) )
  {
    InternetErrorOut( hDlg, 
                      GetLastError( ), 
                      TEXT( "FtpDeleteFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg, 
              TEXT( "File has been deleted" ), 
              szBoxTitle, 
              MB_OK );
  return( TRUE );  // Remember to refresh directory listing
}

Cambiar el nombre de archivos y directorios en un servidor FTP

Los archivos y directorios de un servidor FTP se pueden cambiar de nombre mediante la función FtpRenameFile . FtpRenameFile acepta dos cadenas terminadas en null que contienen nombres completos o parciales en relación con el directorio actual. La función cambia el nombre del archivo designado por la primera cadena al nombre designado por la segunda cadena.

En el ejemplo siguiente se cambia el nombre de un archivo o directorio en el servidor FTP. El nombre actual del archivo o directorio se toma del cuadro de edición del cuadro de diálogo primario cuyo IDC se pasa en el parámetro nOldFileNameId y el nuevo nombre se toma del cuadro de edición cuyo IDC se pasa en el parámetro nNewFileNameId . InternetConnection creó el identificador hConnection después de establecer una sesión FTP. Puesto que esta función no actualiza los listados de archivos ni la presentación de directorios, el proceso de llamada debe hacerlo después de cambiar el nombre correctamente.

BOOL WINAPI RenameFtpFile( HWND hDlg, HINTERNET hConnection,
                           int nOldFileNameId, int nNewFileNameId )
{
  TCHAR szOldFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szNewFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szBoxTitle[] = TEXT( "Rename FTP File" );

  if( !GetDlgItemText( hDlg, nOldFileNameId, szOldFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nNewFileNameId, szNewFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg,
        TEXT( "Both the current and new file names must be supplied" ),
        szBoxTitle, 
        MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpRenameFile( hConnection, szOldFileName, szNewFileName ) )
  {
    MessageBox( hDlg,
        TEXT( "FtpRenameFile failed" ),
        szBoxTitle, 
        MB_OK | MB_ICONERROR );
    return( FALSE );
  }
  return( TRUE );  // Remember to refresh directory listing
}

Nota

WinINet no admite implementaciones de servidor. Además, no se debe usar desde un servicio. En el caso de las implementaciones de servidor o los servicios, use Servicios HTTP de Microsoft Windows (WinHTTP).