You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
666 lines
21 KiB
666 lines
21 KiB
// AUsrExe.cpp : Implementation of WinMain
|
|
#include "stdafx.h"
|
|
#include "resource.h"
|
|
|
|
// DLL\Inc
|
|
#include <wizchain.h>
|
|
#include <propuid.h>
|
|
#include <AUsrUtil.h>
|
|
#include <singleinst.h>
|
|
#include <cmdline.h>
|
|
#include <proputil.h>
|
|
#include <AU_Accnt.h> // Core User component (account, mailbox, group)
|
|
#include <P3admin.h>
|
|
#include <checkuser.h>
|
|
|
|
#include <lmaccess.h>
|
|
#include <lmapibuf.h>
|
|
#include <lmserver.h>
|
|
#include <lmshare.h>
|
|
#include <iads.h>
|
|
#include <adshlp.h>
|
|
#include <adserr.h>
|
|
#include <dsgetdc.h>
|
|
|
|
#define ERROR_CREATION 0x01
|
|
#define ERROR_PROPERTIES 0x02
|
|
#define ERROR_MAILBOX 0x04
|
|
#define ERROR_MEMBERSHIPS 0x08
|
|
#define ERROR_PASSWORD 0x10
|
|
#define ERROR_DUPE 0x20
|
|
#define ERROR_GROUP 0x40
|
|
|
|
// Defines for account flags.
|
|
#define PASSWD_NOCHANGE 0x01
|
|
#define PASSWD_CANCHANGE 0x02
|
|
#define PASSWD_MUSTCHANGE 0x04
|
|
#define ACCOUNT_DISABLED 0x10
|
|
|
|
#define MAX_GUID_STRING_LENGTH 64
|
|
#define SINGLE_INST_NAME _T("{19C2E967-1198-4e4c-A55F-515C5F13B73F}")
|
|
|
|
HINSTANCE g_hInstance;
|
|
DWORD g_dwAutoCompMode;
|
|
TCHAR g_szUserOU[MAX_PATH*2] = {0};
|
|
|
|
// Prototypes
|
|
DWORD FixParams( void );
|
|
|
|
// ****************************************************************************
|
|
inline void MakeLDAPUpper( TCHAR* szIn )
|
|
{
|
|
if( !szIn ) return;
|
|
|
|
if( _tcsnicmp( szIn, _T("ldap://"), 7 ) == 0 )
|
|
{
|
|
szIn[0] = _T('L');
|
|
szIn[1] = _T('D');
|
|
szIn[2] = _T('A');
|
|
szIn[3] = _T('P');
|
|
}
|
|
}
|
|
|
|
class CHBmp
|
|
{
|
|
public:
|
|
CHBmp()
|
|
{
|
|
m_hbmp = NULL;
|
|
}
|
|
|
|
CHBmp( HINSTANCE hinst, INT iRes )
|
|
{
|
|
m_hbmp = (HBITMAP)LoadImage( hinst, MAKEINTRESOURCE(iRes), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR );
|
|
}
|
|
|
|
~CHBmp()
|
|
{
|
|
if ( m_hbmp )
|
|
DeleteObject((HGDIOBJ)m_hbmp);
|
|
}
|
|
|
|
HBITMAP SetBmp( HINSTANCE hinst, INT iRes )
|
|
{
|
|
m_hbmp = (HBITMAP)LoadImage( hinst, MAKEINTRESOURCE(iRes), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR );
|
|
return(m_hbmp);
|
|
}
|
|
|
|
HBITMAP GetBmp()
|
|
{
|
|
return(m_hbmp);
|
|
}
|
|
|
|
private:
|
|
HBITMAP m_hbmp;
|
|
|
|
};
|
|
|
|
CComModule _Module;
|
|
|
|
BEGIN_OBJECT_MAP(ObjectMap)
|
|
END_OBJECT_MAP()
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetPBagPropStr()
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT SetPBagPropStr( IChainWiz *spCW, LPCTSTR szPropGuid, LPCTSTR szValue, PPPBAG_TYPE dwFlags )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if ( !spCW || !szPropGuid )
|
|
return E_FAIL;
|
|
|
|
CComPtr<IDispatch> spDisp;
|
|
spCW->get_PropertyBag( &spDisp );
|
|
CComQIPtr<IPropertyPagePropertyBag> spPPPBag(spDisp);
|
|
|
|
if ( spPPPBag )
|
|
{
|
|
hr = S_OK;
|
|
CComBSTR bstrPropGuid = szPropGuid;
|
|
CComVariant var = szValue;
|
|
spPPPBag->SetProperty (bstrPropGuid, &var, dwFlags);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetPBagPropBool()
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT SetPBagPropBool( IChainWiz *spCW, LPCTSTR szPropGuid, BOOL fValue, PPPBAG_TYPE dwFlags )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if ( !spCW || !szPropGuid )
|
|
return E_FAIL;
|
|
|
|
CComPtr<IDispatch> spDisp;
|
|
spCW->get_PropertyBag( &spDisp );
|
|
CComQIPtr<IPropertyPagePropertyBag> spPPPBag(spDisp);
|
|
|
|
if ( spPPPBag )
|
|
{
|
|
hr = S_OK;
|
|
CComBSTR bstrPropGuid = szPropGuid;
|
|
CComVariant var = (bool) !!fValue;
|
|
spPPPBag->SetProperty (bstrPropGuid, &var, dwFlags);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetPBagPropInt4()
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT SetPBagPropInt4( IChainWiz *spCW, LPCTSTR szPropGuid, long lValue, PPPBAG_TYPE dwFlags )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if ( !spCW || !szPropGuid )
|
|
return E_FAIL;
|
|
|
|
CComPtr<IDispatch> spDisp;
|
|
spCW->get_PropertyBag( &spDisp );
|
|
CComQIPtr<IPropertyPagePropertyBag> spPPPBag(spDisp);
|
|
|
|
if ( spPPPBag )
|
|
{
|
|
hr = S_OK;
|
|
CComBSTR bstrPropGuid = szPropGuid;
|
|
WriteInt4 (spPPPBag, bstrPropGuid, lValue, dwFlags == PPPBAG_TYPE_READONLY ? true : false);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// TmpSetProps()
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT TmpSetProps(IChainWiz *spCW)
|
|
{
|
|
if ( !spCW )
|
|
return(E_FAIL);
|
|
|
|
SetPBagPropInt4( spCW, PROP_AUTOCOMPLETE_MODE, g_dwAutoCompMode, PPPBAG_TYPE_READWRITE );
|
|
SetPBagPropStr ( spCW, PROP_USEROU_GUID_STRING, g_szUserOU, PPPBAG_TYPE_READWRITE );
|
|
|
|
// Check for POP3 installation
|
|
BOOL bPOP3Installed = FALSE;
|
|
BOOL bPOP3Valid = FALSE;
|
|
|
|
CRegKey cReg;
|
|
|
|
//To detect if POP3 is installed:
|
|
//Key: HKLM\SOFTWARE\Microsoft\POP3 Service
|
|
//Value: Version REG_SZ eg. "1.0"
|
|
tstring strPath = _T("Software\\Microsoft\\POP3 Service");
|
|
tstring strKey = _T("Version");
|
|
|
|
if( cReg.Open( HKEY_LOCAL_MACHINE, strPath.c_str() ) == ERROR_SUCCESS )
|
|
{
|
|
TCHAR szValue[MAX_PATH] = {0};
|
|
DWORD dwSize = MAX_PATH;
|
|
bPOP3Installed = (cReg.QueryValue( szValue, strKey.c_str(), &dwSize ) == ERROR_SUCCESS);
|
|
cReg.Close();
|
|
}
|
|
|
|
if( bPOP3Installed )
|
|
{
|
|
// Test if there is at least one domain
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IP3Config> spConfig = NULL;
|
|
CComPtr<IP3Domains> spDomains = NULL;
|
|
CComPtr<IP3Domain> spDomain = NULL;
|
|
long lCount = 0;
|
|
|
|
// Open our Pop3 Admin Interface
|
|
hr = CoCreateInstance(__uuidof(P3Config), NULL, CLSCTX_ALL, __uuidof(IP3Config), (LPVOID*)&spConfig);
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// Get the Domains
|
|
hr = spConfig->get_Domains( &spDomains );
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = spDomains->get_Count( &lCount );
|
|
}
|
|
|
|
bPOP3Valid = (lCount > 0);
|
|
}
|
|
|
|
SetPBagPropBool( spCW, PROP_POP3_CREATE_MB_GUID_STRING, bPOP3Valid, PPPBAG_TYPE_READWRITE );
|
|
SetPBagPropBool( spCW, PROP_POP3_VALID_GUID_STRING, bPOP3Valid, PPPBAG_TYPE_READWRITE );
|
|
SetPBagPropBool( spCW, PROP_POP3_INSTALLED_GUID_STRING, bPOP3Installed, PPPBAG_TYPE_READWRITE );
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// DoAddUsr( )
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT DoAddUsr( )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CHBmp bmpLarge(g_hInstance, IDB_BMP_LARGE);
|
|
CHBmp bmpSmall(g_hInstance, IDB_BMP_SMALL);
|
|
|
|
CString strTitle = _T("");
|
|
CString strWelcomeHeader = _T("");
|
|
CString strWelcomeText = _T("");
|
|
CString strWelcomeNext = _T("");
|
|
CString strFinishHeader = _T("");
|
|
CString strFinishIntro = _T("");
|
|
CString strFinishText = _T("");
|
|
CLSID clsidChainWiz;
|
|
CComPtr<IChainWiz> spCW;
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Init:
|
|
// Initialize the wizard's text.
|
|
// ------------------------------------------------------------------------
|
|
strTitle.LoadString ( IDS_TITLE );
|
|
strWelcomeHeader.LoadString ( IDS_WELCOME_HEADER );
|
|
strWelcomeText.LoadString ( IDS_WELCOME_TEXT );
|
|
strWelcomeNext.LoadString ( IDS_WELCOME_TEXT_NEXT );
|
|
strFinishHeader.LoadString ( IDS_FINISH_HEADER );
|
|
strFinishIntro.LoadString ( IDS_FINISH_TEXT );
|
|
|
|
strWelcomeText += strWelcomeNext;
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Initialize the wizard.
|
|
// ------------------------------------------------------------------------
|
|
hr = CLSIDFromProgID( L"WizChain.ChainWiz", &clsidChainWiz );
|
|
_ASSERT( hr == S_OK && "CLSIDFromProgID failed" );
|
|
|
|
hr = CoCreateInstance( clsidChainWiz, NULL, CLSCTX_INPROC_SERVER, __uuidof(IChainWiz), (void **)&spCW );
|
|
_ASSERT( spCW != NULL && "CoCreateInstance failed to create WizChain.ChainWiz" );
|
|
|
|
if( FAILED(hr) || !spCW )
|
|
{
|
|
ErrorMsg(IDS_ERROR_MISSINGDLL, IDS_ERROR_TITLE);
|
|
return(hr);
|
|
}
|
|
|
|
CComPtr<IDispatch> spDisp;
|
|
spCW->get_PropertyBag( &spDisp );
|
|
CComQIPtr<IPropertyPagePropertyBag> spPPPBag(spDisp);
|
|
|
|
USES_CONVERSION;
|
|
OLECHAR szClsid[MAX_GUID_STRING_LENGTH] = {0};
|
|
|
|
// --------------------------------------------------------------------
|
|
// Setup and run the wizard.
|
|
// --------------------------------------------------------------------
|
|
|
|
TmpSetProps( spCW ); // This is to populate the bag
|
|
|
|
// Initialize the wizard.
|
|
hr = spCW->Initialize( bmpLarge.GetBmp(),
|
|
bmpSmall.GetBmp(),
|
|
T2W((LPTSTR)(LPCTSTR)strTitle),
|
|
T2W((LPTSTR)(LPCTSTR)strWelcomeHeader),
|
|
T2W((LPTSTR)(LPCTSTR)strWelcomeText),
|
|
T2W((LPTSTR)(LPCTSTR)strFinishHeader),
|
|
T2W((LPTSTR)(LPCTSTR)strFinishIntro),
|
|
T2W((LPTSTR)(LPCTSTR)strFinishText) );
|
|
if ( FAILED(hr) )
|
|
return(hr);
|
|
|
|
|
|
|
|
// Add the AddUser Account component.
|
|
szClsid[0] = 0;
|
|
StringFromGUID2( __uuidof(AddUser_AccntWiz), szClsid, 50 );
|
|
hr = spCW->AddWizardComponent(szClsid);
|
|
if ( FAILED(hr) )
|
|
{
|
|
ErrorMsg(IDS_ERROR_MISSINGDLL, IDS_ERROR_TITLE);
|
|
return(hr);
|
|
}
|
|
|
|
// Run the wizard.
|
|
LONG lRet = 0;
|
|
spCW->DoModal(&lRet);
|
|
|
|
// --------------------------------------------------------------------
|
|
// Run the Committer(s) -- Commit()
|
|
// lRet != 1 means they cancelled the wizard.
|
|
// --------------------------------------------------------------------
|
|
if ( lRet != 1 )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
CComPtr<IWizardCommit> spWAccntCommit = NULL;
|
|
CComPtr<IStatusDlg> spSD = NULL;
|
|
CComPtr<IStatusProgress> spComponentProg = NULL;
|
|
|
|
BOOL bRO = FALSE;
|
|
DWORD dwErrCode = 0;
|
|
DWORD dwErrTemp = 0;
|
|
CString strError = StrFormatSystemError(E_FAIL).c_str();
|
|
strTitle.LoadString(IDS_TITLE);
|
|
|
|
// Get the AU_Accnt component.
|
|
hr = CoCreateInstance( __uuidof(AddUser_AccntCommit), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWizardCommit), (void**)&spWAccntCommit );
|
|
if ( FAILED(hr) || !spWAccntCommit ) return FAILED(hr) ? hr : E_FAIL;
|
|
|
|
// Get the Status Dialog
|
|
hr = CoCreateInstance( __uuidof(StatusDlg), NULL, CLSCTX_INPROC_SERVER, __uuidof(IStatusDlg), (void **) &spSD );
|
|
if ( FAILED(hr) || !spSD ) return FAILED(hr) ? hr : E_FAIL;
|
|
|
|
// Initialize the Status Dialog
|
|
VARIANT var;
|
|
CString csText;
|
|
CString csDescription;
|
|
long lAccount;
|
|
|
|
csText.LoadString(IDS_STATUS_INFO);
|
|
|
|
VariantInit(&var);
|
|
V_VT(&var) = VT_I4;
|
|
|
|
var.lVal = SD_BUTTON_OK | SD_PROGRESS_OVERALL;
|
|
|
|
hr = spSD->Initialize( CComBSTR(strTitle), CComBSTR(csText), var );
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Add our four components
|
|
csDescription.LoadString(IDS_STATUS_ACCNT);
|
|
hr = spSD->AddComponent(CComBSTR(csDescription), &lAccount);
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Display the Status Bar
|
|
hr = spSD->Display(TRUE);
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Get the Progress component
|
|
hr = spSD->get_OverallProgress(&spComponentProg);
|
|
if ( FAILED(hr) || !spComponentProg ) return FAILED(hr) ? hr : E_FAIL;
|
|
|
|
// Initialize our stepping
|
|
hr = spComponentProg->put_Step(1);
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Initialize our starting spot
|
|
hr = spComponentProg->put_Position(0);
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Initialize our range
|
|
hr = spComponentProg->put_Range(1); // Just the one!
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
bool bDeleteUser = false;
|
|
|
|
// Wipe out the component status checkmarks
|
|
spSD->SetStatus(lAccount, SD_STATUS_NONE);
|
|
|
|
// Put up the Progress text
|
|
CString csFormatString = _T("");
|
|
CString csUserName = _T("");
|
|
|
|
// Read the two string to format
|
|
csFormatString.LoadString(IDS_ERR_FORMAT_NAME);
|
|
ReadString( spPPPBag, PROP_USER_CN, csUserName, &bRO );
|
|
|
|
// This will be in the format "CN=USERNAME"
|
|
csUserName = csUserName.Right(csUserName.GetLength()-3);
|
|
|
|
// Format the string and display it
|
|
TCHAR szTempAccount[1024] = {0};
|
|
_sntprintf( szTempAccount, 1023, csFormatString, csUserName );
|
|
CComBSTR bstrUserName = szTempAccount;
|
|
spComponentProg->put_Text( bstrUserName );
|
|
|
|
// Set the Account running
|
|
spSD->SetStatus(lAccount, SD_STATUS_RUNNING);
|
|
|
|
// Accnt Commit
|
|
hr = spWAccntCommit->Commit( spDisp );
|
|
if ( FAILED(hr) )
|
|
{
|
|
// We failed this component
|
|
spSD->SetStatus(lAccount, SD_STATUS_FAILED);
|
|
|
|
ReadInt4 ( spPPPBag, PROP_ACCNT_ERROR_CODE_GUID_STRING, (PLONG)&dwErrCode, &bRO );
|
|
ReadString ( spPPPBag, PROP_ACCNT_ERROR_STR_GUID_STRING, strError, &bRO );
|
|
|
|
if ( dwErrCode & ERROR_DUPE )
|
|
{
|
|
MessageBox(NULL, strError, strTitle, MB_OK | MB_ICONERROR);
|
|
}
|
|
else if ( dwErrCode & (ERROR_CREATION | ERROR_PROPERTIES) )
|
|
{
|
|
::MessageBox(NULL, strError, strTitle, MB_OK | MB_ICONERROR);
|
|
spWAccntCommit->Revert();
|
|
}
|
|
else if ( dwErrCode & (ERROR_MAILBOX | ERROR_MEMBERSHIPS | ERROR_PASSWORD) )
|
|
{
|
|
CString strOutput;
|
|
strOutput.FormatMessage( IDS_ERROR_EXTENDED_FMT, strError );
|
|
|
|
// Do they want to revert?
|
|
if ( MessageBox(NULL, strOutput, strTitle, MB_YESNO | MB_ICONERROR) == IDYES )
|
|
{
|
|
spWAccntCommit->Revert();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
spSD->SetStatus(lAccount, SD_STATUS_SUCCEEDED);
|
|
}
|
|
|
|
// Done with the Committer Component
|
|
spComponentProg->StepIt(1);
|
|
spSD->WaitForUser();
|
|
|
|
// ------------------------------------------------------------------------
|
|
// All done.
|
|
// ------------------------------------------------------------------------
|
|
return hr;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Main()
|
|
// ----------------------------------------------------------------------------
|
|
extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
|
|
{
|
|
// Check that we are not already open.
|
|
CSingleInstance cInst( SINGLE_INST_NAME );
|
|
if ( cInst.IsOpen() )
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
HRESULT hrAdmin = IsUserInGroup( DOMAIN_ALIAS_RID_ADMINS );
|
|
if( hrAdmin != S_OK )
|
|
{
|
|
ErrorMsg(IDS_NOT_ADMIN, IDS_ERROR_TITLE);
|
|
return E_ACCESSDENIED;
|
|
}
|
|
|
|
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
|
|
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
#else
|
|
HRESULT hRes = CoInitialize(NULL);
|
|
#endif
|
|
_ASSERT(SUCCEEDED(hRes));
|
|
|
|
BOOL fBadUsage = FALSE;
|
|
LPCTSTR lpszToken = NULL;
|
|
LPTSTR pszCurrentPos = NULL;
|
|
CString csTmp;
|
|
|
|
// Init Global Vars.
|
|
g_dwAutoCompMode = 0;
|
|
g_szUserOU[0] = 0;
|
|
|
|
lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
|
|
|
|
_Module.Init(ObjectMap, hInstance);
|
|
g_hInstance = hInstance;
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Do the initial validation to make sure that we can execute the wizard.
|
|
// If we can't, show an error and exit, if so, get the cmd line parameters
|
|
// and do the wizard.
|
|
// ------------------------------------------------------------------------
|
|
|
|
int iTmp = -1;
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Parse command line
|
|
// ------------------------------------------------------------------------
|
|
for ( fBadUsage = FALSE, lpszToken = _FindOption(lpCmdLine) ; // Init to no bad usage and get the first param.
|
|
(!fBadUsage) && (lpszToken != NULL) && (pszCurrentPos = const_cast<LPTSTR>(lpszToken)) ; // While no bad usage and we still have a param...
|
|
lpszToken = _FindOption(pszCurrentPos) ) // Get the next parameter.
|
|
{
|
|
switch ( *pszCurrentPos )
|
|
{
|
|
|
|
case _T('u'): // HomeOU
|
|
case _T('U'):
|
|
{
|
|
// Only reads in MAX_PATH
|
|
TCHAR szTemp[MAX_PATH+1] = {0};
|
|
if ( !_ReadParam(pszCurrentPos, szTemp) )
|
|
{
|
|
fBadUsage = TRUE;
|
|
}
|
|
else
|
|
{
|
|
_tcsncpy( g_szUserOU, szTemp, MAX_PATH );
|
|
MakeLDAPUpper( g_szUserOU );
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case _T('L'): // Auto Completion Mode
|
|
case _T('l'):
|
|
{
|
|
TCHAR szMode[MAX_PATH+1] = {0};
|
|
|
|
// Only reads in MAX_PATH
|
|
if( !_ReadParam(pszCurrentPos, szMode) )
|
|
{
|
|
fBadUsage = TRUE;
|
|
}
|
|
else
|
|
{
|
|
g_dwAutoCompMode = _ttoi(szMode);
|
|
}
|
|
break;
|
|
}
|
|
|
|
default: // Unknown parameter.
|
|
{
|
|
fBadUsage = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Fix up the command line params and launch the wizard.
|
|
// ------------------------------------------------------------------------
|
|
if ( FixParams() )
|
|
{
|
|
DoAddUsr();
|
|
}
|
|
|
|
_Module.Term();
|
|
CoUninitialize();
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
DWORD FixParams(void)
|
|
{
|
|
CComPtr<IADs> pDS = NULL;
|
|
NET_API_STATUS nApi;
|
|
|
|
HRESULT hr = S_OK;
|
|
CString csDns = L"";
|
|
CString csNetbios = L"";
|
|
PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
|
|
PDOMAIN_CONTROLLER_INFO pDCI = NULL;
|
|
DWORD dwErr = 0;
|
|
ULONG ulGetDcFlags = DS_DIRECTORY_SERVICE_REQUIRED | DS_IP_REQUIRED |
|
|
DS_WRITABLE_REQUIRED | DS_RETURN_FLAT_NAME;
|
|
|
|
hr = DsGetDcName(NULL, NULL, NULL, NULL, DS_DIRECTORY_SERVICE_REQUIRED | DS_RETURN_DNS_NAME, &pDCI);
|
|
if ( (hr == S_OK) && (pDCI != NULL) )
|
|
{
|
|
csDns = pDCI->DomainName;
|
|
|
|
NetApiBufferFree (pDCI);
|
|
pDCI = NULL;
|
|
}
|
|
|
|
// Pre-Windows2000 DNS name
|
|
dwErr = DsGetDcName(NULL, (LPCWSTR)csDns, NULL, NULL, ulGetDcFlags, &pDCInfo);
|
|
if ( pDCInfo )
|
|
{
|
|
csNetbios = pDCInfo->DomainName; // Get the NT4 DNS name.
|
|
NetApiBufferFree(pDCInfo); // Free up the memory DsGetDcName() might have allocated.
|
|
pDCInfo = NULL;
|
|
}
|
|
|
|
if ( dwErr != ERROR_SUCCESS ) // If there was a problem, try again.
|
|
{
|
|
ulGetDcFlags |= DS_FORCE_REDISCOVERY;
|
|
dwErr = DsGetDcName(NULL, (LPCWSTR)csDns, NULL, NULL, ulGetDcFlags, &pDCInfo);
|
|
|
|
if ( pDCInfo )
|
|
{
|
|
csNetbios = pDCInfo->DomainName; // Get the NT4 DNS name.
|
|
NetApiBufferFree(pDCInfo); // Free up the memory DsGetDcName() might have allocated.
|
|
pDCInfo = NULL;
|
|
}
|
|
}
|
|
|
|
tstring strTemp = GetDomainPath((LPCTSTR)csDns);
|
|
if ( strTemp.empty() )
|
|
{
|
|
ErrorMsg(IDS_CANT_FIND_DC, IDS_TITLE);
|
|
return(0);
|
|
}
|
|
|
|
TCHAR szDomainOU[MAX_PATH] = {0};
|
|
_sntprintf( szDomainOU, MAX_PATH-1, _T("LDAP://%s"), strTemp.c_str() );
|
|
if ( FAILED(ADsGetObject(szDomainOU, IID_IADs, (void**)&pDS)) )
|
|
{
|
|
ErrorMsg(IDS_CANT_FIND_DC, IDS_TITLE);
|
|
return(0);
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// g_szUserOU
|
|
// ------------------------------------------------------------------------
|
|
if ( !_tcslen(g_szUserOU) || FAILED(ADsGetObject(g_szUserOU, IID_IADs, (void**) &pDS)) )
|
|
{
|
|
_sntprintf( g_szUserOU, (MAX_PATH*2)-1, L"LDAP://CN=Users,%s", strTemp.c_str() );
|
|
}
|
|
pDS = NULL;
|
|
|
|
if( g_dwAutoCompMode > 3 )
|
|
{
|
|
g_dwAutoCompMode = 0;
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
|