Hello.
I modified again the crt1.c for check the success of the function
__getmainargs

I investigate this function and I learn some things.

The current protoype is:
int __cdecl __getmainargs (int *pargc, char ***pargv, char ***penvp, int
dowildcard, _startupinfo * startinfo)


and is for the version of msvcrt.dll version 7.0 that is present in windows
xp

But I found that in the version 6.0 of that dll that is present in windows
98 the prototype was:
void __cdecl __getmainargs (int *pargc, char ***pargv, char ***penvp, int
dowildcard, _startupinfo * startinfo)

I get the sources of both from the cd of visual studio 98 and visual studio
2010.

And reading the code and with test I found that the possible result of the
function in:
v6.0 are: success or program termination with error code 255 calling
function _amsg_exit because not memory available.
v7.0 success (returning 0) or return -1 or program termination with -1
calling function ExitProcess because not memory available. The difference
in this last is if the dll was compiled with _SYSCRT definition. I do the
test and in windows 7 and 8, and both on no memory available, end the
program with -1 (using ExitProcess) but on windows xp, the function return
-1.

In the 7.0 version after the error checking, argc and argv are assigned.

Thus, for compatibility with version 6.0 and 7.0 of __getmainargs I check
the success of the function, assign NULL to argv, and after the call to the
function check if argv is not NULL, because if the function not terminates
ending the program, it assign a value to argv. I do test and if the
function return -1 (win xp) it not assign a value to argv. Because this I
initialize argv to NULL.

Initializing argv to NULL, call __getmainargs and check if argv is NULL is
a valid way of check the success of the function, because argv always will
point to a address different than 0 (NULL), pointing at least to the the
command with which the program is invoked.

I compiled with tcc (without using TRY and the code of SEH) and run
succesfully with this crt a program on windows 98.

I use this portion of code for full the heap and cause the failure of
__getmainargs :
UINT cant = 1000000;
BYTE *p;
//Alert: fulling heap
while (cant > 1) {
    p = (BYTE *) malloc(cant);
    if (!p) {
        cant /= 2;
    }
}

And this is the portion of code with the call to __getmainargs and checking
the success that works on windows 98 and windows xp and above :

argv = NULL;
__getmainargs(&argc, &argv, &env, 0, &start_info);
// check success comparing if argv now is not NULL
if (! argv)
{
    ExitProcess(-1);
}


Also, I found that in the comments of __getmainargs that it left _pgmptr
pointing to the program name.
This is because it internally call to GetModuleFileName

Inside the main function you can use this (after success call to
__getmainargs).
printf("The full path of the executing program is: %Fs\n", _pgmptr);

This works on both version 6.0 and 7.0 (I tested it on windows 98 and
windows 8)

Note the files that have the source code of the functions are:
crtlib.c // __getmainargs
stdargv.c // _setargv (function used by __getmainargs)

With this way you can sure of the success of the function __getmainargs.


Carlos.
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to