File: wcmd.h

package info (click to toggle)
wine 10.0~repack-6
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 325,920 kB
  • sloc: ansic: 4,156,003; perl: 23,800; yacc: 22,031; javascript: 15,872; makefile: 12,346; pascal: 9,519; objc: 6,923; lex: 5,273; xml: 3,219; python: 2,673; cpp: 1,741; sh: 893; java: 750; asm: 299; cs: 62
file content (452 lines) | stat: -rw-r--r-- 14,499 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
/*
 * CMD - Wine-compatible command line interface.
 *
 * Copyright (C) 1999 D A Pickles
 * Copyright (C) 2007 J Edmeades
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define IDI_ICON1	1
#include <windows.h>
#include <windef.h>
#include <winternl.h>
#ifndef RC_INVOKED
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <wchar.h>

/* msdn specified max for Win XP */
#define MAXSTRING 8192

/* Data structure to express a redirection */
typedef struct _CMD_REDIRECTION
{
    enum CMD_REDIRECTION_KIND {REDIR_READ_FROM, REDIR_WRITE_TO, REDIR_WRITE_APPEND, REDIR_WRITE_CLONE} kind;
    unsigned short fd;
    struct _CMD_REDIRECTION *next;
    union
    {
        unsigned short clone; /* only if kind is REDIR_WRITE_CLONE */
        WCHAR file[1];        /* only if kind is READ_FROM, WRITE or WRITE_APPEND */
    };
} CMD_REDIRECTION;

/* Data structure to hold commands delimiters/separators */

typedef enum _CMD_OPERATOR
{
    CMD_SINGLE,      /* single command          */
    CMD_CONCAT,      /* &                       */
    CMD_ONFAILURE,   /* ||                      */
    CMD_ONSUCCESS,   /* &&                      */
    CMD_PIPE,        /* Single |                */
    CMD_IF,          /* IF command              */
    CMD_FOR,         /* FOR command             */
} CMD_OPERATOR;

/* Data structure to hold commands to be processed */

enum cond_operator {CMD_IF_ERRORLEVEL, CMD_IF_EXIST, CMD_IF_DEFINED,
                    CMD_IF_BINOP_EQUAL /* == */, CMD_IF_BINOP_LSS, CMD_IF_BINOP_LEQ, CMD_IF_BINOP_EQU,
                    CMD_IF_BINOP_NEQ, CMD_IF_BINOP_GEQ, CMD_IF_BINOP_GTR};
typedef struct _CMD_IF_CONDITION
{
    unsigned case_insensitive : 1,
             negated : 1,
             op;
    union
    {
        /* CMD_IF_ERRORLEVEL, CMD_IF_EXIST, CMD_IF_DEFINED */
        const WCHAR *operand;
        /* CMD_BINOP_EQUAL, CMD_BINOP_LSS, CMD_BINOP_LEQ, CMD_BINOP_EQU, CMD_BINOP_NEQ, CMD_BINOP_GEQ, CMD_BINOP_GTR */
        struct
        {
            const WCHAR *left;
            const WCHAR *right;
        };
    };
} CMD_IF_CONDITION;

#define CMD_FOR_FLAG_TREE_RECURSE (1u << 0)
#define CMD_FOR_FLAG_TREE_INCLUDE_FILES (1u << 1)
#define CMD_FOR_FLAG_TREE_INCLUDE_DIRECTORIES (1u << 2)

typedef struct _CMD_FOR_CONTROL
{
    enum for_control_operator {CMD_FOR_FILETREE, CMD_FOR_FILE_SET /* /F */,
                               CMD_FOR_NUMBERS /* /L */} operator;
    unsigned flags;               /* |-ed CMD_FOR_FLAG_* */
    unsigned variable_index;
    const WCHAR *set;
    union
    {
        const WCHAR *root_dir;    /* for CMD_FOR_FILETREE */
        struct                    /* for CMD_FOR_FILE_SET */
        {
            WCHAR eol;
            BOOL use_backq;
            int num_lines_to_skip;
            const WCHAR *delims;
            const WCHAR *tokens;
        };
    };
} CMD_FOR_CONTROL;

typedef struct _CMD_NODE
{
    CMD_OPERATOR      op;            /* operator */
    CMD_REDIRECTION  *redirects;     /* Redirections */
    union
    {
        WCHAR        *command;       /* CMD_SINGLE */
        struct                       /* binary operator (CMD_CONCAT, ONFAILURE, ONSUCCESS, PIPE) */
        {
            struct _CMD_NODE *left;
            struct _CMD_NODE *right;
        };
        struct                       /* CMD_IF */
        {
            CMD_IF_CONDITION  condition;
            struct _CMD_NODE *then_block;
            struct _CMD_NODE *else_block;
        };
        struct                       /* CMD_FOR */
        {
            CMD_FOR_CONTROL   for_ctrl;
            struct _CMD_NODE *do_block;
        };
    };
} CMD_NODE;

