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.

257 lines
4.0 KiB

  1. /*++
  2. CLEANUP.C
  3. CleanupOptionData code.
  4. Created, 6/25/1997 when it was impossible to keep making myself believe
  5. that I could go without allocating any memory in the option parser.
  6. Now, if you care, you're supposed to call CleanupOptionData().
  7. --*/
  8. #include "private.h"
  9. /* OptionDealloc:
  10. same as free() right now. It should change if/when OptionAlloc
  11. changes */
  12. VOID
  13. OptionDealloc( IN PVOID pTarget ) {
  14. ASSERT( pTarget != NULL );
  15. free ( pTarget );
  16. }
  17. BOOL
  18. OptionAddToList( IN PVOID pQueue,
  19. IN PVOID pItem,
  20. IN DEALLOC_METHOD eDealloc) {
  21. PSAVENODE pNode;
  22. PSAVEQUEUE pList;
  23. if ( !pQueue ) {
  24. return TRUE; // vacuous
  25. } else {
  26. pList = (PSAVEQUEUE) pQueue;
  27. }
  28. if( OptionAlloc( NULL, &pNode, sizeof( SAVENODE ) ) ) {
  29. pNode->DataElement = pItem;
  30. pNode->DeallocMethod = eDealloc;
  31. pNode->next = NULL;
  32. if ( pList->FirstNode == NULL ) {
  33. ASSERT( pList->LastNode == NULL );
  34. pList->FirstNode = pNode;
  35. } else {
  36. pList->LastNode->next = pNode;
  37. }
  38. pList->LastNode = pNode;
  39. return TRUE;
  40. }
  41. return FALSE;
  42. }
  43. BOOL
  44. OptionResizeMemory( IN PVOID pSaveQueue,
  45. OUT PVOID *ppResizedMemory,
  46. IN ULONG newSize ) {
  47. ASSERT( ppResizedMemory != NULL );
  48. ASSERT( newSize > 0 );
  49. // ASSERT( *ppResizedMemory != NULL ); // unuseful assertion.
  50. if ( *ppResizedMemory ) {
  51. PSAVENODE pNode = NULL;
  52. PVOID pDataElement;
  53. pDataElement = *ppResizedMemory;
  54. if ( pSaveQueue ) {
  55. PSAVEQUEUE pQ;
  56. pQ = (PSAVEQUEUE) pSaveQueue;
  57. for ( pNode = pQ->FirstNode ;
  58. pNode != NULL;
  59. pNode = pNode->next ) {
  60. if ( pNode->DataElement == pDataElement ) {
  61. break;
  62. }
  63. }
  64. if ( !pNode ) {
  65. return FALSE;
  66. }
  67. }
  68. pDataElement = realloc( pDataElement, newSize ) ;
  69. if ( pDataElement == NULL ) {
  70. fprintf( stderr,
  71. "OptionResizeMemory failed to realloc for %d bytes.\n",
  72. newSize );
  73. // allocation failed.
  74. return FALSE;
  75. } else {
  76. *ppResizedMemory = pDataElement;
  77. if ( pNode ) {
  78. // must change this within the list as well.
  79. pNode->DataElement = pDataElement;
  80. }
  81. return TRUE;
  82. }
  83. } else {
  84. /* just like realloc, if you pass NULL, we'll just malloc the data
  85. anyway. This is just more convenient. */
  86. return OptionAlloc( pSaveQueue, ppResizedMemory, newSize );
  87. }
  88. }
  89. /* OptionAlloc:
  90. currently, malloc.
  91. if you change the method of allocation, you must also change
  92. OptionDealloc above */
  93. BOOL
  94. OptionAlloc( IN PSAVEQUEUE pQueue,
  95. OUT PVOID *pTarget,
  96. IN ULONG size ) {
  97. PVOID ret;
  98. ASSERT( pTarget != NULL );
  99. ASSERT( size > 0 );
  100. ret = malloc( size );
  101. if ( ret ) {
  102. memset( ret, 0, size );
  103. if ( OptionAddToList( pQueue, ret, DeallocWithOptionDealloc ) ) {
  104. *pTarget = ret;
  105. return TRUE;
  106. } else {
  107. free( ret );
  108. // fallthrough
  109. }
  110. }
  111. *pTarget = NULL;
  112. return FALSE;
  113. }
  114. VOID
  115. CleanupOptionDataEx( IN PVOID pVoid ) {
  116. ULONG i;
  117. PSAVEQUEUE pQueue;
  118. ASSERT( pVoid != NULL );
  119. pQueue = ( PSAVEQUEUE ) pVoid;
  120. if ( pQueue->FirstNode != NULL ) {
  121. PSAVENODE p;
  122. PSAVENODE q;
  123. ASSERT( pQueue->LastNode != NULL );
  124. OPTIONS_DEBUG( "CleanupOptionDataEx: Freelist is nonempty.\n" );
  125. for ( p = pQueue->FirstNode ;
  126. p != NULL ;
  127. p = q ) {
  128. q = p->next;
  129. switch( p->DeallocMethod ) {
  130. case DeallocWithFree:
  131. free( p->DataElement );
  132. break;
  133. case DeallocWithLocalFree:
  134. LocalFree( p->DataElement );
  135. break;
  136. case DeallocWithOptionDealloc:
  137. OptionDealloc( p->DataElement );
  138. break;
  139. default:
  140. ASSERT_NOTREACHED( "unknown dealloc flag. Bleah!" );
  141. return;
  142. }
  143. OptionDealloc( p );
  144. }
  145. } else {
  146. OPTIONS_DEBUG( "CleanupOptionDataEx: Freelist is empty.\n" );
  147. ASSERT( pQueue->LastNode == NULL );
  148. }
  149. }