How to replace WinAPI functions calls in the MS VC++ project with my own implementation (name and parameters set are the same)?

StackOverflow https://stackoverflow.com/questions/60641

  •  09-06-2019
  •  | 
  •  

Question

I need to replace all WinAPI calls of the

  • CreateFile,
  • ReadFile,
  • SetFilePointer,
  • CloseHandle

with my own implementation (which use low-level file reading via Bluetooth). The code, where functions will be replaced, is Video File Player and it already works with the regular hdd files. It is also needed, that Video Player still can play files from HDD, if the file in the VideoPlayer input is a regular hdd file.

What is the best practice for such task?

Was it helpful?

Solution

I suggest that you follow these steps:

  1. Write a set of wrapper functions, e.g MyCreateFile, MyReadFile, etc, that initially just call the corresponding API and pass the same arguments along, unmodified.
  2. Use your text editor to search for all calls to the original APIs, and replace these with calls to your new wrapper functions.
  3. Test that the application still functions correctly.
  4. Modify the wrapper functions to suit your own purposes.

Note that CreateFile is a macro which expands to either CreateFileW or CreateFileA, depending on whether UNICODE is defined. Consider using LPCTSTR and the TCHAR functions so that your application can be built as either ANSI or Unicode.

Please don't use #define, as suggested in other responses here, as this will just lead to maintenance problems, and as Maximilian correctly points out, it's not a best-practice.

OTHER TIPS

You could just write your new functions in a custom namespace. e.g.

namespace Bluetooth
{
  void CreateFile(/*params*/);
  void etc...
}

Then in your code, the only thing you would have to change is:

if (::CreateFile(...))
{
}

to

if (Bluetooth::CreateFile(...))
{
}

Easy! :)

If you're trying to intercept calls to these APIs from another application, consider Detours.

If you can edit the code, you should just re-write it to use a custom API that does what you want. Failing that, use Maximilian's technique, but be warned that it is a maintenance horror.

If you cannot edit the code, you can patch the import tables to redirect calls to your own code. A description of this technique can be found in this article - search for the section titled "Spying by altering of the Import Address Table".

This is dangerous, but if you're careful you can make it work. Also check out Microsoft Detours, which does the same sort of thing but doesn't require you to mess around with the actual patching.

If you really want to hijack the API, look at syringe.dll (L-GPL).

I don't think this is best practice but it should work if you put it in an include file that's included everywhere the function you want to change is called:

#define CreateFile MyCreateFile

HRESULT MyCreateFile(whatever the params are);

Implementation of MyCreateFile looks something like this:

#undef CreateFile
HRESULT MyCreateFile(NobodyCanRememberParamListsLikeThat params)
{
    if (InputIsNormalFile())
        CreateFile(params);
    else
        // do your thing
}

You basically make every CreateFile call a MyCreateFile call where you can decide if you want need to use your own implementation or the orginal one.

Disclaimer: I think doing this is ugly and I wouldn't do it. I'd rather search and replace all occurences or something.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top