2025-11-28 00:35:46 +09:00

1226 lines
44 KiB
C++

// userprop.cpp : Defines the entry point for the console application.
//
//For the pow function to calculate powers of 2
#include <math.h>
#include <wchar.h>
#include <objbase.h>
#include <activeds.h>
//Make sure you define UNICODE
//Need to define version 5 for Windows 2000
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#include <sddl.h>
//Function to use the get_* methods of IADsUser.
HRESULT GetUserPropertyMethods(IADsUser *pUser);
HRESULT FindUserByName(IDirectorySearch *pSearchBase, //Container to search
LPWSTR szFindUser, //Name of user to find.
IADs **ppUser); //Return a pointer to the user
void wmain( int argc, wchar_t *argv[ ])
{
//Handle the command line arguments.
wchar_t pszBuffer[MAX_PATH*2] ;
if ( argc != 2 )
{
wprintf( L"This program finds a user in the current domain\n" ) ;
wprintf( L"(Windows 2000 or higher), and displays all the IADsUser\n" ) ;
wprintf( L"properties.\n\n" ) ;
wprintf(L"useage: iadsuser <username>\n");
wprintf( L"where <username> is the DN of the user.\n" ) ;
wprintf( L"Enclose in quotes as necessary.\n" ) ;
return ;
}
wcsncpy_s( pszBuffer, sizeof(pszBuffer)/sizeof(pszBuffer[0]),argv[1], MAX_PATH * 2 ) ;
pszBuffer[(MAX_PATH*2)-1] = 0 ;
//if empty string, exit.
if ( 0==wcscmp(L"", pszBuffer) )
return ;
wprintf(L"\nFinding user: %ws...\n",pszBuffer);
//Intialize COM
CoInitialize(NULL);
HRESULT hr = S_OK;
//Get rootDSE and the domain container's DN.
IADs *pObject = NULL;
IDirectorySearch *pDS = NULL;
wchar_t szPath[MAX_PATH] ;
VARIANT var;
hr = ADsOpenObject(L"LDAP://rootDSE",
NULL,
NULL,
ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
IID_IADs,
(void**)&pObject);
if ( FAILED(hr) )
{
wprintf(L"Not Found. Could not bind to the domain.\n");
if ( pObject )
pObject->Release();
return;
}
VariantInit( &var ) ;
hr = pObject->Get(L"defaultNamingContext",&var);
if ( SUCCEEDED(hr) )
{
_snwprintf_s( szPath, sizeof(szPath)/sizeof(szPath[0]),MAX_PATH, L"LDAP://%ws", var.bstrVal ) ;
szPath[MAX_PATH-1] = 0 ;
VariantClear(&var);
if ( pObject )
{
pObject->Release();
pObject = NULL;
}
//Bind to the root of the current domain.
hr = ADsOpenObject(szPath,
NULL,
NULL,
ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
IID_IDirectorySearch,
(void**)&pDS);
if ( SUCCEEDED(hr) )
{
hr = FindUserByName(pDS, //Container to search
pszBuffer, //Name of user to find.
&pObject); //Return a pointer to the user
if ( SUCCEEDED(hr) )
{
IADsUser *pUser = NULL;
hr = pObject->QueryInterface( IID_IADsUser, (void**) &pUser );
if ( SUCCEEDED(hr) )
{
wprintf (L"----------------------------------------------\n");
wprintf (L"--------Call GetUserPropertyMethods-----------\n");
hr = GetUserPropertyMethods(pUser);
wprintf (L"GetUserPropertyMethods HR: %x\n", hr);
}
if ( pUser )
pUser->Release();
}
else
{
wprintf(L"User \"%ws\" not Found.\n",pszBuffer);
wprintf (L"FindUserByName failed with the following HR: %x\n", hr);
}
if ( pObject )
pObject->Release();
}
if ( pDS )
pDS->Release();
}
//Uninitalize COM
CoUninitialize();
return;
}
HRESULT GetUserPropertyMethods( IADsUser *pUser )
{
VARIANT_BOOL bBool ;
DATE date ;
BSTR bstr ;
LONG lProp ;
VARIANT var ;
HRESULT hr ;
long lBound, uBound ;
if ( NULL == pUser ) {
return( HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER ) ) ;
}
VariantInit( &var ) ;
hr = pUser->get_AccountDisabled( &bBool ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"AccountDisabled: %ws\n", ( bBool ? L"TRUE" : L"FALSE" ) ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"AccountDisabled property not found.\n" ) ;
}
else {
wprintf( L"AccountDisabled failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_AccountExpirationDate( &date ) ;
if ( SUCCEEDED( hr ) ) {
var.vt = VT_DATE ;
var.date = date ;
hr = VariantChangeType( &var, &var, VARIANT_NOVALUEPROP, VT_BSTR ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"AccountExpirationDate: %ws\n", var.bstrVal ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"AccountExpirationDate property not found.\n" ) ;
}
else {
wprintf( L"AccountExpirationDate failed with hr: 0x%08x\n", hr ) ;
}
VariantClear( &var ) ;
}
hr = pUser->get_BadLoginAddress( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"BadLoginAddress: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else {
if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"BadLoginAddress property not found.\n" ) ;
}
else if ( E_ADS_PROPERTY_NOT_SUPPORTED == hr ) {
// Property not supported on all platforms, check documentation.
wprintf( L"BadLoginAddress property is not supported on this platform.\n" ) ;
}
else {
wprintf( L"BadLoginAddress failed with hr: 0x%08x\n", hr ) ;
}
}
hr = pUser->get_BadLoginCount( &lProp ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"BadLoginCount: %d\n", lProp ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"BadLoginCount property not found.\n" ) ;
}
else {
wprintf( L"BadLoginCount failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_Department( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"Department: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"Department property not found.\n" ) ;
}
else {
wprintf( L"Department failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_Description( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"Description: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"Description property not found.\n" ) ;
}
else {
wprintf( L"Description failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_Division( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"Division: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"Division property not found.\n" ) ;
}
else {
wprintf( L"Division failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_EmailAddress( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"EmailAddress: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"EmailAddress property not found.\n" ) ;
}
else {
wprintf( L"EmailAddress failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_EmployeeID( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"EmployeeID: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"EmployeeID property not found.\n" ) ;
}
else {
wprintf( L"EmployeeID failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_FaxNumber( &var ) ;
if ( SUCCEEDED( hr ) ) {
// Note: This property method can return either a VARIANT with
// type VT_BSTR and a single string, or a VARIANT with type
// VT_ARRAY | VT_BSTR and multiple strings, depending on whether
// the target directory's property is single- or multi-valued.
// Generic code should probably handle both cases.
if ( VT_BSTR == var.vt ) {
wprintf( L"FaxNumber: %ws\n", var.bstrVal ) ;
}
else if ( ( VT_ARRAY | VT_BSTR ) == var.vt ) {
VARIANT elem ;
VariantInit( &elem ) ;
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
while ( lBound <= uBound ) {
if ( SUCCEEDED( SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ) ) {
wprintf( L"FaxNumber: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"FaxNumber property not found.\n" ) ;
}
else {
wprintf( L"FaxNumber failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_FirstName( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"FirstName: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"FirstName property not found.\n" ) ;
}
else {
wprintf( L"FirstName failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_FullName( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"FullName: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"FullName property not found.\n" ) ;
}
else {
wprintf( L"FullName failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_GraceLoginsAllowed( &lProp ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"GraceLoginsAllowed: %d\n", lProp ) ;
}
else if ( E_ADS_PROPERTY_NOT_SUPPORTED == hr ) {
// Property not supported on all platforms, check documentation.
wprintf( L"GraceLoginsAllowed property is not supported on this platform.\n" ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"GraceLoginsAllowed property not found.\n" ) ;
}
else {
wprintf( L"GraceLoginsAllowed failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_GraceLoginsRemaining( &lProp ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"GraceLoginsRemaining: %d\n", lProp ) ;
}
else if ( E_ADS_PROPERTY_NOT_SUPPORTED == hr ) {
// Property not supported on all platforms, check documentation.
wprintf( L"GraceLoginsRemaining property is not supported on this platform.\n" ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"GraceLoginsRemaining property not found.\n" ) ;
}
else {
wprintf( L"GraceLoginsRemaining failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_HomeDirectory( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"HomeDirectory: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"HomeDirectory property not found.\n" ) ;
}
else {
wprintf( L"HomeDirectory failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_HomePage( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"HomePage: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"HomePage property not found.\n" ) ;
}
else {
wprintf( L"HomePage failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_IsAccountLocked( &bBool ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"IsAccountLocked: %ws\n", ( bBool ? L"TRUE" : L"FALSE" ) ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"IsAccountLocked property not found.\n" ) ;
}
else {
wprintf( L"IsAccountLocked failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_Languages( &var ) ;
if ( SUCCEEDED( hr ) ) {
// Note: This property method can return either a VARIANT with
// type VT_BSTR and a single string, or a VARIANT with type
// VT_ARRAY | VT_BSTR and multiple strings, depending on whether
// the target directory's property is single- or multi-valued.
// Generic code should probably handle both cases.
if ( VT_BSTR == var.vt ) {
wprintf( L"Languages: %ws\n", var.bstrVal ) ;
}
else if ( ( VT_ARRAY | VT_BSTR ) == var.vt ) {
VARIANT elem ;
VariantInit( &elem ) ;
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
while ( lBound <= uBound ) {
if ( SUCCEEDED( SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ) ) {
wprintf( L"Languages: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"Languages property not found.\n" ) ;
}
else if ( E_ADS_PROPERTY_NOT_SUPPORTED == hr ) {
// Property not supported on all platforms, check documentation.
wprintf( L"Languages property is not supported on this platform.\n" ) ;
}
else {
wprintf( L"Languages failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_LastFailedLogin( &date ) ;
if ( SUCCEEDED( hr ) ) {
var.vt = VT_DATE ;
var.date = date ;
hr = VariantChangeType( &var, &var, VARIANT_NOVALUEPROP, VT_BSTR ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"LastFailedLogin: %ws\n", var.bstrVal ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"LastFailedLogin property not found.\n" ) ;
}
else {
wprintf( L"LastFailedLogin failed with hr: 0x%08x\n", hr ) ;
}
VariantClear( &var ) ;
}
hr = pUser->get_LastLogin( &date ) ;
if ( SUCCEEDED( hr ) ) {
var.vt = VT_DATE ;
var.date = date ;
hr = VariantChangeType( &var, &var, VARIANT_NOVALUEPROP, VT_BSTR ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"LastLogin: %ws\n", var.bstrVal ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"LastLogin property not found.\n" ) ;
}
else {
wprintf( L"LastLogin failed with hr: 0x%08x\n", hr ) ;
}
VariantClear( &var ) ;
}
hr = pUser->get_LastLogoff( &date ) ;
if ( SUCCEEDED( hr ) ) {
var.vt = VT_DATE ;
var.date = date ;
hr = VariantChangeType( &var, &var, VARIANT_NOVALUEPROP, VT_BSTR ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"LastLogoff: %ws\n", var.bstrVal ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"LastLogoff property not found.\n" ) ;
}
else {
wprintf( L"LastLogoff failed with hr: 0x%08x\n", hr ) ;
}
VariantClear( &var ) ;
}
hr = pUser->get_LastName( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"LastName: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"LastName property not found.\n" ) ;
}
else {
wprintf( L"LastName failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_LoginHours( &var ) ;
if ( SUCCEEDED( hr ) ) {
wprintf(L"LoginHours:\n");
//For Octet String
void HUGEP *pArray;
ULONG dwSLBound;
ULONG dwSUBound;
if ( var.vt==(VT_UI1|VT_ARRAY) )
{
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var),
1,
(long FAR *) &dwSLBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var),
1,
(long FAR *) &dwSUBound ) ) ) {
hr = SafeArrayAccessData( V_ARRAY(&var),
&pArray );
//21 byte array representing 8 hour blocks for each day.
//First byte is 16:00-23:59 on saturday.
//Second byte is 0:00-07:59 on sunday,
//Third byte is 8:00-15:59 on sunday,
//and so on up to 8:00-15:59 on saturday.
PBYTE pLogonHours = (PBYTE)pArray;
const DWORD dTimeStrLen = 12;
const DWORD dDayStrLen = 12;
wchar_t szDay[dDayStrLen] ;
wchar_t szTime[dTimeStrLen] ;
double base = 2;
//8 bits in a byte.
DWORD iBitMax = 8;
DWORD dVal, j;
int iTotalBytes = 21;
int iOffset;
for ( int k = 1; k <= iTotalBytes; k++ )
{
if ( k!=iTotalBytes )
iOffset = k;
else
iOffset = 0;
//Get the block of time during the day.
switch ( k-1 )
{
case 0:
case 1:
case 2:
wcscpy_s(szDay, dDayStrLen , L"Sunday" ) ;
break;
case 3:
case 4:
case 5:
wcscpy_s(szDay, dDayStrLen , L"Monday" ) ;
break;
case 6:
case 7:
case 8:
wcscpy_s(szDay, dDayStrLen, L"Tuesday" );
break;
case 9:
case 10:
case 11:
wcscpy_s(szDay, dDayStrLen , L"Wednesday" );
break;
case 12:
case 13:
case 14:
wcscpy_s(szDay, dDayStrLen , L"Thursday" );
break;
case 15:
case 16:
case 17:
wcscpy_s(szDay, dDayStrLen , L"Friday" );
break;
case 18:
case 19:
case 20:
wcscpy_s(szDay, dDayStrLen , L"Saturday");
break;
}
switch ( k-1 )
{
case 0:
case 3:
case 6:
case 9:
case 12:
case 15:
case 18:
for ( j = 0; j < iBitMax; j++ )
{
dVal = (DWORD)pow(base, (double)j);
if ( (pLogonHours[iOffset] & dVal)==dVal )
{
switch ( j )
{
case 0:
wcscpy_s(szTime, dTimeStrLen, L"00:00-59");
break;
case 1:
wcscpy_s(szTime, dTimeStrLen, L"01:00-59");
break;
case 2:
wcscpy_s(szTime, dTimeStrLen, L"02:00-59");
break;
case 3:
wcscpy_s(szTime, dTimeStrLen, L"03:00-59");
break;
case 4:
wcscpy_s(szTime, dTimeStrLen, L"04:00-59");
break;
case 5:
wcscpy_s(szTime, dTimeStrLen, L"05:00-59");
break;
case 6:
wcscpy_s(szTime, dTimeStrLen, L"06:00-59");
break;
case 7:
wcscpy_s(szTime, dTimeStrLen, L"07:00-59");
break;
}
wprintf(L" %ws %ws\n",szDay,szTime);
}
}
break;
case 1:
case 4:
case 7:
case 10:
case 13:
case 16:
case 19:
for ( j = 0; j < iBitMax; j++ )
{
dVal = (DWORD)pow(base, (double)j);
if ( (pLogonHours[iOffset] & dVal)==dVal )
{
switch ( j )
{
case 0:
wcscpy_s(szTime, dTimeStrLen, L"08:00-59");
break;
case 1:
wcscpy_s(szTime, dTimeStrLen, L"09:00-59");
break;
case 2:
wcscpy_s(szTime, dTimeStrLen, L"10:00-59");
break;
case 3:
wcscpy_s(szTime, dTimeStrLen, L"11:00-59");
break;
case 4:
wcscpy_s(szTime, dTimeStrLen, L"12:00-59");
break;
case 5:
wcscpy_s(szTime, dTimeStrLen, L"13:00-59");
break;
case 6:
wcscpy_s(szTime, dTimeStrLen, L"14:00-59");
break;
case 7:
wcscpy_s(szTime, dTimeStrLen, L"15:00-59");
break;
}
wprintf(L" %ws %ws\n",szDay,szTime);
}
}
break;
case 2:
case 5:
case 8:
case 11:
case 14:
case 17:
case 20:
for ( j = 0; j < iBitMax; j++ )
{
dVal = (DWORD)pow(base, (double)j);
if ( (pLogonHours[iOffset] & dVal)==dVal )
{
switch ( j )
{
case 0:
wcscpy_s(szTime, dTimeStrLen, L"16:00-59");
break;
case 1:
wcscpy_s(szTime, dTimeStrLen, L"17:00-59");
break;
case 2:
wcscpy_s(szTime, dTimeStrLen, L"18:00-59");
break;
case 3:
wcscpy_s(szTime, dTimeStrLen, L"19:00-59");
break;
case 4:
wcscpy_s(szTime, dTimeStrLen, L"20:00-59");
break;
case 5:
wcscpy_s(szTime, dTimeStrLen, L"21:00-59");
break;
case 6:
wcscpy_s(szTime, dTimeStrLen, L"22:00-59");
break;
case 7:
wcscpy_s(szTime, dTimeStrLen, L"23:00-59");
break;
}
wprintf(L" %ws %ws\n",szDay,szTime);
}
}
break;
}
}
//Decrement the access count for the array.
SafeArrayUnaccessData( V_ARRAY(&var) );
}
}
VariantClear(&var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"LoginHours property not found.\n" ) ;
}
else {
wprintf( L"LoginHours failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_LoginScript( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"LoginScript: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"LoginScript property not found.\n" ) ;
}
else {
wprintf( L"LoginScript failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_LoginWorkstations( &var ) ;
if ( SUCCEEDED( hr ) ) {
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
VARIANT elem ;
while ( lBound <= uBound ) {
hr = SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"LoginWorkstations: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"LoginWorkstations property not found.\n" ) ;
}
else {
wprintf( L"LoginWorkstations failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_Manager( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"Manager: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"Manager property not found.\n" ) ;
}
else {
wprintf( L"Manager failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_MaxLogins( &lProp ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"MaxLogins: %d\n", lProp ) ;
}
else if ( E_ADS_PROPERTY_NOT_SUPPORTED == hr ) {
// Property not supported on all platforms, check documentation.
wprintf( L"MaxLogins property is not supported on this platform.\n" ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"MaxLogins property not found.\n" ) ;
}
else {
wprintf( L"MaxLogins failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_MaxStorage( &lProp ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"MaxStorage: %d\n", lProp ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"MaxStorage property not found.\n" ) ;
}
else {
wprintf( L"MaxStorage failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_NamePrefix( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"NamePrefix: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"NamePrefix property not found.\n" ) ;
}
else {
wprintf( L"NamePrefix failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_NameSuffix( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"NameSuffix: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"NameSuffix property not found.\n" ) ;
}
else {
wprintf( L"NameSuffix failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_OfficeLocations( &var ) ;
if ( SUCCEEDED( hr ) ) {
// Note: This property method can return either a VARIANT with
// type VT_BSTR and a single string, or a VARIANT with type
// VT_ARRAY | VT_BSTR and multiple strings, depending on whether
// the target directory's property is single- or multi-valued.
// Generic code should probably handle both cases.
if ( VT_BSTR == var.vt ) {
wprintf( L"OfficeLocations: %ws\n", var.bstrVal ) ;
}
else if ( ( VT_ARRAY | VT_BSTR ) == var.vt ) {
VARIANT elem ;
VariantInit( &elem ) ;
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
while ( lBound <= uBound ) {
if ( SUCCEEDED( SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ) ) {
wprintf( L"OfficeLocations: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"OfficeLocations property not found.\n" ) ;
}
else {
wprintf( L"OfficeLocations failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_OtherName( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"OtherName: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"OtherName property not found.\n" ) ;
}
else {
wprintf( L"OtherName failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_PasswordExpirationDate( &date ) ;
if ( SUCCEEDED( hr ) ) {
var.vt = VT_DATE ;
var.date = date ;
hr = VariantChangeType( &var, &var, VARIANT_NOVALUEPROP, VT_BSTR ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"PasswordExpirationDate: %ws\n", var.bstrVal ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"PasswordExpirationDate property not found.\n" ) ;
}
else {
wprintf( L"PasswordExpirationDate failed with hr: 0x%08x\n", hr ) ;
}
VariantClear( &var ) ;
}
hr = pUser->get_PasswordLastChanged( &date ) ;
if ( SUCCEEDED( hr ) ) {
var.vt = VT_DATE ;
var.date = date ;
hr = VariantChangeType( &var, &var, VARIANT_NOVALUEPROP, VT_BSTR ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"PasswordLastChanged: %ws\n", var.bstrVal ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"PasswordLastChanged property not found.\n" ) ;
}
else {
wprintf( L"PasswordLastChanged failed with hr: 0x%08x\n", hr ) ;
}
VariantClear( &var ) ;
}
hr = pUser->get_PasswordMinimumLength( &lProp ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"PasswordMinimumLength: %d\n", lProp ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"PasswordMinimumLength property not found.\n" ) ;
}
else {
wprintf( L"PasswordMinimumLength failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_PasswordRequired( &bBool ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"PasswordRequired: %ws\n", ( bBool ? L"TRUE" : L"FALSE" ) ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"PasswordRequired property not found.\n" ) ;
}
else {
wprintf( L"PasswordRequired failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_Picture( &var ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"Picture is set (not displayed)\n" ) ;
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"Picture property not found.\n" ) ;
}
else {
wprintf( L"Picture failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_PostalAddresses( &var ) ;
if ( SUCCEEDED( hr ) ) {
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
VARIANT elem ;
while ( lBound <= uBound ) {
hr = SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"PostalAddresses: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"PostalAddresses property not found.\n" ) ;
}
else {
wprintf( L"PostalAddresses failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_PostalCodes( &var ) ;
if ( SUCCEEDED( hr ) ) {
// Note: This property method can return either a VARIANT with
// type VT_BSTR and a single string, or a VARIANT with type
// VT_ARRAY | VT_BSTR and multiple strings, depending on whether
// the target directory's property is single- or multi-valued.
// Generic code should probably handle both cases.
if ( VT_BSTR == var.vt ) {
wprintf( L"PostalCodes: %ws\n", var.bstrVal ) ;
}
else if ( ( VT_ARRAY | VT_BSTR ) == var.vt ) {
VARIANT elem ;
VariantInit( &elem ) ;
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
while ( lBound <= uBound ) {
if ( SUCCEEDED( SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ) ) {
wprintf( L"PostalCodes: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"PostalCodes property not found.\n" ) ;
}
else {
wprintf( L"PostalCodes failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_Profile( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"Profile: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"Profile property not found.\n" ) ;
}
else {
wprintf( L"Profile failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_RequireUniquePassword( &bBool ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"RequireUniquePassword: %ws\n", ( bBool ? L"TRUE" : L"FALSE" ) ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"RequireUniquePassword property not found.\n" ) ;
}
else {
wprintf( L"RequireUniquePassword failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_SeeAlso( &var ) ;
if ( SUCCEEDED( hr ) ) {
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
VARIANT elem ;
while ( lBound <= uBound ) {
hr = SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"SeeAlso: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"SeeAlso property not found.\n" ) ;
}
else {
wprintf( L"SeeAlso failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_TelephoneHome( &var ) ;
if ( SUCCEEDED( hr ) ) {
// Note: This property method can return either a VARIANT with
// type VT_BSTR and a single string, or a VARIANT with type
// VT_ARRAY | VT_BSTR and multiple strings, depending on whether
// the target directory's property is single- or multi-valued.
// Generic code should probably handle both cases.
if ( VT_BSTR == var.vt ) {
wprintf( L"TelephoneHome: %ws\n", var.bstrVal ) ;
}
else if ( ( VT_ARRAY | VT_BSTR ) == var.vt ) {
VARIANT elem ;
VariantInit( &elem ) ;
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
while ( lBound <= uBound ) {
if ( SUCCEEDED( SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ) ) {
wprintf( L"TelephoneHome: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"TelephoneHome property not found.\n" ) ;
}
else {
wprintf( L"TelephoneHome failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_TelephoneMobile( &var ) ;
if ( SUCCEEDED( hr ) ) {
// Note: This property method can return either a VARIANT with
// type VT_BSTR and a single string, or a VARIANT with type
// VT_ARRAY | VT_BSTR and multiple strings, depending on whether
// the target directory's property is single- or multi-valued.
// Generic code should probably handle both cases.
if ( VT_BSTR == var.vt ) {
wprintf( L"TelephoneMobile: %ws\n", var.bstrVal ) ;
}
else if ( ( VT_ARRAY | VT_BSTR ) == var.vt ) {
VARIANT elem ;
VariantInit( &elem ) ;
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
while ( lBound <= uBound ) {
if ( SUCCEEDED( SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ) ) {
wprintf( L"TelephoneMobile: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"TelephoneMobile property not found.\n" ) ;
}
else {
wprintf( L"TelephoneMobile failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_TelephoneNumber( &var ) ;
if ( SUCCEEDED( hr ) ) {
// Note: This property method can return either a VARIANT with
// type VT_BSTR and a single string, or a VARIANT with type
// VT_ARRAY | VT_BSTR and multiple strings, depending on whether
// the target directory's property is single- or multi-valued.
// Generic code should probably handle both cases.
if ( VT_BSTR == var.vt ) {
wprintf( L"TelephoneNumber: %ws\n", var.bstrVal ) ;
}
else if ( ( VT_ARRAY | VT_BSTR ) == var.vt ) {
VARIANT elem ;
VariantInit( &elem ) ;
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
while ( lBound <= uBound ) {
if ( SUCCEEDED( SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ) ) {
wprintf( L"TelephoneNumber: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"TelephoneNumber property not found.\n" ) ;
}
else {
wprintf( L"TelephoneNumber failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_TelephonePager( &var ) ;
if ( SUCCEEDED( hr ) ) {
// Note: This property method can return either a VARIANT with
// type VT_BSTR and a single string, or a VARIANT with type
// VT_ARRAY | VT_BSTR and multiple strings, depending on whether
// the target directory's property is single- or multi-valued.
// Generic code should probably handle both cases.
if ( VT_BSTR == var.vt ) {
wprintf( L"TelephonePager: %ws\n", var.bstrVal ) ;
}
else if ( ( VT_ARRAY | VT_BSTR ) == var.vt ) {
VARIANT elem ;
VariantInit( &elem ) ;
if ( SUCCEEDED( SafeArrayGetLBound( V_ARRAY(&var), 1, &lBound ) ) &&
SUCCEEDED( SafeArrayGetUBound( V_ARRAY(&var), 1, &uBound ) ) ) {
while ( lBound <= uBound ) {
if ( SUCCEEDED( SafeArrayGetElement( V_ARRAY(&var), &lBound, &elem ) ) ) {
wprintf( L"TelephonePager: %ws\n", elem.bstrVal ) ;
VariantClear( &elem ) ;
}
++lBound ;
}
}
}
VariantClear( &var ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"TelephonePager property not found.\n" ) ;
}
else {
wprintf( L"TelephonePager failed with hr: 0x%08x\n", hr ) ;
}
hr = pUser->get_Title( &bstr ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"Title: %ws\n", bstr ) ;
SysFreeString( bstr ) ;
}
else if ( E_ADS_PROPERTY_NOT_FOUND == hr ) {
wprintf( L"Title property not found.\n" ) ;
}
else {
wprintf( L"Title failed with hr: 0x%08x\n", hr ) ;
}
return( S_OK ) ;
}
HRESULT FindUserByName( IDirectorySearch *pSearchBase,
LPWSTR szFindUser,
IADs **ppUser )
{
HRESULT hr ;
wchar_t pszSearchFilter[MAX_PATH] ;
wchar_t pszADsPath[MAX_PATH] ;
ADS_SEARCHPREF_INFO searchPrefs ;
ADS_SEARCH_COLUMN col ;
ADS_SEARCH_HANDLE hSearch ;
LPWSTR pszAttribute[1] = { L"ADsPath"} ;
*ppUser = NULL;
if ( NULL == pSearchBase || NULL == szFindUser || NULL == ppUser ) {
return( E_INVALIDARG ) ;
}
// build our search filter.
if ( 0 > _snwprintf_s( pszSearchFilter, sizeof(pszSearchFilter)/sizeof(pszSearchFilter[0]),MAX_PATH, L"(&(objectCategory=person)(objectClass=user)(cn=%ws))", szFindUser ) ) {
// uh oh, username is too long. just abort.
return( E_INVALIDARG ) ;
}
ZeroMemory(&searchPrefs, sizeof( searchPrefs ) ) ;
searchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE ;
searchPrefs.vValue.dwType = ADSTYPE_INTEGER ;
searchPrefs.vValue.Integer = ADS_SCOPE_SUBTREE ;
hr = pSearchBase->SetSearchPreference( &searchPrefs, 1 ) ;
if ( FAILED( hr ) ) {
return( hr ) ;
}
hr = pSearchBase->ExecuteSearch( pszSearchFilter, pszAttribute, 1, &hSearch ) ;
if ( SUCCEEDED( hr ) ) {
if ( S_ADS_NOMORE_ROWS != pSearchBase->GetNextRow( hSearch ) ) {
hr = pSearchBase->GetColumn( hSearch, pszAttribute[0], &col ) ;
if ( SUCCEEDED( hr ) ) {
wcsncpy_s( pszADsPath, sizeof(pszADsPath)/sizeof(pszADsPath[0]),col.pADsValues->CaseIgnoreString, MAX_PATH ) ;
pszADsPath[MAX_PATH-1] = 0 ;
hr = ADsOpenObject( pszADsPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADs, (void**)ppUser ) ;
if ( SUCCEEDED( hr ) ) {
wprintf( L"Found User.\n" ) ;
wprintf( L"%ws: %ws\n", pszAttribute[0], pszADsPath ) ;
}
pSearchBase->FreeColumn( &col ) ;
}
}
pSearchBase->CloseSearchHandle( hSearch ) ;
}
if ( NULL == *ppUser )
hr = E_FAIL;
return( hr ) ;
}