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.

561 lines
13 KiB

  1. #include "user.h"
  2. #include "winnet.h"
  3. #include "netdlg.h"
  4. void FAR PASCAL WriteOutProfiles(void);
  5. #define IFNRESTORECONNECTION 23
  6. #define IERR_MustBeLoggedOnToConnect 5000
  7. #define CFNNETDRIVER 22 /* number of winnet entrypoints */
  8. #define CFNNETDRIVER2 35 /* ... in Windows 3.1 */
  9. extern FARPROC NEAR* pNetInfo; /* pointer to list of WINNET entrypoints */
  10. extern HANDLE hWinnetDriver;
  11. extern void FAR PASCAL WNetEnable( void );
  12. extern WORD FAR PASCAL WNetGetCaps2(WORD nIndex); /* winnet.asm */
  13. typedef struct _conntext
  14. {
  15. char szDevice[5];
  16. char szPath[64];
  17. char szPassword[32];
  18. } CONNTEXT;
  19. char CODESEG szNet[] = "Network";
  20. char CODESEG szDialogs[] = "DefaultDialogs";
  21. HWND hwndTopNet = NULL;
  22. CONNTEXT FAR * lpctDlg;
  23. #ifdef WOW
  24. typedef VOID (FAR *LPTELLKRNL) (HINSTANCE);
  25. #endif
  26. WORD API IWNetGetCaps(WORD nIndex)
  27. {
  28. WORD wRet;
  29. if (nIndex == 0xFFFF)
  30. wRet = (WORD)hWinnetDriver;
  31. else {
  32. wRet = WNetGetCaps2(nIndex);
  33. if (nIndex == WNNC_DIALOG) {
  34. // turn off the drivers built in dialogs if
  35. // win.ini [network] defaultdialogs=1
  36. if (GetProfileInt(szNet, szDialogs, 0)) {
  37. wRet &= ~(WNNC_DLG_ConnectDialog |
  38. WNNC_DLG_DisconnectDialog |
  39. WNNC_DLG_ConnectionDialog);
  40. }
  41. }
  42. }
  43. return wRet;
  44. }
  45. WORD API WNetErrorText(WORD wError,LPSTR lpsz, WORD cbMax)
  46. {
  47. WORD wInternalError;
  48. WORD cb;
  49. char szT[40];
  50. if ((wError == WN_NET_ERROR)
  51. && (WNetGetError(&wInternalError) == WN_SUCCESS)
  52. && (WNetGetErrorText(wInternalError,lpsz,&cbMax) == WN_SUCCESS))
  53. {
  54. return cbMax;
  55. }
  56. else
  57. {
  58. cb = LoadString(hInstanceWin,STR_NETERRORS+wError,lpsz,cbMax);
  59. if (!cb)
  60. {
  61. LoadString(hInstanceWin,STR_NETERRORS,szT,sizeof(szT));
  62. cb = wvsprintf(lpsz, szT, (LPSTR)&wError);
  63. }
  64. }
  65. return cb;
  66. }
  67. #if 0
  68. /* CenterDialog() -
  69. *
  70. * Puts a dialog in an aesthetically pleasing place relative to its parent
  71. */
  72. void near pascal CenterDialog(HWND hwnd)
  73. {
  74. int x, y;
  75. /* center the dialog
  76. */
  77. if (hwnd->hwndOwner)
  78. {
  79. x = hwnd->hwndOwner->rcWindow.left;
  80. y = hwnd->hwndOwner->rcWindow.right;
  81. x += rgwSysMet[SM_CXSIZE] + rgwSysMet[SM_CXFRAME];
  82. y += rgwSysMet[SM_CYSIZE] + rgwSysMet[SM_CYFRAME];
  83. }
  84. else
  85. {
  86. x = (hwndDesktop->rcWindow.right
  87. - (hwnd->rcWindow.right-hwnd->rcWindow.left)) / 2;
  88. y = (hwndDesktop->rcWindow.bottom
  89. - (hwnd->rcWindow.bottom-hwnd->rcWindow.top)) / 2;
  90. }
  91. SetWindowPos(hwnd,NULL,x,y,0,0,SWP_NOSIZE);
  92. }
  93. #endif
  94. /* stub dlg proc for status dialog
  95. */
  96. BOOL CALLBACK ProgressDlgProc(HWND hwnd, WORD wMsg, WPARAM wParam, LPARAM lParam)
  97. {
  98. switch (wMsg)
  99. {
  100. case WM_INITDIALOG:
  101. // CenterDialog(hwnd);
  102. break;
  103. default:
  104. return FALSE;
  105. }
  106. return TRUE;
  107. }
  108. /* PasswordDlgProc() -
  109. *
  110. * Get a password for a network resource
  111. */
  112. BOOL CALLBACK PasswordDlgProc(HWND hwnd, WORD wMsg, WPARAM wParam, LPARAM lParam)
  113. {
  114. switch (wMsg)
  115. {
  116. case WM_INITDIALOG:
  117. // CenterDialog(hwnd);
  118. // Tell PenWin about this
  119. if (lpRegisterPenAwareApp)
  120. (*lpRegisterPenAwareApp)(1, TRUE);
  121. // SetDlgItemText(hwnd,IDD_DEV,lpctDlg->szDevice);
  122. SetDlgItemText(hwnd,IDD_PATH,lpctDlg->szPath);
  123. SendDlgItemMessage(hwnd, IDD_PASS, EM_LIMITTEXT, (WPARAM)(sizeof(lpctDlg->szPassword)-1), 0L);
  124. SetTimer(hwnd, 1, 30 * 1000, NULL);
  125. break;
  126. case WM_TIMER:
  127. KillTimer(hwnd, 1);
  128. wParam = (WPARAM)IDCANCEL;
  129. goto TimeOut;
  130. case WM_COMMAND:
  131. switch ((WORD)wParam)
  132. {
  133. case IDD_PASS:
  134. if (HIWORD(lParam) == EN_CHANGE)
  135. KillTimer(hwnd, 1);
  136. break;
  137. case IDOK:
  138. GetDlgItemText(hwnd,IDD_PASS,lpctDlg->szPassword, sizeof(lpctDlg->szPassword));
  139. /*** FALL THRU ***/
  140. case IDCANCEL:
  141. case IDABORT:
  142. TimeOut:
  143. if (lpRegisterPenAwareApp)
  144. (*lpRegisterPenAwareApp)(1, FALSE);
  145. EndDialog(hwnd, (int)wParam);
  146. break;
  147. }
  148. break;
  149. default:
  150. return FALSE;
  151. }
  152. return TRUE;
  153. }
  154. /* RestoreDevice() -
  155. *
  156. * Restores a single device. If fStartup is true, a dialog box is
  157. * posted to list the connections being made (this posting is deferred
  158. * until here so that if no permanant connections exist, none are
  159. * restored.
  160. */
  161. WORD NEAR PASCAL RestoreDevice(HWND hwndParent, LPSTR lpDev, BOOL fStartup, CONNTEXT FAR *lpct)
  162. {
  163. WORD wT;
  164. WORD err;
  165. WORD errorMode;
  166. WORD result;
  167. errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  168. result = WN_BAD_VALUE;
  169. if (lstrlen(lpDev) > 4)
  170. goto Done;
  171. lstrcpy(lpct->szDevice,lpDev);
  172. // If it's a drive that already exists then don't try to connect
  173. // over it.
  174. if (fStartup && *(lpDev+1) == ':') {
  175. if (GetDriveType(*lpDev-'A')) {
  176. // Drive already exists - don't stomp on it.
  177. result = WN_CANCEL; // Don't report error.
  178. goto Done;
  179. }
  180. }
  181. if (fStartup)
  182. goto GetFromINI;
  183. wT = sizeof(lpct->szPath);
  184. err = WNetGetConnection(lpct->szDevice,lpct->szPath,&wT);
  185. if (err == WN_SUCCESS) {
  186. result = WN_SUCCESS;
  187. goto Done;
  188. }
  189. if (err == WN_DEVICE_ERROR) {
  190. err = WNetCancelConnection(lpct->szDevice,FALSE);
  191. if (err == WN_OPEN_FILES) {
  192. // report a warning error to the user
  193. WNetCancelConnection(lpct->szDevice,TRUE);
  194. } else if (err != WN_SUCCESS) {
  195. result = err;
  196. goto Done;
  197. }
  198. } else if (err == WN_NOT_CONNECTED) {
  199. GetFromINI:
  200. if (!GetProfileString(szNet,lpct->szDevice,"",lpct->szPath,sizeof(lpct->szPath))) {
  201. result = WN_NOT_CONNECTED;
  202. goto Done;
  203. }
  204. } else if (err != WN_CONNECTION_CLOSED) {
  205. result = err;
  206. goto Done;
  207. }
  208. // initially attempt with a blank password
  209. //
  210. lpct->szPassword[0] = 0;
  211. // if on startup, show the status dialog
  212. //
  213. if (fStartup) {
  214. if (!hwndTopNet) {
  215. hwndTopNet = CreateDialog(hInstanceWin,IDD_CONNECTPROGRESS,NULL,ProgressDlgProc);
  216. if (!hwndTopNet)
  217. goto TryConnection;
  218. ShowWindow(hwndTopNet,SW_SHOW);
  219. }
  220. SetDlgItemText(hwndTopNet,IDD_DEV,lpct->szDevice);
  221. SetDlgItemText(hwndTopNet,IDD_PATH,lpct->szPath);
  222. UpdateWindow(hwndTopNet);
  223. hwndParent = hwndTopNet;
  224. }
  225. TryConnection:
  226. // lpct->szPath now contains the path
  227. // and lpct->szPassword the password...
  228. err = WNetAddConnection(lpct->szPath,lpct->szPassword,lpct->szDevice);
  229. // if we're booting and the thing is connected, ignore
  230. if (fStartup && err == WN_ALREADY_CONNECTED) {
  231. result = WN_SUCCESS;
  232. goto Done;
  233. }
  234. // if it was success or some other error, return
  235. if (err != WN_BAD_PASSWORD && err != WN_ACCESS_DENIED) {
  236. result = err;
  237. goto Done;
  238. }
  239. // it was bad password. prompt the user for the correct password
  240. lpctDlg = lpct;
  241. switch (DialogBox(hInstanceWin,IDD_PASSWORD,hwndParent,PasswordDlgProc)) {
  242. case -1:
  243. result = WN_OUT_OF_MEMORY;
  244. break;
  245. case IDOK:
  246. goto TryConnection;
  247. break;
  248. case IDCANCEL:
  249. result = WN_CANCEL;
  250. break;
  251. case IDABORT:
  252. result = WN_NET_ERROR;
  253. break;
  254. }
  255. Done:
  256. SetErrorMode(errorMode);
  257. return result;
  258. }
  259. /* ReportError() -
  260. *
  261. * Tell the user why the network connection failed
  262. */
  263. void NEAR PASCAL ReportError(HWND hwndParent, WORD err, CONNTEXT FAR *lpct)
  264. {
  265. char szTitle[80];
  266. char szT[200];
  267. char szError[150];
  268. LPSTR rglp[2];
  269. switch (err)
  270. {
  271. case WN_SUCCESS:
  272. case WN_CANCEL:
  273. case WN_NOT_CONNECTED:
  274. return;
  275. }
  276. WNetErrorText(err,szT,sizeof(szT));
  277. LoadString(hInstanceWin,STR_NETCONNMSG,szTitle,sizeof(szTitle));
  278. rglp[0] = (LPSTR)lpct->szPath;
  279. rglp[1] = (LPSTR)szT;
  280. wvsprintf(szError,szTitle,(LPSTR)rglp);
  281. LoadString(hInstanceWin,STR_NETCONNTTL,szTitle,sizeof(szTitle));
  282. MessageBox(hwndParent,szError,szTitle,MB_OK|MB_ICONEXCLAMATION);
  283. }
  284. /* WNetRestoreConnection() -
  285. *
  286. * This function implements the "standard" restore-connection process.
  287. * If the function is supported by the network driver, the driver is
  288. * called instead. Otherwise, standard behaviour is supplied.
  289. */
  290. typedef WORD (FAR PASCAL* PFN_NETRESTORECON)(HWND, LPSTR);
  291. UINT API WNetRestoreConnection(HWND hwndParent, LPSTR lpszDevice)
  292. {
  293. static char CODESEG szInRestore[]="InRestoreNetConnect";
  294. static char CODESEG szRestore[]="Restore";
  295. char szDevice[10];
  296. char szTitle[50];
  297. char szMsg[255];
  298. CONNTEXT ct;
  299. WORD i;
  300. WORD err;
  301. BOOL bLoggedIn;
  302. if (!pNetInfo)
  303. return(WN_NOT_SUPPORTED);
  304. if (WNetGetCaps(WNNC_CONNECTION) & WNNC_CON_RestoreConnection)
  305. {
  306. /* The device driver supports this call
  307. */
  308. return (*(PFN_NETRESTORECON)(pNetInfo[IFNRESTORECONNECTION - 1]))(hwndParent, lpszDevice);
  309. }
  310. /* the network does not support restore connections. do the default
  311. */
  312. if (HIWORD(lpszDevice))
  313. return RestoreDevice(hwndParent,lpszDevice,FALSE,&ct);
  314. // check to see if restoring net connects is enabled
  315. if (!GetProfileInt(szNet,szRestore,1))
  316. return(WN_SUCCESS);
  317. /* Check if we previously aborted in the middle of restoring net
  318. * connections.
  319. */
  320. if (GetProfileInt(szNet,szInRestore,0))
  321. {
  322. /* We died in the middle of restoring net connects. Inform user.
  323. */
  324. LoadString(hInstanceWin, STR_NETCRASHEDTITLE, szTitle, sizeof(szTitle));
  325. LoadString(hInstanceWin, STR_NETCRASHEDMSG, szMsg, sizeof(szMsg));
  326. err = MessageBox(NULL, szMsg, szTitle,
  327. MB_ICONEXCLAMATION | MB_RETRYCANCEL | MB_SYSTEMMODAL);
  328. if (err == IDCANCEL)
  329. goto ExitRestoreNet;
  330. }
  331. WriteProfileString(szNet,szInRestore,"1");
  332. /* Flush cache.
  333. */
  334. WriteOutProfiles();
  335. szDevice[1]=':';
  336. szDevice[2]=0;
  337. bLoggedIn = TRUE;
  338. for (i = 0; i < 26; i++)
  339. {
  340. szDevice[0] = (char)('A' + i);
  341. err = GetDriveType(i);
  342. if (err == DRIVE_FIXED || err == DRIVE_REMOVABLE)
  343. {
  344. /* Don't restore to system drives in case the user added a ram
  345. * drive or new hard disk or something...
  346. */
  347. continue;
  348. }
  349. else
  350. {
  351. err = RestoreDevice(hwndParent,szDevice,TRUE,&ct);
  352. }
  353. hwndParent = hwndTopNet;
  354. if ( (err == WN_NET_ERROR) &&
  355. (WNetGetCaps (WNNC_NET_TYPE) == WNNC_NET_LanMan) &&
  356. (WNetGetError (&err) == WN_SUCCESS) &&
  357. (err == IERR_MustBeLoggedOnToConnect) )
  358. {
  359. bLoggedIn = FALSE;
  360. break; /* if not logged on to LanMan, skip rest #8361 RAID */
  361. }
  362. else
  363. // report error to user
  364. ReportError(hwndParent,err,&ct);
  365. }
  366. /* Try to restore printer connections only if logged in. Fix for #8361
  367. * [lalithar] - 11/14/91
  368. */
  369. if (bLoggedIn)
  370. {
  371. szDevice[0] = 'L';
  372. szDevice[1] = 'P';
  373. szDevice[2] = 'T';
  374. szDevice[4] = 0;
  375. for (i = 0; i < 3; i++)
  376. {
  377. szDevice[3] = (char)('1' + i);
  378. err = RestoreDevice(hwndParent,szDevice,TRUE,&ct);
  379. hwndParent = hwndTopNet;
  380. ReportError(hwndParent,err,&ct);
  381. }
  382. }
  383. if (hwndTopNet)
  384. {
  385. DestroyWindow(hwndTopNet);
  386. hwndTopNet = NULL;
  387. }
  388. ExitRestoreNet:
  389. /* Write out a 0 since we are no longer restoring net connections.
  390. */
  391. WriteProfileString(szNet,szInRestore,NULL);
  392. return(WN_SUCCESS);
  393. }
  394. /*--------------------------------------------------------------------------*/
  395. /* */
  396. /* LW_InitNetInfo() - */
  397. /* */
  398. /*--------------------------------------------------------------------------*/
  399. void FAR PASCAL LW_InitNetInfo(void)
  400. {
  401. int i;
  402. char szDriver[64];
  403. char szFile[32];
  404. char szSection[32];
  405. #ifdef WOW
  406. HINSTANCE hInst;
  407. LPTELLKRNL lpTellKrnlWhoNetDrvIs;
  408. #endif
  409. pNetInfo=NULL;
  410. if (!LoadString(hInstanceWin,STR_NETDRIVER,szDriver,sizeof(szDriver)))
  411. return;
  412. if (!LoadString(hInstanceWin,STR_BOOT,szSection,sizeof(szSection)))
  413. return;
  414. if (!LoadString(hInstanceWin,STR_SYSTEMINI,szFile,sizeof(szFile)))
  415. return;
  416. /* look for in the tag NETWORK.DRV, with that as the output and the
  417. * default string...
  418. */
  419. GetPrivateProfileString(szSection,szDriver,szDriver,szDriver,
  420. sizeof(szDriver),szFile);
  421. /* if entry present, but blank, punt
  422. */
  423. if (!*szDriver)
  424. return;
  425. hWinnetDriver = LoadLibrary(szDriver);
  426. if (hWinnetDriver < HINSTANCE_ERROR)
  427. return;
  428. pNetInfo = (FARPROC NEAR*)UserLocalAlloc(ST_STRING,LPTR,sizeof(FARPROC)*CFNNETDRIVER2);
  429. if (!pNetInfo)
  430. {
  431. FreeLibrary(hWinnetDriver);
  432. return;
  433. }
  434. for (i=0; i<CFNNETDRIVER; i++)
  435. {
  436. pNetInfo[i]=GetProcAddress(hWinnetDriver,MAKEINTRESOURCE(i+1));
  437. }
  438. if (WNetGetCaps(WNNC_SPEC_VERSION) >= 0x30D)
  439. {
  440. for (;i<CFNNETDRIVER2; i++)
  441. {
  442. pNetInfo[i]=GetProcAddress(hWinnetDriver,MAKEINTRESOURCE(i+1));
  443. }
  444. }
  445. #ifdef WOW
  446. // Sets up krnl robustness mechanism which allows us to prevent non-user.exe
  447. // modules from freeing the net driver (ie. causing ref count=0). Otherwise
  448. // the proc addresses stored in pNetInfo would become invalid. bug #393078
  449. hInst = LoadLibrary("krnl386.exe");
  450. // if this fails, we just fly without robustness -- the way we used to...
  451. if(HINSTANCE_ERROR <= hInst) {
  452. lpTellKrnlWhoNetDrvIs =
  453. (LPTELLKRNL) GetProcAddress(hInst, MAKEINTRESOURCE(545));
  454. if(lpTellKrnlWhoNetDrvIs) {
  455. lpTellKrnlWhoNetDrvIs(hWinnetDriver);
  456. }
  457. }
  458. FreeLibrary(hInst);
  459. #endif
  460. WNetEnable();
  461. }