From 2c7aa634cbd76467c18876c61418ea80962eb5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Sun, 15 Oct 2006 09:44:02 +0000 Subject: Bug #1567666: Emulate GetFileAttributesExA for Win95. --- Misc/NEWS | 2 + Modules/posixmodule.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 887977a..4cabe95 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -52,6 +52,8 @@ Core and builtins Extension Modules ----------------- +- Bug #1567666: Emulate GetFileAttributesExA for Win95. + - Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode arguments with the system default encoding just like the write() method does, instead of converting it to a raw buffer. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 93d0300..0a84a25 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -828,6 +828,106 @@ attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *resul return 0; } +/* Emulate GetFileAttributesEx[AW] on Windows 95 */ +static int checked = 0; +static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID); +static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID); +static void +check_gfax() +{ + HINSTANCE hKernel32; + if (checked) + return; + checked = 1; + hKernel32 = GetModuleHandle("KERNEL32"); + *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA"); + *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW"); +} + +static BOOL WINAPI +Py_GetFileAttributesExA(LPCSTR pszFile, + GET_FILEEX_INFO_LEVELS level, + LPVOID pv) +{ + BOOL result; + HANDLE hFindFile; + WIN32_FIND_DATAA FileData; + LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv; + /* First try to use the system's implementation, if that is + available and either succeeds to gives an error other than + that it isn't implemented. */ + check_gfax(); + if (gfaxa) { + result = gfaxa(pszFile, level, pv); + if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return result; + } + /* It's either not present, or not implemented. + Emulate using FindFirstFile. */ + if (level != GetFileExInfoStandard) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + /* Use GetFileAttributes to validate that the file name + does not contain wildcards (which FindFirstFile would + accept). */ + if (GetFileAttributesA(pszFile) == 0xFFFFFFFF) + return FALSE; + hFindFile = FindFirstFileA(pszFile, &FileData); + if (hFindFile == INVALID_HANDLE_VALUE) + return FALSE; + FindClose(hFindFile); + pfad->dwFileAttributes = FileData.dwFileAttributes; + pfad->ftCreationTime = FileData.ftCreationTime; + pfad->ftLastAccessTime = FileData.ftLastAccessTime; + pfad->ftLastWriteTime = FileData.ftLastWriteTime; + pfad->nFileSizeHigh = FileData.nFileSizeHigh; + pfad->nFileSizeLow = FileData.nFileSizeLow; + return TRUE; +} + +static BOOL WINAPI +Py_GetFileAttributesExW(LPCWSTR pszFile, + GET_FILEEX_INFO_LEVELS level, + LPVOID pv) +{ + BOOL result; + HANDLE hFindFile; + WIN32_FIND_DATAW FileData; + LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv; + /* First try to use the system's implementation, if that is + available and either succeeds to gives an error other than + that it isn't implemented. */ + check_gfax(); + if (gfaxa) { + result = gfaxw(pszFile, level, pv); + if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return result; + } + /* It's either not present, or not implemented. + Emulate using FindFirstFile. */ + if (level != GetFileExInfoStandard) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + /* Use GetFileAttributes to validate that the file name + does not contain wildcards (which FindFirstFile would + accept). */ + if (GetFileAttributesW(pszFile) == 0xFFFFFFFF) + return FALSE; + hFindFile = FindFirstFileW(pszFile, &FileData); + if (hFindFile == INVALID_HANDLE_VALUE) + return FALSE; + FindClose(hFindFile); + pfad->dwFileAttributes = FileData.dwFileAttributes; + pfad->ftCreationTime = FileData.ftCreationTime; + pfad->ftLastAccessTime = FileData.ftLastAccessTime; + pfad->ftLastWriteTime = FileData.ftLastWriteTime; + pfad->nFileSizeHigh = FileData.nFileSizeHigh; + pfad->nFileSizeLow = FileData.nFileSizeLow; + return TRUE; +} + static int win32_stat(const char* path, struct win32_stat *result) { @@ -835,7 +935,7 @@ win32_stat(const char* path, struct win32_stat *result) int code; char *dot; /* XXX not supported on Win95 and NT 3.x */ - if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) { + if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ errno = 0; @@ -863,7 +963,7 @@ win32_wstat(const wchar_t* path, struct win32_stat *result) const wchar_t *dot; WIN32_FILE_ATTRIBUTE_DATA info; /* XXX not supported on Win95 and NT 3.x */ - if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) { + if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ errno = 0; @@ -8617,3 +8717,4 @@ INITFUNC(void) } #endif + -- cgit v0.12