/*--------------------------------------------------------------------------*\ Module: drv.cpp Purpose: routines for dealing with drivers and their configuration Copyright (c) 1998-1999 Microsoft Corporation History: 8/11/93 CBB - Hack-o-rama from NickH's stuff 10/15/98 ToddB - Major rewrite of ancient crap \*--------------------------------------------------------------------------*/ #include "cplPreComp.h" #include "drv.h" #include "tlnklist.h" #include #include #define DBG_ASSERT(x,y) #define CPL_SUCCESS 0 #define CPL_APP_ERROR 100 #define CPL_BAD_DRIVER 108 #define CPL_MAX_STRING 132 // biggest allowed string //---------- // Externs //---------- typedef BOOL ( APIENTRY PGETFILEVERSIONINFO( LPTSTR lptstrFilename, // pointer to filename string DWORD dwHandle, // ignored DWORD dwLen, // size of buffer LPVOID lpData // pointer to buffer to receive file-version info. )); PGETFILEVERSIONINFO *gpGetFileVersionInfo; typedef DWORD ( APIENTRY PGETFILEVERSIONINFOSIZE( LPTSTR lptstrFilename, // pointer to filename string LPDWORD lpdwHandle // pointer to variable to receive zero )); PGETFILEVERSIONINFOSIZE *gpGetFileVersionInfoSize; //------------ // Public Data //------------ LPLINEPROVIDERLIST glpProviderList; //------------- // Private Data //------------- static TCHAR gszVarFileInfo[] = TEXT("\\VarFileInfo\\Translation"); static TCHAR gszStringFileInfo[] = TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"); static TCHAR gszDriverFiles[] = TEXT("\\*.tsp"); // These are proc names passed to GetProcAddress and are therefore ANSI strings static CHAR gszProviderInstall[] = "TSPI_providerInstall"; static CHAR gszProviderRemove[] = "TSPI_providerRemove"; static CHAR gszProviderSetup[] = "TSPI_providerConfig"; TCHAR gszHelpFile[] = TEXT("tapi.hlp"); //---------------------------- // Private Function Prototypes //---------------------------- BOOL VerifyProcExists( LPTSTR lpszFile, LPSTR lpszProcName ); UINT GetProviderFileDesc( LPTSTR lpszFile, LPTSTR lpszDesc, int cchDesc ); BOOL FillAddDriverList( HWND hwndParent, HWND hwndList ); BOOL AddProvider( HWND hwndParent, HWND hwndList, LPTSTR lpszDriverFile ); LPTSTR ProviderIDToFilename( DWORD dwProviderID ); BOOL RefreshProviderList(); /*--------------------------------------------------------------------------*\ Function: VerifyProcExists Purpose: Verifies that the specified proceedure exists in the specified service provider \*--------------------------------------------------------------------------*/ BOOL VerifyProcExists( LPTSTR lpszFile, LPSTR lpszProcName ) { BOOL fResult = TRUE; HINSTANCE hProviderInst; SetLastError(0); hProviderInst = LoadLibrary( lpszFile ); if ( hProviderInst == NULL ) { #ifdef MEMPHIS // return TRUE for now - assume it is a 16 bit // service provider. thunk sp can handle the // failure cases. fResult = TRUE; #else fResult = FALSE; #endif goto done; } // end if #ifdef MEMPHIS if (GetLastError() == ERROR_BAD_EXE_FORMAT) { // 16 bit DLL return TRUE; } #endif if (GetProcAddress( hProviderInst, lpszProcName ) == NULL) { LOG((TL_ERROR, "GetProcAddress for \"%hs\" failed on file %s", lpszProcName, lpszFile )); fResult = FALSE; goto done; } // end if done: if ( hProviderInst != NULL ) FreeLibrary( hProviderInst ); return fResult; } /*--------------------------------------------------------------------------*\ Function: FillDriverList Purpose: Use lineGetProviderList to retrieve provider list and insert into listbox. \*--------------------------------------------------------------------------*/ BOOL FillDriverList( HWND hwndList ) { BOOL uResult; UINT uIndex; UINT uListIndex; LPLINEPROVIDERENTRY lpProviderEntry; if (!RefreshProviderList()) { LOG((TL_ERROR, "Failing FillDriverList because RefreshProviderList returned FALSE")); return FALSE; } DBG_ASSERT( glpProviderList, "Uninitialized Provider List after refresh" ); SendMessage( hwndList, WM_SETREDRAW, FALSE, 0 ); SendMessage( hwndList, LB_RESETCONTENT, 0, 0 ); // loop through the provider list //------------------------------- lpProviderEntry = (LPLINEPROVIDERENTRY)((LPBYTE)glpProviderList + glpProviderList->dwProviderListOffset); // // Provider list integrity check // DBG_ASSERT( glpProviderList->dwTotalSize >= (glpProviderList->dwNumProviders * sizeof( LINEPROVIDERENTRY )), "TAPI returned lineProviderList structure that is too small for number of providers" ); for ( uIndex = 0; uIndex < glpProviderList->dwNumProviders; uIndex++ ) { LPTSTR lpszProviderFilename; TCHAR szFriendlyName[CPL_MAX_STRING]; // // Another provider list integrity check // DBG_ASSERT( lpProviderEntry[uIndex].dwProviderFilenameOffset + lpProviderEntry[uIndex].dwProviderFilenameSize <= glpProviderList->dwTotalSize, "TAPI LINEPROVIDERLIST too small to hold provider filename" ); // Get an entry to put in the list box //------------------------------------ lpszProviderFilename = (LPTSTR)((LPBYTE)glpProviderList + lpProviderEntry[uIndex].dwProviderFilenameOffset); // Determine the user-friendly name //--------------------------------- #ifdef MEMPHIS // if it's the thunk sp, don't show it in the list if (!lstrcmpi(lpszProviderFilename, "tsp3216l.tsp")) { continue; } #endif uResult = GetProviderFileDesc( lpszProviderFilename, szFriendlyName, ARRAYSIZE(szFriendlyName) ); LOG((TL_INFO, "Provider friendly name: %s", szFriendlyName)); if (uResult != CPL_SUCCESS && uResult != CPL_BAD_DRIVER) // just leave bad driver in list { uResult = FALSE; goto done; } else { uResult = TRUE; } // slam it into the list box //-------------------------- uListIndex = (UINT)SendMessage( hwndList, LB_ADDSTRING, 0, (LPARAM)szFriendlyName ); LOG((TL_INFO, "Setting item for index %ld, value=0x%08lx", (DWORD)uListIndex, (DWORD)(lpProviderEntry[uIndex].dwPermanentProviderID) )); SendMessage( hwndList, LB_SETITEMDATA, uListIndex, (LPARAM)(lpProviderEntry[uIndex].dwPermanentProviderID) ); } if (glpProviderList->dwNumProviders == 0) { // no providers, add in default string! //------------------------------------- TCHAR szText[CPL_MAX_STRING]; LoadString(GetUIInstance(),IDS_NOSERVICEPROVIDER,szText,ARRAYSIZE(szText)); uListIndex = (UINT)SendMessage( hwndList, LB_ADDSTRING, 0, (LPARAM)szText); SendMessage( hwndList, LB_SETITEMDATA, uListIndex, 0 ); } uResult = TRUE; done: SendMessage( hwndList, LB_SETCURSEL, 0, 0 ); // set focus to the top guy SendMessage( hwndList, WM_SETREDRAW, TRUE, 0 ); return uResult; } /*--------------------------------------------------------------------------*\ Function: SetupDriver Purpose: Calls lineConfigProvider \*--------------------------------------------------------------------------*/ BOOL SetupDriver( HWND hwndParent, HWND hwndList ) { LRESULT lResult; LRESULT dwProviderID; LONG res; // get the id and tell tapi to configure the provider //--------------------------------------------------- lResult = SendMessage( hwndList, LB_GETCURSEL, 0, 0 ); dwProviderID = SendMessage( hwndList, LB_GETITEMDATA, (WPARAM)lResult, 0L ); if ((dwProviderID == (LRESULT)LB_ERR) || (!dwProviderID)) { LOG((TL_WARN, "Warning: strange... dwProviderID= 0x%08lx (uResult=0x%08lx)", (DWORD)dwProviderID, (DWORD)lResult)); return FALSE; } lResult = lineConfigProvider( hwndParent, (DWORD)dwProviderID ); if (lResult) { LOG((TL_WARN, "Warning: lineConfigProvider failure %#08lx", lResult )); return FALSE; } return TRUE; } /*--------------------------------------------------------------------------*\ Function: RemoveSelectedDriver Purpose: Calls lineRemoveProvider \*--------------------------------------------------------------------------*/ BOOL RemoveSelectedDriver( HWND hwndParent, HWND hwndList ) { UINT uResult; LRESULT lResult; LRESULT lrListIndex; LRESULT lrProviderID; // find the one we should remove //------------------------------ lrListIndex = SendMessage( hwndList, LB_GETCURSEL, 0, 0 ); lrProviderID = SendMessage( hwndList, LB_GETITEMDATA, lrListIndex, 0 ); LOG((TL_TRACE, "Removing provider ID = %#08lx", (DWORD)lrProviderID )); if ((lrProviderID == (LRESULT)LB_ERR) || (!lrProviderID)) { uResult = FALSE; goto done; } // ask TAPI to remove this provider //--------------------------------- lResult = lineRemoveProvider( (DWORD)lrProviderID, hwndParent ); if (lResult) { LOG((TL_WARN, "Warning: lineRemoveProvider failure %#08lx", lResult )); uResult = FALSE; goto done; } // remove him from the list box //----------------------------- lResult = SendMessage( hwndList, LB_DELETESTRING, lrListIndex, 0 ); if (lResult == LB_ERR ) { uResult = FALSE; goto done; } if ( lResult == 0 ) { // no providers, add in default string! //------------------------------------- TCHAR szText[CPL_MAX_STRING]; LoadString(GetUIInstance(),IDS_NOSERVICEPROVIDER,szText,ARRAYSIZE(szText)); lResult = SendMessage( hwndList, LB_ADDSTRING, 0, (LPARAM)szText); SendMessage( hwndList, LB_SETITEMDATA, (WPARAM)lResult, 0 ); // mark! } uResult = TRUE; done: SendMessage( hwndList, LB_SETCURSEL, 0, 0 ); // set focus to the top guy UpdateDriverDlgButtons(hwndParent); return uResult; } /*--------------------------------------------------------------------------*\ Function: GetProviderFileDesc Purpose: Reads the driver description from it's version info stuff \*--------------------------------------------------------------------------*/ UINT GetProviderFileDesc( LPTSTR lpszFile, LPTSTR lpszDesc, int cchDesc) { UINT uResult; UINT uItemSize; DWORD dwSize; DWORD dwVerHandle; LPTSTR lpszBuffer; LPBYTE lpbVerData; TCHAR szItem[1000]; lpbVerData = NULL; lstrcpyn( lpszDesc, lpszFile, cchDesc ); // returns filename as description if we have any errors { HINSTANCE hVersion = NULL; if ( NULL == gpGetFileVersionInfo ) { hVersion = LoadLibrary( TEXT("Version.dll") ); if ( NULL == hVersion ) { LOG((TL_ERROR, "LoadLibrary('VERSION.DLL') failed! err=0x%08lx", GetLastError() )); return FALSE; } gpGetFileVersionInfo = (PGETFILEVERSIONINFO *)GetProcAddress( hVersion, #ifdef UNICODE "GetFileVersionInfoW" #else "GetFileVersionInfoA" #endif ); if ( NULL == gpGetFileVersionInfo ) { LOG((TL_ERROR, "GetProcAddress('VERSION.DLL', 'GetFileVersionInfo') failed! err=0x%08lx", GetLastError() )); return FALSE; } } if ( NULL == gpGetFileVersionInfoSize ) { if ( NULL == hVersion ) { hVersion = LoadLibrary( TEXT("Version.dll") ); } if ( NULL == hVersion ) // Is it _STILL_ NULL? { LOG((TL_ERROR, "LoadLibrary('VERSION.DLL') failed! err=0x%08lx", GetLastError() )); return FALSE; } gpGetFileVersionInfoSize = (PGETFILEVERSIONINFOSIZE *)GetProcAddress( hVersion, #ifdef UNICODE "GetFileVersionInfoSizeW" #else "GetFileVersionInfoSizeA" #endif ); if ( NULL == gpGetFileVersionInfoSize ) { LOG((TL_ERROR, "GetProcAddress('VERSION.DLL', 'GetFileVersionInfoSize') failed! err=0x%08lx", GetLastError() )); gpGetFileVersionInfo = NULL; FreeLibrary( hVersion ); return FALSE; } } } if ((dwSize = gpGetFileVersionInfoSize( lpszFile, &dwVerHandle )) == 0) { LOG((TL_ERROR, "GetFileVersionInfoSize failure for %s", lpszFile )); uResult = CPL_BAD_DRIVER; goto done; } lpbVerData = (LPBYTE)GlobalAllocPtr( GPTR, dwSize + 10 ); if ( lpbVerData == NULL ) { uResult = CPL_APP_ERROR; goto done; } if ( gpGetFileVersionInfo( lpszFile, dwVerHandle, dwSize, lpbVerData ) == FALSE ) { LOG((TL_ERROR, "GetFileVersionInfo failure for %s", lpszFile )); uResult = CPL_BAD_DRIVER; goto done; } lstrcpy( szItem, gszVarFileInfo ); // bug in VerQueryValue, can't handle static CS based str { HINSTANCE hVersion; typedef BOOL ( APIENTRY PVERQUERYVALUE( const LPVOID pBlock, // address of buffer for version resource LPTSTR lpSubBlock, // address of value to retrieve LPVOID *lplpBuffer, // address of buffer for version pointer PUINT puLen // address of version-value length buffer )); PVERQUERYVALUE *pVerQueryValue = NULL; hVersion = LoadLibrary( TEXT("Version.dll") ); if ( NULL == hVersion ) { LOG((TL_ERROR, "LoadLibrary('VERSION.DLL') failed! err=0x%08lx", GetLastError() )); return FALSE; } pVerQueryValue = (PVERQUERYVALUE *)GetProcAddress( hVersion, #ifdef UNICODE "VerQueryValueW" #else "VerQueryValueA" #endif ); if ( NULL == pVerQueryValue ) { LOG((TL_ERROR, "GetProcAddress('VERSION.DLL', 'VerQueryValue') failed! err=0x%08lx", GetLastError() )); FreeLibrary( hVersion ); return FALSE; } if ((pVerQueryValue( lpbVerData, szItem, (void**)&lpszBuffer, (LPUINT)&uItemSize ) == FALSE) || (uItemSize == 0)) { LOG((TL_ERROR, "ERROR: VerQueryValue failure for %s on file %s", szItem, lpszFile )); uResult = CPL_SUCCESS; // does not matter if this did not work! FreeLibrary( hVersion ); goto done; } // end if wsprintf( szItem, gszStringFileInfo, (WORD)*(LPWORD)lpszBuffer, (WORD)*(((LPWORD)lpszBuffer)+1) ); if ((pVerQueryValue( lpbVerData, szItem, (void**)&lpszBuffer, (LPUINT)&uItemSize ) == FALSE) || (uItemSize == 0)) { LOG((TL_ERROR, "ERROR: VerQueryValue failure for %s on file %s", szItem, lpszFile )); uResult = CPL_SUCCESS; // does not matter if this did not work! FreeLibrary( hVersion ); goto done; } // end if FreeLibrary( hVersion ); } lstrcpyn( lpszDesc, lpszBuffer, cchDesc ); uResult = CPL_SUCCESS; done: if ( lpbVerData ) GlobalFreePtr( lpbVerData ); return uResult; } #define MAX_PROVIDER_NAME 14 #define PROVIDERS_KEY TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Providers") #define NUM_PROVIDERS TEXT("NumProviders") typedef struct { LIST_ENTRY Entry; TCHAR szName[MAX_PROVIDER_NAME]; } INSTALLED_PROVIDER, *PINSTALLED_PROVIDER; typedef struct { LIST_ENTRY Head; DWORD dwEntries; } LIST_HEAD, *PLIST_HEAD; void BuildInstalledProviderList (PLIST_HEAD pListHead) { PINSTALLED_PROVIDER pProvider; HKEY hKeyProviders; DWORD dwNumProviders; DWORD cbData; DWORD i; TCHAR szValueName[24]=TEXT("ProviderFileName"); TCHAR *pNumber = &szValueName[16]; InitializeListHead (&pListHead->Head); pListHead->dwEntries = 0; if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, PROVIDERS_KEY, 0, KEY_READ, &hKeyProviders)) { return; } cbData = sizeof (dwNumProviders); if (ERROR_SUCCESS != RegQueryValueEx (hKeyProviders, NUM_PROVIDERS, NULL, NULL, (PBYTE)&dwNumProviders, &cbData) || 0 == dwNumProviders) { goto CloseKeyAndReturn; } pProvider = (PINSTALLED_PROVIDER)ClientAlloc (sizeof (INSTALLED_PROVIDER)); if (NULL == pProvider) { goto CloseKeyAndReturn; } for (i = 0; i < dwNumProviders; i++) { wsprintf (pNumber, TEXT("%d"), i); cbData = sizeof(pProvider->szName); if (ERROR_SUCCESS == RegQueryValueEx (hKeyProviders, szValueName, NULL, NULL, (PBYTE)pProvider->szName, &cbData)) { InsertHeadList (&pListHead->Head, &pProvider->Entry); pListHead->dwEntries ++; pProvider = (PINSTALLED_PROVIDER)ClientAlloc (sizeof (INSTALLED_PROVIDER)); if (NULL == pProvider) { goto CloseKeyAndReturn; } } } ClientFree (pProvider); CloseKeyAndReturn: RegCloseKey (hKeyProviders); } /*--------------------------------------------------------------------------*\ Function: FillAddDriverList Purpose: \*--------------------------------------------------------------------------*/ BOOL FillAddDriverList( HWND hwndParent, HWND hwndList ) { UINT uIndex; UINT uResult; LPTSTR lpszDrvFile; HANDLE hFindFile; WIN32_FIND_DATA ftFileInfo; TCHAR szFullPath[MAX_PATH+sizeof(gszDriverFiles)/sizeof(TCHAR)]; TCHAR szDrvDescription[CPL_MAX_STRING]; LIST_HEAD InstalledProvidersList; PINSTALLED_PROVIDER pProvider; SendMessage( hwndList, WM_SETREDRAW, FALSE, 0 ); SendMessage( hwndList, LB_RESETCONTENT, 0, 0 ); // build a list of installed providers, // so that we don't allow the user to install them again //------------------------------------------------------ BuildInstalledProviderList (&InstalledProvidersList); // get full path to windows/system dir //------------------------------------ uIndex = GetSystemDirectory( szFullPath, MAX_PATH); if ((0 == uIndex) || (MAX_PATH < uIndex)) { // Either the function failed, // or the path is greater than MAX_PATH uResult = FALSE; goto done; } uIndex = (UINT)lstrlen( szFullPath ); if ((uIndex > 0) && (szFullPath[uIndex-1] != '\\')) lstrcat( szFullPath, gszDriverFiles ); // add the '\' else lstrcat( szFullPath, gszDriverFiles + 1 ); // ignore the '\' (root dir) // find all the entries in the system dir //--------------------------------------- hFindFile = FindFirstFile( szFullPath, &ftFileInfo ); uResult = TRUE; if (hFindFile == INVALID_HANDLE_VALUE) { LOG((TL_ERROR, "FindFirstFile failed, 0x%08lx", GetLastError() )); uResult = FALSE; } while ( uResult ) { // alloc and set the file name to be assocated with each driver //------------------------------------------------------------- lpszDrvFile = (LPTSTR)ClientAlloc((lstrlen(ftFileInfo.cFileName)+1)*sizeof(TCHAR)); if (NULL == lpszDrvFile) { uResult = FALSE; goto done; } lstrcpy( lpszDrvFile, ftFileInfo.cFileName ); LOG((TL_ERROR, "Examining file %s", lpszDrvFile )); #ifdef MEMPHIS if (!lstrcmpi(lpszDrvFile, "tsp3216l.tsp")) { ClientFree (lpszDrvFile); goto next_driver; } #endif // if the provider is already installed, skip it //---------------------------------------------- for (pProvider = (PINSTALLED_PROVIDER)InstalledProvidersList.Head.Flink, uIndex = 0; uIndex < InstalledProvidersList.dwEntries; pProvider = (PINSTALLED_PROVIDER)pProvider->Entry.Flink, uIndex++) { if (!lstrcmpi (lpszDrvFile, pProvider->szName)) { RemoveEntryList (&pProvider->Entry); InstalledProvidersList.dwEntries --; ClientFree (pProvider); ClientFree (lpszDrvFile); goto next_driver; } } // cbb, should we make a full path??? uResult = GetProviderFileDesc( lpszDrvFile, szDrvDescription, ARRAYSIZE(szDrvDescription) ); if ( uResult != CPL_SUCCESS ) { LOG((TL_ERROR, "No description for %s. Default to filename.", lpszDrvFile )); /* Filename will have to suffice */ lstrcpy( szDrvDescription, lpszDrvFile ); uResult = FALSE; } else { uResult = TRUE; } // Verify that provider has install routine //----------------------------------------- if (!VerifyProcExists( lpszDrvFile, gszProviderInstall )) { LOG((TL_ERROR, "No Install Proc")); goto next_driver; } // slam it into the list box //-------------------------- uIndex = (UINT)SendMessage( hwndList, LB_ADDSTRING, 0, (LPARAM)szDrvDescription ); if ( uIndex == CB_ERR ) { uResult = FALSE; goto done; } if ( SendMessage( hwndList, LB_SETITEMDATA, uIndex, (LPARAM)lpszDrvFile ) == CB_ERR ) { uResult = FALSE; goto done; } next_driver: uResult = FALSE; if (FindNextFile( hFindFile, &ftFileInfo )) { uResult = TRUE; } } while (InstalledProvidersList.dwEntries > 0) { pProvider = (PINSTALLED_PROVIDER)RemoveHeadList (&InstalledProvidersList.Head); InstalledProvidersList.dwEntries --; ClientFree (pProvider); } uResult = TRUE; done: if (0 == SendMessage (hwndList, LB_GETCOUNT, 0, 0)) { if (0 < LoadString (GetUIInstance(), IDS_NO_PROVIDERS, szDrvDescription, ARRAYSIZE(szDrvDescription))) { SendMessage( hwndList, LB_ADDSTRING, 0, (LPARAM)szDrvDescription ); } EnableWindow (GetDlgItem (hwndParent, IDC_ADD), FALSE); } else { SendMessage( hwndList, LB_SETCURSEL, 0, 0 ); // set focus to the top guy UpdateDriverDlgButtons( hwndParent ); } SendMessage( hwndList, WM_SETREDRAW, TRUE, 0 ); return uResult; } /*--------------------------------------------------------------------------*\ Function: AddProvider Purpose: Call lineAddProvider \*--------------------------------------------------------------------------*/ BOOL AddProvider( HWND hwndParent, HWND hwndList, LPTSTR lpszDriverFile ) { UINT uIndex; LONG lResult; DWORD dwProviderID; if ( lpszDriverFile == NULL ) { DBG_ASSERT( hWnd, "Simultaneously NULL pointer & hwnd" ); // get the stuff from the list box //-------------------------------- uIndex = (UINT)SendMessage( hwndList, LB_GETCURSEL, 0, 0 ); lpszDriverFile = (LPTSTR)SendMessage( hwndList, LB_GETITEMDATA, uIndex, 0 ); if (lpszDriverFile == NULL) { return FALSE; } } lResult = lineAddProvider( lpszDriverFile, hwndParent, &dwProviderID ); if (lResult) { LOG((TL_ERROR, "Error: lineAddProvider failure %#08lx", lResult )); return FALSE; } return TRUE; } BOOL IsUserAdmin() /*++ Routine Description: Determine if current user is a member of the local admin's group Arguments: Return Value: True if member --*/ { BOOL foundEntry = FALSE; HANDLE hToken = NULL; DWORD dwInfoSize = 0; PTOKEN_GROUPS ptgGroups = NULL; SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY; PSID pSid = NULL; DWORD i; // // Get user thread or process token // if (!OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)) { if(!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken )) { goto ExitHere; } } // // Get user group SIDs // if (!GetTokenInformation( hToken, TokenGroups, NULL, 0, &dwInfoSize )) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { goto ExitHere; } } ptgGroups = (PTOKEN_GROUPS) ClientAlloc (dwInfoSize); if (ptgGroups == NULL) { goto ExitHere; } if (!GetTokenInformation( hToken, TokenGroups, ptgGroups, dwInfoSize, &dwInfoSize )) { goto ExitHere; } // // Get the local admin group SID // if(!AllocateAndInitializeSid( &sia, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid )) { goto ExitHere; } // // Compare to see if the user is in admin group // for (i = 0; i < ptgGroups->GroupCount; ++i) { if (EqualSid (ptgGroups->Groups[i].Sid, pSid)) { break; } } if (i < ptgGroups->GroupCount) { foundEntry = TRUE; } ExitHere: if (pSid) { FreeSid (pSid); } if (ptgGroups) { ClientFree (ptgGroups); } if (hToken) { CloseHandle (hToken); } return foundEntry; } VOID UpdateDriverDlgButtons( HWND hwnd ) { // // Enable/disable the Remove & Config buttons as appropriate // UINT uResult; LPTSTR lpszProviderFilename; DWORD dwProviderID; BOOL bAdmin = IsUserAdmin (); uResult = (UINT) SendDlgItemMessage( hwnd, IDC_LIST, LB_GETCURSEL, 0, 0 ); dwProviderID = (DWORD) SendDlgItemMessage( hwnd, IDC_LIST, LB_GETITEMDATA, uResult, 0 ); lpszProviderFilename = ProviderIDToFilename (dwProviderID); EnableWindow( GetDlgItem (hwnd, IDC_ADD), bAdmin ); EnableWindow( GetDlgItem (hwnd, IDC_REMOVE), bAdmin && (lpszProviderFilename != NULL) && VerifyProcExists (lpszProviderFilename, gszProviderRemove) ); EnableWindow( GetDlgItem( hwnd, IDC_EDIT), bAdmin && (lpszProviderFilename != NULL) && VerifyProcExists (lpszProviderFilename, gszProviderSetup) ); } /*--------------------------------------------------------------------------*\ Function: AddDriver_DialogProc Purpose: \*--------------------------------------------------------------------------*/ INT_PTR AddDriver_DialogProc( HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam ) { switch( wMessage ) { case WM_HELP: // Process clicks on controls after Context Help mode selected WinHelp ((HWND)((LPHELPINFO)lParam)->hItemHandle, gszHelpFile, HELP_WM_HELP, (DWORD_PTR)(LPTSTR) a114HelpIDs); break; case WM_CONTEXTMENU: // Process right-clicks on controls WinHelp ((HWND) wParam, gszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) a114HelpIDs); break; case WM_INITDIALOG: // initalize all the fields //------------------------- if ( !FillAddDriverList(hWnd, GetDlgItem(hWnd, IDC_DRIVER_LIST)) ) { EndDialog( hWnd, IDCANCEL ); return TRUE; } if ( SendDlgItemMessage( hWnd, IDC_DRIVER_LIST, LB_GETCOUNT, 0, 0 ) <= 0 ) EnableWindow( GetDlgItem( hWnd, IDC_ADD ), FALSE ); return TRUE; case WM_COMMAND: // do some work with the buttons //------------------------------ switch ( GET_WM_COMMAND_ID(wParam, lParam) ) { case IDC_DRIVER_LIST: // do the list stuff //------------------ if ((GET_WM_COMMAND_CMD( wParam, lParam ) != LBN_DBLCLK) || (SendDlgItemMessage( hWnd, IDC_DRIVER_LIST, LB_GETCOUNT, 0, 0 ) <= 0 )) break; // done // fall through, threat the double click like an add message case IDC_ADD: // add a new driver //----------------- if ( !AddProvider(hWnd, GetDlgItem(hWnd, IDC_DRIVER_LIST), NULL) ) { wParam = IDCANCEL; } else { wParam = IDOK; } // fall through, exit the dialog case IDOK: case IDCANCEL: { UINT uIndex, uCount; LPTSTR lpszDriverFile; HWND hwndList = GetDlgItem(hWnd, IDC_DRIVER_LIST); uCount = (UINT)SendMessage( hwndList, LB_GETCOUNT, 0, 0 ); for (uIndex = 0; uIndex < uCount; uIndex++) { lpszDriverFile = (LPTSTR)SendMessage( hwndList, LB_GETITEMDATA, uIndex, 0 ); if (NULL != lpszDriverFile) { ClientFree (lpszDriverFile); } } EndDialog( hWnd, wParam ); break; } } return TRUE; } return FALSE; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- BOOL RefreshProviderList() { LONG lResult; if (!glpProviderList) { // Initialize data structure glpProviderList = (LPLINEPROVIDERLIST)GlobalAllocPtr(GPTR, INITIAL_PROVIDER_LIST_SIZE); } if (!glpProviderList) { LOG((TL_ERROR, " RefreshProviderList - glpProviderList is NULL - returning CPL_ERR_MEMORY")); return FALSE; } glpProviderList->dwTotalSize = INITIAL_PROVIDER_LIST_SIZE; lResult = lineGetProviderList( TAPI_VERSION, glpProviderList ); if (lResult) { LOG((TL_ERROR, "Error: lineGetProviderList failure %#08lx", lResult )); return FALSE; } while (glpProviderList->dwNeededSize > glpProviderList->dwTotalSize) { // Expand data structure as necessary LOG((TL_ERROR, " RefreshProviderList - expanding glpProviderList.")); LPLINEPROVIDERLIST lpTemp = (LPLINEPROVIDERLIST)GlobalReAllocPtr( glpProviderList, (size_t)(glpProviderList->dwNeededSize), GPTR); if (!lpTemp) return FALSE; glpProviderList = lpTemp; glpProviderList->dwTotalSize = glpProviderList->dwNeededSize; lResult = lineGetProviderList( TAPI_VERSION, glpProviderList ); if (lResult) { LOG((TL_ERROR, "Error: lineGetProviderList failure %#08lx", lResult )); return FALSE; } } LOG((TL_ERROR, "%d providers", glpProviderList->dwNumProviders )); return TRUE; } LPTSTR ProviderIDToFilename( DWORD dwProviderID ) { UINT uIndex; LPLINEPROVIDERENTRY lpProviderEntry; // loop through the provider list //------------------------------- lpProviderEntry = (LPLINEPROVIDERENTRY)((LPBYTE)glpProviderList + glpProviderList->dwProviderListOffset); for ( uIndex = 0; uIndex < glpProviderList->dwNumProviders; uIndex++ ) { if (lpProviderEntry[uIndex].dwPermanentProviderID == dwProviderID) { // Get an entry to put in the list box //------------------------------------ return (LPTSTR)((LPBYTE)glpProviderList + lpProviderEntry[uIndex].dwProviderFilenameOffset); } } LOG((TL_ERROR, "Provider ID %d not found in list", dwProviderID )); return NULL; }