// userprop.cpp : Defines the entry point for the console application. // //For the pow function to calculate powers of 2 #include #include #include #include //Make sure you define UNICODE //Need to define version 5 for Windows 2000 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #include //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 \n"); wprintf( L"where 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 ) ; }