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