Tuesday, March 22, 2011

ADSI Login Window

An atrociously documented call the IADsUser interface to AD: put_LoginHours and get_LoginHours.  I believe the total documentation says:

"Time periods for each day of the week during which logons are permitted for the user. Represented as a table of Boolean values for the week, each indicating if that time slot is a valid logon time. Be aware that the representation is provider and directory-specific." 

I am using C++, so the 'values' are stored as an array of bytes where each bit is an hour so: 

byte lh[21]; //((24 hours*7 days)/8 bits)

You can find that in other blogs along with the information that it starts at midnight Sunday morning (first hour
1:00- 1am Sunday).  BUT since this is a COM interface it takes a VARIANT* as a parameter.  Howdo you get the array values in and out of the variant?  Like so:

        VARIANT var;
        VariantInit(&var);
        hr=user->get_LoginHours(&var);
        BYTE lh[21];
        memset(lh,0,sizeof(byte)*21);
        VariantArrayToBytes(lh,21,&var);
        VariantClear(&var);
//use byte array

and

        BYTE lh [21];//hours in a week
//fill byte array as needed
        VARIANT var;
        VariantInit(&var);
        hr = BytesToVariantArray(lh, 21, &var);
        if (SUCCEEDED(hr))
            user->put_LoginHours(var);
        else{
           //err
        }
        VariantClear(&var);


where:

HRESULT VariantArrayToBytes(PBYTE pValue, ULONG cValElements, VARIANT *pVar)
{
    HRESULT hr;
    SAFEARRAY *psa = V_ARRAY(pVar);
    CHAR HUGEP *pArray = NULL;
    hr = SafeArrayAccessData(psa, (void HUGEP * FAR *) &pArray);
    if (SUCCEEDED(hr))
    {
        memcpy(pValue, pArray, cValElements);
        SafeArrayUnaccessData(psa);
        hr = S_OK;
    }
    return hr;
}

HRESULT BytesToVariantArray(PBYTE pValue, ULONG cValElements, VARIANT *pVar)
{
    HRESULT hr;
    SAFEARRAY *psa;
    SAFEARRAYBOUND ab;
    CHAR HUGEP *pArray = NULL;

    ab.lLbound = 0;
    ab.cElements = cValElements;

    psa = SafeArrayCreate(VT_UI1, 1, &ab);
    if (psa == NULL)
    {
        hr = E_OUTOFMEMORY;
    }else{
        hr = SafeArrayAccessData(psa, (void HUGEP * FAR *) &pArray);
        if (SUCCEEDED(hr))
        {
            memcpy(pArray, pValue, ab.cElements);
            SafeArrayUnaccessData(psa);
            V_VT(pVar) = VT_ARRAY | VT_UI1;
            V_ARRAY(pVar) = psa;
            hr = S_OK;
        }
        else
        {
            if (psa)
                SafeArrayDestroy(psa);
        }
    }
    return hr;
}

No comments:

Post a Comment