تعداد توجيهات الإخراج المسماة في Windows

StackOverflow https://stackoverflow.com/questions/481759

  •  20-08-2019
  •  | 
  •  

سؤال

أواجه مشكلة في التواصل مع أنبوب اسمه (في هذه الحالة أنبوب CGI سريع المسماة) وفقًا لـ MSDN ، يجب أن أستخدم CreateFile () أو callNamedPipe () (API Flat C ، متزامن - لا يوجد I/O متداخلة)http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

ومع ذلك فإنني أحصل على INVALID_HANDLE_VALUE وعندما أحصل على GetLastError() تكون النتيجة صفرًا!؟

أتساءل أيضًا عما إذا كان بإمكاني تعداد جميع الأنابيب المسماة باستخدام ملف . اتصل من نوع ما ثم قم بتحليل ما أبحث عنه:"\.\pipe\FastCGI\"

وهل لدى أي شخص خبرة في هذه التعليقات:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/225878

هل كانت مفيدة؟

المحلول 4

باستخدام الدالة غير الموثقة:

// نتكويريديركتوريفيل (
// في التعامل مع FileHandle، // التعامل مع الملف
// في المقبض EventHandle اختياري،
// في PIO_APC_ROUTINE ApcRoutine اختياري،
// في PVOID ApcContext اختياري،
// خارج PIO_STATUS_BLOCK IoStatusBlock،
// OUT PVOID Buffer، // مؤشر إلى المخزن المؤقت لتلقي النتيجة
// في طول المخزن المؤقت ULONG، // طول المخزن المؤقت
// في FILE_INFORMATION_CLASS فئة المعلومات، // نوع المعلومات
// في ReturnByOne المنطقية، // تقوم كل مكالمة بإرجاع معلومات لملف واحد فقط
// في PUNICODE_STRING FileTemplate اختياري، // قالب للبحث
// في إعادة تعيين منطقية // إعادة تشغيل البحث
// );

نصائح أخرى

تكمن المشكلة هنا:


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

فقط بعد "بينما (1)" يمكنك التحقق مما إذا كان التاليsequoffset == 0 وهذا يعني أن الإدخال الأخير لم يتم الإبلاغ عنه أبدًا ، حرك "إذا (...) استراحة ؛" إلى بعد مكالمة "wprintf (...)" ، يجب أن تكون قادرًا على تعداد جميع الأنابيب.

تعديل
لأولئك منكم الذين يرغبون في رمز المصدر الكامل (دون الحاجة إلى DDK) هنا. من فضلك لا أن هذا ليس رمزًا الخاص بي وقد تم العثور عليه هنا. التغيير الوحيد بين هذا الرمز والأصل هو إصلاح الأخطاء كما هو مفصل أعلاه.

تحرير v2.0
وجدت خطأ آخر في الكود أدناه. أثناء طبع المعلومات حول العنصر الحالي الذي يكرره ، فإنه يضع حرفًا فارغًا في نهاية الاسم. هذا الحرف الفارغ يكتب فعليًا في أول 2 بايت من الإدخال التالي ، والذي يحدث فقط للكتابة فوق البايتين الأقل أهمية لمتغير "Nextentryoffset" في هذا الإدخال (عادة ما يؤدي إلى ما يساوي 0) ، وبالتالي فإن العناصران الأولان فقط هي كل العناصر الأولى هي كل شيء تم تعداده من كل مكالمة "ntquerydirectoryfile".

لقد أضفت إصلاحًا إلى الكود أدناه الذي يجب حل هذه المشكلة (قم بتخزين WCHAR يتم مسحه ثم استعادته بعد الطباعة. اطبع الاسم ، أو قم بنسخه إلى مخزن مؤقت آخر يمكنك إلغاء نهاية نهاية).



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

إذا كنت تريد أداة تجميعية يمكنها القيام بذلك نيابة عنك ، فقم بإلقاء نظرة على "Pipelist" من Sysinternals (مملوكة لشركة Microsoft).

حمل هنا

هل تهرب من اسم الأنبوب بشكل صحيح؟ يجب أن تبدو مثل: \\\\.\\pipe\\FastCGI

انظر اسم تجريبي العميل المسمى للمزيد من المعلومات.

تم قطع أول عصر خلفي لاسم الأنبوب بواسطة برنامج المنتدى. اسم الأنبوب هو:

\\.\pipe\test

(لا يلزم الهروب من اللغة التي أستخدمها للاختبار)

لقد كتبت تطبيقين ، أحدهما خادم الأنابيب ، أحد عميل الأنبوب لاختبار حظره ، وهما يعملان بشكل مثالي.

أقوم بإنشاء الأنبوب مع:

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 

لا يعيد invalid_handle_value ، ولكن مقبض صالح أستخدمه لاحقًا ويعمل بشكل مثالي يحظره كما هو متوقع ويتواصل بشكل جيد.

حسنًا ، لقد وجدت خطأ آخر في الكود المستخدم لإنشاء قائمة الأنابيب (التفاصيل في المنشور حول الخطأ الأول).

فيما يتعلق بالمعلومات الواردة في الرابط التالي "وهل يتمتع أي شخص بخبرة في هذه التعليقات" ، أفهم ما يتحدثون عنه ، هل يمكن أن تكون أكثر تحديداً بشأن ما لا تفهمه أو فضولي إليه (الجزء إن عدم القدرة على القيام بعمليات غير الحظر هو القليل من الكذبة ، على الرغم من أنه لم يتم القيام به بالطريقة "التقليدية" لأنظمة UNIX).

شكرا لاصطياد ذلك. لقد قمت بتحويل هذا الرمز إلى لغة أخرى مثل اللغة واستخدامها: file_names_information لأنني أبحث فقط عن الأسماء

ثم قمت بإنشاء أنبوب اسمه مع تطبيق آخر:

 \\.\pipe\test
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top