From: Vincent Fatica on
On Mon, 7 Sep 2009 21:44:17 +0300, "Alex Blekhman" <tkfx.REMOVE(a)yahoo.com>
wrote:

|Even if you use a custom entry point it is still must conform to
|the expected signature of [w]WinMain or [w]main. Also, calling
|convention must be __stdcall for Windows subsystem and __cdecl for
|console subsystem.

To avoid the RTL I often use a custom entry point and I often violate the
conventions you mentioned. I haven't gotten into trouble yet. Please
elaborate.
--
- Vince
From: Alex Blekhman on
"Vincent Fatica" wrote:
> To avoid the RTL I often use a custom entry point and I often
> violate the conventions you mentioned. I haven't gotten into
> trouble yet. Please elaborate.

The linker requires that the entry point would be of certain
signature. It means that the code it generates around the call
expects a predefined number of parameters and a predefined calling
convention. I think that calling stack gets corrupted upon exit
from the entry point. I'm not sure why there is no diagnostic
message issued by the system, though. May be it is because there
is no CRT to report it in the convenient way, or the process is
already on its way down when it happens, so no point to report it,
or whatever else. But it seems to me unclean to violate this
requirement while the linker's documentation explicitly insists on
it.

Alex

From: Vincent Fatica on
On Mon, 7 Sep 2009 23:58:19 +0300, "Alex Blekhman" <tkfx.REMOVE(a)yahoo.com>
wrote:

|"Vincent Fatica" wrote:
|> To avoid the RTL I often use a custom entry point and I often
|> violate the conventions you mentioned. I haven't gotten into
|> trouble yet. Please elaborate.
|
|The linker requires that the entry point would be of certain
|signature. It means that the code it generates around the call
|expects a predefined number of parameters and a predefined calling
|convention. I think that calling stack gets corrupted upon exit
|from the entry point. I'm not sure why there is no diagnostic
|message issued by the system, though. May be it is because there
|is no CRT to report it in the convenient way, or the process is
|already on its way down when it happens, so no point to report it,
|or whatever else. But it seems to me unclean to violate this
|requirement while the linker's documentation explicitly insists on
|it.

Can you point me to that linker documentation?

If you look at the CRT startup routines (the typical entry points, crtexe.c) for
EXEs, you see that they are __cdecl, taking, no args and returning an int. They
examine a command line, do their thing, and eventually call main, wmain, or
WinMain. So the signatures of main, wmain, and WinMain are very important. But
if you're not using the CRT startup routines and you are specifying an entry
point, it would seem that int __cdecl ...(void) is appropriate.
--
- Vince
From: xiaosi on
Besides call convention, ExitProcess should be used instead of return, because both tmainCRTStartup and tWinMainCRTStartup call
kernel32!ExitProcess(status) after tmain or tWinMain return status.

If you use Common Dialog Box in your app, and return (instead of ExitProcess) to exit app, the process will not exit (the thread of
Common Dialog Box is still existing).

#pragma comment(linker, "/subsystem:windows")
#pragma comment(linker, "/entry:mywinmain")
int __stdcall mywinmain() {
....
ExitProcess(msg.wParam);
}

#pragma comment(linker, "/subsystem:console")
#pragma comment(linker, "/entry:mymain")
int __cdecl mymain() {
....
ExitProcess(status);
}

"Vincent Fatica" <vince(a)blackholespam.net> wrote:
> On Mon, 7 Sep 2009 21:44:17 +0300, "Alex Blekhman" <tkfx.REMOVE(a)yahoo.com>
> wrote:
>
> |Even if you use a custom entry point it is still must conform to
> |the expected signature of [w]WinMain or [w]main. Also, calling
> |convention must be __stdcall for Windows subsystem and __cdecl for
> |console subsystem.
>
> To avoid the RTL I often use a custom entry point and I often violate the
> conventions you mentioned. I haven't gotten into trouble yet. Please
> elaborate.
> --
> - Vince

From: xiaosi on
One day I dumpbin /headers /exports ntdll.dll > exports_ntdll.txt, and find ntdll.dll has many "built-in" crt functions. When system
loads an app, it always firstly maps ntdll.dll to the app's process. This means every app has these "built-in" crt functions, so why
bother to import these functions from the crt lib (except using inline for speed). wcstoul/wcstol/strtoul/strtol are also "built-in"
in ntdll.dll.

1180 49B 0000E5C6 _CIcos = __CIcos
1181 49C 0000E682 _CIlog = __CIlog
1182 49D 0000E002 _CIpow = __CIpow
1183 49E 000012D1 _CIsin = __CIsin
1184 49F 0000137F _CIsqrt = __CIsqrt
1185 4A0 0002C8A2 __isascii = ___isascii
1186 4A1 0006F64B __iscsym = ___iscsym
1187 4A2 0006F605 __iscsymf = ___iscsymf
1188 4A3 0006F5F3 __toascii = ___toascii
1189 4A4 0000143B _alldiv = __alldiv
1190 4A5 000014E5 _alldvrm = __alldvrm
1191 4A6 000015C4 _allmul = __allmul
1192 4A7 000015F8 _alloca_probe = __alloca_probe
1193 4A8 00001635 _allrem = __allrem
1194 4A9 000016E9 _allshl = __allshl
1195 4AA 00001708 _allshr = __allshr
1196 4AB 0006F691 _atoi64 = __atoi64
1197 4AC 00001729 _aulldiv = __aulldiv
1198 4AD 00001791 _aulldvrm = __aulldvrm
1199 4AE 00001826 _aullrem = __aullrem
1200 4AF 0000189B _aullshr = __aullshr
1201 4B0 000015F8 _chkstk = __alloca_probe
1202 4B1 0007B048 _fltused = __fltused
1203 4B2 000018BA _ftol = __ftol
1204 4B3 0006F80D _i64toa = __i64toa
1205 4B4 0006F92F _i64tow = __i64tow
1206 4B5 0002E964 _itoa = __itoa
1207 4B6 0002DC81 _itow = __itow
1208 4B7 0006F989 _lfind = __lfind
1209 4B8 0006F74E _ltoa = __ltoa
1210 4B9 0006F867 _ltow = __ltow
1211 4BA 000018E1 _memccpy = __memccpy
1212 4BB 0006F9C2 _memicmp = __memicmp
1213 4BC 0006F9D2 _snprintf = __snprintf
1214 4BD 0001BBCA _snwprintf = __snwprintf
1215 4BE 0006FA30 _splitpath = __splitpath
1216 4BF 00012E44 _strcmpi = __stricmp
1217 4C0 00012E44 _stricmp = __stricmp
1218 4C1 0006FB78 _strlwr = __strlwr
1219 4C2 0001987D _strnicmp = __strnicmp
1220 4C3 0006FBA5 _strupr = __strupr
1221 4C4 0006FBD2 _tolower = __tolower
1222 4C5 0006FC1F _toupper = __toupper
1223 4C6 0006F845 _ui64toa = __ui64toa
1224 4C7 0006F967 _ui64tow = __ui64tow
1225 4C8 0006F77A _ultoa = __ultoa
1226 4C9 0006F893 _ultow = __ultow
1227 4CA 0002FB67 _vsnprintf = __vsnprintf
1228 4CB 0006FC31 _vsnwprintf = __vsnwprintf
1229 4CC 00013358 _wcsicmp = __wcsicmp
1230 4CD 00024849 _wcslwr = __wcslwr
1231 4CE 000181CD _wcsnicmp = __wcsnicmp
1232 4CF 0006FCA7 _wcsupr = __wcsupr
1233 4D0 0006FCDD _wtoi = __wtoi
1234 4D1 0006FCED _wtoi64 = __wtoi64
1235 4D2 0003684A _wtol = __wtol
1236 4D3 0006FD8A abs = _labs
1237 4D4 00001934 atan = _atan
1238 4D5 00024889 atoi = _atoi
1239 4D6 00024896 atol = _atol
1240 4D7 000151D3 bsearch = _bsearch
1241 4D8 000019D7 ceil = _ceil
1242 4D9 0000E5DA cos = _cos
1243 4DA 0006FD9F fabs = _fabs
1244 4DB 00001B18 floor = _floor
1245 4DC 0006F518 isalnum = _isalnum
1246 4DD 0006F3DC isalpha = _isalpha
1247 4DE 0006F5C0 iscntrl = _iscntrl
1248 4DF 0002C879 isdigit = _isdigit
1249 4E0 0006F588 isgraph = _isgraph
1250 4E1 0006F447 islower = _islower
1251 4E2 0006F550 isprint = _isprint
1252 4E3 0006F4E5 ispunct = _ispunct
1253 4E4 0006F4B2 isspace = _isspace
1254 4E5 0006F414 isupper = _isupper
1255 4E6 0006FE57 iswalpha = _iswalpha
1256 4E7 000269D1 iswctype = _iswctype
1257 4E8 00026A75 iswdigit = _iswdigit
1258 4E9 0006FE72 iswlower = _iswlower
1259 4EA 0006FEA5 iswspace = _iswspace
1260 4EB 0006FE8A iswxdigit = _iswxdigit
1261 4EC 0006F47A isxdigit = _isxdigit
1262 4ED 0006FD8A labs = _labs
1263 4EE 0000E67E log = _log
1264 4EF 0002490C mbstowcs = _mbstowcs
1265 4F0 00001C60 memchr = _memchr
1266 4F1 00001D07 memcmp = _memcmp
1267 4F2 00001DB3 memcpy = _memcpy
1268 4F3 000020F5 memmove = _memmove
1269 4F4 00002435 memset = _memset
1270 4F5 0000DFFD pow = _pow
1271 4F6 000203B8 qsort = _qsort
1272 4F7 000012E5 sin = _sin
1273 4F8 00025BA4 sprintf = _sprintf
1274 4F9 00001393 sqrt = _sqrt
1275 4FA 0006FEBD sscanf = _sscanf
1276 4FB 0000249D strcat = _strcat
1277 4FC 0000E7ED strchr = _strchr
1278 4FD 00002583 strcmp = _strcmp
1279 4FE 0000248D strcpy = _strcpy
1280 4FF 00002608 strcspn = _strcspn
1281 500 00002645 strlen = _strlen
1282 501 000026C0 strncat = _strncat
1283 502 000027E5 strncmp = _strncmp
1284 503 0000281D strncpy = _strncpy
1285 504 0000291D strpbrk = _strpbrk
1286 505 00002956 strrchr = _strrchr
1287 506 0000297D strspn = _strspn
1288 507 0000E75E strstr = _strstr
1289 508 000700B2 strtol = _strtol
1290 509 000700D1 strtoul = _strtoul
1291 50A 000184BB swprintf = _swprintf
1292 50B 000029CE tan = _tan
1293 50C 0006FBE4 tolower = _tolower
1294 50D 00023D13 toupper = _toupper
1295 50E 0002A826 towlower = _towlower
1296 50F 000700F0 towupper = _towupper
1297 510 00020304 vDbgPrintEx = _vDbgPrintEx(a)16
1298 511 0001EA5B vDbgPrintExWithPrefix = _vDbgPrintExWithPrefix(a)20
1299 512 00070104 vsprintf = _vsprintf
1300 513 00018112 wcscat = _wcscat
1301 514 00014962 wcschr = _wcschr
1302 515 00035424 wcscmp = _wcscmp
1303 516 00012F40 wcscpy = _wcscpy
1304 517 000356EE wcscspn = _wcscspn
1305 518 0000FE2A wcslen = _wcslen
1306 519 00018B24 wcsncat = _wcsncat
1307 51A 0001E40F wcsncmp = _wcsncmp
1308 51B 0001055F wcsncpy = _wcsncpy
1309 51C 00070162 wcspbrk = _wcspbrk
1310 51D 00014671 wcsrchr = _wcsrchr
1311 51E 000701AB wcsspn = _wcsspn
1312 51F 0002380F wcsstr = _wcsstr
1313 520 00029F03 wcstol = _wcstol
1314 521 000701F9 wcstombs = _wcstombs
1315 522 00034D91 wcstoul = _wcstoul

"Vincent Fatica" <vince(a)blackholespam.net> wrote:
> Thanks for that. After grep-ing through an archive of projects for "BOOL
> bInQuotes" I'm embarrassed to admit how many times I have done something
> similar. :-)
>
> Have you got any other tips on avoiding the RTL?
>
> wsprintf() is invaluable as are the lstr* functions (now I've learned that some
> of the wcs* functions have intrinsic/inline versions).
>
> I have often wanted something to turn a string into a number. If I insist on
> avoiding the RTL, I use StrToIntEx and feel a bit guilty dragging in shlwapi.dll
> for only that reason.
> --
> - Vince