Bug #1567666: Emulate GetFileAttributesExA for Win95.
Will backport to 2.5.
This commit is contained in:
parent
cfcd3a9569
commit
012bc7253b
|
@ -137,6 +137,8 @@ Library
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Bug #1567666: Emulate GetFileAttributesExA for Win95.
|
||||||
|
|
||||||
- Patch #1576166: Support os.utime for directories on Windows NT+.
|
- Patch #1576166: Support os.utime for directories on Windows NT+.
|
||||||
|
|
||||||
- Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode
|
- Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode
|
||||||
|
|
|
@ -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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue