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

  1. /* fastcopy - use multiple threads to whack data from one file to another
  2. *
  3. * Modifications:
  4. * 18-Oct-1990 w-barry Removed 'dead' code.
  5. * 21-Nov-1990 w-barry Updated API's to the Win32 set.
  6. */
  7. #define INCL_DOSPROCESS
  8. #define INCL_DOSSEMAPHORES
  9. #include <stdio.h>
  10. #include <process.h>
  11. #include <windows.h>
  12. #include <tools.h>
  13. #include <malloc.h>
  14. #define BUFSIZE 0xFE00 /* full segment minus sector */
  15. #define STACKSIZE 256 /* stack size for child thread */
  16. typedef struct BUF BUF;
  17. struct BUF {
  18. BOOL flag;
  19. DWORD cbBuf;
  20. BUF *fpbufNext;
  21. BYTE ach[BUFSIZE];
  22. };
  23. #define LAST TRUE
  24. #define NOTLAST FALSE
  25. static HANDLE hevQNotEmpty;
  26. static CRITICAL_SECTION hcrtQLock;
  27. //static HMTX hmtxQLock;
  28. //static HEV hevQNotEmpty;
  29. static BUF *fpbufHead = NULL;
  30. static BUF *fpbufTail = NULL;
  31. static HANDLE hfSrc, hfDst;
  32. static HANDLE hThread;
  33. static BOOLEAN fAbort;
  34. /* forward type definitions
  35. */
  36. NPSZ writer( void );
  37. DWORD reader( void );
  38. BUF *dequeue( void );
  39. void enqueue( BUF *fpbuf );
  40. char *fastcopy( HANDLE hfSrcParm, HANDLE hfDstParm );
  41. NPSZ writer ()
  42. {
  43. BUF *fpbuf;
  44. DWORD cbBytesOut;
  45. BOOL f = !LAST;
  46. NPSZ npsz = NULL;
  47. while (f != LAST && npsz == NULL) {
  48. fpbuf = dequeue ();
  49. if ((f = fpbuf->flag) != LAST) {
  50. if( !WriteFile( hfDst, fpbuf->ach, fpbuf->cbBuf, &cbBytesOut, NULL) ) {
  51. npsz = "WriteFile: error";
  52. } else if( cbBytesOut != ( DWORD )fpbuf->cbBuf ) {
  53. npsz = "WriteFile: out-of-space";
  54. }
  55. } else {
  56. npsz = *(NPSZ *)fpbuf->ach;
  57. }
  58. LocalFree(fpbuf);
  59. }
  60. if ( f != LAST ) {
  61. fAbort = TRUE;
  62. }
  63. WaitForSingleObject( hThread, (DWORD)-1 );
  64. CloseHandle( hThread );
  65. CloseHandle(hevQNotEmpty);
  66. DeleteCriticalSection(&hcrtQLock);
  67. return npsz;
  68. }
  69. DWORD reader()
  70. {
  71. BUF *fpbuf;
  72. BOOL f = !LAST;
  73. while ( !fAbort && f != LAST) {
  74. if ( (fpbuf = LocalAlloc(LMEM_FIXED,sizeof(BUF)) ) == 0) {
  75. printf ("LocalAlloc error %ld\n",GetLastError());
  76. exit (1);
  77. }
  78. f = fpbuf->flag = NOTLAST;
  79. if ( !ReadFile( hfSrc, fpbuf->ach, BUFSIZE, &fpbuf->cbBuf, NULL) || fpbuf->cbBuf == 0) {
  80. f = fpbuf->flag = LAST;
  81. *(NPSZ *)fpbuf->ach = NULL;
  82. }
  83. enqueue (fpbuf);
  84. }
  85. return( 0 );
  86. }
  87. BUF *dequeue( void )
  88. {
  89. BUF *fpbuf;
  90. while (TRUE) {
  91. if (fpbufHead != NULL) {
  92. EnterCriticalSection( &hcrtQLock );
  93. fpbufHead = (fpbuf = fpbufHead)->fpbufNext;
  94. if( fpbufTail == fpbuf ) {
  95. fpbufTail = NULL;
  96. }
  97. LeaveCriticalSection( &hcrtQLock );
  98. break;
  99. }
  100. /*
  101. the head pointer is null so the list is empty.
  102. block on eventsem until enqueue posts (ie. adds to queue)
  103. */
  104. WaitForSingleObject( hevQNotEmpty, (DWORD)-1 );
  105. }
  106. return fpbuf;
  107. }
  108. void enqueue( BUF *fpbuf )
  109. {
  110. fpbuf->fpbufNext = NULL;
  111. EnterCriticalSection( &hcrtQLock );
  112. if( fpbufTail == NULL ) {
  113. fpbufHead = fpbuf;
  114. } else {
  115. fpbufTail->fpbufNext = fpbuf;
  116. }
  117. fpbufTail = fpbuf;
  118. LeaveCriticalSection( &hcrtQLock );
  119. SetEvent( hevQNotEmpty );
  120. }
  121. /* fastcopy - copy data quickly from one handle to another
  122. *
  123. * hfSrcParm file handle to read from
  124. * hfDstParm file handle to write to
  125. *
  126. * returns NULL if successful
  127. * pointer to error string otherwise
  128. */
  129. char *fastcopy( HANDLE hfSrcParm, HANDLE hfDstParm)
  130. {
  131. DWORD dwReader;
  132. hfSrc = hfSrcParm;
  133. hfDst = hfDstParm;
  134. hevQNotEmpty = CreateEvent( NULL, (BOOL)FALSE, (BOOL)FALSE,NULL );
  135. if ( hevQNotEmpty == INVALID_HANDLE_VALUE ) {
  136. return NULL;
  137. }
  138. InitializeCriticalSection( &hcrtQLock );
  139. fAbort = FALSE;
  140. hThread = CreateThread( 0, STACKSIZE, (LPTHREAD_START_ROUTINE)reader, 0, 0, &dwReader );
  141. if( hThread == INVALID_HANDLE_VALUE ) {
  142. return "can't create thread";
  143. }
  144. return( writer() );
  145. }