Working with large integers in VB.NET (.lowpart & .highpart)

BMcCubbin
BMcCubbin used Ask the Experts™
on
Hello experts,

I am working on this code below that checks to see when the AD password expires on the logged in user.  I got some of this code from a VBScript that works flawlessly.  I Re-Wrote it in VB.NET and everything works except for 1 part.  I have it commented out where it doesn't work.  From some research I am seeing that it has something to do with the way vb.NET handles large integers.  I think the problem lies in the .lowpart and .highpart properties.  Does anyone know how to use these properties in VB.net to make them work in this project?  Everthing else is working fine.  Thanks!
Private Sub LookupDate()
        Dim objADSystemInfo = CreateObject("ADSystemInfo")
        Dim objUser = GetObject("LDAP://" & objADSystemInfo.UserName)
        Dim intUserAccountControl = objUser.Get("userAccountControl")

        Try
            If intUserAccountControl And ADS_UF_DONT_EXPIRE_PASSWD Then
                SL = "The password does not expire."
                UpdateStatus()
' Password Does not expire
            Else
                Dim dtmValue = objUser.PasswordLastChanged

                If Err.Number = E_ADS_PROPERTY_NOT_FOUND Then
                    SL = ("The password has never been set.")
                    UpdateStatus()
'Password has never been set
                Else
                    Dim tsTimeSpan As TimeSpan
                    tsTimeSpan = Now.Subtract(dtmValue)
                    intTimeInterval = tsTimeSpan.Days

                   SL = ("The password was last set on " & _
                   DateValue(dtmValue) & " at " & TimeValue(dtmValue))
                   UpdateStatus()
                   Application.DoEvents()
'Tell them the last time the password was changed
                End If

                Dim objDomain = GetObject("LDAP://" & objADSystemInfo.DomainDNSName)
                Dim objMaxPwdAge = objDomain.Get("maxPwdAge")
'***** THIS IS THE PART THAT I AM HAVING THE PROBLEM WITH! **********
                If objMaxPwdAge.LowPart = 0 Then
                    SL = ("The maximum password age is set to 0 in the domain.  Therefore, your password does not expire.")
                    UpdateStatus()
                    Application.DoEvents()
' Password is not set to expire
                Else
                    Dim dblMaxPwdNano = _
                        Math.Abs(objMaxPwdAge.HighPart * 2 ^ 32 + objMaxPwdAge.LowPart)
                    Dim dblMaxPwdSecs = dblMaxPwdNano * ONE_HUNDRED_NANOSECOND
                    Dim dblMaxPwdDays = Int(dblMaxPwdSecs / SECONDS_IN_DAY)
                    SL = ("Maximum password age is set to " & dblMaxPwdDays & " days")
                    UpdateStatus()
'Tells them what the max password age is set to within the AD policy
                    If intTimeInterval >= dblMaxPwdDays Then
                        SL = ("Your password has expired!")
                        UpdateStatus()
                        Application.DoEvents()
                        SpawnThread()
' Password Expired! Launch a login box to change password with
                    Else
                        If Int(dblMaxPwdDays - intTimeInterval) <= 3 Then
                            SL = ("Your password is about to expire.  Change it now!")
                            UpdateStatus()
                            Application.DoEvents()
                            SpawnThread()
' Password will expire in 3 days or less! Launch a login box to change password with
                        Else

                            lblExpire.Text = ("Your password expires on " & _
                              DateValue(dtmValue).AddDays(dblMaxPwdDays) & " (" & _
                              Int(dblMaxPwdDays - intTimeInterval) & " days from today).")
                            Application.DoEvents()
'Tells them when their password will expire

                        End If
                    End If
                End If
            End If
        Catch ex As Exception
            SL = "Unable to lookup password information!"
            UpdateStatus()
        End Try

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2012
Top Expert 2014

Commented:
It would help if you tell us the error details as well.
Top Expert 2010

Commented:

Although I'm not exactly sure what the attribute maxPwdAge returns it looks like just a singed 64 bit integer.
Dim objMaxPwdAge as Int64 = objDomain.Get("maxPwdAge")
 
 

Author

Commented:
Attached
err.jpg
Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
When I add that DIM in, I get:

'LowPart' is not a member of 'Long'
'HighPart' is not a member of 'Long'
Top Expert 2010

Commented:
It looks like because you are using CreateObject() it expects a COM object of type IADsLargeInteger.
I don't work much with the Active Directory but it appears .NET has a class already for this stuff so you don't need to use CreateObject() use the .NET class instead.
Imports System.DirectoryServices
Imports ActiveDs
You can read more here: http://msdn.microsoft.com/en-us/library/ms180872(VS.80).aspx

Author

Commented:
Thanks, but I get the same error when I used the ActiveDs.  I am already using the system.directory services.

Author

Commented:
This code is above the previously posted code..... Forgot to copy it in on the first post.
Imports System.Net
Imports System
Imports System.Threading
Imports System.Uri
Imports System.Web
Imports System.DirectoryServices
Imports System.Collections
Imports Microsoft.Win32
Imports System.Management
Imports System.Management.ManagementObjectSearcher
Imports System.ComponentModel
Imports System.Runtime.InteropServices   

    Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
    Const E_ADS_PROPERTY_NOT_FOUND = &H8000500D
    Const ONE_HUNDRED_NANOSECOND = 0.0000001
    Const SECONDS_IN_DAY = 86400

Open in new window

Commented:
So, the solution is to do the following:

Add a COM reference to Active DS Type Library
Use IADsLargeInteger like this:
        Dim li As ActiveDs.IADsLargeInteger
        Dim ticks as long
        Dim d as Date

        ' get the value
        li = CType(dir.Properties("maxPwdAge").Value, ActiveDs.IADsLargeInteger)
        ' see if it is valid
        If (li.HighPart = 0 And li.LowPart = 0) Or (li.HighPart = Int32.MaxValue And li.LowPart = -1) Then

            d = DateTime.MinValue
        Else
            ' get the number of ticks
            ticks = (li.HighPart * 2 ^ 32) + li.LowPart
            ' convert ticks to a date
            d = DateTime.FromFileTime(ticks)
        End If
                        ticks = (li.HighPart * 2 ^ 32) + li.LowPart
                        dr("Acct_Expires") = DateTime.FromFileTime(ticks)

Open in new window

Commented:
oops, just ignore the last two lines...  that was just stuff left over from my copy-n-paste

Author

Commented:
Compilation error - 'Properties' is not a member of 'String'.  

I guess it doesn't help that I don't quite know what this math is trying to do....Are you able to explain what this is actually doing with the number of ticks....?  For example (li.highpart *2 ^32) + li.lowpart    ???

Also, would this chunk of code replace the code that I posted above?  Thanks for your help.

Commented:
That was just an example... not a "drop in replacement".
In your code you'd use:
Dim li As ActiveDs.IADsLargeInteger = objDomain.Get("maxPwdAge")

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial