Make sure sed uses the right locale.
[wine/dcerpc.git] / programs / winevdm / winevdm.c
blobdf2ec9e3290ea8be7c2b0ac0472817fefcdace65
1 /*
2 * Wine virtual DOS machine
4 * Copyright 2003 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wine/winbase16.h"
26 #include "winuser.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(winevdm);
31 extern void WINAPI wine_load_dos_exe( LPCSTR filename, LPCSTR cmdline );
34 /***********************************************************************
35 * build_command_line
37 * Build the command line of a process from the argv array.
38 * Copied from ENV_BuildCommandLine.
40 static char *build_command_line( char **argv )
42 int len;
43 char *p, **arg, *cmd_line;
45 len = 0;
46 for (arg = argv; *arg; arg++)
48 int has_space,bcount;
49 char* a;
51 has_space=0;
52 bcount=0;
53 a=*arg;
54 if( !*a ) has_space=1;
55 while (*a!='\0') {
56 if (*a=='\\') {
57 bcount++;
58 } else {
59 if (*a==' ' || *a=='\t') {
60 has_space=1;
61 } else if (*a=='"') {
62 /* doubling of '\' preceeding a '"',
63 * plus escaping of said '"'
65 len+=2*bcount+1;
67 bcount=0;
69 a++;
71 len+=(a-*arg)+1 /* for the separating space */;
72 if (has_space)
73 len+=2; /* for the quotes */
76 if (!(cmd_line = HeapAlloc( GetProcessHeap(), 0, len ? len + 1 : 2 )))
77 return NULL;
79 p = cmd_line;
80 *p++ = (len < 256) ? len : 255;
81 for (arg = argv; *arg; arg++)
83 int has_space,has_quote;
84 char* a;
86 /* Check for quotes and spaces in this argument */
87 has_space=has_quote=0;
88 a=*arg;
89 if( !*a ) has_space=1;
90 while (*a!='\0') {
91 if (*a==' ' || *a=='\t') {
92 has_space=1;
93 if (has_quote)
94 break;
95 } else if (*a=='"') {
96 has_quote=1;
97 if (has_space)
98 break;
100 a++;
103 /* Now transfer it to the command line */
104 if (has_space)
105 *p++='"';
106 if (has_quote) {
107 int bcount;
108 char* a;
110 bcount=0;
111 a=*arg;
112 while (*a!='\0') {
113 if (*a=='\\') {
114 *p++=*a;
115 bcount++;
116 } else {
117 if (*a=='"') {
118 int i;
120 /* Double all the '\\' preceeding this '"', plus one */
121 for (i=0;i<=bcount;i++)
122 *p++='\\';
123 *p++='"';
124 } else {
125 *p++=*a;
127 bcount=0;
129 a++;
131 } else {
132 strcpy(p,*arg);
133 p+=strlen(*arg);
135 if (has_space)
136 *p++='"';
137 *p++=' ';
139 if (len) p--; /* remove last space */
140 *p = '\0';
141 return cmd_line;
145 /***********************************************************************
146 * usage
148 static void usage(void)
150 WINE_MESSAGE( "Usage: winevdm.exe [--app-name app.exe] command line\n\n" );
151 ExitProcess(1);
155 /***********************************************************************
156 * main
158 int main( int argc, char *argv[] )
160 DWORD count;
161 HINSTANCE16 instance;
162 LOADPARAMS16 params;
163 WORD showCmd[2];
164 char buffer[MAX_PATH];
165 STARTUPINFOA info;
166 char *cmdline, *appname, **first_arg;
168 if (!argv[1]) usage();
170 if (!strcmp( argv[1], "--app-name" ))
172 if (!(appname = argv[2])) usage();
173 first_arg = argv + 3;
175 else
177 if (!SearchPathA( NULL, argv[1], ".exe", sizeof(buffer), buffer, NULL ))
179 WINE_MESSAGE( "winevdm: can't exec '%s': file not found\n", argv[1] );
180 ExitProcess(1);
182 appname = buffer;
183 first_arg = argv + 1;
186 if (*first_arg) first_arg++; /* skip program name */
187 cmdline = build_command_line( first_arg );
189 if (WINE_TRACE_ON(winevdm))
191 int i;
192 WINE_TRACE( "GetCommandLine = '%s'\n", GetCommandLineA() );
193 WINE_TRACE( "appname = '%s'\n", appname );
194 WINE_TRACE( "cmdline = '%.*s'\n", cmdline[0], cmdline+1 );
195 for (i = 0; argv[i]; i++) WINE_TRACE( "argv[%d]: '%s'\n", i, argv[i] );
198 GetStartupInfoA( &info );
199 showCmd[0] = 2;
200 showCmd[1] = (info.dwFlags & STARTF_USESHOWWINDOW) ? info.wShowWindow : SW_SHOWNORMAL;
202 params.hEnvironment = 0;
203 params.cmdLine = MapLS( cmdline );
204 params.showCmd = MapLS( showCmd );
205 params.reserved = 0;
207 RestoreThunkLock(1); /* grab the Win16 lock */
209 /* some programs assume mmsystem is always present */
210 LoadLibrary16( "mmsystem.dll" );
212 /* make sure system drivers are loaded */
213 LoadLibrary16( "comm.drv" );
214 LoadLibrary16( "display.drv" );
215 LoadLibrary16( "keyboard.drv" );
216 LoadLibrary16( "mouse.drv" );
218 if ((instance = LoadModule16( appname, &params )) < 32)
220 if (instance == 11) /* try DOS format */
222 /* loader expects arguments to be regular C strings */
223 wine_load_dos_exe( appname, cmdline + 1 );
224 /* if we get back here it failed */
225 instance = GetLastError();
228 WINE_MESSAGE( "winevdm: can't exec '%s': ", appname );
229 switch (instance)
231 case 2: WINE_MESSAGE("file not found\n" ); break;
232 case 11: WINE_MESSAGE("invalid exe file\n" ); break;
233 default: WINE_MESSAGE("error=%d\n", instance ); break;
235 ExitProcess(instance);
238 /* wait forever; the process will be killed when the last task exits */
239 ReleaseThunkLock( &count );
240 Sleep( INFINITE );
241 return 0;