FTP セッション

WinINet を使用すると、アプリケーションは FTP サーバー上のディレクトリとファイルを移動および操作できます。 CERN プロキシは FTP をサポートしていないため、CERN プロキシを排他的に使用するアプリケーションでは InternetOpenUrl 関数を使用する必要があります。 InternetOpenUrl の使用方法の詳細については、「URL に直接アクセスする」を参照してください。

FTP セッションを開始するには、 InternetConnect を使用してセッション ハンドルを作成します。

WinINet を使用すると、FTP サーバーで次のアクションを実行できます。

  • ディレクトリ間を移動します。
  • ディレクトリの列挙、作成、削除、名前変更を行います。
  • ファイルの名前変更、アップロード、ダウンロード、削除を行います。

ナビゲーションは、 FtpGetCurrentDirectory 関数と FtpSetCurrentDirectory 関数によって提供されます。 これらの関数は、 InternetConnect の以前の呼び出しによって作成されたセッション ハンドルを使用して、アプリケーションが現在存在するディレクトリを決定したり、別のサブディレクトリに変更したりします。

ディレクトリ列挙は、 FtpFindFirstFile 関数と InternetFindNextFile 関数を使用して実行されます。 FtpFindFirstFile、InternetConnect によって作成されたセッション ハンドルを使用して、指定された検索条件に一致する最初のファイルを検索し、ディレクトリ列挙を続行するためのハンドルを返します。 InternetFindNextFile、FtpFindFirstFile によって返されるハンドルを使用して、元の検索条件に一致する次のファイルを返します。 ディレクトリにファイルが残らなくなるまで、アプリケーションは InternetFindNextFile を引き続き呼び出す必要があります。

FtpCreateDirectory 関数を使用して、新しいディレクトリを作成します。 この関数は 、InternetConnect によって作成されたセッション ハンドルを使用し、関数に渡される文字列で指定されたディレクトリを作成します。 文字列には、現在のディレクトリに対する相対ディレクトリ名、または完全修飾ディレクトリ パスを含めることができます。

ファイルまたはディレクトリの名前を変更するには、アプリケーションで FtpRenameFile を呼び出します。 この関数は、元の名前を関数に渡された新しい名前に置き換えます。 ファイルまたはディレクトリの名前は、現在のディレクトリを基準にするか、完全修飾名を使用できます。

FTP サーバーにファイルをアップロードまたは配置するには、アプリケーションで FtpPutFile または FtpOpenFile (InternetWriteFile と共に) を使用できます。 ファイルが既にローカルに存在する場合は FtpPutFile を使用できます。FTP サーバー上のファイルにデータを書き込む必要がある場合は、FtpOpenFileInternetWriteFile を使用できます。

ファイルをダウンロードまたは取得するには、アプリケーションで FtpGetFile または FtpOpenFile ( InternetReadFile を使用) を使用できます。 FtpGetFile は FTP サーバーからファイルを取得してローカルに保存するために使用されます。 FtpOpenFileInternetReadFile を使用して、ダウンロードした情報の移動先を制御できます (たとえば、アプリケーションは編集ボックスに情報を表示できます)。

FtpDeleteFile 関数を使用して FTP サーバー上のファイルを削除します。 この関数は、現在のディレクトリまたは完全修飾ファイル名に対する相対ファイル名を FTP サーバーから削除します。 FtpDeleteFile には、 InternetConnect によって返されるセッション ハンドルが必要です。

FTP 関数ハンドル

FTP 関数を適切に動作させるには、特定の種類の HINTERNET ハンドルが 必要です。 これらのハンドルは、 InternetOpen によって作成されたルート ハンドルから始めて、特定の順序で作成する必要があります。 その後、InternetConnect は FTP セッション ハンドルを作成できます。

次の図は、 InternetConnect によって返される FTP セッション ハンドルに依存する関数を示しています。 網かけのボックスは HINTERNET ハンドルを返す関数を表し、プレーン ボックスは依存する関数によって作成された HINTERNET ハンドルを使用する関数を表します。

internetconnect によって返される ftp セッション ハンドルに依存する ftp 関数

次の図は 、HINTERNET ハンドルを返す 2 つの関数と、それらに依存する関数を示しています。 網かけのボックスは HINTERNET ハンドルを返す関数を表し、プレーン ボックスは依存する関数によって作成された HINTERNET ハンドルを使用する関数を表します。

ヒントネット ハンドルを返す ftp 関数

詳細については、「 HINTERNET ハンドル」を参照してください。

