libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
NetShare.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 "NetShare.hpp"
23 #include "OnNT.hpp"
24 
25 #include "../../../core/trace.hpp"
26 #include "../../../core/unicode_conversions.hpp"
27 
28 /////////////////////////////////////////////////////////////////////////////
29 
30 const TCHAR NetShareAdd_name[]=_T("NetShareAdd");
31 const TCHAR NetShareDel_name[]=_T("NetShareDel");
32 
33 using namespace libNTUtils;
34 using namespace NTUtils;
35 
36 /////////////////////////////////////////////////////////////////////////////
37 
38 NetShare::NetShare(void) :
39  LoadLibraryWrapper(OnNT() ? netapi32_nt_lib_name : server_info_9X_lib_name),
40  pNetShareAdd(reinterpret_cast<NetShareAddType>(::GetProcAddress(Handle(),NetShareAdd_name))),
41  pNetShareDel(reinterpret_cast<NetShareDelType>(::GetProcAddress(Handle(),NetShareDel_name)))
42 {
43  assert(pNetShareAdd);
44  assert(pNetShareDel);
45  deleted=true;
46 }
47 
48 inline
49 NetShare::NetShare(const tstring &DirectoryToShare,const TCHAR * const Sharename,const TCHAR * const description,const TCHAR * const Server,const DWORD max_connections,SECURITY_DESCRIPTOR *sd,const DWORD share_perms) :
50  LoadLibraryWrapper(OnNT() ? netapi32_nt_lib_name : server_info_9X_lib_name),
51  pNetShareAdd(reinterpret_cast<NetShareAddType>(::GetProcAddress(Handle(),NetShareAdd_name))),
52  pNetShareDel(reinterpret_cast<NetShareDelType>(::GetProcAddress(Handle(),NetShareDel_name)))
53 {
54  assert(pNetShareAdd);
55  assert(pNetShareDel);
56  deleted=true;
57  Create(DirectoryToShare,Sharename,description,Server,max_connections,sd,share_perms);
58 }
59 
60 NetShare::NetShare(const tstring &DirectoryToShare,const TCHAR * const Sharename,const TCHAR * const description,const TCHAR * const Username,const TCHAR * const Server,const DWORD access_mask,const DWORD max_connections,const DWORD share_perms) :
61  LoadLibraryWrapper(OnNT() ? netapi32_nt_lib_name : server_info_9X_lib_name),
62  pNetShareAdd(reinterpret_cast<NetShareAddType>(::GetProcAddress(Handle(),NetShareAdd_name))),
63  pNetShareDel(reinterpret_cast<NetShareDelType>(::GetProcAddress(Handle(),NetShareDel_name))) {
64  assert(pNetShareAdd);
65  assert(pNetShareDel);
66  deleted=true;
67  Create(DirectoryToShare,Sharename,description,Username,Server,access_mask,max_connections,share_perms);
68 }
69 
70 NetShare::~NetShare(void) {
71  Delete();
72 }
73 
74 inline bool NetShare::Create(const tstring &DirectoryToShare,const TCHAR * const Sharename,const TCHAR * const description,const TCHAR * const Server,const DWORD max_connections,const SECURITY_DESCRIPTOR * const sd,const DWORD share_perms) {
75  if (deleted) {
76  assert(Sharename);
77  assert(description);
78  SHARE_INFO_502 si502;
79  // setup share info structure
80  // Note that we *must* use Unicode strings, as despite the declarations (which are
81  // wrong), the function will error if Unicode strings aren't used. Hence the
82  // silly casting.
83  sharename_w=TStringToWString(Sharename);
84  si502.shi502_netname = reinterpret_cast<LPWSTR>(const_cast<wchar_t *>(sharename_w.c_str()));
85  si502.shi502_type = STYPE_DISKTREE;
86  std::wstring rmb(TStringToWString(description));
87  si502.shi502_remark = reinterpret_cast<LPWSTR>(const_cast<wchar_t *>(rmb.c_str()));
88  si502.shi502_permissions = share_perms;
89  si502.shi502_max_uses = max_connections;
90  si502.shi502_current_uses = 0;
91  std::wstring dirb(TStringToWString(DirectoryToShare));
92  si502.shi502_path = reinterpret_cast<LPWSTR>(const_cast<wchar_t *>(dirb.c_str()));
93  si502.shi502_passwd = NULL;
94  si502.shi502_reserved = 0;
95  si502.shi502_security_descriptor = const_cast<SECURITY_DESCRIPTOR *>(sd);
96  machine_w=(Server ? TStringToWString(Server) : L"");
97  NET_API_STATUS nas=(*pNetShareAdd)(
98  machine_w.c_str(), // share is on local machine
99  502, // info-level
100  reinterpret_cast<BYTE *>(&si502), // info-buffer
101  NULL // don't bother with parm
102  );
103  if (nas==NERR_Success) {
104  JMMCG_TRACE(_T("NetShare::Create(...): Successfully created the share '")<<Sharename<<_T("' (path '")<<DirectoryToShare<<_T("') on machine '")<<(Server ? Server : _T(""))<<_T("'"));
105  deleted=false;
106  return false;
107  }
108  JMMCG_TRACE(_T("NetShare::Create(...): NetShareAdd error: 0x")<<std::hex<<nas);
109  JMMCG_TRACE(_T("\tDid not create the share '")<<Sharename<<_T("' (path '")<<DirectoryToShare<<_T("') on machine '")<<(Server ? Server : _T(""))<<_T("'"));
110  deleted=true;
111  return true;
112  }
113  return false;
114 }
115 
116 bool NetShare::Create(const tstring &DirectoryToShare,const TCHAR * const Sharename,const TCHAR * const description,const TCHAR * const Username,const TCHAR * const Server,const DWORD access_mask,const DWORD max_connections,const DWORD share_perms) {
117  register OSVERSIONINFO osinfo;
118  osinfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
119  if (::GetVersionEx(&osinfo) && osinfo.dwPlatformId!=VER_PLATFORM_WIN32_NT) {
120  // Create the share with no restrictions if it's a non-NT box.
121  return Create(DirectoryToShare,Sharename,description,Server,max_connections,NULL,share_perms);
122  }
123  if (!sd.Allow(NULL,Username,access_mask)) {
124  return Create(DirectoryToShare,Sharename,description,Server,max_connections,&sd.SD(),share_perms);
125  }
126  return true;
127 }
128 
129 bool NetShare::Delete(void) {
130  if (!deleted) {
131  deleted=true;
132  bool ret=((*pNetShareDel)(machine_w.c_str(),sharename_w.c_str(),0)==NERR_Success);
133  JMMCG_TRACE(_T("NetShare::Create(...): Deleted the share '")<<WStringToTString(sharename_w)<<_T("') on machine '")<<WStringToTString(machine_w)<<_T("', yes/no: ")<<ret);
134  return ret;
135  }
136  return false;
137 }
138 
139 bool NetFindNTSubDir(NetShare &share,const TCHAR * const sharename,const TCHAR * const machine,const TCHAR * const path,const TCHAR * const username,const DWORD access_mask,const DWORD max_connections,const DWORD share_perms) {
140  const TCHAR drive_share_name[]=_T("A1_dir_share$");
141  const TCHAR description[]=_T("Temporary share on drive letter...");
142  const TCHAR search_pattern[]=_T("\\*");
143  NetShare drive_share;
144  // It would be perverse to have the path on a floppy on the remote machine....
145  tstring dir_ltr(_T("c"));
146  do {
147  if (!drive_share.Create(dir_ltr+_T(":\\"),drive_share_name,description,username,machine,GENERIC_READ,1,ACCESS_READ)) {
148  // Found a drive on the remote machine. Is it the right one?
149  CFileFind finder;
150  tstring pattern(machine);
151  pattern+=dir_separator;
152  pattern+=drive_share_name;
153  int len=pattern.length();
154  // Note that we assume they are not so perverse as to plonk NT in a path like "?:\*\*\...\*\system32" although it is possible...
155  pattern+=search_pattern;
156  pattern+=path;
157  if (finder.FindFile(pattern.c_str()) && finder.FindNextFile()) {
158  assert(finder.IsDirectory());
159  tstring remote_sys_path(dir_ltr);
160  remote_sys_path+=_T(':');
161  remote_sys_path+=static_cast<const TCHAR *>(finder.GetFilePath().Right(finder.GetFilePath().GetLength()-len));
162  if (!share.Create(remote_sys_path,sharename,NULL,username,machine,access_mask,max_connections,share_perms)) {
163  return false;
164  }
165  }
166  }
167  drive_share.Delete();
168  }
169  while (++*dir_ltr.begin()<=_T('z'));
170  return true;
171 }