File: sflprocw.imp

package info (click to toggle)
generator-scripting-language 4.1.5-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,424 kB
  • sloc: ansic: 106,060; cpp: 2,232; pascal: 762; sh: 535; xml: 424; makefile: 194
file content (216 lines) | stat: -rw-r--r-- 10,501 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*===========================================================================*
 *                                                                           *
 *  sflprocw.imp - Process control functions for Win32                       *
 *                                                                           *
 *  Copyright (c) 1991-2010 iMatix Corporation                               *
 *                                                                           *
 *  ------------------ GPL Licensed Source Code ------------------           *
 *  iMatix makes this software available under the GNU General               *
 *  Public License (GPL) license for open source projects.  For              *
 *  details of the GPL license please see www.gnu.org or read the            *
 *  file license.gpl provided in this package.                               *
 *                                                                           *
 *  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 3 of           *
 *  the License, or (at your option) any later version.                      *
 *                                                                           *
 *  This program is distributed in the hope that it will be useful,          *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU General Public License for more details.                             *
 *                                                                           *
 *  You should have received a copy of the GNU General Public                *
 *  License along with this program in the file 'license.gpl'; if            *
 *  not, see <http://www.gnu.org/licenses/>.                                 *
 *                                                                           *
 *  You can also license this software under iMatix's General Terms          *
 *  of Business (GTB) for commercial projects.  If you have not              *
 *  explicitly licensed this software under the iMatix GTB you may           *
 *  only use it under the terms of the GNU General Public License.           *
 *                                                                           *
 *  For more information, send an email to info@imatix.com.                  *
 *  --------------------------------------------------------------           *
 *===========================================================================*/
 
/*  Windows (32-bit) implementation of the SFL process_create_full()       
 *  This function receives input in the form of a pointer to a PROCESS_DATA
 *  structure called procinfo.  See sflproc.c for details.
 */

    PROCESS
        process;                        /*  Our created process handle       */
    ARGLIST
        *arglist;                       /*  Argument list                    */
    int
        old_stdin  = NULL_HANDLE,       /*  Dup'd handle for old stdin       */
        old_stdout = NULL_HANDLE,       /*  Dup'd handle for old stdout      */
        old_stderr = NULL_HANDLE;       /*  Dup'd handle for old stderr      */
    Bool
        free_envv = FALSE;              /*  True if we should free envv      */
    const char
        *path,                          /*  Path to search                   */
        *shell,                         /*  Shell to use                     */
        **searchext,                    /*  Extensions to search             */
        *interpreter;                   /*  Name of script interpreter       */
    char
        *olddir,                        /*  Caller's working directory       */
        *fulldir,                       /*  Process' working directory       */
        *full_filename,                 /*  Full filename of program to run  */
        *full_command,                  /*  Full command string              */
        **envv;                         /*  Environment for program          */
    STARTUPINFOA
        newinfo = {0},                  /*  Specification for new process    */
        curinfo;                        /*  Specification of cur process     */
    PROCESS_INFORMATION
        created;                        /*  Information about created proc   */
    HANDLE
        logon_token = 0;                /*  Logged-on user                   */
    DWORD
        dwCreateFlags;

    /*  First, check that minimum arguments needed to do something are set   */
    ASSERT (procinfo);
    if (!procinfo)
        return (NULL_PROCESS);

    ASSERT (procinfo-> filename);
    if (!procinfo-> filename)
      {
        procinfo-> error = EINVAL;
        return (NULL_PROCESS);
      }
    /*  Initialise return information                                        */
    procinfo-> pid        = NULL_PROCESS;
    procinfo-> error      = 0;
    procinfo-> returncode = -1;

