Я хотел бы запросить рабочее определение 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
.