I have written two programs that encrypts and sends and decrypts and receives a text file in asm. The program works fine, the problem I'm having is setting up the com1 port. The transmitter sends the file fine, but the receiver cannot receive the file until i have set up the comm port with hyper terminal on defaults. Once hyper terminal has been set up and exited the receiver will receive the file no problem. I have tried setting up hyperterminal and the using the exact same settings from the DCB structure in my program but it made absolutely no difference. Watever i do the only thing that continues to work is hyperterminal. Am i missing some very imoprtant step here.

This is just introducing me to programming so i know that most of the code is far from perfect, the main thing I want to do is just get rid of the hyper terminal step so it can be a one click interaction with the pc.

Here is my original code for setting up the comm port on both machines as it stands now after reverting all attempts to make it work(copying DCB exactly).

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
   DCB dcb;
   HANDLE hCom;
   BOOL fSuccess;
   TCHAR *pcCommPort = TEXT("COM1");

   hCom = CreateFile( pcCommPort,
                    GENERIC_READ | GENERIC_WRITE,
                    0,    // must be opened with exclusive-access
                    NULL, // default security attributes
                    OPEN_EXISTING, // must use OPEN_EXISTING
                    0,    // not overlapped I/O
                    NULL  // hTemplate must be NULL for comm devices
                    );

   if (hCom == INVALID_HANDLE_VALUE) 
   {
       // Handle the error.
       printf ("CreateFile failed with error %d.\n", GetLastError());
       return (1);
   }

   // Build on the current configuration, and skip setting the size
   // of the input and output buffers with SetupComm.

   SecureZeroMemory(&dcb, sizeof(DCB));
   dcb.DCBlength = sizeof(DCB);
   fSuccess = GetCommState(hCom, &dcb);

   if (!fSuccess) 
   {
      // Handle the error.
      printf ("GetCommState failed with error %d.\n", GetLastError());
      return (2);
   }

   // Fill in DCB: 9,600 bps, 8 data bits, no parity, and 1 stop bit.

   dcb.BaudRate = CBR_9600;     // set the baud rate
   dcb.ByteSize = 8;             // data size, xmit, and rcv
   dcb.Parity = NOPARITY;        // no parity bit
   dcb.StopBits = ONESTOPBIT;    // one stop bit

   fSuccess = SetCommState(hCom, &dcb);

   if (!fSuccess) 
   {
      // Handle the error.
      printf ("SetCommState failed with error %d.\n", GetLastError());
      return (3);
   }

   _tprintf (TEXT("Serial port %s successfully reconfigured.\n"), pcCommPort);
   CloseHandle(hcom);
   return (0);
}

And this is the code for the reciever itself.

/* File receiver/decrypter for transmitter.exe written in asm86 that decrypts a text output sent over com1
  */

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define FEND 0xFF

