Commit 7c7b6861 authored by Martin v. Löwis's avatar Martin v. Löwis

Bug #1567666: Emulate GetFileAttributesExA for Win95.

parent 939c29e2
...@@ -52,6 +52,8 @@ Core and builtins ...@@ -52,6 +52,8 @@ Core and builtins
Extension Modules Extension Modules
----------------- -----------------
- Bug #1567666: Emulate GetFileAttributesExA for Win95.
- Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode - Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode
arguments with the system default encoding just like the write() arguments with the system default encoding just like the write()
method does, instead of converting it to a raw buffer. method does, instead of converting it to a raw buffer.
......
...@@ -828,6 +828,106 @@ attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *resul ...@@ -828,6 +828,106 @@ attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *resul
return 0; 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 static int
win32_stat(const char* path, struct win32_stat *result) win32_stat(const char* path, struct win32_stat *result)
{ {
...@@ -835,7 +935,7 @@ win32_stat(const char* path, struct win32_stat *result) ...@@ -835,7 +935,7 @@ win32_stat(const char* path, struct win32_stat *result)
int code; int code;
char *dot; char *dot;
/* XXX not supported on Win95 and NT 3.x */ /* 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 /* Protocol violation: we explicitly clear errno, instead of
setting it to a POSIX error. Callers should use GetLastError. */ setting it to a POSIX error. Callers should use GetLastError. */
errno = 0; errno = 0;
...@@ -863,7 +963,7 @@ win32_wstat(const wchar_t* path, struct win32_stat *result) ...@@ -863,7 +963,7 @@ win32_wstat(const wchar_t* path, struct win32_stat *result)
const wchar_t *dot; const wchar_t *dot;
WIN32_FILE_ATTRIBUTE_DATA info; WIN32_FILE_ATTRIBUTE_DATA info;
/* XXX not supported on Win95 and NT 3.x */ /* 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 /* Protocol violation: we explicitly clear errno, instead of
setting it to a POSIX error. Callers should use GetLastError. */ setting it to a POSIX error. Callers should use GetLastError. */
errno = 0; errno = 0;
...@@ -8617,3 +8717,4 @@ INITFUNC(void) ...@@ -8617,3 +8717,4 @@ INITFUNC(void)
} }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment