#include "precomp.hxx" // Copied from nt\base\win32\client\thread.c HANDLE OSCompat_OpenThread( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId ) { NTSTATUS Status; OBJECT_ATTRIBUTES Obja; HANDLE Handle; CLIENT_ID ClientId; ClientId.UniqueThread = (HANDLE)LongToHandle(dwThreadId); ClientId.UniqueProcess = (HANDLE)NULL; InitializeObjectAttributes( &Obja, NULL, (bInheritHandle ? OBJ_INHERIT : 0), NULL, NULL ); Status = NtOpenThread( &Handle, (ACCESS_MASK)dwDesiredAccess, &Obja, &ClientId ); if (NT_SUCCESS(Status)) { return Handle; } else { SetLastError(Status); return NULL; } } // Copied from nt\base\ntos\rtl\bitmap.c static CONST ULONG FillMaskUlong[] = { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }; ULONG OSCompat_RtlFindLastBackwardRunClear ( IN PRTL_BITMAP BitMapHeader, IN ULONG FromIndex, IN PULONG StartingRunIndex ) { ULONG Start; ULONG End; PULONG PHunk; ULONG Hunk; // // Take care of the boundary case of the null bitmap // if (BitMapHeader->SizeOfBitMap == 0) { *StartingRunIndex = FromIndex; return 0; } // // Scan backwards for the first clear bit // End = FromIndex; // // Build pointer to the ULONG word in the bitmap // containing the End bit, then read in the bitmap // hunk. Set the rest of the bits in this word, NOT // inclusive of the FromIndex bit. // PHunk = BitMapHeader->Buffer + (End / 32); Hunk = *PHunk | ~FillMaskUlong[(End % 32) + 1]; // // If the first subword is set then we can proceed to // take big steps in the bitmap since we are now ULONG // aligned in the search // if (Hunk == (ULONG)~0) { // // Adjust the pointers backwards // End -= (End % 32) + 1; PHunk--; while ( PHunk > BitMapHeader->Buffer ) { // // Stop at first word with set bits // if (*PHunk != (ULONG)~0) break; PHunk--; End -= 32; } } // // Bitwise search backward for the clear bit // while ((End != MAXULONG) && (RtlCheckBit( BitMapHeader, End ) == 1)) { End -= 1; } // // Scan backwards for the first set bit // Start = End; // // We know that the clear bit was in the last word we looked at, // so continue from there to find the next set bit, clearing the // previous bits in the word. // Hunk = *PHunk & FillMaskUlong[Start % 32]; // // If the subword is unset then we can proceed in big steps // if (Hunk == (ULONG)0) { // // Adjust the pointers backward // Start -= (Start % 32) + 1; PHunk--; while ( PHunk > BitMapHeader->Buffer ) { // // Stop at first word with set bits // if (*PHunk != (ULONG)0) break; PHunk--; Start -= 32; } } // // Bitwise search backward for the set bit // while ((Start != MAXULONG) && (RtlCheckBit( BitMapHeader, Start ) == 0)) { Start -= 1; } // // Compute the index and return the length // *StartingRunIndex = Start + 1; return (End - Start); }