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.

277 lines
9.3 KiB

  1. /****************************************************************************
  2. *
  3. * capfile.c
  4. *
  5. * AVI file writing module.
  6. *
  7. * Microsoft Video for Windows Sample Capture Class
  8. *
  9. * Copyright (c) 1992, 1993 Microsoft Corporation. All Rights Reserved.
  10. *
  11. * You have a royalty-free right to use, modify, reproduce and
  12. * distribute the Sample Files (and/or any modified version) in
  13. * any way you find useful, provided that you agree that
  14. * Microsoft has no warranty obligations or liability for any
  15. * Sample Application Files which are modified.
  16. *
  17. ***************************************************************************/
  18. #include <windows.h>
  19. #include <windowsx.h>
  20. #include <mmsystem.h>
  21. #include <msvideo.h>
  22. #include <avifmt.h>
  23. #include <drawdib.h>
  24. #include "avicap.h"
  25. #include "avicapi.h"
  26. /*----------------------------------------------------------------------+
  27. | fileCapFileIsAVI() - Returns TRUE if the capture file is a valid AVI |
  28. | |
  29. +----------------------------------------------------------------------*/
  30. BOOL FAR PASCAL fileCapFileIsAVI (LPSTR lpsz)
  31. {
  32. BOOL fReturn = TRUE;
  33. HMMIO hmmioSource = NULL;
  34. MMCKINFO ckRIFF;
  35. // Does the file exist?
  36. hmmioSource = mmioOpen(lpsz, NULL, MMIO_READ);
  37. if (!hmmioSource)
  38. return FALSE;
  39. // Is there an AVI RIFF chunk?
  40. // !!! Don't do a FINDRIFF for an AVI chunk or it'll take several minutes to
  41. // !!! come back from checking a really big file
  42. fReturn = (mmioDescend(hmmioSource, &ckRIFF, NULL, 0) == 0) &&
  43. (ckRIFF.ckid == FOURCC_RIFF) &&
  44. (ckRIFF.fccType == formtypeAVI);
  45. if (hmmioSource)
  46. mmioClose(hmmioSource, 0);
  47. return fReturn;
  48. }
  49. /*----------------------------------------------------------------------+
  50. | fileSaveCopy() - save a copy of the current capture file. |
  51. | |
  52. +----------------------------------------------------------------------*/
  53. BOOL FAR PASCAL fileSaveCopy(LPCAPSTREAM lpcs)
  54. {
  55. #define INITFILE_BUFF_SIZE (1024L * 256L)
  56. BOOL fReturn = TRUE;
  57. char achCaption[80]; // caption on Open File dialog
  58. HMMIO hmmioSource = NULL, hmmioDest = NULL;
  59. LONG lFileSize, lFileSizeTotal, lTemp;
  60. HANDLE hMem = NULL;
  61. LPSTR lpstr = NULL;
  62. LONG lBuffSize = INITFILE_BUFF_SIZE;
  63. MMCKINFO ckRIFF;
  64. HCURSOR hOldCursor;
  65. /* grab a big buffer to xfer the file in, start the */
  66. /* buffer size at 32K and hope we get that much. */
  67. TRYAGAIN:
  68. hMem = GlobalAlloc(GMEM_MOVEABLE, lBuffSize);
  69. if (!hMem){
  70. /* we don't have this much mem, go for half that */
  71. lBuffSize /= 2;
  72. if (lBuffSize)
  73. goto TRYAGAIN;
  74. else {
  75. fReturn = FALSE;
  76. goto SAVECOPYOUT;
  77. }
  78. }
  79. /* let's go and create the destination file */
  80. hmmioDest = mmioOpen(lpcs->achSaveAsFile, NULL, MMIO_CREATE|MMIO_WRITE);
  81. if (!hmmioDest){
  82. /* we've got an error of some kind here, let's bail out */
  83. /* on this one. */
  84. errorUpdateError (lpcs, IDS_CAP_CANTOPEN, (LPSTR)lpcs->achSaveAsFile);
  85. fReturn = FALSE;
  86. goto SAVECOPYOUT;
  87. }
  88. /* open up the source file and find the size */
  89. hmmioSource = mmioOpen(lpcs->achFile, NULL, MMIO_READ);
  90. if (!hmmioSource){
  91. /* we are totally hosed here, the source file can't even */
  92. /* be opened up, error out. */
  93. errorUpdateError (lpcs, IDS_CAP_CANTOPEN, (LPSTR)lpcs->achFile);
  94. fReturn = FALSE;
  95. goto SAVECOPYOUT;
  96. }
  97. /* go down to the RIFF chunk and find out the size of this */
  98. /* thing. If there is no RIFF chunk then we can safely */
  99. /* assume that the file is of 0 length. */
  100. ckRIFF.fccType = formtypeAVI;
  101. if (mmioDescend(hmmioSource, &ckRIFF, NULL, MMIO_FINDRIFF) != 0){
  102. /* we are done, this file has no RIFF chunk so it's size */
  103. /* is 0 bytes. Just close up and leave. */
  104. goto SAVECOPYOUT;
  105. } else {
  106. /* there is a RIFF chunk, get the size of the file and */
  107. /* get back to the start of the file. */
  108. lFileSizeTotal = lFileSize = ckRIFF.cksize + 8;
  109. mmioAscend(hmmioSource, &ckRIFF, 0);
  110. mmioSeek(hmmioSource, 0L, SEEK_SET);
  111. }
  112. /* Before trying to write, seek to the end of the destination */
  113. /* file and write one byte. This both preallocates the file, */
  114. /* and confirms enough disk is available for the copy, without */
  115. /* going through the trial and error of writing each byte. */
  116. mmioSeek( hmmioDest, lFileSizeTotal - 1, SEEK_SET );
  117. mmioWrite( hmmioDest, (HPSTR) achCaption, 1L );
  118. if (mmioSeek (hmmioDest, 0, SEEK_END) < lFileSizeTotal) {
  119. /* Notify user with message that disk may be full. */
  120. errorUpdateError (lpcs, IDS_CAP_WRITEERROR, (LPSTR)lpcs->achSaveAsFile);
  121. /* close the file and delete it */
  122. mmioClose(hmmioDest, 0);
  123. mmioOpen(lpcs->achSaveAsFile, NULL, MMIO_DELETE);
  124. hmmioDest = NULL;
  125. fReturn = FALSE;
  126. goto SAVECOPYOUT;
  127. }
  128. mmioSeek (hmmioDest, 0L, SEEK_SET); // Back to the beginning
  129. UpdateWindow(lpcs->hwnd); // Make everything pretty
  130. hOldCursor = SetCursor( lpcs->hWaitCursor );
  131. /* lock our buffer and start xfering data */
  132. lpstr = GlobalLock(hMem);
  133. while (lFileSize > 0) {
  134. if (lFileSize < lBuffSize)
  135. lBuffSize = lFileSize;
  136. mmioRead(hmmioSource, (HPSTR)lpstr, lBuffSize);
  137. if (mmioWrite(hmmioDest, (HPSTR)lpstr, lBuffSize) <= 0) {
  138. /* we got a write error on the file, error on it */
  139. errorUpdateError (lpcs, IDS_CAP_WRITEERROR, (LPSTR)lpcs->achSaveAsFile);
  140. /* close the file and delete it */
  141. mmioClose(hmmioDest, 0);
  142. mmioOpen(lpcs->achSaveAsFile, NULL, MMIO_DELETE);
  143. hmmioDest = NULL;
  144. fReturn = FALSE;
  145. goto SAVECOPYOUT0;
  146. }
  147. // Let the user hit escape to get out
  148. if (GetAsyncKeyState(VK_ESCAPE) & 0x0001) {
  149. /* close the file and delete it */
  150. mmioClose(hmmioDest, 0);
  151. mmioOpen(lpcs->achSaveAsFile, NULL, MMIO_DELETE);
  152. hmmioDest = NULL;
  153. goto SAVECOPYOUT0;
  154. }
  155. lFileSize -= lBuffSize;
  156. // lTemp is percentage complete
  157. lTemp = muldiv32 (lFileSizeTotal - lFileSize, 100L, lFileSizeTotal);
  158. statusUpdateStatus (lpcs, IDS_CAP_SAVEASPERCENT, lTemp);
  159. Yield();
  160. } // endwhile more bytes to copy
  161. SAVECOPYOUT0:
  162. SetCursor( hOldCursor );
  163. SAVECOPYOUT:
  164. /* close files, free up mem, restore cursor and get out */
  165. if (hmmioSource) mmioClose(hmmioSource, 0);
  166. if (hmmioDest){
  167. mmioSeek(hmmioDest, 0L, SEEK_END);
  168. mmioClose(hmmioDest, 0);
  169. }
  170. if (hMem) {
  171. GlobalUnlock(hMem);
  172. GlobalFree(hMem);
  173. }
  174. statusUpdateStatus (lpcs, NULL);
  175. return fReturn;
  176. }
  177. /*--------------------------------------------------------------+
  178. | fileAllocCapFile - allocate the capture file |
  179. | |
  180. +--------------------------------------------------------------*/
  181. BOOL FAR PASCAL fileAllocCapFile(LPCAPSTREAM lpcs, DWORD dwNewSize)
  182. {
  183. BOOL fOK = FALSE;
  184. HMMIO hmmio;
  185. WORD w;
  186. HCURSOR hOldCursor;
  187. lpcs->fCapFileExists = FALSE;
  188. hmmio = mmioOpen(lpcs->achFile, NULL, MMIO_WRITE);
  189. if( !hmmio ) {
  190. /* try and create */
  191. hmmio = mmioOpen(lpcs-> achFile, NULL,
  192. MMIO_CREATE | MMIO_WRITE);
  193. if( !hmmio ) {
  194. /* find out if the file was read only or we are just */
  195. /* totally hosed up here. */
  196. hmmio = mmioOpen(lpcs-> achFile, NULL, MMIO_READ);
  197. if (hmmio){
  198. /* file was read only, error on it */
  199. errorUpdateError (lpcs, IDS_CAP_READONLYFILE, (LPSTR)lpcs-> achFile);
  200. mmioClose(hmmio, 0);
  201. return FALSE;
  202. } else {
  203. /* even weirder error has occured here, give CANTOPEN */
  204. errorUpdateError (lpcs, IDS_CAP_CANTOPEN, (LPSTR) lpcs-> achFile);
  205. return FALSE;
  206. }
  207. }
  208. }
  209. /* find the size */
  210. lpcs-> lCapFileSize = mmioSeek(hmmio, 0L, SEEK_END);
  211. if( dwNewSize == 0 )
  212. dwNewSize = 1;
  213. lpcs-> lCapFileSize = dwNewSize;
  214. hOldCursor = SetCursor( lpcs-> hWaitCursor );
  215. // Delete the existing file so we can recreate to the correct size
  216. mmioClose(hmmio, 0); // close the file before deleting
  217. mmioOpen(lpcs-> achFile, NULL, MMIO_DELETE);
  218. /* now create a new file with that name */
  219. hmmio = mmioOpen(lpcs-> achFile, NULL, MMIO_CREATE | MMIO_WRITE);
  220. if( !hmmio ) {
  221. return FALSE;
  222. }
  223. /* Seek to end of new file */
  224. fOK = (mmioSeek( hmmio, dwNewSize - 1, SEEK_SET ) == (LONG) dwNewSize - 1);
  225. // write any garbage byte at the end of the file
  226. fOK &= (mmioWrite( hmmio, (HPSTR) &w, 1L ) == 1);
  227. mmioClose( hmmio, 0 );
  228. SetCursor( hOldCursor );
  229. if (!fOK)
  230. errorUpdateError (lpcs, IDS_CAP_NODISKSPACE);
  231. return fOK;
  232. }