#   include "sflprocx.imp"              /*  Get implementation core          */

    /*  Logon as specified user if any                                       */
    if (procinfo-> error == 0
    &&  procinfo-> username && *procinfo-> username)
      {
        if (LogonUserA (procinfo-> username,
                        procinfo-> groupname,
                        procinfo-> password,
                        LOGON32_LOGON_INTERACTIVE,
                        LOGON32_PROVIDER_DEFAULT,
                        &logon_token) == FALSE)
            procinfo-> error = EPERM;
      }

    if (procinfo-> error)               /*  And handle errors if any         */
      {
        if (free_envv)
            strtfree (envv);
        arglist_free (arglist);
        return (NULL_PROCESS);
      }
    else
      {
        mem_strfree (&arglist-> next-> value);
        arglist-> next-> value = mem_strdup (full_filename);
      }

    /*  Format full working directory, if specified                          */
    if (procinfo-> workdir)
      {
        olddir = get_curdir ();          /*  Just a lazy way to let the OS   */
        set_curdir (procinfo-> workdir); /*  figure-out if the workdir is a  */
        fulldir = get_curdir ();         /*  relative or absolute directory. */
        set_curdir (olddir);
        mem_free (olddir);
      }
    else
        fulldir = NULL;

    /*  Build full command from arglist                                      */
    full_command = arglist_value (arglist);
    GetShortPathNameA (full_command, full_command, strlen (full_command) + 1);
    
    process = mem_alloc (sizeof (PROC_HANDLE));
    process-> process = NULL;

    /*  Convert environment to a Windows-type packed block of strings        */
    process-> envd = strt2descr (envv);

    GetStartupInfoA (&curinfo);
    newinfo.cb          = sizeof (newinfo);
    newinfo.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    newinfo.wShowWindow = SW_HIDE;
    newinfo.hStdInput   = (HANDLE) _get_osfhandle (procinfo-> in);
    newinfo.hStdOutput  = (HANDLE) _get_osfhandle (procinfo-> out);
    newinfo.hStdError   = (HANDLE) _get_osfhandle (procinfo-> err);
    newinfo.lpTitle     = NULL;

    if (procinfo-> createdaemon)
        dwCreateFlags = DETACHED_PROCESS;
    else
        dwCreateFlags = CREATE_NEW_CONSOLE;

    /*  If necessary, run in separate VM, for 16-bit programs                */
    if (process_compatible)
        dwCreateFlags |= CREATE_SEPARATE_WOW_VDM;

    /*  CreateProcess returns errors sometimes, even when the process was    */
    /*  started correctly.  The cause is not evident.  For now: we detect    */
    /*  an error by checking the value of created.hProcess after the call.   */
    created.hProcess = NULL;

    if (logon_token)
      {
        CreateProcessAsUserA (
            logon_token,                /*  Token for user logon             */
            NULL,                       /*  Name of executable module        */
            full_command,               /*  Command line string              */
            NULL,                       /*  Process security attributes      */
            NULL,                       /*  Thread security attributes       */
            TRUE,                       /*  Handle inheritance flag          */
            dwCreateFlags,              /*  Creation flags                   */
            process-> envd-> data,      /*  New environment block            */
            fulldir,                    /*  Current directory name           */
            &newinfo,                   /*  STARTUPINFO                      */
            &created);                  /*  PROCESS_INFORMATION              */
        CloseHandle (logon_token);
      }
    else
        CreateProcessA (
            NULL,                       /*  Name of executable module        */
            full_command,               /*  Command line string              */
            NULL,                       /*  Process security attributes      */
            NULL,                       /*  Thread security attributes       */
            TRUE,                       /*  Handle inheritance flag          */
            dwCreateFlags,              /*  Creation flags                   */
            process-> envd-> data,      /*  New environment block            */
            fulldir,                    /*  Current directory name           */
            &newinfo,                   /*  STARTUPINFO                      */
            &created);                  /*  PROCESS_INFORMATION              */

    /*  Deallocate any memory we might have used in the meantime             */
    mem_strfree (&fulldir);
    mem_strfree (&full_command);
    if (free_envv)
        strtfree (envv);
    arglist_free (arglist);

    if (created.hProcess == NULL)       /*  Error, we presume                */
      {
        process_close (process);
        return (NULL);
      }

    /*  Release our hold on the thread                                       */
    CloseHandle (created.hThread);
    process-> process = created.hProcess;
    procinfo-> pid    = process;
    restore_redirection (old_stdin, old_stdout, old_stderr);

    /*  Wait for the process to finish or be cancelled                       */
    if (procinfo-> wait)
      {
        WaitForSingleObject (created.hProcess, INFINITE);
        process_close (process);
      }
    return (process);