ZwQuerySystemInformation в Win2000

Тема в разделе "WASM.WIN32", создана пользователем Quark, 15 авг 2008.

  1. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    интересно, что в win2000 эта функция почему-то не считает необходимый размер буфера...

    этот код в ХР возвращает в переменную ul_procinfo_buff_len размер данных, а в Win2000 возвращает 0.
    Код (Text):
    1. ul_status   =   ZwQuerySystemInformation(SystemProcesses, 0, 0, &ul_procinfo_buff_len);
    как получить размер буфера?

    а вообще-то вот что написано в SDK XP:

    [NtQuerySystemInformation is available for use in Windows 2000 and Windows XP. It may be altered or unavailable in subsequent versions. Applications should use the alternate functions listed in this topic.]

    ReturnLength
    [out, optional] Optional pointer to a location where the function writes the actual size of the information requested. If that size is less than or equal to the SystemInformationLength parameter, the function copies the information into the SystemInformation buffer; otherwise, it returns an NTSTATUS error code and returns in ReturnLength the size of buffer required to receive the requested information.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Зависит от инфокласса. В XP тоже не все инфоклассы возвращают необходимый размер буфера.
     
  3. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Смотрите сами. Это часть кода NtQuerySystemInformation, обратите внимание на проверку размера буфера:

    Код (Text):
    1.         case SystemProcessInformation:
    2.  
    3.             if (SystemInformationLength < sizeof( SYSTEM_PROCESS_INFORMATION)) {
    4.                 return STATUS_INFO_LENGTH_MISMATCH;
    5.                 }
    6.  
    7.             Status = ExpGetProcessInformation (SystemInformation,
    8.                                                SystemInformationLength,
    9.                                                &Length,
    10.                                                NULL);
    11.  
    12.             if (NT_SUCCESS(Status) && ARGUMENT_PRESENT( ReturnLength )) {
    13.                 *ReturnLength = Length;
    14.             }
    15.  
    16.             break;
    Таким же образом проверяются параметры и в некоторых других функциях, в т.ч. и в системах Windows XP и Windows Server 2003. Решение простое - передать для начала минимально возможный размер буфера, а не 0. В данном случае это будет sizeof (SYSTEM_PROCESS_INFORMATION).
     
  4. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    SYSTEM_PROCESSES buff;

    ul_status = ZwQuerySystemInformation(SystemProcesses, &buff, sizeof(buff), &ul_procinfo_buff_len);

    ничего не изменилось. по прежднему в ul_procinfo_buff_len 0.
     
  5. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Вот вам код из Windows 2000, разбирайтесь:

    Код (Text):
    1. NTSTATUS
    2. ExpGetProcessInformation (
    3.     OUT PVOID SystemInformation,
    4.     IN ULONG SystemInformationLength,
    5.     OUT PULONG Length,
    6.     IN PULONG SessionId OPTIONAL
    7.     )
    8. /*++
    9.  
    10. Routine Description:
    11.  
    12.     This function returns information about all the processes and
    13.     threads in the system.
    14.  
    15. Arguments:
    16.  
    17.     SystemInformation - A pointer to a buffer which receives the specified
    18.         information.
    19.  
    20.     SystemInformationLength - Specifies the length in bytes of the system
    21.         information buffer.
    22.  
    23.     Length - An optional pointer which, if specified, receives the
    24.         number of bytes placed in the system information buffer.
    25.  
    26.  
    27. Return Value:
    28.  
    29.     Returns one of the following status codes:
    30.  
    31.         STATUS_SUCCESS - normal, successful completion.
    32.  
    33.         STATUS_INVALID_INFO_CLASS - The SystemInformationClass parameter
    34.             did not specify a valid value.
    35.  
    36.         STATUS_INFO_LENGTH_MISMATCH - The value of the SystemInformationLength
    37.             parameter did not match the length required for the information
    38.             class requested by the SystemInformationClass parameter.
    39.  
    40.         STATUS_ACCESS_VIOLATION - Either the SystemInformation buffer pointer
    41.             or the Length pointer value specified an invalid address.
    42.  
    43.         STATUS_WORKING_SET_QUOTA - The process does not have sufficient
    44.             working set to lock the specified output structure in memory.
    45.  
    46.         STATUS_INSUFFICIENT_RESOURCES - Insufficient system resources exist
    47.             for this request to complete.
    48.  
    49. --*/
    50.  
    51. {
    52.     KEVENT Event;
    53.     PEPROCESS Process;
    54.     PETHREAD Thread;
    55.     PSYSTEM_PROCESS_INFORMATION ProcessInfo;
    56.     PSYSTEM_THREAD_INFORMATION ThreadInfo;
    57.     PLIST_ENTRY NextProcess;
    58.     PLIST_ENTRY NextThread;
    59.     PVOID MappedAddress;
    60.     PVOID LockVariable;
    61.     ULONG TotalSize = 0;
    62.     ULONG NextEntryOffset = 0;
    63.     PUCHAR Src;
    64.     PWSTR Dst;
    65.     ULONG n;
    66.     NTSTATUS status = STATUS_SUCCESS;
    67.  
    68.     *Length = 0;
    69.  
    70.     MappedAddress = ExLockUserBuffer( SystemInformation,
    71.                                       SystemInformationLength,
    72.                                       &LockVariable
    73.                                     );
    74.     if (MappedAddress == NULL) {
    75.         return( STATUS_ACCESS_VIOLATION );
    76.     }
    77.     MmLockPagableSectionByHandle (ExPageLockHandle);
    78.     ExAcquireFastMutex(&PspActiveProcessMutex);
    79.  
    80.    
    81.     //
    82.     // Initialize an event object and then set the event with the wait
    83.     // parameter TRUE. This causes the event to be set and control is
    84.     // returned with the dispatcher database locked at dispatch IRQL.
    85.     //
    86.  
    87.     KeInitializeEvent (&Event, NotificationEvent, FALSE);
    88.     try {
    89.      
    90.  
    91.         ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)MappedAddress;
    92.    
    93.  
    94.         if (!ARGUMENT_PRESENT(SessionId)) {
    95.    
    96.            NextEntryOffset = sizeof(SYSTEM_PROCESS_INFORMATION);
    97.  
    98.            TotalSize = sizeof(SYSTEM_PROCESS_INFORMATION);
    99.    
    100.            ExpCopyProcessInfo (ProcessInfo, PsIdleProcess);
    101.    
    102.            //
    103.            // Since Idle process and system process share the same
    104.            // object table, zero out idle processes handle count to
    105.            // reduce confusion
    106.            //
    107.    
    108.            ProcessInfo->HandleCount = 0;
    109.    
    110.            // Idle Process always has SessionId 0
    111.            ProcessInfo->SessionId = 0;
    112.            //
    113.            // Set the event with the wait
    114.            // parameter TRUE. This causes the event to be set and control is
    115.            // returned with the dispatcher database locked at dispatch IRQL.
    116.            //
    117.            // WARNING - The following code assumes that the process structure
    118.            //      uses kernel objects to synchronize access to the thread and
    119.            //      process lists.
    120.            //
    121.    
    122.            KeSetEvent (&Event, 0, TRUE);
    123.    
    124.            //
    125.            // WARNING - The following code runs with the kernel dispatch database
    126.            //      locked. EXTREME caution should be taken when modifying this
    127.            //      code. Extended execution will ADVERSELY affect system operation
    128.            //      and integrity.
    129.            //
    130.            // Get info for idle process's threads
    131.            //
    132.            //
    133.            // Get information for each thread.
    134.            //
    135.    
    136.            ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);
    137.            ProcessInfo->NumberOfThreads = 0;
    138.            NextThread = PsIdleProcess->Pcb.ThreadListHead.Flink;
    139.            while (NextThread != &PsIdleProcess->Pcb.ThreadListHead) {
    140.                NextEntryOffset += sizeof(SYSTEM_THREAD_INFORMATION);
    141.                TotalSize += sizeof(SYSTEM_THREAD_INFORMATION);
    142.    
    143.                if (TotalSize > SystemInformationLength) {
    144.                    status = STATUS_INFO_LENGTH_MISMATCH;
    145.                    KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL);
    146.                    goto Failed;
    147.                }
    148.                Thread = (PETHREAD)(CONTAINING_RECORD(NextThread,
    149.                                                      KTHREAD,
    150.                                                      ThreadListEntry));
    151.                ExpCopyThreadInfo (ThreadInfo,Thread);
    152.    
    153.                ProcessInfo->NumberOfThreads += 1;
    154.                NextThread = NextThread->Flink;
    155.                ThreadInfo += 1;
    156.            }
    157.            
    158.            //
    159.            // Unlock the dispatch database by waiting on the event that was
    160.            // previously set with the wait parameter TRUE.
    161.            //
    162.    
    163.            KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL);
    164.  
    165.            ProcessInfo->ImageName.Buffer = NULL;
    166.            ProcessInfo->ImageName.Length = 0;
    167.            ProcessInfo->NextEntryOffset = NextEntryOffset;
    168.         }
    169.  
    170.         NextProcess = PsActiveProcessHead.Flink;
    171.  
    172.         while (NextProcess != &PsActiveProcessHead) {
    173.             Process = CONTAINING_RECORD(NextProcess,
    174.                                         EPROCESS,
    175.                                         ActiveProcessLinks);
    176.  
    177.             if (ARGUMENT_PRESENT(SessionId) && (Process->SessionId != *SessionId)) {
    178.                NextProcess = NextProcess->Flink;
    179.                continue;
    180.             }
    181.  
    182.             ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)
    183.                             ((PUCHAR)MappedAddress + TotalSize);
    184.  
    185.             NextEntryOffset = sizeof(SYSTEM_PROCESS_INFORMATION);
    186.             TotalSize += sizeof(SYSTEM_PROCESS_INFORMATION);
    187.             if (TotalSize > SystemInformationLength) {
    188.                 status = STATUS_INFO_LENGTH_MISMATCH;
    189.                 goto Failed;
    190.             }
    191.  
    192.             //
    193.             // Get information for each process.
    194.             //
    195.  
    196.             ExpCopyProcessInfo (ProcessInfo, Process);
    197.  
    198.  
    199.             //
    200.             // Set the event with the wait
    201.             // parameter TRUE. This causes the event to be set and control is
    202.             // returned with the dispatcher database locked at dispatch IRQL.
    203.             //
    204.             // WARNING - The following code assumes that the process structure
    205.             //      uses kernel objects to synchronize access to the thread and
    206.             //      process lists.
    207.             //
    208.    
    209.             KeSetEvent (&Event, 0, TRUE);
    210.    
    211.             //
    212.             // WARNING - The following code runs with the kernel dispatch database
    213.             //      locked. EXTREME caution should be taken when modifying this
    214.             //      code. Extended execution will ADVERSELY affect system operation
    215.             //      and integrity.
    216.             //
    217.    
    218.             //
    219.             // Get information for each thread.
    220.             //
    221.    
    222.             ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);
    223.             ProcessInfo->NumberOfThreads = 0;
    224.             NextThread = Process->Pcb.ThreadListHead.Flink;
    225.             while (NextThread != &Process->Pcb.ThreadListHead) {
    226.                 NextEntryOffset += sizeof(SYSTEM_THREAD_INFORMATION);
    227.                 TotalSize += sizeof(SYSTEM_THREAD_INFORMATION);
    228.    
    229.                 if (TotalSize > SystemInformationLength) {
    230.                     status = STATUS_INFO_LENGTH_MISMATCH;
    231.                     KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL);
    232.                     goto Failed;
    233.                 }
    234.                 Thread = (PETHREAD)(CONTAINING_RECORD(NextThread,
    235.                                                       KTHREAD,
    236.                                                       ThreadListEntry));
    237.                 ExpCopyThreadInfo (ThreadInfo,Thread);
    238.    
    239.                 ProcessInfo->NumberOfThreads += 1;
    240.                 NextThread = NextThread->Flink;
    241.                 ThreadInfo += 1;
    242.             }
    243.    
    244.             //
    245.             // Store the Remote Terminal SessionId
    246.             //
    247.             ProcessInfo->SessionId = Process->SessionId;
    248.  
    249.    
    250.             //
    251.             // Unlock the dispatch database by waiting on the event that was
    252.             // previously set with the wait parameter TRUE.
    253.             //
    254.    
    255.             KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL);
    256.             //
    257.             // Get the image name.
    258.             //
    259.  
    260.             ProcessInfo->ImageName.Buffer = NULL;
    261.             ProcessInfo->ImageName.Length = 0;
    262.             ProcessInfo->ImageName.MaximumLength = 0;
    263.  
    264.             if ((n = strlen( Src = Process->ImageFileName ))) {
    265.                 n = ROUND_UP( ((n + 1) * sizeof( WCHAR )), sizeof(LARGE_INTEGER) );
    266.                 TotalSize += n;
    267.                 NextEntryOffset += n;
    268.                 if (TotalSize > SystemInformationLength) {
    269.                     status = STATUS_INFO_LENGTH_MISMATCH;
    270.                 } else {
    271.                     Dst = (PWSTR)(ThreadInfo);
    272.                     while (*Dst++ = (WCHAR)*Src++) {
    273.                         ;
    274.                         }
    275.                     ProcessInfo->ImageName.Length = (USHORT)((PCHAR)Dst - (PCHAR)ThreadInfo - sizeof( UNICODE_NULL ));
    276.                     ProcessInfo->ImageName.MaximumLength = (USHORT)n;
    277.  
    278.                     //
    279.                     // Set the image name to point into the user's memory.
    280.                     //
    281.  
    282.                     ProcessInfo->ImageName.Buffer = (PWSTR)
    283.                                 ((PCHAR)SystemInformation +
    284.                                  ((PCHAR)(ThreadInfo) - (PCHAR)MappedAddress));
    285.                 }
    286.  
    287.                 if (!NT_SUCCESS( status )) {
    288.                     goto Failed;
    289.                 }
    290.             }
    291.  
    292.             //
    293.             // Point to next process.
    294.             //
    295.  
    296.             ProcessInfo->NextEntryOffset = NextEntryOffset;
    297.             NextProcess = NextProcess->Flink;
    298.         }
    299.  
    300.         ProcessInfo->NextEntryOffset = 0;
    301.         status = STATUS_SUCCESS;
    302.         *Length = TotalSize;
    303.  
    304. Failed:
    305.         ;
    306.  
    307.     } finally {
    308.         ExReleaseFastMutex(&PspActiveProcessMutex);
    309.         MmUnlockPagableImageSection(ExPageLockHandle);
    310.         ExUnlockUserBuffer( LockVariable );
    311.     }
    312.  
    313.     return(status);
    314. }
    В Windows XP всё работает как надо, и SystemProcessInformation и SystemModuleInformation, и другие.
     
  6. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    Интересно, програмисты Microsoft сами читают MSDN? нахрена писать вот это:

    ... returns in ReturnLength the size of buffer required to receive the requested information

    и мало того, функция CreateToolhelp32Snapshot выглядит вот так что в XP, что в NT:

    Код (Text):
    1. int __userpurge sub_7C864138<eax>(int a1<ebp>, int a2, int a3, int a4, int a5, int a6)
    2. {
    3.   signed int v6; // ecx@1
    4.   int v7; // edi@1
    5.   int v8; // esi@1
    6.   int v10; // eax@2
    7.   int v11; // eax@3
    8.   int v12; // eax@3
    9.   int v13; // eax@7
    10.   int v14; // eax@13
    11.  
    12.   sub_7C8024CB(&dword_7C8642D8, 28);
    13.   v8 = 0;
    14.   v6 = 65536;
    15.   *(_DWORD *)(a1 - 28) = 65536;
    16.   v7 = *(_DWORD *)(a1 + 16);
    17.   *(_DWORD *)v7 = 0;
    18.   **(_DWORD **)(a1 + 20) = 0;
    19.   **(_DWORD **)(a1 + 24) = 0;
    20.   if ( *(_BYTE *)(a1 + 8) & 6 )
    21.   {
    22.     while ( 1 )
    23.     {
    24.       *(_DWORD *)(a1 - 4) = 0;
    25.       *(_DWORD *)(a1 - 28) = v6;
    26.       v10 = NtAllocateVirtualMemory(-1, v7, 0, a1 - 28, 0x1000u, 4);
    27.       v8 = v10;
    28.       *(_DWORD *)(a1 - 44) = v10;
    29.       *(_DWORD *)(a1 - 4) = -1;
    30.       if ( v10 < 0 )
    31.         break;
    32.       v11 = *(_DWORD *)(a1 - 28);
    33.       *(_DWORD *)(a1 - 32) = *(_DWORD *)(a1 - 28);
    34.       v12 = NtQuerySystemInformation(5, *(_DWORD *)v7, v11, 0);
    35.       v8 = v12;
    36.       if ( v12 != 0xC0000004 )
    37.         break;
    38.       NtFreeVirtualMemory(-1, v7, a1 - 28, 0x8000u);
    39.       *(_DWORD *)v7 = 0;
    40.       *(_DWORD *)(a1 - 32) += 8192;
    41.       v6 = *(_DWORD *)(a1 - 32);
    42.     }
    43.   }
    44.   if ( *(_BYTE *)(a1 + 8) & 0x18 )
    45.   {
    46.     if ( v8 >= 0 )
    47.     {
    48.       v13 = RtlCreateQueryDebugBuffer(0, 0);
    49.       **(_DWORD **)(a1 + 20) = v13;
    50.       if ( !v13 )
    51.         v8 = -1073741823;
    52.       if ( v8 >= 0 )
    53.         v8 = RtlQueryProcessDebugInformation(
    54.                *(_DWORD *)(a1 + 12),
    55.                (*(_DWORD *)(a1 + 8) >> 3) & 1 | 4 * (*(_DWORD *)(a1 + 8) & 0x10 | 0xE0000000),
    56.                **(_DWORD **)(a1 + 20));
    57.     }
    58.   }
    59.   if ( !(*(_BYTE *)(a1 + 8) & 1) )
    60.   {
    61. LABEL_17:
    62.     if ( v8 >= 0 )
    63.       return sub_7C80250B();
    64.     goto LABEL_18;
    65.   }
    66.   if ( v8 >= 0 )
    67.   {
    68.     v14 = RtlCreateQueryDebugBuffer(0, 0);
    69.     **(_DWORD **)(a1 + 24) = v14;
    70.     if ( !v14 )
    71.       v8 = -1073741823;
    72.     if ( v8 >= 0 )
    73.     {
    74.       v8 = RtlQueryProcessDebugInformation(*(_DWORD *)(a1 + 12), 4, **(_DWORD **)(a1 + 24));
    75.       goto LABEL_17;
    76.     }
    77.   }
    78. LABEL_18:
    79.   if ( *(_DWORD *)v7 )
    80.   {
    81.     *(_DWORD *)(a1 - 40) = 0;
    82.     NtFreeVirtualMemory(-1, v7, a1 - 40, 32768);
    83.     *(_DWORD *)v7 = 0;
    84.   }
    85.   if ( **(_DWORD **)(a1 + 20) )
    86.   {
    87.     RtlDestroyQueryDebugBuffer(**(_DWORD **)(a1 + 20));
    88.     **(_DWORD **)(a1 + 20) = 0;
    89.   }
    90.   if ( **(_DWORD **)(a1 + 24) )
    91.   {
    92.     RtlDestroyQueryDebugBuffer(**(_DWORD **)(a1 + 24));
    93.     **(_DWORD **)(a1 + 24) = 0;
    94.   }
    95.   return sub_7C80250B();
    96. }
    нафига делать цикл и крутить его, вычисляя размер, если в MSDN написано, что функция NtQuerySystemInformation должна возвратить необходимый размер???
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Quark
    Сказал же, НЕ ВСЕ ИНФОКЛАССЫ, зачем возвращать размер буфера для SystemProcessesInformation, если состояние этой инфы а значит и размер буфера меняется часто, поэтому вызывающий код должен сам указать размер.
    Ужос, код это ида ?
    Код (Text):
    1. NTSTATUS
    2. ThpCreateRawSnap(
    3.     IN DWORD dwFlags,
    4.     IN DWORD th32ProcessID,
    5.     PUCHAR *RawProcess,
    6.     PRTL_DEBUG_INFORMATION *RawModule,
    7.     PRTL_DEBUG_INFORMATION *RawDebugInfo)
    8. /*++
    9.  
    10. Routine Description:
    11.  
    12.     This function gets raw snapshots for the data types specified by dwFlags.
    13.  
    14. Arguments:
    15.  
    16.     th32ProcessID - Supplies a WIN32 process ID.  See CreateToolhelp32Snapshot
    17.         for full description.
    18.  
    19.     dwFlags - Supplies switches requesting various data.  See
    20.         CreateToolhelp32Snapshot for full description
    21.  
    22. Return Value:
    23.  
    24.     NTSTATUS as appropriate
    25.  
    26. --*/
    27. {
    28.     NTSTATUS Status = 0;
    29.     ULONG BufferSize = BUFFER_SIZE;
    30.     SIZE_T stBufferSize = BUFFER_SIZE;
    31.  
    32.     //
    33.     // get process/thread/module/heap info
    34.     //
    35.  
    36.     *RawProcess = NULL;
    37.     *RawModule = NULL;
    38.     *RawDebugInfo = NULL;
    39.  
    40.     if((dwFlags & TH32CS_SNAPPROCESS) || (dwFlags & TH32CS_SNAPTHREAD)){
    41.         do {
    42.             try {
    43.                 stBufferSize = BufferSize;
    44.                 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
    45.                                                  RawProcess,
    46.                                                  0,
    47.                                                  &stBufferSize,
    48.                                                  MEM_COMMIT,
    49.                                                  PAGE_READWRITE);
    50.             }
    51.             except( EXCEPTION_EXECUTE_HANDLER ) {
    52.                 Status = GetExceptionCode();
    53.             }
    54.  
    55.             if (!NT_SUCCESS(Status)) {
    56.                 break;
    57.             }
    58.  
    59.             BufferSize = (ULONG)stBufferSize;
    60.             //
    61.             // get all of the status information */
    62.             //
    63.             Status = NtQuerySystemInformation(SystemProcessInformation,
    64.                       *RawProcess,
    65.                       BufferSize,
    66.                       NULL);
    67.  
    68.             if (Status == STATUS_INFO_LENGTH_MISMATCH)   {
    69.                 NtFreeVirtualMemory(NtCurrentProcess(),
    70.                                     RawProcess,
    71.                                     &stBufferSize,
    72.                                     MEM_RELEASE);
    73.                 *RawProcess = NULL;
    74.                 BufferSize += 8192;
    75.             }
    76.  
    77.         } while(Status == STATUS_INFO_LENGTH_MISMATCH);
    78.     }
    79.  
    80.     //
    81.     // get module information
    82.     //
    83.  
    84.     if(dwFlags & TH32CS_SNAPMODULE)
    85.     {
    86.         if (NT_SUCCESS(Status))    {
    87.             *RawModule = RtlCreateQueryDebugBuffer(0, FALSE);
    88.             if (!*RawModule) {
    89.                 Status = STATUS_UNSUCCESSFUL;
    90.             }
    91.         }
    92.  
    93.         if (NT_SUCCESS(Status)) {
    94.             Status = RtlQueryProcessDebugInformation((HANDLE)LongToHandle(th32ProcessID),
    95.                                                       RTL_QUERY_PROCESS_MODULES,
    96.                                                       *RawModule);
    97.         }
    98.     }
    99.  
    100.     //
    101.     // get the heap summary information for the specified process */
    102.     //
    103.  
    104.     if (dwFlags & TH32CS_SNAPHEAPLIST)   {
    105.         if (NT_SUCCESS(Status))    {
    106.  
    107.             *RawDebugInfo = RtlCreateQueryDebugBuffer(0, FALSE);
    108.             if (!*RawDebugInfo) {
    109.                 Status = STATUS_UNSUCCESSFUL;
    110.             }
    111.         }
    112.         if (NT_SUCCESS(Status)) {
    113.             Status = RtlQueryProcessDebugInformation((HANDLE)LongToHandle(th32ProcessID),
    114.                                                       RTL_QUERY_PROCESS_HEAP_SUMMARY,
    115.                                                       *RawDebugInfo);
    116.         }
    117.     }
    118.  
    119.  
    120.     if (!NT_SUCCESS(Status))    {
    121.         if (*RawProcess) {
    122.             SIZE_T Size = 0;
    123.             NtFreeVirtualMemory(NtCurrentProcess(),
    124.                                 RawProcess,
    125.                                 &Size,
    126.                                 MEM_RELEASE);
    127.             *RawProcess = NULL;
    128.         }
    129.         if (*RawModule) {
    130.             RtlDestroyQueryDebugBuffer(*RawModule);
    131.             *RawModule = NULL;
    132.         }
    133.         if (*RawDebugInfo) {
    134.             RtlDestroyQueryDebugBuffer(*RawDebugInfo);
    135.             *RawDebugInfo = NULL;
    136.         }
    137.     }
    138.  
    139.     return Status;
    140. }
     
  8. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    1. за тем, что в MSDN написано.
    2. зачем вводить в заблуждение и в разных осях делать по разномку.
    3. конечно, есть вероятность того, что в промежутке между вызовами ZwQuerySystemInformation произойдёт создание ещё одного процесса, но не думаю что большая.
    4. хотя бы приблизительный размер буфера можно узнать одним вызовом ZwQuerySystemInformation. и не выделять сразу 64кб памяти (зачастую 30 из которых лишние).

    кто запрещает - узнай приблизительный размер и запускай цикл, увеличивая размер буфера в случае неудачи на размер одной-двух структур. а тут получается пальцем в небо.
     
  9. Malwara

    Malwara New Member

    Публикаций:
    0
    Регистрация:
    23 авг 2008
    Сообщения:
    30
    Раз читал МСДН, то надо было ещё и шапку перевести.
    Вообще что за бред ты тут развел? Если ты умнее M$ - напиши свой аналог.

    Потому что во 1x: во времена Win2k это в MSDN не было вообще, во 2x: никто никого не вводил в заблуждение. Это внутреннее апи и как хотят так его и декларируют.

    x64
    Интересная позиция. Что бы вы все делали без скомунизденных исходников? :)
     
  10. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    интересный подход... то есть функции документированы, а использовать их нельзя. зачем же их документировать?

    что я и пытаюсь сделать, заюзав вместо Process32First, Process32Next натив апи ZwQuerySystemInformation. получается что вы свой совет называете бредом?

    пусть дулают. видимо вы совершенно не понимаете к чему я привёл пример реализации CreateToolhelp32Snapshot. Я привёл это за тем, чтобы показать что описание MSDN не соответствует реализации функций. если следовать MSDN, то оптимальнее было бы реализовать иначе.
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Quark
    Винапи гуан полный, я не пойму что ты хочешь сделать.
    Ыы песикиато, пример это листинг иды :lol:
    В сорсах более конкретно.
    ;--------------------------------------------------------------------
    Это ты бредишь, если решил юзать натив(как и я :)), то и не думай о винапи. Выбор мелкомягких ведь не идеален, винапи вообще кривые. Чего тока стоит баг слепков с перечислением куч, это точно студенты писали, как ктото сказал. Если хрю не нравится напиши свою ось :lol: DD
     
  12. litrovith

    litrovith Member

    Публикаций:
    0
    Регистрация:
    20 июн 2007
    Сообщения:
    509
    Quark, подумайте логически.. Если вы припомощи етой функции хотите узнать список процессов, то как она может вернуть размер буфера, а вдруг в ето же время будет запущен еще один процесс (ЧИСТО ЛОГИЧЕСКИ)?
    Юзайте ступенчатое увеличение буфера (в разумных пределах).
    п.с. и смотрите в отладчике SYSTEM_PROCESS_INFORMATION (все пи*дят).
     
  13. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Тем не менее размер буфера она таки возвращает. Система возвращает размер буфера, необходимый на момент вызова, а не "вообще". На время вычисления размера какие-либо изменения в списках процессов/потоков не блокируются, т.к. это операции атомарные, нет нужды.
     
  14. litrovith

    litrovith Member

    Публикаций:
    0
    Регистрация:
    20 июн 2007
    Сообщения:
    509
    x64, я подбираю размер буфера 'вслепую'.
     
  15. tylerdurden

    tylerdurden New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    322
    А кто-нибудь пробывал ZwQueryVirtualMemory с классом 2 (или GetMappedImageFileName) ? У меня на 2к сп2 всегда возвращаеться c0000141, хотя судя по сорцам и ошибке этот класс поддерживаеться.
     
  16. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    tylerdurden
    Какое отношение к поддержке имеет c0000141?
    GetMappedImageFileName - это psapi.GetMappedFileName?
     
  17. Quark

    Quark New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2007
    Сообщения:
    211
    +1
    хотя бы не пальцем в небо
     
  18. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    tylerdurden
    XP SP2, давно это юзаем.