2 * MISC.C - misc. functions.
11 * moved functions in here
13 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
14 * added config.h include
16 * 18-Dec-1998 (Eric Kohl)
17 * Changed split() to accept quoted arguments.
18 * Removed parse_firstarg().
20 * 23-Jan-1999 (Eric Kohl)
21 * Fixed an ugly bug in split(). In rare cases (last character
22 * of the string is a space) it ignored the NULL character and
23 * tried to add the following to the argument list.
25 * 28-Jan-1999 (Eric Kohl)
26 * FileGetString() seems to be working now.
28 * 06-Nov-1999 (Eric Kohl)
29 * Added PagePrompt() and FilePrompt().
31 * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
32 * Remove all hardcode string to En.rc
39 * get a character out-of-band and honor Ctrl-Break characters
44 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
45 INPUT_RECORD irBuffer
;
50 ReadConsoleInput (hInput
, &irBuffer
, 1, &dwRead
);
51 if ((irBuffer
.EventType
== KEY_EVENT
) &&
52 (irBuffer
.Event
.KeyEvent
.bKeyDown
== TRUE
))
54 if (irBuffer
.Event
.KeyEvent
.dwControlKeyState
&
55 (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))
57 if (irBuffer
.Event
.KeyEvent
.wVirtualKeyCode
== 'C')
63 else if ((irBuffer
.Event
.KeyEvent
.wVirtualKeyCode
== VK_SHIFT
) ||
64 (irBuffer
.Event
.KeyEvent
.wVirtualKeyCode
== VK_MENU
) ||
65 (irBuffer
.Event
.KeyEvent
.wVirtualKeyCode
== VK_CONTROL
))
79 return irBuffer
.Event
.KeyEvent
.uChar
.AsciiChar
;
81 return irBuffer
.Event
.KeyEvent
.uChar
.UnicodeChar
;
86 * Takes a path in and returns it with the correct case of the letters
88 VOID
GetPathCase( TCHAR
* Path
, TCHAR
* OutPath
)
91 TCHAR TempPath
[MAX_PATH
];
92 WIN32_FIND_DATA FindFileData
;
94 _tcscpy(TempPath
, _T(""));
95 _tcscpy(OutPath
, _T(""));
98 for(i
= 0; i
< _tcslen(Path
); i
++)
100 if(Path
[i
] != _T('\\'))
102 _tcsncat(TempPath
, &Path
[i
], 1);
103 if(i
!= _tcslen(Path
) - 1)
106 /* Handle the base part of the path different.
107 Because if you put it into findfirstfile, it will
108 return your current folder */
109 if(_tcslen(TempPath
) == 2 && TempPath
[1] == _T(':'))
111 _tcscat(OutPath
, TempPath
);
112 _tcscat(OutPath
, _T("\\"));
113 _tcscat(TempPath
, _T("\\"));
117 hFind
= FindFirstFile(TempPath
,&FindFileData
);
118 if(hFind
== INVALID_HANDLE_VALUE
)
120 _tcscpy(OutPath
, Path
);
123 _tcscat(TempPath
, _T("\\"));
124 _tcscat(OutPath
, FindFileData
.cFileName
);
125 _tcscat(OutPath
, _T("\\"));
132 * Check if Ctrl-Break was pressed during the last calls
135 BOOL
CheckCtrlBreak (INT mode
)
137 static BOOL bLeaveAll
= FALSE
; /* leave all batch files */
138 TCHAR options
[4]; /* Yes, No, All */
143 case BREAK_OUTOFBATCH
:
147 case BREAK_BATCHFILE
:
154 LoadString(CMD_ModuleHandle
, STRING_COPY_OPTION
, options
, 4);
156 /* we need to be sure the string arrives on the screen! */
159 ConOutResPuts(STRING_CANCEL_BATCH_FILE
);
160 c
= _totupper(cgetchar());
161 } while (!(_tcschr(options
, c
) || c
== _T('\3')) || !c
);
163 ConOutPuts (_T("\r\n"));
166 return bCtrlBreak
= FALSE
; /* ignore */
168 /* leave all batch files */
169 bLeaveAll
= ((c
== options
[2]) || (c
== _T('\3')));
178 /* state processed */
183 /* add new entry for new argument */
184 BOOL
add_entry (LPINT ac
, LPTSTR
**arg
, LPCTSTR entry
)
189 q
= cmd_alloc ((_tcslen(entry
) + 1) * sizeof (TCHAR
));
197 *arg
= cmd_realloc (oldarg
, (*ac
+ 2) * sizeof (LPTSTR
));
206 (*arg
)[++(*ac
)] = NULL
;
211 static BOOL
expand (LPINT ac
, LPTSTR
**arg
, LPCTSTR pattern
)
214 WIN32_FIND_DATA FindData
;
217 LPTSTR dirpart
, fullname
;
219 pathend
= _tcsrchr (pattern
, _T('\\'));
222 dirpart
= cmd_alloc((pathend
- pattern
+ 2) * sizeof(TCHAR
));
227 memcpy(dirpart
, pattern
, pathend
- pattern
+ 1);
228 dirpart
[pathend
- pattern
+ 1] = _T('\0');
234 hFind
= FindFirstFile (pattern
, &FindData
);
235 if (INVALID_HANDLE_VALUE
!= hFind
)
241 fullname
= cmd_alloc((_tcslen(dirpart
) + _tcslen(FindData
.cFileName
) + 1) * sizeof(TCHAR
));
242 if (NULL
== fullname
)
248 _tcscat (_tcscpy (fullname
, dirpart
), FindData
.cFileName
);
249 ok
= add_entry(ac
, arg
, fullname
);
255 ok
= add_entry(ac
, arg
, FindData
.cFileName
);
257 } while (FindNextFile (hFind
, &FindData
) && ok
);
262 ok
= add_entry(ac
, arg
, pattern
);
274 * split - splits a line up into separate arguments, deliminators
275 * are spaces and slashes ('/').
278 LPTSTR
*split (LPTSTR s
, LPINT args
, BOOL expand_wildcards
)
286 arg
= cmd_alloc (sizeof (LPTSTR
));
294 BOOL bQuoted
= FALSE
;
296 /* skip leading spaces */
297 while (*s
&& (_istspace (*s
) || _istcntrl (*s
)))
302 /* the first character can be '/' */
306 /* skip to next word delimiter or start of next option */
307 while (_istprint(*s
) && (bQuoted
|| (!_istspace(*s
) && *s
!= _T('/'))))
309 /* if quote (") then set bQuoted */
310 bQuoted
^= (*s
== _T('\"'));
314 /* a word was found */
317 q
= cmd_alloc (((len
= s
- start
) + 1) * sizeof (TCHAR
));
322 memcpy (q
, start
, len
* sizeof (TCHAR
));
325 if (expand_wildcards
&& _T('/') != *start
&&
326 (NULL
!= _tcschr(q
, _T('*')) || NULL
!= _tcschr(q
, _T('?'))))
328 if (! expand(&ac
, &arg
, q
))
337 if (! add_entry(&ac
, &arg
, q
))
353 /* splitspace() is a function which uses JUST spaces as delimeters. split() uses "/" AND spaces.
354 * The way it works is real similar to split(), search the difference ;)
355 * splitspace is needed for commands such as "move" where paths as C:\this/is\allowed/ are allowed
357 LPTSTR
*splitspace (LPTSTR s
, LPINT args
)
365 arg
= cmd_alloc (sizeof (LPTSTR
));
373 BOOL bQuoted
= FALSE
;
375 /* skip leading spaces */
376 while (*s
&& (_istspace (*s
) || _istcntrl (*s
)))
381 /* skip to next word delimiter or start of next option */
382 while (_istprint(*s
) && (bQuoted
|| !_istspace(*s
)))
384 /* if quote (") then set bQuoted */
385 bQuoted
^= (*s
== _T('\"'));
389 /* a word was found */
392 q
= cmd_alloc (((len
= s
- start
) + 1) * sizeof (TCHAR
));
397 memcpy (q
, start
, len
* sizeof (TCHAR
));
400 if (! add_entry(&ac
, &arg
, q
))
416 * freep -- frees memory used for a call to split
419 VOID
freep (LPTSTR
*p
)
434 LPTSTR
_stpcpy (LPTSTR dest
, LPCTSTR src
)
437 return (dest
+ _tcslen (src
));
441 StripQuotes(TCHAR
*in
)
455 * Checks if a path is valid (accessible)
458 BOOL
IsValidPathName (LPCTSTR pszPath
)
460 TCHAR szOldPath
[MAX_PATH
];
463 GetCurrentDirectory (MAX_PATH
, szOldPath
);
464 bResult
= SetCurrentDirectory (pszPath
);
466 SetCurrentDirectory (szOldPath
);
473 * Checks if a file exists (accessible)
476 BOOL
IsExistingFile (LPCTSTR pszPath
)
478 DWORD attr
= GetFileAttributes (pszPath
);
479 return (attr
!= 0xFFFFFFFF && (! (attr
& FILE_ATTRIBUTE_DIRECTORY
)) );
483 BOOL
IsExistingDirectory (LPCTSTR pszPath
)
485 DWORD attr
= GetFileAttributes (pszPath
);
486 return (attr
!= 0xFFFFFFFF && (attr
& FILE_ATTRIBUTE_DIRECTORY
) );
490 BOOL
FileGetString (HANDLE hFile
, LPTSTR lpBuffer
, INT nBufferLength
)
496 lpString
= cmd_alloc(nBufferLength
);
501 if (ReadFile(hFile
, lpString
, nBufferLength
- 1, &dwRead
, NULL
))
503 /* break at new line*/
504 CHAR
*end
= memchr(lpString
, '\n', dwRead
);
508 len
= (end
- lpString
) + 1;
509 SetFilePointer(hFile
, len
- dwRead
, NULL
, FILE_CURRENT
);
521 lpString
[len
++] = '\0';
523 MultiByteToWideChar(OutputCodePage
, 0, lpString
, -1, lpBuffer
, len
);
529 INT
PagePrompt (VOID
)
533 ConOutResPuts(STRING_MISC_HELP1
);
535 RemoveBreakHandler ();
542 while ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_SHIFT
) ||
543 (ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_MENU
) ||
544 (ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_CONTROL
));
549 if ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) ||
550 ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== _T('C')) &&
551 (ir
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))))
561 INT
FilePromptYN (UINT resID
)
563 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
565 // LPTSTR szKeys = _T("yna");
571 ConOutResPrintf (resID
);
573 /* preliminary fix */
574 ConInString (szIn
, 10);
575 ConOutPrintf (_T("\n"));
578 for (p
= szIn
; _istspace (*p
); p
++)
581 LoadString(CMD_ModuleHandle
, STRING_CHOICE_OPTION
, szMsg
, RC_STRING_MAX_SIZE
);
583 if (_tcsncmp(p
, &szMsg
[0], 1) == 0)
585 else if (_tcsncmp(p
, &szMsg
[1], 1) == 0)
588 else if (*p
== _T('\03'))
595 /* unfinished sollution */
597 RemoveBreakHandler ();
603 cKey
= _totlower (ir
.Event
.KeyEvent
.uChar
.AsciiChar
);
604 if (_tcschr (szKeys
, cKey
[0]) == NULL
)
609 while ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_SHIFT
) ||
610 (ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_MENU
) ||
611 (ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_CONTROL
));
616 if ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) ||
617 ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== 'C') &&
618 (ir
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))))
626 INT
FilePromptYNA (UINT resID
)
628 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
630 // LPTSTR szKeys = _T("yna");
636 ConOutResPrintf (resID
);
638 /* preliminary fix */
639 ConInString (szIn
, 10);
640 ConOutPrintf (_T("\n"));
643 for (p
= szIn
; _istspace (*p
); p
++)
646 LoadString( CMD_ModuleHandle
, STRING_COPY_OPTION
, szMsg
, RC_STRING_MAX_SIZE
);
648 if (_tcsncmp(p
, &szMsg
[0], 1) == 0)
650 else if (_tcsncmp(p
, &szMsg
[1], 1) == 0)
652 else if (_tcsncmp(p
, &szMsg
[2], 1) == 0)
656 else if (*p
== _T('\03'))
663 /* unfinished sollution */
665 RemoveBreakHandler ();
671 cKey
= _totlower (ir
.Event
.KeyEvent
.uChar
.AsciiChar
);
672 if (_tcschr (szKeys
, cKey
[0]) == NULL
)
675 while ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_SHIFT
) ||
676 (ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_MENU
) ||
677 (ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_CONTROL
));
682 if ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) ||
683 ((ir
.Event
.KeyEvent
.wVirtualKeyCode
== _T('C')) &&
684 (ir
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))))