S
Sebastian Sosna
Hello NG !
Iam developing in C# so my cpp knowledge is limited.
Ive downloaded a C++ sample wich is doing some AD Job. U can get it
here :
http://support.microsoft.com/?id=302515
Ive tried to port into C++ (.Net) and ran into errors wich i have no
clue whats this is about. After compiling the linker is throwing those
errors :
//////////////////////////////////////////////////////////////////////////////
CppGetGuids error LNK2020: unresolved token (0600004D)
CppGetGuids.Class1::GetGuids
CppGetGuids error LNK2020: unresolved token (0A000017) atexit
CppGetGuids error LNK2020: unresolved token (0A000023)
??_7type_info@@6B@
CppGetGuids error LNK2020: unresolved token (0A000024)
_CxxThrowException
CppGetGuids error LNK2020: unresolved token (0A00002D) _CrtDbgReport
CppGetGuids error LNK2020: unresolved token (0A000033) free
CppGetGuids error LNK2020: unresolved token (0A000035) memset
CppGetGuids fatal error LNK1120: 7 unresolved externals
//////////////////////////////////////////////////////////////////////////////
What i have done so far:
-Started a Class Library ( .Net ) Project.
-Copied the Code from Main.cpp to CppGetGuids.cpp
-changed from int wmain(.....) to void GetGuids
-declared this Method in CppGetGuids.h
-Added in the Project Settings under Linker/Input Options the
ActiveDS.lib and Adsiid.lib.
-Got rid of (...wchar_t *argv[ ], wchar_t *envp[ ]) instead
ive declared (...String __gc* argv[ ],String __gc* envp[ ])
well now iam here with no idea what the Problem could be.
Hope somebody is willing to help me.
Thanks!
See below the full code so far:
CppGetGuids.cpp:
// This is the main DLL file.
#include "stdafx.h"
#include "CppGetGuids.h"
#include <String.h>
//
// The following code segment illustrates how to enumerate all of the
controlAccessRight objects
// whose appliesTo property matches the SchemaIDGUID of the given
SchemaClass object
//
#define _WIN32_WINNT 0x0500
#define UNICODE
void GetGuids( int argc,String __gc* argv[ ],String __gc* envp[ ] )
{
//
// NO error checking is performed. If a call fails, the code
// will end ungracefully. Do not use this code as an example of
how
// to properly handle COM errors.
//
// The program expects 1 argument, a CN for a schemaClass object.
// if the object name is missing, the code will terminate very
ungracefully.
// a sample command line would like:
//
// code_executable "cn=SchemaClass_Object_Common_Name"
//
// Assuming of course, that this code was compiled into an
executable called
// code_executable.exe
//
// Be sure to include:
// ActiveDS.lib
// Adsiid.lib
// on the Link tab of the project.
//
HRESULT hr = E_FAIL;
//
// Very Important for ADSI interfaces to work proper, must
initialize COM
//
CoInitialize(NULL);
//
// Check for the correct number of arguments
//
if( argc < 2 )
{
// PrintUsage();
// return E_FAIL;
}
//
// Need to bind to the RootDSE to locate the Schema and
Configuration Containers
//
CComPtr<IADs> oRootDSE;
VARIANT vData;
VariantInit(&vData);
CComBSTR bConfigurationNamingContext;
CComBSTR bSchemaNamingContext;
CComBSTR bDefaultNamingContext;
hr = ADsGetObject(
L"LDAP://deff0stv.adtwwz0sm.adtrootdom.net/RootDSE", IID_IADs, (LPVOID
*)&oRootDSE );
if( FAILED( hr ) )
{
printf("Error %d occured opening RootDSE object\nTerminating
Program\n");
// return E_FAIL;
}
hr = oRootDSE->Get(L"defaultNamingContext", &vData);
bDefaultNamingContext.AppendBSTR( vData.bstrVal );
VariantClear(&vData);
hr = oRootDSE->Get(L"SchemaNamingContext", &vData);
bSchemaNamingContext.AppendBSTR( vData.bstrVal);
VariantClear(&vData);
hr = oRootDSE->Get(L"ConfigurationNamingContext", &vData);
bConfigurationNamingContext.AppendBSTR(vData.bstrVal);
VariantClear(&vData );
oRootDSE.Release();
//
// Build the ControlAccessRight object path from the given
Extended Right
// passed as the first argument
//
const wchar_t __pin* p = PtrToStringChars(argv[1]);
CComBSTR bArg = p ;
CComBSTR bSchemaClassPath =
L"LDAP://deff0stv.adtwwz0sm.adtrootdom.net";
bSchemaClassPath.AppendBSTR( bArg );
bSchemaClassPath.Append( L",");
bSchemaClassPath.AppendBSTR( bSchemaNamingContext);
CComPtr <IADs> oSchemaClass;
hr = ADsGetObject( bSchemaClassPath.m_str, IID_IADs, (LPVOID *)
&oSchemaClass);
if( FAILED(hr) )
{
printf("Unable to open SchemaClass object :\n%S\nReceived error
%d\nTerminating Program\n",
bSchemaClassPath.m_str, hr);
//
// CleanUp and exit
//
oRootDSE.Release();
CoUninitialize();
// return hr;
}
//
// Retrieve the SchemaIDGUID of the SchemaClass object.
// The GUID must be converted into the form of an AppliesTo
// attribute GUID.
//
// Convert the GUID to a string, and strip the "{}"'s
//
oSchemaClass->Get(L"SchemaIDGUID", &vData );
oSchemaClass = NULL;
WCHAR wszGUID[40];
WCHAR *pwsz;
SAFEARRAY *pRefGUID;
SafeArrayAccessData( vData.parray, (VOID **)&pRefGUID);
StringFromGUID2( (REFGUID)*pRefGUID, wszGUID, 40 );
for( pwsz = wszGUID; *pwsz; pwsz++)
{
switch (*pwsz)
{
case '{':
break;
case '}':
*(pwsz-1) = (WCHAR)NULL;
break;
default:
*(pwsz-1) = *pwsz;
}
}
CComBSTR bAppliesToGUID = wszGUID;
//
// Time to do a bit of clean up. We are done with
// the safe array, the schemaIDGuid variant (vData) and
// the Schema Class object SO:
//
// Be sure to release the raw GUIDs safe array.
// Clear the variant AND
// Release the SchemaClass object
//
SafeArrayUnaccessData( pRefGUID );
VariantClear(&vData);
oSchemaClass.Release();
//
// Now, bind to the Extended Rights Container and retrieve an
IDirectorySearch
// interface to prepare for the LDAP search....
//
CComBSTR bExtendedRightBindString = L"LDAP://CN=Extended-Rights,";
bExtendedRightBindString.AppendBSTR( bConfigurationNamingContext);
CComPtr <IADs> oIADsExtendedRights;
hr = ADsGetObject( bExtendedRightBindString.m_str, IID_IADs,
(LPVOID *)&oIADsExtendedRights);
CComQIPtr <IDirectorySearch, &IID_IDirectorySearch> oSearch(
oIADsExtendedRights );
oIADsExtendedRights.Release();
//
// Build the LDAP query string that will look something like:
// LDAP Server : bDefaltNamingContext
// LDAP Query String:
(&(objectclass=controlAccessRight)(AppliesTo=MODIFIED_SCHEMAIDGUID))
// LDAP Properties to return: CN
// Search Properties: Paged Search
// Search Scope: Sub Tree ( from the schema container and beyond)
//
//
// Build the query string...
//
CComBSTR bLDAPQueryStr;
bLDAPQueryStr = L"(&(objectclass=controlAccessRight)(AppliesTo=";
bLDAPQueryStr.Append( bAppliesToGUID );
bLDAPQueryStr.Append(L"))");
//
// Setup the Attributes and search preferences
//
// Perform a subtree search
//
ADS_SEARCHPREF_INFO prefInfo[2];
prefInfo[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
prefInfo[0].vValue.dwType = ADSTYPE_INTEGER;
prefInfo[0].vValue.Integer = ADS_SCOPE_SUBTREE;
//
// Set the maximum records returned to 1000 ( maximum for AD )
//
prefInfo [1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE ;
prefInfo [1].vValue.dwType = ADSTYPE_INTEGER;
prefInfo [1].vValue.Integer = 1000;
//
// bind the search preferences with the IDirectorySearch object...
//
hr = oSearch->SetSearchPreference( prefInfo, 2);
//
// Prepare a list of attributes to return in the query...
// in our case, we want the Common Name only...
//
LPWSTR pszAttr[] = { L"cn"};
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount= sizeof(pszAttr)/sizeof(LPWSTR);
//
// Execute the LDAP Query....
//
hr=oSearch->ExecuteSearch(bLDAPQueryStr.m_str, pszAttr, dwCount,
&hSearch );
if (!SUCCEEDED(hr))
{
printf("LDAP Search failed with error %d\nTerminating
program\n", hr );
//
// Clean up
//
oSearch.Release();
// return hr;
}
//
// Now enumerate the result
//
ADS_SEARCH_COLUMN col;
// "0---------1---------2---------3----5"
BOOL bFirstTime = TRUE;
while( oSearch->GetNextRow(hSearch) != S_ADS_NOMORE_ROWS )
{
// Get attributes
//
// CN
//
hr = oSearch->GetColumn( hSearch, pszAttr[0], &col );
if ( SUCCEEDED(hr) )
{
if( bFirstTime )
{
printf("controlAccessRight ( Extended Rights) objects
associated with SchemaClass object: %S\n", argv[1]);
bFirstTime = FALSE;
}
printf("%S\n",(LPWSTR)col.pADsValues->CaseIgnoreString);
oSearch->FreeColumn( &col );
}
}
oSearch->CloseSearchHandle( hSearch );
oSearch.Release();
CoUninitialize();
// return 0;
}
//////////////////////////////////////////////////////////////////////////////
// CppGetGuids.h:
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <stdio.h>
#include <atlbase.h>
#include <objbase.h>
#include <activeds.h>
#include <winnt.h>
#include <sddl.h>
#include < vcclr.h >
#include <stdlib.h>
#pragma once
using namespace System;
namespace CppGetGuids
{
public __gc class Class1
{
// TODO: Add your methods for this class here.
void GetGuids( int argc,String __gc* argv[ ],String __gc* envp[ ] );
};
}
////////////////////////////////////////////////////////////////////////////
stdafx.cpp :
// stdafx.cpp : source file that includes just the standard includes
// CppGetGuids.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
/////////////////////////////////////////////////////////////////////////////
resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by app.rc
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Iam developing in C# so my cpp knowledge is limited.
Ive downloaded a C++ sample wich is doing some AD Job. U can get it
here :
http://support.microsoft.com/?id=302515
Ive tried to port into C++ (.Net) and ran into errors wich i have no
clue whats this is about. After compiling the linker is throwing those
errors :
//////////////////////////////////////////////////////////////////////////////
CppGetGuids error LNK2020: unresolved token (0600004D)
CppGetGuids.Class1::GetGuids
CppGetGuids error LNK2020: unresolved token (0A000017) atexit
CppGetGuids error LNK2020: unresolved token (0A000023)
??_7type_info@@6B@
CppGetGuids error LNK2020: unresolved token (0A000024)
_CxxThrowException
CppGetGuids error LNK2020: unresolved token (0A00002D) _CrtDbgReport
CppGetGuids error LNK2020: unresolved token (0A000033) free
CppGetGuids error LNK2020: unresolved token (0A000035) memset
CppGetGuids fatal error LNK1120: 7 unresolved externals
//////////////////////////////////////////////////////////////////////////////
What i have done so far:
-Started a Class Library ( .Net ) Project.
-Copied the Code from Main.cpp to CppGetGuids.cpp
-changed from int wmain(.....) to void GetGuids
-declared this Method in CppGetGuids.h
-Added in the Project Settings under Linker/Input Options the
ActiveDS.lib and Adsiid.lib.
-Got rid of (...wchar_t *argv[ ], wchar_t *envp[ ]) instead
ive declared (...String __gc* argv[ ],String __gc* envp[ ])
well now iam here with no idea what the Problem could be.
Hope somebody is willing to help me.
Thanks!
See below the full code so far:
CppGetGuids.cpp:
// This is the main DLL file.
#include "stdafx.h"
#include "CppGetGuids.h"
#include <String.h>
//
// The following code segment illustrates how to enumerate all of the
controlAccessRight objects
// whose appliesTo property matches the SchemaIDGUID of the given
SchemaClass object
//
#define _WIN32_WINNT 0x0500
#define UNICODE
void GetGuids( int argc,String __gc* argv[ ],String __gc* envp[ ] )
{
//
// NO error checking is performed. If a call fails, the code
// will end ungracefully. Do not use this code as an example of
how
// to properly handle COM errors.
//
// The program expects 1 argument, a CN for a schemaClass object.
// if the object name is missing, the code will terminate very
ungracefully.
// a sample command line would like:
//
// code_executable "cn=SchemaClass_Object_Common_Name"
//
// Assuming of course, that this code was compiled into an
executable called
// code_executable.exe
//
// Be sure to include:
// ActiveDS.lib
// Adsiid.lib
// on the Link tab of the project.
//
HRESULT hr = E_FAIL;
//
// Very Important for ADSI interfaces to work proper, must
initialize COM
//
CoInitialize(NULL);
//
// Check for the correct number of arguments
//
if( argc < 2 )
{
// PrintUsage();
// return E_FAIL;
}
//
// Need to bind to the RootDSE to locate the Schema and
Configuration Containers
//
CComPtr<IADs> oRootDSE;
VARIANT vData;
VariantInit(&vData);
CComBSTR bConfigurationNamingContext;
CComBSTR bSchemaNamingContext;
CComBSTR bDefaultNamingContext;
hr = ADsGetObject(
L"LDAP://deff0stv.adtwwz0sm.adtrootdom.net/RootDSE", IID_IADs, (LPVOID
*)&oRootDSE );
if( FAILED( hr ) )
{
printf("Error %d occured opening RootDSE object\nTerminating
Program\n");
// return E_FAIL;
}
hr = oRootDSE->Get(L"defaultNamingContext", &vData);
bDefaultNamingContext.AppendBSTR( vData.bstrVal );
VariantClear(&vData);
hr = oRootDSE->Get(L"SchemaNamingContext", &vData);
bSchemaNamingContext.AppendBSTR( vData.bstrVal);
VariantClear(&vData);
hr = oRootDSE->Get(L"ConfigurationNamingContext", &vData);
bConfigurationNamingContext.AppendBSTR(vData.bstrVal);
VariantClear(&vData );
oRootDSE.Release();
//
// Build the ControlAccessRight object path from the given
Extended Right
// passed as the first argument
//
const wchar_t __pin* p = PtrToStringChars(argv[1]);
CComBSTR bArg = p ;
CComBSTR bSchemaClassPath =
L"LDAP://deff0stv.adtwwz0sm.adtrootdom.net";
bSchemaClassPath.AppendBSTR( bArg );
bSchemaClassPath.Append( L",");
bSchemaClassPath.AppendBSTR( bSchemaNamingContext);
CComPtr <IADs> oSchemaClass;
hr = ADsGetObject( bSchemaClassPath.m_str, IID_IADs, (LPVOID *)
&oSchemaClass);
if( FAILED(hr) )
{
printf("Unable to open SchemaClass object :\n%S\nReceived error
%d\nTerminating Program\n",
bSchemaClassPath.m_str, hr);
//
// CleanUp and exit
//
oRootDSE.Release();
CoUninitialize();
// return hr;
}
//
// Retrieve the SchemaIDGUID of the SchemaClass object.
// The GUID must be converted into the form of an AppliesTo
// attribute GUID.
//
// Convert the GUID to a string, and strip the "{}"'s
//
oSchemaClass->Get(L"SchemaIDGUID", &vData );
oSchemaClass = NULL;
WCHAR wszGUID[40];
WCHAR *pwsz;
SAFEARRAY *pRefGUID;
SafeArrayAccessData( vData.parray, (VOID **)&pRefGUID);
StringFromGUID2( (REFGUID)*pRefGUID, wszGUID, 40 );
for( pwsz = wszGUID; *pwsz; pwsz++)
{
switch (*pwsz)
{
case '{':
break;
case '}':
*(pwsz-1) = (WCHAR)NULL;
break;
default:
*(pwsz-1) = *pwsz;
}
}
CComBSTR bAppliesToGUID = wszGUID;
//
// Time to do a bit of clean up. We are done with
// the safe array, the schemaIDGuid variant (vData) and
// the Schema Class object SO:
//
// Be sure to release the raw GUIDs safe array.
// Clear the variant AND
// Release the SchemaClass object
//
SafeArrayUnaccessData( pRefGUID );
VariantClear(&vData);
oSchemaClass.Release();
//
// Now, bind to the Extended Rights Container and retrieve an
IDirectorySearch
// interface to prepare for the LDAP search....
//
CComBSTR bExtendedRightBindString = L"LDAP://CN=Extended-Rights,";
bExtendedRightBindString.AppendBSTR( bConfigurationNamingContext);
CComPtr <IADs> oIADsExtendedRights;
hr = ADsGetObject( bExtendedRightBindString.m_str, IID_IADs,
(LPVOID *)&oIADsExtendedRights);
CComQIPtr <IDirectorySearch, &IID_IDirectorySearch> oSearch(
oIADsExtendedRights );
oIADsExtendedRights.Release();
//
// Build the LDAP query string that will look something like:
// LDAP Server : bDefaltNamingContext
// LDAP Query String:
(&(objectclass=controlAccessRight)(AppliesTo=MODIFIED_SCHEMAIDGUID))
// LDAP Properties to return: CN
// Search Properties: Paged Search
// Search Scope: Sub Tree ( from the schema container and beyond)
//
//
// Build the query string...
//
CComBSTR bLDAPQueryStr;
bLDAPQueryStr = L"(&(objectclass=controlAccessRight)(AppliesTo=";
bLDAPQueryStr.Append( bAppliesToGUID );
bLDAPQueryStr.Append(L"))");
//
// Setup the Attributes and search preferences
//
// Perform a subtree search
//
ADS_SEARCHPREF_INFO prefInfo[2];
prefInfo[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
prefInfo[0].vValue.dwType = ADSTYPE_INTEGER;
prefInfo[0].vValue.Integer = ADS_SCOPE_SUBTREE;
//
// Set the maximum records returned to 1000 ( maximum for AD )
//
prefInfo [1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE ;
prefInfo [1].vValue.dwType = ADSTYPE_INTEGER;
prefInfo [1].vValue.Integer = 1000;
//
// bind the search preferences with the IDirectorySearch object...
//
hr = oSearch->SetSearchPreference( prefInfo, 2);
//
// Prepare a list of attributes to return in the query...
// in our case, we want the Common Name only...
//
LPWSTR pszAttr[] = { L"cn"};
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount= sizeof(pszAttr)/sizeof(LPWSTR);
//
// Execute the LDAP Query....
//
hr=oSearch->ExecuteSearch(bLDAPQueryStr.m_str, pszAttr, dwCount,
&hSearch );
if (!SUCCEEDED(hr))
{
printf("LDAP Search failed with error %d\nTerminating
program\n", hr );
//
// Clean up
//
oSearch.Release();
// return hr;
}
//
// Now enumerate the result
//
ADS_SEARCH_COLUMN col;
// "0---------1---------2---------3----5"
BOOL bFirstTime = TRUE;
while( oSearch->GetNextRow(hSearch) != S_ADS_NOMORE_ROWS )
{
// Get attributes
//
// CN
//
hr = oSearch->GetColumn( hSearch, pszAttr[0], &col );
if ( SUCCEEDED(hr) )
{
if( bFirstTime )
{
printf("controlAccessRight ( Extended Rights) objects
associated with SchemaClass object: %S\n", argv[1]);
bFirstTime = FALSE;
}
printf("%S\n",(LPWSTR)col.pADsValues->CaseIgnoreString);
oSearch->FreeColumn( &col );
}
}
oSearch->CloseSearchHandle( hSearch );
oSearch.Release();
CoUninitialize();
// return 0;
}
//////////////////////////////////////////////////////////////////////////////
// CppGetGuids.h:
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <stdio.h>
#include <atlbase.h>
#include <objbase.h>
#include <activeds.h>
#include <winnt.h>
#include <sddl.h>
#include < vcclr.h >
#include <stdlib.h>
#pragma once
using namespace System;
namespace CppGetGuids
{
public __gc class Class1
{
// TODO: Add your methods for this class here.
void GetGuids( int argc,String __gc* argv[ ],String __gc* envp[ ] );
};
}
////////////////////////////////////////////////////////////////////////////
stdafx.cpp :
// stdafx.cpp : source file that includes just the standard includes
// CppGetGuids.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
/////////////////////////////////////////////////////////////////////////////
resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by app.rc
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif