home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / ADSDK.ZIP / Samples / ActiveDir / User / vc / iasuser.cpp < prev   
Encoding:
C/C++ Source or Header  |  1999-04-05  |  27.5 KB  |  1,147 lines

  1. // userprop.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. //For the pow function to calculate powers of 2
  5. #include <math.h>
  6. #include <wchar.h>
  7. #include <objbase.h>
  8. #include <activeds.h>
  9.  
  10. //Make sure you define UNICODE
  11. //Need to define version 5 for Windows 2000
  12. #define _WIN32_WINNT 0x0500
  13. #include <sddl.h>
  14.  
  15.  
  16.  
  17. //Function to use the get_* methods of IADsUser.
  18. HRESULT GetUserPropertyMethods(IADsUser *pUser);
  19.  
  20. HRESULT FindUserByName(IDirectorySearch *pSearchBase, //Container to search
  21.                        LPOLESTR szFindUser, //Name of user to find.
  22.                        IADs **ppUser); //Return a pointer to the user
  23.  
  24.  
  25. void wmain( int argc, wchar_t *argv[ ])
  26. {
  27.  
  28. //Handle the command line arguments.
  29. LPOLESTR pszBuffer = new OLECHAR[MAX_PATH*2];
  30. if (argv[1] == NULL)
  31. {
  32.     wprintf(L"This program finds a user in the current Window 2000 domain\n");
  33.     wprintf(L"and displays its IADsUser properties.\n");
  34.     wprintf(L"Enter Common Name of the user to find:");
  35.     _getws(pszBuffer);
  36. }
  37. else
  38.    wcscpy(pszBuffer, argv[1]);
  39. //if empty string, exit.
  40. if (0==wcscmp(L"", pszBuffer))
  41.    return;
  42.     
  43. wprintf(L"\nFinding user: %s...\n",pszBuffer);
  44.     
  45. //Intialize COM
  46. CoInitialize(NULL);
  47. HRESULT hr = S_OK;
  48. //Get rootDSE and the domain container's DN.
  49. IADs *pObject = NULL;
  50. IDirectorySearch *pDS = NULL;
  51. LPOLESTR szPath = new OLECHAR[MAX_PATH];
  52. VARIANT var;
  53. hr = ADsOpenObject(L"LDAP://rootDSE",
  54.                  NULL,
  55.                  NULL,
  56.                  ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  57.                  IID_IADs,
  58.                  (void**)&pObject);
  59. if (FAILED(hr))
  60. {
  61.    wprintf(L"Not Found. Could not bind to the domain.\n");
  62.    if (pObject)
  63.      pObject->Release();
  64.    return;
  65. }
  66.  
  67. hr = pObject->Get(L"defaultNamingContext",&var);
  68. if (SUCCEEDED(hr))
  69. {
  70.     wcscpy(szPath,L"LDAP://");
  71.     wcscat(szPath,var.bstrVal);
  72.     VariantClear(&var);
  73.     if (pObject)
  74.     {
  75.        pObject->Release();
  76.        pObject = NULL;
  77.     }
  78.     //Bind to the root of the current domain.
  79.     hr = ADsOpenObject(szPath,
  80.                      NULL,
  81.                      NULL,
  82.                      ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  83.                      IID_IDirectorySearch,
  84.                      (void**)&pDS);
  85.     if (SUCCEEDED(hr))
  86.     {
  87.         hr =  FindUserByName(pDS, //Container to search
  88.                            pszBuffer, //Name of user to find.
  89.                            &pObject); //Return a pointer to the user
  90.         if (SUCCEEDED(hr))
  91.         {
  92.             IADsUser *pUser = NULL;
  93.             hr = pObject->QueryInterface( IID_IADsUser, (void**) &pUser );
  94.             if (SUCCEEDED(hr))
  95.             {
  96.                wprintf (L"----------------------------------------------\n");
  97.                wprintf (L"--------Call GetUserPropertyMethods-----------\n");
  98.                hr = GetUserPropertyMethods(pUser);
  99.                wprintf (L"GetUserPropertyMethods HR: %x\n", hr);
  100.             }
  101.             if (pUser)
  102.                 pUser->Release();
  103.         }
  104.         else
  105.         {
  106.             wprintf(L"User \"%s\" not Found.\n",pszBuffer);
  107.             wprintf (L"FindUserByName failed with the following HR: %x\n", hr);
  108.         }
  109.         if (pObject)
  110.             pObject->Release();
  111.     }
  112.  
  113.     if (pDS)
  114.        pDS->Release();
  115. }
  116.  
  117. //Uninitalize COM
  118. CoUninitialize();
  119.  
  120.     return;
  121. }
  122.  
  123. HRESULT FindUserByName(IDirectorySearch *pSearchBase, //Container to search
  124.                        LPOLESTR szFindUser, //Name of user to find.
  125.                        IADs **ppUser) //Return a pointer to the user
  126. {
  127.     HRESULT hrObj = E_FAIL;
  128.     HRESULT hr = E_FAIL;
  129.     if ((!pSearchBase)||(!szFindUser))
  130.         return E_INVALIDARG;
  131.     //Create search filter
  132.     LPOLESTR pszSearchFilter = new OLECHAR[MAX_PATH];
  133.     LPOLESTR szADsPath = new OLECHAR[MAX_PATH];
  134.     wcscpy(pszSearchFilter, L"(&(objectCategory=person)(objectClass=user)(cn=");
  135.     wcscat(pszSearchFilter, szFindUser);
  136.     wcscat(pszSearchFilter,    L"))");
  137.     //Search entire subtree from root.
  138.     ADS_SEARCHPREF_INFO SearchPrefs;
  139.     SearchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  140.     SearchPrefs.vValue.dwType = ADSTYPE_INTEGER;
  141.     SearchPrefs.vValue.Integer = ADS_SCOPE_SUBTREE;
  142.     DWORD dwNumPrefs = 1;
  143.     // COL for iterations
  144.     ADS_SEARCH_COLUMN col;
  145.     // Handle used for searching
  146.     ADS_SEARCH_HANDLE hSearch;
  147.     // Set the search preference
  148.     hr = pSearchBase->SetSearchPreference( &SearchPrefs, dwNumPrefs);
  149.     if (FAILED(hr))
  150.         return hr;
  151.     // Set attributes to return
  152.     CONST DWORD dwAttrNameSize = 1;
  153.     LPOLESTR pszAttribute[dwAttrNameSize] = {L"ADsPath"};
  154.  
  155.     // Execute the search
  156.     hr = pSearchBase->ExecuteSearch(pszSearchFilter,
  157.                                   pszAttribute,
  158.                                   dwAttrNameSize,
  159.                                   &hSearch
  160.                                   );
  161.     if (SUCCEEDED(hr))
  162.     {    
  163.  
  164.     // Call IDirectorySearch::GetNextRow() to retrieve the next row 
  165.     //of data
  166.         while( pSearchBase->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS )
  167.         {
  168.             // loop through the array of passed column names,
  169.             // print the data for each column
  170.             for (DWORD x = 0; x < dwAttrNameSize; x++)
  171.             {
  172.                 // Get the data for this column
  173.                 hr = pSearchBase->GetColumn( hSearch, pszAttribute[x], &col );
  174.                 if ( SUCCEEDED(hr) )
  175.                 {
  176.                     // Print the data for the column and free the column
  177.                     // Note the attribute we asked for is type CaseIgnoreString.
  178.                     wcscpy(szADsPath, col.pADsValues->CaseIgnoreString); 
  179.                     hr = ADsOpenObject(szADsPath,
  180.                                      NULL,
  181.                                      NULL,
  182.                                      ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  183.                                      IID_IADs,
  184.                                      (void**)ppUser);
  185.                     if (SUCCEEDED(hr))
  186.                     {
  187.                        wprintf(L"Found User.\n",szFindUser); 
  188.                        wprintf(L"%s: %s\r\n",pszAttribute[x],col.pADsValues->CaseIgnoreString); 
  189.                        hrObj = S_OK;
  190.                     }
  191.                     pSearchBase->FreeColumn( &col );
  192.                 }
  193.                 else
  194.                     hr = E_FAIL;
  195.             }
  196.         }
  197.         // Close the search handle to clean up
  198.         pSearchBase->CloseSearchHandle(hSearch);
  199.     }
  200.     if (FAILED(hrObj))
  201.         hr = hrObj;
  202.     return hr;
  203. }
  204.  
  205. HRESULT GetUserPropertyMethods(IADsUser *pUser)
  206. {
  207. VARIANT_BOOL bBool;
  208. DATE date;
  209. BSTR bstr;
  210. LONG lProp;
  211. VARIANT var;
  212. HRESULT hr;
  213.  
  214.   VARIANT *pVar;
  215.   long lLBound, lUBound;
  216.   long cElements;
  217.  
  218.  
  219.  
  220.  
  221. hr = pUser->get_AccountDisabled(&bBool); 
  222. if (SUCCEEDED(hr))
  223. {
  224.     if (bBool)
  225.       wprintf(L"AccountDisabled: TRUE\n");
  226.     else
  227.       wprintf(L"AccountDisabled: FALSE\n");
  228. }
  229. else
  230. {
  231.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  232.         wprintf(L"AccountDisabled property not found.\n");
  233. }
  234.  
  235. hr = pUser->get_AccountExpirationDate (&date); 
  236. if (SUCCEEDED(hr))
  237. {
  238. //Pack in variant
  239.     var.vt = VT_DATE;
  240.     var.date = date;
  241.     VariantChangeType(&var,&var,VARIANT_NOVALUEPROP,VT_BSTR);
  242.     wprintf(L"AccountExpirationDate: %s\n",var.bstrVal);
  243.     VariantClear(&var);
  244. }
  245. hr = pUser->get_BadLoginAddress (&bstr);
  246. if (SUCCEEDED(hr))
  247. {
  248.       wprintf(L"BadLoginAddress: %s\n", bstr);
  249.       SysFreeString(bstr);
  250. }
  251. else
  252. {
  253.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  254.         wprintf(L"BadLoginAddress property not found.\n");
  255.     else if (hr==E_ADS_PROPERTY_NOT_SUPPORTED)
  256.         //BadLoginAddress is not supported for Windows 2000
  257.         //So don't use this method.
  258.         wprintf(L"BadLoginAddress property is not supported for Windows 2000.\n");
  259.     else
  260.         wprintf(L"BadLoginAddress failed with HR: %x\n", hr);
  261. }
  262. hr = pUser->get_BadLoginCount (&lProp);
  263. if (SUCCEEDED(hr))
  264. {
  265.       wprintf(L"BadLoginCount: %d\n", lProp);
  266. }
  267. else
  268. {
  269.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  270.         wprintf(L"BadLoginCount property not found.\n");
  271.     else
  272.         wprintf(L"BadLoginCount failed with HR: %x\n", hr);
  273. }
  274. hr = pUser->get_Department (&bstr);
  275. if (SUCCEEDED(hr))
  276. {
  277.       wprintf(L"Department: %s\n", bstr);
  278.       SysFreeString(bstr);
  279. }
  280. else
  281. {
  282.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  283.         wprintf(L"Department property not found.\n");
  284.     else
  285.         wprintf(L"Department failed with HR: %x\n", hr);
  286. }
  287.  
  288. hr = pUser->get_Description(&bstr); 
  289. if (SUCCEEDED(hr))
  290. {
  291.       wprintf(L"Description: %s\n", bstr);
  292.       SysFreeString(bstr);
  293. }
  294. else
  295. {
  296.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  297.         wprintf(L"Description property not found.\n");
  298.     else
  299.         wprintf(L"Description failed with HR: %x\n", hr);
  300. }
  301. hr = pUser->get_Division(&bstr); 
  302. if (SUCCEEDED(hr))
  303. {
  304.       wprintf(L"Division: %s\n", bstr);
  305.       SysFreeString(bstr);
  306. }
  307. else
  308. {
  309.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  310.         wprintf(L"Division property not found.\n");
  311.     else
  312.         wprintf(L"Division failed with HR: %x\n", hr);
  313. }
  314.  
  315. hr = pUser->get_EmailAddress(&bstr); 
  316. if (SUCCEEDED(hr))
  317. {
  318.       wprintf(L"EmailAddress: %s\n", bstr);
  319.       SysFreeString(bstr);
  320. }
  321. else
  322. {
  323.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  324.         wprintf(L"EmailAddress property not found.\n");
  325.     else
  326.         wprintf(L"EmailAddress failed with HR: %x\n", hr);
  327. }
  328.  
  329. hr = pUser->get_EmployeeID (&bstr); 
  330. if (SUCCEEDED(hr))
  331. {
  332.       wprintf(L"EmployeeID: %s\n", bstr);
  333.       SysFreeString(bstr);
  334. }
  335. else
  336. {
  337.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  338.         wprintf(L"EmployeeID property not found.\n");
  339.     else
  340.         wprintf(L"EmployeeID failed with HR: %x\n", hr);
  341. }
  342. hr = pUser->get_FaxNumber (&var); 
  343. if (SUCCEEDED(hr))
  344. {
  345.     //Fax is a bstrVal
  346.     if (var.vt==VT_BSTR)
  347.       wprintf(L"FaxNumber: %s\n", var.bstrVal);
  348. }
  349. else
  350. {
  351.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  352.         wprintf(L"FaxNumber property not found.\n");
  353.     else
  354.         wprintf(L"FaxNumber failed with HR: %x\n", hr);
  355. }
  356. VariantClear(&var);
  357. hr = pUser->get_FirstName (&bstr); 
  358. if (SUCCEEDED(hr))
  359. {
  360.       wprintf(L"FirstName: %s\n", bstr);
  361.       SysFreeString(bstr);
  362. }
  363. else
  364. {
  365.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  366.         wprintf(L"FirstName property not found.\n");
  367.     else
  368.         wprintf(L"FirstName failed with HR: %x\n", hr);
  369. }
  370. hr = pUser->get_FullName (&bstr); 
  371. if (SUCCEEDED(hr))
  372. {
  373.       wprintf(L"FullName: %s\n", bstr);
  374.       SysFreeString(bstr);
  375. }
  376. else
  377. {
  378.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  379.         wprintf(L"FullName property not found.\n");
  380.     else
  381.         wprintf(L"FullName failed with HR: %x\n", hr);
  382. }
  383. hr = pUser->get_GraceLoginsAllowed (&lProp); 
  384. if (SUCCEEDED(hr))
  385. {
  386.       wprintf(L"GraceLoginsAllowed: %d\n", lProp);
  387. }
  388. else
  389. {
  390.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  391.         wprintf(L"GraceLoginsAllowed property not found.\n");
  392.     else if (hr==E_ADS_PROPERTY_NOT_SUPPORTED)
  393.         //GraceLoginsAllowed is not supported for Windows 2000
  394.         //So don't use this method.
  395.         wprintf(L"GraceLoginsAllowed property is not supported for Windows 2000.\n");
  396.     else
  397.         wprintf(L"GraceLoginsAllowed failed with HR: %x\n", hr);
  398. }
  399. hr = pUser->get_GraceLoginsRemaining (&lProp); 
  400. if (SUCCEEDED(hr))
  401. {
  402.       wprintf(L"GraceLoginsRemaining: %d\n", lProp);
  403. }
  404. else
  405. {
  406.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  407.         wprintf(L"GraceLoginsRemaining property not found.\n");
  408.     else if (hr==E_ADS_PROPERTY_NOT_SUPPORTED)
  409.         //GraceLoginsRemaining is not supported for Windows 2000
  410.         //So don't use this method.
  411.         wprintf(L"GraceLoginsRemaining property is not supported for Windows 2000.\n");
  412.     else
  413.         wprintf(L"GraceLoginsRemaining failed with HR: %x\n", hr);
  414. }
  415. hr = pUser->get_HomeDirectory(&bstr); 
  416. if (SUCCEEDED(hr))
  417. {
  418.       wprintf(L"HomeDirectory: %s\n", bstr);
  419.       SysFreeString(bstr);
  420. }
  421. else
  422. {
  423.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  424.         wprintf(L"HomeDirectory property not found.\n");
  425.     else
  426.         wprintf(L"HomeDirectory failed with HR: %x\n", hr);
  427. }
  428. hr = pUser->get_HomePage(&bstr); 
  429. if (SUCCEEDED(hr))
  430. {
  431.       wprintf(L"HomePage: %s\n", bstr);
  432.       SysFreeString(bstr);
  433. }
  434. else
  435. {
  436.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  437.         wprintf(L"HomePage property not found.\n");
  438.     else
  439.         wprintf(L"HomePage failed with HR: %x\n", hr);
  440. }
  441. hr = pUser->get_IsAccountLocked (&bBool); 
  442. if (SUCCEEDED(hr))
  443. {
  444.     if (bBool)
  445.       wprintf(L"IsAccountLocked: TRUE\n");
  446.     else
  447.       wprintf(L"IsAccountLocked: FALSE\n");
  448. }
  449. else
  450. {
  451.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  452.         wprintf(L"IsAccountLocked property not found.\n");
  453.     else
  454.         wprintf(L"IsAccountLocked failed with HR: %x\n", hr);
  455. }
  456.  
  457. hr = pUser->get_Languages(&var); 
  458. if (SUCCEEDED(hr))
  459. {
  460.       wprintf(L"Languages (%d):\n", var.vt);
  461. }
  462. else
  463. {
  464.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  465.         wprintf(L"Languages property not found.\n");
  466.     else if (hr==E_ADS_PROPERTY_NOT_SUPPORTED)
  467.         //Languages is not supported for Windows 2000
  468.         //So don't use this method.
  469.         wprintf(L"Languages property is not supported for Windows 2000.\n");
  470.      else
  471.         wprintf(L"Languages failed with HR: %x\n", hr);
  472. }
  473. VariantClear(&var);
  474. hr = pUser->get_LastFailedLogin (&date);
  475. if (SUCCEEDED(hr))
  476. {
  477. //Pack in variant
  478.     var.vt = VT_DATE;
  479.     var.date = date;
  480.     VariantChangeType(&var,&var,VARIANT_NOVALUEPROP,VT_BSTR);
  481.     wprintf(L"LastFailedLogin: %s\n",var.bstrVal);
  482.     VariantClear(&var);
  483. }
  484. else
  485. {
  486.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  487.         wprintf(L"LastFailedLogin property not found.\n");
  488.     else
  489.         wprintf(L"LastFailedLogin failed with HR: %x\n", hr);
  490. }
  491.  
  492. hr = pUser->get_LastLogin (&date);
  493. if (SUCCEEDED(hr))
  494. {
  495. //Pack in variant
  496.     var.vt = VT_DATE;
  497.     var.date = date;
  498.     VariantChangeType(&var,&var,VARIANT_NOVALUEPROP,VT_BSTR);
  499.     wprintf(L"LastLogin: %s\n",var.bstrVal);
  500.     VariantClear(&var);
  501. }
  502. else
  503. {
  504.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  505.         wprintf(L"LastLogin property not found.\n");
  506.     else
  507.         wprintf(L"LastLogin failed with HR: %x\n", hr);
  508. }
  509.  
  510. hr = pUser->get_LastLogoff (&date);
  511. if (SUCCEEDED(hr))
  512. {
  513. //Pack in variant
  514.     var.vt = VT_DATE;
  515.     var.date = date;
  516.     VariantChangeType(&var,&var,VARIANT_NOVALUEPROP,VT_BSTR);
  517.     wprintf(L"LastLogoff: %s\n",var.bstrVal);
  518.     VariantClear(&var);
  519. }
  520. else
  521. {
  522.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  523.         wprintf(L"LastLogoff property not found.\n");
  524.     else
  525.         wprintf(L"LastLogoff failed with HR: %x\n", hr);
  526. }
  527. hr = pUser->get_LastName (&bstr); 
  528. if (SUCCEEDED(hr))
  529. {
  530.       wprintf(L"LastName: %s\n", bstr);
  531.       SysFreeString(bstr);
  532. }
  533. else
  534. {
  535.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  536.         wprintf(L"LastName property not found.\n");
  537.     else
  538.         wprintf(L"LastName failed with HR: %x\n", hr);
  539. }
  540. VariantClear(&var);
  541. hr = pUser->get_LoginHours (&var); 
  542. if (SUCCEEDED(hr))
  543. {
  544.   wprintf(L"LoginHours:\n");
  545.   //For Octet String
  546.   void HUGEP *pArray;
  547.   ULONG dwSLBound;
  548.   ULONG dwSUBound;
  549.   if (var.vt==(VT_UI1|VT_ARRAY))
  550.   {
  551.         hr = SafeArrayGetLBound( V_ARRAY(&var),
  552.                                   1,
  553.                                   (long FAR *) &dwSLBound );
  554.         hr = SafeArrayGetUBound( V_ARRAY(&var),
  555.                                   1,
  556.                                   (long FAR *) &dwSUBound );
  557.         if (SUCCEEDED(hr))
  558.         {
  559.             hr = SafeArrayAccessData( V_ARRAY(&var),
  560.                                       &pArray );
  561.         }
  562.  
  563.        //21 byte array representing 8 hour blocks for each day.
  564.        //First byte is 16:00-23:59 on saturday.
  565.        //Second byte is 0:00-07:59 on sunday,
  566.        //Third byte is 8:00-15:59 on sunday,
  567.        //and so on up to 8:00-15:59 on saturday.
  568.        PBYTE pLogonHours = (PBYTE)pArray;
  569.        LPOLESTR szDay = new OLECHAR[MAX_PATH];
  570.        LPOLESTR szTime = new OLECHAR[MAX_PATH];
  571.        int base = 2;
  572.        //8 bits in a byte.
  573.        DWORD iBitMax = 8;
  574.        DWORD dVal, j;
  575.        int iTotalBytes = 21;
  576.        int iOffset;
  577.           for (int k = 1; k <= iTotalBytes; k++)
  578.        {
  579.             if (k!=iTotalBytes)
  580.               iOffset = k;
  581.             else
  582.               iOffset = 0;
  583.             //Get the block of time during the day.
  584.             switch (k-1)
  585.             {
  586.             case 0:
  587.             case 1:
  588.             case 2:
  589.               wcscpy(szDay, L"Sunday");
  590.               break;
  591.             case 3:
  592.             case 4:
  593.             case 5:
  594.               wcscpy(szDay, L"Monday");
  595.               break;
  596.             case 6:
  597.             case 7:
  598.             case 8:
  599.               wcscpy(szDay, L"Tuesday");
  600.               break;
  601.             case 9:
  602.             case 10:
  603.             case 11:
  604.               wcscpy(szDay, L"Wednesday");
  605.               break;
  606.             case 12:
  607.             case 13:
  608.             case 14:
  609.               wcscpy(szDay, L"Thursday");
  610.               break;
  611.             case 15:
  612.             case 16:
  613.             case 17:
  614.               wcscpy(szDay, L"Friday");
  615.               break;
  616.             case 18:
  617.             case 19:
  618.             case 20:
  619.               wcscpy(szDay, L"Saturday");
  620.               break;
  621.             }
  622.           
  623.             switch (k-1)
  624.             {
  625.             case 0:
  626.             case 3:
  627.             case 6:
  628.             case 9:
  629.             case 12:
  630.             case 15:
  631.             case 18:
  632.                for (j = 0; j < iBitMax; j++)
  633.                {
  634.                    dVal = pow(base, j);
  635.                    if ((pLogonHours[iOffset] & dVal)==dVal)
  636.                    {
  637.                       switch (j)
  638.                       {
  639.                         case 0:
  640.                           wcscpy(szTime, L"00:00-59");
  641.                           break;
  642.                         case 1:
  643.                           wcscpy(szTime, L"01:00-59");
  644.                           break;
  645.                         case 2:
  646.                           wcscpy(szTime, L"02:00-59");
  647.                           break;
  648.                         case 3:
  649.                           wcscpy(szTime, L"03:00-59");
  650.                           break;
  651.                         case 4:
  652.                           wcscpy(szTime, L"04:00-59");
  653.                           break;
  654.                         case 5:
  655.                           wcscpy(szTime, L"05:00-59");
  656.                           break;
  657.                         case 6:
  658.                           wcscpy(szTime, L"06:00-59");
  659.                           break;
  660.                         case 7:
  661.                           wcscpy(szTime, L"07:00-59");
  662.                           break;
  663.                       }
  664.                         wprintf(L"   %s %s\n",szDay,szTime);
  665.                    }
  666.                }
  667.                break;
  668.             case 1:
  669.             case 4:
  670.             case 7:
  671.             case 10:
  672.             case 13:
  673.             case 16:
  674.             case 19:
  675.                for (j = 0; j < iBitMax; j++)
  676.                {
  677.                    dVal = pow(base, j);
  678.                    if ((pLogonHours[iOffset] & dVal)==dVal)
  679.                    {
  680.                       switch (j)
  681.                       {
  682.                         case 0:
  683.                           wcscpy(szTime, L"08:00-59");
  684.                           break;
  685.                         case 1:
  686.                           wcscpy(szTime, L"09:00-59");
  687.                           break;
  688.                         case 2:
  689.                           wcscpy(szTime, L"10:00-59");
  690.                           break;
  691.                         case 3:
  692.                           wcscpy(szTime, L"11:00-59");
  693.                           break;
  694.                         case 4:
  695.                           wcscpy(szTime, L"12:00-59");
  696.                           break;
  697.                         case 5:
  698.                           wcscpy(szTime, L"13:00-59");
  699.                           break;
  700.                         case 6:
  701.                           wcscpy(szTime, L"14:00-59");
  702.                           break;
  703.                         case 7:
  704.                           wcscpy(szTime, L"15:00-59");
  705.                           break;
  706.                       }
  707.                         wprintf(L"   %s %s\n",szDay,szTime);
  708.                    }
  709.                }
  710.                break;
  711.             case 2:
  712.             case 5:
  713.             case 8:
  714.             case 11:
  715.             case 14:
  716.             case 17:
  717.             case 20:
  718.                for (j = 0; j < iBitMax; j++)
  719.                {
  720.                    dVal = pow(base, j);
  721.                    if ((pLogonHours[iOffset] & dVal)==dVal)
  722.                    {
  723.                       switch (j)
  724.                       {
  725.                         case 0:
  726.                           wcscpy(szTime, L"16:00-59");
  727.                           break;
  728.                         case 1:
  729.                           wcscpy(szTime, L"17:00-59");
  730.                           break;
  731.                         case 2:
  732.                           wcscpy(szTime, L"18:00-59");
  733.                           break;
  734.                         case 3:
  735.                           wcscpy(szTime, L"19:00-59");
  736.                           break;
  737.                         case 4:
  738.                           wcscpy(szTime, L"20:00-59");
  739.                           break;
  740.                         case 5:
  741.                           wcscpy(szTime, L"21:00-59");
  742.                           break;
  743.                         case 6:
  744.                           wcscpy(szTime, L"22:00-59");
  745.                           break;
  746.                         case 7:
  747.                           wcscpy(szTime, L"23:00-59");
  748.                           break;
  749.                       }
  750.                         wprintf(L"   %s %s\n",szDay,szTime);
  751.                    }
  752.                }
  753.                break;
  754.           }
  755.         }
  756.                                 
  757.        //Decrement the access count for the array.
  758.         SafeArrayUnaccessData( V_ARRAY(&var) );
  759.         VariantClear(&var);
  760.     }
  761.  
  762. }
  763. else
  764. {
  765.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  766.         wprintf(L"LoginHours property not found.\n");
  767.     else
  768.         wprintf(L"LoginHours failed with HR: %x\n", hr);
  769. }
  770. VariantClear(&var);
  771.  
  772. hr = pUser->get_LoginScript(&bstr); 
  773. if (SUCCEEDED(hr))
  774. {
  775.       wprintf(L"LoginScript: %s\n", bstr);
  776.       SysFreeString(bstr);
  777. }
  778. else
  779. {
  780.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  781.         wprintf(L"LoginScript property not found.\n");
  782.     else
  783.         wprintf(L"LoginScript failed with HR: %x\n", hr);
  784. }
  785. hr = pUser->get_LoginWorkstations (&var); 
  786. if (SUCCEEDED(hr))
  787. {
  788.   wprintf(L"LoginWorkstations: ");
  789.   //Should be safe array containing variants of type BSTR.
  790.   if (var.vt==(VT_VARIANT|VT_ARRAY))
  791.   {
  792.        hr = SafeArrayAccessData((SAFEARRAY*)(var.pparray), (void HUGEP* FAR*)&pVar);
  793.        //One dimensional array. Get the bounds for the array.
  794.         hr = SafeArrayGetLBound((SAFEARRAY*)(var.pparray), 1, &lLBound);
  795.        hr = SafeArrayGetUBound((SAFEARRAY*)(var.pparray), 1, &lUBound);
  796.        //Get the count of elements
  797.        cElements = lUBound-lLBound + 1;
  798.        //Get the elements of the array
  799.        if (SUCCEEDED(hr))
  800.        {
  801.             for (int i = 0; i < cElements; i++ ) 
  802.             {
  803.               switch (pVar[i].vt)
  804.               {
  805.               case VT_BSTR:
  806.                   wprintf(L"%s ",pVar[i].bstrVal);
  807.                   break;
  808.               default:
  809.                   wprintf(L"Unhandled Variant type for property value array: %d\n",pVar[i].vt);
  810.                   break;
  811.               }
  812.             }
  813.        }
  814.        wprintf(L"\n");
  815.  
  816.        //Decrement the access count for the array.
  817.        SafeArrayUnaccessData((SAFEARRAY*)(var.pparray));
  818.   }
  819. }
  820. else
  821. {
  822.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  823.         wprintf(L"LoginWorkstations property not found.\n");
  824.     else
  825.         wprintf(L"LoginWorkstations failed with HR: %x\n", hr);
  826. }
  827. VariantClear(&var);
  828. hr = pUser->get_Manager (&bstr); 
  829. if (SUCCEEDED(hr))
  830. {
  831.       wprintf(L"Manager: %s\n", bstr);
  832.       SysFreeString(bstr);
  833. }
  834. else
  835. {
  836.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  837.         wprintf(L"Manager property not found.\n");
  838.     else
  839.         wprintf(L"Manager failed with HR: %x\n", hr);
  840. }
  841. hr = pUser->get_MaxLogins (&lProp); 
  842. if (SUCCEEDED(hr))
  843. {
  844.       wprintf(L"MaxLogins: %d\n", lProp);
  845. }
  846. else
  847. {
  848.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  849.         wprintf(L"MaxLogins property not found.\n");
  850.     else if (hr==E_ADS_PROPERTY_NOT_SUPPORTED)
  851.         //MaxLogins is not supported for Windows 2000
  852.         //So don't use this method.
  853.         wprintf(L"MaxLogins property is not supported for Windows 2000.\n");
  854.      else
  855.         wprintf(L"MaxLogins failed with HR: %x\n", hr);
  856. }
  857. hr = pUser->get_MaxStorage (&lProp); 
  858. if (SUCCEEDED(hr))
  859. {
  860.       wprintf(L"MaxStorage: %d\n", lProp);
  861. }
  862. else
  863. {
  864.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  865.         wprintf(L"MaxStorage property not found.\n");
  866.     else
  867.         wprintf(L"MaxStorage failed with HR: %x\n", hr);
  868. }
  869. hr = pUser->get_NamePrefix (&bstr); 
  870. if (SUCCEEDED(hr))
  871. {
  872.       wprintf(L"NamePrefix: %s\n", bstr);
  873.       SysFreeString(bstr);
  874. }
  875. else
  876. {
  877.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  878.         wprintf(L"NamePrefix property not found.\n");
  879.     else
  880.         wprintf(L"NamePrefix failed with HR: %x\n", hr);
  881. }
  882. hr = pUser->get_NameSuffix (&bstr); 
  883. if (SUCCEEDED(hr))
  884. {
  885.       wprintf(L"NameSuffix: %s\n", bstr);
  886.       SysFreeString(bstr);
  887. }
  888. else
  889. {
  890.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  891.         wprintf(L"NameSuffix property not found.\n");
  892.     else
  893.         wprintf(L"NameSuffix failed with HR: %x\n", hr);
  894. }
  895. hr = pUser->get_OfficeLocations (&var); 
  896. if (SUCCEEDED(hr))
  897. {
  898.     //OfficeLocations is a bstrVal
  899.     if (var.vt==VT_BSTR)
  900.       wprintf(L"OfficeLocations: %s\n", var.bstrVal);
  901. }
  902. else
  903. {
  904.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  905.         wprintf(L"OfficeLocations property not found.\n");
  906.     else
  907.         wprintf(L"OfficeLocations failed with HR: %x\n", hr);
  908. }
  909. VariantClear(&var);
  910. hr = pUser->get_OtherName (&bstr); 
  911. if (SUCCEEDED(hr))
  912. {
  913.       wprintf(L"OtherName: %s\n", bstr);
  914.       SysFreeString(bstr);
  915. }
  916. else
  917. {
  918.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  919.         wprintf(L"OtherName property not found.\n");
  920.     else
  921.         wprintf(L"OtherName failed with HR: %x\n", hr);
  922. }
  923. hr = pUser->get_PasswordExpirationDate (&date); 
  924. if (SUCCEEDED(hr))
  925. {
  926. //Pack in variant
  927.     var.vt = VT_DATE;
  928.     var.date = date;
  929.     VariantChangeType(&var,&var,VARIANT_NOVALUEPROP,VT_BSTR);
  930.     wprintf(L"PasswordExpirationDate: %s\n",var.bstrVal);
  931.     VariantClear(&var);
  932. }
  933. else
  934. {
  935.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  936.         wprintf(L"PasswordExpirationDate property not found.\n");
  937.     else
  938.         wprintf(L"PasswordExpirationDate failed with HR: %x\n", hr);
  939. }
  940. hr = pUser->get_PasswordLastChanged (&date);
  941. if (SUCCEEDED(hr))
  942. {
  943. //Pack in variant
  944.     var.vt = VT_DATE;
  945.     var.date = date;
  946.     VariantChangeType(&var,&var,VARIANT_NOVALUEPROP,VT_BSTR);
  947.     wprintf(L"PasswordLastChanged: %s\n",var.bstrVal);
  948.     VariantClear(&var);
  949. }
  950. else
  951. {
  952.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  953.         wprintf(L"PasswordLastChanged property not found.\n");
  954.     else
  955.         wprintf(L"PasswordLastChanged failed with HR: %x\n", hr);
  956. }
  957. hr = pUser->get_PasswordMinimumLength (&lProp); 
  958. if (SUCCEEDED(hr))
  959. {
  960.       wprintf(L"PasswordMinimumLength: %d\n", lProp);
  961. }
  962. else
  963. {
  964.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  965.         wprintf(L"PasswordMinimumLength property not found.\n");
  966.     else
  967.         wprintf(L"PasswordMinimumLength failed with HR: %x\n", hr);
  968. }
  969. hr = pUser->get_PasswordRequired (&bBool); 
  970. if (SUCCEEDED(hr))
  971. {
  972.     if (bBool)
  973.       wprintf(L"PasswordRequired: TRUE\n");
  974.     else
  975.       wprintf(L"PasswordRequired: FALSE\n");
  976. }
  977. else
  978. {
  979.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  980.         wprintf(L"PasswordRequired property not found.\n");
  981.     else
  982.         wprintf(L"PasswordRequired failed with HR: %x\n", hr);
  983. }
  984. hr = pUser->get_Picture (&var); 
  985. if (SUCCEEDED(hr))
  986. {
  987.       wprintf(L"Picture (%d):\n", var.vt);
  988. }
  989. else
  990. {
  991.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  992.         wprintf(L"Picture property not found.\n");
  993.     else
  994.         wprintf(L"Picture failed with HR: %x\n", hr);
  995. }
  996. VariantClear(&var);
  997. hr = pUser->get_PostalAddresses (&var); 
  998. if (SUCCEEDED(hr))
  999. {
  1000.     //PostalAddresses is a bstrVal
  1001.     if (var.vt==VT_BSTR)
  1002.       wprintf(L"PostalAddresses: %s\n", var.bstrVal);
  1003. }
  1004. else
  1005. {
  1006.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1007.         wprintf(L"PostalAddresses property not found.\n");
  1008.     else
  1009.         wprintf(L"PostalAddresses failed with HR: %x\n", hr);
  1010. }
  1011. VariantClear(&var);
  1012. hr = pUser->get_PostalCodes (&var); 
  1013. if (SUCCEEDED(hr))
  1014. {
  1015.     //PostalCodes is a bstrVal
  1016.     if (var.vt==VT_BSTR)
  1017.       wprintf(L"PostalCodes: %s\n", var.bstrVal);
  1018. }
  1019. else
  1020. {
  1021.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1022.         wprintf(L"PostalCodes property not found.\n");
  1023.     else
  1024.         wprintf(L"PostalCodes failed with HR: %x\n", hr);
  1025. }
  1026. VariantClear(&var);
  1027. hr = pUser->get_Profile(&bstr); 
  1028. if (SUCCEEDED(hr))
  1029. {
  1030.       wprintf(L"Profile: %s\n", bstr);
  1031.       SysFreeString(bstr);
  1032. }
  1033. else
  1034. {
  1035.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1036.         wprintf(L"Profile property not found.\n");
  1037.     else
  1038.         wprintf(L"Profile failed with HR: %x\n", hr);
  1039. }
  1040.  
  1041. hr = pUser->get_RequireUniquePassword(&bBool);
  1042. if (SUCCEEDED(hr))
  1043. {
  1044.     if (bBool)
  1045.       wprintf(L"RequireUniquePassword: TRUE\n");
  1046.     else
  1047.       wprintf(L"RequireUniquePassword: FALSE\n");
  1048. }
  1049. else
  1050. {
  1051.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1052.         wprintf(L"RequireUniquePassword property not found.\n");
  1053.     else
  1054.         wprintf(L"RequireUniquePassword failed with HR: %x\n", hr);
  1055. }
  1056. hr = pUser->get_SeeAlso (&var); 
  1057. if (SUCCEEDED(hr))
  1058. {
  1059.     //SeeAlso is a bstrVal
  1060.     if (var.vt==VT_BSTR)
  1061.       wprintf(L"SeeAlso: %s\n", var.bstrVal);
  1062. }
  1063. else
  1064. {
  1065.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1066.         wprintf(L"SeeAlso property not found.\n");
  1067.     else
  1068.         wprintf(L"SeeAlso failed with HR: %x\n", hr);
  1069. }
  1070. VariantClear(&var);
  1071. hr = pUser->get_TelephoneHome (&var); 
  1072. if (SUCCEEDED(hr))
  1073. {
  1074.     //TelephoneHome is a bstrVal
  1075.     if (var.vt==VT_BSTR)
  1076.       wprintf(L"TelephoneHome: %s\n", var.bstrVal);
  1077. }
  1078. else
  1079. {
  1080.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1081.         wprintf(L"TelephoneHome property not found.\n");
  1082.     else
  1083.         wprintf(L"TelephoneHome failed with HR: %x\n", hr);
  1084. }
  1085. VariantClear(&var);
  1086. hr = pUser->get_TelephoneMobile (&var); 
  1087. if (SUCCEEDED(hr))
  1088. {
  1089.     //TelephoneMobile is a bstrVal
  1090.     if (var.vt==VT_BSTR)
  1091.       wprintf(L"TelephoneMobile: %s\n", var.bstrVal);
  1092. }
  1093. else
  1094. {
  1095.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1096.         wprintf(L"TelephoneMobile property not found.\n");
  1097.     else
  1098.         wprintf(L"TelephoneMobile failed with HR: %x\n", hr);
  1099. }
  1100. VariantClear(&var);
  1101. hr = pUser->get_TelephoneNumber (&var); 
  1102. if (SUCCEEDED(hr))
  1103. {
  1104.     //TelephoneNumber is a bstrVal
  1105.     if (var.vt==VT_BSTR)
  1106.       wprintf(L"TelephoneNumber: %s\n", var.bstrVal);
  1107. }
  1108. else
  1109. {
  1110.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1111.         wprintf(L"TelephoneNumber property not found.\n");
  1112.     else
  1113.         wprintf(L"TelephoneNumber failed with HR: %x\n", hr);
  1114. }
  1115. VariantClear(&var);
  1116. hr = pUser->get_TelephonePager (&var); 
  1117. if (SUCCEEDED(hr))
  1118. {
  1119.     //TelephonePager is a bstrVal
  1120.     if (var.vt==VT_BSTR)
  1121.       wprintf(L"TelephonePager: %s\n", var.bstrVal);
  1122. }
  1123. else
  1124. {
  1125.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1126.         wprintf(L"TelephonePager property not found.\n");
  1127.     else
  1128.         wprintf(L"TelephonePager failed with HR: %x\n", hr);
  1129. }
  1130. VariantClear(&var);
  1131. hr = pUser->get_Title(&bstr); 
  1132. if (SUCCEEDED(hr))
  1133. {
  1134.       wprintf(L"Title: %s\n", bstr);
  1135.       SysFreeString(bstr);
  1136. }
  1137. else
  1138. {
  1139.     if (hr==E_ADS_PROPERTY_NOT_FOUND)
  1140.         wprintf(L"Title property not found.\n");
  1141.     else
  1142.         wprintf(L"Title failed with HR: %x\n", hr);
  1143. }
  1144.  
  1145. return hr;
  1146.  
  1147. }