+/**\r
+ Store the ModHandle in an array indexed by the Pdb File name.\r
+ The ModHandle is needed to unload the image.\r
+ @param ImageContext - Input data returned from PE Laoder Library. Used to find the\r
+ .PDB file name of the PE Image.\r
+ @param ModHandle - Returned from LoadLibraryEx() and stored for call to\r
+ FreeLibrary().\r
+ @return return EFI_SUCCESS when ModHandle was stored.\r
+--*/\r
+EFI_STATUS\r
+AddModHandle (\r
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ IN VOID *ModHandle\r
+ )\r
+\r
+{\r
+ UINTN Index;\r
+ PDB_NAME_TO_MOD_HANDLE *Array;\r
+ UINTN PreviousSize;\r
+ PDB_NAME_TO_MOD_HANDLE *TempArray;\r
+ HANDLE Handle;\r
+ UINTN Size;\r
+\r
+ //\r
+ // Return EFI_ALREADY_STARTED if this DLL has already been loaded\r
+ //\r
+ Array = mPdbNameModHandleArray;\r
+ for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {\r
+ if (Array->PdbPointer != NULL && Array->ModHandle == ModHandle) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+ }\r
+\r
+ Array = mPdbNameModHandleArray;\r
+ for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {\r
+ if (Array->PdbPointer == NULL) {\r
+ //\r
+ // Make a copy of the stirng and store the ModHandle\r
+ //\r
+ Handle = GetProcessHeap ();\r
+ Size = AsciiStrLen (ImageContext->PdbPointer) + 1;\r
+ Array->PdbPointer = HeapAlloc ( Handle, HEAP_ZERO_MEMORY, Size);\r
+ ASSERT (Array->PdbPointer != NULL);\r
+\r
+ AsciiStrCpyS (Array->PdbPointer, Size, ImageContext->PdbPointer);\r
+ Array->ModHandle = ModHandle;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ //\r
+ // No free space in mPdbNameModHandleArray so grow it by\r
+ // MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE entires.\r
+ //\r
+ PreviousSize = mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE);\r
+ mPdbNameModHandleArraySize += MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE;\r
+ //\r
+ // re-allocate a new buffer and copy the old values to the new locaiton.\r
+ //\r
+ TempArray = HeapAlloc (GetProcessHeap (),\r
+ HEAP_ZERO_MEMORY,\r
+ mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE)\r
+ );\r
+\r
+ CopyMem ((VOID *) (UINTN) TempArray, (VOID *) (UINTN)mPdbNameModHandleArray, PreviousSize);\r
+\r
+ HeapFree (GetProcessHeap (), 0, mPdbNameModHandleArray);\r
+\r
+ mPdbNameModHandleArray = TempArray;\r
+ if (mPdbNameModHandleArray == NULL) {\r
+ ASSERT (FALSE);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ return AddModHandle (ImageContext, ModHandle);\r
+}\r
+\r
+/**\r
+ Return the ModHandle and delete the entry in the array.\r
+ @param ImageContext - Input data returned from PE Laoder Library. Used to find the\r
+ .PDB file name of the PE Image.\r
+ @return\r
+ ModHandle - ModHandle assoicated with ImageContext is returned\r
+ NULL - No ModHandle associated with ImageContext\r
+**/\r
+VOID *\r
+RemoveModHandle (\r
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+{\r
+ UINTN Index;\r
+ PDB_NAME_TO_MOD_HANDLE *Array;\r
+\r
+ if (ImageContext->PdbPointer == NULL) {\r
+ //\r
+ // If no PDB pointer there is no ModHandle so return NULL\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ Array = mPdbNameModHandleArray;\r
+ for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {\r
+ if ((Array->PdbPointer != NULL) && (AsciiStrCmp(Array->PdbPointer, ImageContext->PdbPointer) == 0)) {\r
+ //\r
+ // If you find a match return it and delete the entry\r
+ //\r
+ HeapFree (GetProcessHeap (), 0, Array->PdbPointer);\r
+ Array->PdbPointer = NULL;\r
+ return Array->ModHandle;\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r