+/**\r
+ Find a file by searching the CWD and then the path with a variable set of file \r
+ extensions. If the file is not found it will append each extension in the list \r
+ in the order provided and return the first one that is successful.\r
+\r
+ If FileName is NULL, then ASSERT.\r
+ If FileExtension is NULL, then behavior is identical to ShellFindFilePath.\r
+\r
+ If the return value is not NULL then the memory must be caller freed.\r
+\r
+ @param[in] FileName Filename string.\r
+ @param[in] FileExtension Semi-colon delimeted list of possible extensions.\r
+\r
+ @retval NULL The file was not found.\r
+ @retval !NULL The path to the file.\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+ShellFindFilePathEx (\r
+ IN CONST CHAR16 *FileName,\r
+ IN CONST CHAR16 *FileExtension\r
+ )\r
+{\r
+ CHAR16 *TestPath;\r
+ CHAR16 *RetVal;\r
+ CONST CHAR16 *ExtensionWalker;\r
+ ASSERT(FileName != NULL);\r
+ if (FileExtension == NULL) {\r
+ return (ShellFindFilePath(FileName));\r
+ }\r
+ RetVal = ShellFindFilePath(FileName);\r
+ if (RetVal != NULL) {\r
+ return (RetVal);\r
+ }\r
+ TestPath = AllocateZeroPool(StrSize(FileName) + StrSize(FileExtension));\r
+ for (ExtensionWalker = FileExtension ; ; ExtensionWalker = StrStr(ExtensionWalker, L";") + 1 ){\r
+ StrCpy(TestPath, FileName);\r
+ StrCat(TestPath, ExtensionWalker);\r
+ if (StrStr(TestPath, L";") != NULL) {\r
+ *(StrStr(TestPath, L";")) = CHAR_NULL;\r
+ }\r
+ RetVal = ShellFindFilePath(TestPath);\r
+ if (RetVal != NULL) {\r
+ break;\r
+ }\r
+ //\r
+ // Must be after first loop...\r
+ //\r
+ if (StrStr(ExtensionWalker, L";") == NULL) {\r
+ break;\r
+ }\r
+ }\r
+ FreePool(TestPath);\r
+ return (RetVal);\r
+}\r
+\r