]> cygwin.com Git - cygwin-apps/setup.git/commitdiff
* UserSettings.cc (UserSettings::settingFileForLoad): Fix local load
authorCorinna Vinschen <corinna@vinschen.de>
Mon, 11 May 2009 10:49:15 +0000 (10:49 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Mon, 11 May 2009 10:49:15 +0000 (10:49 +0000)
path strings.
(UserSettings::settingFileForSave): Never store in cwd.
* autoload.c (ntdll): Autoload ntdll.dll functions here.
* desktop.cc (make_cygwin_bat): Use GetFileAttributesW rather than
_waccess.  Use nt_wfopen instead of _wfopen.
(save_icon): Ditto.
* filemanip.cc (get_file_size): Call io_stream::open with empty mode
string to avoid opening file twice.
(GetFileAttributesW): New function to replace Win32 function with
equivalent function opening files with backup intent.
(SetFileAttributesW): Ditto.
(MoveFileW): Ditto.
(DeleteFileW): Ditto.
(RemoveDirectoryW): Ditto.
(nt_wfopen): New function to replace _wfopen with equivalent function
opening files with backup intent.
* filemanip.h (nt_wfopen): Declare.
* io_stream_cygfile.cc (io_stream_cygfile::io_stream_cygfile): Initalize
lasterr to 0.  Allow empty mode and don't open file, if so.  Call
nt_wfopen rather than _wfopen.
(io_stream_cygfile::exists): Use GetFileAttributesW rather than
_waccess.
(io_stream_cygfile::get_size): Use CreateFileW/GetFileSize to get
file size on NT.
* io_stream_file.cc (io_stream_file::io_stream_file): Initalize lasterr
to 0.  Allow empty mode and don't open file, if so.  Call nt_wfopen
rather than _wfopen.
(io_stream_file::exists): Use GetFileAttributesW rather than _waccess.
(io_stream_file::remove): Don't try to remove non-existant file.
(io_stream_file::get_size): Use CreateFileW/GetFileSize to get
file size on NT.  Add comment to keep track of 2GB border.
* mkdir.cc: Remove function pointers for ntdll functions.
(init_ntfuncs): Remove function.
(mkdir_p): Drop call to init_ntfuncs.  Call ntdll functions directly
rather than over local function pointers.
* ntdll.h: New file.
* postinstall.cc (do_postinstall_reflector): Switch to admins group
as primary group after postinstall scripts have been written.
Explain why.
(do_postinstall): Add comment.
* res.rc: Bump copyright date.
* win32.h (class TokenGroupCollection): Remove.
* win32.cc (TokenGroupCollection::populate): Remove.
(TokenGroupCollection::find): Remove.
(NTSecurity::setDefaultSecurity): Drop reading token groups.  Just
try to switch to admins group as primary group.

14 files changed:
ChangeLog
UserSettings.cc
autoload.c
desktop.cc
filemanip.cc
filemanip.h
io_stream_cygfile.cc
io_stream_file.cc
mkdir.cc
ntdll.h [new file with mode: 0644]
postinstall.cc
res.rc
win32.cc
win32.h

index 8c598cec567f7ecd36a415e7252694eebd8a4e37..409045ee3fd55fa68619f159a798d11a70647912 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,53 @@
+2009-05-11  Corinna Vinschen  <corinna@vinschen.de>
+
+       * UserSettings.cc (UserSettings::settingFileForLoad): Fix local load
+       path strings.
+       (UserSettings::settingFileForSave): Never store in cwd.
+       * autoload.c (ntdll): Autoload ntdll.dll functions here.
+       * desktop.cc (make_cygwin_bat): Use GetFileAttributesW rather than
+       _waccess.  Use nt_wfopen instead of _wfopen.
+       (save_icon): Ditto.
+       * filemanip.cc (get_file_size): Call io_stream::open with empty mode
+       string to avoid opening file twice.
+       (GetFileAttributesW): New function to replace Win32 function with
+       equivalent function opening files with backup intent.
+       (SetFileAttributesW): Ditto.
+       (MoveFileW): Ditto.
+       (DeleteFileW): Ditto.
+       (RemoveDirectoryW): Ditto.
+       (nt_wfopen): New function to replace _wfopen with equivalent function
+       opening files with backup intent.
+       * filemanip.h (nt_wfopen): Declare.
+       * io_stream_cygfile.cc (io_stream_cygfile::io_stream_cygfile): Initalize
+       lasterr to 0.  Allow empty mode and don't open file, if so.  Call
+       nt_wfopen rather than _wfopen.
+       (io_stream_cygfile::exists): Use GetFileAttributesW rather than
+       _waccess.
+       (io_stream_cygfile::get_size): Use CreateFileW/GetFileSize to get
+       file size on NT.
+       * io_stream_file.cc (io_stream_file::io_stream_file): Initalize lasterr
+       to 0.  Allow empty mode and don't open file, if so.  Call nt_wfopen
+       rather than _wfopen.
+       (io_stream_file::exists): Use GetFileAttributesW rather than _waccess.
+       (io_stream_file::remove): Don't try to remove non-existant file.
+       (io_stream_file::get_size): Use CreateFileW/GetFileSize to get
+       file size on NT.  Add comment to keep track of 2GB border.
+       * mkdir.cc: Remove function pointers for ntdll functions.
+       (init_ntfuncs): Remove function.
+       (mkdir_p): Drop call to init_ntfuncs.  Call ntdll functions directly
+       rather than over local function pointers.
+       * ntdll.h: New file.
+       * postinstall.cc (do_postinstall_reflector): Switch to admins group
+       as primary group after postinstall scripts have been written. 
+       Explain why.
+       (do_postinstall): Add comment.
+       * res.rc: Bump copyright date.
+       * win32.h (class TokenGroupCollection): Remove.
+       * win32.cc (TokenGroupCollection::populate): Remove.
+       (TokenGroupCollection::find): Remove.
+       (NTSecurity::setDefaultSecurity): Drop reading token groups.  Just
+       try to switch to admins group as primary group.
+
 2009-05-07  Corinna Vinschen  <corinna@vinschen.de>
 
        * package_db.cc (ConnectedLoopFinder::doIt): Revert patch from
index bc6848435305b4bae2711d0229a68f35a560f513..bfa8d4a61f15ec196fb5a350e31ba3ea190db61e 100644 (file)
@@ -88,7 +88,8 @@ UserSettings::saveAllSettings()
 io_stream *
 UserSettings::settingFileForLoad(const std::string& relativeName) const
 {
-  io_stream *result = io_stream::open("file://" + relativeName, "rt");
+  io_stream *result = io_stream::open("file://" + local_dir + "\\"
+                                               + relativeName, "rt");
   if (!result)
     result = io_stream::open("cygfile:///etc/setup/" + relativeName, "rt");
   return result;
@@ -105,9 +106,9 @@ UserSettings::settingFileForSave(const std::string& relativeName) const
   if (get_root_dir ().size())
     {
       result = io_stream::open("cygfile:///etc/setup/" + relativeName, "wb");
-      io_stream::remove("file://" + relativeName);
+      io_stream::remove("file://" + local_dir + "\\" + relativeName);
     }
   else
-    result = io_stream::open("file://" + relativeName, "wb");
+    result = io_stream::open("file://" + local_dir + "\\" + relativeName, "wb");
   return result;
 }
index 0fb9fb476e6f6f728735bcdb2dc85b3fdb724180..9f2a30152ead35853ae9ea13deadd4afdb76faaa 100644 (file)
@@ -61,6 +61,16 @@ Auto (advapi32, OpenServiceA, 16);
 Auto (advapi32, QueryServiceStatus, 8);
 Auto (advapi32, StartServiceA, 16);
 
+DLL (ntdll);
+
+Auto (ntdll, NtCreateFile, 44);
+Auto (ntdll, NtOpenFile, 24);
+Auto (ntdll, NtClose, 4);
+Auto (ntdll, NtQueryAttributesFile, 8);
+Auto (ntdll, NtQueryInformationFile, 20);
+Auto (ntdll, NtSetInformationFile, 20);
+Auto (ntdll, RtlInitUnicodeString, 8);
+Auto (ntdll, RtlNtStatusToDosError, 4);
 
 typedef struct {
   DllInfo *dll;
index df898d19d7c58bd92fa520d376e30488a96a2350..210c32c33cd9668041cbe6766ab1e0a86432b2a8 100644 (file)
@@ -176,10 +176,10 @@ make_cygwin_bat ()
       mklongpath (wname, batname.c_str (), len);
 
       /* if the batch file exists, don't overwrite it */
-      if (_waccess (wname, 0) == 0)
+      if (GetFileAttributesW (wname) != INVALID_FILE_ATTRIBUTES)
        return;
 
-      bat = _wfopen (wname, L"wt");
+      bat = nt_wfopen (wname, "wt", 0755);
     }
   else
     {
@@ -222,7 +222,9 @@ save_icon ()
       size_t ilen = iconname.size () + 7;
       WCHAR wname[ilen];
       mklongpath (wname, iconname.c_str (), ilen);
-      f = _wfopen (wname, L"wb");
+      if (GetFileAttributesW (wname) != INVALID_FILE_ATTRIBUTES)
+       return;
+      f = nt_wfopen (wname, "wb", 0644);
     }
   else
     f = fopen (iconname.c_str (), "wb");
index 04e22300777a03663c305b617a157ea095a88c09..afe98981b970f7f7fff235deb0aff856453631ef 100644 (file)
@@ -27,6 +27,10 @@ static const char *cvsid =
 #include "filemanip.h"
 #include "io_stream.h"
 #include "String++.h"
+#include "win32.h"
+#include "ntdll.h"
+#include "io.h"
+#include "fcntl.h"
 
 using namespace std;
 
@@ -35,7 +39,7 @@ using namespace std;
 size_t
 get_file_size (const std::string& name)
 {
-  io_stream *theFile = io_stream::open (name, "rb");
+  io_stream *theFile = io_stream::open (name, "");
   if (!theFile)
     /* To consider: throw an exception ? */
     return 0;
@@ -237,3 +241,243 @@ mklongpath (wchar_t *tgt, const char *src, size_t len)
     }
   return 0;
 }
+
+/* Replacement functions for Win32 API functions.  The joke here is that the
+   replacement functions always use the FILE_OPEN_FOR_BACKUP_INTENT flag. */
+
+extern "C" DWORD WINAPI
+GetFileAttributesW (LPCWSTR wpath)
+{
+  NTSTATUS status;
+  HANDLE h;
+  IO_STATUS_BLOCK io;
+  UNICODE_STRING uname;
+  OBJECT_ATTRIBUTES attr;
+  DWORD ret = INVALID_FILE_ATTRIBUTES;
+
+  PWCHAR wname = (PWCHAR) wpath;
+  wname[1] = L'?';
+  RtlInitUnicodeString (&uname, wname);
+  InitializeObjectAttributes (&attr, &uname, 0, NULL, NULL);
+  status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES, &attr, &io,
+                      FILE_SHARE_VALID_FLAGS,
+                       FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
+  wname[1] = L'\\';
+  if (NT_SUCCESS (status))
+    {
+      FILE_BASIC_INFORMATION fbi;
+
+      status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
+                                      FileBasicInformation);
+      if (NT_SUCCESS (status))
+       ret = fbi.FileAttributes;
+      NtClose (h);
+    }
+  if (!NT_SUCCESS (status))
+    SetLastError (RtlNtStatusToDosError (status));
+  return ret;
+}
+
+extern "C" BOOL WINAPI
+SetFileAttributesW (LPCWSTR wpath, DWORD attribs)
+{
+  NTSTATUS status;
+  HANDLE h;
+  IO_STATUS_BLOCK io;
+  UNICODE_STRING uname;
+  OBJECT_ATTRIBUTES attr;
+
+  PWCHAR wname = (PWCHAR) wpath;
+  wname[1] = L'?';
+  RtlInitUnicodeString (&uname, wname);
+  InitializeObjectAttributes (&attr, &uname, 0, NULL, NULL);
+  status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_ATTRIBUTES, &attr, &io,
+                      FILE_SHARE_VALID_FLAGS,
+                       FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
+  wname[1] = L'\\';
+  if (NT_SUCCESS (status))
+    {
+      FILE_BASIC_INFORMATION fbi;
+
+      memset (&fbi, 0, sizeof fbi);
+      fbi.FileAttributes = attribs ?: FILE_ATTRIBUTE_NORMAL;
+      status = NtSetInformationFile (h, &io, &fbi, sizeof fbi,
+                                    FileBasicInformation);
+      NtClose (h);
+    }
+  if (!NT_SUCCESS (status))
+    SetLastError (RtlNtStatusToDosError (status));
+  return NT_SUCCESS (status);
+}
+
+typedef struct _FILE_RENAME_INFORMATION {
+  BOOLEAN ReplaceIfExists;
+  HANDLE RootDirectory;
+  ULONG FileNameLength;
+  WCHAR FileName[1];
+} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
+
+extern "C" BOOL WINAPI
+MoveFileW (LPCWSTR from, LPCWSTR to)
+{
+  NTSTATUS status;
+  HANDLE h;
+  IO_STATUS_BLOCK io;
+  UNICODE_STRING uname;
+  OBJECT_ATTRIBUTES attr;
+
+  PWCHAR wfrom = (PWCHAR) from;
+  wfrom[1] = L'?';
+  RtlInitUnicodeString (&uname, wfrom);
+  InitializeObjectAttributes (&attr, &uname, 0, NULL, NULL);
+  status = NtOpenFile (&h, READ_CONTROL | DELETE,
+                      &attr, &io, FILE_SHARE_VALID_FLAGS,
+                      FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
+  wfrom[1] = L'\\';
+  if (NT_SUCCESS (status))
+    {
+      size_t len = wcslen (to) * sizeof (WCHAR);
+      PFILE_RENAME_INFORMATION pfri = (PFILE_RENAME_INFORMATION)
+       malloc (sizeof (FILE_RENAME_INFORMATION) + len);
+      pfri->ReplaceIfExists = TRUE;
+      pfri->RootDirectory = NULL;
+      pfri->FileNameLength = len;
+      memcpy (pfri->FileName, to, len);
+      pfri->FileName[1] = L'?';
+      status = NtSetInformationFile(h, &io, pfri,
+                                   sizeof (FILE_RENAME_INFORMATION) + len,
+                                   FileRenameInformation);
+      free (pfri);
+      NtClose (h);
+    }
+  if (!NT_SUCCESS (status))
+    SetLastError (RtlNtStatusToDosError (status));
+  return NT_SUCCESS (status);
+}
+
+extern "C" BOOL WINAPI
+DeleteFileW (LPCWSTR wpath)
+{
+  NTSTATUS status;
+  HANDLE h;
+  IO_STATUS_BLOCK io;
+  UNICODE_STRING uname;
+  OBJECT_ATTRIBUTES attr;
+
+  PWCHAR wname = (PWCHAR) wpath;
+  wname[1] = L'?';
+  RtlInitUnicodeString (&uname, wname);
+  InitializeObjectAttributes (&attr, &uname, 0, NULL, NULL);
+  status = NtOpenFile (&h, READ_CONTROL | DELETE,
+                      &attr, &io, FILE_SHARE_VALID_FLAGS,
+                      FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
+  wname[1] = L'\\';
+  if (NT_SUCCESS (status))
+    {
+      FILE_DISPOSITION_INFORMATION fdi = { TRUE };
+      status = NtSetInformationFile (h, &io, &fdi, sizeof fdi,
+                                    FileDispositionInformation);
+      NtClose (h);
+    }
+  if (!NT_SUCCESS (status))
+    SetLastError (RtlNtStatusToDosError (status));
+  return NT_SUCCESS (status);
+}
+
+extern "C" BOOL WINAPI
+RemoveDirectoryW (LPCWSTR wpath)
+{
+  return DeleteFileW (wpath);
+}
+
+FILE *
+nt_wfopen (const wchar_t *wpath, const char *mode, mode_t perms)
+{
+  NTSTATUS status;
+  HANDLE h;
+  IO_STATUS_BLOCK io;
+  UNICODE_STRING uname;
+  OBJECT_ATTRIBUTES attr;
+  const char *c;
+  ULONG access, disp;
+  int oflags = 0;
+
+  switch (mode[0])
+    {
+    case 'r':
+      access = GENERIC_READ;
+      disp = FILE_OPEN;
+      break;
+    case 'w':
+      access = GENERIC_WRITE;
+      disp = FILE_OVERWRITE_IF;
+      break;
+    case 'a':
+      access = GENERIC_WRITE;
+      disp = FILE_OPEN_IF;
+      oflags = _O_APPEND;
+      break;
+    default:
+      errno = EINVAL;
+      return NULL;
+    }
+  for (c = mode + 1; *c; ++c)
+    switch (*c)
+      {
+      case '+':
+       access = GENERIC_READ | GENERIC_WRITE;
+       break;
+      case 't':
+       oflags |= _O_TEXT;
+       break;
+      case 'b':
+       oflags |= _O_BINARY;
+       break;
+      default:
+       errno = EINVAL;
+       return NULL;
+      }
+  switch (access)
+    {
+    case GENERIC_READ:
+      oflags |= _O_RDONLY;
+      break;
+    case GENERIC_WRITE:
+      access |= WRITE_DAC;
+      oflags |= _O_WRONLY;
+      break;
+    case GENERIC_READ | GENERIC_WRITE:
+      access |= WRITE_DAC;
+      oflags |= _O_RDWR;
+      break;
+    }
+  PWCHAR wname = (PWCHAR) wpath;
+  wname[1] = L'?';
+  RtlInitUnicodeString (&uname, wname);
+  InitializeObjectAttributes (&attr, &uname, 0, NULL, NULL);
+  status = NtCreateFile (&h, access | SYNCHRONIZE, &attr, &io, NULL,
+                        FILE_ATTRIBUTE_NORMAL, FILE_SHARE_VALID_FLAGS, disp, 
+                        FILE_OPEN_FOR_BACKUP_INTENT
+                        | FILE_OPEN_REPARSE_POINT
+                        | FILE_SYNCHRONOUS_IO_NONALERT,
+                        NULL, 0);
+  wname[1] = L'\\';
+  if (!NT_SUCCESS (status))
+    {
+      if (status == STATUS_OBJECT_NAME_NOT_FOUND
+         || status == STATUS_OBJECT_PATH_NOT_FOUND
+         || status == STATUS_NO_SUCH_FILE)
+       errno = ENOENT;
+      else if (status == STATUS_OBJECT_NAME_INVALID)
+       errno = EINVAL;
+      else
+       errno = EACCES;
+      return NULL;
+    }
+  if (io.Information == FILE_CREATED)
+    nt_sec.SetPosixPerms ("", h, perms);
+  int fd = _open_osfhandle ((long) h, oflags);
+  if (fd < 0)
+    return NULL;
+  return _fdopen (fd, mode);
+}
index 5130d7991f422a145c4d055657084512786f02ad..346c4f7659a00f88f6a0e7ca39d51c9cdee2dfa9 100644 (file)
@@ -34,5 +34,6 @@ size_t get_file_size (const std::string& );
 std::string backslash (const std::string& s);
 const char * trail (const char *, const char *);
 int mklongpath (wchar_t *tgt, const char *src, size_t len);
+FILE *nt_wfopen (const wchar_t *wpath, const char *mode, mode_t perms);
 
 #endif /* SETUP_FILEMANIP_H */
index 3aa9f14d12622f2b89489c80d64870ae48d5677b..10823b4818aca508f6616dc9377625f279c88c92 100644 (file)
@@ -132,10 +132,10 @@ get_root_dir_now ()
   read_mounts (std::string ());
 }
 
-io_stream_cygfile::io_stream_cygfile (const std::string& name, const std::string& mode) : fp(), fname(), wname (NULL)
+io_stream_cygfile::io_stream_cygfile (const std::string& name, const std::string& mode) : fp(), lasterr (0), fname(), wname (NULL)
 {
   errno = 0;
-  if (!name.size() || !mode.size())
+  if (!name.size())
   {
     log(LOG_TIMESTAMP) << "io_stream_cygfile: Bad parameters" << endLog;
     return;
@@ -153,20 +153,19 @@ io_stream_cygfile::io_stream_cygfile (const std::string& name, const std::string
   }
 
   fname = cygpath (normalise(name));
-  if (IsWindowsNT ())
+  if (mode.size ())
     {
-      wchar_t lmode[mode.size () + 1];
-      mbstowcs (lmode, mode.c_str (), mode.size () + 1);
-      fp = _wfopen (w_str(), lmode);
+      if (IsWindowsNT ())
+       fp = nt_wfopen (w_str(), mode.c_str (), 0644);
+      else
+       fp = fopen (fname.c_str (), mode.c_str ());
+      if (!fp)
+      {
+       lasterr = errno;
+       log(LOG_TIMESTAMP) << "io_stream_cygfile: fopen(" << name << ") failed " << errno << " "
+         << strerror(errno) << endLog;
+      }
     }
-  else
-    fp = fopen (fname.c_str (), mode.c_str ());
-  if (!fp)
-  {
-    lasterr = errno;
-    log(LOG_TIMESTAMP) << "io_stream_cygfile: fopen(" << name << ") failed " << errno << " "
-      << strerror(errno) << endLog;
-  }
 }
 
 io_stream_cygfile::~io_stream_cygfile ()
@@ -190,7 +189,8 @@ io_stream_cygfile::exists (const std::string& path)
       size_t len = cygpath (normalise(path)).size () + 7;
       WCHAR wname[len];
       mklongpath (wname, cygpath (normalise(path)).c_str (), len);
-      if (_waccess (wname, 0) == 0)
+      DWORD attr = GetFileAttributesW (wname);
+      if (attr != INVALID_FILE_ATTRIBUTES)
        return 1;
     }
   else if (_access (cygpath (normalise(path)).c_str (), 0))
@@ -435,14 +435,12 @@ io_stream_cygfile::get_size ()
   DWORD ret = 0;
   if (IsWindowsNT ())
     {
-      WIN32_FIND_DATAW buf;
-      h = FindFirstFileW (w_str (), &buf);
+      h = CreateFileW (w_str (), GENERIC_READ,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
+                      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
       if (h != INVALID_HANDLE_VALUE)
-       {
-         if (buf.nFileSizeHigh == 0)
-           ret = buf.nFileSizeLow;
-         FindClose (h);
-       }
+       ret = GetFileSize (h, NULL);
+      CloseHandle (h);
     }
   else
     {
index 9cfc7ba212d9d6b1cd94d03606b778ab9bd6458f..3c60013113788e30f66837764e76e045c705e5c4 100644 (file)
@@ -20,6 +20,7 @@ static const char *cvsid =
 
 #if defined(WIN32) && !defined (_CYGWIN_)
 #include "win32.h"
+#include "ntdll.h"
 #include "mklink2.h"
 #include "filemanip.h"
 #endif
@@ -89,21 +90,20 @@ io_stream_file::w_str ()
   return wname;
 }
 
-io_stream_file::io_stream_file (const std::string& name, const std::string& mode) : fp(), fname(name), wname (NULL)
+io_stream_file::io_stream_file (const std::string& name, const std::string& mode) : fp(), lasterr (0), fname(name), wname (NULL)
 {
   errno = 0;
-  if (!name.size() || !mode.size())
+  if (!name.size())
     return;
-  if (IsWindowsNT ())
+  if (mode.size ())
     {
-      wchar_t lmode[mode.size () + 1];
-      mbstowcs (lmode, mode.c_str (), mode.size () + 1);
-      fp = _wfopen (w_str (), lmode); 
+      if (IsWindowsNT ())
+       fp = nt_wfopen (w_str (), mode.c_str (), 0644); 
+      else
+       fp = fopen (fname.c_str (), mode.c_str ());
+      if (!fp)
+       lasterr = errno;
     }
-  else
-    fp = fopen (fname.c_str (), mode.c_str ());
-  if (!fp)
-    lasterr = errno;
 }
 
 io_stream_file::~io_stream_file ()
@@ -123,7 +123,8 @@ io_stream_file::exists (const std::string& path)
       size_t len = path.size () + 7;
       WCHAR wname[len];
       mklongpath (wname, path.c_str (), len);
-      if (_waccess (wname, 0) == 0)
+      DWORD attr = GetFileAttributesW (wname);
+      if (attr != INVALID_FILE_ATTRIBUTES)
        return 1;
     }
   else if (_access (path.c_str(), F_OK) == 0)
@@ -147,7 +148,9 @@ io_stream_file::remove (const std::string& path)
       mklongpath (wpath, path.c_str (), len);
 
       unsigned long w = GetFileAttributesW (wpath);
-      if (w != INVALID_FILE_ATTRIBUTES && w & FILE_ATTRIBUTE_DIRECTORY)
+      if (w == INVALID_FILE_ATTRIBUTES)
+       return 0;
+      if (w & FILE_ATTRIBUTE_DIRECTORY)
        {
          len = wcslen (wpath);
          WCHAR tmp[len + 10];
@@ -169,7 +172,9 @@ io_stream_file::remove (const std::string& path)
   else
     {
       unsigned long w = GetFileAttributesA (path.c_str ());
-      if (w != INVALID_FILE_ATTRIBUTES && w & FILE_ATTRIBUTE_DIRECTORY)
+      if (w == INVALID_FILE_ATTRIBUTES)
+       return 0;
+      if (w & FILE_ATTRIBUTE_DIRECTORY)
        {
          size_t len = path.size ();
          char tmp[len + 10];
@@ -323,6 +328,8 @@ io_stream_file::move (const std::string& from, const std::string& to)
   return rename (from.c_str(), to.c_str());
 }
 
+/* This only handles file < 2GB.  The chance that files in the distro
+   get bigger is rather small, though... */
 size_t
 io_stream_file::get_size ()
 {
@@ -333,14 +340,12 @@ io_stream_file::get_size ()
   DWORD ret = 0;
   if (IsWindowsNT ())
     {
-      WIN32_FIND_DATAW buf;
-      h = FindFirstFileW (w_str(), &buf);
+      h = CreateFileW (w_str (), GENERIC_READ,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
+                      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
       if (h != INVALID_HANDLE_VALUE)
-       {
-         if (buf.nFileSizeHigh == 0)
-           ret = buf.nFileSizeLow;
-         FindClose (h);
-       }
+       ret = GetFileSize (h, NULL);
+      CloseHandle (h);
     }
   else
     {
index cd9fe4c5d165afab99c122b0a42aa6cb7a4b958a..7ff5366a8c9cb31940fe26310ead68f0990698d9 100644 (file)
--- a/mkdir.cc
+++ b/mkdir.cc
@@ -22,7 +22,7 @@ static const char *cvsid =
 
 #if defined(WIN32) && !defined (_CYGWIN_)
 #include "win32.h"
-#include "ddk/ntapi.h"
+#include "ntdll.h"
 #else
 #include <unistd.h>
 #include <string.h>
@@ -35,28 +35,6 @@ static const char *cvsid =
 #include "mkdir.h"
 #include "filemanip.h"
 
-NTSTATUS DDKAPI (*_NtCreateFile) (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
-                                 PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG,
-                                 ULONG, ULONG, ULONG, PVOID, ULONG);
-NTSTATUS DDKAPI (*_NtClose) (HANDLE);
-ULONG NTAPI (*_RtlNtStatusToDosError) (NTSTATUS);
-
-static void
-init_ntfuncs ()
-{
-  HMODULE h;
-  if (!_NtCreateFile && (h = LoadLibrary ("ntdll.dll")))
-    {
-      _NtCreateFile = (NTSTATUS DDKAPI (*) (PHANDLE, ACCESS_MASK,
-                      POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER,
-                      ULONG, ULONG, ULONG, ULONG, PVOID, ULONG))
-                      GetProcAddress (h, "NtCreateFile");
-      _NtClose = (NTSTATUS DDKAPI (*) (HANDLE)) GetProcAddress (h, "NtClose");
-      _RtlNtStatusToDosError = (ULONG NTAPI (*) (NTSTATUS))
-                              GetProcAddress (h, "RtlNtStatusToDosError");
-    }
-}
-
 int
 mkdir_p (int isadir, const char *in_path, mode_t mode)
 {
@@ -86,28 +64,27 @@ mkdir_p (int isadir, const char *in_path, mode_t mode)
          OBJECT_ATTRIBUTES attr;
          IO_STATUS_BLOCK io;
 
-         init_ntfuncs ();
          wpath[1] = '?';
          upath.Length = wcslen (wpath) * sizeof (WCHAR);
          upath.MaximumLength = upath.Length + sizeof (WCHAR);
          upath.Buffer = wpath;
          InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
                                      NULL, NULL);
-         status = _NtCreateFile (&dir,
-                                 STANDARD_RIGHTS_ALL | FILE_LIST_DIRECTORY,
-                                 &attr, &io, NULL, FILE_ATTRIBUTE_DIRECTORY,
-                                 FILE_SHARE_VALID_FLAGS, FILE_CREATE,
-                                 FILE_DIRECTORY_FILE
-                                 | FILE_SYNCHRONOUS_IO_NONALERT
-                                 | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0);
+         status = NtCreateFile (&dir,
+                                STANDARD_RIGHTS_ALL | FILE_LIST_DIRECTORY,
+                                &attr, &io, NULL, FILE_ATTRIBUTE_DIRECTORY,
+                                FILE_SHARE_VALID_FLAGS, FILE_CREATE,
+                                FILE_DIRECTORY_FILE
+                                | FILE_SYNCHRONOUS_IO_NONALERT
+                                | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0);
          if (NT_SUCCESS (status))
            {
              nt_sec.SetPosixPerms (path, dir, mode);
-             _NtClose (dir);
+             NtClose (dir);
              return 0;
            }
          else
-           SetLastError (_RtlNtStatusToDosError (status));
+           SetLastError (RtlNtStatusToDosError (status));
        }
       else if (CreateDirectoryA (path, 0))
        return 0;
diff --git a/ntdll.h b/ntdll.h
new file mode 100644 (file)
index 0000000..0041cf9
--- /dev/null
+++ b/ntdll.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2009, Red Hat, Inc.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ */
+
+#ifndef SETUP_NTDLL_H
+#define SETUP_NTDLL_H
+
+#include "ddk/ntapi.h"
+
+extern "C" {
+NTSTATUS DDKAPI NtCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
+                             PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,
+                             ULONG, ULONG, PVOID, ULONG);
+NTSTATUS DDKAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
+                           PIO_STATUS_BLOCK, ULONG, ULONG);
+NTSTATUS DDKAPI NtClose (HANDLE);
+NTSTATUS DDKAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
+                                      PFILE_BASIC_INFORMATION);
+NTSTATUS DDKAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
+                                       ULONG, FILE_INFORMATION_CLASS);
+NTSTATUS DDKAPI NtSetInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
+                                     FILE_INFORMATION_CLASS);
+ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
+VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
+};
+
+#endif /* SETUP_NTDLL_H */
index 97b5bed3153368fe2b08dba704696f43fdf09b7c..5e1ae5084e4de49df504d1878464c282281cc6a6 100644 (file)
@@ -25,6 +25,7 @@ static const char *cvsid =
 #include "find.h"
 #include "mount.h"
 #include "script.h"
+#include "state.h"
 #include "FindVisitor.h"
 #include "package_db.h"
 #include "package_meta.h"
@@ -112,8 +113,10 @@ do_postinstall_thread (HINSTANCE h, HWND owner)
   for (i = packages.begin (); i != packages.end (); ++i)
     {
       packagemeta & pkg = **i;
+
       for_each (pkg.installed.scripts().begin(), pkg.installed.scripts().end(),
                RunScript(pkg.name, pkg.installed.scripts().size()));
+
       ++k;
       Progress.SetBar2 (k, numpkg);
     }
@@ -142,6 +145,11 @@ do_postinstall_reflector (void *p)
   }
   TOPLEVEL_CATCH("postinstall");
 
+  /* Revert primary group to admins group.  This allows to create all the
+     state files written by setup as admin group owned. */
+  if (root_scope == IDC_ROOT_SYSTEM)
+    nt_sec.setAdminGroup ();
+
   ExitThread(0);
 }
 
@@ -150,7 +158,13 @@ static HANDLE context[2];
 void
 do_postinstall (HINSTANCE h, HWND owner)
 {
-  nt_sec.resetPrimaryGroup ();
+  /* Switch back to original primary group.  Otherwise we end up with a
+     broken passwd entry for the current user.
+     FIXME: Unfortunately this has the unfortunate side-effect that *all*
+     files created via postinstall are group owned by the original primary
+     group of the user.  Find a way to avoid this at one point. */
+  if (root_scope == IDC_ROOT_SYSTEM)
+    nt_sec.resetPrimaryGroup ();
 
   context[0] = h;
   context[1] = owner;
diff --git a/res.rc b/res.rc
index 91fd67e20d26af286619cceb5ba7ad3285618a87..e6fd2708942fe7ad6df3092511b8d35d727df262 100644 (file)
--- a/res.rc
+++ b/res.rc
@@ -265,7 +265,7 @@ BEGIN
                     "necessary.",IDC_SPLASH_TEXT,115,25,195,90
     ICON            IDI_CYGWIN,IDC_SPLASH_ICON,114,114,21,20,WS_GROUP
     LTEXT           "Version (unknown)",IDC_VERSION,115,137,195,10
-    LTEXT           "Copyright 2000-2008",IDC_SPLASH_COPYR,115,150,195,8
+    LTEXT           "Copyright 2000-2009",IDC_SPLASH_COPYR,115,150,195,8
     LTEXT           "http://www.cygwin.com/",IDC_SPLASH_URL,115,162,90,8
 END
 
index b7fd1e63a4dfc6d001906a891fed919d330582be..97565071d1a9d2732bfef8b71ba6f6c4707a9bd6 100644 (file)
--- a/win32.cc
+++ b/win32.cc
@@ -27,31 +27,6 @@ static const char *cvsid =
 
 NTSecurity nt_sec;
 
-void
-TokenGroupCollection::populate ()
-{
-  if (!GetTokenInformation (token.theHANDLE(), TokenGroups, buffer,
-                            bufferSize, &bufferSize))
-    {
-      log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
-               GetLastError () << endLog;
-       return;
-    }
-  populated_ = true;
-}
-
-bool
-TokenGroupCollection::find (SIDWrapper const &aSID) const
-{
-  if (!populated ())
-    return false;
-  TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buffer;
-  for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
-    if (EqualSid (groups->Groups[pg].Sid, aSID.theSID ()))
-      return true;
-  return false;
-}
-
 void
 NTSecurity::SetPosixPerms (const char *fname, HANDLE fh, mode_t mode)
 {
@@ -357,20 +332,10 @@ NTSecurity::setDefaultSecurity ()
       NoteFailedAPI("GetTokenInformation(pgrp)");
       primaryGroupSID.pgrp.PrimaryGroup = (PSID) NULL;
     }
-  /* Get the token groups */
-  if (!GetTokenInformation (token.theHANDLE(), TokenGroups, NULL, 0, &size)
-         && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
-    {
-      NoteFailedAPI("GetTokenInformation(groups)");
-      return;
-    }
-  TokenGroupCollection ntGroups(size, token);
-  ntGroups.populate ();
-  if (!ntGroups.populated ())
-    return;
-  /* Set the primary group to the Administrators group, but only if
-     the user is admin and if "Install for all users" has been chosen. */
-  if (root_scope == IDC_ROOT_SYSTEM && ntGroups.find (administratorsSID))
+  /* Try to set the primary group to the Administrators group, but only if
+     "Install for all users" has been chosen.  If it doesn't work, we're
+     no admin and that's all there's to say about it. */
+  if (root_scope == IDC_ROOT_SYSTEM)
     setAdminGroup ();
 }
 
diff --git a/win32.h b/win32.h
index 71185dd3f27b35bbd38d76088b5dbbad85ee41b0..d944e8752053fab1c1a3cedf19ad75ba2e8c81ad 100644 (file)
--- a/win32.h
+++ b/win32.h
@@ -90,26 +90,6 @@ class HANDLEWrapper {
     HANDLE value;
 };
 
-class TokenGroupCollection {
-  public:
-    TokenGroupCollection (DWORD aSize, HANDLEWrapper &aHandle) :
-                         populated_(false), buffer(new char[aSize]), 
-                         bufferSize(aSize), token(aHandle) {}
-    ~TokenGroupCollection () { if (buffer) delete[] buffer; }
-
-    /* prevent synthetics */
-    TokenGroupCollection& operator= (TokenGroupCollection const &);
-    TokenGroupCollection (TokenGroupCollection const &);
-    bool find (SIDWrapper const &) const;
-    bool populated() const { return populated_; }
-    void populate();
-  private:
-    mutable bool populated_;
-    char *buffer;
-    DWORD bufferSize;
-    HANDLEWrapper &token;
-};
-
 class NTSecurity
 {
 public:
This page took 0.062186 seconds and 5 git commands to generate.