次の方法で共有


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 は、ファイルが既にローカルに存在する場合に使用できますが、ftpOpenFileInternetWriteFileは、データを FTP サーバー上のファイルに書き込む必要がある場合に使用できます。

ファイルをダウンロードまたは取得するには、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 ハンドルを使用する関数を表します。

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 はユーザー名に "匿名" を使用し、パスワードにはユーザーの電子メール アドレスを使用します。 パスワードのみが NULL に設定されている場合、InternetConnect に渡されるユーザー名がユーザー名に使用され、パスワードには空の文字列が使用されます。 どちらの値も NULL されていない場合は、internetConnect指定されたユーザー名とパスワードが使用されます。

ディレクトリの列挙

FTP サーバー上のディレクトリを列挙するには、FtpFindFirstFileしてハンドルを作成する必要があります。 このハンドルは、InternetConnectによって作成されたセッション ハンドルの分岐です。 FtpFindFirstFile サーバー上の最初のファイルまたはディレクトリを検索し、WIN32_FIND_DATA 構造体で返します。 internetFindNextFile ERROR_NO_MORE_FILESを返すまで を使用します。 このメソッドは、サーバー上の後続のすべてのファイルとディレクトリを検索します。 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-terminated 文字列を受け取り、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 つの方法があります。

  • InternetOpenUrl使用し、InternetReadFileします。
  • FtpOpenFile を使用し、InternetReadFileします。
  • FtpGetFileを使用します。

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

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

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

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

次の例では、FTP サーバーからファイルを取得し、ローカルに保存します。 FTP サーバー上のファイルの名前は、IDC が nFtpFileNameId パラメーターで渡される親ダイアログの編集ボックスから取得され、ファイルが保存されるローカル名は、idC が nLocalFileNameId パラメーターで渡される編集ボックスから取得されます。 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 サーバーにファイルを保存する名前は、nFtpFileNameId パラメーターで IDC が渡される編集ボックスから取得されます。 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-terminated 文字列を受け入れます。 この関数は、最初の文字列で指定されたファイルの名前を、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 Services (WinHTTP)を使用します。