📄 fileserver.cpp
字号:
RAPIBuilder RAPI((BYTE *)(pResponse+1),
_pRawResponse->uiDataSize-sizeof(SMB_COM_TRANSACTION2_SERVER_RESPONSE),
pRequest->MaxParameterCount,
pRequest->MaxDataCount);
//
// Find our connection state
if(!(pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information: -- cant find connection 0x%x!", pSMB->ulConnectionID));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Fetch the FID and info level
if(FAILED(pTokenizer->GetWORD(&usFID))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- not enough memory in request -- sending back request for more"));
goto Error;
}
if(FAILED(pTokenizer->GetWORD(&wLevel))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- not enough memory in request -- sending back request for more"));
goto Error;
}
switch(wLevel) {
case SMB_QUERY_FILE_EA_INFO_ID: //0x0103
{
SMB_QUERY_FILE_EA_INFO QueryResponse;
SMB_QUERY_FILE_EA_INFO *pQueryResponse = NULL;
QueryResponse.EASize = 0;
if(FAILED(RAPI.ReserveParams(0, (BYTE**)&pQueryResponse)))
goto Error;
if(FAILED(RAPI.ReserveBlock(sizeof(SMB_QUERY_FILE_EA_INFO), (BYTE**)&pQueryResponse)))
goto Error;
memcpy(pQueryResponse, &QueryResponse, sizeof(SMB_QUERY_FILE_EA_INFO));
break;
}
case SMB_QUERY_FILE_STANDARD_INFO_ID: //0x0102
{
SMB_QUERY_FILE_STANDARD_INFO QueryResponse;
SMB_QUERY_FILE_STANDARD_INFO *pQueryResponse = NULL;
ce::smart_ptr<TIDState> pTIDState = NULL;
DWORD dwFileOffset = 0;
WIN32_FIND_DATA w32FindData;
WORD attributes;
if(FAILED(RAPI.ReserveParams(0, (BYTE**)&pQueryResponse)))
goto Error;
if(FAILED(RAPI.ReserveBlock(sizeof(SMB_QUERY_FILE_STANDARD_INFO), (BYTE**)&pQueryResponse)))
goto Error;
//
// Find a share state
if(FAILED(pMyConnection->FindTIDState(usTid, pTIDState, SEC_READ)) || !pTIDState) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- couldnt find share state!!"));
goto Error;
}
if(FAILED(pTIDState->QueryFileInformation(usFID, &w32FindData, &nNumberOfLinks))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- couldnt find FID!"));
goto Error;
}
if(FAILED(hr = pTIDState->GetFileSize(usFID, &dwFileOffset))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- couldnt find share state!!"));
dwRet = ConvertHRToError(hr, pSMB);
goto ErrorSet;
}
attributes = Win32AttributeToDos(w32FindData.dwFileAttributes);
QueryResponse.AllocationSize.HighPart = 0;
QueryResponse.AllocationSize.LowPart = dwFileOffset;
QueryResponse.EndofFile.HighPart = 0;
QueryResponse.EndofFile.LowPart = dwFileOffset;
QueryResponse.NumberOfLinks = nNumberOfLinks;
QueryResponse.DeletePending = FALSE;
QueryResponse.Directory = (attributes & FILE_ATTRIBUTE_DIRECTORY)?TRUE:FALSE;
memcpy(pQueryResponse, &QueryResponse, sizeof(SMB_QUERY_FILE_STANDARD_INFO));
break;
}
case SMB_QUERY_FILE_ALL_INFO_ID: //0x0107
{
SMB_QUERY_FILE_ALL_INFO QueryResponse;
SMB_QUERY_FILE_ALL_INFO *pQueryResponse = NULL;
WIN32_FIND_DATA w32FindData;
WORD attributes;
ce::smart_ptr<TIDState> pTIDState = NULL;
ULONG ulFileOffset = 0;
ce::smart_ptr<FileObject> pMyFile = NULL;
if(FAILED(RAPI.ReserveParams(0, (BYTE**)&pQueryResponse)))
goto Error;
if(FAILED(RAPI.ReserveBlock(sizeof(SMB_QUERY_FILE_ALL_INFO), (BYTE**)&pQueryResponse)))
goto Error;
//
// Find a share state
if(FAILED(pMyConnection->FindTIDState(usTid, pTIDState, SEC_READ)) || !pTIDState) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- couldnt find share state!!"));
goto Error;
}
if(FAILED(hr = pTIDState->QueryFileInformation(usFID, &w32FindData, &nNumberOfLinks))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- couldnt find FID!"));
dwRet = ConvertHRToError(hr, pSMB);
goto ErrorSet;
}
if(FAILED(pTIDState->SetFilePointer(usFID, 0, 1, &ulFileOffset))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- couldnt get file offset for FID: %d!", usFID));
ulFileOffset = 0;
}
if(SUCCEEDED(SMB_Globals::g_pAbstractFileSystem->FindFile(usFID, pMyFile)) && !pMyFile) {
StringConverter myString;
myString.append(pMyFile->FileName());
pFileName = myString.NewSTRING(&uiFileNameLen, pMyConnection->SupportsUnicode(pSMB->pInSMB));
}
if(NULL == pFileName) {
StringConverter myString;
myString.append(L"");
pFileName = myString.NewSTRING(&uiFileNameLen, pMyConnection->SupportsUnicode(pSMB->pInSMB));
}
attributes = Win32AttributeToDos(w32FindData.dwFileAttributes);
QueryResponse.CreationTime.LowPart = w32FindData.ftCreationTime.dwLowDateTime;
QueryResponse.CreationTime.HighPart = w32FindData.ftCreationTime.dwHighDateTime;
QueryResponse.LastAccessTime.LowPart = w32FindData.ftLastAccessTime.dwLowDateTime;
QueryResponse.LastAccessTime.HighPart = w32FindData.ftLastAccessTime.dwHighDateTime;
QueryResponse.LastWriteTime.LowPart = w32FindData.ftLastWriteTime.dwLowDateTime;
QueryResponse.LastWriteTime.HighPart = w32FindData.ftLastWriteTime.dwHighDateTime;
QueryResponse.ChangeTime.LowPart = w32FindData.ftLastWriteTime.dwLowDateTime;
QueryResponse.ChangeTime.HighPart = w32FindData.ftLastWriteTime.dwHighDateTime;
QueryResponse.Attributes = attributes;
QueryResponse.AllocationSize.HighPart = w32FindData.nFileSizeHigh;
QueryResponse.AllocationSize.LowPart = w32FindData.nFileSizeLow;
QueryResponse.EndOfFile.QuadPart = QueryResponse.AllocationSize.QuadPart;
QueryResponse.NumberOfLinks = nNumberOfLinks;
//ULONG NumberOfLinks;
QueryResponse.DeletePending = FALSE;
QueryResponse.Directory = (attributes & FILE_ATTRIBUTE_DIRECTORY)?TRUE:FALSE;
QueryResponse.Index_Num.QuadPart = 0;
QueryResponse.EASize = 0; //we dont support extended attributes
QueryResponse.AccessFlags = QFI_FILE_READ_DATA |
QFI_FILE_WRITE_DATA |
QFI_FILE_APPEND_DATA |
QFI_FILE_READ_ATTRIBUTES |
QFI_FILE_WRITE_ATTRIBUTES |
QFI_DELETE;
QueryResponse.IndexNumber.QuadPart = 0;
QueryResponse.CurrentByteOffset.QuadPart = ulFileOffset;
QueryResponse.Mode = QFI_FILE_WRITE_THROUGH;
QueryResponse.AlignmentRequirement = 0;
QueryResponse.FileNameLength = uiFileNameLen;
memcpy(pQueryResponse, &QueryResponse, sizeof(SMB_QUERY_FILE_ALL_INFO));
BYTE *pFileInBlob = NULL;
if(FAILED(RAPI.ReserveBlock(uiFileNameLen, (BYTE**)&pFileInBlob)))
goto Error;
ASSERT(pFileInBlob == (BYTE*)(pQueryResponse+1));
memcpy(pFileInBlob, pFileName, uiFileNameLen);
break;
}
case SMB_QUERY_FILE_BASIC_INFO_ID: //0x0101
{
SMB_FILE_BASIC_INFO *pQueryResponse = NULL;
SMB_FILE_BASIC_INFO QueryResponse;
WIN32_FIND_DATA w32FindData;
WORD attributes;
ce::smart_ptr<TIDState> pTIDState = NULL;
if(FAILED(RAPI.ReserveParams(0, (BYTE**)&pQueryResponse)))
goto Error;
if(FAILED(RAPI.ReserveBlock(sizeof(SMB_FILE_BASIC_INFO), (BYTE**)&pQueryResponse)))
goto Error;
//
// Find a share state and then get the file info
if(FAILED(pMyConnection->FindTIDState(usTid, pTIDState, SEC_READ)) || !pTIDState) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- couldnt find share state!!"));
goto Error;
}
if(FAILED(hr = pTIDState->QueryFileInformation(usFID, &w32FindData, &nNumberOfLinks))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_File_Information -- couldnt find FID!"));
dwRet = ConvertHRToError(hr, pSMB);
goto ErrorSet;
}
attributes = Win32AttributeToDos(w32FindData.dwFileAttributes);
QueryResponse.CreationTime.LowPart = w32FindData.ftCreationTime.dwLowDateTime;
QueryResponse.CreationTime.HighPart = w32FindData.ftCreationTime.dwHighDateTime;
QueryResponse.LastAccessTime.LowPart = w32FindData.ftLastAccessTime.dwLowDateTime;
QueryResponse.LastAccessTime.HighPart = w32FindData.ftLastAccessTime.dwHighDateTime;
QueryResponse.LastWriteTime.LowPart = w32FindData.ftLastWriteTime.dwLowDateTime;
QueryResponse.LastWriteTime.HighPart = w32FindData.ftLastWriteTime.dwHighDateTime;
QueryResponse.ChangeTime.LowPart = w32FindData.ftLastWriteTime.dwLowDateTime;
QueryResponse.ChangeTime.HighPart = w32FindData.ftLastWriteTime.dwHighDateTime;
QueryResponse.Attributes = attributes;
memcpy(pQueryResponse, &QueryResponse, sizeof(SMB_FILE_BASIC_INFO));
dwRet = 0;
break;
}
case SMB_QUERY_FILE_STREAM_INFO_ID: //0x0109
{
SMB_QUERY_FILE_STREAM_INFO QueryResponse;
SMB_QUERY_FILE_STREAM_INFO *pQueryResponse = NULL;
if(FAILED(RAPI.ReserveParams(0, (BYTE**)&pQueryResponse)))
goto Error;
if(FAILED(RAPI.ReserveBlock(sizeof(SMB_QUERY_FILE_STREAM_INFO), (BYTE**)&pQueryResponse)))
goto Error;
memset(&QueryResponse, 0, sizeof(SMB_QUERY_FILE_STREAM_INFO));
memcpy(pQueryResponse, &QueryResponse, sizeof(SMB_QUERY_FILE_STREAM_INFO));
break;
}
default:
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- unknown Trans2 query for SMB_Trans2_Query_File_Information %d", wLevel));
//
// Mark that we are using NT status codes
dwRet = ERROR_CODE(STATUS_INVALID_LEVEL);
goto ErrorSet;
}
dwRet = 0;
goto Done;
Error:
dwRet = ERROR_CODE(STATUS_INVALID_LEVEL);
ErrorSet:
{
BYTE *pTempBuf = (BYTE *)(pResponse+1);
*pTempBuf = 0;
*(pTempBuf+1) = 0;
*(pTempBuf+2) = 0;
*puiUsed = 3;
ASSERT(0 != dwRet);
}
Done:
//
// On error just return that error
if(0 != dwRet)
return dwRet;
//fill out response SMB
memset(pResponse, 0, sizeof(SMB_COM_TRANSACTION2_SERVER_RESPONSE));
//word count is 3 bytes (1=WordCount 2=ByteCount) less than the response
pResponse->WordCount = (sizeof(SMB_COM_TRANSACTION2_SERVER_RESPONSE) - 3) / sizeof(WORD);
pResponse->TotalParameterCount = RAPI.ParamBytesUsed();
pResponse->TotalDataCount = RAPI.DataBytesUsed();
pResponse->ParameterCount = RAPI.ParamBytesUsed();
pResponse->ParameterOffset = RAPI.ParamOffset((BYTE *)_pRawResponse->pSMBHeader);
pResponse->ParameterDisplacement = 0;
pResponse->DataCount = RAPI.DataBytesUsed();
pResponse->DataOffset = RAPI.DataOffset((BYTE *)_pRawResponse->pSMBHeader);
pResponse->DataDisplacement = 0;
pResponse->SetupCount = 0;
pResponse->ByteCount = RAPI.TotalBytesUsed();
ASSERT(10 == pResponse->WordCount);
//set the number of bytes we used
*puiUsed = RAPI.TotalBytesUsed() + sizeof(SMB_COM_TRANSACTION2_SERVER_RESPONSE);
if(NULL != pFileName) {
LocalFree(pFileName);
}
return dwRet;
}
DWORD SMB_Trans2_Query_Path_Information(USHORT usTid,
SMB_COM_TRANSACTION2_CLIENT_REQUEST *pRequest,
StringTokenizer *pTokenizer,
SMB_PROCESS_CMD *_pRawResponse,
SMB_COM_TRANSACTION2_SERVER_RESPONSE *pResponse,
SMB_PACKET *pSMB,
UINT *puiUsed)
{
WORD wLevel;
ULONG ulReserved;
DWORD dwRet;
ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
RAPIBuilder RAPI((BYTE *)(pResponse+1),
_pRawResponse->uiDataSize-sizeof(SMB_COM_TRANSACTION2_SERVER_RESPONSE),
pRequest->MaxParameterCount,
pRequest->MaxDataCount);
StringConverter FileName;
StringConverter FullPath;
HANDLE hFileHand = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA w32FindData;
ce::smart_ptr<TIDState> pTIDState = NULL;
//
// Find our connection state
if(!(pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_Path_Information: -- cant find connection 0x%x!", pSMB->ulConnectionID));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Fetch the info level
if(FAILED(pTokenizer->GetWORD(&wLevel))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Query_Path_Information -- not enough memory in request -- sending back request for more"));
goto Error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -