diff --git a/MemoryModule.c b/MemoryModule.c index cf38388..817ccef 100644 --- a/MemoryModule.c +++ b/MemoryModule.c @@ -27,7 +27,6 @@ #include #include #include -#include #ifdef DEBUG_OUTPUT #include #endif @@ -792,28 +791,95 @@ int MemoryCallEntryPoint(HMEMORYMODULE mod) #define DEFAULT_LANGUAGE MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) -HMEMORYRSRC MemoryFindResource(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type) +HMEMORYRSRC MemoryFindResourceA(HMEMORYMODULE module, LPCSTR name, LPCSTR type) { - return MemoryFindResourceEx(module, name, type, DEFAULT_LANGUAGE); + return MemoryFindResourceExA(module, name, type, DEFAULT_LANGUAGE); } -static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry( +HMEMORYRSRC MemoryFindResourceW(HMEMORYMODULE module, LPCWSTR name, LPCWSTR type) +{ + return MemoryFindResourceExW(module, name, type, DEFAULT_LANGUAGE); +} + +static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntryById( + PIMAGE_RESOURCE_DIRECTORY resources, + WORD id) +{ + PIMAGE_RESOURCE_DIRECTORY_ENTRY entries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (resources + 1); + PIMAGE_RESOURCE_DIRECTORY_ENTRY result = NULL; + DWORD start = resources->NumberOfNamedEntries; + DWORD end = start + resources->NumberOfIdEntries; + + while (end > start) { + DWORD middle = (start + end) >> 1; + WORD entryName = (WORD) entries[middle].Name; + if (id < entryName) { + end = (end != middle ? middle : middle-1); + } else if (id > entryName) { + start = (start != middle ? middle : middle+1); + } else { + result = &entries[middle]; + break; + } + } + return result; +} + +static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntryByString( void *root, PIMAGE_RESOURCE_DIRECTORY resources, - LPCTSTR key) + LPCWSTR key, + size_t keylen) { PIMAGE_RESOURCE_DIRECTORY_ENTRY entries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (resources + 1); PIMAGE_RESOURCE_DIRECTORY_ENTRY result = NULL; - DWORD start; - DWORD end; - DWORD middle; + DWORD start = 0; + DWORD end = resources->NumberOfNamedEntries; + + while (end > start) { + DWORD middle = (start + end) >> 1; + PIMAGE_RESOURCE_DIR_STRING_U resourceString = (PIMAGE_RESOURCE_DIR_STRING_U) OffsetPointer(root, entries[middle].Name & 0x7FFFFFFF); + int cmp = _wcsnicmp(key, resourceString->NameString, resourceString->Length); + if (cmp == 0) { + // Handle partial match + if (keylen > (size_t) resourceString->Length) { + cmp = 1; + } else if (keylen < (size_t) resourceString->Length) { + cmp = -1; + } + } + if (cmp < 0) { + end = (middle != end ? middle : middle-1); + } else if (cmp > 0) { + start = (middle != start ? middle : middle+1); + } else { + result = &entries[middle]; + break; + } + } + + return result; +} + +static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntryA( + void *root, + PIMAGE_RESOURCE_DIRECTORY resources, + LPCSTR key) +{ + PIMAGE_RESOURCE_DIRECTORY_ENTRY result = NULL; + size_t searchKeyLen; +#define MAX_LOCAL_KEY_LENGTH 2048 + // In most cases resource names are short, so optimize for that by + // using a pre-allocated array. + wchar_t _searchKeySpace[MAX_LOCAL_KEY_LENGTH+1]; + LPWSTR _searchKey; - if (!IS_INTRESOURCE(key) && key[0] == TEXT('#')) { + if (!IS_INTRESOURCE(key) && key[0] == '#') { // special case: resource id given as string - TCHAR *endpos = NULL; - long int tmpkey = (WORD) _tcstol((TCHAR *) &key[1], &endpos, 10); - if (tmpkey <= 0xffff && lstrlen(endpos) == 0) { - key = MAKEINTRESOURCE(tmpkey); + char *endpos = NULL; + long int tmpkey = (WORD) strtol(key + 1, &endpos, 10); + if (tmpkey <= 0xffff && strlen(endpos) == 0) { + key = MAKEINTRESOURCEA(tmpkey); } } @@ -821,88 +887,112 @@ static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry( // followed by an ordered list of id entries - we can do // a binary search to find faster... if (IS_INTRESOURCE(key)) { - WORD check = (WORD) (uintptr_t) key; - start = resources->NumberOfNamedEntries; - end = start + resources->NumberOfIdEntries; - - while (end > start) { - WORD entryName; - middle = (start + end) >> 1; - entryName = (WORD) entries[middle].Name; - if (check < entryName) { - end = (end != middle ? middle : middle-1); - } else if (check > entryName) { - start = (start != middle ? middle : middle+1); - } else { - result = &entries[middle]; - break; - } + return _MemorySearchResourceEntryById(resources, (WORD) (uintptr_t) key); + } + + // Resource names are always stored using 16bit characters, need to + // convert string we search for. + searchKeyLen = strlen(key); + if (searchKeyLen > MAX_LOCAL_KEY_LENGTH) { + size_t _searchKeySize = (searchKeyLen + 1) * sizeof(wchar_t); + _searchKey = (LPWSTR) malloc(_searchKeySize); + if (_searchKey == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return NULL; } } else { - LPCWSTR searchKey; - size_t searchKeyLen = _tcslen(key); -#if defined(UNICODE) - searchKey = key; -#else - // Resource names are always stored using 16bit characters, need to - // convert string we search for. -#define MAX_LOCAL_KEY_LENGTH 2048 - // In most cases resource names are short, so optimize for that by - // using a pre-allocated array. - wchar_t _searchKeySpace[MAX_LOCAL_KEY_LENGTH+1]; - LPWSTR _searchKey; - if (searchKeyLen > MAX_LOCAL_KEY_LENGTH) { - size_t _searchKeySize = (searchKeyLen + 1) * sizeof(wchar_t); - _searchKey = (LPWSTR) malloc(_searchKeySize); - if (_searchKey == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - return NULL; - } - } else { - _searchKey = &_searchKeySpace[0]; - } + _searchKey = &_searchKeySpace[0]; + } + mbstowcs(_searchKey, key, searchKeyLen); + _searchKey[searchKeyLen] = 0; - mbstowcs(_searchKey, key, searchKeyLen); - _searchKey[searchKeyLen] = 0; - searchKey = _searchKey; -#endif - start = 0; - end = resources->NumberOfNamedEntries; - while (end > start) { - int cmp; - PIMAGE_RESOURCE_DIR_STRING_U resourceString; - middle = (start + end) >> 1; - resourceString = (PIMAGE_RESOURCE_DIR_STRING_U) OffsetPointer(root, entries[middle].Name & 0x7FFFFFFF); - cmp = _wcsnicmp(searchKey, resourceString->NameString, resourceString->Length); - if (cmp == 0) { - // Handle partial match - if (searchKeyLen > resourceString->Length) { - cmp = 1; - } else if (searchKeyLen < resourceString->Length) { - cmp = -1; - } - } - if (cmp < 0) { - end = (middle != end ? middle : middle-1); - } else if (cmp > 0) { - start = (middle != start ? middle : middle+1); - } else { - result = &entries[middle]; - break; - } + result = _MemorySearchResourceEntryByString(root, resources, _searchKey, searchKeyLen); + if (searchKeyLen > MAX_LOCAL_KEY_LENGTH) { + free(_searchKey); + } +#undef MAX_LOCAL_KEY_LENGTH + return result; +} + +static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntryW( + void *root, + PIMAGE_RESOURCE_DIRECTORY resources, + LPCWSTR key) +{ + if (!IS_INTRESOURCE(key) && key[0] == L'#') { + // special case: resource id given as string + wchar_t *endpos = NULL; + long int tmpkey = (WORD) wcstol(key + 1, &endpos, 10); + if (tmpkey <= 0xffff && wcslen(endpos) == 0) { + key = MAKEINTRESOURCEW(tmpkey); } -#if !defined(UNICODE) - if (searchKeyLen > MAX_LOCAL_KEY_LENGTH) { - free(_searchKey); + } + + // entries are stored as ordered list of named entries, + // followed by an ordered list of id entries - we can do + // a binary search to find faster... + if (IS_INTRESOURCE(key)) { + return _MemorySearchResourceEntryById(resources, (WORD) (uintptr_t) key); + } + + return _MemorySearchResourceEntryByString(root, resources, key, wcslen(key)); +} + +HMEMORYRSRC MemoryFindResourceExA(HMEMORYMODULE module, LPCSTR name, LPCSTR type, WORD language) +{ + unsigned char *codeBase = ((PMEMORYMODULE) module)->codeBase; + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE) module, IMAGE_DIRECTORY_ENTRY_RESOURCE); + PIMAGE_RESOURCE_DIRECTORY rootResources; + PIMAGE_RESOURCE_DIRECTORY nameResources; + PIMAGE_RESOURCE_DIRECTORY typeResources; + PIMAGE_RESOURCE_DIRECTORY_ENTRY foundType; + PIMAGE_RESOURCE_DIRECTORY_ENTRY foundName; + PIMAGE_RESOURCE_DIRECTORY_ENTRY foundLanguage; + if (directory->Size == 0) { + // no resource table found + SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); + return NULL; + } + + if (language == DEFAULT_LANGUAGE) { + // use language from current thread + language = LANGIDFROMLCID(GetThreadLocale()); + } + + // resources are stored as three-level tree + // - first node is the type + // - second node is the name + // - third node is the language + rootResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress); + foundType = _MemorySearchResourceEntryA(rootResources, rootResources, type); + if (foundType == NULL) { + SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND); + return NULL; + } + + typeResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundType->OffsetToData & 0x7fffffff)); + foundName = _MemorySearchResourceEntryA(rootResources, typeResources, name); + if (foundName == NULL) { + SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); + return NULL; + } + + nameResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundName->OffsetToData & 0x7fffffff)); + foundLanguage = _MemorySearchResourceEntryA(rootResources, nameResources, (LPCSTR) (uintptr_t) language); + if (foundLanguage == NULL) { + // requested language not found, use first available + if (nameResources->NumberOfIdEntries == 0) { + SetLastError(ERROR_RESOURCE_LANG_NOT_FOUND); + return NULL; } -#undef MAX_LOCAL_KEY_LENGTH -#endif + + foundLanguage = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (nameResources + 1); } - return result; + return (codeBase + directory->VirtualAddress + (foundLanguage->OffsetToData & 0x7fffffff)); } -HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type, WORD language) +HMEMORYRSRC MemoryFindResourceExW(HMEMORYMODULE module, LPCWSTR name, LPCWSTR type, WORD language) { unsigned char *codeBase = ((PMEMORYMODULE) module)->codeBase; PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE) module, IMAGE_DIRECTORY_ENTRY_RESOURCE); @@ -928,21 +1018,21 @@ HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE module, LPCTSTR name, LPCTSTR typ // - second node is the name // - third node is the language rootResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress); - foundType = _MemorySearchResourceEntry(rootResources, rootResources, type); + foundType = _MemorySearchResourceEntryW(rootResources, rootResources, type); if (foundType == NULL) { SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND); return NULL; } typeResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundType->OffsetToData & 0x7fffffff)); - foundName = _MemorySearchResourceEntry(rootResources, typeResources, name); + foundName = _MemorySearchResourceEntryW(rootResources, typeResources, name); if (foundName == NULL) { SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); return NULL; } nameResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundName->OffsetToData & 0x7fffffff)); - foundLanguage = _MemorySearchResourceEntry(rootResources, nameResources, (LPCTSTR) (uintptr_t) language); + foundLanguage = _MemorySearchResourceEntryW(rootResources, nameResources, (LPWSTR) (uintptr_t) language); if (foundLanguage == NULL) { // requested language not found, use first available if (nameResources->NumberOfIdEntries == 0) { @@ -980,49 +1070,103 @@ LPVOID MemoryLoadResource(HMEMORYMODULE module, HMEMORYRSRC resource) } int -MemoryLoadString(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize) +MemoryLoadStringA(HMEMORYMODULE module, UINT id, LPSTR buffer, int maxsize) { - return MemoryLoadStringEx(module, id, buffer, maxsize, DEFAULT_LANGUAGE); + return MemoryLoadStringExA(module, id, buffer, maxsize, DEFAULT_LANGUAGE); } int -MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WORD language) +MemoryLoadStringW(HMEMORYMODULE module, UINT id, LPWSTR buffer, int maxsize) +{ + return MemoryLoadStringExW(module, id, buffer, maxsize, DEFAULT_LANGUAGE); +} + +static BOOL +MemoryLoadStringData(HMEMORYMODULE module, UINT id, HMEMORYRSRC resource, PIMAGE_RESOURCE_DIR_STRING_U* res) +{ + PIMAGE_RESOURCE_DIR_STRING_U data; + + data = (PIMAGE_RESOURCE_DIR_STRING_U) MemoryLoadResource(module, resource); + id = id & 0x0f; + while (id--) { + data = (PIMAGE_RESOURCE_DIR_STRING_U) OffsetPointer(data, (data->Length + 1) * sizeof(WCHAR)); + } + if (data->Length == 0) { + SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); + return FALSE; + } + + *res = data; + return TRUE; +} + +int +MemoryLoadStringExA(HMEMORYMODULE module, UINT id, LPSTR buffer, int maxsize, WORD language) { HMEMORYRSRC resource; PIMAGE_RESOURCE_DIR_STRING_U data; - DWORD size; + int size; + if (maxsize == 0) { + // TODO(fancycode): Should provide pointer to raw data in "buffer". + // Check what should be returned in this case (bytes or characters?). + buffer[0] = 0; return 0; } - resource = MemoryFindResourceEx(module, MAKEINTRESOURCE((id >> 4) + 1), RT_STRING, language); + resource = MemoryFindResourceExA(module, MAKEINTRESOURCEA((id >> 4) + 1), (LPCSTR) RT_STRING, language); if (resource == NULL) { buffer[0] = 0; return 0; } - data = (PIMAGE_RESOURCE_DIR_STRING_U) MemoryLoadResource(module, resource); - id = id & 0x0f; - while (id--) { - data = (PIMAGE_RESOURCE_DIR_STRING_U) OffsetPointer(data, (data->Length + 1) * sizeof(WCHAR)); + if (!MemoryLoadStringData(module, id, resource, &data)) { + buffer[0] = 0; + return 0; } - if (data->Length == 0) { - SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); + + size = data->Length; + if (size >= maxsize) { + size = maxsize; + } else { + buffer[size] = 0; + } + wcstombs(buffer, data->NameString, size); + return size; +} + +int +MemoryLoadStringExW(HMEMORYMODULE module, UINT id, LPWSTR buffer, int maxsize, WORD language) +{ + HMEMORYRSRC resource; + PIMAGE_RESOURCE_DIR_STRING_U data; + int size; + + if (maxsize == 0) { + // TODO(fancycode): Should provide pointer to raw data in "buffer". + // Check what should be returned in this case (bytes or characters?). + buffer[0] = 0; + return 0; + } + + resource = MemoryFindResourceExW(module, MAKEINTRESOURCEW((id >> 4) + 1), (LPCWSTR) RT_STRING, language); + if (resource == NULL) { + buffer[0] = 0; + return 0; + } + + if (!MemoryLoadStringData(module, id, resource, &data)) { buffer[0] = 0; return 0; } size = data->Length; - if (size >= (DWORD) maxsize) { + if (size >= maxsize) { size = maxsize; } else { buffer[size] = 0; } -#if defined(UNICODE) wcsncpy(buffer, data->NameString, size); -#else - wcstombs(buffer, data->NameString, size); -#endif return size; } diff --git a/MemoryModule.h b/MemoryModule.h index a728f6b..df68957 100644 --- a/MemoryModule.h +++ b/MemoryModule.h @@ -39,6 +39,12 @@ typedef void *HCUSTOMMODULE; extern "C" { #endif +#if defined(UNICODE) +#define MEMORYMODULE_FUNCTION_AW(func) func##W +#else +#define MEMORYMODULE_FUNCTION_AW(func) func##A +#endif + typedef LPVOID (*CustomAllocFunc)(LPVOID, SIZE_T, DWORD, DWORD, void*); typedef BOOL (*CustomFreeFunc)(LPVOID, SIZE_T, DWORD, void*); typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *); @@ -94,12 +100,16 @@ int MemoryCallEntryPoint(HMEMORYMODULE); /** * Find the location of a resource with the specified type and name. */ -HMEMORYRSRC MemoryFindResource(HMEMORYMODULE, LPCTSTR, LPCTSTR); +HMEMORYRSRC MemoryFindResourceA(HMEMORYMODULE, LPCSTR, LPCSTR); +HMEMORYRSRC MemoryFindResourceW(HMEMORYMODULE, LPCWSTR, LPCWSTR); +#define MemoryFindResource MEMORYMODULE_FUNCTION_AW(MemoryFindResource) /** * Find the location of a resource with the specified type, name and language. */ -HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE, LPCTSTR, LPCTSTR, WORD); +HMEMORYRSRC MemoryFindResourceExA(HMEMORYMODULE, LPCSTR, LPCSTR, WORD); +HMEMORYRSRC MemoryFindResourceExW(HMEMORYMODULE, LPCWSTR, LPCWSTR, WORD); +#define MemoryFindResourceEx MEMORYMODULE_FUNCTION_AW(MemoryFindResourceEx) /** * Get the size of the resource in bytes. @@ -114,12 +124,16 @@ LPVOID MemoryLoadResource(HMEMORYMODULE, HMEMORYRSRC); /** * Load a string resource. */ -int MemoryLoadString(HMEMORYMODULE, UINT, LPTSTR, int); +int MemoryLoadStringA(HMEMORYMODULE, UINT, LPSTR, int); +int MemoryLoadStringW(HMEMORYMODULE, UINT, LPWSTR, int); +#define MemoryLoadString MEMORYMODULE_FUNCTION_AW(MemoryLoadString) /** * Load a string resource with a given language. */ -int MemoryLoadStringEx(HMEMORYMODULE, UINT, LPTSTR, int, WORD); +int MemoryLoadStringExA(HMEMORYMODULE, UINT, LPSTR, int, WORD); +int MemoryLoadStringExW(HMEMORYMODULE, UINT, LPWSTR, int, WORD); +#define MemoryLoadStringEx MEMORYMODULE_FUNCTION_AW(MemoryLoadStringEx) /** * Default implementation of CustomAllocFunc that calls VirtualAlloc pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy