📄 ftppidl.cpp
字号:
LPFTPSERVERIDLIST pFtpServerID = NULL;
DWORD cchServerLen = lstrlen(pszServer);
DWORD cchUserNameLen = lstrlen(pszUserName);
DWORD cchPasswordLen = lstrlen(pszPassword);
cchServerLen = LENGTH_AFTER_ALIGN(cchServerLen + 1, sizeof(DWORD));
cchUserNameLen = LENGTH_AFTER_ALIGN(cchUserNameLen + 1, sizeof(DWORD));
cchPasswordLen = LENGTH_AFTER_ALIGN(cchPasswordLen + 1, sizeof(DWORD));
if (!(EVAL(ppidl) && pszServer[0]))
return E_FAIL;
// Set bits in dwFlags that are appropriate
if (pszUserName[0])
dwFlags |= IDVALID_USERNAME;
if (pszPassword[0])
dwFlags |= IDVALID_PASSWORD;
// Find lenght of FTPSERVERIDLIST struct without the MAX_PATH strings
cb = (sizeof(*pFtpServerID) - sizeof(pFtpServerID->szServer) - sizeof(pFtpServerID->szUserName) - sizeof(pFtpServerID->szPassword));
// Add the size of the strings.
cb += (cchServerLen + cchUserNameLen + cchPasswordLen);
ASSERT(0 == (cb % sizeof(DWORD))); // Make sure it's DWORD aligned for Alpha machines.
pidl = (LPITEMIDLIST) pm->Alloc(cb);
if (pidl)
{
LPSTR pszNext;
pFtpServerID = FtpServerID_GetDataSafe(pidl);
pszNext = pFtpServerID->szServer;
ZeroMemory(pFtpServerID, cb);
pFtpServerID->dwIDType = (dwFlags | IDTYPE_ISVALID | IDTYPE_SERVER | IDVALID_PORT_NUM);
ASSERT(IS_VALID_SERVER_ITEMID(pFtpServerID->dwIDType));
pFtpServerID->dwVersion = PIDL_VERSION_NUMBER;
pFtpServerID->sessionKey = GetSessionKey();
pFtpServerID->dwPasswordCookie = -1;
pFtpServerID->dwPortNumber = ipPortNum;
pFtpServerID->cchServerSize = cchServerLen;
SHTCharToAnsi(pszServer, pszNext, pFtpServerID->cchServerSize);
pszNext += cchServerLen; // Advance to cchUserNameSize
*((LPDWORD) pszNext) = cchUserNameLen; // Fill in cchUserNameSize
pszNext = (LPSTR)(((BYTE *) pszNext) + sizeof(DWORD)); // Advance to szUserName
SHTCharToAnsi(pszUserName, pszNext, cchUserNameLen); // Fill in szUserName
if (fHidePassword)
{
pFtpServerID->dwIDType |= IDVALID_HIDE_PASSWORD;
if (EVAL(GetCookieList()))
pFtpServerID->dwPasswordCookie = GetCookieList()->GetCookie(pszPassword);
ASSERT(-1 != pFtpServerID->dwPasswordCookie);
pszPassword = TEXT("");
}
// TraceMsg(TF_FTPURL_UTILS, "FtpServerID_Create(\"ftp://%s:%s@%s/\") dwIDType=%#80lx", pszUserName, pszPassword, pszServer, pFtpServerID->dwIDType);
pszNext += cchUserNameLen; // Advance to cchPasswordLen
*((LPDWORD) pszNext) = cchPasswordLen; // Fill in cchPasswordLen
pszNext = (LPSTR)(((BYTE *) pszNext) + sizeof(DWORD)); // Advance to szPassword
SHTCharToAnsi(pszPassword, pszNext, cchPasswordLen); // Fill in pszPassword
}
*ppidl = pidl;
hr = pidl ? S_OK : E_OUTOFMEMORY;
ASSERT(IsValidPIDL(*ppidl));
return hr;
}
DWORD FtpServerID_GetTypeID(LPCITEMIDLIST pidl)
{
LPFTPSERVERIDLIST pFtpServerID = FtpServerID_GetData(pidl);
ASSERT(FtpID_IsServerItemID(pidl));
if (EVAL(pFtpServerID) &&
EVAL(FtpPidl_IsValid(pidl)))
return pFtpServerID->dwIDType;
return 0;
}
HRESULT FtpServerID_GetServer(LPCITEMIDLIST pidl, LPTSTR pszServer, DWORD cchSize)
{
HRESULT hr = S_OK;
LPFTPSERVERIDLIST pFtpServerID = FtpServerID_GetData(pidl);
if (pFtpServerID)
SHAnsiToTChar(pFtpServerID->szServer, pszServer, cchSize);
else
hr = E_FAIL;
return hr;
}
BOOL FtpServerID_ServerStrCmp(LPCITEMIDLIST pidl, LPCTSTR pszServer)
{
BOOL fMatch = FALSE;
LPFTPSERVERIDLIST pFtpServerID = FtpServerID_GetData(pidl);
#ifdef UNICODE
CHAR szServerAnsi[MAX_PATH];
SHUnicodeToAnsi(pszServer, szServerAnsi, ARRAYSIZE(szServerAnsi));
#endif // UNICODE
if (pFtpServerID)
{
#ifdef UNICODE
fMatch = (0 == StrCmpA(pFtpServerID->szServer, szServerAnsi));
#else // UNICODE
fMatch = (0 == StrCmpA(pFtpServerID->szServer, pszServer));
#endif // UNICODE
}
return fMatch;
}
HRESULT FtpServerID_GetUserName(LPCITEMIDLIST pidl, LPTSTR pszUserName, DWORD cchSize)
{
HRESULT hr = E_FAIL;
LPFTPSERVERIDLIST pFtpServerID = FtpServerID_GetData(pidl);
if (EVAL(pFtpServerID))
{
LPCSTR pszSourceUserName = pFtpServerID->szServer + pFtpServerID->cchServerSize + sizeof(DWORD);
SHAnsiToTChar(pszSourceUserName, pszUserName, cchSize);
hr = S_OK;
}
return hr;
}
HRESULT FtpServerID_GetPassword(LPCITEMIDLIST pidl, LPTSTR pszPassword, DWORD cchSize, BOOL fIncludingHiddenPassword)
{
HRESULT hr = E_FAIL;
LPFTPSERVERIDLIST pFtpServerID = FtpServerID_GetData(pidl);
pszPassword[0] = 0;
if (EVAL(pFtpServerID))
{
// Was the password hidden?
if (fIncludingHiddenPassword &&
(IDVALID_HIDE_PASSWORD & pFtpServerID->dwIDType))
{
// Yes, so get it out of the cookie jar (list)
if (EVAL(GetCookieList()) &&
AreSessionKeysEqual(pFtpServerID->sessionKey, GetSessionKey()))
{
hr = GetCookieList()->GetString(pFtpServerID->dwPasswordCookie, pszPassword, cchSize);
}
}
else
{
// No, so what's in the pidl is the real password.
BYTE * pvSizeOfUserName = (BYTE *) (pFtpServerID->szServer + pFtpServerID->cchServerSize);
DWORD dwSizeOfUserName = *(DWORD *) pvSizeOfUserName;
LPCSTR pszSourcePassword = (LPCSTR) (pvSizeOfUserName + dwSizeOfUserName + 2*sizeof(DWORD));
SHAnsiToTChar(pszSourcePassword, pszPassword, cchSize);
hr = S_OK;
}
}
return hr;
}
INTERNET_PORT FtpServerID_GetPortNum(LPCITEMIDLIST pidl)
{
LPFTPSERVERIDLIST pFtpServerID = FtpServerID_GetData(pidl);
ASSERT(FtpID_IsServerItemID(pidl));
if (EVAL(pFtpServerID))
return (INTERNET_PORT)pFtpServerID->dwPortNumber;
return INTERNET_DEFAULT_FTP_PORT;
}
HRESULT FtpServerID_SetHiddenPassword(LPITEMIDLIST pidl, LPCTSTR pszPassword)
{
HRESULT hr = E_INVALIDARG;
LPFTPSERVERIDLIST pFtpServerID = FtpServerID_GetData(pidl);
ASSERT(FtpID_IsServerItemID(pidl));
if (EVAL(pFtpServerID))
{
pFtpServerID->sessionKey = GetSessionKey();
pFtpServerID->dwIDType |= IDVALID_HIDE_PASSWORD;
if (EVAL(GetCookieList()))
pFtpServerID->dwPasswordCookie = GetCookieList()->GetCookie(pszPassword);
hr = S_OK;
}
return hr;
}
HRESULT FtpServerID_GetStrRet(LPCITEMIDLIST pidl, LPSTRRET lpName)
{
LPFTPSERVERIDLIST pFtpServerID = FtpServerID_GetData(pidl);
ASSERT(FtpID_IsServerItemID(pidl));
if (pFtpServerID)
{
lpName->uType = STRRET_OFFSET;
lpName->uOffset = (DWORD) (sizeof(FTPSERVERIDLIST) - sizeof(pFtpServerID->szServer) + (LPBYTE)pFtpServerID - (LPBYTE)pidl);
}
else
{
lpName->uType = STRRET_CSTR;
lpName->cStr[0] = '\0';
}
return S_OK;
}
/****************************************************\
FTP File/Dir ItemIDs
\****************************************************/
typedef struct tagFTPIDLIST
{
DWORD dwIDType; // Server ItemID or Dir ItemID? Which Bits are valid?
DWORD dwAttributes; // What are the file/dir attributes
ULARGE_INTEGER uliFileSize;
FILETIME ftModified; // Stored in Local Time Zone. (FTP Time)
DWORD dwUNIXPermission; // UNIX CHMOD Permissions (0x00000777, 4=Read, 2=Write, 1=Exec, <Owner><Group><All>)
DWORD dwCompatFlags; // Any special case that needs to be handled
WIRECHAR szWireName[MAX_PATH]; // Needs to go last.
WCHAR wzDisplayName[MAX_PATH]; // Converted to unicode to be displayed in the UI.
} FTPIDLIST;
typedef UNALIGNED FTPIDLIST * LPFTPIDLIST;
HRESULT FtpItemID_Alloc(LPFTPIDLIST pfi, LPITEMIDLIST * ppidl);
typedef struct _FTPIDLIST_WITHHEADER
{
USHORT cb; // size
FTPIDLIST fidListData;
USHORT cbTerminator; // size of next ID (Empty)
} FTPIDLIST_WITHHEADER;
LPFTPIDLIST FtpItemID_GetData(LPCITEMIDLIST pidl)
{
BYTE * pbData = (BYTE *) pidl;
pbData += SIZE_ITEMID_SIZEFIELD; // Skip over the size.
LPFTPIDLIST pFtpItemId = (LPFTPIDLIST) pbData;
if (!EVAL(IS_VALID_DIRORFILE_ITEMID(pFtpItemId->dwIDType))) // If any other bits are sit, it's invalid.
pFtpItemId = NULL;
return pFtpItemId;
}
LPCWSTR FtpItemID_GetDisplayNameReference(LPCITEMIDLIST pidl)
{
BYTE * pbData = (BYTE *) pidl;
LPCWSTR pwzDisplayName = NULL;
DWORD cbWireName;
// Is the version OK?
// if (PIDL_VERSION_NUMBER > FtpPidl_GetVersion(pidl))
// return NULL;
pbData += SIZE_ITEMID_SIZEFIELD; // Skip over the size.
LPFTPIDLIST pFtpItemId = (LPFTPIDLIST) pbData;
cbWireName = LENGTH_AFTER_ALIGN((lstrlenA(pFtpItemId->szWireName) + 1), sizeof(DWORD));
pwzDisplayName = (LPCWSTR) ((BYTE *)(&pFtpItemId->szWireName[0]) + cbWireName);
if (!EVAL(IS_VALID_DIRORFILE_ITEMID(pFtpItemId->dwIDType))) // If any other bits are sit, it's invalid.
pwzDisplayName = NULL;
return pwzDisplayName;
}
DWORD FtpItemID_GetTypeID(LPCITEMIDLIST pidl)
{
LPFTPIDLIST pFtpItemId = FtpItemID_GetData(pidl);
return (pFtpItemId ? pFtpItemId->dwIDType : 0);
}
void FtpItemID_SetTypeID(LPITEMIDLIST pidl, DWORD dwNewTypeID)
{
LPFTPIDLIST pFtpItemId = FtpItemID_GetData(pidl);
ASSERT(pFtpItemId);
pFtpItemId->dwIDType = dwNewTypeID;
}
/****************************************************\
FUNCTION: FtpItemID_Alloc
DESCRIPTION:
We are passed a pointer to a FTPIDLIST data
structure and our goal is to create a ItemID from
it. This mainly includes making it only big enough
for the current string(s).
\****************************************************/
HRESULT FtpItemID_Alloc(LPFTPIDLIST pfi, LPITEMIDLIST * ppidl)
{
HRESULT hr;
WORD cbTotal;
WORD cbDataFirst;
WORD cbData;
BYTE * pbMemory;
DWORD cchSizeOfName = lstrlenA(pfi->szWireName);
DWORD cchSizeOfDispName = lstrlenW(pfi->wzDisplayName);
ASSERT(pfi && ppidl);
// Find lenght of FTPIDLIST struct if the szName member only needed enought room
// for the string, not the full MAX_PATH.
// Size EQUALS: (Everything in the struct) - (the 2 full statusly sized strings) + (the 2 packed strings + alignment)
cbDataFirst = (WORD)((sizeof(*pfi) - sizeof(pfi->szWireName) - sizeof(pfi->wzDisplayName)) + LENGTH_AFTER_ALIGN(cchSizeOfName + 1, sizeof(DWORD)) - sizeof(DWORD));
cbData = cbDataFirst + (WORD) LENGTH_AFTER_ALIGN((cchSizeOfDispName + 1) * sizeof(WCHAR), sizeof(DWORD));
ASSERT((cbData % sizeof(DWORD)) == 0); // Verify it's DWORD aligned.
cbTotal = (SIZE_ITEMID_SIZEFIELD + cbData + SIZE_ITEMID_TERMINATOR);
pbMemory = (BYTE *) CoTaskMemAlloc(cbTotal);
if (EVAL(pbMemory))
{
USHORT * pIDSize = (USHORT *)pbMemory;
BYTE * pbData = (pbMemory + SIZE_ITEMID_SIZEFIELD); // the Data starts at the second DWORD.
USHORT * pIDTerminator = (USHORT *)(pbMemory + SIZE_ITEMID_SIZEFIELD + cbData);
pIDSize[0] = (cbTotal - SIZE_ITEMID_TERMINATOR); // Set the size of the ItemID (including the next ItemID as terminator)
ASSERT(cbData <= sizeof(*pfi)); // Don't let me copy too much.
CopyMemory(pbData, pfi, cbDataFirst);
CopyMemory((pbData + cbDataFirst), &(pfi->wzDisplayName), ((cchSizeOfDispName + 1) * sizeof(WCHAR)));
pIDTerminator[0] = 0; // Terminate the next ID.
// TraceMsg(TF_FTPURL_UTILS, "FtpItemID_Alloc(\"%ls\") dwIDType=%#08lx, dwAttributes=%#08lx", pfi->wzDisplayName, pfi->dwIDType, pfi->dwAttributes);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -