📄 fileserver.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "SMB_Globals.h"
#include "FileServer.h"
#include "Utils.h"
#include "SMBErrors.h"
#include "ShareInfo.h"
#include "RAPI.h"
#include "Cracker.h"
#include "ConnectionManager.h"
#include "SMBCommands.h"
#include "SMBPackets.h"
#include "PC_NET_PROG.h"
using namespace SMB_FILE;
ClassPoolAllocator<10, FileObject> FileObjectAllocator;
extern VOID SendSMBResponse(SMB_PACKET *pSMB, UINT uiUsed, DWORD dwErr);
//
// From CIFS9F.DOC section 3.12
WORD
Win32AttributeToDos(DWORD attributes)
{
WORD attr = 0;
if (attributes & FILE_ATTRIBUTE_READONLY)
attr |= 0x1;
if (attributes & FILE_ATTRIBUTE_HIDDEN)
attr |= 0x2;
if (attributes & FILE_ATTRIBUTE_SYSTEM)
attr |= 0x4;
if (attributes & FILE_ATTRIBUTE_DIRECTORY)
attr |= 0x10;
if (attributes & FILE_ATTRIBUTE_ARCHIVE)
attr |= 0x20;
if (attributes & FILE_ATTRIBUTE_NORMAL)
attr |= 0x80;
if (attributes & FILE_ATTRIBUTE_TEMPORARY)
attr |= 0x100;
if (attributes & FILE_FLAG_WRITE_THROUGH)
attr |= 0x80000000;
return attr;
}
//
// From CIFS9F.DOC section 3.12
WORD
DosAttributeToWin32(DWORD attributes)
{
WORD attr = 0;
if (attributes & 0x1)
attr |= FILE_ATTRIBUTE_READONLY;
if (attributes & 0x2)
attr |= FILE_ATTRIBUTE_HIDDEN;
if (attributes & 0x4)
attr |= FILE_ATTRIBUTE_SYSTEM;
if (attributes & 0x10)
attr |= FILE_ATTRIBUTE_DIRECTORY;
if (attributes & 0x20)
attr |= FILE_ATTRIBUTE_ARCHIVE;
if (attributes & 0x80)
attr |= FILE_ATTRIBUTE_NORMAL;
if (attributes & 0x100)
attr |= FILE_ATTRIBUTE_TEMPORARY;
if (attributes & 0x80000000)
attr |= FILE_FLAG_WRITE_THROUGH;
return attr;
}
//
// Util to return TRUE if the passed thing is a directory, FALSE if not
HRESULT IsDirectory(const WCHAR *pFile, BOOL *fStatus, BOOL *fExists=NULL)
{
//#error use GetFileAttributes
WIN32_FIND_DATA dta;
BOOL fIsDir = FALSE;
HRESULT hr = E_FAIL;
StringConverter CheckFile;
if(NULL == pFile) {
ASSERT(FALSE);
hr = E_INVALIDARG;
goto Done;
}
//
// If there is a trailing \ remove it
// NOTE: that we will switch out buffers to prevent mods to the calling buffer
if('\\' == pFile[wcslen(pFile)-1]) {
WCHAR *pTemp;
if(FAILED(hr = CheckFile.append(pFile))) {
goto Done;
}
pTemp = CheckFile.GetUnsafeString();
pTemp[wcslen(pTemp)-1] = NULL;
pFile = pTemp;
}
HANDLE h = FindFirstFile(pFile, &dta);
if(INVALID_HANDLE_VALUE == h) {
if(fExists) {
*fExists = FALSE;
}
hr = S_OK;
goto Done;
}
FindClose(h);
//
// Figure out what the file/dir is
if(dta.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
fIsDir = TRUE;
}
//
// Success
hr = S_OK;
if(fExists) {
*fExists = TRUE;
}
Done:
*fStatus = fIsDir;
return hr;
}
//
// Util to get a file time w/o having a handle
HRESULT GetFileTimesFromFileName(const WCHAR *pFile, FILETIME *pCreation, FILETIME *pAccess, FILETIME *pWrite)
{
WIN32_FIND_DATA dta;
BOOL fIsDir = FALSE;
HRESULT hr = E_FAIL;
HANDLE h = FindFirstFile(pFile, &dta);
if(INVALID_HANDLE_VALUE == h) {
goto Done;
}
FindClose(h);
if(NULL != pCreation) {
*pCreation = dta.ftCreationTime;
}
if(NULL != pAccess) {
*pAccess = dta.ftLastAccessTime;
}
if(NULL != pWrite) {
*pWrite = dta.ftLastWriteTime;
}
//
// Success
hr = S_OK;
Done:
return hr;
}
DWORD SMB_Trans2_Query_FS_Information(SMB_COM_TRANSACTION2_CLIENT_REQUEST *pRequest,
StringTokenizer *pTokenizer,
RAPIBuilder *pRAPIBuilder,
SMB_COM_TRANSACTION2_SERVER_RESPONSE *pResponse,
USHORT usTID,
SMB_PACKET *pSMB)
{
WORD wLevel;
DWORD dwRet;
ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
BYTE *pLabel = NULL;
//
// 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);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
if(FAILED(pTokenizer->GetWORD(&wLevel))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- not enough memory in request -- sending back request for more"));
goto Error;
}
switch(wLevel) {
case SMB_INFO_ALLOCATION: //0x01
{
SMB_QUERY_INFO_ALLOCATION_SERVER_RESPONSE *pAllocResponse;
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_QUERY_INFO_ALLOCATION_SERVER_RESPONSE), (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
pAllocResponse->idFileSystem = 0; //we dont have a filesysem ID
pAllocResponse->cSectorUnit = 32768;
pAllocResponse->cUnit = (ULONG)(NumberBytes.QuadPart / 32768);
pAllocResponse->cUnitAvail = (ULONG)(FreeToCaller.QuadPart / 32768);
pAllocResponse->cbSector = 1;
break;
}
break;
case SMB_QUERY_FS_ATTRIBUTE_INFO: //0x105
{
StringConverter Label;
UINT uiLabelLen;
BYTE *pLabelInPacket;
SMB_QUERY_FS_ATTRIBUTE_INFO_SERVER_RESPONSE *pAttrResponse;
if(FAILED(Label.append(L"FAT"))) {
goto Error;
}
if(NULL == (pLabel = Label.NewSTRING(&uiLabelLen, pMyConnection->SupportsUnicode(pSMB->pInSMB)))) {
goto Error;
}
//
// Reserve memory
if(FAILED(pRAPIBuilder->ReserveParams(0, (BYTE**)&pAttrResponse))) {
goto Error;
}
if(FAILED(pRAPIBuilder->ReserveBlock(sizeof(SMB_QUERY_FS_ATTRIBUTE_INFO_SERVER_RESPONSE), (BYTE**)&pAttrResponse))) {
goto Error;
}
if(FAILED(pRAPIBuilder->ReserveBlock(uiLabelLen, (BYTE**)&pLabelInPacket))) {
goto Error;
}
pAttrResponse->FileSystemAttributes = 0x20 | 0x03;
pAttrResponse->MaxFileNameComponent = 0xFF;
pAttrResponse->NumCharsInLabel = uiLabelLen;
memcpy(pLabelInPacket, pLabel, uiLabelLen);
break;
}
case SMB_INFO_VOLUME: //0x02
{
SMB_INFO_VOLUME_SERVER_RESPONSE *pVolResponse;
if(FAILED(pRAPIBuilder->ReserveParams(0, (BYTE**)&pVolResponse))) {
goto Error;
}
if(FAILED(pRAPIBuilder->ReserveBlock(sizeof(SMB_INFO_VOLUME_SERVER_RESPONSE), (BYTE**)&pVolResponse))) {
goto Error;
}
pVolResponse->ulVolumeSerialNumber = 0x00000000;
pVolResponse->NumCharsInLabel= 0;
break;
}
case SMB_QUERY_FS_VOLUME_INFO: //0x0102
{
SMB_QUERY_FS_VOLUME_INFO_SERVER_RESPONSE *pVolResponse = NULL;
SMB_QUERY_FS_VOLUME_INFO_SERVER_RESPONSE VolResponse;
BYTE *pLabelInPacket = NULL;
UINT uiLabelLen = 0;
StringConverter Label;
if(FAILED(Label.append(L""))) {
goto Error;
}
if(NULL == (pLabel = Label.NewSTRING(&uiLabelLen, pMyConnection->SupportsUnicode(pSMB->pInSMB)))) {
goto Error;
}
if(FAILED(pRAPIBuilder->ReserveParams(0, (BYTE**)&pVolResponse))) {
goto Error;
}
if(FAILED(pRAPIBuilder->ReserveBlock(sizeof(SMB_QUERY_FS_VOLUME_INFO_SERVER_RESPONSE), (BYTE**)&pVolResponse))) {
goto Error;
}
if(FAILED(pRAPIBuilder->ReserveBlock(uiLabelLen, (BYTE**)&pLabelInPacket))) {
goto Error;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -