📄 fileserver.cpp
字号:
TRACEMSG(ZONE_ERROR, (L"SMBSRV: Error -- not enough memory for find first 2 in trans2"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Find our connection state
if(!(pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_INFO_ALLOCATION: -- cant find connection 0x%x!", pSMB->ulConnectionID));
ASSERT(FALSE);
TRACEMSG(ZONE_ERROR, (L"SMBSRV: Error -- trans2 had name but it was invalid"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Find a share state
if(FAILED(hr = pMyConnection->FindTIDState(usTid, pTIDState, SEC_READ)) || !pTIDState) {
if(E_ACCESSDENIED == hr) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- dont have permissions!!"));
dwRet = ERROR_CODE(STATUS_ACCESS_DENIED);
} else {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- couldnt find share state!!"));
dwRet = ERROR_CODE(STATUS_INVALID_HANDLE);
}
goto Done;
}
//
// Build up a search string
// BUGBUG: check to make sure we dont get .. or / etc here!! for security
if(FAILED(SearchString.append(pTIDState->GetShare()->GetDirectoryName()))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- couldnt build search string!!"));
dwRet = ERROR_CODE(STATUS_INVALID_HANDLE);
goto Done;
}
fUsingUnicode = pMyConnection->SupportsUnicode(pSMB->pInSMB, SMB_COM_TRANSACTION2, TRANS2_FIND_FIRST2);
if(TRUE == fUsingUnicode) {
//
// Get the file name from the tokenizer
WCHAR *pFileName;
if(FAILED(pTokenizer->GetUnicodeString(&pFileName))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: Error -- trans2 had name but it was invalid"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Put in a \ if its not already there
if('\\' != pFileName[0]) {
if(FAILED(SearchString.append("\\"))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: Error -- trans2 had name but it was invalid"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
}
//
// Append the filename
if(FAILED(SearchString.append(pFileName))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- couldnt build search string!!"));
dwRet = ERROR_CODE(STATUS_INVALID_HANDLE);
goto Done;
}
} else {
//
// Get the file name from the tokenizer
CHAR *pFileName;
if(FAILED(pTokenizer->GetString(&pFileName))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: Error -- trans2 had name but it was invalid"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Put in a \ if its not already there
if('\\' != pFileName[0]) {
if(FAILED(SearchString.append("\\"))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: Error -- trans2 had name but it was invalid"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
}
//
// And append the filename
if(FAILED(SearchString.append(pFileName))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- couldnt build search string!!"));
dwRet = ERROR_CODE(STATUS_INVALID_HANDLE);
goto Done;
}
}
//
// Fill out the find first2 response structure with meaningful data
pffResponse->Sid = 0;
pffResponse->SearchCount = 0;
pffResponse->EndOfSearch = 1;
pffResponse->EaErrorOffset = 0;
pffResponse->LastNameOffset = 0;
//
// Fill out the TRANS2 response structure
pResponse->WordCount = 10;
//
// We wont be alligned if we dont make a gap
MYRAPIBuilder.MakeParamByteGap(sizeof(DWORD) - ((UINT)MYRAPIBuilder.DataPtr() % sizeof(DWORD)));
ASSERT(0 == (UINT)MYRAPIBuilder.DataPtr() % 4);
//
// See what flags are used
if(0 != (pffRequest->Flags & FIND_NEXT_RETURN_RESUME_KEY)) {
uiResumeKeySize = 0;//sizeof(ULONG);
}
//
// Start searching for files....
if (SUCCEEDED(pMyConnection->CreateNewFindHandle(SearchString.GetString(), &usSID, fUsingUnicode))) {
TRACEMSG(ZONE_FILES, (L"SMB_SRV: FindFirstFile2 using SID: 0x%x", usSID));
pffResponse->Sid = usSID; //dont do this in the CreateNewFindHandle b/c of alignment
do {
WIN32_FIND_DATA *pwfd = NULL;
if(FAILED(pMyConnection->NextFile(pffResponse->Sid, &pwfd))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- ActiveConnection::NextFile failed!"));
break;
}
//
// See what information level the client wants
switch(pffRequest->InformationLevel) {
case SMB_INFO_STANDARD:
{
StringConverter FileName;
UINT uiFileBlobSize = 0;
BYTE *pNewBlock = NULL;
BYTE *pFileBlob = NULL;
SMB_FIND_FILE_STANDARD_INFO_STRUCT *pFileStruct = NULL;
if(FAILED(FileName.append(pwfd->cFileName))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- not enough memory (OOM) -- failing request"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Get back a STRING
if(NULL == (pFileBlob = FileName.NewSTRING(&uiFileBlobSize, fUsingUnicode))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- not enough memory (OOM) -- failing request"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// If we cant reserve enough memory for this block we need to start up a
// FindNext setup
if(FAILED(MYRAPIBuilder.ReserveBlock(uiResumeKeySize + uiFileBlobSize + sizeof(SMB_FIND_FILE_STANDARD_INFO_STRUCT), (BYTE**)&pFileStruct))) {
dwRet = 0;
pffResponse->EndOfSearch = 0;
LocalFree(pFileBlob);
goto SendOK;
}
//
// Set a bogus resume key value
if(0 != uiResumeKeySize) {
ULONG *ulVal = (ULONG *)pFileStruct;
ASSERT(sizeof(ULONG) == uiResumeKeySize);
*ulVal = 0;
pFileStruct = (SMB_FIND_FILE_STANDARD_INFO_STRUCT *)(((BYTE *)pFileStruct) + uiResumeKeySize);
}
pNewBlock = (BYTE *)(pFileStruct + 1);
SMB_DATE smbDate;
SMB_TIME smbTime;
if(FAILED(FileTimeToSMBTime(&pwfd->ftCreationTime, &smbTime, &smbDate))) {
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
pFileStruct->CreationDate = smbDate;
pFileStruct->CreationTime = smbTime;
if(FAILED(FileTimeToSMBTime(&pwfd->ftLastAccessTime, &smbTime, &smbDate))) {
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
pFileStruct->LastAccessDate = smbDate;
pFileStruct->LastAccessTime = smbTime;
if(FAILED(FileTimeToSMBTime(&pwfd->ftLastWriteTime, &smbTime, &smbDate))) {
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
pFileStruct->LastWriteDate = smbDate;
pFileStruct->LastWriteTime = smbTime;
pFileStruct->DataSize = pwfd->nFileSizeLow;
pFileStruct->AllocationSize = 0;
pFileStruct->Attributes = Win32AttributeToDos(pwfd->dwFileAttributes);
pFileStruct->FileNameLen = uiFileBlobSize;
memcpy(pNewBlock, pFileBlob, uiFileBlobSize);
LocalFree(pFileBlob);
//
// Since we've successfully made a record, increase the search
// count
pffResponse->SearchCount ++;
break;
}
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
{
StringConverter FileName;
UINT uiFileBlobSize = 0;
BYTE *pNewBlock = NULL;
BYTE *pFileBlob = NULL;
SMB_FIND_FILE_BOTH_DIRECTORY_INFO_STRUCT *pFileStruct = NULL;
if(FAILED(FileName.append(pwfd->cFileName))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- not enough memory (OOM) -- failing request"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Get back a STRING
if(NULL == (pFileBlob = FileName.NewSTRING(&uiFileBlobSize, fUsingUnicode))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- not enough memory (OOM) -- failing request"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// If we cant reserve enough memory for this block we need to start up a
// FindNext setup
if(FAILED(MYRAPIBuilder.ReserveBlock(uiFileBlobSize + sizeof(SMB_FIND_FILE_BOTH_DIRECTORY_INFO_STRUCT), (BYTE**)&pFileStruct, sizeof(DWORD)))) {
dwRet = 0;
pffResponse->EndOfSearch = 0;
LocalFree(pFileBlob);
goto SendOK;
}
pNewBlock = (BYTE *)(pFileStruct + 1);
pFileStruct->FileIndex = 0;
pFileStruct->NextEntryOffset = 0;
if(pPrevFile)
pPrevFile->NextEntryOffset = (UINT)pFileStruct - (UINT)pPrevFile;
pFileStruct->CreationTime.LowPart = pwfd->ftCreationTime.dwLowDateTime;
pFileStruct->CreationTime.HighPart = pwfd->ftCreationTime.dwHighDateTime;
pFileStruct->LastAccessTime.LowPart = pwfd->ftLastAccessTime.dwLowDateTime;
pFileStruct->LastAccessTime.HighPart = pwfd->ftLastAccessTime.dwHighDateTime;
pFileStruct->LastWriteTime.LowPart = pwfd->ftLastWriteTime.dwLowDateTime;
pFileStruct->LastWriteTime.HighPart = pwfd->ftLastWriteTime.dwHighDateTime;
pFileStruct->ChangeTime.LowPart = pwfd->ftLastWriteTime.dwLowDateTime;
pFileStruct->ChangeTime.HighPart = pwfd->ftLastWriteTime.dwHighDateTime;
pFileStruct->EndOfFile.LowPart = pwfd->nFileSizeLow;
pFileStruct->EndOfFile.HighPart = pwfd->nFileSizeHigh;
pFileStruct->ExtFileAttributes = Win32AttributeToDos(pwfd->dwFileAttributes);
pFileStruct->FileNameLength = uiFileBlobSize;
pFileStruct->EaSize = 0;
pFileStruct->ShortNameLength = 0;
memset(pFileStruct->ShortName, 0, sizeof(pFileStruct->ShortName));
memcpy(pNewBlock, pFileBlob, uiFileBlobSize);
LocalFree(pFileBlob);
//
// Since we've successfully made a record, increase the search
// count
pffResponse->SearchCount ++;
pPrevFile = pFileStruct;
break;
}
default:
ASSERT(FALSE); //not supported!!
break;
}
} while (SUCCEEDED(pMyConnection->AdvanceToNextFile(pffResponse->Sid)));
//
// If we get here, yippie! we can fit the entire search into one packet!
// just close up shop
pMyConnection->CloseFindHandle(pffResponse->Sid);
pffResponse->Sid = 0;
}else {
TRACEMSG(ZONE_FILES, (L"SMB_FILE: searching for %s failed! -- file not found",SearchString.GetString()));
SMB_COM_GENERIC_RESPONSE *pGenricResponse = (SMB_COM_GENERIC_RESPONSE *)(pResponse);
pGenricResponse->ByteCount = 0;
pGenricResponse->WordCount = 0;
*puiUsed = sizeof(SMB_COM_GENERIC_RESPONSE);
dwRet = ERROR_CODE(STATUS_NO_SUCH_FILE);
goto Done;
}
SendOK:
dwRet = 0;
pResponse->WordCount = (sizeof(SMB_COM_TRANSACTION2_SERVER_RESPONSE) - 3) / sizeof(WORD);
pResponse->TotalParameterCount = MYRAPIBuilder.ParamBytesUsed();
pResponse->TotalDataCount = MYRAPIBuilder.DataBytesUsed();
pResponse->Reserved = 0;
pResponse->ParameterCount = MYRAPIBuilder.ParamBytesUsed();
pResponse->ParameterOffset = MYRAPIBuilder.ParamOffset((BYTE *)_pRawResponse->pSMBHeader);
pResponse->ParameterDisplacement = 0;
pResponse->DataCount = MYRAPIBuilder.DataBytesUsed();
pResponse->DataOffset = MYRAPIBuilder.DataOffset((BYTE *)_pRawResponse->pSMBHeader);
pResponse
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -