Domanda

Sto avendo problemi di connessione a una Pipe con Nome (in questo caso un fast cgi named pipe) Secondo MSDN, dovrebbe usare CreateFile() o CallNamedPipe() (appartamento C API, sincrono - no overlapped I/O) http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

Ma io sono sempre INVALID_HANDLE_VALUE e quando ho GetLastError() è pari a zero!?

Sto anche chiedendo se posso enumerare tutte le named pipe con un . chiamata di un certo tipo e quindi analizzare quello che sto cercando:"\.\pipe\FastCGI\"

e qualcuno ha esperienza con questi commenti:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/225878

È stato utile?

Soluzione 4

Utilizzando la funzione non documentata:

// NtQueryDirectoryFile(
// NEL GESTIRE FileHandle, // handle del file
// NEL GESTIRE EventHandle OPZIONALE,
// IN PIO_APC_ROUTINE ApcRoutine OPZIONALE,
// IN PVOID ApcContext OPZIONALE,
// OUT PIO_STATUS_BLOCK IoStatusBlock,
// OUT PVOID Buffer, // puntatore al buffer di ricevere il risultato
// IN ULONG BufferLength, // lunghezza del Buffer
// IN FILE_INFORMATION_CLASS InformationClass,// tipo di informazioni
// IN BOOLEAN ReturnByOne, // ogni chiamata restituisce informazioni per un solo file
// IN PUNICODE_STRING FileTemplate OPZIONALE, // template per la ricerca
// IN BOOLEAN Reset / riavvio di ricerca
// );

Altri suggerimenti

problema sta qui:


    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);   
    }   

appena dopo il "while(1)" permette di verificare se il AccantoEntryOffset == 0 questo significa che l'ultima voce non viene mai segnalato, spostare il "se(...) break;" dopo il "wprintf(...)" chiamata e si dovrebbe essere in grado di enumerare tutti i tubi.

MODIFICA
Per quelli di voi che vorrebbero il codice sorgente completo (senza la necessità di DDK) è qui.Si prega di notare che questo non è il mio codice ed è stato trovato qui.L'unico cambiamento tra questo codice e originale è il bug fix, come descritto sopra.

EDIT v2.0
Trovato un altro bug nel codice riportato di seguito.Come si va a stampare le informazioni per l'elemento corrente è scorrere, inserisce un carattere null alla fine del nome.Questo carattere null effettivamente sovrascrive i primi 2 byte per la voce successiva, cosa che accade solo a sovrascrivere il 2 byte meno significativi del 'NextEntryOffset' variabile in ingresso (in genere derivanti rendendolo uguale a 0), quindi solo i primi 2 elementi sono tutti numerati da ogni 'NtQueryDirectoryFile' chiamata.

Ho aggiunto un fix per il codice riportato di seguito che dovrebbe risolvere questo problema (memorizzare il WCHAR essere cancellato e quindi il ripristino dopo la stampa.Po ' di trucco, ma questo è solo un esempio di codice, per una corretta attuazione, sia per evitare l'uso di wprintf per stampare il nome, o copia di un altro buffer che si può tranquillamente NULL fine).



// pipelist.cpp (Windows NT/2000)   
//   
// This example will show how you can enumerate all named pipes   
// active on a system.   
//   
// (c)2000 Ashot Oganesyan K, SmartLine, Inc   
// mailto:ashot@aha.ru, http://www.protect-me.com, http://www.codepile.com   

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

#define FileDirectoryInformation 1   
#define STATUS_NO_MORE_FILES 0x80000006L   

typedef struct   
{   
    USHORT Length;   
    USHORT MaximumLength;   
    PWSTR  Buffer;   
} UNICODE_STRING, *PUNICODE_STRING;   

