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