Reading Message Table resources from DLL files: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
CancerFace (talk | contribs) No edit summary |
(acoueltri) |
||
Line 2: | Line 2: | ||
NSIS forum [http://forums.winamp.com/showthread.php?s=&threadid=246116 thread] | NSIS forum [http://forums.winamp.com/showthread.php?s=&threadid=246116 thread] | ||
lileto | |||
== Usage == | == Usage == |
Revision as of 22:24, 4 December 2008
Author: CancerFace (talk, contrib) |
NSIS forum thread
lileto
Usage
Call the macro from within your script passing the full path and name of the DLL file containing the Message Table, the ID of the string to get out as well as a variable that will accept the output:
Var "StringFromDLL" !insertmacro ReadStringFromDLL "<path_to_dll>\<filename.dll>" <String_ID> $StringFromDLL
Macro
If you want to get the string into a variable use the following macro:
!define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 !define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 !define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 !define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF !macro ReadStringFromDLL LIBRARY STRING_ID VAR System::Call 'kernel32::GetSystemDefaultLangID(i v)i .R0' System::Call 'kernel32::LoadLibraryExW(w "${LIBRARY}", i n, i 2) i .R1' StrCpy $0 ${FORMAT_MESSAGE_FROM_HMODULE} IntOp $0 $0 + ${FORMAT_MESSAGE_ALLOCATE_BUFFER} IntOp $0 $0 + ${FORMAT_MESSAGE_IGNORE_INSERTS} IntOp $0 $0 + ${FORMAT_MESSAGE_MAX_WIDTH_MASK} System::Call 'kernel32::FormatMessageW(i r0, i R1, i ${STRING_ID}, i R0, *w .R2, i 0, i n) i .R3' System::Call 'kernel32::FreeLibrary(i R1)i .R8' StrCpy ${VAR} $R2 !macroend
If you want to get the string into a buffer and use it directly from the buffer in order to avoid placing unicode characters into an NSIS variable use the following macro:
!define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 !define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 !define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF !macro ReadStringFromDLL LIBRARY STRING_ID BUFFER_VAR System::Call 'kernel32::GetSystemDefaultLangID(i v)i .R0' System::Call 'kernel32::LoadLibraryExW(w "${LIBRARY}", i n, i 2) i .R1' StrCpy $0 ${FORMAT_MESSAGE_FROM_HMODULE} IntOp $0 $0 + ${FORMAT_MESSAGE_IGNORE_INSERTS} IntOp $0 $0 + ${FORMAT_MESSAGE_MAX_WIDTH_MASK} System::Call '*(&w${NSIS_MAX_STRLEN})i.R2' System::Call 'kernel32::FormatMessageW(i r0, i R1, i ${STRING_ID}, i R0, i R2, i ${NSIS_MAX_STRLEN}, i n) i .R3' System::Call 'kernel32::FreeLibrary(i R1)i .R8' StrCpy ${BUFFER_VAR} $R2 !macroend
Now ${BUFFER_VAR} will be a pointer to an address containing the wide string. This address can be directly passed to other APIs without exporting the string to an NSIS variable.
Notes
- The FormatMessage function used in the above macros exports to $R3 the size of the string that has been read from the library expressed as TCHARS.
- If the ${FORMAT_MESSAGE_ALLOCATE_BUFFER} parameter is not used when calling the FormatMessage API, the user should provide the size of the buffer to be allocated (6th parameter of the FormatMessage call) in TCHARS.
Resources and Links
- NSIS forum thread
API Functions used: