Use of binary search in LdrFindResource_U. Patch by Alexey Stepanenko <alexeystepanenko@mail.ru>.

svn path=/trunk/; revision=7148
This commit is contained in:
Filip Navara 2003-12-20 21:43:27 +00:00
parent 088013a7f1
commit 01d6bd1786

View file

@ -1,4 +1,4 @@
/* $Id: res.c,v 1.5 2003/08/22 20:00:39 weiden Exp $ /* $Id: res.c,v 1.6 2003/12/20 21:43:27 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -49,12 +49,11 @@ LdrFindResource_U(PVOID BaseAddress,
PIMAGE_RESOURCE_DIRECTORY ResBase; PIMAGE_RESOURCE_DIRECTORY ResBase;
PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry; PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
ULONG EntryCount;
PWCHAR ws; PWCHAR ws;
ULONG i; ULONG i;
ULONG Id; ULONG Id;
LONG low, high, mid, result;
//DPRINT("LdrFindResource_U()\n");
DPRINT("LdrFindResource_U(%08x, %08x, %d, %08x)\n", BaseAddress, ResourceInfo, Level, ResourceDataEntry); DPRINT("LdrFindResource_U(%08x, %08x, %d, %08x)\n", BaseAddress, ResourceInfo, Level, ResourceDataEntry);
/* Get the pointer to the resource directory */ /* Get the pointer to the resource directory */
@ -77,43 +76,51 @@ LdrFindResource_U(PVOID BaseAddress,
// ResourceInfo.Name = (ULONG)lpName; // ResourceInfo.Name = (ULONG)lpName;
// ResourceInfo.Language = (ULONG)wLanguage; // ResourceInfo.Language = (ULONG)wLanguage;
EntryCount = ResDir->NumberOfNamedEntries;
DPRINT(" Id: %d NumberOfNamedEntries: %d\n", Id, EntryCount);
ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1);
//DPRINT("ResEntry %x\n", (ULONG)ResEntry);
if (Id & 0xFFFF0000) { if (Id & 0xFFFF0000) {
/* Resource name is a unicode string */ /* Resource name is a unicode string */
ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1);
DPRINT("ResEntry %x - Resource name is a unicode string\n", (ULONG)ResEntry); DPRINT("ResEntry %x - Resource name is a unicode string\n", (ULONG)ResEntry);
DPRINT("EntryCount %d\n", (ULONG)EntryCount); DPRINT("EntryCount %d\n", (ULONG)ResDir->NumberOfNamedEntries);
for (; EntryCount--; ResEntry++) {
/* Scan entries for equal name */ low = 0;
if (ResEntry->Name & 0x80000000) { high = ResDir->NumberOfNamedEntries - 1;
ws = (PWCHAR)((ULONG)ResBase + (ResEntry->Name & 0x7FFFFFFF)); mid = high/2;
if (!_wcsnicmp((PWCHAR)Id, ws + 1, *ws) && while( low <= high ) {
wcslen((PWCHAR)Id) == (int)*ws) { /* Does we need check if it's named entry, think not */
goto found; ws = (PWCHAR)((ULONG)ResBase + (ResEntry[mid].Name & 0x7FFFFFFF));
} result = _wcsnicmp((PWCHAR)Id, ws + 1, *ws);
} /* Need double check for lexical & length */
if(result == 0) {
result = (wcslen((PWCHAR)Id) - (int)*ws);
if(result == 0) goto found;
}
if(result < 0)
high = mid - 1;
else
low = mid + 1;
mid = (low + high)/2;
} }
} else { } else {
/* We use ID number instead of string */ /* We use ID number instead of string */
ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1) + ResDir->NumberOfNamedEntries;
DPRINT("ResEntry %x - Resource ID number instead of string\n", (ULONG)ResEntry); DPRINT("ResEntry %x - Resource ID number instead of string\n", (ULONG)ResEntry);
DPRINT("EntryCount %d\n", (ULONG)EntryCount); DPRINT("EntryCount %d\n", (ULONG)ResDir->NumberOfIdEntries);
ResEntry += EntryCount;
EntryCount = ResDir->NumberOfIdEntries;
DPRINT("EntryCount %d\n", (ULONG)EntryCount);
for (; EntryCount--; ResEntry++) {
/* Scan entries for equal name */
DPRINT("EntryCount %d ResEntry %x\n", (ULONG)EntryCount, ResEntry);
DPRINT("ResEntry->Name %x Id %x\n", (ULONG)ResEntry->Name, Id);
if (ResEntry->Name == Id) {
DPRINT("ID entry found %x\n", Id);
goto found;
}
}
}
//DPRINT("Error %lu\n", i); low = 0;
high = ResDir->NumberOfIdEntries - 1;
mid = high/2;
while( low <= high ) {
result = Id - ResEntry[mid].Name;
if(result == 0) goto found;
if(result < 0)
high = mid - 1;
else
low = mid + 1;
mid = (low + high)/2;
}
}
switch (i) { switch (i) {
case 0: case 0:
@ -139,7 +146,7 @@ LdrFindResource_U(PVOID BaseAddress,
} }
found:; found:;
ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase + ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase +
(ResEntry->OffsetToData & 0x7FFFFFFF)); (ResEntry[mid].OffsetToData & 0x7FFFFFFF));
} }
DPRINT("ResourceDataEntry: %x\n", (ULONG)ResDir); DPRINT("ResourceDataEntry: %x\n", (ULONG)ResDir);