FTP セッションに WinINet 関数を使用する

FTP セッション中は、次の関数が使用されます。 これらの関数は CERN プロキシでは認識されません。 CERN プロキシを介して機能する必要があるアプリケーションでは、 InternetOpenUrl を 使用し、リソースに直接アクセスする必要があります。 直接リソース アクセスの詳細については、「 URL への直接アクセス」を参照してください。

機能 説明
FtpCreateDirectory サーバー上に新しいディレクトリを作成します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpDeleteFile サーバーからファイルを削除します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpFindFirstFile 現在のディレクトリでファイル列挙またはファイル検索を開始します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpGetCurrentDirectory サーバー上のクライアントの現在のディレクトリを返します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpGetFile サーバーからファイルを取得します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpOpenFile 読み取りまたは書き込みのために、サーバー上のファイルへのアクセスを開始します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpPutFile ファイルをサーバーに書き込みます。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpRemoveDirectory サーバー上のディレクトリを削除します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpRenameFile サーバー上のファイルの名前を変更します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
FtpSetCurrentDirectory サーバー上のクライアントの現在のディレクトリを変更します。 この関数には、 InternetConnect によって作成されたハンドルが必要です。
InternetWriteFile サーバー上の開いているファイルにデータを書き込みます。 この関数には、 FtpOpenFile によって作成されたハンドルが必要です。

 

FTP セッションの開始

アプリケーションは、InternetOpen によって作成されたハンドルで InternetConnect を呼び出して FTP セッションを確立します。 InternetConnect には、サーバー名、ポート番号、ユーザー名、パスワード、サービスの種類 (INTERNET_SERVICE_FTPに設定する必要があります) が必要です。 パッシブ FTP セマンティクスの場合、アプリケーションでは INTERNET_FLAG_PASSIVE フラグも設定する必要があります。

ポート番号には、INTERNET_DEFAULT_FTP_PORTとINTERNET_INVALID_PORT_NUMBERの値を使用できます。 INTERNET_DEFAULT_FTP_PORTは既定の FTP ポートを使用しますが、サービスの種類を設定する必要があります。 INTERNET_INVALID_PORT_NUMBERは、指定されたサービスの種類の既定値を使用します。

ユーザー名とパスワードの値を NULL に設定できます。 両方の値が NULL に設定されている場合、 InternetConnect はユーザー名に "anonymous" を使用し、パスワードにはユーザーのメール アドレスを使用します。 パスワードのみが NULL に設定されている場合、 InternetConnect に渡されるユーザー名がユーザー名に使用され、パスワードには空の文字列が使用されます。 どちらの値も NULL でない場合は、 InternetConnect に指定されたユーザー名とパスワードが使用されます。

ディレクトリの列挙

FTP サーバー上のディレクトリを列挙するには、 FtpFindFirstFile によるハンドルの作成が必要です。 このハンドルは、 InternetConnect によって作成されたセッション ハンドルの分岐です。 FtpFindFirstFile は、サーバー上の最初のファイルまたはディレクトリを検索し、 WIN32_FIND_DATA 構造で返します。 ERROR_NO_MORE_FILESを返すまで InternetFindNextFile を使用します。 このメソッドは、サーバー上の後続のすべてのファイルとディレクトリを検索します。 InternetFindNextFile の詳細については、「次のファイルの検索」を参照してください。

FtpFindFirstFile または InternetFindNextFile によって取得されたファイルがディレクトリであるかどうかを確認するには、WIN32_FIND_DATA構造体の dwFileAttributes メンバーをチェックして、FILE_ATTRIBUTE_DIRECTORYと等しいかどうかを確認します。

アプリケーションが FTP サーバーで変更を加える場合、または FTP サーバーが頻繁に変更される場合は、ftpFindFirstFileINTERNET_FLAG_NO_CACHE_WRITEフラグとINTERNET_FLAG_RELOADフラグを設定する必要があります。 これらのフラグは、FTP サーバーから取得されるディレクトリ情報が最新であることを確認します。

アプリケーションがディレクトリ列挙を完了したら、アプリケーションは FtpFindFirstFile によって作成されたハンドルで InternetCloseHandle を呼び出す必要があります。 そのハンドルが閉じられるまで、アプリケーションは InternetConnect によって作成されたセッション ハンドルで FtpFindFirstFile を再度呼び出すことはできません。 同じ関数の前の呼び出しが閉じられる前に、同じセッション ハンドルで FtpFindFirstFile の呼び出しが行われた場合、関数は失敗し、 ERROR_FTP_TRANSFER_IN_PROGRESSが返されます。

