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.

1450 lines
43 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. TOKEN_VALUE InterfaceTypes[ 5 ] =
  4. {
  5. { VAL_CLIENT, ROUTER_IF_TYPE_CLIENT },
  6. { VAL_HOMEROUTER, ROUTER_IF_TYPE_HOME_ROUTER },
  7. { VAL_WANROUTER, ROUTER_IF_TYPE_FULL_ROUTER },
  8. { VAL_DEDICATED, ROUTER_IF_TYPE_DEDICATED },
  9. { VAL_INTERNAL, ROUTER_IF_TYPE_INTERNAL }
  10. };
  11. TOKEN_VALUE InterfaceStates[ 3 ] =
  12. {
  13. { VAL_DOWN, ROUTER_IF_STATE_DISCONNECTED },
  14. { VAL_DOWN, ROUTER_IF_STATE_CONNECTING },
  15. { VAL_UP, ROUTER_IF_STATE_CONNECTED }
  16. };
  17. TOKEN_VALUE InterfaceEnableStatus[ 2 ] =
  18. {
  19. { VAL_ENABLED, FALSE },
  20. { VAL_DISABLED, TRUE }
  21. };
  22. TOKEN_VALUE AdminStates[ 2 ] =
  23. {
  24. { VAL_DISABLED, ADMIN_STATE_DISABLED },
  25. { VAL_ENABLED, ADMIN_STATE_ENABLED }
  26. };
  27. TOKEN_VALUE OperStates[ 3 ] =
  28. {
  29. { VAL_DOWN, OPER_STATE_DOWN },
  30. { VAL_UP, OPER_STATE_UP },
  31. { VAL_SLEEPING, OPER_STATE_SLEEPING }
  32. };
  33. TOKEN_VALUE IpxInterfaceTypes[ 8 ] =
  34. {
  35. { VAL_OTHER, IF_TYPE_OTHER },
  36. { VAL_DEDICATED, IF_TYPE_LAN },
  37. { VAL_WANROUTER, IF_TYPE_WAN_ROUTER },
  38. { VAL_CLIENT, IF_TYPE_WAN_WORKSTATION },
  39. { VAL_INTERNAL, IF_TYPE_INTERNAL },
  40. { VAL_HOMEROUTER, IF_TYPE_PERSONAL_WAN_ROUTER },
  41. { VAL_DIALOUT, IF_TYPE_ROUTER_WORKSTATION_DIALOUT },
  42. { VAL_DIALOUT, IF_TYPE_STANDALONE_WORKSTATION_DIALOUT }
  43. };
  44. TOKEN_VALUE RouterInterfaceTypes[ 5 ] =
  45. {
  46. { VAL_CLIENT, ROUTER_IF_TYPE_CLIENT },
  47. { VAL_HOMEROUTER, ROUTER_IF_TYPE_HOME_ROUTER },
  48. { VAL_WANROUTER, ROUTER_IF_TYPE_FULL_ROUTER },
  49. { VAL_DEDICATED, ROUTER_IF_TYPE_DEDICATED },
  50. { VAL_INTERNAL, ROUTER_IF_TYPE_INTERNAL }
  51. };
  52. TOKEN_VALUE NbDeliverStates[ 4 ] =
  53. {
  54. { VAL_DISABLED, ADMIN_STATE_DISABLED },
  55. { VAL_ENABLED, ADMIN_STATE_ENABLED },
  56. { VAL_STATICONLY, ADMIN_STATE_ENABLED_ONLY_FOR_NETBIOS_STATIC_ROUTING },
  57. { VAL_ONLYWHENUP, ADMIN_STATE_ENABLED_ONLY_FOR_OPER_STATE_UP}
  58. };
  59. TOKEN_VALUE UpdateModes[ 3 ] =
  60. {
  61. { VAL_STANDARD, IPX_STANDARD_UPDATE },
  62. { VAL_NONE, IPX_NO_UPDATE },
  63. { VAL_AUTOSTATIC, IPX_AUTO_STATIC_UPDATE }
  64. };
  65. TOKEN_VALUE IpxProtocols[ 4 ] =
  66. {
  67. { VAL_LOCAL, IPX_PROTOCOL_LOCAL },
  68. { VAL_STATIC, IPX_PROTOCOL_STATIC },
  69. { VAL_RIP, IPX_PROTOCOL_RIP },
  70. { VAL_SAP, IPX_PROTOCOL_SAP }
  71. };
  72. TOKEN_VALUE TfFilterActions[ 2 ] =
  73. {
  74. { VAL_PERMIT, IPX_TRAFFIC_FILTER_ACTION_PERMIT },
  75. { VAL_DENY, IPX_TRAFFIC_FILTER_ACTION_DENY }
  76. };
  77. TOKEN_VALUE RipFilterActions[ 2 ] =
  78. {
  79. { VAL_PERMIT, IPX_ROUTE_FILTER_PERMIT },
  80. { VAL_DENY, IPX_ROUTE_FILTER_DENY }
  81. };
  82. TOKEN_VALUE SapFilterActions[ 2 ] =
  83. {
  84. { VAL_PERMIT, IPX_SERVICE_FILTER_PERMIT },
  85. { VAL_DENY, IPX_SERVICE_FILTER_DENY }
  86. };
  87. TOKEN_VALUE FilterModes[ 2 ] =
  88. {
  89. { VAL_INPUT, INPUT_FILTER },
  90. { VAL_OUTPUT, OUTPUT_FILTER }
  91. };
  92. TOKEN_VALUE LogLevels[ 4 ] =
  93. {
  94. { VAL_NONE , 0 },
  95. { VAL_ERRORS_ONLY , EVENTLOG_ERROR_TYPE },
  96. { VAL_ERRORS_AND_WARNINGS, EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE },
  97. { VAL_MAXINFO,
  98. EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE }
  99. };
  100. DWORD
  101. GetIpxInterfaceIndex(
  102. IN MIB_SERVER_HANDLE hRouterMIB,
  103. IN LPCWSTR InterfaceName,
  104. OUT ULONG *InterfaceIndex
  105. )
  106. /*++
  107. Routine Description :
  108. This routine retrives the index of an interface given its name.
  109. Arguments :
  110. hRouterMIB - Handle to the router service
  111. InterfaceName - Name of interface for which index is required
  112. InterfaceIndex - On return contains the interface of the interface
  113. if found.
  114. Return values :
  115. --*/
  116. {
  117. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  118. DWORD IfSize = sizeof(IPX_INTERFACE);
  119. PIPX_INTERFACE Ifp;
  120. DWORD rc;
  121. UCHAR InterfaceNameA[ MAX_INTERFACE_NAME_LEN + 1 ];
  122. //
  123. // Convert interface name to Ansi
  124. //
  125. wcstombs( InterfaceNameA, InterfaceName, MAX_INTERFACE_NAME_LEN );
  126. MibGetInputData.TableId = IPX_INTERFACE_TABLE;
  127. //
  128. // Begin enumerating interfaces
  129. //
  130. rc = MprAdminMIBEntryGetFirst(
  131. hRouterMIB, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData,
  132. sizeof( IPX_MIB_GET_INPUT_DATA ), (LPVOID *) &Ifp,
  133. &IfSize
  134. );
  135. //
  136. // until a match is found or there are no more interfaces
  137. //
  138. while ( rc == NO_ERROR )
  139. {
  140. //
  141. // Is this the interface
  142. //
  143. if ( _stricmp( (LPSTR)InterfaceNameA, (LPSTR) Ifp->InterfaceName) == 0 )
  144. {
  145. *InterfaceIndex = Ifp->InterfaceIndex;
  146. MprAdminMIBBufferFree (Ifp);
  147. break;
  148. }
  149. else
  150. {
  151. MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex =
  152. Ifp->InterfaceIndex;
  153. MprAdminMIBBufferFree (Ifp);
  154. }
  155. rc = MprAdminMIBEntryGetNext(
  156. hRouterMIB, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData,
  157. sizeof(IPX_MIB_GET_INPUT_DATA), (LPVOID *)&Ifp, &IfSize
  158. );
  159. }
  160. if ( rc == ERROR_NO_MORE_ITEMS )
  161. {
  162. rc = ERROR_NO_SUCH_INTERFACE;
  163. }
  164. return rc;
  165. }
  166. DWORD
  167. GetIpxInterfaceName (
  168. IN MIB_SERVER_HANDLE hRouterMIB,
  169. IN ULONG InterfaceIndex,
  170. OUT LPWSTR InterfaceName
  171. )
  172. /*++
  173. Routine Description :
  174. This routine retrives the index of an interface given its name.
  175. Arguments :
  176. hRouterMIB - Handle to the router service
  177. InterfaceName - Name of interface for which index is required
  178. InterfaceIndex - On return contains the interface of the interface
  179. if found.
  180. Return values :
  181. --*/
  182. {
  183. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  184. DWORD IfSize = sizeof( IPX_INTERFACE );
  185. PIPX_INTERFACE Ifp;
  186. DWORD rc;
  187. MibGetInputData.TableId = IPX_INTERFACE_TABLE;
  188. MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex =
  189. InterfaceIndex;
  190. rc = MprAdminMIBEntryGet(
  191. hRouterMIB, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData,
  192. sizeof(IPX_MIB_GET_INPUT_DATA), (LPVOID *)&Ifp, &IfSize
  193. );
  194. if ( rc == NO_ERROR )
  195. {
  196. mbstowcs(
  197. InterfaceName, (LPSTR)Ifp->InterfaceName,
  198. IPX_INTERFACE_ANSI_NAME_LEN
  199. );
  200. MprAdminMIBBufferFree( Ifp );
  201. }
  202. else if ( rc == ERROR_NO_MORE_ITEMS )
  203. {
  204. rc = ERROR_NO_SUCH_INTERFACE;
  205. }
  206. return rc;
  207. }
  208. /*++
  209. *******************************************************************
  210. G e t I P X T o c E n t r y
  211. Routine Description:
  212. Returns pointer to entry in Router Table Of Context
  213. Arguments:
  214. pInterfaceInfo - pointer to table of content
  215. InfoEntryType - type of entry to look for
  216. Return Value:
  217. Pointer to entry in table of content
  218. NULL if there is no such entry in the table
  219. Remarks:
  220. *******************************************************************
  221. --*/
  222. PIPX_TOC_ENTRY
  223. GetIPXTocEntry(
  224. IN PIPX_INFO_BLOCK_HEADER pInterfaceInfo,
  225. IN ULONG InfoEntryType
  226. )
  227. {
  228. UINT i;
  229. PIPX_TOC_ENTRY pTocEntry;
  230. if (pInterfaceInfo)
  231. {
  232. for ( i = 0, pTocEntry = pInterfaceInfo->TocEntry;
  233. i < pInterfaceInfo->TocEntriesCount;
  234. i++, pTocEntry++)
  235. {
  236. if (pTocEntry->InfoType == InfoEntryType)
  237. {
  238. return pTocEntry;
  239. }
  240. }
  241. }
  242. SetLastError( ERROR_FILE_NOT_FOUND );
  243. return NULL;
  244. }
  245. DWORD
  246. AddIPXInfoEntry (
  247. IN PIPX_INFO_BLOCK_HEADER pOldBlock,
  248. IN ULONG InfoType,
  249. IN ULONG InfoSize,
  250. IN PVOID Info,
  251. IN PINFO_CMP_PROC InfoEqualCB OPTIONAL,
  252. OUT PIPX_INFO_BLOCK_HEADER *pNewBlock
  253. )
  254. {
  255. ULONG i, entriesCount = 1;
  256. PIPX_TOC_ENTRY pTocEntry;
  257. PIPX_INFO_BLOCK_HEADER pBlock;
  258. ULONG newBlockSize =
  259. InfoSize + sizeof( IPX_INFO_BLOCK_HEADER );
  260. BOOLEAN done = FALSE;
  261. DWORD rc;
  262. if ( pOldBlock != NULL )
  263. {
  264. ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
  265. for ( i=0, pTocEntry = pOldBlock->TocEntry;
  266. i < pOldBlock->TocEntriesCount;
  267. i++, pTocEntry++)
  268. {
  269. newBlockSize += pTocEntry->InfoSize*pTocEntry->Count;
  270. if (pTocEntry->InfoType == InfoType)
  271. {
  272. ULONG j;
  273. LPBYTE pInfo = (LPBYTE)pOldBlock+pTocEntry->Offset;
  274. ASSERT (pTocEntry->InfoSize == InfoSize);
  275. for (j=0; j<pTocEntry->Count; j++, pInfo+=InfoSize)
  276. {
  277. BOOL found;
  278. if (InfoEqualCB!=NULL)
  279. {
  280. found = (*InfoEqualCB) (pInfo, Info);
  281. }
  282. else
  283. {
  284. found = memcmp (pInfo, Info, InfoSize)==0;
  285. }
  286. if (found)
  287. {
  288. return ERROR_ALREADY_EXISTS;
  289. }
  290. }
  291. }
  292. else
  293. {
  294. entriesCount += 1;
  295. newBlockSize += sizeof (IPX_TOC_ENTRY);
  296. }
  297. }
  298. }
  299. pBlock = (PIPX_INFO_BLOCK_HEADER)GlobalAlloc (GPTR, newBlockSize);
  300. if ( pBlock != NULL )
  301. {
  302. ULONG dstOffset =
  303. FIELD_OFFSET (IPX_INFO_BLOCK_HEADER,TocEntry[entriesCount]);
  304. PIPX_TOC_ENTRY dstToc = pBlock->TocEntry;
  305. pBlock->Version = IPX_ROUTER_VERSION_1;
  306. pBlock->Size = newBlockSize;
  307. pBlock->TocEntriesCount = entriesCount;
  308. if (pOldBlock!=NULL)
  309. {
  310. for (i=0, pTocEntry = pOldBlock->TocEntry;
  311. i<pOldBlock->TocEntriesCount; i++, pTocEntry++)
  312. {
  313. *dstToc = *pTocEntry;
  314. dstToc->Offset = dstOffset;
  315. memcpy ((PUCHAR)pBlock+dstOffset,
  316. (PUCHAR)pOldBlock+pTocEntry->Offset,
  317. pTocEntry->InfoSize*pTocEntry->Count);
  318. dstOffset += dstToc->InfoSize*dstToc->Count;
  319. if (dstToc->InfoType==InfoType)
  320. {
  321. memcpy ((PUCHAR)pBlock+dstOffset, Info, InfoSize);
  322. dstToc->Count += 1;
  323. dstOffset += InfoSize;
  324. done = TRUE;
  325. }
  326. dstToc += 1;
  327. }
  328. }
  329. if (!done)
  330. {
  331. dstToc->InfoType = InfoType;
  332. dstToc->InfoSize = InfoSize;
  333. dstToc->Count = 1;
  334. dstToc->Offset = dstOffset;
  335. memcpy ((PUCHAR)pBlock+dstOffset, Info, InfoSize);
  336. }
  337. *pNewBlock = pBlock;
  338. rc = NO_ERROR;
  339. }
  340. else
  341. {
  342. rc = ERROR_NOT_ENOUGH_MEMORY;
  343. }
  344. return rc;
  345. }
  346. DWORD
  347. DeleteIPXInfoEntry (
  348. IN PIPX_INFO_BLOCK_HEADER pOldBlock,
  349. IN ULONG InfoType,
  350. IN ULONG InfoSize,
  351. IN PVOID Info,
  352. IN PINFO_CMP_PROC InfoEqualCB OPTIONAL,
  353. IN PIPX_INFO_BLOCK_HEADER *pNewBlock
  354. )
  355. {
  356. ULONG i, entriesCount = 1, j;
  357. PIPX_TOC_ENTRY pTocEntry, dstToc;
  358. ULONG newBlockSize = sizeof (IPX_INFO_BLOCK_HEADER)-InfoSize;
  359. ULONG dstOffset;
  360. BOOLEAN found = FALSE;
  361. ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
  362. for ( i=0, pTocEntry = pOldBlock->TocEntry;
  363. i<pOldBlock->TocEntriesCount;
  364. i++, pTocEntry++)
  365. {
  366. newBlockSize += pTocEntry->InfoSize*pTocEntry->Count;
  367. if (pTocEntry->InfoType == InfoType)
  368. {
  369. LPBYTE pInfo = (LPBYTE)pOldBlock+pTocEntry->Offset;
  370. ASSERT (pTocEntry->InfoSize == InfoSize);
  371. for (j=0; j<pTocEntry->Count; j++, pInfo+=InfoSize)
  372. {
  373. if ( InfoEqualCB != NULL )
  374. {
  375. found = (BOOLEAN) (*InfoEqualCB) (pInfo, Info);
  376. }
  377. else
  378. {
  379. found = memcmp (pInfo, Info, InfoSize)==0;
  380. }
  381. if (found)
  382. {
  383. if (pTocEntry->Count==1)
  384. {
  385. entriesCount -= 1;
  386. newBlockSize -= sizeof (IPX_TOC_ENTRY);
  387. }
  388. break;
  389. }
  390. }
  391. if (!found)
  392. {
  393. return ERROR_FILE_NOT_FOUND;
  394. }
  395. }
  396. else
  397. {
  398. entriesCount += 1;
  399. newBlockSize += sizeof (IPX_TOC_ENTRY);
  400. }
  401. }
  402. if (!found)
  403. {
  404. return ERROR_FILE_NOT_FOUND;
  405. }
  406. for ( i=0, dstToc = pTocEntry = pOldBlock->TocEntry;
  407. i < pOldBlock->TocEntriesCount; i++, pTocEntry++)
  408. {
  409. if (pTocEntry->InfoType==InfoType)
  410. {
  411. if (pTocEntry->Count>1)
  412. {
  413. pTocEntry->Count -= 1;
  414. dstToc += 1;
  415. }
  416. }
  417. else
  418. {
  419. if (dstToc!=pTocEntry)
  420. {
  421. ASSERT (dstToc<pTocEntry);
  422. *dstToc = *pTocEntry;
  423. }
  424. dstToc += 1;
  425. }
  426. }
  427. dstOffset = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER,TocEntry[entriesCount]);
  428. for (i=0, pTocEntry = pOldBlock->TocEntry;
  429. i<entriesCount; i++, pTocEntry++)
  430. {
  431. if (pTocEntry->InfoType==InfoType)
  432. {
  433. ULONG newInfoSize = InfoSize*j;
  434. if ( j > 0 )
  435. {
  436. if (dstOffset!=pTocEntry->Offset)
  437. {
  438. ASSERT (dstOffset<pTocEntry->Offset);
  439. memmove ((PUCHAR)pOldBlock+dstOffset,
  440. (PUCHAR)pOldBlock+pTocEntry->Offset,
  441. newInfoSize);
  442. }
  443. }
  444. if ( j < pTocEntry->Count )
  445. {
  446. memmove ((PUCHAR)pOldBlock+dstOffset+newInfoSize,
  447. (PUCHAR)pOldBlock+pTocEntry->Offset+newInfoSize+InfoSize,
  448. InfoSize*(pTocEntry->Count-j));
  449. newInfoSize += InfoSize*(pTocEntry->Count-j);
  450. }
  451. pTocEntry->Offset = dstOffset;
  452. dstOffset += newInfoSize;
  453. }
  454. else
  455. {
  456. if (dstOffset!=pTocEntry->Offset)
  457. {
  458. ASSERT (dstOffset<pTocEntry->Offset);
  459. memmove ((PUCHAR)pOldBlock+dstOffset,
  460. (PUCHAR)pOldBlock+pTocEntry->Offset,
  461. pTocEntry->InfoSize*pTocEntry->Count);
  462. pTocEntry->Offset = dstOffset;
  463. }
  464. dstOffset += pTocEntry->InfoSize*pTocEntry->Count;
  465. }
  466. }
  467. pOldBlock->Size = newBlockSize;
  468. pOldBlock->TocEntriesCount = entriesCount;
  469. *pNewBlock = pOldBlock;
  470. return NO_ERROR;
  471. }
  472. DWORD
  473. UpdateIPXInfoEntry (
  474. IN PIPX_INFO_BLOCK_HEADER pOldBlock,
  475. IN ULONG InfoType,
  476. IN ULONG InfoSize,
  477. IN PVOID OldInfo OPTIONAL,
  478. IN PVOID NewInfo,
  479. IN PINFO_CMP_PROC InfoEqualCB OPTIONAL,
  480. OUT PIPX_INFO_BLOCK_HEADER *pNewBlock
  481. )
  482. {
  483. ULONG i, j, entriesCount = 1;
  484. PIPX_TOC_ENTRY pTocEntry;
  485. PIPX_INFO_BLOCK_HEADER pBlock;
  486. ULONG newBlockSize =
  487. InfoSize+sizeof (IPX_INFO_BLOCK_HEADER);
  488. BOOLEAN done = FALSE;
  489. DWORD rc;
  490. ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
  491. for ( i=0, pTocEntry = pOldBlock->TocEntry;
  492. i < pOldBlock->TocEntriesCount;
  493. i++, pTocEntry++)
  494. {
  495. if (pTocEntry->InfoType == InfoType)
  496. {
  497. LPBYTE pInfo = (LPBYTE)pOldBlock+pTocEntry->Offset;
  498. if (OldInfo!=NULL)
  499. {
  500. ASSERT (pTocEntry->InfoSize == InfoSize);
  501. for (j=0; j<pTocEntry->Count; j++, pInfo+=InfoSize)
  502. {
  503. BOOLEAN found;
  504. if (InfoEqualCB!=NULL)
  505. {
  506. found = (BOOLEAN) (*InfoEqualCB) (pInfo, OldInfo);
  507. }
  508. else
  509. {
  510. found = memcmp (pInfo, OldInfo, InfoSize)==0;
  511. }
  512. if (found)
  513. {
  514. memcpy (pInfo, NewInfo, InfoSize);
  515. *pNewBlock = pOldBlock;
  516. return NO_ERROR;
  517. }
  518. }
  519. }
  520. else
  521. {
  522. ASSERT (pTocEntry->Count==1);
  523. if (pTocEntry->InfoSize==InfoSize)
  524. {
  525. memcpy (pInfo, NewInfo, InfoSize);
  526. *pNewBlock = pOldBlock;
  527. return NO_ERROR;
  528. }
  529. newBlockSize -= pTocEntry->InfoSize+sizeof (IPX_INFO_BLOCK_HEADER);
  530. }
  531. }
  532. else
  533. {
  534. entriesCount += 1;
  535. newBlockSize += sizeof (IPX_TOC_ENTRY)+pTocEntry->InfoSize*pTocEntry->Count;
  536. }
  537. }
  538. pBlock = (PIPX_INFO_BLOCK_HEADER)GlobalAlloc (GPTR, newBlockSize);
  539. if ( pBlock != NULL )
  540. {
  541. ULONG dstOffset = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER,TocEntry[entriesCount]);
  542. PIPX_TOC_ENTRY dstToc = pBlock->TocEntry;
  543. pBlock->Version = IPX_ROUTER_VERSION_1;
  544. pBlock->Size = newBlockSize;
  545. pBlock->TocEntriesCount = entriesCount;
  546. for (i=0, pTocEntry = pOldBlock->TocEntry;
  547. i<pOldBlock->TocEntriesCount; i++, pTocEntry++)
  548. {
  549. *dstToc = *pTocEntry;
  550. dstToc->Offset = dstOffset;
  551. if (dstToc->InfoType==InfoType)
  552. {
  553. if (pTocEntry->InfoSize==InfoSize)
  554. {
  555. memcpy ((PUCHAR)pBlock+dstOffset,
  556. (PUCHAR)pOldBlock+pTocEntry->Offset,
  557. pTocEntry->InfoSize*pTocEntry->Count);
  558. dstOffset += dstToc->InfoSize*dstToc->Count;
  559. memcpy ((PUCHAR)pBlock+dstOffset, NewInfo, InfoSize);
  560. dstOffset += InfoSize;
  561. dstToc->Count += 1;
  562. }
  563. else
  564. {
  565. memcpy ((PUCHAR)pBlock+dstOffset, NewInfo, InfoSize);
  566. dstToc->InfoSize = InfoSize;
  567. dstOffset += InfoSize;
  568. }
  569. done = TRUE;
  570. }
  571. else
  572. {
  573. memcpy ((PUCHAR)pBlock+dstOffset,
  574. (PUCHAR)pOldBlock+pTocEntry->Offset,
  575. pTocEntry->InfoSize*pTocEntry->Count);
  576. dstOffset += dstToc->InfoSize*dstToc->Count;
  577. }
  578. dstToc += 1;
  579. }
  580. if (!done)
  581. {
  582. dstToc->InfoType = InfoType;
  583. dstToc->InfoSize = InfoSize;
  584. dstToc->Count = 1;
  585. dstToc->Offset = dstOffset;
  586. memcpy ((PUCHAR)pBlock+dstOffset, NewInfo, InfoSize);
  587. }
  588. *pNewBlock = pBlock;
  589. rc = NO_ERROR;
  590. }
  591. else
  592. {
  593. rc = ERROR_NOT_ENOUGH_MEMORY;
  594. }
  595. return rc;
  596. }
  597. DWORD
  598. UpdateRipFilter (
  599. IN PIPX_INFO_BLOCK_HEADER pOldBlock,
  600. IN BOOLEAN Output,
  601. IN PRIP_ROUTE_FILTER_INFO pOldFilter OPTIONAL,
  602. IN PRIP_ROUTE_FILTER_INFO pNewFilter OPTIONAL,
  603. OUT PIPX_INFO_BLOCK_HEADER *pNewBlock
  604. )
  605. {
  606. ULONG i,j;
  607. PIPX_TOC_ENTRY pTocEntry, dstToc;
  608. PIPX_INFO_BLOCK_HEADER pBlock;
  609. ULONG newBlockSize = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER, TocEntry);
  610. BOOLEAN found = FALSE;
  611. PRIP_ROUTE_FILTER_INFO pRfInfo;
  612. ULONG supplyCount, listenCount, count, newCount;
  613. PRIP_IF_CONFIG pRipCfg;
  614. ULONG dstOffset;
  615. if (pOldBlock == NULL)
  616. {
  617. return ERROR_INVALID_PARAMETER;
  618. }
  619. ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
  620. for ( i = 0, pTocEntry = pOldBlock->TocEntry;
  621. i < pOldBlock->TocEntriesCount;
  622. i++, pTocEntry++ )
  623. {
  624. if ( pTocEntry->InfoType == IPX_PROTOCOL_RIP )
  625. {
  626. found = TRUE;
  627. pRipCfg = (PRIP_IF_CONFIG)((LPBYTE)pOldBlock+pTocEntry->Offset);
  628. supplyCount = pRipCfg->RipIfFilters.SupplyFilterCount;
  629. listenCount = pRipCfg->RipIfFilters.ListenFilterCount;
  630. if (Output)
  631. {
  632. pRfInfo = &pRipCfg->RipIfFilters.RouteFilter[0];
  633. count = supplyCount;
  634. }
  635. else
  636. {
  637. pRfInfo = &pRipCfg->RipIfFilters.RouteFilter[
  638. pRipCfg->RipIfFilters.SupplyFilterCount];
  639. count = listenCount;
  640. }
  641. newCount = count;
  642. if (ARGUMENT_PRESENT (pNewFilter))
  643. {
  644. for (j=0; j<count; j++)
  645. {
  646. if (memcmp (&pRfInfo[j],pNewFilter,sizeof (*pNewFilter))==0)
  647. {
  648. return ERROR_ALREADY_EXISTS;
  649. }
  650. }
  651. newBlockSize += sizeof (*pNewFilter);
  652. newCount += 1;
  653. }
  654. if (ARGUMENT_PRESENT (pOldFilter))
  655. {
  656. for (j=0; j<count; j++)
  657. {
  658. if (memcmp (&pRfInfo[j],pOldFilter,sizeof (*pOldFilter))==0)
  659. {
  660. break;
  661. }
  662. }
  663. if (j>=count)
  664. {
  665. return ERROR_FILE_NOT_FOUND;
  666. }
  667. newBlockSize -= sizeof (*pNewFilter);
  668. newCount -= 1;
  669. }
  670. else
  671. {
  672. j = count;
  673. }
  674. }
  675. newBlockSize += sizeof (IPX_TOC_ENTRY)+pTocEntry->InfoSize*pTocEntry->Count;
  676. }
  677. if (!found)
  678. {
  679. return ERROR_FILE_NOT_FOUND;
  680. }
  681. if ( (newBlockSize>pOldBlock->Size) ||
  682. !ARGUMENT_PRESENT (pOldFilter))
  683. {
  684. pBlock = (PIPX_INFO_BLOCK_HEADER)GlobalAlloc (GPTR, newBlockSize);
  685. if (pBlock==NULL)
  686. {
  687. return ERROR_NOT_ENOUGH_MEMORY;
  688. }
  689. pBlock->Version = IPX_ROUTER_VERSION_1;
  690. pBlock->TocEntriesCount = pOldBlock->TocEntriesCount;
  691. dstToc = pBlock->TocEntry;
  692. }
  693. else
  694. {
  695. pBlock = pOldBlock;
  696. }
  697. dstOffset = FIELD_OFFSET(
  698. IPX_INFO_BLOCK_HEADER, TocEntry[pBlock->TocEntriesCount]
  699. );
  700. for (i=0, pTocEntry = pOldBlock->TocEntry;
  701. i<pOldBlock->TocEntriesCount;
  702. i++, pTocEntry++, dstToc++)
  703. {
  704. if (pTocEntry->InfoType == IPX_PROTOCOL_RIP)
  705. {
  706. ULONG curOffset =
  707. FIELD_OFFSET (RIP_IF_CONFIG, RipIfFilters.RouteFilter);
  708. if (pBlock!=pOldBlock)
  709. {
  710. memcpy ((LPBYTE)pBlock+dstOffset,
  711. pRipCfg,
  712. curOffset);
  713. }
  714. else if (dstOffset!=pTocEntry->Offset)
  715. {
  716. ASSERT (dstOffset<pTocEntry->Offset);
  717. memmove ((LPBYTE)pBlock+dstOffset,
  718. pRipCfg,
  719. curOffset);
  720. }
  721. if (Output)
  722. {
  723. if (j>0)
  724. {
  725. if (pBlock!=pOldBlock)
  726. {
  727. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  728. pRfInfo, j*sizeof (pRfInfo[0]));
  729. }
  730. else if (dstOffset!=pTocEntry->Offset)
  731. {
  732. ASSERT (dstOffset<pTocEntry->Offset);
  733. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  734. pRfInfo, j*sizeof (pRfInfo[0]));
  735. }
  736. curOffset += j*sizeof (pRfInfo[0]);
  737. }
  738. if (ARGUMENT_PRESENT (pNewFilter))
  739. {
  740. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  741. pNewFilter,
  742. sizeof (*pNewFilter));
  743. curOffset += sizeof (*pNewFilter);
  744. }
  745. if (ARGUMENT_PRESENT (pOldFilter))
  746. {
  747. j += 1;
  748. }
  749. if (j<count)
  750. {
  751. if (pBlock!=pOldBlock)
  752. {
  753. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  754. &pRfInfo[j], (count-j)*sizeof (pRfInfo[0]));
  755. }
  756. else if ( (dstOffset!=pTocEntry->Offset) ||
  757. !ARGUMENT_PRESENT (pNewFilter))
  758. {
  759. ASSERT (dstOffset<= pTocEntry->Offset);
  760. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  761. &pRfInfo[j], (count-j)*sizeof (pRfInfo[0]));
  762. }
  763. curOffset += (count-j)*sizeof (pRfInfo[0]);
  764. }
  765. if (pBlock!=pOldBlock)
  766. {
  767. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  768. &pRipCfg->RipIfFilters.RouteFilter[supplyCount],
  769. listenCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0]));
  770. }
  771. else if ( (dstOffset!=pTocEntry->Offset) ||
  772. !ARGUMENT_PRESENT (pNewFilter))
  773. {
  774. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  775. &pRipCfg->RipIfFilters.RouteFilter[supplyCount],
  776. listenCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0]));
  777. }
  778. curOffset += listenCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0]);
  779. ((PRIP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->RipIfFilters.SupplyFilterCount = newCount;
  780. if ((newCount==1) && (count==0))
  781. {
  782. ((PRIP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->RipIfFilters.SupplyFilterAction = IPX_ROUTE_FILTER_DENY;
  783. }
  784. }
  785. else
  786. {
  787. if (pBlock!=pOldBlock)
  788. {
  789. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  790. &pRipCfg->RipIfFilters.RouteFilter[0],
  791. supplyCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0]));
  792. }
  793. else if (dstOffset!=pTocEntry->Offset)
  794. {
  795. ASSERT (dstOffset<pTocEntry->Offset);
  796. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  797. &pRipCfg->RipIfFilters.RouteFilter[0],
  798. supplyCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0]));
  799. }
  800. curOffset += supplyCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0]);
  801. if (j>0)
  802. {
  803. if (pBlock!=pOldBlock)
  804. {
  805. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  806. pRfInfo, j*sizeof (pRfInfo[0]));
  807. }
  808. else if (dstOffset!=pTocEntry->Offset)
  809. {
  810. ASSERT (dstOffset<pTocEntry->Offset);
  811. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  812. pRfInfo, j*sizeof (pRfInfo[0]));
  813. }
  814. curOffset += j*sizeof (pRfInfo[0]);
  815. }
  816. if (ARGUMENT_PRESENT (pNewFilter))
  817. {
  818. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  819. pNewFilter,
  820. sizeof (*pNewFilter));
  821. curOffset += sizeof (*pNewFilter);
  822. }
  823. if (ARGUMENT_PRESENT (pOldFilter))
  824. {
  825. j += 1;
  826. }
  827. if (j<count)
  828. {
  829. if (pBlock!=pOldBlock)
  830. {
  831. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  832. &pRfInfo[j], (count-j)*sizeof (pRfInfo[0]));
  833. }
  834. else if ( (dstOffset!=pTocEntry->Offset) ||
  835. !ARGUMENT_PRESENT (pNewFilter))
  836. {
  837. ASSERT (dstOffset<=pTocEntry->Offset);
  838. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  839. &pRfInfo[j], (count-j)*sizeof (pRfInfo[0]));
  840. }
  841. curOffset += (count-j)*sizeof (pRfInfo[0]);
  842. }
  843. ((PRIP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->RipIfFilters.ListenFilterCount = newCount;
  844. if ((newCount==1) && (count==0))
  845. {
  846. ((PRIP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->RipIfFilters.ListenFilterAction = IPX_ROUTE_FILTER_DENY;
  847. }
  848. }
  849. if (pBlock!=pOldBlock)
  850. {
  851. *dstToc = *pTocEntry;
  852. dstToc->Offset = dstOffset;
  853. dstToc->InfoSize = curOffset;
  854. }
  855. else
  856. {
  857. pTocEntry->Offset = dstOffset;
  858. pTocEntry->InfoSize = curOffset;
  859. }
  860. dstOffset += curOffset;
  861. }
  862. else
  863. {
  864. if (pBlock!=pOldBlock)
  865. {
  866. memcpy ((PUCHAR)pBlock+dstOffset,
  867. (PUCHAR)pOldBlock+pTocEntry->Offset,
  868. pTocEntry->InfoSize*pTocEntry->Count);
  869. *dstToc = *pTocEntry;
  870. dstToc->Offset = dstOffset;
  871. }
  872. else if (dstOffset!=pTocEntry->Offset)
  873. {
  874. ASSERT (dstOffset<pTocEntry->Offset);
  875. memmove ((PUCHAR)pBlock+dstOffset,
  876. (PUCHAR)pOldBlock+pTocEntry->Offset,
  877. pTocEntry->InfoSize*pTocEntry->Count);
  878. pTocEntry->Offset = dstOffset;
  879. }
  880. dstOffset += pTocEntry->InfoSize*pTocEntry->Count;
  881. }
  882. }
  883. pBlock->Size = newBlockSize;
  884. *pNewBlock = pBlock;
  885. return NO_ERROR;
  886. }
  887. DWORD
  888. UpdateSapFilter (
  889. IN PIPX_INFO_BLOCK_HEADER pOldBlock,
  890. IN BOOLEAN Output,
  891. IN PSAP_SERVICE_FILTER_INFO pOldFilter OPTIONAL,
  892. IN PSAP_SERVICE_FILTER_INFO pNewFilter OPTIONAL,
  893. OUT PIPX_INFO_BLOCK_HEADER *pNewBlock
  894. )
  895. {
  896. ULONG i,j;
  897. PIPX_TOC_ENTRY pTocEntry, dstToc;
  898. PIPX_INFO_BLOCK_HEADER pBlock;
  899. ULONG newBlockSize = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER, TocEntry);
  900. BOOLEAN found = FALSE;
  901. PSAP_SERVICE_FILTER_INFO pSfInfo;
  902. ULONG supplyCount, listenCount, count, newCount;
  903. PSAP_IF_CONFIG pSapCfg;
  904. ULONG dstOffset;
  905. if (pOldBlock == NULL)
  906. {
  907. return ERROR_INVALID_PARAMETER;
  908. }
  909. ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
  910. for ( i=0, pTocEntry = pOldBlock->TocEntry;
  911. i<pOldBlock->TocEntriesCount;
  912. i++, pTocEntry++)
  913. {
  914. if (pTocEntry->InfoType == IPX_PROTOCOL_SAP)
  915. {
  916. found = TRUE;
  917. pSapCfg = (PSAP_IF_CONFIG)((LPBYTE)pOldBlock+pTocEntry->Offset);
  918. supplyCount = pSapCfg->SapIfFilters.SupplyFilterCount;
  919. listenCount = pSapCfg->SapIfFilters.ListenFilterCount;
  920. if (Output)
  921. {
  922. pSfInfo = &pSapCfg->SapIfFilters.ServiceFilter[0];
  923. count = supplyCount;
  924. }
  925. else
  926. {
  927. pSfInfo = &pSapCfg->SapIfFilters.ServiceFilter[
  928. pSapCfg->SapIfFilters.SupplyFilterCount];
  929. count = listenCount;
  930. }
  931. newCount = count;
  932. if (ARGUMENT_PRESENT (pNewFilter))
  933. {
  934. for (j=0; j<count; j++)
  935. {
  936. if ((pSfInfo[j].ServiceType==pNewFilter->ServiceType)
  937. && (strncmp ((LPSTR)pSfInfo[j].ServiceName,
  938. (LPSTR)pNewFilter->ServiceName,
  939. sizeof (pNewFilter->ServiceName))==0))
  940. break;
  941. }
  942. if (j<count)
  943. {
  944. return ERROR_CAN_NOT_COMPLETE;
  945. }
  946. newBlockSize += sizeof (*pNewFilter);
  947. newCount += 1;
  948. }
  949. if (ARGUMENT_PRESENT (pOldFilter))
  950. {
  951. for (j=0; j<count; j++)
  952. {
  953. if ((pSfInfo[j].ServiceType==pOldFilter->ServiceType)
  954. && (strncmp ((LPSTR)pSfInfo[j].ServiceName,
  955. (LPSTR)pOldFilter->ServiceName,
  956. sizeof (pOldFilter->ServiceName))==0))
  957. break;
  958. }
  959. if (j>=count)
  960. {
  961. return ERROR_CAN_NOT_COMPLETE;
  962. }
  963. newBlockSize -= sizeof (*pNewFilter);
  964. newCount -= 1;
  965. }
  966. else
  967. {
  968. j = count;
  969. }
  970. }
  971. newBlockSize += sizeof (IPX_TOC_ENTRY)+pTocEntry->InfoSize*pTocEntry->Count;
  972. }
  973. if (!found)
  974. {
  975. return ERROR_CAN_NOT_COMPLETE;
  976. }
  977. if ((newBlockSize>pOldBlock->Size) || !ARGUMENT_PRESENT (pOldFilter))
  978. {
  979. pBlock = (PIPX_INFO_BLOCK_HEADER)GlobalAlloc (GPTR, newBlockSize);
  980. if (pBlock==NULL)
  981. {
  982. return ERROR_NOT_ENOUGH_MEMORY;
  983. }
  984. pBlock->Version = IPX_ROUTER_VERSION_1;
  985. pBlock->TocEntriesCount = pOldBlock->TocEntriesCount;
  986. dstToc = pBlock->TocEntry;
  987. }
  988. else
  989. {
  990. pBlock = pOldBlock;
  991. }
  992. dstOffset = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER, TocEntry[pBlock->TocEntriesCount]);
  993. for ( i=0, pTocEntry = pOldBlock->TocEntry;
  994. i < pOldBlock->TocEntriesCount;
  995. i++, pTocEntry++, dstToc++)
  996. {
  997. if (pTocEntry->InfoType == IPX_PROTOCOL_SAP)
  998. {
  999. ULONG curOffset = FIELD_OFFSET (SAP_IF_CONFIG, SapIfFilters.ServiceFilter);
  1000. if (pBlock!=pOldBlock)
  1001. {
  1002. memcpy ((LPBYTE)pBlock+dstOffset,
  1003. pSapCfg,
  1004. curOffset);
  1005. }
  1006. else if (dstOffset!=pTocEntry->Offset)
  1007. {
  1008. ASSERT (dstOffset<pTocEntry->Offset);
  1009. memmove ((LPBYTE)pBlock+dstOffset,
  1010. pSapCfg,
  1011. curOffset);
  1012. }
  1013. if (Output)
  1014. {
  1015. if (j>0)
  1016. {
  1017. if (pBlock!=pOldBlock)
  1018. {
  1019. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  1020. pSfInfo, j*sizeof (pSfInfo[0]));
  1021. }
  1022. else if (dstOffset!=pTocEntry->Offset)
  1023. {
  1024. ASSERT (dstOffset<pTocEntry->Offset);
  1025. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  1026. pSfInfo, j*sizeof (pSfInfo[0]));
  1027. }
  1028. curOffset += j*sizeof (pSfInfo[0]);
  1029. }
  1030. if (ARGUMENT_PRESENT (pNewFilter))
  1031. {
  1032. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  1033. pNewFilter,
  1034. sizeof (*pNewFilter));
  1035. curOffset += sizeof (*pNewFilter);
  1036. }
  1037. if (ARGUMENT_PRESENT (pOldFilter))
  1038. {
  1039. j += 1;
  1040. }
  1041. if (j<count)
  1042. {
  1043. if (pBlock!=pOldBlock)
  1044. {
  1045. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  1046. &pSfInfo[j], (count-j)*sizeof (pSfInfo[0]));
  1047. }
  1048. else if ((dstOffset!=pTocEntry->Offset) || !ARGUMENT_PRESENT (pNewFilter))
  1049. {
  1050. ASSERT (dstOffset<=pTocEntry->Offset);
  1051. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  1052. &pSfInfo[j], (count-j)*sizeof (pSfInfo[0]));
  1053. }
  1054. curOffset += (count-j)*sizeof (pSfInfo[0]);
  1055. }
  1056. if (pBlock!=pOldBlock)
  1057. {
  1058. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  1059. &pSapCfg->SapIfFilters.ServiceFilter[supplyCount],
  1060. listenCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0]));
  1061. }
  1062. else if ((dstOffset!=pTocEntry->Offset) || !ARGUMENT_PRESENT (pNewFilter))
  1063. {
  1064. ASSERT (dstOffset<=pTocEntry->Offset);
  1065. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  1066. &pSapCfg->SapIfFilters.ServiceFilter[supplyCount],
  1067. listenCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0]));
  1068. }
  1069. curOffset += listenCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0]);
  1070. ((PSAP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->SapIfFilters.SupplyFilterCount = newCount;
  1071. if ((newCount==1) && (count==0))
  1072. {
  1073. ((PSAP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->SapIfFilters.SupplyFilterAction = IPX_SERVICE_FILTER_DENY;
  1074. }
  1075. }
  1076. else
  1077. {
  1078. if (pBlock!=pOldBlock)
  1079. {
  1080. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  1081. &pSapCfg->SapIfFilters.ServiceFilter[0],
  1082. supplyCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0]));
  1083. }
  1084. else if (dstOffset!=pTocEntry->Offset)
  1085. {
  1086. ASSERT (dstOffset<pTocEntry->Offset);
  1087. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  1088. &pSapCfg->SapIfFilters.ServiceFilter[0],
  1089. supplyCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0]));
  1090. }
  1091. curOffset += supplyCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0]);
  1092. if (j>0)
  1093. {
  1094. if (pBlock!=pOldBlock)
  1095. {
  1096. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  1097. pSfInfo, j*sizeof (pSfInfo[0]));
  1098. }
  1099. else if (dstOffset!=pTocEntry->Offset)
  1100. {
  1101. ASSERT (dstOffset<pTocEntry->Offset);
  1102. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  1103. pSfInfo, j*sizeof (pSfInfo[0]));
  1104. }
  1105. curOffset += j*sizeof (pSfInfo[0]);
  1106. }
  1107. if (ARGUMENT_PRESENT (pNewFilter))
  1108. {
  1109. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  1110. pNewFilter,
  1111. sizeof (*pNewFilter));
  1112. curOffset += sizeof (*pNewFilter);
  1113. }
  1114. if (ARGUMENT_PRESENT (pOldFilter))
  1115. {
  1116. j += 1;
  1117. }
  1118. if (j<count)
  1119. {
  1120. if (pBlock!=pOldBlock)
  1121. {
  1122. memcpy ((LPBYTE)pBlock+dstOffset+curOffset,
  1123. &pSfInfo[j], (count-j)*sizeof (pSfInfo[0]));
  1124. }
  1125. else if ( (dstOffset!=pTocEntry->Offset) ||
  1126. !ARGUMENT_PRESENT (pNewFilter))
  1127. {
  1128. ASSERT (dstOffset<=pTocEntry->Offset);
  1129. memmove ((LPBYTE)pBlock+dstOffset+curOffset,
  1130. &pSfInfo[j], (count-j)*sizeof (pSfInfo[0]));
  1131. }
  1132. curOffset += (count-j)*sizeof (pSfInfo[0]);
  1133. }
  1134. ((PSAP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->SapIfFilters.ListenFilterCount = newCount;
  1135. if ((newCount==1) && (count==0))
  1136. {
  1137. ((PSAP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->SapIfFilters.ListenFilterAction = IPX_SERVICE_FILTER_DENY;
  1138. }
  1139. }
  1140. if (pBlock!=pOldBlock)
  1141. {
  1142. *dstToc = *pTocEntry;
  1143. dstToc->Offset = dstOffset;
  1144. dstToc->InfoSize = curOffset;
  1145. }
  1146. else
  1147. {
  1148. pTocEntry->Offset = dstOffset;
  1149. pTocEntry->InfoSize = curOffset;
  1150. }
  1151. dstOffset += curOffset;
  1152. }
  1153. else
  1154. {
  1155. if (pBlock!=pOldBlock)
  1156. {
  1157. memcpy ((PUCHAR)pBlock+dstOffset,
  1158. (PUCHAR)pOldBlock+pTocEntry->Offset,
  1159. pTocEntry->InfoSize*pTocEntry->Count);
  1160. *dstToc = *pTocEntry;
  1161. dstToc->Offset = dstOffset;
  1162. }
  1163. else if (dstOffset!=pTocEntry->Offset)
  1164. {
  1165. ASSERT (dstOffset<pTocEntry->Offset);
  1166. memmove ((PUCHAR)pBlock+dstOffset,
  1167. (PUCHAR)pOldBlock+pTocEntry->Offset,
  1168. pTocEntry->InfoSize*pTocEntry->Count);
  1169. pTocEntry->Offset = dstOffset;
  1170. }
  1171. dstOffset += pTocEntry->InfoSize*pTocEntry->Count;
  1172. }
  1173. }
  1174. pBlock->Size = newBlockSize;
  1175. *pNewBlock = pBlock;
  1176. return NO_ERROR;
  1177. }