I would like to request a working P/Invoke definition for the undocumented RtlCrc32 and RtlCrc64 functions.
I'm aware about existing CRC-32 algorithms in managed code, but I prefer to go the Microsoft Windows way to avoid possible human errors and/or negative performance from my side due inexperience on checksum calculation, just that.
These are the functions declared in winnt.h header file (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
);
And this is what I tried:
[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);
and:
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"));
But when I compare the returned value with any other program that calculates CRC-32, my value does not corresponds.
Because I'm not experienced with C/C++, I have some doubts... first I don't get whether the functions returns a NTSATUS error code, or they returns DWORD and ULONGLONG respectively. Secondly, I don't get what I need to pass to InitialCrc
parameter.
Your definitions are fine. The functions return the CRC value rather than an error code.
It might be easier to declare the buffer as byte[]
and let the marshaler pin the array for you, avoiding a copy.
The initial value is part of the input to a CRC algorithm. When comparing against output from another CRC algorithm you need to know what initial value was used.