static int load_entries(struct search *search, size_t offset) { if (find_first_entry(search->file, search->key, &offset) != 0) return -1; while (!is_full(search) && offset < search->size) { struct entry entry; if (get_entry(search->file, offset, &entry) != 0) return -1; if (entry.key != search->key) return 0; if (entry.weight != 0 && entry.move != 0) add_entry(search, &entry); ++offset; } return 0; }
/********************************************************************** * find_entry * * Find a resource entry */ static NTSTATUS find_entry( HMODULE hmod, const LDR_RESOURCE_INFO *info, ULONG level, const void **ret, int want_dir ) { ULONG size; const void *root; const IMAGE_RESOURCE_DIRECTORY *resdirptr; WORD list[9]; /* list of languages to try */ int i, pos = 0; root = RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size ); if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND; if (size < sizeof(*resdirptr)) return STATUS_RESOURCE_DATA_NOT_FOUND; resdirptr = root; if (!level--) goto done; if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Type, root, want_dir || level ))) return STATUS_RESOURCE_TYPE_NOT_FOUND; if (!level--) return STATUS_SUCCESS; resdirptr = *ret; if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Name, root, want_dir || level ))) return STATUS_RESOURCE_NAME_NOT_FOUND; if (!level--) return STATUS_SUCCESS; if (level) return STATUS_INVALID_PARAMETER; /* level > 3 */ /* 1. specified language */ pos = push_language( list, pos, info->Language ); /* 2. specified language with neutral sublanguage */ pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(info->Language), SUBLANG_NEUTRAL ) ); /* 3. neutral language with neutral sublanguage */ pos = push_language( list, pos, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) ); /* if no explicitly specified language, try some defaults */ if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL) { /* user defaults, unless SYS_DEFAULT sublanguage specified */ if (SUBLANGID(info->Language) != SUBLANG_SYS_DEFAULT) { /* 4. current thread locale language */ pos = push_language( list, pos, LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale) ); /* 5. user locale language */ pos = push_language( list, pos, LANGIDFROMLCID(user_lcid) ); /* 6. user locale language with neutral sublanguage */ pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(user_lcid), SUBLANG_NEUTRAL ) ); } /* now system defaults */ /* 7. system locale language */ pos = push_language( list, pos, LANGIDFROMLCID( system_lcid ) ); /* 8. system locale language with neutral sublanguage */ pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(system_lcid), SUBLANG_NEUTRAL ) ); /* 9. English */ pos = push_language( list, pos, MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) ); } resdirptr = *ret; for (i = 0; i < pos; i++) if ((*ret = find_entry_by_id( resdirptr, list[i], root, want_dir ))) return STATUS_SUCCESS; /* if no explicitly specified language, return the first entry */ if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL) { if ((*ret = find_first_entry( resdirptr, root, want_dir ))) return STATUS_SUCCESS; } return STATUS_RESOURCE_LANG_NOT_FOUND; done: *ret = resdirptr; return STATUS_SUCCESS; }
/** Get all the entries in the directory @param fs FS_Instance to find all the information from @param directory To find all the entries for @return List of entries in the directory **/ FS_EntryList* get_entries(FS_Instance *fs, uint32_t directory) { uint8_t root_directory = find_root_of_directory(fs, directory); uint32_t bytes_per_cluster = ((!root_directory) ? fs->BPB_SecPerClus : 1) * fs->BPB_BytsPerSec; uint32_t entries_per_cluster = bytes_per_cluster / sizeof(FatEntry); FatEntry *entries = malloc(entries_per_cluster * sizeof(FatEntry)); if(NULL == entries) { return NULL; } uint16_t *long_name = NULL; FS_EntryList *list_head = NULL; FS_EntryList *list_tail = NULL; if(root_directory) { directory = fs->current_directory_position; } do { uint64_t seek = directory; if(!root_directory) { seek = get_first_sector(fs, directory); } fseek(fs->image, (seek * fs->BPB_BytsPerSec), SEEK_SET); fread(entries, sizeof(FatEntry), entries_per_cluster, fs->image); for(int i = 0; i < entries_per_cluster; i++) { FatEntry *entry = &(entries[i]); if(0x00 == entry->DIR_Name[0]) { break; } if(0xE5 == entry->DIR_Name[0]) { continue; } if(0x05 == entry->DIR_Name[0]) { entry->DIR_Name[0] = 0xE5; } if(!check_mask(entry->DIR_Attr, ATTR_LONG_NAME)) { uint8_t valid = 1; for (int j = 0; j < DIR_Name_LENGTH; j++) { if (0x20 > entry->DIR_Name[j]) { valid = 0; } } if(!valid) { continue; } FS_EntryList *listEntry = malloc(sizeof(FS_EntryList)); listEntry->node = malloc(sizeof(FS_Entry)); listEntry->node->entry = malloc(sizeof(FatEntry)); memcpy(listEntry->node->entry, entry, sizeof(FatEntry)); listEntry->node->file_name = long_name; long_name = NULL; listEntry->next = NULL; if(NULL != list_tail) { list_tail->next = listEntry; } list_tail = listEntry; if(NULL == list_head) { list_head = listEntry; } } } if(!root_directory) { directory = find_first_entry(fs, directory); } else { directory++; } } while(root_directory ? (directory < (fs->current_directory_position + fs->root_sectors)) : !is_eof(fs, directory)); free(entries); return list_head; }