diff options
Diffstat (limited to '')
-rw-r--r-- | private/nw/convert/nwconv/fastcopy.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/private/nw/convert/nwconv/fastcopy.c b/private/nw/convert/nwconv/fastcopy.c new file mode 100644 index 000000000..e97191e10 --- /dev/null +++ b/private/nw/convert/nwconv/fastcopy.c @@ -0,0 +1,244 @@ +/* + +-------------------------------------------------------------------------+ + | File Copying Routines | + +-------------------------------------------------------------------------+ + | (c) Copyright 1993-1994 | + | Microsoft Corp. | + | All rights reserved | + | | + | Program : [FastCopy.c] | + | Programmer : Arthur Hanson | + | Original Program Date : [Jul 27, 1993] | + | Last Update : [Jun 18, 1994] | + | | + | Version: 1.00 | + | | + | Use multiple threads to whack data from one file to another | + | | + | Modifications: | + | 18-Oct-1990 w-barry Removed 'dead' code. | + | 21-Nov-1990 w-barry Updated API's to the Win32 set. | + | | + +-------------------------------------------------------------------------+ +*/ + +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES + +#include "globals.h" +#include <stdio.h> +#include <process.h> +#include <windows.h> +#include <malloc.h> +#include "mem.h" +#include "debug.h" +#include "utils.h" +#include "convapi.h" + +#define BUFSIZE 0xFE00 // full segment minus sector +#define STACKSIZE 256 // stack size for child thread + +typedef struct BUF BUF; + +struct BUF { + BOOL flag; + DWORD cbBuf; + BUF *fpbufNext; + BYTE ach[BUFSIZE]; +}; + +#define LAST TRUE +#define NOTLAST FALSE + +static HANDLE hevQNotEmpty; +static CRITICAL_SECTION hcrtQLock; +static BUF *fpbufHead = NULL; +static BUF *fpbufTail = NULL; +static HANDLE hfSrc, hfDst; +static HANDLE hThread; +static BOOLEAN fAbort; + +// forward type definitions + +LPTSTR writer( void ); +DWORD reader( void ); +BUF *dequeue( void ); +void enqueue( BUF *fpbuf ); +TCHAR *fastcopy( HANDLE hfSrcParm, HANDLE hfDstParm ); + +/*+-------------------------------------------------------------------------+ + | writer() + | + +-------------------------------------------------------------------------+*/ +LPTSTR writer ( void ) { + BUF *fpbuf; + DWORD cbBytesOut; + BOOL f = !LAST; + LPTSTR npsz = NULL; + ULONG BytesCopied = 0; + + TCHAR buffer[MAX_PATH]; + + Status_Bytes(lToStr(BytesCopied)); + + while (f != LAST && npsz == NULL) { + fpbuf = dequeue (); + + if (fpbuf) { + if ((f = fpbuf->flag) != LAST) { + if (!WriteFile(hfDst, fpbuf->ach, fpbuf->cbBuf, &cbBytesOut, NULL)) { + npsz = Lids(IDS_L_4); +#ifdef DEBUG +dprintf(TEXT("ERROR: WriteFile\n")); +#endif + } else { + BytesCopied += cbBytesOut; + Status_Bytes(lToStr(BytesCopied)); + + + if (cbBytesOut != (DWORD)fpbuf->cbBuf) { + npsz = Lids(IDS_L_5); +#ifdef DEBUG +dprintf(TEXT("ERROR: WriteFile: out-of-space\n")); +#endif + } + } + } + else + npsz = *(LPTSTR *)fpbuf->ach; + + FreeMemory(fpbuf); + + } else { + wsprintf (buffer, Lids(IDS_L_4), fpbuf); +#ifdef DEBUG +dprintf(TEXT("ERROR: WriteFile - FileBuffer is NULL\n")); +#endif + } + } + + if (f != LAST) + fAbort = TRUE; + + WaitForSingleObject(hThread, (DWORD)-1); + CloseHandle(hThread); + CloseHandle(hevQNotEmpty); + DeleteCriticalSection(&hcrtQLock); + + return (npsz); +} // writer + + +/*+-------------------------------------------------------------------------+ + | reader() + | + +-------------------------------------------------------------------------+*/ +DWORD reader( void ) { + BUF *fpbuf; + BOOL f = !LAST; + + while (!fAbort && f != LAST) { + if ((fpbuf = AllocMemory(sizeof(BUF))) == NULL) { +#ifdef DEBUG +dprintf(TEXT("ERROR: MemoryAlloc error %ld\n"), GetLastError()); +#endif + return(0); + } + + f = fpbuf->flag = NOTLAST; + if (!ReadFile(hfSrc, fpbuf->ach, BUFSIZE, &fpbuf->cbBuf, NULL) || fpbuf->cbBuf == 0) { + f = fpbuf->flag = LAST; + *(LPTSTR *)(fpbuf->ach) = NULL; + } + + enqueue (fpbuf); + } + + return(0); +} // reader + + +/*+-------------------------------------------------------------------------+ + | dequeue() + | + +-------------------------------------------------------------------------+*/ +BUF *dequeue( void ) { + BUF *fpbuf; + + while (TRUE) { + if (fpbufHead != NULL) { + EnterCriticalSection(&hcrtQLock); + fpbufHead = (fpbuf = fpbufHead)->fpbufNext; + + if (fpbufTail == fpbuf) + fpbufTail = NULL; + + LeaveCriticalSection(&hcrtQLock); + break; + } + + // the head pointer is null so the list is empty. Block on eventsem + // until enqueue posts (ie. adds to queue) + WaitForSingleObject(hevQNotEmpty, (DWORD)-1); + } + + return fpbuf; +} // dequeue + + +/*+-------------------------------------------------------------------------+ + | enqueue() + | + +-------------------------------------------------------------------------+*/ +void enqueue( BUF *fpbuf ) { + fpbuf->fpbufNext = NULL; + + EnterCriticalSection(&hcrtQLock); + + if (fpbufTail == NULL) + fpbufHead = fpbuf; + else + fpbufTail->fpbufNext = fpbuf; + + fpbufTail = fpbuf; + LeaveCriticalSection(&hcrtQLock); + + SetEvent(hevQNotEmpty); +} // enqueue + + +/*+-------------------------------------------------------------------------+ + | fastcopy() + | + | hfSrcParm file handle to read from + | hfDstParm file handle to write to + | + | returns NULL if successful + | pointer to error string otherwise + +-------------------------------------------------------------------------+*/ +TCHAR *fastcopy (HANDLE hfSrcParm, HANDLE hfDstParm) { + DWORD dwReader; + + hfSrc = hfSrcParm; + hfDst = hfDstParm; + + + hevQNotEmpty = CreateEvent(NULL, (BOOL)FALSE, (BOOL)FALSE, NULL); + if (hevQNotEmpty == INVALID_HANDLE_VALUE) + return NULL; + + InitializeCriticalSection(&hcrtQLock); + + fAbort = FALSE; + hThread = CreateThread(0, STACKSIZE, (LPTHREAD_START_ROUTINE)reader, 0, 0, &dwReader); + if (hThread == INVALID_HANDLE_VALUE) { +#ifdef DEBUG +dprintf(TEXT("ERROR: Can't create thread - FileCopy\n")); +#endif + return Lids(IDS_L_6); + } + + return(writer()); +} // fastcopy + + |