📄 nfsserver.cpp
字号:
HandleUintOp_1P(sock, pFileSystem, nOpCommand);
break;
case OPTYPE_SPECIAL:
switch(nOpCommand)
{
case REQUEST_GETFILESTATUS:
HandleSpecial_GetFileStatus(sock, pFileSystem);
break;
case REQUEST_FILLFILEINFO:
HandleSpecial_FillFileInfo(sock, pFileSystem);
break;
case REQUEST_TRANSFERFILECACHE:
HandleSpecial_BuildCache(sock, pFileSystem);
break;
case REQUEST_MACHINEINFO:
HandleSpecial_GetCompInfo(sock, pFileSystem);
break;
default:
// This should never happen.
ASSERT(0);
break;
}
break;
default:
// Unknown operation type; we'll just close the socket.
break;
}
// Done. Return and close the connection.
AppendComment(_T("NFSServer: Done with request"));
return;
}
int CNFSServer::GenerateNewInstanceID(UINT nClientVer, UINT &nServerVer)
{
// Create a new instance identifier and associated FileSystem.
// Protect against malicious attacks
if(m_nNumInstances > MAX_INSTANCES)
return -1;
// Pick a compatible server version. It must be no greater than the
// client version, and no greater than the current version of the server.
if(nClientVer > SERVER_VERSION)
nServerVer = SERVER_VERSION;
else
nServerVer = nClientVer;
// Allocate a new entry for the identifier.
m_nNumInstances += 1;
ASSERT(m_nNumInstances > 0);
NFS_FSEntry *pNewEntries = new NFS_FSEntry[m_nNumInstances];
if(m_pEntries)
{
// Copy the old entries into the new buffer
memcpy((void *)pNewEntries, (void *)m_pEntries,
sizeof(NFS_FSEntry) * (m_nNumInstances - 1));
// Delete the old entries
delete m_pEntries;
}
m_pEntries = pNewEntries;
// Fill the new entry.
NFS_FSEntry *pEntry = &(m_pEntries[m_nNumInstances - 1]);
pEntry->pFileSystem = new CSecureFileSystem(m_pFilter);
pEntry->bIsValid = TRUE;
pEntry->nNum = m_nNextID;
pEntry->nServerVer = nServerVer;
m_nNextID += 1;
// Clean out the buffer.
PruneIdentifiers();
// Prune changes the memory position of the entry list. Retrieve the new
// one.
pEntry = &(m_pEntries[m_nNumInstances - 1]);
return (int)pEntry->nNum;
}
CSecureFileSystem *CNFSServer::GetFileSystem(UINT nID)
{
// Find the entry with the appropriate ID and return its filesystem
NFS_FSEntry *pEntry;
for(UINT i = 0; i < m_nNumInstances; i++)
{
pEntry = &m_pEntries[i];
if(pEntry->bIsValid && (pEntry->nNum == nID))
return pEntry->pFileSystem;
}
return NULL;
}
void CNFSServer::ReleaseIdentifier(UINT nID)
{
// Find the entry with the appropriate ID and turn it off
NFS_FSEntry *pEntry;
for(UINT i = 0; i < m_nNumInstances; i++)
{
pEntry = &m_pEntries[i];
if(pEntry->bIsValid && (pEntry->nNum == nID))
{
pEntry->bIsValid = FALSE;
return;
}
}
return;
}
// Be careful: this changes the pointer to the entry list
void CNFSServer::PruneIdentifiers()
{
// Physically delete invalid entries.
UINT nNumValids = 0;
NFS_FSEntry *pEntry;
for(UINT i = 0; i < m_nNumInstances; i++)
{
pEntry = &m_pEntries[i];
if(pEntry->bIsValid)
nNumValids += 1;
}
// Don't clean the whole thing out; we want to keep pointers.
if(nNumValids == 0)
return;
// Create new buffer.
NFS_FSEntry *pNewEntries = new NFS_FSEntry[nNumValids];
// Fill the new buffer.
UINT j;
for(i = j = 0; i < m_nNumInstances; i++)
{
pEntry = &m_pEntries[i];
if(pEntry->bIsValid)
{
memcpy((void *)&pNewEntries[j], (void *)pEntry,
sizeof(NFS_FSEntry));
j += 1;
}
else
{
delete pEntry->pFileSystem;
}
}
// Delete the old buffer.
delete m_pEntries;
// Setup the new buffer.
m_pEntries = pNewEntries;
m_nNumInstances = nNumValids;
return;
}
FileCacheEntry *CNFSServer::BuildFileCache(LPCTSTR strSearch,
UINT *pnNumEntries,
CSecureFileSystem *pFileSystem)
{
BOOL bFind;
FileCacheEntry *pEntry;
int nNumEntries;
int nNumAllocs;
bFind = pFileSystem->FindFile(strSearch);
if(!bFind)
{
*pnNumEntries = 0;
return NULL;
}
// Setup the memory
nNumAllocs = 40;
nNumEntries = 0;
pEntry = new FileCacheEntry[nNumAllocs];
// Loop through all the files, building the information
while(bFind)
{
bFind = pFileSystem->FindNextFile();
// Fill the buffer
pEntry[nNumEntries].bIsHidden = pFileSystem->IsHidden();
pEntry[nNumEntries].bIsDirectory = pFileSystem->IsDirectory();
pEntry[nNumEntries].bIsDots = pFileSystem->IsDots();
CString cszPath = pFileSystem->GetFilePath();
pEntry[nNumEntries].bHasSubDir = pFileSystem->HasSubDirectory(cszPath);
ASSERT(cszPath.GetLength() <= MAX_PATH);
memcpy((void *)pEntry[nNumEntries].czFullPath,
(void *)cszPath.GetBuffer(0), sizeof(TCHAR) * (cszPath.GetLength() + 1));
CFileStatus cFileStatus;
pEntry[nNumEntries].bFileStatusResult =
pFileSystem->GetFileStatus(pEntry[nNumEntries].czFullPath,
cFileStatus);
FillTransferStruct(&(pEntry[nNumEntries].FileStatus),
cFileStatus);
// This was the old way of doing things. It caught the icon
// identifiers. We don't want to do this anymore; it may waste
// a LOT of time, and we don't use the icons on the other side.
/*
pEntry[nNumEntries].bFileInfoResult[0] =
pFileSystem->FillFileInfo(pEntry[nNumEntries].czFullPath,
&(pEntry[nNumEntries].FileInfo_LargeIcon),
SHGFI_ICON | SHGFI_LARGEICON | SHGFI_DISPLAYNAME | SHGFI_TYPENAME);
pEntry[nNumEntries].bFileInfoResult[1] =
pFileSystem->FillFileInfo(pEntry[nNumEntries].czFullPath,
&(pEntry[nNumEntries].FileInfo_SmallIcon),
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME | SHGFI_TYPENAME);
pEntry[nNumEntries].bFileInfoResult[2] =
pFileSystem->FillFileInfo(pEntry[nNumEntries].czFullPath,
&(pEntry[nNumEntries].FileInfo_OpenIcon),
SHGFI_ICON | SHGFI_OPENICON | SHGFI_DISPLAYNAME | SHGFI_TYPENAME);
*/
// Fairly wasteful in bandwidth.
pEntry[nNumEntries].bFileInfoResult[0] =
pFileSystem->FillFileInfo(pEntry[nNumEntries].czFullPath,
&(pEntry[nNumEntries].FileInfo_LargeIcon),
SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ATTRIBUTES);
pEntry[nNumEntries].bFileInfoResult[1] =
pFileSystem->FillFileInfo(pEntry[nNumEntries].czFullPath,
&(pEntry[nNumEntries].FileInfo_SmallIcon),
SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ATTRIBUTES);
pEntry[nNumEntries].bFileInfoResult[2] =
pFileSystem->FillFileInfo(pEntry[nNumEntries].czFullPath,
&(pEntry[nNumEntries].FileInfo_OpenIcon),
SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ATTRIBUTES);
// Update the buffer as necessary
nNumEntries += 1;
if(nNumEntries == nNumAllocs)
{
FileCacheEntry *pNewEntry;
nNumAllocs += 40;
pNewEntry = new FileCacheEntry[nNumAllocs];
ASSERT(pNewEntry != NULL);
memcpy((void *)pNewEntry, (void *)pEntry,
sizeof(FileCacheEntry) * (nNumAllocs - 40));
delete pEntry;
pEntry = pNewEntry;
}
}
*pnNumEntries = (UINT)nNumEntries;
if(!nNumEntries)
{
if(pEntry) delete pEntry;
pEntry = NULL;
}
return pEntry;
}
void CNFSServer::FillTransferStruct(FileStatusTransferStruct *fsTrans,
CFileStatus fileStatus)
{
ASSERT(fsTrans != NULL);
if(!fsTrans)
return;
fsTrans->m_ctime = fileStatus.m_ctime.GetTime();
fsTrans->m_mtime = fileStatus.m_mtime.GetTime();
fsTrans->m_atime = fileStatus.m_atime.GetTime();
fsTrans->m_size = fileStatus.m_size;
fsTrans->m_attribute = fileStatus.m_attribute;
memcpy((void *)fsTrans->m_szFullName,
(void *)fileStatus.m_szFullName,
MAX_PATH);
return;
}
BOOL CNFSServer::AppendComment(LPCTSTR czComment)
{
// Get the app.
COscarApp *pApp = (COscarApp *)AfxGetApp();
ASSERT(pApp);
// Check to see if the user's Network Monitor is open.
if(pApp->m_pNetworkMonitor)
{
// Insert the feedback item in the Network Monitor.
pApp->m_pNetworkMonitor->AddComment(czComment);
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -