libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
Directory.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright � 2002 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 #include "stdafx.h"
20 
21 #include "Directory.hpp"
22 
23 #include "../../../core/info.hpp"
24 #include "../../../core/exception.hpp"
25 #include "../../../core/trace.hpp"
26 
27 /////////////////////////////////////////////////////////////////////////////
28 
29 using namespace libjmmcg;
30 using namespace NTUtils;
31 
32 /////////////////////////////////////////////////////////////////////////////
33 
35 
36 /////////////////////////////////////////////////////////////////////////////
37 
38 const tchar security_lib_name[]=_T("advapi32.dll");
39 #ifdef UNICODE
40  const TCHAR SetFileSecurity_name[]=_T("SetFileSecurityW");
41 #else
42  const tchar SetFileSecurity_name[]=_T("SetFileSecurityA");
43 #endif // !UNICODE
44 
45 /////////////////////////////////////////////////////////////////////////////
46 
47 Directory::Directory(const tstring &unc_to_dir,const TCHAR * const machine,const TCHAR * const user,const DWORD access)
48 : LoadLibraryWrapper(security_lib_name),
49  pSetFileSecurity(reinterpret_cast<SetFileSecurityType>(::GetProcAddress(Handle(),SetFileSecurity_name))),
50  unc(unc_to_dir+dir_separator_s) {
51  JMMCG_TRACE(_T("Directory::Directory(...): Dir name: ")<<unc);
52  unsigned long err=sd.Allow(machine,user,access);
53  if (err) {
54  info::function info(__LINE__,__PRETTY_FUNCTION__,typeid(*this),info::function::argument(_T("const tstring &"),unc_to_dir));
55  info.add_arg(_T("const tstring &"),machine);
56  info.add_arg(_T("const tstring &"),user);
57  info.add_arg(_T("const DWORD"),access);
58  throw exception_type(_T("Failed to add access allowed ACE to security descriptor for user."),info,__REV_INFO__);
59  }
60  err=sd.Allow(machine,_T("SYSTEM"),GENERIC_ALL);
61  if (err) {
62  info::function info(__LINE__,__PRETTY_FUNCTION__,typeid(*this),info::function::argument(_T("const tstring &"),unc_to_dir));
63  info.add_arg(_T("const tstring &"),machine);
64  info.add_arg(_T("const tstring &"),user);
65  info.add_arg(_T("const DWORD"),access);
66  throw exception_type(_T("Failed to add access allowed ACE to security descriptor for user 'SYSTEM' on the specified machine with an access mask of 'GENERIC_ALL'."),info,__REV_INFO__);
67  }
68  SECURITY_ATTRIBUTES sa={
69  sizeof(SECURITY_ATTRIBUTES),
70  const_cast<SECURITY_DESCRIPTOR *>(&sd.SD()),
71  true
72  };
73  if (!::CreateDirectory(unc.c_str(),&sa)) {
74  info::function info(__LINE__,__PRETTY_FUNCTION__,typeid(*this),info::function::argument(_T("const tstring &"),unc_to_dir));
75  info.add_arg(_T("const tstring &"),machine);
76  info.add_arg(_T("const tstring &"),user);
77  info.add_arg(_T("const DWORD"),access);
78  throw exception_type(_T("Failed to create the specified directory on the specified machine using the specified user name with the specified access mask."),info,__REV_INFO__);
79  }
80 }
81 
82 Directory::~Directory(void) {
83  CFileFind finder;
84  bool bWorking = finder.FindFile((unc+wildcard).c_str());
85  bool emptied=true;
86  while (bWorking) {
87  bWorking=finder.FindNextFile();
88  if (!finder.IsDirectory()) {
89  const tstring path(unc+finder.GetFileName().GetBuffer(0));
90  if (pSetFileSecurity) {
91  // Ensure we have permission to delete the file...
92  (*pSetFileSecurity)(path.c_str(),DACL_SECURITY_INFORMATION,const_cast<SECURITY_DESCRIPTOR *>(&sd.SD()));
93  }
94  JMMCG_TRACE(_T("Directory::~Directory(): Deleting: ")<<path);
95  if (!DeleteFile(path.c_str())) {
96  JMMCG_TRACE(_T("Directory::~Directory(): Failed to delete: ")<<path);
97  emptied=false;
98  }
99  }
100  }
101  bool err=::RemoveDirectory(unc.c_str());
102  if (!err) {
103  std::stringstream ss;
104  ss<<"Failed to delete directory '"<<unc<<"'. "<<(emptied ? "For some unknown reason" : "Because it wasn't empty")<<".";
105  throw exception_type(ss.str(),info::function(__LINE__,__PRETTY_FUNCTION__,typeid(*this)),__REV_INFO__);
106  }
107  JMMCG_TRACE(_T("Directory::~Directory(): Deleted (and all contents) directory: ")<<unc);
108 }