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.

758 lines
21 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: etcmap.c
  7. //
  8. // Description: This module contains support routines for the extension/
  9. // type/creator mappings category API's for the AFP server
  10. // service. These routines are called directly by the RPC
  11. // runtime.
  12. //
  13. // History:
  14. // June 11,1992. NarenG Created original version.
  15. //
  16. #include "afpsvcp.h"
  17. //**
  18. //
  19. // Call: AfpAdminrETCMapGetInfo
  20. //
  21. // Returns: NO_ERROR
  22. // ERROR_ACCESS_DENIED
  23. // ERROR_NOT_ENOUGH_MEMORY
  24. //
  25. // Description: Will alllocate enough memory to contain all mappings, copy
  26. // the information and return.
  27. //
  28. DWORD
  29. AfpAdminrETCMapGetInfo(
  30. IN AFP_SERVER_HANDLE hServer,
  31. OUT PAFP_ETCMAP_INFO *ppAfpETCMapInfo
  32. )
  33. {
  34. DWORD dwRetCode=0;
  35. DWORD dwAccessStatus=0;
  36. // Check if caller has access
  37. //
  38. if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
  39. {
  40. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapGetInfo, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
  41. AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
  42. dwRetCode, EVENTLOG_ERROR_TYPE );
  43. return( ERROR_ACCESS_DENIED );
  44. }
  45. if ( dwAccessStatus )
  46. {
  47. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapGetInfo, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
  48. return( ERROR_ACCESS_DENIED );
  49. }
  50. // MUTEX start
  51. //
  52. WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
  53. // This loop is used to allow break's instead of goto's to be used
  54. // on an error condition.
  55. //
  56. do {
  57. dwRetCode = NO_ERROR;
  58. // Allocate memory and copy ETC mappings information
  59. //
  60. *ppAfpETCMapInfo = MIDL_user_allocate( sizeof(AFP_ETCMAP_INFO) );
  61. if ( *ppAfpETCMapInfo == NULL ) {
  62. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  63. break;
  64. }
  65. (*ppAfpETCMapInfo)->afpetc_num_type_creators =
  66. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
  67. (*ppAfpETCMapInfo)->afpetc_type_creator = MIDL_user_allocate(
  68. sizeof(AFP_TYPE_CREATOR)
  69. *AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators);
  70. if ( (*ppAfpETCMapInfo)->afpetc_type_creator == NULL ) {
  71. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  72. break;
  73. }
  74. (*ppAfpETCMapInfo)->afpetc_num_extensions =
  75. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions;
  76. (*ppAfpETCMapInfo)->afpetc_extension = MIDL_user_allocate(
  77. sizeof(AFP_EXTENSION)
  78. *AfpGlobals.AfpETCMapInfo.afpetc_num_extensions);
  79. if ( (*ppAfpETCMapInfo)->afpetc_extension == NULL ) {
  80. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  81. break;
  82. }
  83. CopyMemory( (LPBYTE)(*ppAfpETCMapInfo)->afpetc_type_creator,
  84. (LPBYTE)(AfpGlobals.AfpETCMapInfo.afpetc_type_creator),
  85. sizeof(AFP_TYPE_CREATOR)
  86. * AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators);
  87. CopyMemory( (LPBYTE)(*ppAfpETCMapInfo)->afpetc_extension,
  88. (LPBYTE)(AfpGlobals.AfpETCMapInfo.afpetc_extension),
  89. sizeof(AFP_EXTENSION)
  90. * AfpGlobals.AfpETCMapInfo.afpetc_num_extensions);
  91. } while( FALSE );
  92. // MUTEX end
  93. //
  94. ReleaseMutex( AfpGlobals.hmutexETCMap );
  95. if ( dwRetCode ) {
  96. if ( *ppAfpETCMapInfo != NULL ) {
  97. if ( (*ppAfpETCMapInfo)->afpetc_type_creator != NULL )
  98. MIDL_user_free( (*ppAfpETCMapInfo)->afpetc_type_creator );
  99. MIDL_user_free( *ppAfpETCMapInfo );
  100. }
  101. }
  102. return( dwRetCode );
  103. }
  104. //**
  105. //
  106. // Call: AfpAdminrETCMapAdd
  107. //
  108. // Returns: NO_ERROR
  109. // ERROR_ACCESS_DENIED
  110. // AFPERR_DuplicateTypeCreator;
  111. // non-zero returns from the registry API's
  112. //
  113. // Description: This routine will add a type/creator/comment tupple to the
  114. // registry and the cache.
  115. //
  116. DWORD
  117. AfpAdminrETCMapAdd(
  118. IN AFP_SERVER_HANDLE hServer,
  119. IN PAFP_TYPE_CREATOR pAfpTypeCreator
  120. )
  121. {
  122. DWORD dwRetCode=0;
  123. DWORD dwAccessStatus=0;
  124. PAFP_TYPE_CREATOR pTypeCreator;
  125. DWORD dwNumTypeCreators;
  126. // Check if caller has access
  127. //
  128. if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
  129. {
  130. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapAdd, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
  131. AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
  132. dwRetCode, EVENTLOG_ERROR_TYPE );
  133. return( ERROR_ACCESS_DENIED );
  134. }
  135. if ( dwAccessStatus )
  136. {
  137. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapAdd, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
  138. return( ERROR_ACCESS_DENIED );
  139. }
  140. // MUTEX start
  141. //
  142. WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
  143. // This loop is used to allow break's instead of goto's to be used
  144. // on an error condition.
  145. //
  146. do {
  147. dwRetCode = NO_ERROR;
  148. // First check to see if the type already exists.
  149. //
  150. pTypeCreator = AfpBinarySearch(
  151. pAfpTypeCreator,
  152. AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
  153. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
  154. sizeof(AFP_TYPE_CREATOR),
  155. AfpBCompareTypeCreator );
  156. // It exists so return error
  157. //
  158. if ( pTypeCreator != NULL ) {
  159. dwRetCode = (DWORD)AFPERR_DuplicateTypeCreator;
  160. break;
  161. }
  162. // Set the ID for this type/creator
  163. //
  164. pAfpTypeCreator->afptc_id = ++AfpGlobals.dwCurrentTCId;
  165. // It does not exist so add it to the registry and the cache.
  166. //
  167. if ( dwRetCode = AfpRegTypeCreatorAdd( pAfpTypeCreator ) )
  168. break;
  169. // Grow the cache size by one entry.
  170. //
  171. pTypeCreator = AfpGlobals.AfpETCMapInfo.afpetc_type_creator;
  172. dwNumTypeCreators = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
  173. pTypeCreator = (PAFP_TYPE_CREATOR)LocalReAlloc(
  174. pTypeCreator,
  175. (dwNumTypeCreators+1)*sizeof(AFP_TYPE_CREATOR),
  176. LMEM_MOVEABLE );
  177. if ( pTypeCreator == NULL ) {
  178. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  179. break;
  180. }
  181. pTypeCreator[dwNumTypeCreators++] = *pAfpTypeCreator;
  182. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators = dwNumTypeCreators;
  183. AfpGlobals.AfpETCMapInfo.afpetc_type_creator = pTypeCreator;
  184. // Sort the table
  185. //
  186. qsort( pTypeCreator,
  187. dwNumTypeCreators,
  188. sizeof(AFP_TYPE_CREATOR),
  189. AfpBCompareTypeCreator );
  190. } while( FALSE );
  191. // MUTEX end
  192. //
  193. ReleaseMutex( AfpGlobals.hmutexETCMap );
  194. return( dwRetCode );
  195. }
  196. //**
  197. //
  198. // Call: AfpAdminrETCMapDelete
  199. //
  200. // Returns: NO_ERROR
  201. // ERROR_ACCESS_DENIED
  202. // AFPERR_TypeCreatorNotExistant
  203. // non-zero returns from registry api's.
  204. // non-zero returns from the FSD.
  205. //
  206. //
  207. // Description: This routine will delete a type/creator tupple from the
  208. // registry and the cache. If there are any extensions that map
  209. // to this tupple, they are deleted.
  210. // Shrinking by reallocating is not done. This will be done the
  211. // next time an extension is added or if the server is restarted.
  212. //
  213. DWORD
  214. AfpAdminrETCMapDelete(
  215. IN AFP_SERVER_HANDLE hServer,
  216. IN PAFP_TYPE_CREATOR pAfpTypeCreator
  217. )
  218. {
  219. AFP_REQUEST_PACKET AfpSrp;
  220. DWORD dwRetCode=0;
  221. DWORD dwAccessStatus=0;
  222. PAFP_TYPE_CREATOR pTypeCreator;
  223. AFP_EXTENSION AfpExtensionKey;
  224. PAFP_EXTENSION pExtension;
  225. PAFP_EXTENSION pExtensionWalker;
  226. DWORD cbSize;
  227. DWORD dwIndex;
  228. ETCMAPINFO2 ETCMapFSDBuf;
  229. DWORD dwCount;
  230. // Check if caller has access
  231. //
  232. if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
  233. {
  234. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapDelete, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
  235. AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
  236. dwRetCode, EVENTLOG_ERROR_TYPE );
  237. return( ERROR_ACCESS_DENIED );
  238. }
  239. if ( dwAccessStatus )
  240. {
  241. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapDelete, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
  242. return( ERROR_ACCESS_DENIED );
  243. }
  244. // MUTEX start
  245. //
  246. WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
  247. // This loop is used to allow break's instead of goto's to be used
  248. // on an error condition.
  249. //
  250. do {
  251. dwRetCode = NO_ERROR;
  252. // First check to see if the type/creator exists.
  253. //
  254. pTypeCreator = AfpBinarySearch(
  255. pAfpTypeCreator,
  256. AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
  257. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
  258. sizeof(AFP_TYPE_CREATOR),
  259. AfpBCompareTypeCreator );
  260. // It does not exist so return error
  261. //
  262. if ( pTypeCreator == NULL ) {
  263. dwRetCode = (DWORD)AFPERR_TypeCreatorNotExistant;
  264. break;
  265. }
  266. // If this is the default type/creator
  267. //
  268. if ( pTypeCreator->afptc_id == AFP_DEF_TCID ) {
  269. dwRetCode = (DWORD)AFPERR_CannotDeleteDefaultTC;
  270. break;
  271. }
  272. // Store the id of this type/creator. All extensions with this
  273. // id will have to be deleted.
  274. //
  275. AfpExtensionKey.afpe_tcid = pTypeCreator->afptc_id;
  276. // Walk the list of extensions and delete all entries with
  277. // the corresponding type/creator ID
  278. //
  279. pExtension = AfpBinarySearch(
  280. &AfpExtensionKey,
  281. AfpGlobals.AfpETCMapInfo.afpetc_extension,
  282. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions,
  283. sizeof(AFP_EXTENSION),
  284. AfpBCompareExtension );
  285. if ( pExtension != NULL ) {
  286. for ( dwIndex = (DWORD)(((ULONG_PTR)pExtension -
  287. (ULONG_PTR)(AfpGlobals.AfpETCMapInfo.afpetc_extension)) / sizeof(AFP_EXTENSION)),
  288. pExtensionWalker = pExtension,
  289. dwCount = 0;
  290. ( dwIndex < AfpGlobals.AfpETCMapInfo.afpetc_num_extensions )
  291. &&
  292. ( pExtensionWalker->afpe_tcid == AfpExtensionKey.afpe_tcid );
  293. dwIndex++,
  294. dwCount++,
  295. pExtensionWalker++ )
  296. {
  297. // IOCTL the FSD to delete this tupple
  298. //
  299. AfpBufCopyFSDETCMapInfo( pAfpTypeCreator,
  300. pExtensionWalker,
  301. &ETCMapFSDBuf );
  302. AfpSrp.dwRequestCode = OP_SERVER_DELETE_ETC;
  303. AfpSrp.dwApiType = AFP_API_TYPE_DELETE;
  304. AfpSrp.Type.Delete.pInputBuf = &ETCMapFSDBuf;
  305. AfpSrp.Type.Delete.cbInputBufSize = sizeof(ETCMAPINFO2);
  306. if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
  307. {
  308. break;
  309. }
  310. // Delete this extension from the registry
  311. //
  312. if ( dwRetCode = AfpRegExtensionDelete( pExtensionWalker ))
  313. {
  314. break;
  315. }
  316. }
  317. if ( dwRetCode )
  318. break;
  319. // Remove the extensions from the cache
  320. //
  321. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions -= dwCount;
  322. // Remove these extensions from the cache too
  323. //
  324. cbSize = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions
  325. * sizeof(AFP_EXTENSION);
  326. cbSize -= (DWORD)((ULONG_PTR)pExtension -
  327. (ULONG_PTR)(AfpGlobals.AfpETCMapInfo.afpetc_extension));
  328. CopyMemory( (LPBYTE)pExtension, (LPBYTE)pExtensionWalker, cbSize );
  329. }
  330. // Delete the type/creator from the registry
  331. //
  332. if ( dwRetCode = AfpRegTypeCreatorDelete( pTypeCreator ) )
  333. break;
  334. // Delete the type/creator from the cache
  335. //
  336. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators--;
  337. cbSize = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators
  338. * sizeof(AFP_TYPE_CREATOR);
  339. cbSize -= (DWORD)((ULONG_PTR)pTypeCreator -
  340. (ULONG_PTR)AfpGlobals.AfpETCMapInfo.afpetc_type_creator);
  341. CopyMemory( (LPBYTE)pTypeCreator,
  342. (LPBYTE)((ULONG_PTR)pTypeCreator+sizeof(AFP_TYPE_CREATOR)),
  343. cbSize );
  344. } while( FALSE );
  345. // MUTEX end
  346. //
  347. ReleaseMutex( AfpGlobals.hmutexETCMap );
  348. return( dwRetCode );
  349. }
  350. //**
  351. //
  352. // Call: AfpAdminrETCMapSetInfo
  353. //
  354. // Returns: NO_ERROR
  355. // ERROR_ACCESS_DENIED
  356. // AFPERR_TypeCreatorNotExistant
  357. // AFPERR_CannotEditDefaultTC;
  358. // non-zero returns from registry api's.
  359. //
  360. // Description: This routine will simply change the comment for a type/creator
  361. // tupple.
  362. //
  363. DWORD
  364. AfpAdminrETCMapSetInfo(
  365. IN AFP_SERVER_HANDLE hServer,
  366. IN PAFP_TYPE_CREATOR pAfpTypeCreator
  367. )
  368. {
  369. DWORD dwRetCode=0;
  370. DWORD dwAccessStatus=0;
  371. PAFP_TYPE_CREATOR pTypeCreator;
  372. // Check if caller has access
  373. //
  374. if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
  375. {
  376. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapSetInfo, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
  377. AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
  378. dwRetCode, EVENTLOG_ERROR_TYPE );
  379. return( ERROR_ACCESS_DENIED );
  380. }
  381. if ( dwAccessStatus )
  382. {
  383. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapSetInfo, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
  384. return( ERROR_ACCESS_DENIED );
  385. }
  386. // MUTEX start
  387. //
  388. WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
  389. // This loop is used to allow break's instead of goto's to be used
  390. // on an error condition.
  391. //
  392. do {
  393. dwRetCode = NO_ERROR;
  394. // First check to see if the type/creator exists.
  395. //
  396. pTypeCreator = AfpBinarySearch(
  397. pAfpTypeCreator,
  398. AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
  399. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
  400. sizeof(AFP_TYPE_CREATOR),
  401. AfpBCompareTypeCreator );
  402. // It does not exist so return error
  403. //
  404. if ( pTypeCreator == NULL ) {
  405. dwRetCode = (DWORD)AFPERR_TypeCreatorNotExistant;
  406. break;
  407. }
  408. // If this is the default type/creator
  409. //
  410. if ( pTypeCreator->afptc_id == AFP_DEF_TCID ) {
  411. dwRetCode = (DWORD)AFPERR_CannotEditDefaultTC;
  412. break;
  413. }
  414. // Copy the id.
  415. //
  416. pAfpTypeCreator->afptc_id = pTypeCreator->afptc_id;
  417. // Set the comment in the registry
  418. //
  419. if ( dwRetCode = AfpRegTypeCreatorSetInfo( pAfpTypeCreator ) ) {
  420. break;
  421. }
  422. // Set the comment in the cache.
  423. //
  424. STRCPY( pTypeCreator->afptc_comment, pAfpTypeCreator->afptc_comment );
  425. } while( FALSE );
  426. // MUTEX end
  427. //
  428. ReleaseMutex( AfpGlobals.hmutexETCMap );
  429. return( dwRetCode );
  430. }
  431. //**
  432. //
  433. // Call: AfpAdminrETCMapAssociate
  434. //
  435. // Returns: NO_ERROR
  436. // ERROR_ACCESS_DENIED
  437. // AFPERR_TypeCreatorNotExistant
  438. // non-zero returns from registry api's.
  439. // non-zero returns from the FSD
  440. //
  441. //
  442. // Description: This routine will associate the given extension with the
  443. // specified type/creator if it exists. If the extension is
  444. // being mapped to the default type/creator, it will be
  445. // deleted.
  446. //
  447. DWORD
  448. AfpAdminrETCMapAssociate(
  449. IN AFP_SERVER_HANDLE hServer,
  450. IN PAFP_TYPE_CREATOR pAfpTypeCreator,
  451. IN PAFP_EXTENSION pAfpExtension
  452. )
  453. {
  454. AFP_REQUEST_PACKET AfpSrp;
  455. DWORD dwRetCode=0;
  456. DWORD dwAccessStatus=0;
  457. PAFP_TYPE_CREATOR pTypeCreator;
  458. PAFP_EXTENSION pExtension;
  459. SRVETCPKT SrvETCPkt;
  460. DWORD dwNumExtensions;
  461. DWORD cbSize;
  462. BYTE bETCMapFSDBuf[sizeof(ETCMAPINFO2)+sizeof(SETINFOREQPKT)];
  463. // Check if caller has access
  464. //
  465. if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
  466. {
  467. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapAssociate, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
  468. AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
  469. dwRetCode, EVENTLOG_ERROR_TYPE );
  470. return( ERROR_ACCESS_DENIED );
  471. }
  472. if ( dwAccessStatus )
  473. {
  474. AFP_PRINT(( "SFMSVC: AfpAdminrETCMapAssociate, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
  475. return( ERROR_ACCESS_DENIED );
  476. }
  477. // MUTEX start
  478. //
  479. WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
  480. // This loop is used to allow break's instead of goto's to be used
  481. // on an error condition.
  482. //
  483. do {
  484. dwRetCode = NO_ERROR;
  485. // First check to see if the type/creator pair that the
  486. // new extension is to be associated with, exists.
  487. //
  488. pTypeCreator = AfpBinarySearch(
  489. pAfpTypeCreator,
  490. AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
  491. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
  492. sizeof(AFP_TYPE_CREATOR),
  493. AfpBCompareTypeCreator );
  494. // It does not exist so return error
  495. //
  496. if ( pTypeCreator == NULL ) {
  497. dwRetCode = (DWORD)AFPERR_TypeCreatorNotExistant;
  498. break;
  499. }
  500. // Now check to see if the extension is already associated with
  501. // a type/creator pair.
  502. //
  503. dwNumExtensions = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions;
  504. pExtension = _lfind( pAfpExtension,
  505. AfpGlobals.AfpETCMapInfo.afpetc_extension,
  506. (unsigned int *)&dwNumExtensions,
  507. sizeof(AFP_EXTENSION),
  508. AfpLCompareExtension );
  509. // Not currently associated so we need to add an entry
  510. //
  511. if ( pExtension == NULL ) {
  512. // If this extension is being associated with the default
  513. // then simply return.
  514. //
  515. if ( pTypeCreator->afptc_id == AFP_DEF_TCID ) {
  516. dwRetCode = NO_ERROR;
  517. break;
  518. }
  519. // Add mapping to FSD
  520. //
  521. AfpBufCopyFSDETCMapInfo( pAfpTypeCreator,
  522. pAfpExtension,
  523. &(SrvETCPkt.retc_EtcMaps[0]) );
  524. SrvETCPkt.retc_NumEtcMaps = 1;
  525. AfpSrp.dwRequestCode = OP_SERVER_ADD_ETC;
  526. AfpSrp.dwApiType = AFP_API_TYPE_ADD;
  527. AfpSrp.Type.Add.pInputBuf = &SrvETCPkt;
  528. AfpSrp.Type.Add.cbInputBufSize = sizeof(SRVETCPKT);
  529. if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
  530. break;
  531. // Add extension to registry.
  532. //
  533. pAfpExtension->afpe_tcid = pTypeCreator->afptc_id;
  534. if ( dwRetCode = AfpRegExtensionSetInfo( pAfpExtension ) ) {
  535. break;
  536. }
  537. // Add extension to cache.
  538. //
  539. pExtension = AfpGlobals.AfpETCMapInfo.afpetc_extension;
  540. dwNumExtensions = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions;
  541. pExtension = (PAFP_EXTENSION)LocalReAlloc(
  542. pExtension,
  543. (dwNumExtensions+1)*sizeof(AFP_EXTENSION),
  544. LMEM_MOVEABLE );
  545. if ( pExtension == NULL ) {
  546. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  547. break;
  548. }
  549. pExtension[dwNumExtensions++] = *pAfpExtension;
  550. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions = dwNumExtensions;
  551. AfpGlobals.AfpETCMapInfo.afpetc_extension = pExtension;
  552. }
  553. // Extension is already mapped.
  554. //
  555. else {
  556. // If this extension is being associated with the default
  557. // then delete this extension from the registry and cache and
  558. // delete the mapping from the FSD
  559. //
  560. if ( pTypeCreator->afptc_id == AFP_DEF_TCID ) {
  561. // IOCTL the FSD to delete this tupple
  562. //
  563. AfpBufCopyFSDETCMapInfo( pAfpTypeCreator,
  564. pAfpExtension,
  565. (PETCMAPINFO2)bETCMapFSDBuf );
  566. AfpSrp.dwRequestCode = OP_SERVER_DELETE_ETC;
  567. AfpSrp.dwApiType = AFP_API_TYPE_DELETE;
  568. AfpSrp.Type.Delete.pInputBuf = bETCMapFSDBuf;
  569. AfpSrp.Type.Delete.cbInputBufSize = sizeof(ETCMAPINFO2);
  570. if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
  571. break;
  572. // Delete this extension from the registry
  573. //
  574. if ( dwRetCode = AfpRegExtensionDelete( pAfpExtension ) ) {
  575. break;
  576. }
  577. // Remove this extensions from the cache too
  578. //
  579. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions--;
  580. cbSize = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions
  581. * sizeof(AFP_EXTENSION);
  582. cbSize -= (DWORD)((ULONG_PTR)pExtension -
  583. (ULONG_PTR)(AfpGlobals.AfpETCMapInfo.afpetc_extension));
  584. CopyMemory( (LPBYTE)pExtension,
  585. (LPBYTE)((ULONG_PTR)pExtension+sizeof(AFP_EXTENSION)),
  586. cbSize );
  587. }
  588. else {
  589. // Otherwise simply change the mapping in the FSD
  590. //
  591. pExtension->afpe_tcid = pTypeCreator->afptc_id;
  592. AfpBufCopyFSDETCMapInfo(pTypeCreator,
  593. pExtension,
  594. (PETCMAPINFO2)(bETCMapFSDBuf+sizeof(SETINFOREQPKT)));
  595. AfpSrp.dwRequestCode = OP_SERVER_SET_ETC;
  596. AfpSrp.dwApiType = AFP_API_TYPE_SETINFO;
  597. AfpSrp.Type.SetInfo.pInputBuf = bETCMapFSDBuf;
  598. AfpSrp.Type.SetInfo.cbInputBufSize = sizeof(bETCMapFSDBuf);
  599. if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
  600. break;
  601. // Change the registry
  602. //
  603. if ( dwRetCode = AfpRegExtensionSetInfo( pExtension ) ) {
  604. break;
  605. }
  606. }
  607. }
  608. // Sort the table
  609. //
  610. qsort( AfpGlobals.AfpETCMapInfo.afpetc_extension,
  611. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions,
  612. sizeof(AFP_EXTENSION),
  613. AfpBCompareExtension );
  614. } while( FALSE );
  615. // MUTEX end
  616. //
  617. ReleaseMutex( AfpGlobals.hmutexETCMap );
  618. return( dwRetCode );
  619. }