Если говорить "грубо" - в ядре нет никаких ANSI строк, есть только Юникод. То есть любая функция, имеющая префикс А, конвертируется в функцию с префиксом W. Делается это простыми Rtl функциями https://learn.microsoft.com/en-us/w...s/ddi/wdm/nf-wdm-rtlunicodestringtoansistring и https://learn.microsoft.com/en-us/w...s/ddi/wdm/nf-wdm-rtlansistringtounicodestring Можно даже посмотреть на примере. Возьмите любую А-функцию и посмотрите что в конечном итоге будет вызвано. Уже упомянутая CreateProcessInternalW: предположим, мы вызываем CreateProcessA как и следовало ожидать это переопределенный стаб на внутреннюю не экспортируемую функцию CreateProcessInternalA. Затем, переходим к внутренностям CreateProcessInternalA и смотрим что там происходит. А в конечном итоге там происходит преобразование ANSI в строку Юникод (с помощью функции RtlAnsiStringToUnicodeString) и... вызов CreateProcessInternalW.
Пример. Код (Text): LoadLibraryExA( LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags ) /*++ Routine Description: ANSI thunk to LoadLibraryExW --*/ { PUNICODE_STRING Unicode; Unicode = Basep8BitStringToStaticUnicodeString( lpLibFileName ); if (Unicode == NULL) { return NULL; } return LoadLibraryExW( Unicode->Buffer, hFile, dwFlags); } k3rnl Примерно тут.
"Настоящие" функции WinAPI имеют суффикс W. Функции с суффиксом A конвертируют строки из текущего charset системных настроек в двухбайтовую кодировку винды и вызывают *W. Все функции без префикса это просто макросы которые путём анализа #ifdef _UNICODE выставляются либо на имя *A либо на имя *W. Но можно без стеснений напрямую тягать имя *W и не парится с тем какой там выставлен макрос _UNICODE при компиляции. Вся эта петрушка с TCHAR и _tmain (или как там его) была затеяна MS чтобы облегчить переход с однобайтовых кодировок на свою двухбайтовую, но ныне уже полностью себя изжила - пользоваться однобайтовым режимом компиляции просто уже незачем. А если охота с ним быть совместимым, то можно просто вызывать нужный вариант функций без макросов-обёрток. Поэтому проблемы никакой скорее всего и не было.
С самых первых. Вот в Win 9x как то сложнее было, нараскоряку, но NT-шка сразу стояла на прямых ногах.
Сервисные апи вот. Одно из свойств обьекта это его имя, оно задается как OBJECT_ATTRIBUTES.ObjectName:PUNICODE_STRING
Так в итоге и сделал, завел в библиотеке две функции, а какую вызывать решает клиент, исходя из своей кодировки. Неудобство в том что надо вместо одной лепить пару функций - этакая плата за совместимость.
Это все компиляторные нюансы, пример выше: Код (C): CreateProcess%( IN LPCTSTR% lpApplicationName, IN LPTSTR% lpCommandLine, - A/W за раз