247 lines
6.9 KiB
C++
247 lines
6.9 KiB
C++
|
//
|
||
|
// NetUtil.cpp
|
||
|
//
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "Util.h"
|
||
|
#include "TheApp.h"
|
||
|
|
||
|
#include <lmjoin.h>
|
||
|
#include <devguid.h>
|
||
|
|
||
|
#include "NetUtil.h"
|
||
|
|
||
|
|
||
|
// Network registry entries
|
||
|
#define c_szNetConfig _T("System\\CurrentControlSet\\Services\\VxD\\VNETSUP")
|
||
|
#define c_szNetConfig_ComputerName _T("ComputerName")
|
||
|
#define c_szNetConfig_Description _T("Comment")
|
||
|
#define c_szNetConfig_Workgroup _T("Workgroup")
|
||
|
|
||
|
|
||
|
// A valid computer name is a max of MAX_COMPUTERNAME_LENGTH (15) chars,
|
||
|
// and contains only the following characters:
|
||
|
// A-Z a-z 0-9 `!#$@%&'()-.^_{}~
|
||
|
// It also may not consist of all periods.
|
||
|
//
|
||
|
// REVIEW: Is this accurate even on Japanese and other international Windows?
|
||
|
//
|
||
|
|
||
|
static const BYTE c_rgValidChars[] = {
|
||
|
1, // 32 (space)
|
||
|
1, // 33 !
|
||
|
0, // 34 "
|
||
|
1,1,1,1,1,1,1, // 35-41 #$%&'()
|
||
|
0,0,0, // 42-44 *+,
|
||
|
1,1, // 45-46 -.
|
||
|
0, // 47 /
|
||
|
1,1,1,1,1,1,1,1,1,1, // 48-57 0123456789
|
||
|
0,0,0,0,0,0, // 58-63 :;<=>?
|
||
|
1,1,1,1,1,1,1,1,1,1, // 64-73 @ABCDEFGHI
|
||
|
1,1,1,1,1,1,1,1,1,1, // 74-83 JKLMNOPQRS
|
||
|
1,1,1,1,1,1,1, // 84-90 TUVWXYZ
|
||
|
0,0,0, // 91-93 [\]
|
||
|
1,1,1, // 94-96 ^_`
|
||
|
1,1,1,1,1,1,1,1,1,1, // 97-106 abcdefghij
|
||
|
1,1,1,1,1,1,1,1,1,1, // 107-116 klmnopqrst
|
||
|
1,1,1,1,1,1,1, // 117-123 uvwxyz{
|
||
|
0, // 124 |
|
||
|
1,1, // 125-126 }~
|
||
|
};
|
||
|
|
||
|
#define CH_FIRST_VALID 32
|
||
|
#define CH_LAST_VALID (_countof(c_rgValidChars) + CH_FIRST_VALID - 1)
|
||
|
|
||
|
|
||
|
BOOL IsComputerNameValid(LPCTSTR pszName)
|
||
|
{
|
||
|
if (lstrlen(pszName) > MAX_COMPUTERNAME_LENGTH)
|
||
|
return FALSE;
|
||
|
|
||
|
UCHAR ch;
|
||
|
BOOL bAllPeriods = TRUE; // can't be all periods and/or whitespace
|
||
|
|
||
|
while ((ch = (UCHAR)*pszName) != _T('\0'))
|
||
|
{
|
||
|
if (ch < CH_FIRST_VALID || ch > CH_LAST_VALID)
|
||
|
{
|
||
|
if (ch < 128) // Bug 116203 - allow extended chars for international
|
||
|
return FALSE;
|
||
|
}
|
||
|
else if (c_rgValidChars[ch - CH_FIRST_VALID] == 0)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (ch != _T('.') && ch != _T(' '))
|
||
|
bAllPeriods = FALSE;
|
||
|
|
||
|
pszName = CharNext(pszName);
|
||
|
}
|
||
|
|
||
|
if (bAllPeriods)
|
||
|
return FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL GetWorkgroupName(LPTSTR pszBuffer, int cchBuffer)
|
||
|
{
|
||
|
ASSERT(pszBuffer != NULL);
|
||
|
*pszBuffer = _T('\0');
|
||
|
BOOL bResult = FALSE;
|
||
|
|
||
|
if (IsWindows9x())
|
||
|
{
|
||
|
CRegistry reg;
|
||
|
if (reg.OpenKey(HKEY_LOCAL_MACHINE, c_szNetConfig, KEY_QUERY_VALUE))
|
||
|
{
|
||
|
reg.QueryStringValue(c_szNetConfig_Workgroup, pszBuffer, cchBuffer);
|
||
|
bResult = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else // NT
|
||
|
{
|
||
|
LPWSTR pszWorkgroup;
|
||
|
NETSETUP_JOIN_STATUS njs;
|
||
|
|
||
|
if (NERR_Success == NetGetJoinInformation(NULL, &pszWorkgroup, &njs))
|
||
|
{
|
||
|
if (NetSetupWorkgroupName == njs)
|
||
|
{
|
||
|
StrCpyNW(pszBuffer, pszWorkgroup, cchBuffer);
|
||
|
|
||
|
bResult = TRUE;
|
||
|
}
|
||
|
|
||
|
NetApiBufferFree(pszWorkgroup);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL SetWorkgroupName(LPCTSTR pszWorkgroup)
|
||
|
{
|
||
|
ASSERT(pszWorkgroup != NULL);
|
||
|
ASSERT(IsComputerNameValid(pszWorkgroup));
|
||
|
|
||
|
BOOL bResult = FALSE;
|
||
|
|
||
|
if (g_fRunningOnNT)
|
||
|
{
|
||
|
NET_API_STATUS nas = NetUnjoinDomain(NULL, NULL, NULL, NETSETUP_ACCT_DELETE);
|
||
|
if ( (nas != NERR_Success) && (nas != NERR_SetupNotJoined) )
|
||
|
{
|
||
|
NetUnjoinDomain(NULL, NULL, NULL, 0x0);
|
||
|
}
|
||
|
|
||
|
nas = NetJoinDomain(NULL, pszWorkgroup, NULL, NULL, NULL, 0);
|
||
|
|
||
|
bResult = (nas == NERR_Success);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CRegistry reg;
|
||
|
if (reg.OpenKey(HKEY_LOCAL_MACHINE, c_szNetConfig, KEY_SET_VALUE))
|
||
|
{
|
||
|
reg.SetStringValue(c_szNetConfig_Workgroup, pszWorkgroup);
|
||
|
bResult = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
BOOL DoComputerNamesMatch(LPCTSTR pszName1, LPCTSTR pszName2)
|
||
|
{
|
||
|
if (pszName1[0] == _T('\\') && pszName1[1] == _T('\\'))
|
||
|
pszName1 += 2;
|
||
|
if (pszName2[0] == _T('\\') && pszName2[1] == _T('\\'))
|
||
|
pszName2 += 2;
|
||
|
|
||
|
return !StrCmpI(pszName1, pszName2);
|
||
|
}
|
||
|
|
||
|
void MakeComputerNamePretty(LPCTSTR pszUgly, LPTSTR pszPretty, int cchPretty)
|
||
|
{
|
||
|
if (pszUgly[0] == _T('\\') && pszUgly[1] == _T('\\'))
|
||
|
pszUgly += 2;
|
||
|
StrCpyN(pszPretty, pszUgly, cchPretty);
|
||
|
|
||
|
#ifdef SIMPLE_PRETTY_NAMES
|
||
|
CharLower(CharNext(pszPretty));
|
||
|
#else
|
||
|
static const LPCTSTR c_rgUpperNames[] = { _T("PC"), _T("HP"), _T("IBM"), _T("AT&T"), _T("NEC") };
|
||
|
|
||
|
LPTSTR pch = pszPretty;
|
||
|
BOOL bStartWord = TRUE;
|
||
|
TCHAR szTemp[MAX_PATH];
|
||
|
while (*pch)
|
||
|
{
|
||
|
if (*pch == _T(' ') || *pch == _T('_'))
|
||
|
{
|
||
|
pch++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LPTSTR pchNextSpace = StrChr(pch, _T(' '));
|
||
|
LPTSTR pchNextUnderscore = StrChr(pch, _T('_'));
|
||
|
LPTSTR pchNext = pchNextSpace;
|
||
|
if (pchNext == NULL || (pchNextUnderscore != NULL && pchNextUnderscore < pchNext))
|
||
|
pchNext = pchNextUnderscore;
|
||
|
LPTSTR pchEnd = pchNext;
|
||
|
if (pchNext == NULL)
|
||
|
pchNext = pch + lstrlen(pch);
|
||
|
int cchWord = (int)(pchNext - pch);
|
||
|
StrCpyN(szTemp, pch, cchWord + 1);
|
||
|
CharUpper(szTemp);
|
||
|
|
||
|
for (int iUpper = _countof(c_rgUpperNames)-1; iUpper >= 0; iUpper--)
|
||
|
{
|
||
|
if (!StrCmpI(szTemp, c_rgUpperNames[iUpper]))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (iUpper < 0)
|
||
|
CharLower(CharNext(szTemp));
|
||
|
|
||
|
CopyMemory(pch, szTemp, cchWord * sizeof(TCHAR));
|
||
|
pch = pchNext;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
LPTSTR FormatShareNameAlloc(LPCTSTR pszComputerName, LPCTSTR pszShareName)
|
||
|
{
|
||
|
ASSERT(pszComputerName != NULL);
|
||
|
ASSERT(pszShareName != NULL);
|
||
|
|
||
|
TCHAR szPrettyComputer[MAX_COMPUTERNAME_LENGTH+1];
|
||
|
MakeComputerNamePretty(pszComputerName, szPrettyComputer, _countof(szPrettyComputer));
|
||
|
|
||
|
TCHAR szPrettyShare[100];
|
||
|
MakeComputerNamePretty(pszShareName, szPrettyShare, _countof(szPrettyShare));
|
||
|
|
||
|
LPTSTR pszResult = theApp.FormatStringAlloc(IDS_SHARENAME, szPrettyShare, szPrettyComputer);
|
||
|
return pszResult;
|
||
|
}
|
||
|
|
||
|
// pszComputerAndShare is of the form \\kensh\printer
|
||
|
LPTSTR FormatShareNameAlloc(LPCTSTR pszComputerAndShare)
|
||
|
{
|
||
|
ASSERT(pszComputerAndShare[0] == _T('\\') && pszComputerAndShare[1] == _T('\\'));
|
||
|
ASSERT(CountChars(pszComputerAndShare, _T('\\')) == 3);
|
||
|
|
||
|
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
|
||
|
StrCpyN(szComputerName, pszComputerAndShare+2, _countof(szComputerName));
|
||
|
LPTSTR pchSlash = StrChr(szComputerName, _T('\\'));
|
||
|
if (pchSlash != NULL)
|
||
|
*pchSlash = _T('\0');
|
||
|
|
||
|
return FormatShareNameAlloc(szComputerName, FindFileTitle(pszComputerAndShare));
|
||
|
}
|
||
|
|