/************************************************************************* * This function adds a node of certain gain into a partition **************************************************************************/ int PQueueInsert(PQueueType *queue, int node, int gain) { int i, j, k; idxtype *locator; ListNodeType *newnode; KeyValueType *heap; if (queue->type == 1) { ASSERT(gain >= -queue->ngainspan && gain <= queue->pgainspan); /* Allocate and add the node */ queue->nnodes++; newnode = queue->nodes + node; /* Attach this node in the doubly-linked list */ newnode->next = queue->buckets[gain]; newnode->prev = NULL; if (newnode->next != NULL) newnode->next->prev = newnode; queue->buckets[gain] = newnode; if (queue->maxgain < gain) queue->maxgain = gain; } else { ASSERT(CheckHeap(queue)); heap = queue->heap; locator = queue->locator; ASSERT(locator[node] == -1); i = queue->nnodes++; while (i > 0) { j = (i-1)/2; if (heap[j].key < gain) { heap[i] = heap[j]; locator[heap[i].val] = i; i = j; } else break; } ASSERT(i >= 0); heap[i].key = gain; heap[i].val = node; locator[node] = i; ASSERT(CheckHeap(queue)); } return 0; }
NTSTATUS InfOpenBufferedFile(PHINF InfHandle, PVOID Buffer, ULONG BufferSize, PULONG ErrorLine) { INFSTATUS Status; PINFCACHE Cache; PCHAR FileBuffer; CheckHeap(); *InfHandle = NULL; *ErrorLine = (ULONG)-1; /* Allocate file buffer */ FileBuffer = MALLOC(BufferSize + 1); if (FileBuffer == NULL) { DPRINT1("MALLOC() failed\n"); return(INF_STATUS_INSUFFICIENT_RESOURCES); } MEMCPY(FileBuffer, Buffer, BufferSize); /* Append string terminator */ FileBuffer[BufferSize] = 0; /* Allocate infcache header */ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); if (Cache == NULL) { DPRINT("MALLOC() failed\n"); FREE(FileBuffer); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Initialize inicache header */ ZEROMEMORY(Cache, sizeof(INFCACHE)); /* Parse the inf buffer */ Status = InfpParseBuffer (Cache, FileBuffer, FileBuffer + BufferSize, ErrorLine); if (!INF_SUCCESS(Status)) { FREE(Cache); Cache = NULL; } /* Free file buffer */ FREE(FileBuffer); *InfHandle = (HINF)Cache; return(Status); }
int main(void) { ULONG ulCount = 0; srand(1); for (;;) { USHORT usIndex = (USHORT)(ulCount % 1000); size_t tSize = rand(); if (rgpMem[usIndex]) Free(rgpMem[usIndex]); CheckHeap(); rgpMem[usIndex] = Malloc(tSize); if (rgpMem[usIndex]) memset(rgpMem[usIndex], 0, tSize); CheckHeap(); ulCount++; } return 0; }
/************************************************************************* * This function deletes a node from a partition and reinserts it with * an updated gain **************************************************************************/ int PQueueDelete(PQueueType *queue, int node, int gain) { int i, j, newgain, oldgain; idxtype *locator; ListNodeType *newnode, **buckets; KeyValueType *heap; if (queue->type == 1) { ASSERT(gain >= -queue->ngainspan && gain <= queue->pgainspan); ASSERT(queue->nnodes > 0); buckets = queue->buckets; queue->nnodes--; newnode = queue->nodes+node; /* Remove newnode from the doubly-linked list */ if (newnode->prev != NULL) newnode->prev->next = newnode->next; else buckets[gain] = newnode->next; if (newnode->next != NULL) newnode->next->prev = newnode->prev; if (buckets[gain] == NULL && gain == queue->maxgain) { if (queue->nnodes == 0) queue->maxgain = -queue->ngainspan; else for (; buckets[queue->maxgain]==NULL; queue->maxgain--); } } else { /* Heap Priority Queue */ heap = queue->heap; locator = queue->locator; ASSERT(locator[node] != -1); ASSERT(heap[locator[node]].val == node); ASSERT(CheckHeap(queue)); i = locator[node]; locator[node] = -1; if (--queue->nnodes > 0 && heap[queue->nnodes].val != node) { node = heap[queue->nnodes].val; newgain = heap[queue->nnodes].key; oldgain = heap[i].key; if (oldgain < newgain) { /* Filter-up */ while (i > 0) { j = (i-1)>>1; if (heap[j].key < newgain) { heap[i] = heap[j]; locator[heap[i].val] = i; i = j; } else break; } } else { /* Filter down */ while ((j=2*i+1) < queue->nnodes) { if (heap[j].key > newgain) { if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) j = j+1; heap[i] = heap[j]; locator[heap[i].val] = i; i = j; } else if (j+1 < queue->nnodes && heap[j+1].key > newgain) { j = j+1; heap[i] = heap[j]; locator[heap[i].val] = i; i = j; } else break; } } heap[i].key = newgain; heap[i].val = node; locator[node] = i; }
NTSTATUS InfOpenFile(PHINF InfHandle, PUNICODE_STRING FileName, PULONG ErrorLine) { OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION FileInfo; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; NTSTATUS Status; PCHAR FileBuffer; ULONG FileLength; LARGE_INTEGER FileOffset; PINFCACHE Cache; CheckHeap(); *InfHandle = NULL; *ErrorLine = (ULONG)-1; /* Open the inf file */ InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL); Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!INF_SUCCESS(Status)) { DPRINT("NtOpenFile() failed (Status %lx)\n", Status); return(Status); } DPRINT("NtOpenFile() successful\n"); /* Query file size */ Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!INF_SUCCESS(Status)) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return(Status); } FileLength = FileInfo.EndOfFile.u.LowPart; DPRINT("File size: %lu\n", FileLength); /* Allocate file buffer */ FileBuffer = MALLOC(FileLength + 1); if (FileBuffer == NULL) { DPRINT1("MALLOC() failed\n"); NtClose(FileHandle); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Read file */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FileBuffer, FileLength, &FileOffset, NULL); /* Append string terminator */ FileBuffer[FileLength] = 0; NtClose(FileHandle); if (!INF_SUCCESS(Status)) { DPRINT("NtReadFile() failed (Status %lx)\n", Status); FREE(FileBuffer); return(Status); } /* Allocate infcache header */ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); if (Cache == NULL) { DPRINT("MALLOC() failed\n"); FREE(FileBuffer); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Initialize inicache header */ ZEROMEMORY(Cache, sizeof(INFCACHE)); /* Parse the inf buffer */ Status = InfpParseBuffer (Cache, FileBuffer, FileBuffer + FileLength, ErrorLine); if (!INF_SUCCESS(Status)) { FREE(Cache); Cache = NULL; } /* Free file buffer */ FREE(FileBuffer); *InfHandle = (HINF)Cache; return(Status); }
NTSTATUS InfOpenBufferedFile(PHINF InfHandle, PVOID Buffer, ULONG BufferSize, LANGID LanguageId, PULONG ErrorLine) { INFSTATUS Status; PINFCACHE Cache; PCHAR FileBuffer; ULONG FileBufferSize; CheckHeap(); *InfHandle = NULL; *ErrorLine = (ULONG)-1; /* Allocate file buffer */ FileBufferSize = BufferSize + 2; FileBuffer = MALLOC(FileBufferSize); if (FileBuffer == NULL) { DPRINT1("MALLOC() failed\n"); return(INF_STATUS_INSUFFICIENT_RESOURCES); } MEMCPY(FileBuffer, Buffer, BufferSize); /* Append string terminator */ FileBuffer[BufferSize] = 0; FileBuffer[BufferSize + 1] = 0; /* Allocate infcache header */ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); if (Cache == NULL) { DPRINT("MALLOC() failed\n"); FREE(FileBuffer); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Initialize inicache header */ ZEROMEMORY(Cache, sizeof(INFCACHE)); Cache->LanguageId = LanguageId; /* Parse the inf buffer */ if (!RtlIsTextUnicode(FileBuffer, FileBufferSize, NULL)) { // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf }; WCHAR *new_buff; // UINT codepage = CP_ACP; UINT offset = 0; // if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) )) // { // codepage = CP_UTF8; // offset = sizeof(utf8_bom); // } new_buff = MALLOC(FileBufferSize * sizeof(WCHAR)); if (new_buff != NULL) { ULONG len; Status = RtlMultiByteToUnicodeN(new_buff, FileBufferSize * sizeof(WCHAR), &len, (char *)FileBuffer + offset, FileBufferSize - offset); Status = InfpParseBuffer(Cache, new_buff, new_buff + len / sizeof(WCHAR), ErrorLine); FREE(new_buff); } else Status = INF_STATUS_INSUFFICIENT_RESOURCES; } else { WCHAR *new_buff = (WCHAR *)FileBuffer; /* UCS-16 files should start with the Unicode BOM; we should skip it */ if (*new_buff == 0xfeff) { new_buff++; FileBufferSize -= sizeof(WCHAR); } Status = InfpParseBuffer(Cache, new_buff, (WCHAR*)((char*)new_buff + FileBufferSize), ErrorLine); } if (!INF_SUCCESS(Status)) { FREE(Cache); Cache = NULL; } /* Free file buffer */ FREE(FileBuffer); *InfHandle = (HINF)Cache; return(Status); }
NTSTATUS InfOpenFile(PHINF InfHandle, PUNICODE_STRING FileName, LANGID LanguageId, PULONG ErrorLine) { OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION FileInfo; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; NTSTATUS Status; PCHAR FileBuffer; ULONG FileLength; ULONG FileBufferLength; LARGE_INTEGER FileOffset; PINFCACHE Cache; CheckHeap(); *InfHandle = NULL; *ErrorLine = (ULONG)-1; /* Open the inf file */ InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL); Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!INF_SUCCESS(Status)) { DPRINT("NtOpenFile() failed (Status %lx)\n", Status); return(Status); } DPRINT("NtOpenFile() successful\n"); /* Query file size */ Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!INF_SUCCESS(Status)) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return(Status); } FileLength = FileInfo.EndOfFile.u.LowPart; DPRINT("File size: %lu\n", FileLength); /* Allocate file buffer */ FileBufferLength = FileLength + 2; FileBuffer = MALLOC(FileBufferLength); if (FileBuffer == NULL) { DPRINT1("MALLOC() failed\n"); NtClose(FileHandle); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Read file */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FileBuffer, FileLength, &FileOffset, NULL); /* Append string terminator */ FileBuffer[FileLength] = 0; FileBuffer[FileLength + 1] = 0; NtClose(FileHandle); if (!INF_SUCCESS(Status)) { DPRINT("NtReadFile() failed (Status %lx)\n", Status); FREE(FileBuffer); return(Status); } /* Allocate infcache header */ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); if (Cache == NULL) { DPRINT("MALLOC() failed\n"); FREE(FileBuffer); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Initialize inicache header */ ZEROMEMORY(Cache, sizeof(INFCACHE)); Cache->LanguageId = LanguageId; /* Parse the inf buffer */ if (!RtlIsTextUnicode(FileBuffer, FileBufferLength, NULL)) { // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf }; WCHAR *new_buff; // UINT codepage = CP_ACP; UINT offset = 0; // if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) )) // { // codepage = CP_UTF8; // offset = sizeof(utf8_bom); // } new_buff = MALLOC(FileBufferLength * sizeof(WCHAR)); if (new_buff != NULL) { ULONG len; Status = RtlMultiByteToUnicodeN(new_buff, FileBufferLength * sizeof(WCHAR), &len, (char *)FileBuffer + offset, FileBufferLength - offset); Status = InfpParseBuffer(Cache, new_buff, new_buff + len / sizeof(WCHAR), ErrorLine); FREE(new_buff); } else Status = INF_STATUS_INSUFFICIENT_RESOURCES; } else { WCHAR *new_buff = (WCHAR *)FileBuffer; /* UCS-16 files should start with the Unicode BOM; we should skip it */ if (*new_buff == 0xfeff) { new_buff++; FileBufferLength -= sizeof(WCHAR); } Status = InfpParseBuffer(Cache, new_buff, (WCHAR*)((char*)new_buff + FileBufferLength), ErrorLine); } if (!INF_SUCCESS(Status)) { FREE(Cache); Cache = NULL; } /* Free file buffer */ FREE(FileBuffer); *InfHandle = (HINF)Cache; return(Status); }