📄 fileserver.cpp
字号:
VolResponse.VolumeCreationTime.QuadPart = 0;
VolResponse.VolumeSerialNumber = 0x00000000;
VolResponse.LengthOfLabel = Label.Length();
VolResponse.Reserved1 = 0;
VolResponse.Reserved2 = 0;
memcpy(pVolResponse, &VolResponse, sizeof(SMB_QUERY_FS_VOLUME_INFO_SERVER_RESPONSE));
memcpy(pLabelInPacket, pLabel, uiLabelLen);
break;
}
case SMB_QUERY_DISK_ALLOCATION_NT: //0x0103
{
SMB_DISK_ALLOCATION_NT *pAllocResponse;
SMB_DISK_ALLOCATION_NT AllocResponse;
ce::smart_ptr<TIDState> pTIDState = NULL;
ULARGE_INTEGER FreeToCaller;
ULARGE_INTEGER NumberBytes;
ULARGE_INTEGER TotalFree;
if(FAILED(pRAPIBuilder->ReserveParams(0, (BYTE**)&pAllocResponse)))
goto Error;
if(FAILED(pRAPIBuilder->ReserveBlock(sizeof(SMB_DISK_ALLOCATION_NT), (BYTE**)&pAllocResponse)))
goto Error;
//
// Find a share state
if(FAILED(pMyConnection->FindTIDState(usTID, pTIDState, SEC_READ)) || !pTIDState)
{
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_INFO_ALLOCATION -- couldnt find share state!!"));
goto Error;
}
//
// Get the amount of free disk space
if(0 == GetDiskFreeSpaceEx(pTIDState->GetShare()->GetDirectoryName(),
&FreeToCaller,
&NumberBytes,
&TotalFree)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_INFO_ALLOCATION -- couldnt get free disk space!!"));
goto Error;
}
//
// Fill in parameters
AllocResponse.TotalAllocationUnits.QuadPart = NumberBytes.QuadPart / (512 * 64);
AllocResponse.AvailableAllocationUnits.QuadPart = FreeToCaller.QuadPart / (512 * 64);
AllocResponse.BlocksPerUnit = 64;
AllocResponse.BytesPerBlock = 512;
memcpy(pAllocResponse, &AllocResponse, sizeof(SMB_DISK_ALLOCATION_NT));
break;
}
default:
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- unknown Trans2 query for SMB_Trans2_Query_FS_Information %d", wLevel));
ASSERT(FALSE);
goto Error;
}
dwRet = 0;
goto Done;
Error:
dwRet = ERROR_CODE(STATUS_NOT_SUPPORTED);
Done:
if(NULL != pLabel) {
LocalFree(pLabel);
}
return dwRet;
}
DWORD SMB_Trans2_Set_File_Information(USHORT usTid,
SMB_COM_TRANSACTION2_CLIENT_REQUEST *pRequest,
StringTokenizer *pTokenizer,
SMB_PROCESS_CMD *_pRawRequest,
SMB_PROCESS_CMD *_pRawResponse,
SMB_COM_TRANSACTION2_SERVER_RESPONSE *pResponse,
SMB_PACKET *pSMB,
UINT *puiUsed)
{
WORD wLevel;
WORD wReserved;
USHORT usFID;
DWORD dwRet;
ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
UINT uiFileNameLen = 0;
BYTE *pFileName = NULL;
ce::smart_ptr<TIDState> pTIDState = NULL;
StringTokenizer DataTokenizer;
BYTE *pTransData = NULL;
HRESULT hr;
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_Set_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_Set_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_Set_File_Information -- not enough memory in request -- sending back request for more"));
goto Error;
}
if(FAILED(pTokenizer->GetWORD(&wReserved))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- not enough memory in request -- sending back request for more"));
goto Error;
}
pTransData = (BYTE *)_pRawRequest->pSMBHeader + pRequest->DataOffset;
DataTokenizer.Reset(pTransData, pRequest->DataCount);
//
// Find a share state
if(FAILED(hr = pMyConnection->FindTIDState(usTid, pTIDState, SEC_WRITE)) || !pTIDState) {
if(E_ACCESSDENIED == hr) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- access denied!!"));
dwRet = ERROR_CODE(STATUS_NETWORK_ACCESS_DENIED);
goto Done;
} else {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- couldnt find share state!!"));
goto Error;
}
}
switch(wLevel) {
case SMB_SET_FILE_BASIC_INFO: //0x0101
{
BYTE *pFileTemp = NULL;
SMB_FILE_BASIC_INFO FileInfo;
ce::smart_ptr<SMBFileStream> pStream = NULL;
FILETIME Creation;
FILETIME Access;
FILETIME Write;
FILETIME *pCreation = NULL;
FILETIME *pAccess = NULL;
FILETIME *pWrite = NULL;
USHORT usAttributes;
if(FAILED(DataTokenizer.GetByteArray((BYTE **)&pFileTemp, sizeof(SMB_FILE_BASIC_INFO)))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- get EOF Info!!"));
goto Error;
}
memcpy(&FileInfo, pFileTemp, sizeof(SMB_FILE_BASIC_INFO));
if(!(usAttributes = DosAttributeToWin32(FileInfo.Attributes))) {
usAttributes = FILE_ATTRIBUTE_NORMAL;
}
if(0!=FileInfo.CreationTime.QuadPart) {
pCreation = &Creation;
Creation.dwLowDateTime = FileInfo.CreationTime.LowPart;
Creation.dwHighDateTime = FileInfo.CreationTime.HighPart;
}
if(0!=FileInfo.LastAccessTime.QuadPart) {
pAccess = &Access;
Access.dwLowDateTime = FileInfo.LastAccessTime.LowPart;
Access.dwHighDateTime = FileInfo.LastAccessTime.HighPart;
}
if(0!=FileInfo.LastWriteTime.QuadPart) {
pWrite = &Write;
Write.dwLowDateTime = FileInfo.LastWriteTime.LowPart;
Write.dwHighDateTime = FileInfo.LastWriteTime.HighPart;
}
//
// Set the actual file time
if(FAILED(hr = pTIDState->SetFileTime(usFID, pCreation, pAccess, pWrite))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- couldnt set filetime!!"));
dwRet = ConvertHRToError(hr, pSMB);
goto Done;
}
if(FAILED(pTIDState->FindFileStream(usFID, pStream))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- couldnt get file stream!!"));
goto Error;
}
ASSERT(usAttributes);
if(0 == SetFileAttributes(pStream->GetFileName(), usAttributes)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- set file attributes %d -- GLE:%d!!",usAttributes, GetLastError()));
goto Error;
}
break;
}
case SMB_SET_FILE_DISPOSITION_INFO: //0x0102
{
SMB_FILE_DISPOSITION_INFO *pFileInfo;
if(FAILED(DataTokenizer.GetByteArray((BYTE **)&pFileInfo, sizeof(SMB_FILE_DISPOSITION_INFO)))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- get EOF Info!!"));
goto Error;
}
if(TRUE == pFileInfo->FileIsDeleted && FAILED(pTIDState->Delete(usFID))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- couldnt set EOF!!"));
goto Error;
}
break;
}
case SMB_SET_FILE_ALLOCATION_INFO: //0x0103
{
SMB_FILE_ALLOCATION_INFO *pFileInfo;
if(FAILED(DataTokenizer.GetByteArray((BYTE **)&pFileInfo, sizeof(SMB_FILE_END_OF_FILE_INFO)))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- get EOF Info!!"));
goto Error;
}
ASSERT(0 == pFileInfo->EndOfFile.HighPart);
if(FAILED(pTIDState->SetEndOfStream(usFID, pFileInfo->EndOfFile.LowPart))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- couldnt set EOF!!"));
goto Error;
}
break;
}
case SMB_SET_FILE_END_OF_FILE_INFO: //0x0104
{
SMB_FILE_END_OF_FILE_INFO *pFileInfo;
if(FAILED(DataTokenizer.GetByteArray((BYTE **)&pFileInfo, sizeof(SMB_FILE_END_OF_FILE_INFO)))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- get EOF Info!!"));
goto Error;
}
ASSERT(0 == pFileInfo->EndOfFile.HighPart);
if(FAILED(hr = pTIDState->SetEndOfStream(usFID, pFileInfo->EndOfFile.LowPart))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_Trans2_Set_File_Information -- couldnt set EOF!!"));
dwRet = ConvertHRToError(hr, pSMB);
goto Done;
}
break;
}
default:
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- unknown Trans2 query for SMB_Trans2_Set_File_Information %d", wLevel));
//
// Mark that we are using NT status codes
dwRet = ERROR_CODE(STATUS_INVALID_LEVEL);
goto Done;
}
dwRet = 0;
goto Done;
Error:
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
Done:
{
BYTE *pTempBuf = NULL;
if(SUCCEEDED(RAPI.ReserveParams(2, (BYTE**)&pTempBuf))) {
//
// We wont be alligned if we dont make a gap
while(0 != ((UINT)RAPI.DataPtr() % sizeof(DWORD)))
RAPI.MakeParamByteGap(1);
*pTempBuf = 0;
*(pTempBuf+1) = 0;
*(pTempBuf+2) = 0;
}
//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);
}
//
// return any error
return dwRet;
}
DWORD SMB_Trans2_Query_File_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;
USHORT usFID;
DWORD dwRet;
DWORD nNumberOfLinks = 0;
ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
UINT uiFileNameLen = 0;
BYTE *pFileName = NULL;
HRESULT hr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -