Использование ZwQuerySystemInformation в C#: проблема
От: CL0NE Украина  
Дата: 07.09.09 20:32
Оценка:
Синтаксис данной функции (в дополнение к ссылке на мсдн — здесь):

NTSTATUS WINAPI ZwQuerySystemInformation(
  __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,
  __inout    PVOID SystemInformation,
  __in       ULONG SystemInformationLength,
  __out_opt  PULONG ReturnLength
);


Привел я ее к такому виду в своем коде:
[DllImport("Ntdll.dll", EntryPoint="ZwQuerySystemInformation")]
static extern Int32 APIQuerySystemInformation(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 requested 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.Sequential)]
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: " + APIQuerySystemInformation(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);


Ну а теперь, самое "вкусное":

  1. Если я неправильно привел к "надлежащему виду" сигнатуру функции и сами структуры — поправьте, пожалуйста, буду очень признателен
  2. Проблема: при вызове функция возвращает STATUS_INFO_LENGTH_MISMATCH. с чем это может быть связано?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.