windows-nt/Source/XPSP1/NT/base/mvdm/sim32/sim32.c
2020-09-26 16:20:57 +08:00

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);
}
/******************************