home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / ADSDK.ZIP / Samples / ActiveDir / OtherWKO / vc / otherwko.cpp next >
Encoding:
C/C++ Source or Header  |  1999-02-16  |  9.6 KB  |  321 lines

  1. // otherwko.cpp : Defines the entry point for the console application.
  2. //
  3. #include <wchar.h>
  4. #include <objbase.h>
  5. #include <activeds.h>
  6.  
  7. //Make sure you define UNICODE
  8. //Need to define version 5 for Windows 2000
  9. #define _WIN32_WINNT 0x0500
  10. //FOR LDAP API...Required for Beta 3 only.
  11. #include <winldap.h>
  12. //Need to link against the following LIBs:
  13. //wldap32.lib
  14.  
  15.  
  16. static GUID MyWKOTestObjectGUID = { /* df447b5e-aa5b-11d2-8d53-00c04f79ab81 */
  17.     0xdf447b5e,
  18.     0xaa5b,
  19.     0x11d2,
  20.     {0x8d, 0x53, 0x00, 0xc0, 0x4f, 0x79, 0xab, 0x81}
  21.   };
  22.  
  23.  
  24.  
  25. HRESULT GUIDtoBindableString (LPGUID pGUID, LPOLESTR *ppGUIDString);
  26.  
  27. HRESULT AddValueToOtherWKOProperty(LPOLESTR szContainerDN, //DN for container whose otherWellKnownObjects property to modify
  28.                                    LPGUID pWKOGUID, //WKO GUID for the well-known object.
  29.                                    LPOLESTR szWKOObjectDN //DN of the well-known object.
  30.                                    );
  31.  
  32.  
  33.  
  34.  
  35. void wmain( int argc, wchar_t *argv[ ])
  36. {
  37.  
  38. //Handle the command line arguments.
  39. LPOLESTR pszBuffer = new OLECHAR[MAX_PATH*2];
  40.     wprintf(L"This program does the following:\n");
  41.     wprintf(L"1. Creates a container (MyWKOTestContainer) in the current Window 2000 domain.\n");
  42.     wprintf(L"2. Creates a container object (MyWKOTestObject) within the container.\n");
  43.     wprintf(L"3. Adds a value for the container object on the otherWellKnownObject property of the container.\n");
  44.     wprintf(L"4. Binds to the container object using WKGUID binding string.\n");
  45.     wprintf(L"5. Renames the container object using WKGUID binding string.\n");
  46.     wprintf(L"6. Binds to the container object using WKGUID binding string.\n");
  47.     wprintf(L"7. Optionally, cleans up by removing the container and leaf object.\n\n");
  48.     
  49.     
  50. //Intialize COM
  51. CoInitialize(NULL);
  52.  
  53. HRESULT hr = S_OK;
  54. IADs *pObject = NULL;
  55. IADsContainer *pDomain = NULL;
  56. IDispatch *pDisp = NULL;
  57. IDispatch *pDispNewContainerObject = NULL;
  58. IADsContainer *pNewContainer = NULL;
  59. IADs *pIADsObject = NULL;
  60. IADs *pNewContainerObject = NULL;
  61.  
  62. LPOLESTR szNewContainerDN = new OLECHAR[MAX_PATH];
  63. LPOLESTR szPath = new OLECHAR[MAX_PATH];
  64. LPOLESTR szRelPath = new OLECHAR[MAX_PATH];
  65.  
  66. //Names of the container and child object.
  67. LPOLESTR szContainer = L"MyWKOTestContainer";
  68. LPOLESTR szNewContainerObject = L"MyWKOTestObject";
  69.  
  70. //Get rootDSE and the domain container's DN.
  71. VARIANT var;
  72. hr = ADsOpenObject(L"LDAP://rootDSE",
  73.                  NULL,
  74.                  NULL,
  75.                  ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  76.                  IID_IADs,
  77.                  (void**)&pObject);
  78. if (FAILED(hr))
  79. {
  80.    wprintf(L"Not Found. Could not bind to the domain.\n");
  81.    if (pObject)
  82.      pObject->Release();
  83.    return;
  84. }
  85.  
  86. hr = pObject->Get(L"defaultNamingContext",&var);
  87. if (SUCCEEDED(hr))
  88. {
  89.     //Build the ADsPath to the domain
  90.     wcscpy(szPath,L"LDAP://");
  91.     wcscat(szPath,var.bstrVal);
  92.     VariantClear(&var);
  93.     //Bind to the current domain.
  94.     hr = ADsOpenObject(szPath,
  95.                      NULL,
  96.                      NULL,
  97.                      ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  98.                      IID_IADsContainer,
  99.                      (void**)&pDomain);
  100.     if (SUCCEEDED(hr))
  101.     {
  102.       //Create the container.
  103.       wcscpy(szRelPath,L"cn=");
  104.       wcscat(szRelPath,szContainer);
  105.       hr = pDomain->Create(L"container", //ldapDisplayName of the class of the object to create.
  106.                              szRelPath, //relative path in RDN=value format
  107.                              &pDisp); //return an IDispatch pointer to the new object.
  108.       if (SUCCEEDED(hr))
  109.       {
  110.         //QI for an IADsContainer interface.
  111.         hr = pDisp->QueryInterface(IID_IADsContainer, (void **)&pNewContainer);
  112.         if (SUCCEEDED(hr))
  113.         {
  114.           //Create the leaf object in the container.
  115.           wcscpy(szRelPath,L"cn=");
  116.           wcscat(szRelPath,szNewContainerObject);
  117.           hr = pNewContainer->Create(L"leaf", //ldapDisplayName of the class of the object to create.
  118.                      szRelPath, //relative path in RDN=value format
  119.                      &pDispNewContainerObject); //return an IDispatch pointer to the new object.
  120.           //QI for an IADs interface.
  121.             hr = pNewContainer->QueryInterface(IID_IADs, (void **)&pIADsObject);
  122.           if (SUCCEEDED(hr))
  123.           {
  124.             //Get the DN of the new container object
  125.             hr = pIADsObject->Get(L"distinguishedName", &var);
  126.             if (SUCCEEDED(hr))
  127.             {
  128.               wcscpy(szNewContainerDN, var.bstrVal);
  129.               VariantClear(&var);
  130.               hr = NewContainerObject->QueryInterface(IID_IADs, (void **)&pNewContainerObject);
  131.               if (SUCCEEDED(hr))
  132.               {
  133.                 //Get the DN for the leaf object
  134.                 hr = pNewContainerObject->Get(L"distinguishedName", &var);
  135.                 if (SUCCEEDED(hr))
  136.                 {
  137.                   //FOR BETA 3 only. Need to use LDAP API to set the otherWellKnownObjects property.
  138.                   hr = AddValueToOtherWKOProperty(szNewContainerDN, //DN for container whose otherWellKnownObjects property to modify
  139.                                    &MyWKOTestObjectGUID, //WKO GUID for the well-known object.
  140.                                    var.bstrVal //DN of the well-known object.
  141.                                    );
  142.                 }
  143.               }
  144.               if (pNewContainerObject)
  145.                 pNewContainerObject->Release();
  146.             }
  147.             VariantClear(&var);
  148.           }
  149.           if (pIADsObject)
  150.             pIADsObject->Release();
  151.           if (pDispNewContainerObject)
  152.             pDispNewContainerObject->Release();
  153.         }
  154.         if (pNewContainer)
  155.           pNewContainer->Release();
  156.       }
  157.       if (pDisp)
  158.           pDisp->Release();
  159.     }
  160.     if (pDomain)
  161.     pDomain->Release();
  162. }
  163. if (pObject)
  164.    pObject->Release();
  165.  
  166. //Uninitalize COM
  167. CoUninitialize();
  168.  
  169.     return;
  170. }
  171.  
  172. HRESULT AddValueToOtherWKOProperty(LPOLESTR szContainerDN, //DN for container whose otherWellKnownObjects property to modify
  173.                                    LPGUID pWKOGUID, //WKO GUID for the well-known object.
  174.                                    LPOLESTR szWKOObjectDN //DN of the well-known object.
  175.                                    )
  176. {
  177. HRESULT hr = E_FAIL;
  178. LPOLESTR szGUIDString = new OLECHAR[MAX_PATH];
  179. LPOLESTR szDNwithOctetString = new OLECHAR[MAX_PATH*2];
  180. DWORD dwReturn;
  181. //Connection handle
  182. LDAP *hConnect = NULL;
  183. //Specify NULL to bind to a DC in the current computer's domain.
  184. //LDAP_PORT is the default port, 389
  185. hConnect  = ldap_open(NULL,  LDAP_PORT);
  186. //Bind using the preferred authentication method on Windows 2000
  187. //and the logged on user's security context.
  188. dwReturn = ldap_bind_s( hConnect, NULL, NULL, LDAP_AUTH_NEGOTIATE );
  189. if (dwReturn==LDAP_SUCCESS)
  190. {
  191.   //Create the WKO value to add.
  192.   GUIDtoBindableString (pWKOGUID, &szGUIDString);
  193.   DWORD dwGUIDSize = sizeof(OLECHAR)*(wcslen(szGUIDString));
  194.   //Build the DNwithoctetstring
  195.   swprintf(szDNwithOctetString, L"B:%d:%s:%s", dwGUIDSize, szGUIDString,szWKOObjectDN); 
  196.   ULONG ulBerSize = sizeof(OLECHAR)*(wcslen(szDNwithOctetString));
  197.   //Build the BerVal
  198.   PCHAR pByteVal = (PCHAR)szDNwithOctetString;
  199.   berval berWKO;
  200.   berWKO.bv_len = ulBerSize;
  201.   berWKO.bv_val = pByteVal;
  202.  
  203.   //Build the mod structure to add the value.
  204.   LDAPMod ldWKO;
  205.   //mod_values takes a NULL terminated array of WCHARs.
  206.   //We're adding a single value.
  207.   OLECHAR *berValues[] = { szDNwithOctetString, NULL };
  208.   //Operation
  209.   ldWKO.mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
  210.   //Attribute
  211.   ldWKO.mod_type = L"otherWellKnownValues";
  212.   //Value to set.
  213.   ldWKO.mod_values = berValues;
  214.   //mods is a NULL terminated array of LDAPMod structures.
  215.   //We're adding a single value.
  216.   LDAPMod *pMod[] = {&ldWKO,NULL};
  217.     
  218.   //Modify the object specified by szContainerDN.
  219.   dwReturn = ldap_modify_s(  hConnect,
  220.                              szContainerDN,
  221.                              pMod);
  222.   if (dwReturn==LDAP_SUCCESS)
  223.       hr = S_OK;
  224. }
  225. return hr;
  226. }
  227.  
  228.  
  229.  
  230.  
  231.  
  232. HRESULT GUIDtoBindableString (LPGUID pGUID, LPOLESTR *ppGUIDString)
  233. {
  234. HRESULT hr = E_FAIL;
  235. if (!pGUID)
  236.   return E_INVALIDARG;
  237. //Build bindable GUID string
  238. LPOLESTR szDSGUID = new WCHAR [128];
  239. DWORD dwLen =  sizeof(*pGUID);
  240. LPBYTE lpByte = (LPBYTE) pGUID;
  241. //Copy a blank string to make it a zero length string.
  242. wcscpy( szDSGUID, L"" );
  243. //Loop through to add each byte to the string.
  244. for( DWORD dwItem = 0L; dwItem < dwLen ; dwItem++ )
  245. {
  246.   //Append to szDSGUID, double-byte, byte at dwItem index.
  247.   swprintf(szDSGUID + wcslen(szDSGUID), L"%02x", lpByte[dwItem]);
  248.   if( wcslen( szDSGUID ) > 128 )
  249.     break;
  250. }
  251. //Allocate memory for string
  252. *ppGUIDString = (OLECHAR *)CoTaskMemAlloc (sizeof(OLECHAR)*(wcslen(szDSGUID)+1));
  253. if (*ppGUIDString)
  254.   wcscpy(*ppGUIDString, szDSGUID);
  255. else
  256.   hr=E_FAIL;
  257. //Caller must free ppGUIDString using CoTaskMemFree.
  258. return hr;
  259. }
  260.  
  261.  
  262. // This function gets the specified well-known object for the current user's domain.
  263.  
  264. HRESULT GetWKOObject(LPOLESTR szBindableWKGUID, //IN. Bindable string GUID of well-known object.
  265.                           IADs **ppObject //OUT. Return a pointer to the specified well-known object.
  266.                           )
  267. {
  268. HRESULT hr = E_FAIL;
  269. //Get rootDSE and the domain container's DN.
  270. IADs *pObject = NULL;
  271. LPOLESTR szPath = new OLECHAR[MAX_PATH];
  272. VARIANT var;
  273. hr = ADsOpenObject(L"LDAP://rootDSE",
  274.                  NULL,
  275.                  NULL,
  276.                  ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  277.                  IID_IADs,
  278.                  (void**)&pObject);
  279.  
  280. //Get current domain DN.
  281. if (SUCCEEDED(hr))
  282. {
  283.     hr = pObject->Get(L"defaultNamingContext",&var);
  284.     if (SUCCEEDED(hr))
  285.     {
  286.         //Build the WKGUID binding string.
  287.         wcscpy(szPath,L"LDAP://");
  288.         wcscat(szPath,L"<WKGUID=");
  289.         wcscat(szPath,szBindableWKGUID);
  290.         wcscat(szPath,L",");
  291.         wcscat(szPath,var.bstrVal);
  292.         wcscat(szPath,L">");
  293.         //Print the binding string.
  294.         //wprintf(L"WKGUID binding string: %s\n",szPath);
  295.         VariantClear(&var);
  296.         //Bind to the well-known object.
  297.         hr = ADsOpenObject(szPath,
  298.                          NULL,
  299.                          NULL,
  300.                          ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  301.                          IID_IADs,
  302.                          (void**)ppObject);
  303.         if (FAILED(hr))
  304.         {
  305.             if (*ppObject)
  306.             {
  307.               (*ppObject)->Release();
  308.               (*ppObject) = NULL;
  309.             }
  310.         }
  311.     }
  312. }
  313. if (pObject)
  314.   pObject->Release();
  315.  
  316. return hr;
  317. }
  318.     
  319.  
  320.  
  321.