Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1174 lines
33 KiB

/*--------------------------------------------------------------------------*\
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 <windowsx.h>
#include <shlwapi.h>
#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;
}