mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-02-04 06:02:24 +00:00
Remove hard dependency on GetFileAttributesEx.
This fixes a load-time failure on versions of Windows too old to have that function in kernel32.dll. We use it to determine whether a file was safe to overwrite in the context of PuTTY session logging: if it's safe, we skip the 'do you want to overwrite or append?' dialog box. On earlier Windows you can use FindFirstFile to get a similar effect, so that's what we fall back to. It's not quite the same, though - if you pass a wildcard then it will succeed when you'd rather it had failed. But it's good enough to at least work in normal cases.
This commit is contained in:
parent
51f0057b67
commit
83ff08f9db
@ -4,20 +4,19 @@
|
|||||||
|
|
||||||
#include "putty.h"
|
#include "putty.h"
|
||||||
|
|
||||||
bool open_for_write_would_lose_data(const Filename *fn)
|
/*
|
||||||
|
* This is slightly fiddly because we want to be backwards-compatible
|
||||||
|
* with systems too old to have GetFileAttributesEx. The next best
|
||||||
|
* thing is FindFirstFile, which will return a different data
|
||||||
|
* structure, but one that also contains the fields we want. (But it
|
||||||
|
* will behave more unhelpfully - for this application - in the
|
||||||
|
* presence of wildcards, so we'd prefer to use GFAE if we can.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool open_for_write_would_lose_data_impl(
|
||||||
|
DWORD dwFileAttributes, DWORD nFileSizeHigh, DWORD nFileSizeLow)
|
||||||
{
|
{
|
||||||
WIN32_FILE_ATTRIBUTE_DATA attrs;
|
if (dwFileAttributes & (FILE_ATTRIBUTE_DEVICE|FILE_ATTRIBUTE_DIRECTORY)) {
|
||||||
if (!GetFileAttributesEx(fn->path, GetFileExInfoStandard, &attrs)) {
|
|
||||||
/*
|
|
||||||
* Generally, if we don't identify a specific reason why we
|
|
||||||
* should return true from this function, we return false, and
|
|
||||||
* let the subsequent attempt to open the file for real give a
|
|
||||||
* more useful error message.
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (attrs.dwFileAttributes & (FILE_ATTRIBUTE_DEVICE |
|
|
||||||
FILE_ATTRIBUTE_DIRECTORY)) {
|
|
||||||
/*
|
/*
|
||||||
* File is something other than an ordinary disk file, so
|
* File is something other than an ordinary disk file, so
|
||||||
* opening it for writing will not cause truncation. (It may
|
* opening it for writing will not cause truncation. (It may
|
||||||
@ -25,7 +24,7 @@ bool open_for_write_would_lose_data(const Filename *fn)
|
|||||||
*/
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (attrs.nFileSizeHigh == 0 && attrs.nFileSizeLow == 0) {
|
if (nFileSizeHigh == 0 && nFileSizeLow == 0) {
|
||||||
/*
|
/*
|
||||||
* File is zero-length (or may be a named pipe, which
|
* File is zero-length (or may be a named pipe, which
|
||||||
* dwFileAttributes can't tell apart from a regular file), so
|
* dwFileAttributes can't tell apart from a regular file), so
|
||||||
@ -36,3 +35,42 @@ bool open_for_write_would_lose_data(const Filename *fn)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool open_for_write_would_lose_data(const Filename *fn)
|
||||||
|
{
|
||||||
|
static HMODULE kernel32_module;
|
||||||
|
DECL_WINDOWS_FUNCTION(static, BOOL, GetFileAttributesExA,
|
||||||
|
(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID));
|
||||||
|
|
||||||
|
if (!kernel32_module) {
|
||||||
|
kernel32_module = load_system32_dll("kernel32.dll");
|
||||||
|
GET_WINDOWS_FUNCTION(kernel32_module, GetFileAttributesExA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_GetFileAttributesExA) {
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA attrs;
|
||||||
|
if (!p_GetFileAttributesExA(fn->path, GetFileExInfoStandard, &attrs)) {
|
||||||
|
/*
|
||||||
|
* Generally, if we don't identify a specific reason why we
|
||||||
|
* should return true from this function, we return false, and
|
||||||
|
* let the subsequent attempt to open the file for real give a
|
||||||
|
* more useful error message.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return open_for_write_would_lose_data_impl(
|
||||||
|
attrs.dwFileAttributes, attrs.nFileSizeHigh, attrs.nFileSizeLow);
|
||||||
|
} else {
|
||||||
|
WIN32_FIND_DATA fd;
|
||||||
|
HANDLE h = FindFirstFile(fn->path, &fd);
|
||||||
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
|
/*
|
||||||
|
* As above, if we can't find the file at all, return false.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CloseHandle(h);
|
||||||
|
return open_for_write_would_lose_data_impl(
|
||||||
|
fd.dwFileAttributes, fd.nFileSizeHigh, fd.nFileSizeLow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user