367 lines
7.9 KiB
C
367 lines
7.9 KiB
C
#include <nt.h>
|
|
#include <ntddtx.h>
|
|
#include <malloc.h>
|
|
|
|
#include "sim32.h"
|
|
|
|
UCHAR TransmitPkt[MAXSIZE];
|
|
UCHAR ReceivePkt[MAXSIZE];
|
|
|
|
HANDLE DeviceHandle;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status;
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Sim32GetVDMMemory
|
|
*
|
|
* This routine gets 'Size' bytes from WOW VDM starting at address
|
|
* specified by 'Address'. These bytes are returned to the caller in
|
|
* the Buffer (which is owned by the caller).
|
|
*
|
|
*****************************************************************************/
|
|
|
|
|
|
USHORT Sim32GetVDMMemory (IN ULONG Address,
|
|
IN USHORT Size,
|
|
IN OUT PVOID Buffer)
|
|
|
|
{
|
|
if (Size < MAXSIZE-11) {
|
|
TransmitPkt[0] = SOH;
|
|
TransmitPkt[1] = GETMEM;
|
|
TransmitPkt[2] = 11;
|
|
TransmitPkt[3] = 0;
|
|
TransmitPkt[4] = (UCHAR) FIRSTBYTE(Address);
|
|
TransmitPkt[5] = (UCHAR) SECONDBYTE(Address);
|
|
TransmitPkt[6] = (UCHAR) THIRDBYTE(Address);
|
|
TransmitPkt[7] = (UCHAR) FOURTHBYTE(Address);
|
|
TransmitPkt[8] = (UCHAR) FIRSTBYTE(Size);
|
|
TransmitPkt[9] = (UCHAR) SECONDBYTE(Size);
|
|
TransmitPkt[10] = EOT;
|
|
|
|
if (!Xceive((USHORT)(Size+5), 11)) {
|
|
DbgPrint ("Sim32GetVDMMemory.....BAD Memory \a\n");
|
|
return (BAD);
|
|
}
|
|
|
|
RtlMoveMemory(Buffer, &ReceivePkt[4], Size);
|
|
|
|
return(GOOD);
|
|
|
|
}
|
|
else {
|
|
DbgPrint ("Bad Packet Size %d\n", Size);
|
|
return (BADSIZE);
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Sim32SetVDMMemory
|
|
*
|
|
* This routine sets 'Size' bytes in WOW VDM starting at address
|
|
* specified by 'Address' to the values in Buffer.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
|
|
USHORT Sim32SetVDMMemory (IN ULONG Address,
|
|
IN USHORT Size,
|
|
IN OUT PVOID Buffer)
|
|
{
|
|
if (Size < MAXSIZE-11) {
|
|
TransmitPkt[0] = SOH;
|
|
TransmitPkt[1] = SETMEM;
|
|
TransmitPkt[2] = (UCHAR) (Size+11);
|
|
TransmitPkt[3] = 0;
|
|
TransmitPkt[4] = (UCHAR) FIRSTBYTE(Address);
|
|
TransmitPkt[5] = (UCHAR) SECONDBYTE(Address);
|
|
TransmitPkt[6] = (UCHAR) THIRDBYTE(Address);
|
|
TransmitPkt[7] = (UCHAR) FOURTHBYTE(Address);
|
|
TransmitPkt[8] = (UCHAR) FIRSTBYTE(Size);
|
|
TransmitPkt[9] = (UCHAR) SECONDBYTE(Size);
|
|
TransmitPkt[10+Size] = EOT;
|
|
|
|
RtlMoveMemory(&TransmitPkt[10], Buffer, Size);
|
|
|
|
if (!Xceive(7, (USHORT)(Size+11))) {
|
|
DbgPrint ("Sim32SetVDMMemory... could not set : \a\n");
|
|
return (BAD);
|
|
}
|
|
|
|
return(GOOD);
|
|
|
|
}
|
|
else {
|
|
DbgPrint ("Bad Packet Size %d\n", Size);
|
|
return (BADSIZE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Sim32GetVDMPSZPointer
|
|
*
|
|
* This routine returns a pointer to a null terminated string in the WOW
|
|
* VDM at the specified address.
|
|
*
|
|
* This routine does the following,
|
|
* allocates a sufficient size buffer,
|
|
* gets the string from SIM16,
|
|
* copies the string into buffer,
|
|
* returns a pointer to the buffer.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
|
|
PSZ Sim32GetVDMPSZPointer (IN ULONG Address)
|
|
{
|
|
USHORT Size;
|
|
PSZ Ptr;
|
|
|
|
|
|
TransmitPkt[0] = SOH;
|
|
TransmitPkt[1] = PSZLEN;
|
|
TransmitPkt[2] = 9;
|
|
TransmitPkt[3] = 0;
|
|
TransmitPkt[4] = (UCHAR) FIRSTBYTE(Address);
|
|
TransmitPkt[5] = (UCHAR) SECONDBYTE(Address);
|
|
TransmitPkt[6] = (UCHAR) THIRDBYTE(Address);
|
|
TransmitPkt[7] = (UCHAR) FOURTHBYTE(Address);
|
|
TransmitPkt[8] = EOT;
|
|
|
|
if (!Xceive(7, 9)) {
|
|
DbgPrint ("Sim32GetVDMPSZPointer.....Attempt to get PSZ length failed \a\a\n");
|
|
return NULL;
|
|
}
|
|
|
|
Size = *(PUSHORT)(ReceivePkt+4);
|
|
|
|
|
|
//
|
|
// allocate buffer to copy string into
|
|
//
|
|
|
|
Ptr = (PSZ) malloc(Size);
|
|
|
|
if (!Ptr) {
|
|
DbgPrint ("Sim32GetVDMPSZPointer..., malloc failed \a\a\n");
|
|
}
|
|
|
|
|
|
//
|
|
// get null terminated string
|
|
//
|
|
|
|
if (Size < MAXSIZE-11) {
|
|
TransmitPkt[1] = GETMEM;
|
|
TransmitPkt[2] = 11;
|
|
TransmitPkt[3] = 0;
|
|
TransmitPkt[8] = (UCHAR) FIRSTBYTE(Size);
|
|
TransmitPkt[9] = (UCHAR) SECONDBYTE(Size);
|
|
TransmitPkt[10] = EOT;
|
|
|
|
if (!Xceive((USHORT)(Size+5), 11)) {
|
|
DbgPrint ("Sim32GetVDMPSZPointer.....Unsuccessful \a\a\n");
|
|
return NULL;
|
|
}
|
|
|
|
RtlMoveMemory(Ptr, &ReceivePkt[4], Size);
|
|
} else {
|
|
DbgPrint ("Sim32GetVDMPSZPointer.....Size of the string too big Size = %d\a\a\n", Size);
|
|
return NULL;
|
|
}
|
|
|
|
return Ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Sim32FreeVDMPointer
|
|
*
|
|
* This routine frees the buffer which was allocated earlier.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
|
|
VOID Sim32FreeVDMPointer (PVOID Ptr)
|
|
{
|
|
free (Ptr);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Sim32SendSim16
|
|
*
|
|
* This routine specifies the stack of the WOW VDM task and asks the
|
|
* WOW 16 to make that task run.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
|
|
USHORT Sim32SendSim16 (IN OUT ULONG *WOWStack)
|
|
{
|
|
static USHORT fInit = 0;
|
|
|
|
if (fInit) {
|
|
TransmitPkt[0] = SOH;
|
|
TransmitPkt[1] = WAKEUP;
|
|
TransmitPkt[2] = 9;
|
|
TransmitPkt[3] = 0;
|
|
TransmitPkt[4] = (UCHAR) FIRSTBYTE(*WOWStack);
|
|
TransmitPkt[5] = (UCHAR) SECONDBYTE(*WOWStack);
|
|
TransmitPkt[6] = (UCHAR) THIRDBYTE(*WOWStack);
|
|
TransmitPkt[7] = (UCHAR) FOURTHBYTE(*WOWStack);
|
|
TransmitPkt[8] = EOT;
|
|
|
|
if (!Xceive(9, 9)) {
|
|
return (BAD);
|
|
}
|
|
|
|
*WOWStack = *(PULONG)(ReceivePkt+4);
|
|
|
|
return(GOOD);
|
|
}
|
|
else {
|
|
Initialize(9);
|
|
*WOWStack = *(PULONG)(ReceivePkt+4);
|
|
fInit = 1;
|
|
return (GOOD);
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Xceive
|
|
*
|
|
* This routine transmits a packet and waits for the data from the remote
|
|
* side to come. When this routine returns, the ReceivePkt has the data
|
|
* sent by the remote machine.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
|
|
USHORT Xceive(IN USHORT Length_In, IN USHORT Length_Out)
|
|
{
|
|
BOOLEAN Done = FALSE;
|
|
USHORT i = 0;
|
|
|
|
while ((i < MAXTRY) && (!Done)) {
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
DeviceHandle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_TRNXT_XCEIVE,
|
|
TransmitPkt,
|
|
(ULONG) Length_Out,
|
|
ReceivePkt,
|
|
(ULONG) Length_In
|
|
);
|
|
|
|
//
|
|
// check error condition
|
|
// if no error, then
|
|
//
|
|
|
|
if (ReceivePkt[0] == SOH) {
|
|
if (ReceivePkt[1] != NAK) {
|
|
i = *(PUSHORT)(ReceivePkt+2);
|
|
if (ReceivePkt[(--i)] == EOT) {
|
|
Done = TRUE;
|
|
}
|
|
else {
|
|
DbgPrint ("EOT is missing from the packet, *ERROR*, Do Not Proceed Further !\a\a\n");
|
|
}
|
|
}
|
|
else {
|
|
DbgPrint ("It is a NAK packet, *ERROR*, Do Not Proceed Further !\a\a\n");
|
|
}
|
|
}
|
|
else {
|
|
DbgPrint ("SOH is missing from the packet, *ERROR*, Do Not Proceed Further !\a\a\n");
|
|
}
|
|
|
|
if (!Done) {
|
|
i++;
|
|
DbgPrint ("\nSTOP STOP STOP !!!\a\a\a\a\a\n");
|
|
}
|
|
}
|
|
|
|
if (Done) {
|
|
return (GOOD);
|
|
}
|
|
else {
|
|
return (BAD);
|
|
}
|
|
|
|
}
|
|
|
|
void Initialize (IN USHORT Length_In)
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
STRING DeviceName;
|
|
USHORT j;
|
|
char TestPkt[] = "WOW 32 Simulator on NT\n\r";
|
|
|
|
RtlInitString(&DeviceName, "\\Device\\Serial1");
|
|
|
|
//
|
|
// set attributes
|
|
//
|
|
|
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
|
ObjectAttributes.RootDirectory = NULL;
|
|
ObjectAttributes.ObjectName = &DeviceName;
|
|
ObjectAttributes.Attributes = OBJ_INHERIT;
|
|
ObjectAttributes.SecuriAR) SECONDBYTE(Size);
|
|
TransmitPkt[10] = EOT;
|
|
|
|
if (!Xceive((USHORT)(Size+5), 11)) {
|
|
DbgPrint ("Sim32GetVDMPSZPointer.....Unsuccessful \a\a\n");
|
|
return NULL;
|
|
}
|
|
|
|
RtlMoveMemory(Ptr, &ReceivePkt[4], Size);
|
|
} else {
|
|
DbgPrint ("Sim32GetVDMPSZPointer.....Size of the string too big Size = %d\a\a\n", Size);
|
|
return NULL;
|
|
}
|
|
|
|
return Ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Sim32FreeVDMPointer
|
|
*
|
|
* This routine frees the buffer which was allocated earlier.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
|
|
VOID Sim32FreeVDMPointer (PVOID Ptr)
|
|
{
|
|
free (Ptr);
|
|
}
|
|
|
|
|
|
|
|
/******************************
|