P / Вызов определения для функций RtlCrc32 и RtlCrc64? - PullRequest
0 голосов
/ 17 марта 2019

Я хотел бы запросить рабочее определение P / Invoke для недокументированных RtlCrc32 и RtlCrc64 функций.

Я знаю о существующих алгоритмах CRC-32 в управляемом коде, но я предпочитаю пойти по пути Microsoft Windows, чтобы избежать возможных человеческих ошибок и / или отрицательной производительности с моей стороны из-за неопытности в вычислении контрольной суммы, просто так.

Это функции, объявленные в заголовочном файле winnt.h (Windows 10 SDK):

//
//  Crc32 and Crc64 routines that use standardized algorithms
//

NTSYSAPI
DWORD
NTAPI
RtlCrc32(
    _In_reads_bytes_(Size) const void *Buffer,
    _In_ size_t Size,
    _In_ DWORD InitialCrc
    );

NTSYSAPI
ULONGLONG
NTAPI
RtlCrc64(
    _In_reads_bytes_(Size) const void *Buffer,
    _In_ size_t Size,
    _In_ ULONGLONG InitialCrc
    );

И вот что я попробовал:

[DllImport("NtDll.dll", SetLastError=false)]
public extern static uint RtlCrc32([In] IntPtr buffer, 
                                   [In] IntPtr size, 
                                   [In] uint initialCrc);

[DllImport("NtDll.dll", SetLastError=false)]
public extern static ulong RtlCrc64([In] IntPtr buffer, 
                                    [In] IntPtr size, 
                                    [In] ulong initialCrc);

и

byte[] bytes = File.ReadAllBytes(@"C:\File.txt");
uint initialCrc = 0; // I tried to use 0x4C11DB7
                     // standarized polynomial value 
                     // just to try something random.

IntPtr buffer = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, buffer, bytes.Length);

uint crc32 = NativeMethods.RtlCrc32(buffer, new IntPtr(bytes.Length), initialCrc);

Console.WriteLine(crc32.ToString("X2"));

Но когда я сравниваю возвращаемое значение с любой другой программой, которая вычисляет CRC-32, мое значение не соответствует.

Поскольку у меня нет опыта работы с C / C ++, у меня есть некоторые сомнения ... во-первых, я не понимаю, возвращают ли функции код ошибки NTSATUS или они возвращают DWORD и ULONGLONG соответственно. Во-вторых, я не получаю то, что мне нужно передать параметру InitialCrc.

1 Ответ

1 голос
/ 17 марта 2019

Ваши определения в порядке. Функции возвращают значение CRC, а не код ошибки.

Может быть проще объявить буфер как byte[] и позволить маршалеру закрепить массив за вас, избегая копирования.

Начальное значение является частью ввода в алгоритм CRC. При сравнении с выводом из другого алгоритма CRC необходимо знать, какое начальное значение было использовано.

...