📄 ftp.c
字号:
*
*/
BOOL WINAPI FtpRemoveDirectoryW(HINTERNET hFtpSession, LPCWSTR lpszDirectory)
{
LPWININETFTPSESSIONW lpwfs;
LPWININETAPPINFOW hIC = NULL;
BOOL r = FALSE;
lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
goto lend;
}
hIC = (LPWININETAPPINFOW) lpwfs->hdr.lpwhparent;
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
WORKREQUEST workRequest;
struct WORKREQ_FTPREMOVEDIRECTORYW *req;
workRequest.asyncall = FTPREMOVEDIRECTORYW;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpRemoveDirectoryW;
req->lpszDirectory = WININET_strdupW(lpszDirectory);
r = INTERNET_AsyncCall(&workRequest);
}
else
{
r = FTP_FtpRemoveDirectoryW(lpwfs, lpszDirectory);
}
lend:
if( lpwfs )
WININET_Release( &lpwfs->hdr );
return r;
}
/***********************************************************************
* FTP_FtpRemoveDirectoryW (Internal)
*
* Remove a directory on the ftp server
*
* RETURNS
* TRUE on success
* FALSE on failure
*
*/
BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory)
{
INT nResCode;
BOOL bSuccess = FALSE;
LPWININETAPPINFOW hIC = NULL;
TRACE("\n");
assert (WH_HFTPSESSION == lpwfs->hdr.htype);
/* Clear any error information */
INTERNET_SetLastError(0);
if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RMD, lpszDirectory, 0, 0, 0))
goto lend;
nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
if (nResCode)
{
if (nResCode == 250)
bSuccess = TRUE;
else
FTP_SetResponseError(nResCode);
}
lend:
hIC = (LPWININETAPPINFOW) lpwfs->hdr.lpwhparent;
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
INTERNET_ASYNC_RESULT iar;
iar.dwResult = (DWORD)bSuccess;
iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
return bSuccess;
}
/***********************************************************************
* FtpRenameFileA (WININET.@)
*
* Rename a file on the ftp server
*
* RETURNS
* TRUE on success
* FALSE on failure
*
*/
BOOL WINAPI FtpRenameFileA(HINTERNET hFtpSession, LPCSTR lpszSrc, LPCSTR lpszDest)
{
LPWSTR lpwzSrc;
LPWSTR lpwzDest;
BOOL ret;
lpwzSrc = lpszSrc?WININET_strdup_AtoW(lpszSrc):NULL;
lpwzDest = lpszDest?WININET_strdup_AtoW(lpszDest):NULL;
ret = FtpRenameFileW(hFtpSession, lpwzSrc, lpwzDest);
HeapFree(GetProcessHeap(), 0, lpwzSrc);
HeapFree(GetProcessHeap(), 0, lpwzDest);
return ret;
}
/***********************************************************************
* FtpRenameFileW (WININET.@)
*
* Rename a file on the ftp server
*
* RETURNS
* TRUE on success
* FALSE on failure
*
*/
BOOL WINAPI FtpRenameFileW(HINTERNET hFtpSession, LPCWSTR lpszSrc, LPCWSTR lpszDest)
{
LPWININETFTPSESSIONW lpwfs;
LPWININETAPPINFOW hIC = NULL;
BOOL r = FALSE;
lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
goto lend;
}
hIC = (LPWININETAPPINFOW) lpwfs->hdr.lpwhparent;
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
WORKREQUEST workRequest;
struct WORKREQ_FTPRENAMEFILEW *req;
workRequest.asyncall = FTPRENAMEFILEW;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpRenameFileW;
req->lpszSrcFile = WININET_strdupW(lpszSrc);
req->lpszDestFile = WININET_strdupW(lpszDest);
r = INTERNET_AsyncCall(&workRequest);
}
else
{
r = FTP_FtpRenameFileW(hFtpSession, lpszSrc, lpszDest);
}
lend:
if( lpwfs )
WININET_Release( &lpwfs->hdr );
return r;
}
/***********************************************************************
* FTP_FtpRenameFileA (Internal)
*
* Rename a file on the ftp server
*
* RETURNS
* TRUE on success
* FALSE on failure
*
*/
BOOL FTP_FtpRenameFileW( LPWININETFTPSESSIONW lpwfs,
LPCWSTR lpszSrc, LPCWSTR lpszDest)
{
INT nResCode;
BOOL bSuccess = FALSE;
LPWININETAPPINFOW hIC = NULL;
TRACE("\n");
assert (WH_HFTPSESSION == lpwfs->hdr.htype);
/* Clear any error information */
INTERNET_SetLastError(0);
if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RNFR, lpszSrc, 0, 0, 0))
goto lend;
nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
if (nResCode == 350)
{
if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RNTO, lpszDest, 0, 0, 0))
goto lend;
nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
}
if (nResCode == 250)
bSuccess = TRUE;
else
FTP_SetResponseError(nResCode);
lend:
hIC = (LPWININETAPPINFOW) lpwfs->hdr.lpwhparent;
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
INTERNET_ASYNC_RESULT iar;
iar.dwResult = (DWORD)bSuccess;
iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
return bSuccess;
}
/***********************************************************************
* FtpCommandA (WININET.@)
*/
BOOL WINAPI FtpCommandA( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags,
LPCSTR lpszCommand, DWORD_PTR dwContext, HINTERNET* phFtpCommand )
{
FIXME("%p %d 0x%08lx %s 0x%08lx %p\n", hConnect, fExpectResponse, dwFlags,
debugstr_a(lpszCommand), dwContext, phFtpCommand);
return TRUE;
}
/***********************************************************************
* FtpCommandW (WININET.@)
*/
BOOL WINAPI FtpCommandW( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags,
LPCWSTR lpszCommand, DWORD_PTR dwContext, HINTERNET* phFtpCommand )
{
FIXME("%p %d 0x%08lx %s 0x%08lx %p\n", hConnect, fExpectResponse, dwFlags,
debugstr_w(lpszCommand), dwContext, phFtpCommand);
return TRUE;
}
/***********************************************************************
* FTP_Connect (internal)
*
* Connect to a ftp server
*
* RETURNS
* HINTERNET a session handle on success
* NULL on failure
*
*/
HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext,
DWORD dwInternalFlags)
{
static const WCHAR szDefaultUsername[] = {'a','n','o','n','y','m','o','u','s','\0'};
static const WCHAR szDefaultPassword[] = {'u','s','e','r','@','s','e','r','v','e','r','\0'};
struct sockaddr_in socketAddr;
INT nsocket = -1;
UINT sock_namelen;
BOOL bSuccess = FALSE;
LPWININETFTPSESSIONW lpwfs = NULL;
HINTERNET handle = NULL;
TRACE("%p Server(%s) Port(%d) User(%s) Paswd(%s)\n",
hIC, debugstr_w(lpszServerName),
nServerPort, debugstr_w(lpszUserName), debugstr_w(lpszPassword));
assert( hIC->hdr.htype == WH_HINIT );
if (NULL == lpszUserName && NULL != lpszPassword)
{
INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
goto lerror;
}
lpwfs = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPSESSIONW));
if (NULL == lpwfs)
{
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
goto lerror;
}
if (nServerPort == INTERNET_INVALID_PORT_NUMBER)
nServerPort = INTERNET_DEFAULT_FTP_PORT;
lpwfs->hdr.htype = WH_HFTPSESSION;
lpwfs->hdr.lpwhparent = WININET_AddRef( &hIC->hdr );
lpwfs->hdr.dwFlags = dwFlags;
lpwfs->hdr.dwContext = dwContext;
lpwfs->hdr.dwInternalFlags = dwInternalFlags;
lpwfs->hdr.dwRefCount = 1;
lpwfs->hdr.destroy = FTP_CloseSessionHandle;
lpwfs->hdr.lpfnStatusCB = hIC->hdr.lpfnStatusCB;
lpwfs->download_in_progress = NULL;
handle = WININET_AllocHandle( &lpwfs->hdr );
if( !handle )
{
ERR("Failed to alloc handle\n");
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
goto lerror;
}
if(hIC->lpszProxy && hIC->dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
if(strchrW(hIC->lpszProxy, ' '))
FIXME("Several proxies not implemented.\n");
if(hIC->lpszProxyBypass)
FIXME("Proxy bypass is ignored.\n");
}
if ( !lpszUserName) {
lpwfs->lpszUserName = WININET_strdupW(szDefaultUsername);
lpwfs->lpszPassword = WININET_strdupW(szDefaultPassword);
}
else {
lpwfs->lpszUserName = WININET_strdupW(lpszUserName);
lpwfs->lpszPassword = WININET_strdupW(lpszPassword);
}
/* Don't send a handle created callback if this handle was created with InternetOpenUrl */
if (!(lpwfs->hdr.dwInternalFlags & INET_OPENURL))
{
INTERNET_ASYNC_RESULT iar;
iar.dwResult = (DWORD)handle;
iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&hIC->hdr, dwContext,
INTERNET_STATUS_HANDLE_CREATED, &iar,
sizeof(INTERNET_ASYNC_RESULT));
}
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_RESOLVING_NAME,
(LPWSTR) lpszServerName, strlenW(lpszServerName));
if (!GetAddress(lpszServerName, nServerPort, &socketAddr))
{
INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED);
goto lerror;
}
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED,
(LPWSTR) lpszServerName, strlenW(lpszServerName));
nsocket = socket(AF_INET,SOCK_STREAM,0);
if (nsocket == -1)
{
INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT);
goto lerror;
}
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTING_TO_SERVER,
&socketAddr, sizeof(struct sockaddr_in));
if (connect(nsocket, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) < 0)
{
ERR("Unable to connect (%s)\n", strerror(errno));
INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT);
}
else
{
TRACE("Connected to server\n");
lpwfs->sndSocket = nsocket;
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTED_TO_SERVER,
&socketAddr, sizeof(struct sockaddr_in));
sock_namelen = sizeof(lpwfs->socketAddress);
getsockname(nsocket, (struct sockaddr *) &lpwfs->socketAddress, &sock_namelen);
if (FTP_ConnectToHost(lpwfs))
{
TRACE("Successfully logged into server\n");
bSuccess = TRUE;
}
}
lerror:
if (!bSuccess && nsocket == -1)
closesocket(nsocket);
if (!bSuccess && lpwfs)
{
HeapFree(GetProcessHeap(), 0, lpwfs);
WININET_FreeHandle( handle );
lpwfs = NULL;
}
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
INTERNET_ASYNC_RESULT iar;
iar.dwResult = (DWORD)lpwfs;
iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
return handle;
}
/***********************************************************************
* FTP_ConnectToHost (internal)
*
* Connect to a ftp server
*
* RETURNS
* TRUE on success
* NULL on failure
*
*/
static BOOL FTP_ConnectToHost(LPWININETFTPSESSIONW lpwfs)
{
INT nResCode;
BOOL bSuccess = FALSE;
TRACE("\n");
FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_USER, lpwfs->lpszUserName, 0, 0, 0))
goto lend;
nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
if (nResCode)
{
/* Login successful... */
if (nResCode == 230)
bSuccess = TRUE;
/* User name okay, need password... */
else if (nResCode == 331)
bSuccess = FTP_SendPassword(lpwfs);
/* Need account for login... */
else if (nResCode == 332)
bSuccess = FTP_SendAccount(lpwfs);
else
FTP_SetResponseError(nResCode);
}
TRACE("Returning %d\n", bSuccess);
lend:
return bSuccess;
}
/***********************************************************************
* FTP_SendCommandA (internal)
*
* Send command to server
*
* RETURNS
* TRUE on success
* NULL on failure
*
*/
static BOOL FTP_SendCommandA(INT nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam,
INTERNET_STATUS_CALLBACK lpfnStatusCB, LPWININETHANDLEHEADER hdr, DWORD dwContext)
{
DWORD len;
CHAR *buf;
DWORD nBytesSent = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -