locked
Windows update 19041 (2004) GetCommandLineA() vs rasman.dll RRS feed

  • Question

  • Hello, 

    short problem description: looks like rasman.dll internally modifies block of memory where process's command line string resides.

    After running mixed application (C++/.NET) on a new Windows update 19041 (2004) found a following issue (?) with a scenario:

    On the startup of application I'm reading process's command line with GetCommandLineA() function. At this point the command line returned as it was entered.

    Then I call .NET method via COM wrapper. This method makes another remote call to a SOAP service.

    After remote call has been done I try to read process command line again (GetCommandLineA());

    Problem: command line returned is in lowercase.

    I've done some investigation with WinDbg and found that memory address where command line resided is modified by rasman.dll with the following stack:

    msvcrt.dll!__strlwr()  Unknown
            rasman.dll!_IsRasmanProcess@0()        Unknown
            rasman.dll!_RasInitializeNoWait@0()    Unknown
            rasman.dll!_RasInitialize@0()  Unknown
            rasapi32.dll!_LoadRasmanDllAndInit@0() Unknown
            rasapi32.dll!_RasEnumConnectionsW@12() Unknown
            System.ni.dll!719fe908()        Unknown
            System.ni.dll![Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack]     Unknown

            [External Code]

    I've compared binary files of rasman.dll for Windows builds 10.0.18363 and 10.0.19041 and found that call to strlwr function was added in recent builds...

    Could someone help with explanation what is the reason for this call?

    Is it a bug or intended behavior?

    Is there any workaround to fix this problem?

    Thank you in advance.

    Regards,

    Vadym Lenda.

    Friday, July 24, 2020 3:46 PM

All replies

  • Hi,

    Thanks for posting here,

    I can reproduce this issue after calling RasEnumConnections.

    Use the Unicode version GetCommandLineW works for me.

    The best practice is to get this command line from the beginning, copy and save it.

    I will confirm this issue with the Internal engineer, and update here.

    Best Regards,

    Drake

    This “General Windows Desktop Development Issues” Forum will be migrating to a new home on Microsoft Q&A, please refer to this sticky post for more details. 


    "Win32 API" forum will be migrating to a new home on Microsoft Q&A !
    We invite you to post new questions in the "Win32 API" forum’s new home on Microsoft Q&A !
    For more information, please refer to the sticky post.

    Monday, July 27, 2020 3:41 AM
  • Raymond Chen's blog at https://devblogs.microsoft.com/oldnewthing/ contains various articles that discuss the GetCommandLine function. Common threads in these articles are that the command line passed to a process is not immutable, its interpretation is governed by convention not by rules, and that Windows does not care about the command line after passing it to a new process.

    Just a few as examples -

    Why does GetCommandLine give me a corrupted command line?

    How do I get the command line of another process?

    Why does the CreateProcess function modify its input command line?

    Monday, July 27, 2020 9:21 AM
  • Thank you for provided information. Now it's clear that there are no rules, just a convention, but it's still not clear what is the necessity of command line memory modification instead of copying and then processing? Particularly in the case of rasman.dll, where the task is to find a substring in another string...

    Regards,

    Vadym

    Monday, July 27, 2020 5:53 PM
  • Drake,

    thank you for acknowledgment.

    Waiting for official answer regarding this issue. We have to know whether it's a bug and a fix should be prepared by Microsoft, or we need to fix our code and do not rely on command line's value immutability.

    Thank you.

    Regards, Vadym

    Monday, July 27, 2020 5:55 PM
  • It is probably not necessity but instead convenience.

    As an example, if you had the choice between:

    #include <Windows.h>
    #include <cstring>
    
    int main()
    {
    	LPSTR str = GetCommandLineA();
    
    	char * ret = strtok(str, " ");
    	while (ret != nullptr)
    	{
    		//examine token
    		ret = strtok(nullptr, " ");
    	}
    
    	return 0;
    }

    and:

    #include <Windows.h>
    #include <cstring>
    
    int main()
    {
    	LPSTR str = GetCommandLineA();
    
    	char *buffer;
    	size_t buflen = strlen(str);
    
    	buffer = (char *)malloc(buflen + 1);
    	strcpy(buffer, str);
    
    	char *ret = strtok(buffer, " ");
    	while (ret != nullptr)
    	{
    		//examine token
    		ret = strtok(nullptr, " ");
    	}
    
    	return 0;
    }

    what would you choose? Ignoring the fact that main could get the command line and try to be impartial because of this thread.

    You could say that the first one isn't good form, but it is rare for an application to access its own command line memory block after it starts anyway.

    But you really should go to the Windows 10 Feedback Hub and report this there.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Monday, July 27, 2020 6:43 PM