Gewusst wie: Bearbeiten die ThumbNailPhoto Attributen ein Benutzerobjekt in Active Directory

SPRACHE AUSWÄHLEN SPRACHE AUSWÄHLEN
Artikel-ID: 292029 - Produkte anzeigen, auf die sich dieser Artikel bezieht
Alles erweitern | Alles schließen

Auf dieser Seite

Zusammenfassung

Dieser Artikel beschreibt das Platzieren von Bilddaten in und Abrufen von Daten aus dem ThumbNailPhoto-Attribut eines Benutzerobjekts in Active Directory mithilfe der IDirectoryObject und IADsUser Schnittstellen.

Weitere Informationen

Die IADsUser::Picture -Eigenschaft ermöglicht Zugriff auf das ThumbNailPhoto-Attribut für ein Klasse-Benutzerobjekt in Active Directory (AD). Das ThumbNailPhoto-Attribut enthält Oktett Typ Zeichenfolgendaten. Das AD interpretiert Oktett Zeichenfolgendaten als ein Array von Bytes. Der Benutzer hat die Freiheit, jede Art von binären Daten in das ThumbNailPhoto-Attribut zu speichern. Der Benutzer ist verantwortlich für sowohl die Bilddaten Rendern und was gewährleistet, dass die entsprechenden Daten in das Attribut gespeichert werden.

Schritte, um den Code in diesem Artikel bereitgestellte verwenden

  1. Erstellen Sie eine neue Win32-Konsolenanwendung in Visual C++. Wählen Sie einen Hello World -Anwendung. Benennen Sie die Anwendung Getpicture .
  2. Ersetzen Sie den gesamten Inhalt der Datei getpicture.cpp durch Code am Ende dieses Artikels.
  3. Fügen Sie die ADSIID.lib und ACTIVEDS.lib Dateien zur Liste Projekte-Verknüpfung hinzu. Die Schritte zum Hinzufügen von diese Dateien zur Liste der verknüpften Bibliotheken des Projekts sind wie folgt:

    1. Wählen Sie im Projekt Einstellungen .
    2. Klicken Sie auf die Registerkarte Verbindung .
    3. Klicken Sie im Text --Objektbibliothek Module hinzufügen, die folgenden zwei Bibliotheken: ADSIID.lib und ACTIVEDS.lib .
    4. Klicken Sie auf OK .
  4. Deaktivieren Sie die vorkompilierte Header -Optionen für das Projekt unter Projekteinstellungen . Die Schritte zum Ändern der vorkompilierten Header-Optionen sind:

    1. Klicken Sie im Menü Projekt auf Einstellungen .
    2. Klicken Sie auf die Registerkarte C/c++ .
    3. In der Kategorie: Dropdownfeld, wählen Sie Vorkompilierte Header .
    4. Wählen Sie vorkompilierte Header nicht verwenden .
    5. Klicken Sie auf OK
  5. Ersetzen Sie die vordefinierten Zeichenfolgen in getpicture.cpp, durch die entsprechenden Werte.

    Hinweis: Ist ein begrenzt die Größe des Bildes auf dem ThumbNailPhoto Attribut gespeichert, und dies wird in Byte auf "Bild" AttributeSchema-Objekts in Active Directory-Schema gespeichert. Die Attribute, die die Größenbeschränkungen zu definieren sind "RangeLower" und "RangeUpper":
    • LDAP_USER_PATH - LDAP ADsPath für ein Benutzerobjekt
    • PICTURE_LOCAL_PATH - lokaler Pfadname für eine Bilddatei (BMP/JPG/GIF)
    • OUTPUT_PATH - lokaler Pfadname, um die Daten aus Active Directory empfangen
  6. Kompilieren Sie und verknüpfen Sie das Projekt.
  7. Führen Sie das Projekt.

Getpicture.cpp-Quellcode

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>

