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.
2041 lines
51 KiB
2041 lines
51 KiB
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <lm.h>
|
|
#include "resource.h"
|
|
#include <tapi.h>
|
|
|
|
#include "ntsecapi.h"
|
|
|
|
HINSTANCE ghInstance;
|
|
HWND ghWnd;
|
|
BOOLEAN gfQuietMode = FALSE;
|
|
DWORD gdwNoDSQuery = 0;
|
|
DWORD gdwConnectionOrientedOnly = 0;
|
|
|
|
const TCHAR gszProductType[] = TEXT("ProductType");
|
|
const TCHAR gszProductTypeServer[] = TEXT("ServerNT");
|
|
const TCHAR gszProductTypeLanmanNt[] = TEXT("LANMANNT");
|
|
const TCHAR gszRegKeyNTServer[] = TEXT("System\\CurrentControlSet\\Control\\ProductOptions");
|
|
const TCHAR gszRegKeyProviders[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Providers");
|
|
const TCHAR gszRegKeyTelephony[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Telephony");
|
|
const TCHAR gszProviderID[] = TEXT("ProviderID");
|
|
const TCHAR gszNumProviders[] = TEXT("NumProviders");
|
|
const TCHAR gszNextProviderID[] = TEXT("NextProviderID");
|
|
const TCHAR gszProviderFilename[] = TEXT("ProviderFilename");
|
|
const TCHAR gszRemoteSP[] = TEXT("RemoteSP.TSP");
|
|
const TCHAR gszProvider[] = TEXT("Provider");
|
|
const TCHAR gszServer[] = TEXT("Server");
|
|
const TCHAR gszNumServers[] = TEXT("NumServers");
|
|
const TCHAR gszConnectionOrientedOnly[] = TEXT("ConnectionOrientedOnly");
|
|
const TCHAR gszNoDSQuery[] = TEXT("NoDSQuery");
|
|
|
|
#define MAXERRORTEXTLEN 512
|
|
|
|
TCHAR gszTapiAdminSetup[MAXERRORTEXTLEN];
|
|
|
|
LPTSTR glpszFullName = NULL;
|
|
LPTSTR glpszPassword= NULL;
|
|
LPTSTR glpszMapper = NULL;
|
|
LPTSTR glpszDllList = NULL;
|
|
LPTSTR glpszRemoteServer = NULL;
|
|
|
|
BOOL
|
|
CALLBACK
|
|
DlgProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
BOOL
|
|
IsAdministrator(
|
|
);
|
|
|
|
BOOL
|
|
DoServer(
|
|
LPTSTR lpszServerLine
|
|
);
|
|
|
|
BOOL
|
|
DoClient(
|
|
LPTSTR lpszClientLine
|
|
);
|
|
|
|
|
|
//*****************************************************************************
|
|
//*****************************************************************************
|
|
//*****************************************************************************
|
|
UINT TAPIstrlen( const TCHAR *p )
|
|
{
|
|
UINT nLength = 0;
|
|
|
|
while ( *p )
|
|
{
|
|
nLength++;
|
|
p++;
|
|
}
|
|
|
|
return nLength;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//*****************************************************************************
|
|
//*****************************************************************************
|
|
void TAPIstrcat( TCHAR *p1, const TCHAR *p2 )
|
|
{
|
|
while ( *p1 )
|
|
{
|
|
p1++;
|
|
}
|
|
|
|
while ( *p2 )
|
|
{
|
|
*p1 = *p2;
|
|
p1++;
|
|
p2++;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//*****************************************************************************
|
|
//*****************************************************************************
|
|
void
|
|
ErrorStr(
|
|
int iMsg
|
|
)
|
|
{
|
|
TCHAR szError[MAXERRORTEXTLEN];
|
|
|
|
|
|
if ( !gfQuietMode )
|
|
{
|
|
if (LoadString(
|
|
ghInstance,
|
|
iMsg,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
|
|
MessageBox(
|
|
NULL,
|
|
szError,
|
|
gszTapiAdminSetup,
|
|
MB_OK
|
|
);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
ShowHelp()
|
|
{
|
|
TCHAR szError[MAXERRORTEXTLEN];
|
|
LPTSTR szBuffer;
|
|
|
|
if (gfQuietMode)
|
|
{
|
|
return;
|
|
}
|
|
|
|
szBuffer = (LPTSTR)GlobalAlloc(
|
|
GPTR,
|
|
11 * MAXERRORTEXTLEN * sizeof(TCHAR)
|
|
);
|
|
|
|
if (!szBuffer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LoadString(
|
|
ghInstance,
|
|
iszHelp0,
|
|
szBuffer,
|
|
MAXERRORTEXTLEN
|
|
);
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp1,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp2,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp3,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp4,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp5,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp6,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp7,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp8,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp9,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
if (LoadString(
|
|
ghInstance,
|
|
iszHelp10,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
))
|
|
{
|
|
TAPIstrcat(
|
|
szBuffer,
|
|
szError
|
|
);
|
|
}
|
|
|
|
LoadString(
|
|
ghInstance,
|
|
iszHelpTitle,
|
|
szError,
|
|
MAXERRORTEXTLEN
|
|
);
|
|
|
|
MessageBox(
|
|
NULL,
|
|
szBuffer,
|
|
szError,
|
|
MB_OK
|
|
);
|
|
|
|
GlobalFree (szBuffer);
|
|
}
|
|
|
|
LPTSTR
|
|
GetNextString(
|
|
LPTSTR lpszIn
|
|
)
|
|
{
|
|
static LPTSTR lpszLine;
|
|
LPTSTR lpszReturn = NULL;
|
|
|
|
if (lpszIn)
|
|
lpszLine = lpszIn;
|
|
|
|
while (*lpszLine && (*lpszLine == L' ' || *lpszLine == L'\t'))
|
|
lpszLine++;
|
|
|
|
if (!*lpszLine)
|
|
return NULL;
|
|
|
|
lpszReturn = lpszLine;
|
|
|
|
while (*lpszLine && (*lpszLine != L' ' && *lpszLine != L'\t'))
|
|
lpszLine++;
|
|
|
|
|
|
if (*lpszLine)
|
|
{
|
|
*lpszLine = '\0';
|
|
lpszLine++;
|
|
}
|
|
|
|
return lpszReturn;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ParseCommandLine(
|
|
LPTSTR lpszCommandLine
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
//
|
|
// Skip the first segment which is the executable itself
|
|
// it is either in double quotes or a string until a white
|
|
// space
|
|
//
|
|
|
|
if (*lpszCommandLine == TEXT('\"'))
|
|
{
|
|
++lpszCommandLine;
|
|
while (*lpszCommandLine &&
|
|
*lpszCommandLine != TEXT('\"'))
|
|
{
|
|
++lpszCommandLine;
|
|
}
|
|
if (*lpszCommandLine == TEXT('\"'))
|
|
{
|
|
++lpszCommandLine;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (
|
|
*lpszCommandLine &&
|
|
*lpszCommandLine != TEXT(' ') &&
|
|
*lpszCommandLine != TEXT('\t') &&
|
|
*lpszCommandLine != 0x0a &&
|
|
*lpszCommandLine != 0x0d)
|
|
{
|
|
++lpszCommandLine;
|
|
}
|
|
}
|
|
|
|
while (*lpszCommandLine)
|
|
{
|
|
//
|
|
// Search for / or - as the start of option
|
|
//
|
|
while (*lpszCommandLine == TEXT(' ') ||
|
|
*lpszCommandLine == TEXT('\t') ||
|
|
*lpszCommandLine == 0x0a ||
|
|
*lpszCommandLine == 0x0d)
|
|
{
|
|
lpszCommandLine++;
|
|
}
|
|
|
|
if (*lpszCommandLine != TEXT('/') &&
|
|
*lpszCommandLine != TEXT('-'))
|
|
{
|
|
break;
|
|
}
|
|
++lpszCommandLine;
|
|
|
|
if ( (L'r' == *lpszCommandLine) ||
|
|
(L'R' == *lpszCommandLine)
|
|
)
|
|
{
|
|
++lpszCommandLine;
|
|
if (*lpszCommandLine == TEXT(' ') ||
|
|
*lpszCommandLine == TEXT('\t') ||
|
|
*lpszCommandLine == 0x0a ||
|
|
*lpszCommandLine == 0x0d)
|
|
{
|
|
gdwNoDSQuery = (DWORD) TRUE;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if ( (L'q' == *lpszCommandLine) ||
|
|
(L'Q' == *lpszCommandLine))
|
|
{
|
|
++lpszCommandLine;
|
|
if (*lpszCommandLine == TEXT(' ') ||
|
|
*lpszCommandLine == TEXT('\t') ||
|
|
*lpszCommandLine == 0x0a ||
|
|
*lpszCommandLine == 0x0d)
|
|
{
|
|
gfQuietMode = TRUE;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if ((L'x' == *lpszCommandLine) ||
|
|
(L'X' == *lpszCommandLine))
|
|
{
|
|
++lpszCommandLine;
|
|
if (*lpszCommandLine == TEXT(' ') ||
|
|
*lpszCommandLine == TEXT('\t') ||
|
|
*lpszCommandLine == 0x0a ||
|
|
*lpszCommandLine == 0x0d)
|
|
{
|
|
gdwConnectionOrientedOnly = 1;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if ((L'c' == *lpszCommandLine) ||
|
|
(L'C' == *lpszCommandLine))
|
|
{
|
|
++lpszCommandLine;
|
|
if (*lpszCommandLine == TEXT(' ') ||
|
|
*lpszCommandLine == TEXT('\t') ||
|
|
*lpszCommandLine == 0x0a ||
|
|
*lpszCommandLine == 0x0d)
|
|
{
|
|
bRet = DoClient(++lpszCommandLine);
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
int WINAPI WinMain (HINSTANCE hInstance,
|
|
HINSTANCE hPrevInstance,
|
|
LPSTR lpszCmdLine,
|
|
int nCmdShow)
|
|
{
|
|
LPTSTR lpszCommandLine;
|
|
|
|
ghInstance = GetModuleHandle( NULL );
|
|
|
|
LoadString(
|
|
ghInstance,
|
|
iszTapiAdminSetup,
|
|
gszTapiAdminSetup,
|
|
MAXERRORTEXTLEN
|
|
);
|
|
|
|
if (!IsAdministrator())
|
|
{
|
|
ErrorStr(iszMustBeAdmin);
|
|
|
|
return 1;
|
|
}
|
|
|
|
lpszCommandLine = GetCommandLine();
|
|
|
|
if (!lpszCommandLine)
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
if (!(ParseCommandLine(
|
|
lpszCommandLine
|
|
)))
|
|
{
|
|
ShowHelp();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL
|
|
IsServer()
|
|
{
|
|
HKEY hKey;
|
|
DWORD dwDataSize;
|
|
DWORD dwDataType;
|
|
TCHAR szProductType[64];
|
|
|
|
|
|
// check to see if this is running on NT Server
|
|
// if so, enable the telephony server stuff
|
|
if (ERROR_SUCCESS !=
|
|
RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyNTServer,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
dwDataSize = 64;
|
|
RegQueryValueEx(
|
|
hKey,
|
|
gszProductType,
|
|
0,
|
|
&dwDataType,
|
|
(LPBYTE) szProductType,
|
|
&dwDataSize
|
|
);
|
|
|
|
RegCloseKey(
|
|
hKey
|
|
);
|
|
|
|
if ((!lstrcmpi(
|
|
szProductType,
|
|
gszProductTypeServer
|
|
))
|
|
||
|
|
(!lstrcmpi(
|
|
szProductType,
|
|
gszProductTypeLanmanNt
|
|
)))
|
|
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
ErrorStr(iszNotRunningServer);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set the disableserver key to true
|
|
//
|
|
BOOL
|
|
DisableServer()
|
|
{
|
|
HKEY hKeyTelephony, hKey;
|
|
DWORD dw;
|
|
BOOL bRet = TRUE;
|
|
|
|
if (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyTelephony,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyTelephony
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (RegCreateKeyEx(
|
|
hKeyTelephony,
|
|
TEXT("Server"),
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
&dw
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyTelephony);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
dw=1;
|
|
|
|
if (RegSetValueEx(
|
|
hKey,
|
|
TEXT("DisableSharing"),
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dw,
|
|
sizeof(dw)
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
RegCloseKey(hKeyTelephony);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////
|
|
//
|
|
// Determine if the currently logged on person is an admin
|
|
//
|
|
BOOL
|
|
IsAdministrator(
|
|
)
|
|
{
|
|
PSID psidAdministrators;
|
|
BOOL bResult = FALSE;
|
|
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
|
|
|
|
|
|
if (AllocateAndInitializeSid(
|
|
&siaNtAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&psidAdministrators
|
|
))
|
|
{
|
|
CheckTokenMembership (NULL, psidAdministrators, &bResult);
|
|
|
|
FreeSid (psidAdministrators);
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Determine the name of 'Administrators' group
|
|
//
|
|
BOOL LookupAdministratorsAlias(
|
|
LPWSTR Name,
|
|
PDWORD cchName
|
|
)
|
|
|
|
{
|
|
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
|
|
SID_NAME_USE snu;
|
|
PSID pSid;
|
|
WCHAR DomainName[DNLEN+1];
|
|
DWORD cchDomainName = DNLEN;
|
|
BOOL bSuccess = FALSE;
|
|
|
|
//
|
|
// Sid is the same regardless of machine, since the well-known
|
|
// BUILTIN domain is referenced.
|
|
//
|
|
|
|
if(AllocateAndInitializeSid(
|
|
&sia,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&pSid
|
|
))
|
|
{
|
|
bSuccess = LookupAccountSidW(
|
|
NULL,
|
|
pSid,
|
|
Name,
|
|
cchName,
|
|
DomainName,
|
|
&cchDomainName,
|
|
&snu
|
|
);
|
|
|
|
FreeSid(pSid);
|
|
}
|
|
|
|
return bSuccess;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Determine if the person specified is an administrator
|
|
//
|
|
BOOL
|
|
IsUserAdministrator(
|
|
LPTSTR lpszFullName
|
|
)
|
|
{
|
|
DWORD dwRead, dwTotal, x;
|
|
NET_API_STATUS nas;
|
|
LPLOCALGROUP_USERS_INFO_0 pGroups = NULL;
|
|
LPWSTR lpszNewFullName;
|
|
#define MAXADMINLEN 256
|
|
WCHAR szAdministrators[MAXADMINLEN];
|
|
|
|
|
|
#ifndef UNICODE
|
|
|
|
DWORD dwSize;
|
|
|
|
dwSize = (TAPIstrlen( lpszFullName ) + 1) * sizeof( WCHAR );
|
|
|
|
if (!(lpszNewFullName = (LPWSTR) GlobalAlloc (GPTR, dwSize)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
MultiByteToWideChar(
|
|
CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
lpszFullName,
|
|
-1,
|
|
lpszNewFullName,
|
|
dwSize
|
|
);
|
|
#else
|
|
|
|
lpszNewFullName = lpszFullName;
|
|
|
|
#endif
|
|
|
|
// First, get the name of the 'Administrators' group.
|
|
// Normally, this will be Administrators, but the use
|
|
// can change it (also, it will be different for foreign
|
|
// versions of NT)
|
|
dwTotal = sizeof(szAdministrators)/sizeof(WCHAR); // reuse dwTotal
|
|
if (!(LookupAdministratorsAlias(
|
|
szAdministrators,
|
|
&dwTotal
|
|
)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Next, get all the groups the user is part of
|
|
// (directly OR indirectly) and see if administrators
|
|
// is among them.
|
|
#define MAX_PREFERRED_LEN 4096*2 // 2 pages (or 1 on alpha)
|
|
nas = NetUserGetLocalGroups (
|
|
NULL, // server
|
|
lpszNewFullName, // user name
|
|
0, // level
|
|
LG_INCLUDE_INDIRECT, // flags
|
|
(PBYTE*)&pGroups, // output buffer
|
|
MAX_PREFERRED_LEN, // preferred maximum length
|
|
&dwRead, // entries read
|
|
&dwTotal // total entries
|
|
);
|
|
|
|
if (NERR_Success != nas)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
for (x = 0; x < dwRead; x++)
|
|
{
|
|
if (lstrcmpiW(
|
|
pGroups[x].lgrui0_name,
|
|
szAdministrators
|
|
) == 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
NetApiBufferFree ((PVOID)pGroups);
|
|
if (x < dwRead)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
ErrorStr(iszUserNotAdmin);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Write out server registry keys
|
|
//
|
|
BOOL
|
|
WriteRegistryKeys(
|
|
LPTSTR lpszMapper,
|
|
LPTSTR lpszDlls
|
|
)
|
|
{
|
|
HKEY hKeyTelephony, hKey;
|
|
DWORD dw;
|
|
|
|
if (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Telephony"),
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyTelephony
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (RegCreateKeyEx(
|
|
hKeyTelephony,
|
|
TEXT("Server"),
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
&dw
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyTelephony);
|
|
return FALSE;
|
|
}
|
|
|
|
dw=0;
|
|
|
|
if ((RegSetValueEx(
|
|
hKey,
|
|
TEXT("DisableSharing"),
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dw,
|
|
sizeof(dw)
|
|
) != ERROR_SUCCESS) ||
|
|
|
|
(RegSetValueEx(
|
|
hKey,
|
|
TEXT("MapperDll"),
|
|
0,
|
|
REG_SZ,
|
|
// (LPBYTE)lpszMapper,
|
|
(LPBYTE)TEXT("TSEC.DLL"),
|
|
// (TAPIstrlen(lpszMapper)+1)*sizeof(TCHAR)
|
|
(TAPIstrlen(TEXT("TSEC.DLL"))+1)*sizeof(TCHAR)
|
|
) != ERROR_SUCCESS))
|
|
{
|
|
RegCloseKey(hKey);
|
|
RegCloseKey(hKeyTelephony);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if (lpszDlls)
|
|
{
|
|
if (RegSetValueEx(
|
|
hKey,
|
|
TEXT("ManagementDlls"),
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)lpszDlls,
|
|
(TAPIstrlen(lpszDlls)+1)*sizeof(TCHAR)
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKey);
|
|
RegCloseKey(hKeyTelephony);
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RegDeleteValue(
|
|
hKey,
|
|
TEXT("ManagementDlls")
|
|
);
|
|
}
|
|
|
|
|
|
RegCloseKey(hKey);
|
|
RegCloseKey(hKeyTelephony);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set server setting for the tapisrv service
|
|
//
|
|
BOOL
|
|
DoServiceStuff(
|
|
LPTSTR lpszName,
|
|
LPTSTR lpszPassword,
|
|
BOOL bServer
|
|
)
|
|
{
|
|
SC_HANDLE sch, sc_tapisrv;
|
|
BOOL bReturn = TRUE;
|
|
|
|
if (!(sch = OpenSCManager(
|
|
NULL,
|
|
NULL,
|
|
SC_MANAGER_ENUMERATE_SERVICE
|
|
)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
if (!(sc_tapisrv = OpenService(
|
|
sch,
|
|
TEXT("TAPISRV"),
|
|
SERVICE_CHANGE_CONFIG
|
|
)))
|
|
{
|
|
CloseHandle(sch);
|
|
|
|
ErrorStr(iszOpenServiceFailed);
|
|
return FALSE;
|
|
}
|
|
|
|
// this sets tapisrv to start as auto, not manual
|
|
// and set the log on as person to be the name/password passed in
|
|
if (!(ChangeServiceConfig(
|
|
sc_tapisrv,
|
|
SERVICE_WIN32_OWN_PROCESS,
|
|
bServer?SERVICE_AUTO_START:SERVICE_DEMAND_START,
|
|
SERVICE_NO_CHANGE,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
lpszName,
|
|
(lpszPassword ? lpszPassword : TEXT("")),
|
|
NULL
|
|
)))
|
|
{
|
|
bReturn = FALSE;
|
|
}
|
|
|
|
|
|
CloseServiceHandle(sc_tapisrv);
|
|
CloseServiceHandle(sch);
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
OpenPolicy(
|
|
LPWSTR ServerName, // machine to open policy on (Unicode)
|
|
DWORD DesiredAccess, // desired access to policy
|
|
PLSA_HANDLE PolicyHandle // resultant policy handle
|
|
);
|
|
|
|
BOOL
|
|
GetAccountSid(
|
|
LPTSTR SystemName, // where to lookup account
|
|
LPTSTR AccountName, // account of interest
|
|
PSID *Sid // resultant buffer containing SID
|
|
);
|
|
NTSTATUS
|
|
SetPrivilegeOnAccount(
|
|
LSA_HANDLE PolicyHandle, // open policy handle
|
|
PSID AccountSid, // SID to grant privilege to
|
|
LPWSTR PrivilegeName, // privilege to grant (Unicode)
|
|
BOOL bEnable // enable or disable
|
|
);
|
|
|
|
void
|
|
InitLsaString(
|
|
PLSA_UNICODE_STRING LsaString, // destination
|
|
LPWSTR String // source (Unicode)
|
|
);
|
|
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// grant the person the right to Log On As A Service
|
|
//
|
|
BOOL
|
|
DoRight(
|
|
LPTSTR AccountName,
|
|
LPWSTR Right,
|
|
BOOL bEnable
|
|
)
|
|
{
|
|
LSA_HANDLE PolicyHandle;
|
|
PSID pSid;
|
|
NTSTATUS Status;
|
|
BOOL bReturn = FALSE;
|
|
WCHAR wComputerName[MAX_COMPUTERNAME_LENGTH+1];
|
|
DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
|
|
|
|
|
|
|
|
GetComputerNameW(
|
|
wComputerName,
|
|
&dwSize
|
|
);
|
|
//
|
|
// Open the policy on the target machine.
|
|
//
|
|
if((Status=OpenPolicy(
|
|
wComputerName, // target machine
|
|
POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
|
|
&PolicyHandle // resultant policy handle
|
|
)) != ERROR_SUCCESS)
|
|
{
|
|
ErrorStr(iszOpenPolicyFailed);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Obtain the SID of the user/group.
|
|
// Note that we could target a specific machine, but we don't.
|
|
// Specifying NULL for target machine searches for the SID in the
|
|
// following order: well-known, Built-in and local, primary domain,
|
|
// trusted domains.
|
|
//
|
|
if(GetAccountSid(
|
|
NULL, // default lookup logic
|
|
AccountName,// account to obtain SID
|
|
&pSid // buffer to allocate to contain resultant SID
|
|
))
|
|
{
|
|
PLSA_UNICODE_STRING rights;
|
|
DWORD dwcount = 0;
|
|
//
|
|
// We only grant the privilege if we succeeded in obtaining the
|
|
// SID. We can actually add SIDs which cannot be looked up, but
|
|
// looking up the SID is a good sanity check which is suitable for
|
|
// most cases.
|
|
|
|
//
|
|
// Grant the SeServiceLogonRight to users represented by pSid.
|
|
//
|
|
|
|
LsaEnumerateAccountRights(
|
|
PolicyHandle,
|
|
pSid,
|
|
&rights,
|
|
&dwcount
|
|
);
|
|
if((Status=SetPrivilegeOnAccount(
|
|
PolicyHandle, // policy handle
|
|
pSid, // SID to grant privilege
|
|
Right,//L"SeServiceLogonRight", // Unicode privilege
|
|
bEnable // enable the privilege
|
|
)) == ERROR_SUCCESS)
|
|
{
|
|
bReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
ErrorStr(iszSetPrivilegeOnAccount);
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Close the policy handle.
|
|
//
|
|
LsaClose(PolicyHandle);
|
|
|
|
//
|
|
// Free memory allocated for SID.
|
|
//
|
|
if(pSid != NULL) GlobalFree(pSid);
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
void
|
|
InitLsaString(
|
|
PLSA_UNICODE_STRING LsaString,
|
|
LPWSTR String
|
|
)
|
|
{
|
|
DWORD StringLength;
|
|
|
|
if (String == NULL) {
|
|
LsaString->Buffer = NULL;
|
|
LsaString->Length = 0;
|
|
LsaString->MaximumLength = 0;
|
|
return;
|
|
}
|
|
|
|
StringLength = TAPIstrlen(String);
|
|
LsaString->Buffer = String;
|
|
LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
|
|
LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
|
|
}
|
|
|
|
NTSTATUS
|
|
OpenPolicy(
|
|
LPWSTR ServerName,
|
|
DWORD DesiredAccess,
|
|
PLSA_HANDLE PolicyHandle
|
|
)
|
|
{
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LSA_UNICODE_STRING ServerString;
|
|
PLSA_UNICODE_STRING Server = NULL;
|
|
|
|
//
|
|
// Always initialize the object attributes to all zeroes.
|
|
//
|
|
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
|
|
|
|
if (ServerName != NULL)
|
|
{
|
|
//
|
|
// Make a LSA_UNICODE_STRING out of the LPTSTR passed in
|
|
//
|
|
InitLsaString(&ServerString, ServerName);
|
|
Server = &ServerString;
|
|
}
|
|
|
|
//
|
|
// Attempt to open the policy.
|
|
//
|
|
return LsaOpenPolicy(
|
|
Server,
|
|
&ObjectAttributes,
|
|
DesiredAccess,
|
|
PolicyHandle
|
|
);
|
|
}
|
|
|
|
/*++
|
|
This function attempts to obtain a SID representing the supplied
|
|
account on the supplied system.
|
|
|
|
If the function succeeds, the return value is TRUE. A buffer is
|
|
allocated which contains the SID representing the supplied account.
|
|
This buffer should be freed when it is no longer needed by calling
|
|
HeapFree(GetProcessHeap(), 0, buffer)
|
|
|
|
If the function fails, the return value is FALSE. Call GetLastError()
|
|
to obtain extended error information.
|
|
|
|
Scott Field (sfield) 12-Jul-95
|
|
--*/
|
|
|
|
BOOL
|
|
GetAccountSid(
|
|
LPTSTR SystemName,
|
|
LPTSTR AccountName,
|
|
PSID *Sid
|
|
)
|
|
{
|
|
LPTSTR ReferencedDomain=NULL;
|
|
DWORD cbSid=1000; // initial allocation attempt
|
|
DWORD cbReferencedDomain=256; // initial allocation size
|
|
SID_NAME_USE peUse;
|
|
BOOL bSuccess=TRUE; // assume this function will fail
|
|
|
|
//
|
|
// initial memory allocations
|
|
//
|
|
if((*Sid=GlobalAlloc(
|
|
GPTR,
|
|
cbSid
|
|
)) == NULL)
|
|
{
|
|
bSuccess = FALSE;
|
|
goto failure;
|
|
}
|
|
|
|
if((ReferencedDomain=GlobalAlloc(
|
|
GPTR,
|
|
cbReferencedDomain
|
|
)) == NULL)
|
|
{
|
|
bSuccess = FALSE;
|
|
goto failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Obtain the SID of the specified account on the specified system.
|
|
//
|
|
if (!LookupAccountName(
|
|
SystemName, // machine to lookup account on
|
|
AccountName, // account to lookup
|
|
*Sid, // SID of interest
|
|
&cbSid, // size of SID
|
|
ReferencedDomain, // domain account was found on
|
|
&cbReferencedDomain,
|
|
&peUse
|
|
))
|
|
{
|
|
bSuccess = FALSE;
|
|
goto failure;
|
|
}
|
|
|
|
failure:
|
|
|
|
if (ReferencedDomain)
|
|
{
|
|
GlobalFree(ReferencedDomain);
|
|
}
|
|
|
|
if(!bSuccess)
|
|
{
|
|
if(*Sid != NULL)
|
|
{
|
|
GlobalFree(*Sid);
|
|
*Sid = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
NTSTATUS
|
|
SetPrivilegeOnAccount(
|
|
LSA_HANDLE PolicyHandle, // open policy handle
|
|
PSID AccountSid, // SID to grant privilege to
|
|
LPWSTR PrivilegeName, // privilege to grant (Unicode)
|
|
BOOL bEnable // enable or disable
|
|
)
|
|
{
|
|
LSA_UNICODE_STRING PrivilegeString;
|
|
|
|
//
|
|
// Create a LSA_UNICODE_STRING for the privilege name.
|
|
//
|
|
InitLsaString(&PrivilegeString, PrivilegeName);
|
|
|
|
//
|
|
// grant or revoke the privilege, accordingly
|
|
//
|
|
if(bEnable) {
|
|
return LsaAddAccountRights(
|
|
PolicyHandle, // open policy handle
|
|
AccountSid, // target SID
|
|
&PrivilegeString, // privileges
|
|
1 // privilege count
|
|
);
|
|
}
|
|
else {
|
|
return LsaRemoveAccountRights(
|
|
PolicyHandle, // open policy handle
|
|
AccountSid, // target SID
|
|
FALSE, // do not disable all rights
|
|
&PrivilegeString, // privileges
|
|
1 // privilege count
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
DisableServerStuff()
|
|
{
|
|
HKEY hKeyTelephony;
|
|
LONG lResult;
|
|
|
|
if (!IsServer())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyTelephony,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyTelephony
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
lResult = RegDeleteKey (hKeyTelephony, TEXT("Server"));
|
|
RegCloseKey (hKeyTelephony);
|
|
if (ERROR_SUCCESS != lResult)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (!(DoServiceStuff(
|
|
TEXT("LocalSystem"),
|
|
TEXT(""),
|
|
FALSE
|
|
)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
DoServer(
|
|
LPTSTR lpszServerLine
|
|
)
|
|
{
|
|
if (!(glpszFullName = GetNextString(
|
|
lpszServerLine
|
|
)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (!(lstrcmpi(
|
|
glpszFullName,
|
|
TEXT("/d")
|
|
)))
|
|
{
|
|
if (!(DisableServerStuff()))
|
|
{
|
|
ErrorStr(iszServerDisabledFailure);
|
|
return FALSE;
|
|
}
|
|
|
|
ErrorStr(iszServerDisabled);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// dow we want a password?
|
|
if (!(lstrcmpi(
|
|
glpszFullName,
|
|
TEXT("/n")
|
|
)))
|
|
{
|
|
// NO!
|
|
glpszFullName = GetNextString(
|
|
NULL
|
|
);
|
|
glpszPassword = NULL;
|
|
}
|
|
else
|
|
{
|
|
// yes - get the password
|
|
if (!(glpszPassword = GetNextString(
|
|
NULL
|
|
)))
|
|
{
|
|
ErrorStr(iszNoPasswordSupplied);
|
|
ErrorStr(iszServerSetupFailure);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// if (!(glpszMapper = GetNextString(
|
|
// NULL
|
|
// )))
|
|
// {
|
|
// ErrorStr(iszNoMapperSupplied);
|
|
// ErrorStr(iszServerSetupFailure);
|
|
// return FALSE;
|
|
// }
|
|
|
|
// dll list is not mandatory
|
|
glpszDllList = GetNextString(
|
|
NULL
|
|
);
|
|
|
|
if (!IsServer())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (!IsUserAdministrator(
|
|
glpszFullName
|
|
)
|
|
)
|
|
{
|
|
ErrorStr(iszUserNotAnAdmin);
|
|
goto exit_now;
|
|
}
|
|
|
|
if (!DoRight(
|
|
glpszFullName,
|
|
L"SeServiceLogonRight",
|
|
TRUE
|
|
))
|
|
{
|
|
goto exit_now;
|
|
}
|
|
|
|
|
|
if (!WriteRegistryKeys(
|
|
glpszMapper,
|
|
glpszDllList
|
|
))
|
|
{
|
|
ErrorStr(iszRegWriteFailed);
|
|
goto exit_now;
|
|
}
|
|
|
|
if (!DoServiceStuff(
|
|
glpszFullName,
|
|
glpszPassword,
|
|
TRUE
|
|
))
|
|
{
|
|
goto exit_now;
|
|
}
|
|
|
|
ErrorStr(iszServerSetup);
|
|
|
|
return TRUE;
|
|
|
|
exit_now:
|
|
|
|
ErrorStr(iszServerSetupFailure);
|
|
return FALSE;
|
|
}
|
|
|
|
#define MAX_KEY_LENGTH 256
|
|
DWORD RegDeleteKeyNT(HKEY hStartKey , LPCTSTR pKeyName )
|
|
{
|
|
DWORD dwRtn, dwSubKeyLength;
|
|
LPTSTR pSubKey = NULL;
|
|
TCHAR szSubKey[MAX_KEY_LENGTH]; // (256) this should be dynamic.
|
|
HKEY hKey;
|
|
|
|
// Do not allow NULL or empty key name
|
|
if ( pKeyName && lstrlen(pKeyName))
|
|
{
|
|
if( (dwRtn=RegOpenKeyEx(hStartKey,pKeyName,
|
|
0, KEY_ENUMERATE_SUB_KEYS | DELETE, &hKey )) == ERROR_SUCCESS)
|
|
{
|
|
while (dwRtn == ERROR_SUCCESS )
|
|
{
|
|
dwSubKeyLength = MAX_KEY_LENGTH;
|
|
dwRtn=RegEnumKeyEx(
|
|
hKey,
|
|
0, // always index zero
|
|
szSubKey,
|
|
&dwSubKeyLength,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if(dwRtn == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
dwRtn = RegDeleteKey(hStartKey, pKeyName);
|
|
break;
|
|
}
|
|
else if(dwRtn == ERROR_SUCCESS)
|
|
dwRtn=RegDeleteKeyNT(hKey, szSubKey);
|
|
}
|
|
RegCloseKey(hKey);
|
|
// Do not save return code because error
|
|
// has already occurred
|
|
}
|
|
}
|
|
else
|
|
dwRtn = ERROR_BADKEY;
|
|
|
|
return dwRtn;
|
|
}
|
|
|
|
BOOL
|
|
RemoveRemoteSP()
|
|
{
|
|
HKEY hKeyProviders, hKeyTelephony;
|
|
DWORD dwSize, dwCount, dwID, dwType, dwNumProviders ;
|
|
TCHAR szBuffer[256], szProviderName[256];
|
|
|
|
|
|
// open providers key
|
|
if (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyProviders,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyProviders
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// open telephony key
|
|
if (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyTelephony,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyTelephony
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyProviders);
|
|
return FALSE;
|
|
}
|
|
|
|
dwSize = sizeof (DWORD);
|
|
|
|
// get current num providers
|
|
if (RegQueryValueEx(
|
|
hKeyProviders,
|
|
gszNumProviders,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwNumProviders,
|
|
&dwSize) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyTelephony);
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//check to see if remotesp is already installed
|
|
//loop through all providers and compare filename
|
|
for (dwCount = 0; dwCount < dwNumProviders; dwCount++)
|
|
{
|
|
wsprintf(
|
|
szBuffer,
|
|
TEXT("%s%d"),
|
|
gszProviderFilename,
|
|
dwCount
|
|
);
|
|
|
|
dwSize = 256;
|
|
|
|
if (RegQueryValueEx(
|
|
hKeyProviders,
|
|
szBuffer,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szProviderName,
|
|
&dwSize) != ERROR_SUCCESS)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// this is remotesp
|
|
if (!lstrcmpi(
|
|
szProviderName,
|
|
gszRemoteSP
|
|
))
|
|
{
|
|
|
|
|
|
wsprintf(
|
|
szBuffer,
|
|
TEXT("%s%d"),
|
|
gszProviderID,
|
|
dwCount
|
|
);
|
|
|
|
dwSize = sizeof(DWORD);
|
|
|
|
RegQueryValueEx(
|
|
hKeyProviders,
|
|
szBuffer,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwID,
|
|
&dwSize
|
|
);
|
|
return (lineRemoveProvider (dwID, NULL) == S_OK);
|
|
}
|
|
}
|
|
|
|
if (dwCount == dwNumProviders)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WriteRemoteSPKeys(
|
|
LPTSTR lpszRemoteServer
|
|
)
|
|
{
|
|
HKEY hKeyProviders, hKeyTelephony = NULL, hKey;
|
|
DWORD dwSize, dwType, dwNumProviders, dwNextProviderID,
|
|
dwDisp, dwCount, i;
|
|
TCHAR szBuffer[256], szProviderName[256];
|
|
#ifdef NEVER
|
|
BOOL fAlreadyExists = FALSE;
|
|
#endif
|
|
|
|
|
|
// open providers key
|
|
if (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyProviders,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyProviders
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
dwSize = sizeof (DWORD);
|
|
|
|
// get current num providers
|
|
if (RegQueryValueEx(
|
|
hKeyProviders,
|
|
gszNumProviders,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwNumProviders,
|
|
&dwSize) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//check to see if remotesp is already installed
|
|
//loop through all providers and compare filename
|
|
|
|
for (dwCount = 0; dwCount < dwNumProviders; dwCount++)
|
|
{
|
|
wsprintf(
|
|
szBuffer,
|
|
TEXT("%s%d"),
|
|
gszProviderFilename,
|
|
dwCount
|
|
);
|
|
|
|
dwSize = 256;
|
|
|
|
if (RegQueryValueEx(
|
|
hKeyProviders,
|
|
szBuffer,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szProviderName,
|
|
&dwSize) != ERROR_SUCCESS)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!lstrcmpi(
|
|
szProviderName,
|
|
gszRemoteSP
|
|
))
|
|
{
|
|
// if there's a match, return TRUE
|
|
wsprintf(
|
|
szBuffer,
|
|
TEXT("%s%d"),
|
|
gszProviderID,
|
|
dwCount
|
|
);
|
|
|
|
dwSize = sizeof(DWORD);
|
|
|
|
RegQueryValueEx(
|
|
hKeyProviders,
|
|
szBuffer,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwNextProviderID,
|
|
&dwSize
|
|
);
|
|
|
|
// first remove the provider
|
|
if (lineRemoveProvider (dwNextProviderID, NULL))
|
|
{
|
|
RegCloseKey (hKeyProviders);
|
|
return FALSE;
|
|
}
|
|
|
|
if (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyTelephony,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyTelephony
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
wsprintf(
|
|
szBuffer,
|
|
TEXT("%s%d"),
|
|
gszProvider,
|
|
dwNextProviderID
|
|
);
|
|
|
|
RegDeleteKeyNT(
|
|
hKeyTelephony,
|
|
szBuffer
|
|
);
|
|
|
|
#ifdef NEVER
|
|
wsprintf(
|
|
szBuffer,
|
|
TEXT("%s%d"),
|
|
gszProvider,
|
|
dwNextProviderID
|
|
);
|
|
|
|
// open telephony key
|
|
if (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyTelephony,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyTelephony
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
fAlreadyExists = TRUE;
|
|
goto createProviderNKey;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
dwSize = sizeof (DWORD);
|
|
|
|
// get next provider id
|
|
if (RegQueryValueEx(
|
|
hKeyProviders,
|
|
gszNextProviderID,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwNextProviderID,
|
|
&dwSize) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#ifdef NEVER
|
|
// make the filename id
|
|
wsprintf(szBuffer, TEXT("%s%d"), gszProviderFilename, dwNumProviders);
|
|
|
|
// set the filename
|
|
if (RegSetValueEx(
|
|
hKeyProviders,
|
|
szBuffer,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)gszRemoteSP,
|
|
(TAPIstrlen(gszRemoteSP)+1) * sizeof(TCHAR)
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// make the provideid id
|
|
wsprintf(szBuffer, TEXT("%s%d"), gszProviderID, dwNumProviders);
|
|
|
|
// set the providerid id
|
|
if (RegSetValueEx(
|
|
hKeyProviders,
|
|
szBuffer,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwNextProviderID,
|
|
sizeof(DWORD)
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// inc next provider id
|
|
dwNextProviderID++;
|
|
|
|
// set it
|
|
if (RegSetValueEx(
|
|
hKeyProviders,
|
|
gszNextProviderID,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwNextProviderID,
|
|
sizeof(DWORD)
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// inc num providers
|
|
dwNumProviders++;
|
|
|
|
// set it
|
|
if (RegSetValueEx(
|
|
hKeyProviders,
|
|
gszNumProviders,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwNumProviders,
|
|
sizeof(DWORD)
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// close this one
|
|
RegCloseKey(hKeyProviders);
|
|
#endif // NEVER
|
|
|
|
// open telephony key
|
|
if ((hKeyTelephony == NULL) && (RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
gszRegKeyTelephony,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyTelephony
|
|
) != ERROR_SUCCESS))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// make the provider# key
|
|
wsprintf(szBuffer, TEXT("%s%d"), gszProvider, dwNextProviderID);
|
|
|
|
#if NEVER
|
|
createProviderNKey:
|
|
|
|
//
|
|
// First nuke the existing key to clear out all the old values,
|
|
// the recreate it & add the new values
|
|
//
|
|
|
|
RegDeleteKeyNT (hKeyTelephony, szBuffer);
|
|
#endif
|
|
|
|
if (RegCreateKeyEx(
|
|
hKeyTelephony,
|
|
szBuffer,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
&dwDisp
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKeyTelephony);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
for (i = 0; lpszRemoteServer; i++)
|
|
{
|
|
wsprintf (szBuffer, TEXT("%s%d"), gszServer, i);
|
|
|
|
if (RegSetValueEx(
|
|
hKey,
|
|
szBuffer,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE) lpszRemoteServer,
|
|
(TAPIstrlen (lpszRemoteServer) + 1) * sizeof(TCHAR)
|
|
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey (hKey);
|
|
RegCloseKey (hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
lpszRemoteServer = GetNextString (NULL);
|
|
}
|
|
|
|
if (RegSetValueEx(
|
|
hKey,
|
|
gszNumServers,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE) &i,
|
|
sizeof (i)
|
|
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey (hKey);
|
|
RegCloseKey (hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// set the ConnectionOrientedOnly value appropriately
|
|
|
|
if (RegSetValueEx(
|
|
hKey,
|
|
gszConnectionOrientedOnly,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE) &gdwConnectionOrientedOnly,
|
|
sizeof(DWORD)
|
|
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKey);
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// Set NoDSQuery value appropriately
|
|
if (RegSetValueEx(
|
|
hKey,
|
|
gszNoDSQuery,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE) &gdwNoDSQuery,
|
|
sizeof(DWORD)
|
|
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKey);
|
|
RegCloseKey(hKeyProviders);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Add the new remotesp.tsp
|
|
//
|
|
lineAddProvider (gszRemoteSP, NULL, &dwNextProviderID);
|
|
|
|
RegCloseKey (hKey);
|
|
RegCloseKey (hKeyProviders);
|
|
RegCloseKey(hKeyTelephony);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
DoClient(
|
|
LPTSTR lpszClientLine
|
|
)
|
|
{
|
|
HANDLE hProvidersMutex = NULL;
|
|
BOOL bRet = FALSE;
|
|
|
|
glpszRemoteServer = GetNextString(
|
|
lpszClientLine
|
|
);
|
|
|
|
if (!glpszRemoteServer)
|
|
{
|
|
goto ExitHere;
|
|
}
|
|
|
|
hProvidersMutex = CreateMutex (
|
|
NULL,
|
|
FALSE,
|
|
TEXT("TapisrvProviderListMutex")
|
|
);
|
|
if (NULL == hProvidersMutex)
|
|
{
|
|
ErrorStr(iszCreateMutexFailed);
|
|
goto ExitHere;
|
|
}
|
|
|
|
WaitForSingleObject (hProvidersMutex, INFINITE);
|
|
|
|
if (!lstrcmpi(
|
|
glpszRemoteServer,
|
|
TEXT("/d")
|
|
))
|
|
{
|
|
if (!RemoveRemoteSP())
|
|
{
|
|
ErrorStr(iszClientDisabledFailure);
|
|
goto ExitHere;
|
|
}
|
|
else
|
|
{
|
|
ErrorStr(iszClientDisabled);
|
|
|
|
bRet = TRUE;
|
|
goto ExitHere;
|
|
}
|
|
}
|
|
|
|
|
|
if (!WriteRemoteSPKeys(
|
|
glpszRemoteServer
|
|
))
|
|
{
|
|
ErrorStr(iszClientSetupFailure);
|
|
goto ExitHere;
|
|
}
|
|
else
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
ErrorStr(iszClientSetup);
|
|
|
|
ExitHere:
|
|
|
|
if (hProvidersMutex)
|
|
{
|
|
ReleaseMutex (hProvidersMutex);
|
|
CloseHandle (hProvidersMutex);
|
|
}
|
|
|
|
return bRet;
|
|
}
|