Source code of Windows XP (NT5)
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.

246 lines
6.9 KiB

  1. //
  2. // NetUtil.cpp
  3. //
  4. #include "stdafx.h"
  5. #include "Util.h"
  6. #include "TheApp.h"
  7. #include <lmjoin.h>
  8. #include <devguid.h>
  9. #include "NetUtil.h"
  10. // Network registry entries
  11. #define c_szNetConfig _T("System\\CurrentControlSet\\Services\\VxD\\VNETSUP")
  12. #define c_szNetConfig_ComputerName _T("ComputerName")
  13. #define c_szNetConfig_Description _T("Comment")
  14. #define c_szNetConfig_Workgroup _T("Workgroup")
  15. // A valid computer name is a max of MAX_COMPUTERNAME_LENGTH (15) chars,
  16. // and contains only the following characters:
  17. // A-Z a-z 0-9 `!#$@%&'()-.^_{}~
  18. // It also may not consist of all periods.
  19. //
  20. // REVIEW: Is this accurate even on Japanese and other international Windows?
  21. //
  22. static const BYTE c_rgValidChars[] = {
  23. 1, // 32 (space)
  24. 1, // 33 !
  25. 0, // 34 "
  26. 1,1,1,1,1,1,1, // 35-41 #$%&'()
  27. 0,0,0, // 42-44 *+,
  28. 1,1, // 45-46 -.
  29. 0, // 47 /
  30. 1,1,1,1,1,1,1,1,1,1, // 48-57 0123456789
  31. 0,0,0,0,0,0, // 58-63 :;<=>?
  32. 1,1,1,1,1,1,1,1,1,1, // 64-73 @ABCDEFGHI
  33. 1,1,1,1,1,1,1,1,1,1, // 74-83 JKLMNOPQRS
  34. 1,1,1,1,1,1,1, // 84-90 TUVWXYZ
  35. 0,0,0, // 91-93 [\]
  36. 1,1,1, // 94-96 ^_`
  37. 1,1,1,1,1,1,1,1,1,1, // 97-106 abcdefghij
  38. 1,1,1,1,1,1,1,1,1,1, // 107-116 klmnopqrst
  39. 1,1,1,1,1,1,1, // 117-123 uvwxyz{
  40. 0, // 124 |
  41. 1,1, // 125-126 }~
  42. };
  43. #define CH_FIRST_VALID 32
  44. #define CH_LAST_VALID (_countof(c_rgValidChars) + CH_FIRST_VALID - 1)
  45. BOOL IsComputerNameValid(LPCTSTR pszName)
  46. {
  47. if (lstrlen(pszName) > MAX_COMPUTERNAME_LENGTH)
  48. return FALSE;
  49. UCHAR ch;
  50. BOOL bAllPeriods = TRUE; // can't be all periods and/or whitespace
  51. while ((ch = (UCHAR)*pszName) != _T('\0'))
  52. {
  53. if (ch < CH_FIRST_VALID || ch > CH_LAST_VALID)
  54. {
  55. if (ch < 128) // Bug 116203 - allow extended chars for international
  56. return FALSE;
  57. }
  58. else if (c_rgValidChars[ch - CH_FIRST_VALID] == 0)
  59. {
  60. return FALSE;
  61. }
  62. if (ch != _T('.') && ch != _T(' '))
  63. bAllPeriods = FALSE;
  64. pszName = CharNext(pszName);
  65. }
  66. if (bAllPeriods)
  67. return FALSE;
  68. return TRUE;
  69. }
  70. BOOL GetWorkgroupName(LPTSTR pszBuffer, int cchBuffer)
  71. {
  72. ASSERT(pszBuffer != NULL);
  73. *pszBuffer = _T('\0');
  74. BOOL bResult = FALSE;
  75. if (IsWindows9x())
  76. {
  77. CRegistry reg;
  78. if (reg.OpenKey(HKEY_LOCAL_MACHINE, c_szNetConfig, KEY_QUERY_VALUE))
  79. {
  80. reg.QueryStringValue(c_szNetConfig_Workgroup, pszBuffer, cchBuffer);
  81. bResult = TRUE;
  82. }
  83. }
  84. else // NT
  85. {
  86. LPWSTR pszWorkgroup;
  87. NETSETUP_JOIN_STATUS njs;
  88. if (NERR_Success == NetGetJoinInformation(NULL, &pszWorkgroup, &njs))
  89. {
  90. if (NetSetupWorkgroupName == njs)
  91. {
  92. StrCpyNW(pszBuffer, pszWorkgroup, cchBuffer);
  93. bResult = TRUE;
  94. }
  95. NetApiBufferFree(pszWorkgroup);
  96. }
  97. }
  98. return bResult;
  99. }
  100. BOOL SetWorkgroupName(LPCTSTR pszWorkgroup)
  101. {
  102. ASSERT(pszWorkgroup != NULL);
  103. ASSERT(IsComputerNameValid(pszWorkgroup));
  104. BOOL bResult = FALSE;
  105. if (g_fRunningOnNT)
  106. {
  107. NET_API_STATUS nas = NetUnjoinDomain(NULL, NULL, NULL, NETSETUP_ACCT_DELETE);
  108. if ( (nas != NERR_Success) && (nas != NERR_SetupNotJoined) )
  109. {
  110. NetUnjoinDomain(NULL, NULL, NULL, 0x0);
  111. }
  112. nas = NetJoinDomain(NULL, pszWorkgroup, NULL, NULL, NULL, 0);
  113. bResult = (nas == NERR_Success);
  114. }
  115. else
  116. {
  117. CRegistry reg;
  118. if (reg.OpenKey(HKEY_LOCAL_MACHINE, c_szNetConfig, KEY_SET_VALUE))
  119. {
  120. reg.SetStringValue(c_szNetConfig_Workgroup, pszWorkgroup);
  121. bResult = TRUE;
  122. }
  123. }
  124. return bResult;
  125. }
  126. BOOL DoComputerNamesMatch(LPCTSTR pszName1, LPCTSTR pszName2)
  127. {
  128. if (pszName1[0] == _T('\\') && pszName1[1] == _T('\\'))
  129. pszName1 += 2;
  130. if (pszName2[0] == _T('\\') && pszName2[1] == _T('\\'))
  131. pszName2 += 2;
  132. return !StrCmpI(pszName1, pszName2);
  133. }
  134. void MakeComputerNamePretty(LPCTSTR pszUgly, LPTSTR pszPretty, int cchPretty)
  135. {
  136. if (pszUgly[0] == _T('\\') && pszUgly[1] == _T('\\'))
  137. pszUgly += 2;
  138. StrCpyN(pszPretty, pszUgly, cchPretty);
  139. #ifdef SIMPLE_PRETTY_NAMES
  140. CharLower(CharNext(pszPretty));
  141. #else
  142. static const LPCTSTR c_rgUpperNames[] = { _T("PC"), _T("HP"), _T("IBM"), _T("AT&T"), _T("NEC") };
  143. LPTSTR pch = pszPretty;
  144. BOOL bStartWord = TRUE;
  145. TCHAR szTemp[MAX_PATH];
  146. while (*pch)
  147. {
  148. if (*pch == _T(' ') || *pch == _T('_'))
  149. {
  150. pch++;
  151. }
  152. else
  153. {
  154. LPTSTR pchNextSpace = StrChr(pch, _T(' '));
  155. LPTSTR pchNextUnderscore = StrChr(pch, _T('_'));
  156. LPTSTR pchNext = pchNextSpace;
  157. if (pchNext == NULL || (pchNextUnderscore != NULL && pchNextUnderscore < pchNext))
  158. pchNext = pchNextUnderscore;
  159. LPTSTR pchEnd = pchNext;
  160. if (pchNext == NULL)
  161. pchNext = pch + lstrlen(pch);
  162. int cchWord = (int)(pchNext - pch);
  163. StrCpyN(szTemp, pch, cchWord + 1);
  164. CharUpper(szTemp);
  165. for (int iUpper = _countof(c_rgUpperNames)-1; iUpper >= 0; iUpper--)
  166. {
  167. if (!StrCmpI(szTemp, c_rgUpperNames[iUpper]))
  168. break;
  169. }
  170. if (iUpper < 0)
  171. CharLower(CharNext(szTemp));
  172. CopyMemory(pch, szTemp, cchWord * sizeof(TCHAR));
  173. pch = pchNext;
  174. }
  175. }
  176. #endif
  177. }
  178. LPTSTR FormatShareNameAlloc(LPCTSTR pszComputerName, LPCTSTR pszShareName)
  179. {
  180. ASSERT(pszComputerName != NULL);
  181. ASSERT(pszShareName != NULL);
  182. TCHAR szPrettyComputer[MAX_COMPUTERNAME_LENGTH+1];
  183. MakeComputerNamePretty(pszComputerName, szPrettyComputer, _countof(szPrettyComputer));
  184. TCHAR szPrettyShare[100];
  185. MakeComputerNamePretty(pszShareName, szPrettyShare, _countof(szPrettyShare));
  186. LPTSTR pszResult = theApp.FormatStringAlloc(IDS_SHARENAME, szPrettyShare, szPrettyComputer);
  187. return pszResult;
  188. }
  189. // pszComputerAndShare is of the form \\kensh\printer
  190. LPTSTR FormatShareNameAlloc(LPCTSTR pszComputerAndShare)
  191. {
  192. ASSERT(pszComputerAndShare[0] == _T('\\') && pszComputerAndShare[1] == _T('\\'));
  193. ASSERT(CountChars(pszComputerAndShare, _T('\\')) == 3);
  194. TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
  195. StrCpyN(szComputerName, pszComputerAndShare+2, _countof(szComputerName));
  196. LPTSTR pchSlash = StrChr(szComputerName, _T('\\'));
  197. if (pchSlash != NULL)
  198. *pchSlash = _T('\0');
  199. return FormatShareNameAlloc(szComputerName, FindFileTitle(pszComputerAndShare));
  200. }