Leaked source code of windows server 2003
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.

1060 lines
35 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. DWORD vFSize; /* Current file size */
  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. void
  575. DumpFileInHex(
  576. void
  577. )
  578. {
  579. struct HexEditParm ei;
  580. ULONG CurLine;
  581. SyncReader ();
  582. memset ((char *) &ei, 0, sizeof (ei));
  583. ei.handle = CreateFile( vpFlCur->fname,
  584. GENERIC_READ | GENERIC_WRITE,
  585. FILE_SHARE_READ|FILE_SHARE_WRITE,
  586. NULL,
  587. OPEN_EXISTING,
  588. 0,
  589. NULL );
  590. if (ei.handle == INVALID_HANDLE_VALUE) {
  591. ei.handle = CreateFile( vpFlCur->fname,
  592. GENERIC_READ,
  593. FILE_SHARE_READ|FILE_SHARE_WRITE,
  594. NULL,
  595. OPEN_EXISTING,
  596. 0,
  597. NULL );
  598. }
  599. if (ei.handle == INVALID_HANDLE_VALUE) {
  600. SetEvent (vSemReader);
  601. return ;
  602. }
  603. //
  604. // Save current settings for possible restore
  605. //
  606. vpFlCur->Wrap = vWrap;
  607. vpFlCur->HighTop = vHighTop;
  608. vpFlCur->HighLen = vHighLen;
  609. vpFlCur->TopLine = vTopLine;
  610. vpFlCur->Loffset = GetLoffset();
  611. vpFlCur->LastLine = vLastLine;
  612. vpFlCur->NLine = vNLine;
  613. memcpy (vpFlCur->prgLineTable, vprgLineTable, sizeof (long *) * MAXTPAGE);
  614. vFSize = 0;
  615. setattr2 (0, 0, vWidth, (char)vAttrTitle);
  616. //
  617. // Setup for HexEdit call
  618. //
  619. if (vHighTop >= 0) { // If highlighted area,
  620. CurLine = vHighTop; // use that for the HexEdit
  621. if (vHighLen < 0) // location
  622. CurLine += vHighLen;
  623. } else {
  624. CurLine = vTopLine;
  625. }
  626. ei.ename = vpFname;
  627. ei.ioalign = 1;
  628. ei.flag = FHE_VERIFYONCE;
  629. ei.read = fncRead;
  630. ei.write = fncWrite;
  631. ei.start = vprgLineTable[CurLine/PLINES][CurLine%PLINES];
  632. ei.totlen = SetFilePointer (ei.handle, 0, NULL, FILE_END);
  633. ei.Console = vhConsoleOutput; // our console handle
  634. ei.AttrNorm = vAttrList;
  635. ei.AttrHigh = vAttrTitle;
  636. ei.AttrReverse = vAttrHigh;
  637. HexEdit (&ei);
  638. CloseHandle (ei.handle);
  639. //
  640. // HexEdit is done, let reader and return to listing
  641. //
  642. vReaderFlag = F_NEXT; // re-open current file
  643. // (in case it was editted)
  644. SetEvent (vSemReader);
  645. WaitForSingleObject(vSemMoreData, WAITFOREVER);
  646. ResetEvent(vSemMoreData);
  647. QuickRestore (); /* Get to the old location */
  648. }
  649. int
  650. NextFile (
  651. int dir,
  652. struct Flist *pNewFile)
  653. {
  654. struct Flist *vpFLCur;
  655. long *pLine;
  656. vpFLCur = vpFlCur;
  657. if (pNewFile == NULL) {
  658. if (dir < 0) {
  659. if (vpFlCur->prev == NULL) {
  660. beep ();
  661. return (0);
  662. }
  663. vpFlCur = vpFlCur->prev;
  664. } else if (dir > 0) {
  665. if (vpFlCur->next == NULL) {
  666. beep ();
  667. return (0);
  668. }
  669. vpFlCur = vpFlCur->next;
  670. }
  671. } else
  672. vpFlCur = pNewFile;
  673. SyncReader ();
  674. /*
  675. * Remove current file from list, if open error
  676. * occured and we are moving off of it.
  677. */
  678. if (vFSize == -1L && vpFLCur != vpFlCur) {
  679. if (vpFLCur->prev)
  680. vpFLCur->prev->next = vpFLCur->next;
  681. if (vpFLCur->next)
  682. vpFLCur->next->prev = vpFLCur->prev;
  683. FreePages (vpFLCur);
  684. free ((char*) vpFLCur->fname);
  685. free ((char*) vpFLCur->rootname);
  686. free ((char*) vpFLCur);
  687. } else {
  688. /*
  689. * Else, save current status for possible restore
  690. */
  691. vpFLCur->Wrap = vWrap;
  692. vpFLCur->HighTop = vHighTop;
  693. vpFLCur->HighLen = vHighLen;
  694. vpFLCur->TopLine = vTopLine;
  695. vpFLCur->Loffset = GetLoffset();
  696. vpFLCur->LastLine = vLastLine;
  697. vpFLCur->NLine = vNLine;
  698. memcpy (vpFLCur->prgLineTable, vprgLineTable, sizeof (long *) * MAXTPAGE);
  699. if (vLastLine == NOLASTLINE) {
  700. pLine = vprgLineTable [vNLine/PLINES] + vNLine % PLINES;
  701. }
  702. }
  703. vFSize = 0;
  704. setattr2 (0, 0, vWidth, (char)vAttrTitle);
  705. vHighTop = -1L;
  706. UpdateHighClear ();
  707. vHighTop = vpFlCur->HighTop;
  708. vHighLen = vpFlCur->HighLen;
  709. strcpy (vpFname, vpFlCur->rootname);
  710. DisLn (0, 0, vpFname);
  711. vReaderFlag = F_NEXT;
  712. SetEvent (vSemReader);
  713. WaitForSingleObject(vSemMoreData, WAITFOREVER);
  714. ResetEvent(vSemMoreData);
  715. if (pNewFile == NULL)
  716. QuickRestore (); /* Get to the old location */
  717. return (1);
  718. }
  719. void
  720. ToggleWrap(
  721. )
  722. {
  723. SyncReader ();
  724. vWrap = (Uchar)(vWrap == (Uchar)(vWidth - 1) ? 254 : vWidth - 1);
  725. vpFlCur->FileTime.dwLowDateTime = (unsigned)-1; /* Cause info to be invalid */
  726. vpFlCur->FileTime.dwHighDateTime = (unsigned)-1; /* Cause info to be invalid */
  727. FreePages (vpFlCur);
  728. NextFile (0, NULL);
  729. }
  730. /*** QuickHome - Deciede which HOME method is better.
  731. *
  732. * Roll que backwards or reset it.
  733. *
  734. */
  735. void
  736. QuickHome ()
  737. {
  738. vTopLine = 0L; /* Line we're after */
  739. if (vpHead->offset >= BLOCKSIZE * 5) /* Reset is fastest */
  740. QuickRestore ();
  741. /* Else Read backwards */
  742. vpCur = vpHead;
  743. }
  744. void
  745. QuickEnd ()
  746. {
  747. vTopLine = 1L;
  748. while (vLastLine == NOLASTLINE) {
  749. if (_abort()) {
  750. vTopLine = vNLine - 1;
  751. return ;
  752. }
  753. fancy_percent ();
  754. vpBlockTop = vpCur = vpTail;
  755. vReaderFlag = F_DOWN;
  756. ResetEvent (vSemMoreData);
  757. SetEvent (vSemReader);
  758. WaitForSingleObject(vSemMoreData, WAITFOREVER);
  759. ResetEvent(vSemMoreData);
  760. }
  761. vTopLine = vLastLine - vLines;
  762. if (vTopLine < 0L)
  763. vTopLine = 0L;
  764. QuickRestore ();
  765. }
  766. void
  767. QuickRestore ()
  768. {
  769. long l;
  770. long indx1 = vTopLine/PLINES;
  771. long indx2 = vTopLine%PLINES;
  772. SyncReader ();
  773. if(indx1 < MAXTPAGE) {
  774. l = vprgLineTable[indx1][indx2];
  775. } else {
  776. puts("Sorry, This file is too big for LIST to handle. MAXTPAGE limit exceeded\n");
  777. CleanUp();
  778. ExitProcess(0);
  779. }
  780. if ((l >= vpHead->offset) &&
  781. (l <= vpTail->offset + BLOCKSIZE))
  782. {
  783. vReaderFlag = F_CHECK; /* Jump location is alread in */
  784. /* memory. */
  785. SetEvent (vSemReader);
  786. return ;
  787. }
  788. /* Command read for direct placement */
  789. vDirOffset = (long) l - l % ((long)BLOCKSIZE);
  790. vReaderFlag = F_DIRECT;
  791. SetEvent (vSemReader);
  792. WaitForSingleObject(vSemMoreData, WAITFOREVER);
  793. ResetEvent(vSemMoreData);
  794. }
  795. /*** InfoRead - return on/off depending if screen area is in memory
  796. *
  797. * Also sets some external value to prepair for the screens printing
  798. *
  799. * Should be modified to be smarter about one line movements.
  800. *
  801. */
  802. int
  803. InfoReady(
  804. void
  805. )
  806. {
  807. struct Block *pBlock;
  808. LONG *pLine;
  809. long foffset, boffset;
  810. int index, i, j;
  811. /*
  812. * Check that first line has been calced
  813. */
  814. if (vTopLine >= vNLine) {
  815. if (vTopLine+vLines > vLastLine) /* BUGFIX. TopLine can */
  816. vTopLine = vLastLine - vLines; /* get past EOF. */
  817. vReaderFlag = F_DOWN;
  818. return (0);
  819. }
  820. pLine = vprgLineTable [(int)vTopLine / PLINES];
  821. index = (int)(vTopLine % PLINES);
  822. foffset = *(pLine+=index);
  823. /*
  824. * Check that last line has been calced
  825. */
  826. if (vTopLine + (i = vLines) > vLastLine) {
  827. i = (int)(vLastLine - vTopLine + 1);
  828. for (j=i; j < vLines; j++) /* Clear ending len */
  829. vrgNewLen[j] = 0;
  830. }
  831. if (vTopLine + i > vNLine) {
  832. vReaderFlag = F_DOWN;
  833. return (0);
  834. }
  835. /*
  836. * Put this loop in assembler.. For more speed
  837. * boffset = calc_lens (foffset, i, pLine, index);
  838. */
  839. boffset = foffset;
  840. for (j=0; j < i; j++) { /* Calc new line len*/
  841. pLine++;
  842. if (++index >= PLINES) {
  843. index = 0;
  844. pLine = vprgLineTable [vTopLine / PLINES + 1];
  845. }
  846. boffset += (long)((vrgNewLen[j] = (Uchar)(*pLine - boffset)));
  847. }
  848. vScrMass = (unsigned)(boffset - foffset);
  849. /*
  850. * Check for both ends of display in memory
  851. */
  852. pBlock = vpCur;
  853. if (pBlock->offset <= foffset) {
  854. while (pBlock->offset + BLOCKSIZE <= foffset)
  855. if ( (pBlock = pBlock->next) == NULL) {
  856. vReaderFlag = F_DOWN;
  857. return (0);
  858. }
  859. vOffTop = (int)(foffset - pBlock->offset);
  860. vpBlockTop = vpCalcBlock = pBlock;
  861. while (pBlock->offset + BLOCKSIZE <= boffset)
  862. if ( (pBlock = pBlock->next) == NULL) {
  863. vReaderFlag = F_DOWN;
  864. return (0);
  865. }
  866. if (vpCur != pBlock) {
  867. vpCur = pBlock;
  868. vReaderFlag = F_CHECK;
  869. SetEvent (vSemReader);
  870. }
  871. return (1);
  872. } else {
  873. while (pBlock->offset > foffset)
  874. if ( (pBlock = pBlock->prev) == NULL) {
  875. vReaderFlag = F_UP;
  876. return (0);
  877. }
  878. vOffTop = (int)(foffset - pBlock->offset);
  879. vpBlockTop = vpCalcBlock = pBlock;
  880. while (pBlock->offset + BLOCKSIZE <= boffset)
  881. if ( (pBlock = pBlock->next) == NULL) {
  882. vReaderFlag = F_DOWN;
  883. return (0);
  884. }
  885. if (vpCur != pBlock) {
  886. vpCur = pBlock;
  887. vReaderFlag = F_CHECK;
  888. SetEvent (vSemReader);
  889. }
  890. return (1);
  891. }
  892. }