Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmisc.c
Go to the documentation of this file.
00001 /* 00002 * MISC.C - misc. functions. 00003 * 00004 * 00005 * History: 00006 * 00007 * 07/12/98 (Rob Lake) 00008 * started 00009 * 00010 * 07/13/98 (Rob Lake) 00011 * moved functions in here 00012 * 00013 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>) 00014 * added config.h include 00015 * 00016 * 18-Dec-1998 (Eric Kohl) 00017 * Changed split() to accept quoted arguments. 00018 * Removed parse_firstarg(). 00019 * 00020 * 23-Jan-1999 (Eric Kohl) 00021 * Fixed an ugly bug in split(). In rare cases (last character 00022 * of the string is a space) it ignored the NULL character and 00023 * tried to add the following to the argument list. 00024 * 00025 * 28-Jan-1999 (Eric Kohl) 00026 * FileGetString() seems to be working now. 00027 * 00028 * 06-Nov-1999 (Eric Kohl) 00029 * Added PagePrompt() and FilePrompt(). 00030 * 00031 * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>) 00032 * Remove all hardcode string to En.rc 00033 */ 00034 00035 #include <precomp.h> 00036 00037 00038 /* 00039 * get a character out-of-band and honor Ctrl-Break characters 00040 */ 00041 TCHAR 00042 cgetchar (VOID) 00043 { 00044 HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); 00045 INPUT_RECORD irBuffer; 00046 DWORD dwRead; 00047 00048 do 00049 { 00050 ReadConsoleInput (hInput, &irBuffer, 1, &dwRead); 00051 if ((irBuffer.EventType == KEY_EVENT) && 00052 (irBuffer.Event.KeyEvent.bKeyDown == TRUE)) 00053 { 00054 if (irBuffer.Event.KeyEvent.dwControlKeyState & 00055 (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) 00056 { 00057 if (irBuffer.Event.KeyEvent.wVirtualKeyCode == 'C') 00058 { 00059 bCtrlBreak = TRUE; 00060 break; 00061 } 00062 } 00063 else if ((irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || 00064 (irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || 00065 (irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)) 00066 { 00067 ; 00068 } 00069 00070 else 00071 { 00072 break; 00073 } 00074 } 00075 } 00076 while (TRUE); 00077 00078 #ifndef _UNICODE 00079 return irBuffer.Event.KeyEvent.uChar.AsciiChar; 00080 #else 00081 return irBuffer.Event.KeyEvent.uChar.UnicodeChar; 00082 #endif /* _UNICODE */ 00083 } 00084 00085 /* 00086 * Takes a path in and returns it with the correct case of the letters 00087 */ 00088 VOID GetPathCase( TCHAR * Path, TCHAR * OutPath) 00089 { 00090 UINT i = 0; 00091 TCHAR TempPath[MAX_PATH]; 00092 WIN32_FIND_DATA FindFileData; 00093 HANDLE hFind; 00094 _tcscpy(TempPath, _T("")); 00095 _tcscpy(OutPath, _T("")); 00096 00097 00098 for(i = 0; i < _tcslen(Path); i++) 00099 { 00100 if(Path[i] != _T('\\')) 00101 { 00102 _tcsncat(TempPath, &Path[i], 1); 00103 if(i != _tcslen(Path) - 1) 00104 continue; 00105 } 00106 /* Handle the base part of the path different. 00107 Because if you put it into findfirstfile, it will 00108 return your current folder */ 00109 if(_tcslen(TempPath) == 2 && TempPath[1] == _T(':')) 00110 { 00111 _tcscat(OutPath, TempPath); 00112 _tcscat(OutPath, _T("\\")); 00113 _tcscat(TempPath, _T("\\")); 00114 } 00115 else 00116 { 00117 hFind = FindFirstFile(TempPath,&FindFileData); 00118 if(hFind == INVALID_HANDLE_VALUE) 00119 { 00120 _tcscpy(OutPath, Path); 00121 return; 00122 } 00123 _tcscat(TempPath, _T("\\")); 00124 _tcscat(OutPath, FindFileData.cFileName); 00125 _tcscat(OutPath, _T("\\")); 00126 FindClose(hFind); 00127 } 00128 } 00129 } 00130 00131 /* 00132 * Check if Ctrl-Break was pressed during the last calls 00133 */ 00134 00135 BOOL CheckCtrlBreak (INT mode) 00136 { 00137 static BOOL bLeaveAll = FALSE; /* leave all batch files */ 00138 TCHAR options[4]; /* Yes, No, All */ 00139 TCHAR c; 00140 00141 switch (mode) 00142 { 00143 case BREAK_OUTOFBATCH: 00144 bLeaveAll = 0; 00145 return FALSE; 00146 00147 case BREAK_BATCHFILE: 00148 if (bLeaveAll) 00149 return TRUE; 00150 00151 if (!bCtrlBreak) 00152 return FALSE; 00153 00154 LoadString(CMD_ModuleHandle, STRING_COPY_OPTION, options, 4); 00155 00156 /* we need to be sure the string arrives on the screen! */ 00157 do 00158 { 00159 ConOutResPuts(STRING_CANCEL_BATCH_FILE); 00160 c = _totupper(cgetchar()); 00161 } while (!(_tcschr(options, c) || c == _T('\3')) || !c); 00162 00163 ConOutPuts (_T("\r\n")); 00164 00165 if (c == options[1]) 00166 return bCtrlBreak = FALSE; /* ignore */ 00167 00168 /* leave all batch files */ 00169 bLeaveAll = ((c == options[2]) || (c == _T('\3'))); 00170 break; 00171 00172 case BREAK_INPUT: 00173 if (!bCtrlBreak) 00174 return FALSE; 00175 break; 00176 } 00177 00178 /* state processed */ 00179 bCtrlBreak = FALSE; 00180 return TRUE; 00181 } 00182 00183 /* add new entry for new argument */ 00184 BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry) 00185 { 00186 LPTSTR q; 00187 LPTSTR *oldarg; 00188 00189 q = cmd_alloc ((_tcslen(entry) + 1) * sizeof (TCHAR)); 00190 if (NULL == q) 00191 { 00192 return FALSE; 00193 } 00194 00195 _tcscpy (q, entry); 00196 oldarg = *arg; 00197 *arg = cmd_realloc (oldarg, (*ac + 2) * sizeof (LPTSTR)); 00198 if (NULL == *arg) 00199 { 00200 *arg = oldarg; 00201 return FALSE; 00202 } 00203 00204 /* save new entry */ 00205 (*arg)[*ac] = q; 00206 (*arg)[++(*ac)] = NULL; 00207 00208 return TRUE; 00209 } 00210 00211 static BOOL expand (LPINT ac, LPTSTR **arg, LPCTSTR pattern) 00212 { 00213 HANDLE hFind; 00214 WIN32_FIND_DATA FindData; 00215 BOOL ok; 00216 LPCTSTR pathend; 00217 LPTSTR dirpart, fullname; 00218 00219 pathend = _tcsrchr (pattern, _T('\\')); 00220 if (NULL != pathend) 00221 { 00222 dirpart = cmd_alloc((pathend - pattern + 2) * sizeof(TCHAR)); 00223 if (NULL == dirpart) 00224 { 00225 return FALSE; 00226 } 00227 memcpy(dirpart, pattern, pathend - pattern + 1); 00228 dirpart[pathend - pattern + 1] = _T('\0'); 00229 } 00230 else 00231 { 00232 dirpart = NULL; 00233 } 00234 hFind = FindFirstFile (pattern, &FindData); 00235 if (INVALID_HANDLE_VALUE != hFind) 00236 { 00237 do 00238 { 00239 if (NULL != dirpart) 00240 { 00241 fullname = cmd_alloc((_tcslen(dirpart) + _tcslen(FindData.cFileName) + 1) * sizeof(TCHAR)); 00242 if (NULL == fullname) 00243 { 00244 ok = FALSE; 00245 } 00246 else 00247 { 00248 _tcscat (_tcscpy (fullname, dirpart), FindData.cFileName); 00249 ok = add_entry(ac, arg, fullname); 00250 cmd_free (fullname); 00251 } 00252 } 00253 else 00254 { 00255 ok = add_entry(ac, arg, FindData.cFileName); 00256 } 00257 } while (FindNextFile (hFind, &FindData) && ok); 00258 FindClose (hFind); 00259 } 00260 else 00261 { 00262 ok = add_entry(ac, arg, pattern); 00263 } 00264 00265 if (NULL != dirpart) 00266 { 00267 cmd_free (dirpart); 00268 } 00269 00270 return ok; 00271 } 00272 00273 /* 00274 * split - splits a line up into separate arguments, deliminators 00275 * are spaces and slashes ('/'). 00276 */ 00277 00278 LPTSTR *split (LPTSTR s, LPINT args, BOOL expand_wildcards, BOOL handle_plus) 00279 { 00280 LPTSTR *arg; 00281 LPTSTR start; 00282 LPTSTR q; 00283 INT ac; 00284 INT_PTR len; 00285 00286 arg = cmd_alloc (sizeof (LPTSTR)); 00287 if (!arg) 00288 return NULL; 00289 *arg = NULL; 00290 00291 ac = 0; 00292 while (*s) 00293 { 00294 BOOL bQuoted = FALSE; 00295 00296 /* skip leading spaces */ 00297 while (*s && (_istspace(*s) || _istcntrl(*s))) 00298 ++s; 00299 00300 start = s; 00301 00302 /* the first character can be '/' */ 00303 if (*s == _T('/')) 00304 ++s; 00305 00306 /* skip to next word delimiter or start of next option */ 00307 while (_istprint(*s)) 00308 { 00309 /* if quote (") then set bQuoted */ 00310 bQuoted ^= (*s == _T('\"')); 00311 00312 /* Check if we have unquoted text */ 00313 if (!bQuoted) 00314 { 00315 /* check for separators */ 00316 if (_istspace(*s) || 00317 (*s == _T('/')) || 00318 (handle_plus && (*s == _T('+')))) 00319 { 00320 /* Make length at least one character */ 00321 if (s == start) s++; 00322 break; 00323 } 00324 } 00325 00326 ++s; 00327 } 00328 00329 /* a word was found */ 00330 if (s != start) 00331 { 00332 q = cmd_alloc (((len = s - start) + 1) * sizeof (TCHAR)); 00333 if (!q) 00334 { 00335 return NULL; 00336 } 00337 memcpy (q, start, len * sizeof (TCHAR)); 00338 q[len] = _T('\0'); 00339 StripQuotes(q); 00340 if (expand_wildcards && (_T('/') != *start) && 00341 (NULL != _tcschr(q, _T('*')) || NULL != _tcschr(q, _T('?')))) 00342 { 00343 if (! expand(&ac, &arg, q)) 00344 { 00345 cmd_free (q); 00346 freep (arg); 00347 return NULL; 00348 } 00349 } 00350 else 00351 { 00352 if (! add_entry(&ac, &arg, q)) 00353 { 00354 cmd_free (q); 00355 freep (arg); 00356 return NULL; 00357 } 00358 } 00359 cmd_free (q); 00360 } 00361 } 00362 00363 *args = ac; 00364 00365 return arg; 00366 } 00367 00368 /* splitspace() is a function which uses JUST spaces as delimeters. split() uses "/" AND spaces. 00369 * The way it works is real similar to split(), search the difference ;) 00370 * splitspace is needed for commands such as "move" where paths as C:\this/is\allowed/ are allowed 00371 */ 00372 LPTSTR *splitspace (LPTSTR s, LPINT args) 00373 { 00374 LPTSTR *arg; 00375 LPTSTR start; 00376 LPTSTR q; 00377 INT ac; 00378 INT_PTR len; 00379 00380 arg = cmd_alloc (sizeof (LPTSTR)); 00381 if (!arg) 00382 return NULL; 00383 *arg = NULL; 00384 00385 ac = 0; 00386 while (*s) 00387 { 00388 BOOL bQuoted = FALSE; 00389 00390 /* skip leading spaces */ 00391 while (*s && (_istspace (*s) || _istcntrl (*s))) 00392 ++s; 00393 00394 start = s; 00395 00396 /* skip to next word delimiter or start of next option */ 00397 while (_istprint(*s) && (bQuoted || !_istspace(*s))) 00398 { 00399 /* if quote (") then set bQuoted */ 00400 bQuoted ^= (*s == _T('\"')); 00401 ++s; 00402 } 00403 00404 /* a word was found */ 00405 if (s != start) 00406 { 00407 q = cmd_alloc (((len = s - start) + 1) * sizeof (TCHAR)); 00408 if (!q) 00409 { 00410 return NULL; 00411 } 00412 memcpy (q, start, len * sizeof (TCHAR)); 00413 q[len] = _T('\0'); 00414 StripQuotes(q); 00415 if (! add_entry(&ac, &arg, q)) 00416 { 00417 cmd_free (q); 00418 freep (arg); 00419 return NULL; 00420 } 00421 cmd_free (q); 00422 } 00423 } 00424 00425 *args = ac; 00426 00427 return arg; 00428 } 00429 00430 /* 00431 * freep -- frees memory used for a call to split 00432 * 00433 */ 00434 VOID freep (LPTSTR *p) 00435 { 00436 LPTSTR *q; 00437 00438 if (!p) 00439 return; 00440 00441 q = p; 00442 while (*q) 00443 cmd_free(*q++); 00444 00445 cmd_free(p); 00446 } 00447 00448 00449 LPTSTR _stpcpy (LPTSTR dest, LPCTSTR src) 00450 { 00451 _tcscpy (dest, src); 00452 return (dest + _tcslen (src)); 00453 } 00454 00455 VOID 00456 StripQuotes(TCHAR *in) 00457 { 00458 TCHAR *out = in; 00459 for (; *in; in++) 00460 { 00461 if (*in != _T('"')) 00462 *out++ = *in; 00463 } 00464 *out = _T('\0'); 00465 } 00466 00467 00468 00469 /* 00470 * Checks if a path is valid (accessible) 00471 */ 00472 00473 BOOL IsValidPathName (LPCTSTR pszPath) 00474 { 00475 TCHAR szOldPath[MAX_PATH]; 00476 BOOL bResult; 00477 00478 GetCurrentDirectory (MAX_PATH, szOldPath); 00479 bResult = SetCurrentDirectory (pszPath); 00480 00481 SetCurrentDirectory (szOldPath); 00482 00483 return bResult; 00484 } 00485 00486 00487 /* 00488 * Checks if a file exists (accessible) 00489 */ 00490 00491 BOOL IsExistingFile (LPCTSTR pszPath) 00492 { 00493 DWORD attr = GetFileAttributes (pszPath); 00494 return (attr != 0xFFFFFFFF && (! (attr & FILE_ATTRIBUTE_DIRECTORY)) ); 00495 } 00496 00497 00498 BOOL IsExistingDirectory (LPCTSTR pszPath) 00499 { 00500 DWORD attr = GetFileAttributes (pszPath); 00501 return (attr != 0xFFFFFFFF && (attr & FILE_ATTRIBUTE_DIRECTORY) ); 00502 } 00503 00504 00505 BOOL FileGetString (HANDLE hFile, LPTSTR lpBuffer, INT nBufferLength) 00506 { 00507 LPSTR lpString; 00508 DWORD dwRead; 00509 INT len = 0; 00510 #ifdef _UNICODE 00511 lpString = cmd_alloc(nBufferLength); 00512 #else 00513 lpString = lpBuffer; 00514 #endif 00515 00516 if (ReadFile(hFile, lpString, nBufferLength - 1, &dwRead, NULL)) 00517 { 00518 /* break at new line*/ 00519 CHAR *end = memchr(lpString, '\n', dwRead); 00520 len = dwRead; 00521 if (end) 00522 { 00523 len = (INT)(end - lpString) + 1; 00524 SetFilePointer(hFile, len - dwRead, NULL, FILE_CURRENT); 00525 } 00526 } 00527 00528 if (!len) 00529 { 00530 #ifdef _UNICODE 00531 cmd_free(lpString); 00532 #endif 00533 return FALSE; 00534 } 00535 00536 lpString[len++] = '\0'; 00537 #ifdef _UNICODE 00538 MultiByteToWideChar(OutputCodePage, 0, lpString, -1, lpBuffer, len); 00539 cmd_free(lpString); 00540 #endif 00541 return TRUE; 00542 } 00543 00544 INT PagePrompt (VOID) 00545 { 00546 INPUT_RECORD ir; 00547 00548 ConOutResPuts(STRING_MISC_HELP1); 00549 00550 RemoveBreakHandler (); 00551 ConInDisable (); 00552 00553 do 00554 { 00555 ConInKey (&ir); 00556 } 00557 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || 00558 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || 00559 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); 00560 00561 AddBreakHandler (); 00562 ConInEnable (); 00563 00564 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || 00565 ((ir.Event.KeyEvent.wVirtualKeyCode == _T('C')) && 00566 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) 00567 { 00568 bCtrlBreak = TRUE; 00569 return PROMPT_BREAK; 00570 } 00571 00572 return PROMPT_YES; 00573 } 00574 00575 00576 INT FilePromptYN (UINT resID) 00577 { 00578 TCHAR szMsg[RC_STRING_MAX_SIZE]; 00579 // TCHAR cKey = 0; 00580 // LPTSTR szKeys = _T("yna"); 00581 00582 TCHAR szIn[10]; 00583 LPTSTR p; 00584 00585 if (resID != 0) 00586 ConOutResPrintf (resID); 00587 00588 /* preliminary fix */ 00589 ConInString (szIn, 10); 00590 ConOutPrintf (_T("\n")); 00591 00592 _tcsupr (szIn); 00593 for (p = szIn; _istspace (*p); p++) 00594 ; 00595 00596 LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, szMsg, RC_STRING_MAX_SIZE); 00597 00598 if (_tcsncmp(p, &szMsg[0], 1) == 0) 00599 return PROMPT_YES; 00600 else if (_tcsncmp(p, &szMsg[1], 1) == 0) 00601 return PROMPT_NO; 00602 #if 0 00603 else if (*p == _T('\03')) 00604 return PROMPT_BREAK; 00605 #endif 00606 00607 return PROMPT_NO; 00608 00609 00610 /* unfinished sollution */ 00611 #if 0 00612 RemoveBreakHandler (); 00613 ConInDisable (); 00614 00615 do 00616 { 00617 ConInKey (&ir); 00618 cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); 00619 if (_tcschr (szKeys, cKey[0]) == NULL) 00620 cKey = 0; 00621 00622 00623 } 00624 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || 00625 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || 00626 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); 00627 00628 AddBreakHandler (); 00629 ConInEnable (); 00630 00631 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || 00632 ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') && 00633 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) 00634 return PROMPT_BREAK; 00635 00636 return PROMPT_YES; 00637 #endif 00638 } 00639 00640 00641 INT FilePromptYNA (UINT resID) 00642 { 00643 TCHAR szMsg[RC_STRING_MAX_SIZE]; 00644 // TCHAR cKey = 0; 00645 // LPTSTR szKeys = _T("yna"); 00646 00647 TCHAR szIn[10]; 00648 LPTSTR p; 00649 00650 if (resID != 0) 00651 ConOutResPrintf (resID); 00652 00653 /* preliminary fix */ 00654 ConInString (szIn, 10); 00655 ConOutPrintf (_T("\n")); 00656 00657 _tcsupr (szIn); 00658 for (p = szIn; _istspace (*p); p++) 00659 ; 00660 00661 LoadString( CMD_ModuleHandle, STRING_COPY_OPTION, szMsg, RC_STRING_MAX_SIZE); 00662 00663 if (_tcsncmp(p, &szMsg[0], 1) == 0) 00664 return PROMPT_YES; 00665 else if (_tcsncmp(p, &szMsg[1], 1) == 0) 00666 return PROMPT_NO; 00667 else if (_tcsncmp(p, &szMsg[2], 1) == 0) 00668 return PROMPT_ALL; 00669 00670 #if 0 00671 else if (*p == _T('\03')) 00672 return PROMPT_BREAK; 00673 #endif 00674 00675 return PROMPT_NO; 00676 00677 00678 /* unfinished sollution */ 00679 #if 0 00680 RemoveBreakHandler (); 00681 ConInDisable (); 00682 00683 do 00684 { 00685 ConInKey (&ir); 00686 cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); 00687 if (_tcschr (szKeys, cKey[0]) == NULL) 00688 cKey = 0; 00689 } 00690 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || 00691 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || 00692 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); 00693 00694 AddBreakHandler (); 00695 ConInEnable (); 00696 00697 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || 00698 ((ir.Event.KeyEvent.wVirtualKeyCode == _T('C')) && 00699 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) 00700 return PROMPT_BREAK; 00701 00702 return PROMPT_YES; 00703 #endif 00704 } 00705 00706 /* EOF */ Generated on Sun May 27 2012 04:16:46 for ReactOS by
1.7.6.1
|