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.

626 lines
16 KiB

  1. /* Copyright (c) 1995-1996, Microsoft Corporation, all rights reserved
  2. **
  3. ** rasphone.c
  4. ** Remote Access Phonebook
  5. ** Main routines
  6. **
  7. ** 05/31/95 Steve Cobb
  8. */
  9. #include <windows.h> // Win32 core
  10. #include <stdlib.h> // __argc and __argv
  11. #include <rasdlg.h> // RAS common dialog APIs
  12. #include <raserror.h> // RAS error constants
  13. #include <debug.h> // Trace/Assert
  14. #include <nouiutil.h> // No-HWND utilities
  15. #include <uiutil.h> // HWND utilities
  16. #include <rnk.h> // Dial-up shortcut file
  17. #include <rasphone.rch> // Our resource constants
  18. #include <lmsname.h> // for SERVICE_NETLOGON definition
  19. #include <commctrl.h> // added to be "Fusionized"
  20. #include <shfusion.h> // added to be "Fusionized"
  21. /*----------------------------------------------------------------------------
  22. ** Datatypes
  23. **----------------------------------------------------------------------------
  24. */
  25. /* Identifies a running mode of the application. The non-default entries
  26. ** indicate some alternate behavior has been specified on the command line,
  27. ** e.g. command line delete entry.
  28. */
  29. #define RUNMODE enum tagRUNMODE
  30. RUNMODE
  31. {
  32. RM_None,
  33. RM_AddEntry,
  34. RM_EditEntry,
  35. RM_CloneEntry,
  36. RM_RemoveEntry,
  37. RM_DialEntry,
  38. RM_HangUpEntry,
  39. };
  40. /*----------------------------------------------------------------------------
  41. ** Globals
  42. **----------------------------------------------------------------------------
  43. */
  44. HINSTANCE g_hinst = NULL;
  45. RUNMODE g_mode = RM_None;
  46. BOOL g_fNoRename = FALSE;
  47. TCHAR* g_pszAppName = NULL;
  48. TCHAR* g_pszPhonebookPath = NULL;
  49. TCHAR* g_pszEntryName = NULL;
  50. TCHAR* g_pszShortcutPath = NULL;
  51. /*-----------------------------------------------------------------------------
  52. ** Local prototypes
  53. **-----------------------------------------------------------------------------
  54. */
  55. DWORD
  56. HangUpEntry(
  57. void );
  58. DWORD
  59. ParseCmdLineArgs(
  60. void );
  61. DWORD
  62. RemoveEntry(
  63. void );
  64. DWORD
  65. Run(
  66. void );
  67. DWORD
  68. StringArgFollows(
  69. IN UINT argc,
  70. IN CHAR** argv,
  71. IN OUT UINT* piCurArg,
  72. OUT TCHAR** ppszOut );
  73. INT WINAPI
  74. WinMain(
  75. HINSTANCE hInstance,
  76. HINSTANCE hPrevInstance,
  77. LPSTR pszCmdLine,
  78. int nCmdShow );
  79. /*-----------------------------------------------------------------------------
  80. ** Routines
  81. **-----------------------------------------------------------------------------
  82. */
  83. INT WINAPI
  84. WinMain(
  85. HINSTANCE hInstance,
  86. HINSTANCE hPrevInstance,
  87. LPSTR pszCmdLine,
  88. int nCmdShow )
  89. /* Standard Win32 application entry point.
  90. */
  91. {
  92. DWORD dwErr;
  93. DEBUGINIT("RASPHONE");
  94. TRACE("WinMain");
  95. g_hinst = hInstance;
  96. /* Whistler bug 293751 rasphone.exe / rasautou.exe need to be "Fusionized"
  97. ** for UI conistency w/Connections Folder
  98. */
  99. SHFusionInitializeFromModule( g_hinst );
  100. dwErr = ParseCmdLineArgs();
  101. if (dwErr == 0)
  102. {
  103. /* Execute based on command line arguments.
  104. */
  105. dwErr = Run();
  106. }
  107. else
  108. {
  109. MSGARGS msgargs;
  110. /* Popup a "usage" message.
  111. */
  112. ZeroMemory( &msgargs, sizeof(msgargs) );
  113. msgargs.apszArgs[ 0 ] = g_pszAppName;
  114. msgargs.apszArgs[ 1 ] = PszFromId( g_hinst, SID_Usage2 );
  115. msgargs.apszArgs[ 2 ] = PszFromId( g_hinst, SID_Usage3 );
  116. msgargs.apszArgs[ 3 ] = PszFromId( g_hinst, SID_Usage4 );
  117. msgargs.apszArgs[ 4 ] = PszFromId( g_hinst, SID_Usage5 );
  118. msgargs.apszArgs[ 5 ] = PszFromId( g_hinst, SID_Usage6 );
  119. MsgDlgUtil( NULL, SID_Usage, &msgargs, g_hinst, SID_UsageTitle );
  120. Free0( msgargs.apszArgs[ 1 ] );
  121. Free0( msgargs.apszArgs[ 2 ] );
  122. Free0( msgargs.apszArgs[ 3 ] );
  123. Free0( msgargs.apszArgs[ 4 ] );
  124. Free0( msgargs.apszArgs[ 5 ] );
  125. }
  126. Free0( g_pszAppName );
  127. Free0( g_pszPhonebookPath );
  128. Free0( g_pszEntryName );
  129. /* Whistler bug 293751 rasphone.exe / rasautou.exe need to be "Fusionized"
  130. ** for UI conistency w/Connections Folder
  131. */
  132. SHFusionUninitialize();
  133. TRACE1("WinMain=%d",dwErr);
  134. DEBUGTERM();
  135. return (INT )dwErr;
  136. }
  137. BOOL
  138. FIsRasInstalled ()
  139. {
  140. static const TCHAR c_szRegKeyRasman[] =
  141. TEXT("SYSTEM\\CurrentControlSet\\Services\\Rasman");
  142. BOOL fIsRasInstalled = FALSE;
  143. HKEY hkey;
  144. if (RegOpenKey( HKEY_LOCAL_MACHINE, c_szRegKeyRasman, &hkey ) == 0)
  145. {
  146. fIsRasInstalled = TRUE;
  147. RegCloseKey( hkey );
  148. }
  149. return fIsRasInstalled;
  150. }
  151. DWORD
  152. HangUpEntry(
  153. void )
  154. /* Hang up the entry specified on the command line.
  155. **
  156. ** Returns 0 if successful, or an error code.
  157. */
  158. {
  159. DWORD dwErr;
  160. HRASCONN hrasconn;
  161. TRACE("HangUpEntry");
  162. if (!g_pszEntryName)
  163. return ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
  164. dwErr = LoadRasapi32Dll();
  165. if (dwErr != 0)
  166. return dwErr;
  167. /* Currently, if user does not specify a phonebook path on the command
  168. ** line we look for any entry with the name he selected disregarding what
  169. ** phonebook it comes from. Should probably map it specifically to the
  170. ** default phonebook as the other options do, but that would mean linking
  171. ** in all of PBK.LIB. Seems like overkill for this little quibble. Maybe
  172. ** we need a RasGetDefaultPhonebookName API.
  173. */
  174. hrasconn = HrasconnFromEntry( g_pszPhonebookPath, g_pszEntryName );
  175. if (hrasconn)
  176. {
  177. ASSERT(g_pRasHangUp);
  178. TRACE("RasHangUp");
  179. dwErr = g_pRasHangUp( hrasconn );
  180. TRACE1("RasHangUp=%d",dwErr);
  181. }
  182. UnloadRasapi32Dll();
  183. return dwErr;
  184. }
  185. DWORD
  186. ParseCmdLineArgs(
  187. void )
  188. /* Parse command line arguments, filling in global settings accordingly.
  189. **
  190. ** Returns 0 if successful, or a non-0 error code.
  191. */
  192. {
  193. DWORD dwErr;
  194. UINT argc;
  195. CHAR** argv;
  196. UINT i;
  197. /* Usage: appname [-v] [-f file] [-e|-c|-d|-h|-r entry]
  198. ** appname [-v] [-f file] -a [entry]
  199. ** appname [-v] -lx link
  200. ** appname -s
  201. **
  202. ** '-a' Popup new entry dialogs
  203. ** '-e' Popup edit entry dialogs
  204. ** '-d' Popup dial entry dialogs
  205. ** '-h' Quietly hang up the entry
  206. ** '-r' Quietly delete the entry
  207. ** '-lx' Execute command 'x' on dial-up shortcut file
  208. ** 'x' Any of the commands e, v, c, r, d, h, or a
  209. ** 'entry' The entry name to which the operation applies
  210. ** 'file' The full path to the dial-up phonebook file (.pbk)
  211. ** 'link' The full path to the dial-up shortcut file (.rnk)
  212. **
  213. ** 'entry' without a preceding flag starts the phone list dialog with
  214. ** the entry selected.
  215. */
  216. argc = __argc;
  217. argv = __argv;
  218. dwErr = 0;
  219. {
  220. CHAR* pStart = argv[ 0 ];
  221. CHAR* p;
  222. for (p = pStart + lstrlenA( pStart ) - 1; p >= pStart; --p)
  223. {
  224. if (*p == '\\' || *p == ':')
  225. break;
  226. }
  227. g_pszAppName = StrDupTFromA( p + 1 );
  228. }
  229. for (i = 1; i < argc && dwErr == 0; ++i)
  230. {
  231. CHAR* pszArg = argv[ i ];
  232. if (*pszArg == '-' || *pszArg == '/')
  233. {
  234. switch (pszArg[ 1 ])
  235. {
  236. case 'a':
  237. case 'A':
  238. g_mode = RM_AddEntry;
  239. StringArgFollows( argc, argv, &i, &g_pszEntryName );
  240. break;
  241. case 'e':
  242. case 'E':
  243. g_mode = RM_EditEntry;
  244. dwErr = StringArgFollows( argc, argv, &i, &g_pszEntryName );
  245. break;
  246. case 'r':
  247. case 'R':
  248. g_mode = RM_RemoveEntry;
  249. dwErr = StringArgFollows( argc, argv, &i, &g_pszEntryName );
  250. break;
  251. case 'd':
  252. case 'D':
  253. case 't':
  254. case 'T':
  255. g_mode = RM_DialEntry;
  256. dwErr = StringArgFollows( argc, argv, &i, &g_pszEntryName );
  257. break;
  258. case 'h':
  259. case 'H':
  260. g_mode = RM_HangUpEntry;
  261. dwErr = StringArgFollows( argc, argv, &i, &g_pszEntryName );
  262. break;
  263. case 'f':
  264. case 'F':
  265. dwErr = StringArgFollows(
  266. argc, argv, &i, &g_pszPhonebookPath );
  267. break;
  268. case 'l':
  269. case 'L':
  270. switch (pszArg[ 2 ])
  271. {
  272. case 'a':
  273. case 'A':
  274. g_mode = RM_AddEntry;
  275. StringArgFollows( argc, argv, &i, &g_pszEntryName );
  276. break;
  277. case 'e':
  278. case 'E':
  279. g_mode = RM_EditEntry;
  280. break;
  281. case 'c':
  282. case 'C':
  283. g_mode = RM_CloneEntry;
  284. break;
  285. case 'v':
  286. case 'V':
  287. g_fNoRename = TRUE;
  288. break;
  289. case 'r':
  290. case 'R':
  291. g_mode = RM_RemoveEntry;
  292. break;
  293. case 'd':
  294. case 'D':
  295. case 't':
  296. case 'T':
  297. g_mode = RM_DialEntry;
  298. break;
  299. case 'h':
  300. case 'H':
  301. g_mode = RM_HangUpEntry;
  302. break;
  303. default:
  304. dwErr = ERROR_INVALID_PARAMETER;
  305. break;
  306. }
  307. if (dwErr == 0)
  308. {
  309. dwErr = StringArgFollows(
  310. argc, argv, &i, &g_pszShortcutPath );
  311. }
  312. break;
  313. default:
  314. dwErr = ERROR_INVALID_PARAMETER;
  315. break;
  316. }
  317. }
  318. else if (i == 1)
  319. {
  320. --i;
  321. dwErr = StringArgFollows( argc, argv, &i, &g_pszEntryName );
  322. break;
  323. }
  324. else
  325. {
  326. dwErr = ERROR_INVALID_PARAMETER;
  327. break;
  328. }
  329. }
  330. if (dwErr == 0 && g_pszShortcutPath)
  331. {
  332. RNKINFO* pInfo;
  333. /* Read the phonebook and entry from the dial-up shortcut file.
  334. */
  335. pInfo = ReadShortcutFile( g_pszShortcutPath );
  336. if (!pInfo)
  337. dwErr = ERROR_OPEN_FAILED;
  338. else
  339. {
  340. g_pszPhonebookPath = StrDup( pInfo->pszPhonebook );
  341. if (g_mode != RM_AddEntry)
  342. g_pszEntryName = StrDup( pInfo->pszEntry );
  343. FreeRnkInfo( pInfo );
  344. }
  345. }
  346. TRACE2("CmdLine: m=%d,v=%d",g_mode,g_fNoRename);
  347. TRACEW1("CmdLine: e=%s",(g_pszEntryName)?g_pszEntryName:TEXT(""));
  348. TRACEW1("CmdLine: f=%s",(g_pszPhonebookPath)?g_pszPhonebookPath:TEXT(""));
  349. TRACEW1("CmdLine: l=%s",(g_pszShortcutPath)?g_pszShortcutPath:TEXT(""));
  350. return dwErr;
  351. }
  352. DWORD
  353. RemoveEntry(
  354. void )
  355. /* Remove the entry specified on the command line.
  356. **
  357. ** Returns 0 if successful, or an error code.
  358. */
  359. {
  360. DWORD dwErr;
  361. HRASCONN hrasconn = NULL;
  362. TRACE("RemoveEntry");
  363. dwErr = LoadRasapi32Dll();
  364. if (dwErr != 0)
  365. return dwErr;
  366. //If this entry is currently connected, we wont delete it
  367. //for whislter bug 311846 gangz
  368. //
  369. hrasconn = HrasconnFromEntry( g_pszPhonebookPath, g_pszEntryName );
  370. if (hrasconn)
  371. {
  372. TRACE("RemoveEntry: Connection is Active, wont delete it");
  373. dwErr = ERROR_CAN_NOT_COMPLETE;
  374. }
  375. else
  376. {
  377. ASSERT(g_pRasDeleteEntry);
  378. TRACE("RasDeleteEntry");
  379. dwErr = g_pRasDeleteEntry( g_pszPhonebookPath, g_pszEntryName );
  380. TRACE1("RasDeleteEntry=%d",dwErr);
  381. }
  382. UnloadRasapi32Dll();
  383. return dwErr;
  384. }
  385. DWORD
  386. Run(
  387. void )
  388. /* Execute the command line instructions.
  389. **
  390. ** Returns 0 if successful, or an error code.
  391. */
  392. {
  393. DWORD dwErr;
  394. BOOL fStatus;
  395. TCHAR* pszEntry;
  396. TRACE("Run");
  397. if (g_mode == RM_HangUpEntry)
  398. return HangUpEntry();
  399. else if (g_mode == RM_RemoveEntry)
  400. return RemoveEntry();
  401. dwErr = LoadRasdlgDll();
  402. if (dwErr != 0)
  403. return dwErr;
  404. switch (g_mode)
  405. {
  406. case RM_DialEntry:
  407. {
  408. RASDIALDLG info;
  409. ZeroMemory( &info, sizeof(info) );
  410. info.dwSize = sizeof(info);
  411. pszEntry = g_pszEntryName;
  412. ASSERT(g_pRasDialDlg);
  413. TRACE("RasDialDlg");
  414. fStatus = g_pRasDialDlg(
  415. g_pszPhonebookPath, g_pszEntryName, NULL, &info );
  416. TRACE2("RasDialDlg=%d,e=%d",fStatus,info.dwError);
  417. dwErr = info.dwError;
  418. break;
  419. }
  420. case RM_None:
  421. {
  422. RASPBDLG info;
  423. DWORD dwGupErr;
  424. PBUSER user;
  425. ZeroMemory( &info, sizeof(info) );
  426. info.dwSize = sizeof(info);
  427. info.dwFlags = RASPBDFLAG_UpdateDefaults;
  428. dwGupErr = GetUserPreferences( NULL, &user, FALSE );
  429. if (dwGupErr == 0)
  430. {
  431. if (user.dwXPhonebook != 0x7FFFFFFF)
  432. {
  433. info.dwFlags |= RASPBDFLAG_PositionDlg;
  434. info.xDlg = user.dwXPhonebook;
  435. info.yDlg = user.dwYPhonebook;
  436. }
  437. pszEntry = user.pszDefaultEntry;
  438. }
  439. else
  440. pszEntry = NULL;
  441. if (g_pszEntryName)
  442. pszEntry = g_pszEntryName;
  443. ASSERT(g_pRasPhonebookDlg);
  444. TRACE("RasPhonebookDlg...");
  445. fStatus = g_pRasPhonebookDlg( g_pszPhonebookPath, pszEntry, &info );
  446. TRACE2("RasPhonebookDlg=%d,e=%d",fStatus,info.dwError);
  447. if (dwGupErr == 0)
  448. DestroyUserPreferences( &user );
  449. dwErr = info.dwError;
  450. break;
  451. }
  452. case RM_AddEntry:
  453. case RM_EditEntry:
  454. case RM_CloneEntry:
  455. {
  456. RASENTRYDLG info;
  457. ZeroMemory( &info, sizeof(info) );
  458. info.dwSize = sizeof(info);
  459. if (g_mode == RM_AddEntry)
  460. info.dwFlags |= RASEDFLAG_NewEntry;
  461. else if (g_mode == RM_CloneEntry)
  462. info.dwFlags |= RASEDFLAG_CloneEntry;
  463. if (g_fNoRename)
  464. info.dwFlags |= RASEDFLAG_NoRename;
  465. #if 0
  466. ASSERT(g_pRouterEntryDlg);
  467. TRACE("RouterEntryDlg");
  468. fStatus = g_pRouterEntryDlg(
  469. TEXT("stevec5"), TEXT("\\\\stevec5\\admin$\\system32\\ras\\router.pbk"), g_pszEntryName, &info );
  470. TRACE2("RouterEntryDlg=%f,e=%d",fStatus,info.dwError);
  471. #else
  472. ASSERT(g_pRasEntryDlg);
  473. TRACE("RasEntryDlg");
  474. fStatus = g_pRasEntryDlg(
  475. g_pszPhonebookPath, g_pszEntryName, &info );
  476. TRACE2("RasEntryDlg=%f,e=%d",fStatus,info.dwError);
  477. #endif
  478. dwErr = info.dwError;
  479. break;
  480. }
  481. default:
  482. {
  483. dwErr = ERROR_INVALID_PARAMETER;
  484. break;
  485. }
  486. }
  487. UnloadRasdlgDll();
  488. TRACE1("Run=%d",dwErr);
  489. return dwErr;
  490. }
  491. DWORD
  492. StringArgFollows(
  493. IN UINT argc,
  494. IN CHAR** argv,
  495. IN OUT UINT* piCurArg,
  496. OUT TCHAR** ppszOut )
  497. /* Loads a copy of the next argument into callers '*ppszOut'.
  498. **
  499. ** Returns 0 if successful, or a non-0 error code. If successful, it is
  500. ** caller's responsibility to Free the returned '*ppszOut'.
  501. */
  502. {
  503. TCHAR* psz;
  504. if (++(*piCurArg) >= argc)
  505. return ERROR_INVALID_PARAMETER;
  506. psz = StrDupTFromAUsingAnsiEncoding( argv[ *piCurArg ] );
  507. if (!psz)
  508. return ERROR_NOT_ENOUGH_MEMORY;
  509. *ppszOut = psz;
  510. return 0;
  511. }