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.

665 lines
16 KiB

  1. /* Copyright (c) 1994, Microsoft Corporation, all rights reserved
  2. **
  3. ** rasapi16.c
  4. ** Remote Access external APIs
  5. ** Windows NT WOW 16->32 thunks, 16-bit side
  6. **
  7. ** 04/02/94 Steve Cobb
  8. **
  9. ** This is Win16 code and all included headers are Win16 headers. By it's
  10. ** nature, this code is sensitive to changes in either the Win16 or Win32
  11. ** versions of RAS.H and the system definitions used therein. Numerous name
  12. ** conflicts make it unfeasible to include the Win32 headers here. Win32
  13. ** definitions needed for mapping are defined locally with a "Win32: <header>"
  14. ** comment indicating the location of the duplicated Win32 definition.
  15. */
  16. #include <bseerr.h>
  17. #include <windows.h>
  18. #include <ras.h>
  19. #include <raserror.h>
  20. //#define BREAKONENTRY
  21. LPVOID AlignedAlloc( HGLOBAL FAR* ph, DWORD cb );
  22. VOID AlignedFree( HGLOBAL h );
  23. DWORD MapErrorCode( DWORD dwError );
  24. /*---------------------------------------------------------------------------
  25. ** Win32 definitions
  26. **---------------------------------------------------------------------------
  27. */
  28. /* The Win32 RAS structures are packed on 4-byte boundaries.
  29. */
  30. #pragma pack(4)
  31. /* Win32: ras.h - RASCONNA
  32. ** Pads to different size.
  33. */
  34. #define RASCONNA struct tagRASCONNA
  35. RASCONNA
  36. {
  37. DWORD dwSize;
  38. HRASCONN hrasconn;
  39. CHAR szEntryName[ RAS_MaxEntryName + 1 ];
  40. };
  41. #define LPRASCONNA RASCONNA FAR*
  42. /* Win32: ras.h - RASCONNSTATUSA
  43. ** The size of the RASCONNSTATE enum is different.
  44. ** Pads to different size.
  45. */
  46. #define RASCONNSTATUSA struct tagRASCONNSTATUSA
  47. RASCONNSTATUSA
  48. {
  49. DWORD dwSize;
  50. DWORD rasconnstate;
  51. DWORD dwError;
  52. CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
  53. CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
  54. };
  55. #define LPRASCONNSTATUSA RASCONNSTATUSA FAR*
  56. /* Win32: lmcons.h - UNLEN, PWLEN, and DNLEN
  57. */
  58. #define NTUNLEN 256
  59. #define NTPWLEN 256
  60. #define NTDNLEN 15
  61. /* Win32: ras.h - RASDIALPARAMSA
  62. ** The credential constants are different.
  63. */
  64. #define RASDIALPARAMSA struct tagRASDIALPARAMSA
  65. RASDIALPARAMSA
  66. {
  67. DWORD dwSize;
  68. CHAR szEntryName[ RAS_MaxEntryName + 1 ];
  69. CHAR szPhoneNumber[ RAS_MaxPhoneNumber + 1 ];
  70. CHAR szCallbackNumber[ RAS_MaxCallbackNumber + 1 ];
  71. CHAR szUserName[ NTUNLEN + 1 ];
  72. CHAR szPassword[ NTPWLEN + 1 ];
  73. CHAR szDomain[ NTDNLEN + 1 ];
  74. };
  75. #define LPRASDIALPARAMSA RASDIALPARAMSA FAR*
  76. /* Win32: ras.h - RASENTRYNAMEA
  77. ** Pads to different size.
  78. */
  79. #define RASENTRYNAMEA struct tagRASENTRYNAMEA
  80. RASENTRYNAMEA
  81. {
  82. DWORD dwSize;
  83. CHAR szEntryName[ RAS_MaxEntryName + 1 ];
  84. };
  85. #define LPRASENTRYNAMEA RASENTRYNAMEA FAR*
  86. #pragma pack()
  87. /* Win32: <rasui>\extapi\src\wow.c - RASAPI32.DLL WOW entry point prototypes
  88. */
  89. typedef DWORD (FAR PASCAL* RASDIALWOW)( LPSTR, LPRASDIALPARAMS, DWORD, LPRASCONN );
  90. typedef DWORD (FAR PASCAL* RASENUMCONNECTIONSWOW)( LPRASCONN, LPDWORD, LPDWORD );
  91. typedef DWORD (FAR PASCAL* RASENUMENTRIESWOW)( LPSTR, LPSTR, LPRASENTRYNAME, LPDWORD, LPDWORD );
  92. typedef DWORD (FAR PASCAL* RASGETCONNECTSTATUSWOW)( HRASCONN, LPRASCONNSTATUS );
  93. typedef DWORD (FAR PASCAL* RASGETERRORSTRINGWOW)( DWORD, LPSTR, DWORD );
  94. typedef DWORD (FAR PASCAL* RASHANGUPWOW)( HRASCONN );
  95. /*---------------------------------------------------------------------------
  96. ** Globals
  97. **---------------------------------------------------------------------------
  98. */
  99. /* The handle of the RASAPI32.DLL module returned by LoadLibraryEx32W.
  100. */
  101. DWORD HRasApi32Dll = NULL;
  102. /* The unique RasDial notification message as registered in the system at
  103. ** startup (WM_RASDIALEVENT is just a default).
  104. */
  105. UINT UnRasDialEventMsg = WM_RASDIALEVENT;
  106. /*---------------------------------------------------------------------------
  107. ** Standard DLL entry points
  108. **---------------------------------------------------------------------------
  109. */
  110. int FAR PASCAL
  111. LibMain(
  112. HINSTANCE hInst,
  113. WORD wDataSeg,
  114. WORD cbHeapSize,
  115. LPSTR lpszCmdLine )
  116. /* Standard DLL startup routine.
  117. */
  118. {
  119. #ifdef BREAKONENTRY
  120. { _asm int 3 }
  121. #endif
  122. /* Don't even load on anything but NT WOW.
  123. */
  124. if (!(GetWinFlags() & WF_WINNT))
  125. return FALSE;
  126. /* Load the Win32 RAS API DLL.
  127. */
  128. HRasApi32Dll = LoadLibraryEx32W( "RASAPI32.DLL", NULL, 0 );
  129. if (!HRasApi32Dll)
  130. return FALSE;
  131. /* Register a unique message for RasDial notifications.
  132. */
  133. {
  134. UINT unMsg = RegisterWindowMessage( RASDIALEVENT );
  135. if (unMsg > 0)
  136. UnRasDialEventMsg = unMsg;
  137. }
  138. return TRUE;
  139. }
  140. int FAR PASCAL
  141. WEP(
  142. int nExitType )
  143. /* Standard DLL exit routine.
  144. */
  145. {
  146. #ifdef BREAKONENTRY
  147. { _asm int 3 }
  148. #endif
  149. if (HRasApi32Dll)
  150. FreeLibrary32W( HRasApi32Dll );
  151. return TRUE;
  152. }
  153. /*---------------------------------------------------------------------------
  154. ** 16->32 thunks
  155. **---------------------------------------------------------------------------
  156. */
  157. DWORD APIENTRY
  158. RasDial(
  159. LPSTR reserved,
  160. LPSTR lpszPhonebookPath,
  161. LPRASDIALPARAMS lprasdialparams,
  162. LPVOID reserved2,
  163. HWND hwndNotify,
  164. LPHRASCONN lphrasconn )
  165. {
  166. DWORD dwErr;
  167. RASDIALWOW proc;
  168. LPRASDIALPARAMSA prdpa;
  169. HGLOBAL hrdpa;
  170. LPHRASCONN phrc;
  171. HGLOBAL hhrc;
  172. #ifdef BREAKONENTRY
  173. { _asm int 3 }
  174. #endif
  175. proc =
  176. (RASDIALWOW )GetProcAddress32W(
  177. HRasApi32Dll, "RasDialWow" );
  178. if (!proc)
  179. return ERROR_INVALID_FUNCTION;
  180. (void )reserved;
  181. (void )reserved2;
  182. /* Account for the increased user name and password field lengths on NT.
  183. */
  184. if (!(prdpa = (LPRASDIALPARAMSA )AlignedAlloc(
  185. &hrdpa, sizeof(RASDIALPARAMSA) )))
  186. {
  187. return ERROR_NOT_ENOUGH_MEMORY;
  188. }
  189. prdpa->dwSize = sizeof(RASDIALPARAMSA);
  190. lstrcpy( prdpa->szEntryName, lprasdialparams->szEntryName );
  191. lstrcpy( prdpa->szPhoneNumber, lprasdialparams->szPhoneNumber );
  192. lstrcpy( prdpa->szCallbackNumber, lprasdialparams->szCallbackNumber );
  193. lstrcpy( prdpa->szUserName, lprasdialparams->szUserName );
  194. lstrcpy( prdpa->szPassword, lprasdialparams->szPassword );
  195. lstrcpy( prdpa->szDomain, lprasdialparams->szDomain );
  196. if (!(phrc = (LPHRASCONN )AlignedAlloc(
  197. &hhrc, sizeof(HRASCONN) )))
  198. {
  199. AlignedFree( hrdpa );
  200. return ERROR_NOT_ENOUGH_MEMORY;
  201. }
  202. *phrc = *lphrasconn;
  203. dwErr =
  204. CallProc32W(
  205. /* 16 */ (DWORD )lpszPhonebookPath,
  206. /* 8 */ (DWORD )prdpa,
  207. /* 4 */ (DWORD )hwndNotify | 0xFFFF0000,
  208. /* 2 */ (DWORD )UnRasDialEventMsg,
  209. /* 1 */ (DWORD )phrc,
  210. (LPVOID )proc,
  211. (DWORD )(16 + 8 + 1),
  212. (DWORD )5 );
  213. *lphrasconn = *phrc;
  214. AlignedFree( hrdpa );
  215. AlignedFree( hhrc );
  216. return MapErrorCode( dwErr );
  217. }
  218. DWORD APIENTRY
  219. RasEnumConnections(
  220. LPRASCONN lprasconn,
  221. LPDWORD lpcb,
  222. LPDWORD lpcConnections )
  223. {
  224. DWORD dwErr;
  225. RASENUMCONNECTIONSWOW proc;
  226. LPRASCONNA prca;
  227. HGLOBAL hrca;
  228. LPDWORD pcb;
  229. HGLOBAL hcb;
  230. LPDWORD pcConnections;
  231. HGLOBAL hcConnections;
  232. #ifdef BREAKONENTRY
  233. { _asm int 3 }
  234. #endif
  235. proc =
  236. (RASENUMCONNECTIONSWOW )GetProcAddress32W(
  237. HRasApi32Dll, "RasEnumConnectionsWow" );
  238. if (!proc)
  239. return ERROR_INVALID_FUNCTION;
  240. /* Check for bad sizes on this side before setting up a substitute buffer.
  241. */
  242. if (!lprasconn || lprasconn->dwSize != sizeof(RASCONN))
  243. return ERROR_INVALID_SIZE;
  244. if (!lpcb)
  245. return ERROR_INVALID_PARAMETER;
  246. if (!(pcb = (LPDWORD )AlignedAlloc( &hcb, sizeof(DWORD) )))
  247. return ERROR_NOT_ENOUGH_MEMORY;
  248. *pcb = (*lpcb / sizeof(RASCONN)) * sizeof(RASCONNA);
  249. if (!(pcConnections = (LPDWORD )AlignedAlloc(
  250. &hcConnections, sizeof(DWORD) )))
  251. {
  252. AlignedFree( hcb );
  253. return ERROR_NOT_ENOUGH_MEMORY;
  254. }
  255. if (lpcConnections)
  256. *pcConnections = *lpcConnections;
  257. if (!(prca = (LPRASCONNA )AlignedAlloc( &hrca, *pcb )))
  258. {
  259. AlignedFree( hcb );
  260. AlignedFree( hcConnections );
  261. return ERROR_NOT_ENOUGH_MEMORY;
  262. }
  263. prca->dwSize = sizeof(RASCONNA);
  264. dwErr =
  265. CallProc32W(
  266. /* 4 */ (DWORD )prca,
  267. /* 2 */ (DWORD )pcb,
  268. /* 1 */ (DWORD )pcConnections,
  269. (LPVOID )proc,
  270. (DWORD )(4 + 2 + 1),
  271. (DWORD )3 );
  272. /* Copy result from substitute buffer back to caller's buffer.
  273. */
  274. *lpcb = (*pcb / sizeof(RASCONNA)) * sizeof(RASCONN);
  275. if (lpcConnections)
  276. *lpcConnections = *pcConnections;
  277. if (MapErrorCode( dwErr ) != ERROR_BUFFER_TOO_SMALL)
  278. {
  279. DWORD i;
  280. LPRASCONNA lprcaSub = prca;
  281. LPRASCONN lprcCaller = lprasconn;
  282. for (i = 0; i < *pcConnections; ++i)
  283. {
  284. lprcCaller->dwSize = sizeof(RASCONN);
  285. lprcCaller->hrasconn = lprcaSub->hrasconn;
  286. lstrcpy( lprcCaller->szEntryName, lprcaSub->szEntryName );
  287. ++lprcaSub;
  288. ++lprcCaller;
  289. }
  290. }
  291. AlignedFree( hcb );
  292. AlignedFree( hcConnections );
  293. AlignedFree( hrca );
  294. return MapErrorCode( dwErr );
  295. }
  296. DWORD APIENTRY
  297. RasEnumEntries(
  298. LPSTR reserved,
  299. LPSTR lpszPhonebookPath,
  300. LPRASENTRYNAME lprasentryname,
  301. LPDWORD lpcb,
  302. LPDWORD lpcEntries )
  303. {
  304. DWORD dwErr;
  305. RASENUMENTRIESWOW proc;
  306. LPRASENTRYNAMEA prena;
  307. HGLOBAL hrena;
  308. LPDWORD pcb;
  309. HGLOBAL hcb;
  310. LPDWORD pcEntries;
  311. HGLOBAL hcEntries;
  312. #ifdef BREAKONENTRY
  313. { _asm int 3 }
  314. #endif
  315. proc =
  316. (RASENUMENTRIESWOW )GetProcAddress32W(
  317. HRasApi32Dll, "RasEnumEntriesWow" );
  318. if (!proc)
  319. return ERROR_INVALID_FUNCTION;
  320. /* Check for bad sizes on this side before setting up a substitute buffer.
  321. */
  322. if (!lprasentryname || lprasentryname->dwSize != sizeof(RASENTRYNAME))
  323. return ERROR_INVALID_SIZE;
  324. if (!lpcb)
  325. return ERROR_INVALID_PARAMETER;
  326. if (!(pcb = (LPDWORD )AlignedAlloc( &hcb, sizeof(DWORD) )))
  327. return ERROR_NOT_ENOUGH_MEMORY;
  328. *pcb = (*lpcb / sizeof(RASENTRYNAME)) * sizeof(RASENTRYNAMEA);
  329. if (!(pcEntries = (LPDWORD )AlignedAlloc(
  330. &hcEntries, sizeof(DWORD) )))
  331. {
  332. AlignedFree( hcb );
  333. return ERROR_NOT_ENOUGH_MEMORY;
  334. }
  335. if (lpcEntries)
  336. *pcEntries = *lpcEntries;
  337. if (!(prena = (LPRASENTRYNAMEA )AlignedAlloc( &hrena, *pcb )))
  338. {
  339. AlignedFree( hcb );
  340. AlignedFree( hcEntries );
  341. return ERROR_NOT_ENOUGH_MEMORY;
  342. }
  343. prena->dwSize = sizeof(RASENTRYNAMEA);
  344. dwErr =
  345. CallProc32W(
  346. /* 16 */ (DWORD )reserved,
  347. /* 8 */ (DWORD )lpszPhonebookPath,
  348. /* 4 */ (DWORD )prena,
  349. /* 2 */ (DWORD )pcb,
  350. /* 1 */ (DWORD )pcEntries,
  351. (LPVOID )proc,
  352. (DWORD )(16 + 8 + 4 + 2 + 1),
  353. (DWORD ) 5 );
  354. /* Copy result from substitute buffer back to caller's buffer.
  355. */
  356. *lpcb = (*pcb / sizeof(RASENTRYNAMEA)) * sizeof(RASENTRYNAME);
  357. if (lpcEntries)
  358. *lpcEntries = *pcEntries;
  359. if (MapErrorCode( dwErr ) != ERROR_BUFFER_TOO_SMALL)
  360. {
  361. DWORD i;
  362. LPRASENTRYNAMEA lprenaSub = prena;
  363. LPRASENTRYNAME lprenCaller = lprasentryname;
  364. for (i = 0; i < *pcEntries; ++i)
  365. {
  366. lprenCaller->dwSize = sizeof(RASENTRYNAME);
  367. lstrcpy( lprenCaller->szEntryName, lprenaSub->szEntryName );
  368. ++lprenaSub;
  369. ++lprenCaller;
  370. }
  371. }
  372. AlignedFree( hcb );
  373. AlignedFree( hcEntries );
  374. AlignedFree( hrena );
  375. return MapErrorCode( dwErr );
  376. }
  377. DWORD APIENTRY
  378. RasGetConnectStatus(
  379. HRASCONN hrasconn,
  380. LPRASCONNSTATUS lprasconnstatus )
  381. {
  382. DWORD dwErr;
  383. RASGETCONNECTSTATUSWOW proc;
  384. LPRASCONNSTATUSA prcsa;
  385. HGLOBAL hrcsa;
  386. #ifdef BREAKONENTRY
  387. { _asm int 3 }
  388. #endif
  389. proc =
  390. (RASGETCONNECTSTATUSWOW )GetProcAddress32W(
  391. HRasApi32Dll, "RasGetConnectStatusWow" );
  392. if (!proc)
  393. return ERROR_INVALID_FUNCTION;
  394. /* Check for bad size on this side before setting up a substitute buffer.
  395. */
  396. if (!lprasconnstatus || lprasconnstatus->dwSize != sizeof(RASCONNSTATUS))
  397. return ERROR_INVALID_SIZE;
  398. if (!(prcsa = (LPRASCONNSTATUSA )AlignedAlloc(
  399. &hrcsa, sizeof(RASCONNSTATUSA) )))
  400. {
  401. return ERROR_NOT_ENOUGH_MEMORY;
  402. }
  403. prcsa->dwSize = sizeof(RASCONNSTATUSA);
  404. dwErr =
  405. CallProc32W(
  406. /* 2 */ (DWORD )hrasconn,
  407. /* 1 */ (DWORD )prcsa,
  408. (LPVOID )proc,
  409. (DWORD )1,
  410. (DWORD )2 );
  411. /* Copy result from substitute buffer back to caller's buffer.
  412. */
  413. lprasconnstatus->rasconnstate = (RASCONNSTATE )prcsa->rasconnstate;
  414. lprasconnstatus->dwError = prcsa->dwError;
  415. lstrcpy( lprasconnstatus->szDeviceType, prcsa->szDeviceType );
  416. lstrcpy( lprasconnstatus->szDeviceName, prcsa->szDeviceName );
  417. AlignedFree( hrcsa );
  418. return MapErrorCode( dwErr );
  419. }
  420. DWORD APIENTRY
  421. RasGetErrorString(
  422. UINT uErrorCode,
  423. LPSTR lpszBuf,
  424. DWORD cbBuf )
  425. {
  426. DWORD dwErr;
  427. RASGETERRORSTRINGWOW proc;
  428. #ifdef BREAKONENTRY
  429. { _asm int 3 }
  430. #endif
  431. proc =
  432. (RASGETERRORSTRINGWOW )GetProcAddress32W(
  433. HRasApi32Dll, "RasGetErrorStringWow" );
  434. if (!proc)
  435. return ERROR_INVALID_FUNCTION;
  436. dwErr =
  437. CallProc32W(
  438. /* 4 */ (DWORD )uErrorCode,
  439. /* 2 */ (DWORD )lpszBuf,
  440. /* 1 */ (DWORD )cbBuf,
  441. (LPVOID )proc,
  442. (DWORD )2,
  443. (DWORD )3 );
  444. return MapErrorCode( dwErr );
  445. }
  446. DWORD APIENTRY
  447. RasHangUp(
  448. HRASCONN hrasconn )
  449. {
  450. DWORD dwErr;
  451. RASHANGUPWOW proc;
  452. #ifdef BREAKONENTRY
  453. { _asm int 3 }
  454. #endif
  455. proc =
  456. (RASHANGUPWOW )GetProcAddress32W(
  457. HRasApi32Dll, "RasHangUpWow" );
  458. if (!proc)
  459. return ERROR_INVALID_FUNCTION;
  460. dwErr =
  461. CallProc32W(
  462. /* 1 */ (DWORD )hrasconn,
  463. (LPVOID )proc,
  464. (DWORD )0,
  465. (DWORD )1 );
  466. return MapErrorCode( dwErr );
  467. }
  468. /*---------------------------------------------------------------------------
  469. ** Utilities
  470. **---------------------------------------------------------------------------
  471. */
  472. LPVOID
  473. AlignedAlloc(
  474. HGLOBAL FAR* ph,
  475. DWORD cb )
  476. /* Returns address of block of 'cb' bytes aligned suitably for all
  477. ** platforms, or NULL if out of memory. If successful, callers '*ph' is
  478. ** set to the handle of the block, used with AllignedFree.
  479. */
  480. {
  481. LPVOID pv = NULL;
  482. *ph = NULL;
  483. if (!(*ph = GlobalAlloc( GPTR, cb )))
  484. return NULL;
  485. if (!(pv = (LPVOID )GlobalLock( *ph )))
  486. {
  487. GlobalFree( *ph );
  488. *ph = NULL;
  489. }
  490. return pv;
  491. }
  492. VOID
  493. AlignedFree(
  494. HGLOBAL h )
  495. /* Frees a block allocated with AlignedAlloc identified by the 'h'
  496. ** returned from same.
  497. */
  498. {
  499. if (h)
  500. {
  501. GlobalUnlock( h );
  502. GlobalFree( h );
  503. }
  504. }
  505. DWORD
  506. MapErrorCode(
  507. DWORD dwError )
  508. /* Map Win32 error codes to Win16. (Win32: raserror.h)
  509. */
  510. {
  511. /* These codes map, but the codes are different in Win16 and Win32.
  512. ** ERROR_NO_ISDN_CHANNELS_AVAILABLE truncated to 31 characters. See
  513. ** raserror.h.
  514. */
  515. switch (dwError)
  516. {
  517. case 709: return ERROR_CHANGING_PASSWORD;
  518. case 710: return ERROR_OVERRUN;
  519. case 713: return ERROR_NO_ACTIVE_ISDN_LINES;
  520. case 714: return ERROR_NO_ISDN_CHANNELS_AVAILABL;
  521. }
  522. /* Pass everything else thru including codes that don't match up to
  523. ** anything on Win16 (e.g. RAS errors outside the 600 to 706 range).
  524. ** Reasoning is that an unmapped code is more valuable that some generic
  525. ** error like ERROR_UNKNOWN.
  526. */
  527. return dwError;
  528. }