You mentioned that this trick is done on kernelbase and not in NtWriteVirtualMemory level. I think we don't have pre-existing NtWriteVirtualMemory tests, maybe worth adding one right at the same place where you test WriteProcessMemory to make it clear?
I guess pre-querying is better than unconditionally changing protection. First, "well-behaved" case performance already mentioned which I suppose is the majority of practical usage at least now, since things mostly work without this functionality.
Then, you are changing the protection PAGE_READWRITE when the page can't be written with existing permissions. Are you sure is it correct and, e. g., it shouldn't be PAGE_EXECUTEREADWRITE when appropriate? I guess it can be tested with a thread repeatedly calling a PAGE_EXECUTEREAD code region being written with the same data instructions. The behaviour like in the present patch should make that cause access violation.