From: Corinna Vinschen Date: Wed, 13 Aug 2008 08:54:14 +0000 (+0000) Subject: * install.cc (Installer::installOne): Use MoveFileExW on NT. Special X-Git-Tag: release_2.869~287 X-Git-Url: https://cygwin.com/git/?a=commitdiff_plain;h=53d33c5d5a9c2729d49c6850de074695acc20c31;p=cygwin-apps%2Fsetup.git * install.cc (Installer::installOne): Use MoveFileExW on NT. Special case for bug in Windows 2000. * package_meta.cc (packagemeta::uninstall): Use wide char file functions on NT. * win32.h (VersionInfo::major): New method. (VersionInfo::minor): New method. (OSMajorVersion): Define. (OSMinorVersion): Define. --- diff --git a/ChangeLog b/ChangeLog index 9ec6136c..3723a093 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-08-13 Corinna Vinschen + + * install.cc (Installer::installOne): Use MoveFileExW on NT. Special + case for bug in Windows 2000. + * package_meta.cc (packagemeta::uninstall): Use wide char file functions + on NT. + * win32.h (VersionInfo::major): New method. + (VersionInfo::minor): New method. + (OSMajorVersion): Define. + (OSMinorVersion): Define. + 2008-08-12 Corinna Vinschen Revamp for Cygwin 1.7. diff --git a/install.cc b/install.cc index df1e6d9e..885a0e86 100644 --- a/install.cc +++ b/install.cc @@ -406,9 +406,25 @@ Installer::installOne (packagemeta &pkgm, const packageversion &ver, * - we need a io method to get win32 paths * or to wrap this system call */ - if (!MoveFileEx (s.c_str (), d.c_str (), - MOVEFILE_DELAY_UNTIL_REBOOT | - MOVEFILE_REPLACE_EXISTING)) + WCHAR sname[s.size () + 7]; + WCHAR dname[d.size () + 7]; + /* Windows 2000 has a bug: Prepending \\?\ does not + * work in conjunction with MOVEFILE_DELAY_UNTIL_REBOOT. + * So in case of Windows 2000 we just convert the path + * to wide char and hope for the best. */ + if (OSMajorVersion () == 5 && OSMinorVersion () == 0) + { + mbstowcs (sname, s.c_str (), s.size () + 7); + mbstowcs (dname, d.c_str (), d.size () + 7); + } + else + { + mklongpath (sname, s.c_str (), s.size () + 7); + mklongpath (dname, d.c_str (), d.size () + 7); + } + if (!MoveFileExW (sname, dname, + MOVEFILE_DELAY_UNTIL_REBOOT | + MOVEFILE_REPLACE_EXISTING)) replaceOnRebootFailed (fn); else replaceOnRebootSucceeded (fn, rebootneeded); diff --git a/package_meta.cc b/package_meta.cc index 3c0baf6a..706d0fbb 100644 --- a/package_meta.cc +++ b/package_meta.cc @@ -170,24 +170,54 @@ packagemeta::uninstall () } std::string d = cygpath ("/" + line); - DWORD dw = GetFileAttributes (d.c_str()); - if (dw != INVALID_FILE_ATTRIBUTES - && !(dw & FILE_ATTRIBUTE_DIRECTORY)) + WCHAR wname[d.size () + 11]; /* Prefix + ".lnk". */ + if (IsWindowsNT ()) { - log (LOG_BABBLE) << "unlink " << d << endLog; - SetFileAttributes (d.c_str(), dw & ~FILE_ATTRIBUTE_READONLY); - DeleteFile (d.c_str()); + mklongpath (wname, d.c_str (), d.size () + 11); + DWORD dw = GetFileAttributesW (wname); + if (dw != INVALID_FILE_ATTRIBUTES + && !(dw & FILE_ATTRIBUTE_DIRECTORY)) + { + log (LOG_BABBLE) << "unlink " << d << endLog; + SetFileAttributesW (wname, dw & ~FILE_ATTRIBUTE_READONLY); + DeleteFileW (wname); + } + } + else + { + DWORD dw = GetFileAttributesA (d.c_str()); + if (dw != INVALID_FILE_ATTRIBUTES + && !(dw & FILE_ATTRIBUTE_DIRECTORY)) + { + log (LOG_BABBLE) << "unlink " << d << endLog; + SetFileAttributesA (d.c_str(), dw & ~FILE_ATTRIBUTE_READONLY); + DeleteFileA (d.c_str()); + } } /* Check for Windows shortcut of same name. */ d += ".lnk"; - dw = GetFileAttributes (d.c_str()); - if (dw != INVALID_FILE_ATTRIBUTES - && !(dw & FILE_ATTRIBUTE_DIRECTORY)) + if (IsWindowsNT ()) + { + wcscat (wname, L".lnk"); + DWORD dw = GetFileAttributesW (wname); + if (dw != INVALID_FILE_ATTRIBUTES + && !(dw & FILE_ATTRIBUTE_DIRECTORY)) + { + log (LOG_BABBLE) << "unlink " << d << endLog; + SetFileAttributesW (wname, dw & ~FILE_ATTRIBUTE_READONLY); + DeleteFileW (wname); + } + } + else { - log (LOG_BABBLE) << "unlink " << d << endLog; - SetFileAttributes (d.c_str(), - dw & ~FILE_ATTRIBUTE_READONLY); - DeleteFile (d.c_str()); + DWORD dw = GetFileAttributesA (d.c_str()); + if (dw != INVALID_FILE_ATTRIBUTES + && !(dw & FILE_ATTRIBUTE_DIRECTORY)) + { + log (LOG_BABBLE) << "unlink " << d << endLog; + SetFileAttributesA (d.c_str(), dw & ~FILE_ATTRIBUTE_READONLY); + DeleteFileA (d.c_str()); + } } line = installed.getnextfile (); } @@ -200,7 +230,14 @@ packagemeta::uninstall () { it--; std::string d = cygpath("/" + *it); - if (RemoveDirectory (d.c_str())) + WCHAR wname[d.size () + 11]; + if (IsWindowsNT ()) + { + mklongpath (wname, d.c_str (), d.size () + 11); + if (RemoveDirectoryW (wname)) + log (LOG_BABBLE) << "rmdir " << d << endLog; + } + else if (RemoveDirectoryA (d.c_str())) log (LOG_BABBLE) << "rmdir " << d << endLog; } } diff --git a/win32.h b/win32.h index ea023503..16d5fdae 100644 --- a/win32.h +++ b/win32.h @@ -143,6 +143,8 @@ class VersionInfo public: VersionInfo (); bool isNT () { return (v.dwPlatformId == VER_PLATFORM_WIN32_NT); } + DWORD major () const { return v.dwMajorVersion; } + DWORD minor () const { return v.dwMinorVersion; } private: OSVERSIONINFO v; }; @@ -150,5 +152,7 @@ class VersionInfo VersionInfo& GetVer (); #define IsWindowsNT() (GetVer ().isNT ()) +#define OSMajorVersion() (GetVer ().major ()) +#define OSMinorVersion() (GetVer ().minor ()) #endif /* SETUP_WIN32_H */