Solved

c++  Can't resolve call to AdsOpenObject

Posted on 2015-01-12
19
242 Views
Last Modified: 2015-02-11
I am including for following in a C++ project

#include <activeds.h>
#include <adsiid.h>
#include <sddl.h>

and I've added reference to ActiveDs.lib

but I can't resolve a call to ADsOpenObject

    //  Initialize COM.
    CoInitialize(NULL);
    HRESULT hr = S_OK;
    //  Get rootDSE and the current user domain container distinguished name.
    IADs *pObject = NULL;
    IDirectorySearch *pContainerToSearch = NULL;
    LPOLESTR szPath = new OLECHAR[MAX_PATH];
    VARIANT var;
    hr = ADsOpenObject(L"LDAP://rootDSE",
                       NULL,
                       NULL,
                       ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
                       IID_IADs,
                       (void**)&pObject);

I am not very familier with COM objects

Any ideas?

Thanks
0
Comment
Question by:PeterC_UK
  • 10
  • 9
19 Comments
 
LVL 32

Expert Comment

by:sarabande
ID: 40546081
you did not supply neither username nor password. because of that the call cannot succeed.

here a sample of msdn:

IADs *pObject;
LPWSTR szUsername = NULL;
LPWSTR szPassword = NULL
HRESULT hr;

// Insert code to securely retrieve the user name and password.

hr = ADsOpenObject(L"LDAP://CN=Jeff,DC=Fabrikam,DC=com",
                   "jeffsmith",
                   "etercespot",
                   ADS_SECURE_AUTHENTICATION, 
                   IID_IADs,
                   (void**) &pObject);

Open in new window


see the following link how the credentials for more information:

http://msdn.microsoft.com/en-us/library/aa772238(v=vs.85).aspx

Sara
0
 

Author Comment

by:PeterC_UK
ID: 40546086
It's not a question of the call not succeeding!  I can't compile the code.  Linker can't find ADsOpenObject although I have added the reference and the include files.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 40546139
can't compile the code.  Linker can't find ADsOpenObject
can you post the compiler or linker error you got? compiler errors have code Cxxxx and linker error Lxxxx

if it is a compiler error please post the statement it points to.

Sara
0
 
LVL 32

Expert Comment

by:sarabande
ID: 40546299
the ActiveDs.lib should be added to Configuration Properties\Linker\Input\Additional Dependencies for both Debug and Release configuration.

you also have to check where the ActiveDs.lib resides on your disk (it is not necessarily part of the visual c++ setup but also could be provided by a Microsoft SDK kit). then check whether the folder was defined in
Configuration Properties\VC++ Directories\Library Directories.

if the ActiveDs.lib cannot be found at all, you have to download a Microsoft SDK from MSDN which fits to your Visual C++ version.

Sara
0
 

Author Comment

by:PeterC_UK
ID: 40557355
ActiveDs.lib is added as stated in the Original question.  I have just tried a 32 bit compile and this works.  However I need it for 64 bit.  I have tried various other suggestions i.e. added references to ActiveDs.tlb and ActiveDs.dll from the sysWOW64 folder as there isn't an ActiveDs.lib file there.  Any ideas?
0
 
LVL 32

Expert Comment

by:sarabande
ID: 40557877
I have tried various other suggestions i.e. added references to ActiveDs.tlb and ActiveDs.dll from the sysWOW64 folder as there isn't an ActiveDs.lib file there.  
references are nothing the linker will care for. the syswow64 folder contains 32-bit libraries. on a 64-bit system it is still the system32 folder which contains 64-bit libraries.

hence you need to call into activeds.dll from system32 by importing activeds.tlb also from system32.

Sara
0
 

Author Comment

by:PeterC_UK
ID: 40558014
My original attempts referenced ActiveDs.lib from system32.  This compiles for 32 bit but not 64 bit!
0
 
LVL 32

Expert Comment

by:sarabande
ID: 40558044
what do you mean by "referenced"? did you actively import the activeds.tlb from system32 folder?

another thing is that you need to use the 64-bit compiler because the 32-bit compiler only would "see" the libraries from syswow64 folder. note, both the 32-bit and the 64-bit compiler can be used to build 64-bit projects but only the 64-bit compiler is able to access 64-bit components.

Sara
0
 

Author Comment

by:PeterC_UK
ID: 40558352
Configuration Properties\Linker\Input\Additional Dependencies Added ActiveDs.lib from System 32.  This is added in Debug and Release

This is a large stable project which is separately compiled for 32 and 64 bit systems.  I have to add a call to Active Directory and as far as I can see I have tried every possible combination of references to ActiveDs.lib but the 64 bit compile always fails to resolve the call to ADsOpenObject.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 32

Accepted Solution

by:
sarabande earned 500 total points
ID: 40559194
I am working on a windows 7 64-bit system. the system32 folder only contains ActiveDs.dll and ActiveDs.tlb but no ActiveDs.lib. I would assume that the ActiveDs.lib from system32 was copied to system32 but actually is a 32-bit library. you could check this by creating a little test project which only calls ADsOpenObject:

