Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ZwQuerySystemInformation && C#, есть проблемка 
:(
    Опции темы
CL0NE
Дата 9.9.2009, 03:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 3.9.2009

Репутация: нет
Всего: нет



Синтаксис данной функции (в дополнение к ссылке на мсдн - здесь): 
Цитата
Код
NTSTATUS WINAPI ZwquoteuerySystemInformation(
  __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,
  __inout    PVOID SystemInformation,
  __in       ULONG SystemInformationLength,
  __out_opt  PULONG ReturnLength
);

 
Привел я ее к такому виду в своем коде:
Код

[DllImport("Ntdll.dll", EntryPoint="ZwquoteuerySystemInformation")]
static extern Int32 APIquoteuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass,
               IntPtr SystemInformation,
               int SystemInformationLength,
               out long ReturnLength);


Первый параметр указывает на тип получаемой информации:

Цитата

SystemInformationClass 
The type of system information to be retrieved. This parameter can be one of the following values from the SYSTEM_INFORMATION_CLASS enumeration type.



сделал его енумерейшном:
Код

        public enum SYSTEM_INFORMATION_CLASS
        {
            SystemBasicInformation = 0x02c,
            SystemPerformanceInformation = 0x138,
            SystemTimeOfDayInformation = 0x020,
            SystemProcessInformation = 0x088,
            SystemProcessorPerformanceInformation = 0x030,
            SystemInterruptInformation = 0x018,
            SystemExceptionInformation = 0x010
       } 

Ради теста использовал первый вариант, самый простой:
Цитата
SystemBasicInformation

The number of processors in the system in a SYSTEM_BASIC_INFORMATION structure. Use the GetSystemInfo function instead.


Второй параметр - 
Цитата
SystemInformation
A pointer to a buffer that receives the requoteuested information. The size and structure of this information varies depending on the value of the SystemInformationClass parameter, as indicated in the following table.
 (лень переводить, да и, думаю, те, кто сможеть помочь, в состоянии читать англицкий текст)

Следовательно, при первом варианте получим структуру:

Цитата
SYSTEM_BASIC_INFORMATION

When the SystemInformationClass parameter is SystemBasicInformation, the buffer pointed to by the SystemInformation parameter should be large enough to hold a single SYSTEM_BASIC_INFORMATION structure having the following layout: 

Код
typedef struct _SYSTEM_BASIC_INFORMATION {
    BYTE Reserved1[24];
    PVOID Reserved2[4];
    CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION;



The NumberOfProcessors member contains the number of processors present in the system. Use GetSystemInfo instead to retrieve this information.

The other members of the structure are reserved for internal use by the operating system.


Привел ее к "надлежащему" виду:


Код

[StructLayout(LayoutKind.Sequoteuential)]
public struct SYSTEM_BASIC_INFORMATION {
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
      public byte[] Reserved1;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
      public IntPtr[] Reserved2;
      public Char NumberOfProcessors;
}


При вызове функция возвращает код NTSATUS

Цитата
Код

//STATUS_SUCCESS              = NTStatus($00000000);
//STATUS_ACCESS_DENIED        = NTStatus($C0000022);
//STATUS_INFO_LENGTH_MISMATCH = NTStatus($C0000004);
//SEVERITY_ERROR              = NTStatus($C0000000);


Первый при удачном вызове, третий - при слишком маленьком буфере.

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

Мой тестовый код, попытка использовать данную функцию:


Код
long formal;
int size = Marshal.SizeOf(typeof(SYSTEM_BASIC_INFORMATION));
IntPtr ptr = Marshal.AllocHGlobal(size); 

Console.WriteLine("NTSTATUS: " + APIquoteuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemBasicInformation, ptr, size, out formal).ToString("X"));
            
SYSTEM_BASIC_INFORMATION INFO = ((SYSTEM_BASIC_INFORMATION)Marshal.PtrToStructure(ptr, typeof(SYSTEM_BASIC_INFORMATION)));
Console.WriteLine(INFO.NumberOfProcessors);
Console.WriteLine(formal);


Ну а теперь, самое "вкусное" (смысл топика smile):
  • Если я неправильно привел к "надлежащему виду" сигнатуру функции и сами структуры - поправьте, пожалуйста, буду очень признателен smile
  • Проблема: при вызове функция возвращает STATUS_INFO_LENGTH_MISMATCH. с чем это может быть связано?


Это сообщение отредактировал(а) CL0NE - 9.9.2009, 03:31
PM MAIL   Вверх
mihryak
Дата 9.9.2009, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 10
Всего: 36



а откуда ты взял значения энума SYSTEM_INFORMATION_CLASS?
везде, где попадались, SystemBasicInformation был равен 0
например, здесь
если взять оттуда и структуру
Код

[StructLayout(LayoutKind.Sequential)]
struct SYSTEM_BASIC_INFORMATION
{
    public int Reserved;
    public int TimerResolution;
    public int PageSize; // 4096 (4kB) on 32-bit systems, 8192 (8kB) on 64-bit systems
    public int NumberOfPhysicalPages; // pages of physical memory
    public int LowestPhysicalPageNumber;
    public int HighestPhysicalPageNumber;
    public int AllocationGranularity;
    public int MinimumUserModeAddress;
    public int MaximumUserModeAddress;
    public int ActiveProcessorsAffinityMask;
    public byte NumberOfProcessors;
}

то на домашней висте успешно выдалось 2 процессора
а вот на рабочем 2003 сервере не прокатило
тем не менее, и там, и там по коду 0x02c мне выдавался требуемый размер памяти, равный 172, ни из твоего варианта структуры, ни из моего такой размер не получить, у нас 44
так, кстати, я и убедился, что 0 - подходящее значение, при нём и при 62(0x3E) выдавалось 44 требуемых байта (при 62 те же значения полей структуры). ни одно другое число из интервала 0..99999999 44 не дало

как бы то ни было, ZW-функции не предназначены для использования вне внутренностей системы, советую поискать альтернативный вариант. тот же МСДН рекомендует для получения числа процессоров GetSystemInfo

Это сообщение отредактировал(а) mihryak - 9.9.2009, 21:03
PM MAIL ICQ   Вверх
CL0NE
Дата 10.9.2009, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 3.9.2009

Репутация: нет
Всего: нет



Цитата

как бы то ни было, ZW-функции не предназначены для использования вне внутренностей системы, советую поискать альтернативный вариант. тот же МСДН рекомендует для получения числа процессоров GetSystemInfo

Цитата

Ради теста использовал первый вариант, самый простой:

Вообще-то мне нужа функция ради SystemProcessorPerformanceInformation. Ибо функция GetSystemTimes, предлагаемая, как альтернатива, возвращает суммарную загрузку процессора. Так же само и WMI (который я использовал до этого, причем, как на каком-то форуме упоминалось, добавляет загрузку процессора на 10% Оо). А хочется на каждое ядро smile

Цитата

а откуда ты взял значения энума SYSTEM_INFORMATION_CLASS?

Только что, погуглив, нашел где я их взял. http://undocumented.ntinternals.net/
о_О Спросонья я почемуто посчитал
Цитата

Buffer size : 0x02C 
 значением...

Мораль: никогда не пишите код на сонную голову! smile

mihryak спасибо огромное, все работает!

Это сообщение отредактировал(а) CL0NE - 10.9.2009, 01:17
PM MAIL   Вверх
CL0NE
Дата 13.9.2009, 05:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 3.9.2009

Репутация: нет
Всего: нет



все. да не все smile как оказалось для второго ядра не выводит правильную загрузку. выводит заоблачные цифры от -1ххххххх до 1хххххххх smile
Это при использовании SystemProcessorPerformanceInformation

Цитата


[StructLayout(LayoutKind.Sequential)]
        public struct SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
        {
            public long IdleTime;
            public long KernelTime;
            public long UserTime;
            public long Reserved1;
            public ulong Reserved2;
        }



Код

[S][StructLayout(LayoutKind.Sequential)]
        public struct SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
        {
            public Int32 IdleTime;
            public Int32 KernelTime;
            public Int32 UserTime;
            public Int32 Reserved1;
            public UInt32 Reserved2;
        }[/S]


Первое поле - время, проведенное процессором в режиме бездействия, измеряется в тиках. Берем определенный промежуток (n tick, тик- 100 наносекунд, если не ошибаюсь). Замеряем время простоя процессора в начале промежутка и в конце. Делим на время промежутка и получаем процент бездействия. Отняв от единицы - получим процент загрузки smile.
Цитата
1 - (idleCurrent - idleOld)/(tickNow - tickOld)

что ж, будем дальше ломать код smile

p.s.: сделал поправку, т.к. упустил момент о размерах типов в С++ (long - 32-bit signed integer), C# (64-bit signed integer.) Теперь появилась проблема... постоянно выводит загрузку 100% оО

Это сообщение отредактировал(а) CL0NE - 14.9.2009, 00:36
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0708 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.