#include <stdio.h>
#include <atlbase.h>
#include <activeds.h>
#include <adsiid.h>
// 
// Predefined strings to use for examples.
// LDAP_USER_PATH must be set to a valid DN of a user object
// PICTURE_LOCAL_PATH must be set to a pathname of a BMP/JPG/GIF or some other picture format file
// OUTPUT_PATH must be set to a filename to receive data from the AD
// 
#define LDAP_USER_PATH L"LDAP://USER_DN"
#define PICTURE_LOCAL_PATH "smile.bmp"
#define OUTPUT_PATH "directory.bmp"
// 
// BytesToVariantArry creates an ADSTYPE_OCTET_STRING variant
// from a given set of bytes
// 
HRESULT BytesToVariantArray(PBYTE pValue, //Pointer to bytes to put in a variant array.
                            ULONG cValueElements,//Size of pValue in bytes.
                            VARIANT *pVariant //Return variant containing octet string (VT_UI1|VT_ARRAY).
                            );
// 
// VariantArrayToBytes -> Assumes a single dimentioned array of bytes passed in the 
// Variant parameter as an ADSTYPE_OCTET_STRING, returns an array of bytes. the bytes parameter must be freed
// using the free() api call.
// 
HRESULT VariantArrayToBytes(
                            VARIANT Variant,
                            LPBYTE *bytes,
                            long *plcb
                            );
// 
// UseIDirectoryObjectSet-> Takes an IADs inteface of a user object, 
// QIs for an IDirectoryObject interface and places the bytes pointed to
// by pBuffer into the thumbNailPhoto attribute.
// 
HRESULT UseIDirectoryObjectSet( IADs *oIADs, 
                            LPBYTE pBuffer, 
                            DWORD cbBuffer );
