Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
b8aa5fc5
Commit
b8aa5fc5
authored
Jun 03, 2007
by
Jason Edmeades
Committed by
Alexandre Julliard
Jun 04, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd.exe: Convert cmd to Unicode.
parent
398e7103
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1308 additions
and
945 deletions
+1308
-945
Cs.rc
programs/cmd/Cs.rc
+4
-0
De.rc
programs/cmd/De.rc
+4
-0
En.rc
programs/cmd/En.rc
+4
-0
Es.rc
programs/cmd/Es.rc
+4
-0
Fr.rc
programs/cmd/Fr.rc
+4
-0
Ja.rc
programs/cmd/Ja.rc
+4
-0
Ko.rc
programs/cmd/Ko.rc
+4
-0
Makefile.in
programs/cmd/Makefile.in
+1
-0
Nl.rc
programs/cmd/Nl.rc
+4
-0
No.rc
programs/cmd/No.rc
+4
-0
Pl.rc
programs/cmd/Pl.rc
+4
-0
Pt.rc
programs/cmd/Pt.rc
+4
-0
Ru.rc
programs/cmd/Ru.rc
+4
-0
Si.rc
programs/cmd/Si.rc
+4
-0
Tr.rc
programs/cmd/Tr.rc
+4
-0
batch.c
programs/cmd/batch.c
+93
-90
builtins.c
programs/cmd/builtins.c
+462
-399
directory.c
programs/cmd/directory.c
+185
-138
wcmd.h
programs/cmd/wcmd.h
+55
-47
wcmdmain.c
programs/cmd/wcmdmain.c
+456
-271
No files found.
programs/cmd/Cs.rc
View file @
b8aa5fc5
...
@@ -263,4 +263,8 @@ Zadejte HELP <pkaz> pro podrobnj informace o nkterm z ve uvedench pk
...
@@ -263,4 +263,8 @@ Zadejte HELP <pkaz> pro podrobnj informace o nkterm z ve uvedench pk
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/De.rc
View file @
b8aa5fc5
...
@@ -287,4 +287,8 @@ obigen Befehle erhalten.\n"
...
@@ -287,4 +287,8 @@ obigen Befehle erhalten.\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/En.rc
View file @
b8aa5fc5
...
@@ -267,4 +267,8 @@ Enter HELP <command> for further information on any of the above commands\n"
...
@@ -267,4 +267,8 @@ Enter HELP <command> for further information on any of the above commands\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Es.rc
View file @
b8aa5fc5
...
@@ -284,4 +284,8 @@ Introduzca HELP <comando> para ms informacin sobre cualquiera de los comandos\
...
@@ -284,4 +284,8 @@ Introduzca HELP <comando> para ms informacin sobre cualquiera de los comandos\
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Fr.rc
View file @
b8aa5fc5
...
@@ -257,4 +257,8 @@ Entrez HELP <commande> pour plus d'informations sur les commandes ci-dessus\n"
...
@@ -257,4 +257,8 @@ Entrez HELP <commande> pour plus d'informations sur les commandes ci-dessus\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Ja.rc
View file @
b8aa5fc5
...
@@ -261,4 +261,8 @@ EXIT\t\tCMDI\n\n\
...
@@ -261,4 +261,8 @@ EXIT\t\tCMDI\n\n\
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Ko.rc
View file @
b8aa5fc5
...
@@ -259,4 +259,8 @@ HELP <명령>을 치면 그 명령의 상세한 정보를 보여줌\n"
...
@@ -259,4 +259,8 @@ HELP <명령>을 치면 그 명령의 상세한 정보를 보여줌\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Makefile.in
View file @
b8aa5fc5
...
@@ -4,6 +4,7 @@ SRCDIR = @srcdir@
...
@@ -4,6 +4,7 @@ SRCDIR = @srcdir@
VPATH
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
cmd.exe
MODULE
=
cmd.exe
APPMODE
=
-mconsole
APPMODE
=
-mconsole
EXTRADEFS
=
-DUNICODE
IMPORTS
=
shell32 user32 advapi32 kernel32
IMPORTS
=
shell32 user32 advapi32 kernel32
C_SRCS
=
\
C_SRCS
=
\
...
...
programs/cmd/Nl.rc
View file @
b8aa5fc5
...
@@ -260,4 +260,8 @@ type HELP <opdracht> voor meer informatie over bovengenoemde opdrachten\n"
...
@@ -260,4 +260,8 @@ type HELP <opdracht> voor meer informatie over bovengenoemde opdrachten\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/No.rc
View file @
b8aa5fc5
...
@@ -265,4 +265,8 @@ Skriv HELP <kommando> for mer informasjon om kommandoene ovenfor\n"
...
@@ -265,4 +265,8 @@ Skriv HELP <kommando> for mer informasjon om kommandoene ovenfor\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Pl.rc
View file @
b8aa5fc5
...
@@ -262,4 +262,8 @@ Wpisz HELP <komenda> dla dokadniejszych informacji o komendzie\n"
...
@@ -262,4 +262,8 @@ Wpisz HELP <komenda> dla dokadniejszych informacji o komendzie\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Pt.rc
View file @
b8aa5fc5
...
@@ -470,4 +470,8 @@ Digite HELP <comando> para mais informaes sobre alguns dos comandos acima\n"
...
@@ -470,4 +470,8 @@ Digite HELP <comando> para mais informaes sobre alguns dos comandos acima\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Ru.rc
View file @
b8aa5fc5
...
@@ -273,4 +273,8 @@ EXIT\t\t CMD\n\n\
...
@@ -273,4 +273,8 @@ EXIT\t\t CMD\n\n\
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Si.rc
View file @
b8aa5fc5
...
@@ -259,4 +259,8 @@ Enter HELP <command> for further information on any of the above commands\n"
...
@@ -259,4 +259,8 @@ Enter HELP <command> for further information on any of the above commands\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/Tr.rc
View file @
b8aa5fc5
...
@@ -261,4 +261,8 @@ Yukardaki komutlar hakknda daha fazla bilgi iin HELP <komut> girin\n"
...
@@ -261,4 +261,8 @@ Yukardaki komutlar hakknda daha fazla bilgi iin HELP <komut> girin\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_ARGERR, "Parameter error\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
WCMD_NOPATH, "PATH not found\n"
WCMD_ANYKEY,"Press Return key to continue: "
WCMD_CONSTITLE,"Wine Command Prompt"
WCMD_VERSION,"CMD Version %s\n\n"
}
}
programs/cmd/batch.c
View file @
b8aa5fc5
...
@@ -21,7 +21,7 @@
...
@@ -21,7 +21,7 @@
#include "wcmd.h"
#include "wcmd.h"
extern
int
echo_mode
;
extern
int
echo_mode
;
extern
char
quals
[
MAX_PATH
],
param1
[
MAX_PATH
],
param2
[
MAX_PATH
];
extern
WCHAR
quals
[
MAX_PATH
],
param1
[
MAX_PATH
],
param2
[
MAX_PATH
];
extern
BATCH_CONTEXT
*
context
;
extern
BATCH_CONTEXT
*
context
;
extern
DWORD
errorlevel
;
extern
DWORD
errorlevel
;
...
@@ -41,30 +41,31 @@ extern DWORD errorlevel;
...
@@ -41,30 +41,31 @@ extern DWORD errorlevel;
* a label to goto once opened.
* a label to goto once opened.
*/
*/
void
WCMD_batch
(
char
*
file
,
char
*
command
,
int
called
,
char
*
startLabel
,
HANDLE
pgmHandle
)
{
void
WCMD_batch
(
WCHAR
*
file
,
WCHAR
*
command
,
int
called
,
WCHAR
*
startLabel
,
HANDLE
pgmHandle
)
{
#define WCMD_BATCH_EXT_SIZE 5
#define WCMD_BATCH_EXT_SIZE 5
HANDLE
h
=
INVALID_HANDLE_VALUE
;
HANDLE
h
=
INVALID_HANDLE_VALUE
;
char
string
[
MAXSTRING
];
WCHAR
string
[
MAXSTRING
];
char
extension_batch
[][
WCMD_BATCH_EXT_SIZE
]
=
{
".bat"
,
".cmd"
};
static
const
WCHAR
extension_batch
[][
WCMD_BATCH_EXT_SIZE
]
=
{{
'.'
,
'b'
,
'a'
,
't'
,
'\0'
},
char
extension_exe
[
WCMD_BATCH_EXT_SIZE
]
=
".exe"
;
{
'.'
,
'c'
,
'm'
,
'd'
,
'\0'
}};
static
const
WCHAR
extension_exe
[
WCMD_BATCH_EXT_SIZE
]
=
{
'.'
,
'e'
,
'x'
,
'e'
,
'\0'
};
unsigned
int
i
;
unsigned
int
i
;
BATCH_CONTEXT
*
prev_context
;
BATCH_CONTEXT
*
prev_context
;
if
(
startLabel
==
NULL
)
{
if
(
startLabel
==
NULL
)
{
for
(
i
=
0
;
(
i
<
(
sizeof
(
extension_batch
)
/
WCMD_BATCH_EXT_SIZE
))
&&
for
(
i
=
0
;
(
i
<
(
(
sizeof
(
extension_batch
)
*
sizeof
(
WCHAR
)
)
/
WCMD_BATCH_EXT_SIZE
))
&&
(
h
==
INVALID_HANDLE_VALUE
);
i
++
)
{
(
h
==
INVALID_HANDLE_VALUE
);
i
++
)
{
strcpy
(
string
,
file
);
strcpyW
(
string
,
file
);
CharLower
(
string
);
CharLower
(
string
);
if
(
strstr
(
string
,
extension_batch
[
i
])
==
NULL
)
strcat
(
string
,
extension_batch
[
i
]);
if
(
strstr
W
(
string
,
extension_batch
[
i
])
==
NULL
)
strcatW
(
string
,
extension_batch
[
i
]);
h
=
CreateFile
(
string
,
GENERIC_READ
,
FILE_SHARE_READ
,
h
=
CreateFile
(
string
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
}
}
if
(
h
==
INVALID_HANDLE_VALUE
)
{
if
(
h
==
INVALID_HANDLE_VALUE
)
{
strcpy
(
string
,
file
);
strcpy
W
(
string
,
file
);
CharLower
(
string
);
CharLower
(
string
);
if
(
strstr
(
string
,
extension_exe
)
==
NULL
)
strcat
(
string
,
extension_exe
);
if
(
strstr
W
(
string
,
extension_exe
)
==
NULL
)
strcatW
(
string
,
extension_exe
);
h
=
CreateFile
(
string
,
GENERIC_READ
,
FILE_SHARE_READ
,
h
=
CreateFile
(
string
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
h
!=
INVALID_HANDLE_VALUE
)
{
if
(
h
!=
INVALID_HANDLE_VALUE
)
{
...
@@ -95,7 +96,7 @@ void WCMD_batch (char *file, char *command, int called, char *startLabel, HANDLE
...
@@ -95,7 +96,7 @@ void WCMD_batch (char *file, char *command, int called, char *startLabel, HANDLE
/* If processing a call :label, 'goto' the label in question */
/* If processing a call :label, 'goto' the label in question */
if
(
startLabel
)
{
if
(
startLabel
)
{
strcpy
(
param1
,
startLabel
);
strcpy
W
(
param1
,
startLabel
);
WCMD_goto
();
WCMD_goto
();
}
}
...
@@ -105,7 +106,7 @@ void WCMD_batch (char *file, char *command, int called, char *startLabel, HANDLE
...
@@ -105,7 +106,7 @@ void WCMD_batch (char *file, char *command, int called, char *startLabel, HANDLE
*/
*/
while
(
context
->
skip_rest
==
FALSE
&&
WCMD_fgets
(
string
,
sizeof
(
string
),
h
))
{
while
(
context
->
skip_rest
==
FALSE
&&
WCMD_fgets
(
string
,
sizeof
(
string
),
h
))
{
if
(
strlen
(
string
)
==
MAXSTRING
-
1
)
{
if
(
strlen
W
(
string
)
==
MAXSTRING
-
1
)
{
WCMD_output_asis
(
WCMD_LoadMessage
(
WCMD_TRUNCATEDLINE
));
WCMD_output_asis
(
WCMD_LoadMessage
(
WCMD_TRUNCATEDLINE
));
WCMD_output_asis
(
string
);
WCMD_output_asis
(
string
);
WCMD_output_asis
(
newline
);
WCMD_output_asis
(
newline
);
...
@@ -141,11 +142,11 @@ void WCMD_batch (char *file, char *command, int called, char *startLabel, HANDLE
...
@@ -141,11 +142,11 @@ void WCMD_batch (char *file, char *command, int called, char *startLabel, HANDLE
* Also returns a pointer to the location of the parameter in the command line.
* Also returns a pointer to the location of the parameter in the command line.
*/
*/
char
*
WCMD_parameter
(
char
*
s
,
int
n
,
char
**
where
)
{
WCHAR
*
WCMD_parameter
(
WCHAR
*
s
,
int
n
,
WCHAR
**
where
)
{
int
i
=
0
;
int
i
=
0
;
static
char
param
[
MAX_PATH
];
static
WCHAR
param
[
MAX_PATH
];
char
*
p
;
WCHAR
*
p
;
if
(
where
!=
NULL
)
*
where
=
NULL
;
if
(
where
!=
NULL
)
*
where
=
NULL
;
p
=
param
;
p
=
param
;
...
@@ -211,32 +212,32 @@ char *WCMD_parameter (char *s, int n, char **where) {
...
@@ -211,32 +212,32 @@ char *WCMD_parameter (char *s, int n, char **where) {
* the LF (or CRLF) from the line.
* the LF (or CRLF) from the line.
*/
*/
char
*
WCMD_fgets
(
char
*
s
,
int
n
,
HANDLE
h
)
{
WCHAR
*
WCMD_fgets
(
WCHAR
*
s
,
int
noChars
,
HANDLE
h
)
{
DWORD
bytes
;
DWORD
bytes
;
BOOL
status
;
BOOL
status
;
char
*
p
;
WCHAR
*
p
;
p
=
s
;
p
=
s
;
do
{
do
{
status
=
ReadFile
(
h
,
s
,
1
,
&
bytes
,
NULL
);
status
=
WCMD_
ReadFile
(
h
,
s
,
1
,
&
bytes
,
NULL
);
if
((
status
==
0
)
||
((
bytes
==
0
)
&&
(
s
==
p
)))
return
NULL
;
if
((
status
==
0
)
||
((
bytes
==
0
)
&&
(
s
==
p
)))
return
NULL
;
if
(
*
s
==
'\n'
)
bytes
=
0
;
if
(
*
s
==
'\n'
)
bytes
=
0
;
else
if
(
*
s
!=
'\r'
)
{
else
if
(
*
s
!=
'\r'
)
{
s
++
;
s
++
;
n
--
;
n
oChars
--
;
}
}
*
s
=
'\0'
;
*
s
=
'\0'
;
}
while
((
bytes
==
1
)
&&
(
n
>
1
));
}
while
((
bytes
==
1
)
&&
(
n
oChars
>
1
));
return
p
;
return
p
;
}
}
/* WCMD_splitpath - copied from winefile as no obvious way to use it otherwise */
/* WCMD_splitpath - copied from winefile as no obvious way to use it otherwise */
void
WCMD_splitpath
(
const
CHAR
*
path
,
CHAR
*
drv
,
CHAR
*
dir
,
CHAR
*
name
,
CHAR
*
ext
)
void
WCMD_splitpath
(
const
WCHAR
*
path
,
WCHAR
*
drv
,
WCHAR
*
dir
,
WCHAR
*
name
,
W
CHAR
*
ext
)
{
{
const
CHAR
*
end
;
/* end of processed string */
const
W
CHAR
*
end
;
/* end of processed string */
const
CHAR
*
p
;
/* search pointer */
const
W
CHAR
*
p
;
/* search pointer */
const
CHAR
*
s
;
/* copy pointer */
const
W
CHAR
*
s
;
/* copy pointer */
/* extract drive name */
/* extract drive name */
if
(
path
[
0
]
&&
path
[
1
]
==
':'
)
{
if
(
path
[
0
]
&&
path
[
1
]
==
':'
)
{
...
@@ -307,7 +308,7 @@ void WCMD_splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ex
...
@@ -307,7 +308,7 @@ void WCMD_splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ex
* To work out the length of the modifier:
* To work out the length of the modifier:
*
*
* Note: In the case of %0-9 knowing the end of the modifier is easy,
* Note: In the case of %0-9 knowing the end of the modifier is easy,
* but in a for loop, the for end
char
acter may also be a modifier
* but in a for loop, the for end
WCHAR
acter may also be a modifier
* eg. for %a in (c:\a.a) do echo XXX
* eg. for %a in (c:\a.a) do echo XXX
* where XXX = %~a (just ~)
* where XXX = %~a (just ~)
* %~aa (~ and attributes)
* %~aa (~ and attributes)
...
@@ -317,22 +318,22 @@ void WCMD_splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ex
...
@@ -317,22 +318,22 @@ void WCMD_splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ex
* Hence search forwards until find an invalid modifier, and then
* Hence search forwards until find an invalid modifier, and then
* backwards until find for variable or 0-9
* backwards until find for variable or 0-9
*/
*/
void
WCMD_HandleTildaModifiers
(
char
**
start
,
char
*
forVariable
)
{
void
WCMD_HandleTildaModifiers
(
WCHAR
**
start
,
WCHAR
*
forVariable
)
{
#define NUMMODIFIERS 11
#define NUMMODIFIERS 11
const
char
validmodifiers
[
NUMMODIFIERS
]
=
{
static
const
WCHAR
validmodifiers
[
NUMMODIFIERS
]
=
{
'~'
,
'f'
,
'd'
,
'p'
,
'n'
,
'x'
,
's'
,
'a'
,
't'
,
'z'
,
'$'
'~'
,
'f'
,
'd'
,
'p'
,
'n'
,
'x'
,
's'
,
'a'
,
't'
,
'z'
,
'$'
};
};
const
char
space
[]
=
" "
;
static
const
WCHAR
space
[]
=
{
' '
,
'\0'
}
;
WIN32_FILE_ATTRIBUTE_DATA
fileInfo
;
WIN32_FILE_ATTRIBUTE_DATA
fileInfo
;
char
outputparam
[
MAX_PATH
];
WCHAR
outputparam
[
MAX_PATH
];
char
finaloutput
[
MAX_PATH
];
WCHAR
finaloutput
[
MAX_PATH
];
char
fullfilename
[
MAX_PATH
];
WCHAR
fullfilename
[
MAX_PATH
];
char
thisoutput
[
MAX_PATH
];
WCHAR
thisoutput
[
MAX_PATH
];
char
*
pos
=
*
start
+
1
;
WCHAR
*
pos
=
*
start
+
1
;
char
*
firstModifier
=
pos
;
WCHAR
*
firstModifier
=
pos
;
char
*
lastModifier
=
NULL
;
WCHAR
*
lastModifier
=
NULL
;
int
modifierLen
=
0
;
int
modifierLen
=
0
;
BOOL
finished
=
FALSE
;
BOOL
finished
=
FALSE
;
int
i
=
0
;
int
i
=
0
;
...
@@ -340,10 +341,10 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
...
@@ -340,10 +341,10 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
BOOL
skipFileParsing
=
FALSE
;
BOOL
skipFileParsing
=
FALSE
;
BOOL
doneModifier
=
FALSE
;
BOOL
doneModifier
=
FALSE
;
/* Search forwards until find invalid
char
acter modifier */
/* Search forwards until find invalid
WCHAR
acter modifier */
while
(
!
finished
)
{
while
(
!
finished
)
{
/* Work on the previous
char
acter */
/* Work on the previous
WCHAR
acter */
if
(
lastModifier
!=
NULL
)
{
if
(
lastModifier
!=
NULL
)
{
for
(
i
=
0
;
i
<
NUMMODIFIERS
;
i
++
)
{
for
(
i
=
0
;
i
<
NUMMODIFIERS
;
i
++
)
{
...
@@ -374,10 +375,10 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
...
@@ -374,10 +375,10 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
/* Now make sure the position we stopped at is a valid parameter */
/* Now make sure the position we stopped at is a valid parameter */
if
(
!
(
*
lastModifier
>=
'0'
||
*
lastModifier
<=
'9'
)
&&
if
(
!
(
*
lastModifier
>=
'0'
||
*
lastModifier
<=
'9'
)
&&
(
forVariable
!=
NULL
)
&&
(
forVariable
!=
NULL
)
&&
(
toupper
(
*
lastModifier
)
!=
toupper
(
*
forVariable
)))
{
(
toupper
W
(
*
lastModifier
)
!=
toupperW
(
*
forVariable
)))
{
/* Its not... Step backwards until it matches or we get to the start */
/* Its not... Step backwards until it matches or we get to the start */
while
(
toupper
(
*
lastModifier
)
!=
toupper
(
*
forVariable
)
&&
while
(
toupper
W
(
*
lastModifier
)
!=
toupperW
(
*
forVariable
)
&&
lastModifier
>
firstModifier
)
{
lastModifier
>
firstModifier
)
{
lastModifier
--
;
lastModifier
--
;
}
}
...
@@ -386,7 +387,7 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
...
@@ -386,7 +387,7 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
/* Extract the parameter to play with */
/* Extract the parameter to play with */
if
((
*
lastModifier
>=
'0'
&&
*
lastModifier
<=
'9'
))
{
if
((
*
lastModifier
>=
'0'
&&
*
lastModifier
<=
'9'
))
{
strcpy
(
outputparam
,
WCMD_parameter
(
context
->
command
,
strcpy
W
(
outputparam
,
WCMD_parameter
(
context
->
command
,
*
lastModifier
-
'0'
+
context
->
shift_count
[
*
lastModifier
-
'0'
],
NULL
));
*
lastModifier
-
'0'
+
context
->
shift_count
[
*
lastModifier
-
'0'
],
NULL
));
}
else
{
}
else
{
/* FIXME: Retrieve 'for' variable %c\n", *lastModifier); */
/* FIXME: Retrieve 'for' variable %c\n", *lastModifier); */
...
@@ -407,26 +408,26 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
...
@@ -407,26 +408,26 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
/* 1. Handle '~' : Strip surrounding quotes */
/* 1. Handle '~' : Strip surrounding quotes */
if
(
outputparam
[
0
]
==
'"'
&&
if
(
outputparam
[
0
]
==
'"'
&&
memchr
(
firstModifier
,
'~'
,
modifierLen
)
!=
NULL
)
{
memchr
W
(
firstModifier
,
'~'
,
modifierLen
)
!=
NULL
)
{
int
len
=
strlen
(
outputparam
);
int
len
=
strlen
W
(
outputparam
);
if
(
outputparam
[
len
-
1
]
==
'"'
)
{
if
(
outputparam
[
len
-
1
]
==
'"'
)
{
outputparam
[
len
-
1
]
=
0x00
;
outputparam
[
len
-
1
]
=
0x00
;
len
=
len
-
1
;
len
=
len
-
1
;
}
}
memmove
(
outputparam
,
&
outputparam
[
1
],
len
-
1
);
memmove
(
outputparam
,
&
outputparam
[
1
],
(
len
*
sizeof
(
WCHAR
))
-
1
);
}
}
/* 2. Handle the special case of a $ */
/* 2. Handle the special case of a $ */
if
(
memchr
(
firstModifier
,
'$'
,
modifierLen
)
!=
NULL
)
{
if
(
memchr
W
(
firstModifier
,
'$'
,
modifierLen
)
!=
NULL
)
{
/* Special Case: Search envar specified in $[envvar] for outputparam
/* Special Case: Search envar specified in $[envvar] for outputparam
Note both $ and : are guaranteed otherwise check above would fail */
Note both $ and : are guaranteed otherwise check above would fail */
char
*
start
=
strchr
(
firstModifier
,
'$'
)
+
1
;
WCHAR
*
start
=
strchrW
(
firstModifier
,
'$'
)
+
1
;
char
*
end
=
strchr
(
firstModifier
,
':'
);
WCHAR
*
end
=
strchrW
(
firstModifier
,
':'
);
char
env
[
MAX_PATH
];
WCHAR
env
[
MAX_PATH
];
char
fullpath
[
MAX_PATH
];
WCHAR
fullpath
[
MAX_PATH
];
/* Extract the env var */
/* Extract the env var */
strncpy
(
env
,
start
,
(
end
-
start
));
memcpy
(
env
,
start
,
(
end
-
start
)
*
sizeof
(
WCHAR
));
env
[(
end
-
start
)]
=
0x00
;
env
[(
end
-
start
)]
=
0x00
;
/* If env var not found, return emptry string */
/* If env var not found, return emptry string */
...
@@ -445,15 +446,16 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
...
@@ -445,15 +446,16 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
if
(
GetFullPathName
(
outputparam
,
MAX_PATH
,
fullfilename
,
NULL
)
==
0
)
if
(
GetFullPathName
(
outputparam
,
MAX_PATH
,
fullfilename
,
NULL
)
==
0
)
return
;
return
;
exists
=
GetFileAttributesEx
A
(
fullfilename
,
GetFileExInfoStandard
,
exists
=
GetFileAttributesEx
W
(
fullfilename
,
GetFileExInfoStandard
,
&
fileInfo
);
&
fileInfo
);
/* 2. Handle 'a' : Output attributes */
/* 2. Handle 'a' : Output attributes */
if
(
exists
&&
if
(
exists
&&
memchr
(
firstModifier
,
'a'
,
modifierLen
)
!=
NULL
)
{
memchr
W
(
firstModifier
,
'a'
,
modifierLen
)
!=
NULL
)
{
WCHAR
defaults
[]
=
{
'-'
,
'-'
,
'-'
,
'-'
,
'-'
,
'-'
,
'-'
,
'-'
,
'-'
,
'\0'
};
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
strcpy
(
thisoutput
,
"---------"
);
strcpy
W
(
thisoutput
,
defaults
);
if
(
fileInfo
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
if
(
fileInfo
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
thisoutput
[
0
]
=
'd'
;
thisoutput
[
0
]
=
'd'
;
if
(
fileInfo
.
dwFileAttributes
&
FILE_ATTRIBUTE_READONLY
)
if
(
fileInfo
.
dwFileAttributes
&
FILE_ATTRIBUTE_READONLY
)
...
@@ -469,114 +471,115 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
...
@@ -469,114 +471,115 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
/* FIXME: What are 6 and 7? */
/* FIXME: What are 6 and 7? */
if
(
fileInfo
.
dwFileAttributes
&
FILE_ATTRIBUTE_REPARSE_POINT
)
if
(
fileInfo
.
dwFileAttributes
&
FILE_ATTRIBUTE_REPARSE_POINT
)
thisoutput
[
8
]
=
'l'
;
thisoutput
[
8
]
=
'l'
;
strcat
(
finaloutput
,
thisoutput
);
strcat
W
(
finaloutput
,
thisoutput
);
}
}
/* 3. Handle 't' : Date+time */
/* 3. Handle 't' : Date+time */
if
(
exists
&&
if
(
exists
&&
memchr
(
firstModifier
,
't'
,
modifierLen
)
!=
NULL
)
{
memchr
W
(
firstModifier
,
't'
,
modifierLen
)
!=
NULL
)
{
SYSTEMTIME
systime
;
SYSTEMTIME
systime
;
int
datelen
;
int
datelen
;
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
(
finaloutput
,
space
);
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
W
(
finaloutput
,
space
);
/* Format the time */
/* Format the time */
FileTimeToSystemTime
(
&
fileInfo
.
ftLastWriteTime
,
&
systime
);
FileTimeToSystemTime
(
&
fileInfo
.
ftLastWriteTime
,
&
systime
);
GetDateFormat
(
LOCALE_USER_DEFAULT
,
DATE_SHORTDATE
,
&
systime
,
GetDateFormat
(
LOCALE_USER_DEFAULT
,
DATE_SHORTDATE
,
&
systime
,
NULL
,
thisoutput
,
MAX_PATH
);
NULL
,
thisoutput
,
MAX_PATH
);
strcat
(
thisoutput
,
space
);
strcat
W
(
thisoutput
,
space
);
datelen
=
strlen
(
thisoutput
);
datelen
=
strlen
W
(
thisoutput
);
GetTimeFormat
(
LOCALE_USER_DEFAULT
,
TIME_NOSECONDS
,
&
systime
,
GetTimeFormat
(
LOCALE_USER_DEFAULT
,
TIME_NOSECONDS
,
&
systime
,
NULL
,
(
thisoutput
+
datelen
),
MAX_PATH
-
datelen
);
NULL
,
(
thisoutput
+
datelen
),
MAX_PATH
-
datelen
);
strcat
(
finaloutput
,
thisoutput
);
strcat
W
(
finaloutput
,
thisoutput
);
}
}
/* 4. Handle 'z' : File length */
/* 4. Handle 'z' : File length */
if
(
exists
&&
if
(
exists
&&
memchr
(
firstModifier
,
'z'
,
modifierLen
)
!=
NULL
)
{
memchr
W
(
firstModifier
,
'z'
,
modifierLen
)
!=
NULL
)
{
/* FIXME: Output full 64 bit size (sprintf does not support I64 here) */
/* FIXME: Output full 64 bit size (sprintf does not support I64 here) */
ULONG
/*64*/
fullsize
=
/*(fileInfo.nFileSizeHigh << 32) +*/
ULONG
/*64*/
fullsize
=
/*(fileInfo.nFileSizeHigh << 32) +*/
fileInfo
.
nFileSizeLow
;
fileInfo
.
nFileSizeLow
;
static
const
WCHAR
fmt
[]
=
{
'%'
,
'u'
,
'\0'
};
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
(
finaloutput
,
space
);
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
W
(
finaloutput
,
space
);
sprintf
(
thisoutput
,
"%u"
,
fullsize
);
wsprintf
(
thisoutput
,
fmt
,
fullsize
);
strcat
(
finaloutput
,
thisoutput
);
strcat
W
(
finaloutput
,
thisoutput
);
}
}
/* 4. Handle 's' : Use short paths (File doesn't have to exist) */
/* 4. Handle 's' : Use short paths (File doesn't have to exist) */
if
(
memchr
(
firstModifier
,
's'
,
modifierLen
)
!=
NULL
)
{
if
(
memchr
W
(
firstModifier
,
's'
,
modifierLen
)
!=
NULL
)
{
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
(
finaloutput
,
space
);
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
W
(
finaloutput
,
space
);
/* Don't flag as doneModifier - %~s on its own is processed later */
/* Don't flag as doneModifier - %~s on its own is processed later */
GetShortPathName
(
outputparam
,
outputparam
,
sizeof
(
outputparam
));
GetShortPathName
(
outputparam
,
outputparam
,
sizeof
(
outputparam
));
}
}
/* 5. Handle 'f' : Fully qualified path (File doesn't have to exist) */
/* 5. Handle 'f' : Fully qualified path (File doesn't have to exist) */
/* Note this overrides d,p,n,x */
/* Note this overrides d,p,n,x */
if
(
memchr
(
firstModifier
,
'f'
,
modifierLen
)
!=
NULL
)
{
if
(
memchr
W
(
firstModifier
,
'f'
,
modifierLen
)
!=
NULL
)
{
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
(
finaloutput
,
space
);
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
W
(
finaloutput
,
space
);
strcat
(
finaloutput
,
fullfilename
);
strcat
W
(
finaloutput
,
fullfilename
);
}
else
{
}
else
{
char
drive
[
10
];
WCHAR
drive
[
10
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
char
fname
[
MAX_PATH
];
WCHAR
fname
[
MAX_PATH
];
char
ext
[
MAX_PATH
];
WCHAR
ext
[
MAX_PATH
];
BOOL
doneFileModifier
=
FALSE
;
BOOL
doneFileModifier
=
FALSE
;
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
(
finaloutput
,
space
);
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
W
(
finaloutput
,
space
);
/* Split into components */
/* Split into components */
WCMD_splitpath
(
fullfilename
,
drive
,
dir
,
fname
,
ext
);
WCMD_splitpath
(
fullfilename
,
drive
,
dir
,
fname
,
ext
);
/* 5. Handle 'd' : Drive Letter */
/* 5. Handle 'd' : Drive Letter */
if
(
memchr
(
firstModifier
,
'd'
,
modifierLen
)
!=
NULL
)
{
if
(
memchr
W
(
firstModifier
,
'd'
,
modifierLen
)
!=
NULL
)
{
strcat
(
finaloutput
,
drive
);
strcat
W
(
finaloutput
,
drive
);
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
doneFileModifier
=
TRUE
;
doneFileModifier
=
TRUE
;
}
}
/* 6. Handle 'p' : Path */
/* 6. Handle 'p' : Path */
if
(
memchr
(
firstModifier
,
'p'
,
modifierLen
)
!=
NULL
)
{
if
(
memchr
W
(
firstModifier
,
'p'
,
modifierLen
)
!=
NULL
)
{
strcat
(
finaloutput
,
dir
);
strcat
W
(
finaloutput
,
dir
);
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
doneFileModifier
=
TRUE
;
doneFileModifier
=
TRUE
;
}
}
/* 7. Handle 'n' : Name */
/* 7. Handle 'n' : Name */
if
(
memchr
(
firstModifier
,
'n'
,
modifierLen
)
!=
NULL
)
{
if
(
memchr
W
(
firstModifier
,
'n'
,
modifierLen
)
!=
NULL
)
{
strcat
(
finaloutput
,
fname
);
strcat
W
(
finaloutput
,
fname
);
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
doneFileModifier
=
TRUE
;
doneFileModifier
=
TRUE
;
}
}
/* 8. Handle 'x' : Ext */
/* 8. Handle 'x' : Ext */
if
(
memchr
(
firstModifier
,
'x'
,
modifierLen
)
!=
NULL
)
{
if
(
memchr
W
(
firstModifier
,
'x'
,
modifierLen
)
!=
NULL
)
{
strcat
(
finaloutput
,
ext
);
strcat
W
(
finaloutput
,
ext
);
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
doneFileModifier
=
TRUE
;
doneFileModifier
=
TRUE
;
}
}
/* If 's' but no other parameter, dump the whole thing */
/* If 's' but no other parameter, dump the whole thing */
if
(
!
doneFileModifier
&&
if
(
!
doneFileModifier
&&
memchr
(
firstModifier
,
's'
,
modifierLen
)
!=
NULL
)
{
memchr
W
(
firstModifier
,
's'
,
modifierLen
)
!=
NULL
)
{
doneModifier
=
TRUE
;
doneModifier
=
TRUE
;
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
(
finaloutput
,
space
);
if
(
finaloutput
[
0
]
!=
0x00
)
strcat
W
(
finaloutput
,
space
);
strcat
(
finaloutput
,
outputparam
);
strcat
W
(
finaloutput
,
outputparam
);
}
}
}
}
}
}
/* If No other modifier processed, just add in parameter */
/* If No other modifier processed, just add in parameter */
if
(
!
doneModifier
)
strcpy
(
finaloutput
,
outputparam
);
if
(
!
doneModifier
)
strcpy
W
(
finaloutput
,
outputparam
);
/* Finish by inserting the replacement into the string */
/* Finish by inserting the replacement into the string */
pos
=
strdup
(
lastModifier
+
1
);
pos
=
WCMD_strdupW
(
lastModifier
+
1
);
strcpy
(
*
start
,
finaloutput
);
strcpy
W
(
*
start
,
finaloutput
);
strcat
(
*
start
,
pos
);
strcat
W
(
*
start
,
pos
);
free
(
pos
);
free
(
pos
);
}
}
...
@@ -586,16 +589,16 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
...
@@ -586,16 +589,16 @@ void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
* If there is a leading ':', calls within this batch program
* If there is a leading ':', calls within this batch program
* otherwise launches another program.
* otherwise launches another program.
*/
*/
void
WCMD_call
(
char
*
command
)
{
void
WCMD_call
(
WCHAR
*
command
)
{
/* Run other program if no leading ':' */
/* Run other program if no leading ':' */
if
(
*
command
!=
':'
)
{
if
(
*
command
!=
':'
)
{
WCMD_run_program
(
command
,
1
);
WCMD_run_program
(
command
,
1
);
}
else
{
}
else
{
char
gotoLabel
[
MAX_PATH
];
WCHAR
gotoLabel
[
MAX_PATH
];
strcpy
(
gotoLabel
,
param1
);
strcpy
W
(
gotoLabel
,
param1
);
if
(
context
)
{
if
(
context
)
{
...
...
programs/cmd/builtins.c
View file @
b8aa5fc5
...
@@ -40,19 +40,29 @@
...
@@ -40,19 +40,29 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
cmd
);
WINE_DEFAULT_DEBUG_CHANNEL
(
cmd
);
void
WCMD_execute
(
char
*
orig_command
,
char
*
parameter
,
char
*
substitution
);
void
WCMD_execute
(
WCHAR
*
orig_command
,
WCHAR
*
parameter
,
WCHAR
*
substitution
);
struct
env_stack
*
saved_environment
;
struct
env_stack
*
saved_environment
;
struct
env_stack
*
pushd_directories
;
struct
env_stack
*
pushd_directories
;
extern
HINSTANCE
hinst
;
extern
HINSTANCE
hinst
;
extern
char
*
inbuilt
[];
extern
WCHAR
*
inbuilt
[];
extern
int
echo_mode
,
verify_mode
,
defaultColor
;
extern
int
echo_mode
,
verify_mode
,
defaultColor
;
extern
char
quals
[
MAX_PATH
],
param1
[
MAX_PATH
],
param2
[
MAX_PATH
];
extern
WCHAR
quals
[
MAX_PATH
],
param1
[
MAX_PATH
],
param2
[
MAX_PATH
];
extern
BATCH_CONTEXT
*
context
;
extern
BATCH_CONTEXT
*
context
;
extern
DWORD
errorlevel
;
extern
DWORD
errorlevel
;
static
const
WCHAR
dotW
[]
=
{
'.'
,
'\0'
};
static
const
WCHAR
dotdotW
[]
=
{
'.'
,
'.'
,
'\0'
};
static
const
WCHAR
slashW
[]
=
{
'\\'
,
'\0'
};
static
const
WCHAR
starW
[]
=
{
'*'
,
'\0'
};
static
const
WCHAR
equalW
[]
=
{
'='
,
'\0'
};
static
const
WCHAR
fslashW
[]
=
{
'/'
,
'\0'
};
static
const
WCHAR
onW
[]
=
{
'O'
,
'N'
,
'\0'
};
static
const
WCHAR
offW
[]
=
{
'O'
,
'F'
,
'F'
,
'\0'
};
static
const
WCHAR
parmY
[]
=
{
'/'
,
'Y'
,
'\0'
};
static
const
WCHAR
parmNoY
[]
=
{
'/'
,
'-'
,
'Y'
,
'\0'
};
static
const
WCHAR
nullW
[]
=
{
'\0'
};
/****************************************************************************
/****************************************************************************
* WCMD_clear_screen
* WCMD_clear_screen
...
@@ -105,55 +115,56 @@ void WCMD_copy (void) {
...
@@ -105,55 +115,56 @@ void WCMD_copy (void) {
WIN32_FIND_DATA
fd
;
WIN32_FIND_DATA
fd
;
HANDLE
hff
;
HANDLE
hff
;
BOOL
force
,
status
;
BOOL
force
,
status
;
char
outpath
[
MAX_PATH
],
inpath
[
MAX_PATH
],
*
infile
,
copycmd
[
3
];
WCHAR
outpath
[
MAX_PATH
],
inpath
[
MAX_PATH
],
*
infile
,
copycmd
[
3
];
DWORD
len
;
DWORD
len
;
static
const
WCHAR
copyCmdW
[]
=
{
'C'
,
'O'
,
'P'
,
'Y'
,
'C'
,
'M'
,
'D'
,
'\0'
};
if
(
param1
[
0
]
==
0x00
)
{
if
(
param1
[
0
]
==
0x00
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOARG
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOARG
));
return
;
return
;
}
}
if
((
strchr
(
param1
,
'*'
)
!=
NULL
)
&&
(
strchr
(
param1
,
'%'
)
!=
NULL
))
{
if
((
strchr
W
(
param1
,
'*'
)
!=
NULL
)
&&
(
strchrW
(
param1
,
'%'
)
!=
NULL
))
{
WCMD_output
(
"Wildcards not yet supported
\n
"
);
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NYI
)
);
return
;
return
;
}
}
/* If no destination supplied, assume current directory */
/* If no destination supplied, assume current directory */
if
(
param2
[
0
]
==
0x00
)
{
if
(
param2
[
0
]
==
0x00
)
{
strcpy
(
param2
,
"."
);
strcpy
W
(
param2
,
dotW
);
}
}
GetFullPathName
(
param2
,
sizeof
(
outpath
),
outpath
,
NULL
);
GetFullPathName
(
param2
,
sizeof
(
outpath
)
/
sizeof
(
WCHAR
)
,
outpath
,
NULL
);
if
(
outpath
[
strlen
(
outpath
)
-
1
]
==
'\\'
)
if
(
outpath
[
strlen
W
(
outpath
)
-
1
]
==
'\\'
)
outpath
[
strlen
(
outpath
)
-
1
]
=
'\0'
;
outpath
[
strlen
W
(
outpath
)
-
1
]
=
'\0'
;
hff
=
FindFirstFile
(
outpath
,
&
fd
);
hff
=
FindFirstFile
(
outpath
,
&
fd
);
if
(
hff
!=
INVALID_HANDLE_VALUE
)
{
if
(
hff
!=
INVALID_HANDLE_VALUE
)
{
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
{
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
{
GetFullPathName
(
param1
,
sizeof
(
inpath
),
inpath
,
&
infile
);
GetFullPathName
(
param1
,
sizeof
(
inpath
)
/
sizeof
(
WCHAR
)
,
inpath
,
&
infile
);
strcat
(
outpath
,
"
\\
"
);
strcat
W
(
outpath
,
slashW
);
strcat
(
outpath
,
infile
);
strcat
W
(
outpath
,
infile
);
}
}
FindClose
(
hff
);
FindClose
(
hff
);
}
}
/* /-Y has the highest priority, then /Y and finally the COPYCMD env. variable */
/* /-Y has the highest priority, then /Y and finally the COPYCMD env. variable */
if
(
strstr
(
quals
,
"/-Y"
))
if
(
strstr
W
(
quals
,
parmNoY
))
force
=
FALSE
;
force
=
FALSE
;
else
if
(
strstr
(
quals
,
"/Y"
))
else
if
(
strstr
W
(
quals
,
parmY
))
force
=
TRUE
;
force
=
TRUE
;
else
{
else
{
len
=
GetEnvironmentVariable
(
"COPYCMD"
,
copycmd
,
sizeof
(
copycmd
));
len
=
GetEnvironmentVariable
(
copyCmdW
,
copycmd
,
sizeof
(
copycmd
)
/
sizeof
(
WCHAR
));
force
=
(
len
&&
len
<
sizeof
(
copycmd
)
&&
!
lstrcmpi
(
copycmd
,
"/Y"
));
force
=
(
len
&&
len
<
(
sizeof
(
copycmd
)
/
sizeof
(
WCHAR
))
&&
!
lstrcmpiW
(
copycmd
,
parmY
));
}
}
if
(
!
force
)
{
if
(
!
force
)
{
hff
=
FindFirstFile
(
outpath
,
&
fd
);
hff
=
FindFirstFile
(
outpath
,
&
fd
);
if
(
hff
!=
INVALID_HANDLE_VALUE
)
{
if
(
hff
!=
INVALID_HANDLE_VALUE
)
{
char
buffer
[
MAXSTRING
];
WCHAR
buffer
[
MAXSTRING
];
FindClose
(
hff
);
FindClose
(
hff
);
sprintf
(
buffer
,
WCMD_LoadMessage
(
WCMD_OVERWRITE
),
outpath
);
w
sprintf
(
buffer
,
WCMD_LoadMessage
(
WCMD_OVERWRITE
),
outpath
);
force
=
WCMD_ask_confirm
(
buffer
,
FALSE
,
NULL
);
force
=
WCMD_ask_confirm
(
buffer
,
FALSE
,
NULL
);
}
}
else
force
=
TRUE
;
else
force
=
TRUE
;
...
@@ -173,21 +184,21 @@ void WCMD_copy (void) {
...
@@ -173,21 +184,21 @@ void WCMD_copy (void) {
* they do not already exist.
* they do not already exist.
*/
*/
static
BOOL
create_full_path
(
CHAR
*
path
)
static
BOOL
create_full_path
(
W
CHAR
*
path
)
{
{
int
len
;
int
len
;
CHAR
*
new_path
;
W
CHAR
*
new_path
;
BOOL
ret
=
TRUE
;
BOOL
ret
=
TRUE
;
new_path
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
path
)
+
1
);
new_path
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
strlenW
(
path
)
*
sizeof
(
WCHAR
)
)
+
1
);
strcpy
(
new_path
,
path
);
strcpy
W
(
new_path
,
path
);
while
((
len
=
strlen
(
new_path
))
&&
new_path
[
len
-
1
]
==
'\\'
)
while
((
len
=
strlen
W
(
new_path
))
&&
new_path
[
len
-
1
]
==
'\\'
)
new_path
[
len
-
1
]
=
0
;
new_path
[
len
-
1
]
=
0
;
while
(
!
CreateDirectory
(
new_path
,
NULL
))
while
(
!
CreateDirectory
(
new_path
,
NULL
))
{
{
CHAR
*
slash
;
W
CHAR
*
slash
;
DWORD
last_error
=
GetLastError
();
DWORD
last_error
=
GetLastError
();
if
(
last_error
==
ERROR_ALREADY_EXISTS
)
if
(
last_error
==
ERROR_ALREADY_EXISTS
)
break
;
break
;
...
@@ -198,7 +209,7 @@ static BOOL create_full_path(CHAR* path)
...
@@ -198,7 +209,7 @@ static BOOL create_full_path(CHAR* path)
break
;
break
;
}
}
if
(
!
(
slash
=
strrchr
(
new_path
,
'\\'
))
&&
!
(
slash
=
strrchr
(
new_path
,
'/'
)))
if
(
!
(
slash
=
strrchr
W
(
new_path
,
'\\'
))
&&
!
(
slash
=
strrchrW
(
new_path
,
'/'
)))
{
{
ret
=
FALSE
;
ret
=
FALSE
;
break
;
break
;
...
@@ -239,58 +250,66 @@ void WCMD_create_dir (void) {
...
@@ -239,58 +250,66 @@ void WCMD_create_dir (void) {
* non-hidden files
* non-hidden files
*/
*/
BOOL
WCMD_delete
(
char
*
command
,
BOOL
expectDir
)
{
BOOL
WCMD_delete
(
WCHAR
*
command
,
BOOL
expectDir
)
{
int
argno
=
0
;
int
argno
=
0
;
int
argsProcessed
=
0
;
int
argsProcessed
=
0
;
char
*
argN
=
command
;
WCHAR
*
argN
=
command
;
BOOL
foundAny
=
FALSE
;
BOOL
foundAny
=
FALSE
;
static
const
WCHAR
parmA
[]
=
{
'/'
,
'A'
,
'\0'
};
static
const
WCHAR
parmQ
[]
=
{
'/'
,
'Q'
,
'\0'
};
static
const
WCHAR
parmP
[]
=
{
'/'
,
'P'
,
'\0'
};
static
const
WCHAR
parmS
[]
=
{
'/'
,
'S'
,
'\0'
};
static
const
WCHAR
parmF
[]
=
{
'/'
,
'F'
,
'\0'
};
/* If not recursing, clear error flag */
/* If not recursing, clear error flag */
if
(
expectDir
)
errorlevel
=
0
;
if
(
expectDir
)
errorlevel
=
0
;
/* Loop through all args */
/* Loop through all args */
while
(
argN
)
{
while
(
argN
)
{
char
*
thisArg
=
WCMD_parameter
(
command
,
argno
++
,
&
argN
);
WCHAR
*
thisArg
=
WCMD_parameter
(
command
,
argno
++
,
&
argN
);
char
argCopy
[
MAX_PATH
];
WCHAR
argCopy
[
MAX_PATH
];
if
(
argN
&&
argN
[
0
]
!=
'/'
)
{
if
(
argN
&&
argN
[
0
]
!=
'/'
)
{
WIN32_FIND_DATA
fd
;
WIN32_FIND_DATA
fd
;
HANDLE
hff
;
HANDLE
hff
;
char
fpath
[
MAX_PATH
];
WCHAR
fpath
[
MAX_PATH
];
char
*
p
;
WCHAR
*
p
;
BOOL
handleParm
=
TRUE
;
BOOL
handleParm
=
TRUE
;
BOOL
found
=
FALSE
;
BOOL
found
=
FALSE
;
static
const
WCHAR
anyExt
[]
=
{
'.'
,
'*'
,
'\0'
};
strcpy
(
argCopy
,
thisArg
);
strcpyW
(
argCopy
,
thisArg
);
WINE_TRACE
(
"del: Processing arg %s (quals:%s)
\n
"
,
argCopy
,
quals
);
WINE_TRACE
(
"del: Processing arg %s (quals:%s)
\n
"
,
wine_dbgstr_w
(
argCopy
),
wine_dbgstr_w
(
quals
));
argsProcessed
++
;
argsProcessed
++
;
/* If filename part of parameter is * or *.*, prompt unless
/* If filename part of parameter is * or *.*, prompt unless
/Q supplied. */
/Q supplied. */
if
((
strstr
(
quals
,
"/Q"
)
==
NULL
)
&&
(
strstr
(
quals
,
"/P"
)
==
NULL
))
{
if
((
strstr
W
(
quals
,
parmQ
)
==
NULL
)
&&
(
strstrW
(
quals
,
parmP
)
==
NULL
))
{
char
drive
[
10
];
WCHAR
drive
[
10
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
char
fname
[
MAX_PATH
];
WCHAR
fname
[
MAX_PATH
];
char
ext
[
MAX_PATH
];
WCHAR
ext
[
MAX_PATH
];
/* Convert path into actual directory spec */
/* Convert path into actual directory spec */
GetFullPathName
(
argCopy
,
sizeof
(
fpath
),
fpath
,
NULL
);
GetFullPathName
(
argCopy
,
sizeof
(
fpath
)
/
sizeof
(
WCHAR
)
,
fpath
,
NULL
);
WCMD_splitpath
(
fpath
,
drive
,
dir
,
fname
,
ext
);
WCMD_splitpath
(
fpath
,
drive
,
dir
,
fname
,
ext
);
/* Only prompt for * and *.*, not *a, a*, *.a* etc */
/* Only prompt for * and *.*, not *a, a*, *.a* etc */
if
((
strcmp
(
fname
,
"*"
)
==
0
)
&&
if
((
strcmp
W
(
fname
,
starW
)
==
0
)
&&
(
*
ext
==
0x00
||
(
strcmp
(
ext
,
".*"
)
==
0
)))
{
(
*
ext
==
0x00
||
(
strcmp
W
(
ext
,
anyExt
)
==
0
)))
{
BOOL
ok
;
BOOL
ok
;
char
question
[
MAXSTRING
];
WCHAR
question
[
MAXSTRING
];
static
const
WCHAR
fmt
[]
=
{
'%'
,
's'
,
' '
,
'\0'
};
/* Note: Flag as found, to avoid file not found message */
/* Note: Flag as found, to avoid file not found message */
found
=
TRUE
;
found
=
TRUE
;
/* Ask for confirmation */
/* Ask for confirmation */
sprintf
(
question
,
"%s, "
,
fpath
);
wsprintf
(
question
,
fmt
,
fpath
);
ok
=
WCMD_ask_confirm
(
question
,
TRUE
,
NULL
);
ok
=
WCMD_ask_confirm
(
question
,
TRUE
,
NULL
);
/* Abort if answer is 'N' */
/* Abort if answer is 'N' */
...
@@ -307,11 +326,13 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
...
@@ -307,11 +326,13 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
}
}
/* Support del <dirname> by just deleting all files dirname\* */
/* Support del <dirname> by just deleting all files dirname\* */
if
(
handleParm
&&
(
strchr
(
argCopy
,
'*'
)
==
NULL
)
&&
(
strchr
(
argCopy
,
'?'
)
==
NULL
)
if
(
handleParm
&&
(
strchr
W
(
argCopy
,
'*'
)
==
NULL
)
&&
(
strchrW
(
argCopy
,
'?'
)
==
NULL
)
&&
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
))
{
&&
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
))
{
char
modifiedParm
[
MAX_PATH
];
WCHAR
modifiedParm
[
MAX_PATH
];
strcpy
(
modifiedParm
,
argCopy
);
static
const
WCHAR
slashStar
[]
=
{
'\\'
,
'*'
,
'\0'
};
strcat
(
modifiedParm
,
"
\\
*"
);
strcpyW
(
modifiedParm
,
argCopy
);
strcatW
(
modifiedParm
,
slashStar
);
FindClose
(
hff
);
FindClose
(
hff
);
found
=
TRUE
;
found
=
TRUE
;
WCMD_delete
(
modifiedParm
,
FALSE
);
WCMD_delete
(
modifiedParm
,
FALSE
);
...
@@ -319,24 +340,24 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
...
@@ -319,24 +340,24 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
}
else
if
(
handleParm
)
{
}
else
if
(
handleParm
)
{
/* Build the filename to delete as <supplied directory>\<findfirst filename> */
/* Build the filename to delete as <supplied directory>\<findfirst filename> */
strcpy
(
fpath
,
argCopy
);
strcpy
W
(
fpath
,
argCopy
);
do
{
do
{
p
=
strrchr
(
fpath
,
'\\'
);
p
=
strrchr
W
(
fpath
,
'\\'
);
if
(
p
!=
NULL
)
{
if
(
p
!=
NULL
)
{
*++
p
=
'\0'
;
*++
p
=
'\0'
;
strcat
(
fpath
,
fd
.
cFileName
);
strcat
W
(
fpath
,
fd
.
cFileName
);
}
}
else
strcpy
(
fpath
,
fd
.
cFileName
);
else
strcpy
W
(
fpath
,
fd
.
cFileName
);
if
(
!
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
))
{
if
(
!
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
))
{
BOOL
ok
=
TRUE
;
BOOL
ok
=
TRUE
;
char
*
nextA
=
strstr
(
quals
,
"/A"
);
WCHAR
*
nextA
=
strstrW
(
quals
,
parmA
);
/* Handle attribute matching (/A) */
/* Handle attribute matching (/A) */
if
(
nextA
!=
NULL
)
{
if
(
nextA
!=
NULL
)
{
ok
=
FALSE
;
ok
=
FALSE
;
while
(
nextA
!=
NULL
&&
!
ok
)
{
while
(
nextA
!=
NULL
&&
!
ok
)
{
char
*
thisA
=
(
nextA
+
2
);
WCHAR
*
thisA
=
(
nextA
+
2
);
BOOL
stillOK
=
TRUE
;
BOOL
stillOK
=
TRUE
;
/* Skip optional : */
/* Skip optional : */
...
@@ -383,16 +404,16 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
...
@@ -383,16 +404,16 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
ok
=
stillOK
;
ok
=
stillOK
;
/* Step on to next /A set */
/* Step on to next /A set */
nextA
=
strstr
(
nextA
+
1
,
"/A"
);
nextA
=
strstr
W
(
nextA
+
1
,
parmA
);
}
}
}
}
/* /P means prompt for each file */
/* /P means prompt for each file */
if
(
ok
&&
strstr
(
quals
,
"/P"
)
!=
NULL
)
{
if
(
ok
&&
strstr
W
(
quals
,
parmP
)
!=
NULL
)
{
char
question
[
MAXSTRING
];
WCHAR
question
[
MAXSTRING
];
/* Ask for confirmation */
/* Ask for confirmation */
sprintf
(
question
,
WCMD_LoadMessage
(
WCMD_DELPROMPT
),
fpath
);
w
sprintf
(
question
,
WCMD_LoadMessage
(
WCMD_DELPROMPT
),
fpath
);
ok
=
WCMD_ask_confirm
(
question
,
FALSE
,
NULL
);
ok
=
WCMD_ask_confirm
(
question
,
FALSE
,
NULL
);
}
}
...
@@ -401,7 +422,7 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
...
@@ -401,7 +422,7 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
/* If file is read only, and /F supplied, delete it */
/* If file is read only, and /F supplied, delete it */
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_READONLY
&&
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_READONLY
&&
strstr
(
quals
,
"/F"
)
!=
NULL
)
{
strstr
W
(
quals
,
parmF
)
!=
NULL
)
{
SetFileAttributes
(
fpath
,
fd
.
dwFileAttributes
&
~
FILE_ATTRIBUTE_READONLY
);
SetFileAttributes
(
fpath
,
fd
.
dwFileAttributes
&
~
FILE_ATTRIBUTE_READONLY
);
}
}
...
@@ -415,25 +436,25 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
...
@@ -415,25 +436,25 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
}
}
/* Now recurse into all subdirectories handling the parameter in the same way */
/* Now recurse into all subdirectories handling the parameter in the same way */
if
(
strstr
(
quals
,
"/S"
)
!=
NULL
)
{
if
(
strstr
W
(
quals
,
parmS
)
!=
NULL
)
{
char
thisDir
[
MAX_PATH
];
WCHAR
thisDir
[
MAX_PATH
];
int
cPos
;
int
cPos
;
char
drive
[
10
];
WCHAR
drive
[
10
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
char
fname
[
MAX_PATH
];
WCHAR
fname
[
MAX_PATH
];
char
ext
[
MAX_PATH
];
WCHAR
ext
[
MAX_PATH
];
/* Convert path into actual directory spec */
/* Convert path into actual directory spec */
GetFullPathName
(
argCopy
,
sizeof
(
thisDir
),
thisDir
,
NULL
);
GetFullPathName
(
argCopy
,
sizeof
(
thisDir
)
/
sizeof
(
WCHAR
)
,
thisDir
,
NULL
);
WCMD_splitpath
(
thisDir
,
drive
,
dir
,
fname
,
ext
);
WCMD_splitpath
(
thisDir
,
drive
,
dir
,
fname
,
ext
);
strcpy
(
thisDir
,
drive
);
strcpy
W
(
thisDir
,
drive
);
strcat
(
thisDir
,
dir
);
strcat
W
(
thisDir
,
dir
);
cPos
=
strlen
(
thisDir
);
cPos
=
strlen
W
(
thisDir
);
WINE_TRACE
(
"Searching recursively in '%s'
\n
"
,
thisDir
);
WINE_TRACE
(
"Searching recursively in '%s'
\n
"
,
wine_dbgstr_w
(
thisDir
)
);
/* Append '*' to the directory */
/* Append '*' to the directory */
thisDir
[
cPos
]
=
'*'
;
thisDir
[
cPos
]
=
'*'
;
...
@@ -450,19 +471,19 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
...
@@ -450,19 +471,19 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
do
{
do
{
if
((
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
&&
if
((
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
&&
(
strcmp
(
fd
.
cFileName
,
".."
)
!=
0
)
&&
(
strcmp
W
(
fd
.
cFileName
,
dotdotW
)
!=
0
)
&&
(
strcmp
(
fd
.
cFileName
,
"."
)
!=
0
))
{
(
strcmp
W
(
fd
.
cFileName
,
dotW
)
!=
0
))
{
DIRECTORY_STACK
*
nextDir
;
DIRECTORY_STACK
*
nextDir
;
char
subParm
[
MAX_PATH
];
WCHAR
subParm
[
MAX_PATH
];
/* Work out search parameter in sub dir */
/* Work out search parameter in sub dir */
strcpy
(
subParm
,
thisDir
);
strcpy
W
(
subParm
,
thisDir
);
strcat
(
subParm
,
fd
.
cFileName
);
strcat
W
(
subParm
,
fd
.
cFileName
);
strcat
(
subParm
,
"
\\
"
);
strcat
W
(
subParm
,
slashW
);
strcat
(
subParm
,
fname
);
strcat
W
(
subParm
,
fname
);
strcat
(
subParm
,
ext
);
strcat
W
(
subParm
,
ext
);
WINE_TRACE
(
"Recursive, Adding to search list '%s'
\n
"
,
subParm
);
WINE_TRACE
(
"Recursive, Adding to search list '%s'
\n
"
,
wine_dbgstr_w
(
subParm
)
);
/* Allocate memory, add to list */
/* Allocate memory, add to list */
nextDir
=
(
DIRECTORY_STACK
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DIRECTORY_STACK
));
nextDir
=
(
DIRECTORY_STACK
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DIRECTORY_STACK
));
...
@@ -470,8 +491,9 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
...
@@ -470,8 +491,9 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
if
(
lastEntry
!=
NULL
)
lastEntry
->
next
=
nextDir
;
if
(
lastEntry
!=
NULL
)
lastEntry
->
next
=
nextDir
;
lastEntry
=
nextDir
;
lastEntry
=
nextDir
;
nextDir
->
next
=
NULL
;
nextDir
->
next
=
NULL
;
nextDir
->
dirName
=
HeapAlloc
(
GetProcessHeap
(),
0
,(
strlen
(
subParm
)
+
1
));
nextDir
->
dirName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strcpy
(
nextDir
->
dirName
,
subParm
);
(
strlenW
(
subParm
)
+
1
)
*
sizeof
(
WCHAR
));
strcpyW
(
nextDir
->
dirName
,
subParm
);
}
}
}
while
(
FindNextFile
(
hff
,
&
fd
)
!=
0
);
}
while
(
FindNextFile
(
hff
,
&
fd
)
!=
0
);
FindClose
(
hff
);
FindClose
(
hff
);
...
@@ -516,7 +538,7 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
...
@@ -516,7 +538,7 @@ BOOL WCMD_delete (char *command, BOOL expectDir) {
* in DOS (try typing "ECHO ON AGAIN" for an example).
* in DOS (try typing "ECHO ON AGAIN" for an example).
*/
*/
void
WCMD_echo
(
const
char
*
command
)
{
void
WCMD_echo
(
const
WCHAR
*
command
)
{
int
count
;
int
count
;
...
@@ -526,17 +548,17 @@ void WCMD_echo (const char *command) {
...
@@ -526,17 +548,17 @@ void WCMD_echo (const char *command) {
}
}
if
(
command
[
0
]
==
' '
)
if
(
command
[
0
]
==
' '
)
command
++
;
command
++
;
count
=
strlen
(
command
);
count
=
strlen
W
(
command
);
if
(
count
==
0
)
{
if
(
count
==
0
)
{
if
(
echo_mode
)
WCMD_output
(
WCMD_LoadMessage
(
WCMD_ECHOPROMPT
),
"ON"
);
if
(
echo_mode
)
WCMD_output
(
WCMD_LoadMessage
(
WCMD_ECHOPROMPT
),
onW
);
else
WCMD_output
(
WCMD_LoadMessage
(
WCMD_ECHOPROMPT
),
"OFF"
);
else
WCMD_output
(
WCMD_LoadMessage
(
WCMD_ECHOPROMPT
),
offW
);
return
;
return
;
}
}
if
(
lstrcmpi
(
command
,
"ON"
)
==
0
)
{
if
(
lstrcmpi
W
(
command
,
onW
)
==
0
)
{
echo_mode
=
1
;
echo_mode
=
1
;
return
;
return
;
}
}
if
(
lstrcmpi
(
command
,
"OFF"
)
==
0
)
{
if
(
lstrcmpi
W
(
command
,
offW
)
==
0
)
{
echo_mode
=
0
;
echo_mode
=
0
;
return
;
return
;
}
}
...
@@ -553,23 +575,25 @@ void WCMD_echo (const char *command) {
...
@@ -553,23 +575,25 @@ void WCMD_echo (const char *command) {
* will probably work here, but the reverse is not necessarily the case...
* will probably work here, but the reverse is not necessarily the case...
*/
*/
void
WCMD_for
(
char
*
p
)
{
void
WCMD_for
(
WCHAR
*
p
)
{
WIN32_FIND_DATA
fd
;
WIN32_FIND_DATA
fd
;
HANDLE
hff
;
HANDLE
hff
;
char
*
cmd
,
*
item
;
WCHAR
*
cmd
,
*
item
;
char
set
[
MAX_PATH
],
param
[
MAX_PATH
];
WCHAR
set
[
MAX_PATH
],
param
[
MAX_PATH
];
int
i
;
int
i
;
const
WCHAR
inW
[]
=
{
'i'
,
'n'
,
'\0'
};
const
WCHAR
doW
[]
=
{
'd'
,
'o'
,
'\0'
};
if
(
lstrcmpi
(
WCMD_parameter
(
p
,
1
,
NULL
),
"in"
)
if
(
lstrcmpi
W
(
WCMD_parameter
(
p
,
1
,
NULL
),
inW
)
||
lstrcmpi
(
WCMD_parameter
(
p
,
3
,
NULL
),
"do"
)
||
lstrcmpi
W
(
WCMD_parameter
(
p
,
3
,
NULL
),
doW
)
||
(
param1
[
0
]
!=
'%'
))
{
||
(
param1
[
0
]
!=
'%'
))
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_SYNTAXERR
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_SYNTAXERR
));
return
;
return
;
}
}
lstrcpyn
(
set
,
WCMD_parameter
(
p
,
2
,
NULL
),
sizeof
(
set
));
lstrcpyn
W
(
set
,
WCMD_parameter
(
p
,
2
,
NULL
),
sizeof
(
set
)
/
sizeof
(
WCHAR
));
WCMD_parameter
(
p
,
4
,
&
cmd
);
WCMD_parameter
(
p
,
4
,
&
cmd
);
lstrcpy
(
param
,
param1
);
strcpyW
(
param
,
param1
);
/*
/*
* If the parameter within the set has a wildcard then search for matching files
* If the parameter within the set has a wildcard then search for matching files
...
@@ -578,7 +602,8 @@ void WCMD_for (char *p) {
...
@@ -578,7 +602,8 @@ void WCMD_for (char *p) {
i
=
0
;
i
=
0
;
while
(
*
(
item
=
WCMD_parameter
(
set
,
i
,
NULL
)))
{
while
(
*
(
item
=
WCMD_parameter
(
set
,
i
,
NULL
)))
{
if
(
strpbrk
(
item
,
"*?"
))
{
static
const
WCHAR
wildcards
[]
=
{
'*'
,
'?'
,
'\0'
};
if
(
strpbrkW
(
item
,
wildcards
))
{
hff
=
FindFirstFile
(
item
,
&
fd
);
hff
=
FindFirstFile
(
item
,
&
fd
);
if
(
hff
==
INVALID_HANDLE_VALUE
)
{
if
(
hff
==
INVALID_HANDLE_VALUE
)
{
return
;
return
;
...
@@ -601,24 +626,24 @@ void WCMD_for (char *p) {
...
@@ -601,24 +626,24 @@ void WCMD_for (char *p) {
* Execute a command after substituting variable text for the supplied parameter
* Execute a command after substituting variable text for the supplied parameter
*/
*/
void
WCMD_execute
(
char
*
orig_cmd
,
char
*
param
,
char
*
subst
)
{
void
WCMD_execute
(
WCHAR
*
orig_cmd
,
WCHAR
*
param
,
WCHAR
*
subst
)
{
char
*
new_cmd
,
*
p
,
*
s
,
*
dup
;
WCHAR
*
new_cmd
,
*
p
,
*
s
,
*
dup
;
int
size
;
int
size
;
size
=
lstrlen
(
orig_cmd
);
size
=
strlenW
(
orig_cmd
);
new_cmd
=
(
char
*
)
LocalAlloc
(
LMEM_FIXED
|
LMEM_ZEROINIT
,
size
);
new_cmd
=
(
WCHAR
*
)
LocalAlloc
(
LMEM_FIXED
|
LMEM_ZEROINIT
,
size
);
dup
=
s
=
strdup
(
orig_cmd
);
dup
=
s
=
WCMD_strdupW
(
orig_cmd
);
while
((
p
=
strstr
(
s
,
param
)))
{
while
((
p
=
strstr
W
(
s
,
param
)))
{
*
p
=
'\0'
;
*
p
=
'\0'
;
size
+=
lstrlen
(
subst
);
size
+=
strlenW
(
subst
);
new_cmd
=
(
char
*
)
LocalReAlloc
((
HANDLE
)
new_cmd
,
size
,
0
);
new_cmd
=
(
WCHAR
*
)
LocalReAlloc
((
HANDLE
)
new_cmd
,
size
,
0
);
strcat
(
new_cmd
,
s
);
strcat
W
(
new_cmd
,
s
);
strcat
(
new_cmd
,
subst
);
strcat
W
(
new_cmd
,
subst
);
s
=
p
+
lstrlen
(
param
);
s
=
p
+
strlenW
(
param
);
}
}
strcat
(
new_cmd
,
s
);
strcat
W
(
new_cmd
,
s
);
WCMD_process_command
(
new_cmd
);
WCMD_process_command
(
new_cmd
);
free
(
dup
);
free
(
dup
);
LocalFree
((
HANDLE
)
new_cmd
);
LocalFree
((
HANDLE
)
new_cmd
);
...
@@ -631,21 +656,21 @@ void WCMD_execute (char *orig_cmd, char *param, char *subst) {
...
@@ -631,21 +656,21 @@ void WCMD_execute (char *orig_cmd, char *param, char *subst) {
* Simple on-line help. Help text is stored in the resource file.
* Simple on-line help. Help text is stored in the resource file.
*/
*/
void
WCMD_give_help
(
char
*
command
)
{
void
WCMD_give_help
(
WCHAR
*
command
)
{
int
i
;
int
i
;
char
buffer
[
2048
];
WCHAR
buffer
[
2048
];
command
=
WCMD_strtrim_leading_spaces
(
command
);
command
=
WCMD_strtrim_leading_spaces
(
command
);
if
(
lstrlen
(
command
)
==
0
)
{
if
(
strlenW
(
command
)
==
0
)
{
LoadString
(
hinst
,
1000
,
buffer
,
sizeof
(
buffer
));
LoadString
(
hinst
,
1000
,
buffer
,
sizeof
(
buffer
)
/
sizeof
(
WCHAR
)
);
WCMD_output_asis
(
buffer
);
WCMD_output_asis
(
buffer
);
}
}
else
{
else
{
for
(
i
=
0
;
i
<=
WCMD_EXIT
;
i
++
)
{
for
(
i
=
0
;
i
<=
WCMD_EXIT
;
i
++
)
{
if
(
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
if
(
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
param1
,
-
1
,
inbuilt
[
i
],
-
1
)
==
2
)
{
param1
,
-
1
,
inbuilt
[
i
],
-
1
)
==
2
)
{
LoadString
(
hinst
,
i
,
buffer
,
sizeof
(
buffer
));
LoadString
(
hinst
,
i
,
buffer
,
sizeof
(
buffer
)
/
sizeof
(
WCHAR
)
);
WCMD_output_asis
(
buffer
);
WCMD_output_asis
(
buffer
);
return
;
return
;
}
}
...
@@ -666,17 +691,18 @@ void WCMD_give_help (char *command) {
...
@@ -666,17 +691,18 @@ void WCMD_give_help (char *command) {
void
WCMD_goto
(
void
)
{
void
WCMD_goto
(
void
)
{
char
string
[
MAX_PATH
];
WCHAR
string
[
MAX_PATH
];
if
(
param1
[
0
]
==
0x00
)
{
if
(
param1
[
0
]
==
0x00
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOARG
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOARG
));
return
;
return
;
}
}
if
(
context
!=
NULL
)
{
if
(
context
!=
NULL
)
{
char
*
paramStart
=
param1
;
WCHAR
*
paramStart
=
param1
;
static
const
WCHAR
eofW
[]
=
{
':'
,
'e'
,
'o'
,
'f'
,
'\0'
};
/* Handle special :EOF label */
/* Handle special :EOF label */
if
(
lstrcmpi
(
":eof"
,
param1
)
==
0
)
{
if
(
lstrcmpi
W
(
eofW
,
param1
)
==
0
)
{
context
->
skip_rest
=
TRUE
;
context
->
skip_rest
=
TRUE
;
return
;
return
;
}
}
...
@@ -685,8 +711,8 @@ void WCMD_goto (void) {
...
@@ -685,8 +711,8 @@ void WCMD_goto (void) {
if
(
*
paramStart
==
':'
)
paramStart
++
;
if
(
*
paramStart
==
':'
)
paramStart
++
;
SetFilePointer
(
context
->
h
,
0
,
NULL
,
FILE_BEGIN
);
SetFilePointer
(
context
->
h
,
0
,
NULL
,
FILE_BEGIN
);
while
(
WCMD_fgets
(
string
,
sizeof
(
string
),
context
->
h
))
{
while
(
WCMD_fgets
(
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
)
,
context
->
h
))
{
if
((
string
[
0
]
==
':'
)
&&
(
lstrcmpi
(
&
string
[
1
],
paramStart
)
==
0
))
return
;
if
((
string
[
0
]
==
':'
)
&&
(
lstrcmpi
W
(
&
string
[
1
],
paramStart
)
==
0
))
return
;
}
}
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOTARGET
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOTARGET
));
}
}
...
@@ -699,11 +725,12 @@ void WCMD_goto (void) {
...
@@ -699,11 +725,12 @@ void WCMD_goto (void) {
* Push a directory onto the stack
* Push a directory onto the stack
*/
*/
void
WCMD_pushd
(
char
*
command
)
{
void
WCMD_pushd
(
WCHAR
*
command
)
{
struct
env_stack
*
curdir
;
struct
env_stack
*
curdir
;
WCHAR
*
thisdir
;
WCHAR
*
thisdir
;
static
const
WCHAR
parmD
[]
=
{
'/'
,
'D'
,
'\0'
};
if
(
strchr
(
command
,
'/'
)
!=
NULL
)
{
if
(
strchr
W
(
command
,
'/'
)
!=
NULL
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
SetLastError
(
ERROR_INVALID_PARAMETER
);
WCMD_print_error
();
WCMD_print_error
();
return
;
return
;
...
@@ -719,7 +746,7 @@ void WCMD_pushd (char *command) {
...
@@ -719,7 +746,7 @@ void WCMD_pushd (char *command) {
}
}
/* Change directory using CD code with /D parameter */
/* Change directory using CD code with /D parameter */
strcpy
(
quals
,
"/D"
);
strcpy
W
(
quals
,
parmD
);
GetCurrentDirectoryW
(
1024
,
thisdir
);
GetCurrentDirectoryW
(
1024
,
thisdir
);
errorlevel
=
0
;
errorlevel
=
0
;
WCMD_setshow_default
(
command
);
WCMD_setshow_default
(
command
);
...
@@ -766,37 +793,42 @@ void WCMD_popd (void) {
...
@@ -766,37 +793,42 @@ void WCMD_popd (void) {
* FIXME: Much more syntax checking needed!
* FIXME: Much more syntax checking needed!
*/
*/
void
WCMD_if
(
char
*
p
)
{
void
WCMD_if
(
WCHAR
*
p
)
{
int
negate
=
0
,
test
=
0
;
int
negate
=
0
,
test
=
0
;
char
condition
[
MAX_PATH
],
*
command
,
*
s
;
WCHAR
condition
[
MAX_PATH
],
*
command
,
*
s
;
static
const
WCHAR
notW
[]
=
{
'n'
,
'o'
,
't'
,
'\0'
};
if
(
!
lstrcmpi
(
param1
,
"not"
))
{
static
const
WCHAR
errlvlW
[]
=
{
'e'
,
'r'
,
'r'
,
'o'
,
'r'
,
'l'
,
'e'
,
'v'
,
'e'
,
'l'
,
'\0'
};
static
const
WCHAR
existW
[]
=
{
'e'
,
'x'
,
'i'
,
's'
,
't'
,
'\0'
};
static
const
WCHAR
defdW
[]
=
{
'd'
,
'e'
,
'f'
,
'i'
,
'n'
,
'e'
,
'd'
,
'\0'
};
static
const
WCHAR
eqeqW
[]
=
{
'='
,
'='
,
'\0'
};
if
(
!
lstrcmpiW
(
param1
,
notW
))
{
negate
=
1
;
negate
=
1
;
lstrcpy
(
condition
,
param2
);
strcpyW
(
condition
,
param2
);
}
}
else
{
else
{
lstrcpy
(
condition
,
param1
);
strcpyW
(
condition
,
param1
);
}
}
if
(
!
lstrcmpi
(
condition
,
"errorlevel"
))
{
if
(
!
lstrcmpi
W
(
condition
,
errlvlW
))
{
if
(
errorlevel
>=
atoi
(
WCMD_parameter
(
p
,
1
+
negate
,
NULL
)))
test
=
1
;
if
(
errorlevel
>=
atoi
W
(
WCMD_parameter
(
p
,
1
+
negate
,
NULL
)))
test
=
1
;
WCMD_parameter
(
p
,
2
+
negate
,
&
command
);
WCMD_parameter
(
p
,
2
+
negate
,
&
command
);
}
}
else
if
(
!
lstrcmpi
(
condition
,
"exist"
))
{
else
if
(
!
lstrcmpi
W
(
condition
,
existW
))
{
if
(
GetFileAttributes
A
(
WCMD_parameter
(
p
,
1
+
negate
,
NULL
))
!=
INVALID_FILE_ATTRIBUTES
)
{
if
(
GetFileAttributes
(
WCMD_parameter
(
p
,
1
+
negate
,
NULL
))
!=
INVALID_FILE_ATTRIBUTES
)
{
test
=
1
;
test
=
1
;
}
}
WCMD_parameter
(
p
,
2
+
negate
,
&
command
);
WCMD_parameter
(
p
,
2
+
negate
,
&
command
);
}
}
else
if
(
!
lstrcmpi
(
condition
,
"defined"
))
{
else
if
(
!
lstrcmpi
W
(
condition
,
defdW
))
{
if
(
GetEnvironmentVariable
A
(
WCMD_parameter
(
p
,
1
+
negate
,
NULL
),
NULL
,
0
)
>
0
)
{
if
(
GetEnvironmentVariable
(
WCMD_parameter
(
p
,
1
+
negate
,
NULL
),
NULL
,
0
)
>
0
)
{
test
=
1
;
test
=
1
;
}
}
WCMD_parameter
(
p
,
2
+
negate
,
&
command
);
WCMD_parameter
(
p
,
2
+
negate
,
&
command
);
}
}
else
if
((
s
=
strstr
(
p
,
"=="
)))
{
else
if
((
s
=
strstr
W
(
p
,
eqeqW
)))
{
s
+=
2
;
s
+=
2
;
if
(
!
lstrcmpi
(
condition
,
WCMD_parameter
(
s
,
0
,
NULL
)))
test
=
1
;
if
(
!
lstrcmpi
W
(
condition
,
WCMD_parameter
(
s
,
0
,
NULL
)))
test
=
1
;
WCMD_parameter
(
s
,
1
,
&
command
);
WCMD_parameter
(
s
,
1
,
&
command
);
}
}
else
{
else
{
...
@@ -804,7 +836,7 @@ void WCMD_if (char *p) {
...
@@ -804,7 +836,7 @@ void WCMD_if (char *p) {
return
;
return
;
}
}
if
(
test
!=
negate
)
{
if
(
test
!=
negate
)
{
command
=
strdup
(
command
);
command
=
WCMD_strdupW
(
command
);
WCMD_process_command
(
command
);
WCMD_process_command
(
command
);
free
(
command
);
free
(
command
);
}
}
...
@@ -821,12 +853,12 @@ void WCMD_move (void) {
...
@@ -821,12 +853,12 @@ void WCMD_move (void) {
int
status
;
int
status
;
WIN32_FIND_DATA
fd
;
WIN32_FIND_DATA
fd
;
HANDLE
hff
;
HANDLE
hff
;
char
input
[
MAX_PATH
];
WCHAR
input
[
MAX_PATH
];
char
output
[
MAX_PATH
];
WCHAR
output
[
MAX_PATH
];
char
drive
[
10
];
WCHAR
drive
[
10
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
char
fname
[
MAX_PATH
];
WCHAR
fname
[
MAX_PATH
];
char
ext
[
MAX_PATH
];
WCHAR
ext
[
MAX_PATH
];
if
(
param1
[
0
]
==
0x00
)
{
if
(
param1
[
0
]
==
0x00
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOARG
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOARG
));
...
@@ -835,48 +867,49 @@ void WCMD_move (void) {
...
@@ -835,48 +867,49 @@ void WCMD_move (void) {
/* If no destination supplied, assume current directory */
/* If no destination supplied, assume current directory */
if
(
param2
[
0
]
==
0x00
)
{
if
(
param2
[
0
]
==
0x00
)
{
strcpy
(
param2
,
"."
);
strcpy
W
(
param2
,
dotW
);
}
}
/* If 2nd parm is directory, then use original filename */
/* If 2nd parm is directory, then use original filename */
/* Convert partial path to full path */
/* Convert partial path to full path */
GetFullPathName
(
param1
,
sizeof
(
input
),
input
,
NULL
);
GetFullPathName
(
param1
,
sizeof
(
input
)
/
sizeof
(
WCHAR
),
input
,
NULL
);
GetFullPathName
(
param2
,
sizeof
(
output
),
output
,
NULL
);
GetFullPathName
(
param2
,
sizeof
(
output
)
/
sizeof
(
WCHAR
),
output
,
NULL
);
WINE_TRACE
(
"Move from '%s'('%s') to '%s'
\n
"
,
input
,
param1
,
output
);
WINE_TRACE
(
"Move from '%s'('%s') to '%s'
\n
"
,
wine_dbgstr_w
(
input
),
wine_dbgstr_w
(
param1
),
wine_dbgstr_w
(
output
));
/* Split into components */
/* Split into components */
WCMD_splitpath
(
input
,
drive
,
dir
,
fname
,
ext
);
WCMD_splitpath
(
input
,
drive
,
dir
,
fname
,
ext
);
hff
=
FindFirstFile
(
input
,
&
fd
);
hff
=
FindFirstFile
(
input
,
&
fd
);
while
(
hff
!=
INVALID_HANDLE_VALUE
)
{
while
(
hff
!=
INVALID_HANDLE_VALUE
)
{
char
dest
[
MAX_PATH
];
WCHAR
dest
[
MAX_PATH
];
char
src
[
MAX_PATH
];
WCHAR
src
[
MAX_PATH
];
DWORD
attribs
;
DWORD
attribs
;
WINE_TRACE
(
"Processing file '%s'
\n
"
,
fd
.
cFileName
);
WINE_TRACE
(
"Processing file '%s'
\n
"
,
wine_dbgstr_w
(
fd
.
cFileName
)
);
/* Build src & dest name */
/* Build src & dest name */
strcpy
(
src
,
drive
);
strcpy
W
(
src
,
drive
);
strcat
(
src
,
dir
);
strcat
W
(
src
,
dir
);
/* See if dest is an existing directory */
/* See if dest is an existing directory */
attribs
=
GetFileAttributes
(
output
);
attribs
=
GetFileAttributes
(
output
);
if
(
attribs
!=
INVALID_FILE_ATTRIBUTES
&&
if
(
attribs
!=
INVALID_FILE_ATTRIBUTES
&&
(
attribs
&
FILE_ATTRIBUTE_DIRECTORY
))
{
(
attribs
&
FILE_ATTRIBUTE_DIRECTORY
))
{
strcpy
(
dest
,
output
);
strcpy
W
(
dest
,
output
);
strcat
(
dest
,
"
\\
"
);
strcat
W
(
dest
,
slashW
);
strcat
(
dest
,
fd
.
cFileName
);
strcat
W
(
dest
,
fd
.
cFileName
);
}
else
{
}
else
{
strcpy
(
dest
,
output
);
strcpy
W
(
dest
,
output
);
}
}
strcat
(
src
,
fd
.
cFileName
);
strcat
W
(
src
,
fd
.
cFileName
);
WINE_TRACE
(
"Source '%s'
\n
"
,
src
);
WINE_TRACE
(
"Source '%s'
\n
"
,
wine_dbgstr_w
(
src
)
);
WINE_TRACE
(
"Dest '%s'
\n
"
,
dest
);
WINE_TRACE
(
"Dest '%s'
\n
"
,
wine_dbgstr_w
(
dest
)
);
/* Check if file is read only, otherwise move it */
/* Check if file is read only, otherwise move it */
attribs
=
GetFileAttributes
A
(
src
);
attribs
=
GetFileAttributes
(
src
);
if
((
attribs
!=
INVALID_FILE_ATTRIBUTES
)
&&
if
((
attribs
!=
INVALID_FILE_ATTRIBUTES
)
&&
(
attribs
&
FILE_ATTRIBUTE_READONLY
))
{
(
attribs
&
FILE_ATTRIBUTE_READONLY
))
{
SetLastError
(
ERROR_ACCESS_DENIED
);
SetLastError
(
ERROR_ACCESS_DENIED
);
...
@@ -885,30 +918,32 @@ void WCMD_move (void) {
...
@@ -885,30 +918,32 @@ void WCMD_move (void) {
BOOL
ok
=
TRUE
;
BOOL
ok
=
TRUE
;
/* If destination exists, prompt unless /Y supplied */
/* If destination exists, prompt unless /Y supplied */
if
(
GetFileAttributes
A
(
dest
)
!=
INVALID_FILE_ATTRIBUTES
)
{
if
(
GetFileAttributes
(
dest
)
!=
INVALID_FILE_ATTRIBUTES
)
{
BOOL
force
=
FALSE
;
BOOL
force
=
FALSE
;
char
copycmd
[
MAXSTRING
];
WCHAR
copycmd
[
MAXSTRING
];
int
len
;
int
len
;
/* /-Y has the highest priority, then /Y and finally the COPYCMD env. variable */
/* /-Y has the highest priority, then /Y and finally the COPYCMD env. variable */
if
(
strstr
(
quals
,
"/-Y"
))
if
(
strstr
W
(
quals
,
parmNoY
))
force
=
FALSE
;
force
=
FALSE
;
else
if
(
strstr
(
quals
,
"/Y"
))
else
if
(
strstr
W
(
quals
,
parmY
))
force
=
TRUE
;
force
=
TRUE
;
else
{
else
{
len
=
GetEnvironmentVariable
(
"COPYCMD"
,
copycmd
,
sizeof
(
copycmd
));
const
WCHAR
copyCmdW
[]
=
{
'C'
,
'O'
,
'P'
,
'Y'
,
'C'
,
'M'
,
'D'
,
'\0'
};
force
=
(
len
&&
len
<
sizeof
(
copycmd
)
&&
!
lstrcmpi
(
copycmd
,
"/Y"
));
len
=
GetEnvironmentVariable
(
copyCmdW
,
copycmd
,
sizeof
(
copycmd
)
/
sizeof
(
WCHAR
));
force
=
(
len
&&
len
<
(
sizeof
(
copycmd
)
/
sizeof
(
WCHAR
))
&&
!
lstrcmpiW
(
copycmd
,
parmY
));
}
}
/* Prompt if overwriting */
/* Prompt if overwriting */
if
(
!
force
)
{
if
(
!
force
)
{
char
question
[
MAXSTRING
];
WCHAR
question
[
MAXSTRING
];
char
yesChar
[
10
];
WCHAR
yesChar
[
10
];
strcpy
(
yesChar
,
WCMD_LoadMessage
(
WCMD_YES
));
strcpy
W
(
yesChar
,
WCMD_LoadMessage
(
WCMD_YES
));
/* Ask for confirmation */
/* Ask for confirmation */
sprintf
(
question
,
WCMD_LoadMessage
(
WCMD_OVERWRITE
),
dest
);
w
sprintf
(
question
,
WCMD_LoadMessage
(
WCMD_OVERWRITE
),
dest
);
ok
=
WCMD_ask_confirm
(
question
,
FALSE
,
NULL
);
ok
=
WCMD_ask_confirm
(
question
,
FALSE
,
NULL
);
/* So delete the destination prior to the move */
/* So delete the destination prior to the move */
...
@@ -952,10 +987,11 @@ void WCMD_move (void) {
...
@@ -952,10 +987,11 @@ void WCMD_move (void) {
void
WCMD_pause
(
void
)
{
void
WCMD_pause
(
void
)
{
DWORD
count
;
DWORD
count
;
char
string
[
32
];
WCHAR
string
[
32
];
WCMD_output
(
anykey
);
WCMD_output
(
anykey
);
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
),
&
count
,
NULL
);
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
}
}
/****************************************************************************
/****************************************************************************
...
@@ -964,22 +1000,25 @@ void WCMD_pause (void) {
...
@@ -964,22 +1000,25 @@ void WCMD_pause (void) {
* Delete a directory.
* Delete a directory.
*/
*/
void
WCMD_remove_dir
(
char
*
command
)
{
void
WCMD_remove_dir
(
WCHAR
*
command
)
{
int
argno
=
0
;
int
argno
=
0
;
int
argsProcessed
=
0
;
int
argsProcessed
=
0
;
char
*
argN
=
command
;
WCHAR
*
argN
=
command
;
static
const
WCHAR
parmS
[]
=
{
'/'
,
'S'
,
'\0'
};
static
const
WCHAR
parmQ
[]
=
{
'/'
,
'Q'
,
'\0'
};
/* Loop through all args */
/* Loop through all args */
while
(
argN
)
{
while
(
argN
)
{
char
*
thisArg
=
WCMD_parameter
(
command
,
argno
++
,
&
argN
);
WCHAR
*
thisArg
=
WCMD_parameter
(
command
,
argno
++
,
&
argN
);
if
(
argN
&&
argN
[
0
]
!=
'/'
)
{
if
(
argN
&&
argN
[
0
]
!=
'/'
)
{
WINE_TRACE
(
"rd: Processing arg %s (quals:%s)
\n
"
,
thisArg
,
quals
);
WINE_TRACE
(
"rd: Processing arg %s (quals:%s)
\n
"
,
wine_dbgstr_w
(
thisArg
),
wine_dbgstr_w
(
quals
));
argsProcessed
++
;
argsProcessed
++
;
/* If subdirectory search not supplied, just try to remove
/* If subdirectory search not supplied, just try to remove
and report error if it fails (eg if it contains a file) */
and report error if it fails (eg if it contains a file) */
if
(
strstr
(
quals
,
"/S"
)
==
NULL
)
{
if
(
strstr
W
(
quals
,
parmS
)
==
NULL
)
{
if
(
!
RemoveDirectory
(
thisArg
))
WCMD_print_error
();
if
(
!
RemoveDirectory
(
thisArg
))
WCMD_print_error
();
/* Otherwise use ShFileOp to recursively remove a directory */
/* Otherwise use ShFileOp to recursively remove a directory */
...
@@ -988,12 +1027,13 @@ void WCMD_remove_dir (char *command) {
...
@@ -988,12 +1027,13 @@ void WCMD_remove_dir (char *command) {
SHFILEOPSTRUCT
lpDir
;
SHFILEOPSTRUCT
lpDir
;
/* Ask first */
/* Ask first */
if
(
strstr
(
quals
,
"/Q"
)
==
NULL
)
{
if
(
strstr
W
(
quals
,
parmQ
)
==
NULL
)
{
BOOL
ok
;
BOOL
ok
;
char
question
[
MAXSTRING
];
WCHAR
question
[
MAXSTRING
];
static
const
WCHAR
fmt
[]
=
{
'%'
,
's'
,
' '
,
'\0'
};
/* Ask for confirmation */
/* Ask for confirmation */
sprintf
(
question
,
"%s, "
,
thisArg
);
wsprintf
(
question
,
fmt
,
thisArg
);
ok
=
WCMD_ask_confirm
(
question
,
TRUE
,
NULL
);
ok
=
WCMD_ask_confirm
(
question
,
TRUE
,
NULL
);
/* Abort if answer is 'N' */
/* Abort if answer is 'N' */
...
@@ -1006,7 +1046,7 @@ void WCMD_remove_dir (char *command) {
...
@@ -1006,7 +1046,7 @@ void WCMD_remove_dir (char *command) {
lpDir
.
pFrom
=
thisArg
;
lpDir
.
pFrom
=
thisArg
;
lpDir
.
fFlags
=
FOF_SILENT
|
FOF_NOCONFIRMATION
|
FOF_NOERRORUI
;
lpDir
.
fFlags
=
FOF_SILENT
|
FOF_NOCONFIRMATION
|
FOF_NOERRORUI
;
lpDir
.
wFunc
=
FO_DELETE
;
lpDir
.
wFunc
=
FO_DELETE
;
if
(
SHFileOperation
A
(
&
lpDir
))
WCMD_print_error
();
if
(
SHFileOperation
(
&
lpDir
))
WCMD_print_error
();
}
}
}
}
}
}
...
@@ -1030,12 +1070,12 @@ void WCMD_rename (void) {
...
@@ -1030,12 +1070,12 @@ void WCMD_rename (void) {
int
status
;
int
status
;
HANDLE
hff
;
HANDLE
hff
;
WIN32_FIND_DATA
fd
;
WIN32_FIND_DATA
fd
;
char
input
[
MAX_PATH
];
WCHAR
input
[
MAX_PATH
];
char
*
dotDst
=
NULL
;
WCHAR
*
dotDst
=
NULL
;
char
drive
[
10
];
WCHAR
drive
[
10
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
char
fname
[
MAX_PATH
];
WCHAR
fname
[
MAX_PATH
];
char
ext
[
MAX_PATH
];
WCHAR
ext
[
MAX_PATH
];
DWORD
attribs
;
DWORD
attribs
;
errorlevel
=
0
;
errorlevel
=
0
;
...
@@ -1048,7 +1088,7 @@ void WCMD_rename (void) {
...
@@ -1048,7 +1088,7 @@ void WCMD_rename (void) {
}
}
/* Destination cannot contain a drive letter or directory separator */
/* Destination cannot contain a drive letter or directory separator */
if
((
strchr
(
param1
,
':'
)
!=
NULL
)
||
(
strchr
(
param1
,
'\\'
)
!=
NULL
))
{
if
((
strchr
W
(
param1
,
':'
)
!=
NULL
)
||
(
strchrW
(
param1
,
'\\'
)
!=
NULL
))
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
SetLastError
(
ERROR_INVALID_PARAMETER
);
WCMD_print_error
();
WCMD_print_error
();
errorlevel
=
1
;
errorlevel
=
1
;
...
@@ -1056,21 +1096,22 @@ void WCMD_rename (void) {
...
@@ -1056,21 +1096,22 @@ void WCMD_rename (void) {
}
}
/* Convert partial path to full path */
/* Convert partial path to full path */
GetFullPathName
(
param1
,
sizeof
(
input
),
input
,
NULL
);
GetFullPathName
(
param1
,
sizeof
(
input
)
/
sizeof
(
WCHAR
),
input
,
NULL
);
WINE_TRACE
(
"Rename from '%s'('%s') to '%s'
\n
"
,
input
,
param1
,
param2
);
WINE_TRACE
(
"Rename from '%s'('%s') to '%s'
\n
"
,
wine_dbgstr_w
(
input
),
dotDst
=
strchr
(
param2
,
'.'
);
wine_dbgstr_w
(
param1
),
wine_dbgstr_w
(
param2
));
dotDst
=
strchrW
(
param2
,
'.'
);
/* Split into components */
/* Split into components */
WCMD_splitpath
(
input
,
drive
,
dir
,
fname
,
ext
);
WCMD_splitpath
(
input
,
drive
,
dir
,
fname
,
ext
);
hff
=
FindFirstFile
(
input
,
&
fd
);
hff
=
FindFirstFile
(
input
,
&
fd
);
while
(
hff
!=
INVALID_HANDLE_VALUE
)
{
while
(
hff
!=
INVALID_HANDLE_VALUE
)
{
char
dest
[
MAX_PATH
];
WCHAR
dest
[
MAX_PATH
];
char
src
[
MAX_PATH
];
WCHAR
src
[
MAX_PATH
];
char
*
dotSrc
=
NULL
;
WCHAR
*
dotSrc
=
NULL
;
int
dirLen
;
int
dirLen
;
WINE_TRACE
(
"Processing file '%s'
\n
"
,
fd
.
cFileName
);
WINE_TRACE
(
"Processing file '%s'
\n
"
,
wine_dbgstr_w
(
fd
.
cFileName
)
);
/* FIXME: If dest name or extension is *, replace with filename/ext
/* FIXME: If dest name or extension is *, replace with filename/ext
part otherwise use supplied name. This supports:
part otherwise use supplied name. This supports:
...
@@ -1078,36 +1119,36 @@ void WCMD_rename (void) {
...
@@ -1078,36 +1119,36 @@ void WCMD_rename (void) {
ren jim.* fred.* etc
ren jim.* fred.* etc
However, windows has a more complex algorithum supporting eg
However, windows has a more complex algorithum supporting eg
?'s and *'s mid name */
?'s and *'s mid name */
dotSrc
=
strchr
(
fd
.
cFileName
,
'.'
);
dotSrc
=
strchr
W
(
fd
.
cFileName
,
'.'
);
/* Build src & dest name */
/* Build src & dest name */
strcpy
(
src
,
drive
);
strcpy
W
(
src
,
drive
);
strcat
(
src
,
dir
);
strcat
W
(
src
,
dir
);
strcpy
(
dest
,
src
);
strcpy
W
(
dest
,
src
);
dirLen
=
strlen
(
src
);
dirLen
=
strlen
W
(
src
);
strcat
(
src
,
fd
.
cFileName
);
strcat
W
(
src
,
fd
.
cFileName
);
/* Build name */
/* Build name */
if
(
param2
[
0
]
==
'*'
)
{
if
(
param2
[
0
]
==
'*'
)
{
strcat
(
dest
,
fd
.
cFileName
);
strcat
W
(
dest
,
fd
.
cFileName
);
if
(
dotSrc
)
dest
[
dirLen
+
(
dotSrc
-
fd
.
cFileName
)]
=
0x00
;
if
(
dotSrc
)
dest
[
dirLen
+
(
dotSrc
-
fd
.
cFileName
)]
=
0x00
;
}
else
{
}
else
{
strcat
(
dest
,
param2
);
strcat
W
(
dest
,
param2
);
if
(
dotDst
)
dest
[
dirLen
+
(
dotDst
-
param2
)]
=
0x00
;
if
(
dotDst
)
dest
[
dirLen
+
(
dotDst
-
param2
)]
=
0x00
;
}
}
/* Build Extension */
/* Build Extension */
if
(
dotDst
&&
(
*
(
dotDst
+
1
)
==
'*'
))
{
if
(
dotDst
&&
(
*
(
dotDst
+
1
)
==
'*'
))
{
if
(
dotSrc
)
strcat
(
dest
,
dotSrc
);
if
(
dotSrc
)
strcat
W
(
dest
,
dotSrc
);
}
else
if
(
dotDst
)
{
}
else
if
(
dotDst
)
{
if
(
dotDst
)
strcat
(
dest
,
dotDst
);
if
(
dotDst
)
strcat
W
(
dest
,
dotDst
);
}
}
WINE_TRACE
(
"Source '%s'
\n
"
,
src
);
WINE_TRACE
(
"Source '%s'
\n
"
,
wine_dbgstr_w
(
src
)
);
WINE_TRACE
(
"Dest '%s'
\n
"
,
dest
);
WINE_TRACE
(
"Dest '%s'
\n
"
,
wine_dbgstr_w
(
dest
)
);
/* Check if file is read only, otherwise move it */
/* Check if file is read only, otherwise move it */
attribs
=
GetFileAttributes
A
(
src
);
attribs
=
GetFileAttributes
(
src
);
if
((
attribs
!=
INVALID_FILE_ATTRIBUTES
)
&&
if
((
attribs
!=
INVALID_FILE_ATTRIBUTES
)
&&
(
attribs
&
FILE_ATTRIBUTE_READONLY
))
{
(
attribs
&
FILE_ATTRIBUTE_READONLY
))
{
SetLastError
(
ERROR_ACCESS_DENIED
);
SetLastError
(
ERROR_ACCESS_DENIED
);
...
@@ -1145,7 +1186,7 @@ static WCHAR *WCMD_dupenv( const WCHAR *env )
...
@@ -1145,7 +1186,7 @@ static WCHAR *WCMD_dupenv( const WCHAR *env )
len
=
0
;
len
=
0
;
while
(
env
[
len
]
)
while
(
env
[
len
]
)
len
+=
(
l
strlenW
(
&
env
[
len
])
+
1
);
len
+=
(
strlenW
(
&
env
[
len
])
+
1
);
env_copy
=
LocalAlloc
(
LMEM_FIXED
,
(
len
+
1
)
*
sizeof
(
WCHAR
)
);
env_copy
=
LocalAlloc
(
LMEM_FIXED
,
(
len
+
1
)
*
sizeof
(
WCHAR
)
);
if
(
!
env_copy
)
if
(
!
env_copy
)
...
@@ -1165,10 +1206,10 @@ static WCHAR *WCMD_dupenv( const WCHAR *env )
...
@@ -1165,10 +1206,10 @@ static WCHAR *WCMD_dupenv( const WCHAR *env )
* setlocal pushes the environment onto a stack
* setlocal pushes the environment onto a stack
* Save the environment as unicode so we don't screw anything up.
* Save the environment as unicode so we don't screw anything up.
*/
*/
void
WCMD_setlocal
(
const
char
*
s
)
{
void
WCMD_setlocal
(
const
WCHAR
*
s
)
{
WCHAR
*
env
;
WCHAR
*
env
;
struct
env_stack
*
env_copy
;
struct
env_stack
*
env_copy
;
char
cwd
[
MAX_PATH
];
WCHAR
cwd
[
MAX_PATH
];
/* DISABLEEXTENSIONS ignored */
/* DISABLEEXTENSIONS ignored */
...
@@ -1199,24 +1240,10 @@ void WCMD_setlocal (const char *s) {
...
@@ -1199,24 +1240,10 @@ void WCMD_setlocal (const char *s) {
}
}
/*****************************************************************************
/*****************************************************************************
* WCMD_strchrW
*/
static
inline
WCHAR
*
WCMD_strchrW
(
WCHAR
*
str
,
WCHAR
ch
)
{
while
(
*
str
)
{
if
(
*
str
==
ch
)
return
str
;
str
++
;
}
return
NULL
;
}
/*****************************************************************************
* WCMD_endlocal
* WCMD_endlocal
*
*
* endlocal pops the environment off a stack
* endlocal pops the environment off a stack
* Note: When searching for '=', search from
char
position 1, to handle
* Note: When searching for '=', search from
WCHAR
position 1, to handle
* special internal environment variables =C:, =D: etc
* special internal environment variables =C:, =D: etc
*/
*/
void
WCMD_endlocal
(
void
)
{
void
WCMD_endlocal
(
void
)
{
...
@@ -1236,8 +1263,8 @@ void WCMD_endlocal (void) {
...
@@ -1236,8 +1263,8 @@ void WCMD_endlocal (void) {
old
=
WCMD_dupenv
(
GetEnvironmentStringsW
());
old
=
WCMD_dupenv
(
GetEnvironmentStringsW
());
len
=
0
;
len
=
0
;
while
(
old
[
len
])
{
while
(
old
[
len
])
{
n
=
l
strlenW
(
&
old
[
len
])
+
1
;
n
=
strlenW
(
&
old
[
len
])
+
1
;
p
=
WCMD_
strchrW
(
&
old
[
len
]
+
1
,
'='
);
p
=
strchrW
(
&
old
[
len
]
+
1
,
'='
);
if
(
p
)
if
(
p
)
{
{
*
p
++
=
0
;
*
p
++
=
0
;
...
@@ -1252,8 +1279,8 @@ void WCMD_endlocal (void) {
...
@@ -1252,8 +1279,8 @@ void WCMD_endlocal (void) {
env
=
temp
->
strings
;
env
=
temp
->
strings
;
len
=
0
;
len
=
0
;
while
(
env
[
len
])
{
while
(
env
[
len
])
{
n
=
l
strlenW
(
&
env
[
len
])
+
1
;
n
=
strlenW
(
&
env
[
len
])
+
1
;
p
=
WCMD_
strchrW
(
&
env
[
len
]
+
1
,
'='
);
p
=
strchrW
(
&
env
[
len
]
+
1
,
'='
);
if
(
p
)
if
(
p
)
{
{
*
p
++
=
0
;
*
p
++
=
0
;
...
@@ -1264,11 +1291,13 @@ void WCMD_endlocal (void) {
...
@@ -1264,11 +1291,13 @@ void WCMD_endlocal (void) {
/* Restore current drive letter */
/* Restore current drive letter */
if
(
IsCharAlpha
(
temp
->
u
.
cwd
))
{
if
(
IsCharAlpha
(
temp
->
u
.
cwd
))
{
char
envvar
[
4
];
WCHAR
envvar
[
4
];
char
cwd
[
MAX_PATH
];
WCHAR
cwd
[
MAX_PATH
];
sprintf
(
envvar
,
"=%c:"
,
temp
->
u
.
cwd
);
static
const
WCHAR
fmt
[]
=
{
'='
,
'%'
,
'c'
,
':'
,
'\0'
};
wsprintf
(
envvar
,
fmt
,
temp
->
u
.
cwd
);
if
(
GetEnvironmentVariable
(
envvar
,
cwd
,
MAX_PATH
))
{
if
(
GetEnvironmentVariable
(
envvar
,
cwd
,
MAX_PATH
))
{
WINE_TRACE
(
"Resetting cwd to %s
\n
"
,
cwd
);
WINE_TRACE
(
"Resetting cwd to %s
\n
"
,
wine_dbgstr_w
(
cwd
)
);
SetCurrentDirectory
(
cwd
);
SetCurrentDirectory
(
cwd
);
}
}
}
}
...
@@ -1295,16 +1324,18 @@ void WCMD_setshow_attrib (void) {
...
@@ -1295,16 +1324,18 @@ void WCMD_setshow_attrib (void) {
DWORD
count
;
DWORD
count
;
HANDLE
hff
;
HANDLE
hff
;
WIN32_FIND_DATA
fd
;
WIN32_FIND_DATA
fd
;
char
flags
[
9
]
=
{
" "
};
WCHAR
flags
[
9
]
=
{
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
'\0'
};
if
(
param1
[
0
]
==
'-'
)
{
if
(
param1
[
0
]
==
'-'
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NYI
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NYI
));
return
;
return
;
}
}
if
(
lstrlen
(
param1
)
==
0
)
{
if
(
strlenW
(
param1
)
==
0
)
{
GetCurrentDirectory
(
sizeof
(
param1
),
param1
);
static
const
WCHAR
slashStarW
[]
=
{
'\\'
,
'*'
,
'\0'
};
strcat
(
param1
,
"
\\
*"
);
GetCurrentDirectory
(
sizeof
(
param1
)
/
sizeof
(
WCHAR
),
param1
);
strcatW
(
param1
,
slashStarW
);
}
}
hff
=
FindFirstFile
(
param1
,
&
fd
);
hff
=
FindFirstFile
(
param1
,
&
fd
);
...
@@ -1314,6 +1345,7 @@ void WCMD_setshow_attrib (void) {
...
@@ -1314,6 +1345,7 @@ void WCMD_setshow_attrib (void) {
else
{
else
{
do
{
do
{
if
(
!
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
))
{
if
(
!
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
))
{
static
const
WCHAR
fmt
[]
=
{
'%'
,
's'
,
' '
,
' '
,
' '
,
'%'
,
's'
,
'\n'
,
'\0'
};
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_HIDDEN
)
{
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_HIDDEN
)
{
flags
[
0
]
=
'H'
;
flags
[
0
]
=
'H'
;
}
}
...
@@ -1332,7 +1364,7 @@ void WCMD_setshow_attrib (void) {
...
@@ -1332,7 +1364,7 @@ void WCMD_setshow_attrib (void) {
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_COMPRESSED
)
{
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_COMPRESSED
)
{
flags
[
5
]
=
'C'
;
flags
[
5
]
=
'C'
;
}
}
WCMD_output
(
"%s %s
\n
"
,
flags
,
fd
.
cFileName
);
WCMD_output
(
fmt
,
flags
,
fd
.
cFileName
);
for
(
count
=
0
;
count
<
8
;
count
++
)
flags
[
count
]
=
' '
;
for
(
count
=
0
;
count
<
8
;
count
++
)
flags
[
count
]
=
' '
;
}
}
}
while
(
FindNextFile
(
hff
,
&
fd
)
!=
0
);
}
while
(
FindNextFile
(
hff
,
&
fd
)
!=
0
);
...
@@ -1346,28 +1378,29 @@ void WCMD_setshow_attrib (void) {
...
@@ -1346,28 +1378,29 @@ void WCMD_setshow_attrib (void) {
* Set/Show the current default directory
* Set/Show the current default directory
*/
*/
void
WCMD_setshow_default
(
char
*
command
)
{
void
WCMD_setshow_default
(
WCHAR
*
command
)
{
BOOL
status
;
BOOL
status
;
char
string
[
1024
];
WCHAR
string
[
1024
];
char
cwd
[
1024
];
WCHAR
cwd
[
1024
];
char
*
pos
;
WCHAR
*
pos
;
WIN32_FIND_DATA
fd
;
WIN32_FIND_DATA
fd
;
HANDLE
hff
;
HANDLE
hff
;
static
const
WCHAR
parmD
[]
=
{
'/'
,
'D'
,
'\0'
};
WINE_TRACE
(
"Request change to directory '%s'
\n
"
,
command
);
WINE_TRACE
(
"Request change to directory '%s'
\n
"
,
wine_dbgstr_w
(
command
)
);
/* Skip /D and trailing whitespace if on the front of the command line */
/* Skip /D and trailing whitespace if on the front of the command line */
if
(
CompareString
(
LOCALE_USER_DEFAULT
,
if
(
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
command
,
2
,
"/D"
,
-
1
)
==
2
)
{
command
,
2
,
parmD
,
-
1
)
==
2
)
{
command
+=
2
;
command
+=
2
;
while
(
*
command
&&
*
command
==
' '
)
command
++
;
while
(
*
command
&&
*
command
==
' '
)
command
++
;
}
}
GetCurrentDirectory
(
sizeof
(
cwd
),
cwd
);
GetCurrentDirectory
(
sizeof
(
cwd
)
/
sizeof
(
WCHAR
)
,
cwd
);
if
(
strlen
(
command
)
==
0
)
{
if
(
strlen
W
(
command
)
==
0
)
{
strcat
(
cwd
,
newline
);
strcat
W
(
cwd
,
newline
);
WCMD_output
(
cwd
);
WCMD_output
(
cwd
);
}
}
else
{
else
{
...
@@ -1381,22 +1414,23 @@ void WCMD_setshow_default (char *command) {
...
@@ -1381,22 +1414,23 @@ void WCMD_setshow_default (char *command) {
*
pos
=
0x00
;
*
pos
=
0x00
;
/* Search for approprate directory */
/* Search for approprate directory */
WINE_TRACE
(
"Looking for directory '%s'
\n
"
,
string
);
WINE_TRACE
(
"Looking for directory '%s'
\n
"
,
wine_dbgstr_w
(
string
)
);
hff
=
FindFirstFile
(
string
,
&
fd
);
hff
=
FindFirstFile
(
string
,
&
fd
);
while
(
hff
!=
INVALID_HANDLE_VALUE
)
{
while
(
hff
!=
INVALID_HANDLE_VALUE
)
{
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
{
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
{
char
fpath
[
MAX_PATH
];
WCHAR
fpath
[
MAX_PATH
];
char
drive
[
10
];
WCHAR
drive
[
10
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
char
fname
[
MAX_PATH
];
WCHAR
fname
[
MAX_PATH
];
char
ext
[
MAX_PATH
];
WCHAR
ext
[
MAX_PATH
];
static
const
WCHAR
fmt
[]
=
{
'%'
,
's'
,
'%'
,
's'
,
'%'
,
's'
,
'\0'
};
/* Convert path into actual directory spec */
/* Convert path into actual directory spec */
GetFullPathName
(
string
,
sizeof
(
fpath
),
fpath
,
NULL
);
GetFullPathName
(
string
,
sizeof
(
fpath
)
/
sizeof
(
WCHAR
)
,
fpath
,
NULL
);
WCMD_splitpath
(
fpath
,
drive
,
dir
,
fname
,
ext
);
WCMD_splitpath
(
fpath
,
drive
,
dir
,
fname
,
ext
);
/* Rebuild path */
/* Rebuild path */
sprintf
(
string
,
"%s%s%s"
,
drive
,
dir
,
fd
.
cFileName
);
wsprintf
(
string
,
fmt
,
drive
,
dir
,
fd
.
cFileName
);
FindClose
(
hff
);
FindClose
(
hff
);
hff
=
INVALID_HANDLE_VALUE
;
hff
=
INVALID_HANDLE_VALUE
;
...
@@ -1412,7 +1446,7 @@ void WCMD_setshow_default (char *command) {
...
@@ -1412,7 +1446,7 @@ void WCMD_setshow_default (char *command) {
}
}
/* Change to that directory */
/* Change to that directory */
WINE_TRACE
(
"Really changing to directory '%s'
\n
"
,
string
);
WINE_TRACE
(
"Really changing to directory '%s'
\n
"
,
wine_dbgstr_w
(
string
)
);
status
=
SetCurrentDirectory
(
string
);
status
=
SetCurrentDirectory
(
string
);
if
(
!
status
)
{
if
(
!
status
)
{
...
@@ -1423,7 +1457,7 @@ void WCMD_setshow_default (char *command) {
...
@@ -1423,7 +1457,7 @@ void WCMD_setshow_default (char *command) {
/* Restore old directory if drive letter would change, and
/* Restore old directory if drive letter would change, and
CD x:\directory /D (or pushd c:\directory) not supplied */
CD x:\directory /D (or pushd c:\directory) not supplied */
if
((
strstr
(
quals
,
"/D"
)
==
NULL
)
&&
if
((
strstr
W
(
quals
,
parmD
)
==
NULL
)
&&
(
param1
[
1
]
==
':'
)
&&
(
toupper
(
param1
[
0
])
!=
toupper
(
cwd
[
0
])))
{
(
param1
[
1
]
==
':'
)
&&
(
toupper
(
param1
[
0
])
!=
toupper
(
cwd
[
0
])))
{
SetCurrentDirectory
(
cwd
);
SetCurrentDirectory
(
cwd
);
}
}
...
@@ -1434,10 +1468,11 @@ void WCMD_setshow_default (char *command) {
...
@@ -1434,10 +1468,11 @@ void WCMD_setshow_default (char *command) {
/D (allows changing drive letter when not resident on that
/D (allows changing drive letter when not resident on that
drive */
drive */
if
((
string
[
1
]
==
':'
)
&&
IsCharAlpha
(
string
[
0
]))
{
if
((
string
[
1
]
==
':'
)
&&
IsCharAlpha
(
string
[
0
]))
{
char
env
[
4
];
WCHAR
env
[
4
];
strcpy
(
env
,
"="
);
strcpy
W
(
env
,
equalW
);
strncpy
(
env
+
1
,
string
,
2
);
memcpy
(
env
+
1
,
string
,
2
*
sizeof
(
WCHAR
)
);
env
[
3
]
=
0x00
;
env
[
3
]
=
0x00
;
WINE_FIXME
(
"Setting '%s' to '%s'
\n
"
,
wine_dbgstr_w
(
env
),
wine_dbgstr_w
(
string
));
SetEnvironmentVariable
(
env
,
string
);
SetEnvironmentVariable
(
env
,
string
);
}
}
...
@@ -1454,16 +1489,18 @@ void WCMD_setshow_default (char *command) {
...
@@ -1454,16 +1489,18 @@ void WCMD_setshow_default (char *command) {
void
WCMD_setshow_date
(
void
)
{
void
WCMD_setshow_date
(
void
)
{
char
curdate
[
64
],
buffer
[
64
];
WCHAR
curdate
[
64
],
buffer
[
64
];
DWORD
count
;
DWORD
count
;
static
const
WCHAR
parmT
[]
=
{
'/'
,
'T'
,
'\0'
};
if
(
lstrlen
(
param1
)
==
0
)
{
if
(
strlenW
(
param1
)
==
0
)
{
if
(
GetDateFormat
(
LOCALE_USER_DEFAULT
,
0
,
NULL
,
NULL
,
if
(
GetDateFormat
(
LOCALE_USER_DEFAULT
,
0
,
NULL
,
NULL
,
curdate
,
sizeof
(
curdate
)))
{
curdate
,
sizeof
(
curdate
)
/
sizeof
(
WCHAR
)))
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_CURRENTDATE
),
curdate
);
WCMD_output
(
WCMD_LoadMessage
(
WCMD_CURRENTDATE
),
curdate
);
if
(
strstr
(
quals
,
"/T"
)
==
NULL
)
{
if
(
strstr
W
(
quals
,
parmT
)
==
NULL
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NEWDATE
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NEWDATE
));
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
buffer
,
sizeof
(
buffer
),
&
count
,
NULL
);
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
buffer
,
sizeof
(
buffer
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
if
(
count
>
2
)
{
if
(
count
>
2
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NYI
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NYI
));
}
}
...
@@ -1482,7 +1519,7 @@ void WCMD_setshow_date (void) {
...
@@ -1482,7 +1519,7 @@ void WCMD_setshow_date (void) {
static
int
WCMD_compare
(
const
void
*
a
,
const
void
*
b
)
static
int
WCMD_compare
(
const
void
*
a
,
const
void
*
b
)
{
{
int
r
;
int
r
;
const
char
*
const
*
str_a
=
a
,
*
const
*
str_b
=
b
;
const
WCHAR
*
const
*
str_a
=
a
,
*
const
*
str_b
=
b
;
r
=
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
r
=
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
*
str_a
,
-
1
,
*
str_b
,
-
1
);
*
str_a
,
-
1
,
*
str_b
,
-
1
);
if
(
r
==
CSTR_LESS_THAN
)
return
-
1
;
if
(
r
==
CSTR_LESS_THAN
)
return
-
1
;
...
@@ -1497,29 +1534,29 @@ static int WCMD_compare( const void *a, const void *b )
...
@@ -1497,29 +1534,29 @@ static int WCMD_compare( const void *a, const void *b )
* Optionally only display those who start with a stub
* Optionally only display those who start with a stub
* returns the count displayed
* returns the count displayed
*/
*/
static
int
WCMD_setshow_sortenv
(
const
char
*
s
,
const
char
*
stub
)
static
int
WCMD_setshow_sortenv
(
const
WCHAR
*
s
,
const
WCHAR
*
stub
)
{
{
UINT
count
=
0
,
len
=
0
,
i
,
displayedcount
=
0
,
stublen
=
0
;
UINT
count
=
0
,
len
=
0
,
i
,
displayedcount
=
0
,
stublen
=
0
;
const
char
**
str
;
const
WCHAR
**
str
;
if
(
stub
)
stublen
=
strlen
(
stub
);
if
(
stub
)
stublen
=
strlen
W
(
stub
);
/* count the number of strings, and the total length */
/* count the number of strings, and the total length */
while
(
s
[
len
]
)
{
while
(
s
[
len
]
)
{
len
+=
(
lstrlen
(
&
s
[
len
])
+
1
);
len
+=
(
strlenW
(
&
s
[
len
])
+
1
);
count
++
;
count
++
;
}
}
/* add the strings to an array */
/* add the strings to an array */
str
=
LocalAlloc
(
LMEM_FIXED
|
LMEM_ZEROINIT
,
count
*
sizeof
(
char
*
)
);
str
=
LocalAlloc
(
LMEM_FIXED
|
LMEM_ZEROINIT
,
count
*
sizeof
(
WCHAR
*
)
);
if
(
!
str
)
if
(
!
str
)
return
0
;
return
0
;
str
[
0
]
=
s
;
str
[
0
]
=
s
;
for
(
i
=
1
;
i
<
count
;
i
++
)
for
(
i
=
1
;
i
<
count
;
i
++
)
str
[
i
]
=
str
[
i
-
1
]
+
lstrlen
(
str
[
i
-
1
])
+
1
;
str
[
i
]
=
str
[
i
-
1
]
+
strlenW
(
str
[
i
-
1
])
+
1
;
/* sort the array */
/* sort the array */
qsort
(
str
,
count
,
sizeof
(
char
*
),
WCMD_compare
);
qsort
(
str
,
count
,
sizeof
(
WCHAR
*
),
WCMD_compare
);
/* print it */
/* print it */
for
(
i
=
0
;
i
<
count
;
i
++
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
{
...
@@ -1545,11 +1582,12 @@ static int WCMD_setshow_sortenv(const char *s, const char *stub)
...
@@ -1545,11 +1582,12 @@ static int WCMD_setshow_sortenv(const char *s, const char *stub)
* Set/Show the environment variables
* Set/Show the environment variables
*/
*/
void
WCMD_setshow_env
(
char
*
s
)
{
void
WCMD_setshow_env
(
WCHAR
*
s
)
{
LPVOID
env
;
LPVOID
env
;
char
*
p
;
WCHAR
*
p
;
int
status
;
int
status
;
static
const
WCHAR
parmP
[]
=
{
'/'
,
'P'
,
'\0'
};
errorlevel
=
0
;
errorlevel
=
0
;
if
(
param1
[
0
]
==
0x00
&&
quals
[
0
]
==
0x00
)
{
if
(
param1
[
0
]
==
0x00
&&
quals
[
0
]
==
0x00
)
{
...
@@ -1561,35 +1599,37 @@ void WCMD_setshow_env (char *s) {
...
@@ -1561,35 +1599,37 @@ void WCMD_setshow_env (char *s) {
/* See if /P supplied, and if so echo the prompt, and read in a reply */
/* See if /P supplied, and if so echo the prompt, and read in a reply */
if
(
CompareString
(
LOCALE_USER_DEFAULT
,
if
(
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
s
,
2
,
"/P"
,
-
1
)
==
2
)
{
s
,
2
,
parmP
,
-
1
)
==
2
)
{
char
string
[
MAXSTRING
];
WCHAR
string
[
MAXSTRING
];
DWORD
count
;
DWORD
count
;
s
+=
2
;
s
+=
2
;
while
(
*
s
&&
*
s
==
' '
)
s
++
;
while
(
*
s
&&
*
s
==
' '
)
s
++
;
/* If no parameter, or no '=' sign, return an error */
/* If no parameter, or no '=' sign, return an error */
if
(
!
(
*
s
)
||
((
p
=
strchr
(
s
,
'='
))
==
NULL
))
{
if
(
!
(
*
s
)
||
((
p
=
strchr
W
(
s
,
'='
))
==
NULL
))
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOARG
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOARG
));
return
;
return
;
}
}
/* Output the prompt */
/* Output the prompt */
*
p
++
=
'\0'
;
*
p
++
=
'\0'
;
if
(
strlen
(
p
)
!=
0
)
WCMD_output
(
p
);
if
(
strlen
W
(
p
)
!=
0
)
WCMD_output
(
p
);
/* Read the reply */
/* Read the reply */
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
),
&
count
,
NULL
);
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
if
(
count
>
1
)
{
if
(
count
>
1
)
{
string
[
count
-
1
]
=
'\0'
;
/* ReadFile output is not null-terminated! */
string
[
count
-
1
]
=
'\0'
;
/* ReadFile output is not null-terminated! */
if
(
string
[
count
-
2
]
==
'\r'
)
string
[
count
-
2
]
=
'\0'
;
/* Under Windoze we get CRLF! */
if
(
string
[
count
-
2
]
==
'\r'
)
string
[
count
-
2
]
=
'\0'
;
/* Under Windoze we get CRLF! */
WINE_TRACE
(
"set /p: Setting var '%s' to '%s'
\n
"
,
s
,
string
);
WINE_TRACE
(
"set /p: Setting var '%s' to '%s'
\n
"
,
wine_dbgstr_w
(
s
),
wine_dbgstr_w
(
string
));
status
=
SetEnvironmentVariable
(
s
,
string
);
status
=
SetEnvironmentVariable
(
s
,
string
);
}
}
}
else
{
}
else
{
DWORD
gle
;
DWORD
gle
;
p
=
strchr
(
s
,
'='
);
p
=
strchr
W
(
s
,
'='
);
if
(
p
==
NULL
)
{
if
(
p
==
NULL
)
{
env
=
GetEnvironmentStrings
();
env
=
GetEnvironmentStrings
();
if
(
WCMD_setshow_sortenv
(
env
,
s
)
==
0
)
{
if
(
WCMD_setshow_sortenv
(
env
,
s
)
==
0
)
{
...
@@ -1600,7 +1640,7 @@ void WCMD_setshow_env (char *s) {
...
@@ -1600,7 +1640,7 @@ void WCMD_setshow_env (char *s) {
}
}
*
p
++
=
'\0'
;
*
p
++
=
'\0'
;
if
(
strlen
(
p
)
==
0
)
p
=
NULL
;
if
(
strlen
W
(
p
)
==
0
)
p
=
NULL
;
status
=
SetEnvironmentVariable
(
s
,
p
);
status
=
SetEnvironmentVariable
(
s
,
p
);
gle
=
GetLastError
();
gle
=
GetLastError
();
if
((
!
status
)
&
(
gle
==
ERROR_ENVVAR_NOT_FOUND
))
{
if
((
!
status
)
&
(
gle
==
ERROR_ENVVAR_NOT_FOUND
))
{
...
@@ -1615,25 +1655,27 @@ void WCMD_setshow_env (char *s) {
...
@@ -1615,25 +1655,27 @@ void WCMD_setshow_env (char *s) {
* Set/Show the path environment variable
* Set/Show the path environment variable
*/
*/
void
WCMD_setshow_path
(
char
*
command
)
{
void
WCMD_setshow_path
(
WCHAR
*
command
)
{
char
string
[
1024
];
WCHAR
string
[
1024
];
DWORD
status
;
DWORD
status
;
static
const
WCHAR
pathW
[]
=
{
'P'
,
'A'
,
'T'
,
'H'
,
'\0'
};
static
const
WCHAR
pathEqW
[]
=
{
'P'
,
'A'
,
'T'
,
'H'
,
'='
,
'\0'
};
if
(
strlen
(
param1
)
==
0
)
{
if
(
strlen
W
(
param1
)
==
0
)
{
status
=
GetEnvironmentVariable
(
"PATH"
,
string
,
sizeof
(
string
));
status
=
GetEnvironmentVariable
(
pathW
,
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
));
if
(
status
!=
0
)
{
if
(
status
!=
0
)
{
WCMD_output_asis
(
"PATH="
);
WCMD_output_asis
(
pathEqW
);
WCMD_output_asis
(
string
);
WCMD_output_asis
(
string
);
WCMD_output_asis
(
newline
);
WCMD_output_asis
(
newline
);
}
}
else
{
else
{
WCMD_output
(
"PATH not found
\n
"
);
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NOPATH
)
);
}
}
}
}
else
{
else
{
if
(
*
command
==
'='
)
command
++
;
/* Skip leading '=' */
if
(
*
command
==
'='
)
command
++
;
/* Skip leading '=' */
status
=
SetEnvironmentVariable
(
"PATH"
,
command
);
status
=
SetEnvironmentVariable
(
pathW
,
command
);
if
(
!
status
)
WCMD_print_error
();
if
(
!
status
)
WCMD_print_error
();
}
}
}
}
...
@@ -1646,18 +1688,19 @@ void WCMD_setshow_path (char *command) {
...
@@ -1646,18 +1688,19 @@ void WCMD_setshow_path (char *command) {
void
WCMD_setshow_prompt
(
void
)
{
void
WCMD_setshow_prompt
(
void
)
{
char
*
s
;
WCHAR
*
s
;
static
const
WCHAR
promptW
[]
=
{
'P'
,
'R'
,
'O'
,
'M'
,
'P'
,
'T'
,
'\0'
};
if
(
strlen
(
param1
)
==
0
)
{
if
(
strlen
W
(
param1
)
==
0
)
{
SetEnvironmentVariable
(
"PROMPT"
,
NULL
);
SetEnvironmentVariable
(
promptW
,
NULL
);
}
}
else
{
else
{
s
=
param1
;
s
=
param1
;
while
((
*
s
==
'='
)
||
(
*
s
==
' '
))
s
++
;
while
((
*
s
==
'='
)
||
(
*
s
==
' '
))
s
++
;
if
(
strlen
(
s
)
==
0
)
{
if
(
strlen
W
(
s
)
==
0
)
{
SetEnvironmentVariable
(
"PROMPT"
,
NULL
);
SetEnvironmentVariable
(
promptW
,
NULL
);
}
}
else
SetEnvironmentVariable
(
"PROMPT"
,
s
);
else
SetEnvironmentVariable
(
promptW
,
s
);
}
}
}
}
...
@@ -1670,18 +1713,20 @@ void WCMD_setshow_prompt (void) {
...
@@ -1670,18 +1713,20 @@ void WCMD_setshow_prompt (void) {
void
WCMD_setshow_time
(
void
)
{
void
WCMD_setshow_time
(
void
)
{
char
curtime
[
64
],
buffer
[
64
];
WCHAR
curtime
[
64
],
buffer
[
64
];
DWORD
count
;
DWORD
count
;
SYSTEMTIME
st
;
SYSTEMTIME
st
;
static
const
WCHAR
parmT
[]
=
{
'/'
,
'T'
,
'\0'
};
if
(
strlen
(
param1
)
==
0
)
{
if
(
strlen
W
(
param1
)
==
0
)
{
GetLocalTime
(
&
st
);
GetLocalTime
(
&
st
);
if
(
GetTimeFormat
(
LOCALE_USER_DEFAULT
,
0
,
&
st
,
NULL
,
if
(
GetTimeFormat
(
LOCALE_USER_DEFAULT
,
0
,
&
st
,
NULL
,
curtime
,
sizeof
(
curtime
)))
{
curtime
,
sizeof
(
curtime
)
/
sizeof
(
WCHAR
)))
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_CURRENTDATE
),
curtime
);
WCMD_output
(
WCMD_LoadMessage
(
WCMD_CURRENTDATE
),
curtime
);
if
(
strstr
(
quals
,
"/T"
)
==
NULL
)
{
if
(
strstr
W
(
quals
,
parmT
)
==
NULL
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NEWTIME
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NEWTIME
));
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
buffer
,
sizeof
(
buffer
),
&
count
,
NULL
);
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
buffer
,
sizeof
(
buffer
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
if
(
count
>
2
)
{
if
(
count
>
2
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NYI
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_NYI
));
}
}
...
@@ -1701,11 +1746,11 @@ void WCMD_setshow_time (void) {
...
@@ -1701,11 +1746,11 @@ void WCMD_setshow_time (void) {
* Optional /n says where to start shifting (n=0-8)
* Optional /n says where to start shifting (n=0-8)
*/
*/
void
WCMD_shift
(
char
*
command
)
{
void
WCMD_shift
(
WCHAR
*
command
)
{
int
start
;
int
start
;
if
(
context
!=
NULL
)
{
if
(
context
!=
NULL
)
{
char
*
pos
=
strchr
(
command
,
'/'
);
WCHAR
*
pos
=
strchrW
(
command
,
'/'
);
int
i
;
int
i
;
if
(
pos
==
NULL
)
{
if
(
pos
==
NULL
)
{
...
@@ -1732,7 +1777,7 @@ void WCMD_shift (char *command) {
...
@@ -1732,7 +1777,7 @@ void WCMD_shift (char *command) {
*
*
* Set the console title
* Set the console title
*/
*/
void
WCMD_title
(
char
*
command
)
{
void
WCMD_title
(
WCHAR
*
command
)
{
SetConsoleTitle
(
command
);
SetConsoleTitle
(
command
);
}
}
...
@@ -1742,10 +1787,10 @@ void WCMD_title (char *command) {
...
@@ -1742,10 +1787,10 @@ void WCMD_title (char *command) {
* Copy a file to standard output.
* Copy a file to standard output.
*/
*/
void
WCMD_type
(
char
*
command
)
{
void
WCMD_type
(
WCHAR
*
command
)
{
int
argno
=
0
;
int
argno
=
0
;
char
*
argN
=
command
;
WCHAR
*
argN
=
command
;
BOOL
writeHeaders
=
FALSE
;
BOOL
writeHeaders
=
FALSE
;
if
(
param1
[
0
]
==
0x00
)
{
if
(
param1
[
0
]
==
0x00
)
{
...
@@ -1758,15 +1803,15 @@ void WCMD_type (char *command) {
...
@@ -1758,15 +1803,15 @@ void WCMD_type (char *command) {
/* Loop through all args */
/* Loop through all args */
errorlevel
=
0
;
errorlevel
=
0
;
while
(
argN
)
{
while
(
argN
)
{
char
*
thisArg
=
WCMD_parameter
(
command
,
argno
++
,
&
argN
);
WCHAR
*
thisArg
=
WCMD_parameter
(
command
,
argno
++
,
&
argN
);
HANDLE
h
;
HANDLE
h
;
char
buffer
[
512
];
WCHAR
buffer
[
512
];
DWORD
count
;
DWORD
count
;
if
(
!
argN
)
break
;
if
(
!
argN
)
break
;
WINE_TRACE
(
"type: Processing arg '%s'
\n
"
,
thisArg
);
WINE_TRACE
(
"type: Processing arg '%s'
\n
"
,
wine_dbgstr_w
(
thisArg
)
);
h
=
CreateFile
(
thisArg
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
h
=
CreateFile
(
thisArg
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
h
==
INVALID_HANDLE_VALUE
)
{
if
(
h
==
INVALID_HANDLE_VALUE
)
{
...
@@ -1775,9 +1820,10 @@ void WCMD_type (char *command) {
...
@@ -1775,9 +1820,10 @@ void WCMD_type (char *command) {
errorlevel
=
1
;
errorlevel
=
1
;
}
else
{
}
else
{
if
(
writeHeaders
)
{
if
(
writeHeaders
)
{
WCMD_output
(
"
\n
%s
\n\n
"
,
thisArg
);
static
const
WCHAR
fmt
[]
=
{
'\n'
,
'%'
,
's'
,
'\n'
,
'\n'
,
'\0'
};
WCMD_output
(
fmt
,
thisArg
);
}
}
while
(
ReadFile
(
h
,
buffer
,
sizeof
(
buffer
),
&
count
,
NULL
))
{
while
(
WCMD_ReadFile
(
h
,
buffer
,
sizeof
(
buffer
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
))
{
if
(
count
==
0
)
break
;
/* ReadFile reports success on EOF! */
if
(
count
==
0
)
break
;
/* ReadFile reports success on EOF! */
buffer
[
count
]
=
0
;
buffer
[
count
]
=
0
;
WCMD_output_asis
(
buffer
);
WCMD_output_asis
(
buffer
);
...
@@ -1793,20 +1839,26 @@ void WCMD_type (char *command) {
...
@@ -1793,20 +1839,26 @@ void WCMD_type (char *command) {
* Output either a file or stdin to screen in pages
* Output either a file or stdin to screen in pages
*/
*/
void
WCMD_more
(
char
*
command
)
{
void
WCMD_more
(
WCHAR
*
command
)
{
int
argno
=
0
;
int
argno
=
0
;
char
*
argN
=
command
;
WCHAR
*
argN
=
command
;
BOOL
useinput
=
FALSE
;
BOOL
useinput
=
FALSE
;
char
moreStr
[
100
];
WCHAR
moreStr
[
100
];
char
moreStrPage
[
100
];
WCHAR
moreStrPage
[
100
];
char
buffer
[
512
];
WCHAR
buffer
[
512
];
DWORD
count
;
DWORD
count
;
static
const
WCHAR
moreStart
[]
=
{
'-'
,
'-'
,
' '
,
'\0'
};
static
const
WCHAR
moreFmt
[]
=
{
'%'
,
's'
,
' '
,
'-'
,
'-'
,
'\n'
,
'\0'
};
static
const
WCHAR
moreFmt2
[]
=
{
'%'
,
's'
,
' '
,
'('
,
'%'
,
'2'
,
'.'
,
'2'
,
'd'
,
'%'
,
'%'
,
')'
,
' '
,
'-'
,
'-'
,
'\n'
,
'\0'
};
static
const
WCHAR
conInW
[]
=
{
'C'
,
'O'
,
'N'
,
'I'
,
'N'
,
'$'
,
'\0'
};
/* Prefix the NLS more with '-- ', then load the text */
/* Prefix the NLS more with '-- ', then load the text */
errorlevel
=
0
;
errorlevel
=
0
;
strcpy
(
moreStr
,
"-- "
);
strcpyW
(
moreStr
,
moreStart
);
LoadString
(
hinst
,
WCMD_MORESTR
,
&
moreStr
[
3
],
sizeof
(
moreStr
)
-
3
);
LoadString
(
hinst
,
WCMD_MORESTR
,
&
moreStr
[
3
],
(
sizeof
(
moreStr
)
/
sizeof
(
WCHAR
))
-
3
);
if
(
param1
[
0
]
==
0x00
)
{
if
(
param1
[
0
]
==
0x00
)
{
...
@@ -1815,7 +1867,7 @@ void WCMD_more (char *command) {
...
@@ -1815,7 +1867,7 @@ void WCMD_more (char *command) {
more are satistied by the next line from the input (file). To
more are satistied by the next line from the input (file). To
avoid this, ensure stdin is to the console */
avoid this, ensure stdin is to the console */
HANDLE
hstdin
=
GetStdHandle
(
STD_INPUT_HANDLE
);
HANDLE
hstdin
=
GetStdHandle
(
STD_INPUT_HANDLE
);
HANDLE
hConIn
=
CreateFile
(
"CONIN$"
,
GENERIC_READ
|
GENERIC_WRITE
,
HANDLE
hConIn
=
CreateFile
(
conInW
,
GENERIC_READ
|
GENERIC_WRITE
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
0
);
FILE_ATTRIBUTE_NORMAL
,
0
);
SetStdHandle
(
STD_INPUT_HANDLE
,
hConIn
);
SetStdHandle
(
STD_INPUT_HANDLE
,
hConIn
);
...
@@ -1823,10 +1875,10 @@ void WCMD_more (char *command) {
...
@@ -1823,10 +1875,10 @@ void WCMD_more (char *command) {
/* Warning: No easy way of ending the stream (ctrl+z on windows) so
/* Warning: No easy way of ending the stream (ctrl+z on windows) so
once you get in this bit unless due to a pipe, its going to end badly... */
once you get in this bit unless due to a pipe, its going to end badly... */
useinput
=
TRUE
;
useinput
=
TRUE
;
sprintf
(
moreStrPage
,
"%s --
\n
"
,
moreStr
);
wsprintf
(
moreStrPage
,
moreFmt
,
moreStr
);
WCMD_enter_paged_mode
(
moreStrPage
);
WCMD_enter_paged_mode
(
moreStrPage
);
while
(
ReadFile
(
hstdin
,
buffer
,
sizeof
(
buffer
)
-
1
,
&
count
,
NULL
))
{
while
(
WCMD_ReadFile
(
hstdin
,
buffer
,
(
sizeof
(
buffer
)
/
sizeof
(
WCHAR
)
)
-
1
,
&
count
,
NULL
))
{
if
(
count
==
0
)
break
;
/* ReadFile reports success on EOF! */
if
(
count
==
0
)
break
;
/* ReadFile reports success on EOF! */
buffer
[
count
]
=
0
;
buffer
[
count
]
=
0
;
WCMD_output_asis
(
buffer
);
WCMD_output_asis
(
buffer
);
...
@@ -1845,7 +1897,7 @@ void WCMD_more (char *command) {
...
@@ -1845,7 +1897,7 @@ void WCMD_more (char *command) {
WCMD_enter_paged_mode
(
moreStrPage
);
WCMD_enter_paged_mode
(
moreStrPage
);
while
(
argN
)
{
while
(
argN
)
{
char
*
thisArg
=
WCMD_parameter
(
command
,
argno
++
,
&
argN
);
WCHAR
*
thisArg
=
WCMD_parameter
(
command
,
argno
++
,
&
argN
);
HANDLE
h
;
HANDLE
h
;
if
(
!
argN
)
break
;
if
(
!
argN
)
break
;
...
@@ -1853,15 +1905,16 @@ void WCMD_more (char *command) {
...
@@ -1853,15 +1905,16 @@ void WCMD_more (char *command) {
if
(
needsPause
)
{
if
(
needsPause
)
{
/* Wait */
/* Wait */
sprintf
(
moreStrPage
,
"%s (100%%) --
\n
"
,
moreStr
);
wsprintf
(
moreStrPage
,
moreFmt2
,
moreStr
,
100
);
WCMD_leave_paged_mode
();
WCMD_leave_paged_mode
();
WCMD_output_asis
(
moreStrPage
);
WCMD_output_asis
(
moreStrPage
);
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
buffer
,
sizeof
(
buffer
),
&
count
,
NULL
);
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
buffer
,
sizeof
(
buffer
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
WCMD_enter_paged_mode
(
moreStrPage
);
WCMD_enter_paged_mode
(
moreStrPage
);
}
}
WINE_TRACE
(
"more: Processing arg '%s'
\n
"
,
thisArg
);
WINE_TRACE
(
"more: Processing arg '%s'
\n
"
,
wine_dbgstr_w
(
thisArg
)
);
h
=
CreateFile
(
thisArg
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
h
=
CreateFile
(
thisArg
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
h
==
INVALID_HANDLE_VALUE
)
{
if
(
h
==
INVALID_HANDLE_VALUE
)
{
...
@@ -1878,13 +1931,13 @@ void WCMD_more (char *command) {
...
@@ -1878,13 +1931,13 @@ void WCMD_more (char *command) {
fileLen
=
(((
ULONG64
)
fileInfo
.
nFileSizeHigh
)
<<
32
)
+
fileInfo
.
nFileSizeLow
;
fileLen
=
(((
ULONG64
)
fileInfo
.
nFileSizeHigh
)
<<
32
)
+
fileInfo
.
nFileSizeLow
;
needsPause
=
TRUE
;
needsPause
=
TRUE
;
while
(
ReadFile
(
h
,
buffer
,
sizeof
(
buffer
)
,
&
count
,
NULL
))
{
while
(
WCMD_ReadFile
(
h
,
buffer
,
(
sizeof
(
buffer
)
/
sizeof
(
WCHAR
))
-
1
,
&
count
,
NULL
))
{
if
(
count
==
0
)
break
;
/* ReadFile reports success on EOF! */
if
(
count
==
0
)
break
;
/* ReadFile reports success on EOF! */
buffer
[
count
]
=
0
;
buffer
[
count
]
=
0
;
curPos
+=
count
;
curPos
+=
count
;
/* Update % count (would be used in WCMD_output_asis as prompt) */
/* Update % count (would be used in WCMD_output_asis as prompt) */
sprintf
(
moreStrPage
,
"%s (%2.2d%%) --
\n
"
,
moreStr
,
(
int
)
min
(
99
,
(
curPos
*
100
)
/
fileLen
));
wsprintf
(
moreStrPage
,
moreFmt2
,
moreStr
,
(
int
)
min
(
99
,
(
curPos
*
100
)
/
fileLen
));
WCMD_output_asis
(
buffer
);
WCMD_output_asis
(
buffer
);
}
}
...
@@ -1904,21 +1957,21 @@ void WCMD_more (char *command) {
...
@@ -1904,21 +1957,21 @@ void WCMD_more (char *command) {
* it...
* it...
*/
*/
void
WCMD_verify
(
char
*
command
)
{
void
WCMD_verify
(
WCHAR
*
command
)
{
int
count
;
int
count
;
count
=
strlen
(
command
);
count
=
strlen
W
(
command
);
if
(
count
==
0
)
{
if
(
count
==
0
)
{
if
(
verify_mode
)
WCMD_output
(
WCMD_LoadMessage
(
WCMD_VERIFYPROMPT
),
"ON"
);
if
(
verify_mode
)
WCMD_output
(
WCMD_LoadMessage
(
WCMD_VERIFYPROMPT
),
onW
);
else
WCMD_output
(
WCMD_LoadMessage
(
WCMD_VERIFYPROMPT
),
"OFF"
);
else
WCMD_output
(
WCMD_LoadMessage
(
WCMD_VERIFYPROMPT
),
offW
);
return
;
return
;
}
}
if
(
lstrcmpi
(
command
,
"ON"
)
==
0
)
{
if
(
lstrcmpi
W
(
command
,
onW
)
==
0
)
{
verify_mode
=
1
;
verify_mode
=
1
;
return
;
return
;
}
}
else
if
(
lstrcmpi
(
command
,
"OFF"
)
==
0
)
{
else
if
(
lstrcmpi
W
(
command
,
offW
)
==
0
)
{
verify_mode
=
0
;
verify_mode
=
0
;
return
;
return
;
}
}
...
@@ -1943,28 +1996,30 @@ void WCMD_version (void) {
...
@@ -1943,28 +1996,30 @@ void WCMD_version (void) {
* Display volume info and/or set volume label. Returns 0 if error.
* Display volume info and/or set volume label. Returns 0 if error.
*/
*/
int
WCMD_volume
(
int
mode
,
char
*
path
)
{
int
WCMD_volume
(
int
mode
,
WCHAR
*
path
)
{
DWORD
count
,
serial
;
DWORD
count
,
serial
;
char
string
[
MAX_PATH
],
label
[
MAX_PATH
],
curdir
[
MAX_PATH
];
WCHAR
string
[
MAX_PATH
],
label
[
MAX_PATH
],
curdir
[
MAX_PATH
];
BOOL
status
;
BOOL
status
;
if
(
lstrlen
(
path
)
==
0
)
{
if
(
strlenW
(
path
)
==
0
)
{
status
=
GetCurrentDirectory
(
sizeof
(
curdir
),
curdir
);
status
=
GetCurrentDirectory
(
sizeof
(
curdir
)
/
sizeof
(
WCHAR
)
,
curdir
);
if
(
!
status
)
{
if
(
!
status
)
{
WCMD_print_error
();
WCMD_print_error
();
return
0
;
return
0
;
}
}
status
=
GetVolumeInformation
(
NULL
,
label
,
sizeof
(
label
)
,
&
serial
,
NULL
,
status
=
GetVolumeInformation
(
NULL
,
label
,
sizeof
(
label
)
/
sizeof
(
WCHAR
)
,
NULL
,
NULL
,
0
);
&
serial
,
NULL
,
NULL
,
NULL
,
0
);
}
}
else
{
else
{
if
((
path
[
1
]
!=
':'
)
||
(
lstrlen
(
path
)
!=
2
))
{
static
const
WCHAR
fmt
[]
=
{
'%'
,
's'
,
'\\'
,
'\0'
};
if
((
path
[
1
]
!=
':'
)
||
(
strlenW
(
path
)
!=
2
))
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_SYNTAXERR
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_SYNTAXERR
));
return
0
;
return
0
;
}
}
wsprintf
(
curdir
,
"%s
\\
"
,
path
);
wsprintf
(
curdir
,
fmt
,
path
);
status
=
GetVolumeInformation
(
curdir
,
label
,
sizeof
(
label
),
&
serial
,
NULL
,
status
=
GetVolumeInformation
(
curdir
,
label
,
sizeof
(
label
)
/
sizeof
(
WCHAR
),
&
serial
,
NULL
,
NULL
,
NULL
,
0
);
NULL
,
NULL
,
0
);
}
}
if
(
!
status
)
{
if
(
!
status
)
{
...
@@ -1975,12 +2030,13 @@ int WCMD_volume (int mode, char *path) {
...
@@ -1975,12 +2030,13 @@ int WCMD_volume (int mode, char *path) {
curdir
[
0
],
label
,
HIWORD
(
serial
),
LOWORD
(
serial
));
curdir
[
0
],
label
,
HIWORD
(
serial
),
LOWORD
(
serial
));
if
(
mode
)
{
if
(
mode
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_VOLUMEPROMPT
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_VOLUMEPROMPT
));
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
),
&
count
,
NULL
);
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
if
(
count
>
1
)
{
if
(
count
>
1
)
{
string
[
count
-
1
]
=
'\0'
;
/* ReadFile output is not null-terminated! */
string
[
count
-
1
]
=
'\0'
;
/* ReadFile output is not null-terminated! */
if
(
string
[
count
-
2
]
==
'\r'
)
string
[
count
-
2
]
=
'\0'
;
/* Under Windoze we get CRLF! */
if
(
string
[
count
-
2
]
==
'\r'
)
string
[
count
-
2
]
=
'\0'
;
/* Under Windoze we get CRLF! */
}
}
if
(
lstrlen
(
path
)
!=
0
)
{
if
(
strlenW
(
path
)
!=
0
)
{
if
(
!
SetVolumeLabel
(
curdir
,
string
))
WCMD_print_error
();
if
(
!
SetVolumeLabel
(
curdir
,
string
))
WCMD_print_error
();
}
}
else
{
else
{
...
@@ -1999,9 +2055,10 @@ int WCMD_volume (int mode, char *path) {
...
@@ -1999,9 +2055,10 @@ int WCMD_volume (int mode, char *path) {
void
WCMD_exit
(
void
)
{
void
WCMD_exit
(
void
)
{
int
rc
=
atoi
(
param1
);
/* Note: atoi of empty parameter is 0 */
static
const
WCHAR
parmB
[]
=
{
'/'
,
'B'
,
'\0'
};
int
rc
=
atoiW
(
param1
);
/* Note: atoi of empty parameter is 0 */
if
(
context
&&
lstrcmpi
(
quals
,
"/B"
)
==
0
)
{
if
(
context
&&
lstrcmpi
W
(
quals
,
parmB
)
==
0
)
{
errorlevel
=
rc
;
errorlevel
=
rc
;
context
->
skip_rest
=
TRUE
;
context
->
skip_rest
=
TRUE
;
}
else
{
}
else
{
...
@@ -2020,38 +2077,41 @@ void WCMD_exit (void) {
...
@@ -2020,38 +2077,41 @@ void WCMD_exit (void) {
* set to TRUE
* set to TRUE
*
*
*/
*/
BOOL
WCMD_ask_confirm
(
char
*
message
,
BOOL
showSureText
,
BOOL
*
optionAll
)
{
BOOL
WCMD_ask_confirm
(
WCHAR
*
message
,
BOOL
showSureText
,
BOOL
*
optionAll
)
{
char
msgbuffer
[
MAXSTRING
];
WCHAR
msgbuffer
[
MAXSTRING
];
char
Ybuffer
[
MAXSTRING
];
WCHAR
Ybuffer
[
MAXSTRING
];
char
Nbuffer
[
MAXSTRING
];
WCHAR
Nbuffer
[
MAXSTRING
];
char
Abuffer
[
MAXSTRING
];
WCHAR
Abuffer
[
MAXSTRING
];
char
answer
[
MAX_PATH
]
=
""
;
WCHAR
answer
[
MAX_PATH
]
=
{
'\0'
}
;
DWORD
count
=
0
;
DWORD
count
=
0
;
/* Load the translated 'Are you sure', plus valid answers */
/* Load the translated 'Are you sure', plus valid answers */
LoadString
(
hinst
,
WCMD_CONFIRM
,
msgbuffer
,
sizeof
(
msgbuffer
));
LoadString
(
hinst
,
WCMD_CONFIRM
,
msgbuffer
,
sizeof
(
msgbuffer
)
/
sizeof
(
WCHAR
)
);
LoadString
(
hinst
,
WCMD_YES
,
Ybuffer
,
sizeof
(
Ybuffer
));
LoadString
(
hinst
,
WCMD_YES
,
Ybuffer
,
sizeof
(
Ybuffer
)
/
sizeof
(
WCHAR
)
);
LoadString
(
hinst
,
WCMD_NO
,
Nbuffer
,
sizeof
(
Nbuffer
));
LoadString
(
hinst
,
WCMD_NO
,
Nbuffer
,
sizeof
(
Nbuffer
)
/
sizeof
(
WCHAR
)
);
LoadString
(
hinst
,
WCMD_ALL
,
Abuffer
,
sizeof
(
Abuffer
));
LoadString
(
hinst
,
WCMD_ALL
,
Abuffer
,
sizeof
(
Abuffer
)
/
sizeof
(
WCHAR
)
);
/* Loop waiting on a Y or N */
/* Loop waiting on a Y or N */
while
(
answer
[
0
]
!=
Ybuffer
[
0
]
&&
answer
[
0
]
!=
Nbuffer
[
0
])
{
while
(
answer
[
0
]
!=
Ybuffer
[
0
]
&&
answer
[
0
]
!=
Nbuffer
[
0
])
{
static
const
WCHAR
startBkt
[]
=
{
' '
,
'('
,
'\0'
};
static
const
WCHAR
endBkt
[]
=
{
')'
,
'?'
,
'\0'
};
WCMD_output_asis
(
message
);
WCMD_output_asis
(
message
);
if
(
showSureText
)
{
if
(
showSureText
)
{
WCMD_output_asis
(
msgbuffer
);
WCMD_output_asis
(
msgbuffer
);
}
}
WCMD_output_asis
(
" ("
);
WCMD_output_asis
(
startBkt
);
WCMD_output_asis
(
Ybuffer
);
WCMD_output_asis
(
Ybuffer
);
WCMD_output_asis
(
"/"
);
WCMD_output_asis
(
fslashW
);
WCMD_output_asis
(
Nbuffer
);
WCMD_output_asis
(
Nbuffer
);
if
(
optionAll
)
{
if
(
optionAll
)
{
WCMD_output_asis
(
"/"
);
WCMD_output_asis
(
fslashW
);
WCMD_output_asis
(
Abuffer
);
WCMD_output_asis
(
Abuffer
);
}
}
WCMD_output_asis
(
")?"
);
WCMD_output_asis
(
endBkt
);
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
answer
,
sizeof
(
answer
)
,
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
answer
,
&
count
,
NULL
);
sizeof
(
answer
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
answer
[
0
]
=
toupper
(
answer
[
0
]);
answer
[
0
]
=
toupper
(
answer
[
0
]);
}
}
...
@@ -2066,24 +2126,25 @@ BOOL WCMD_ask_confirm (char *message, BOOL showSureText, BOOL *optionAll) {
...
@@ -2066,24 +2126,25 @@ BOOL WCMD_ask_confirm (char *message, BOOL showSureText, BOOL *optionAll) {
* Lists or sets file associations (assoc = TRUE)
* Lists or sets file associations (assoc = TRUE)
* Lists or sets file types (assoc = FALSE)
* Lists or sets file types (assoc = FALSE)
*/
*/
void
WCMD_assoc
(
char
*
command
,
BOOL
assoc
)
{
void
WCMD_assoc
(
WCHAR
*
command
,
BOOL
assoc
)
{
HKEY
key
;
HKEY
key
;
DWORD
accessOptions
=
KEY_READ
;
DWORD
accessOptions
=
KEY_READ
;
char
*
newValue
;
WCHAR
*
newValue
;
LONG
rc
=
ERROR_SUCCESS
;
LONG
rc
=
ERROR_SUCCESS
;
char
keyValue
[
MAXSTRING
];
WCHAR
keyValue
[
MAXSTRING
];
DWORD
valueLen
=
MAXSTRING
;
DWORD
valueLen
=
MAXSTRING
;
HKEY
readKey
;
HKEY
readKey
;
static
const
WCHAR
shOpCmdW
[]
=
{
'\\'
,
'S'
,
'h'
,
'e'
,
'l'
,
'l'
,
'\\'
,
'O'
,
'p'
,
'e'
,
'n'
,
'\\'
,
'C'
,
'o'
,
'm'
,
'm'
,
'a'
,
'n'
,
'd'
,
'\0'
};
/* See if parameter includes '=' */
/* See if parameter includes '=' */
errorlevel
=
0
;
errorlevel
=
0
;
newValue
=
strchr
(
command
,
'='
);
newValue
=
strchr
W
(
command
,
'='
);
if
(
newValue
)
accessOptions
|=
KEY_WRITE
;
if
(
newValue
)
accessOptions
|=
KEY_WRITE
;
/* Open a key to HKEY_CLASSES_ROOT for enumerating */
/* Open a key to HKEY_CLASSES_ROOT for enumerating */
if
(
RegOpenKeyEx
(
HKEY_CLASSES_ROOT
,
""
,
0
,
if
(
RegOpenKeyEx
(
HKEY_CLASSES_ROOT
,
nullW
,
0
,
accessOptions
,
&
key
)
!=
ERROR_SUCCESS
)
{
accessOptions
,
&
key
)
!=
ERROR_SUCCESS
)
{
WINE_FIXME
(
"Unexpected failure opening HKCR key: %d
\n
"
,
GetLastError
());
WINE_FIXME
(
"Unexpected failure opening HKCR key: %d
\n
"
,
GetLastError
());
return
;
return
;
...
@@ -2095,7 +2156,7 @@ void WCMD_assoc (char *command, BOOL assoc) {
...
@@ -2095,7 +2156,7 @@ void WCMD_assoc (char *command, BOOL assoc) {
/* Enumerate all the keys */
/* Enumerate all the keys */
while
(
rc
!=
ERROR_NO_MORE_ITEMS
)
{
while
(
rc
!=
ERROR_NO_MORE_ITEMS
)
{
char
keyName
[
MAXSTRING
];
WCHAR
keyName
[
MAXSTRING
];
DWORD
nameLen
;
DWORD
nameLen
;
/* Find the next value */
/* Find the next value */
...
@@ -2111,18 +2172,18 @@ void WCMD_assoc (char *command, BOOL assoc) {
...
@@ -2111,18 +2172,18 @@ void WCMD_assoc (char *command, BOOL assoc) {
if
((
keyName
[
0
]
==
'.'
&&
assoc
)
||
if
((
keyName
[
0
]
==
'.'
&&
assoc
)
||
(
!
(
keyName
[
0
]
==
'.'
)
&&
(
!
assoc
)))
(
!
(
keyName
[
0
]
==
'.'
)
&&
(
!
assoc
)))
{
{
char
subkey
[
MAXSTRING
];
WCHAR
subkey
[
MAXSTRING
];
strcpy
(
subkey
,
keyName
);
strcpy
W
(
subkey
,
keyName
);
if
(
!
assoc
)
strcat
(
subkey
,
"
\\
Shell
\\
Open
\\
Command"
);
if
(
!
assoc
)
strcat
W
(
subkey
,
shOpCmdW
);
if
(
RegOpenKeyEx
(
key
,
subkey
,
0
,
if
(
RegOpenKeyEx
(
key
,
subkey
,
0
,
accessOptions
,
&
readKey
)
==
ERROR_SUCCESS
)
{
accessOptions
,
&
readKey
)
==
ERROR_SUCCESS
)
{
valueLen
=
sizeof
(
keyValue
);
valueLen
=
sizeof
(
keyValue
)
/
sizeof
(
WCHAR
)
;
rc
=
RegQueryValueEx
(
readKey
,
NULL
,
NULL
,
NULL
,
rc
=
RegQueryValueEx
(
readKey
,
NULL
,
NULL
,
NULL
,
(
LPBYTE
)
keyValue
,
&
valueLen
);
(
LPBYTE
)
keyValue
,
&
valueLen
);
WCMD_output_asis
(
keyName
);
WCMD_output_asis
(
keyName
);
WCMD_output_asis
(
"="
);
WCMD_output_asis
(
equalW
);
/* If no default value found, leave line empty after '=' */
/* If no default value found, leave line empty after '=' */
if
(
rc
==
ERROR_SUCCESS
)
{
if
(
rc
==
ERROR_SUCCESS
)
{
WCMD_output_asis
(
keyValue
);
WCMD_output_asis
(
keyValue
);
...
@@ -2138,17 +2199,17 @@ void WCMD_assoc (char *command, BOOL assoc) {
...
@@ -2138,17 +2199,17 @@ void WCMD_assoc (char *command, BOOL assoc) {
/* Parameter supplied - if no '=' on command line, its a query */
/* Parameter supplied - if no '=' on command line, its a query */
if
(
newValue
==
NULL
)
{
if
(
newValue
==
NULL
)
{
char
*
space
;
WCHAR
*
space
;
char
subkey
[
MAXSTRING
];
WCHAR
subkey
[
MAXSTRING
];
/* Query terminates the parameter at the first space */
/* Query terminates the parameter at the first space */
strcpy
(
keyValue
,
command
);
strcpy
W
(
keyValue
,
command
);
space
=
strchr
(
keyValue
,
' '
);
space
=
strchr
W
(
keyValue
,
' '
);
if
(
space
)
*
space
=
0x00
;
if
(
space
)
*
space
=
0x00
;
/* Set up key name */
/* Set up key name */
strcpy
(
subkey
,
keyValue
);
strcpy
W
(
subkey
,
keyValue
);
if
(
!
assoc
)
strcat
(
subkey
,
"
\\
Shell
\\
Open
\\
Command"
);
if
(
!
assoc
)
strcat
W
(
subkey
,
shOpCmdW
);
if
(
RegOpenKeyEx
(
key
,
subkey
,
0
,
if
(
RegOpenKeyEx
(
key
,
subkey
,
0
,
accessOptions
,
&
readKey
)
==
ERROR_SUCCESS
)
{
accessOptions
,
&
readKey
)
==
ERROR_SUCCESS
)
{
...
@@ -2156,23 +2217,23 @@ void WCMD_assoc (char *command, BOOL assoc) {
...
@@ -2156,23 +2217,23 @@ void WCMD_assoc (char *command, BOOL assoc) {
rc
=
RegQueryValueEx
(
readKey
,
NULL
,
NULL
,
NULL
,
rc
=
RegQueryValueEx
(
readKey
,
NULL
,
NULL
,
NULL
,
(
LPBYTE
)
keyValue
,
&
valueLen
);
(
LPBYTE
)
keyValue
,
&
valueLen
);
WCMD_output_asis
(
command
);
WCMD_output_asis
(
command
);
WCMD_output_asis
(
"="
);
WCMD_output_asis
(
equalW
);
/* If no default value found, leave line empty after '=' */
/* If no default value found, leave line empty after '=' */
if
(
rc
==
ERROR_SUCCESS
)
WCMD_output_asis
(
keyValue
);
if
(
rc
==
ERROR_SUCCESS
)
WCMD_output_asis
(
keyValue
);
WCMD_output_asis
(
newline
);
WCMD_output_asis
(
newline
);
RegCloseKey
(
readKey
);
RegCloseKey
(
readKey
);
}
else
{
}
else
{
char
msgbuffer
[
MAXSTRING
];
WCHAR
msgbuffer
[
MAXSTRING
];
char
outbuffer
[
MAXSTRING
];
WCHAR
outbuffer
[
MAXSTRING
];
/* Load the translated 'File association not found' */
/* Load the translated 'File association not found' */
if
(
assoc
)
{
if
(
assoc
)
{
LoadString
(
hinst
,
WCMD_NOASSOC
,
msgbuffer
,
sizeof
(
msgbuffer
));
LoadString
(
hinst
,
WCMD_NOASSOC
,
msgbuffer
,
sizeof
(
msgbuffer
)
/
sizeof
(
WCHAR
)
);
}
else
{
}
else
{
LoadString
(
hinst
,
WCMD_NOFTYPE
,
msgbuffer
,
sizeof
(
msgbuffer
));
LoadString
(
hinst
,
WCMD_NOFTYPE
,
msgbuffer
,
sizeof
(
msgbuffer
)
/
sizeof
(
WCHAR
)
);
}
}
sprintf
(
outbuffer
,
msgbuffer
,
keyValue
);
w
sprintf
(
outbuffer
,
msgbuffer
,
keyValue
);
WCMD_output_asis
(
outbuffer
);
WCMD_output_asis
(
outbuffer
);
errorlevel
=
2
;
errorlevel
=
2
;
}
}
...
@@ -2180,38 +2241,40 @@ void WCMD_assoc (char *command, BOOL assoc) {
...
@@ -2180,38 +2241,40 @@ void WCMD_assoc (char *command, BOOL assoc) {
/* Not a query - its a set or clear of a value */
/* Not a query - its a set or clear of a value */
}
else
{
}
else
{
char
subkey
[
MAXSTRING
];
WCHAR
subkey
[
MAXSTRING
];
/* Get pointer to new value */
/* Get pointer to new value */
*
newValue
=
0x00
;
*
newValue
=
0x00
;
newValue
++
;
newValue
++
;
/* Set up key name */
/* Set up key name */
strcpy
(
subkey
,
command
);
strcpy
W
(
subkey
,
command
);
if
(
!
assoc
)
strcat
(
subkey
,
"
\\
Shell
\\
Open
\\
Command"
);
if
(
!
assoc
)
strcat
W
(
subkey
,
shOpCmdW
);
/* If nothing after '=' then clear value - only valid for ASSOC */
/* If nothing after '=' then clear value - only valid for ASSOC */
if
(
*
newValue
==
0x00
)
{
if
(
*
newValue
==
0x00
)
{
if
(
assoc
)
rc
=
RegDeleteKey
(
key
,
command
);
if
(
assoc
)
rc
=
RegDeleteKey
(
key
,
command
);
if
(
assoc
&&
rc
==
ERROR_SUCCESS
)
{
if
(
assoc
&&
rc
==
ERROR_SUCCESS
)
{
WINE_TRACE
(
"HKCR Key '%s' deleted
\n
"
,
command
);
WINE_TRACE
(
"HKCR Key '%s' deleted
\n
"
,
wine_dbgstr_w
(
command
)
);
}
else
if
(
assoc
&&
rc
!=
ERROR_FILE_NOT_FOUND
)
{
}
else
if
(
assoc
&&
rc
!=
ERROR_FILE_NOT_FOUND
)
{
WCMD_print_error
();
WCMD_print_error
();
errorlevel
=
2
;
errorlevel
=
2
;
}
else
{
}
else
{
char
msgbuffer
[
MAXSTRING
];
WCHAR
msgbuffer
[
MAXSTRING
];
char
outbuffer
[
MAXSTRING
];
WCHAR
outbuffer
[
MAXSTRING
];
/* Load the translated 'File association not found' */
/* Load the translated 'File association not found' */
if
(
assoc
)
{
if
(
assoc
)
{
LoadString
(
hinst
,
WCMD_NOASSOC
,
msgbuffer
,
sizeof
(
msgbuffer
));
LoadString
(
hinst
,
WCMD_NOASSOC
,
msgbuffer
,
sizeof
(
msgbuffer
)
/
sizeof
(
WCHAR
));
}
else
{
}
else
{
LoadString
(
hinst
,
WCMD_NOFTYPE
,
msgbuffer
,
sizeof
(
msgbuffer
));
LoadString
(
hinst
,
WCMD_NOFTYPE
,
msgbuffer
,
sizeof
(
msgbuffer
)
/
sizeof
(
WCHAR
));
}
}
sprintf
(
outbuffer
,
msgbuffer
,
keyValue
);
w
sprintf
(
outbuffer
,
msgbuffer
,
keyValue
);
WCMD_output_asis
(
outbuffer
);
WCMD_output_asis
(
outbuffer
);
errorlevel
=
2
;
errorlevel
=
2
;
}
}
...
@@ -2222,7 +2285,7 @@ void WCMD_assoc (char *command, BOOL assoc) {
...
@@ -2222,7 +2285,7 @@ void WCMD_assoc (char *command, BOOL assoc) {
accessOptions
,
NULL
,
&
readKey
,
NULL
);
accessOptions
,
NULL
,
&
readKey
,
NULL
);
if
(
rc
==
ERROR_SUCCESS
)
{
if
(
rc
==
ERROR_SUCCESS
)
{
rc
=
RegSetValueEx
(
readKey
,
NULL
,
0
,
REG_SZ
,
rc
=
RegSetValueEx
(
readKey
,
NULL
,
0
,
REG_SZ
,
(
LPBYTE
)
newValue
,
strlen
(
newValue
));
(
LPBYTE
)
newValue
,
strlen
W
(
newValue
));
RegCloseKey
(
readKey
);
RegCloseKey
(
readKey
);
}
}
...
@@ -2231,7 +2294,7 @@ void WCMD_assoc (char *command, BOOL assoc) {
...
@@ -2231,7 +2294,7 @@ void WCMD_assoc (char *command, BOOL assoc) {
errorlevel
=
2
;
errorlevel
=
2
;
}
else
{
}
else
{
WCMD_output_asis
(
command
);
WCMD_output_asis
(
command
);
WCMD_output_asis
(
"="
);
WCMD_output_asis
(
equalW
);
WCMD_output_asis
(
newValue
);
WCMD_output_asis
(
newValue
);
WCMD_output_asis
(
newline
);
WCMD_output_asis
(
newline
);
}
}
...
@@ -2256,7 +2319,7 @@ void WCMD_color (void) {
...
@@ -2256,7 +2319,7 @@ void WCMD_color (void) {
CONSOLE_SCREEN_BUFFER_INFO
consoleInfo
;
CONSOLE_SCREEN_BUFFER_INFO
consoleInfo
;
HANDLE
hStdOut
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
HANDLE
hStdOut
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
if
(
param1
[
0
]
!=
0x00
&&
strlen
(
param1
)
>
2
)
{
if
(
param1
[
0
]
!=
0x00
&&
strlen
W
(
param1
)
>
2
)
{
WCMD_output
(
WCMD_LoadMessage
(
WCMD_ARGERR
));
WCMD_output
(
WCMD_LoadMessage
(
WCMD_ARGERR
));
return
;
return
;
}
}
...
@@ -2276,7 +2339,7 @@ void WCMD_color (void) {
...
@@ -2276,7 +2339,7 @@ void WCMD_color (void) {
if
(
param1
[
0
]
==
0x00
)
{
if
(
param1
[
0
]
==
0x00
)
{
color
=
defaultColor
;
color
=
defaultColor
;
}
else
{
}
else
{
color
=
strtoul
(
param1
,
NULL
,
16
);
color
=
strtoul
W
(
param1
,
NULL
,
16
);
}
}
/* Fail if fg == bg color */
/* Fail if fg == bg color */
...
...
programs/cmd/directory.c
View file @
b8aa5fc5
...
@@ -33,13 +33,13 @@
...
@@ -33,13 +33,13 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
cmd
);
WINE_DEFAULT_DEBUG_CHANNEL
(
cmd
);
int
WCMD_dir_sort
(
const
void
*
a
,
const
void
*
b
);
int
WCMD_dir_sort
(
const
void
*
a
,
const
void
*
b
);
char
*
WCMD_filesize64
(
ULONGLONG
free
);
WCHAR
*
WCMD_filesize64
(
ULONGLONG
free
);
char
*
WCMD_strrev
(
char
*
buff
);
WCHAR
*
WCMD_strrev
(
WCHAR
*
buff
);
static
void
WCMD_getfileowner
(
char
*
filename
,
char
*
owner
,
int
ownerlen
);
static
void
WCMD_getfileowner
(
WCHAR
*
filename
,
WCHAR
*
owner
,
int
ownerlen
);
static
void
WCMD_dir_trailer
(
char
drive
);
static
void
WCMD_dir_trailer
(
WCHAR
drive
);
extern
int
echo_mode
;
extern
int
echo_mode
;
extern
char
quals
[
MAX_PATH
],
param1
[
MAX_PATH
],
param2
[
MAX_PATH
];
extern
WCHAR
quals
[
MAX_PATH
],
param1
[
MAX_PATH
],
param2
[
MAX_PATH
];
extern
DWORD
errorlevel
;
extern
DWORD
errorlevel
;
typedef
enum
_DISPLAYTIME
typedef
enum
_DISPLAYTIME
...
@@ -67,6 +67,12 @@ static BOOL orderReverse, orderGroupDirs, orderGroupDirsReverse, orderByCol;
...
@@ -67,6 +67,12 @@ static BOOL orderReverse, orderGroupDirs, orderGroupDirsReverse, orderByCol;
static
BOOL
separator
;
static
BOOL
separator
;
static
ULONG
showattrs
,
attrsbits
;
static
ULONG
showattrs
,
attrsbits
;
static
const
WCHAR
dotW
[]
=
{
'.'
,
'\0'
};
static
const
WCHAR
dotdotW
[]
=
{
'.'
,
'.'
,
'\0'
};
static
const
WCHAR
starW
[]
=
{
'*'
,
'\0'
};
static
const
WCHAR
slashW
[]
=
{
'\\'
,
'\0'
};
static
const
WCHAR
emptyW
[]
=
{
'\0'
};
/*****************************************************************************
/*****************************************************************************
* WCMD_directory
* WCMD_directory
*
*
...
@@ -74,34 +80,35 @@ static ULONG showattrs, attrsbits;
...
@@ -74,34 +80,35 @@ static ULONG showattrs, attrsbits;
*
*
*/
*/
void
WCMD_directory
(
char
*
cmd
)
{
void
WCMD_directory
(
WCHAR
*
cmd
)
{
char
path
[
MAX_PATH
],
cwd
[
MAX_PATH
];
WCHAR
path
[
MAX_PATH
],
cwd
[
MAX_PATH
];
int
status
,
paged_mode
;
int
status
,
paged_mode
;
CONSOLE_SCREEN_BUFFER_INFO
consoleInfo
;
CONSOLE_SCREEN_BUFFER_INFO
consoleInfo
;
char
*
p
;
WCHAR
*
p
;
char
string
[
MAXSTRING
];
WCHAR
string
[
MAXSTRING
];
int
argno
=
0
;
int
argno
=
0
;
int
argsProcessed
=
0
;
int
argsProcessed
=
0
;
char
*
argN
=
cmd
;
WCHAR
*
argN
=
cmd
;
char
lastDrive
;
WCHAR
lastDrive
;
BOOL
trailerReqd
=
FALSE
;
BOOL
trailerReqd
=
FALSE
;
DIRECTORY_STACK
*
fullParms
=
NULL
;
DIRECTORY_STACK
*
fullParms
=
NULL
;
DIRECTORY_STACK
*
prevEntry
=
NULL
;
DIRECTORY_STACK
*
prevEntry
=
NULL
;
DIRECTORY_STACK
*
thisEntry
=
NULL
;
DIRECTORY_STACK
*
thisEntry
=
NULL
;
char
drive
[
10
];
WCHAR
drive
[
10
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
char
fname
[
MAX_PATH
];
WCHAR
fname
[
MAX_PATH
];
char
ext
[
MAX_PATH
];
WCHAR
ext
[
MAX_PATH
];
static
const
WCHAR
dircmdW
[]
=
{
'D'
,
'I'
,
'R'
,
'C'
,
'M'
,
'D'
,
'\0'
};
errorlevel
=
0
;
errorlevel
=
0
;
/* Prefill Quals with (uppercased) DIRCMD env var */
/* Prefill Quals with (uppercased) DIRCMD env var */
if
(
GetEnvironmentVariable
(
"DIRCMD"
,
string
,
sizeof
(
string
)))
{
if
(
GetEnvironmentVariable
(
dircmdW
,
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
)))
{
p
=
string
;
p
=
string
;
while
(
(
*
p
=
toupper
(
*
p
))
)
++
p
;
while
(
(
*
p
=
toupper
(
*
p
))
)
++
p
;
strcat
(
string
,
quals
);
strcat
W
(
string
,
quals
);
strcpy
(
quals
,
string
);
strcpy
W
(
quals
,
string
);
}
}
byte_total
=
0
;
byte_total
=
0
;
...
@@ -138,7 +145,7 @@ void WCMD_directory (char *cmd) {
...
@@ -138,7 +145,7 @@ void WCMD_directory (char *cmd) {
p
++
;
p
++
;
}
}
WINE_TRACE
(
"Processing arg '%c' (in %s)
\n
"
,
*
p
,
quals
);
WINE_TRACE
(
"Processing arg '%c' (in %s)
\n
"
,
*
p
,
wine_dbgstr_w
(
quals
)
);
switch
(
*
p
)
{
switch
(
*
p
)
{
case
'P'
:
if
(
negate
)
paged_mode
=
!
paged_mode
;
case
'P'
:
if
(
negate
)
paged_mode
=
!
paged_mode
;
else
paged_mode
=
TRUE
;
else
paged_mode
=
TRUE
;
...
@@ -188,7 +195,7 @@ void WCMD_directory (char *cmd) {
...
@@ -188,7 +195,7 @@ void WCMD_directory (char *cmd) {
case
'O'
:
p
=
p
+
1
;
case
'O'
:
p
=
p
+
1
;
if
(
*
p
==
':'
)
p
++
;
/* Skip optional : */
if
(
*
p
==
':'
)
p
++
;
/* Skip optional : */
while
(
*
p
&&
*
p
!=
'/'
)
{
while
(
*
p
&&
*
p
!=
'/'
)
{
WINE_TRACE
(
"Processing subparm '%c' (in %s)
\n
"
,
*
p
,
quals
);
WINE_TRACE
(
"Processing subparm '%c' (in %s)
\n
"
,
*
p
,
wine_dbgstr_w
(
quals
)
);
switch
(
*
p
)
{
switch
(
*
p
)
{
case
'N'
:
dirOrder
=
Name
;
break
;
case
'N'
:
dirOrder
=
Name
;
break
;
case
'E'
:
dirOrder
=
Extension
;
break
;
case
'E'
:
dirOrder
=
Extension
;
break
;
...
@@ -222,7 +229,7 @@ void WCMD_directory (char *cmd) {
...
@@ -222,7 +229,7 @@ void WCMD_directory (char *cmd) {
p
++
;
p
++
;
}
}
WINE_TRACE
(
"Processing subparm '%c' (in %s)
\n
"
,
*
p
,
quals
);
WINE_TRACE
(
"Processing subparm '%c' (in %s)
\n
"
,
*
p
,
wine_dbgstr_w
(
quals
)
);
switch
(
*
p
)
{
switch
(
*
p
)
{
case
'D'
:
mask
=
FILE_ATTRIBUTE_DIRECTORY
;
break
;
case
'D'
:
mask
=
FILE_ATTRIBUTE_DIRECTORY
;
break
;
case
'H'
:
mask
=
FILE_ATTRIBUTE_HIDDEN
;
break
;
case
'H'
:
mask
=
FILE_ATTRIBUTE_HIDDEN
;
break
;
...
@@ -276,62 +283,64 @@ void WCMD_directory (char *cmd) {
...
@@ -276,62 +283,64 @@ void WCMD_directory (char *cmd) {
argno
=
0
;
argno
=
0
;
argsProcessed
=
0
;
argsProcessed
=
0
;
argN
=
cmd
;
argN
=
cmd
;
GetCurrentDirectory
(
1024
,
cwd
);
GetCurrentDirectory
(
MAX_PATH
,
cwd
);
strcat
(
cwd
,
"
\\
"
);
strcat
W
(
cwd
,
slashW
);
/* Loop through all args, calculating full effective directory */
/* Loop through all args, calculating full effective directory */
fullParms
=
NULL
;
fullParms
=
NULL
;
prevEntry
=
NULL
;
prevEntry
=
NULL
;
while
(
argN
)
{
while
(
argN
)
{
char
fullname
[
MAXSTRING
];
WCHAR
fullname
[
MAXSTRING
];
char
*
thisArg
=
WCMD_parameter
(
cmd
,
argno
++
,
&
argN
);
WCHAR
*
thisArg
=
WCMD_parameter
(
cmd
,
argno
++
,
&
argN
);
if
(
argN
&&
argN
[
0
]
!=
'/'
)
{
if
(
argN
&&
argN
[
0
]
!=
'/'
)
{
WINE_TRACE
(
"Found parm '%s'
\n
"
,
thisArg
);
WINE_TRACE
(
"Found parm '%s'
\n
"
,
wine_dbgstr_w
(
thisArg
)
);
if
(
thisArg
[
1
]
==
':'
&&
thisArg
[
2
]
==
'\\'
)
{
if
(
thisArg
[
1
]
==
':'
&&
thisArg
[
2
]
==
'\\'
)
{
strcpy
(
fullname
,
thisArg
);
strcpy
W
(
fullname
,
thisArg
);
}
else
if
(
thisArg
[
1
]
==
':'
&&
thisArg
[
2
]
!=
'\\'
)
{
}
else
if
(
thisArg
[
1
]
==
':'
&&
thisArg
[
2
]
!=
'\\'
)
{
char
envvar
[
4
];
WCHAR
envvar
[
4
];
sprintf
(
envvar
,
"=%c:"
,
thisArg
[
0
]);
static
const
WCHAR
envFmt
[]
=
{
'='
,
'%'
,
'c'
,
':'
,
'\0'
};
wsprintf
(
envvar
,
envFmt
,
thisArg
[
0
]);
if
(
!
GetEnvironmentVariable
(
envvar
,
fullname
,
MAX_PATH
))
{
if
(
!
GetEnvironmentVariable
(
envvar
,
fullname
,
MAX_PATH
))
{
sprintf
(
fullname
,
"%c:"
,
thisArg
[
0
]);
static
const
WCHAR
noEnvFmt
[]
=
{
'%'
,
'c'
,
':'
,
'\0'
};
wsprintf
(
fullname
,
noEnvFmt
,
thisArg
[
0
]);
}
}
strcat
(
fullname
,
"
\\
"
);
strcat
W
(
fullname
,
slashW
);
strcat
(
fullname
,
&
thisArg
[
2
]);
strcat
W
(
fullname
,
&
thisArg
[
2
]);
}
else
if
(
thisArg
[
0
]
==
'\\'
)
{
}
else
if
(
thisArg
[
0
]
==
'\\'
)
{
strncpy
(
fullname
,
cwd
,
2
);
memcpy
(
fullname
,
cwd
,
2
*
sizeof
(
WCHAR
));
fullname
[
2
]
=
0x00
;
strcpyW
(
fullname
+
2
,
thisArg
);
strcat
((
fullname
+
2
),
thisArg
);
}
else
{
}
else
{
strcpy
(
fullname
,
cwd
);
strcpy
W
(
fullname
,
cwd
);
strcat
(
fullname
,
thisArg
);
strcat
W
(
fullname
,
thisArg
);
}
}
WINE_TRACE
(
"Using location '%s'
\n
"
,
fullname
);
WINE_TRACE
(
"Using location '%s'
\n
"
,
wine_dbgstr_w
(
fullname
)
);
status
=
GetFullPathName
(
fullname
,
sizeof
(
path
),
path
,
NULL
);
status
=
GetFullPathName
(
fullname
,
sizeof
(
path
)
/
sizeof
(
WCHAR
)
,
path
,
NULL
);
/*
/*
* If the path supplied does not include a wildcard, and the endpoint of the
* If the path supplied does not include a wildcard, and the endpoint of the
* path references a directory, we need to list the *contents* of that
* path references a directory, we need to list the *contents* of that
* directory not the directory file itself.
* directory not the directory file itself.
*/
*/
if
((
strchr
(
path
,
'*'
)
==
NULL
)
&&
(
strchr
(
path
,
'%'
)
==
NULL
))
{
if
((
strchr
W
(
path
,
'*'
)
==
NULL
)
&&
(
strchrW
(
path
,
'%'
)
==
NULL
))
{
status
=
GetFileAttributes
(
path
);
status
=
GetFileAttributes
(
path
);
if
((
status
!=
INVALID_FILE_ATTRIBUTES
)
&&
(
status
&
FILE_ATTRIBUTE_DIRECTORY
))
{
if
((
status
!=
INVALID_FILE_ATTRIBUTES
)
&&
(
status
&
FILE_ATTRIBUTE_DIRECTORY
))
{
if
(
path
[
strlen
(
path
)
-
1
]
==
'\\'
)
{
if
(
path
[
strlen
W
(
path
)
-
1
]
==
'\\'
)
{
strcat
(
path
,
"*"
);
strcat
W
(
path
,
starW
);
}
}
else
{
else
{
strcat
(
path
,
"
\\
*"
);
const
WCHAR
slashStarW
[]
=
{
'\\'
,
'*'
,
'\0'
};
strcatW
(
path
,
slashStarW
);
}
}
}
}
}
else
{
}
else
{
/* Special case wildcard search with no extension (ie parameters ending in '.') as
/* Special case wildcard search with no extension (ie parameters ending in '.') as
GetFullPathName strips off the additional '.' */
GetFullPathName strips off the additional '.' */
if
(
fullname
[
strlen
(
fullname
)
-
1
]
==
'.'
)
strcat
(
path
,
"."
);
if
(
fullname
[
strlen
W
(
fullname
)
-
1
]
==
'.'
)
strcatW
(
path
,
dotW
);
}
}
WINE_TRACE
(
"Using path '%s'
\n
"
,
path
);
WINE_TRACE
(
"Using path '%s'
\n
"
,
wine_dbgstr_w
(
path
)
);
thisEntry
=
(
DIRECTORY_STACK
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DIRECTORY_STACK
));
thisEntry
=
(
DIRECTORY_STACK
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DIRECTORY_STACK
));
if
(
fullParms
==
NULL
)
fullParms
=
thisEntry
;
if
(
fullParms
==
NULL
)
fullParms
=
thisEntry
;
if
(
prevEntry
!=
NULL
)
prevEntry
->
next
=
thisEntry
;
if
(
prevEntry
!=
NULL
)
prevEntry
->
next
=
thisEntry
;
...
@@ -341,15 +350,18 @@ void WCMD_directory (char *cmd) {
...
@@ -341,15 +350,18 @@ void WCMD_directory (char *cmd) {
/* Split into components */
/* Split into components */
WCMD_splitpath
(
path
,
drive
,
dir
,
fname
,
ext
);
WCMD_splitpath
(
path
,
drive
,
dir
,
fname
,
ext
);
WINE_TRACE
(
"Path Parts: drive: '%s' dir: '%s' name: '%s' ext:'%s'
\n
"
,
WINE_TRACE
(
"Path Parts: drive: '%s' dir: '%s' name: '%s' ext:'%s'
\n
"
,
drive
,
dir
,
fname
,
ext
);
wine_dbgstr_w
(
drive
),
wine_dbgstr_w
(
dir
),
wine_dbgstr_w
(
fname
),
wine_dbgstr_w
(
ext
));
thisEntry
->
dirName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
drive
)
+
strlen
(
dir
)
+
1
);
thisEntry
->
dirName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strcpy
(
thisEntry
->
dirName
,
drive
);
sizeof
(
WCHAR
)
*
(
strlenW
(
drive
)
+
strlenW
(
dir
)
+
1
));
strcat
(
thisEntry
->
dirName
,
dir
);
strcpyW
(
thisEntry
->
dirName
,
drive
);
strcatW
(
thisEntry
->
dirName
,
dir
);
thisEntry
->
fileName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
fname
)
+
strlen
(
ext
)
+
1
);
thisEntry
->
fileName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strcpy
(
thisEntry
->
fileName
,
fname
);
sizeof
(
WCHAR
)
*
(
strlenW
(
fname
)
+
strlenW
(
ext
)
+
1
));
strcat
(
thisEntry
->
fileName
,
ext
);
strcpyW
(
thisEntry
->
fileName
,
fname
);
strcatW
(
thisEntry
->
fileName
,
ext
);
}
}
}
}
...
@@ -359,10 +371,10 @@ void WCMD_directory (char *cmd) {
...
@@ -359,10 +371,10 @@ void WCMD_directory (char *cmd) {
WINE_TRACE
(
"Inserting default '*'
\n
"
);
WINE_TRACE
(
"Inserting default '*'
\n
"
);
fullParms
=
(
DIRECTORY_STACK
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DIRECTORY_STACK
));
fullParms
=
(
DIRECTORY_STACK
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DIRECTORY_STACK
));
fullParms
->
next
=
NULL
;
fullParms
->
next
=
NULL
;
fullParms
->
dirName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
strlen
(
cwd
)
+
1
));
fullParms
->
dirName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WCHAR
)
*
(
strlenW
(
cwd
)
+
1
));
strcpy
(
fullParms
->
dirName
,
cwd
);
strcpy
W
(
fullParms
->
dirName
,
cwd
);
fullParms
->
fileName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
2
);
fullParms
->
fileName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WCHAR
)
*
2
);
strcpy
(
fullParms
->
fileName
,
"*"
);
strcpy
W
(
fullParms
->
fileName
,
starW
);
}
}
lastDrive
=
'?'
;
lastDrive
=
'?'
;
...
@@ -385,10 +397,10 @@ void WCMD_directory (char *cmd) {
...
@@ -385,10 +397,10 @@ void WCMD_directory (char *cmd) {
lastDrive
=
toupper
(
thisEntry
->
dirName
[
0
]);
lastDrive
=
toupper
(
thisEntry
->
dirName
[
0
]);
if
(
!
bare
)
{
if
(
!
bare
)
{
char
drive
[
3
];
WCHAR
drive
[
3
];
WINE_TRACE
(
"Writing volume for '%c:'
\n
"
,
thisEntry
->
dirName
[
0
]);
WINE_TRACE
(
"Writing volume for '%c:'
\n
"
,
thisEntry
->
dirName
[
0
]);
strncpy
(
drive
,
thisEntry
->
dirName
,
2
);
memcpy
(
drive
,
thisEntry
->
dirName
,
2
*
sizeof
(
WCHAR
)
);
drive
[
2
]
=
0x00
;
drive
[
2
]
=
0x00
;
status
=
WCMD_volume
(
0
,
drive
);
status
=
WCMD_volume
(
0
,
drive
);
trailerReqd
=
TRUE
;
trailerReqd
=
TRUE
;
...
@@ -398,7 +410,8 @@ void WCMD_directory (char *cmd) {
...
@@ -398,7 +410,8 @@ void WCMD_directory (char *cmd) {
}
}
}
}
}
else
{
}
else
{
if
(
!
bare
)
WCMD_output
(
"
\n\n
"
);
static
const
WCHAR
newLine2
[]
=
{
'\n'
,
'\n'
,
'\0'
};
if
(
!
bare
)
WCMD_output
(
newLine2
);
}
}
/* Clear any errors from previous invocations, and process it */
/* Clear any errors from previous invocations, and process it */
...
@@ -436,8 +449,8 @@ exit:
...
@@ -436,8 +449,8 @@ exit:
static
DIRECTORY_STACK
*
WCMD_list_directory
(
DIRECTORY_STACK
*
inputparms
,
int
level
)
{
static
DIRECTORY_STACK
*
WCMD_list_directory
(
DIRECTORY_STACK
*
inputparms
,
int
level
)
{
char
string
[
1024
],
datestring
[
32
],
timestring
[
32
];
WCHAR
string
[
1024
],
datestring
[
32
],
timestring
[
32
];
char
real_path
[
MAX_PATH
];
WCHAR
real_path
[
MAX_PATH
];
WIN32_FIND_DATA
*
fd
;
WIN32_FIND_DATA
*
fd
;
FILETIME
ft
;
FILETIME
ft
;
SYSTEMTIME
st
;
SYSTEMTIME
st
;
...
@@ -450,6 +463,14 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -450,6 +463,14 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
int
concurrentDirs
=
0
;
int
concurrentDirs
=
0
;
BOOL
done_header
=
FALSE
;
BOOL
done_header
=
FALSE
;
static
const
WCHAR
fmtDir
[]
=
{
'%'
,
'1'
,
'0'
,
's'
,
' '
,
' '
,
'%'
,
'8'
,
's'
,
' '
,
' '
,
'<'
,
'D'
,
'I'
,
'R'
,
'>'
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
'\0'
};
static
const
WCHAR
fmtFile
[]
=
{
'%'
,
'1'
,
'0'
,
's'
,
' '
,
' '
,
'%'
,
'8'
,
's'
,
' '
,
' '
,
' '
,
' '
,
'%'
,
'1'
,
'0'
,
's'
,
' '
,
' '
,
'\0'
};
static
const
WCHAR
fmt2
[]
=
{
'%'
,
'-'
,
'1'
,
'3'
,
's'
,
'\0'
};
static
const
WCHAR
fmt3
[]
=
{
'%'
,
'-'
,
'2'
,
'3'
,
's'
,
'\0'
};
static
const
WCHAR
fmt4
[]
=
{
'%'
,
's'
,
'\0'
};
static
const
WCHAR
fmt5
[]
=
{
'%'
,
's'
,
'%'
,
's'
,
'\0'
};
dir_count
=
0
;
dir_count
=
0
;
file_count
=
0
;
file_count
=
0
;
...
@@ -463,15 +484,15 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -463,15 +484,15 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
mirrors what windows does */
mirrors what windows does */
parms
=
inputparms
;
parms
=
inputparms
;
fd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WIN32_FIND_DATA
));
fd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WIN32_FIND_DATA
));
while
(
parms
&&
strcmp
(
inputparms
->
dirName
,
parms
->
dirName
)
==
0
)
{
while
(
parms
&&
strcmp
W
(
inputparms
->
dirName
,
parms
->
dirName
)
==
0
)
{
concurrentDirs
++
;
concurrentDirs
++
;
/* Work out the full path + filename */
/* Work out the full path + filename */
strcpy
(
real_path
,
parms
->
dirName
);
strcpy
W
(
real_path
,
parms
->
dirName
);
strcat
(
real_path
,
parms
->
fileName
);
strcat
W
(
real_path
,
parms
->
fileName
);
/* Load all files into an in memory structure */
/* Load all files into an in memory structure */
WINE_TRACE
(
"Looking for matches to '%s'
\n
"
,
real_path
);
WINE_TRACE
(
"Looking for matches to '%s'
\n
"
,
wine_dbgstr_w
(
real_path
)
);
hff
=
FindFirstFile
(
real_path
,
(
fd
+
entry_count
));
hff
=
FindFirstFile
(
real_path
,
(
fd
+
entry_count
));
if
(
hff
!=
INVALID_HANDLE_VALUE
)
{
if
(
hff
!=
INVALID_HANDLE_VALUE
)
{
do
{
do
{
...
@@ -482,7 +503,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -482,7 +503,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
/* Keep running track of longest filename for wide output */
/* Keep running track of longest filename for wide output */
if
(
wide
||
orderByCol
)
{
if
(
wide
||
orderByCol
)
{
int
tmpLen
=
strlen
((
fd
+
(
entry_count
-
1
))
->
cFileName
)
+
3
;
int
tmpLen
=
strlen
W
((
fd
+
(
entry_count
-
1
))
->
cFileName
)
+
3
;
if
((
fd
+
(
entry_count
-
1
))
->
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
tmpLen
=
tmpLen
+
2
;
if
((
fd
+
(
entry_count
-
1
))
->
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
tmpLen
=
tmpLen
+
2
;
if
(
tmpLen
>
widest
)
widest
=
tmpLen
;
if
(
tmpLen
>
widest
)
widest
=
tmpLen
;
}
}
...
@@ -499,14 +520,16 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -499,14 +520,16 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
}
}
/* Work out the actual current directory name without a trailing \ */
/* Work out the actual current directory name without a trailing \ */
strcpy
(
real_path
,
parms
->
dirName
);
strcpy
W
(
real_path
,
parms
->
dirName
);
real_path
[
strlen
(
parms
->
dirName
)
-
1
]
=
0x00
;
real_path
[
strlen
W
(
parms
->
dirName
)
-
1
]
=
0x00
;
/* Output the results */
/* Output the results */
if
(
!
bare
)
{
if
(
!
bare
)
{
if
(
level
!=
0
&&
(
entry_count
>
0
))
WCMD_output
(
newline
);
if
(
level
!=
0
&&
(
entry_count
>
0
))
WCMD_output
(
newline
);
if
(
!
recurse
||
((
entry_count
>
0
)
&&
done_header
==
FALSE
))
{
if
(
!
recurse
||
((
entry_count
>
0
)
&&
done_header
==
FALSE
))
{
WCMD_output
(
"Directory of %s
\n\n
"
,
real_path
);
static
const
WCHAR
headerW
[]
=
{
'D'
,
'i'
,
'r'
,
'e'
,
'c'
,
't'
,
'o'
,
'r'
,
'y'
,
' '
,
'o'
,
'f'
,
' '
,
'%'
,
's'
,
'\n'
,
'\n'
,
'\0'
};
WCMD_output
(
headerW
,
real_path
);
done_header
=
TRUE
;
done_header
=
TRUE
;
}
}
}
}
...
@@ -536,7 +559,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -536,7 +559,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
for
(
rows
=
0
;
rows
<
numRows
;
rows
++
)
{
for
(
rows
=
0
;
rows
<
numRows
;
rows
++
)
{
BOOL
addNewLine
=
TRUE
;
BOOL
addNewLine
=
TRUE
;
for
(
cols
=
0
;
cols
<
numCols
;
cols
++
)
{
for
(
cols
=
0
;
cols
<
numCols
;
cols
++
)
{
char
username
[
24
];
WCHAR
username
[
24
];
/* Work out the index of the entry being pointed to */
/* Work out the index of the entry being pointed to */
if
(
orderByCol
)
{
if
(
orderByCol
)
{
...
@@ -549,15 +572,15 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -549,15 +572,15 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
/* /L convers all names to lower case */
/* /L convers all names to lower case */
if
(
lower
)
{
if
(
lower
)
{
char
*
p
=
(
fd
+
i
)
->
cFileName
;
WCHAR
*
p
=
(
fd
+
i
)
->
cFileName
;
while
(
(
*
p
=
tolower
(
*
p
))
)
++
p
;
while
(
(
*
p
=
tolower
(
*
p
))
)
++
p
;
}
}
/* /Q gets file ownership information */
/* /Q gets file ownership information */
if
(
usernames
)
{
if
(
usernames
)
{
lstrcpy
(
string
,
inputparms
->
dirName
);
strcpyW
(
string
,
inputparms
->
dirName
);
lstrcat
(
string
,
(
fd
+
i
)
->
cFileName
);
strcatW
(
string
,
(
fd
+
i
)
->
cFileName
);
WCMD_getfileowner
(
string
,
username
,
sizeof
(
username
));
WCMD_getfileowner
(
string
,
username
,
sizeof
(
username
)
/
sizeof
(
WCHAR
)
);
}
}
if
(
dirTime
==
Written
)
{
if
(
dirTime
==
Written
)
{
...
@@ -569,20 +592,22 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -569,20 +592,22 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
}
}
FileTimeToSystemTime
(
&
ft
,
&
st
);
FileTimeToSystemTime
(
&
ft
,
&
st
);
GetDateFormat
(
0
,
DATE_SHORTDATE
,
&
st
,
NULL
,
datestring
,
GetDateFormat
(
0
,
DATE_SHORTDATE
,
&
st
,
NULL
,
datestring
,
sizeof
(
datestring
));
sizeof
(
datestring
)
/
sizeof
(
WCHAR
)
);
GetTimeFormat
(
0
,
TIME_NOSECONDS
,
&
st
,
GetTimeFormat
(
0
,
TIME_NOSECONDS
,
&
st
,
NULL
,
timestring
,
sizeof
(
timestring
));
NULL
,
timestring
,
sizeof
(
timestring
)
/
sizeof
(
WCHAR
)
);
if
(
wide
)
{
if
(
wide
)
{
tmp_width
=
cur_width
;
tmp_width
=
cur_width
;
if
((
fd
+
i
)
->
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
{
if
((
fd
+
i
)
->
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
{
WCMD_output
(
"[%s]"
,
(
fd
+
i
)
->
cFileName
);
static
const
WCHAR
fmt
[]
=
{
'['
,
'%'
,
's'
,
']'
,
'\0'
};
WCMD_output
(
fmt
,
(
fd
+
i
)
->
cFileName
);
dir_count
++
;
dir_count
++
;
tmp_width
=
tmp_width
+
strlen
((
fd
+
i
)
->
cFileName
)
+
2
;
tmp_width
=
tmp_width
+
strlen
W
((
fd
+
i
)
->
cFileName
)
+
2
;
}
else
{
}
else
{
WCMD_output
(
"%s"
,
(
fd
+
i
)
->
cFileName
);
static
const
WCHAR
fmt
[]
=
{
'%'
,
's'
,
'\0'
};
tmp_width
=
tmp_width
+
strlen
((
fd
+
i
)
->
cFileName
)
;
WCMD_output
(
fmt
,
(
fd
+
i
)
->
cFileName
);
tmp_width
=
tmp_width
+
strlenW
((
fd
+
i
)
->
cFileName
)
;
file_count
++
;
file_count
++
;
file_size
.
u
.
LowPart
=
(
fd
+
i
)
->
nFileSizeLow
;
file_size
.
u
.
LowPart
=
(
fd
+
i
)
->
nFileSizeLow
;
file_size
.
u
.
HighPart
=
(
fd
+
i
)
->
nFileSizeHigh
;
file_size
.
u
.
HighPart
=
(
fd
+
i
)
->
nFileSizeHigh
;
...
@@ -593,21 +618,22 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -593,21 +618,22 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
if
((
cur_width
+
widest
)
>
max_width
)
{
if
((
cur_width
+
widest
)
>
max_width
)
{
cur_width
=
0
;
cur_width
=
0
;
}
else
{
}
else
{
WCMD_output
(
"%*.s"
,
(
tmp_width
-
cur_width
)
,
""
);
static
const
WCHAR
fmt
[]
=
{
'%'
,
'*'
,
'.'
,
's'
,
'\0'
};
WCMD_output
(
fmt
,
(
tmp_width
-
cur_width
),
emptyW
);
}
}
}
else
if
((
fd
+
i
)
->
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
{
}
else
if
((
fd
+
i
)
->
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
{
dir_count
++
;
dir_count
++
;
if
(
!
bare
)
{
if
(
!
bare
)
{
WCMD_output
(
"%10s %8s <DIR> "
,
datestring
,
timestring
);
WCMD_output
(
fmtDir
,
datestring
,
timestring
);
if
(
shortname
)
WCMD_output
(
"%-13s"
,
(
fd
+
i
)
->
cAlternateFileName
);
if
(
shortname
)
WCMD_output
(
fmt2
,
(
fd
+
i
)
->
cAlternateFileName
);
if
(
usernames
)
WCMD_output
(
"%-23s"
,
username
);
if
(
usernames
)
WCMD_output
(
fmt3
,
username
);
WCMD_output
(
"%s"
,(
fd
+
i
)
->
cFileName
);
WCMD_output
(
fmt4
,(
fd
+
i
)
->
cFileName
);
}
else
{
}
else
{
if
(
!
((
strcmp
((
fd
+
i
)
->
cFileName
,
"."
)
==
0
)
||
if
(
!
((
strcmp
W
((
fd
+
i
)
->
cFileName
,
dotW
)
==
0
)
||
(
strcmp
((
fd
+
i
)
->
cFileName
,
".."
)
==
0
)))
{
(
strcmp
W
((
fd
+
i
)
->
cFileName
,
dotdotW
)
==
0
)))
{
WCMD_output
(
"%s%s"
,
recurse
?
inputparms
->
dirName
:
""
,
(
fd
+
i
)
->
cFileName
);
WCMD_output
(
fmt5
,
recurse
?
inputparms
->
dirName
:
emptyW
,
(
fd
+
i
)
->
cFileName
);
}
else
{
}
else
{
addNewLine
=
FALSE
;
addNewLine
=
FALSE
;
}
}
...
@@ -619,13 +645,13 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -619,13 +645,13 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
file_size
.
u
.
HighPart
=
(
fd
+
i
)
->
nFileSizeHigh
;
file_size
.
u
.
HighPart
=
(
fd
+
i
)
->
nFileSizeHigh
;
byte_count
.
QuadPart
+=
file_size
.
QuadPart
;
byte_count
.
QuadPart
+=
file_size
.
QuadPart
;
if
(
!
bare
)
{
if
(
!
bare
)
{
WCMD_output
(
"%10s %8s %10s "
,
datestring
,
timestring
,
WCMD_output
(
fmtFile
,
datestring
,
timestring
,
WCMD_filesize64
(
file_size
.
QuadPart
));
WCMD_filesize64
(
file_size
.
QuadPart
));
if
(
shortname
)
WCMD_output
(
"%-13s"
,
(
fd
+
i
)
->
cAlternateFileName
);
if
(
shortname
)
WCMD_output
(
fmt2
,
(
fd
+
i
)
->
cAlternateFileName
);
if
(
usernames
)
WCMD_output
(
"%-23s"
,
username
);
if
(
usernames
)
WCMD_output
(
fmt3
,
username
);
WCMD_output
(
"%s"
,(
fd
+
i
)
->
cFileName
);
WCMD_output
(
fmt4
,(
fd
+
i
)
->
cFileName
);
}
else
{
}
else
{
WCMD_output
(
"%s%s"
,
recurse
?
inputparms
->
dirName
:
""
,
(
fd
+
i
)
->
cFileName
);
WCMD_output
(
fmt5
,
recurse
?
inputparms
->
dirName
:
emptyW
,
(
fd
+
i
)
->
cFileName
);
}
}
}
}
}
}
...
@@ -635,10 +661,14 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -635,10 +661,14 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
if
(
!
bare
)
{
if
(
!
bare
)
{
if
(
file_count
==
1
)
{
if
(
file_count
==
1
)
{
WCMD_output
(
" 1 file %25s bytes
\n
"
,
WCMD_filesize64
(
byte_count
.
QuadPart
));
static
const
WCHAR
fmt
[]
=
{
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
'1'
,
' '
,
'f'
,
'i'
,
'l'
,
'e'
,
' '
,
'%'
,
'2'
,
'5'
,
's'
,
' '
,
'b'
,
'y'
,
't'
,
'e'
,
's'
,
'\n'
,
'\0'
};
WCMD_output
(
fmt
,
WCMD_filesize64
(
byte_count
.
QuadPart
));
}
}
else
{
else
{
WCMD_output
(
"%8d files %24s bytes
\n
"
,
file_count
,
WCMD_filesize64
(
byte_count
.
QuadPart
));
static
const
WCHAR
fmt
[]
=
{
'%'
,
'8'
,
'd'
,
' '
,
'f'
,
'i'
,
'l'
,
'e'
,
's'
,
' '
,
'%'
,
'2'
,
'4'
,
's'
,
' '
,
'b'
,
'y'
,
't'
,
'e'
,
's'
,
'\n'
,
'\0'
};
WCMD_output
(
fmt
,
file_count
,
WCMD_filesize64
(
byte_count
.
QuadPart
));
}
}
}
}
byte_total
=
byte_total
+
byte_count
.
QuadPart
;
byte_total
=
byte_total
+
byte_count
.
QuadPart
;
...
@@ -646,8 +676,15 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -646,8 +676,15 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
dir_total
=
dir_total
+
dir_count
;
dir_total
=
dir_total
+
dir_count
;
if
(
!
bare
&&
!
recurse
)
{
if
(
!
bare
&&
!
recurse
)
{
if
(
dir_count
==
1
)
WCMD_output
(
"%8d directory "
,
1
);
if
(
dir_count
==
1
)
{
else
WCMD_output
(
"%8d directories"
,
dir_count
);
static
const
WCHAR
fmt
[]
=
{
'%'
,
'8'
,
'd'
,
' '
,
'd'
,
'i'
,
'r'
,
'e'
,
'c'
,
't'
,
'o'
,
'r'
,
'y'
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
'\0'
};
WCMD_output
(
fmt
,
1
);
}
else
{
static
const
WCHAR
fmt
[]
=
{
'%'
,
'8'
,
'd'
,
' '
,
'd'
,
'i'
,
'r'
,
'e'
,
'c'
,
't'
,
'o'
,
'r'
,
'i'
,
'e'
,
's'
,
'\0'
};
WCMD_output
(
fmt
,
dir_count
);
}
}
}
}
}
HeapFree
(
GetProcessHeap
(),
0
,
fd
);
HeapFree
(
GetProcessHeap
(),
0
,
fd
);
...
@@ -659,16 +696,16 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -659,16 +696,16 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
WIN32_FIND_DATA
finddata
;
WIN32_FIND_DATA
finddata
;
/* Build path to search */
/* Build path to search */
strcpy
(
string
,
inputparms
->
dirName
);
strcpy
W
(
string
,
inputparms
->
dirName
);
strcat
(
string
,
"*"
);
strcat
W
(
string
,
starW
);
WINE_TRACE
(
"Recursive, looking for '%s'
\n
"
,
string
);
WINE_TRACE
(
"Recursive, looking for '%s'
\n
"
,
wine_dbgstr_w
(
string
)
);
hff
=
FindFirstFile
(
string
,
&
finddata
);
hff
=
FindFirstFile
(
string
,
&
finddata
);
if
(
hff
!=
INVALID_HANDLE_VALUE
)
{
if
(
hff
!=
INVALID_HANDLE_VALUE
)
{
do
{
do
{
if
((
finddata
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
&&
if
((
finddata
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
&&
(
strcmp
(
finddata
.
cFileName
,
".."
)
!=
0
)
&&
(
strcmp
W
(
finddata
.
cFileName
,
dotdotW
)
!=
0
)
&&
(
strcmp
(
finddata
.
cFileName
,
"."
)
!=
0
))
{
(
strcmp
W
(
finddata
.
cFileName
,
dotW
)
!=
0
))
{
DIRECTORY_STACK
*
thisDir
;
DIRECTORY_STACK
*
thisDir
;
int
dirsToCopy
=
concurrentDirs
;
int
dirsToCopy
=
concurrentDirs
;
...
@@ -679,10 +716,10 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -679,10 +716,10 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
dirsToCopy
--
;
dirsToCopy
--
;
/* Work out search parameter in sub dir */
/* Work out search parameter in sub dir */
strcpy
(
string
,
inputparms
->
dirName
);
strcpy
W
(
string
,
inputparms
->
dirName
);
strcat
(
string
,
finddata
.
cFileName
);
strcat
W
(
string
,
finddata
.
cFileName
);
strcat
(
string
,
"
\\
"
);
strcat
W
(
string
,
slashW
);
WINE_TRACE
(
"Recursive, Adding to search list '%s'
\n
"
,
string
);
WINE_TRACE
(
"Recursive, Adding to search list '%s'
\n
"
,
wine_dbgstr_w
(
string
)
);
/* Allocate memory, add to list */
/* Allocate memory, add to list */
thisDir
=
(
DIRECTORY_STACK
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DIRECTORY_STACK
));
thisDir
=
(
DIRECTORY_STACK
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DIRECTORY_STACK
));
...
@@ -690,10 +727,12 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -690,10 +727,12 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
if
(
lastEntry
!=
NULL
)
lastEntry
->
next
=
thisDir
;
if
(
lastEntry
!=
NULL
)
lastEntry
->
next
=
thisDir
;
lastEntry
=
thisDir
;
lastEntry
=
thisDir
;
thisDir
->
next
=
NULL
;
thisDir
->
next
=
NULL
;
thisDir
->
dirName
=
HeapAlloc
(
GetProcessHeap
(),
0
,(
strlen
(
string
)
+
1
));
thisDir
->
dirName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strcpy
(
thisDir
->
dirName
,
string
);
sizeof
(
WCHAR
)
*
(
strlenW
(
string
)
+
1
));
thisDir
->
fileName
=
HeapAlloc
(
GetProcessHeap
(),
0
,(
strlen
(
parms
->
fileName
)
+
1
));
strcpyW
(
thisDir
->
dirName
,
string
);
strcpy
(
thisDir
->
fileName
,
parms
->
fileName
);
thisDir
->
fileName
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WCHAR
)
*
(
strlenW
(
parms
->
fileName
)
+
1
));
strcpyW
(
thisDir
->
fileName
,
parms
->
fileName
);
parms
=
parms
->
next
;
parms
=
parms
->
next
;
}
}
}
}
...
@@ -727,17 +766,17 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
...
@@ -727,17 +766,17 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
/*****************************************************************************
/*****************************************************************************
* WCMD_filesize64
* WCMD_filesize64
*
*
* Convert a 64-bit number into a
char
acter string, with commas every three digits.
* Convert a 64-bit number into a
WCHAR
acter string, with commas every three digits.
* Result is returned in a static string overwritten with each call.
* Result is returned in a static string overwritten with each call.
* FIXME: There must be a better algorithm!
* FIXME: There must be a better algorithm!
*/
*/
char
*
WCMD_filesize64
(
ULONGLONG
n
)
{
WCHAR
*
WCMD_filesize64
(
ULONGLONG
n
)
{
ULONGLONG
q
;
ULONGLONG
q
;
unsigned
int
r
,
i
;
unsigned
int
r
,
i
;
char
*
p
;
WCHAR
*
p
;
static
char
buff
[
32
];
static
WCHAR
buff
[
32
];
p
=
buff
;
p
=
buff
;
i
=
-
3
;
i
=
-
3
;
...
@@ -756,15 +795,15 @@ char * WCMD_filesize64 (ULONGLONG n) {
...
@@ -756,15 +795,15 @@ char * WCMD_filesize64 (ULONGLONG n) {
/*****************************************************************************
/*****************************************************************************
* WCMD_strrev
* WCMD_strrev
*
*
* Reverse a
char
acter string in-place (strrev() is not available under unixen :-( ).
* Reverse a
WCHAR
acter string in-place (strrev() is not available under unixen :-( ).
*/
*/
char
*
WCMD_strrev
(
char
*
buff
)
{
WCHAR
*
WCMD_strrev
(
WCHAR
*
buff
)
{
int
r
,
i
;
int
r
,
i
;
char
b
;
WCHAR
b
;
r
=
lstrlen
(
buff
);
r
=
strlenW
(
buff
);
for
(
i
=
0
;
i
<
r
/
2
;
i
++
)
{
for
(
i
=
0
;
i
<
r
/
2
;
i
++
)
{
b
=
buff
[
i
];
b
=
buff
[
i
];
buff
[
i
]
=
buff
[
r
-
i
-
1
];
buff
[
i
]
=
buff
[
r
-
i
-
1
];
...
@@ -799,7 +838,7 @@ int WCMD_dir_sort (const void *a, const void *b)
...
@@ -799,7 +838,7 @@ int WCMD_dir_sort (const void *a, const void *b)
/* Order by Name: */
/* Order by Name: */
}
else
if
(
dirOrder
==
Name
)
{
}
else
if
(
dirOrder
==
Name
)
{
result
=
lstrcmpi
(
filea
->
cFileName
,
fileb
->
cFileName
);
result
=
lstrcmpi
W
(
filea
->
cFileName
,
fileb
->
cFileName
);
/* Order by Size: */
/* Order by Size: */
}
else
if
(
dirOrder
==
Size
)
{
}
else
if
(
dirOrder
==
Size
)
{
...
@@ -837,16 +876,16 @@ int WCMD_dir_sort (const void *a, const void *b)
...
@@ -837,16 +876,16 @@ int WCMD_dir_sort (const void *a, const void *b)
/* Order by Extension: (Takes into account which date (/T option) */
/* Order by Extension: (Takes into account which date (/T option) */
}
else
if
(
dirOrder
==
Extension
)
{
}
else
if
(
dirOrder
==
Extension
)
{
char
drive
[
10
];
WCHAR
drive
[
10
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
char
fname
[
MAX_PATH
];
WCHAR
fname
[
MAX_PATH
];
char
extA
[
MAX_PATH
];
WCHAR
extA
[
MAX_PATH
];
char
extB
[
MAX_PATH
];
WCHAR
extB
[
MAX_PATH
];
/* Split into components */
/* Split into components */
WCMD_splitpath
(
filea
->
cFileName
,
drive
,
dir
,
fname
,
extA
);
WCMD_splitpath
(
filea
->
cFileName
,
drive
,
dir
,
fname
,
extA
);
WCMD_splitpath
(
fileb
->
cFileName
,
drive
,
dir
,
fname
,
extB
);
WCMD_splitpath
(
fileb
->
cFileName
,
drive
,
dir
,
fname
,
extB
);
result
=
lstrcmpi
(
extA
,
extB
);
result
=
lstrcmpi
W
(
extA
,
extB
);
}
}
if
(
orderReverse
)
result
=
-
result
;
if
(
orderReverse
)
result
=
-
result
;
...
@@ -856,14 +895,14 @@ int WCMD_dir_sort (const void *a, const void *b)
...
@@ -856,14 +895,14 @@ int WCMD_dir_sort (const void *a, const void *b)
/*****************************************************************************
/*****************************************************************************
* WCMD_getfileowner
* WCMD_getfileowner
*
*
* Reverse a
char
acter string in-place (strrev() is not available under unixen :-( ).
* Reverse a
WCHAR
acter string in-place (strrev() is not available under unixen :-( ).
*/
*/
void
WCMD_getfileowner
(
char
*
filename
,
char
*
owner
,
int
ownerlen
)
{
void
WCMD_getfileowner
(
WCHAR
*
filename
,
WCHAR
*
owner
,
int
ownerlen
)
{
ULONG
sizeNeeded
=
0
;
ULONG
sizeNeeded
=
0
;
DWORD
rc
;
DWORD
rc
;
char
name
[
MAXSTRING
];
WCHAR
name
[
MAXSTRING
];
char
domain
[
MAXSTRING
];
WCHAR
domain
[
MAXSTRING
];
/* In case of error, return empty string */
/* In case of error, return empty string */
*
owner
=
0x00
;
*
owner
=
0x00
;
...
@@ -899,7 +938,8 @@ void WCMD_getfileowner(char *filename, char *owner, int ownerlen) {
...
@@ -899,7 +938,8 @@ void WCMD_getfileowner(char *filename, char *owner, int ownerlen) {
/* Convert to a username */
/* Convert to a username */
if
(
LookupAccountSid
(
NULL
,
pSID
,
name
,
&
nameLen
,
domain
,
&
domainLen
,
&
nameuse
))
{
if
(
LookupAccountSid
(
NULL
,
pSID
,
name
,
&
nameLen
,
domain
,
&
domainLen
,
&
nameuse
))
{
snprintf
(
owner
,
ownerlen
,
"%s%c%s"
,
domain
,
'\\'
,
name
);
static
const
WCHAR
fmt
[]
=
{
'%'
,
's'
,
'%'
,
'c'
,
'%'
,
's'
,
'\0'
};
snprintfW
(
owner
,
ownerlen
,
fmt
,
domain
,
'\\'
,
name
);
}
}
HeapFree
(
GetProcessHeap
(),
0
,
secBuffer
);
HeapFree
(
GetProcessHeap
(),
0
,
secBuffer
);
}
}
...
@@ -911,23 +951,30 @@ void WCMD_getfileowner(char *filename, char *owner, int ownerlen) {
...
@@ -911,23 +951,30 @@ void WCMD_getfileowner(char *filename, char *owner, int ownerlen) {
*
*
* Print out the trailer for the supplied drive letter
* Print out the trailer for the supplied drive letter
*/
*/
static
void
WCMD_dir_trailer
(
char
drive
)
{
static
void
WCMD_dir_trailer
(
WCHAR
drive
)
{
ULARGE_INTEGER
avail
,
total
,
freebytes
;
ULARGE_INTEGER
avail
,
total
,
freebytes
;
DWORD
status
;
DWORD
status
;
char
driveName
[
4
]
=
"c:
\\
"
;
WCHAR
driveName
[
4
]
=
{
'c'
,
':'
,
'\\'
,
'\0'
}
;
driveName
[
0
]
=
drive
;
driveName
[
0
]
=
drive
;
status
=
GetDiskFreeSpaceEx
(
driveName
,
&
avail
,
&
total
,
&
freebytes
);
status
=
GetDiskFreeSpaceEx
(
driveName
,
&
avail
,
&
total
,
&
freebytes
);
WINE_TRACE
(
"Writing trailer for '%s' gave %d(%d)
\n
"
,
driveName
,
status
,
GetLastError
());
WINE_TRACE
(
"Writing trailer for '%s' gave %d(%d)
\n
"
,
wine_dbgstr_w
(
driveName
),
status
,
GetLastError
());
if
(
errorlevel
==
0
&&
!
bare
)
{
if
(
errorlevel
==
0
&&
!
bare
)
{
if
(
recurse
)
{
if
(
recurse
)
{
WCMD_output
(
"
\n
Total files listed:
\n
%8d files%25s bytes
\n
"
,
static
const
WCHAR
fmt1
[]
=
{
'\n'
,
' '
,
' '
,
' '
,
' '
,
' '
,
'T'
,
'o'
,
't'
,
'a'
,
'l'
,
' '
,
'f'
,
'i'
,
'l'
,
'e'
,
's'
,
file_total
,
WCMD_filesize64
(
byte_total
));
' '
,
'l'
,
'i'
,
's'
,
't'
,
'e'
,
'd'
,
':'
,
'\n'
,
'%'
,
'8'
,
'd'
,
' '
,
'f'
,
'i'
,
'l'
,
'e'
,
WCMD_output
(
"%8d directories %18s bytes free
\n\n
"
,
's'
,
'%'
,
'2'
,
'5'
,
's'
,
' '
,
'b'
,
'y'
,
't'
,
'e'
,
's'
,
'\n'
,
'\0'
};
dir_total
,
WCMD_filesize64
(
freebytes
.
QuadPart
));
static
const
WCHAR
fmt2
[]
=
{
'%'
,
'8'
,
'd'
,
' '
,
'd'
,
'i'
,
'r'
,
'e'
,
'c'
,
't'
,
'o'
,
'r'
,
'i'
,
'e'
,
's'
,
' '
,
'%'
,
'1'
,
'8'
,
's'
,
' '
,
'b'
,
'y'
,
't'
,
'e'
,
's'
,
' '
,
'f'
,
'r'
,
'e'
,
'e'
,
'\n'
,
'\n'
,
'\0'
};
WCMD_output
(
fmt1
,
file_total
,
WCMD_filesize64
(
byte_total
));
WCMD_output
(
fmt2
,
dir_total
,
WCMD_filesize64
(
freebytes
.
QuadPart
));
}
else
{
}
else
{
WCMD_output
(
" %18s bytes free
\n\n
"
,
WCMD_filesize64
(
freebytes
.
QuadPart
));
static
const
WCHAR
fmt
[]
=
{
' '
,
'%'
,
'1'
,
'8'
,
's'
,
' '
,
'b'
,
'y'
,
't'
,
'e'
,
's'
,
' '
,
'f'
,
'r'
,
'e'
,
'e'
,
'\n'
,
'\n'
,
'\0'
};
WCMD_output
(
fmt
,
WCMD_filesize64
(
freebytes
.
QuadPart
));
}
}
}
}
}
}
programs/cmd/wcmd.h
View file @
b8aa5fc5
...
@@ -28,71 +28,74 @@
...
@@ -28,71 +28,74 @@
#include <ctype.h>
#include <ctype.h>
#include <wine/unicode.h>
#include <wine/unicode.h>
void
WCMD_assoc
(
char
*
,
BOOL
);
void
WCMD_assoc
(
WCHAR
*
,
BOOL
);
void
WCMD_batch
(
char
*
,
char
*
,
int
,
char
*
,
HANDLE
);
void
WCMD_batch
(
WCHAR
*
,
WCHAR
*
,
int
,
WCHAR
*
,
HANDLE
);
void
WCMD_call
(
char
*
command
);
void
WCMD_call
(
WCHAR
*
command
);
void
WCMD_change_tty
(
void
);
void
WCMD_change_tty
(
void
);
void
WCMD_clear_screen
(
void
);
void
WCMD_clear_screen
(
void
);
void
WCMD_color
(
void
);
void
WCMD_color
(
void
);
void
WCMD_copy
(
void
);
void
WCMD_copy
(
void
);
void
WCMD_create_dir
(
void
);
void
WCMD_create_dir
(
void
);
BOOL
WCMD_delete
(
char
*
,
BOOL
);
BOOL
WCMD_delete
(
WCHAR
*
,
BOOL
);
void
WCMD_directory
(
char
*
);
void
WCMD_directory
(
WCHAR
*
);
void
WCMD_echo
(
const
char
*
);
void
WCMD_echo
(
const
WCHAR
*
);
void
WCMD_endlocal
(
void
);
void
WCMD_endlocal
(
void
);
void
WCMD_enter_paged_mode
(
const
char
*
);
void
WCMD_enter_paged_mode
(
const
WCHAR
*
);
void
WCMD_exit
(
void
);
void
WCMD_exit
(
void
);
void
WCMD_for
(
char
*
);
void
WCMD_for
(
WCHAR
*
);
void
WCMD_give_help
(
char
*
command
);
void
WCMD_give_help
(
WCHAR
*
command
);
void
WCMD_goto
(
void
);
void
WCMD_goto
(
void
);
void
WCMD_if
(
char
*
);
void
WCMD_if
(
WCHAR
*
);
void
WCMD_leave_paged_mode
(
void
);
void
WCMD_leave_paged_mode
(
void
);
void
WCMD_more
(
char
*
);
void
WCMD_more
(
WCHAR
*
);
void
WCMD_move
(
void
);
void
WCMD_move
(
void
);
void
WCMD_output
(
const
char
*
format
,
...);
void
WCMD_output
(
const
WCHAR
*
format
,
...);
void
WCMD_output_asis
(
const
char
*
message
);
void
WCMD_output_asis
(
const
WCHAR
*
message
);
void
WCMD_parse
(
char
*
s
,
char
*
q
,
char
*
p1
,
char
*
p2
);
void
WCMD_parse
(
WCHAR
*
s
,
WCHAR
*
q
,
WCHAR
*
p1
,
WCHAR
*
p2
);
void
WCMD_pause
(
void
);
void
WCMD_pause
(
void
);
void
WCMD_pipe
(
char
*
command
);
void
WCMD_pipe
(
WCHAR
*
command
);
void
WCMD_popd
(
void
);
void
WCMD_popd
(
void
);
void
WCMD_print_error
(
void
);
void
WCMD_print_error
(
void
);
void
WCMD_process_command
(
char
*
command
);
void
WCMD_process_command
(
WCHAR
*
command
);
void
WCMD_pushd
(
char
*
);
void
WCMD_pushd
(
WCHAR
*
);
int
WCMD_read_console
(
char
*
string
,
int
str_len
);
int
WCMD_read_console
(
WCHAR
*
string
,
int
str_len
);
void
WCMD_remove_dir
(
char
*
command
);
void
WCMD_remove_dir
(
WCHAR
*
command
);
void
WCMD_rename
(
void
);
void
WCMD_rename
(
void
);
void
WCMD_run_program
(
char
*
command
,
int
called
);
void
WCMD_run_program
(
WCHAR
*
command
,
int
called
);
void
WCMD_setlocal
(
const
char
*
command
);
void
WCMD_setlocal
(
const
WCHAR
*
command
);
void
WCMD_setshow_attrib
(
void
);
void
WCMD_setshow_attrib
(
void
);
void
WCMD_setshow_date
(
void
);
void
WCMD_setshow_date
(
void
);
void
WCMD_setshow_default
(
char
*
command
);
void
WCMD_setshow_default
(
WCHAR
*
command
);
void
WCMD_setshow_env
(
char
*
command
);
void
WCMD_setshow_env
(
WCHAR
*
command
);
void
WCMD_setshow_path
(
char
*
command
);
void
WCMD_setshow_path
(
WCHAR
*
command
);
void
WCMD_setshow_prompt
(
void
);
void
WCMD_setshow_prompt
(
void
);
void
WCMD_setshow_time
(
void
);
void
WCMD_setshow_time
(
void
);
void
WCMD_shift
(
char
*
command
);
void
WCMD_shift
(
WCHAR
*
command
);
void
WCMD_show_prompt
(
void
);
void
WCMD_show_prompt
(
void
);
void
WCMD_title
(
char
*
);
void
WCMD_title
(
WCHAR
*
);
void
WCMD_type
(
char
*
);
void
WCMD_type
(
WCHAR
*
);
void
WCMD_verify
(
char
*
command
);
void
WCMD_verify
(
WCHAR
*
command
);
void
WCMD_version
(
void
);
void
WCMD_version
(
void
);
int
WCMD_volume
(
int
mode
,
char
*
command
);
int
WCMD_volume
(
int
mode
,
WCHAR
*
command
);
char
*
WCMD_fgets
(
char
*
s
,
int
n
,
HANDLE
stream
);
WCHAR
*
WCMD_fgets
(
WCHAR
*
s
,
int
n
,
HANDLE
stream
);
char
*
WCMD_parameter
(
char
*
s
,
int
n
,
char
**
where
);
WCHAR
*
WCMD_parameter
(
WCHAR
*
s
,
int
n
,
WCHAR
**
where
);
char
*
WCMD_strtrim_leading_spaces
(
char
*
string
);
WCHAR
*
WCMD_strtrim_leading_spaces
(
WCHAR
*
string
);
void
WCMD_strtrim_trailing_spaces
(
char
*
string
);
void
WCMD_strtrim_trailing_spaces
(
WCHAR
*
string
);
void
WCMD_opt_s_strip_quotes
(
char
*
cmd
);
void
WCMD_opt_s_strip_quotes
(
WCHAR
*
cmd
);
void
WCMD_HandleTildaModifiers
(
char
**
start
,
char
*
forVariable
);
void
WCMD_HandleTildaModifiers
(
WCHAR
**
start
,
WCHAR
*
forVariable
);
BOOL
WCMD_ask_confirm
(
char
*
message
,
BOOL
showSureText
,
BOOL
*
optionAll
);
BOOL
WCMD_ask_confirm
(
WCHAR
*
message
,
BOOL
showSureText
,
BOOL
*
optionAll
);
void
WCMD_splitpath
(
const
CHAR
*
path
,
CHAR
*
drv
,
CHAR
*
dir
,
CHAR
*
name
,
CHAR
*
ext
);
void
WCMD_splitpath
(
const
WCHAR
*
path
,
WCHAR
*
drv
,
WCHAR
*
dir
,
WCHAR
*
name
,
WCHAR
*
ext
);
char
*
WCMD_LoadMessage
(
UINT
id
);
WCHAR
*
WCMD_LoadMessage
(
UINT
id
);
WCHAR
*
WCMD_strdupW
(
WCHAR
*
input
);
BOOL
WCMD_ReadFile
(
const
HANDLE
hIn
,
WCHAR
*
intoBuf
,
const
DWORD
maxChars
,
LPDWORD
charsRead
,
const
LPOVERLAPPED
unused
);
/* Data structure to hold context when executing batch files */
/* Data structure to hold context when executing batch files */
typedef
struct
{
typedef
struct
{
char
*
command
;
/* The command which invoked the batch file */
WCHAR
*
command
;
/* The command which invoked the batch file */
HANDLE
h
;
/* Handle to the open batch file */
HANDLE
h
;
/* Handle to the open batch file */
int
shift_count
[
10
];
/* Offset in terms of shifts for %0 - %9 */
int
shift_count
[
10
];
/* Offset in terms of shifts for %0 - %9 */
void
*
prev_context
;
/* Pointer to the previous context block */
void
*
prev_context
;
/* Pointer to the previous context block */
...
@@ -106,7 +109,7 @@ struct env_stack
...
@@ -106,7 +109,7 @@ struct env_stack
struct
env_stack
*
next
;
struct
env_stack
*
next
;
union
{
union
{
int
stackdepth
;
/* Only used for pushd and popd */
int
stackdepth
;
/* Only used for pushd and popd */
char
cwd
;
/* Only used for set/endlocal */
WCHAR
cwd
;
/* Only used for set/endlocal */
}
u
;
}
u
;
WCHAR
*
strings
;
WCHAR
*
strings
;
};
};
...
@@ -116,8 +119,8 @@ struct env_stack
...
@@ -116,8 +119,8 @@ struct env_stack
typedef
struct
_DIRECTORY_STACK
typedef
struct
_DIRECTORY_STACK
{
{
struct
_DIRECTORY_STACK
*
next
;
struct
_DIRECTORY_STACK
*
next
;
char
*
dirName
;
WCHAR
*
dirName
;
char
*
fileName
;
WCHAR
*
fileName
;
}
DIRECTORY_STACK
;
}
DIRECTORY_STACK
;
#endif
/* !RC_INVOKED */
#endif
/* !RC_INVOKED */
...
@@ -181,9 +184,9 @@ typedef struct _DIRECTORY_STACK
...
@@ -181,9 +184,9 @@ typedef struct _DIRECTORY_STACK
#define WCMD_EXIT 44
#define WCMD_EXIT 44
/* Some standard messages */
/* Some standard messages */
extern
const
char
newline
[];
extern
const
WCHAR
newline
[];
extern
const
char
version_string
[];
extern
WCHAR
anykey
[];
extern
const
char
anykey
[];
extern
WCHAR
version_string
[];
/* Translated messages */
/* Translated messages */
#define WCMD_CONFIRM 1001
#define WCMD_CONFIRM 1001
...
@@ -215,6 +218,11 @@ extern const char anykey[];
...
@@ -215,6 +218,11 @@ extern const char anykey[];
#define WCMD_ARGERR 1027
#define WCMD_ARGERR 1027
#define WCMD_VOLUMEDETAIL 1028
#define WCMD_VOLUMEDETAIL 1028
#define WCMD_VOLUMEPROMPT 1029
#define WCMD_VOLUMEPROMPT 1029
#define WCMD_NOPATH 1030
#define WCMD_ANYKEY 1031
#define WCMD_CONSTITLE 1032
#define WCMD_VERSION 1033
/* msdn specified max for Win XP */
/* msdn specified max for Win XP */
#define MAXSTRING 8192
#define MAXSTRING 8192
programs/cmd/wcmdmain.c
View file @
b8aa5fc5
...
@@ -30,27 +30,70 @@
...
@@ -30,27 +30,70 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
cmd
);
WINE_DEFAULT_DEBUG_CHANNEL
(
cmd
);
const
char
*
const
inbuilt
[]
=
{
"ATTRIB"
,
"CALL"
,
"CD"
,
"CHDIR"
,
"CLS"
,
"COPY"
,
"CTTY"
,
const
WCHAR
inbuilt
[][
10
]
=
{
"DATE"
,
"DEL"
,
"DIR"
,
"ECHO"
,
"ERASE"
,
"FOR"
,
"GOTO"
,
{
'A'
,
'T'
,
'T'
,
'R'
,
'I'
,
'B'
,
'\0'
},
"HELP"
,
"IF"
,
"LABEL"
,
"MD"
,
"MKDIR"
,
"MOVE"
,
"PATH"
,
"PAUSE"
,
{
'C'
,
'A'
,
'L'
,
'L'
,
'\0'
},
"PROMPT"
,
"REM"
,
"REN"
,
"RENAME"
,
"RD"
,
"RMDIR"
,
"SET"
,
"SHIFT"
,
{
'C'
,
'D'
,
'\0'
},
"TIME"
,
"TITLE"
,
"TYPE"
,
"VERIFY"
,
"VER"
,
"VOL"
,
{
'C'
,
'H'
,
'D'
,
'I'
,
'R'
,
'\0'
},
"ENDLOCAL"
,
"SETLOCAL"
,
"PUSHD"
,
"POPD"
,
"ASSOC"
,
"COLOR"
,
"FTYPE"
,
{
'C'
,
'L'
,
'S'
,
'\0'
},
"MORE"
,
"EXIT"
};
{
'C'
,
'O'
,
'P'
,
'Y'
,
'\0'
},
{
'C'
,
'T'
,
'T'
,
'Y'
,
'\0'
},
{
'D'
,
'A'
,
'T'
,
'E'
,
'\0'
},
{
'D'
,
'E'
,
'L'
,
'\0'
},
{
'D'
,
'I'
,
'R'
,
'\0'
},
{
'E'
,
'C'
,
'H'
,
'O'
,
'\0'
},
{
'E'
,
'R'
,
'A'
,
'S'
,
'E'
,
'\0'
},
{
'F'
,
'O'
,
'R'
,
'\0'
},
{
'G'
,
'O'
,
'T'
,
'O'
,
'\0'
},
{
'H'
,
'E'
,
'L'
,
'P'
,
'\0'
},
{
'I'
,
'F'
,
'\0'
},
{
'L'
,
'A'
,
'B'
,
'E'
,
'L'
,
'\0'
},
{
'M'
,
'D'
,
'\0'
},
{
'M'
,
'K'
,
'D'
,
'I'
,
'R'
,
'\0'
},
{
'M'
,
'O'
,
'V'
,
'E'
,
'\0'
},
{
'P'
,
'A'
,
'T'
,
'H'
,
'\0'
},
{
'P'
,
'A'
,
'U'
,
'S'
,
'E'
,
'\0'
},
{
'P'
,
'R'
,
'O'
,
'M'
,
'P'
,
'T'
,
'\0'
},
{
'R'
,
'E'
,
'M'
,
'\0'
},
{
'R'
,
'E'
,
'N'
,
'\0'
},
{
'R'
,
'E'
,
'N'
,
'A'
,
'M'
,
'E'
,
'\0'
},
{
'R'
,
'D'
,
'\0'
},
{
'R'
,
'M'
,
'D'
,
'I'
,
'R'
,
'\0'
},
{
'S'
,
'E'
,
'T'
,
'\0'
},
{
'S'
,
'H'
,
'I'
,
'F'
,
'T'
,
'\0'
},
{
'T'
,
'I'
,
'M'
,
'E'
,
'\0'
},
{
'T'
,
'I'
,
'T'
,
'L'
,
'E'
,
'\0'
},
{
'T'
,
'Y'
,
'P'
,
'E'
,
'\0'
},
{
'V'
,
'E'
,
'R'
,
'I'
,
'F'
,
'Y'
,
'\0'
},
{
'V'
,
'E'
,
'R'
,
'\0'
},
{
'V'
,
'O'
,
'L'
,
'\0'
},
{
'E'
,
'N'
,
'D'
,
'L'
,
'O'
,
'C'
,
'A'
,
'L'
,
'\0'
},
{
'S'
,
'E'
,
'T'
,
'L'
,
'O'
,
'C'
,
'A'
,
'L'
,
'\0'
},
{
'P'
,
'U'
,
'S'
,
'H'
,
'D'
,
'\0'
},
{
'P'
,
'O'
,
'P'
,
'D'
,
'\0'
},
{
'A'
,
'S'
,
'S'
,
'O'
,
'C'
,
'\0'
},
{
'C'
,
'O'
,
'L'
,
'O'
,
'R'
,
'\0'
},
{
'F'
,
'T'
,
'Y'
,
'P'
,
'E'
,
'\0'
},
{
'M'
,
'O'
,
'R'
,
'E'
,
'\0'
},
{
'E'
,
'X'
,
'I'
,
'T'
,
'\0'
}
};
HINSTANCE
hinst
;
HINSTANCE
hinst
;
DWORD
errorlevel
;
DWORD
errorlevel
;
int
echo_mode
=
1
,
verify_mode
=
0
,
defaultColor
=
7
;
int
echo_mode
=
1
,
verify_mode
=
0
,
defaultColor
=
7
;
static
int
opt_c
,
opt_k
,
opt_s
;
static
int
opt_c
,
opt_k
,
opt_s
;
const
char
newline
[]
=
"
\n
"
;
const
WCHAR
newline
[]
=
{
'\n'
,
'\0'
};
const
char
version_string
[]
=
"CMD Version "
PACKAGE_VERSION
"
\n\n
"
;
static
const
WCHAR
equalsW
[]
=
{
'='
,
'\0'
};
const
char
anykey
[]
=
"Press Return key to continue: "
;
WCHAR
anykey
[
100
];
char
quals
[
MAX_PATH
],
param1
[
MAX_PATH
],
param2
[
MAX_PATH
];
WCHAR
version_string
[
100
];
WCHAR
quals
[
MAX_PATH
],
param1
[
MAX_PATH
],
param2
[
MAX_PATH
];
BATCH_CONTEXT
*
context
=
NULL
;
BATCH_CONTEXT
*
context
=
NULL
;
extern
struct
env_stack
*
pushd_directories
;
extern
struct
env_stack
*
pushd_directories
;
static
const
char
*
pagedMessage
=
NULL
;
static
const
WCHAR
*
pagedMessage
=
NULL
;
static
char
*
output_bufA
=
NULL
;
#define MAX_WRITECONSOLE_SIZE 65535
static
char
*
WCMD_expand_envvar
(
char
*
start
);
static
WCHAR
*
WCMD_expand_envvar
(
WCHAR
*
start
);
/*****************************************************************************
/*****************************************************************************
* Main entry point. This is a console application so we have a main() not a
* Main entry point. This is a console application so we have a main() not a
...
@@ -61,14 +104,22 @@ int main (int argc, char *argv[])
...
@@ -61,14 +104,22 @@ int main (int argc, char *argv[])
{
{
LPWSTR
*
argvW
=
NULL
;
LPWSTR
*
argvW
=
NULL
;
int
args
;
int
args
;
WCHAR
*
cmdW
=
NULL
;
WCHAR
*
cmd
=
NULL
;
char
string
[
1024
];
WCHAR
string
[
1024
];
char
envvar
[
4
];
WCHAR
envvar
[
4
];
char
*
cmd
=
NULL
;
DWORD
count
;
DWORD
count
;
HANDLE
h
;
HANDLE
h
;
int
opt_q
;
int
opt_q
;
int
opt_t
=
0
;
int
opt_t
=
0
;
static
const
WCHAR
autoexec
[]
=
{
'\\'
,
'a'
,
'u'
,
't'
,
'o'
,
'e'
,
'x'
,
'e'
,
'c'
,
'.'
,
'b'
,
'a'
,
't'
,
'\0'
};
char
ansiVersion
[
100
];
/* Pre initialize some messages */
strcpy
(
ansiVersion
,
PACKAGE_VERSION
);
MultiByteToWideChar
(
CP_ACP
,
0
,
ansiVersion
,
-
1
,
string
,
1024
);
wsprintf
(
version_string
,
WCMD_LoadMessage
(
WCMD_VERSION
),
string
);
strcpyW
(
anykey
,
WCMD_LoadMessage
(
WCMD_ANYKEY
));
/* Get a Unicode command line */
/* Get a Unicode command line */
argvW
=
CommandLineToArgvW
(
GetCommandLineW
(),
&
argc
);
argvW
=
CommandLineToArgvW
(
GetCommandLineW
(),
&
argc
);
...
@@ -114,7 +165,8 @@ int main (int argc, char *argv[])
...
@@ -114,7 +165,8 @@ int main (int argc, char *argv[])
}
}
if
(
opt_q
)
{
if
(
opt_q
)
{
WCMD_echo
(
"OFF"
);
const
WCHAR
eoff
[]
=
{
'O'
,
'F'
,
'F'
,
'\0'
};
WCMD_echo
(
eoff
);
}
}
if
(
opt_c
||
opt_k
)
{
if
(
opt_c
||
opt_k
)
{
...
@@ -185,11 +237,11 @@ int main (int argc, char *argv[])
...
@@ -185,11 +237,11 @@ int main (int argc, char *argv[])
}
}
}
}
cmd
W
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
));
cmd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
));
if
(
!
cmd
W
)
if
(
!
cmd
)
exit
(
1
);
exit
(
1
);
p
=
cmd
W
;
p
=
cmd
;
argsLeft
=
args
;
argsLeft
=
args
;
for
(
arg
=
argvW
;
argsLeft
>
0
;
arg
++
,
argsLeft
--
)
for
(
arg
=
argvW
;
argsLeft
>
0
;
arg
++
,
argsLeft
--
)
{
{
...
@@ -249,19 +301,11 @@ int main (int argc, char *argv[])
...
@@ -249,19 +301,11 @@ int main (int argc, char *argv[])
*
p
++=
'"'
;
*
p
++=
'"'
;
*
p
++=
' '
;
*
p
++=
' '
;
}
}
if
(
p
>
cmd
W
)
if
(
p
>
cmd
)
p
--
;
/* remove last space */
p
--
;
/* remove last space */
*
p
=
'\0'
;
*
p
=
'\0'
;
/* FIXME: Convert back to ansi until more is in unicode */
WINE_TRACE
(
"/c command line: '%s'
\n
"
,
wine_dbgstr_w
(
cmd
));
cmd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
if
(
!
cmd
)
{
exit
(
1
);
}
else
{
WideCharToMultiByte
(
CP_ACP
,
0
,
cmdW
,
len
,
cmd
,
len
,
NULL
,
NULL
);
}
WINE_TRACE
(
"Input (U): '%s'
\n
"
,
wine_dbgstr_w
(
cmdW
));
WINE_TRACE
(
"Input (A): '%s'
\n
"
,
cmd
);
/* strip first and last quote characters if opt_s; check for invalid
/* strip first and last quote characters if opt_s; check for invalid
* executable is done later */
* executable is done later */
...
@@ -275,18 +319,17 @@ int main (int argc, char *argv[])
...
@@ -275,18 +319,17 @@ int main (int argc, char *argv[])
* the currently allocated input and output handles. This allows
* the currently allocated input and output handles. This allows
* us to pipe to and read from the command interpreter.
* us to pipe to and read from the command interpreter.
*/
*/
if
(
strchr
(
cmd
,
'|'
)
!=
NULL
)
if
(
strchr
W
(
cmd
,
'|'
)
!=
NULL
)
WCMD_pipe
(
cmd
);
WCMD_pipe
(
cmd
);
else
else
WCMD_process_command
(
cmd
);
WCMD_process_command
(
cmd
);
HeapFree
(
GetProcessHeap
(),
0
,
cmd
);
HeapFree
(
GetProcessHeap
(),
0
,
cmd
);
HeapFree
(
GetProcessHeap
(),
0
,
cmdW
);
return
errorlevel
;
return
errorlevel
;
}
}
SetConsoleMode
(
GetStdHandle
(
STD_INPUT_HANDLE
),
ENABLE_LINE_INPUT
|
SetConsoleMode
(
GetStdHandle
(
STD_INPUT_HANDLE
),
ENABLE_LINE_INPUT
|
ENABLE_ECHO_INPUT
|
ENABLE_PROCESSED_INPUT
);
ENABLE_ECHO_INPUT
|
ENABLE_PROCESSED_INPUT
);
SetConsoleTitle
(
"Wine Command Prompt"
);
SetConsoleTitle
(
WCMD_LoadMessage
(
WCMD_CONSTITLE
)
);
/* Note: cmd.exe /c dir does not get a new color, /k dir does */
/* Note: cmd.exe /c dir does not get a new color, /k dir does */
if
(
opt_t
)
{
if
(
opt_t
)
{
...
@@ -304,44 +347,47 @@ int main (int argc, char *argv[])
...
@@ -304,44 +347,47 @@ int main (int argc, char *argv[])
HKEY
key
;
HKEY
key
;
DWORD
type
;
DWORD
type
;
DWORD
value
=
0
,
size
=
4
;
DWORD
value
=
0
,
size
=
4
;
static
const
WCHAR
regKeyW
[]
=
{
'S'
,
'o'
,
'f'
,
't'
,
'w'
,
'a'
,
'r'
,
'e'
,
'\\'
,
'M'
,
'i'
,
'c'
,
'r'
,
'o'
,
's'
,
'o'
,
'f'
,
't'
,
'\\'
,
'C'
,
'o'
,
'm'
,
'm'
,
'a'
,
'n'
,
'd'
,
' '
,
'P'
,
'r'
,
'o'
,
'c'
,
'e'
,
's'
,
's'
,
'o'
,
'r'
,
'\0'
};
static
const
WCHAR
dfltColorW
[]
=
{
'D'
,
'e'
,
'f'
,
'a'
,
'u'
,
'l'
,
't'
,
'C'
,
'o'
,
'l'
,
'o'
,
'r'
,
'\0'
};
if
(
RegOpenKeyEx
(
HKEY_CURRENT_USER
,
"Software
\\
Microsoft
\\
Command Processor"
,
if
(
RegOpenKeyEx
(
HKEY_CURRENT_USER
,
regKeyW
,
0
,
KEY_READ
,
&
key
)
==
ERROR_SUCCESS
)
{
0
,
KEY_READ
,
&
key
)
==
ERROR_SUCCESS
)
{
char
strvalue
[
4
];
WCHAR
strvalue
[
4
];
/* See if DWORD or REG_SZ */
/* See if DWORD or REG_SZ */
if
(
RegQueryValueEx
(
key
,
"DefaultColor"
,
NULL
,
&
type
,
if
(
RegQueryValueEx
(
key
,
dfltColorW
,
NULL
,
&
type
,
NULL
,
NULL
)
==
ERROR_SUCCESS
)
{
NULL
,
NULL
)
==
ERROR_SUCCESS
)
{
if
(
type
==
REG_DWORD
)
{
if
(
type
==
REG_DWORD
)
{
size
=
sizeof
(
DWORD
);
size
=
sizeof
(
DWORD
);
RegQueryValueEx
(
key
,
"DefaultColor"
,
NULL
,
NULL
,
RegQueryValueEx
(
key
,
dfltColorW
,
NULL
,
NULL
,
(
LPBYTE
)
&
value
,
&
size
);
(
LPBYTE
)
&
value
,
&
size
);
}
else
if
(
type
==
REG_SZ
)
{
}
else
if
(
type
==
REG_SZ
)
{
size
=
sizeof
(
strvalue
);
size
=
sizeof
(
strvalue
)
/
sizeof
(
WCHAR
)
;
RegQueryValueEx
(
key
,
"DefaultColor"
,
NULL
,
NULL
,
RegQueryValueEx
(
key
,
dfltColorW
,
NULL
,
NULL
,
(
LPBYTE
)
strvalue
,
&
size
);
(
LPBYTE
)
strvalue
,
&
size
);
value
=
strtoul
(
strvalue
,
NULL
,
10
);
value
=
strtoul
W
(
strvalue
,
NULL
,
10
);
}
}
}
}
}
}
if
(
value
==
0
&&
RegOpenKeyEx
(
HKEY_LOCAL_MACHINE
,
if
(
value
==
0
&&
RegOpenKeyEx
(
HKEY_LOCAL_MACHINE
,
regKeyW
,
"Software
\\
Microsoft
\\
Command Processor"
,
0
,
KEY_READ
,
&
key
)
==
ERROR_SUCCESS
)
{
0
,
KEY_READ
,
&
key
)
==
ERROR_SUCCESS
)
{
char
strvalue
[
4
];
WCHAR
strvalue
[
4
];
/* See if DWORD or REG_SZ */
/* See if DWORD or REG_SZ */
if
(
RegQueryValueEx
(
key
,
"DefaultColor"
,
NULL
,
&
type
,
if
(
RegQueryValueEx
(
key
,
dfltColorW
,
NULL
,
&
type
,
NULL
,
NULL
)
==
ERROR_SUCCESS
)
{
NULL
,
NULL
)
==
ERROR_SUCCESS
)
{
if
(
type
==
REG_DWORD
)
{
if
(
type
==
REG_DWORD
)
{
size
=
sizeof
(
DWORD
);
size
=
sizeof
(
DWORD
);
RegQueryValueEx
(
key
,
"DefaultColor"
,
NULL
,
NULL
,
RegQueryValueEx
(
key
,
dfltColorW
,
NULL
,
NULL
,
(
LPBYTE
)
&
value
,
&
size
);
(
LPBYTE
)
&
value
,
&
size
);
}
else
if
(
type
==
REG_SZ
)
{
}
else
if
(
type
==
REG_SZ
)
{
size
=
sizeof
(
strvalue
);
size
=
sizeof
(
strvalue
)
/
sizeof
(
WCHAR
)
;
RegQueryValueEx
(
key
,
"DefaultColor"
,
NULL
,
NULL
,
RegQueryValueEx
(
key
,
dfltColorW
,
NULL
,
NULL
,
(
LPBYTE
)
strvalue
,
&
size
);
(
LPBYTE
)
strvalue
,
&
size
);
value
=
strtoul
(
strvalue
,
NULL
,
10
);
value
=
strtoul
W
(
strvalue
,
NULL
,
10
);
}
}
}
}
}
}
...
@@ -358,26 +404,26 @@ int main (int argc, char *argv[])
...
@@ -358,26 +404,26 @@ int main (int argc, char *argv[])
/* Save cwd into appropriate env var */
/* Save cwd into appropriate env var */
GetCurrentDirectory
(
1024
,
string
);
GetCurrentDirectory
(
1024
,
string
);
if
(
IsCharAlpha
(
string
[
0
])
&&
string
[
1
]
==
':'
)
{
if
(
IsCharAlpha
(
string
[
0
])
&&
string
[
1
]
==
':'
)
{
sprintf
(
envvar
,
"=%c:"
,
string
[
0
]);
static
const
WCHAR
fmt
[]
=
{
'='
,
'%'
,
'c'
,
':'
,
'\0'
};
wsprintf
(
envvar
,
fmt
,
string
[
0
]);
SetEnvironmentVariable
(
envvar
,
string
);
SetEnvironmentVariable
(
envvar
,
string
);
}
}
if
(
opt_k
)
{
if
(
opt_k
)
{
WCMD_process_command
(
cmd
);
WCMD_process_command
(
cmd
);
HeapFree
(
GetProcessHeap
(),
0
,
cmd
);
HeapFree
(
GetProcessHeap
(),
0
,
cmd
);
HeapFree
(
GetProcessHeap
(),
0
,
cmdW
);
}
}
/*
/*
* If there is an AUTOEXEC.BAT file, try to execute it.
* If there is an AUTOEXEC.BAT file, try to execute it.
*/
*/
GetFullPathName
(
"
\\
autoexec.bat"
,
sizeof
(
string
),
string
,
NULL
);
GetFullPathName
(
autoexec
,
sizeof
(
string
)
/
sizeof
(
WCHAR
),
string
,
NULL
);
h
=
CreateFile
(
string
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
h
=
CreateFile
(
string
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
h
!=
INVALID_HANDLE_VALUE
)
{
if
(
h
!=
INVALID_HANDLE_VALUE
)
{
CloseHandle
(
h
);
CloseHandle
(
h
);
#if 0
#if 0
WCMD_batch (
(char *)"\\autoexec.bat", (char *)"\\autoexec.bat"
, 0, NULL, INVALID_HANDLE_VALUE);
WCMD_batch (
autoexec, autoexec
, 0, NULL, INVALID_HANDLE_VALUE);
#endif
#endif
}
}
...
@@ -388,12 +434,13 @@ int main (int argc, char *argv[])
...
@@ -388,12 +434,13 @@ int main (int argc, char *argv[])
WCMD_version
();
WCMD_version
();
while
(
TRUE
)
{
while
(
TRUE
)
{
WCMD_show_prompt
();
WCMD_show_prompt
();
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
),
&
count
,
NULL
);
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
if
(
count
>
1
)
{
if
(
count
>
1
)
{
string
[
count
-
1
]
=
'\0'
;
/* ReadFile output is not null-terminated! */
string
[
count
-
1
]
=
'\0'
;
/* ReadFile output is not null-terminated! */
if
(
string
[
count
-
2
]
==
'\r'
)
string
[
count
-
2
]
=
'\0'
;
/* Under Windoze we get CRLF! */
if
(
string
[
count
-
2
]
==
'\r'
)
string
[
count
-
2
]
=
'\0'
;
/* Under Windoze we get CRLF! */
if
(
lstrlen
(
string
)
!=
0
)
{
if
(
strlenW
(
string
)
!=
0
)
{
if
(
strchr
(
string
,
'|'
)
!=
NULL
)
{
if
(
strchr
W
(
string
,
'|'
)
!=
NULL
)
{
WCMD_pipe
(
string
);
WCMD_pipe
(
string
);
}
}
else
{
else
{
...
@@ -411,16 +458,16 @@ int main (int argc, char *argv[])
...
@@ -411,16 +458,16 @@ int main (int argc, char *argv[])
*/
*/
void
WCMD_process_command
(
char
*
command
)
void
WCMD_process_command
(
WCHAR
*
command
)
{
{
char
*
cmd
,
*
p
,
*
s
,
*
t
,
*
redir
;
WCHAR
*
cmd
,
*
p
,
*
s
,
*
t
,
*
redir
;
int
status
,
i
;
int
status
,
i
;
DWORD
count
,
creationDisposition
;
DWORD
count
,
creationDisposition
;
HANDLE
h
;
HANDLE
h
;
char
*
whichcmd
;
WCHAR
*
whichcmd
;
SECURITY_ATTRIBUTES
sa
;
SECURITY_ATTRIBUTES
sa
;
char
*
new_cmd
;
WCHAR
*
new_cmd
;
char
*
first_redir
=
NULL
;
WCHAR
*
first_redir
=
NULL
;
HANDLE
old_stdhandles
[
3
]
=
{
INVALID_HANDLE_VALUE
,
HANDLE
old_stdhandles
[
3
]
=
{
INVALID_HANDLE_VALUE
,
INVALID_HANDLE_VALUE
,
INVALID_HANDLE_VALUE
,
INVALID_HANDLE_VALUE
};
INVALID_HANDLE_VALUE
};
...
@@ -429,8 +476,8 @@ void WCMD_process_command (char *command)
...
@@ -429,8 +476,8 @@ void WCMD_process_command (char *command)
STD_ERROR_HANDLE
};
STD_ERROR_HANDLE
};
/* Move copy of the command onto the heap so it can be expanded */
/* Move copy of the command onto the heap so it can be expanded */
new_cmd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
MAXSTRING
);
new_cmd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
MAXSTRING
*
sizeof
(
WCHAR
)
);
strcpy
(
new_cmd
,
command
);
strcpy
W
(
new_cmd
,
command
);
/* For commands in a context (batch program): */
/* For commands in a context (batch program): */
/* Expand environment variables in a batch file %{0-9} first */
/* Expand environment variables in a batch file %{0-9} first */
...
@@ -442,7 +489,7 @@ void WCMD_process_command (char *command)
...
@@ -442,7 +489,7 @@ void WCMD_process_command (char *command)
/* manual expansion of environment variables here */
/* manual expansion of environment variables here */
p
=
new_cmd
;
p
=
new_cmd
;
while
((
p
=
strchr
(
p
,
'%'
)))
{
while
((
p
=
strchr
W
(
p
,
'%'
)))
{
i
=
*
(
p
+
1
)
-
'0'
;
i
=
*
(
p
+
1
)
-
'0'
;
/* Replace %~ modifications if in batch program */
/* Replace %~ modifications if in batch program */
...
@@ -452,20 +499,20 @@ void WCMD_process_command (char *command)
...
@@ -452,20 +499,20 @@ void WCMD_process_command (char *command)
/* Replace use of %0...%9 if in batch program*/
/* Replace use of %0...%9 if in batch program*/
}
else
if
(
context
&&
(
i
>=
0
)
&&
(
i
<=
9
))
{
}
else
if
(
context
&&
(
i
>=
0
)
&&
(
i
<=
9
))
{
s
=
strdup
(
p
+
2
);
s
=
WCMD_strdupW
(
p
+
2
);
t
=
WCMD_parameter
(
context
->
command
,
i
+
context
->
shift_count
[
i
],
NULL
);
t
=
WCMD_parameter
(
context
->
command
,
i
+
context
->
shift_count
[
i
],
NULL
);
strcpy
(
p
,
t
);
strcpy
W
(
p
,
t
);
strcat
(
p
,
s
);
strcat
W
(
p
,
s
);
free
(
s
);
free
(
s
);
/* Replace use of %* if in batch program*/
/* Replace use of %* if in batch program*/
}
else
if
(
context
&&
*
(
p
+
1
)
==
'*'
)
{
}
else
if
(
context
&&
*
(
p
+
1
)
==
'*'
)
{
char
*
startOfParms
=
NULL
;
WCHAR
*
startOfParms
=
NULL
;
s
=
strdup
(
p
+
2
);
s
=
WCMD_strdupW
(
p
+
2
);
t
=
WCMD_parameter
(
context
->
command
,
1
,
&
startOfParms
);
t
=
WCMD_parameter
(
context
->
command
,
1
,
&
startOfParms
);
if
(
startOfParms
!=
NULL
)
strcpy
(
p
,
startOfParms
);
if
(
startOfParms
!=
NULL
)
strcpy
W
(
p
,
startOfParms
);
else
*
p
=
0x00
;
else
*
p
=
0x00
;
strcat
(
p
,
s
);
strcat
W
(
p
,
s
);
free
(
s
);
free
(
s
);
}
else
{
}
else
{
...
@@ -478,13 +525,13 @@ void WCMD_process_command (char *command)
...
@@ -478,13 +525,13 @@ void WCMD_process_command (char *command)
/* so remove any remaining %var% */
/* so remove any remaining %var% */
if
(
context
)
{
if
(
context
)
{
p
=
cmd
;
p
=
cmd
;
while
((
p
=
strchr
(
p
,
'%'
)))
{
while
((
p
=
strchr
W
(
p
,
'%'
)))
{
s
=
strchr
(
p
+
1
,
'%'
);
s
=
strchr
W
(
p
+
1
,
'%'
);
if
(
!
s
)
{
if
(
!
s
)
{
*
p
=
0x00
;
*
p
=
0x00
;
}
else
{
}
else
{
t
=
strdup
(
s
+
1
);
t
=
WCMD_strdupW
(
s
+
1
);
strcpy
(
p
,
t
);
strcpy
W
(
p
,
t
);
free
(
t
);
free
(
t
);
}
}
}
}
...
@@ -501,17 +548,18 @@ void WCMD_process_command (char *command)
...
@@ -501,17 +548,18 @@ void WCMD_process_command (char *command)
* Changing default drive has to be handled as a special case.
* Changing default drive has to be handled as a special case.
*/
*/
if
((
cmd
[
1
]
==
':'
)
&&
IsCharAlpha
(
cmd
[
0
])
&&
(
strlen
(
cmd
)
==
2
))
{
if
((
cmd
[
1
]
==
':'
)
&&
IsCharAlpha
(
cmd
[
0
])
&&
(
strlen
W
(
cmd
)
==
2
))
{
char
envvar
[
5
];
WCHAR
envvar
[
5
];
char
dir
[
MAX_PATH
];
WCHAR
dir
[
MAX_PATH
];
/* According to MSDN CreateProcess docs, special env vars record
/* According to MSDN CreateProcess docs, special env vars record
the current directory on each drive, in the form =C:
the current directory on each drive, in the form =C:
so see if one specified, and if so go back to it */
so see if one specified, and if so go back to it */
strcpy
(
envvar
,
"="
);
strcpy
W
(
envvar
,
equalsW
);
strcat
(
envvar
,
cmd
);
strcat
W
(
envvar
,
cmd
);
if
(
GetEnvironmentVariable
(
envvar
,
dir
,
MAX_PATH
)
==
0
)
{
if
(
GetEnvironmentVariable
(
envvar
,
dir
,
MAX_PATH
)
==
0
)
{
sprintf
(
cmd
,
"%s
\\
"
,
cmd
);
static
const
WCHAR
fmt
[]
=
{
'%'
,
's'
,
'\\'
,
'\0'
};
wsprintf
(
cmd
,
fmt
,
cmd
);
}
}
status
=
SetCurrentDirectory
(
cmd
);
status
=
SetCurrentDirectory
(
cmd
);
if
(
!
status
)
WCMD_print_error
();
if
(
!
status
)
WCMD_print_error
();
...
@@ -527,7 +575,7 @@ void WCMD_process_command (char *command)
...
@@ -527,7 +575,7 @@ void WCMD_process_command (char *command)
* Redirect stdin, stdout and/or stderr if required.
* Redirect stdin, stdout and/or stderr if required.
*/
*/
if
((
p
=
strchr
(
cmd
,
'<'
))
!=
NULL
)
{
if
((
p
=
strchr
W
(
cmd
,
'<'
))
!=
NULL
)
{
if
(
first_redir
==
NULL
)
first_redir
=
p
;
if
(
first_redir
==
NULL
)
first_redir
=
p
;
h
=
CreateFile
(
WCMD_parameter
(
++
p
,
0
,
NULL
),
GENERIC_READ
,
FILE_SHARE_READ
,
&
sa
,
OPEN_EXISTING
,
h
=
CreateFile
(
WCMD_parameter
(
++
p
,
0
,
NULL
),
GENERIC_READ
,
FILE_SHARE_READ
,
&
sa
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
FILE_ATTRIBUTE_NORMAL
,
NULL
);
...
@@ -542,7 +590,7 @@ void WCMD_process_command (char *command)
...
@@ -542,7 +590,7 @@ void WCMD_process_command (char *command)
/* Scan the whole command looking for > and 2> */
/* Scan the whole command looking for > and 2> */
redir
=
cmd
;
redir
=
cmd
;
while
(
redir
!=
NULL
&&
((
p
=
strchr
(
redir
,
'>'
))
!=
NULL
))
{
while
(
redir
!=
NULL
&&
((
p
=
strchr
W
(
redir
,
'>'
))
!=
NULL
))
{
int
handle
=
0
;
int
handle
=
0
;
if
(
*
(
p
-
1
)
!=
'2'
)
{
if
(
*
(
p
-
1
)
!=
'2'
)
{
...
@@ -577,7 +625,7 @@ void WCMD_process_command (char *command)
...
@@ -577,7 +625,7 @@ void WCMD_process_command (char *command)
WINE_TRACE
(
"Redirect %d (%p) to %d (%p)
\n
"
,
handle
,
GetStdHandle
(
idx_stdhandles
[
idx
]),
idx
,
h
);
WINE_TRACE
(
"Redirect %d (%p) to %d (%p)
\n
"
,
handle
,
GetStdHandle
(
idx_stdhandles
[
idx
]),
idx
,
h
);
}
else
{
}
else
{
char
*
param
=
WCMD_parameter
(
p
,
0
,
NULL
);
WCHAR
*
param
=
WCMD_parameter
(
p
,
0
,
NULL
);
h
=
CreateFile
(
param
,
GENERIC_WRITE
,
0
,
&
sa
,
creationDisposition
,
h
=
CreateFile
(
param
,
GENERIC_WRITE
,
0
,
&
sa
,
creationDisposition
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
h
==
INVALID_HANDLE_VALUE
)
{
if
(
h
==
INVALID_HANDLE_VALUE
)
{
...
@@ -589,7 +637,7 @@ void WCMD_process_command (char *command)
...
@@ -589,7 +637,7 @@ void WCMD_process_command (char *command)
INVALID_SET_FILE_POINTER
)
{
INVALID_SET_FILE_POINTER
)
{
WCMD_print_error
();
WCMD_print_error
();
}
}
WINE_TRACE
(
"Redirect %d to '%s' (%p)
\n
"
,
handle
,
param
,
h
);
WINE_TRACE
(
"Redirect %d to '%s' (%p)
\n
"
,
handle
,
wine_dbgstr_w
(
param
)
,
h
);
}
}
old_stdhandles
[
handle
]
=
GetStdHandle
(
idx_stdhandles
[
handle
]);
old_stdhandles
[
handle
]
=
GetStdHandle
(
idx_stdhandles
[
handle
]);
...
@@ -603,7 +651,7 @@ void WCMD_process_command (char *command)
...
@@ -603,7 +651,7 @@ void WCMD_process_command (char *command)
* Strip leading whitespaces, and a '@' if supplied
* Strip leading whitespaces, and a '@' if supplied
*/
*/
whichcmd
=
WCMD_strtrim_leading_spaces
(
cmd
);
whichcmd
=
WCMD_strtrim_leading_spaces
(
cmd
);
WINE_TRACE
(
"Command: '%s'
\n
"
,
cmd
);
WINE_TRACE
(
"Command: '%s'
\n
"
,
wine_dbgstr_w
(
cmd
)
);
if
(
whichcmd
[
0
]
==
'@'
)
whichcmd
++
;
if
(
whichcmd
[
0
]
==
'@'
)
whichcmd
++
;
/*
/*
...
@@ -712,7 +760,7 @@ void WCMD_process_command (char *command)
...
@@ -712,7 +760,7 @@ void WCMD_process_command (char *command)
WCMD_setshow_time
();
WCMD_setshow_time
();
break
;
break
;
case
WCMD_TITLE
:
case
WCMD_TITLE
:
if
(
strlen
(
&
whichcmd
[
count
])
>
0
)
if
(
strlen
W
(
&
whichcmd
[
count
])
>
0
)
WCMD_title
(
&
whichcmd
[
count
+
1
]);
WCMD_title
(
&
whichcmd
[
count
+
1
]);
break
;
break
;
case
WCMD_TYPE
:
case
WCMD_TYPE
:
...
@@ -778,13 +826,13 @@ static void init_msvcrt_io_block(STARTUPINFO* st)
...
@@ -778,13 +826,13 @@ static void init_msvcrt_io_block(STARTUPINFO* st)
* to change those std handles (this depends on the way wcmd sets
* to change those std handles (this depends on the way wcmd sets
* it's new input & output handles)
* it's new input & output handles)
*/
*/
size_t
sz
=
max
(
sizeof
(
unsigned
)
+
(
sizeof
(
char
)
+
sizeof
(
HANDLE
))
*
3
,
st_p
.
cbReserved2
);
size_t
sz
=
max
(
sizeof
(
unsigned
)
+
(
sizeof
(
WCHAR
)
+
sizeof
(
HANDLE
))
*
3
,
st_p
.
cbReserved2
);
BYTE
*
ptr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
);
BYTE
*
ptr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
);
if
(
ptr
)
if
(
ptr
)
{
{
unsigned
num
=
*
(
unsigned
*
)
st_p
.
lpReserved2
;
unsigned
num
=
*
(
unsigned
*
)
st_p
.
lpReserved2
;
char
*
flags
=
(
char
*
)(
ptr
+
sizeof
(
unsigned
));
WCHAR
*
flags
=
(
WCHAR
*
)(
ptr
+
sizeof
(
unsigned
));
HANDLE
*
handles
=
(
HANDLE
*
)(
flags
+
num
*
sizeof
(
char
));
HANDLE
*
handles
=
(
HANDLE
*
)(
flags
+
num
*
sizeof
(
WCHAR
));
memcpy
(
ptr
,
st_p
.
lpReserved2
,
st_p
.
cbReserved2
);
memcpy
(
ptr
,
st_p
.
lpReserved2
,
st_p
.
cbReserved2
);
st
->
cbReserved2
=
sz
;
st
->
cbReserved2
=
sz
;
...
@@ -834,81 +882,91 @@ static void init_msvcrt_io_block(STARTUPINFO* st)
...
@@ -834,81 +882,91 @@ static void init_msvcrt_io_block(STARTUPINFO* st)
* findexecutable to acheive this which is left untouched.
* findexecutable to acheive this which is left untouched.
*/
*/
void
WCMD_run_program
(
char
*
command
,
int
called
)
{
void
WCMD_run_program
(
WCHAR
*
command
,
int
called
)
{
char
temp
[
MAX_PATH
];
WCHAR
temp
[
MAX_PATH
];
char
pathtosearch
[
MAXSTRING
];
WCHAR
pathtosearch
[
MAXSTRING
];
char
*
pathposn
;
WCHAR
*
pathposn
;
char
stemofsearch
[
MAX_PATH
];
WCHAR
stemofsearch
[
MAX_PATH
];
char
*
lastSlash
;
WCHAR
*
lastSlash
;
char
pathext
[
MAXSTRING
];
WCHAR
pathext
[
MAXSTRING
];
BOOL
extensionsupplied
=
FALSE
;
BOOL
extensionsupplied
=
FALSE
;
BOOL
launched
=
FALSE
;
BOOL
launched
=
FALSE
;
BOOL
status
;
BOOL
status
;
BOOL
assumeInternal
=
FALSE
;
BOOL
assumeInternal
=
FALSE
;
DWORD
len
;
DWORD
len
;
static
const
WCHAR
envPath
[]
=
{
'P'
,
'A'
,
'T'
,
'H'
,
'\0'
};
static
const
WCHAR
envPathExt
[]
=
{
'P'
,
'A'
,
'T'
,
'H'
,
'E'
,
'X'
,
'T'
,
'\0'
};
static
const
WCHAR
delims
[]
=
{
'/'
,
'\\'
,
':'
,
'\0'
};
WCMD_parse
(
command
,
quals
,
param1
,
param2
);
/* Quick way to get the filename */
WCMD_parse
(
command
,
quals
,
param1
,
param2
);
/* Quick way to get the filename */
if
(
!
(
*
param1
)
&&
!
(
*
param2
))
if
(
!
(
*
param1
)
&&
!
(
*
param2
))
return
;
return
;
/* Calculate the search path and stem to search for */
/* Calculate the search path and stem to search for */
if
(
strpbrk
(
param1
,
"/
\\
:"
)
==
NULL
)
{
/* No explicit path given, search path */
if
(
strpbrkW
(
param1
,
delims
)
==
NULL
)
{
/* No explicit path given, search path */
strcpy
(
pathtosearch
,
".;"
);
static
const
WCHAR
curDir
[]
=
{
'.'
,
';'
,
'\0'
};
len
=
GetEnvironmentVariable
(
"PATH"
,
&
pathtosearch
[
2
],
sizeof
(
pathtosearch
)
-
2
);
strcpyW
(
pathtosearch
,
curDir
);
if
((
len
==
0
)
||
(
len
>=
sizeof
(
pathtosearch
)
-
2
))
{
len
=
GetEnvironmentVariable
(
envPath
,
&
pathtosearch
[
2
],
(
sizeof
(
pathtosearch
)
/
sizeof
(
WCHAR
))
-
2
);
lstrcpy
(
pathtosearch
,
"."
);
if
((
len
==
0
)
||
(
len
>=
(
sizeof
(
pathtosearch
)
/
sizeof
(
WCHAR
))
-
2
))
{
static
const
WCHAR
curDir
[]
=
{
'.'
,
'\0'
};
strcpyW
(
pathtosearch
,
curDir
);
}
}
if
(
strchr
(
param1
,
'.'
)
!=
NULL
)
extensionsupplied
=
TRUE
;
if
(
strchr
W
(
param1
,
'.'
)
!=
NULL
)
extensionsupplied
=
TRUE
;
strcpy
(
stemofsearch
,
param1
);
strcpy
W
(
stemofsearch
,
param1
);
}
else
{
}
else
{
/* Convert eg. ..\fred to include a directory by removing file part */
/* Convert eg. ..\fred to include a directory by removing file part */
GetFullPathName
(
param1
,
sizeof
(
pathtosearch
),
pathtosearch
,
NULL
);
GetFullPathName
(
param1
,
sizeof
(
pathtosearch
)
/
sizeof
(
WCHAR
)
,
pathtosearch
,
NULL
);
lastSlash
=
strrchr
(
pathtosearch
,
'\\'
);
lastSlash
=
strrchr
W
(
pathtosearch
,
'\\'
);
if
(
lastSlash
&&
strchr
(
lastSlash
,
'.'
)
!=
NULL
)
extensionsupplied
=
TRUE
;
if
(
lastSlash
&&
strchr
W
(
lastSlash
,
'.'
)
!=
NULL
)
extensionsupplied
=
TRUE
;
if
(
lastSlash
)
*
lastSlash
=
0x00
;
if
(
lastSlash
)
*
lastSlash
=
0x00
;
strcpy
(
stemofsearch
,
lastSlash
+
1
);
strcpy
W
(
stemofsearch
,
lastSlash
+
1
);
}
}
/* Now extract PATHEXT */
/* Now extract PATHEXT */
len
=
GetEnvironmentVariable
(
"PATHEXT"
,
pathext
,
sizeof
(
pathext
));
len
=
GetEnvironmentVariable
(
envPathExt
,
pathext
,
sizeof
(
pathext
)
/
sizeof
(
WCHAR
));
if
((
len
==
0
)
||
(
len
>=
sizeof
(
pathext
)))
{
if
((
len
==
0
)
||
(
len
>=
(
sizeof
(
pathext
)
/
sizeof
(
WCHAR
))))
{
lstrcpy
(
pathext
,
".bat;.com;.cmd;.exe"
);
static
const
WCHAR
dfltPathExt
[]
=
{
'.'
,
'b'
,
'a'
,
't'
,
';'
,
'.'
,
'c'
,
'o'
,
'm'
,
';'
,
'.'
,
'c'
,
'm'
,
'd'
,
';'
,
'.'
,
'e'
,
'x'
,
'e'
,
'\0'
};
strcpyW
(
pathext
,
dfltPathExt
);
}
}
/* Loop through the search path, dir by dir */
/* Loop through the search path, dir by dir */
pathposn
=
pathtosearch
;
pathposn
=
pathtosearch
;
WINE_TRACE
(
"Searching in '%s' for '%s'
\n
"
,
pathtosearch
,
stemofsearch
);
WINE_TRACE
(
"Searching in '%s' for '%s'
\n
"
,
wine_dbgstr_w
(
pathtosearch
),
wine_dbgstr_w
(
stemofsearch
));
while
(
!
launched
&&
pathposn
)
{
while
(
!
launched
&&
pathposn
)
{
char
thisDir
[
MAX_PATH
]
=
""
;
WCHAR
thisDir
[
MAX_PATH
]
=
{
'\0'
}
;
char
*
pos
=
NULL
;
WCHAR
*
pos
=
NULL
;
BOOL
found
=
FALSE
;
BOOL
found
=
FALSE
;
const
WCHAR
slashW
[]
=
{
'\\'
,
'\0'
};
/* Work on the first directory on the search path */
/* Work on the first directory on the search path */
pos
=
strchr
(
pathposn
,
';'
);
pos
=
strchr
W
(
pathposn
,
';'
);
if
(
pos
)
{
if
(
pos
)
{
strncpy
(
thisDir
,
pathposn
,
(
pos
-
pathposn
));
memcpy
(
thisDir
,
pathposn
,
(
pos
-
pathposn
)
*
sizeof
(
WCHAR
));
thisDir
[(
pos
-
pathposn
)]
=
0x00
;
thisDir
[(
pos
-
pathposn
)]
=
0x00
;
pathposn
=
pos
+
1
;
pathposn
=
pos
+
1
;
}
else
{
}
else
{
strcpy
(
thisDir
,
pathposn
);
strcpy
W
(
thisDir
,
pathposn
);
pathposn
=
NULL
;
pathposn
=
NULL
;
}
}
/* Since you can have eg. ..\.. on the path, need to expand
/* Since you can have eg. ..\.. on the path, need to expand
to full information */
to full information */
strcpy
(
temp
,
thisDir
);
strcpy
W
(
temp
,
thisDir
);
GetFullPathName
(
temp
,
MAX_PATH
,
thisDir
,
NULL
);
GetFullPathName
(
temp
,
MAX_PATH
,
thisDir
,
NULL
);
/* 1. If extension supplied, see if that file exists */
/* 1. If extension supplied, see if that file exists */
strcat
(
thisDir
,
"
\\
"
);
strcat
W
(
thisDir
,
slashW
);
strcat
(
thisDir
,
stemofsearch
);
strcat
W
(
thisDir
,
stemofsearch
);
pos
=
&
thisDir
[
strlen
(
thisDir
)];
/* Pos = end of name */
pos
=
&
thisDir
[
strlen
W
(
thisDir
)];
/* Pos = end of name */
/* 1. If extension supplied, see if that file exists */
/* 1. If extension supplied, see if that file exists */
if
(
extensionsupplied
)
{
if
(
extensionsupplied
)
{
...
@@ -921,24 +979,25 @@ void WCMD_run_program (char *command, int called) {
...
@@ -921,24 +979,25 @@ void WCMD_run_program (char *command, int called) {
if
(
!
found
)
{
if
(
!
found
)
{
HANDLE
h
;
HANDLE
h
;
WIN32_FIND_DATA
finddata
;
WIN32_FIND_DATA
finddata
;
static
const
WCHAR
allFiles
[]
=
{
'.'
,
'*'
,
'\0'
};
strcat
(
thisDir
,
".*"
);
strcat
W
(
thisDir
,
allFiles
);
h
=
FindFirstFile
(
thisDir
,
&
finddata
);
h
=
FindFirstFile
(
thisDir
,
&
finddata
);
FindClose
(
h
);
FindClose
(
h
);
if
(
h
!=
INVALID_HANDLE_VALUE
)
{
if
(
h
!=
INVALID_HANDLE_VALUE
)
{
char
*
thisExt
=
pathext
;
WCHAR
*
thisExt
=
pathext
;
/* 3. Yes - Try each path ext */
/* 3. Yes - Try each path ext */
while
(
thisExt
)
{
while
(
thisExt
)
{
char
*
nextExt
=
strchr
(
thisExt
,
';'
);
WCHAR
*
nextExt
=
strchrW
(
thisExt
,
';'
);
if
(
nextExt
)
{
if
(
nextExt
)
{
strncpy
(
pos
,
thisExt
,
(
nextExt
-
thisExt
));
memcpy
(
pos
,
thisExt
,
(
nextExt
-
thisExt
)
*
sizeof
(
WCHAR
));
pos
[(
nextExt
-
thisExt
)]
=
0x00
;
pos
[(
nextExt
-
thisExt
)]
=
0x00
;
thisExt
=
nextExt
+
1
;
thisExt
=
nextExt
+
1
;
}
else
{
}
else
{
strcpy
(
pos
,
thisExt
);
strcpy
W
(
pos
,
thisExt
);
thisExt
=
NULL
;
thisExt
=
NULL
;
}
}
...
@@ -959,7 +1018,7 @@ void WCMD_run_program (char *command, int called) {
...
@@ -959,7 +1018,7 @@ void WCMD_run_program (char *command, int called) {
WINE_TRACE
(
"ASSUMING INTERNAL
\n
"
);
WINE_TRACE
(
"ASSUMING INTERNAL
\n
"
);
assumeInternal
=
TRUE
;
assumeInternal
=
TRUE
;
}
else
{
}
else
{
WINE_TRACE
(
"Found as %s
\n
"
,
thisDir
);
WINE_TRACE
(
"Found as %s
\n
"
,
wine_dbgstr_w
(
thisDir
)
);
}
}
/* Once found, launch it */
/* Once found, launch it */
...
@@ -969,14 +1028,17 @@ void WCMD_run_program (char *command, int called) {
...
@@ -969,14 +1028,17 @@ void WCMD_run_program (char *command, int called) {
SHFILEINFO
psfi
;
SHFILEINFO
psfi
;
DWORD
console
;
DWORD
console
;
HINSTANCE
hinst
;
HINSTANCE
hinst
;
char
*
ext
=
strrchr
(
thisDir
,
'.'
);
WCHAR
*
ext
=
strrchrW
(
thisDir
,
'.'
);
static
const
WCHAR
batExt
[]
=
{
'.'
,
'b'
,
'a'
,
't'
,
'\0'
};
static
const
WCHAR
cmdExt
[]
=
{
'.'
,
'c'
,
'm'
,
'd'
,
'\0'
};
launched
=
TRUE
;
launched
=
TRUE
;
/* Special case BAT and CMD */
/* Special case BAT and CMD */
if
(
ext
&&
!
strc
asecmp
(
ext
,
".bat"
))
{
if
(
ext
&&
!
strc
mpiW
(
ext
,
batExt
))
{
WCMD_batch
(
thisDir
,
command
,
called
,
NULL
,
INVALID_HANDLE_VALUE
);
WCMD_batch
(
thisDir
,
command
,
called
,
NULL
,
INVALID_HANDLE_VALUE
);
return
;
return
;
}
else
if
(
ext
&&
!
strc
asecmp
(
ext
,
".cmd"
))
{
}
else
if
(
ext
&&
!
strc
mpiW
(
ext
,
cmdExt
))
{
WCMD_batch
(
thisDir
,
command
,
called
,
NULL
,
INVALID_HANDLE_VALUE
);
WCMD_batch
(
thisDir
,
command
,
called
,
NULL
,
INVALID_HANDLE_VALUE
);
return
;
return
;
}
else
{
}
else
{
...
@@ -999,7 +1061,7 @@ void WCMD_run_program (char *command, int called) {
...
@@ -999,7 +1061,7 @@ void WCMD_run_program (char *command, int called) {
command
,
NULL
,
NULL
,
TRUE
,
0
,
NULL
,
NULL
,
&
st
,
&
pe
);
command
,
NULL
,
NULL
,
TRUE
,
0
,
NULL
,
NULL
,
&
st
,
&
pe
);
if
((
opt_c
||
opt_k
)
&&
!
opt_s
&&
!
status
if
((
opt_c
||
opt_k
)
&&
!
opt_s
&&
!
status
&&
GetLastError
()
==
ERROR_FILE_NOT_FOUND
&&
command
[
0
]
==
'\"'
)
{
&&
GetLastError
()
==
ERROR_FILE_NOT_FOUND
&&
command
[
0
]
==
'\"'
)
{
/* strip first and last quote
char
acters and try again */
/* strip first and last quote
WCHAR
acters and try again */
WCMD_opt_s_strip_quotes
(
command
);
WCMD_opt_s_strip_quotes
(
command
);
opt_s
=
1
;
opt_s
=
1
;
WCMD_run_program
(
command
,
called
);
WCMD_run_program
(
command
,
called
);
...
@@ -1047,13 +1109,16 @@ void WCMD_run_program (char *command, int called) {
...
@@ -1047,13 +1109,16 @@ void WCMD_run_program (char *command, int called) {
void
WCMD_show_prompt
(
void
)
{
void
WCMD_show_prompt
(
void
)
{
int
status
;
int
status
;
char
out_string
[
MAX_PATH
],
curdir
[
MAX_PATH
],
prompt_string
[
MAX_PATH
];
WCHAR
out_string
[
MAX_PATH
],
curdir
[
MAX_PATH
],
prompt_string
[
MAX_PATH
];
char
*
p
,
*
q
;
WCHAR
*
p
,
*
q
;
DWORD
len
;
DWORD
len
;
static
const
WCHAR
envPrompt
[]
=
{
'P'
,
'R'
,
'O'
,
'M'
,
'P'
,
'T'
,
'\0'
};
len
=
GetEnvironmentVariable
(
"PROMPT"
,
prompt_string
,
sizeof
(
prompt_string
));
len
=
GetEnvironmentVariable
(
envPrompt
,
prompt_string
,
if
((
len
==
0
)
||
(
len
>=
sizeof
(
prompt_string
)))
{
sizeof
(
prompt_string
)
/
sizeof
(
WCHAR
));
lstrcpy
(
prompt_string
,
"$P$G"
);
if
((
len
==
0
)
||
(
len
>=
(
sizeof
(
prompt_string
)
/
sizeof
(
WCHAR
))))
{
const
WCHAR
dfltPrompt
[]
=
{
'$'
,
'P'
,
'$'
,
'G'
,
'\0'
};
strcpyW
(
prompt_string
,
dfltPrompt
);
}
}
p
=
prompt_string
;
p
=
prompt_string
;
q
=
out_string
;
q
=
out_string
;
...
@@ -1098,15 +1163,15 @@ void WCMD_show_prompt (void) {
...
@@ -1098,15 +1163,15 @@ void WCMD_show_prompt (void) {
*
q
++
=
'<'
;
*
q
++
=
'<'
;
break
;
break
;
case
'N'
:
case
'N'
:
status
=
GetCurrentDirectory
(
sizeof
(
curdir
),
curdir
);
status
=
GetCurrentDirectory
(
sizeof
(
curdir
)
/
sizeof
(
WCHAR
)
,
curdir
);
if
(
status
)
{
if
(
status
)
{
*
q
++
=
curdir
[
0
];
*
q
++
=
curdir
[
0
];
}
}
break
;
break
;
case
'P'
:
case
'P'
:
status
=
GetCurrentDirectory
(
sizeof
(
curdir
),
curdir
);
status
=
GetCurrentDirectory
(
sizeof
(
curdir
)
/
sizeof
(
WCHAR
)
,
curdir
);
if
(
status
)
{
if
(
status
)
{
lstrcat
(
q
,
curdir
);
strcatW
(
q
,
curdir
);
while
(
*
q
)
q
++
;
while
(
*
q
)
q
++
;
}
}
break
;
break
;
...
@@ -1121,7 +1186,7 @@ void WCMD_show_prompt (void) {
...
@@ -1121,7 +1186,7 @@ void WCMD_show_prompt (void) {
while
(
*
q
)
q
++
;
while
(
*
q
)
q
++
;
break
;
break
;
case
'V'
:
case
'V'
:
lstrcat
(
q
,
version_string
);
strcatW
(
q
,
version_string
);
while
(
*
q
)
q
++
;
while
(
*
q
)
q
++
;
break
;
break
;
case
'_'
:
case
'_'
:
...
@@ -1175,7 +1240,7 @@ void WCMD_print_error (void) {
...
@@ -1175,7 +1240,7 @@ void WCMD_print_error (void) {
* Parameters in quotes are handled.
* Parameters in quotes are handled.
*/
*/
void
WCMD_parse
(
char
*
s
,
char
*
q
,
char
*
p1
,
char
*
p2
)
{
void
WCMD_parse
(
WCHAR
*
s
,
WCHAR
*
q
,
WCHAR
*
p1
,
WCHAR
*
p2
)
{
int
p
=
0
;
int
p
=
0
;
...
@@ -1222,12 +1287,47 @@ int p = 0;
...
@@ -1222,12 +1287,47 @@ int p = 0;
/*******************************************************************
/*******************************************************************
* WCMD_output_asis_len - send output to current standard output
* WCMD_output_asis_len - send output to current standard output
* device without formatting eg. when message contains '%'
*
* of a supplied length.
* Output a formatted unicode string. Ideally this will go to the console
* and hence required WriteConsoleW to output it, however if file i/o is
* redirected, it needs to be WriteFile'd using OEM (not ANSI) format
*/
*/
static
void
WCMD_output_asis_len
(
const
char
*
message
,
int
len
)
{
static
void
WCMD_output_asis_len
(
const
WCHAR
*
message
,
int
len
)
{
DWORD
count
;
WriteFile
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
message
,
len
,
&
count
,
NULL
);
DWORD
nOut
=
0
;
DWORD
res
=
0
;
/* If nothing to write, return (MORE does this sometimes) */
if
(
!
len
)
return
;
/* Try to write as unicode assuming it is to a console */
res
=
WriteConsoleW
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
message
,
len
,
&
nOut
,
NULL
);
/* If writing to console fails, assume its file
i/o so convert to OEM codepage and output */
if
(
!
res
)
{
BOOL
usedDefaultChar
=
FALSE
;
DWORD
convertedChars
;
/*
* Allocate buffer to use when writing to file. (Not freed, as one off)
*/
if
(
!
output_bufA
)
output_bufA
=
HeapAlloc
(
GetProcessHeap
(),
0
,
MAX_WRITECONSOLE_SIZE
);
if
(
!
output_bufA
)
{
WINE_FIXME
(
"Out of memory - could not allocate ansi 64K buffer
\n
"
);
return
;
}
/* Convert to OEM, then output */
convertedChars
=
WideCharToMultiByte
(
GetConsoleOutputCP
(),
0
,
message
,
len
,
output_bufA
,
MAX_WRITECONSOLE_SIZE
,
"?"
,
&
usedDefaultChar
);
WriteFile
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
output_bufA
,
convertedChars
,
&
nOut
,
FALSE
);
}
return
;
}
}
/*******************************************************************
/*******************************************************************
...
@@ -1235,38 +1335,44 @@ static void WCMD_output_asis_len(const char *message, int len) {
...
@@ -1235,38 +1335,44 @@ static void WCMD_output_asis_len(const char *message, int len) {
*
*
*/
*/
void
WCMD_output
(
const
char
*
format
,
...)
{
void
WCMD_output
(
const
WCHAR
*
format
,
...)
{
va_list
ap
;
va_list
ap
;
char
string
[
1024
];
WCHAR
string
[
1024
];
int
ret
;
int
ret
;
va_start
(
ap
,
format
);
va_start
(
ap
,
format
);
ret
=
vsnprintf
(
string
,
sizeof
(
string
),
format
,
ap
);
ret
=
wvsprintf
(
string
,
format
,
ap
);
va_end
(
ap
);
if
(
ret
>=
(
sizeof
(
string
)
/
sizeof
(
WCHAR
)))
{
if
(
ret
>=
sizeof
(
string
))
{
WINE_ERR
(
"Output truncated in WCMD_output
\n
"
);
WINE_ERR
(
"Output truncated in WCMD_output
\n
"
);
ret
=
sizeof
(
string
)
-
1
;
ret
=
(
sizeof
(
string
)
/
sizeof
(
WCHAR
)
)
-
1
;
string
[
ret
]
=
'\0'
;
string
[
ret
]
=
'\0'
;
}
}
va_end
(
ap
);
WCMD_output_asis_len
(
string
,
ret
);
WCMD_output_asis_len
(
string
,
ret
);
}
}
static
int
line_count
;
static
int
line_count
;
static
int
max_height
;
static
int
max_height
;
static
int
max_width
;
static
BOOL
paged_mode
;
static
BOOL
paged_mode
;
static
int
numChars
;
void
WCMD_enter_paged_mode
(
const
char
*
msg
)
void
WCMD_enter_paged_mode
(
const
WCHAR
*
msg
)
{
{
CONSOLE_SCREEN_BUFFER_INFO
consoleInfo
;
CONSOLE_SCREEN_BUFFER_INFO
consoleInfo
;
if
(
GetConsoleScreenBufferInfo
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
&
consoleInfo
))
if
(
GetConsoleScreenBufferInfo
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
&
consoleInfo
))
{
max_height
=
consoleInfo
.
dwSize
.
Y
;
max_height
=
consoleInfo
.
dwSize
.
Y
;
else
max_width
=
consoleInfo
.
dwSize
.
X
;
}
else
{
max_height
=
25
;
max_height
=
25
;
max_width
=
80
;
}
paged_mode
=
TRUE
;
paged_mode
=
TRUE
;
line_count
=
0
;
line_count
=
0
;
numChars
=
0
;
pagedMessage
=
(
msg
==
NULL
)
?
anykey
:
msg
;
pagedMessage
=
(
msg
==
NULL
)
?
anykey
:
msg
;
}
}
...
@@ -1281,28 +1387,36 @@ void WCMD_leave_paged_mode(void)
...
@@ -1281,28 +1387,36 @@ void WCMD_leave_paged_mode(void)
* without formatting eg. when message contains '%'
* without formatting eg. when message contains '%'
*/
*/
void
WCMD_output_asis
(
const
char
*
message
)
{
void
WCMD_output_asis
(
const
WCHAR
*
message
)
{
DWORD
count
;
DWORD
count
;
c
har
*
ptr
;
c
onst
WCHAR
*
ptr
;
char
string
[
1024
];
WCHAR
string
[
1024
];
if
(
paged_mode
)
{
if
(
paged_mode
)
{
do
{
do
{
if
((
ptr
=
strchr
(
message
,
'\n'
))
!=
NULL
)
ptr
++
;
ptr
=
message
;
WCMD_output_asis_len
(
message
,
(
ptr
)
?
ptr
-
message
:
lstrlen
(
message
));
while
(
*
ptr
&&
*
ptr
!=
'\n'
&&
(
numChars
<
max_width
))
{
numChars
++
;
ptr
++
;
};
if
(
*
ptr
==
'\n'
)
ptr
++
;
WCMD_output_asis_len
(
message
,
(
ptr
)
?
ptr
-
message
:
strlenW
(
message
));
if
(
ptr
)
{
if
(
ptr
)
{
numChars
=
0
;
if
(
++
line_count
>=
max_height
-
1
)
{
if
(
++
line_count
>=
max_height
-
1
)
{
line_count
=
1
;
line_count
=
0
;
WCMD_output_asis_len
(
pagedMessage
,
lstrlen
(
pagedMessage
));
WCMD_output_asis_len
(
pagedMessage
,
strlenW
(
pagedMessage
));
ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
),
&
count
,
NULL
);
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
}
}
}
}
}
while
((
message
=
ptr
)
!=
NULL
);
}
while
((
(
message
=
ptr
)
!=
NULL
)
&&
(
*
ptr
)
);
}
else
{
}
else
{
WCMD_output_asis_len
(
message
,
lstrlen
(
message
));
WCMD_output_asis_len
(
message
,
lstrlen
(
message
));
}
}
}
}
/***************************************************************************
/***************************************************************************
* WCMD_strtrim_leading_spaces
* WCMD_strtrim_leading_spaces
*
*
...
@@ -1310,9 +1424,9 @@ void WCMD_output_asis (const char *message) {
...
@@ -1310,9 +1424,9 @@ void WCMD_output_asis (const char *message) {
* non-space character. Does not modify the input string
* non-space character. Does not modify the input string
*/
*/
char
*
WCMD_strtrim_leading_spaces
(
char
*
string
)
{
WCHAR
*
WCMD_strtrim_leading_spaces
(
WCHAR
*
string
)
{
char
*
ptr
;
WCHAR
*
ptr
;
ptr
=
string
;
ptr
=
string
;
while
(
*
ptr
==
' '
)
ptr
++
;
while
(
*
ptr
==
' '
)
ptr
++
;
...
@@ -1323,14 +1437,14 @@ char *WCMD_strtrim_leading_spaces (char *string) {
...
@@ -1323,14 +1437,14 @@ char *WCMD_strtrim_leading_spaces (char *string) {
* WCMD_strtrim_trailing_spaces
* WCMD_strtrim_trailing_spaces
*
*
* Remove trailing spaces from a string. This routine modifies the input
* Remove trailing spaces from a string. This routine modifies the input
* string by placing a null after the last non-space
char
acter
* string by placing a null after the last non-space
WCHAR
acter
*/
*/
void
WCMD_strtrim_trailing_spaces
(
char
*
string
)
{
void
WCMD_strtrim_trailing_spaces
(
WCHAR
*
string
)
{
char
*
ptr
;
WCHAR
*
ptr
;
ptr
=
string
+
lstrlen
(
string
)
-
1
;
ptr
=
string
+
strlenW
(
string
)
-
1
;
while
((
*
ptr
==
' '
)
&&
(
ptr
>=
string
))
{
while
((
*
ptr
==
' '
)
&&
(
ptr
>=
string
))
{
*
ptr
=
'\0'
;
*
ptr
=
'\0'
;
ptr
--
;
ptr
--
;
...
@@ -1340,11 +1454,11 @@ void WCMD_strtrim_trailing_spaces (char *string) {
...
@@ -1340,11 +1454,11 @@ void WCMD_strtrim_trailing_spaces (char *string) {
/*************************************************************************
/*************************************************************************
* WCMD_opt_s_strip_quotes
* WCMD_opt_s_strip_quotes
*
*
* Remove first and last quote
char
acters, preserving all other text
* Remove first and last quote
WCHAR
acters, preserving all other text
*/
*/
void
WCMD_opt_s_strip_quotes
(
char
*
cmd
)
{
void
WCMD_opt_s_strip_quotes
(
WCHAR
*
cmd
)
{
char
*
src
=
cmd
+
1
,
*
dest
=
cmd
,
*
lastq
=
NULL
;
WCHAR
*
src
=
cmd
+
1
,
*
dest
=
cmd
,
*
lastq
=
NULL
;
while
((
*
dest
=*
src
)
!=
'\0'
)
{
while
((
*
dest
=*
src
)
!=
'\0'
)
{
if
(
*
src
==
'\"'
)
if
(
*
src
==
'\"'
)
lastq
=
dest
;
lastq
=
dest
;
...
@@ -1363,28 +1477,33 @@ void WCMD_opt_s_strip_quotes(char *cmd) {
...
@@ -1363,28 +1477,33 @@ void WCMD_opt_s_strip_quotes(char *cmd) {
* Handle pipes within a command - the DOS way using temporary files.
* Handle pipes within a command - the DOS way using temporary files.
*/
*/
void
WCMD_pipe
(
char
*
command
)
{
void
WCMD_pipe
(
WCHAR
*
command
)
{
char
*
p
;
WCHAR
*
p
;
char
temp_path
[
MAX_PATH
],
temp_file
[
MAX_PATH
],
temp_file2
[
MAX_PATH
],
temp_cmd
[
1024
];
WCHAR
temp_path
[
MAX_PATH
],
temp_file
[
MAX_PATH
],
temp_file2
[
MAX_PATH
],
temp_cmd
[
1024
];
static
const
WCHAR
redirOut
[]
=
{
'%'
,
's'
,
' '
,
'>'
,
' '
,
'%'
,
's'
,
'\0'
};
static
const
WCHAR
redirIn
[]
=
{
'%'
,
's'
,
' '
,
'<'
,
' '
,
'%'
,
's'
,
'\0'
};
static
const
WCHAR
redirBoth
[]
=
{
'%'
,
's'
,
' '
,
'<'
,
' '
,
'%'
,
's'
,
' '
,
'>'
,
'%'
,
's'
,
'\0'
};
static
const
WCHAR
cmdW
[]
=
{
'C'
,
'M'
,
'D'
,
'\0'
};
GetTempPath
(
sizeof
(
temp_path
),
temp_path
);
GetTempFileName
(
temp_path
,
"CMD"
,
0
,
temp_file
);
GetTempPath
(
sizeof
(
temp_path
)
/
sizeof
(
WCHAR
),
temp_path
);
p
=
strchr
(
command
,
'|'
);
GetTempFileName
(
temp_path
,
cmdW
,
0
,
temp_file
);
p
=
strchrW
(
command
,
'|'
);
*
p
++
=
'\0'
;
*
p
++
=
'\0'
;
wsprintf
(
temp_cmd
,
"%s > %s"
,
command
,
temp_file
);
wsprintf
(
temp_cmd
,
redirOut
,
command
,
temp_file
);
WCMD_process_command
(
temp_cmd
);
WCMD_process_command
(
temp_cmd
);
command
=
p
;
command
=
p
;
while
((
p
=
strchr
(
command
,
'|'
)))
{
while
((
p
=
strchr
W
(
command
,
'|'
)))
{
*
p
++
=
'\0'
;
*
p
++
=
'\0'
;
GetTempFileName
(
temp_path
,
"CMD"
,
0
,
temp_file2
);
GetTempFileName
(
temp_path
,
cmdW
,
0
,
temp_file2
);
wsprintf
(
temp_cmd
,
"%s < %s > %s"
,
command
,
temp_file
,
temp_file2
);
wsprintf
(
temp_cmd
,
redirBoth
,
command
,
temp_file
,
temp_file2
);
WCMD_process_command
(
temp_cmd
);
WCMD_process_command
(
temp_cmd
);
DeleteFile
(
temp_file
);
DeleteFile
(
temp_file
);
lstrcpy
(
temp_file
,
temp_file2
);
strcpyW
(
temp_file
,
temp_file2
);
command
=
p
;
command
=
p
;
}
}
wsprintf
(
temp_cmd
,
"%s < %s"
,
command
,
temp_file
);
wsprintf
(
temp_cmd
,
redirIn
,
command
,
temp_file
);
WCMD_process_command
(
temp_cmd
);
WCMD_process_command
(
temp_cmd
);
DeleteFile
(
temp_file
);
DeleteFile
(
temp_file
);
}
}
...
@@ -1392,26 +1511,37 @@ void WCMD_pipe (char *command) {
...
@@ -1392,26 +1511,37 @@ void WCMD_pipe (char *command) {
/*************************************************************************
/*************************************************************************
* WCMD_expand_envvar
* WCMD_expand_envvar
*
*
* Expands environment variables, allowing for
char
acter substitution
* Expands environment variables, allowing for
WCHAR
acter substitution
*/
*/
static
char
*
WCMD_expand_envvar
(
char
*
start
)
{
static
WCHAR
*
WCMD_expand_envvar
(
WCHAR
*
start
)
{
char
*
endOfVar
=
NULL
,
*
s
;
WCHAR
*
endOfVar
=
NULL
,
*
s
;
char
*
colonpos
=
NULL
;
WCHAR
*
colonpos
=
NULL
;
char
thisVar
[
MAXSTRING
];
WCHAR
thisVar
[
MAXSTRING
];
char
thisVarContents
[
MAXSTRING
];
WCHAR
thisVarContents
[
MAXSTRING
];
char
savedchar
=
0x00
;
WCHAR
savedchar
=
0x00
;
int
len
;
int
len
;
static
const
WCHAR
ErrorLvl
[]
=
{
'E'
,
'R'
,
'R'
,
'O'
,
'R'
,
'L'
,
'E'
,
'V'
,
'E'
,
'L'
,
'\0'
};
static
const
WCHAR
ErrorLvlP
[]
=
{
'%'
,
'E'
,
'R'
,
'R'
,
'O'
,
'R'
,
'L'
,
'E'
,
'V'
,
'E'
,
'L'
,
'%'
,
'\0'
};
static
const
WCHAR
Date
[]
=
{
'D'
,
'A'
,
'T'
,
'E'
,
'\0'
};
static
const
WCHAR
DateP
[]
=
{
'%'
,
'D'
,
'A'
,
'T'
,
'E'
,
'%'
,
'\0'
};
static
const
WCHAR
Time
[]
=
{
'T'
,
'I'
,
'M'
,
'E'
,
'\0'
};
static
const
WCHAR
TimeP
[]
=
{
'%'
,
'T'
,
'I'
,
'M'
,
'E'
,
'%'
,
'\0'
};
static
const
WCHAR
Cd
[]
=
{
'C'
,
'D'
,
'\0'
};
static
const
WCHAR
CdP
[]
=
{
'%'
,
'C'
,
'D'
,
'%'
,
'\0'
};
static
const
WCHAR
Random
[]
=
{
'R'
,
'A'
,
'N'
,
'D'
,
'O'
,
'M'
,
'\0'
};
static
const
WCHAR
RandomP
[]
=
{
'%'
,
'R'
,
'A'
,
'N'
,
'D'
,
'O'
,
'M'
,
'%'
,
'\0'
};
/* Find the end of the environment variable, and extract name */
/* Find the end of the environment variable, and extract name */
endOfVar
=
strchr
(
start
+
1
,
'%'
);
endOfVar
=
strchr
W
(
start
+
1
,
'%'
);
if
(
endOfVar
==
NULL
)
{
if
(
endOfVar
==
NULL
)
{
/* FIXME: Some special conditions here depending o
p
n whether
/* FIXME: Some special conditions here depending on whether
in batch, complex or not, and whether env var exists or not! */
in batch, complex or not, and whether env var exists or not! */
return
start
+
1
;
return
start
+
1
;
}
}
strncpy
(
thisVar
,
start
,
(
endOfVar
-
start
)
+
1
);
memcpy
(
thisVar
,
start
,
((
endOfVar
-
start
)
+
1
)
*
sizeof
(
WCHAR
)
);
thisVar
[(
endOfVar
-
start
)
+
1
]
=
0x00
;
thisVar
[(
endOfVar
-
start
)
+
1
]
=
0x00
;
colonpos
=
strchr
(
thisVar
+
1
,
':'
);
colonpos
=
strchr
W
(
thisVar
+
1
,
':'
);
/* If there's complex substitution, just need %var% for now
/* If there's complex substitution, just need %var% for now
to get the expanded data to play with */
to get the expanded data to play with */
...
@@ -1421,56 +1551,60 @@ static char *WCMD_expand_envvar(char *start) {
...
@@ -1421,56 +1551,60 @@ static char *WCMD_expand_envvar(char *start) {
*
(
colonpos
+
1
)
=
0x00
;
*
(
colonpos
+
1
)
=
0x00
;
}
}
WINE_TRACE
(
"Retrieving contents of %s
\n
"
,
wine_dbgstr_w
(
thisVar
));
/* Expand to contents, if unchanged, return */
/* Expand to contents, if unchanged, return */
/* Handle DATE, TIME, ERRORLEVEL and CD replacements allowing */
/* Handle DATE, TIME, ERRORLEVEL and CD replacements allowing */
/* override if existing env var called that name */
/* override if existing env var called that name */
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
thisVar
,
12
,
"%ERRORLEVEL%"
,
-
1
)
==
2
)
&&
thisVar
,
12
,
ErrorLvlP
,
-
1
)
==
2
)
&&
(
GetEnvironmentVariable
(
"ERRORLEVEL"
,
thisVarContents
,
1
)
==
0
)
&&
(
GetEnvironmentVariable
(
ErrorLvl
,
thisVarContents
,
1
)
==
0
)
&&
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
sprintf
(
thisVarContents
,
"%d"
,
errorlevel
);
static
const
WCHAR
fmt
[]
=
{
'%'
,
'd'
,
'\0'
};
len
=
strlen
(
thisVarContents
);
wsprintf
(
thisVarContents
,
fmt
,
errorlevel
);
len
=
strlenW
(
thisVarContents
);
}
else
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
}
else
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
thisVar
,
6
,
"%DATE%"
,
-
1
)
==
2
)
&&
thisVar
,
6
,
DateP
,
-
1
)
==
2
)
&&
(
GetEnvironmentVariable
(
"DATE"
,
thisVarContents
,
1
)
==
0
)
&&
(
GetEnvironmentVariable
(
Date
,
thisVarContents
,
1
)
==
0
)
&&
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
GetDateFormat
(
LOCALE_USER_DEFAULT
,
DATE_SHORTDATE
,
NULL
,
GetDateFormat
(
LOCALE_USER_DEFAULT
,
DATE_SHORTDATE
,
NULL
,
NULL
,
thisVarContents
,
MAXSTRING
);
NULL
,
thisVarContents
,
MAXSTRING
);
len
=
strlen
(
thisVarContents
);
len
=
strlen
W
(
thisVarContents
);
}
else
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
}
else
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
thisVar
,
6
,
"%TIME%"
,
-
1
)
==
2
)
&&
thisVar
,
6
,
TimeP
,
-
1
)
==
2
)
&&
(
GetEnvironmentVariable
(
"TIME"
,
thisVarContents
,
1
)
==
0
)
&&
(
GetEnvironmentVariable
(
Time
,
thisVarContents
,
1
)
==
0
)
&&
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
GetTimeFormat
(
LOCALE_USER_DEFAULT
,
TIME_NOSECONDS
,
NULL
,
GetTimeFormat
(
LOCALE_USER_DEFAULT
,
TIME_NOSECONDS
,
NULL
,
NULL
,
thisVarContents
,
MAXSTRING
);
NULL
,
thisVarContents
,
MAXSTRING
);
len
=
strlen
(
thisVarContents
);
len
=
strlen
W
(
thisVarContents
);
}
else
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
}
else
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
thisVar
,
4
,
"%CD%"
,
-
1
)
==
2
)
&&
thisVar
,
4
,
CdP
,
-
1
)
==
2
)
&&
(
GetEnvironmentVariable
(
"CD"
,
thisVarContents
,
1
)
==
0
)
&&
(
GetEnvironmentVariable
(
Cd
,
thisVarContents
,
1
)
==
0
)
&&
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
GetCurrentDirectory
(
MAXSTRING
,
thisVarContents
);
GetCurrentDirectory
(
MAXSTRING
,
thisVarContents
);
len
=
strlen
(
thisVarContents
);
len
=
strlen
W
(
thisVarContents
);
}
else
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
}
else
if
((
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
thisVar
,
8
,
"%RANDOM%"
,
-
1
)
==
2
)
&&
thisVar
,
8
,
RandomP
,
-
1
)
==
2
)
&&
(
GetEnvironmentVariable
(
"RANDOM"
,
thisVarContents
,
1
)
==
0
)
&&
(
GetEnvironmentVariable
(
Random
,
thisVarContents
,
1
)
==
0
)
&&
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
(
GetLastError
()
==
ERROR_ENVVAR_NOT_FOUND
))
{
sprintf
(
thisVarContents
,
"%d"
,
rand
()
%
32768
);
static
const
WCHAR
fmt
[]
=
{
'%'
,
'd'
,
'\0'
};
len
=
strlen
(
thisVarContents
);
wsprintf
(
thisVarContents
,
fmt
,
rand
()
%
32768
);
len
=
strlenW
(
thisVarContents
);
}
else
{
}
else
{
len
=
ExpandEnvironmentStrings
(
thisVar
,
thisVarContents
,
len
=
ExpandEnvironmentStrings
(
thisVar
,
thisVarContents
,
sizeof
(
thisVarContents
));
sizeof
(
thisVarContents
)
/
sizeof
(
WCHAR
));
}
}
if
(
len
==
0
)
if
(
len
==
0
)
...
@@ -1480,7 +1614,7 @@ static char *WCMD_expand_envvar(char *start) {
...
@@ -1480,7 +1614,7 @@ static char *WCMD_expand_envvar(char *start) {
note syntax %garbage:1,3% results in anything after the ':'
note syntax %garbage:1,3% results in anything after the ':'
except the %
except the %
From the command line, you just get back what you entered */
From the command line, you just get back what you entered */
if
(
lstrcmpi
(
thisVar
,
thisVarContents
)
==
0
)
{
if
(
lstrcmpi
W
(
thisVar
,
thisVarContents
)
==
0
)
{
/* Restore the complex part after the compare */
/* Restore the complex part after the compare */
if
(
colonpos
)
{
if
(
colonpos
)
{
...
@@ -1488,25 +1622,25 @@ static char *WCMD_expand_envvar(char *start) {
...
@@ -1488,25 +1622,25 @@ static char *WCMD_expand_envvar(char *start) {
*
(
colonpos
+
1
)
=
savedchar
;
*
(
colonpos
+
1
)
=
savedchar
;
}
}
s
=
strdup
(
endOfVar
+
1
);
s
=
WCMD_strdupW
(
endOfVar
+
1
);
/* Command line - just ignore this */
/* Command line - just ignore this */
if
(
context
==
NULL
)
return
endOfVar
+
1
;
if
(
context
==
NULL
)
return
endOfVar
+
1
;
/* Batch - replace unknown env var with nothing */
/* Batch - replace unknown env var with nothing */
if
(
colonpos
==
NULL
)
{
if
(
colonpos
==
NULL
)
{
strcpy
(
start
,
s
);
strcpy
W
(
start
,
s
);
}
else
{
}
else
{
len
=
strlen
(
thisVar
);
len
=
strlen
W
(
thisVar
);
thisVar
[
len
-
1
]
=
0x00
;
thisVar
[
len
-
1
]
=
0x00
;
/* If %:...% supplied, : is retained */
/* If %:...% supplied, : is retained */
if
(
colonpos
==
thisVar
+
1
)
{
if
(
colonpos
==
thisVar
+
1
)
{
strcpy
(
start
,
colonpos
);
strcpy
W
(
start
,
colonpos
);
}
else
{
}
else
{
strcpy
(
start
,
colonpos
+
1
);
strcpy
W
(
start
,
colonpos
+
1
);
}
}
strcat
(
start
,
s
);
strcat
W
(
start
,
s
);
}
}
free
(
s
);
free
(
s
);
return
start
;
return
start
;
...
@@ -1516,9 +1650,9 @@ static char *WCMD_expand_envvar(char *start) {
...
@@ -1516,9 +1650,9 @@ static char *WCMD_expand_envvar(char *start) {
/* See if we need to do complex substitution (any ':'s), if not
/* See if we need to do complex substitution (any ':'s), if not
then our work here is done */
then our work here is done */
if
(
colonpos
==
NULL
)
{
if
(
colonpos
==
NULL
)
{
s
=
strdup
(
endOfVar
+
1
);
s
=
WCMD_strdupW
(
endOfVar
+
1
);
strcpy
(
start
,
thisVarContents
);
strcpy
W
(
start
,
thisVarContents
);
strcat
(
start
,
s
);
strcat
W
(
start
,
s
);
free
(
s
);
free
(
s
);
return
start
;
return
start
;
}
}
...
@@ -1531,23 +1665,23 @@ static char *WCMD_expand_envvar(char *start) {
...
@@ -1531,23 +1665,23 @@ static char *WCMD_expand_envvar(char *start) {
Handle complex substitutions:
Handle complex substitutions:
xxx=yyy (replace xxx with yyy)
xxx=yyy (replace xxx with yyy)
*xxx=yyy (replace up to and including xxx with yyy)
*xxx=yyy (replace up to and including xxx with yyy)
~x (from x
char
s in)
~x (from x
WCHAR
s in)
~-x (from x
char
s from the end)
~-x (from x
WCHAR
s from the end)
~x,y (from x
chars in for y char
acters)
~x,y (from x
WCHARs in for y WCHAR
acters)
~x,-y (from x
chars in until y char
acters from the end)
~x,-y (from x
WCHARs in until y WCHAR
acters from the end)
*/
*/
/* ~ is substring manipulation */
/* ~ is substring manipulation */
if
(
savedchar
==
'~'
)
{
if
(
savedchar
==
'~'
)
{
int
substrposition
,
substrlength
=
0
;
int
substrposition
,
substrlength
=
0
;
char
*
commapos
=
strchr
(
colonpos
+
2
,
','
);
WCHAR
*
commapos
=
strchrW
(
colonpos
+
2
,
','
);
char
*
startCopy
;
WCHAR
*
startCopy
;
substrposition
=
atol
(
colonpos
+
2
);
substrposition
=
atol
W
(
colonpos
+
2
);
if
(
commapos
)
substrlength
=
atol
(
commapos
+
1
);
if
(
commapos
)
substrlength
=
atol
W
(
commapos
+
1
);
s
=
strdup
(
endOfVar
+
1
);
s
=
WCMD_strdupW
(
endOfVar
+
1
);
/* Check bounds */
/* Check bounds */
if
(
substrposition
>=
0
)
{
if
(
substrposition
>=
0
)
{
...
@@ -1557,81 +1691,80 @@ static char *WCMD_expand_envvar(char *start) {
...
@@ -1557,81 +1691,80 @@ static char *WCMD_expand_envvar(char *start) {
}
}
if
(
commapos
==
NULL
)
{
if
(
commapos
==
NULL
)
{
strcpy
(
start
,
startCopy
);
/* Copy the lot */
strcpy
W
(
start
,
startCopy
);
/* Copy the lot */
}
else
if
(
substrlength
<
0
)
{
}
else
if
(
substrlength
<
0
)
{
int
copybytes
=
(
len
+
substrlength
-
1
)
-
(
startCopy
-
thisVarContents
);
int
copybytes
=
(
len
+
substrlength
-
1
)
-
(
startCopy
-
thisVarContents
);
if
(
copybytes
>
len
)
copybytes
=
len
;
if
(
copybytes
>
len
)
copybytes
=
len
;
else
if
(
copybytes
<
0
)
copybytes
=
0
;
else
if
(
copybytes
<
0
)
copybytes
=
0
;
strncpy
(
start
,
startCopy
,
copybytes
);
/* Copy the lot */
memcpy
(
start
,
startCopy
,
copybytes
*
sizeof
(
WCHAR
)
);
/* Copy the lot */
start
[
copybytes
]
=
0x00
;
start
[
copybytes
]
=
0x00
;
}
else
{
}
else
{
strncpy
(
start
,
startCopy
,
substrlength
);
/* Copy the lot */
memcpy
(
start
,
startCopy
,
substrlength
*
sizeof
(
WCHAR
)
);
/* Copy the lot */
start
[
substrlength
]
=
0x00
;
start
[
substrlength
]
=
0x00
;
}
}
strcat
(
start
,
s
);
strcat
W
(
start
,
s
);
free
(
s
);
free
(
s
);
return
start
;
return
start
;
/* search and replace manipulation */
/* search and replace manipulation */
}
else
{
}
else
{
char
*
equalspos
=
strstr
(
colonpos
,
"="
);
WCHAR
*
equalspos
=
strstrW
(
colonpos
,
equalsW
);
char
*
replacewith
=
equalspos
+
1
;
WCHAR
*
replacewith
=
equalspos
+
1
;
char
*
found
=
NULL
;
WCHAR
*
found
=
NULL
;
char
*
searchIn
;
WCHAR
*
searchIn
;
char
*
searchFor
;
WCHAR
*
searchFor
;
s
=
strdup
(
endOfVar
+
1
);
s
=
WCMD_strdupW
(
endOfVar
+
1
);
if
(
equalspos
==
NULL
)
return
start
+
1
;
if
(
equalspos
==
NULL
)
return
start
+
1
;
/* Null terminate both strings */
/* Null terminate both strings */
thisVar
[
strlen
(
thisVar
)
-
1
]
=
0x00
;
thisVar
[
strlen
W
(
thisVar
)
-
1
]
=
0x00
;
*
equalspos
=
0x00
;
*
equalspos
=
0x00
;
/* Since we need to be case insensitive, copy the 2 buffers */
/* Since we need to be case insensitive, copy the 2 buffers */
searchIn
=
strdup
(
thisVarContents
);
searchIn
=
WCMD_strdupW
(
thisVarContents
);
CharUpperBuff
(
searchIn
,
strlen
(
thisVarContents
));
CharUpperBuff
(
searchIn
,
strlen
W
(
thisVarContents
));
searchFor
=
strdup
(
colonpos
+
1
);
searchFor
=
WCMD_strdupW
(
colonpos
+
1
);
CharUpperBuff
(
searchFor
,
strlen
(
colonpos
+
1
));
CharUpperBuff
(
searchFor
,
strlen
W
(
colonpos
+
1
));
/* Handle wildcard case */
/* Handle wildcard case */
if
(
*
(
colonpos
+
1
)
==
'*'
)
{
if
(
*
(
colonpos
+
1
)
==
'*'
)
{
/* Search for string to replace */
/* Search for string to replace */
found
=
strstr
(
searchIn
,
searchFor
+
1
);
found
=
strstr
W
(
searchIn
,
searchFor
+
1
);
if
(
found
)
{
if
(
found
)
{
/* Do replacement */
/* Do replacement */
strcpy
(
start
,
replacewith
);
strcpy
W
(
start
,
replacewith
);
strcat
(
start
,
thisVarContents
+
(
found
-
searchIn
)
+
strlen
(
searchFor
+
1
));
strcat
W
(
start
,
thisVarContents
+
(
found
-
searchIn
)
+
strlenW
(
searchFor
+
1
));
strcat
(
start
,
s
);
strcat
W
(
start
,
s
);
free
(
s
);
free
(
s
);
}
else
{
}
else
{
/* Copy as it */
/* Copy as it */
strcpy
(
start
,
thisVarContents
);
strcpy
W
(
start
,
thisVarContents
);
strcat
(
start
,
s
);
strcat
W
(
start
,
s
);
}
}
}
else
{
}
else
{
/* Loop replacing all instances */
/* Loop replacing all instances */
char
*
lastFound
=
searchIn
;
WCHAR
*
lastFound
=
searchIn
;
char
*
outputposn
=
start
;
WCHAR
*
outputposn
=
start
;
*
start
=
0x00
;
*
start
=
0x00
;
while
((
found
=
strstr
(
lastFound
,
searchFor
)))
{
while
((
found
=
strstr
W
(
lastFound
,
searchFor
)))
{
strncpy
(
outputposn
,
lstrcpynW
(
outputposn
,
thisVarContents
+
(
lastFound
-
searchIn
),
thisVarContents
+
(
lastFound
-
searchIn
),
(
found
-
lastFound
));
(
found
-
lastFound
)
+
1
);
outputposn
=
outputposn
+
(
found
-
lastFound
);
outputposn
=
outputposn
+
(
found
-
lastFound
);
*
outputposn
=
0x00
;
strcatW
(
outputposn
,
replacewith
);
strcat
(
outputposn
,
replacewith
);
outputposn
=
outputposn
+
strlenW
(
replacewith
);
outputposn
=
outputposn
+
strlen
(
replacewith
);
lastFound
=
found
+
strlenW
(
searchFor
);
lastFound
=
found
+
strlen
(
searchFor
);
}
}
strcat
(
outputposn
,
strcat
W
(
outputposn
,
thisVarContents
+
(
lastFound
-
searchIn
));
thisVarContents
+
(
lastFound
-
searchIn
));
strcat
(
outputposn
,
s
);
strcat
W
(
outputposn
,
s
);
}
}
free
(
searchIn
);
free
(
searchIn
);
free
(
searchFor
);
free
(
searchFor
);
...
@@ -1645,13 +1778,65 @@ static char *WCMD_expand_envvar(char *start) {
...
@@ -1645,13 +1778,65 @@ static char *WCMD_expand_envvar(char *start) {
* Load a string from the resource file, handling any error
* Load a string from the resource file, handling any error
* Returns string retrieved from resource file
* Returns string retrieved from resource file
*/
*/
char
*
WCMD_LoadMessage
(
UINT
id
)
{
WCHAR
*
WCMD_LoadMessage
(
UINT
id
)
{
static
char
msg
[
2048
];
static
WCHAR
msg
[
2048
];
const
char
failedMsg
[]
=
"Failed!"
;
static
const
WCHAR
failedMsg
[]
=
{
'F'
,
'a'
,
'i'
,
'l'
,
'e'
,
'd'
,
'!'
,
'\0'
}
;
if
(
!
LoadString
(
GetModuleHandle
(
NULL
),
id
,
msg
,
sizeof
(
msg
)))
{
if
(
!
LoadString
(
GetModuleHandle
(
NULL
),
id
,
msg
,
sizeof
(
msg
)
/
sizeof
(
WCHAR
)
))
{
WINE_FIXME
(
"LoadString failed with %d
\n
"
,
GetLastError
());
WINE_FIXME
(
"LoadString failed with %d
\n
"
,
GetLastError
());
lstrcpy
(
msg
,
failedMsg
);
strcpyW
(
msg
,
failedMsg
);
}
}
return
msg
;
return
msg
;
}
}
/*************************************************************************
* WCMD_strdupW
* A wide version of strdup as its missing from unicode.h
*/
WCHAR
*
WCMD_strdupW
(
WCHAR
*
input
)
{
int
len
=
strlenW
(
input
)
+
1
;
/* Note: Use malloc not HeapAlloc to emulate strdup */
WCHAR
*
result
=
malloc
(
len
*
sizeof
(
WCHAR
));
memcpy
(
result
,
input
,
len
*
sizeof
(
WCHAR
));
return
result
;
}
/***************************************************************************
* WCMD_Readfile
*
* Read characters in from a console/file, returning result in Unicode
* with signature identical to ReadFile
*/
BOOL
WCMD_ReadFile
(
const
HANDLE
hIn
,
WCHAR
*
intoBuf
,
const
DWORD
maxChars
,
LPDWORD
charsRead
,
const
LPOVERLAPPED
unused
)
{
BOOL
res
;
/* Try to read from console as Unicode */
res
=
ReadConsoleW
(
hIn
,
intoBuf
,
maxChars
,
charsRead
,
NULL
);
/* If reading from console has failed we assume its file
i/o so read in and convert from OEM codepage */
if
(
!
res
)
{
DWORD
numRead
;
/*
* Allocate buffer to use when reading from file. Not freed
*/
if
(
!
output_bufA
)
output_bufA
=
HeapAlloc
(
GetProcessHeap
(),
0
,
MAX_WRITECONSOLE_SIZE
);
if
(
!
output_bufA
)
{
WINE_FIXME
(
"Out of memory - could not allocate ansi 64K buffer
\n
"
);
return
0
;
}
/* Read from file (assume OEM codepage) */
res
=
ReadFile
(
hIn
,
output_bufA
,
maxChars
,
&
numRead
,
unused
);
/* Convert from OEM */
*
charsRead
=
MultiByteToWideChar
(
GetConsoleCP
(),
0
,
output_bufA
,
numRead
,
intoBuf
,
maxChars
);
}
return
res
;
}
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