Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1063 lines
34 KiB

  1. /*** List.c
  2. *
  3. */
  4. #include <stdio.h>
  5. #include <malloc.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <windows.h>
  9. #include "list.h"
  10. #include "..\he\hexedit.h"
  11. BOOL IsValidKey (PINPUT_RECORD pRecord);
  12. void DumpFileInHex (void);
  13. static char Name[] = "Ken Reneris. List Ver 1.0.";
  14. struct Block *vpHead = NULL; /* Current first block */
  15. struct Block *vpTail = NULL; /* Current last block */
  16. struct Block *vpCur = NULL; /* Current block for display 1st line */
  17. /* (used by read ahead to sense) */
  18. struct Block *vpBCache = NULL; /* 'free' blocks which can cache reads */
  19. struct Block *vpBOther = NULL; /* (above) + for other files */
  20. struct Block *vpBFree = NULL; /* free blocks. not valid for caching reads */
  21. int vCntBlks; /* No of blocks currently is use by cur file*/
  22. int vAllocBlks = 0; /* No of blocks currently alloced */
  23. int vMaxBlks = MINBLKS; /* Max blocks allowed to alloc */
  24. long vThreshold = MINTHRES*BLOCKSIZE; /* Min bytes before read ahead */
  25. HANDLE vSemBrief = 0L; /* To serialize access to Linked list info */
  26. HANDLE vSemReader = 0L; /* To wakeup reader thread when threshold */
  27. HANDLE vSemMoreData = 0L; /* Blocker for Disp thread if ahead of read */
  28. HANDLE vSemSync = 0L; /* Used to syncronize to sync to the reader */
  29. USHORT vReadPriNormal; /* Normal priority for reader thread */
  30. unsigned vReadPriBoost; /* Boosted priority for reader thread */
  31. char vReaderFlag; /* Insructions to reader */
  32. HANDLE vFhandle = 0; /* Current file handle */
  33. long vCurOffset; /* Current offset in file */
  34. char vpFname [40]; /* Current files name */
  35. struct Flist *vpFlCur =NULL; /* Current file */
  36. USHORT vFType; /* Current files handle type */
  37. WIN32_FIND_DATA vFInfo; /* Current files info */
  38. char vDate [30]; /* Printable dat of current file */
  39. char vSearchString [50]; /* Searching for this string */
  40. char vStatCode; /* Codes for search */
  41. long vHighTop = -1L; /* Current topline of hightlighting */
  42. int vHighLen; /* Current bottom line of hightlighting */
  43. char vHLTop = 0; /* Last top line displayed as highlighted */
  44. char vHLBot = 0; /* Last bottom line displayed as highlighed */
  45. char vLastBar; /* Last line for thumb mark */
  46. int vMouHandle; /* Mouse handle (for Mou Apis) */
  47. HANDLE vhConsoleOutput; // Handle to the console
  48. char *vpOrigScreen; /* Orinal screen contents */
  49. int vOrigSize; /* # of bytes in orignal screen */
  50. USHORT vVioOrigRow = 0; /* Save orignal screen stuff. */
  51. USHORT vVioOrigCol = 0;
  52. int vSetBlks = 0; /* Used to set INI value */
  53. long vSetThres = 0L; /* Used to set INI value */
  54. int vSetLines; /* Used to set INI value */
  55. int vSetWidth; /* Used to set INI value */
  56. CONSOLE_SCREEN_BUFFER_INFO vConsoleCurScrBufferInfo;
  57. CONSOLE_SCREEN_BUFFER_INFO vConsoleOrigScrBufferInfo;
  58. /* Screen controling... used to be static in ldisp.c */
  59. char vcntScrLock = 0; /* Locked screen count */
  60. char vSpLockFlag = 0; /* Special locked flag */
  61. HANDLE vSemLock = 0; /* To access vcntScrLock */
  62. char vUpdate;
  63. int vLines = 23; /* CRTs no of lines */
  64. int vWidth = 80; /* CRTs width */
  65. int vCurLine; /* When processing lines on CRT */
  66. Uchar vWrap = 254; /* # of chars to wrap at */
  67. Uchar vIndent = 0; /* # of chars dispaly is indented */
  68. Uchar vDisTab = 8; /* # of chars per tab stop */
  69. Uchar vIniFlag = 0; /* Various ini bits */
  70. Uchar vrgLen [MAXLINES]; /* Last len of data on each line */
  71. Uchar vrgNewLen[MAXLINES]; /* Temp moved to DS for speed */
  72. char *vScrBuf; /* Ram to build screen into */
  73. ULONG vSizeScrBuf;
  74. int vOffTop; /* Offset into data for top line */
  75. unsigned vScrMass = 0; /* # of bytes for last screen (used for %) */
  76. struct Block *vpBlockTop; /* Block for start of screen (dis.asm) overw*/
  77. struct Block *vpCalcBlock; /* Block for start of screen */
  78. long vTopLine = 0L; /* Top line on the display */
  79. #define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
  80. #define BACKGROUND_WHITE (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
  81. #define HIWHITE_ON_BLUE (BACKGROUND_BLUE | FOREGROUND_WHITE | FOREGROUND_INTENSITY)
  82. WORD vAttrTitle = HIWHITE_ON_BLUE;
  83. WORD vAttrList = BACKGROUND_BLUE | FOREGROUND_WHITE;
  84. WORD vAttrHigh = BACKGROUND_WHITE | FOREGROUND_BLUE;
  85. WORD vAttrKey = HIWHITE_ON_BLUE;
  86. WORD vAttrCmd = BACKGROUND_BLUE | FOREGROUND_WHITE;
  87. WORD vAttrBar = BACKGROUND_BLUE | FOREGROUND_WHITE;
  88. WORD vSaveAttrTitle = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
  89. WORD vSaveAttrList = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
  90. WORD vSaveAttrHigh = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
  91. WORD vSaveAttrKey = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
  92. WORD vSaveAttrCmd = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
  93. WORD vSaveAttrBar = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
  94. char vChar; /* Scratch area */
  95. char *vpReaderStack; /* Readers stack */
  96. long vDirOffset; /* Direct offset to seek to */
  97. /* table */
  98. long vLastLine; /* Absolute last line */
  99. long vNLine; /* Next line to process into line table */
  100. long *vprgLineTable [MAXTPAGE]; /* Number of pages for line table */
  101. HANDLE vStdOut;
  102. HANDLE vStdIn;
  103. char MEMERR[]= "Malloc failed. Out of memory?";
  104. void __cdecl
  105. main (
  106. int argc,
  107. char **argv
  108. )
  109. {
  110. void usage (void);
  111. char *pt;
  112. DWORD dwMode;
  113. if (argc < 2)
  114. usage ();
  115. while (--argc) {
  116. ++argv;
  117. if (*argv[0] != '-' && *argv[0] != '/') {
  118. AddFileToList (*argv);
  119. continue;
  120. }
  121. pt = (*argv) + 2;
  122. if (*pt == ':') pt++;
  123. switch ((*argv)[1]) {
  124. case 'g': // Goto line #
  125. case 'G':
  126. if (!atol (pt))
  127. usage ();
  128. vIniFlag |= I_GOTO;
  129. vHighTop = atol (pt);
  130. vHighLen = 0;
  131. break;
  132. case 's': // Search for string
  133. case 'S':
  134. vIniFlag |= I_SEARCH;
  135. strncpy (vSearchString, pt, 40);
  136. vSearchString[39] = 0;
  137. vStatCode |= S_NEXT | S_NOCASE;
  138. InitSearchReMap ();
  139. break;
  140. default:
  141. usage ();
  142. }
  143. }
  144. if ((vIniFlag & I_GOTO) && (vIniFlag & I_SEARCH))
  145. usage ();
  146. if (!vpFlCur)
  147. usage ();
  148. while (vpFlCur->prev)
  149. vpFlCur = vpFlCur->prev;
  150. strcpy (vpFname, vpFlCur->rootname);
  151. vSemBrief = CreateEvent( NULL,
  152. MANUAL_RESET,
  153. SIGNALED,NULL );
  154. vSemReader = CreateEvent( NULL,
  155. MANUAL_RESET,
  156. SIGNALED,NULL );
  157. vSemMoreData = CreateEvent( NULL,
  158. MANUAL_RESET,
  159. SIGNALED,NULL );
  160. vSemSync = CreateEvent( NULL,
  161. MANUAL_RESET,
  162. SIGNALED,NULL );
  163. vSemLock = CreateEvent( NULL,
  164. MANUAL_RESET,
  165. SIGNALED,NULL );
  166. if( !(vSemBrief && vSemReader &&vSemMoreData && vSemSync && vSemLock) ) {
  167. printf("Couldn't create events \n");
  168. ExitProcess (0); // Have to put an error message here
  169. }
  170. vhConsoleOutput = CreateConsoleScreenBuffer(GENERIC_WRITE | GENERIC_READ,
  171. FILE_SHARE_WRITE | FILE_SHARE_READ,
  172. NULL,
  173. CONSOLE_TEXTMODE_BUFFER,
  174. NULL );
  175. if( vhConsoleOutput == (HANDLE)(-1) ) {
  176. printf( "Couldn't create handle to console output \n" );
  177. ExitProcess (0);
  178. }
  179. vStdIn = GetStdHandle( STD_INPUT_HANDLE );
  180. GetConsoleMode( vStdIn, &dwMode );
  181. SetConsoleMode( vStdIn, dwMode | ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT );
  182. vStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
  183. init_list ();
  184. vUpdate = U_NMODE;
  185. if (vIniFlag & I_SEARCH)
  186. FindString ();
  187. if (vIniFlag & I_GOTO)
  188. GoToMark ();
  189. main_loop ();
  190. }
  191. void
  192. usage (
  193. void
  194. )
  195. {
  196. puts ("list [-s:string] [-g:line#] filename, ...");
  197. CleanUp();
  198. ExitProcess(0);
  199. }
  200. /*** main_loop
  201. *
  202. */
  203. void
  204. main_loop ()
  205. {
  206. int i;
  207. int ccnt = 0;
  208. char SkipCnt=0;
  209. WORD RepeatCnt=0;
  210. INPUT_RECORD InpBuffer;
  211. DWORD cEvents;
  212. BOOL bSuccess;
  213. BOOL bKeyDown = FALSE;
  214. for (; ;) {
  215. if (RepeatCnt <= 1) {
  216. if (vUpdate != U_NONE) {
  217. if (SkipCnt++ > 5) {
  218. SkipCnt = 0;
  219. SetUpdate (U_NONE);
  220. } else {
  221. cEvents = 0;
  222. bSuccess = PeekConsoleInput( vStdIn,
  223. &InpBuffer,
  224. 1,
  225. &cEvents );
  226. if (!bSuccess || cEvents == 0) {
  227. PerformUpdate ();
  228. continue;
  229. }
  230. }
  231. }
  232. // there's either a charactor available from peek, or vUpdate is U_NONE
  233. bSuccess = ReadConsoleInput( vStdIn,
  234. &InpBuffer,
  235. 1,
  236. &cEvents );
  237. if (InpBuffer.EventType != KEY_EVENT) {
  238. // TCHAR s[1024];
  239. switch (InpBuffer.EventType) {
  240. #if 0
  241. case WINDOW_BUFFER_SIZE_EVENT:
  242. sprintf (s,
  243. "WindowSz X=%d, Y=%d",
  244. InpBuffer.Event.WindowBufferSizeEvent.dwSize.X,
  245. InpBuffer.Event.WindowBufferSizeEvent.dwSize.Y );
  246. DisLn (20, (Uchar)(vLines+1), s);
  247. break;
  248. #endif
  249. case MOUSE_EVENT:
  250. #if 0
  251. sprintf (s,
  252. "Mouse (%d,%d), state %x, event %x",
  253. InpBuffer.Event.MouseEvent.dwMousePosition.X,
  254. InpBuffer.Event.MouseEvent.dwMousePosition.Y,
  255. InpBuffer.Event.MouseEvent.dwButtonState,
  256. InpBuffer.Event.MouseEvent.dwEventFlags );
  257. #endif
  258. if (InpBuffer.Event.MouseEvent.dwEventFlags == MOUSE_WHEELED)
  259. {
  260. // HiWord of ButtonState is signed int, in increments of 120 (WHEEL_DELTA).
  261. // Map each 'detent' to a 4 line scroll in the console window.
  262. // Rolling away from the user should scroll up (dLines should be negative).
  263. // Since rolling away generates a positive dwButtonState, the negative sign
  264. // makes rolling away scroll up, and rolling towards you scroll down.
  265. SHORT dLines = -(SHORT)(HIWORD(InpBuffer.Event.MouseEvent.dwButtonState)) / (WHEEL_DELTA / 4);
  266. vTopLine += dLines;
  267. // make sure to stay between line 0 and vLastLine
  268. if (vTopLine+vLines > vLastLine)
  269. vTopLine = vLastLine-vLines;
  270. if (vTopLine < 0)
  271. vTopLine = 0;
  272. SetUpdateM (U_ALL);
  273. }
  274. // DisLn (20, (Uchar)(vLines+1), s);
  275. break;
  276. default:
  277. #if 0
  278. sprintf (s, "Unkown event %d", InpBuffer.EventType);
  279. DisLn (20, (Uchar)(vLines+1), s);
  280. #endif
  281. break;
  282. }
  283. continue;
  284. }
  285. if (!InpBuffer.Event.KeyEvent.bKeyDown)
  286. continue; // don't move on upstrokes
  287. if (!IsValidKey( &InpBuffer ))
  288. continue;
  289. RepeatCnt = InpBuffer.Event.KeyEvent.wRepeatCount;
  290. if (RepeatCnt > 20)
  291. RepeatCnt = 20;
  292. } else
  293. RepeatCnt--;
  294. // First check for a known scan code
  295. switch (InpBuffer.Event.KeyEvent.wVirtualKeyCode) {
  296. case 0x21: /* PgUp */
  297. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift up
  298. SHIFT_PRESSED ) {
  299. HPgUp ();
  300. }
  301. else if (InpBuffer.Event.KeyEvent.dwControlKeyState & // ctrl up
  302. ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED ) ) {
  303. if (NextFile (-1, NULL)) {
  304. vStatCode |= S_UPDATE;
  305. SetUpdate (U_ALL);
  306. }
  307. }
  308. else {
  309. if (vTopLine != 0L) {
  310. vTopLine -= vLines-1;
  311. if (vTopLine < 0L)
  312. vTopLine = 0L;
  313. SetUpdateM (U_ALL);
  314. }
  315. }
  316. continue;
  317. case 0x26: /* Up */
  318. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift or ctrl up
  319. ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED |
  320. SHIFT_PRESSED ) ) {
  321. HUp ();
  322. }
  323. else { // Up
  324. if (vTopLine != 0L) {
  325. vTopLine--;
  326. SetUpdateM (U_ALL);
  327. }
  328. }
  329. continue;
  330. case 0x22: /* PgDn */
  331. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift down
  332. SHIFT_PRESSED ) {
  333. HPgDn ();
  334. }
  335. else if (InpBuffer.Event.KeyEvent.dwControlKeyState & // next file
  336. ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED ) ) {
  337. if (NextFile (+1, NULL)) {
  338. vStatCode |= S_UPDATE;
  339. SetUpdate (U_ALL);
  340. }
  341. }
  342. else { // PgDn
  343. if (vTopLine+vLines < vLastLine) {
  344. vTopLine += vLines-1;
  345. if (vTopLine+vLines > vLastLine)
  346. vTopLine = vLastLine - vLines;
  347. SetUpdateM (U_ALL);
  348. }
  349. }
  350. continue;
  351. case 0x28: /* Down */
  352. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift or ctrl down
  353. ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED |
  354. SHIFT_PRESSED ) ) {
  355. HDn ();
  356. }
  357. else { // Down
  358. if (vTopLine+vLines < vLastLine) {
  359. vTopLine++;
  360. SetUpdateM (U_ALL);
  361. }
  362. }
  363. continue;
  364. case 0x25: /* Left */
  365. if (vIndent == 0)
  366. continue;
  367. vIndent = (Uchar)(vIndent < vDisTab ? 0 : vIndent - vDisTab);
  368. SetUpdateM (U_ALL);
  369. continue;
  370. case 0x27: /* Right */
  371. if (vIndent >= (Uchar)(254-vWidth))
  372. continue;
  373. vIndent += vDisTab;
  374. SetUpdateM (U_ALL);
  375. continue;
  376. case 0x24: /* HOME */
  377. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift or ctrl home
  378. ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED |
  379. SHIFT_PRESSED ) ) {
  380. HSUp ();
  381. }
  382. else {
  383. if (vTopLine != 0L) {
  384. QuickHome ();
  385. SetUpdate (U_ALL);
  386. }
  387. }
  388. continue;
  389. case 0x23: /* END */
  390. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift or ctrl end
  391. ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED |
  392. SHIFT_PRESSED ) ) {
  393. HSDn ();
  394. }
  395. else {
  396. if (vTopLine+vLines < vLastLine) {
  397. QuickEnd ();
  398. SetUpdate (U_ALL);
  399. }
  400. }
  401. continue;
  402. case 0x72: /* F3 */
  403. FindString ();
  404. SetUpdate (U_ALL);
  405. continue;
  406. case 0x73: /* F4 */
  407. vStatCode = (char)((vStatCode^S_MFILE) | S_UPDATE);
  408. vDate[ST_SEARCH] = (char)(vStatCode & S_MFILE ? '*' : ' ');
  409. SetUpdate (U_HEAD);
  410. continue;
  411. case 69:
  412. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // ALT-E
  413. ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) ) {
  414. i = vLines <= 41 ? 25 : 43;
  415. if (set_mode (i, 0, 0))
  416. SetUpdate (U_NMODE);
  417. }
  418. continue;
  419. case 86: // ALT-V
  420. if (InpBuffer.Event.KeyEvent.dwControlKeyState &
  421. ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) ) {
  422. i = vLines >= 48 ? 25 : 60;
  423. if (set_mode (i, 0, 0))
  424. {
  425. SetUpdate (U_NMODE);
  426. continue;
  427. }
  428. if (i == 60)
  429. if (set_mode (50, 0, 0))
  430. SetUpdate (U_NMODE);
  431. }
  432. continue;
  433. case 0x70: /* F1 */
  434. ShowHelp ();
  435. SetUpdate (U_NMODE);
  436. continue;
  437. case 24: /* Offset */
  438. if (!(vIniFlag & I_SLIME))
  439. continue;
  440. SlimeTOF ();
  441. SetUpdate (U_ALL);
  442. continue;
  443. case 0x77: // F8
  444. case 0x1b: // ESC
  445. case 0x51: // Q or q
  446. CleanUp();
  447. ExitProcess(0);
  448. }
  449. // Now check for a known char code...
  450. switch (InpBuffer.Event.KeyEvent.uChar.AsciiChar) {
  451. case '?':
  452. ShowHelp ();
  453. SetUpdate (U_NMODE);
  454. continue;
  455. case '/':
  456. vStatCode = (char)((vStatCode & ~S_NOCASE) | S_NEXT);
  457. GetSearchString ();
  458. FindString ();
  459. continue;
  460. case '\\':
  461. vStatCode |= S_NEXT | S_NOCASE;
  462. GetSearchString ();
  463. FindString ();
  464. continue;
  465. case 'n':
  466. vStatCode = (char)((vStatCode & ~S_PREV) | S_NEXT);
  467. FindString ();
  468. continue;
  469. case 'N':
  470. vStatCode = (char)((vStatCode & ~S_NEXT) | S_PREV);
  471. FindString ();
  472. continue;
  473. case 'c':
  474. case 'C': /* Clear marked line */
  475. UpdateHighClear ();
  476. continue;
  477. case 'j':
  478. case 'J': /* Jump to marked line */
  479. GoToMark ();
  480. continue;
  481. case 'g':
  482. case 'G': /* Goto line # */
  483. GoToLine ();
  484. SetUpdate (U_ALL);
  485. continue;
  486. case 'm': /* Mark line or Mono */
  487. case 'M':
  488. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // ALT-M
  489. ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) ) {
  490. i = set_mode (vSetLines, vSetWidth, 1);
  491. if (!i)
  492. i = set_mode (0, 0, 1);
  493. if (!i)
  494. i = set_mode (25, 80, 1);
  495. if (i)
  496. SetUpdate (U_NMODE);
  497. }
  498. else {
  499. MarkSpot ();
  500. }
  501. continue;
  502. case 'p': /* Paste buffer to file */
  503. case 'P':
  504. FileHighLighted ();
  505. continue;
  506. case 'f': /* get a new file */
  507. case 'F':
  508. if (GetNewFile ())
  509. if (NextFile (+1, NULL))
  510. SetUpdate (U_ALL);
  511. continue;
  512. case 'h': /* hexedit */
  513. case 'H':
  514. DumpFileInHex();
  515. SetUpdate (U_NMODE);
  516. continue;
  517. case 'w': /* WRAP */
  518. case 'W':
  519. ToggleWrap ();
  520. SetUpdate (U_ALL);
  521. continue;
  522. case 'l': /* REFRESH */
  523. case 'L': /* REFRESH */
  524. if (InpBuffer.Event.KeyEvent.dwControlKeyState & // ctrl L
  525. ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED ) ) {
  526. SetUpdate (U_NMODE);
  527. }
  528. continue;
  529. case '\r': /* ENTER*/
  530. SetUpdate (U_HEAD);
  531. continue;
  532. default:
  533. continue;
  534. }
  535. } /* Forever loop */
  536. }
  537. void
  538. SetUpdate(
  539. int i
  540. )
  541. {
  542. while (vUpdate>(char)i)
  543. PerformUpdate ();
  544. vUpdate=(char)i;
  545. }
  546. void
  547. PerformUpdate (
  548. )
  549. {
  550. if (vUpdate == U_NONE)
  551. return;
  552. if (vSpLockFlag == 0) {
  553. vSpLockFlag = 1;
  554. ScrLock (1);
  555. }
  556. switch (vUpdate) {
  557. case U_NMODE:
  558. ClearScr ();
  559. DisLn (0, 0, vpFname);
  560. DrawBar ();
  561. break;
  562. case U_ALL:
  563. Update_display ();
  564. break;
  565. case U_HEAD:
  566. Update_head ();
  567. break;
  568. case U_CLEAR:
  569. SpScrUnLock ();
  570. break;
  571. }
  572. vUpdate --;
  573. }
  574. NTSTATUS fncRead(HANDLE, DWORD, DWORD, char *, ULONG *);
  575. NTSTATUS fncWrite(HANDLE, DWORD, DWORD, char *, ULONG *);
  576. void
  577. DumpFileInHex(
  578. void
  579. )
  580. {
  581. struct HexEditParm ei;
  582. ULONG CurLine;
  583. SyncReader ();
  584. memset ((char *) &ei, 0, sizeof (ei));
  585. ei.handle = CreateFile( vpFlCur->fname,
  586. GENERIC_READ | GENERIC_WRITE,
  587. FILE_SHARE_READ|FILE_SHARE_WRITE,
  588. NULL,
  589. OPEN_EXISTING,
  590. 0,
  591. NULL );
  592. if (ei.handle == INVALID_HANDLE_VALUE) {
  593. ei.handle = CreateFile( vpFlCur->fname,
  594. GENERIC_READ,
  595. FILE_SHARE_READ|FILE_SHARE_WRITE,
  596. NULL,
  597. OPEN_EXISTING,
  598. 0,
  599. NULL );
  600. }
  601. if (ei.handle == INVALID_HANDLE_VALUE) {
  602. SetEvent (vSemReader);
  603. return ;
  604. }
  605. //
  606. // Save current settings for possible restore
  607. //
  608. vpFlCur->Wrap = vWrap;
  609. vpFlCur->HighTop = vHighTop;
  610. vpFlCur->HighLen = vHighLen;
  611. vpFlCur->TopLine = vTopLine;
  612. vpFlCur->Loffset = GetLoffset();
  613. vpFlCur->LastLine = vLastLine;
  614. vpFlCur->NLine = vNLine;
  615. memcpy (vpFlCur->prgLineTable, vprgLineTable, sizeof (long *) * MAXTPAGE);
  616. vFInfo.nFileSizeLow = 0;
  617. setattr2 (0, 0, vWidth, (char)vAttrTitle);
  618. //
  619. // Setup for HexEdit call
  620. //
  621. if (vHighTop >= 0) { // If highlighted area,
  622. CurLine = vHighTop; // use that for the HexEdit
  623. if (vHighLen < 0) // location
  624. CurLine += vHighLen;
  625. } else {
  626. CurLine = vTopLine;
  627. }
  628. ei.ename = vpFname;
  629. ei.ioalign = 1;
  630. ei.flag = FHE_VERIFYONCE;
  631. ei.read = fncRead;
  632. ei.write = fncWrite;
  633. ei.start = vprgLineTable[CurLine/PLINES][CurLine%PLINES];
  634. ei.totlen = SetFilePointer (ei.handle, 0, NULL, FILE_END);
  635. ei.Console = vhConsoleOutput; // our console handle
  636. ei.AttrNorm = vAttrList;
  637. ei.AttrHigh = vAttrTitle;
  638. ei.AttrReverse = vAttrHigh;
  639. HexEdit (&ei);
  640. CloseHandle (ei.handle);
  641. //
  642. // HexEdit is done, let reader and return to listing
  643. //
  644. vReaderFlag = F_NEXT; // re-open current file
  645. // (in case it was editted)
  646. SetEvent (vSemReader);
  647. WaitForSingleObject(vSemMoreData, WAITFOREVER);
  648. ResetEvent(vSemMoreData);
  649. QuickRestore (); /* Get to the old location */
  650. }
  651. int
  652. NextFile (
  653. int dir,
  654. struct Flist *pNewFile)
  655. {
  656. struct Flist *vpFLCur;
  657. long *pLine;
  658. vpFLCur = vpFlCur;
  659. if (pNewFile == NULL) {
  660. if (dir < 0) {
  661. if (vpFlCur->prev == NULL) {
  662. beep ();
  663. return (0);
  664. }
  665. vpFlCur = vpFlCur->prev;
  666. } else if (dir > 0) {
  667. if (vpFlCur->next == NULL) {
  668. beep ();
  669. return (0);
  670. }
  671. vpFlCur = vpFlCur->next;
  672. }
  673. } else
  674. vpFlCur = pNewFile;
  675. SyncReader ();
  676. /*
  677. * Remove current file from list, if open error
  678. * occured and we are moving off of it.
  679. */
  680. if (vFInfo.nFileSizeLow == -1L && vpFLCur != vpFlCur) {
  681. if (vpFLCur->prev)
  682. vpFLCur->prev->next = vpFLCur->next;
  683. if (vpFLCur->next)
  684. vpFLCur->next->prev = vpFLCur->prev;
  685. FreePages (vpFLCur);
  686. free ((char*) vpFLCur->fname);
  687. free ((char*) vpFLCur->rootname);
  688. free ((char*) vpFLCur);
  689. } else {
  690. /*
  691. * Else, save current status for possible restore
  692. */
  693. vpFLCur->Wrap = vWrap;
  694. vpFLCur->HighTop = vHighTop;
  695. vpFLCur->HighLen = vHighLen;
  696. vpFLCur->TopLine = vTopLine;
  697. vpFLCur->Loffset = GetLoffset();
  698. vpFLCur->LastLine = vLastLine;
  699. vpFLCur->NLine = vNLine;
  700. memcpy (vpFLCur->prgLineTable, vprgLineTable, sizeof (long *) * MAXTPAGE);
  701. if (vLastLine == NOLASTLINE) {
  702. pLine = vprgLineTable [vNLine/PLINES] + vNLine % PLINES;
  703. }
  704. }
  705. vFInfo.nFileSizeLow = 0;
  706. setattr2 (0, 0, vWidth, (char)vAttrTitle);
  707. vHighTop = -1L;
  708. UpdateHighClear ();
  709. vHighTop = vpFlCur->HighTop;
  710. vHighLen = vpFlCur->HighLen;
  711. strcpy (vpFname, vpFlCur->rootname);
  712. DisLn (0, 0, vpFname);
  713. vReaderFlag = F_NEXT;
  714. SetEvent (vSemReader);
  715. WaitForSingleObject(vSemMoreData, WAITFOREVER);
  716. ResetEvent(vSemMoreData);
  717. if (pNewFile == NULL)
  718. QuickRestore (); /* Get to the old location */
  719. return (1);
  720. }
  721. void
  722. ToggleWrap(
  723. )
  724. {
  725. SyncReader ();
  726. vWrap = (Uchar)(vWrap == (Uchar)(vWidth - 1) ? 254 : vWidth - 1);
  727. vpFlCur->FileTime.dwLowDateTime = (unsigned)-1; /* Cause info to be invalid */
  728. vpFlCur->FileTime.dwHighDateTime = (unsigned)-1; /* Cause info to be invalid */
  729. FreePages (vpFlCur);
  730. NextFile (0, NULL);
  731. }
  732. /*** QuickHome - Deciede which HOME method is better.
  733. *
  734. * Roll que backwards or reset it.
  735. *
  736. */
  737. void
  738. QuickHome ()
  739. {
  740. vTopLine = 0L; /* Line we're after */
  741. if (vpHead->offset >= BLOCKSIZE * 5) /* Reset is fastest */
  742. QuickRestore ();
  743. /* Else Read backwards */
  744. vpCur = vpHead;
  745. }
  746. void
  747. QuickEnd ()
  748. {
  749. vTopLine = 1L;
  750. while (vLastLine == NOLASTLINE) {
  751. if (_abort()) {
  752. vTopLine = vNLine - 1;
  753. return ;
  754. }
  755. fancy_percent ();
  756. vpBlockTop = vpCur = vpTail;
  757. vReaderFlag = F_DOWN;
  758. ResetEvent (vSemMoreData);
  759. SetEvent (vSemReader);
  760. WaitForSingleObject(vSemMoreData, WAITFOREVER);
  761. ResetEvent(vSemMoreData);
  762. }
  763. vTopLine = vLastLine - vLines;
  764. if (vTopLine < 0L)
  765. vTopLine = 0L;
  766. QuickRestore ();
  767. }
  768. void
  769. QuickRestore ()
  770. {
  771. long l;
  772. long indx1 = vTopLine/PLINES;
  773. long indx2 = vTopLine%PLINES;
  774. SyncReader ();
  775. if(indx1 < MAXTPAGE) {
  776. l = vprgLineTable[indx1][indx2];
  777. } else {
  778. puts("Sorry, This file is too big for LIST to handle. MAXTPAGE limit exceeded\n");
  779. CleanUp();
  780. ExitProcess(0);
  781. }
  782. if ((l >= vpHead->offset) &&
  783. (l <= vpTail->offset + BLOCKSIZE))
  784. {
  785. vReaderFlag = F_CHECK; /* Jump location is alread in */
  786. /* memory. */
  787. SetEvent (vSemReader);
  788. return ;
  789. }
  790. /* Command read for direct placement */
  791. vDirOffset = (long) l - l % ((long)BLOCKSIZE);
  792. vReaderFlag = F_DIRECT;
  793. SetEvent (vSemReader);
  794. WaitForSingleObject(vSemMoreData, WAITFOREVER);
  795. ResetEvent(vSemMoreData);
  796. }
  797. /*** InfoRead - return on/off depending if screen area is in memory
  798. *
  799. * Also sets some external value to prepair for the screens printing
  800. *
  801. * Should be modified to be smarter about one line movements.
  802. *
  803. */
  804. int
  805. InfoReady(
  806. void
  807. )
  808. {
  809. struct Block *pBlock;
  810. LONG *pLine;
  811. long foffset, boffset;
  812. int index, i, j;
  813. /*
  814. * Check that first line has been calced
  815. */
  816. if (vTopLine >= vNLine) {
  817. if (vTopLine+vLines > vLastLine) /* BUGFIX. TopLine can */
  818. vTopLine = vLastLine - vLines; /* get past EOF. */
  819. vReaderFlag = F_DOWN;
  820. return (0);
  821. }
  822. pLine = vprgLineTable [(int)vTopLine / PLINES];
  823. index = (int)(vTopLine % PLINES);
  824. foffset = *(pLine+=index);
  825. /*
  826. * Check that last line has been calced
  827. */
  828. if (vTopLine + (i = vLines) > vLastLine) {
  829. i = (int)(vLastLine - vTopLine + 1);
  830. for (j=i; j < vLines; j++) /* Clear ending len */
  831. vrgNewLen[j] = 0;
  832. }
  833. if (vTopLine + i > vNLine) {
  834. vReaderFlag = F_DOWN;
  835. return (0);
  836. }
  837. /*
  838. * Put this loop in assembler.. For more speed
  839. * boffset = calc_lens (foffset, i, pLine, index);
  840. */
  841. boffset = foffset;
  842. for (j=0; j < i; j++) { /* Calc new line len*/
  843. pLine++;
  844. if (++index >= PLINES) {
  845. index = 0;
  846. pLine = vprgLineTable [vTopLine / PLINES + 1];
  847. }
  848. boffset += (long)((vrgNewLen[j] = (Uchar)(*pLine - boffset)));
  849. }
  850. vScrMass = (unsigned)(boffset - foffset);
  851. /*
  852. * Check for both ends of display in memory
  853. */
  854. pBlock = vpCur;
  855. if (pBlock->offset <= foffset) {
  856. while (pBlock->offset + BLOCKSIZE <= foffset)
  857. if ( (pBlock = pBlock->next) == NULL) {
  858. vReaderFlag = F_DOWN;
  859. return (0);
  860. }
  861. vOffTop = (int)(foffset - pBlock->offset);
  862. vpBlockTop = vpCalcBlock = pBlock;
  863. while (pBlock->offset + BLOCKSIZE <= boffset)
  864. if ( (pBlock = pBlock->next) == NULL) {
  865. vReaderFlag = F_DOWN;
  866. return (0);
  867. }
  868. if (vpCur != pBlock) {
  869. vpCur = pBlock;
  870. vReaderFlag = F_CHECK;
  871. SetEvent (vSemReader);
  872. }
  873. return (1);
  874. } else {
  875. while (pBlock->offset > foffset)
  876. if ( (pBlock = pBlock->prev) == NULL) {
  877. vReaderFlag = F_UP;
  878. return (0);
  879. }
  880. vOffTop = (int)(foffset - pBlock->offset);
  881. vpBlockTop = vpCalcBlock = pBlock;
  882. while (pBlock->offset + BLOCKSIZE <= boffset)
  883. if ( (pBlock = pBlock->next) == NULL) {
  884. vReaderFlag = F_DOWN;
  885. return (0);
  886. }
  887. if (vpCur != pBlock) {
  888. vpCur = pBlock;
  889. vReaderFlag = F_CHECK;
  890. SetEvent (vSemReader);
  891. }
  892. return (1);
  893. }
  894. }