Thread: pipe failure problem between Win7 & XP

  1. #1
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24

    pipe failure problem between Win7 & XP

    Hello everyone,

    I have run into a very peculiar problem while trying to run a client/server app on a small wireless LAN using Windows named pipes.

    When the server is the Win7 box and the client is the XP box the app runs perfectly. When, however, the server is the XP box and the client is the Win7 box, the Win7 machine cannot successfully call CreateFile and open the pipe. The message back from the OS is "invalid file handle". Moreover, the XP server reports that it is able to create the pipe so the problem seems to be something about named pipes itself when it runs on an XP machine connected to a Win7 client.

    I have turned off windows firewalls on the XP box and the problem persists. Both machines can share files and printers without any problem.

    I would be happy to post the code for the app, but it seemed to me that the code itself is not the source of the problem since the code runs...something else is.

    Any thoughts would be welcome.

    Regards,
    Mark Allyn

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Just because code runs doesn't mean it's right. Please post your code. Also, are you using the same executable on both machines or are you compiling the same code independently on both systems?
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24

    Here is named pipe codee

    Hello Itsme86.

    Thanks for your response. As requested, here is the code, starting with client.

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <assert.h>
    #include <tchar.h>
    #include <string.h>
    
    typedef struct {
    	DWORD Rqlen ;
    	TCHAR Command[10] ;
    	TCHAR Record[80] ;
    	TCHAR Arg1[10] ;
    	TCHAR Arg2[10] ;
    } REQUEST ;
    
    typedef struct {
    	DWORD Rslen ;
    	TCHAR Status[10] ;
    	TCHAR Record[80] ;
    	TCHAR Res1[10] ;
    	
    } RESPONSE ;
    #define RQ_SIZE sizeof(REQUEST) 
    #define RS_SIZE sizeof(RESPONSE) 
    REQUEST Request ;
    RESPONSE Response ;
    DOUBLE result ;
    LPCTSTR PipeName=TEXT("\\\\MarkPC\\pipe\\ThePipe");
    int ConnectToPipe ( void ) ;
    BOOL ConsolePrompt ( LPCTSTR, LPTSTR, DWORD, BOOL) ;
    
    int main(int argc, char * argv[ ])
    {
    
    ConnectToPipe( ) ;
    
    return 0 ;
    
    }
    
    int ConnectToPipe (void) 
    {
    HANDLE hPipe;
    //char buf[100], ReqBuf[100] ;//"Hi Server, it's your client" ; 
    LPCTSTR pPromptMsg="Enter your request: " ;
    BOOL bRet ;
    DWORD dwRead, dwWrite, dwMode = PIPE_READMODE_MESSAGE | PIPE_WAIT ;
    DWORD State, CurInstances, MaxCollectionCount, CollectionDataTimeout, MaxUserNameSize=255 ;
    TCHAR UserName[80] ;
    int i ;
    LPCTSTR UserMsg=TEXT("Func blew up, you rascal you...");
    DWORD ExitCode=99;
    BOOL PrintErrorMsg=TRUE ;
    printf("pipename is %s\n", PipeName) ;
    printf("Size of Request struct is %d and size of Response struct is %d \n", 
    		RQ_SIZE, RS_SIZE) ;
    Sleep(50) ;
    WaitNamedPipe(PipeName, NMPWAIT_WAIT_FOREVER) ;
    
    sprintf(Request.Arg1,"%lf", 23.5 ) ;
    printf("TCHAR version of the first number is %s\n", Request.Arg1) ;
    sprintf(Request.Arg2, "%lf",  45.7 ) ;
    printf("TCHAR version of the second number is %s\n", Request.Arg2) ;
    strcpy(Request.Record, "Nothing to send in record") ;
    
    hPipe= CreateFile(PipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
    	FILE_ATTRIBUTE_NORMAL, NULL) ;
    if(hPipe==INVALID_HANDLE_VALUE)
    	{
    	printf("Pipe Open Failure \n") ;
    	ReportError(UserMsg, ExitCode, TRUE) ;
    	return 1 ;
    	}
    SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) ;
    GetNamedPipeHandleState(hPipe, &State, &CurInstances, &MaxCollectionCount,&CollectionDataTimeout, 
    	UserName, MaxUserNameSize) ;
    printf ("State: %d ; CurInstances: %d ; MaxCollectionCount: %d ; CollectionDataTimeout: %d\n",State, CurInstances, MaxCollectionCount,CollectionDataTimeout) ;
    		
    printf ("UserName: %s ; MaxUserNameSize: %d \n", UserName, MaxUserNameSize ) ;
    		
    ConsolePrompt(pPromptMsg, Request.Command, 512, TRUE) ;
    //for (i=0 ; i <3; i++) 
    	//{
    	bRet=WriteFile(hPipe, &Request, RQ_SIZE, &dwWrite, NULL) ;
    	if (bRet==FALSE)
    		{
    		printf("Write Failed : Bytes Written: %u \n", dwWrite) ;
    		}
    	else printf("Wrote %d bytes to the server \n", dwWrite ) ;
    	FlushFileBuffers(hPipe) ;
    	bRet=ReadFile(hPipe, &Response, RS_SIZE, &dwRead, NULL) ;
    	if (bRet==FALSE) 
    		{
    		printf("Read Failed : Bytes Read: %u \n", dwRead) ;
    		}//break ;
    	//Response.Record[dwRead] = 0;
    	printf("Server Says: %s\n", Response.Record ) ;
    	result = atof(Response.Res1) ;
    	printf("Server results from %s command are: %lf \n", Request.Command, result ) ;
    
    	//}
    DisconnectNamedPipe (hPipe) ;
    CloseHandle(hPipe) ;
    return 0 ;
    }
    Now for the server.

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <assert.h>
    #include <tchar.h>
    #include <string.h>
    
    LPCTSTR PipeName ="\\\\.\\pipe\\ThePipe";
    
    int MaxServers = 1 ;
    
    typedef struct{
    	DWORD Rqlen ;
    	TCHAR Command[10] ;
    	TCHAR Record[80];
    	TCHAR Arg1[10] ;
    	TCHAR Arg2[10] ;
    } REQUEST ;
    
    typedef struct{
    	DWORD Rslen ;
    	TCHAR Status[10] ;
    	TCHAR Record[80] ;
    	TCHAR Res1[10] ;
    } RESPONSE ;
    
    #define RQ_SIZE sizeof(REQUEST) 
    #define RS_SIZE sizeof(RESPONSE)
    RESPONSE Response;
    REQUEST Request ;
    DOUBLE first, second, result ;
    
    BOOL ConnectToClient(HANDLE, char *) ;
    
    
    
    int main(int argc, char *argv[] ) 
    {
    int i ;
    HANDLE hPipe ;
    BOOL bRet ;
    if (argc !=2)
    	{
    	printf("usage: Server <ServerName>\n");
    	return 1 ;
    	}
    hPipe=CreateNamedPipe(PipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH,
    	PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE |PIPE_WAIT, MaxServers, 512, 512, 1000, NULL);
    assert(hPipe != INVALID_HANDLE_VALUE) ;
    //for (i = 0; i <100; i++)
    	//{
    	ConnectToClient(hPipe, argv[1]);
    	//}
    //bRet=DisconnectNamedPipe(hPipe) ;
    CloseHandle(hPipe );
    return 0;
    }
    
    BOOL ConnectToClient(HANDLE hPipe, char *ServerName)
    {
    int i, len,S1 ;
    BOOL bRet ;
    DWORD dwWrite, dwRead ;
    //char buf[100], ReqBuf[100] ;
    bRet=ConnectNamedPipe(hPipe, NULL) ;
    assert(bRet==TRUE);
    for (i = 0;i < 1;i++)
    	{
    	ReadFile(hPipe, &Request, RQ_SIZE, &dwRead, NULL) ;
    	if (bRet==TRUE)
    		{
    		printf("Client says: %s \n", Request.Command );
    		first = atof(Request.Arg1) ;
    		second = atof(Request.Arg2) ;
    		printf("value of first variable sent to server is %lf\n", first) ;
    		printf("value of second variable sent to server is %lf\n", second) ;
    		printf("value of command is %s \n", Request.Command ) ;
    		if (strcmp(Request.Command,"ADD") == 0)
    			{
    			S1 = 1;
    			}
    		else if(strcmp(Request.Command,"QUIT")== 0) S1 = 2;
    		printf("The value of the switch variable is %d \n", S1) ;
    		switch(S1) 
    		  {
    		  case 1:
    		  
    		  printf("The values of Arg1 are %lf and Arg2 are %lf\n", 
    			first, second );	
    		  result = first + second;
    		  break;
    		  case 2 :
    		  break;
    		  }
    		}
    		else
    		{
    		printf("Problems reading the client request\n") ;
    		}
    	len=sprintf(Response.Record,"Hello Client From Server %s(msg#%d)\n",
    		ServerName, i );
    	sprintf(Response.Res1, "%lf", result) ;
    	printf("The results of the add request are %s and %lf\n", Response.Res1, result) ;
    	bRet=WriteFile(hPipe, &Response, RS_SIZE, &dwWrite, NULL) ;
    	FlushFileBuffers( hPipe) ;
    	printf("Wrote %d bytes to the client \n", dwWrite) ;
    	if (bRet==FALSE)
    	{
    	printf("Problems writing to the client\n" );
    	break;
    		
    	}
    }
    printf("Sent Mesg from %s: %s\n",ServerName, Response.Record);
    
    bRet=DisconnectNamedPipe(hPipe);
    
    //CloseHandle(hPipe) ;
    return TRUE;
    }
    Finally, you raise an interesting question regarding where the code is compiled and linked. The answer is that I have built the executables separately, at least to this point. The compiler/linkers are the same (cl and link, respectively) and they both are from the same distribution of VC Express. But, I take your point as to how they might be compiled differently on the two OSs. I will check your suggestion.

    Thanks very much,
    Mark

  4. #4
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I could be wrong, but I believe you're supposed to call WaitNamedPipe() after CreateFile() returns INVALID_HANDLE_VALUE. I'm not sure if you've viewed this webpage already, but you might find it useful: Named Pipe Client (Windows)
    If you understand what you're doing, you're not learning anything.

  5. #5
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24

    Yes, I had read the MSDN pages on Named Pipe

    Hello Itsme86,

    As it turns out, I had read the MSDN page you noted. I noticed the same thing you did, but I have not tried to use waitnamedpipe() AFTER the createfile() call, and perhaps it does make a difference depending upon which OS is used.

    The model that I followed when I wrote my stuff was a code snippet written by Johnson Hart (3rd edition of "Windows System Programming", pages 324-325) in which he calls waitnamedpipe() BEFORE the call to CreateFile(). The Hart snippet was written before Win7 (and maybe even before XP!).

    It's an easy experiment to conduct, however, and I will try it out. I will be doing the experiment you suggested concerning using the same executable on the XP as I'm using on the Win7 machine.

    Regards,
    Mark

  6. #6
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24

    Update on failed experiments

    Hello Itsme (and others)

    I tried two experiments discussed previously.

    1. I ran identical server executable (compiled and linked on the same Win7 machine) on the XP box, and it too failed to provide usable pipe.

    2. I rewrote the server code to conform to the MSDN (library aa365443) doc and this failed to provide a usable pipe to the client, although it did create an instance of a message oriented pipe.

    The client reports a system error 5 ("Access denied") when it tries to access the pipe via CreateFile command.

    What is going on here?

    Mark

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Named pipe problem
    By rahul_c in forum C Programming
    Replies: 3
    Last Post: 10-02-2007, 05:40 PM
  2. Problem with Peer-Peer Networking with XP Pro
    By Davros in forum Tech Board
    Replies: 14
    Last Post: 10-03-2002, 09:09 AM
  3. XP Autoplay problem
    By (TNT) in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 08-09-2002, 08:59 AM
  4. Windows XP Pro Problem!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 11-30-2001, 11:12 PM
  5. problem with output
    By Garfield in forum C Programming
    Replies: 2
    Last Post: 11-18-2001, 08:34 PM