Leaked source code of windows server 2003
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.

554 lines
14 KiB

  1. /* Copyright (c) 1995, Microsoft Corporation, all rights reserved
  2. **
  3. ** rasapi.c
  4. ** RAS API helpers (with no RASMAN calls)
  5. ** Listed alphabetically
  6. **
  7. ** 12/20/95 Steve Cobb
  8. */
  9. #include <windows.h> // Win32 root
  10. #include <list.h> // for LIST_ENTRY definitions
  11. #include <stdlib.h> // for atol()
  12. #include <debug.h> // Trace/Assert library
  13. #include <nouiutil.h> // Our public header
  14. #include <raserror.h> // RAS error constants
  15. DWORD
  16. FreeRasconnList(
  17. LIST_ENTRY *pListHead )
  18. /* Frees a list built by GetRasconnList.
  19. **
  20. ** Returns 0 always.
  21. **
  22. ** (Abolade Gbadegesin Nov-9-1995)
  23. */
  24. {
  25. RASCONNLINK *plink;
  26. RASCONNENTRY *pentry;
  27. LIST_ENTRY *ple, *plel;
  28. while (!IsListEmpty(pListHead)) {
  29. ple = RemoveHeadList(pListHead);
  30. pentry = CONTAINING_RECORD(ple, RASCONNENTRY, RCE_Node);
  31. while (!IsListEmpty(&pentry->RCE_Links)) {
  32. plel = RemoveHeadList(&pentry->RCE_Links);
  33. plink = CONTAINING_RECORD(plel, RASCONNLINK, RCL_Node);
  34. Free(plink);
  35. }
  36. Free(pentry);
  37. }
  38. return NO_ERROR;
  39. }
  40. DWORD
  41. GetRasconnList(
  42. LIST_ENTRY *pListHead )
  43. /* Builds a sorted list containing entries for each connected network.
  44. ** Each entry consists of an entry-name and a list of RASCONN structures
  45. ** for each link connected to the entry-name's network.
  46. **
  47. ** The type of each node in the list of entries is RASCONNENTRY.
  48. ** The type of each node in each list of links is RASCONNLINK.
  49. **
  50. ** Returns 0 if successful, or an error code.
  51. **
  52. ** (Abolade Gbadegesin Nov-9-1995)
  53. */
  54. {
  55. DWORD dwErr;
  56. INT cmp, cmpl;
  57. RASCONNLINK *plink;
  58. RASCONNENTRY *pentry;
  59. DWORD i, iConnCount;
  60. RASCONN *pConnTable, *pconn;
  61. LIST_ENTRY *ple, *plel, *pheadl;
  62. InitializeListHead(pListHead);
  63. //
  64. // get an array of all the connections
  65. //
  66. dwErr = GetRasconnTable(&pConnTable, &iConnCount);
  67. if (dwErr != NO_ERROR) { return dwErr; }
  68. //
  69. // convert the array into a list
  70. //
  71. for (i = 0, pconn = pConnTable; i < iConnCount; i++, pconn++) {
  72. //
  73. // see if there is an entry for the network to which
  74. // this RASCONN corresponds
  75. //
  76. for (ple = pListHead->Flink; ple != pListHead; ple = ple->Flink) {
  77. pentry = CONTAINING_RECORD(ple, RASCONNENTRY, RCE_Node);
  78. cmp = lstrcmp(pconn->szEntryName, pentry->RCE_Entry->szEntryName);
  79. if (cmp > 0) { continue; }
  80. else
  81. if (cmp < 0) { break; }
  82. //
  83. // the entry has been found;
  84. // now insert a link for the connection
  85. //
  86. pheadl = &pentry->RCE_Links;
  87. for (plel = pheadl->Flink; plel != pheadl; plel = plel->Flink) {
  88. plink = CONTAINING_RECORD(plel, RASCONNLINK, RCL_Node);
  89. cmpl = lstrcmp(
  90. pconn->szDeviceName, plink->RCL_Link.szDeviceName
  91. );
  92. if (cmpl > 0) { continue; }
  93. else
  94. if (cmpl < 0) { break; }
  95. //
  96. // the link already exists, so do nothing
  97. //
  98. break;
  99. }
  100. //
  101. // the link was not found but we found where to insert it,
  102. // insert the link now
  103. //
  104. if (plel == pheadl || cmpl < 0) {
  105. plink = Malloc(sizeof(RASCONNLINK));
  106. if (plink == NULL) {
  107. FreeRasconnList(pListHead);
  108. Free(pConnTable);
  109. return ERROR_NOT_ENOUGH_MEMORY;
  110. }
  111. plink->RCL_Link = *pconn;
  112. InsertTailList(plel, &plink->RCL_Node);
  113. }
  114. break;
  115. }
  116. //
  117. // the entry was not found, but now we know where to insert it
  118. //
  119. if (ple == pListHead || cmp < 0) {
  120. //
  121. // allocate the new entry
  122. //
  123. pentry = Malloc(sizeof(RASCONNENTRY));
  124. if (pentry == NULL) {
  125. FreeRasconnList(pListHead);
  126. Free(pConnTable);
  127. return ERROR_NOT_ENOUGH_MEMORY;
  128. }
  129. InitializeListHead(&pentry->RCE_Links);
  130. //
  131. // insert it in the list of entries
  132. //
  133. InsertTailList(ple, &pentry->RCE_Node);
  134. //
  135. // allocate the link which corresponds to the RASCONN
  136. // we are currently working on
  137. //
  138. plink = Malloc(sizeof(RASCONNLINK));
  139. if (plink == NULL) {
  140. FreeRasconnList(pListHead);
  141. Free(pConnTable);
  142. return ERROR_NOT_ENOUGH_MEMORY;
  143. }
  144. plink->RCL_Link = *pconn;
  145. //
  146. // insert it in the entry's list of links
  147. //
  148. InsertHeadList(&pentry->RCE_Links, &plink->RCL_Node);
  149. pentry->RCE_Entry = &plink->RCL_Link;
  150. }
  151. }
  152. Free(pConnTable);
  153. return NO_ERROR;
  154. }
  155. DWORD
  156. GetRasconnTable(
  157. OUT RASCONN** ppConnTable,
  158. OUT DWORD* pdwConnCount )
  159. /* Get active RAS dial-out connections. Loads '*ppConnTable' with the
  160. ** address of a heap block containing an array of '*pdwConnCount' active
  161. ** connections.
  162. **
  163. ** (Abolade Gbadegesin Nov-9-1995)
  164. */
  165. {
  166. RASCONN conn, *pconn;
  167. DWORD dwErr, dwSize, dwCount;
  168. //
  169. // validate arguments
  170. //
  171. if (ppConnTable == NULL || pdwConnCount == NULL) {
  172. return ERROR_INVALID_PARAMETER;
  173. }
  174. *pdwConnCount = 0;
  175. *ppConnTable = NULL;
  176. //
  177. // RasEnumConnections doesn't give the size required
  178. // unless a valid buffer is specified, so pass in a dummy buffer
  179. //
  180. conn.dwSize = dwSize = sizeof(RASCONN);
  181. pconn = &conn;
  182. ASSERT(g_pRasEnumConnections);
  183. dwErr = g_pRasEnumConnections(pconn, &dwSize, &dwCount);
  184. if (dwErr == NO_ERROR) {
  185. if (dwCount == 0) {
  186. return NO_ERROR;
  187. }
  188. else {
  189. //
  190. // only one entry, so return it
  191. //
  192. pconn = Malloc(sizeof(RASCONN));
  193. if (pconn == NULL) {
  194. return ERROR_NOT_ENOUGH_MEMORY;
  195. }
  196. *pconn = conn;
  197. *ppConnTable = pconn;
  198. *pdwConnCount = 1;
  199. return NO_ERROR;
  200. }
  201. }
  202. if (dwErr != ERROR_BUFFER_TOO_SMALL) {
  203. return dwErr;
  204. }
  205. //
  206. // allocate more space
  207. //
  208. pconn = Malloc(dwSize);
  209. if (pconn == NULL) {
  210. return ERROR_NOT_ENOUGH_MEMORY;
  211. }
  212. pconn->dwSize = sizeof(RASCONN);
  213. dwErr = g_pRasEnumConnections(pconn, &dwSize, &dwCount);
  214. if (dwErr != NO_ERROR) {
  215. Free(pconn);
  216. return dwErr;
  217. }
  218. *ppConnTable = pconn;
  219. *pdwConnCount = dwCount;
  220. return NO_ERROR;
  221. }
  222. DWORD
  223. GetRasEntrynameTable(
  224. OUT RASENTRYNAME** ppEntrynameTable,
  225. OUT DWORD* pdwEntrynameCount )
  226. /* Get active RAS dial-out connections. Loads '*ppEntrynameTable' with the
  227. ** address of a heap block containing an array of '*pdwEntrynameCount'
  228. ** active connections.
  229. **
  230. ** (Abolade Gbadegesin Nov-9-1995)
  231. */
  232. {
  233. RASENTRYNAME ename, *pename;
  234. DWORD dwErr, dwSize, dwCount;
  235. //
  236. // validate arguments
  237. //
  238. if (ppEntrynameTable == NULL || pdwEntrynameCount == NULL) {
  239. return ERROR_INVALID_PARAMETER;
  240. }
  241. *pdwEntrynameCount = 0;
  242. *ppEntrynameTable = NULL;
  243. //
  244. // RasEnumEntries doesn't give the size required
  245. // unless a valid buffer is specified, so pass in a dummy buffer
  246. //
  247. ename.dwSize = dwSize = sizeof(ename);
  248. pename = &ename;
  249. ASSERT(g_pRasEnumEntries);
  250. dwErr = g_pRasEnumEntries(NULL, NULL, pename, &dwSize, &dwCount);
  251. if (dwErr == NO_ERROR) {
  252. if (dwCount == 0) {
  253. return NO_ERROR;
  254. }
  255. else {
  256. //
  257. // only one entry, so return it
  258. //
  259. pename = Malloc(sizeof(*pename));
  260. if (pename == NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
  261. *pename = ename;
  262. *ppEntrynameTable = pename;
  263. *pdwEntrynameCount = 1;
  264. return NO_ERROR;
  265. }
  266. }
  267. if (dwErr != ERROR_BUFFER_TOO_SMALL) {
  268. return dwErr;
  269. }
  270. //
  271. // allocate more space
  272. //
  273. pename = Malloc(dwSize);
  274. if (pename == NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
  275. pename->dwSize = sizeof(*pename);
  276. dwErr = g_pRasEnumEntries(NULL, NULL, pename, &dwSize, &dwCount);
  277. if (dwErr != NO_ERROR) { Free(pename); return dwErr; }
  278. *ppEntrynameTable = pename;
  279. *pdwEntrynameCount = dwCount;
  280. return NO_ERROR;
  281. }
  282. DWORD
  283. GetRasProjectionInfo(
  284. IN HRASCONN hrasconn,
  285. OUT RASAMB* pamb,
  286. OUT RASPPPNBF* pnbf,
  287. OUT RASPPPIP* pip,
  288. OUT RASPPPIPX* pipx,
  289. OUT RASPPPLCP* plcp,
  290. OUT RASSLIP* pslip,
  291. OUT RASPPPCCP* pccp)
  292. /* Reads projection info for all protocols, translating "not requested"
  293. ** into an in-structure code of ERROR_PROTOCOL_NOT_CONFIGURED.
  294. **
  295. ** Returns 0 is successful, otherwise a non-0 error code.
  296. */
  297. {
  298. DWORD dwErr;
  299. DWORD dwSize;
  300. ZeroMemory( pamb, sizeof(*pamb) );
  301. ZeroMemory( pnbf, sizeof(*pnbf) );
  302. ZeroMemory( pip, sizeof(*pip) );
  303. ZeroMemory( pipx, sizeof(*pipx) );
  304. ZeroMemory( plcp, sizeof(*plcp) );
  305. ZeroMemory( pslip,sizeof(*pslip) );
  306. ZeroMemory( pccp, sizeof(*pccp) );
  307. dwSize = pamb->dwSize = sizeof(*pamb);
  308. ASSERT(g_pRasGetProjectionInfo);
  309. TRACE("RasGetProjectionInfo(AMB)");
  310. dwErr = g_pRasGetProjectionInfo( hrasconn, RASP_Amb, pamb, &dwSize );
  311. TRACE2("RasGetProjectionInfo(AMB)=%d,e=%d",dwErr,pamb->dwError);
  312. if (dwErr == ERROR_PROTOCOL_NOT_CONFIGURED)
  313. {
  314. ZeroMemory( pamb, sizeof(*pamb) );
  315. pamb->dwError = ERROR_PROTOCOL_NOT_CONFIGURED;
  316. }
  317. else if (dwErr != 0)
  318. return dwErr;
  319. dwSize = pnbf->dwSize = sizeof(*pnbf);
  320. TRACE("RasGetProjectionInfo(NBF)");
  321. dwErr = g_pRasGetProjectionInfo( hrasconn, RASP_PppNbf, pnbf, &dwSize );
  322. TRACE2("RasGetProjectionInfo(NBF)=%d,e=%d",dwErr,pnbf->dwError);
  323. if (dwErr == ERROR_PROTOCOL_NOT_CONFIGURED)
  324. {
  325. ZeroMemory( pnbf, sizeof(*pnbf) );
  326. pnbf->dwError = ERROR_PROTOCOL_NOT_CONFIGURED;
  327. }
  328. else if (dwErr != 0)
  329. return dwErr;
  330. dwSize = pip->dwSize = sizeof(*pip);
  331. TRACE("RasGetProjectionInfo(IP)");
  332. dwErr = g_pRasGetProjectionInfo( hrasconn, RASP_PppIp, pip, &dwSize );
  333. TRACE2("RasGetProjectionInfo(IP)=%d,e=%d",dwErr,pip->dwError);
  334. if (dwErr == ERROR_PROTOCOL_NOT_CONFIGURED)
  335. {
  336. ZeroMemory( pip, sizeof(*pip) );
  337. pip->dwError = ERROR_PROTOCOL_NOT_CONFIGURED;
  338. }
  339. else if (dwErr != 0)
  340. return dwErr;
  341. dwSize = pipx->dwSize = sizeof(*pipx);
  342. TRACE("RasGetProjectionInfo(IPX)");
  343. dwErr = g_pRasGetProjectionInfo( hrasconn, RASP_PppIpx, pipx, &dwSize );
  344. TRACE2("RasGetProjectionInfo(IPX)=%d,e=%d",dwErr,pipx->dwError);
  345. if (dwErr == ERROR_PROTOCOL_NOT_CONFIGURED)
  346. {
  347. dwErr = 0;
  348. ZeroMemory( pipx, sizeof(*pipx) );
  349. pipx->dwError = ERROR_PROTOCOL_NOT_CONFIGURED;
  350. }
  351. dwSize = plcp->dwSize = sizeof(*plcp);
  352. TRACE("RasGetProjectionInfo(LCP)");
  353. dwErr = g_pRasGetProjectionInfo( hrasconn, RASP_PppLcp, plcp, &dwSize );
  354. TRACE2("RasGetProjectionInfo(LCP)=%d,f=%d",dwErr,plcp->fBundled);
  355. if (dwErr == ERROR_PROTOCOL_NOT_CONFIGURED)
  356. {
  357. dwErr = 0;
  358. plcp->fBundled = FALSE;
  359. }
  360. dwSize = pccp->dwSize = sizeof(*pccp);
  361. TRACE("RasGetProjectionInfo(CCP)");
  362. dwErr = g_pRasGetProjectionInfo( hrasconn, RASP_PppCcp, pccp, &dwSize);
  363. TRACE1("RasGetProjectionInfo(CCP)=%d",dwErr);
  364. #if 0
  365. pslip->dwError = ERROR_PROTOCOL_NOT_CONFIGURED;
  366. #else
  367. dwSize = pslip->dwSize = sizeof(*pslip);
  368. TRACE("RasGetProjectionInfo(SLIP)");
  369. dwErr = g_pRasGetProjectionInfo( hrasconn, RASP_Slip, pslip, &dwSize );
  370. TRACE2("RasGetProjectionInfo(SLIP)=%d,e=%d",dwErr,pslip->dwError);
  371. if (dwErr == ERROR_PROTOCOL_NOT_CONFIGURED)
  372. {
  373. dwErr = 0;
  374. ZeroMemory( pslip, sizeof(*pslip) );
  375. pslip->dwError = ERROR_PROTOCOL_NOT_CONFIGURED;
  376. }
  377. #endif
  378. return dwErr;
  379. }
  380. HRASCONN
  381. HrasconnFromEntry(
  382. IN TCHAR* pszPhonebook,
  383. IN TCHAR* pszEntry )
  384. /* Returns the HRASCONN associated with entry 'pszEntry' from phonebook
  385. ** 'pszPhonebook' or NULL if not connected or error.
  386. */
  387. {
  388. DWORD dwErr;
  389. RASCONN* prc;
  390. DWORD c;
  391. HRASCONN h;
  392. TRACE("HrasconnFromEntry");
  393. if (!pszEntry)
  394. return NULL;
  395. h = NULL;
  396. dwErr = GetRasconnTable( &prc, &c );
  397. if (dwErr == 0 && c > 0)
  398. {
  399. RASCONN* p;
  400. DWORD i;
  401. for (i = 0, p = prc; i < c; ++i, ++p)
  402. {
  403. //let the entryname non-case sensitive, for whislter bug 311846 gangz
  404. //
  405. if ((!pszPhonebook
  406. || lstrcmpi( p->szPhonebook, pszPhonebook ) == 0)
  407. && lstrcmpi( p->szEntryName, pszEntry ) == 0)
  408. {
  409. h = p->hrasconn;
  410. break;
  411. }
  412. }
  413. Free( prc );
  414. }
  415. TRACE1("HrasconnFromEntry=$%08x",h);
  416. return h;
  417. }