gh-102255: Improve build support on xbox by maxbachmann · Pull Request #102256 · python/cpython
Okay, thanks for holding. What I'm hearing from my colleagues at Microsoft is that the PathCch* APIs are implemented in the Xbox OS, just not exposed through the partition or their import lib. It sounds like both of these will be fixed for an update later this year, at which point our original code will be fine. The only restriction seems to be that the APIs are not implemented on Win7, so even though games are meant to be compatible all the way back, if we were to use the API then it would not work.
Until the GDK update arrives, it seems like we can probably use code like what we used to have to load the API dynamically (from getpathp.c in the 3.7 branch):
static int _PathCchCombineEx_Initialized = 0;
typedef HRESULT(__stdcall *PPathCchCombineEx) (PWSTR pszPathOut, size_t cchPathOut,
PCWSTR pszPathIn, PCWSTR pszMore,
unsigned long dwFlags);
static PPathCchCombineEx _PathCchCombineEx;
static void
join(wchar_t *buffer, const wchar_t *stuff)
{
if (_PathCchCombineEx_Initialized == 0) {
HMODULE pathapi = LoadLibraryExW(L"api-ms-win-core-path-l1-1-0.dll", NULL,
LOAD_LIBRARY_SEARCH_SYSTEM32);
if (pathapi) {
_PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx");
}
else {
_PathCchCombineEx = NULL;
}
_PathCchCombineEx_Initialized = 1;
}
if (_PathCchCombineEx) {
if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0))) {
Py_FatalError("buffer overflow in getpathp.c's join()");
}
} else {
if (!PathCombineW(buffer, buffer, stuff)) {
Py_FatalError("buffer overflow in getpathp.c's join()");
}
}
}
@maxbachmann Would you be able to give this approach a try and see if it works? Unfortunately, I don't think there's any way to detect the version of the games SDK involved, so we'd just have to keep this until we assume everyone's on the fixed update.
If it helps (and I suspect it won't), it also ought to be okay to temporarily define the PARTITION constants needed when including pathcch.h. It's more likely going to be better to exclude the include statement in GAMES when we're defining a GetProcAddress wrapper, since that way we can define our own PathCchCombineEx implementation and it shouldn't collide with the real one until we choose to let it. You can probably even keep the existing implementation as a fallback for the (hopefully rare) cases where games may be running on Win7, but I'm happy to defer to you on that one, as you've likely got a better view of the gamedev landscape than I do.