I find it a bit odd, the way this API works, but fooling around with it, it seems to do it's job... Optional params are involved to identify a filepath, as well as the extension, otherwise you can actually define the extension as null, and declare the filename with the name and path directly no problem. This tells me it's nothing more than a concatenation that they do lol.

I've ran across a few weird events though lately, it's been a night working on this, i'll take a further look at it later. Today I was just fooling around with various API's to see what was out there. This turned into a small app, but in the beginning it was really just a fool around project, so still nothing serious, haven't provided any permissional checks yet, that's pretty much just up for testing when the user finds out the application stops working lol; probably due to not having permission to search a dir/file.

Here's what I did so far... You can get the basics for how to use this monster API... I wouldn't suggest taking the rest of the code too seriously though, I did lots of fooling around as mentioned before. I even had time to create a video of my first trial:



Source code
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace FileReaper
{
	public partial class Form1 : Form
	{

		[DllImport("kernel32.dll", CharSet = CharSet.Auto, EntryPoint = "SearchPath", SetLastError = true)]
		private static unsafe extern int SearchPath(
														[Optional] string lpPath,
														string lpFileName,
														[Optional] string lpExtension,
														int nBufferLength,
														[MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpBuffer,
														[Optional] out string lpFilePart
													);

		public Form1()
		{
			InitializeComponent();
			textBox3.Text = Application.StartupPath;
		}

		private unsafe void button1_Click(object sender, EventArgs e)
		{
			string fileName = textBox1.Text;
			string fileExt = textBox2.Text;
			string searchDir = textBox3.Text;

			new Thread(x => SearchForFile(searchDir, fileName, fileExt)).Start();
		}

		private void ProgBarStatus()
		{
			if (progressBar1.Style == ProgressBarStyle.Blocks)
				progressBar1.Style = ProgressBarStyle.Marquee;
			else
				progressBar1.Style = ProgressBarStyle.Blocks;
		}

		private void SearchForFile(string searchDir, string fileName, string fileExt)
		{
			bool foundfile = false;
			string fullPath = null, filePart = null;

			progressBar1.Invoke((MethodInvoker)delegate { ProgBarStatus(); });

			if (SearchLocation(Application.StartupPath, fileName, fileExt, out fullPath, out filePart) != 0)
			{
				//Bad permission stuff here
				foreach (string dir in Directory.GetDirectories(searchDir, "*", SearchOption.AllDirectories))
				{
					try
					{
						if (SearchLocation(dir, fileName, fileExt, out fullPath, out filePart) == 0) foundfile = true;
					}
					catch (Exception) { }
					if (foundfile) break;
				}
			}

			progressBar1.Invoke((MethodInvoker)delegate { ProgBarStatus(); });

			if (fullPath == null)
			{
				MessageBox.Show(string.Format("Could not find the specified file \"{0}\"\n\nSearch Directory: {1}", fileName + fileExt, searchDir),
						"Win32 Error",
						MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
			else
			{
				MessageBox.Show(fullPath,
						"Found File",
						MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
			}

		}

		private int SearchLocation(string searchDir, string fileName, string fileExt, out string fullPath, out string filePart)
		{
			StringBuilder lpBufferOut = new StringBuilder(255);
			string lpFilePartOut;

			if (SearchPath(searchDir, fileName, fileExt, lpBufferOut.Capacity, lpBufferOut, out lpFilePartOut) != 0)
			{
				fullPath = lpBufferOut.ToString(); //Retrieve Found Path
				filePart = lpFilePartOut; //Retrieve FilePart Component
				return 0;
			}
			else
			{
				fullPath = null; filePart = null;
				return -1;
			}
		}

	}

}