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.

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