struct _DIRECTORY_STACK;
void WCMD_add_dirstowalk(struct _DIRECTORY_STACK *dirsToWalk);
struct _DIRECTORY_STACK *WCMD_dir_stack_create(const WCHAR *dir, const WCHAR *file);
struct _DIRECTORY_STACK *WCMD_dir_stack_free(struct _DIRECTORY_STACK *dir);

/* The return code:
 * - some of them are directly mapped to kernel32's errors
 * - some others are cmd.exe specific
 * - ABORTED if used to break out of FOR/IF blocks (to handle GOTO, EXIT commands)
 */
typedef int RETURN_CODE;
#define RETURN_CODE_SYNTAX_ERROR         255
#define RETURN_CODE_CANT_LAUNCH          9009
#define RETURN_CODE_ABORTED              (-999999)

BOOL WCMD_print_volume_information(const WCHAR *);

RETURN_CODE WCMD_assoc(const WCHAR *, BOOL);
RETURN_CODE WCMD_call(WCHAR *command);
RETURN_CODE WCMD_choice(WCHAR *);
RETURN_CODE WCMD_clear_screen(void);
RETURN_CODE WCMD_color(void);
RETURN_CODE WCMD_copy(WCHAR *);
RETURN_CODE WCMD_create_dir(WCHAR *);
RETURN_CODE WCMD_delete(WCHAR *);
RETURN_CODE WCMD_directory(WCHAR *);
RETURN_CODE WCMD_echo(const WCHAR *);
RETURN_CODE WCMD_endlocal(void);
void WCMD_enter_paged_mode(const WCHAR *);
RETURN_CODE WCMD_exit(void);
BOOL WCMD_get_fullpath(const WCHAR *, SIZE_T, WCHAR *, WCHAR **);
RETURN_CODE WCMD_give_help(WCHAR *args);
RETURN_CODE WCMD_goto(void);
RETURN_CODE WCMD_label(void);
void WCMD_leave_paged_mode(void);
RETURN_CODE WCMD_more(WCHAR *);
RETURN_CODE WCMD_move (void);
WCHAR* WINAPIV WCMD_format_string (const WCHAR *format, ...);
void WINAPIV WCMD_output (const WCHAR *format, ...);
void WINAPIV WCMD_output_stderr (const WCHAR *format, ...);
void WCMD_output_asis (const WCHAR *message);
void WCMD_output_asis_stderr (const WCHAR *message);
RETURN_CODE WCMD_pause(void);
RETURN_CODE WCMD_popd(void);
void WCMD_print_error (void);
RETURN_CODE WCMD_pushd(const WCHAR *args);
RETURN_CODE WCMD_remove_dir(WCHAR *command);
RETURN_CODE WCMD_rename(void);
RETURN_CODE WCMD_setlocal(WCHAR *args);
RETURN_CODE WCMD_setshow_date(void);
RETURN_CODE WCMD_setshow_default(const WCHAR *args);
RETURN_CODE WCMD_setshow_env(WCHAR *command);
RETURN_CODE WCMD_setshow_path(const WCHAR *args);
RETURN_CODE WCMD_setshow_prompt(void);
RETURN_CODE WCMD_setshow_time(void);
RETURN_CODE WCMD_shift(const WCHAR *args);
RETURN_CODE WCMD_start(WCHAR *args);
RETURN_CODE WCMD_title(const WCHAR *);
RETURN_CODE WCMD_type(WCHAR *);
RETURN_CODE WCMD_verify(void);
RETURN_CODE WCMD_version(void);
RETURN_CODE WCMD_volume(void);
RETURN_CODE WCMD_mklink(WCHAR *args);
RETURN_CODE WCMD_change_drive(WCHAR drive);

WCHAR *WCMD_fgets (WCHAR *buf, DWORD n, HANDLE stream);
WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, BOOL raw, BOOL wholecmdline);
WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, BOOL raw,
                                   BOOL wholecmdline, const WCHAR *delims);
WCHAR *WCMD_skip_leading_spaces (WCHAR *string);
BOOL WCMD_keyword_ws_found(const WCHAR *keyword, const WCHAR *ptr);
void WCMD_HandleTildeModifiers(WCHAR **start, BOOL atExecute);