int main(void)
{
       char wmode[] = "wb";
       char rmode[] = "rb";
       char filename[255];
	   char filepath[]="\nType the full filepath and filename of where you would like to save the file.\n->";
       char portname[] = "COM1";
       char error[] = "\nFile has failed to open\n";
       char error1[] = "\nThe com port has failed to open\n";
	   char success[] = "\nFile opened succesfully\n";				//success and error messages for opening com ports
       char success2[] ="\nCom port opened succesfully\n";
       char recieved[] = "\nFile received\n";
	   char requestkey[] = "Please Enter 8 character passkey\n->";
	   char scanparam[] = "%8s";
	   char scanparam1[] = "%255s";
	   int password[8];

	
       FILE * fileptr;
       FILE * portptr;


__asm
{

/*get file path*/

		lea eax, filepath  //load effective address of filepath string
		push eax	  //push onto stack
		call DWORD PTR (printf)	//call printf, using filepath as parameter.
		add esp,4		//scrub stack
		lea eax, filename      //load address of character array password
		push eax		//push onto stack
		lea eax, scanparam1  //load address of scanparam to general register
		push eax	   //push to stack
		call DWORD PTR (scanf)	//call scanf with using values pushed to stack
		add esp,8		//scrub from stack
/*get password*/
		lea eax, requestkey	//load effective address of requestkey string
		push eax		//push onto stack
		call DWORD PTR (printf)	//call printf, using requestkey as parameter.
		add esp,4		//scrub call off stack
		lea eax, password	//load address of character array password
		push eax		//push onto stack
		lea eax, scanparam	//load address of scanparam to general register
		push eax		 //push to stack
		call DWORD PTR (scanf)	//call as paramater to scanf
		add esp,8		//scrub from stack



/*declare file write mode and open*/
               lea eax,wmode	//load effective address of wmode into eax
               push eax				//push to stack
               lea eax,filename		//load effective address of filename
               push eax			//push to stack
               call DWORD PTR (fopen)	//open data file for reading with parameters wb and chosen filename
               add esp,8	//scrub parameters from stack
               mov ebx, eax //mov eax to ebx so it can be store in filepointer later
	       or eax,eax   //check fopen has returned a value to show succes
	       jnz fileOpened //jump to fileOpened if not zero
               lea eax,error	//print error and jump to endit
               push eax
               call printf                
               add esp, 4
               jmp endit

fileOpened:	   lea eax, success //load effective address of success string
		   push eax		//push onto stack
		   call DWORD PTR (printf)//call printf, using requestkey as parameter.
	           add esp,4	//scrub call of stack		
	           mov DWORD PTR(fileptr),ebx	//put value returned by fopen into filept
               lea eax, rmode	//load read address mode into eax
               push eax		//push onto stack
               lea eax,portname	//load portname and push onto stack
               push eax
               call DWORD PTR (fopen) //using parameters pushed onto stack open com port
               add esp,8	//scrub parameters from stack
               or eax,eax    //check that file has been succesfully opened (returns value not null)
               jnz portOK 	//jump to port ok
               lea eax,error1  	//load address of error one and push onto stack
               push eax					
               call DWORD PTR (printf)	// call function print f and print error1
               add esp,4   	//scrub stack
               mov eax,DWORD PTR(fileptr) //move fileptr to eax then push to stack 
               push eax
               call DWORD PTR(fclose)	// call function fclose with parameter file pointer
               add esp,4	// closing file then jump to endit
               jmp endit

portOK:        mov DWORD PTR(portptr),eax//store addres of comport in portptr
	    lea eax, success2	//load effective address of requestkey string
	   push eax		//push onto stack
           call DWORD PTR (printf)	//call printf, using requestkey as parameter.
	    add esp,4			//scrub call off stack
				
			   
	   mov ebx,0	//set ebx to zero for decrypt counter loop
           mov ecx,0 	//set ecx to 0 for EOF character loop
more:     push ecx	//push ecx to stack so it remains unchange by fgetc
	  mov eax, DWORD PTR(portptr) //move com port address to eax
          push eax			//push to stack
	call DWORD PTR(fgetc)	//call fgetc with com port address as parameter to get character from com port
               
         add esp,4	//scrub stack
        pop ecx  	//pop eof loop counter off of stack  
        cmp al, FEND	//cmp recieved hex character to FEND
        jz endofile	//If zero(the same) jump to endofile
        cmp ecx,0	//compare eof counter to zero
        jz more1	//if not zero dec 1, if zero skip(so does not become minus)
        dec ecx		//this step is skipped each time eof
more1:   push ecx	/push ecx to stack so it can be freely used by deCrypt
        mov ecx, ebx	//move deCrypt counter to ecx
       mov ebx, eax    //move character retrieved by fgetc to ebx
      call deCrypt

/*write*/
	   mov eax, DWORD PTR(fileptr)	//mov filepointer to eax
	push ecx   //push ecx(nowdecrypt loop counter) to stack so not lost by function call
        push eax		//push file address and character to stack to be used by fputc
        push ebx
        call DWORD PTR(fputc)
        add esp,8	//scrub the parameters from stack
        pop ebx		//push decrypt loop counter to ebx 
        pop ecx    	//push eof counter to ecx
        jmp more	//return to begining of more with incremented count values
deCrypt:		
        cmp ecx,1	//perform rotate on first 4 characters of password then
        ja decrypt2	// use first character to xor with character from com port
        rol password[0], 8	// Do this until decrypt count is 2
        mov edx, password[0]	// when deCrypt is called and counter is already 3 skip to decrypt2
       xor bl, dl
       add ecx,1
       ret	//return to where function was called from
decrypt2:
	cmp ecx,3   // same as deCrypt but rotate characters 2-5 until count is 4	
	ja  decrypt3//when deCrypt2 is called and counter is already 4 skip to decrypt3
	rol password[2], 8
	mov edx,password[2]
	xor bl, dl
	inc ecx
	ret	//return to where function was called from
decrypt3:
	inc ecx	//same as previous but for characters 4-7
	rol password[4],8// performs rotate and xor until ecx = 7 
	mov edx,password[4]
	xor bl,dl
	cmp ecx,7  //if ecx is not 7 skip return to 0 step
	jb decrypt4
	mov ecx, 0 //when ecx is 7 return counter to 0
decrypt4:
	ret	// return to where function was call from


			
  
			  
endofile:	 
			  inc ecx		//increment eof loop counter	
			  cmp ecx,   	//return to more1 until eof character found 4 consequetive times(reduce chance of incorrect exit to negligle)
			  jnz more1


finished:	  lea eax,recieved // display file recieved message
               push eax
               call DWORD PTR printf
               add esp,4

               mov eax, DWORD PTR(fileptr) // close the file
               push eax
               call DWORD PTR(fclose)               
               add esp,4

              mov eax, DWORD PTR(portptr)		//close the com port
               push eax
               call DWORD PTR(fclose)               
               add esp,4
	
										
	   push 5000//wait for 5 seconds before program close so messages can be seen,(for if not running from command prompt.)
	   call DWORD PTR(Sleep)



endit:			
	xor eax, eax	//clear all general registers		
	xor ebx, ebx
	xor ecx, ecx
	xor edx, edx

} //asm
 return 0;
} // main[}

I'm not going to be able to help with the details of the asm code (is there a reason why it's programmed in asm?) but I have a bit of know-how on serial ports. Did you try to implement the receiver in C++ code? From what I see (from the comments of the asm code) there is no parts that set up the receiver's serial port config (baudrate, parity, checksum, etc.). This needs to be in the receiver code too, just like in the transmitter's code.

One way to avoid going into hyperterminal to set up the port all the time, is by setting it up in the Windows Device Manager (I know it's not a nice solution, but at least you don't have to reconfigure with hyperterminal all the time).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.