📄 uploaderbase.cpp
字号:
// UploaderBase.cpp: implementation of the CUploaderBase class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "UploaderBase.h"
#include <afxtempl.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define UPLOAD_OK 0x0000
#define FILESIZE_INVALID 0x0001
#define EXTENSION_NOT_ALLOWED 0x0002
#define DESTINATION_PATH_INVALID 0x0003
#define UNKNOWN_ERROR 0x0004
#define UNABLE_TO_CREATE_FILE 0x0005
#define FILE_DOESNT_EXIST 0x0006
char* MyStrStr(char* string, const char* strCharSet, long lSizeString)
{
if (!strCharSet || !strCharSet[0])
return 0;
int iIndex = 0;
int iBkIndex = -1;
long lBkSizeString = -1L;
int iCharSetIndex = 0;
while (lSizeString >= 0)
{
if (iBkIndex == -1 && iCharSetIndex && string[iIndex] == strCharSet[0])
{
iBkIndex = iIndex;
lBkSizeString = lSizeString;
}
if (string[iIndex] == strCharSet[iCharSetIndex])
{
iCharSetIndex++;
iIndex++;
if (strCharSet[iCharSetIndex] == 0)
return &(string[iIndex-iCharSetIndex]);
}
else
{
iCharSetIndex = 0;
if (iBkIndex != -1)
{
iIndex = iBkIndex;
lSizeString = lBkSizeString + 1;
iBkIndex = -1;
lBkSizeString = -1L;
}
else
{
iIndex++;
}
}
lSizeString--;
}
return 0;
}
BOOL StrEqual(LPCTSTR lpszString, LPCTSTR lpszSrc)
{
if (!lpszString || !lpszString[0])
return FALSE;
if (!lpszSrc || !lpszSrc[0])
return FALSE;
int i=0;
while (TRUE)
{
if (!lpszSrc[i])
return TRUE;
if (!lpszString[i])
return FALSE;
if (lpszSrc[i] != lpszString[i])
return FALSE;
i++;
}
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CUploaderBase::CUploaderBase()
{
m_lMaxSize = -1L;
m_lpBytesData = NULL;
m_lDataSize = 0L;
}
CUploaderBase::~CUploaderBase()
{
if (m_lpBytesData)
delete [] m_lpBytesData;
}
HRESULT CUploaderBase::SetMaxFileSize(long lMaxSize)
{
m_lMaxSize = lMaxSize;
return S_OK;
}
HRESULT CUploaderBase::SetDestinationPath(BSTR bsDestinationPath)
{
m_sDestPath = bsDestinationPath;
if (!m_sDestPath.IsEmpty())
if (m_sDestPath.Right(1) != "\\")
m_sDestPath += "\\";
return S_OK;
}
HRESULT CUploaderBase::StartUpload(IRequest* pIRequest)
{
HRESULT hr = pIRequest->get_TotalBytes(&m_lDataSize);
if (FAILED(hr))
return hr;
if (m_lDataSize == 0L)
{
return S_OK;
}
COleVariant varBytesToRead;
COleSafeArray sarrayBytes;
varBytesToRead = m_lDataSize;
sarrayBytes.CreateOneDim(VT_UI1, m_lDataSize);
hr = pIRequest->BinaryRead(&varBytesToRead, &sarrayBytes);
if (FAILED(hr))
{
sarrayBytes.Clear();
return hr;
}
LPVOID lpData;
sarrayBytes.AccessData(&lpData);
m_lpBytesData = new BYTE[m_lDataSize];
memcpy(m_lpBytesData, lpData, m_lDataSize);
sarrayBytes.UnaccessData();
sarrayBytes.Clear();
// gets the header
TCHAR szHeaderEnd[] = { 13, 10, 13, 10, 0 };
int iCount = 0;
CArray<char, char> charArray;
charArray.SetSize(0, 64);
while (!StrEqual((LPTSTR)&m_lpBytesData[iCount], szHeaderEnd))
{
charArray.Add(m_lpBytesData[iCount++]);
// we reached the end
if (iCount == m_lDataSize)
{
m_sHeader.Empty();
break;
}
}
charArray.Add(0);
m_sHeader = charArray.GetData();
if (!m_sHeader.IsEmpty())
{
TCHAR szCrLf[] = { 13, 10, 0 };
// gets the delimiter from the header
m_sDelimiter = m_sHeader.Left(m_sHeader.Find(szCrLf));
}
// make this a buffer a null string
// it ends with an 13 10
// so replace the 13 with a 0 :)
m_lpBytesData[m_lDataSize-2] = 0;
TRACE("DELIMITER: %s\n", m_sDelimiter);
/*
#ifdef _DEBUG
CStdioFile file;
if (file.Open("output.txt", CFile::modeWrite | CFile::modeCreate))
{
file.Write(m_lpBytesData, m_lDataSize);
file.Close();
WinExec("Notepad output.txt", SW_SHOW);
}
#endif
*/
return S_OK;
}
HRESULT CUploaderBase::GetError(long lError, BSTR* pbsReturn)
{
CString sError;
switch (lError)
{
case UPLOAD_OK:
sError = _T("No Error");
break;
case FILESIZE_INVALID:
sError = _T("Filesize invalid");
break;
case EXTENSION_NOT_ALLOWED:
sError = _T("Extension not allowed");
break;
case DESTINATION_PATH_INVALID:
sError = _T("Invalid destination path");
break;
case UNKNOWN_ERROR:
sError = _T("Unkown Error");
break;
case UNABLE_TO_CREATE_FILE:
sError = _T("Error creating file");
break;
case FILE_DOESNT_EXIST:
sError = _T("The file doesn't exists");
break;
}
*pbsReturn = sError.AllocSysString();
return S_OK;
}
HRESULT CUploaderBase::GetFormValue(CString sFieldName, BSTR* pbsReturn)
{
BOOL bOK = FALSE;
if (m_lpBytesData)
{
// looks for name="fieldName"
CString sField("name=\"");
sField += sFieldName;
sField += "\"";
LPCTSTR lpszField = MyStrStr((LPTSTR)m_lpBytesData, sField, m_lDataSize);
if (lpszField)
{
// we found the start now looks for the end
LPCTSTR lpszEndField = strstr(lpszField + sField.GetLength() + 4, m_sDelimiter);
lpszField += (sField.GetLength() + 4);
// figures out the size and gets the value
int nSize = (lpszEndField - lpszField) - 2;
LPBYTE lpFieldValue = new BYTE[nSize + 1];
memcpy(lpFieldValue, lpszField, nSize);
lpFieldValue[nSize] = 0;
// pass to the returning variable
CString sFieldValue(lpFieldValue);
*pbsReturn = sFieldValue.AllocSysString();
delete [] lpFieldValue;
bOK = TRUE;
}
}
if (!bOK)
{
// oh god, we didn't find it
*pbsReturn = SysAllocString(OLESTR(""));
}
return S_OK;
}
HRESULT CUploaderBase::UploadFile(CString sFieldName, long* plResult)
{
// we don't have the destination path
if (m_sDestPath.IsEmpty())
{
*plResult = DESTINATION_PATH_INVALID;
return S_OK;
}
if (m_lpBytesData)
{
// looks for name="fieldName"
CString sField("name=\"");
sField += sFieldName;
sField += "\"";
LPTSTR lpszField = MyStrStr((LPTSTR)m_lpBytesData, sField, m_lDataSize);
if (lpszField)
{
// we found it now looks for the filename
lpszField += sField.GetLength();
LPTSTR lpszFilenameStart = strstr(lpszField, "filename=""");
LPTSTR lpszContentType = strstr(lpszField, "Content-Type: ");
if (!lpszFilenameStart || !lpszContentType)
{
*plResult = UNKNOWN_ERROR;
return S_OK;
}
// this is COOL!!!
lpszContentType[-3] = 0;
LPTSTR lpszFilename = strrchr(lpszFilenameStart, '\\');
if (!lpszFilename)
{
// restore the buffer
lpszContentType[-3] = '"';
*plResult = FILE_DOESNT_EXIST;
return S_OK;
}
// that's the filename
CString sFilename = lpszFilename + 1;
lpszContentType[-3] = '"';
// check if the file extension is ok
CString sExtension;
int iPosDoth = sFilename.ReverseFind('.');
if (iPosDoth != -1)
{
sExtension = sFilename.Mid(iPosDoth + 1);
}
if (!FileExtensionAllowed(sExtension))
{
*plResult = EXTENSION_NOT_ALLOWED;
return S_OK;
}
// try to find the beginning of the file
TCHAR szEndContentType[] = { 13, 10, 13, 10, 0 };
LPTSTR lpszFileStart = MyStrStr(lpszContentType, szEndContentType, m_lDataSize - (lpszContentType - (LPTSTR)m_lpBytesData));
if (!lpszFileStart)
{
*plResult = UNKNOWN_ERROR;
return S_OK;
}
lpszFileStart += 4; // strlen(szEndContentType)
// checks the end of the file
LPTSTR lpszFileEnd = MyStrStr(lpszFileStart, m_sDelimiter, m_lDataSize - (lpszFileStart - (LPTSTR)m_lpBytesData));
if (!lpszFileEnd)
{
*plResult = UNKNOWN_ERROR;
return S_OK;
}
lpszFileEnd -= 2;
// now figures out the size
int nSize = lpszFileEnd - lpszFileStart;
if (m_lMaxSize != -1L)
{
if (nSize > m_lMaxSize)
{
*plResult = FILESIZE_INVALID;
return S_OK;
}
}
// creates the file
CreateDirectory(m_sDestPath, NULL);
// copies the file
CString sPath(m_sDestPath);
sPath += sFilename;
CFile fileUpload;
if (fileUpload.Open(sPath, CFile::modeWrite | CFile::modeCreate))
{
fileUpload.Write(lpszFileStart, nSize);
fileUpload.Close();
*plResult = UPLOAD_OK;
}
else
{
*plResult = UNABLE_TO_CREATE_FILE;
}
}
else
{
*plResult = FILE_DOESNT_EXIST;
}
}
else
{
*plResult = UNKNOWN_ERROR;
}
return S_OK;
}
HRESULT CUploaderBase::SetAllowedExtensions(const SAFEARRAY* psarray)
{
COleSafeArray sarray(*psarray, VT_BSTR);
long lLowerBound;
long lUpBound;
sarray.GetLBound(1, &lLowerBound);
sarray.GetUBound(1, &lUpBound);
long lIndex[2];
VARIANT val;
lIndex[1] = 1;
for (; lLowerBound <= lUpBound; lLowerBound++)
{
lIndex[0] = lLowerBound;
sarray.GetElement(lIndex, &val);
m_ExtensionList.AddTail(CString(val.bstrVal));
}
return S_OK;
}
HRESULT CUploaderBase::SetForbiddenExtensions(const SAFEARRAY* psarray)
{
COleSafeArray sarray(*psarray, VT_BSTR);
long lLowerBound;
long lUpBound;
sarray.GetLBound(1, &lLowerBound);
sarray.GetUBound(1, &lUpBound);
long lIndex[2];
VARIANT val;
lIndex[1] = 1;
for (; lLowerBound <= lUpBound; lLowerBound++)
{
lIndex[0] = lLowerBound;
sarray.GetElement(lIndex, &val);
m_ForbiddenList.AddTail(CString(val.bstrVal));
}
return S_OK;
}
BOOL CUploaderBase::FileExtensionAllowed(LPCTSTR lpszExtension)
{
// try to search in the forbidden extensions
CString sElement;
POSITION pos = m_ForbiddenList.GetHeadPosition();
while (pos)
{
sElement = m_ExtensionList.GetNext(pos);
if (sElement.CompareNoCase(lpszExtension) == 0)
return FALSE;
}
// now watch the allowed extensions
pos = m_ExtensionList.GetHeadPosition();
if (!pos)
return TRUE;
while (pos)
{
sElement = m_ExtensionList.GetNext(pos);
if (sElement.CompareNoCase(lpszExtension) == 0)
return TRUE;
if (sElement == _T("*") || sElement == _T("*.*"))
return TRUE;
}
return FALSE;
}
HRESULT CUploaderBase::GetUploadFilename(CString sFieldName, BSTR *pbsReturn)
{
if (m_lpBytesData)
{
// looks for name="fieldName"
CString sField("name=\"");
sField += sFieldName;
sField += "\"";
LPTSTR lpszField = MyStrStr((LPTSTR)m_lpBytesData, sField, m_lDataSize);
if (lpszField)
{
// we found it now looks for the filename
lpszField += sField.GetLength();
LPTSTR lpszFilenameStart = strstr(lpszField, "filename=""");
LPTSTR lpszContentType = strstr(lpszField, "Content-Type: ");
if (!lpszFilenameStart || !lpszContentType)
{
*pbsReturn = SysAllocString(OLESTR(""));
return S_OK;
}
// this is COOL!!!
lpszContentType[-3] = 0;
LPTSTR lpszFilename = strrchr(lpszFilenameStart, '\\');
if (!lpszFilename)
{
// restore the buffer
lpszContentType[-3] = '"';
*pbsReturn = SysAllocString(OLESTR(""));
return S_OK;
}
// that's the filename
CString sFilename = lpszFilename + 1;
lpszContentType[-3] = '"';
*pbsReturn = sFilename.AllocSysString();
return S_OK;
}
}
*pbsReturn = SysAllocString(OLESTR(""));
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -