0

I am using CreateNamedPipe. It returns 0XFFFFFFFF but when I call GetLastError and perror I get "NO ERROR".

I have checked https://learn.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-server and I heve coded very similar.

I coded this using an example provided here: https://stackoverflow.com/questions/47731784/c-createnamedpipe-error-path-not-found-3#= and he says it means ERROR_PATH_NOT_FOUND (3). But my address is "\\.\pipe\pipe_com1. Note that StackOverflow seems to remove the extra slashes but you will see them in the paste of my code.

I followed the example here: Create Named Pipe C++ Windows but I still get the error. Here is my code:

//  Create a named pipe
//  It is used to test TcpToNamedPipe to be sore it it is addressing the named pipe

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

    char    ch;
    int main(int nargs,  char** argv)
    {
        if (nargs != 2)
        {
            printf("Usage pipe name is first arg\n");
            printf("press any key to exit ");
            scanf("%c", &ch);
            return -1;
        }

        char buffer[1024];
        HANDLE  hPipe;
        DWORD dwRead;
        sprintf(buffer, "\\\\.\\pipe\\%s", argv[1]);
        hPipe = CreateNamedPipe((LPCWSTR)buffer,
            PIPE_ACCESS_DUPLEX, 
            PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,    // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists... 
            1,
            1024*16,
            1024*16,
            NMPWAIT_USE_DEFAULT_WAIT, 
            NULL);

        if (hPipe == INVALID_HANDLE_VALUE)
        {
            //int errorno = GetLastError();
            //printf("error creating pipe %d\n", errorno);
            perror("");
            printf("press any key to exit ");
            scanf("%c", &ch);
            return -1;
        }

        while (hPipe != INVALID_HANDLE_VALUE)
        {
            if (ConnectNamedPipe(hPipe, NULL) != FALSE)   // wait for someone to connect to the pipe
            {
                while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE)
                {
                    /* add terminating zero */
                    buffer[dwRead] = '\0';

                    /* do something with data in buffer */
                    printf("%s", buffer);
                }
            }

            DisconnectNamedPipe(hPipe);
        }

        return 0;
    }

I'm guessing that the pointer to the address may be wrong and CreateNamedPipe is not seeing the name of the pipe properly. So I used disassembly and notice that the address is in fact a far pointer. Here is that disassembly:

00CA1A45  mov         esi,esp  
00CA1A47  push        0  
00CA1A49  push        0  
00CA1A4B  push        4000h  
00CA1A50  push        4000h  
00CA1A55  push        1  
00CA1A57  push        0  
00CA1A59  push        3  
00CA1A5B  lea         eax,[buffer]  
00CA1A61  push        eax  
00CA1A62  call        dword ptr [__imp__CreateNamedPipeW@32 (0CAB00Ch)] 

Can someone spot my problem?

Aabbee
  • 91
  • 6
  • It looks like `CreateNamedPipe` takes a LPCTSTR as the first argument, but you're casting to LPCWSTR. What happens if you instead pass in something like `TEXT("\\\\.\\pipe\\name")` directly? – flau Jan 29 '20 at 13:26
  • TEXT works. I didn't know about that. Thanks, add it to the solution so you get credit. – Aabbee Jan 29 '20 at 20:40
  • But I need to point to the string that I created in buffer. What you said gave me a clue but I still need to figure out how to make the pointer a LPCTSTR and 00CA1A5B lea eax,[buffer] 00CA1A61 push eax is passing a long pointer which is what TEXT does. – Aabbee Jan 29 '20 at 20:45
  • The doc says the first argument is a wide string LPCWSTR lpName. Maybe I have to convert buffer to a wide string. – Aabbee Jan 29 '20 at 20:51
  • Since this is just a test program to see if my client is getting through, I took the cowards way out and used the TEXT macro with a fixed string. Thanks for your solution. – Aabbee Jan 29 '20 at 21:05
  • I think you could probably just build the cstring with sprintf like you did, then cast/assign to LPCTSTR, but I don't have a Windows machine to test this on. – flau Jan 30 '20 at 09:38

0 Answers0