File:  [WindowsNT SDKs] / mstools / samples / porttool / ptbkport.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:22:11 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-oct-1992, HEAD
Microsoft Windows NT Build 328 10-12-1992

#include "porttool.h"
#include "port.h"


// define line types returned from GetNextLine
#define VALID_LINE	 0
#define COMMENT_LINE	 1
#define EOF_LINE	 2

#define CARRIAGE_RETURN  13
#define LINE_FEED	 10

// define worker functions for this module
int  WINAPI GetNextLine (char *, int, char *, char *, BOOL *);
int  WINAPI NextLineLength (char *, char *, int);
BOOL WINAPI BkFilePortThread (LPBKPORTFILESTRUCT);
void WINAPI DateTimeStamp (char *);



// function creates a background porting thread
HANDLE WINAPI StartBkPortThread (LPBKPORTFILESTRUCT    lpBkPort)
{
    DWORD    id;

    // create thread with initial structure
    return (lpBkPort->hThread = CreateThread ((LPSECURITY_ATTRIBUTES)NULL,
				      4096,
				      (LPTHREAD_START_ROUTINE)BkFilePortThread,
				      (LPVOID)lpBkPort,
				      0,
				      &id));
}


// independent thread function that performs background file porting
BOOL WINAPI BkFilePortThread (
    LPBKPORTFILESTRUCT	  lpBkPort)
{
    HANDLE	hEvents[nBKPORTEVENTS];
    HANDLE	hFile;
    OFSTRUCT	of;
    DWORD	nFileSize;
    DWORD       nBytes;
    HANDLE	hFileBuffer;
    char	*lpFile, *lpFilePtr;
    WORD	wComplete, wIssues = 0;
    int 	nLines = 0;
    BOOL	bCommentOn;
    HANDLE	hLine;
    HANDLE	hToken, hIssue, hSuggest, hHelp;
    RESULT	rIssue;
    char	*lpLine;
    char	szHeader[MAX_PATH], szToken[50], szIssue[50], szdt[50],
		szSuggest[50], szHelp[50], szHelpFile[50], szEOL[50], szNL[5];


    // adjust our priority to below normal
    SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_BELOW_NORMAL);

    // load file comment strings
    LoadString (GetModuleHandle (NULL), IDS_BKPORTNEWLINE, szNL, 5);
    LoadString (GetModuleHandle (NULL), IDS_BKPORTHEADER, szHeader, MAX_PATH);
    LoadString (GetModuleHandle (NULL), IDS_BKPORTTOKEN, szToken, 50);
    LoadString (GetModuleHandle (NULL), IDS_BKPORTISSUE, szIssue, 50);
    LoadString (GetModuleHandle (NULL), IDS_BKPORTSUGGEST, szSuggest, 50);
    LoadString (GetModuleHandle (NULL), IDS_BKPORTHELP, szHelp, 50);
    LoadString (GetModuleHandle (NULL), IDS_BKPORTHELPFILE, szHelpFile, 50);
    LoadString (GetModuleHandle (NULL), IDS_BKPORTEOL, szEOL, 50);

    // initialize wait events for communication between threads
    if (!CreateEvents (hEvents, lpBkPort))
	return FALSE;

    // open file for porting and read into buffer
    if ((int)(hFile = (HANDLE)OpenFile (lpBkPort->szFilePath, &of, OF_READWRITE)) == -1)
	{
	DestroyEvents (hEvents);
	return FALSE;
	}

    // global allocate buffer for file
    if (!(hFileBuffer = GlobalAlloc (GPTR, (nFileSize = GetFileSize (hFile, NULL))+1)) ||
	!(lpFile = (char *)GlobalLock (hFileBuffer)))
	{
	CloseHandle (hFile);
	DestroyEvents (hEvents);
	return FALSE;
	}

    // allocate initial line buffer of reasonable size
    hLine = GlobalAlloc (GMEM_MOVEABLE, 1024);

    // allocate local memory segments for porttool RESULT strings
    if (!(rIssue.lpszToken = LocalLock (hToken = LocalAlloc (LHND, MAXTOKENLEN))) ||
	!(rIssue.lpszHelpStr = LocalLock (hHelp = LocalAlloc (LHND, MAXHELPLEN))) ||
	!(rIssue.lpszIssue = LocalLock (hIssue = LocalAlloc (LHND, MAXISSUELEN))) ||
	!(rIssue.lpszSuggest = LocalLock (hSuggest = LocalAlloc (LHND, MAXSUGGESTLEN))))
	{
	CloseHandle (hFile);
	GlobalUnlock (lpFile);
	GlobalFree (hFileBuffer);
	DestroyEvents (hEvents);
	GlobalFree (hLine);
	return FALSE;
	}

    // read entire file into buffer and zero terminate
    ReadFile (hFile, lpFile, nFileSize, &nBytes, NULL);
    lpFile[nFileSize] = 0;
    lpFilePtr = lpFile;

    // if bytes read not equal to size of file, abort
    if (nBytes != nFileSize)
	{
	CloseHandle (hFile);
	GlobalUnlock (lpFile);
	GlobalFree (hFileBuffer);
	DestroyEvents (hEvents);
	GlobalFree (hLine);
	return FALSE;
	}

    // reset file to size zero before beginning porting
    SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
    SetEndOfFile (hFile);
    WriteFile (hFile, szHeader, strlen (szHeader), &nBytes, NULL);
    WriteFile (hFile, lpBkPort->szFile, strlen (lpBkPort->szFile), &nBytes, NULL);
    WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL);
    WriteFile (hFile, szNL, strlen (szNL), &nBytes, NULL);

    while (TRUE)
	{
	// wait 1ms for either abort or status events to signal
	switch (WaitForMultipleObjects (nBKPORTEVENTS, hEvents, FALSE, 1))
	    {
	    case BKPORT_ABORT:
		{
		char	szAbort[MAX_PATH];

		// create time and date
		DateTimeStamp (szdt);

		// write header line
		WriteFile (hFile, szHeader, strlen (szHeader), &nBytes, NULL);
		WriteFile (hFile, szdt, strlen (szdt), &nBytes, NULL);
		WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL);
		WriteFile (hFile, szNL, strlen (szNL), &nBytes, NULL);

		// load abort string and write to file
		LoadString (GetModuleHandle (NULL),
			    IDS_BKPORTABORT,
			    szAbort,
			    MAX_PATH);
		WriteFile (hFile, szAbort, strlen (szAbort), (LPDWORD)&nBytes, NULL);

		// write rest of file to disk
		WriteFile (hFile,
			   (VOID *)lpFilePtr,
			   (nFileSize - (lpFilePtr-lpFile)),
			   (LPDWORD)&nBytes,
			   NULL);

		// clean up
		CloseHandle (hFile);
		GlobalUnlock (lpFile);
		GlobalFree (hFileBuffer);
		GlobalFree (hLine);
		DestroyEvents (hEvents);

		// free RESULT strings
		LocalUnlock (hToken); LocalFree (hToken);
		LocalUnlock (hHelp); LocalFree (hHelp);
		LocalUnlock (hIssue); LocalFree (hIssue);
		LocalUnlock (hSuggest); LocalFree (hSuggest);

		// send message to parent that thread is dead
		PostMessage (lpBkPort->hDlg,
			     UM_THREADCOMPLETE,
			     (UINT)lpBkPort->hThread,
			     0);

		// exit thread
		return FALSE;
		}
		break;

	    case BKPORT_STATUS:
		// send message to dialog with status info
		PostMessage (lpBkPort->hDlg,
			     UM_STATUSUPDATE,
			     MAKELONG (wIssues, wComplete),
			     nLines);
		break;
	    }

	// reset line buffer
	GlobalReAlloc (hLine,
		       NextLineLength (lpFilePtr, lpFile, nFileSize),
		       GMEM_MOVEABLE);
	lpLine = (char *)GlobalLock (hLine);
	*lpLine = 0;

	// get next line from  file buffer
	switch (GetNextLine (lpFile, nFileSize, lpFilePtr, lpLine, &bCommentOn))
	    {
	    // check valid strings for porting issues
	    case VALID_LINE:
		// initialize rIssue string lengths
		*(WORD *)rIssue.lpszToken = MAXTOKENLEN;
		*(WORD *)rIssue.lpszHelpStr = MAXHELPLEN;
		*(WORD *)rIssue.lpszIssue = MAXISSUELEN;
		*(WORD *)rIssue.lpszSuggest = MAXSUGGESTLEN;

		if (CheckString (lpLine, lpBkPort->dwPTFlags, &rIssue))
		    {
		    // create time and date
		    DateTimeStamp (szdt);

		    // write header line
		    WriteFile (hFile, szNL, strlen (szNL), &nBytes, NULL);
		    WriteFile (hFile, szHeader, strlen (szHeader), &nBytes, NULL);
		    WriteFile (hFile, szdt, strlen (szdt), &nBytes, NULL);
		    WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL);

		    // write token line
		    WriteFile (hFile, szToken, strlen (szToken), &nBytes, NULL);
		    WriteFile (hFile,
			       rIssue.lpszToken,
			       strlen (rIssue.lpszToken),
			       &nBytes,
			       NULL);
		    WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL);

		    // write issue line
		    WriteFile (hFile, szIssue, strlen (szIssue), &nBytes, NULL);
		    WriteFile (hFile,
			       rIssue.lpszIssue,
			       strlen (rIssue.lpszIssue),
			       &nBytes,
			       NULL);
		    WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL);

		    // if suggestion
		    if (*(rIssue.lpszSuggest))
			{
			WriteFile (hFile, szSuggest, strlen (szSuggest), &nBytes, NULL);
			WriteFile (hFile,
				   rIssue.lpszSuggest,
				   strlen (rIssue.lpszSuggest),
				   &nBytes,
				   NULL);
			WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL);
			}

		    // if help string
		    if (*(rIssue.lpszSuggest))
			{
			WriteFile (hFile, szHelp, strlen (szHelp), &nBytes, NULL);
			WriteFile (hFile,
				   rIssue.lpszHelpStr,
				   strlen (rIssue.lpszHelpStr),
				   &nBytes,
				   NULL);
			WriteFile (hFile, szHelpFile, strlen (szHelpFile), &nBytes, NULL);
			WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL);
			}

		    wIssues++;
		    }

	    case COMMENT_LINE:
		// write line to file whether comment or not
		WriteFile (hFile, lpLine, strlen (lpLine), &nBytes, NULL);
		break;

	    case EOF_LINE:
		if (*lpLine)
		    WriteFile (hFile, lpLine, strlen (lpLine), &nBytes, NULL);
		goto DONE;
		break;
	    }

	// unlock line buffer
	GlobalUnlock (hLine);

	// update status counts
	lpFilePtr += strlen (lpLine);
	nLines++;
	wComplete = (WORD)(((lpFilePtr-lpFile)*100)/nFileSize);
	}

DONE:
    // clean up
    CloseHandle (hFile);
    GlobalUnlock (lpFile);
    GlobalFree (hFileBuffer);
    GlobalFree (hLine);
    DestroyEvents (hEvents);

    // free RESULT strings
    LocalUnlock (hToken); LocalFree (hToken);
    LocalUnlock (hHelp); LocalFree (hHelp);
    LocalUnlock (hIssue); LocalFree (hIssue);
    LocalUnlock (hSuggest); LocalFree (hSuggest);

    // send message to parent that thread is dead
    PostMessage (lpBkPort->hDlg,
		 UM_THREADCOMPLETE,
		 (UINT)lpBkPort->hThread,
		 0);

    // exit thread
    return TRUE;
}



void WINAPI DateTimeStamp (
    char    *lpszDT)
{
    SYSTEMTIME	  dt;
    char	  Buff[10];

    // create time and date stamp
    GetSystemTime (&dt);
    strcpy (lpszDT, itoa (dt.wMonth, Buff, 10));
    strcat (lpszDT, "/");
    strcat (lpszDT, itoa (dt.wDay, Buff, 10));
    strcat (lpszDT, "/");
    strcat (lpszDT, itoa (dt.wYear, Buff, 10));
    strcat (lpszDT, "    ");
    strcat (lpszDT, itoa (dt.wHour, Buff, 10));
    strcat (lpszDT, ":");
    strcat (lpszDT, itoa (dt.wMinute, Buff, 10));
}





