Is there export function 'GetEnvironmentStrings' in kernel32.lib of masm32 v8.0 or v9.0 ?
masm32 program(masm32 v8.0 compile)
386
.model flat,stdcall
includelib libc.lib
includelib kernel32.lib
printf proto c :dword
.data
msg byte 'Hello',0
.code
main proc c
invoke printf,offset msg
ret
main endp
end
link error:
libc.lib(a_env.obj) : error LNK2001: unresolved external symbol __imp__GetEnvironmentStrings@0
v9.exe : fatal error LNK1120: 1 unresolved externals
if using kernel32.lib of vc6.0 or masm32 v7.0, there are not errors
What the difference between kernel32.lib of masm32 v7(687k) and kernel32.lib of masm32 v8(489k) ?
To use LIBC.LIB, you need to have a lot more of it prototyped but for the API GetEnvironmentStrings() try including the kernel32.inc file from masm32.
If you have it, use masm32 version 9.0, it is much later and has had a lot more work done on it.
Note with the c runtime function "printf" that it is not the library that does the C escapes but the compiler so you will not get them to work without doing the escape expansions yourself.
including the kernel32.inc file from masm32 ,same result (masm32 v9 or masm32 v8)
when using masm v7.0,It work perfectly,I don't get errors,why?
The libraries from version 7 were from the win98 platformsdk where the later ones are built using ML and LINK. If you have your full VC installation try using the lkernel32.lib from there, it should work. Other than that, download a current platformsdk and use the libraries from there, they should also do the job and are probably later than a VC installation.
You may have a chuckle with this one, instead of 32k of c runtime junk using "printf" the MSVCRT routine can be called but it does not have any c escape formatting. I have added a masm32 macro to do most of this.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
.code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
call main
inkey
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
LOCAL estr :DWORD
LOCAL buffer[4096]:BYTE
invoke GetEnvironmentStrings
mov estr, eax
ccout "GetEnvironmentStrings result\n\t"
invoke crt_printf,estr
ccout "\n"
fn GetEnvironmentVariable,"include",ADDR buffer,4096
ccout "GetEnvironmentVariable result\n\t"
invoke crt_printf,ADDR buffer
ccout "\n"
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
thanks.
winbase.h from vc6.0:
WINBASEAPI
LPSTR
WINAPI
GetEnvironmentStrings(
VOID
);
WINBASEAPI
LPWSTR
WINAPI
GetEnvironmentStringsW(
VOID
);
#ifdef UNICODE
#define GetEnvironmentStrings GetEnvironmentStringsW
#else
#define GetEnvironmentStringsA GetEnvironmentStrings---------------------------(1)
#endif // !UNICODE
kernel32.inc form masm32 v8 :
GetEnvironmentStringsA PROTO
GetEnvironmentStrings equ <GetEnvironmentStringsA>-----------------------------(2)
GetEnvironmentStringsW PROTO
compare (1) and (2)
according winbase.h from vc6.0
(2) should like this: GetEnvironmentStringA equ <GetEnvironmentStrings>
why kernel32.inc is
GetEnvironmentStrings equ <GetEnvironmentStringsA>
The following would fail.
GetEnvironmentStringA equ <GetEnvironmentStrings>
The export from the DLL is GetEnvironmentStringA so for the ANSI version the include file for masm does it correctly.
GetEnvironmentStringsA PROTO ; the ANSI prototype
GetEnvironmentStrings equ <GetEnvironmentStringsA> ; the equate for the normal name.
All thisa means in MASM is that when you use "GetEnvironmentStrings" in your code, the name is inserted as "GetEnvironmentStringsA".
Hi,
GetEnvironmentStrings indeed is a bit particular, because kernel32 exports 3 versions:
GetEnvironmentStrings,
GetEnvironmentStringsA and
GetEnvironmentStringsW
Exports GetEnvironmentStrings and GetEnvironmentStringsA have the same address.
GetEnvironmentStrings indeed is a bit particular, because kernel32 exports 3 versions:
GetEnvironmentStrings,
GetEnvironmentStringsA and
GetEnvironmentStringsW
kernel32.dll Exports these functions. but kernel32.lib (masm32 v8) have only exports two of them (GetEnvironmentStringsA and GetEnvironmentStringsW)
kernel32.lib from masm32 v7 exports 3 versions,why?
Hello,
For most of of the api there is an ASCII version and a UNICODE version.
The last letter tell you if you are in ascii or unicode (unicode is two bytes for a caracter)
A for ASCII
W for unicode
Sample GetEnvironmentStringsA is the ascii version of GetEnvironmentStrings
GetEnvironmentStringsW unicode version
Then at compile you can choose ascii or unicode version of the API.
In .h you find
IF @defined UNICODE
GetEnvironmentStrings equ "GetEnvironmentStringsW"
ELSE
GetEnvironmentStrings equ "GetEnvironmentStringsA"
#endif
That all,ToutEnMasm
The problem then being, why does kernel32.dll also export "GetEnvironmentStrings" with no A or W on the end?
Since the entry point is the same as for GetEnvironmentStringsA, I'd guess it is to ensure backwards compatibility with an earlier version. Though one of the better people to ask would be Raymond Chen (http://blogs.msdn.com/oldnewthing/); he talks quite often about compatibility hacks that have been made in Windows.
Taking the view that this extra export is a compatibility hack, I'd say don't use it. Hopefully the day will come where Windows gets cleaned up and all these hacks are removed, though that won't happen until people stop using them. Stick with the equates in kernel32.inc.
BTW. Version 9 of MASM32 is out - any reason for using the older version?
Cheers,
Zooba :U
There is a very simple solution, change the kernel32.inc file like this.
GetEnvironmentStrings PROTO
GetEnvironmentStringsA PROTO
;;; GetEnvironmentStrings equ <GetEnvironmentStringsA>
GetEnvironmentStringsW PROTO
Build the library with inc2l.exe then remove the "GetEnvironmentStrings PROTO" and uncomment the equate.
Thank all of you !
hutch,
Your solution is good,it works find.
btw
when installing masm32 v7.0 ,installer call l2inca.exe to generate the inc file
when installing masm32 v8 or v9 ,installer call inc2l.exe to generate the lib file
is it true ?
Yep,
They worked under a different system. The inc2l.exe in masm32 9.0 is a better version that fixed a potential problem with how some function names were recognised, mainly with the trailing @number in the decorated names.
Sorry for resurrecting this ancient thread but this is still an existing problem with the current v10 release of MASM. I was wondering, is this something which will be addressed or is GetEnvironmentStrings being left behind? I mean, i guess its not a problem to rebuild the lib file, but possibly a small footnote in the changelog/release notes?
I have static libraries, written with VC++ 6.0 and created from dll files with Dll2Lib and for both types, i had to recreate the kernel32.lib file with the prototype instead of an equate and now my projects link just fine.
BR,
Ghandi
Hi Ghandi,
Welcome to the forum.
To create import libraries from DLLs, you could try def2lib (http://www.masm32.com/board/index.php?topic=6390.0) All what you need is a module definition file.
kernel32.def :
LIBRARY kernel32
EXPORTS
"_ActivateActCtx@8"
"_AddAtomA@4"
"_AddAtomW@4"
"_AddConsoleAliasA@12"
"_AddConsoleAliasW@12"
.
.
.
Hi Vortex,
Thanks for the welcome. :) I ended up using Inc2L.exe, but i'll check out Def2Lib. This question is OOT, so disregard if you want, but do you know whether it is possible to create VC++ 9.0 static libraries for use with MASM? When i tried it i got an error from linking, basically saying "File format not recognized".
BR,
Ghandi
Hi Ghandi,
Could try Pelle's library manager Polib to create the static library?
\masm32\bin\ml /c /coff *.asm ; assemble all the files
\masm32\bin\polib /OUT:statlib.lib /MACHINE:IX86 *.obj