Source code of Windows XP (NT5)
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.

244 lines
6.8 KiB

  1. /*
  2. +-------------------------------------------------------------------------+
  3. | File Copying Routines |
  4. +-------------------------------------------------------------------------+
  5. | (c) Copyright 1993-1994 |
  6. | Microsoft Corp. |
  7. | All rights reserved |
  8. | |
  9. | Program : [FastCopy.c] |
  10. | Programmer : Arthur Hanson |
  11. | Original Program Date : [Jul 27, 1993] |
  12. | Last Update : [Jun 18, 1994] |
  13. | |
  14. | Version: 1.00 |
  15. | |
  16. | Use multiple threads to whack data from one file to another |
  17. | |
  18. | Modifications: |
  19. | 18-Oct-1990 w-barry Removed 'dead' code. |
  20. | 21-Nov-1990 w-barry Updated API's to the Win32 set. |
  21. | |
  22. +-------------------------------------------------------------------------+
  23. */
  24. #define INCL_DOSPROCESS
  25. #define INCL_DOSSEMAPHORES
  26. #include "globals.h"
  27. #include <stdio.h>
  28. #include <process.h>
  29. #include <windows.h>
  30. #include <malloc.h>
  31. #include "mem.h"
  32. #include "debug.h"
  33. #include "utils.h"
  34. #include "convapi.h"
  35. #define BUFSIZE 0xFE00 // full segment minus sector
  36. #define STACKSIZE 256 // stack size for child thread
  37. typedef struct BUF BUF;
  38. struct BUF {
  39. BOOL flag;
  40. DWORD cbBuf;
  41. BUF *fpbufNext;
  42. BYTE ach[BUFSIZE];
  43. };
  44. #define LAST TRUE
  45. #define NOTLAST FALSE
  46. static HANDLE hevQNotEmpty;
  47. static CRITICAL_SECTION hcrtQLock;
  48. static BUF *fpbufHead = NULL;
  49. static BUF *fpbufTail = NULL;
  50. static HANDLE hfSrc, hfDst;
  51. static HANDLE hThread;
  52. static BOOLEAN fAbort;
  53. // forward type definitions
  54. LPTSTR writer( void );
  55. DWORD reader( void );
  56. BUF *dequeue( void );
  57. void enqueue( BUF *fpbuf );
  58. TCHAR *fastcopy( HANDLE hfSrcParm, HANDLE hfDstParm );
  59. /*+-------------------------------------------------------------------------+
  60. | writer()
  61. |
  62. +-------------------------------------------------------------------------+*/
  63. LPTSTR writer ( void ) {
  64. BUF *fpbuf;
  65. DWORD cbBytesOut;
  66. BOOL f = !LAST;
  67. LPTSTR npsz = NULL;
  68. ULONG BytesCopied = 0;
  69. TCHAR buffer[MAX_PATH];
  70. Status_Bytes(lToStr(BytesCopied));
  71. while (f != LAST && npsz == NULL) {
  72. fpbuf = dequeue ();
  73. if (fpbuf) {
  74. if ((f = fpbuf->flag) != LAST) {
  75. if (!WriteFile(hfDst, fpbuf->ach, fpbuf->cbBuf, &cbBytesOut, NULL)) {
  76. npsz = Lids(IDS_L_4);
  77. #ifdef DEBUG
  78. dprintf(TEXT("ERROR: WriteFile\n"));
  79. #endif
  80. } else {
  81. BytesCopied += cbBytesOut;
  82. Status_Bytes(lToStr(BytesCopied));
  83. if (cbBytesOut != (DWORD)fpbuf->cbBuf) {
  84. npsz = Lids(IDS_L_5);
  85. #ifdef DEBUG
  86. dprintf(TEXT("ERROR: WriteFile: out-of-space\n"));
  87. #endif
  88. }
  89. }
  90. }
  91. else
  92. npsz = *(LPTSTR *)fpbuf->ach;
  93. FreeMemory(fpbuf);
  94. } else {
  95. wsprintf (buffer, Lids(IDS_L_4), fpbuf);
  96. #ifdef DEBUG
  97. dprintf(TEXT("ERROR: WriteFile - FileBuffer is NULL\n"));
  98. #endif
  99. }
  100. }
  101. if (f != LAST)
  102. fAbort = TRUE;
  103. WaitForSingleObject(hThread, (DWORD)-1);
  104. CloseHandle(hThread);
  105. CloseHandle(hevQNotEmpty);
  106. DeleteCriticalSection(&hcrtQLock);
  107. return (npsz);
  108. } // writer
  109. /*+-------------------------------------------------------------------------+
  110. | reader()
  111. |
  112. +-------------------------------------------------------------------------+*/
  113. DWORD reader( void ) {
  114. BUF *fpbuf;
  115. BOOL f = !LAST;
  116. while (!fAbort && f != LAST) {
  117. if ((fpbuf = AllocMemory(sizeof(BUF))) == NULL) {
  118. #ifdef DEBUG
  119. dprintf(TEXT("ERROR: MemoryAlloc error %ld\n"), GetLastError());
  120. #endif
  121. return(0);
  122. }
  123. f = fpbuf->flag = NOTLAST;
  124. if (!ReadFile(hfSrc, fpbuf->ach, BUFSIZE, &fpbuf->cbBuf, NULL) || fpbuf->cbBuf == 0) {
  125. f = fpbuf->flag = LAST;
  126. *(LPTSTR *)(fpbuf->ach) = NULL;
  127. }
  128. enqueue (fpbuf);
  129. }
  130. return(0);
  131. } // reader
  132. /*+-------------------------------------------------------------------------+
  133. | dequeue()
  134. |
  135. +-------------------------------------------------------------------------+*/
  136. BUF *dequeue( void ) {
  137. BUF *fpbuf;
  138. while (TRUE) {
  139. if (fpbufHead != NULL) {
  140. EnterCriticalSection(&hcrtQLock);
  141. fpbufHead = (fpbuf = fpbufHead)->fpbufNext;
  142. if (fpbufTail == fpbuf)
  143. fpbufTail = NULL;
  144. LeaveCriticalSection(&hcrtQLock);
  145. break;
  146. }
  147. // the head pointer is null so the list is empty. Block on eventsem
  148. // until enqueue posts (ie. adds to queue)
  149. WaitForSingleObject(hevQNotEmpty, (DWORD)-1);
  150. }
  151. return fpbuf;
  152. } // dequeue
  153. /*+-------------------------------------------------------------------------+
  154. | enqueue()
  155. |
  156. +-------------------------------------------------------------------------+*/
  157. void enqueue( BUF *fpbuf ) {
  158. fpbuf->fpbufNext = NULL;
  159. EnterCriticalSection(&hcrtQLock);
  160. if (fpbufTail == NULL)
  161. fpbufHead = fpbuf;
  162. else
  163. fpbufTail->fpbufNext = fpbuf;
  164. fpbufTail = fpbuf;
  165. LeaveCriticalSection(&hcrtQLock);
  166. SetEvent(hevQNotEmpty);
  167. } // enqueue
  168. /*+-------------------------------------------------------------------------+
  169. | fastcopy()
  170. |
  171. | hfSrcParm file handle to read from
  172. | hfDstParm file handle to write to
  173. |
  174. | returns NULL if successful
  175. | pointer to error string otherwise
  176. +-------------------------------------------------------------------------+*/
  177. TCHAR *fastcopy (HANDLE hfSrcParm, HANDLE hfDstParm) {
  178. DWORD dwReader;
  179. hfSrc = hfSrcParm;
  180. hfDst = hfDstParm;
  181. hevQNotEmpty = CreateEvent(NULL, (BOOL)FALSE, (BOOL)FALSE, NULL);
  182. if (hevQNotEmpty == INVALID_HANDLE_VALUE)
  183. return NULL;
  184. InitializeCriticalSection(&hcrtQLock);
  185. fAbort = FALSE;
  186. hThread = CreateThread(0, STACKSIZE, (LPTHREAD_START_ROUTINE)reader, 0, 0, &dwReader);
  187. if (hThread == INVALID_HANDLE_VALUE) {
  188. #ifdef DEBUG
  189. dprintf(TEXT("ERROR: Can't create thread - FileCopy\n"));
  190. #endif
  191. return Lids(IDS_L_6);
  192. }
  193. return(writer());
  194. } // fastcopy