BOOL WINAPI CreateEvents (
    HANDLE		  *lphEvents,
    LPBKPORTFILESTRUCT	  lpBkPort)
{
    char    szEvent[MAX_PATH];


    LoadString (GetModuleHandle (NULL), IDS_BKPORTABORT, szEvent, MAX_PATH);
    strcat (szEvent, lpBkPort->szFile);
    if (!(lphEvents[BKPORT_ABORT] = CreateEvent (NULL, TRUE, FALSE, szEvent)))
	return FALSE;

    LoadString (GetModuleHandle (NULL), IDS_BKPORTSTATUS, szEvent, MAX_PATH);
    strcat (szEvent, lpBkPort->szFile);
    if (!(lphEvents[BKPORT_STATUS] = CreateEvent (NULL, TRUE, FALSE, szEvent)))
	{
	CloseHandle (lphEvents[BKPORT_ABORT]);
	return FALSE;
	}

    // return success
    return TRUE;
}




void WINAPI DestroyEvents (
    HANDLE    *lphEvents)
{
    // close event handles
    CloseHandle (lphEvents[BKPORT_ABORT]);
    CloseHandle (lphEvents[BKPORT_STATUS]);
}




int WINAPI NextLineLength (
    char    *lpFilePtr,
    char    *lpFile,
    int     nFileSize)
{
    int    nCnt;
    char   *lpf = lpFilePtr;

    // count all characters up to end of file or CR/LF sequence
    while (lpf				 &&
	   lpf-lpFile < nFileSize	 &&
	   *lpf       != CARRIAGE_RETURN &&
	   *(lpf+1)   != LINE_FEED)
	{
	lpf++;
	nCnt++;
	}

    // length plus 3 for CR/LF/0 terminator sequence
    return nCnt + 3;
}




