tags:

views:

1514

answers:

8

I am having trouble connecting to a Named Pipe (in this case a fast cgi named pipe) According to MSDN, I should be using CreateFile() or CallNamedPipe() (flat C API, synchronous - no overlapped I/O) http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

Yet I am getting INVALID_HANDLE_VALUE and when I GetLastError() it is zero!?

I am also wondering if I can just enumerate all the named pipes with a . call of some sort and then parse out the one I am looking for: "\.\pipe\FastCGI\"

and does anyone have experience with these comments: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/225878

A: 

Are you escaping the pipe name properly? It should look like: \\\\.\\pipe\\FastCGI

See the Named Pipe Client Demo for more information.

Kevin
+1  A: 

Using the undocumented function:

// NtQueryDirectoryFile(
// IN HANDLE FileHandle, // handle to the file
// IN HANDLE EventHandle OPTIONAL,
// IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
// IN PVOID ApcContext OPTIONAL,
// OUT PIO_STATUS_BLOCK IoStatusBlock,
// OUT PVOID Buffer, // pointer to the buffer to receive the result
// IN ULONG BufferLength, // length of Buffer
// IN FILE_INFORMATION_CLASS InformationClass,// information type
// IN BOOLEAN ReturnByOne, // each call returns info for only one file
// IN PUNICODE_STRING FileTemplate OPTIONAL, // template for search
// IN BOOLEAN Reset // restart search
// );

Mike Trader
You still need to escape the backslashes. The demo is written in C and it too escapes them.
Kevin
correct. I use C because it is the defacto language but I use another language to implement that does not require escaping backslashes.
Mike Trader
A: 

The following Code will detect some pipes, but not my named pipe.

void main(void)
{
LONG ntStatus;
IO_STATUS_BLOCK IoStatus;
HANDLE hPipe;
BOOL bReset = TRUE;
PFILE_QUERY_DIRECTORY DirInfo,
TmpInfo;

 WCHAR ff[1];

 int a =  sizeof(FILE_QUERY_DIRECTORY);

 NtQueryDirectoryFile = (PROCNTQDF)GetProcAddress(   
                                   GetModuleHandle("ntdll"),   
                                   "NtQueryDirectoryFile"   
                                   );   

 if (!NtQueryDirectoryFile)   
    return;   

 hPipe = CreateFile("\\\\.\\Pipe\\",GENERIC_READ,   
                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,   
                    NULL,OPEN_EXISTING,0,NULL);   

if(hPipe == INVALID_HANDLE_VALUE)   
  return;   

DirInfo = (PFILE_QUERY_DIRECTORY) new BYTE[1024];   

printf("Pipe name (Number of instances, Maximum instances)\n\n");   
while(1)   
{   
    ntStatus = NtQueryDirectoryFile(hPipe,NULL,NULL,NULL,&IoStatus,DirInfo,1024,   
                                    FileDirectoryInformation,FALSE,NULL,bReset);   

    if (ntStatus!=NO_ERROR)   
    {   
       if (ntStatus == STATUS_NO_MORE_FILES)   
          break;   

       return;   
    }   

    TmpInfo = DirInfo;   
    while(1)   
    {   
       if(TmpInfo->NextEntryOffset==0)   
         break;   

       TmpInfo->FileDirectoryInformationClass.FileName[TmpInfo->FileNameLength/sizeof(WCHAR)] = NULL;   

       wprintf(L"%s (%d, %d)\n",TmpInfo->FileDirectoryInformationClass.FileName,   
                                TmpInfo->EndOfFile.LowPart,   
                                TmpInfo->AllocationSize.LowPart );   

       TmpInfo = (PFILE_QUERY_DIRECTORY)((DWORD)TmpInfo+TmpInfo->NextEntryOffset);   
    }   

    bReset = FALSE;   
}   

delete DirInfo;   
CloseHandle(hPipe);

}

How do I detect ALL pipes?

Mike Trader
+1  A: 
Grant Peters
A: 

Thank you for catching that. I converted this code to another C like language and used: FILE_NAMES_INFORMATION as I am only looking for the names

I then created a named pipe with another application:

 \\.\pipe\test
Mike Trader
A: 

The first backslash of the pipe name was cut off by the forum software. The pipe name is:

\\.\pipe\test

(It does not need to be escaped in the language I am using for testing)

I wrote two applications, one a pipe server, one a pipe client to test blocking etc They work perfectly.

I create the pipe with:

Pipe_Name      = "\\.\pipe\test"
MaxInstances   = 1
OutBufferSize  = 1024
InBufferSize   = 1024

hPipe = CreateNamedPipe(_
Pipe_Name, _                                     ' Name of the Pipe
PIPE_ACCESS_DUPLEX, _                            ' Specifies the pipe access/overlapped/write-through/security access modes 
PIPE_TYPE_MESSAGE OR PIPE_READMODE_MESSAGE, _    ' Specifies the type, read, and wait modes of the pipe handle
MaxInstances, _                                  ' Specifies the maximum number of instances that can be created for this pipe
OutBufferSize, _                                 ' Specifies the number of bytes to reserve for the output buffer
InBufferSize, _                                  ' Specifies the number of bytes to reserve for the input buffer
0, _                                             ' Specifies the default time-out value, in milliseconds
Security_Declaration)                            ' Pointer to a SECURITY_ATTRIBUTES structure

It does not return INVALID_HANDLE_VALUE, but a valid handle which I use subsequently and works perfectly They block as expected and communicate fine.

Mike Trader
A: 

If you want a compiled tool that can do this for you, have a look at "PipeList" from SysInternals (owned by Microsoft).

Download Here

Mick
A: 

Ok, I found another bug in the code being used to generate the pipe list (details in the the post about the first bug).

As far as the information in the link following "and does anyone have experience with these comments", I understand what they are talking about, could you be a little more specific about what you don't understand or are curious about (the part about not being able to do non-blocking operations is a bit of a lie btw, though its not done in the "traditional" way of unix systems).

Grant Peters
Thanks Grant. Did you get my email?
Mike Trader
Yeah, that helped lead me in the right direction, seeing that they were both wrong, but neither returned the same value led me to play with a few values which eventually revealed the problem.
Grant Peters

related questions