WCHAR *WCMD_strip_quotes(WCHAR *cmd);
WCHAR *WCMD_LoadMessage(UINT id);
WCHAR *WCMD_strsubstW(WCHAR *start, const WCHAR* next, const WCHAR* insert, int len);
BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars, LPDWORD charsRead);

enum read_parse_line {RPL_SUCCESS, RPL_EOF, RPL_SYNTAXERROR};
enum read_parse_line WCMD_ReadAndParseLine(const WCHAR *initialcmd, CMD_NODE **output);
void      node_dispose_tree(CMD_NODE *cmds);
RETURN_CODE node_execute(CMD_NODE *node);

RETURN_CODE WCMD_call_batch(const WCHAR *, WCHAR *);
RETURN_CODE WCMD_call_command(WCHAR *command);
RETURN_CODE WCMD_run_builtin_command(int cmd_index, WCHAR *cmd);

BOOL WCMD_find_label(HANDLE h, const WCHAR*, LARGE_INTEGER *pos);
void WCMD_set_label_end(WCHAR *string);

void *xrealloc(void *, size_t) __WINE_ALLOC_SIZE(2) __WINE_DEALLOC(free);

static inline void *xalloc(size_t sz) __WINE_MALLOC;
static inline void *xalloc(size_t sz)
{
    return xrealloc(NULL, sz);
}

static inline WCHAR *xstrdupW(const WCHAR *str)
{
    WCHAR *ret = NULL;

    if(str) {
        size_t size;

        size = (lstrlenW(str)+1)*sizeof(WCHAR);
        ret = xalloc(size);
        memcpy(ret, str, size);
    }

    return ret;
}

static inline BOOL ends_with_backslash( const WCHAR *path )
{
    return path[0] && path[lstrlenW(path) - 1] == '\\';
}

int evaluate_if_condition(WCHAR *p, WCHAR **command, int *test, int *negate);

/* Data structure to hold context when executing batch files */

typedef struct _BATCH_CONTEXT
{
    WCHAR *command;	  /* The command which invoked the batch file */
    LARGE_INTEGER file_position;
    WCHAR *batchfileW;    /* Name of same */
    int shift_count[10];  /* Offset in terms of shifts for %0 - %9 */
    struct _BATCH_CONTEXT *prev_context; /* Pointer to the previous context block */
    BOOL  skip_rest;      /* Skip the rest of the batch program and exit */
} BATCH_CONTEXT;

/* Data structure to handle building lists during recursive calls */

struct env_stack
{
    BATCH_CONTEXT *context;
    struct env_stack *next;
    union
    {
        int     stackdepth;   /* Only used for pushd and popd */
        WCHAR   cwd;          /* Only used for set/endlocal   */
    } u;
    WCHAR *strings;
    BOOL delayedsubst;        /* Is delayed substitution in effect */
};

/* Data structure to save setlocal and pushd information */

typedef struct _DIRECTORY_STACK
{
  struct _DIRECTORY_STACK *next;
  WCHAR  *dirName;
  WCHAR  *fileName;
} DIRECTORY_STACK;

static inline const char *debugstr_for_var(WCHAR ch)
{
    static char tmp[16];
    if (iswprint(ch))
        sprintf(tmp, "%%%lc", ch);
    else
        sprintf(tmp, "%%[%x]", ch);
    return tmp;
}

typedef struct _FOR_CONTEXT
{
    struct _FOR_CONTEXT *previous;
    WCHAR *variable[128];
} FOR_CONTEXT;

extern FOR_CONTEXT *forloopcontext;
static inline BOOL for_var_is_valid(WCHAR ch) {return ch && ch < ARRAY_SIZE(forloopcontext->variable);}

void WCMD_save_for_loop_context(BOOL reset);
void WCMD_restore_for_loop_context(void);
void WCMD_set_for_loop_variable(unsigned varidx, const WCHAR *value);

/*
 * Global variables quals, param1, param2 contain the current qualifiers
 * (uppercased and concatenated) and parameters entered, with environment
 * variables and batch parameters substitution already done.
 */
extern WCHAR quals[MAXSTRING], param1[MAXSTRING], param2[MAXSTRING];
extern int errorlevel;
extern BATCH_CONTEXT *context;
extern BOOL delayedsubst;

static inline BOOL WCMD_is_in_context(const WCHAR *ext)
{
    size_t c_len, e_len;
    if (!context) return FALSE;
    if (!ext) return TRUE;
    c_len = wcslen(context->batchfileW);
    e_len = wcslen(ext);
    return (c_len > e_len) && !wcsicmp(&context->batchfileW[c_len - e_len], ext);
}

 #endif /* !RC_INVOKED */

