[Python-checkins] r52339 - in python/trunk: Misc/NEWS Modules/posixmodule.c

martin.v.loewis python-checkins at python.org
Sun Oct 15 11:43:40 CEST 2006


Author: martin.v.loewis
Date: Sun Oct 15 11:43:39 2006
New Revision: 52339

Modified:
   python/trunk/Misc/NEWS
   python/trunk/Modules/posixmodule.c
Log:
Bug #1567666: Emulate GetFileAttributesExA for Win95.
Will backport to 2.5.

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Sun Oct 15 11:43:39 2006
@@ -137,6 +137,8 @@
 Extension Modules
 -----------------
 
+- Bug #1567666: Emulate GetFileAttributesExA for Win95.
+
 - Patch #1576166: Support os.utime for directories on Windows NT+.
 
 - Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode

Modified: python/trunk/Modules/posixmodule.c
==============================================================================
--- python/trunk/Modules/posixmodule.c	(original)
+++ python/trunk/Modules/posixmodule.c	Sun Oct 15 11:43:39 2006
@@ -828,6 +828,106 @@
 	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 @@
 	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 @@
 	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;


More information about the Python-checkins mailing list