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.

181 lines
6.2 KiB

  1. #ifndef __ProgressInfo_h__
  2. #define __ProgressInfo_h__
  3. #include <windows.h>
  4. #include "stdstring.h"
  5. #include "httpfilepost.h"
  6. enum TRANSFER_STATUS
  7. {
  8. TRANSFER_FATAL_ERROR = -1, // transfer is aborting due to unrecoverable error
  9. TRANSFER_OK, // currently not used
  10. TRANSFER_SKIPPING_FILE, // file transfer failed, non-fatal, continuing with remaining files
  11. TRANSFER_SESSION_INITIATE, // beginning batch file transfer (only agragate vars are valid)
  12. TRANSFER_FILE_INITATE, // starting the transfer of a file (current file vars are now valid)
  13. TRANSFER_FILE_TRANSFERING, // all vars reflect current progress
  14. TRANSFER_FILE_COMPLETE, // file has completed transfering
  15. TRANSFER_SESSION_COMPLETE, // session compelete, last callback that will be sent unless
  16. // there is an unrecoverable error in which case
  17. // TRANSFER_FATAL_ERROR will be the final message
  18. };
  19. #include <MMSystem.h> // Windows Multimedia Support (for timeGetTime())
  20. class CProgressInfo;
  21. class CWebCabPublisher;
  22. typedef UINT (*CS_PROGRESS_PROC)(CProgressInfo*);
  23. #define STATUS_BUFFSIZE 1024
  24. class CProgressInfo
  25. {
  26. public:
  27. // while the upload/download thread is updating the variables,
  28. // critsec will be locked. users of this class must lock
  29. // this critsec before accessing the variables, or they
  30. // may get only partially updated values
  31. CRITICAL_SECTION critsec;
  32. DWORD dwStatusCallback; // status from WinInet
  33. char szStatusString[STATUS_BUFFSIZE]; //buffer for status message
  34. TRANSFER_STATUS dwStatus;
  35. DWORD dwErrorCount; // count of errors encountered this transfer
  36. CStdString strFilename; // full path of the currently transfering file
  37. CStdString strTitle; // friendly (user specified) title of the file
  38. DWORD dwTotalFiles; // total count of files to transfer
  39. DWORD dwDoneFiles; // count of files done
  40. DWORD dwTotalBytes; // total bytes to transfer
  41. DWORD dwTotalDone; // bytes transfered
  42. DWORD dwCurrentBytes; // total bytes to transfer for this file
  43. DWORD dwCurrentDone; // bytes transfered for this file
  44. DWORD dwStartMS; // time started (milliseconds)
  45. DWORD dwTransferRate; // (estimated) transfer rate
  46. time_t timeElapsed; // time elapsed
  47. time_t timeRemaining; // (estimated) time remaining
  48. DWORD dwOverallPercent; // overall percent done
  49. DWORD dwCurrentPercent; // percent done for this file
  50. // these two are used for updating a progress ctrl
  51. DWORD dwOverallPos; // (estimated) overall progress (range 0-ffffffff)
  52. DWORD dwCurrentPos; // (estimated) current progress (range 0-ffffffff)
  53. CS_PROGRESS_PROC pfnProgress; // pointer to callback function
  54. LPARAM lParam; // lParam (caller defined value passed back to caller)
  55. // caller returns 0 to continue, non-zero to abort (value will be reason for abort)
  56. // if caller didn't specify a callback, then assume continue (0)
  57. void NotifyCaller()
  58. {
  59. if(pfnProgress && (*pfnProgress)(this))
  60. {
  61. ThrowUploaderException(0);
  62. }
  63. }
  64. void StartSession(DWORD dwCountFiles, DWORD dwCountBytes)
  65. {
  66. InitializeCriticalSection(&critsec);
  67. EnterCriticalSection(&critsec);
  68. { // critical section
  69. dwStatus = TRANSFER_SESSION_INITIATE;
  70. dwErrorCount = 0;
  71. strFilename = "";
  72. dwTotalFiles = dwCountFiles;
  73. dwDoneFiles = 0;
  74. dwTotalDone = 0;
  75. dwTotalBytes = dwCountBytes;
  76. dwTotalDone = 0;
  77. dwCurrentBytes = 0;
  78. dwCurrentDone = 0;
  79. dwStartMS = timeGetTime();
  80. dwTransferRate = 0;
  81. timeElapsed = 0;
  82. timeRemaining = 0;
  83. dwOverallPercent = 0;
  84. dwCurrentPercent = 0;
  85. dwOverallPos = 0;
  86. dwCurrentPos = 0;
  87. }
  88. LeaveCriticalSection(&critsec);
  89. NotifyCaller();
  90. }
  91. void EndSession(UINT uSuccess)
  92. {
  93. EnterCriticalSection(&critsec);
  94. {
  95. dwStatus = uSuccess ? TRANSFER_SESSION_COMPLETE : TRANSFER_FATAL_ERROR;
  96. }
  97. LeaveCriticalSection(&critsec);
  98. //DeleteCriticalSection(&critsec);
  99. NotifyCaller();
  100. }
  101. void StartFile(const CStdString& name, const CStdString& title, DWORD size)
  102. {
  103. EnterCriticalSection(&critsec);
  104. { // critical section
  105. dwStatus = TRANSFER_FILE_INITATE;
  106. strFilename = name;
  107. strTitle = title;
  108. dwCurrentBytes = size;
  109. dwCurrentDone = 0;
  110. dwCurrentPercent = 0;
  111. dwCurrentPos = 0;
  112. }
  113. LeaveCriticalSection(&critsec);
  114. NotifyCaller();
  115. }
  116. void UpdateProgress(DWORD dwBytesTransfered)
  117. {
  118. EnterCriticalSection(&critsec);
  119. { // critical section
  120. dwStatus = TRANSFER_FILE_TRANSFERING;
  121. dwTotalDone += dwBytesTransfered;
  122. dwCurrentDone += dwBytesTransfered;
  123. dwOverallPos = dwTotalBytes ? MulDiv(dwTotalDone, 0xFFFF, dwTotalBytes) : 0;
  124. dwCurrentPos = dwCurrentBytes ? MulDiv(dwCurrentDone, 0xFFFF, dwCurrentBytes) : 0;
  125. dwOverallPercent = (dwOverallPos * 100) / 0xFFFF;
  126. dwCurrentPercent = (dwCurrentPos * 100) / 0xFFFF;
  127. DWORD dwElapsedMS = timeGetTime() - dwStartMS;
  128. dwTransferRate = MulDiv(dwTotalDone, 1000, dwElapsedMS);
  129. DWORD dwTimeRemaining = MulDiv(dwElapsedMS, dwTotalBytes, dwTotalDone) - dwElapsedMS;
  130. timeRemaining = dwTimeRemaining / 1000;
  131. timeElapsed = dwElapsedMS / 1000;
  132. }
  133. LeaveCriticalSection(&critsec);
  134. NotifyCaller();
  135. }
  136. void EndFile()
  137. {
  138. EnterCriticalSection(&critsec);
  139. { // critical section
  140. dwStatus = TRANSFER_FILE_COMPLETE;
  141. dwDoneFiles++;
  142. }
  143. LeaveCriticalSection(&critsec);
  144. NotifyCaller();
  145. }
  146. };
  147. #endif //__ProgressInfo_h__