612 lines
19 KiB
C
612 lines
19 KiB
C
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
srvutil.c
|
|
|
|
Abstract:
|
|
|
|
Implements misc. smb stuff
|
|
|
|
Author:
|
|
|
|
Ahmed Mohamed (ahmedm) 1-Feb-2000
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "srv.h"
|
|
|
|
#if TRANS2_MAX_FUNCTION > 0xFF
|
|
#pragma error "TRANS2_MAX_FUNCTION > 0xFF"
|
|
#endif
|
|
|
|
typedef BOOL (*SMB_DISPATCH_FUNC)(Packet_t *);
|
|
typedef BOOL (*TRANS2_DISPATCH_FUNC)(Packet_t *, Trans2_t *);
|
|
|
|
static SMB_DISPATCH_FUNC SrvDispatchTable[0x100] = {0};
|
|
static TRANS2_DISPATCH_FUNC Trans2DispatchTable[0x100] = {0};
|
|
|
|
|
|
VOID
|
|
SrvInitDispTable();
|
|
|
|
void
|
|
SrvUtilInit(SrvCtx_t *ctx)
|
|
{
|
|
extern void Trans2Init();
|
|
|
|
SrvInitDispTable();
|
|
|
|
Trans2Init();
|
|
}
|
|
|
|
void
|
|
SrvUtilExit(SrvCtx_t *ctx)
|
|
{
|
|
// nothing to do
|
|
return;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsSmb(
|
|
LPVOID pBuffer,
|
|
DWORD nLength
|
|
)
|
|
{
|
|
PNT_SMB_HEADER pSmb = (PNT_SMB_HEADER) pBuffer;
|
|
return (pSmb && !(nLength < sizeof(NT_SMB_HEADER)) &&
|
|
(*(PULONG)pSmb->Protocol == SMB_HEADER_PROTOCOL));
|
|
}
|
|
|
|
BOOL
|
|
SrvDispatch(
|
|
Packet_t * msg
|
|
)
|
|
{
|
|
USHORT command = msg->in.command;
|
|
if (command > 0xFF) {
|
|
SrvLogError(("(command > 0xFF)\n"));
|
|
return FALSE;
|
|
}
|
|
SrvLog(("- parameter block - <0x%02x = %s>\n",
|
|
command,
|
|
SrvUnparseCommand(command)));
|
|
if (SrvDispatchTable[command])
|
|
return SrvDispatchTable[command](msg);
|
|
else {
|
|
return SrvComUnknown(msg);
|
|
}
|
|
}
|
|
|
|
// returns whether or not to conitnue
|
|
BOOL
|
|
Trans2Dispatch(
|
|
Packet_t * msg,
|
|
Trans2_t * trans
|
|
)
|
|
{
|
|
USHORT command = msg->in.command;
|
|
if (command > 0xFF) {
|
|
SrvLogError(("DOSERROR: (function > 0xFF)\n"));
|
|
SET_DOSERROR(msg, SERVER, NO_SUPPORT);
|
|
return FALSE;
|
|
}
|
|
if (command > TRANS2_MAX_FUNCTION) {
|
|
SrvLogError(("DOSERROR: (function > maximum)\n"));
|
|
SET_DOSERROR(msg, SERVER, NO_SUPPORT);
|
|
return FALSE;
|
|
}
|
|
SrvLog(("- parameter block - <0x%02x = %s>\n",
|
|
command,
|
|
SrvUnparseTrans2(command)));
|
|
if (Trans2DispatchTable[command])
|
|
return Trans2DispatchTable[command](msg, trans);
|
|
else {
|
|
return Trans2Unknown(msg, trans);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
InitSmbHeader(
|
|
Packet_t * msg
|
|
)
|
|
{
|
|
ZeroMemory(msg->out.smb, sizeof(NT_SMB_HEADER));
|
|
CopyMemory(msg->out.smb->Protocol, msg->in.smb->Protocol,
|
|
sizeof(msg->out.smb->Protocol));
|
|
msg->out.smb->Command = msg->in.smb->Command;
|
|
msg->out.smb->Flags = 0x80;
|
|
msg->out.smb->Flags2 = 1;
|
|
msg->out.smb->Pid = msg->in.smb->Pid;
|
|
msg->out.smb->Tid = msg->in.smb->Tid;
|
|
msg->out.smb->Mid = msg->in.smb->Mid;
|
|
msg->out.smb->Uid = msg->in.smb->Uid;
|
|
}
|
|
|
|
#define XLAT_STRING(code) static const char STRING_##code[] = #code
|
|
#define XLAT_CASE(code) case code: return STRING_##code
|
|
#define XLAT_STRING_DEFAULT XLAT_STRING(Unknown)
|
|
#define XLAT_CASE_DEFAULT default: return STRING_Unknown
|
|
|
|
LPCSTR
|
|
SrvUnparseCommand(
|
|
USHORT command
|
|
)
|
|
{
|
|
XLAT_STRING_DEFAULT;
|
|
XLAT_STRING(SMB_COM_CREATE_DIRECTORY);
|
|
XLAT_STRING(SMB_COM_DELETE_DIRECTORY);
|
|
XLAT_STRING(SMB_COM_OPEN);
|
|
XLAT_STRING(SMB_COM_CREATE);
|
|
XLAT_STRING(SMB_COM_CLOSE);
|
|
XLAT_STRING(SMB_COM_FLUSH);
|
|
XLAT_STRING(SMB_COM_DELETE);
|
|
XLAT_STRING(SMB_COM_RENAME);
|
|
XLAT_STRING(SMB_COM_QUERY_INFORMATION);
|
|
XLAT_STRING(SMB_COM_SET_INFORMATION);
|
|
XLAT_STRING(SMB_COM_READ);
|
|
XLAT_STRING(SMB_COM_WRITE);
|
|
XLAT_STRING(SMB_COM_LOCK_BYTE_RANGE);
|
|
XLAT_STRING(SMB_COM_UNLOCK_BYTE_RANGE);
|
|
XLAT_STRING(SMB_COM_CREATE_TEMPORARY);
|
|
XLAT_STRING(SMB_COM_CREATE_NEW);
|
|
XLAT_STRING(SMB_COM_CHECK_DIRECTORY);
|
|
XLAT_STRING(SMB_COM_PROCESS_EXIT);
|
|
XLAT_STRING(SMB_COM_SEEK);
|
|
XLAT_STRING(SMB_COM_LOCK_AND_READ);
|
|
XLAT_STRING(SMB_COM_WRITE_AND_UNLOCK);
|
|
XLAT_STRING(SMB_COM_READ_RAW);
|
|
XLAT_STRING(SMB_COM_READ_MPX);
|
|
XLAT_STRING(SMB_COM_READ_MPX_SECONDARY); // server to redir only
|
|
XLAT_STRING(SMB_COM_WRITE_RAW);
|
|
XLAT_STRING(SMB_COM_WRITE_MPX);
|
|
XLAT_STRING(SMB_COM_WRITE_MPX_SECONDARY);
|
|
XLAT_STRING(SMB_COM_WRITE_COMPLETE); // server to redir only
|
|
XLAT_STRING(SMB_COM_QUERY_INFORMATION_SRV);
|
|
XLAT_STRING(SMB_COM_SET_INFORMATION2);
|
|
XLAT_STRING(SMB_COM_QUERY_INFORMATION2);
|
|
XLAT_STRING(SMB_COM_LOCKING_ANDX);
|
|
XLAT_STRING(SMB_COM_TRANSACTION);
|
|
XLAT_STRING(SMB_COM_TRANSACTION_SECONDARY);
|
|
XLAT_STRING(SMB_COM_IOCTL);
|
|
XLAT_STRING(SMB_COM_IOCTL_SECONDARY);
|
|
XLAT_STRING(SMB_COM_COPY);
|
|
XLAT_STRING(SMB_COM_MOVE);
|
|
XLAT_STRING(SMB_COM_ECHO);
|
|
XLAT_STRING(SMB_COM_WRITE_AND_CLOSE);
|
|
XLAT_STRING(SMB_COM_OPEN_ANDX);
|
|
XLAT_STRING(SMB_COM_READ_ANDX);
|
|
XLAT_STRING(SMB_COM_WRITE_ANDX);
|
|
XLAT_STRING(SMB_COM_CLOSE_AND_TREE_DISC);
|
|
XLAT_STRING(SMB_COM_TRANSACTION2);
|
|
XLAT_STRING(SMB_COM_TRANSACTION2_SECONDARY);
|
|
XLAT_STRING(SMB_COM_FIND_CLOSE2);
|
|
XLAT_STRING(SMB_COM_FIND_NOTIFY_CLOSE);
|
|
XLAT_STRING(SMB_COM_TREE_CONNECT);
|
|
XLAT_STRING(SMB_COM_TREE_DISCONNECT);
|
|
XLAT_STRING(SMB_COM_NEGOTIATE);
|
|
XLAT_STRING(SMB_COM_SESSION_SETUP_ANDX);
|
|
XLAT_STRING(SMB_COM_LOGOFF_ANDX);
|
|
XLAT_STRING(SMB_COM_TREE_CONNECT_ANDX);
|
|
XLAT_STRING(SMB_COM_QUERY_INFORMATION_DISK);
|
|
XLAT_STRING(SMB_COM_SEARCH);
|
|
XLAT_STRING(SMB_COM_FIND);
|
|
XLAT_STRING(SMB_COM_FIND_UNIQUE);
|
|
XLAT_STRING(SMB_COM_FIND_CLOSE);
|
|
XLAT_STRING(SMB_COM_NT_TRANSACT);
|
|
XLAT_STRING(SMB_COM_NT_TRANSACT_SECONDARY);
|
|
XLAT_STRING(SMB_COM_NT_CREATE_ANDX);
|
|
XLAT_STRING(SMB_COM_NT_CANCEL);
|
|
XLAT_STRING(SMB_COM_NT_RENAME);
|
|
XLAT_STRING(SMB_COM_OPEN_PRINT_FILE);
|
|
XLAT_STRING(SMB_COM_WRITE_PRINT_FILE);
|
|
XLAT_STRING(SMB_COM_CLOSE_PRINT_FILE);
|
|
XLAT_STRING(SMB_COM_GET_PRINT_QUEUE);
|
|
XLAT_STRING(SMB_COM_SEND_MESSAGE);
|
|
XLAT_STRING(SMB_COM_SEND_BROADCAST_MESSAGE);
|
|
XLAT_STRING(SMB_COM_FORWARD_USER_NAME);
|
|
XLAT_STRING(SMB_COM_CANCEL_FORWARD);
|
|
XLAT_STRING(SMB_COM_GET_MACHINE_NAME);
|
|
XLAT_STRING(SMB_COM_SEND_START_MB_MESSAGE);
|
|
XLAT_STRING(SMB_COM_SEND_END_MB_MESSAGE);
|
|
XLAT_STRING(SMB_COM_SEND_TEXT_MB_MESSAGE);
|
|
|
|
switch (command)
|
|
{
|
|
XLAT_CASE(SMB_COM_CREATE_DIRECTORY);
|
|
XLAT_CASE(SMB_COM_DELETE_DIRECTORY);
|
|
XLAT_CASE(SMB_COM_OPEN);
|
|
XLAT_CASE(SMB_COM_CREATE);
|
|
XLAT_CASE(SMB_COM_CLOSE);
|
|
XLAT_CASE(SMB_COM_FLUSH);
|
|
XLAT_CASE(SMB_COM_DELETE);
|
|
XLAT_CASE(SMB_COM_RENAME);
|
|
XLAT_CASE(SMB_COM_QUERY_INFORMATION);
|
|
XLAT_CASE(SMB_COM_SET_INFORMATION);
|
|
XLAT_CASE(SMB_COM_READ);
|
|
XLAT_CASE(SMB_COM_WRITE);
|
|
XLAT_CASE(SMB_COM_LOCK_BYTE_RANGE);
|
|
XLAT_CASE(SMB_COM_UNLOCK_BYTE_RANGE);
|
|
XLAT_CASE(SMB_COM_CREATE_TEMPORARY);
|
|
XLAT_CASE(SMB_COM_CREATE_NEW);
|
|
XLAT_CASE(SMB_COM_CHECK_DIRECTORY);
|
|
XLAT_CASE(SMB_COM_PROCESS_EXIT);
|
|
XLAT_CASE(SMB_COM_SEEK);
|
|
XLAT_CASE(SMB_COM_LOCK_AND_READ);
|
|
XLAT_CASE(SMB_COM_WRITE_AND_UNLOCK);
|
|
XLAT_CASE(SMB_COM_READ_RAW);
|
|
XLAT_CASE(SMB_COM_READ_MPX);
|
|
XLAT_CASE(SMB_COM_READ_MPX_SECONDARY); // server to redir only
|
|
XLAT_CASE(SMB_COM_WRITE_RAW);
|
|
XLAT_CASE(SMB_COM_WRITE_MPX);
|
|
XLAT_CASE(SMB_COM_WRITE_MPX_SECONDARY);
|
|
XLAT_CASE(SMB_COM_WRITE_COMPLETE); // server to redir only
|
|
XLAT_CASE(SMB_COM_QUERY_INFORMATION_SRV);
|
|
XLAT_CASE(SMB_COM_SET_INFORMATION2);
|
|
XLAT_CASE(SMB_COM_QUERY_INFORMATION2);
|
|
XLAT_CASE(SMB_COM_LOCKING_ANDX);
|
|
XLAT_CASE(SMB_COM_TRANSACTION);
|
|
XLAT_CASE(SMB_COM_TRANSACTION_SECONDARY);
|
|
XLAT_CASE(SMB_COM_IOCTL);
|
|
XLAT_CASE(SMB_COM_IOCTL_SECONDARY);
|
|
XLAT_CASE(SMB_COM_COPY);
|
|
XLAT_CASE(SMB_COM_MOVE);
|
|
XLAT_CASE(SMB_COM_ECHO);
|
|
XLAT_CASE(SMB_COM_WRITE_AND_CLOSE);
|
|
XLAT_CASE(SMB_COM_OPEN_ANDX);
|
|
XLAT_CASE(SMB_COM_READ_ANDX);
|
|
XLAT_CASE(SMB_COM_WRITE_ANDX);
|
|
XLAT_CASE(SMB_COM_CLOSE_AND_TREE_DISC);
|
|
XLAT_CASE(SMB_COM_TRANSACTION2);
|
|
XLAT_CASE(SMB_COM_TRANSACTION2_SECONDARY);
|
|
XLAT_CASE(SMB_COM_FIND_CLOSE2);
|
|
XLAT_CASE(SMB_COM_FIND_NOTIFY_CLOSE);
|
|
XLAT_CASE(SMB_COM_TREE_CONNECT);
|
|
XLAT_CASE(SMB_COM_TREE_DISCONNECT);
|
|
XLAT_CASE(SMB_COM_NEGOTIATE);
|
|
XLAT_CASE(SMB_COM_SESSION_SETUP_ANDX);
|
|
XLAT_CASE(SMB_COM_LOGOFF_ANDX);
|
|
XLAT_CASE(SMB_COM_TREE_CONNECT_ANDX);
|
|
XLAT_CASE(SMB_COM_QUERY_INFORMATION_DISK);
|
|
XLAT_CASE(SMB_COM_SEARCH);
|
|
XLAT_CASE(SMB_COM_FIND);
|
|
XLAT_CASE(SMB_COM_FIND_UNIQUE);
|
|
XLAT_CASE(SMB_COM_FIND_CLOSE);
|
|
XLAT_CASE(SMB_COM_NT_TRANSACT);
|
|
XLAT_CASE(SMB_COM_NT_TRANSACT_SECONDARY);
|
|
XLAT_CASE(SMB_COM_NT_CREATE_ANDX);
|
|
XLAT_CASE(SMB_COM_NT_CANCEL);
|
|
XLAT_CASE(SMB_COM_NT_RENAME);
|
|
XLAT_CASE(SMB_COM_OPEN_PRINT_FILE);
|
|
XLAT_CASE(SMB_COM_WRITE_PRINT_FILE);
|
|
XLAT_CASE(SMB_COM_CLOSE_PRINT_FILE);
|
|
XLAT_CASE(SMB_COM_GET_PRINT_QUEUE);
|
|
XLAT_CASE(SMB_COM_SEND_MESSAGE);
|
|
XLAT_CASE(SMB_COM_SEND_BROADCAST_MESSAGE);
|
|
XLAT_CASE(SMB_COM_FORWARD_USER_NAME);
|
|
XLAT_CASE(SMB_COM_CANCEL_FORWARD);
|
|
XLAT_CASE(SMB_COM_GET_MACHINE_NAME);
|
|
XLAT_CASE(SMB_COM_SEND_START_MB_MESSAGE);
|
|
XLAT_CASE(SMB_COM_SEND_END_MB_MESSAGE);
|
|
XLAT_CASE(SMB_COM_SEND_TEXT_MB_MESSAGE);
|
|
XLAT_CASE_DEFAULT;
|
|
}
|
|
}
|
|
|
|
LPCSTR
|
|
SrvUnparseTrans2(
|
|
USHORT code
|
|
)
|
|
{
|
|
XLAT_STRING_DEFAULT;
|
|
XLAT_STRING(TRANS2_OPEN2);
|
|
XLAT_STRING(TRANS2_FIND_FIRST2);
|
|
XLAT_STRING(TRANS2_FIND_NEXT2);
|
|
XLAT_STRING(TRANS2_QUERY_FS_INFORMATION);
|
|
XLAT_STRING(TRANS2_SET_FS_INFORMATION);
|
|
XLAT_STRING(TRANS2_QUERY_PATH_INFORMATION);
|
|
XLAT_STRING(TRANS2_SET_PATH_INFORMATION);
|
|
XLAT_STRING(TRANS2_QUERY_FILE_INFORMATION);
|
|
XLAT_STRING(TRANS2_SET_FILE_INFORMATION);
|
|
XLAT_STRING(TRANS2_FSCTL);
|
|
XLAT_STRING(TRANS2_IOCTL2);
|
|
XLAT_STRING(TRANS2_FIND_NOTIFY_FIRST);
|
|
XLAT_STRING(TRANS2_FIND_NOTIFY_NEXT);
|
|
XLAT_STRING(TRANS2_CREATE_DIRECTORY);
|
|
XLAT_STRING(TRANS2_SESSION_SETUP);
|
|
XLAT_STRING(TRANS2_QUERY_FS_INFORMATION_FID);
|
|
XLAT_STRING(TRANS2_GET_DFS_REFERRAL);
|
|
XLAT_STRING(TRANS2_REPORT_DFS_INCONSISTENCY);
|
|
|
|
switch (code)
|
|
{
|
|
XLAT_CASE(TRANS2_OPEN2);
|
|
XLAT_CASE(TRANS2_FIND_FIRST2);
|
|
XLAT_CASE(TRANS2_FIND_NEXT2);
|
|
XLAT_CASE(TRANS2_QUERY_FS_INFORMATION);
|
|
XLAT_CASE(TRANS2_SET_FS_INFORMATION);
|
|
XLAT_CASE(TRANS2_QUERY_PATH_INFORMATION);
|
|
XLAT_CASE(TRANS2_SET_PATH_INFORMATION);
|
|
XLAT_CASE(TRANS2_QUERY_FILE_INFORMATION);
|
|
XLAT_CASE(TRANS2_SET_FILE_INFORMATION);
|
|
XLAT_CASE(TRANS2_FSCTL);
|
|
XLAT_CASE(TRANS2_IOCTL2);
|
|
XLAT_CASE(TRANS2_FIND_NOTIFY_FIRST);
|
|
XLAT_CASE(TRANS2_FIND_NOTIFY_NEXT);
|
|
XLAT_CASE(TRANS2_CREATE_DIRECTORY);
|
|
XLAT_CASE(TRANS2_SESSION_SETUP);
|
|
XLAT_CASE(TRANS2_QUERY_FS_INFORMATION_FID);
|
|
XLAT_CASE(TRANS2_GET_DFS_REFERRAL);
|
|
XLAT_CASE(TRANS2_REPORT_DFS_INCONSISTENCY);
|
|
XLAT_CASE_DEFAULT;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
SrvInitDispTable(
|
|
)
|
|
{
|
|
ZeroMemory((PVOID) SrvDispatchTable, sizeof(SrvDispatchTable));
|
|
SrvDispatchTable[SMB_COM_NEGOTIATE] = SrvComNegotiate;
|
|
SrvDispatchTable[SMB_COM_TRANSACTION] = SrvComTrans;
|
|
SrvDispatchTable[SMB_COM_TRANSACTION2] = SrvComTrans2;
|
|
SrvDispatchTable[SMB_COM_SESSION_SETUP_ANDX] = SrvComSessionSetupAndx;
|
|
SrvDispatchTable[SMB_COM_TREE_CONNECT_ANDX] = SrvComTreeConnectAndx;
|
|
SrvDispatchTable[SMB_COM_NO_ANDX_COMMAND] = SrvComNoAndx;
|
|
SrvDispatchTable[SMB_COM_QUERY_INFORMATION] = SrvComQueryInformation;
|
|
SrvDispatchTable[SMB_COM_SET_INFORMATION] = SrvComSetInformation;
|
|
SrvDispatchTable[SMB_COM_CHECK_DIRECTORY] = SrvComCheckDirectory;
|
|
SrvDispatchTable[SMB_COM_FIND_CLOSE2] = SrvComFindClose2;
|
|
SrvDispatchTable[SMB_COM_DELETE] = SrvComDelete;
|
|
SrvDispatchTable[SMB_COM_RENAME] = SrvComRename;
|
|
SrvDispatchTable[SMB_COM_CREATE_DIRECTORY] = SrvComCreateDirectory;
|
|
SrvDispatchTable[SMB_COM_DELETE_DIRECTORY] = SrvComDeleteDirectory;
|
|
SrvDispatchTable[SMB_COM_OPEN_ANDX] = SrvComOpenAndx;
|
|
SrvDispatchTable[SMB_COM_OPEN] = SrvComOpen;
|
|
SrvDispatchTable[SMB_COM_WRITE] = SrvComWrite;
|
|
SrvDispatchTable[SMB_COM_CLOSE] = SrvComClose;
|
|
SrvDispatchTable[SMB_COM_READ_ANDX] = SrvComReadAndx;
|
|
SrvDispatchTable[SMB_COM_QUERY_INFORMATION2] = SrvComQueryInformation2;
|
|
SrvDispatchTable[SMB_COM_SET_INFORMATION2] = SrvComSetInformation2;
|
|
SrvDispatchTable[SMB_COM_LOCKING_ANDX] = SrvComLockingAndx;
|
|
SrvDispatchTable[SMB_COM_SEEK] = SrvComSeek;
|
|
SrvDispatchTable[SMB_COM_FLUSH] = SrvComFlush;
|
|
SrvDispatchTable[SMB_COM_LOGOFF_ANDX] = SrvComLogoffAndx;
|
|
SrvDispatchTable[SMB_COM_TREE_DISCONNECT] = SrvComTreeDisconnect;
|
|
SrvDispatchTable[SMB_COM_FIND_NOTIFY_CLOSE] = SrvComFindNotifyClose;
|
|
|
|
SrvDispatchTable[SMB_COM_SEARCH] = SrvComSearch;
|
|
|
|
SrvDispatchTable[SMB_COM_IOCTL] = SrvComIoctl;
|
|
|
|
SrvDispatchTable[SMB_COM_ECHO] = SrvComEcho;
|
|
|
|
ZeroMemory((PVOID) Trans2DispatchTable, sizeof(Trans2DispatchTable));
|
|
Trans2DispatchTable[TRANS2_QUERY_FS_INFORMATION] = Trans2QueryFsInfo;
|
|
Trans2DispatchTable[TRANS2_FIND_FIRST2] = Trans2FindFirst2;
|
|
Trans2DispatchTable[TRANS2_FIND_NEXT2] = Trans2FindNext2;
|
|
Trans2DispatchTable[TRANS2_QUERY_PATH_INFORMATION] = Trans2QueryPathInfo;
|
|
Trans2DispatchTable[TRANS2_SET_PATH_INFORMATION] = Trans2SetPathInfo;
|
|
Trans2DispatchTable[TRANS2_QUERY_FILE_INFORMATION] = Trans2QueryFileInfo;
|
|
Trans2DispatchTable[TRANS2_SET_FILE_INFORMATION] = Trans2SetFileInfo;
|
|
Trans2DispatchTable[TRANS2_GET_DFS_REFERRAL] = Trans2GetDfsReferral;
|
|
}
|
|
|
|
|
|
|
|
USHORT
|
|
attribs_to_smb_attribs(
|
|
UINT32 attribs
|
|
)
|
|
{
|
|
USHORT smb_attribs = 0;
|
|
if (attribs & ATTR_READONLY) smb_attribs |= SMB_FILE_ATTRIBUTE_READONLY;
|
|
if (attribs & ATTR_HIDDEN) smb_attribs |= SMB_FILE_ATTRIBUTE_HIDDEN;
|
|
if (attribs & ATTR_SYSTEM) smb_attribs |= SMB_FILE_ATTRIBUTE_SYSTEM;
|
|
if (attribs & ATTR_ARCHIVE) smb_attribs |= SMB_FILE_ATTRIBUTE_ARCHIVE;
|
|
if (attribs & ATTR_DIRECTORY) smb_attribs |= SMB_FILE_ATTRIBUTE_DIRECTORY;
|
|
return smb_attribs;
|
|
}
|
|
|
|
UINT32
|
|
smb_attribs_to_attribs(
|
|
USHORT smb_attribs
|
|
)
|
|
{
|
|
UINT32 attribs = 0;
|
|
if (smb_attribs & SMB_FILE_ATTRIBUTE_READONLY) attribs |= ATTR_READONLY;
|
|
if (smb_attribs & SMB_FILE_ATTRIBUTE_HIDDEN) attribs |= ATTR_HIDDEN;
|
|
if (smb_attribs & SMB_FILE_ATTRIBUTE_SYSTEM) attribs |= ATTR_SYSTEM;
|
|
if (smb_attribs & SMB_FILE_ATTRIBUTE_ARCHIVE) attribs |= ATTR_ARCHIVE;
|
|
if (smb_attribs & SMB_FILE_ATTRIBUTE_DIRECTORY) attribs |= ATTR_DIRECTORY;
|
|
return attribs;
|
|
}
|
|
|
|
UINT32
|
|
smb_access_to_flags(
|
|
USHORT access
|
|
)
|
|
{
|
|
UINT32 flags = 0;
|
|
switch (access & SMB_DA_SHARE_MASK) {
|
|
case SMB_DA_SHARE_COMPATIBILITY:
|
|
case SMB_DA_SHARE_DENY_NONE:
|
|
flags |= SHARE_READ | SHARE_WRITE;
|
|
break;
|
|
case SMB_DA_SHARE_DENY_WRITE:
|
|
flags |= SHARE_READ;
|
|
break;
|
|
case SMB_DA_SHARE_DENY_READ:
|
|
flags |= SHARE_WRITE;
|
|
break;
|
|
case SMB_DA_SHARE_EXCLUSIVE:
|
|
default:
|
|
break;
|
|
}
|
|
switch (access & SMB_DA_ACCESS_MASK) {
|
|
case SMB_DA_ACCESS_READ:
|
|
case SMB_DA_ACCESS_EXECUTE:
|
|
flags |= ACCESS_READ;
|
|
break;
|
|
case SMB_DA_ACCESS_WRITE:
|
|
flags |= ACCESS_WRITE;
|
|
break;
|
|
case SMB_DA_ACCESS_READ_WRITE:
|
|
flags |= ACCESS_READ | ACCESS_WRITE;
|
|
break;
|
|
}
|
|
|
|
if (access & SMB_DO_NOT_CACHE) {
|
|
flags |= CACHE_NO_BUFFERING;
|
|
}
|
|
if (access & SMB_DA_WRITE_THROUGH) {
|
|
flags |= CACHE_WRITE_THROUGH;
|
|
}
|
|
return flags;
|
|
}
|
|
|
|
UINT32
|
|
smb_openfunc_to_flags(
|
|
USHORT openfunc
|
|
)
|
|
{
|
|
switch (openfunc & (SMB_OFUN_OPEN_MASK | SMB_OFUN_CREATE_MASK)) {
|
|
case (SMB_OFUN_CREATE_FAIL | SMB_OFUN_OPEN_FAIL):
|
|
return 0;
|
|
case (SMB_OFUN_CREATE_FAIL | SMB_OFUN_OPEN_OPEN):
|
|
return DISP_OPEN_EXISTING;
|
|
case (SMB_OFUN_CREATE_FAIL | SMB_OFUN_OPEN_TRUNCATE):
|
|
return DISP_TRUNCATE_EXISTING;
|
|
case (SMB_OFUN_CREATE_CREATE | SMB_OFUN_OPEN_FAIL):
|
|
return DISP_CREATE_NEW;
|
|
case (SMB_OFUN_CREATE_CREATE | SMB_OFUN_OPEN_OPEN):
|
|
return DISP_OPEN_ALWAYS;
|
|
case (SMB_OFUN_CREATE_CREATE | SMB_OFUN_OPEN_TRUNCATE):
|
|
return DISP_CREATE_ALWAYS;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void
|
|
local_time64(
|
|
TIME64 *time // system time to be converted to local time
|
|
)
|
|
{
|
|
TIME64 local = *time;
|
|
FileTimeToLocalFileTime((LPFILETIME)time, (LPFILETIME)&local);
|
|
*time = local;
|
|
}
|
|
|
|
void
|
|
sys_time64(
|
|
TIME64 *time // local time to be converted to system time
|
|
)
|
|
{
|
|
TIME64 sys = *time;
|
|
LocalFileTimeToFileTime((LPFILETIME)time, (LPFILETIME)&sys);
|
|
*time = sys;
|
|
}
|
|
|
|
void
|
|
smb_datetime_to_time64(
|
|
const USHORT smbdate,
|
|
const USHORT smbtime,
|
|
TIME64 *time
|
|
)
|
|
{
|
|
DosDateTimeToFileTime(smbdate, smbtime, (LPFILETIME)time);
|
|
sys_time64(time);
|
|
}
|
|
|
|
typedef struct {
|
|
SMB_TIME time;
|
|
SMB_DATE date;
|
|
}SMB_TIMEDATE;
|
|
|
|
TIME64 // system time
|
|
smb_timedate_to_time64(
|
|
ULONG smb_timedate // local time
|
|
)
|
|
{
|
|
TIME64 time = 0;
|
|
DosDateTimeToFileTime(((SMB_TIMEDATE*)&smb_timedate)->date.Ushort,
|
|
((SMB_TIMEDATE*)&smb_timedate)->time.Ushort,
|
|
(LPFILETIME)&time);
|
|
sys_time64(&time);
|
|
return time;
|
|
}
|
|
|
|
void
|
|
_time64_to_smb_datetime(
|
|
TIME64 *time,
|
|
USHORT *smbdate,
|
|
USHORT *smbtime
|
|
)
|
|
{
|
|
local_time64(time);
|
|
*smbdate = *smbtime = 0;
|
|
FileTimeToDosDateTime((LPFILETIME)time, smbdate, smbtime);
|
|
}
|
|
|
|
ULONG // local time
|
|
time64_to_smb_timedate(
|
|
TIME64 *time // system time
|
|
)
|
|
{
|
|
ULONG smb_timedate = 0;
|
|
local_time64(time);
|
|
FileTimeToDosDateTime((LPFILETIME)&time,
|
|
&(((SMB_TIMEDATE*)&smb_timedate)->date.Ushort),
|
|
&(((SMB_TIMEDATE*)&smb_timedate)->date.Ushort));
|
|
return smb_timedate;
|
|
}
|
|
|
|
|
|
#define dword_in_range(in, low, high) ((low <= in) && (in <= high))
|
|
|
|
void set_DOSERROR(Packet_t * msg, USHORT ec, USHORT err)
|
|
{
|
|
msg->out.smb->Status.DosError.ErrorClass = (unsigned char) ec;
|
|
msg->out.smb->Status.DosError.Error = err;
|
|
}
|
|
|
|
void SET_WIN32ERROR(
|
|
Packet_t * msg,
|
|
DWORD error
|
|
)
|
|
{
|
|
|
|
if (!error) return;
|
|
if (dword_in_range(error, 1, 18) || (error == 32) || (error == 33) ||
|
|
(error == 80) || dword_in_range(error, 230, 234) || (error == 145)) {
|
|
set_DOSERROR(msg,
|
|
SMB_ERR_CLASS_DOS,
|
|
(USHORT)error);
|
|
} else if (dword_in_range(error, 19, 31) ||
|
|
(error == 34) || (error == 36) || (error == 39)) {
|
|
set_DOSERROR(msg,
|
|
SMB_ERR_CLASS_HARDWARE,
|
|
(USHORT)error);
|
|
} else if (error == 112) {
|
|
SET_DOSERROR(msg, HARDWARE, DISK_FULL);
|
|
} else if (error == 67) {
|
|
SET_DOSERROR(msg, SERVER, BAD_NET_NAME);
|
|
} else if (error == 123) {
|
|
set_DOSERROR(msg,
|
|
SMB_ERR_CLASS_SERVER,
|
|
(USHORT)error);
|
|
} else if (error == 183) {
|
|
SET_DOSERROR(msg, DOS, FILE_EXISTS);
|
|
} else {
|
|
SET_DOSERROR(msg, SERVER, ERROR);
|
|
}
|
|
}
|
|
|
|
|