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.

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