]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Bug #1567666: Emulate GetFileAttributesExA for Win95.
authorMartin v. Löwis <martin@v.loewis.de>
Sun, 15 Oct 2006 09:44:02 +0000 (09:44 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Sun, 15 Oct 2006 09:44:02 +0000 (09:44 +0000)
Misc/NEWS
Modules/posixmodule.c

index 887977a3a3f67ad1f5a528814a5ff9ff6296ff5f..4cabe95ad922790e2d3fbe1bbf5da5bcba0233b7 100644 (file)
--- 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.
index 93d030017d10f9900ccd66906ba603c9732c027c..0a84a2556b556e82c4ae8bb30c1729fad9635cd5 100644 (file)
@@ -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
 
+