Thread: Mailslots anyone?

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    4

    Mailslots anyone?

    Hiya guys, so here's the deal:

    I have to make a small program in which a first program launches 3 other programs which will print a,b,c in synchroniziation. Like you start my main.exe (or something) which launches 3 other dos boxes where the first one wil print an A, then the second one prints an A and finally the third one prints an A, after it the same story only with the letter B, and so on and so forth.

    anonytmouse helped me somewhat in this thread: http://cboard.cprogramming.com/showt...threadid=50041

    So what i currently have is this:

    Here is the C-file from my program which will print the characters and needs to contain a mailslot:

    Code:
    #include "stdio.h"
    #include "windows.h"
    
    void showChar(char character)
    {  
    	printf("character= %c \n",character); 	
    }
    
    int main(int argc,char * argv[]){	
        
    HANDLE hSlot = CreateMailslot("\\\\.\\mailslot\\msname", 0,  MAILSLOT_WAIT_FOREVER,  NULL);
    
    while (TRUE)
    {
      ReadFile(hSlot, buf, sizeof(buf), &dwRead, NULL);	// receive message from master.
      showChar(buf);// print what the master has told us to.
    }	
    return 0;
    }
    and this is the code for the 'main' program:
    Code:
    #include <windows.h>
    #include <iostream>
    
    void main()
    
    {
      // Set the startup information
      STARTUPINFO startup_info = {0};
      startup_info.cb = sizeof startup_info;
      PROCESS_INFORMATION pi = {0};
      character = 'a';
    
      // Create the process
      CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
    				"D:\\ipc\\opdracht\\debug\\printer.exe", 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
      
      CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
    				"D:\\ipc\\opdracht\\debug\\printer.exe", 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
      
      CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
    				"D:\\ipc\\opdracht\\debug\\printer.exe", 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
    
    	// Connect to mailslots.
    	hSlot1 = CreateFile("\\\\.\\mailslot\\msname",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    
    	// Write to mailslots what you want them to output.
    	WriteFile(hSlot1, character, sizeof(character),(LPDWORD) &n,NULL);
    }
    So my main concern now are:
    - giving the mailslots different names, how would this best be done? Simply by passing the name as an argument in the command line?
    - variable 'character' needs to be upped by one after all three sub-programs have printed the a.... would this imply i need to listen to mailslots in the sub program as wel?

    Help a fellow out!

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Before you continue you need to get the code you have to compile and run.

    Start by creating one output process(comment out the two other calls to CreateProcess) and getting that to work. Once you have got one output process working and are comfortable with mailslots you can worry about the other two.

    You have the 'correct' code to get one output process working once you have made your code compilable.

    Once you have one working, or if you have trouble compiling it or getting it to work please post back.

    Usage of CreateProcess:
    Code:
      CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
    				"Arguments go here", 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);

  3. #3
    Registered User
    Join Date
    Mar 2004
    Posts
    4
    Wel, i got the source to compile in both programs now. But when i start the program is simply prints: Character = ( while TRUE...

    So im guessing there is something wrong with the mailslotconnection.... I just cant put my finger on it. I think its either A) the main program doesn't send the attributes correctly over the command line or B) the output program doesnt read it correct.

    This is the code so far:
    Main program:
    Code:
    #include <windows.h>
    #include <iostream>
    
    void main()
    
    {
      // Set the startup information
      HANDLE hSlot1;
      STARTUPINFO startup_info = {0};
      PROCESS_INFORMATION pi = {0};
    
      startup_info.cb = sizeof startup_info;
    
      int n;
      char toPrint = 'a';
      char msname[30] = "";
    
      // Create the process
      /*strcpy(msname, "slot1");
    	CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
    				"D:\\ipc\\opdracht\\debug\\printer.exe", 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
      
        strcpy(msname, "slot2");
    	CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
    		  		"D:\\ipc\\opdracht\\debug\\printer.exe", 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);*/
      
        strcpy(msname, "slot3");
    	CreateProcess("D:\\ipc\\opdracht\\debug\\print.exe", 
    				msname, 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
    
    	// Connect to mailslots.
    	hSlot1 = CreateFile(strcat("\\\\.\\mailslot\\",msname),GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    
    	// Write to mailslots what you want them to output.
    	WriteFile(hSlot1, &toPrint, sizeof(toPrint),(LPDWORD)&n,NULL);
    
    	CloseHandle(hSlot1);
    }
    - with the question wether the mailslot name (slot3) is correctly transferred.
    - If the character toPrint (a for now) is correctly transferred
    - Is the (LPDWORD)&n in the writeFile correct, i just made an var named n and then converted it in the function to a LPDWORD which seems to work for compilation, but i dont know if i need to use n somewhere....

    These are the concerns for my main program, but there is more yet, here is the source for the output program. Which compiles also .

    Code:
    #include "stdio.h"
    #include "windows.h"
    
    void showChar(char * character)
    {  
    	printf("character= %c \n",&character); 	
    }
    
    int main(int argc,char * argv[]){	
        
    	int dwRead;
    
    	HANDLE hSlot = CreateMailslot(argv[1], 0,  MAILSLOT_WAIT_FOREVER,  NULL);
    
    	while (TRUE)
    	{
    		ReadFile(hSlot, argv[1], sizeof(argv[1]), (LPDWORD)&dwRead, NULL);	// Receive message from master.
    		showChar(??);										// print what the master has told us to.
    	}
    	return 0;
    }
    And here i have the following mysteries:
    - instead of an n like in the main program i here used a var dwRead which isnt used anywhere, but i cant figure out IF i need it anywhere....
    - i created the mailslot and am trying to retrieve information, but i am doubting if the name i gave in the main program came through...
    - an finally: i want to use showChar to print the character i specified in the main program, but how should i make this clear to the function? I dont think i can use arg[1] since that would be the name of the mailslot... right? I guess either argv[1] is OR the mailslot name OR the character to print... but i cant figure out the precise what and how...

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    I think you could do with some more experience in basic C before tackling advanced topics such as mailslots.

    See comments and bolded sections inline.

    Master:
    Code:
    #include <windows.h>
    #include <iostream>
    
    int main()
    {
    	HANDLE hSlot1, hSlot2, hSlot3;
    	STARTUPINFO startup_info = {0};
    	PROCESS_INFORMATION pi   = {0};
    
    	startup_info.cb = sizeof startup_info;
    
    	DWORD dwWritten; /* WriteFile wants a LPDWORD - give it one. ie. address of dwWritten. */
    
    	char toPrint = 'a';
    
    	CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
    				" \\\\.\\mailslot\\slot1", /* Pass the COMPLETE mailslot name here */
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
      
    	CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
    		  		" \\\\.\\mailslot\\slot2", 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
      
    	CreateProcess("D:\\ipc\\opdracht\\debug\\print.exe", 
    				" mailslot 3 name here", 
    				NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
    
    	/* strcat("\\\\.\\mailslot\\",msname) will NOT work.
    	 * Just use string literal mailslot names for now. */
    
    	hSlot1 = CreateFile("\\\\.\\mailslot\\slot1", GENERIC_WRITE, FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    
    	/* Complete these lines.
    	  hSlot2 = CreateFile("\\\\.\\mailslot\\slot2", ...);
    	  hSlot3 = ...
    	 */
    
    	WriteFile(hSlot1, &toPrint, sizeof(toPrint), &dwWritten, NULL);
    
    	/* Complete these lines.
    	  WriteFile(hSlot2, ...);
    	  WriteFile(hSlot3, ...);
    	 */
    
    	CloseHandle(hSlot1);
    
    	/* Close hSlot2 and hSlot3 also. */
    
    	return 0;
    }
    Output Program:
    Code:
    #include <stdio.h> /* For standard headers use <...> */
    #include <windows.h>
    
    void showChar(char character) /* We take a single character as argument. */
    {  
    	printf("character= %c \n", character); 	/* Print the single character. */
    }
    
    int main(int argc,char * argv[]){	
        
    	DWORD dwRead; /* ReadFile wants a LPDWORD so give it the address of a DWORD - not an int. */
    
    	/* As we have fixed the master program we know that argv[1] should contain
    	 * the COMPLETE mailslot name.
    	 * Check this by printing argv[1] with printf. */
    
    	printf("Mailslot name: %s\n", argv[1]);
    
    	HANDLE hSlot = CreateMailslot(argv[1], 0, MAILSLOT_WAIT_FOREVER, NULL);
    
    	while (TRUE)
    	{
    		/* We can not use argv[1] as our buffer for ReadFile.
    		 * We must create our own.  */
    		char buf[32];
    
    		ReadFile(hSlot, buf, sizeof(buf), &dwRead, NULL); /* Read into buf. */
    		showChar(buf[0]); /* Print the first character in buf. */ 
    	}
    	return 0;
    }
    >>- with the question wether the mailslot name (slot3) is correctly transferred.<<
    You were not transferring the complete mailslot name. This meant the mailslot was not being created.

    >>- Is the (LPDWORD)&n in the writeFile correct, i just made an var named n and then converted it in the function to a LPDWORD which seems to work for compilation, but i dont know if i need to use n somewhere....<<
    I have renamed n to dwWritten for clarity. It must be provided to WriteFile so that it can return how many characters are actually written.

    >>- instead of an n like in the main program i here used a var dwRead which isnt used anywhere, but i cant figure out IF i need it anywhere....<<
    It must be provided to ReadFile, even if you do not need the value that is returned.

    >>- i created the mailslot and am trying to retrieve information, but i am doubting if the name i gave in the main program came through...<<
    I have added a printf to print out argv[1] so you can check this.

    >>- an finally: i want to use showChar to print the character i specified in the main program, but how should i make this clear to the function? I dont think i can use arg[1] since that would be the name of the mailslot... right? I guess either argv[1] is OR the mailslot name OR the character to print... but i cant figure out the precise what and how...<<
    As mentioned in my comments you can not use argv[1] as the buffer you pass to ReadFile.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mailslots usage
    By Lionel in forum Windows Programming
    Replies: 0
    Last Post: 05-14-2005, 03:05 AM
  2. Aargh mailslots and the like!!
    By Frietbakker in forum C++ Programming
    Replies: 2
    Last Post: 03-02-2004, 11:40 AM