/*
 *	Serial nos of builtin commands. These constants must be in step with
 *	the list of strings defined in wcmd.rc, and WCMD_EXIT *must* always be
 *	the last one.
 *
 *	Yes it *would* be nice to use an enumeration here, but the Resource
 *	Compiler won't accept resource IDs from enumerations :-(
 */

#define WCMD_CALL      0
#define WCMD_CD        1
#define WCMD_CHDIR     2
#define WCMD_CLS       3
#define WCMD_COPY      4
/* no longer used slot */
#define WCMD_DATE      6
#define WCMD_DEL       7
#define WCMD_DIR       8
#define WCMD_ECHO      9
#define WCMD_ERASE    10
#define WCMD_FOR      11
#define WCMD_GOTO     12
#define WCMD_HELP     13
#define WCMD_IF       14
#define WCMD_LABEL    15
#define WCMD_MD       16
#define WCMD_MKDIR    17
#define WCMD_MOVE     18
#define WCMD_PATH     19
#define WCMD_PAUSE    20
#define WCMD_PROMPT   21
#define WCMD_REM      22
#define WCMD_REN      23
#define WCMD_RENAME   24
#define WCMD_RD       25
#define WCMD_RMDIR    26
#define WCMD_SET      27
#define WCMD_SHIFT    28
#define WCMD_START    29
#define WCMD_TIME     30
#define WCMD_TITLE    31
#define WCMD_TYPE     32
#define WCMD_VERIFY   33
#define WCMD_VER      34
#define WCMD_VOL      35

#define WCMD_ENDLOCAL 36
#define WCMD_SETLOCAL 37
#define WCMD_PUSHD    38
#define WCMD_POPD     39
#define WCMD_ASSOC    40
#define WCMD_COLOR    41
#define WCMD_FTYPE    42
#define WCMD_MORE     43
#define WCMD_CHOICE   44
#define WCMD_MKLINK   45
#define WCMD_CHGDRIVE 46

/* Must be last in list */
#define WCMD_EXIT     47

/* Some standard messages */
extern WCHAR anykey[];
extern WCHAR version_string[];

/* Translated messages */
#define WCMD_ALLHELP          1000
#define WCMD_CONFIRM          1001
#define WCMD_YES              1002
#define WCMD_NO               1003
#define WCMD_NOASSOC          1004
#define WCMD_NOFTYPE          1005
#define WCMD_OVERWRITE        1006
#define WCMD_MORESTR          1007
#define WCMD_TRUNCATEDLINE    1008
#define WCMD_NYI              1009
#define WCMD_NOARG            1010
#define WCMD_SYNTAXERR        1011
#define WCMD_FILENOTFOUND     1012
#define WCMD_NOCMDHELP        1013
#define WCMD_NOTARGET         1014
#define WCMD_CURRENTDATE      1015
#define WCMD_CURRENTTIME      1016
#define WCMD_NEWDATE          1017
#define WCMD_NEWTIME          1018
#define WCMD_MISSINGENV       1019
#define WCMD_READFAIL         1020
#define WCMD_CALLINSCRIPT     1021
#define WCMD_ALL              1022
#define WCMD_DELPROMPT        1023
#define WCMD_ECHOPROMPT       1024
#define WCMD_VERIFYPROMPT     1025
#define WCMD_VERIFYERR        1026
#define WCMD_ARGERR           1027
#define WCMD_VOLUMESERIALNO   1028
#define WCMD_VOLUMEPROMPT     1029
#define WCMD_ANYKEY           1031
#define WCMD_CONSTITLE        1032
#define WCMD_VERSION          1033
#define WCMD_MOREPROMPT       1034
#define WCMD_LINETOOLONG      1035
#define WCMD_VOLUMELABEL      1036
#define WCMD_VOLUMENOLABEL    1037
#define WCMD_YESNO            1038
#define WCMD_YESNOALL         1039
#define WCMD_NO_COMMAND_FOUND 1040
#define WCMD_DIVIDEBYZERO     1041
#define WCMD_NOOPERAND        1042
#define WCMD_NOOPERATOR       1043
#define WCMD_BADPAREN         1044
#define WCMD_BADHEXOCT        1045
#define WCMD_FILENAMETOOLONG  1046
#define WCMD_BADTOKEN         1047
#define WCMD_ENDOFLINE        1048
#define WCMD_ENDOFFILE        1049