// 
// UseIDirectoryObjectGet-> Takes an IADs interface of a user object,
// QIs for an IDirectorObject interface and copies the buffer returned 
// from the thumbNailPhoto attribute into the bytes parameter.  The bytes
// parameter is allocated by the function and must be free using 
// the free() API.  The length of the buffer is returned in the plcb parameter.
// 
HRESULT UseIDirectoryObjectGet( IADs *pIADs, LPBYTE *bytes, long *plcb );
// 
// Main Function
// 
int main(int argc, char* argv[])
{

    int hFile;
    CoInitialize( NULL );
    // 
    // Read in the test file
    // and determine how many bytes are in the file
    // using _lseek
    // 
    hFile = _open( PICTURE_LOCAL_PATH, _O_BINARY | _O_RDONLY );
    long retval = _lseek( hFile, 0l, SEEK_END);
    // 
    // Allocate memory and copy the file contents into memory
    // 
    LPBYTE lpbPicture = (LPBYTE)malloc( retval );
    _lseek( hFile, 0l, SEEK_SET);
    long bRead = _read( hFile, lpbPicture, retval);
    // 
    // Put the memory into a safe array in order to place it
    // into the directory
    // 
    VARIANT vPicture;
    HRESULT hr = BytesToVariantArray( lpbPicture, retval, &vPicture);
    // 
    // Retrieve an IADsUser object interface
    // 
    CComPtr <IADsUser> pOusr;
    CComPtr <IADs> pIADs;
    // 
    hr = ADsGetObject(LDAP_USER_PATH, IID_IADsUser, (VOID **)&pOusr);
    // 
    // Example of how to call the UseIDirectoryObjectSet function:
    //hr = UseIDirectoryObjectSet( pIADs, lpbPicture, retval);
    // 
    // Put the variant data into the directory
    // 
    hr = pOusr->put_Picture( vPicture );
    hr = pOusr->SetInfo();  // flush the cache back to the server...
    pOusr.Release();        // Release the interface and rebind....
    // 
    // Bind to the directory again, and read the property
    // 
    hr = ADsGetObject(LDAP_USER_PATH, IID_IADsUser, (VOID **)&pOusr);
    // 
    // To retrieve the buffer using UseIDirectoryObjectGet, here are the declarations
    // and the call:
    // 
    // CComQIPtr<IADs, &IID_IADs> pds( pOusr);
    // LPBYTE bBuffer;
    // long cbBuffer;
    // hr = UseIDirectoryObjectGet( pds, &bBuffer, &cbBuffer);
    // pds.Release();
    // .
    // .
    // .
    // free( bBuffer );
    // 
    VariantClear( &vPicture ); // Release the old variant, **very important** to free the 
                               // the safe array before reusing the variable vPicture
    hr = pOusr->get_Picture( &vPicture );
    pOusr.Release();
    // 
    // Write it back to a file
    // 
    PBYTE lpbADPicture;
    long cb;
    hr = VariantArrayToBytes( vPicture, &lpbADPicture, &cb);
    // 
    // Copy the data back out to the disk file
    // 
    int hFile2 = _open(OUTPUT_PATH, _O_BINARY | _O_CREAT | _O_RDWR);
    retval = _lseek( hFile2, 0l, SEEK_SET );
    retval = _write( hFile2, lpbADPicture, cb );
    // 
    // Time to clean up..
    // 
    _close( hFile2 );
    _close(hFile );
    free( (void *)lpbADPicture );
    free( (void *)lpbPicture );
    VariantClear( &vPicture );
    pOusr.Release();
    CoUninitialize( );
    printf("Done\n");
    
    return 0;
}
// 
// This function can be found in the Platform SDK documention
// It allocates the buffer from heap. The buffer must be freed
// when the caller is finished using it.
// 
HRESULT VariantArrayToBytes(
                            VARIANT Variant,
                            LPBYTE *bytes,
                            long *plcb
                            )
{
    HRESULT hr = E_FAIL;
    SAFEARRAY *pArrayVal = NULL;
    CHAR HUGEP *pArray = NULL;
    
    // 
    //Retrieve the safe array....
    // 
    pArrayVal = Variant.parray;
    
    if (!(pArrayVal == NULL) )
    {
        long cSize = pArrayVal->rgsabound[0].cElements;
        *bytes = (LPBYTE)malloc( cSize );
        if( *bytes == NULL ) return E_FAIL;
        hr = SafeArrayAccessData(pArrayVal, (void HUGEP * FAR *) &pArray );
        if (SUCCEEDED(hr))
        {
            //Copy the bytes to the safe array.
            memcpy( *bytes, pArray, cSize );
            SafeArrayUnaccessData( pArrayVal );
            *plcb = cSize;
            hr = S_OK;
        }
    }
    else
    {
        hr = E_OUTOFMEMORY;
    }
    
    return hr;
}
// 
// This function can be found in the Platform SDK documention
// 
HRESULT BytesToVariantArray(
                            PBYTE pValue, //Pointer to bytes to put in a variant array.
                            ULONG cValueElements,//Size of pValue in bytes.
                            VARIANT *pVariant //Return variant containing octet string (VT_UI1|VT_ARRAY).
                            )
{
    HRESULT hr = E_FAIL;
    SAFEARRAY *pArrayVal = NULL;
    SAFEARRAYBOUND arrayBound;
    CHAR HUGEP *pArray = NULL;
    
    //Set bound for array
    arrayBound.lLbound = 0;
    arrayBound.cElements = cValueElements;
    
    //Create the safe array for the octet string. unsigned char elements;single dimension;aBound size.
    pArrayVal = SafeArrayCreate( VT_UI1, 1, &arrayBound );
    
    if (!(pArrayVal == NULL) )
    {
        hr = SafeArrayAccessData(pArrayVal, (void HUGEP * FAR *) &pArray );
        if (SUCCEEDED(hr))
        {
            //Copy the bytes to the safe array.
            memcpy( pArray, pValue, arrayBound.cElements );
            SafeArrayUnaccessData( pArrayVal );
            //Set type to array of unsigned char
            V_VT(pVariant) = VT_ARRAY | VT_UI1;
            //Assign the safe array to the array member.
            V_ARRAY(pVariant) = pArrayVal;
            hr = S_OK;
        }
        else
        {
            //Clean up if array can't be accessed.
            if ( pArrayVal )
                SafeArrayDestroy( pArrayVal );
        }
    }
    else
    {
        hr = E_OUTOFMEMORY;
    }
    
    return hr;
}
// 
// Take an IADs interface obtain an IDirectoryObject interface, then
// put the buffer pointed to by pBuffer into the thumbNailPhoto attribute
// of the user object
// 
// the IADs interface must have been obtained using the LDAP provider.  WinNT
// provided IADs interfaces do not support the IDirectoryObject interface.
// 
// IDirectoryObject is supported by the LDAP provider.
// 
HRESULT UseIDirectoryObjectSet( IADs *oIADs, LPBYTE pBuffer, DWORD cbBuffer )
{
    CComQIPtr<IDirectoryObject, &IID_IDirectoryObject> poDirObj(oIADs);
    HRESULT    hr;
    DWORD  dwReturn;
    ADSVALUE  snValue;
    ADS_OCTET_STRING octString = { cbBuffer, pBuffer };
    ADS_ATTR_INFO  attrInfo[] = {   {L"thumbNailPhoto",ADS_ATTR_UPDATE,ADSTYPE_OCTET_STRING,&snValue,1} };
    DWORD dwAttrs = sizeof(attrInfo)/sizeof(ADS_ATTR_INFO); 
    
    snValue.dwType=ADSTYPE_OCTET_STRING;
    snValue.OctetString = octString;
    
    hr=poDirObj->SetObjectAttributes(attrInfo, dwAttrs, &dwReturn);
    return hr;
}
// 
// Illustration of how to use the IDirectoryObject to retrieve 
// the thumbNailPhoto attribute
// 
// The method takes an IADs interface pointer obtained from the LDAP
// provider.
// See comments above for information on WinNT and IDirectoryObject.
// 
// The buffer pointer returned in the bytes parameter must be freed using
// the free() api.
// 
HRESULT UseIDirectoryObjectGet( IADs *pIADs, LPBYTE *bytes, long *plcb )
{
    CComQIPtr<IDirectoryObject, &IID_IDirectoryObject> poDirObj( pIADs );
    HRESULT   hr;
    ADS_ATTR_INFO   *pAttrInfo=NULL;
    DWORD   dwReturn;
    LPWSTR   pAttrNames[]={L"thumbNailPhoto" };
    DWORD   dwNumAttr=sizeof(pAttrNames)/sizeof(LPWSTR);
 
    ///////////////////////////////////////// 
    // Get attribute values requested
    // Note: The order is not necessarily the 
    // same as requested using pAttrNames.
    /////////////////////////////////////////// 
    hr = poDirObj->GetObjectAttributes( pAttrNames,
                                        dwNumAttr, 
                                        &pAttrInfo, 
                                        &dwReturn );
 
    if ( SUCCEEDED(hr) )
    {
       for(DWORD idx=0; idx < dwReturn;idx++, pAttrInfo++ )
       {
           if ( _wcsicmp(pAttrInfo->pszAttrName,L"thumbNailPhoto") == 0 )
           {
               if (pAttrInfo->dwADsType == ADSTYPE_OCTET_STRING)
               {
                   *bytes = (LPBYTE)malloc( pAttrInfo->pADsValues->OctetString.dwLength);
                   *plcb = pAttrInfo->pADsValues->OctetString.dwLength;
                   memcpy( *bytes, pAttrInfo->pADsValues->OctetString.lpValue, *plcb);
               }
           }

       }
    }
 
   ///////////////////////////////////////////////////////////// 
   // Use FreeADsMem for all memory obtained from the ADSI call. 
   ///////////////////////////////////////////////////////////// 
   FreeADsMem( pAttrInfo );


    return hr;
}
				

Eigenschaften

Artikel-ID: 292029 - Geändert am: Donnerstag, 1. Juli 2004 - Version: 2.2
Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft Active Directory Service Interfaces 2.5
Keywords: 
kbmt kbdswadsi2003swept kbdswadsi2003swept kbhowto KB292029 KbMtde
Maschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 292029
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.
Disclaimer zu nicht mehr gepflegten KB-Inhalten
Dieser Artikel wurde für Produkte verfasst, für die Microsoft keinen Support mehr anbietet. Der Artikel wird deshalb in der vorliegenden Form bereitgestellt und nicht mehr weiter aktualisiert.

Ihr Feedback an uns

 

Kontaktieren Sie uns, um weitere Hilfe zu erhalten

Kontaktieren Sie uns, um weitere Hilfe zu erhalten
Wenden Sie sich an den Answer Desk, um professionelle Hilfe zu erhalten.