2012-03-13 2 views

ответ

4

Directory Object Picker

Пример псевдокода:

String SelectUsers(HWND hwndParent, IList<String> usersLdapPaths) 
{ 
    IDsObjectPicker objPicker; 
    IDataObject objData; 
    PDSOP_INIT_INFO pInfo; 
    LPWSTR[0..2] attr; 
    HRESULT hr; 

    /* 
     Returns the LDAP path to the selected user, e.g.: 
     LDAP://stackoverflow.com/CN=Ian Boyd,OU=Stack Users,DC=stackoverflow,DC=com 

     usersLdapPaths can be null. 
     If not null then the user can mutli-select users, 
     and the selected user's LDAP paths will be returned in usersLdapPaths 
     (with the function result containing just the first user) 

     If the user cancels the dialog, then the result (and usersLdapPaths) will be empty 
    */ 
    Result := ''; 

    objPicker = CreateComObject(CLSID_DsObjectPicker) as IDsObjectPicker; 

    System.New(pInfo); 
    try 
    { 
     ZeroMemory(pInfo, SizeOf(DSOP_INIT_INFO)); 
     pInfo.cbSize = SizeOf(DSOP_INIT_INFO); 
     pInfo.pwzTargetComputer = nil; //local computer 

     pInfo.cDsScopeInfos := 1; 
     System.New(pInfo.aDsScopeInfos); 
     try 
     { 
     ZeroMemory(pInfo.aDsScopeInfos, SizeOf(DSOP_SCOPE_INIT_INFO)); 
     pInfo.aDsScopeInfos.cbSize = SizeOf(pInfo.aDsScopeInfos); 
     pInfo.aDsScopeInfos.flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN; //or DSOP_SCOPE_TYPE_TARGET_COMPUTER; 
     pInfo.aDsScopeInfos.flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_LDAP; 
     pInfo.aDsScopeInfos.FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS; 
     pInfo.aDsScopeInfos.FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS; 

     if (UsersLdapPaths != null) 
      pInfo.flOptions = DSOP_FLAG_MULTISELECT; 

     pInfo.cAttributesToFetch := 3; 
     attr[0] = "description"; 
     attr[1] = "name"; 
     attr[2] = "fullName"; 
     pInfo.apwzAttributeNames = @attr; 

     hr = objPicker.Initialize(pInfo); 
     OleCheck(hr); 
     hr = objPicker.InvokeDialog(hwndParent, objData); 
     OleCheck(hr); 

     //the result is false if the user cancelled the dialog 
     if hr = S_FALSE then 
      return ''; 

     return ReadAttributes(objData, UsersLdapPaths); 
     } 
     finally 
     { 
     System.Dispose(pInfo.aDsScopeInfos); 
     }  
    } 
    finally 
    { 
     Dispose(pInfo); 
    } 
} 

И вспомогательной функции (что я не буду беспокоить перекодировать с одного языка псевдокода на другой язык псевдокода):

function TActiveDirectory.ReadAttributes(ADataObject: IDataObject; AValues: TStrings): string; 
var 
    fmtIn: TFormatEtc; 
    stgOut: TStgMedium; 
    pSelList: PDS_SELECTION_LIST; 
    i: Integer; 
    path: string; 
// x: LongWord; 
// pVar: POleVariant; 
    items: PDsSelectionArray; 
begin 
    Result := ''; 

    if Assigned(AValues) then 
     AValues.Clear; 

    if not Assigned(ADataObject) then 
     Exit; 

    stgOut.tymed := TYMED_HGLOBAL; 
    fmtIn.tymed := TYMED_HGLOBAL; 
    fmtIn.cfFormat := RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST); 
    fmtIn.dwAspect := DVASPECT_CONTENT; 
    fmtIn.lindex := -1; 

    if (ADataObject.GetData(fmtIn, stgOut) <> S_OK) then 
     Exit; 

    pSelList := GlobalLock(stgOut.hGlobal); 
    try 
     if pSelList.cItems > 0 then 
      items := PDsSelectionArray(@pSellist.aDsSelection) 
     else 
      items := nil; 

     for i := 0 to pSelList^.cItems-1 do 
     begin 
//   path := TDsSelectionArray(pSellist.aDsSelection)[i].pwzADsPath; 
      path := items[i].pwzADsPath; 

      if Assigned(AValues) then 
       AValues.Add(path); 

      if Result = '' then 
       Result := path; 

{   Result := pSelList^.aDsSelection[i].pwzName+' ('+pSelList.aDsSelection[i].pwzADsPath+')'; 
      AValues.Add(Result); 
      AValues.Add(' Class: '+pSelList^.aDsSelection[i].pwzClass); //"user" 
      AValues.Add(' UPN: '+pSelList^.aDsSelection[i].pwzUPN); //e.g. "[email protected]" 
      pVar := pSelList^.aDsSelection[i].pvarFetchedAttributes; 
      for x := 0 to pSelList^.cFetchedAttributes-1 do 
      begin 
       AValues.Add(' '+VarToStr(pVar^)); 
       if x < pSelList^.cFetchedAttributes then 
        Inc(pVar); 
      end;} 
     end; 
    finally 
     GlobalUnlock(stgOut.hGlobal); 
    end; 
end; 
+0

Доступен как NuGet https://github.com/Tulpep/Active-Directory-Object-Picker –

Смежные вопросы