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.
 
 
 
 
 
 

172 lines
4.3 KiB

/* fastcopy - 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 <stdio.h>
#include <process.h>
#include <windows.h>
#include <tools.h>
#include <malloc.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 HMTX hmtxQLock;
//static HEV hevQNotEmpty;
static BUF *fpbufHead = NULL;
static BUF *fpbufTail = NULL;
static HANDLE hfSrc, hfDst;
static HANDLE hThread;
static BOOLEAN fAbort;
/* forward type definitions
*/
NPSZ writer( void );
DWORD reader( void );
BUF *dequeue( void );
void enqueue( BUF *fpbuf );
char *fastcopy( HANDLE hfSrcParm, HANDLE hfDstParm );
NPSZ writer ()
{
BUF *fpbuf;
DWORD cbBytesOut;
BOOL f = !LAST;
NPSZ npsz = NULL;
while (f != LAST && npsz == NULL) {
fpbuf = dequeue ();
if ((f = fpbuf->flag) != LAST) {
if( !WriteFile( hfDst, fpbuf->ach, fpbuf->cbBuf, &cbBytesOut, NULL) ) {
npsz = "WriteFile: error";
} else if( cbBytesOut != ( DWORD )fpbuf->cbBuf ) {
npsz = "WriteFile: out-of-space";
}
} else {
npsz = *(NPSZ *)fpbuf->ach;
}
LocalFree(fpbuf);
}
if ( f != LAST ) {
fAbort = TRUE;
}
WaitForSingleObject( hThread, (DWORD)-1 );
CloseHandle( hThread );
CloseHandle(hevQNotEmpty);
DeleteCriticalSection(&hcrtQLock);
return npsz;
}
DWORD reader()
{
BUF *fpbuf;
BOOL f = !LAST;
while ( !fAbort && f != LAST) {
if ( (fpbuf = LocalAlloc(LMEM_FIXED,sizeof(BUF)) ) == 0) {
printf ("LocalAlloc error %ld\n",GetLastError());
exit (1);
}
f = fpbuf->flag = NOTLAST;
if ( !ReadFile( hfSrc, fpbuf->ach, BUFSIZE, &fpbuf->cbBuf, NULL) || fpbuf->cbBuf == 0) {
f = fpbuf->flag = LAST;
*(NPSZ *)fpbuf->ach = NULL;
}
enqueue (fpbuf);
}
return( 0 );
}
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;
}
void enqueue( BUF *fpbuf )
{
fpbuf->fpbufNext = NULL;
EnterCriticalSection( &hcrtQLock );
if( fpbufTail == NULL ) {
fpbufHead = fpbuf;
} else {
fpbufTail->fpbufNext = fpbuf;
}
fpbufTail = fpbuf;
LeaveCriticalSection( &hcrtQLock );
SetEvent( hevQNotEmpty );
}
/* fastcopy - copy data quickly from one handle to another
*
* hfSrcParm file handle to read from
* hfDstParm file handle to write to
*
* returns NULL if successful
* pointer to error string otherwise
*/
char *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 ) {
return "can't create thread";
}
return( writer() );
}