// // NetUtil.cpp // #include "stdafx.h" #include "Util.h" #include "TheApp.h" #include #include #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)); }