MS VC++ 2003 and ADSI IID_IDirectorySearch

  • Thread starter Thread starter Sten Westerback
  • Start date Start date
S

Sten Westerback

Hi

Can anyone help me understand why i get and how to fix the following
MS VC++ 2003 error message
ReadAD.obj : error LNK2001: unresolved external symbol
_IID_IDirectorySearch
while trying to compile...
CoInitialize(NULL);
if (ADsOpenObject(L"WinNT://NOE/Workstations", p_szU, p_szP,
ADS_READONLY_SERVER, IID_IDirectorySearch, (void **) &p_DS)!=S_OK) return
FALSE;

i=sprintf((char *) szQuery, "(Computer=%s)", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1, wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
if (S_OK != (p_DS->ExecuteSearch(wszQuery, (LPWSTR *) L"ADsPath", 1,
&hADS)))
{ CoUninitialize(); return FALSE; }
// ... other lines here
return TRUE;

What puzzles me is that the IID_IDirectorySearch is declared
as extern in two headers both of which i have included.

ADSIid.h
extern const GUID IID_IDirectorySearch;

Iads.h
EXTERN_C const IID IID_IDirectorySearch;

But obviously that variable isn't defined anywhere such as the
ActiveDS.lib that i have included in the project. So where is it?

The .cpp module is part of a native style Win32 GUI application
which also contains .c modules.

Also, is this the proper method to get the fully qualified domain
name ("path") of a computer object in Active Directory or how
would one do that?

Thanks,
Sten
 
Simply insert in one of yours cpp files the following line:

extern const IID IID_IDirectorySearch=__uuidof(IDirectorySearch);
 
Thanks, that was the key information i needed.

Now i would only need to know which LDAP (i noticed that
IDirectorySearch doesn't support "WinNT:") query to use to
find a PC under "Workstations" container/folder and also how
to get the full folder name ("Workstations\Country\Area").
The reference only seems to discuss User related queries so help
would be appreciated.

- Sten

lev said:
Simply insert in one of yours cpp files the following line:

extern const IID IID_IDirectorySearch=__uuidof(IDirectorySearch);


Sten Westerback said:
Hi

Can anyone help me understand why i get and how to fix the following
MS VC++ 2003 error message
ReadAD.obj : error LNK2001: unresolved external symbol
_IID_IDirectorySearch
while trying to compile...
CoInitialize(NULL);
if (ADsOpenObject(L"WinNT://NOE/Workstations", p_szU, p_szP,
ADS_READONLY_SERVER, IID_IDirectorySearch, (void **) &p_DS)!=S_OK) return
FALSE;

i=sprintf((char *) szQuery, "(Computer=%s)", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1, wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
if (S_OK != (p_DS->ExecuteSearch(wszQuery, (LPWSTR *) L"ADsPath", 1,
&hADS)))
{ CoUninitialize(); return FALSE; }
// ... other lines here
return TRUE;

What puzzles me is that the IID_IDirectorySearch is declared
as extern in two headers both of which i have included.

ADSIid.h
extern const GUID IID_IDirectorySearch;

Iads.h
EXTERN_C const IID IID_IDirectorySearch;

But obviously that variable isn't defined anywhere such as the
ActiveDS.lib that i have included in the project. So where is it?

The .cpp module is part of a native style Win32 GUI application
which also contains .c modules.

Also, is this the proper method to get the fully qualified domain
name ("path") of a computer object in Active Directory or how
would one do that?

Thanks,
Sten
 
Do you know the name of the computer? Generally, you are going to write an
LDAP search filter for this that would go something like:

(sAMAccoutName=xxxx)

Where xxxx is the name of the computer you are looking for. sAMAccountName
is unique on the domain for all objects and is indexed, so this will find
the computer in any container and will be fast.

You also need to specify a root for your search which will probably be the
defaultNamingContext of the domain. You can get this dynamically by binding
to RootDSE with IADs and getting the defaultNamingContext attribute.

If you don't know the computer name, tell us what you do know.

I also highly recommend using MS's ldp.exe tool for modeling LDAP searches
against AD. It comes with the server support tools or the ADAM install.

HTH,

Joe K.

Sten Westerback said:
Thanks, that was the key information i needed.

Now i would only need to know which LDAP (i noticed that
IDirectorySearch doesn't support "WinNT:") query to use to
find a PC under "Workstations" container/folder and also how
to get the full folder name ("Workstations\Country\Area").
The reference only seems to discuss User related queries so help
would be appreciated.

- Sten

lev said:
Simply insert in one of yours cpp files the following line:

extern const IID IID_IDirectorySearch=__uuidof(IDirectorySearch);


Sten Westerback said:
Hi

Can anyone help me understand why i get and how to fix the following
MS VC++ 2003 error message
ReadAD.obj : error LNK2001: unresolved external symbol
_IID_IDirectorySearch
while trying to compile...
CoInitialize(NULL);
if (ADsOpenObject(L"WinNT://NOE/Workstations", p_szU, p_szP,
ADS_READONLY_SERVER, IID_IDirectorySearch, (void **) &p_DS)!=S_OK) return
FALSE;

i=sprintf((char *) szQuery, "(Computer=%s)", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1, wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
if (S_OK != (p_DS->ExecuteSearch(wszQuery, (LPWSTR *) L"ADsPath", 1,
&hADS)))
{ CoUninitialize(); return FALSE; }
// ... other lines here
return TRUE;

What puzzles me is that the IID_IDirectorySearch is declared
as extern in two headers both of which i have included.

ADSIid.h
extern const GUID IID_IDirectorySearch;

Iads.h
EXTERN_C const IID IID_IDirectorySearch;

But obviously that variable isn't defined anywhere such as the
ActiveDS.lib that i have included in the project. So where is it?

The .cpp module is part of a native style Win32 GUI application
which also contains .c modules.

Also, is this the proper method to get the fully qualified domain
name ("path") of a computer object in Active Directory or how
would one do that?

Thanks,
Sten
 
Joe Kaplan (MVP - ADSI) said:
Do you know the name of the computer?
Yes, that is the input data i've got.
Generally, you are going to write an LDAP search filter for this that would go something like:

(sAMAccoutName=xxxx)
SAMaccountname? Is that name documented somewhere? And btw, is that case
sensitive
(keyword and value)?
Where xxxx is the name of the computer you are looking for. sAMAccountName
is unique on the domain for all objects and is indexed, so this will find
the computer in any container and will be fast.

You also need to specify a root for your search which will probably be the
defaultNamingContext of the domain. You can get this dynamically by binding
to RootDSE with IADs and getting the defaultNamingContext attribute.

Well i would like to restrict it to the OU "Workstations" and it's
subfolders
as that is where the wanted computers are. What i want is the ADsPAth
of the computer. Here is the code i have tried so far (with error checking
omitted for clearity):

CoInitialize(NULL);
ADsOpenObject(L"LDAP://ourDomController", p_szU, p_szP,
0, IID_IDirectorySearch, (void **) &p_DS);
spi.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
spi.vValue.dwType = ADSTYPE_INTEGER; spi.vValue.Integer = ADS_SCOPE_SUBTREE;
hres=p_DS->SetSearchPreference(&spi, 1);
i=sprintf((char *) szQuery,
"(&(objectClass=computer)(CN=%s)(OU=Workstations)(DC=ourDom)(DC=company)(DC=
com))", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1, wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
hres=p_DS->ExecuteSearch(wszQuery, NULL, -1, &hADS);
hres=p_DS->GetFirstRow(hADS);
if (hres==S_ADS_NOMORE_ROWS) MessageBox(NULL, "Same error as always ;)", "No
result", 0);

I now also tried with
"(&(objectClass=computer)(SAMAccountName=%s)(OU=Workstations)"
"(DC=ourDom)(DC=company)(DC=com))" but that also fails with "no rows".
Only working version was with "(objectClass=computer)" as the filter but i
have to restrict it. ;)

BTW, what's the purpose of the & in the query that all examples have? And
does the location
fof the SAMAccountName (or CN) matter?
I also highly recommend using MS's ldp.exe tool for modeling LDAP searches
against AD. It comes with the server support tools or the ADAM install.
Hmm.. i bumped into references to ldp and Adap recently and
i'll try to see if i can find it somewhere.. even if i don't care much about
the server side...

Thanks for the information.

- Sten
Sten Westerback said:
Thanks, that was the key information i needed.

Now i would only need to know which LDAP (i noticed that
IDirectorySearch doesn't support "WinNT:") query to use to
find a PC under "Workstations" container/folder and also how
to get the full folder name ("Workstations\Country\Area").
The reference only seems to discuss User related queries so help
would be appreciated.

- Sten

lev said:
Simply insert in one of yours cpp files the following line:

extern const IID IID_IDirectorySearch=__uuidof(IDirectorySearch);


Hi

Can anyone help me understand why i get and how to fix the following
MS VC++ 2003 error message
ReadAD.obj : error LNK2001: unresolved external symbol
_IID_IDirectorySearch
while trying to compile...
CoInitialize(NULL);
if (ADsOpenObject(L"WinNT://NOE/Workstations", p_szU, p_szP,
ADS_READONLY_SERVER, IID_IDirectorySearch, (void **) &p_DS)!=S_OK)
return
FALSE;

i=sprintf((char *) szQuery, "(Computer=%s)", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1,
wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
if (S_OK != (p_DS->ExecuteSearch(wszQuery, (LPWSTR *) L"ADsPath", 1,
&hADS)))
{ CoUninitialize(); return FALSE; }
// ... other lines here
return TRUE;

What puzzles me is that the IID_IDirectorySearch is declared
as extern in two headers both of which i have included.

ADSIid.h
extern const GUID IID_IDirectorySearch;

Iads.h
EXTERN_C const IID IID_IDirectorySearch;

But obviously that variable isn't defined anywhere such as the
ActiveDS.lib that i have included in the project. So where is it?

The .cpp module is part of a native style Win32 GUI application
which also contains .c modules.

Also, is this the proper method to get the fully qualified domain
name ("path") of a computer object in Active Directory or how
would one do that?

Thanks,
Sten
 
Ah,

You want to set the root of your search to the OU you want (not sure of the
C++ syntax, but look around for the search root parameter). It may have to
do with the IADs object you use to bootstrap the IDirectorySearch.

and set your filter to just find computers in that OU (and children if you
do a subtree search)

filter = "(&(objectCategory=user)(objectClass=computer))"

Filters on DN's only work if the DN is an exact match.

HTH,

Joe K.

Sten Westerback said:
Joe Kaplan (MVP - ADSI) said:
Do you know the name of the computer?
Yes, that is the input data i've got.
Generally, you are going to write an LDAP search filter for this that would go something like:

(sAMAccoutName=xxxx)
SAMaccountname? Is that name documented somewhere? And btw, is that case
sensitive
(keyword and value)?
Where xxxx is the name of the computer you are looking for. sAMAccountName
is unique on the domain for all objects and is indexed, so this will find
the computer in any container and will be fast.

You also need to specify a root for your search which will probably be the
defaultNamingContext of the domain. You can get this dynamically by binding
to RootDSE with IADs and getting the defaultNamingContext attribute.

Well i would like to restrict it to the OU "Workstations" and it's
subfolders
as that is where the wanted computers are. What i want is the ADsPAth
of the computer. Here is the code i have tried so far (with error checking
omitted for clearity):

CoInitialize(NULL);
ADsOpenObject(L"LDAP://ourDomController", p_szU, p_szP,
0, IID_IDirectorySearch, (void **) &p_DS);
spi.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
spi.vValue.dwType = ADSTYPE_INTEGER; spi.vValue.Integer = ADS_SCOPE_SUBTREE;
hres=p_DS->SetSearchPreference(&spi, 1);
i=sprintf((char *) szQuery,
"(&(objectClass=computer)(CN=%s)(OU=Workstations)(DC=ourDom)(DC=company)(DC=
com))", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1, wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
hres=p_DS->ExecuteSearch(wszQuery, NULL, -1, &hADS);
hres=p_DS->GetFirstRow(hADS);
if (hres==S_ADS_NOMORE_ROWS) MessageBox(NULL, "Same error as always ;)", "No
result", 0);

I now also tried with
"(&(objectClass=computer)(SAMAccountName=%s)(OU=Workstations)"
"(DC=ourDom)(DC=company)(DC=com))" but that also fails with "no rows".
Only working version was with "(objectClass=computer)" as the filter but i
have to restrict it. ;)

BTW, what's the purpose of the & in the query that all examples have? And
does the location
fof the SAMAccountName (or CN) matter?
I also highly recommend using MS's ldp.exe tool for modeling LDAP searches
against AD. It comes with the server support tools or the ADAM install.
Hmm.. i bumped into references to ldp and Adap recently and
i'll try to see if i can find it somewhere.. even if i don't care much about
the server side...

Thanks for the information.

- Sten
Sten Westerback said:
Thanks, that was the key information i needed.

Now i would only need to know which LDAP (i noticed that
IDirectorySearch doesn't support "WinNT:") query to use to
find a PC under "Workstations" container/folder and also how
to get the full folder name ("Workstations\Country\Area").
The reference only seems to discuss User related queries so help
would be appreciated.

- Sten

Simply insert in one of yours cpp files the following line:

extern const IID IID_IDirectorySearch=__uuidof(IDirectorySearch);


Hi

Can anyone help me understand why i get and how to fix the following
MS VC++ 2003 error message
ReadAD.obj : error LNK2001: unresolved external symbol
_IID_IDirectorySearch
while trying to compile...
CoInitialize(NULL);
if (ADsOpenObject(L"WinNT://NOE/Workstations", p_szU, p_szP,
ADS_READONLY_SERVER, IID_IDirectorySearch, (void **) &p_DS)!=S_OK)
return
FALSE;

i=sprintf((char *) szQuery, "(Computer=%s)", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1,
wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
if (S_OK != (p_DS->ExecuteSearch(wszQuery, (LPWSTR *) L"ADsPath", 1,
&hADS)))
{ CoUninitialize(); return FALSE; }
// ... other lines here
return TRUE;

What puzzles me is that the IID_IDirectorySearch is declared
as extern in two headers both of which i have included.

ADSIid.h
extern const GUID IID_IDirectorySearch;

Iads.h
EXTERN_C const IID IID_IDirectorySearch;

But obviously that variable isn't defined anywhere such as the
ActiveDS.lib that i have included in the project. So where is it?

The .cpp module is part of a native style Win32 GUI application
which also contains .c modules.

Also, is this the proper method to get the fully qualified domain
name ("path") of a computer object in Active Directory or how
would one do that?

Thanks,
Sten
 
Thanks.

Now i looked back at the description of ADsOpenObject() and
tried again.. and it works!
Here are the parameters that works:

hres=ADsOpenObject(L"LDAP://OU=Workstations,DC=ourdomain,DC=dom,DC=com",
p_szU, p_szP,
0, IID_IDirectorySearch, (void **) &p_DS);

... and the filter is now..
i=sprintf((char *) szQuery, "(&(objectClass=Computer)(CN=%s))", p_szPCname);

- Sten

Joe Kaplan (MVP - ADSI) said:
Ah,

You want to set the root of your search to the OU you want (not sure of the
C++ syntax, but look around for the search root parameter). It may have to
do with the IADs object you use to bootstrap the IDirectorySearch.

and set your filter to just find computers in that OU (and children if you
do a subtree search)

filter = "(&(objectCategory=user)(objectClass=computer))"

Filters on DN's only work if the DN is an exact match.

HTH,

Joe K.

Sten Westerback said:
in message news:[email protected]...
Yes, that is the input data i've got.

SAMaccountname? Is that name documented somewhere? And btw, is that case
sensitive
(keyword and value)?


Well i would like to restrict it to the OU "Workstations" and it's
subfolders
as that is where the wanted computers are. What i want is the ADsPAth
of the computer. Here is the code i have tried so far (with error checking
omitted for clearity):

CoInitialize(NULL);
ADsOpenObject(L"LDAP://ourDomController", p_szU, p_szP,
0, IID_IDirectorySearch, (void **) &p_DS);
spi.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
spi.vValue.dwType = ADSTYPE_INTEGER; spi.vValue.Integer = ADS_SCOPE_SUBTREE;
hres=p_DS->SetSearchPreference(&spi, 1);
i=sprintf((char *) szQuery,
"(&(objectClass=computer)(CN=%s)(OU=Workstations)(DC=ourDom)(DC=company)(DC=
com))", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1, wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
hres=p_DS->ExecuteSearch(wszQuery, NULL, -1, &hADS);
hres=p_DS->GetFirstRow(hADS);
if (hres==S_ADS_NOMORE_ROWS) MessageBox(NULL, "Same error as always ;)", "No
result", 0);

I now also tried with
"(&(objectClass=computer)(SAMAccountName=%s)(OU=Workstations)"
"(DC=ourDom)(DC=company)(DC=com))" but that also fails with "no rows".
Only working version was with "(objectClass=computer)" as the filter but i
have to restrict it. ;)

BTW, what's the purpose of the & in the query that all examples have? And
does the location
fof the SAMAccountName (or CN) matter?
I also highly recommend using MS's ldp.exe tool for modeling LDAP searches
against AD. It comes with the server support tools or the ADAM
install.
Hmm.. i bumped into references to ldp and Adap recently and
i'll try to see if i can find it somewhere.. even if i don't care much about
the server side...

Thanks for the information.

- Sten
Thanks, that was the key information i needed.

Now i would only need to know which LDAP (i noticed that
IDirectorySearch doesn't support "WinNT:") query to use to
find a PC under "Workstations" container/folder and also how
to get the full folder name ("Workstations\Country\Area").
The reference only seems to discuss User related queries so help
would be appreciated.

- Sten

Simply insert in one of yours cpp files the following line:

extern const IID IID_IDirectorySearch=__uuidof(IDirectorySearch);


Hi

Can anyone help me understand why i get and how to fix the following
MS VC++ 2003 error message
ReadAD.obj : error LNK2001: unresolved external symbol
_IID_IDirectorySearch
while trying to compile...
CoInitialize(NULL);
if (ADsOpenObject(L"WinNT://NOE/Workstations", p_szU, p_szP,
ADS_READONLY_SERVER, IID_IDirectorySearch, (void **) &p_DS)!=S_OK)
return
FALSE;

i=sprintf((char *) szQuery, "(Computer=%s)", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1,
wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
if (S_OK != (p_DS->ExecuteSearch(wszQuery, (LPWSTR *)
L"ADsPath",
 
Great. Glad you got it working.

Joe K.

Sten Westerback said:
Thanks.

Now i looked back at the description of ADsOpenObject() and
tried again.. and it works!
Here are the parameters that works:

hres=ADsOpenObject(L"LDAP://OU=Workstations,DC=ourdomain,DC=dom,DC=com",
p_szU, p_szP,
0, IID_IDirectorySearch, (void **) &p_DS);

.. and the filter is now..
i=sprintf((char *) szQuery, "(&(objectClass=Computer)(CN=%s))", p_szPCname);

- Sten

Joe Kaplan (MVP - ADSI) said:
Ah,

You want to set the root of your search to the OU you want (not sure of the
C++ syntax, but look around for the search root parameter). It may have to
do with the IADs object you use to bootstrap the IDirectorySearch.

and set your filter to just find computers in that OU (and children if you
do a subtree search)

filter = "(&(objectCategory=user)(objectClass=computer))"

Filters on DN's only work if the DN is an exact match.

HTH,

Joe K.

be
the
"(&(objectClass=computer)(CN=%s)(OU=Workstations)(DC=ourDom)(DC=company)(DC=
com))", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1, wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
hres=p_DS->ExecuteSearch(wszQuery, NULL, -1, &hADS);
hres=p_DS->GetFirstRow(hADS);
if (hres==S_ADS_NOMORE_ROWS) MessageBox(NULL, "Same error as always
;)",
"No
result", 0);

I now also tried with
"(&(objectClass=computer)(SAMAccountName=%s)(OU=Workstations)"
"(DC=ourDom)(DC=company)(DC=com))" but that also fails with "no rows".
Only working version was with "(objectClass=computer)" as the filter
but
i
have to restrict it. ;)

BTW, what's the purpose of the & in the query that all examples have? And
does the location
fof the SAMAccountName (or CN) matter?

I also highly recommend using MS's ldp.exe tool for modeling LDAP searches
against AD. It comes with the server support tools or the ADAM install.
Hmm.. i bumped into references to ldp and Adap recently and
i'll try to see if i can find it somewhere.. even if i don't care much about
the server side...

Thanks for the information.

- Sten


Thanks, that was the key information i needed.

Now i would only need to know which LDAP (i noticed that
IDirectorySearch doesn't support "WinNT:") query to use to
find a PC under "Workstations" container/folder and also how
to get the full folder name ("Workstations\Country\Area").
The reference only seems to discuss User related queries so help
would be appreciated.

- Sten

Simply insert in one of yours cpp files the following line:

extern const IID IID_IDirectorySearch=__uuidof(IDirectorySearch);


Hi

Can anyone help me understand why i get and how to fix the following
MS VC++ 2003 error message
ReadAD.obj : error LNK2001: unresolved external symbol
_IID_IDirectorySearch
while trying to compile...
CoInitialize(NULL);
if (ADsOpenObject(L"WinNT://NOE/Workstations", p_szU, p_szP,
ADS_READONLY_SERVER, IID_IDirectorySearch, (void **) &p_DS)!=S_OK)
return
FALSE;

i=sprintf((char *) szQuery, "(Computer=%s)", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR) szQuery, i+1,
wszQuery,
sizeof(wszQuery)/sizeof(wszQuery[0]));
if (S_OK != (p_DS->ExecuteSearch(wszQuery, (LPWSTR *)
L"ADsPath",
1,
&hADS)))
{ CoUninitialize(); return FALSE; }
// ... other lines here
return TRUE;

What puzzles me is that the IID_IDirectorySearch is declared
as extern in two headers both of which i have included.

ADSIid.h
extern const GUID IID_IDirectorySearch;

Iads.h
EXTERN_C const IID IID_IDirectorySearch;

But obviously that variable isn't defined anywhere such as the
ActiveDS.lib that i have included in the project. So where is it?

The .cpp module is part of a native style Win32 GUI application
which also contains .c modules.

Also, is this the proper method to get the fully qualified domain
name ("path") of a computer object in Active Directory or how
would one do that?

Thanks,
Sten
 
Back
Top