none
Net Use and C# ...

    Question

  • My main issue is, running this C# line of code Console.WriteLine(Properties.Settings.Default.GreetingText); throws this exception : 

    System.ArgumentException: The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))
       at System.Security.Policy.PEFileEvidenceFactory.GetLocationEvidence(SafePEFileHandle peFile, SecurityZone& zone, StringHandleOnStack retUrl).

    When the process using that line of code is started with user "A" from a mapped drive created by user "SYSTEM".

    Note that the mapped drive created by SYSTEM is showing an X (disconnected) in explorer, but is still accessible by all users. This shows most probably that what I am trying to do is not supported by Microsoft. I was running several processes (C# or Native) without any problem until we used that particular process with that C# line of code. We tried to remove the line of code, but other C# line of codes are causing a similar problem.

    I was looking into changing how the "net use" is created to use a supported way, but my research led to think that net use is PER USER ... but with the exception of SYSTEM user.

    If I could create a S: mapped drive with SYSTEM and the same mapped drive S: with the logged in user, this would solve my problem, but its apparently impossible since the S: drive is seen in some way by the logged user even if doing "NET USE" doesn't show the S: drive.

    Is it possible to run this C# code on a mapped drive by SYSTEM user ?
    How can this problem be solved without having to define another letter ? Having to support 2 drive letter would have a huge impact on the scripts running all the processes because some are running SYSTEM, others are running as the logged user.

    Thursday, April 20, 2017 1:08 PM

All replies

  • To reproduce the problem : 

    1) psexec -s cmd.exe (from Systernals and from an admin account)

    2) net use S: \\127.0.0.1\<localshare> (Creating a mapped drive with SYSTEM user)

    3) net use (will show the S: drive mapped)

    4) exit (exit from the session with system)

    5) net use (wont show the S: drive mapped from the SYSTEM user)

    6) net use S: \\127.0.0.1\<localshare> (this will fail with "The local device name is already in use.")

    7) S:\TestProcess.exe (Run a C# process with the line of code Properties.Settings.Default.GreetingText)

    Notes :

    - The step 6 should have been a success if the net use command is per user.

    - The step 7 should have failed to access the mapped drive by system if the net use command is per user.

    - Otherwise, if windows allows S: drive to be accessed, the process shouldn't throw an exception.

    Thursday, April 20, 2017 1:09 PM
  • Sample code for TestProcess.exe (with the definition of GreetingText as a string in the project resources)  : 

            static int Main(string[] args)
            {
                try
                {
                    Console.WriteLine(Properties.Settings.Default.GreetingText);
                    Console.WriteLine("Hurray");
                    return 0;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    return 7;
                }
            }
    Thursday, April 20, 2017 1:09 PM
  • Multiple users can have the same drive mapped to the same letter. It happens all the time. But SYSTEM is a global account so I'm not surprised that you're running into issues trying to map a drive letter to the same drive.

    I don't think this is a .NET question at all. You're trying to manipulate mapped drives across users. This is a Windows question. Please post your question in the TechNet forums. Once they have gotten you working with the mapped drives your code will likely work.

    However the exception you're posting makes it look like this is a pre-v4 app and you're trying to run it from a network drive. That isn't going to work because of CAS. You'd either need to upgrade the app (because CAS, for the most part, is deprecated) or change the CAS policy to allow a network zone app to run properly.

    Michael Taylor
    http://www.michaeltaylorp3.net

    Thursday, April 20, 2017 2:08 PM
    Moderator
  • Thx for the fast answer. 

    I already posted my question on the TechNet forum (https://social.technet.microsoft.com/Forums/windows/en-US/0a202d95-b880-4d0b-a6e1-f72c38c25302/net-use-per-user-?forum=w7itpronetworking) and they suggest to post here.

    I would like to look more into the exception. The code posted here was built using the Target framework ".NET Framework 4 Client Profile", so it was built with a v4 framework. I tried to add the <loadFromRemoteSources enabled="true" /> in the application.config file but it still throws the exception.

    Can you put more detail on the "change the CAS policy" ?

    Thursday, April 20, 2017 2:42 PM
  • CAS policies are documented here. This is just a guess based upon the exception mentioning the evidence and would only apply if the console app you're running is running from a UNC path. If it is running locally on the machine then CAS doesn't apply.
    Thursday, April 20, 2017 2:56 PM
    Moderator
  • You seem to have pointed in the right direction, but not sure what this information is giving me. The full call stack is pointing to some of the Evidence calls that the article is about. 

    System.ArgumentException: The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))
       at System.Security.Policy.PEFileEvidenceFactory.GetLocationEvidence(SafePEFileHandle peFile, SecurityZone& zone, StringHandleOnStack retUrl)
       at System.Security.Policy.PEFileEvidenceFactory.GenerateLocationEvidence()
       at System.Security.Policy.PEFileEvidenceFactory.GenerateEvidence(Type evidenceType)
       at System.Security.Policy.AssemblyEvidenceFactory.GenerateEvidence(Type evidenceType)
       at System.Security.Policy.Evidence.GenerateHostEvidence(Type type, Boolean hostCanGenerate)
       at System.Security.Policy.Evidence.GetHostEvidenceNoLock(Type type)
       at System.Security.Policy.Evidence.GetHostEvidence(Type type, Boolean markDelayEvaluatedEvidenceUsed)
       at System.Security.Policy.AppDomainEvidenceFactory.GenerateEvidence(Type evidenceType)
       at System.Security.Policy.Evidence.GenerateHostEvidence(Type type, Boolean hostCanGenerate)
       at System.Security.Policy.Evidence.GetHostEvidenceNoLock(Type type)
       at System.Security.Policy.Evidence.RawEvidenceEnumerator.MoveNext()
       at System.Security.Policy.Evidence.EvidenceEnumerator.MoveNext()
       at System.Configuration.ClientConfigPaths.GetEvidenceInfo(AppDomain appDomain, String exePath, String& typeName)
       at System.Configuration.ClientConfigPaths.GetTypeAndHashSuffix(AppDomain appDomain, String exePath)
       at System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig)
       at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)
       at System.Configuration.Internal.ConfigurationManagerInternal.System.Configuration.Internal.IConfigurationManagerInternal.get_ExeProductName()
       at System.Configuration.ApplicationSettingsBase.get_Initializer()
       at System.Configuration.ApplicationSettingsBase.CreateSetting(PropertyInfo propInfo)
       at System.Configuration.ApplicationSettingsBase.EnsureInitialized()
       at System.Configuration.ApplicationSettingsBase.get_Properties()
       at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
       at System.Configuration.SettingsBase.get_Item(String propertyName)
       at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
       at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
       at TestProcess.Properties.Settings.get_GreetingText() in F:\TestProcess\TestProcess\TestProcess\Properties\Settings.Designer.cs:line 31
       at TestProcess.Program.Main(String[] args) in F:\TestProcess\TestProcess\TestProcess\Program.cs:line 13

    I cannot step in this code to see what is happening and not sure if I can/need to manipulate some classes (Evidence?) to setup more security permissions. 

    This said, the problem is quite easy to reproduce on a single PC with the steps above. Can someone, with the code, reproduce the problem and step in to get the exact reason why this throws an exception ? Do I have to manipulate the permissions through the code or at the system level (maybe with caspol.exe) ? 

    Thursday, April 20, 2017 8:11 PM
  • Given the full callstack, it is failing when trying to read your app.config file.

    I'm unable to replicate the net use issue you're seeing. After closing the admin session the share is still available and visible with net use. Since SYSTEM is always logged in the share will remain until the reboot. This lines up with a post that seems to be doing what you are trying to do and it mentions that this mapped drive is going to be disconnected. Hence it isn't really usable but you also cannot overwrite it.


    Thursday, April 20, 2017 9:47 PM
    Moderator

  • I am surprised that you were not able to reproduce the net use problem. Frederick Long from that post (https://answers.microsoft.com/en-us/windows/forum/windows_7-files/net-use-per-user/bb907eb8-80b4-4880-9115-01d5b9105449?auth=1) reproduced it. 

    c:\>psexec -s cmd
    Microsoft Windows [Version 10.0.14393]

    C:\WINDOWS\system32>net use s: \\127.0.0.1\DriveE
    The command completed successfully.

    C:\WINDOWS\system32>exit
    cmd exited on SPRING with error code 0.

    c:\>net use
    New connections will not be remembered.
    There are no entries in the list.

    c:\>dir s:
     Volume in drive S is Drivers
     Volume Serial Number is ECFB-9CF0
     Directory of S:\
    22.11.2016  23:44    <DIR>          $RECYCLE.BIN
    13.11.2016  13:25    <DIR>          Backup
    17.01.2017  12:02    <DIR>          Drivers

    Running the following code with a USER other than SYSTEM from that S: drive : 

            static int Main(string[] args)
            {
                try
                {
                    string configvalue1 = ConfigurationManager.AppSettings["testInt"];
                    string configvalue2 = ConfigurationManager.AppSettings["testString"];
                    Console.WriteLine("Values in app.config are " + configvalue1 + " " + configvalue2);

                    Console.WriteLine(Properties.Settings.Default.GreetingText);
                    Console.WriteLine("Hurray");
                    return 0;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    return 7;
                }
            }


    With app.config : 

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="testInt" value="7" />
        <add key="testString" value="abc.txt" />
      </appSettings>
    </configuration>


    Gives me : 

    Values in app.config are 7 abc.txt
    System.ArgumentException: The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))
       at System.Security.Policy.PEFileEvidenceFactory.GetLocationEvidence(SafePEFileHandle peFile, SecurityZone& zone, StringHandleOnStack retUrl)
       at System.Security.Policy.PEFileEvidenceFactory.GenerateLocationEvidence()

    So its actually able to read the app.config file without any problems. Properties.Settings.Default.GreetingText is getting the values from application settings.

    Friday, April 21, 2017 2:31 PM
  • Are you using UAC? It's possible that UAC is causing you issues such that you cannot see the shares. Irrelevant none of this is going to solve your problem. Windows is clearly not going to allow you to use a mapped drive from SYSTEM. You are going to need to start rethinking the solution. Personally I would either just use UNC paths or consider dynamically creating the mapping and then dropping it when the app is done.

    "So its actually able to read the app.config file without any problems. "

    Your updated sample is different. The config file is loading when you use ConfigurationManager but when you use Properties.Settings that triggers the LocalFileSettingsProvider which looks for the app and user configs. It is this enumeration that is failing (at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)). Here's the basic algorithm of that code:

    If include EXE
       Load EXE config
    
    If include USER config
       If Not ClickOnce
          Validate the app domain
          Get the type and hash suffix of the current domain
             Get the evidence for the current domain

    It is failing trying to get the evidence for the current domain so it can load the user.config for the app. You would not see this issue with ConfigurationManager.AppSettings.

    Friday, April 21, 2017 2:59 PM
    Moderator
  • Are you using UAC? It's possible that UAC is causing you issues such that you cannot see the shares

    I have looked at the different User Account Control settings and they are all disabled. We are using an infrastructure with a 

    Irrelevant none of this is going to solve your problem. Windows is clearly not going to allow you to use a mapped drive from SYSTEM. You are going to need to start rethinking the solution.

    That's what I was afraid from the beginning of my posts, but I persisting because all this seems pretty odd behaviour. I am doing this because I have a 15Gigs product that is loaded on multiple PCs, each of them loading different part of that 15Gigs. We used to copy locally the product, but to avoid this we decided to try, with success up to today, to load from a mapped drive. So we are currently loaded severals processes, managed, unmanaged, C# or old legacy C, without having any problems. It just until lately that one fairly new system is throwing an exception.

    Its just seems odd behaviour because of :

    Its just seems like the SYSTEM mapped drive should have been only seen by the SYSTEM user for it to be consistent with all I read or noticed up until now.

    OR 

    Its just seems that the C# exception is something that should need to be corrected to be consistent with all the other C# code that is working. 

    I have a hard time believing that we can't have a shared drive across all PCs. A mapped drive that's acts as if the drive is local. We created that mapped drive with the system process because we load processes on "not logged" PCs remotely with a daemon started with SYSTEM. 

    Friday, April 21, 2017 5:36 PM
  • SYSTEM (and the other pre-defined accounts) are special. They are not normal accounts and don't necessarily follow the same rules. I suspect your problems are being caused by the fact that you're using this account at all. I suspect that if you were to use a regular user (local or domain) account then you're problems would go away. This is probably good security practice anyway since your program probably shouldn't have complete access to the entire system. This would impact your daemons but remotely logging into another computer with a user account is pretty standard and, besides configuring permissions, the approach you should probably consider.
    Friday, April 21, 2017 6:22 PM
    Moderator