次の例では、FTP ディレクトリの内容をリスト ボックス コントロールに列挙します。 hConnection パラメーターは、FTP セッションを確立した後に InternetConnect 関数によって返されるハンドルです。 この例で参照されている InternetErrorOut 関数のサンプル ソース コードについては、「 エラーの処理」トピックを参照してください。

#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 );
}

FtpGetCurrentDirectory 関数と FtpSetCurrentDirectory 関数は、ディレクトリ ナビゲーションを処理します。

FtpGetCurrentDirectory は 、FTP サーバー上のアプリケーションの現在のディレクトリを返します。 FTP サーバー上のルート ディレクトリからのディレクトリ パスが含まれています。

FtpSetCurrentDirectory は 、サーバー上の作業ディレクトリを変更します。 FtpSetCurrentDirectory に渡されるディレクトリ情報は、現在のディレクトリに対する相対パス名として部分的または完全修飾にすることができます。 たとえば、アプリケーションが現在ディレクトリ "public/info" にあり、パスが "ftp/example" の場合、 FtpSetCurrentDirectory は現在のディレクトリを "public/info/ftp/example" に変更します。

次の例では、InternetConnect によって返される FTP セッション ハンドル hConnection を使用します。 新しいディレクトリ名は、 IDC が nDirNameId パラメーターで渡される親ダイアログの編集ボックスから取得されます。 ディレクトリの変更が行われる前に、関数は現在のディレクトリを取得し、同じ編集ボックスに格納します。 最後に呼び出された DisplayFtpDir 関数の souce コードを上に示します。

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 );
}

FTP サーバー上のディレクトリの操作

WinINet には、アプリケーションが必要な特権を持つ FTP サーバー上のディレクトリを作成および削除する機能が用意されています。 アプリケーションが特定のユーザー名とパスワードを使用してサーバーにログオンする必要がある場合は、FTP セッション ハンドルの作成時に InternetConnect で値を使用できます。

FtpCreateDirectory 関数は、有効な FTP セッション ハンドルと null で終わる文字列を受け取ります。この文字列には、完全修飾パスまたは現在のディレクトリに対する相対名が含まれており、FTP サーバー上にディレクトリが作成されます。

次の例は、 FtpCreateDirectory の 2 つの個別の呼び出しを示しています。 どちらの例でも、hFtpSession は InternetConnect 関数によって作成されたセッション ハンドルであり、ルート ディレクトリは現在のディレクトリです。

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

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

FtpRemoveDirectory 関数は、現在のディレクトリに対する完全修飾パスまたは相対名を含むセッション ハンドルと null で終わる文字列を受け取り、そのディレクトリを FTP サーバーから削除します。

次の例は、 FtpRemoveDirectory の 2 つのサンプル呼び出しを示しています。 どちらの呼び出しでも、hFtpSession は InternetConnect 関数によって作成されたセッション ハンドルであり、ルート ディレクトリは現在のディレクトリです。 ルート ディレクトリには "test" というディレクトリがあり、"test" ディレクトリには "example" というディレクトリがあります。

/* 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. */

次の例では、FTP サーバーに新しいディレクトリを作成します。 新しいディレクトリ名は、 IDC が nDirNameId パラメーターで渡される親ダイアログの編集ボックスから取得されます。 hConnection ハンドルは、FTP セッションを確立した後に InternetConnect によって作成されました。 最後に呼び出された DisplayFtpDir 関数のソース コードを上に示します。

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 ) );
}

次の例では、FTP サーバーからディレクトリを削除します。 削除するディレクトリの名前は、IDC が nDirNameId パラメーターに渡される親ダイアログの編集ボックスから取得されます。 hConnection ハンドルは、FTP セッションを確立した後に InternetConnect によって作成されました。 最後に呼び出された DisplayFtpDir 関数のソース コードを上に示します。

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 ) );
}

FTP サーバーでのファイルの取得

FTP サーバーからファイルを取得する方法は 3 つあります。

InternetReadFile 関数の使用方法の詳細については、「ファイルの読み取り」を参照してください。

ファイルの URL が使用可能な場合、アプリケーションは InternetOpenUrl を呼び出してその URL に接続し、 InternetReadFile を使用してファイルのダウンロードを制御できます。 これにより、アプリケーションはダウンロードをより厳密に制御でき、FTP サーバーで他の操作を行う必要がない状況に最適です。 リソースに直接アクセスする方法の詳細については、「 URL に直接アクセスする」を参照してください。

