Optimum X NetUsers.exe, .
++, LastWriteTime , "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
, WMI, , pInvoke "LastWriteTime" #
, HKLM:
private static DateTime GetHKLMRegistryKeyLastWriteTime(RegistryKey key, string RemoteComputer)
{
DateTime LastWriteTime = DateTime.MinValue;
RegSAM desiredSAM = RegSAM.Read;
if (key.View == RegistryView.Registry32)
{
desiredSAM |= RegSAM.WOW64_32Key;
}
else if(key.View == RegistryView.Registry64)
{
desiredSAM |= RegSAM.WOW64_64Key;
}
UIntPtr computerRegHive = ConnectToRegistryHive(RemoteComputer, HKEY_LOCAL_MACHINE);
if(computerRegHive != UIntPtr.Zero)
{
string keyPath = key.Name;
int rootSeperatorIndex = keyPath.IndexOf(@"\");
if (rootSeperatorIndex != -1)
{
keyPath = keyPath.Substring(rootSeperatorIndex + 1, keyPath.Length - (rootSeperatorIndex + 1));
}
UIntPtr computerRegKey = OpenRegistrySubKey(computerRegHive, keyPath, desiredSAM);
RegCloseKey(computerRegHive);
if(computerRegKey != UIntPtr.Zero)
{
LastWriteTime = GetRegistryKeyLastWriteTime(computerRegKey);
RegCloseKey(computerRegKey);
}
}
return LastWriteTime;
}
, , :
public static uint HKEY_LOCAL_MACHINE = 0x80000002u;
[DllImport("advapi32.dll")]
private static extern int RegConnectRegistry(string lpmachineName, uint hKey, out UIntPtr phKResult);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
private static extern int RegOpenKeyEx(
UIntPtr hKey,
string subKey,
int ulOptions, //Set to 0
RegSAM samDesired, //Desired Access (win32/win64 & Read or ReadWrite)
out UIntPtr hkResult);
[DllImport("advapi32.dll")]
private static extern int RegQueryInfoKey(
UIntPtr hKey,
StringBuilder lpClass,
IntPtr lpcbClass,
IntPtr lpReserved,
IntPtr lpcSubKeys,
IntPtr lpcbMaxSubKeyLen,
IntPtr lpcbMaxClassLen,
IntPtr lpcValues,
IntPtr lpcbMaxValueNameLen,
IntPtr lpcbMaxValueLen,
IntPtr lpcbSecurityDescriptor,
[Out][Optional]out FILETIME lpftLastWriteTime
);
[DllImport("advapi32.dll")]
private static extern int RegCloseKey(UIntPtr hKey);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FileTimeToSystemTime([In] ref FILETIME lpFileTime, out SYSTEMTIME lpSystemTime);
[Flags]
public enum RegSAM
{
QueryValue = 0x0001,
SetValue = 0x0002,
CreateSubKey = 0x0004,
EnumerateSubKeys = 0x0008,
Notify = 0x0010,
CreateLink = 0x0020,
WOW64_32Key = 0x0200,
WOW64_64Key = 0x0100,
WOW64_Res = 0x0300,
Read = 0x00020019,
Write = 0x00020006,
Execute = 0x00020019,
AllAccess = 0x000f003f
}
[StructLayout(LayoutKind.Sequential)]
public struct FILETIME
{
public uint LowPart;
public uint HighPart;
};
[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct SYSTEMTIME
{
public ushort Year;
public ushort Month;
public ushort DayOfWeek;
public ushort Day;
public ushort Hour;
public ushort Minute;
public ushort Second;
public ushort Milliseconds;
public SYSTEMTIME(DateTime dt)
{
dt = dt.ToUniversalTime();
Year = Convert.ToUInt16(dt.Year);
Month = Convert.ToUInt16(dt.Month);
DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
Day = Convert.ToUInt16(dt.Day);
Hour = Convert.ToUInt16(dt.Hour);
Minute = Convert.ToUInt16(dt.Minute);
Second = Convert.ToUInt16(dt.Second);
Milliseconds = Convert.ToUInt16(dt.Millisecond);
}
public SYSTEMTIME(ushort year, ushort month, ushort day, ushort hour = 0, ushort minute = 0, ushort second = 0, ushort millisecond = 0)
{
Year = year;
Month = month;
Day = day;
Hour = hour;
Minute = minute;
Second = second;
Milliseconds = millisecond;
DayOfWeek = 0;
}
public static implicit operator DateTime(SYSTEMTIME st)
{
if (st.Year == 0 || st == MinValue)
return DateTime.MinValue;
if (st == MaxValue)
return DateTime.MaxValue;
return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Utc);
}
public static bool operator ==(SYSTEMTIME s1, SYSTEMTIME s2)
{
return (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
}
public static bool operator !=(SYSTEMTIME s1, SYSTEMTIME s2)
{
return !(s1 == s2);
}
public static readonly SYSTEMTIME MinValue, MaxValue;
static SYSTEMTIME()
{
MinValue = new SYSTEMTIME(1601, 1, 1);
MaxValue = new SYSTEMTIME(30827, 12, 31, 23, 59, 59, 999);
}
public override bool Equals(object obj)
{
if (obj is SYSTEMTIME)
return ((SYSTEMTIME)obj) == this;
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
private static UIntPtr ConnectToRegistryHive(string RemoteComputer, uint hKey)
{
UIntPtr computerRegHive = UIntPtr.Zero;
RegConnectRegistry(@"\\" + RemoteComputer, hKey, out computerRegHive);
return computerRegHive;
}
private static UIntPtr OpenRegistrySubKey(UIntPtr CurrentHKey, string SubKeyName, RegSAM desiredSAM)
{
UIntPtr hRegKey = UIntPtr.Zero;
RegOpenKeyEx(CurrentHKey, SubKeyName, 0, desiredSAM, out hRegKey);
return hRegKey;
}
private static DateTime GetRegistryKeyLastWriteTime(UIntPtr hKey)
{
FILETIME ft = new FILETIME();
int ret = RegQueryInfoKey(hKey, null, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out ft);
if(ret == 0)
{
SYSTEMTIME st = new SYSTEMTIME(DateTime.MinValue);
FileTimeToSystemTime(ref ft, out st);
DateTime LastWriteTime = st;
return LastWriteTime.ToLocalTime();
}
return DateTime.MinValue;
}
Win32_NetworkLoginProfile, datestamp , .