//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2000 - 2001. // // File: headers.h // // Contents: // // History: 07-26-2001 Hiteshr Created // //---------------------------------------------------------------------------- #include "headers.h" //+---------------------------------------------------------------------------- // Function:IsValidStoreType // Synopsis:Vaildates the store type //----------------------------------------------------------------------------- BOOL IsValidStoreType(ULONG lStoreType) { if((lStoreType == AZ_ADMIN_STORE_XML) || (lStoreType == AZ_ADMIN_STORE_AD)) return TRUE; return FALSE; } //+---------------------------------------------------------------------------- // Function: AddColumnToListView // Synopsis: Add Columns to Listview and set column width according to // percentage specified in the COL_FOR_LV // Arguments:IN pListCtrl: ListCtrl pointer // IN pColForLV: Column Infomration Array // // Returns: //----------------------------------------------------------------------------- VOID AddColumnToListView(IN CListCtrl* pListCtrl, IN COL_FOR_LV* pColForLV) { if(!pListCtrl || !pColForLV) { ASSERT(pListCtrl); ASSERT(pColForLV); } UINT iTotal = 0; RECT rc; pListCtrl->GetClientRect(&rc); for( UINT iCol = 0; pColForLV[iCol].idText != LAST_COL_ENTRY_IDTEXT; ++iCol) { CString strHeader; VERIFY(strHeader.LoadString(pColForLV[iCol].idText)); LV_COLUMN col; col.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; col.fmt = LVCFMT_LEFT; col.pszText = (LPWSTR)(LPCTSTR)strHeader; col.iSubItem = iCol; col.cx = (rc.right * pColForLV[iCol].iPercent) / 100; pListCtrl->InsertColumn(iCol,&col); iTotal += col.cx; } } //+---------------------------------------------------------------------------- // Function: BaseAzInListCtrl // Synopsis: Checks if Object of type eObjectTypeAz named strName is // in the Listview. If its present, returns // its index else returns -1. // Arguments:IN pListCtrl: ListCtrl pointer // IN strName: string to search for // IN eObjectTypeAz Compare the object of this type only // // Returns: If its present, returns its index else returns -1 //----------------------------------------------------------------------------- int BaseAzInListCtrl(IN CListCtrl* pListCtrl, IN const CString& strName, IN OBJECT_TYPE_AZ eObjectTypeAz) { if(!pListCtrl) { ASSERT(pListCtrl); return -1; } int iCount = pListCtrl->GetItemCount(); for( int i = 0; i < iCount; ++i) { CBaseAz* pBaseAz = (CBaseAz*)pListCtrl->GetItemData(i); if(pBaseAz) { if((pBaseAz->GetObjectType() == eObjectTypeAz) && (pBaseAz->GetName() == strName)) return i; } } return -1; } //+---------------------------------------------------------------------------- // Function: AddBaseAzFromListToListCtrl // Synopsis: Take the items from List and Add them to ListCtrl. Doesn't // add the items which are already in ListCtrl // Arguments:listBaseAz: List of items // pListCtrl: ListControl Pointer // uiFlags : Column Info // bCheckDuplicate: Check for duplicate items // Returns: The index of the new item if it is successful; otherwise, -1 // NOTE: Function assume the Order of column is Name, Type and Description //----------------------------------------------------------------------------- void AddBaseAzFromListToListCtrl(IN CList& listBaseAz, IN CListCtrl* pListCtrl, IN UINT uiFlags, IN BOOL bCheckDuplicate) { //Remember index of selected item int iFirstSelectedItem = pListCtrl->GetNextItem(-1, LVIS_SELECTED); POSITION pos = listBaseAz.GetHeadPosition(); for (int i = 0; i < listBaseAz.GetCount(); i++) { CBaseAz* pBaseAz = listBaseAz.GetNext(pos); //Check if item is in ListControl if(!bCheckDuplicate || BaseAzInListCtrl(pListCtrl, pBaseAz->GetName(), pBaseAz->GetObjectType()) == -1) { VERIFY( AddBaseAzToListCtrl(pListCtrl, pListCtrl->GetItemCount(), pBaseAz, uiFlags) != -1); } } //Restore Selection if(pListCtrl->GetItemCount() <= iFirstSelectedItem) --iFirstSelectedItem; SelectListCtrlItem(pListCtrl, iFirstSelectedItem); } //+---------------------------------------------------------------------------- // Function: AddActionItemFromListToListCtrl // Synopsis: Take the Actions items from List and Add them to ListCtrl. // Arguments:listBaseAz: List of items // pListCtrl: ListControl Pointer // uiFlags : Column Info // bCheckDuplicate: Check for duplicate items // Returns: The index of the new item if it is successful; otherwise, -1 // NOTE: Function assume the Order of column is Name, Type and Description //----------------------------------------------------------------------------- void AddActionItemFromListToListCtrl(IN CList& listActionItem, IN CListCtrl* pListCtrl, IN UINT uiFlags, IN BOOL bCheckDuplicate) { //Remember index of selected item int iFirstSelectedItem = pListCtrl->GetNextItem(-1, LVIS_SELECTED); POSITION pos = listActionItem.GetHeadPosition(); for (int i = 0; i < listActionItem.GetCount(); i++) { ActionItem* pActionItem = listActionItem.GetNext(pos); if(pActionItem->action == ACTION_REMOVE || pActionItem->action == ACTION_REMOVED) continue; //Check if item is in ListControl if(!bCheckDuplicate || BaseAzInListCtrl(pListCtrl, (pActionItem->m_pMemberAz)->GetName(), (pActionItem->m_pMemberAz)->GetObjectType()) == -1) { VERIFY( AddActionItemToListCtrl(pListCtrl, pListCtrl->GetItemCount(), pActionItem, uiFlags) != -1); } } //Restore Selection if(pListCtrl->GetItemCount() <= iFirstSelectedItem) --iFirstSelectedItem; SelectListCtrlItem(pListCtrl, iFirstSelectedItem); } //+---------------------------------------------------------------------------- // Function: AddActionItemFromMapToListCtrl // Synopsis: Take the Actions items from Map and Add them to ListCtrl. // Arguments:listBaseAz: List of items // pListCtrl: ListControl Pointer // uiFlags : Column Info // bCheckDuplicate: Check for duplicate items // Returns: The index of the new item if it is successful; otherwise, -1 // NOTE: Function assume the Order of column is Name, Type and Description //----------------------------------------------------------------------------- void AddActionItemFromMapToListCtrl(IN ActionMap& mapActionItem, IN CListCtrl* pListCtrl, IN UINT uiFlags, IN BOOL bCheckDuplicate) { //Remember index of selected item int iFirstSelectedItem = pListCtrl->GetNextItem(-1, LVIS_SELECTED); for (ActionMap::iterator it = mapActionItem.begin(); it != mapActionItem.end(); ++it) { ActionItem* pActionItem = (*it).second; if(pActionItem->action == ACTION_REMOVE || pActionItem->action == ACTION_REMOVED) continue; //Check if item is in ListControl if(!bCheckDuplicate || BaseAzInListCtrl(pListCtrl, (pActionItem->m_pMemberAz)->GetName(), (pActionItem->m_pMemberAz)->GetObjectType()) == -1) { VERIFY( AddActionItemToListCtrl(pListCtrl, pListCtrl->GetItemCount(), pActionItem, uiFlags) != -1); } } //Restore Selection if(pListCtrl->GetItemCount() <= iFirstSelectedItem) --iFirstSelectedItem; SelectListCtrlItem(pListCtrl, iFirstSelectedItem); } //+---------------------------------------------------------------------------- // Function: AddBaseAzToListCtrl // Synopsis: Adds a new item to ListCtrl. // Arguments:pListCtrl: ListControl Pointer // iIndex: Index at which to Add // pBaseAz: Item to add // uiFlags: column info // Returns: The index of the new item if it is successful; otherwise, -1 //----------------------------------------------------------------------------- int AddBaseAzToListCtrl(IN CListCtrl* pListCtrl, IN int iIndex, IN CBaseAz* pBaseAz, IN UINT uiFlags) { if(!pListCtrl || !pBaseAz) { ASSERT(pListCtrl); ASSERT(pBaseAz); return -1; } //Add Name and Item Data CString strName = pBaseAz->GetName(); int iNewIndex = pListCtrl->InsertItem(LVIF_TEXT|LVIF_STATE|LVIF_PARAM|LVIF_IMAGE, iIndex,strName,0,0, pBaseAz->GetImageIndex(), (LPARAM)pBaseAz); if(iNewIndex == -1) return iNewIndex; int iCol = 1; if(uiFlags & COL_TYPE ) { CString strType = pBaseAz->GetType(); pListCtrl->SetItemText(iNewIndex, iCol, (LPWSTR)(LPCTSTR)strType); iCol++; } if(uiFlags & COL_PARENT_TYPE) { CString strParentType = pBaseAz->GetParentType(); pListCtrl->SetItemText(iNewIndex, iCol, (LPWSTR)(LPCTSTR)strParentType); iCol++; } if(uiFlags & COL_DESCRIPTION) { //Add Description CString strDesc = pBaseAz->GetDescription(); pListCtrl->SetItemText(iNewIndex, iCol, (LPWSTR)(LPCTSTR)strDesc); } return iNewIndex; } //+---------------------------------------------------------------------------- // Function: AddActionItemToListCtrl // Synopsis: Adds a new item to ListCtrl. // Arguments:pListCtrl: ListControl Pointer // iIndex: Index at which to Add // pActionItem: Item to add // uiFlags: column info // Returns: The index of the new item if it is successful; otherwise, -1 //----------------------------------------------------------------------------- int AddActionItemToListCtrl(IN CListCtrl* pListCtrl, IN int iIndex, IN ActionItem* pActionItem, IN UINT uiFlags) { if(!pListCtrl || !pActionItem) { ASSERT(pListCtrl); ASSERT(pActionItem); return -1; } CBaseAz* pBaseAz = pActionItem->m_pMemberAz; //Add Name and Item Data CString strName = pBaseAz->GetName(); int iNewIndex = pListCtrl->InsertItem(LVIF_TEXT|LVIF_STATE|LVIF_PARAM|LVIF_IMAGE, iIndex, strName, 0,0, pBaseAz->GetImageIndex(), (LPARAM)pActionItem); if(iNewIndex == -1) return iNewIndex; int iCol = 1; if(uiFlags & COL_TYPE ) { CString strType = pBaseAz->GetType(); pListCtrl->SetItemText(iNewIndex, iCol, (LPWSTR)(LPCTSTR)strType); iCol++; } if(uiFlags & COL_PARENT_TYPE) { CString strParentType = pBaseAz->GetParentType(); pListCtrl->SetItemText(iNewIndex, iCol, (LPWSTR)(LPCTSTR)strParentType); iCol++; } if(uiFlags & COL_DESCRIPTION) { //Add Description CString strDesc = pBaseAz->GetDescription(); pListCtrl->SetItemText(iNewIndex, iCol, (LPWSTR)(LPCTSTR)strDesc); } return iNewIndex; } //+---------------------------------------------------------------------------- // Function: EnableButtonIfSelectedInListCtrl // Synopsis: Enables the button if something is selected in Listctrl // Arguments: // Returns: TRUE if Enabled the button, FALSE if didn't. //----------------------------------------------------------------------------- BOOL EnableButtonIfSelectedInListCtrl(IN CListCtrl * pListCtrl, IN CButton* pButton) { if(!pListCtrl || !pButton) { ASSERT(pListCtrl); ASSERT(pButton); return FALSE; } int nSelectedItem = pListCtrl->GetNextItem(-1, LVIS_SELECTED); if (nSelectedItem != -1) { pButton->EnableWindow(TRUE); return TRUE; } else { if(pButton->GetFocus() == pButton) pListCtrl->SetFocus(); pButton->EnableWindow(FALSE); return FALSE; } } //+---------------------------------------------------------------------------- // Function: DeleteSelectedRows // Synopsis: Deletes the selected rows //----------------------------------------------------------------------------- void DeleteSelectedRows(IN CListCtrl* pListCtrl) { //Remember the Position of first selected entry. //In the end set the position back to it int iFirstSelectedItem = pListCtrl->GetNextItem(-1, LVIS_SELECTED); int iSelectedItem = -1; while( (iSelectedItem = pListCtrl->GetNextItem(-1, LVIS_SELECTED)) != -1) { pListCtrl->DeleteItem(iSelectedItem); } if(pListCtrl->GetItemCount() <= iFirstSelectedItem) --iFirstSelectedItem; SelectListCtrlItem(pListCtrl, iFirstSelectedItem); } //+---------------------------------------------------------------------------- // Function: SelectListCtrlItem // Synopsis: Select the item in List Ctrl and mark it visible //----------------------------------------------------------------------------- void SelectListCtrlItem(IN CListCtrl* pListCtrl, IN int iSelected) { if(iSelected == -1) iSelected = 0; pListCtrl->SetItemState(iSelected, LVIS_SELECTED| LVIS_FOCUSED, LVIS_SELECTED| LVIS_FOCUSED); pListCtrl->EnsureVisible(iSelected,FALSE); } //+---------------------------------------------------------------------------- // Function: AddBaseAzItemsFromListCtrlToList // Synopsis: Add items from ListCtrl to List //----------------------------------------------------------------------------- VOID AddBaseAzItemsFromListCtrlToList(IN CListCtrl* pListCtrl, OUT CList& listBaseAz) { if(!pListCtrl) { ASSERT(pListCtrl); return; } int iCount = pListCtrl->GetItemCount(); for( int i = 0; i < iCount; ++i) { CBaseAz* pBaseAz = (CBaseAz*)pListCtrl->GetItemData(i); listBaseAz.AddTail(pBaseAz); } } //+---------------------------------------------------------------------------- // Synopsis: Gets long value from Edit box // Returns: FALSE if edit box is empty. Assumes only numeric can be entered // in edit box //----------------------------------------------------------------------------- GetLongValue(CEdit& refEdit, LONG& reflValue, HWND hWnd) { CString strValue; refEdit.GetWindowText(strValue); if(strValue.IsEmpty()) { reflValue = 0; return TRUE; } return ConvertStringToLong(strValue, reflValue, hWnd); } //+---------------------------------------------------------------------------- // Synopsis: Sets long value in Edit box //----------------------------------------------------------------------------- VOID SetLongValue(CEdit* pEdit, LONG lValue) { //Maximum required size for _itow is 33. //When radix is 2, 32 char for 32bits + NULL terminator WCHAR buffer[33]; _ltow(lValue,buffer,10); pEdit->SetWindowText(buffer); return; } //+---------------------------------------------------------------------------- // Synopsis: Converts a sid in binary format to a sid in string format //----------------------------------------------------------------------------- BOOL ConvertSidToStringSid(IN PSID pSid, OUT CString* pstrSid) { if(!pSid || !pstrSid) { ASSERT(pSid); ASSERT(pstrSid); return FALSE; } LPWSTR pszSid = NULL; if(ConvertSidToStringSid(pSid, &pszSid)) { ASSERT(pszSid); *pstrSid = pszSid; LocalFree(pszSid); return TRUE; } return FALSE; } //+---------------------------------------------------------------------------- // Synopsis: Converts a sid in string format to sid in binary format //----------------------------------------------------------------------------- BOOL ConvertStringSidToSid(IN const CString& strSid, OUT PSID *ppSid) { if(!ppSid) { ASSERT(ppSid); return FALSE; } return ::ConvertStringSidToSid((LPCTSTR)strSid,ppSid); } //+---------------------------------------------------------------------------- // Function:GetStringSidFromSidCachecAz // Synopsis:Gets the string sid from CSidCacheAz object //----------------------------------------------------------------------------- BOOL GetStringSidFromSidCachecAz(CBaseAz* pBaseAz, CString* pstrStringSid) { if(!pBaseAz || !pstrStringSid) { ASSERT(pBaseAz); ASSERT(pstrStringSid); return FALSE; } CSidCacheAz *pSidCacheAz = dynamic_cast(pBaseAz); if(!pSidCacheAz) { ASSERT(pSidCacheAz); return FALSE; } return ConvertSidToStringSid(pSidCacheAz->GetSid(), pstrStringSid); } //+---------------------------------------------------------------------------- // Function: AddAzObjectNodesToList // Synopsis: Adds the nodes for object of type eObjectType to the Container // node. // Arguments:IN eObjectType: Type of object // IN listAzChildObject: List of objects to be added // IN pContainerNode: Container in snapin to which new nodes will // be added. // Returns: //----------------------------------------------------------------------------- HRESULT AddAzObjectNodesToList(IN OBJECT_TYPE_AZ eObjectType, IN CList& listAzChildObject, IN CBaseContainerNode* pContainerNode) { if(!pContainerNode) { ASSERT(pContainerNode); return E_POINTER; } switch (eObjectType) { case APPLICATION_AZ: return ADD_APPLICATION_FUNCTION::DoEnum(listAzChildObject,pContainerNode); case SCOPE_AZ: return ADD_SCOPE_FUNCTION::DoEnum(listAzChildObject,pContainerNode); case GROUP_AZ: return ADD_GROUP_FUNCTION::DoEnum(listAzChildObject,pContainerNode); case TASK_AZ: return ADD_TASK_FUNCTION::DoEnum(listAzChildObject,pContainerNode); case ROLE_AZ: return ADD_ROLE_FUNCTION::DoEnum(listAzChildObject,pContainerNode); case OPERATION_AZ: return ADD_OPERATION_FUNCTION::DoEnum(listAzChildObject,pContainerNode); } ASSERT(FALSE); return E_UNEXPECTED; } // //Error Handling and Message Display Routines // VOID vFormatString(CString &strOutput, UINT nIDPrompt, va_list *pargs) { CString strFormat; if(!strFormat.LoadString(nIDPrompt)) return; LPWSTR pszResult = NULL; if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, strFormat, 0, 0, (LPTSTR)&pszResult, 1, pargs) && pszResult) { strOutput = pszResult; LocalFree(pszResult); } return; } VOID FormatString(CString &strOutput, UINT nIDPrompt, ...) { CString strFormat; if(!strFormat.LoadString(nIDPrompt)) return; va_list args; va_start(args, nIDPrompt); LPWSTR pszResult = NULL; if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, strFormat, 0, 0, (LPTSTR)&pszResult, 1, &args)) { strOutput = pszResult; LocalFree(pszResult); } va_end(args); return; } VOID GetSystemError(CString &strOutput, DWORD dwErr) { LPWSTR pszErrorMsg = NULL; if( FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &pszErrorMsg, 0, NULL) && pszErrorMsg) { strOutput = pszErrorMsg; LocalFree(pszErrorMsg); } else { strOutput.Format(L"<0x%08x>",dwErr); } return; } int DisplayMessageBox(HWND hWnd, const CString& strMessage, UINT uStyle) { CThemeContextActivator activator; CString strTitle; strTitle.LoadString(IDS_SNAPIN_NAME); return ::MessageBox(hWnd, strMessage, strTitle, uStyle|MB_TASKMODAL); } int FormatAndDisplayMessageBox(HWND hWnd, UINT uStyle, UINT nIDPrompt, va_list &args) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CThemeContextActivator activator; CString strMessage; vFormatString(strMessage,nIDPrompt,&args); int iReturn = 0; if(!strMessage.IsEmpty()) iReturn = DisplayMessageBox(hWnd, strMessage,uStyle); va_end(args); return iReturn; } void DisplayError(HWND hWnd, UINT nIDPrompt, ...) { va_list args; va_start(args, nIDPrompt); FormatAndDisplayMessageBox(hWnd, MB_OK | MB_ICONERROR,nIDPrompt,args); va_end(args); } void DisplayInformation(HWND hWnd, UINT nIDPrompt, ...) { va_list args; va_start(args, nIDPrompt); FormatAndDisplayMessageBox(hWnd, MB_OK | MB_ICONINFORMATION,nIDPrompt,args); va_end(args); } void DisplayWarning(HWND hWnd, UINT nIDPrompt, ...) { va_list args; va_start(args, nIDPrompt); FormatAndDisplayMessageBox(hWnd, MB_OK | MB_ICONWARNING, nIDPrompt,args); va_end(args); } int DisplayConfirmation(HWND hwnd, UINT nIDPrompt,...) { va_list args; va_start(args, nIDPrompt); int iReturn = FormatAndDisplayMessageBox(hwnd, MB_YESNO | MB_ICONEXCLAMATION,nIDPrompt,args); va_end(args); return iReturn; } BOOL IsDeleteConfirmed(HWND hwndOwner, CBaseAz& refBaseAz) { CString strType = refBaseAz.GetType(); strType.MakeLower(); return IDYES == DisplayConfirmation(hwndOwner, IDS_DELETE_CONFIRMATION, (LPCTSTR)strType, (LPCTSTR)refBaseAz.GetName()); } // //Error Map for object types containing some common error info for //each object type // ErrorMap ERROR_MAP[] = { { ADMIN_MANAGER_AZ, IDS_TYPE_ADMIN_MANAGER, IDS_ADMIN_MANAGER_NAME_EXIST, IDS_ADMIN_MANAGER_NAME_INVAILD, L"\\ / : * ? \" < > | [tab]", }, { APPLICATION_AZ, IDS_TYPE_APPLICATION, IDS_APPLICATION_NAME_EXIST, IDS_APPLICATION_NAME_INVAILD, L"\\ / : * ? \" < > | [tab]", }, { SCOPE_AZ, IDS_TYPE_SCOPE, IDS_SCOPE_NAME_EXIST, IDS_SCOPE_NAME_INVAILD, L"", }, { GROUP_AZ, IDS_TYPE_GROUP, IDS_GROUP_NAME_EXIST, IDS_GROUP_NAME_INVAILD, L"\\ / : * ? \" < > | [tab]", }, { TASK_AZ, IDS_TYPE_TASK, IDS_TASK_OP_ALREADY_EXIST, IDS_TASK_NAME_INVAILD, L"\\ / : * ? \" < > | [tab]", }, { ROLE_AZ, IDS_TYPE_ROLE, IDS_ROLE_NAME_EXIST, IDS_ROLE_NAME_INVAILD, L"\\ / : * ? \" < > | [tab]", }, { OPERATION_AZ, IDS_TYPE_OPERATION, IDS_TASK_OP_ALREADY_EXIST, IDS_OPERATION_NAME_INVAILD, L"\\ / : * ? \" < > | [tab]", }, }; ErrorMap *GetErrorMap(OBJECT_TYPE_AZ eObjectType) { for(int i = 0; i < ARRAYLEN(ERROR_MAP); ++i) { if(ERROR_MAP[i].eObjectType == eObjectType) return ERROR_MAP + i; } return NULL; } //+---------------------------------------------------------------------------- // Function: GetLSAConnection // Synopsis: Wrapper for LsaOpenPolicy //----------------------------------------------------------------------------- LSA_HANDLE GetLSAConnection(IN const CString& strServer, IN DWORD dwAccessDesired) { TRACE_FUNCTION_EX(DEB_SNAPIN,GetLSAConnection) LSA_OBJECT_ATTRIBUTES oa; SECURITY_QUALITY_OF_SERVICE sqos; sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); sqos.ImpersonationLevel = SecurityImpersonation; sqos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; sqos.EffectiveOnly = FALSE; InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL); oa.SecurityQualityOfService = &sqos; LSA_UNICODE_STRING uszServer = {0}; LSA_UNICODE_STRING *puszServer = NULL; if (!strServer.IsEmpty() && RtlCreateUnicodeString(&uszServer, (LPCTSTR)strServer)) { puszServer = &uszServer; } LSA_HANDLE hPolicy = NULL; LsaOpenPolicy(puszServer, &oa, dwAccessDesired, &hPolicy); if (puszServer) RtlFreeUnicodeString(puszServer); return hPolicy; } //+---------------------------------------------------------------------------- // Function:GetFileName // Synopsis:Displays FileOpen dialog box and return file selected by user // Arguments:hwndOwner : owner window // bOpen: File must exist // nIDTitle : title of open dialog box // pszFilter : filter // strFileName : gets selected file name // //----------------------------------------------------------------------------- BOOL GetFileName(IN HWND hwndOwner, IN BOOL bOpen, IN INT nIDTitle, IN const CString& strInitFolderPath, IN LPCTSTR pszFilter, IN OUT CString& strFileName) { TRACE_FUNCTION_EX(DEB_SNAPIN,GetFileName) OPENFILENAME of; ZeroMemory(&of,sizeof(OPENFILENAME)); WCHAR szFilePathBuffer[MAX_PATH]; ZeroMemory(szFilePathBuffer,sizeof(szFilePathBuffer)); of.lStructSize = sizeof(OPENFILENAME); of.hwndOwner = hwndOwner; of.lpstrFilter = pszFilter; of.nFilterIndex = 1; of.lpstrFile = szFilePathBuffer; of.nMaxFile = MAX_PATH; of.lpstrInitialDir = (LPCWSTR)strInitFolderPath; if(nIDTitle) { CString strTitle; if(strTitle.LoadString(nIDTitle)) of.lpstrTitle = (LPWSTR)(LPCTSTR)strTitle; } of.Flags = OFN_HIDEREADONLY; if(bOpen) of.Flags |= (OFN_FILEMUSTEXIST |OFN_PATHMUSTEXIST); if(GetOpenFileName(&of)) { strFileName = of.lpstrFile; return TRUE; } return FALSE; } int ServerBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /*lParam*/, LPARAM lpData) { switch (uMsg) { case BFFM_INITIALIZED: SendMessage(hwnd, BFFM_SETEXPANDED, TRUE, lpData); SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData); break; } return 0; } //+---------------------------------------------------------------------------- // Function:GetFolderName // Synopsis:Displays Folder selection dialog box and return folder selected // by user // Arguments:hwndOwner : owner window // nIDTitle : title of dialog box // strInitBrowseRoot : location of the root folder from which to // start browsing // strFolderName : gets selected file name //----------------------------------------------------------------------------- BOOL GetFolderName(IN HWND hwndOwner, IN INT nIDTitle, IN const CString& strInitBrowseRoot, IN OUT CString& strFolderName) { TRACE_FUNCTION_EX(DEB_SNAPIN,GetFolderName) BROWSEINFO bi; ZeroMemory(&bi,sizeof(bi)); WCHAR szBuffer[MAX_PATH]; szBuffer[0] = 0; CString strTitle; VERIFY(strTitle.LoadString(nIDTitle)); bi.hwndOwner = hwndOwner; bi.pszDisplayName = szBuffer; bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; bi.lpszTitle = strTitle; bi.lpfn = ServerBrowseCallbackProc; bi.lParam = (LPARAM)(LPCWSTR)strInitBrowseRoot; LPITEMIDLIST pidl = SHBrowseForFolder(&bi); if(pidl) { WCHAR szFolderPath[MAX_PATH]; if(SHGetPathFromIDList(pidl,szFolderPath)) { PathAddBackslash(szFolderPath); strFolderName = szFolderPath; } } return !strFolderName.IsEmpty(); } //+---------------------------------------------------------------------------- // Function:GetADContainerPath // Synopsis:Displays a dialog box to allow for selecting a AD container //----------------------------------------------------------------------------- BOOL GetADContainerPath(HWND hWndOwner, ULONG nIDCaption, ULONG nIDTitle, CString& strPath, CADInfo& refAdInfo) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); TRACE_FUNCTION_EX(DEB_SNAPIN,GetADContainerPath) HRESULT hr = refAdInfo.GetRootDSE(); CHECK_HRESULT(hr); if(FAILED(hr)) { DisplayError(hWndOwner,IDS_CANNOT_ACCESS_AD); return FALSE; } CString strRootDomainPath; if(!refAdInfo.GetRootDomainDn().IsEmpty()) { if(!refAdInfo.GetRootDomainDCName().IsEmpty()) { strRootDomainPath = L"LDAP://" + refAdInfo.GetRootDomainDCName() + L"/" + refAdInfo.GetRootDomainDn(); } else { strRootDomainPath = L"LDAP://" + refAdInfo.GetRootDomainDn(); } } DSBROWSEINFOW dsbrowse; ZeroMemory(&dsbrowse,sizeof(dsbrowse)); dsbrowse.cbStruct = sizeof(dsbrowse); //Set Root of search to forest root if(!strRootDomainPath.IsEmpty()) dsbrowse.pszRoot = (LPCTSTR)strRootDomainPath; //Construct the path to which tree will expand on opening of //dialog box CString strInitialPath; GetDefaultADContainerPath(refAdInfo,TRUE,TRUE,strInitialPath); WCHAR szPath[MAX_PATH]; ZeroMemory(szPath,sizeof(szPath)); if(!strInitialPath.IsEmpty() && MAX_PATH > strInitialPath.GetLength()) { wcscpy(szPath,(LPCTSTR)strInitialPath); } dsbrowse.hwndOwner = hWndOwner; CString strCaption; if(nIDCaption) { strCaption.LoadString(nIDCaption); dsbrowse.pszCaption = strCaption; } CString strTitle; if(nIDTitle) { strTitle.LoadString(nIDTitle); dsbrowse.pszTitle = strTitle; } dsbrowse.pszPath = szPath; dsbrowse.cchPath = MAX_PATH; dsbrowse.dwFlags = DSBI_ENTIREDIRECTORY|DSBI_RETURN_FORMAT|DSBI_INCLUDEHIDDEN|DSBI_EXPANDONOPEN; dsbrowse.dwReturnFormat = ADS_FORMAT_X500_NO_SERVER; BOOL bRet = FALSE; BOOL iRet = 0; iRet = DsBrowseForContainer(&dsbrowse); if(IDOK == iRet) { //Path contains LDAP:// string which we don't want size_t nLen = wcslen(g_szLDAP); if(_wcsnicmp(dsbrowse.pszPath,g_szLDAP,nLen) == 0 ) strPath = (dsbrowse.pszPath + nLen); else strPath = dsbrowse.pszPath; bRet = TRUE; } else if (-1 == iRet) { Dbg(DEB_SNAPIN, "DsBrowseForContainer Failed\n"); DisplayError(hWndOwner,IDS_CANNOT_ACCESS_AD); } return bRet; } //+---------------------------------------------------------------------------- // Function:CompareBaseAzObjects // Synopsis:Compares two baseaz objects for equivalance. If two pAzA and pAzB // are two different instances of same coreaz object, they are equal //----------------------------------------------------------------------------- BOOL CompareBaseAzObjects(CBaseAz* pAzA, CBaseAz* pAzB) { if(pAzA == pAzB) return TRUE; if(!pAzA || !pAzB) return FALSE; if(!(pAzA->GetObjectType() == pAzB->GetObjectType() && pAzA->GetName() == pAzB->GetName())) return FALSE; //If object if of type AdminManager, it must be same node if(pAzA->GetObjectType() == ADMIN_MANAGER_AZ) return (pAzA == pAzB); //Two objects with same name and object type can exist under different //parent-> Check if their parents are same-> if(pAzA->GetParentAz()->GetName() == pAzB->GetParentAz()->GetName()) return TRUE; return FALSE; } //+---------------------------------------------------------------------------- // //Below Code maps dialog box id to Help Map //Ported from DNS Manager // //----------------------------------------------------------------------------- #include "HelpMap.H" #define BEGIN_HELP_MAP(map) static DWORD_PTR map[] = { #define HELP_MAP_ENTRY(x) x, (DWORD_PTR)&g_aHelpIDs_##x , #define END_HELP_MAP 0, 0 }; #define NEXT_HELP_MAP_ENTRY(p) ((p)+2) #define MAP_ENTRY_DLG_ID(p) (*p) #define MAP_ENTRY_TABLE(p) ((DWORD*)(*(p+1))) #define IS_LAST_MAP_ENTRY(p) (MAP_ENTRY_DLG_ID(p) == 0) BEGIN_HELP_MAP(AuthManContextHelpMap) HELP_MAP_ENTRY(IDD_ADD_GROUP) HELP_MAP_ENTRY(IDD_ADD_OPERATION) HELP_MAP_ENTRY(IDD_ADD_ROLE_DEFINITION) HELP_MAP_ENTRY(IDD_ADD_TASK) HELP_MAP_ENTRY(IDD_ADMIN_MANAGER_ADVANCED_PROPERTY) HELP_MAP_ENTRY(IDD_ADMIN_MANAGER_GENERAL_PROPERTY) HELP_MAP_ENTRY(IDD_APPLICATION_GENERAL_PROPERTY) HELP_MAP_ENTRY(IDD_AUDIT) HELP_MAP_ENTRY(IDD_GROUP_GENERAL_PROPERTY) HELP_MAP_ENTRY(IDD_GROUP_LDAP_QUERY) HELP_MAP_ENTRY(IDD_GROUP_MEMBER) HELP_MAP_ENTRY(IDD_GROUP_NON_MEMBER) HELP_MAP_ENTRY(IDD_NEW_APPLICATION) HELP_MAP_ENTRY(IDD_NEW_AUTHORIZATION_STORE) HELP_MAP_ENTRY(IDD_NEW_GROUP) HELP_MAP_ENTRY(IDD_NEW_OPERATION) HELP_MAP_ENTRY(IDD_NEW_ROLE_DEFINITION) HELP_MAP_ENTRY(IDD_NEW_SCOPE) HELP_MAP_ENTRY(IDD_NEW_TASK) HELP_MAP_ENTRY(IDD_OPEN_AUTHORIZATION_STORE) HELP_MAP_ENTRY(IDD_OPERATION_GENERAL_PROPERTY) HELP_MAP_ENTRY(IDD_ROLE_DEFINITION_PROPERTY) HELP_MAP_ENTRY(IDD_SCOPE_GENERAL_PROPERTY) HELP_MAP_ENTRY(IDD_ROLE_DEFINITION_PROPERTY) HELP_MAP_ENTRY(IDD_SECURITY) HELP_MAP_ENTRY(IDD_TASK_DEFINITION_PROPERTY) HELP_MAP_ENTRY(IDD_TASK_GENERAL_PROPERTY) HELP_MAP_ENTRY(IDD_ROLE_DEFINITION_GENERAL_PROPERTY) HELP_MAP_ENTRY(IDD_ROLE_GENERAL_PROPERTY) HELP_MAP_ENTRY(IDD_ROLE_DEF_DIALOG) HELP_MAP_ENTRY(IDD_BROWSE_AD_STORE) HELP_MAP_ENTRY(IDD_SCRIPT) HELP_MAP_ENTRY(IDD_ADD_ROLE_DEFINITION_1) END_HELP_MAP //+---------------------------------------------------------------------------- // Function:FindDialogContextTopic // Synopsis:Finds the helpmap for a given dialog id //----------------------------------------------------------------------------- BOOL FindDialogContextTopic(IN UINT nDialogID, OUT DWORD_PTR* pMap) { if(!pMap) { ASSERT(pMap); return FALSE; } const DWORD_PTR* pMapEntry = AuthManContextHelpMap; while (!IS_LAST_MAP_ENTRY(pMapEntry)) { if (nDialogID == MAP_ENTRY_DLG_ID(pMapEntry)) { DWORD_PTR pTable = (DWORD_PTR)MAP_ENTRY_TABLE(pMapEntry); ASSERT(pTable); *pMap = pTable; return TRUE; } pMapEntry = NEXT_HELP_MAP_ENTRY(pMapEntry); } return FALSE; } //+---------------------------------------------------------------------------- // Function:CanReadOneProperty // Synopsis:Function tries to read IsWriteable property. If that fails displays // an error message. This is used before adding property pages. // if we cannot read IsWritable property,thereisn't much hope. //----------------------------------------------------------------------------- BOOL CanReadOneProperty(LPCWSTR pszName, CBaseAz* pBaseAz) { TRACE_FUNCTION_EX(DEB_SNAPIN,CanReadOneProperty) if(!pBaseAz) { ASSERT(pBaseAz); return FALSE; } BOOL bWrite; HRESULT hr = pBaseAz->IsWritable(bWrite); if(SUCCEEDED(hr)) { return TRUE; } else { if(hr == HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE)) { DisplayError(NULL, IDS_PROP_ERROR_OBJECT_DELETED, pszName); } else { //Display Generic Error CString strError; GetSystemError(strError, hr); DisplayError(NULL, IDS_GENERIC_PROP_DISPLAY_ERROR, (LPCWSTR)strError, pszName); } return FALSE; } } //+---------------------------------------------------------------------------- // Function: ListCompareProc // Synopsis: Comparison function used by list control //----------------------------------------------------------------------------- int CALLBACK ListCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { int iResult = CSTR_EQUAL; if(!lParam1 || !lParam2 || !lParamSort) { ASSERT(lParam1); ASSERT(lParam2); ASSERT(lParamSort); return iResult; } CompareInfo *pCompareInfo = (CompareInfo*)lParamSort; CBaseAz* pBaseAz1 = NULL; CBaseAz* pBaseAz2 = NULL; if(pCompareInfo->bActionItem) { pBaseAz1 = ((ActionItem*)lParam1)->m_pMemberAz; pBaseAz2 = ((ActionItem*)lParam2)->m_pMemberAz; } else { pBaseAz1 = (CBaseAz*)lParam1; pBaseAz2 = (CBaseAz*)lParam2; } CString str1; CString str2; int iColType = -1; int iColParentType = -1; int iColDescription = -1; int iCol = 1; if(pCompareInfo->uiFlags & COL_TYPE ) { iColType = iCol++; } if(pCompareInfo->uiFlags & COL_PARENT_TYPE) { iColParentType = iCol++; } if(pCompareInfo->uiFlags & COL_DESCRIPTION) { iColDescription = iCol++; } if (pBaseAz1 && pBaseAz2) { if(pCompareInfo->iColumn == 0) { str1 = pBaseAz1->GetName(); str2 = pBaseAz2->GetName(); } else if(pCompareInfo->iColumn == iColType) { str1 = pBaseAz1->GetType(); str2 = pBaseAz2->GetType(); } else if(pCompareInfo->iColumn == iColDescription) { str1 = pBaseAz1->GetDescription(); str2 = pBaseAz2->GetDescription(); } else if(pCompareInfo->iColumn == iColParentType) { str1 = pBaseAz1->GetParentType(); str2 = pBaseAz2->GetParentType(); } iResult = CompareString(LOCALE_USER_DEFAULT, 0, str1, -1, str2, -1) - 2; iResult *= pCompareInfo->iSortDirection; } return iResult; } //+---------------------------------------------------------------------------- // Function:SortListControl // Synopsis:Sorts a list control // Arguments:pListCtrl: List control to sort // iColumnClicked: column clicked // iSortDirection: direction in which to sort // uiFlags: column info // bActionItem: if item in list is actionitem //----------------------------------------------------------------------------- void SortListControl(CListCtrl* pListCtrl, int iColumnClicked, int iSortDirection, UINT uiFlags, BOOL bActionItem) { if(!pListCtrl) { ASSERT(pListCtrl); return; } CompareInfo compareInfo; compareInfo.bActionItem = bActionItem; compareInfo.iColumn = iColumnClicked; compareInfo.iSortDirection = iSortDirection; compareInfo.uiFlags = uiFlags; pListCtrl->SortItems(ListCompareProc, (DWORD_PTR)&compareInfo); } //+---------------------------------------------------------------------------- // Synopsis: Ensures that selection in listview control is visible //----------------------------------------------------------------------------- void EnsureListViewSelectionIsVisible(CListCtrl *pListCtrl) { ASSERT(pListCtrl); int iSelected = pListCtrl->GetNextItem(-1, LVNI_SELECTED); if (-1 != iSelected) pListCtrl->EnsureVisible(iSelected, FALSE); } //+---------------------------------------------------------------------------- // Synopsis:Convert input number in string format to long. if number is out // of range displays a message. //----------------------------------------------------------------------------- BOOL ConvertStringToLong(LPCWSTR pszInput, long &reflongOutput, HWND hWnd) { if(!pszInput) { ASSERT(pszInput); return FALSE; } // //Get the Max len of long long lMaxLong = LONG_MAX; WCHAR szMaxLongBuffer[34]; _ltow(lMaxLong,szMaxLongBuffer,10); size_t nMaxLen = wcslen(szMaxLongBuffer); // //Get the length of input LPCWSTR pszTempInput = pszInput; if(pszInput[0] == L'-') { pszTempInput++; } // //Length of input greater than length of Max Long, than //input is out of range. size_t nInputLen = wcslen(pszTempInput); if(nInputLen > nMaxLen) { if(hWnd) { DisplayError(hWnd,IDS_GREATER_THAN_MAX_LONG,pszTempInput,szMaxLongBuffer); } return FALSE; } // //Convert input to int64 and check its less that max integer // __int64 i64Input = _wtoi64(pszTempInput); if(i64Input > (__int64)lMaxLong) { if(hWnd) { DisplayError(hWnd,IDS_GREATER_THAN_MAX_LONG,pszTempInput,szMaxLongBuffer); } return FALSE; } // //Value is good // reflongOutput = _wtol(pszInput); return TRUE; } VOID SetSel(CEdit& refEdit) { refEdit.SetFocus(); refEdit.SetSel(0,-1); } //+---------------------------------------------------------------------------- // Function: ValidateStoreTypeAndName // Synopsis: Validates the user entered AD Store Name // Arguments: strName: User entered store name to verify // Returns: TRUE if name is valid else false //----------------------------------------------------------------------------- BOOL ValidateStoreTypeAndName(HWND hWnd, LONG ulStoreType, const CString& strName) { TRACE_FUNCTION_EX(DEB_SNAPIN,ValidateStoreTypeAndName) //Store Name is not entered in the valid format. We should come here only //when store name is entered at the command line. if((AZ_ADMIN_STORE_INVALID == ulStoreType) || strName.IsEmpty()) { DisplayError(hWnd,IDS_INVALIDSTORE_ON_COMMANDLINE); return FALSE; } //No validation is required for XML Store if(ulStoreType == AZ_ADMIN_STORE_XML) { return TRUE; } ASSERT(ulStoreType == AZ_ADMIN_STORE_AD); BOOL bRet = FALSE; PDS_NAME_RESULT pResult = NULL; do { //Get the store name with LDAP:// prefix CString strFormalName; NameToStoreName(AZ_ADMIN_STORE_AD, strName, TRUE, strFormalName); Dbg(DEB_SNAPIN, "AD store name entered is: %ws\n", CHECK_NULL(strFormalName)); CComPtr spPathName; HRESULT hr = spPathName.CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER); BREAK_ON_FAIL_HRESULT(hr); hr = spPathName->Set(CComBSTR(strFormalName), ADS_SETTYPE_FULL); BREAK_ON_FAIL_HRESULT(hr); //Get the DN entered by user CComBSTR bstrDN; hr = spPathName->Retrieve(ADS_FORMAT_X500_DN,&bstrDN); BREAK_ON_FAIL_HRESULT(hr); if(bstrDN.Length() == 0) { Dbg(DEB_SNAPIN, "spPathName->Retrieve returned 0 len DN\n"); break; } //Do a syntactical crack for the DN to see if its a valid DN LPCWSTR pszName = bstrDN; if( DsCrackNames(NULL, DS_NAME_FLAG_SYNTACTICAL_ONLY, DS_FQDN_1779_NAME, DS_CANONICAL_NAME, 1, &pszName, &pResult) != DS_NAME_NO_ERROR) { Dbg(DEB_SNAPIN, "DsCrackName failed to crack the name"); break; } ASSERT(pResult); if(pResult->rItems->status == DS_NAME_NO_ERROR) { bRet = TRUE; } }while(0); if(pResult) DsFreeNameResult(pResult); if(!bRet) { DisplayError(hWnd,IDS_INVALID_AD_STORE_NAME); } return bRet; } //+---------------------------------------------------------------------------- // Function: NameToFormatStoreName // Synopsis: Converts user entered name to format which core understands // Arguments: ulStoreType: Type of store // strName: User entered store name // bUseLDAP:use LDAP string to format AD name instead msldap // strFormalName: gets the output ldap name //----------------------------------------------------------------------------- void NameToStoreName(IN LONG lStoreType, IN const CString& strName, IN BOOL bUseLDAP, OUT CString& strFormalName) { strFormalName.Empty(); if(lStoreType == AZ_ADMIN_STORE_XML) { if(_wcsnicmp(strName,g_szMSXML,wcslen(g_szMSXML)) == 0 ) { strFormalName = strName; } else { strFormalName = g_szMSXML + strName; } return; } else if(lStoreType == AZ_ADMIN_STORE_AD) { LPCWSTR lpcszPrefix = bUseLDAP ? g_szLDAP : g_szMSLDAP; LPCWSTR lpcszOtherPrefix = bUseLDAP ? g_szMSLDAP : g_szLDAP; if(_wcsnicmp(strName,lpcszPrefix,wcslen(lpcszPrefix)) == 0 ) { strFormalName = strName; } else { size_t nlen = wcslen(lpcszOtherPrefix); //Check if user has put other prefix in the name if(_wcsnicmp(strName,lpcszOtherPrefix,nlen) == 0 ) { strFormalName = lpcszPrefix + strName.Right(strName.GetLength() - (int)nlen); } else { strFormalName = lpcszPrefix + strName; } } return; } ASSERT(FALSE); return; } void TrimWhiteSpace(CString& str) { str.TrimLeft(L"\t "); str.TrimRight(L"\t "); } BOOL TranslateNameFromDnToDns(const CString& strInputDN, CString& strOutputDNS) { TRACE_FUNCTION_EX(DEB_SNAPIN,TranslateNameFromDnToDns) if(strInputDN.IsEmpty()) return FALSE; strOutputDNS.Empty(); Dbg(DEB_SNAPIN, "DN of Forest is %ws\n", (LPCWSTR)strInputDN); LPCWSTR pstrName = strInputDN; PDS_NAME_RESULT pResult; if( DS_NAME_NO_ERROR == DsCrackNames(NULL, DS_NAME_FLAG_SYNTACTICAL_ONLY, DS_FQDN_1779_NAME, DS_CANONICAL_NAME, 1, (LPWSTR*)(&pstrName), &pResult)) { if(pResult && pResult->cItems == 1 && pResult->rItems[0].status == DS_NAME_NO_ERROR && pResult->rItems[0].pDomain) { strOutputDNS = pResult->rItems[0].pDomain; Dbg(DEB_SNAPIN, "DNS of Forest is %ws\n", (LPCWSTR)strOutputDNS); } if(pResult) { DsFreeNameResult(pResult); } } return !strOutputDNS.IsEmpty(); } //+---------------------------------------------------------------------------- // Function:GetSearchObject // Synopsis:Get IDirectorySearch object to search at forest //----------------------------------------------------------------------------- HRESULT GetSearchObject(IN CADInfo& refAdInfo, OUT CComPtr& refspSearchObject) { TRACE_FUNCTION_EX(DEB_SNAPIN,GetSearchObject) HRESULT hr = S_OK; do { // hr = refAdInfo.GetRootDSE(); BREAK_ON_FAIL_HRESULT(hr); const CString& strForestDNS = refAdInfo.GetRootDomainDnsName(); CString strGCPath = L"GC://"; strGCPath += strForestDNS; // //Get IDirectorySearch Object // hr = AzRoleAdsOpenObject((LPWSTR)(LPCWSTR)strGCPath, NULL, NULL, IID_IDirectorySearch, (void**)&refspSearchObject); BREAK_ON_FAIL_HRESULT(hr); }while(0); return hr; } // // Attributes that we want the Object Picker to retrieve // static const LPCTSTR g_aszOPAttributes[] = { TEXT("distinguishedName"), }; //+---------------------------------------------------------------------------- // Function:GetListOfAuthorizationStore // Synopsis:Search at GC for AD policy stores and returns list. //----------------------------------------------------------------------------- HRESULT GetListOfAuthorizationStore(IN CADInfo& refAdInfo, OUT CList &strList) { HRESULT hr = S_OK; //If List is not empty, empty it while(!strList.IsEmpty()) strList.RemoveHead(); do { TIMER("Time to search GC for AD Stores"); CComPtr spSearchObject; CString str; hr = GetSearchObject(refAdInfo, spSearchObject); BREAK_ON_FAIL_HRESULT(hr); CDSSearch searchObject(spSearchObject); searchObject.SetFilterString((LPWSTR)g_pszAuthorizationStoreQueryFilter); searchObject.SetAttributeList((LPWSTR*)g_aszOPAttributes,1); hr = searchObject.DoQuery(); BREAK_ON_FAIL_HRESULT(hr); int iIndex = 0; while(TRUE) { hr = searchObject.GetNextRow(); //We are done if(hr == S_ADS_NOMORE_ROWS) { hr = S_OK; break; } BREAK_ON_FAIL_HRESULT(hr); ADS_SEARCH_COLUMN ColumnData; hr = searchObject.GetColumn((LPWSTR)g_aszOPAttributes[0], &ColumnData); if(SUCCEEDED(hr)) { ASSERT(ADSTYPE_DN_STRING == ColumnData.dwADsType); strList.AddTail(ColumnData.pADsValues->DNString); searchObject.FreeColumn(&ColumnData); } }//End of while loop }while(0); if(!strList.IsEmpty()) return S_OK; return hr; } /****************************************************************************** Class: CBaseAddDialog Purpose:Displays a dialog box with list of AD Policy stores ******************************************************************************/ class CBrowseADStoreDlg : public CHelpEnabledDialog { public: CBrowseADStoreDlg(CList&strList, CString& strSelectedADStorePath) :CHelpEnabledDialog(IDD_BROWSE_AD_STORE), m_strList(strList), m_strSelectedADStorePath(strSelectedADStorePath) { } virtual BOOL OnInitDialog(); virtual void OnOK(); private: CList &m_strList; CString& m_strSelectedADStorePath; }; BOOL CBrowseADStoreDlg:: OnInitDialog() { CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST); ASSERT(pListCtrl); // //Initialize the list control // ListView_SetImageList(pListCtrl->GetSafeHwnd(), LoadImageList(::AfxGetInstanceHandle (), MAKEINTRESOURCE(IDB_ICONS)), LVSIL_SMALL); //Add ListBox Extended Style pListCtrl->SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); //Add List box Columns AddColumnToListView(pListCtrl,Col_For_Browse_ADStore_Page); POSITION pos = m_strList.GetHeadPosition(); for (int i=0;i < m_strList.GetCount();i++) { pListCtrl->InsertItem(LVIF_TEXT|LVIF_STATE|LVIF_IMAGE, i, m_strList.GetNext(pos), 0, 0, iIconStore, NULL); } return TRUE; } void CBrowseADStoreDlg:: OnOK() { TRACE_METHOD_EX(DEB_SNAPIN,CBrowseADStoreDlg,OnOK) CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST); int iSelected = -1; if((iSelected = pListCtrl->GetNextItem(-1, LVIS_SELECTED)) != -1) { m_strSelectedADStorePath = pListCtrl->GetItemText(iSelected,0); } CHelpEnabledDialog::OnOK(); } //+---------------------------------------------------------------------------- // Function:BrowseAdStores // Synopsis:Displays a dialog box with list of AD stores available. // Arguments:strDN: Gets the selected ad store name //----------------------------------------------------------------------------- void BrowseAdStores(IN HWND hwndOwner, OUT CString& strDN, IN CADInfo& refAdInfo) { TRACE_FUNCTION_EX(DEB_SNAPIN,BrowseAdStores) CList strList; if(SUCCEEDED(GetListOfAuthorizationStore(refAdInfo, strList))) { if(!strList.IsEmpty()) { CBrowseADStoreDlg dlg(strList,strDN); dlg.DoModal(); } else { DisplayInformation(hwndOwner, IDS_NO_AD_STORE); } } else { //Display Error DisplayError(hwndOwner, IDS_CANNOT_ACCESS_AD); } } //+---------------------------------------------------------------------------- // Function:LoadIcons // Synopsis:Adds icons to imagelist //----------------------------------------------------------------------------- HRESULT LoadIcons(LPIMAGELIST pImageList) { TRACE_FUNCTION_EX(DEB_SNAPIN,LoadIcons) if(!pImageList) { ASSERT(pImageList); return E_POINTER; } struct RESID2IICON { UINT uIconId; // Icon resource ID int iIcon; // Index of the icon in the image list }; const static RESID2IICON rgzLoadIconList[] = { {IDI_UNKNOWN_SID, iIconUnknownSid}, {IDI_COMPUTER, iIconComputerSid}, {IDI_GROUP, iIconGroup}, //iIconLocalGroup, //This is not used, but since its in the imagelist // //i added an entry here {IDI_USER, iIconUser,}, { IDI_BASIC_GROUP, iIconBasicGroup}, { IDI_LDAP_GROUP, iIconLdapGroup}, { IDI_OPERATION, iIconOperation}, { IDI_TASK, iIconTask}, { IDI_ROLE_DEFINITION, iIconRoleDefinition}, { IDI_STORE, iIconStore}, { IDI_APP, iIconApplication}, { IDI_ROLE, iIconRole}, { IDI_ROLE_SNAPIN, iIconRoleSnapin}, { IDI_SCOPE, iIconScope}, { IDI_CONTAINER, iIconContainer}, { 0, 0} // Must be last }; for (int i = 0; rgzLoadIconList[i].uIconId != 0; i++) { HICON hIcon = ::LoadIcon (AfxGetInstanceHandle (), MAKEINTRESOURCE (rgzLoadIconList[i].uIconId)); ASSERT (hIcon && "Icon ID not found in resources"); pImageList->ImageListSetIcon ((PLONG_PTR) hIcon, rgzLoadIconList[i].iIcon); } return S_OK; } //+---------------------------------------------------------------------------- // Function: LoadImageList // Synopsis: Loads image list //----------------------------------------------------------------------------- HIMAGELIST LoadImageList(HINSTANCE hInstance, LPCTSTR pszBitmapID) { HIMAGELIST himl = NULL; HBITMAP hbm = LoadBitmap(hInstance, pszBitmapID); if (hbm != NULL) { BITMAP bm; GetObject(hbm, sizeof(BITMAP), &bm); himl = ImageList_Create(bm.bmHeight, // height == width bm.bmHeight, ILC_COLOR | ILC_MASK, bm.bmWidth / bm.bmHeight, 0); // don't need to grow if (himl != NULL) ImageList_AddMasked(himl, hbm, CLR_DEFAULT); DeleteObject(hbm); } return himl; } //+---------------------------------------------------------------------------- // Function: AddExtensionToFileName // Synopsis: Functions adds .xml extension to name of file if no extension // is present. // Arguments: // Returns: //----------------------------------------------------------------------------- VOID AddExtensionToFileName(IN OUT CString& strFileName) { if(strFileName.IsEmpty()) return; //if the last char is "\" don't do anything if((strFileName.ReverseFind(L'\\') + 1) == strFileName.GetLength()) return; int iLastDot = strFileName.ReverseFind(L'.'); if(iLastDot != -1) { //if there are three chars after last dot, //file has extension. Index returned is zero based if(strFileName.GetLength() == (iLastDot + 3 + 1)) return; } //File doesn't have extension. Add extension to the file. strFileName += g_pszFileStoreExtension; } //+---------------------------------------------------------------------------- // Function: GetFileExtension // Synopsis: Get the extension of the file. //----------------------------------------------------------------------------- BOOL GetFileExtension(IN const CString& strFileName, OUT CString& strExtension) { if(strFileName.IsEmpty()) return FALSE; //Find the position of last dot int iLastDot = strFileName.ReverseFind(L'.'); if(iLastDot != -1) { strExtension = strFileName.Right(strFileName.GetLength() - (iLastDot+1)); return TRUE; } return FALSE; } //+---------------------------------------------------------------------------- // Function:GetCurrentWorkingDirectory // Synopsis:Gets the current working directory //----------------------------------------------------------------------------- BOOL GetCurrentWorkingDirectory(IN OUT CString& strCWD) { TRACE_FUNCTION_EX(DEB_SNAPIN,GetCurrentWorkingDirectory) strCWD.Empty(); LPWSTR pszBuffer = NULL; do { int nLen = 0; WCHAR szBuffer[MAX_PATH]; if((nLen = GetCurrentDirectory(MAX_PATH,szBuffer)) != 0) { //If the return value is less than MAX_PATH, function //was successful. If its greater, buffer is not big enough, //dynamically allocate it below. if(nLen < MAX_PATH) { strCWD = szBuffer; break; } //Bigger buffer is required pszBuffer = new WCHAR[nLen]; if(pszBuffer) { if((nLen = GetCurrentDirectory(nLen,pszBuffer)) != 0) { strCWD = pszBuffer; break; } } } }while(0);//FALSE LOOP if(pszBuffer) delete [] pszBuffer; //Add \ at the end of string if(!strCWD.IsEmpty() && ((strCWD.ReverseFind(L'\\') + 1) != strCWD.GetLength())) { strCWD += L'\\'; } return !strCWD.IsEmpty(); } VOID RemoveItemsFromActionMap(ActionMap& mapActionItem) { for (ActionMap::iterator it = mapActionItem.begin(); it != mapActionItem.end(); ++it) { delete (*it).second; } } /****************************************************************************** Class: CADInfo Purpose:Keeps a cache of Active Directory info avoiding multiple binds ******************************************************************************/ HRESULT CADInfo:: GetRootDSE() { TRACE_METHOD_EX(DEB_SNAPIN,CADInfo,GetRootDSE) HRESULT hr = S_OK; if(m_spRootDSE == NULL) { // //Bind to RootDSE // hr = AzRoleAdsOpenObject(L"LDAP://RootDSE", NULL, NULL, IID_IADs, (void**)&m_spRootDSE); CHECK_HRESULT(hr); } return hr; } const CString& CADInfo::GetDomainDnsName() { TRACE_METHOD_EX(DEB_SNAPIN,CADInfo,GetDomainDnsName) if(m_strDomainDnsName.IsEmpty()) { if(m_strDomainDn.IsEmpty()) GetDomainDn(); if(!m_strDomainDn.IsEmpty()) { TranslateNameFromDnToDns(m_strDomainDn,m_strDomainDnsName); Dbg(DEB_SNAPIN, "Domain Dns is: %ws\n", CHECK_NULL((LPCTSTR)m_strDomainDnsName)); } } return m_strDomainDnsName; } const CString& CADInfo::GetDomainDn() { TRACE_METHOD_EX(DEB_SNAPIN,CADInfo,GetDomainDn) if((m_spRootDSE != NULL) && m_strDomainDn.IsEmpty()) { // Get the default name VARIANT Default; VariantInit(&Default); HRESULT hr = m_spRootDSE->Get (CComBSTR(L"defaultNamingContext"), &Default); if(SUCCEEDED(hr)) { ASSERT(VT_BSTR == Default.vt); if(VT_BSTR == Default.vt) { m_strDomainDn = Default.bstrVal; ::VariantClear(&Default); Dbg(DEB_SNAPIN, "Domain Dn is: %ws\n", CHECK_NULL((LPCTSTR)m_strDomainDn)); } } } return m_strDomainDn; } const CString& CADInfo::GetRootDomainDnsName() { TRACE_METHOD_EX(DEB_SNAPIN,CADInfo,GetRootDomainDnsName) if(m_strRootDomainDnsName.IsEmpty()) { if(m_strRootDomainDn.IsEmpty()) GetRootDomainDn(); if(!m_strRootDomainDn.IsEmpty()) { TranslateNameFromDnToDns(m_strRootDomainDn,m_strRootDomainDnsName); Dbg(DEB_SNAPIN, "Root Domain Dns is: %ws\n", CHECK_NULL((LPCTSTR)m_strRootDomainDnsName)); } } return m_strRootDomainDnsName; } const CString& CADInfo::GetRootDomainDn() { TRACE_METHOD_EX(DEB_SNAPIN,CADInfo,GetRootDomainDn) if((m_spRootDSE != NULL) && m_strRootDomainDn.IsEmpty()) { // Get the default name VARIANT Default; VariantInit(&Default); HRESULT hr = m_spRootDSE->Get(CComBSTR(L"rootDomainNamingContext"), &Default); if(SUCCEEDED(hr)) { //Convert DN to DNS name m_strRootDomainDn = Default.bstrVal; ::VariantClear(&Default); Dbg(DEB_SNAPIN, "Root Domain DN is: %ws\n", CHECK_NULL((LPCTSTR)m_strRootDomainDn)); } } return m_strRootDomainDn; } BOOL GetDcNameForDomain(IN const CString& strDomainName, OUT CString& strDCName) { TRACE_FUNCTION_EX(DEB_SNAPIN,GetDcNameForDomain) if(strDomainName.IsEmpty()) { return FALSE; } strDCName.Empty(); PDOMAIN_CONTROLLER_INFO pDomainInfo = NULL; //Get the DC Name DWORD dwErr = DsGetDcName(NULL, (LPCWSTR)strDomainName, NULL, NULL, DS_IS_DNS_NAME|DS_DIRECTORY_SERVICE_REQUIRED, &pDomainInfo); if((ERROR_SUCCESS == dwErr) && pDomainInfo) { LPWSTR pszDCName = pDomainInfo->DomainControllerName; //The returned computer name is prefixed with \\ //Remove backslashes if(pszDCName[0] == L'\\' && pszDCName[1] == L'\\') pszDCName += 2; //If a DNS-style name is returned, it is terminated with a period, //indicating that the returned name is an absolute (non-relative) //DNS name. //We don't need period, remove it //DomainControllerName is in DNS format. if(pDomainInfo->Flags & DS_DNS_CONTROLLER_FLAG) { size_t dwLen = wcslen(pszDCName); if(dwLen && (L'.' == pszDCName[dwLen -1])) { pszDCName[dwLen -1] = L'\0'; } } Dbg(DEB_SNAPIN, "DC is %ws\n", pszDCName); strDCName = pszDCName; NetApiBufferFree(pDomainInfo); return TRUE; } return FALSE; } const CString& CADInfo:: GetRootDomainDCName() { TRACE_METHOD_EX(DEB_SNAPIN,CADInfo,GetRootDomainDCName) if((m_spRootDSE != NULL) && m_strRootDomainDcName.IsEmpty()) { GetDcNameForDomain(GetRootDomainDnsName(),m_strRootDomainDcName); } return m_strRootDomainDcName; } const CString& CADInfo:: GetDomainDCName() { TRACE_METHOD_EX(DEB_SNAPIN,CADInfo,GetDomainDCName) if((m_spRootDSE != NULL) && m_strDomainDcName.IsEmpty()) { GetDcNameForDomain(GetDomainDnsName(),m_strDomainDcName); } return m_strDomainDcName; } //+-------------------------------------------------------------------------- // Function: AzRoleAdsOpenObject // Synopsis: A thin wrapper around ADsOpenObject //+-------------------------------------------------------------------------- HRESULT AzRoleAdsOpenObject(LPWSTR lpszPathName, LPWSTR lpszUserName, LPWSTR lpszPassword, REFIID riid, VOID** ppObject, BOOL bBindToServer) { static DWORD additionalFlags = GetADsOpenObjectFlags(); DWORD dwFlags = ADS_SECURE_AUTHENTICATION | additionalFlags; if (bBindToServer) { // // If we know we are connecting to a specific server and not domain in general // then pass the ADS_SERVER_BIND flag to save ADSI the trouble of figuring it out // dwFlags |= ADS_SERVER_BIND; } // //Get IDirectorySearch Object // return ADsOpenObject(lpszPathName, lpszUserName, lpszPassword, additionalFlags, riid, ppObject); } VOID GetDefaultADContainerPath(IN CADInfo& refAdInfo, IN BOOL bAddServer, IN BOOL bAddLdap, OUT CString& strPath) { strPath.Empty(); if(!refAdInfo.GetDomainDn().IsEmpty()) { if(!refAdInfo.GetDomainDCName().IsEmpty()) { if(bAddLdap) { strPath += L"LDAP://"; } if(bAddServer) { strPath += refAdInfo.GetDomainDCName(); strPath += L"/"; } strPath += g_pszProgramDataPrefix; strPath += refAdInfo.GetDomainDn(); } else { if(bAddLdap) { strPath = L"LDAP://"; } strPath += g_pszProgramDataPrefix; strPath += refAdInfo.GetDomainDn(); } } } //+-------------------------------------------------------------------------- // Function: IsBizRuleWritable // Synopsis: Checks if bizrules are writable for this object //+-------------------------------------------------------------------------- BOOL IsBizRuleWritable(HWND hWnd, CContainerAz& refBaseAz) { CScopeAz* pScopeAz = dynamic_cast(&refBaseAz); //Bizrules are always writable for at //application level if(!pScopeAz) { return TRUE; } BOOL bBizRuleWritable = TRUE; HRESULT hr = pScopeAz->BizRulesWritable(bBizRuleWritable); if(SUCCEEDED(hr) && !bBizRuleWritable) { DisplayInformation(hWnd, IDS_BIZRULE_NOT_ALLOWED, pScopeAz->GetName()); return FALSE; } return TRUE; } //+-------------------------------------------------------------------------- // Function: ParseStoreURL // Synopsis: Extracts the store name and type from a store url // store url are in format msldap://DN or msxml://filepath //+-------------------------------------------------------------------------- void ParseStoreURL(IN const CString& strStoreURL, OUT CString& refstrStoreName, OUT LONG& reflStoreType) { if(_wcsnicmp(strStoreURL,g_szMSXML,wcslen(g_szMSXML)) == 0 ) { reflStoreType = AZ_ADMIN_STORE_XML; refstrStoreName = strStoreURL.Mid((int)wcslen(g_szMSXML)); } else if(_wcsnicmp(strStoreURL,g_szMSLDAP,wcslen(g_szMSLDAP)) == 0 ) { reflStoreType = AZ_ADMIN_STORE_AD; refstrStoreName = strStoreURL.Mid((int)wcslen(g_szMSLDAP)); } else { reflStoreType = AZ_ADMIN_STORE_INVALID; refstrStoreName = strStoreURL; } } /****************************************************************************** Class: CCommandLineOptions Purpose:class for reading the command line options for console file ******************************************************************************/ void CCommandLineOptions:: Initialize() { TRACE_METHOD_EX(DEB_SNAPIN,CCommandLineOptions,Initialize) //This should be called only once if(m_bInit) { return; } m_bInit = TRUE; // see if we have command line arguments // Count of arguments int cArgs = 0; // Array of pointers to string LPCWSTR * lpServiceArgVectors = (LPCWSTR *)CommandLineToArgvW(GetCommandLineW(), &cArgs); if (lpServiceArgVectors == NULL || cArgs <= 2) { // none, just return return; } m_bCommandLineSpecified = TRUE; CString strStoreURL = lpServiceArgVectors[2]; ParseStoreURL(strStoreURL, m_strStoreName, m_lStoreType); Dbg(DEB_SNAPIN, "Store URL Name entered at commandline is %ws\n", CHECK_NULL(strStoreURL)); Dbg(DEB_SNAPIN, "Store Name entered at commandline is %ws\n", CHECK_NULL(m_strStoreName)); Dbg(DEB_SNAPIN, "AD store type entered is: %u\n", m_lStoreType); } //+---------------------------------------------------------------------------- // Function: OpenAdminManager // Synopsis: Open an existing Authorization Store adds // corresponding adminManager object to snapin // Arguments:IN hWnd: Handle of window for dialog box // IN bOpenFromSavedConsole: True if open is in response to a console // file. // IN lStoreType: XML or AD // IN strName: Name of store // IN strScriptDir : Script directory // IN pRootData: Snapin Rootdata // IN pComponentData: ComponentData // Returns: //----------------------------------------------------------------------------- HRESULT OpenAdminManager(IN HWND hWnd, IN BOOL bOpenFromSavedConsole, IN ULONG lStoreType, IN const CString& strStoreName, IN const CString& strScriptDir, IN CRootData* pRootData, IN CComponentDataObject* pComponentData) { TRACE_FUNCTION_EX(DEB_SNAPIN,OpenAdminManager) if(!pRootData || !pComponentData) { ASSERT(pRootData); ASSERT(pComponentData); return E_POINTER; } //NTRAID#NTBUG9-706617-2002/07/17-hiteshr Our validation code cannot validate //ADAM dn. Do not do any validation. ////Vaidate the store name //if(!ValidateStoreTypeAndName(hWnd, // lStoreType, // strStoreName)) //{ // return E_INVALIDARG; //} HRESULT hr = OpenCreateAdminManager(FALSE, bOpenFromSavedConsole, lStoreType, strStoreName, L"", strScriptDir, pRootData, pComponentData); if(FAILED(hr)) { //Display Error if(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { if(!bOpenFromSavedConsole) { ::DisplayError(hWnd, IDS_ADMIN_MANAGER_NOT_FOUND, (LPCTSTR)strStoreName); } else { ::DisplayError(hWnd, IDS_CANNOT_FIND_AUTHORIZATION_STORE, (LPCTSTR)strStoreName); } } else if(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME)) { ErrorMap * pErrorMap = GetErrorMap(ADMIN_MANAGER_AZ); ::DisplayError(hWnd, pErrorMap->idInvalidName, pErrorMap->pszInvalidChars); } else { //Display Generic Error CString strError; GetSystemError(strError, hr); ::DisplayError(hWnd, IDS_OPEN_ADMIN_MANAGER_GENERIC_ERROR, (LPCTSTR)strError); } } return hr; } //+---------------------------------------------------------------------------- // Function: GetDisplayNameFromStoreURL // Synopsis: Get the display name for the store. // Arguments: strPolicyURL: This is store url in msxml://filepath or // msldap://dn format. // strDisplayName: This gets the display name. For xml, display // name is name of file, for AD its name of leaf element // Returns: //----------------------------------------------------------------------------- void GetDisplayNameFromStoreURL(IN const CString& strPolicyURL, OUT CString& strDisplayName) { //Store URL format has msxml:// or msldap:// prefix //Get the store name without any prefix CString strStorePath; LONG lStoreType; ParseStoreURL(strPolicyURL, strStorePath, lStoreType); //Default Display Name of store is path without prefix. strDisplayName = strStorePath; if(AZ_ADMIN_STORE_INVALID == lStoreType) { ASSERT(FALSE); return; } //For XML store, display name is name of the file if(AZ_ADMIN_STORE_XML == lStoreType) { strDisplayName = PathFindFileName(strStorePath); } //For AD store, display name is name of the leaf element else { do { CComPtr spPathName; HRESULT hr = spPathName.CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER); BREAK_ON_FAIL_HRESULT(hr); //The path which we have right now can be dn or server/dn. //append LDAP:// to it. CString strLDAPStorePath = g_szLDAP + strStorePath; hr = spPathName->Set(CComBSTR(strLDAPStorePath), ADS_SETTYPE_FULL); BREAK_ON_FAIL_HRESULT(hr); //Get the leaf element. This will return leaf element in the //format cn=foo. We only want "foo". CComBSTR bstrLeaf; hr = spPathName->Retrieve(ADS_FORMAT_LEAF ,&bstrLeaf); BREAK_ON_FAIL_HRESULT(hr); if(bstrLeaf.Length()) { strDisplayName = bstrLeaf; strDisplayName.Delete(0,strDisplayName.Find(L'=') + 1); } }while(0); } } void SetXMLStoreDirectory(IN CRoleRootData& roleRootData, IN const CString& strXMLStorePath) { CString strXMLStoreDirectory = GetDirectoryFromPath(strXMLStorePath); roleRootData.SetXMLStorePath(strXMLStoreDirectory); } //+---------------------------------------------------------------------------- // Function: GetDirectoryFromPath // Synopsis: Removes the file name from the input file path and return // the folder path. For Ex: Input is C:\temp\foo.xml. Return // value will be C:\temp\ //----------------------------------------------------------------------------- CString GetDirectoryFromPath(IN const CString& strPath) { TRACE_FUNCTION_EX(DEB_SNAPIN,GetDirectoryFromPath) Dbg(DEB_SNAPIN, "Input path", CHECK_NULL(strPath)); CString strDir; if(strPath.GetLength() < MAX_PATH) { WCHAR szPath[MAX_PATH]; HRESULT hr = StringCchCopy(szPath,MAX_PATH,(LPCWSTR)strPath); if(FAILED(hr)) return strDir; if(!PathRemoveFileSpec(szPath)) return strDir; PathAddBackslash(szPath); strDir = szPath; } Dbg(DEB_SNAPIN, "Output Dir", CHECK_NULL(strDir)); return strDir; } //+---------------------------------------------------------------------------- // Function: ConvertToExpandedAndAbsolutePath // Synopsis: Expands the environment variables in the input path and also // makes it absolute if necessary. //----------------------------------------------------------------------------- void ConvertToExpandedAndAbsolutePath(IN OUT CString& strPath) { TRACE_FUNCTION_EX(DEB_SNAPIN,ConvertToExpandedAndAbsolutePath) Dbg(DEB_SNAPIN, "Input name", CHECK_NULL(strPath)); do { // //Expand evironment variables in the path // WCHAR szExpandedPath[MAX_PATH]; DWORD dwSize = ExpandEnvironmentStrings(strPath, szExpandedPath, MAX_PATH); //Buffer is small, allocate required buffer and try again if(dwSize > MAX_PATH) { LPWSTR pszExpandedPath = (LPWSTR)LocalAlloc(LPTR,dwSize*sizeof(WCHAR)); if(pszExpandedPath) { dwSize = ExpandEnvironmentStrings(strPath, pszExpandedPath, dwSize); if(dwSize) { strPath = pszExpandedPath; } LocalFree(pszExpandedPath); pszExpandedPath = NULL; if(!dwSize) { break; } } } else if(dwSize) { strPath = szExpandedPath; } else { break; } //Make absolute path WCHAR szAbsolutePath[MAX_PATH]; dwSize = GetFullPathName(strPath, MAX_PATH, szAbsolutePath, NULL); //Buffer is small if(dwSize > MAX_PATH) { LPWSTR pszAbsolutePath = (LPWSTR)LocalAlloc(LPTR,dwSize*sizeof(WCHAR)); if(pszAbsolutePath) { dwSize = GetFullPathName(strPath, MAX_PATH, pszAbsolutePath, NULL); if(dwSize) { strPath = pszAbsolutePath; } LocalFree(pszAbsolutePath); pszAbsolutePath = NULL; } } else if(dwSize) { strPath = szAbsolutePath; } }while(0); Dbg(DEB_SNAPIN, "Output name", CHECK_NULL(strPath)); } //+---------------------------------------------------------------------------- // Function: PreprocessScript // Synopsis: Script is read from XML file and displayed multi line edit control. // End of line in the XML is indicated by LF instead of CRLF sequence, // however Edit Control requires CRLF sequence to format correctly and // with only LF it displays everything in a single line with a box for // LF char. This function checks if script uses LF for line termination // and changes it with CRLF sequence. //----------------------------------------------------------------------------- void PreprocessScript(CString& strScript) { WCHAR chLF = 0x0a; WCHAR szCRLF[3] = {0x0D, 0x0A, 0}; if(strScript.Find(chLF) != -1 && strScript.Find(szCRLF) == -1) { CString strProcessedScript; int len = strScript.GetLength(); for( int i = 0; i < len; ++i) { WCHAR ch = strScript.GetAt(i); if(ch == chLF) { strProcessedScript += szCRLF; } else { strProcessedScript += ch; } } strScript = strProcessedScript; } }