Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

702 lines
19 KiB

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <memory.h>
#include <windows.h>
#include "list.h"
/*** ReaderThread - Reads from the file
*
*
* This thread is woken up by clearing SemReader,
* then vReaderFlag instructs the thread on the course of
* action to take. When displaying gets to close to the end
* of the buffer pool, vReadFlag is set and this thread is
* started.
*
*
*/
DWORD
ReaderThread (
DWORD dwParameter
)
{
unsigned rc, code, curPri;
LPVOID lpParameter=(LPVOID)dwParameter;
lpParameter; // to get rid of warning message
for (; ;) {
/*
* go into 'boosted' pririoty until we start
* working on 'non-critical' read ahead. (Ie, far away).
*
*/
if (curPri != vReadPriBoost) {
SetThreadPriority( GetCurrentThread(),
vReadPriBoost );
curPri = vReadPriBoost;
}
DosSemRequest (vSemReader, WAITFOREVER);
code = vReaderFlag;
for (; ;) {
/*
* Due to this loop, a new command may have arrived
* which takes presidence over the automated command
*/
rc = DosSemWait (vSemReader, DONTWAIT);
if (rc == 0) /* New command has arrived */
break;
switch (code) {
case F_NEXT: /* NEXT FILE */
NewFile ();
ReadDirect (vDirOffset);
/*
* Hack... adjust priority to make first screen look
* fast. (Ie, reader thread will have lower priority
* at first; eventhough the display is really close
* to the end of the buffer)
*/
SetThreadPriority( GetCurrentThread(),
vReadPriNormal );
break;
case F_HOME: /* HOME of FILE */
vTopLine = 0L;
ReadDirect (0L);
break;
case F_DIRECT:
ReadDirect (vDirOffset);
break;
case F_DOWN:
ReadNext ();
break;
case F_UP:
ReadPrev ();
break;
case F_END:
break;
case F_SYNC:
DosSemSet (vSemMoreData);
DosSemClear (vSemSync);
DosSemRequest (vSemReader, WAITFOREVER);
DosSemSet (vSemSync); /* Reset trigger for*/
/* Next use. */
code = vReaderFlag;
continue; /* Execute Syncronized command */
case F_CHECK: /* No command. */
break;
default:
ckdebug (1, "Bad Reader Flag");
}
/*
* Command has been processed.
* Now check to see if read ahead is low, if so set
* command and loop.
*/
if (vpTail->offset - vpCur->offset < vThreshold &&
vpTail->flag != F_EOF) {
code = F_DOWN; /* Too close to ending */
continue;
}
if (vpCur->offset - vpHead->offset < vThreshold &&
vpHead->offset != vpFlCur->SlimeTOF) {
code = F_UP; /* Too close to begining */
continue;
}
/*
* Not critical, read ahead logic. The current file
*
*/
/* Normal priority (below display thread) for this */
if (curPri != vReadPriNormal) {
SetThreadPriority( GetCurrentThread(),
vReadPriNormal );
curPri = vReadPriNormal;
}
if (vCntBlks == vMaxBlks) /* All blks in use for */
break; /* this one file? */
if (vpTail->flag != F_EOF) {
code = F_DOWN;
continue;
}
if (vpHead->offset != vpFlCur->SlimeTOF) {
code = F_UP;
continue;
}
if (vFhandle != 0) { /* Must have whole file read in */
CloseHandle (vFhandle); /* Close the file, and set flag */
vFhandle = 0;
if (!(vStatCode & S_INSEARCH)) {
ScrLock (1);
Update_head ();
vDate [ST_MEMORY] = 'M';
dis_str ((Uchar)(vWidth - ST_ADJUST), 0, vDate);
ScrUnLock ();
}
}
break; /* Nothing to do. Wait */
}
}
return(0);
}
/***
* WARNING: Microsoft Confidential!!!
*/
void
NewFile ()
{
char s [60];
char h, c;
SYSTEMTIME SystemTime;
FILETIME LocalFileTime;
long *pLine;
HANDLE TempHandle;
struct Block **pBlk, **pBlkCache;
if (vFhandle)
CloseHandle (vFhandle);
vFType = 0;
vCurOffset = 0L;
/***
* WARNING: Microsoft Confidential!!!
*/
strcpy (s, "Listing ");
strcpy (s+8, vpFname);
/* Design change per DougHo.. open files in read-only deny-none mode.*/
vFhandle = CreateFile( vpFlCur->fname,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );
if (vFhandle == (HANDLE)(-1)) {
if (vpFlCur->prev == NULL && vpFlCur->next == NULL) {
/* Only one file specified? */
printf ("Could not open file '%Fs': %s",
(CFP) vpFlCur->fname, GetErrorCode( GetLastError() ));
CleanUp();
ExitProcess(0);
}
vFhandle = 0; /* Error. Set externals to "safe" */
vFInfo.nFileSizeLow = (unsigned)-1L; /* settings. Flag error by setting */
vNLine = 1; /* file_size = -1 */
vLastLine = NOLASTLINE;
vDirOffset = vTopLine = 0L;
SetLoffset(0L);
memset (vprgLineTable, 0, sizeof (long *) * MAXTPAGE);
vprgLineTable[0] = (LFP) alloc_page ();
vprgLineTable[0][0] = 0L; /* 1st line always starts @ 0 */
strncpy (vDate, GetErrorCode( GetLastError() ), 20);
vDate[20] = 0;
return ;
}
TempHandle = FindFirstFile( vpFlCur->fname,
&vFInfo );
if( TempHandle == (HANDLE)(-1) ){
ckerr (GetLastError(), "FindFirstFile");
if (!FindClose( TempHandle ))
ckerr (GetLastError(), "FindCloseFile");
}
FileTimeToLocalFileTime( &(vFInfo.ftLastWriteTime), &LocalFileTime );
FileTimeToSystemTime( &LocalFileTime, &SystemTime );
h = (char)SystemTime.wHour;
if (h > 12) {
h -= 12;
c = 'p';
} else c = 'a';
sprintf (vDate, "%c%c %c%c%c%c %2d/%02d/%02d %2d:%02d%c",
/* File is in memory */
/* Search is set for mult files */
vStatCode & S_MFILE ? '*' : ' ',
/* File is in memory */
vFType & 0x8000 ? 'N' : ' ', /* Network */
vFInfo.dwFileAttributes & FILE_ATTRIBUTE_NORMAL ? 'R' : ' ', /* Readonly */
vFInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ? 'H' : ' ', /* Hidden */
vFInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM ? 'S' : ' ', /* System */
' ', /* Vio */
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wYear,
h,
SystemTime.wMinute,
c);
pBlkCache = &vpBCache;
if (CompareFileTime( &vFInfo.ftLastWriteTime, &vpFlCur->FileTime ) != 0) {
vpFlCur->NLine = 1L; /* Something has changed. */
vpFlCur->LastLine = NOLASTLINE; /* Scrap the old info, and */
vpFlCur->HighTop = -1; /* start over */
vpFlCur->TopLine = 0L;
vpFlCur->Loffset = vpFlCur->SlimeTOF;
FreePages (vpFlCur);
memset (vpFlCur->prgLineTable, 0, sizeof (long *) * MAXTPAGE);
vpFlCur->FileTime = vFInfo.ftLastWriteTime;
pBlkCache = &vpBFree; /* Move blks to free list, not cache list */
}
/*
* Restore last known information
*/
vTopLine = vpFlCur->TopLine;
SetLoffset(vpFlCur->Loffset);
vLastLine = vpFlCur->LastLine;
vNLine = vpFlCur->NLine;
vOffTop = 0;
if (vpFlCur->Wrap)
vWrap = vpFlCur->Wrap;
memcpy (vprgLineTable, vpFlCur->prgLineTable, sizeof (long *) * MAXTPAGE);
if (vLastLine == NOLASTLINE) {
pLine = vprgLineTable [vNLine/PLINES] + vNLine % PLINES;
}
if (vprgLineTable[0] == NULL) {
vprgLineTable[0] = (LFP) alloc_page ();
vprgLineTable[0][0] = vpFlCur->SlimeTOF;
}
vDirOffset = vprgLineTable[vTopLine/PLINES][vTopLine%PLINES];
vDirOffset -= vDirOffset % ((long)BLOCKSIZE);
/*
* Adjust buffers..
* Move cur buffers to other list
* Move cache buffers to other list
* Scan other list for cache blks, and move to cache (or free) list
*/
if (vpHead) {
vpTail->next = vpBOther; /* move them into the other */
vpBOther = vpHead; /* list */
vpHead = NULL;
}
pBlk = &vpBCache;
while (*pBlk)
MoveBlk (pBlk, &vpBOther) ;
pBlk = &vpBOther;
while (*pBlk) {
if ((*pBlk)->pFile == vpFlCur)
MoveBlk (pBlk, pBlkCache);
else pBlk = &(*pBlk)->next;
}
}
/*** ReadDirect - Moves to the direct position in the file
*
* First check to see if start of buffers have direct position file,
* if so then do nothing. If not, clear all buffers and start
* reading blocks.
*
*/
void
ReadDirect (
long offset
)
{
DosSemRequest (vSemBrief, WAITFOREVER);
if (vpHead) {
vpTail->next = vpBCache; /* move them into the cache */
vpBCache = vpHead; /* list */
}
vpTail = vpHead = vpCur = alloc_block (offset);
vpHead->next = vpTail->prev = NULL;
vCntBlks = 1;
/*
* Freeing is complete, now read in the first block.
* and process lines.
*/
ReadBlock (vpHead, offset);
//
// maybe it fixes the bug
//
vpBlockTop = vpHead;
if (GetLoffset() <= vpHead->offset)
add_more_lines (vpHead, NULL);
DosSemClear (vSemBrief);
DosSemClear (vSemMoreData); /* Signal another BLK read */
}
/*** ReadNext - To read further into file
*
*/
void
ReadNext ()
{
struct Block *pt;
long offset;
if (vpTail->flag == F_EOF) {
/* No next to get, Trip */
DosSemClear (vSemMoreData); /* moredata just in case */
return; /* t1 has blocked on it */
/* No next to get, Trip */
}
offset = vpTail->offset+BLOCKSIZE;
/*
* Get a block
*/
if (vCntBlks == vMaxBlks) {
DosSemRequest (vSemBrief, WAITFOREVER);
if (vpHead == vpCur) {
DosSemClear (vSemBrief);
if ((GetLoffset() > vpTail->offset) && (GetLoffset() <= (vpTail->offset + BLOCKSIZE))) {
offset = GetLoffset();
}
ReadDirect (offset);
return;
}
pt = vpHead;
vpHead = vpHead->next;
vpHead->prev = NULL;
DosSemClear (vSemBrief);
} else
pt = alloc_block (offset);
pt->next = NULL;
/*
* Before linking record into chain, or signaling MoreData
* line info is processed
*/
ReadBlock (pt, offset);
if (GetLoffset() <= pt->offset)
add_more_lines (pt, vpTail);
DosSemRequest (vSemBrief, WAITFOREVER); /* Link in new */
vpTail->next = pt; /* block, then */
pt->prev = vpTail; /* signal */
vpTail = pt;
DosSemClear (vSemBrief);
DosSemClear (vSemMoreData); /* Signal another BLK read */
}
void
add_more_lines (
struct Block *cur,
struct Block *prev
)
{
char *pData;
long *pLine;
Uchar LineLen;
Uchar c;
unsigned LineIndex;
unsigned DataIndex;
BOOL fLastBlock;
/*
* BUGBUG: doesn't work w/ tabs... it should count the line len
* with a different param, and figure in the TABs
*/
if (vLastLine != NOLASTLINE)
return;
if (vNLine/PLINES >= MAXTPAGE) {
puts("Sorry, This file is too big for LIST to handle - MAXTPAGE limit exceeded\n");
CleanUp();
ExitProcess(0);
}
/*
* Find starting data position
*/
if (GetLoffset() < cur->offset) {
DataIndex = (unsigned)(BLOCKSIZE - (GetLoffset() - prev->offset));
pData = prev->Data + BLOCKSIZE - DataIndex;
fLastBlock = FALSE;
} else {
DataIndex = cur->size; /* Use cur->size, in case EOF */
pData = cur->Data;
fLastBlock = TRUE;
}
/*
* Get starting line length table position
*/
LineIndex = (unsigned)(vNLine % PLINES);
pLine = vprgLineTable [vNLine / PLINES] + LineIndex;
LineLen = 0;
/*
* Look for lines in the file
*/
for (; ;) {
c = *(pData++);
if (--DataIndex == 0) {
if (fLastBlock)
break; /* Last block to scan? */
DataIndex = cur->size; /* No, move onto next */
pData = cur->Data; /* Block of data */
fLastBlock = TRUE;
}
LineLen++;
if (c == '\n' || c == '\r' || LineLen == vWrap) {
/*
* Got a line. Check for CR/LF sequence, then record
* it's length.
*/
if ( (c == '\n' && *pData == '\r') ||
(c == '\r' && *pData == '\n'))
{
LineLen++;
pData++;
if (--DataIndex == 0) {
if (fLastBlock)
break;
DataIndex = cur->size;
pData = cur->Data;
fLastBlock = TRUE;
}
}
SetLoffset(GetLoffset() + LineLen);
*(pLine++) = GetLoffset();
LineLen = 0;
vNLine++;
if (++LineIndex >= PLINES) { /* Overflowed table */
LineIndex = 0;
vprgLineTable[vNLine / PLINES] = pLine = (LFP) alloc_page();
}
}
}
/*
* Was last line just processed?
* ... 0 len lines past EOF
*/
if (cur->flag & F_EOF) {
if (LineLen) {
SetLoffset(GetLoffset() + LineLen);
*(pLine++) = GetLoffset();
vNLine++;
LineIndex++;
}
vLastLine = vNLine-1;
for (c=0; c<MAXLINES; c++) {
if (++LineIndex >= PLINES) {
LineIndex = 0;
vprgLineTable[vNLine / PLINES] = pLine = (LFP) alloc_page();
}
*(pLine++) = GetLoffset();
}
/* Free the memory we don't need */
}
}
/*** ReadPrev - To read backwards into file
*
*/
void
ReadPrev ()
{
struct Block *pt;
long offset;
if (vpHead->offset == 0L) { /* No next to get, Trip */
DosSemClear (vSemMoreData); /* moredata just in case */
return; /* t1 has blocked on it */
}
if (vpHead->offset == 0L) { /* No next to get, Trip */
return; /* t1 has blocked on it */
}
offset = vpHead->offset-BLOCKSIZE;
/*
* Get a block
*/
if (vCntBlks == vMaxBlks) {
DosSemRequest (vSemBrief, WAITFOREVER);
if (vpHead == vpCur) {
DosSemClear (vSemBrief);
ReadDirect (offset);
return;
}
pt = vpTail;
vpTail = vpTail->prev;
vpTail->next = NULL;
DosSemClear (vSemBrief);
} else
pt = alloc_block (offset);
pt->prev = NULL;
ReadBlock (pt, offset);
DosSemRequest (vSemBrief, WAITFOREVER); /* Link in new */
vpHead->prev = pt; /* block, then */
pt->next = vpHead; /* signal */
vpHead = pt;
DosSemClear (vSemBrief);
DosSemClear (vSemMoreData); /* Signal another BLK read */
}
/*** ReadBlock - Read in one block
*
*/
void
ReadBlock (
struct Block *pt,
long offset
)
{
long l;
DWORD dwSize;
if (pt->offset == offset)
return;
pt->offset = offset;
if (vFhandle == 0) { /* No file? */
pt->size = 1;
pt->flag = F_EOF;
pt->Data[0] = '\n';
return;
}
if (offset != vCurOffset) {
l = SetFilePointer( vFhandle, offset, NULL, FILE_BEGIN );
if (l == -1) {
ckerr (GetLastError(), "SetFilePointer");
}
}
if( !ReadFile (vFhandle, pt->Data, BLOCKSIZE, &dwSize, NULL) ) {
ckerr ( GetLastError(), "ReadFile" );
}
pt->size = (USHORT) dwSize;
if (pt->size != BLOCKSIZE) {
pt->Data[pt->size++] = '\n';
memset (pt->Data + pt->size, 0, BLOCKSIZE-pt->size);
pt->flag = F_EOF;
vCurOffset += pt->size;
} else {
pt->flag = 0;
vCurOffset += BLOCKSIZE;
}
}
void
SyncReader ()
{
vReaderFlag = F_SYNC;
DosSemClear (vSemReader);
DosSemRequest (vSemSync, WAITFOREVER);
}
//
// These functions are used for the call to HexEdit()
//
NTSTATUS
fncRead (
HANDLE h,
DWORD loc,
char *data,
DWORD len,
ULONG *ploc
)
{
DWORD l, br;
l = SetFilePointer (h, loc, NULL, FILE_BEGIN);
if (l == -1)
return GetLastError();
if (!ReadFile (h, data, len, &br, NULL))
return GetLastError();
return (br != len ? ERROR_READ_FAULT : 0);
}
NTSTATUS
fncWrite (
HANDLE h,
DWORD loc,
char *data,
DWORD len,
ULONG ploc
)
{
DWORD l, bw;
l = SetFilePointer (h, loc, NULL, FILE_BEGIN);
if (l == -1)
return GetLastError();
if (!WriteFile (h, data, len, &bw, NULL))
return GetLastError();
return (bw != len ? ERROR_WRITE_FAULT : 0);
}
long CurrentLineOffset;
long GetLoffset() {
return(CurrentLineOffset);
}
void SetLoffset(long l) {
CurrentLineOffset = l;
return;
}