taskmgr

Тема в разделе "WASM.NT.KERNEL", создана пользователем Wizard109, 21 июл 2011.

  1. Wizard109

    Wizard109 New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2006
    Сообщения:
    346
    Собственно после длительного перерыва вернулся к кодингу в ядре, посему заранее извиняюсь за возможную "тупость".

    Значит есть задача: дабы не напрягать пользователя высокой загрузкой ЦП - не давать ему увидеть что какой-то процесс хавает 99% процессорного времени. (Ага. Ситуевина: винт и кулера свистят как резанные, а юзер ни сном - ни духом. Хотя... Заказ есть заказ). Ок. Реверсинг диспетчера задач под XP sp3 показал что "да, действительно он юзает NtQuerySystemInformation с параметром SystemProcessInformation{=5}". Хм. Ок. Перехватываем. Вот здесь начинается собственно вопрос. В MSDN описание SYSTEM_PROCESS_INFORMATION:

    Код (Text):
    1. typedef struct _SYSTEM_PROCESS_INFORMATION
    2. {
    3.     ULONG NextEntryOffset;
    4.     BYTE Reserved1[52];
    5.     PVOID Reserved2[3];
    6.     HANDLE UniqueProcessId;
    7.     PVOID Reserved3;
    8.     ULONG HandleCount;
    9.     BYTE Reserved4[4];
    10.     PVOID Reserved5[11];
    11.     SIZE_T PeakPagefileUsage;
    12.     SIZE_T PrivatePageCount;
    13.     LARGE_INTEGER Reserved6[6];
    14. }SYSTEM_PROCESS_INFORMATION;
    Где там собцтвенно Кернел и Юзер тайм ?
    Структурка сама по себе вроди правильная (ну я посмотрел... ProcessUID стоит на нужном месте).

    Собцтвенно наглый и глобальный вопрос из разряда "швырните кодом": как решить задачу ? (ибо времени мало)
    Или мелкий и скромный: собцтвенно как именно taskmgr подсчитывает(если кто знает) процент загруженности для опред. задачи и как на самом деле выглядит SYSTEM_PROCESS_INFORMATION
     
  2. Hellspawn

    Hellspawn New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2006
    Сообщения:
    310
    Адрес:
    Москва
  3. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
  4. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    Код (Text):
    1. /*++ CalcCpuTime
    2.  
    3. Routine Description:
    4.  
    5.    calculate and return %cpu time and time periods
    6.  
    7. Arguments:
    8.  
    9.    None
    10.  
    11. Notes:
    12.  
    13. Revision History:
    14.  
    15.       Nov-13-95 DavePl  Created
    16.  
    17. --*/
    18.  
    19. void CalcCpuTime(BOOL fUpdateHistory)
    20. {
    21.     SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ProcessorInfo[MAX_PROCESSOR];
    22.     LARGE_INTEGER                            CPUIdleTime[MAX_PROCESSOR];
    23.     LARGE_INTEGER                            CPUTotalTime[MAX_PROCESSOR];
    24.     LARGE_INTEGER                            CPUKernelTime[MAX_PROCESSOR];
    25.  
    26.     LARGE_INTEGER                            SumIdleTime   = { 0 ,0 };
    27.     LARGE_INTEGER                            SumTotalTime  = { 0, 0 };
    28.     LARGE_INTEGER                            SumKernelTime = { 0, 0 };
    29.  
    30.     NTSTATUS Status;
    31.  
    32.     Status = NtQuerySystemInformation(
    33.        SystemProcessorPerformanceInformation,
    34.        ProcessorInfo,
    35.        sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * MAX_PROCESSOR,
    36.        NULL
    37.     );
    38.  
    39.     if (!NT_SUCCESS(Status))
    40.     {
    41.         return;
    42.     }
    43.  
    44.     //
    45.     // Walk through the info for each CPU, and compile
    46.     //
    47.     //  - Amount of time each CPU has spent idle (since last check)
    48.     //  - Amount of time each CPU has spent entirely (since last check)
    49.     //
    50.     // In addition to keeping per-CPU stats, compile a sum for
    51.     //
    52.     //  - Amount of time system has spent idle (since last check)
    53.     //  - Amount of time that has elapsed, in total (since last check)
    54.     //
    55.  
    56.     for (int ListIndex = 0; ListIndex < g_cProcessors; ListIndex++)
    57.     {
    58.         LARGE_INTEGER DeltaCPUIdleTime;
    59.         LARGE_INTEGER DeltaCPUTotalTime;
    60.         LARGE_INTEGER DeltaCPUKernelTime;
    61.  
    62.         CPUIdleTime[ListIndex].QuadPart  = ProcessorInfo[ListIndex].IdleTime.QuadPart;
    63.         CPUKernelTime[ListIndex].QuadPart= ProcessorInfo[ListIndex].KernelTime.QuadPart-
    64.                                            ProcessorInfo[ListIndex].IdleTime.QuadPart;
    65.         CPUTotalTime[ListIndex].QuadPart = ProcessorInfo[ListIndex].KernelTime.QuadPart +
    66.                                            ProcessorInfo[ListIndex].UserTime.QuadPart;// +
    67.                                            //ProcessorInfo[ListIndex].IdleTime.QuadPart;
    68.  
    69.         DeltaCPUIdleTime.QuadPart        = CPUIdleTime[ListIndex].QuadPart -
    70.                                            PreviousCPUIdleTime[ListIndex].QuadPart;
    71.         DeltaCPUKernelTime.QuadPart      = CPUKernelTime[ListIndex].QuadPart -
    72.                                            PreviousCPUKernelTime[ListIndex].QuadPart;
    73.         DeltaCPUTotalTime.QuadPart       = CPUTotalTime[ListIndex].QuadPart -
    74.                                            PreviousCPUTotalTime[ListIndex].QuadPart;
    75.  
    76.         SumIdleTime.QuadPart            += DeltaCPUIdleTime.QuadPart;
    77.         SumTotalTime.QuadPart           += DeltaCPUTotalTime.QuadPart;
    78.         SumKernelTime.QuadPart          += DeltaCPUKernelTime.QuadPart;
    79.  
    80.         // Calc CPU Usage % for this processor, scroll the history buffer, and store
    81.         // the newly calced value at the head of the history buffer
    82.  
    83.         BYTE ThisCPU =  DeltaCPUTotalTime.QuadPart ?
    84.                         (BYTE) (100 - ((DeltaCPUIdleTime.QuadPart * 100) / DeltaCPUTotalTime.QuadPart))
    85.                         : 0;
    86.  
    87.         BYTE * pbHistory = g_pCPUHistory[ListIndex];
    88.         MoveMemory((LPVOID) (pbHistory + 1),
    89.                    (LPVOID) (pbHistory),
    90.                    sizeof(BYTE) * (HIST_SIZE - 1) );
    91.         pbHistory[0] = ThisCPU;
    92.  
    93.         BYTE ThisKernel = DeltaCPUTotalTime.QuadPart ?
    94.                           (BYTE) (((DeltaCPUKernelTime.QuadPart * 100) / DeltaCPUTotalTime.QuadPart))
    95.                           : 0;
    96.  
    97.         pbHistory = g_pKernelHistory[ListIndex];
    98.         MoveMemory((LPVOID) (pbHistory + 1),
    99.                    (LPVOID) (pbHistory),
    100.                    sizeof(BYTE) * (HIST_SIZE - 1) );
    101.         pbHistory[0] = ThisKernel;
    102.  
    103.  
    104.         PreviousCPUTotalTime[ListIndex].QuadPart = CPUTotalTime[ListIndex].QuadPart;
    105.         PreviousCPUIdleTime[ListIndex].QuadPart  = CPUIdleTime[ListIndex].QuadPart;
    106.         PreviousCPUKernelTime[ListIndex].QuadPart = CPUKernelTime[ListIndex].QuadPart;
    107.     }
    108.  
    109.     g_CPUUsage = SumTotalTime.QuadPart ?
    110.                  (BYTE) (100 - ((SumIdleTime.QuadPart * 100) / SumTotalTime.QuadPart))
    111.                  : 0;
    112.  
    113.     if (fUpdateHistory)
    114.     {
    115.         g_KernelUsage = SumTotalTime.QuadPart ?
    116.                         (BYTE) ((SumKernelTime.QuadPart * 100) / SumTotalTime.QuadPart)
    117.                         : 0;
    118.  
    119.         //
    120.         // Get the commit size
    121.         //
    122.  
    123.         SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
    124.  
    125.         Status = NtQuerySystemInformation(
    126.                     SystemPerformanceInformation,
    127.                     &PerfInfo,
    128.                     sizeof(PerfInfo),
    129.                     NULL);
    130.  
    131.         if (!NT_SUCCESS(Status))
    132.         {
    133.             return;
    134.         }
    135.  
    136.         g_MEMUsage = PerfInfo.CommittedPages * (g_PageSize / 1024);
    137.         MoveMemory((LPVOID) (g_pMEMHistory + 1),
    138.                    (LPVOID) (g_pMEMHistory),
    139.                    sizeof(BYTE) * (HIST_SIZE - 1) );
    140.  
    141.         g_pMEMHistory[0] = (BYTE) ((g_MEMUsage * 100) / g_MEMMax);
    142.     }
    143. }
    Он же опенсурсный.. win2k\private\shell\applets\taskmgr
     
  5. Wizard109

    Wizard109 New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2006
    Сообщения:
    346
    Многа спасиба !
    Hellspawn
    Загуглить не сложилось. Нашлось с десяток разных вариантов. Все проверять оч. некогда было :)
     
  6. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    Wizard109
    Это самый важный момент. Уж не патч ли выпиливающийся ?
     
  7. Wizard109

    Wizard109 New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2006
    Сообщения:
    346
    klzlk
    Задачка без сложностей. Перехват тупым инлайн jmp'ом :)
     
  8. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    Wizard109
    Разумеется)