Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
67271dcf
Commit
67271dcf
authored
Dec 11, 2007
by
Anatoly Lyutin
Committed by
Alexandre Julliard
Dec 13, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
start: Convert to Unicode.
parent
b3caf368
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
49 deletions
+72
-49
Makefile.in
programs/start/Makefile.in
+1
-1
start.c
programs/start/start.c
+71
-48
No files found.
programs/start/Makefile.in
View file @
67271dcf
...
...
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
SRCDIR
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
start.exe
APPMODE
=
-mconsole
APPMODE
=
-mconsole
-municode
IMPORTS
=
shell32 user32 kernel32
C_SRCS
=
start.c
...
...
programs/start/start.c
View file @
67271dcf
...
...
@@ -3,6 +3,7 @@
* Compatible with Microsoft's "c:\windows\command\start.exe"
*
* Copyright 2003 Dan Kegel
* Copyright 2007 Lyutin Anatoly (Etersoft)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -25,67 +26,90 @@
#include <stdlib.h>
#include <shlobj.h>
#include <wine/unicode.h>
#include <wine/debug.h>
#include "resources.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
start
);
/**
Output given message to stdout without formatting.
*/
static
void
output
(
const
char
*
message
)
static
void
output
(
const
WCHAR
*
message
)
{
DWORD
count
;
WriteFile
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
message
,
strlen
(
message
),
&
count
,
NULL
);
DWORD
res
;
int
wlen
=
strlenW
(
message
);
if
(
!
wlen
)
return
;
res
=
WriteConsoleW
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
message
,
wlen
,
&
count
,
NULL
);
/* If writing to console fails, assume its file
i/o so convert to OEM codepage and output */
if
(
!
res
)
{
DWORD
len
;
char
*
mesA
;
/* Convert to OEM, then output */
len
=
WideCharToMultiByte
(
GetConsoleOutputCP
(),
0
,
message
,
wlen
,
NULL
,
0
,
NULL
,
NULL
);
mesA
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
char
));
if
(
!
mesA
)
return
;
WideCharToMultiByte
(
GetConsoleOutputCP
(),
0
,
message
,
wlen
,
mesA
,
len
,
NULL
,
NULL
);
WriteFile
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
mesA
,
len
,
&
count
,
FALSE
);
HeapFree
(
GetProcessHeap
(),
0
,
mesA
);
}
}
/**
Output given message,
Output given message
from string table
,
followed by ": ",
followed by description of given GetLastError() value to stdout,
followed by a trailing newline,
then terminate.
*/
static
void
fatal_error
(
const
char
*
msg
,
DWORD
error_code
)
static
void
fatal_error
(
const
WCHAR
*
msg
,
DWORD
error_code
)
{
LPVOID
lpMsgBuf
;
int
status
;
static
const
WCHAR
colonsW
[]
=
{
':'
,
' '
,
0
};
static
const
WCHAR
newlineW
[]
=
{
'\n'
,
0
};
output
(
msg
);
output
(
": "
);
status
=
FormatMessage
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_FROM_SYSTEM
,
NULL
,
error_code
,
0
,
(
LPTSTR
)
&
lpMsgBuf
,
0
,
NULL
);
if
(
!
status
)
{
output
(
"FormatMessage failed
\n
"
);
}
else
{
output
(
colonsW
);
status
=
FormatMessageW
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_FROM_SYSTEM
,
NULL
,
error_code
,
0
,
(
LPWSTR
)
&
lpMsgBuf
,
0
,
NULL
);
if
(
!
status
)
{
WINE_ERR
(
"FormatMessage failed
\n
"
);
}
else
{
output
(
lpMsgBuf
);
LocalFree
((
HLOCAL
)
lpMsgBuf
);
output
(
"
\n
"
);
output
(
newlineW
);
}
ExitProcess
(
1
);
}
/**
Output given message from string table,
followed by ": ",
followed by description of given GetLastError() value to stdout,
followed by a trailing newline,
then terminate.
*/
static
void
fatal_string_error
(
int
which
,
DWORD
error_code
)
{
char
msg
[
2048
];
WCHAR
msg
[
2048
];
if
(
!
LoadString
(
GetModuleHandle
(
NULL
),
which
,
msg
,
sizeof
(
msg
)))
fatal_error
(
"LoadString failed
"
,
GetLastError
());
if
(
!
LoadString
W
(
GetModuleHandle
(
NULL
),
which
,
msg
,
sizeof
(
msg
)
/
sizeof
(
WCHAR
)
))
WINE_ERR
(
"LoadString failed, error %d
\n
"
,
GetLastError
());
fatal_error
(
msg
,
error_code
);
}
static
void
fatal_string
(
int
which
)
{
char
msg
[
2048
];
WCHAR
msg
[
2048
];
if
(
!
LoadString
(
GetModuleHandle
(
NULL
),
which
,
msg
,
sizeof
(
msg
)))
fatal_error
(
"LoadString failed
"
,
GetLastError
());
if
(
!
LoadString
W
(
GetModuleHandle
(
NULL
),
which
,
msg
,
sizeof
(
msg
)
/
sizeof
(
WCHAR
)
))
WINE_ERR
(
"LoadString failed, error %d
\n
"
,
GetLastError
());
output
(
msg
);
ExitProcess
(
1
);
...
...
@@ -101,39 +125,43 @@ static void license(void)
fatal_string
(
STRING_LICENSE
);
}
static
char
*
build_args
(
int
argc
,
char
**
argv
)
static
WCHAR
*
build_args
(
int
argc
,
WCHAR
**
argvW
)
{
int
i
,
len
=
1
;
char
*
ret
,
*
p
;
int
i
,
wlen
=
1
;
WCHAR
*
ret
,
*
p
;
static
const
WCHAR
FormatQuotesW
[]
=
{
' '
,
'\"'
,
'%'
,
's'
,
'\"'
,
0
};
static
const
WCHAR
FormatW
[]
=
{
' '
,
'%'
,
's'
,
0
};
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
len
+=
strlen
(
argv
[
i
])
+
1
;
if
(
strchr
(
argv
[
i
],
' '
))
len
+=
2
;
wlen
+=
strlenW
(
argvW
[
i
])
+
1
;
if
(
strchr
W
(
argvW
[
i
],
' '
))
w
len
+=
2
;
}
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
wlen
*
sizeof
(
WCHAR
)
);
ret
[
0
]
=
0
;
for
(
i
=
0
,
p
=
ret
;
i
<
argc
;
i
++
)
{
if
(
strchr
(
argv
[
i
],
' '
))
p
+=
sprintf
(
p
,
"
\"
%s
\"
"
,
argv
[
i
]);
if
(
strchr
W
(
argvW
[
i
],
' '
))
p
+=
sprintf
W
(
p
,
FormatQuotesW
,
argvW
[
i
]);
else
p
+=
sprintf
(
p
,
" %s"
,
argv
[
i
]);
p
+=
sprintf
W
(
p
,
FormatW
,
argvW
[
i
]);
}
return
ret
;
}
int
main
(
int
argc
,
char
*
argv
[])
int
wmain
(
int
argc
,
WCHAR
*
argv
[])
{
SHELLEXECUTEINFO
sei
;
char
*
args
;
SHELLEXECUTEINFO
W
sei
;
WCHAR
*
args
=
NULL
;
int
i
;
static
const
WCHAR
openW
[]
=
{
'o'
,
'p'
,
'e'
,
'n'
,
0
};
memset
(
&
sei
,
0
,
sizeof
(
sei
));
sei
.
cbSize
=
sizeof
(
sei
);
sei
.
lpVerb
=
"open"
;
sei
.
lpVerb
=
openW
;
sei
.
nShow
=
SW_SHOWNORMAL
;
/* Dunno what these mean, but it looks like winMe's start uses them */
sei
.
fMask
=
SEE_MASK_FLAG_DDEWAIT
|
...
...
@@ -175,7 +203,7 @@ int main(int argc, char *argv[])
sei
.
fMask
|=
SEE_MASK_NOCLOSEPROCESS
;
break
;
default:
printf
(
"Option '%s' not recognized
\n
"
,
argv
[
i
]
+
ci
-
1
);
WINE_ERR
(
"Option '%s' not recognized
\n
"
,
wine_dbgstr_w
(
argv
[
i
]
+
ci
-
1
)
);
usage
();
}
/* Skip to next slash */
...
...
@@ -192,20 +220,15 @@ int main(int argc, char *argv[])
args
=
build_args
(
argc
-
i
,
&
argv
[
i
]
);
sei
.
lpParameters
=
args
;
if
(
!
ShellExecuteEx
(
&
sei
))
if
(
!
ShellExecuteEx
W
(
&
sei
))
fatal_string_error
(
STRING_EXECFAIL
,
GetLastError
());
HeapFree
(
GetProcessHeap
(),
0
,
args
);
if
(
sei
.
fMask
&
SEE_MASK_NOCLOSEPROCESS
)
{
DWORD
exitcode
;
DWORD
waitcode
;
waitcode
=
WaitForSingleObject
(
sei
.
hProcess
,
INFINITE
);
if
(
waitcode
)
fatal_error
(
"WaitForSingleObject"
,
GetLastError
());
if
(
!
GetExitCodeProcess
(
sei
.
hProcess
,
&
exitcode
))
fatal_error
(
"GetExitCodeProcess"
,
GetLastError
());
/* fixme: haven't tested whether exit code works properly */
WaitForSingleObject
(
sei
.
hProcess
,
INFINITE
);
GetExitCodeProcess
(
sei
.
hProcess
,
&
exitcode
);
ExitProcess
(
exitcode
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment