IGroupPolicyObject

  • Thread starter Thread starter J-P Roberts
  • Start date Start date
J

J-P Roberts

I have to automate the creation of GPOs as part of an unattended build,
and have come to the conclusion that the only way to do this is to use
the IGroupPolicyObject interface.

Unfortunately, my C ability is pretty basic and GPEdit.h is like no
header file I've seen before - I can't get a simple program that
includes it to compile without errors.

Does anyone have any source that does anything at all with the
IGroupPolicyObject interface? Once I've got a start I'll be able to cope
but starting completely from scratch is proving beyond me.

Thanks,

J-P
 
Hope you're familiar with COM, because you'll need to use it quite a bit :)

Here's something to get you started:

#define INITGUID
#include <windows.h>
#include <GPEdit.h>


void main()
{
CoInitialize(NULL);

IGroupPolicyObject* p = NULL;
HRESULT hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL, CLSCTX_ALL,
IID_IGroupPolicyObject, (LPVOID*)&p);
if (SUCCEEDED(hr))
{
DWORD dwSection = GPO_SECTION_USER;
HKEY key = NULL;

p->GetRegistryKey(dwSection, &key);

p->Release();
}

CoUninitialize();

return;
}
 
Hi and thanks,

That's great! I'm ok with COM (although from Delphi and VB, not from C).

I created a simple Win32 Application, pasted in your code and called
main() from the WinMain function. I get the same compilation error that
my attempt gave:

c:\program files\microsoft sdk\include\gpedit.h(617) : error C2061:
syntax error : identifier 'HPROPSHEETPAGE'

in the following line in GPEdit.h:

STDMETHOD(GetPropertySheetPages) (THIS_ HPROPSHEETPAGE **hPages,
UINT *uPageCount) PURE;

My attempt was created using the ATL COM AppWizard and I'm using the
February 2003 Platform SDK. That header file is way above me, so I
haven't got a clue what's going on (I believe GPEdit.h is OK, it's from
an SDK 3 years after the interface was published and would have been
corrected if it contained a bug).

There seems to be a real dearth of information on all of this, just
function prototypes with brief descriptions on MSDN - no code samples or
anything.

Still, there is a bright side - it's got me using newsgroups after 18
years online ;-)
 
Hmm...I'm not understanding what you're trying to do. Are you creating a
COM server by using the ATL COM AppWizard, or are you creating a "normal"
Win32 application? If I understand your requirements, you'll only need a
regular application, and using the ATL wizard is a rather large overkill -
it's designed and best used to create COM servers, not regular applications.

At any rate, I did the same thing as you, just to try it out. Compiles fine
for me. I just pasted the main() function above WinMain(), and added
#include <GPEdit.h> after the #include "..._i.c" line.

The February 2003 Platform SDK should be okay, but you need to ensure that
VC is set to use header files and libraries from that directory (by default,
it uses the headers and libraries from the original install, and installing
the Platform SDK doesn't change the setting).

FWIW, HPROPSHEETPAGE is defined in PrSht.h. But you shouldn't need to
include it explicitly.
 
Hmm...I'm not understanding what you're trying to do.
Oh good, then I'm not alone! More seriously, I only chose the ATL COM
AppWizard for my first attempt 'cause I thought "I'm using COM, I'll
start with one of those". Using a regular Win32 Application (then
choosing "A simple Win32 application") gives the error I mentioned before.

I suspect there's something wrong with my environment - I don't have a
#include "..._i.c" line, for example, only .h files are included:

// =======================================================
// GPO4.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
// #include <GPEdit.h> // - makes no difference if this is here or in
stdafx.h

void main()
{
CoInitialize(NULL);

IGroupPolicyObject* p = NULL;
HRESULT hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL,
CLSCTX_ALL, IID_IGroupPolicyObject, (LPVOID*)&p);
if (SUCCEEDED(hr))
{
DWORD dwSection = GPO_SECTION_USER;
HKEY key = NULL;

p->GetRegistryKey(dwSection, &key);

p->Release();
}

CoUninitialize();

return;
} // main()


int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
main();
return 0;
} // WinMain()
// =======================================================

// =================================================================
// stdafx.cpp : source file that includes just the standard includes
// GPO4.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
// =================================================================

// ==========================================================
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_

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

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows
headers

#include <windows.h>


// TODO: reference additional headers your program requires here
#include <GPEdit.h>

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately
before the previous line.

#endif //
!defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
// ==========================================================

Thanks for the comment about PrSht.h, saved me searching through the 86
files containing it! And you were right, including it made no difference.
 
Yeah, basically, you can use COM from any application type, even the console
application we were playing with earlier. The ATL Wizards are best used to
create COM -=servers=-, not COM -=clients=-, which is what this is.

And my comment about an #include "..._i.c" line was for your ATL Server
project, not the Win32 Application.

At any rate, I was able to duplicate your problem, and here are the steps
you should take:
1. Put "#define INITGUID" between the "lean and mean" and "#include
<windows.h>" lines in stdafx.h
2. In your GPO4.cpp file, after #include stdafx.h, put "#include <PrSht.h>"
and "#include <GPEdit.h>".
3. Do a Build-->Rebuild All
 
Hi,

That's brilliant! Thank you seems inadequate, I really appreciate the time
you've taken on this. I now have something that compiles - and runs! Any further
problems I get will be in code I understand (hopefully, as I'll have written it ;-).

I also paid more attention to your comment about using headers and libraries
from the SDK directory - as well as the Directories option in VC (which had been
changed), there are 2 environment variables that hadn't, INCLUDE and LIB.

As my team is a bit short on C experience I was wondering about wrapping this
interface in a more usable COM object, but that got me wondering why Microsoft
haven't already done so - they're usually pretty good at making their
technologies available. Perhaps it's not a good idea to create something that
script-kiddy virus writers could use to mess with GPOs?

Thanks again,

J-P
 
Erm...well, it -=is=- packaged as a COM object...that's why we use
CoCreateInstance(), CoInitialize(), etc. There's nothing to stop anybody
from executing basically the same code, but from inside Javascript or VB or
any COM-aware language.

Of course, you may be questioning the wisdom of splitting up the GPO
functionality in that particular way and into those particular interfaces.
Fair enough - I can't debate you since I really have no experience in using
GPO, my experience in this case was in COM in C++. Generally Microsoft
provides functionality in the smallest chunks possible - it's up to the
developer to put them together. More code on your end, perhaps, but
flexibility is always appreciated.

At any rate, good luck with your project.
 
Yes, I'm showing my ignorance again. I'm used to COM objects that expose
IDispatch and IUnknown interfaces, and as far as I can see this one doesn't.
Which is why I'm having to use C, I guess. If I wrapped it in a COM object that
did provide an IDispatch interface it could then be used from VBScript, and it
was the wisdom of allowing this that I was questioning. I'll have a better idea
once I find out how much havoc I can wreak with it (I too have very little
experience of GPO - makes you wonder why I got given this project!).

I've no problem at all with the functionality provided, btw. I certainly
wouldn't criticise Microsoft for the way they do things in that respect and try
to model my objects on the way they organise theirs. They are just a little bit
more successful than me, after all ;-)

Thanks again,

J-P
 
Back
Top