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.

437 lines
13 KiB

  1. /*
  2. +-------------------------------------------------------------------------+
  3. | Network Utility Functions |
  4. +-------------------------------------------------------------------------+
  5. | (c) Copyright 1993-1994 |
  6. | Microsoft Corp. |
  7. | All rights reserved |
  8. | |
  9. | Program : [NetUtil.c] |
  10. | Programmer : Arthur Hanson |
  11. | Original Program Date : [Feb 16, 1993] |
  12. | Last Update : [Jun 16, 1994] |
  13. | |
  14. | Version: 1.00 |
  15. | |
  16. | Description: |
  17. | |
  18. | History: |
  19. | arth Jun 16, 1994 1.00 Original Version. |
  20. | |
  21. +-------------------------------------------------------------------------+
  22. */
  23. #include "globals.h"
  24. #include "netutil.h"
  25. static LPTSTR ServName;
  26. static TCHAR szPassword[PWLEN+1];
  27. static TCHAR szUserName[MAX_USER_NAME_LEN + 1];
  28. LRESULT CALLBACK PasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  29. BOOL BadPassword;
  30. /*+-------------------------------------------------------------------------+
  31. | FixPathSlash()
  32. |
  33. +-------------------------------------------------------------------------+*/
  34. void FixPathSlash(LPTSTR NewPath, LPTSTR Path) {
  35. UINT PathLen;
  36. lstrcpy(NewPath, Path);
  37. PathLen = lstrlen(Path);
  38. // If ending character is not a slash then put one on
  39. if (PathLen && (Path[PathLen - 1] != '\\'))
  40. lstrcat(NewPath, TEXT("\\"));
  41. } // FixPathSlash
  42. /*+-------------------------------------------------------------------------+
  43. | ShareNameParse()
  44. |
  45. +-------------------------------------------------------------------------+*/
  46. LPTSTR ShareNameParse(LPTSTR ShareName) {
  47. ULONG i;
  48. i = lstrlen(ShareName);
  49. if (!i)
  50. return ShareName;
  51. // Scan backwards for first slash
  52. i--;
  53. while (i && ShareName[i] != TEXT('\\'))
  54. i--;
  55. // if found slash then increment past it
  56. if (i)
  57. i++;
  58. return &ShareName[i];
  59. } // ShareNameParse
  60. static LPTSTR LocName = NULL;
  61. /*+-------------------------------------------------------------------------+
  62. | GetLocalName()
  63. |
  64. +-------------------------------------------------------------------------+*/
  65. void GetLocalName(LPTSTR *lpLocalName) {
  66. int size;
  67. if (LocName != NULL) {
  68. *lpLocalName = LocName;
  69. } else {
  70. LocName = AllocMemory((MAX_COMPUTERNAME_LENGTH + 1) * sizeof(TCHAR));
  71. size = MAX_COMPUTERNAME_LENGTH + 1;
  72. if (LocName) {
  73. GetComputerName(LocName, &size);
  74. *lpLocalName = LocName;
  75. } else
  76. *lpLocalName = NULL;
  77. }
  78. } // GetLocalName
  79. /*+-------------------------------------------------------------------------+
  80. | SetProvider()
  81. |
  82. +-------------------------------------------------------------------------+*/
  83. BOOL SetProvider(LPTSTR Provider, NETRESOURCE *ResourceBuf) {
  84. ResourceBuf->dwScope = RESOURCE_GLOBALNET;
  85. ResourceBuf->dwType = RESOURCETYPE_DISK;
  86. ResourceBuf->dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
  87. // Don't take the frigging _RESERVED flag out - it isn't documented except in the include
  88. // file and it crashes without it!
  89. ResourceBuf->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
  90. ResourceBuf->lpLocalName = NULL;
  91. ResourceBuf->lpRemoteName = Provider;
  92. ResourceBuf->lpComment = NULL;
  93. ResourceBuf->lpProvider = Provider;
  94. return TRUE;
  95. } // SetProvider
  96. /*+-------------------------------------------------------------------------+
  97. | AllocEnumBuffer()
  98. |
  99. +-------------------------------------------------------------------------+*/
  100. ENUM_REC *AllocEnumBuffer() {
  101. ENUM_REC *Buf;
  102. Buf = (ENUM_REC *) AllocMemory(sizeof(ENUM_REC));
  103. if (Buf) {
  104. // Init the record
  105. Buf->next = NULL;
  106. Buf->cEntries = 0;
  107. Buf->cbBuffer = 0;
  108. Buf->lpnr = NULL;
  109. }
  110. return Buf;
  111. } // AllocEnumBuffer
  112. /*+-------------------------------------------------------------------------+
  113. | EnumBufferBuild()
  114. |
  115. | Uses WNetEnum to enumerate the resource. WNetEnum is really brain-
  116. | dead so we need to create a temporary holding array and then build
  117. | up a finalized complete buffer in the end. A linked list of inter-
  118. | mediate buffer records is created first.
  119. |
  120. +-------------------------------------------------------------------------+*/
  121. DWORD FAR PASCAL EnumBufferBuild(ENUM_REC **BufHead, int *NumBufs, NETRESOURCE ResourceBuf) {
  122. DWORD status = ERROR_NO_NETWORK;
  123. ENUM_REC *CurrBuf;
  124. DWORD dwResultEnum;
  125. HANDLE hEnum = NULL;
  126. DWORD cbBuffer = 16384; // 16K default buffer size.
  127. DWORD cEntries = 0xFFFFFFFF; // enumerate all possible entries
  128. ENUM_REC **lppEnumRec;
  129. LPNETRESOURCE lpnrLocal;
  130. status = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, &ResourceBuf, &hEnum);
  131. if (status == NO_ERROR) {
  132. *BufHead = NULL;
  133. lppEnumRec = BufHead;
  134. do {
  135. cbBuffer = 16384; // 16K default buffer size
  136. cEntries = 0xFFFFFFFF; // enumerate all possible entries
  137. // Allocate memory for NETRESOURCE structures.
  138. lpnrLocal = (LPNETRESOURCE) AllocMemory(cbBuffer);
  139. if (lpnrLocal == NULL) {
  140. status = ERROR_NOT_ENOUGH_MEMORY;
  141. break;
  142. }
  143. dwResultEnum = WNetEnumResource(hEnum, &cEntries, (LPVOID) lpnrLocal, &cbBuffer);
  144. if (dwResultEnum == NO_ERROR) {
  145. // Create a new Enum rec and link it to the chain
  146. *lppEnumRec = AllocEnumBuffer();
  147. if (*lppEnumRec == NULL) {
  148. status = ERROR_NOT_ENOUGH_MEMORY;
  149. break;
  150. }
  151. CurrBuf = *lppEnumRec;
  152. // Init for next loop through buffer
  153. lppEnumRec = &CurrBuf->next;
  154. // Put enumeration buffer in our Enum rec.
  155. CurrBuf->lpnr = lpnrLocal;
  156. CurrBuf->cEntries = cEntries;
  157. CurrBuf->cbBuffer = cbBuffer;
  158. (*NumBufs)++;
  159. } else { // Since this is not assigned in a rec we need to free it here.
  160. FreeMemory((HGLOBAL) lpnrLocal);
  161. if (dwResultEnum != ERROR_NO_MORE_ITEMS) {
  162. status = dwResultEnum;
  163. break;
  164. }
  165. }
  166. } while (dwResultEnum != ERROR_NO_MORE_ITEMS);
  167. status = WNetCloseEnum(hEnum);
  168. }
  169. return status;
  170. } // EnumBufferBuild
  171. /*+-------------------------------------------------------------------------+
  172. | UseAddPswd()
  173. |
  174. | Attempts to make connections to \\szServer\admin$, asking for
  175. | passwords if necessary.
  176. |
  177. | Returns TRUE if use was added,
  178. | FALSE otherwise
  179. |
  180. +-------------------------------------------------------------------------+*/
  181. BOOL UseAddPswd(HWND hwnd, LPTSTR UserName, LPTSTR lpszServer, LPTSTR lpszShare, LPTSTR Provider) {
  182. WORD nState;
  183. WORD fCancel;
  184. DLGPROC lpProc;
  185. NETRESOURCE nr;
  186. NET_API_STATUS retcode;
  187. LPTSTR lpPassword;
  188. static TCHAR szTmp[MAX_UNC_PATH+1];
  189. ServName = lpszServer;
  190. nr.dwScope = 0;
  191. nr.dwType = RESOURCETYPE_DISK;
  192. nr.dwDisplayType = 0;
  193. nr.dwUsage = 0;
  194. nr.lpProvider = NULL;
  195. nState = 1; // try default password
  196. lpPassword = NULL;
  197. BadPassword = FALSE;
  198. lstrcpy(szUserName, UserName);
  199. for(;;) {
  200. // Concatenate server and share
  201. wsprintf(szTmp, TEXT("%s\\%s"), lpszServer, lpszShare);
  202. // Fill in data structure
  203. nr.lpLocalName = NULL;
  204. nr.lpRemoteName = szTmp;
  205. nr.lpProvider = Provider;
  206. // Try to make the connection
  207. if (lstrlen(szUserName))
  208. retcode = WNetAddConnection2(&nr, lpPassword, szUserName, 0);
  209. else
  210. retcode = WNetAddConnection2(&nr, lpPassword, NULL, 0);
  211. switch(retcode) {
  212. case NERR_Success:
  213. lstrcpy(UserName, szUserName);
  214. return TRUE;
  215. case ERROR_INVALID_PASSWORD:
  216. BadPassword = TRUE;
  217. break;
  218. case ERROR_ACCESS_DENIED:
  219. case ERROR_NETWORK_ACCESS_DENIED:
  220. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  221. case ERROR_NO_SUCH_USER:
  222. case ERROR_NO_MORE_ITEMS:
  223. case ERROR_LOGON_FAILURE:
  224. BadPassword = FALSE;
  225. break;
  226. case ERROR_BAD_NETPATH:
  227. case ERROR_BAD_NET_NAME:
  228. default:
  229. return FALSE;
  230. }
  231. // Get new password from user
  232. lpProc = (DLGPROC) MakeProcInstance(PasswordDlgProc, hInst);
  233. fCancel = !DialogBoxParam(hInst, TEXT("PasswordEnter"), hwnd, lpProc, 0);
  234. // Gamble call only once
  235. FreeProcInstance(lpProc);
  236. // Save...
  237. if(!fCancel) {
  238. if(nState) {
  239. nState = 2; // try specified password
  240. lpPassword = szPassword;
  241. } else {
  242. nState = 1; // try default password
  243. lpPassword = NULL;
  244. }
  245. } else {
  246. SetLastError(ERROR_SUCCESS); // just aborting...
  247. return FALSE;
  248. }
  249. }
  250. } // UseAddPswd
  251. /*+-------------------------------------------------------------------------+
  252. | PasswordDlgProc()
  253. |
  254. | Gets a password from the user and copies it into the string pointed
  255. | to by lParam. This string must have room for at least (PWLEN + 1)
  256. | characters. Returns TRUE if OK is pressed, or FALSE if Cancel
  257. |
  258. +-------------------------------------------------------------------------+*/
  259. LRESULT CALLBACK PasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  260. switch (msg) {
  261. case WM_INITDIALOG:
  262. CursorNormal();
  263. // Center the dialog over the application window
  264. CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
  265. SetDlgItemText(hDlg, IDC_SERVNAME, ServName);
  266. SendDlgItemMessage(hDlg, IDC_PASSWORD, EM_LIMITTEXT, PWLEN, 0L);
  267. SendDlgItemMessage(hDlg, IDC_USERNAME, EM_LIMITTEXT, MAX_USER_NAME_LEN, 0L);
  268. PostMessage(hDlg, WM_COMMAND, ID_INIT, 0L);
  269. break;
  270. case WM_COMMAND:
  271. switch(wParam) {
  272. case IDOK:
  273. CursorHourGlass();
  274. GetDlgItemText(hDlg, IDC_PASSWORD, szPassword, PWLEN+1);
  275. GetDlgItemText(hDlg, IDC_USERNAME, szUserName, MAX_USER_NAME_LEN+1);
  276. EndDialog(hDlg, TRUE);
  277. break;
  278. case IDCANCEL:
  279. CursorHourGlass();
  280. EndDialog(hDlg, FALSE);
  281. break;
  282. case ID_INIT:
  283. SendDlgItemMessage(hDlg, IDC_USERNAME, WM_SETTEXT, 0, (LPARAM) szUserName);
  284. if (BadPassword)
  285. SetFocus(GetDlgItem(hDlg, IDC_PASSWORD));
  286. else {
  287. SetFocus(GetDlgItem(hDlg, IDC_USERNAME));
  288. SendDlgItemMessage(hDlg, IDC_USERNAME, EM_SETSEL, 0, (LPARAM) MAKELPARAM(0, -1) );
  289. }
  290. break;
  291. default:
  292. return FALSE;
  293. }
  294. break;
  295. default:
  296. return FALSE;
  297. }
  298. return TRUE;
  299. } // PasswordDlgProc
  300. /*+-------------------------------------------------------------------------+
  301. | NicePath()
  302. |
  303. +-------------------------------------------------------------------------+*/
  304. LPTSTR NicePath(int Len, LPTSTR Path) {
  305. static TCHAR NewPath[MAX_PATH + 80];
  306. int eptr, fptr;
  307. // If the path fits then just return it
  308. if (lstrlen(Path) <= Len) {
  309. lstrcpy(NewPath, Path);
  310. return NewPath;
  311. }
  312. // The path doesn't fit, so need to reduce it down in size - to do this first try
  313. // to get the last part of the path looking for slash that starts it.
  314. eptr = fptr = 0;
  315. while (Path[eptr] != TEXT('\0'))
  316. eptr++;
  317. // back up before ending NULL also before any ending slash
  318. eptr--;
  319. while ((Path[eptr] == TEXT('\\')) && eptr > 0)
  320. eptr--;
  321. // now try to find beginning slash
  322. while ((Path[eptr] != TEXT('\\')) && eptr > 0)
  323. eptr--;
  324. // if at beginning of string then is just one name so copy all of it we can
  325. if (eptr == 0) {
  326. lstrcpyn(NewPath, Path, Len);
  327. return NewPath;
  328. }
  329. // check if the name after the last slash can all fit - also take into account
  330. // the "..." we are going to tack into the name
  331. fptr = lstrlen(Path) - eptr;
  332. fptr += 4;
  333. if (fptr >= Len) {
  334. lstrcpyn(NewPath, &Path[eptr], Len);
  335. return NewPath;
  336. }
  337. // We need to create a path shortening to the desired length by removing the mid
  338. // part of the path and replacing it with "..."
  339. fptr = Len - fptr;
  340. lstrcpyn(NewPath, Path, fptr);
  341. lstrcat(NewPath, TEXT("..."));
  342. lstrcat(NewPath, &Path[eptr]);
  343. return NewPath;
  344. } // NicePath