1

On Windows 7, i'm used to manage the Windows Firewall by myself.

I usually block all IN & OUT connection rules, except my needed.

But i want the OS remain synchronized as well.

To do this i know there are some ways, but i would like to do it by code (C#).

I run a little piece of code that:

  1. Search/create a Windows Firewall rule that temporarely open UDP port 123

  2. Enable 'OS Time Resync Firewall rule'

  3. Resync OS Windows System Time

  4. Check if resynchronization correctly executed

  5. Disable 'OS Time Resync Firewall Rule'

The parts where i create and modify Windows Firewall rules, works well, but not the same when i try to update OS Time.

The code:

Public Declare Function W32TimeSyncNow Lib "w32time.dll" (ByVal computername As String, ByVal wait As Boolean, ByVal flag As UInteger) As UInteger

that i found here Windows API to trigger the time synchronization

Seems doesn't work.

I would also like to understand if there is a way to get the status of w32time request.

Here the full code.

public class WFM {

private string ruleName = "resync Windows OS";

[DllImport("w32time.dll")]
public static extern System.UInt32 W32TimeSyncNow(string computername, bool wait, System.UInt32 flag);

private void WFM_Load(object sender, EventArgs e) {
    this.resyncOs();
}

private void resyncOs() {
    try {
        Type tNetFwPolicy2 = Type.GetTypeFromProgID("HNetCfg.FwPolicy2");
        INetFwPolicy2 fwPolicy2 = ((INetFwPolicy2)(Activator.CreateInstance(tNetFwPolicy2)));
        object currentProfiles = fwPolicy2.CurrentProfileTypes;
        INetFwRule2 resyncRule = null;
        foreach (INetFwRule2 rule in fwPolicy2.Rules) {
            if ((rule.Name == ruleName)) {
                resyncRule = rule;
            }
            
        }
        
        if ((resyncRule == null)) {
            resyncRule = this.createResyncRule();
            INetFwPolicy2 firewallPolicy = ((INetFwPolicy2)(Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"))));
            firewallPolicy.Rules.Add(resyncRule);
        }
        
        // enable rule
        resyncRule.Enabled = true;
        WFM.W32TimeSyncNow(Environment.MachineName, true, 8);
        resyncRule.Enabled = false;
    }
    catch (Exception ex) {
        bool debug = true;
    }
    
}

private INetFwRule2 createResyncRule() {
    INetFwRule2 firewallRule = ((INetFwRule2)(Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"))));
    firewallRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT;
    // **General
    firewallRule.Name = ruleName;
    // name
    firewallRule.Description = "Enable UDP port 123 to resync Windows OS System time";
    firewallRule.Enabled = false;
    firewallRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
    // operation
    // **Programs and Services
    // firewallRule.ApplicationName = ""                               'program
    // firewallRule.serviceName = ""                                   'service
    // **Remote Computers
    // **Protocols and e Ports
    firewallRule.Protocol = int.Parse(NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_UDP);
    firewallRule.LocalPorts = "123";
    firewallRule.RemotePorts = "*";
    firewallRule.Profiles = (((int)(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE)) || ((int)(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_DOMAIN)));
    return firewallRule;
}

}

P.S. NB. to be able to create a Windows Firewall rule, it needed to allow the code execution as admin, so it need to modify the app.manifest replacing line

<requestedExecutionLevel level="asInvoker" uiAccess="false" />

with

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

Appreciated any help. Thanks.

Marcello
  • 438
  • 5
  • 21
  • "Seems doesn't work." What does not work? Is it "opening the firewall", or "reading the time from time.windows.com", or "something else" ? – Luuk Jun 27 '21 at 14:36
  • 1
    Did you check the code @codeproject.com here: [An SNTP Client for C# and VB.NET](https://www.codeproject.com/Articles/38276/An-SNTP-Client-for-C-and-VB-NET) ? – Luuk Jun 27 '21 at 14:41
  • @Luuk Thanks so much, maybe you missing this in my post: '...The parts where i create and modify Windows Firewall rules, works well, but not the same when i try to update OS Time...' – Marcello Jun 27 '21 at 15:12
  • @Luuk i'll check your link and then will update post. Anyway, thanks so much for your help – Marcello Jun 27 '21 at 15:13

1 Answers1

0

Ok, after some test, i find the solution.

just change

public static extern System.UInt32 W32TimeSyncNow(string computername, bool wait, System.UInt32 flag);

with

public static extern uint W32TimeSyncNow([MarshalAs(UnmanagedType.LPWStr)]String computername, bool wait, uint flag);

I still miss the point 5), where i would liked to check if the resync executed well.

NB. The synchronization request data to the Ntp Server already set in the OS (which is in the registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Parameters\NtpServer", Which in my case is with value "time.windows.com0x9")

Marcello
  • 438
  • 5
  • 21