0028110: Configuration - specify Unicode charset instead of multibyte in project...
[occt.git] / src / OSD / OSD_Process.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _WIN32
16
17 #include <OSD_Environment.hxx>
18 #include <OSD_OSDError.hxx>
19 #include <OSD_Path.hxx>
20 #include <OSD_Process.hxx>
21 #include <OSD_WhoAmI.hxx>
22 #include <Quantity_Date.hxx>
23 #include <TCollection_AsciiString.hxx>
24
25 const OSD_WhoAmI Iam = OSD_WProcess;
26
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <sys/param.h>
30 #include <sys/time.h>
31 #include <pwd.h>       // For command getpwuid
32 #include <unistd.h>
33
34 OSD_Process::OSD_Process(){
35 }
36
37
38 Standard_Integer OSD_Process::Spawn (const TCollection_AsciiString& cmd,
39                          const Standard_Boolean /*ShowWindow*/)
40 {
41  return system(cmd.ToCString());
42 }
43
44
45 void OSD_Process::TerminalType(TCollection_AsciiString& Name){
46 TCollection_AsciiString which="TERM";
47 OSD_Environment term (which,"");
48
49  term.Value();
50  which = term.Value();
51  Name = term.Name();
52 }
53
54
55 // Get date of system date
56
57 Quantity_Date  OSD_Process::SystemDate(){
58 Quantity_Date result;
59 Standard_Integer month=0,day=0,year=0,hh=0,mn=0,ss=0;
60 struct tm transfert;
61 struct timeval tval;
62 struct timezone tzone;
63 int status;
64
65  status = gettimeofday( &tval, &tzone );
66  if (status == -1) myError.SetValue (errno, Iam, "GetSystem");
67  else {
68   memcpy(&transfert, localtime((time_t *)&tval.tv_sec), sizeof(struct
69 tm));
70   month = transfert.tm_mon + 1;  // Add to January (month #1)
71   day   = transfert.tm_mday;
72   year  = transfert.tm_year;
73   hh    = transfert.tm_hour;
74   mn    = transfert.tm_min ;
75   ss    = transfert.tm_sec ;
76 }
77
78  result.SetValues ( month, day, year+1900, hh, mn, ss);
79  return (result);
80 }
81
82
83 Standard_Integer OSD_Process::ProcessId(){
84  return (getpid());
85 }
86
87 TCollection_AsciiString OSD_Process::UserName(){
88  struct passwd *infos;
89  infos = getpwuid(getuid()); 
90  TCollection_AsciiString result=infos->pw_name;
91
92  return(result);
93 }
94
95 Standard_Boolean OSD_Process::IsSuperUser (){
96   if (getuid()) {
97     return Standard_False;
98   }
99   else {
100     return Standard_True;
101   }
102 }
103
104
105 OSD_Path OSD_Process::CurrentDirectory(){
106 char cwd[MAXPATHLEN+1] ;
107 OSD_Path result;
108 TCollection_AsciiString Name;
109
110  if (!getcwd(cwd,MAXPATHLEN+1))
111    myError.SetValue (errno, Iam, "Where");
112  else {
113    Name = cwd;
114
115 //   JPT : August,20 1993. This code has been replaced by #ifdef ... #endif
116 //   position = Name.SearchFromEnd(".");
117 //   if (position != -1){
118 //     Ext = Name;
119 //     Ext.Remove(1,position);
120 //     Name.Remove( position,Ext.Length()+1);
121 //   }
122 //   result.SetValues("","","","","",Name,Ext);
123 //   End
124
125 #if defined(vax) || defined(__vms)
126    Standard_Integer iDisk = Name.Search(":");
127    if (iDisk){
128      TCollection_AsciiString Disk;
129      TCollection_AsciiString Directory;
130      Disk = Name.SubString(1,iDisk-1);
131      Directory = Name.SubString(iDisk+1,Name.Length());
132      result.SetValues("","","",Disk,Directory,"","");
133    }
134 #else
135    Name += TCollection_AsciiString("/");
136    result = OSD_Path(Name);
137    //      result.SetValues("","","","",Name,"","");
138 #endif
139
140  }
141 return (result);
142 }
143
144
145 void OSD_Process::SetCurrentDirectory(const OSD_Path& where){
146 TCollection_AsciiString Name;
147 int status;
148
149  where.SystemName(Name);
150
151  status = chdir (Name.ToCString());
152  if (status == -1) myError.SetValue(errno, Iam, "Move to directory");
153 }
154
155
156 void OSD_Process::Reset(){
157  myError.Reset();
158 }
159
160 Standard_Boolean OSD_Process::Failed()const{
161  return( myError.Failed());
162 }
163
164 void OSD_Process::Perror() {
165  myError.Perror();
166 }
167
168
169 Standard_Integer OSD_Process::Error()const{
170  return( myError.Error());
171 }
172
173 #else
174
175 //------------------------------------------------------------------------
176 //-------------------  WNT Sources of OSD_Path ---------------------------
177 //------------------------------------------------------------------------
178
179 //it is important to undefine NOUSER and enforce including <windows.h> before
180 //Standard_Macro.hxx defines it and includes <windows.h> causing compilation errors
181 #ifdef NOUSER
182 #undef NOUSER /* we need SW_HIDE from windows.h */
183 #endif
184 #include <windows.h>
185
186 #ifdef SetCurrentDirectory
187 # undef SetCurrentDirectory /* undefine SetCurrentDirectory from <winbase.h> to correctly include <OSD_Process.hxx> */
188 #endif
189 #include <OSD_Process.hxx>
190
191 #include <OSD_Path.hxx>
192 #include <Quantity_Date.hxx>
193 #include <Standard_PExtCharacter.hxx>
194 #include <TCollection_ExtendedString.hxx>
195
196 #include <OSD_WNT_1.hxx>
197 #include <LMCONS.H> // for UNLEN - maximum user name length GetUserName()
198
199 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
200
201 // =======================================================================
202 // function : OSD_Process
203 // purpose  :
204 // =======================================================================
205 OSD_Process::OSD_Process()
206 {
207   //
208 }
209
210 // =======================================================================
211 // function : Spawn
212 // purpose  :
213 // =======================================================================
214 Standard_Integer OSD_Process::Spawn (const TCollection_AsciiString& theCmd,
215                                                        const Standard_Boolean theToShowWindow)
216 {
217 #ifndef OCCT_UWP
218   STARTUPINFOW aStartupInfo;
219   ZeroMemory (&aStartupInfo, sizeof(STARTUPINFO));
220   aStartupInfo.cb = sizeof(STARTUPINFO);
221   if (!theToShowWindow)
222   {
223     aStartupInfo.dwFlags     = STARTF_USESHOWWINDOW;
224     aStartupInfo.wShowWindow = SW_HIDE;
225   }
226
227   DWORD aRes = 0;
228   TCollection_ExtendedString aCmdWide (theCmd);
229   wchar_t* aCmdWidePtr = const_cast<wchar_t*>(aCmdWide.ToWideString()); // CreateProcessW() can modify content of this string
230   PROCESS_INFORMATION aProcessInfo;
231   if (!CreateProcessW (NULL, aCmdWidePtr, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &aStartupInfo, &aProcessInfo))
232   {
233     _osd_wnt_set_error (myError, OSD_WProcess);
234     aRes = myError.Error();
235   }
236   else
237   {
238     CloseHandle (aProcessInfo.hThread);
239     WaitForSingleObject (aProcessInfo.hProcess, INFINITE);
240     GetExitCodeProcess  (aProcessInfo.hProcess, &aRes);
241     CloseHandle (aProcessInfo.hProcess);
242   }
243
244   return aRes;
245 #else
246   (void )theCmd;
247   (void )theToShowWindow;
248   return 0;
249 #endif
250 }
251
252 void OSD_Process :: TerminalType ( TCollection_AsciiString& Name ) {
253
254  Name = "WIN32 console";
255
256 }  // end OSD_Process :: TerminalType
257
258 Quantity_Date OSD_Process :: SystemDate () {
259
260  Quantity_Date retVal;
261  SYSTEMTIME    st;
262
263  GetLocalTime ( &st );
264
265  retVal.SetValues (
266          st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds
267         );
268
269  return retVal;
270
271 }  // end OSD_Process :: SystemDate
272
273 // =======================================================================
274 // function : UserName
275 // purpose  :
276 // =======================================================================
277 TCollection_AsciiString OSD_Process::UserName()
278 {
279 #ifndef OCCT_UWP
280   wchar_t aUserName[UNLEN + 1];
281   DWORD aNameSize = UNLEN + 1;
282   TCollection_AsciiString retVal;
283   if (!GetUserNameW (aUserName, &aNameSize))
284   {
285     _osd_wnt_set_error(myError, OSD_WProcess);
286     return TCollection_AsciiString();
287   }
288   return TCollection_AsciiString (aUserName);
289 #else
290   return TCollection_AsciiString();
291 #endif
292 }
293
294 Standard_Boolean OSD_Process :: IsSuperUser () {
295 #ifndef OCCT_UWP
296  Standard_Boolean retVal = FALSE;
297  PSID             pSIDadmin;
298  HANDLE           hProcessToken = INVALID_HANDLE_VALUE;
299  PTOKEN_GROUPS    pTKgroups = NULL;
300
301  if (  !OpenProcessToken (
302          GetCurrentProcess (),
303          TOKEN_QUERY, &hProcessToken
304         ) ||
305         (  pTKgroups = ( PTOKEN_GROUPS )GetTokenInformationEx (
306                                          hProcessToken, TokenGroups
307                                         )
308         ) == NULL
309  )
310
311   _osd_wnt_set_error ( myError, OSD_WProcess );
312
313  else {
314  
315   pSIDadmin = AdminSid ();
316
317   for ( int i = 0; i < ( int )pTKgroups -> GroupCount; ++i )
318
319    if (  EqualSid ( pTKgroups -> Groups[ i ].Sid, pSIDadmin )  ) {
320    
321     retVal = TRUE;
322     break;
323    
324    }  // end if
325  
326  }  // end else
327
328  if ( hProcessToken != INVALID_HANDLE_VALUE ) CloseHandle ( hProcessToken );
329  if ( pTKgroups     != NULL                 ) FreeTokenInformation ( pTKgroups );
330
331  return retVal;
332 #else
333  return FALSE;
334 #endif
335 }  // end OSD_Process :: IsSuperUser
336
337 // =======================================================================
338 // function : ProcessId
339 // purpose  :
340 // =======================================================================
341 Standard_Integer OSD_Process::ProcessId()
342 {
343   return (Standard_Integer )GetCurrentProcessId();
344 }
345
346 // =======================================================================
347 // function : CurrentDirectory
348 // purpose  :
349 // =======================================================================
350 OSD_Path OSD_Process::CurrentDirectory()
351 {
352   OSD_Path anCurrentDirectory;
353 #ifndef OCCT_UWP
354   const DWORD aBuffLen = GetCurrentDirectoryW (0, NULL);
355   if (aBuffLen > 0)
356   {
357     wchar_t* aBuff = new wchar_t[aBuffLen + 1];
358     GetCurrentDirectoryW (aBuffLen, aBuff);
359     aBuff[aBuffLen] = L'\0';
360     const TCollection_AsciiString aPath (aBuff);
361     delete[] aBuff;
362
363     anCurrentDirectory = OSD_Path (aPath);
364   }
365   else
366   {
367     _osd_wnt_set_error (myError, OSD_WProcess);
368   }
369 #endif
370   return anCurrentDirectory;
371 }
372
373 void OSD_Process :: SetCurrentDirectory ( const OSD_Path& where ) {
374
375  TCollection_AsciiString path;
376
377  where.SystemName ( path );
378  TCollection_ExtendedString pathW(path);
379
380  if (!::SetCurrentDirectoryW (pathW.ToWideString()))
381
382   _osd_wnt_set_error ( myError, OSD_WProcess );
383
384 }  // end OSD_Process :: SetCurrentDirectory
385
386 Standard_Boolean OSD_Process :: Failed () const {
387
388  return myError.Failed ();
389
390 }  // end OSD_Process :: Failed
391
392 void OSD_Process :: Reset () {
393
394  myError.Reset ();
395
396 }  // end OSD_Process :: Reset
397
398 void OSD_Process :: Perror () {
399
400  myError.Perror ();
401
402 }  // end OSD_Process :: Perror
403
404 Standard_Integer OSD_Process :: Error () const {
405
406  return myError.Error ();
407
408 }  // end OSD_Process :: Error
409
410 #endif