windows-nt/Source/XPSP1/NT/shell/ext/hnw/wizard/netutil.cpp
2020-09-26 16:20:57 +08:00

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));
}