int WINAPI GetNextLine (
    char    *lpFile,
    int     nFileSize,
    char    *lpFilePtr,
    char    *lpLine,
    BOOL    *bCommentOn)
{
    char    *lpf = lpFilePtr;
    char    *lpl = lpLine;

    // copy all characters up to end of file or CR/LF sequence
    while (lpf				 &&
	   lpf-lpFile < nFileSize	 &&
	   *lpf       != CARRIAGE_RETURN &&
	   *(lpf+1)   != LINE_FEED)
	*lpl++ = *lpf++;

    // check for end of buffer
    if (lpf-lpFile >= nFileSize)
	return EOF_LINE;

    // copy carriage return and line feed to line and terminate
    *lpl++ = *lpf++;
    *lpl++ = *lpf++;
    *lpl = 0;

    // increment lpl to first non space character in line
    lpl = lpLine;
    while (*lpl == ' ')
	lpl++;

    // see if single line comments exist
    if (*lpl	 == '/' &&
	*(lpl+1) == '/')
	return COMMENT_LINE;

    // see if comments begin
    if (*lpl	 == '/'  &&
	*(lpl+1) == '*')
	*bCommentOn = TRUE;

    // if comment on, see if it terminates yet
    if (*bCommentOn)
	{
	lpl = lpLine;
	while (*lpl)
	    {
	    if (*lpl	 == '*'  &&
		*(lpl+1) == '/')
		{
		*bCommentOn = FALSE;
		break;
		}
	    lpl++;
	    }

	// if more text on line, valid line
	while (*lpl)
	    if (*lpl != '*'	 &&
		*(lpl+1) != '/')
		return VALID_LINE;
	    else
		return COMMENT_LINE;
	}

    // if haven't returned yet, must be valid line
    return VALID_LINE;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.