typedef struct   
{   
    LONG Status;   
    ULONG Information;   
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;   

typedef struct {   
    ULONG NextEntryOffset;   
    ULONG FileIndex;   
    LARGE_INTEGER CreationTime;   
    LARGE_INTEGER LastAccessTime;   
    LARGE_INTEGER LastWriteTime;   
    LARGE_INTEGER ChangeTime;   
    LARGE_INTEGER EndOfFile;   
    LARGE_INTEGER AllocationSize;   
    ULONG FileAttributes;   
    ULONG FileNameLength;   
    union {   
        struct {   
            WCHAR FileName[1];   
        } FileDirectoryInformationClass;   

        struct {   
            DWORD dwUknown1;   
            WCHAR FileName[1];   
        } FileFullDirectoryInformationClass;   

        struct {   
            DWORD dwUknown2;   
            USHORT AltFileNameLen;   
            WCHAR AltFileName[12];   
            WCHAR FileName[1];   
    } FileBothDirectoryInformationClass;   
    };   
} FILE_QUERY_DIRECTORY, *PFILE_QUERY_DIRECTORY;   


// ntdll!NtQueryDirectoryFile (NT specific!)   
//   
// The function searches a directory for a file whose name and attributes   
// match those specified in the function call.   
//   
// NTSYSAPI   
// NTSTATUS   
// NTAPI   
// 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   
// );   
typedef LONG (WINAPI *PROCNTQDF)( HANDLE,HANDLE,PVOID,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,   
                                  UINT,BOOL,PUNICODE_STRING,BOOL );   

PROCNTQDF NtQueryDirectoryFile;   

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


    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)   
       {
          // Store old values before we mangle the buffer
          const int endStringAt = TmpInfo->FileNameLength/sizeof(WCHAR);
          const WCHAR oldValue = TmpInfo->FileDirectoryInformationClass.FileName[endStringAt];

          // Place a null character at the end of the string so wprintf doesn't read past the end
          TmpInfo->FileDirectoryInformationClass.FileName[endStringAt] = NULL;   

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

          // Restore the buffer to its correct state
          TmpInfo->FileDirectoryInformationClass.FileName[endStringAt] = oldValue;

          if(TmpInfo->NextEntryOffset==0)   
            break;   

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

       bReset = FALSE;   
   }   

   delete DirInfo;   
   CloseHandle(hPipe);   
}   

Se si desidera un compilato strumento che può fare questo per voi, date un'occhiata a "PipeList" da SysInternals (di proprietà di Microsoft).

Scarica Qui

Sei in fuga il nome di pipe correttamente?Dovrebbe apparire come: \\\\.\\pipe\\FastCGI

Vedere la Named Pipe Client Demo per ulteriori informazioni.

La prima barra rovesciata del tubo nome è stato tagliato fuori dal software del forum.Il nome di pipe è:

\\.\pipe\test

(Non ha bisogno di essere sfuggito nella lingua che sto usando per i test)

Ho scritto due applicazioni, una per tubo server, un client di pipe a prova di blocco ecc Funzionano perfettamente.

Ho creato il tubo con:

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 

Non ritorno INVALID_HANDLE_VALUE, ma un handle valido che io uso successivamente e funziona perfettamente Il blocco come previsto e comunicare bene.

Ok, ho trovato un altro bug nel codice che viene utilizzato per generare il tubo elenco (dettagli nel post il primo bug).

Per quanto riguarda le informazioni nel link seguente "e qualcuno ha esperienza con questi commenti", ho capito di cosa stanno parlando, potrebbe essere un po 'più specifiche su ciò che non hai capito o siete curiosi di sapere (la parte di non essere in grado di fare non le operazioni di blocco è un po' una bugia btw, anche se la sua non è fatto nel modo "tradizionale" di sistemi unix).

Grazie per la cattura di che.Ho convertito questo codice ad un altro C come linguaggio e usati:FILE_NAMES_INFORMATION come sto solo cercando i nomi

Ho poi creato una named pipe con un'altra domanda:

 \\.\pipe\test
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top