アプリケーションが InternetConnect を使用してサーバーへの FTP セッション ハンドルを確立している場合、アプリケーションは、既存のファイル名と、ローカルに格納されているファイルの新しい名前を使用して FtpOpenFile を呼び出すことができます。 その後、アプリケーションは InternetReadFile を使用してファイルをダウンロードできます。 これにより、アプリケーションでダウンロードをより厳密に制御し、FTP サーバーへの接続を保持できるため、より多くのコマンドを実行できます。

アプリケーションがダウンロードを厳密に制御する必要がない場合、アプリケーションは FTP セッション ハンドル、リモート ファイル名、およびローカル ファイル名と共に FtpGetFile を使用してファイルを取得できます。 FtpGetFile は、FTP サーバーからファイルを読み取り、ローカルに格納することに関連するすべての簿記とオーバーヘッドを実行します。

次の例では、FTP サーバーからファイルを取得し、ローカルに保存します。 FTP サーバー上のファイルの名前は、 nFtpFileNameId パラメーターで IDC が渡される親ダイアログの編集ボックスから取得され、ファイルを保存するローカル名は、 nLocalFileNameId パラメーターで IDC が渡される編集ボックスから取得されます。 hConnection ハンドルは、FTP セッションを確立した後に InternetConnect によって作成されました。

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 );
}

FTP サーバーへのファイルの配置

FTP サーバーにファイルを配置する方法は 2 つあります。

FTP サーバーにデータを送信する必要があるが、すべてのデータを含むローカル ファイルがないアプリケーションでは、 FtpOpenFile を使用して ftp サーバー上のファイルを作成して開く必要があります。 その後、アプリケーションは InternetWriteFile を使用して、情報をファイルにアップロードできます。

ファイルが既にローカルに存在する場合、アプリケーションは FtpPutFile を使用してファイルを FTP サーバーにアップロードできます。 FtpPutFile は、リモート FTP サーバーへのローカル ファイルのアップロードに伴うすべてのオーバーヘッドを実行します。

次の例では、ローカル ファイルを FTP サーバーにコピーします。 ファイルのローカル名は、IDC が nLocalFileNameId パラメーターで渡される親ダイアログの編集ボックスから取得され、FTP サーバーにファイルを保存する名前は、 IDC が nFtpFileNameId パラメーターで渡される編集ボックスから取得されます。 hConnection ハンドルは、FTP セッションを確立した後に InternetConnect によって作成されました。

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
}

FTP サーバーからのファイルの削除

FTP サーバーからファイルを削除するには、 FtpDeleteFile 関数を使用します。 呼び出し元のアプリケーションには、FTP サーバーからファイルを削除するために必要な特権が必要です。

次の例では、FTP サーバーからファイルを削除します。 削除するファイルの名前は、IDC が nFtpFileNameId パラメーターに渡される親ダイアログの編集ボックスから取得されます。 hConnection ハンドルは、FTP セッションを確立した後に InternetConnect によって作成されました。 この関数はファイルの一覧やディレクトリの表示を更新しないため、正常に削除されると呼び出し元のプロセスで更新する必要があります。

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
}

FTP サーバー上のファイルとディレクトリの名前を変更する

FTP サーバー上のファイルとディレクトリの名前は、 FtpRenameFile 関数を使用して変更できます。 FtpRenameFile は 、現在のディレクトリを基準にして、部分的または完全修飾名を含む 2 つの null で終わる文字列を受け入れます。 関数は、最初の文字列で指定されたファイルの名前を、2 番目の文字列で指定された名前に変更します。

次の例では、FTP サーバー上のファイルまたはディレクトリの名前を変更します。 ファイルまたはディレクトリの現在の名前は、IDC が nOldFileNameId パラメーターで渡される親ダイアログの編集ボックスから取得され、新しい名前は、 nNewFileNameId パラメーターで IDC が渡される編集ボックスから取得されます。 hConnection ハンドルは、FTP セッションを確立した後に InternetConnect によって作成されました。 この関数はファイル一覧やディレクトリ表示を更新しないため、呼び出しプロセスは名前の変更が正常に完了したときに更新する必要があります。

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
}

注意

WinINet では、サーバーの実装はサポートされていません。 また、サービスから使用しないでください。 サーバーの実装またはサービスの場合は、 Microsoft Windows HTTP サービス (WinHTTP) を使用します。