int main()
{
     return (int)ADsOpenObject("", NULL, NULL, 0, IID_IADs, (void**)(NULL));
}

Open in new window


and uses the #import "ActiveDs.tlb" rather than linking against  ActiveDs.lib.

Sara
0
 

Author Comment

by:PeterC_UK
ID: 40560589
Hi Sara,  Please  can I have a copy of your project, because I can't get the #import function to work.  I am using #import "ActiveDs.tlb".  I have tried to include the full path name but I get the same error,' Cannot open source file "C:/......./ActiveDs.tlh" ' What and where is ActiveDs.tlh?  I have also tried #import "ActiveDs.dll" with the same result.

Thanks
Peter
0
 

Author Comment

by:PeterC_UK
ID: 40560676
Hi Sara - Update.  I had removed #include <ActiveDs.h>.  I have re-instated it and I now just get:
Error C2011: '_LARGE_INTEGER' 'Union' type redefinition in file ActiveDs.tlh
I have tried #undef _LARGE_DEFINITION before the #import "ActiveDs.tlb" line but it makes no difference.
Peter
0
 

Author Comment

by:PeterC_UK
ID: 40560678
I meant #undef _LARGE_INTEGER not _LARGE_DEFINEITION :-)
0
 
LVL 32

Expert Comment

by:sarabande
ID: 40560957
I have tried #undef _LARGE_DEFINITION before the #import "ActiveDs.tlb" line but it makes no difference.
you may check both definitions of _LARGE_INTEGER. to prevent from duplicate issue one of these definitions (most likely the one in activeds.tlh) is within an #ifndef xxxx or #if not defined (xxxx) block. the way out is to define the xxxx as preprocessor macro in configuration properties - c++ - preprocessor for both debug and release configuration.

if you don't find the 'xxxx' you may post the contents of the activeds.tlh around the definition of _LARGE_INTEGER.

Sara
0
 
LVL 32

Expert Comment

by:sarabande
ID: 40560965
What and where is ActiveDs.tlh?

the .tlh file was extracted out from activeds.tlb by the #import statement. normally it was put into debug or release folder below the project folder. you either may add this folder to the include directories of the configuration or you copy/move the .tlh file to a source or include folder. the copying could be done in a build step or once manually. if doing the latter you must repeat the operation after any update.

Sara
0
 

Author Comment

by:PeterC_UK
ID: 40561375
Sara - If I edit ActiveDs.tlh it gets replaced when I compile.
The other definition is in WinNT.h - if I remove this I get multiple errors from other windows include files.

I'm not sure I understand your comment

"if you don't find the 'xxxx' you may post the contents of the activeds.tlh around the definition of _LARGE_INTEGER."

Peter
0
 

Author Comment

by:PeterC_UK
ID: 40601043
Eventually gave up trying to get AD calls to work from 64 bit c++ program.  Wrote a separate .NET Application to do the AD stuff and used named pipes to communicate from the main application.  This all works but it would have been good to be able to do it directly from 64 bit c++
0
 
LVL 32

Expert Comment

by:sarabande
ID: 40602560
If I edit ActiveDs.tlh it gets replaced when I compile.
that could be avoided by commenting the #import statement and including the .tlh file instead.

"if you don't find the 'xxxx' you may post the contents of the activeds.tlh around the definition of _LARGE_INTEGER."
if the preprocessor complains about a duplicate definition of a type, you can check both header files where the definitions were located. at least one of the definitions was conditioned by one or more macros such that a source which includes both the header files can omit one of the definitions by setting the conditional macro prior to including the headers.

//header1.h
....
#define LARGE_INTEGER _int64

//header2.h
....
#ifndef BASE_TYPES_INCLUDED
#define LARGE_INTEGER long long
....
#endif

//yoursource.cpp
....
#include <header1.h>
#ifndef BASE_TYPES_INCLUDED
#define BASE_TYPES_INCLUDED
#define UNDEF_BASETYPES_INCLUDED
#endif

#include <header2.h>  // now it should compile

#ifdef  UNDEF_BASETYPES_INCLUDED
#undef BASE_TYPES_INCLUDED
#endif

Open in new window


of course the above is only a simplified sample. though real scenarios of the issue are more complex they mostly have a more comfortable solution as in my sample. often the problem could be solved by simply changing the order of the include statements or by removing include statements not needed. for example if the header1.h is one of your files you simple can remove the definition of LARGE_INTEGER and include the header2.h instead in header1.h and the issue is solved.

you should see that there are millions of developers which are using standard headers and only a few have got the issue. because of that it is a good chance to get the issue solved if you analyze the case.

Sara
0
 

Author Closing Comment

by:PeterC_UK
ID: 40602628
Thanks Sara

I will get back to the C++ solution when I can.  The .NET for AD is working OK for now but is not elegant. :-)
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This collection of functions covers all the normal rounding methods of just about any numeric value.
Viewers will learn the different options available in the Backstage view in Excel 2013.
The viewer will learn how to create a normally distributed random variable in Excel, use a normal distribution to simulate the return on an investment over a period of years, Create a Monte Carlo simulation using a normal random variable, and calcul…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now