You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
8.9 KiB
268 lines
8.9 KiB
#include <ntreppch.h>
|
|
#include <frs.h>
|
|
|
|
#include "attack.h"
|
|
|
|
|
|
|
|
ULONG NtFrsMajor = NTFRS_MAJOR;
|
|
|
|
ULONG NtFrsCommMinor = NTFRS_COMM_MINOR_7;
|
|
//
|
|
// Note: When using COMM_DECODE_VAR_LEN_BLOB you must also use COMM_SZ_NULL
|
|
// in the table below so that no length check is made when the field is decoded.
|
|
// This allows the field size to grow. Down level members must be able to
|
|
// handle this by ignoring var len field components they do not understand.
|
|
//
|
|
|
|
//
|
|
// The Communication packet element table below is used to construct and
|
|
// decode comm packet data sent between members.
|
|
// *** WARNING *** - the order of the rows in the table must match the
|
|
// the order of the elements in the COMM_TYPE enum. See comments for COMM_TYPE
|
|
// enum for restrictions on adding new elements to the table.
|
|
//
|
|
// Data Element Type DisplayText Size Decode Type Offset to Native Cmd Packet
|
|
//
|
|
COMM_PACKET_ELEMENT CommPacketTable[COMM_MAX] = {
|
|
{COMM_NONE, "NONE" , COMM_SZ_NULL, COMM_DECODE_NONE, 0 },
|
|
|
|
{COMM_BOP, "BOP" , COMM_SZ_UL, COMM_DECODE_ULONG, RsOffsetSkip },
|
|
{COMM_COMMAND, "COMMAND" , COMM_SZ_UL, COMM_DECODE_ULONG_TO_USHORT, OFFSET(COMMAND_PACKET, Command)},
|
|
{COMM_TO, "TO" , COMM_SZ_NULL, COMM_DECODE_GNAME, RsOffset(To) },
|
|
{COMM_FROM, "FROM" , COMM_SZ_NULL, COMM_DECODE_GNAME, RsOffset(From) },
|
|
{COMM_REPLICA, "REPLICA" , COMM_SZ_NULL, COMM_DECODE_GNAME, RsOffset(ReplicaName) },
|
|
{COMM_JOIN_GUID, "JOIN_GUID" , COMM_SZ_GUL, COMM_DECODE_BLOB, RsOffset(JoinGuid) },
|
|
{COMM_VVECTOR, "VVECTOR" , COMM_SZ_GVSN, COMM_DECODE_VVECTOR, RsOffset(VVector) },
|
|
{COMM_CXTION, "CXTION" , COMM_SZ_NULL, COMM_DECODE_GNAME, RsOffset(Cxtion) },
|
|
|
|
{COMM_BLOCK, "BLOCK" , COMM_SZ_NULL, COMM_DECODE_BLOB, RsOffset(Block) },
|
|
{COMM_BLOCK_SIZE, "BLOCK_SIZE" , COMM_SZ_ULL, COMM_DECODE_ULONGLONG, RsOffset(BlockSize) },
|
|
{COMM_FILE_SIZE, "FILE_SIZE" , COMM_SZ_ULL, COMM_DECODE_ULONGLONG, RsOffset(FileSize) },
|
|
{COMM_FILE_OFFSET, "FILE_OFFSET" , COMM_SZ_ULL, COMM_DECODE_ULONGLONG, RsOffset(FileOffset) },
|
|
|
|
{COMM_REMOTE_CO, "REMOTE_CO" , COMM_SZ_COC, COMM_DECODE_REMOTE_CO, RsOffset(PartnerChangeOrderCommand)},
|
|
{COMM_GVSN, "GVSN" , COMM_SZ_GVSN, COMM_DECODE_BLOB, RsOffset(GVsn) },
|
|
|
|
{COMM_CO_GUID, "CO_GUID" , COMM_SZ_GUL, COMM_DECODE_BLOB, RsOffset(ChangeOrderGuid) },
|
|
{COMM_CO_SEQUENCE_NUMBER, "CO_SEQUENCE_NUMBER" , COMM_SZ_UL, COMM_DECODE_ULONG, RsOffset(ChangeOrderSequenceNumber)},
|
|
{COMM_JOIN_TIME, "JOIN_TIME" , COMM_SZ_JTIME, COMM_DECODE_BLOB, RsOffset(JoinTime) },
|
|
{COMM_LAST_JOIN_TIME, "LAST_JOIN_TIME" , COMM_SZ_ULL, COMM_DECODE_ULONGLONG, RsOffset(LastJoinTime) },
|
|
{COMM_EOP, "EOP" , COMM_SZ_UL, COMM_DECODE_ULONG, RsOffsetSkip },
|
|
{COMM_REPLICA_VERSION_GUID, "REPLICA_VERSION_GUID", COMM_SZ_GUL, COMM_DECODE_BLOB, RsOffset(ReplicaVersionGuid)},
|
|
{COMM_MD5_DIGEST, "MD5_DIGEST" , COMM_SZ_MD5, COMM_DECODE_BLOB, RsOffset(Md5Digest) },
|
|
{COMM_CO_EXT_WIN2K, "CO_EXT_WIN2K" , COMM_SZ_COEXT_W2K,COMM_DECODE_BLOB, RsOffset(PartnerChangeOrderCommandExt)},
|
|
{COMM_CO_EXTENSION_2, "CO_EXTENSION_2" , COMM_SZ_NULL, COMM_DECODE_VAR_LEN_BLOB, RsOffset(PartnerChangeOrderCommandExt)},
|
|
|
|
{COMM_COMPRESSION_GUID, "COMPRESSION_GUID" , COMM_SZ_GUID, COMM_DECODE_GUID, RsOffset(CompressionTable)}
|
|
|
|
};
|
|
|
|
|
|
|
|
VOID
|
|
CommCopyMemory(
|
|
IN PCOMM_PACKET CommPkt,
|
|
IN PUCHAR Src,
|
|
IN ULONG Len
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Copy memory into a comm packet, extending as necessary
|
|
|
|
Arguments:
|
|
CommPkt
|
|
Src
|
|
Len
|
|
|
|
Return Value:
|
|
None.
|
|
--*/
|
|
{
|
|
#undef DEBSUB
|
|
#define DEBSUB "CommCopyMemory:"
|
|
ULONG MemLeft;
|
|
PUCHAR NewPkt;
|
|
|
|
//
|
|
// Adjust size of comm packet if necessary
|
|
//
|
|
// PERF: How many allocs get done to send a CO??? This looks expensive.
|
|
|
|
MemLeft = CommPkt->MemLen - CommPkt->PktLen;
|
|
if (Len > MemLeft) {
|
|
//
|
|
// Just filling memory; extend memory, tacking on a little extra
|
|
//
|
|
CommPkt->MemLen = (((CommPkt->MemLen + Len) + (COMM_MEM_SIZE - 1))
|
|
/ COMM_MEM_SIZE)
|
|
* COMM_MEM_SIZE;
|
|
NewPkt = MALLOC(CommPkt->MemLen);
|
|
CopyMemory(NewPkt, CommPkt->Pkt, CommPkt->PktLen);
|
|
FREE(CommPkt->Pkt);
|
|
CommPkt->Pkt = NewPkt;
|
|
}
|
|
|
|
//
|
|
// Copy into the packet
|
|
//
|
|
if (Src != NULL) {
|
|
CopyMemory(CommPkt->Pkt + CommPkt->PktLen, Src, Len);
|
|
} else {
|
|
ZeroMemory(CommPkt->Pkt + CommPkt->PktLen, Len);
|
|
}
|
|
CommPkt->PktLen += Len;
|
|
}
|
|
|
|
|
|
VOID
|
|
CommPackULong(
|
|
IN PCOMM_PACKET CommPkt,
|
|
IN COMM_TYPE Type,
|
|
IN ULONG Data
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Copy a header and a ulong into the comm packet.
|
|
|
|
Arguments:
|
|
CommPkt
|
|
Type
|
|
Data
|
|
|
|
Return Value:
|
|
None.
|
|
--*/
|
|
{
|
|
#undef DEBSUB
|
|
#define DEBSUB "CommPackULong:"
|
|
ULONG Len = sizeof(ULONG);
|
|
USHORT CommType = (USHORT)Type;
|
|
|
|
CommCopyMemory(CommPkt, (PUCHAR)&CommType, sizeof(USHORT));
|
|
printf("Packed CommType.\n");
|
|
CommCopyMemory(CommPkt, (PUCHAR)&Len, sizeof(ULONG));
|
|
printf("Packed Len.\n");
|
|
CommCopyMemory(CommPkt, (PUCHAR)&Data, sizeof(ULONG));
|
|
printf("Packed Data.\n");
|
|
}
|
|
|
|
|
|
PCOMM_PACKET
|
|
CommStartCommPkt(
|
|
IN PWCHAR Name
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Allocate a comm packet.
|
|
|
|
Arguments:
|
|
Name
|
|
|
|
Return Value:
|
|
Address of a comm packet.
|
|
--*/
|
|
{
|
|
#undef DEBSUB
|
|
#define DEBSUB "CommStartCommPkt:"
|
|
ULONG Size;
|
|
PCOMM_PACKET CommPkt;
|
|
|
|
//
|
|
// We can create a comm packet in a file or in memory
|
|
//
|
|
CommPkt = MALLOC(sizeof(COMM_PACKET));
|
|
Size = COMM_MEM_SIZE;
|
|
CommPkt->Pkt = MALLOC(Size);
|
|
CommPkt->MemLen = Size;
|
|
CommPkt->Major = NtFrsMajor;
|
|
CommPkt->Minor = NtFrsCommMinor;
|
|
|
|
printf("CommPkt initialized. Getting ready to add BOP\n");
|
|
//
|
|
// Pack the beginning-of-packet
|
|
//
|
|
CommPackULong(CommPkt, COMM_BOP, 0);
|
|
return CommPkt;
|
|
}
|
|
|
|
PCOMM_PACKET
|
|
BuildCommPktFromDescriptorList(
|
|
IN PCOMM_PKT_DESCRIPTOR pListHead,
|
|
IN ULONG ActualPktSize,
|
|
IN OPTIONAL ULONG *Major,
|
|
IN OPTIONAL ULONG *Minor,
|
|
IN OPTIONAL ULONG *CsId,
|
|
IN OPTIONAL ULONG *MemLen,
|
|
IN OPTIONAL ULONG *PktLen,
|
|
IN OPTIONAL ULONG *UpkLen
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Allocate a comm packet and fill it acording to the parameters specified..
|
|
|
|
|
|
Arguments:
|
|
pListHead - Address of the pListEntry of a COMM_PKT_DESCRIPTOR. We walk
|
|
the list of descriptors to build the Pkt.
|
|
|
|
ActualPktSize - Amount of memory to allocate for the Pkt.
|
|
|
|
Major
|
|
Minor
|
|
CsId
|
|
MemLen
|
|
PktLen
|
|
UpkLen - These parameters correspond to the fields in a COMM_PACKET. If
|
|
they are NULL, the default value is used.
|
|
|
|
|
|
Return Value:
|
|
Address of a comm packet.
|
|
--*/
|
|
{
|
|
PCOMM_PKT_DESCRIPTOR pDescriptor = pListHead;
|
|
PCOMM_PACKET CommPkt = NULL;
|
|
|
|
//
|
|
// Allocate the CommPkt struct
|
|
//
|
|
CommPkt = MALLOC(sizeof(COMM_PACKET));
|
|
|
|
//
|
|
// Allocate the Pkt
|
|
//
|
|
CommPkt->Pkt = MALLOC(ActualPktSize);
|
|
|
|
//
|
|
// Set struct values. Use defaults if parameters are not specified.
|
|
//
|
|
CommPkt->MemLen = (MemLen?*MemLen:COMM_MEM_SIZE);
|
|
CommPkt->Major = (Major?*Major:NtFrsMajor);
|
|
CommPkt->Minor = (Minor?*Minor:NtFrsCommMinor);
|
|
CommPkt->CsId = (CsId?*CsId:CS_RS);
|
|
CommPkt->UpkLen = (UpkLen?*UpkLen:0);
|
|
|
|
//
|
|
// PktLen must be 0 for now so that CommCopyMemory will work correctly.
|
|
// We'll set it to the provided value later.
|
|
//
|
|
CommPkt->PktLen = 0;
|
|
|
|
|
|
while(pDescriptor != NULL) {
|
|
CommCopyMemory(CommPkt, (PUCHAR)&(pDescriptor->CommType), sizeof(USHORT));
|
|
CommCopyMemory(CommPkt, (PUCHAR)&(pDescriptor->CommDataLength), sizeof(ULONG));
|
|
CommCopyMemory(CommPkt, (PUCHAR)(pDescriptor->Data), pDescriptor->ActualDataLength );
|
|
pDescriptor = pDescriptor->Next;
|
|
};
|
|
|
|
|
|
//
|
|
// We're done building the packet.
|
|
// Now we can set PktLen tot he supplied value.
|
|
//
|
|
CommPkt->PktLen = (PktLen?*PktLen:CommPkt->PktLen);
|
|
|
|
return CommPkt;
|
|
}
|