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.

312 lines
10 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 - 1995 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. #define INC_OLE2
  19. #pragma warning(disable:4103)
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #include <win32.h>
  23. #include <mmsystem.h>
  24. #include <vfw.h>
  25. #include "ivideo32.h"
  26. #include "avicapi.h"
  27. /*----------------------------------------------------------------------+
  28. | fileCapFileIsAVI() - Returns TRUE if the capture file is a valid AVI |
  29. | |
  30. +----------------------------------------------------------------------*/
  31. BOOL FAR PASCAL fileCapFileIsAVI (LPTSTR lpsz)
  32. {
  33. BOOL fReturn = TRUE;
  34. HMMIO hmmioSource = NULL;
  35. MMCKINFO ckRIFF;
  36. // Does the file exist?
  37. hmmioSource = mmioOpen(lpsz, NULL, MMIO_READ);
  38. if (!hmmioSource)
  39. return FALSE;
  40. // Is there an AVI RIFF chunk?
  41. // !!! Don't do a FINDRIFF for an AVI chunk or it'll take several minutes to
  42. // !!! come back from checking a really big file
  43. fReturn = (mmioDescend(hmmioSource, &ckRIFF, NULL, 0) == 0) &&
  44. (ckRIFF.ckid == FOURCC_RIFF) &&
  45. (ckRIFF.fccType == formtypeAVI);
  46. if (hmmioSource)
  47. mmioClose(hmmioSource, 0);
  48. return fReturn;
  49. }
  50. /*----------------------------------------------------------------------+
  51. | fileSaveCopy() - save a copy of the current capture file. |
  52. | |
  53. +----------------------------------------------------------------------*/
  54. BOOL FAR PASCAL fileSaveCopy(LPCAPSTREAM lpcs)
  55. {
  56. #define INITFILE_BUFF_SIZE (1024L * 256L)
  57. BOOL fReturn = TRUE;
  58. char achCaption[80]; // caption on Open File dialog
  59. HMMIO hmmioSource = NULL, hmmioDest = NULL;
  60. LONG lFileSize, lFileSizeTotal, lTemp;
  61. HANDLE hMem = NULL;
  62. LPBYTE lpstr = NULL;
  63. LONG lBuffSize = INITFILE_BUFF_SIZE;
  64. MMCKINFO ckRIFF;
  65. HCURSOR hOldCursor;
  66. UpdateWindow(lpcs->hwnd); // Make everything pretty
  67. hOldCursor = SetCursor( lpcs->hWaitCursor );
  68. if (0 == lstrcmpi(lpcs->achSaveAsFile, lpcs->achFile)) {
  69. // IF the source and destination names are the same, then there
  70. // is nothing to do
  71. return(TRUE);
  72. }
  73. /* grab a big buffer to xfer the file in, start the */
  74. /* buffer size at 32K and hope we get that much. */
  75. TRYAGAIN:
  76. hMem = GlobalAlloc(GMEM_MOVEABLE, lBuffSize);
  77. if (!hMem){
  78. /* we don't have this much mem, go for half that */
  79. lBuffSize /= 2;
  80. if (lBuffSize)
  81. goto TRYAGAIN;
  82. else {
  83. fReturn = FALSE;
  84. goto SAVECOPYOUT;
  85. }
  86. }
  87. /* open up the source file and find the size */
  88. /* Open the source first in case source==destination. Despite the */
  89. /* test above this may still be the case (consider two net use */
  90. /* commands to the same share point with different drive letters). */
  91. /* When we open the destination we truncate the file, which will */
  92. /* lose any existing data. */
  93. hmmioSource = mmioOpen(lpcs->achFile, NULL, MMIO_READ | MMIO_DENYWRITE);
  94. if (!hmmioSource){
  95. /* we are totally hosed here, the source file can't even */
  96. /* be opened up, error out. */
  97. errorUpdateError (lpcs, IDS_CAP_CANTOPEN, (LPTSTR)lpcs->achFile);
  98. fReturn = FALSE;
  99. goto SAVECOPYOUT;
  100. }
  101. /* let's go and create the destination file */
  102. hmmioDest = mmioOpen(lpcs->achSaveAsFile, NULL, MMIO_CREATE|MMIO_WRITE);
  103. if (!hmmioDest){
  104. /* we've got an error of some kind here, let's bail out */
  105. /* on this one. */
  106. errorUpdateError (lpcs, IDS_CAP_CANTOPEN, (LPTSTR)lpcs->achSaveAsFile);
  107. fReturn = FALSE;
  108. goto SAVECOPYOUT;
  109. }
  110. /* go down to the RIFF chunk and find out the size of this */
  111. /* thing. If there is no RIFF chunk then we can safely */
  112. /* assume that the file is of 0 length. */
  113. ckRIFF.fccType = formtypeAVI;
  114. if (mmioDescend(hmmioSource, &ckRIFF, NULL, MMIO_FINDRIFF) != 0){
  115. /* we are done, this file has no RIFF chunk so it's size */
  116. /* is 0 bytes. Just close up and leave. */
  117. goto SAVECOPYOUT;
  118. } else {
  119. /* there is a RIFF chunk, get the size of the file and */
  120. /* get back to the start of the file. */
  121. lFileSizeTotal = lFileSize = ckRIFF.cksize + 8;
  122. mmioAscend(hmmioSource, &ckRIFF, 0);
  123. mmioSeek(hmmioSource, 0L, SEEK_SET);
  124. }
  125. /* Before trying to write, seek to the end of the destination */
  126. /* file and write one byte. This both preallocates the file, */
  127. /* and confirms enough disk is available for the copy, without */
  128. /* going through the trial and error of writing each byte. */
  129. mmioSeek( hmmioDest, lFileSizeTotal - 1, SEEK_SET );
  130. mmioWrite( hmmioDest, (HPSTR) achCaption, 1L );
  131. if (mmioSeek (hmmioDest, 0, SEEK_END) < lFileSizeTotal) {
  132. /* Notify user with message that disk may be full. */
  133. errorUpdateError (lpcs, IDS_CAP_WRITEERROR, (LPTSTR)lpcs->achSaveAsFile);
  134. /* close the file and delete it */
  135. mmioClose(hmmioDest, 0);
  136. mmioOpen(lpcs->achSaveAsFile, NULL, MMIO_DELETE);
  137. hmmioDest = NULL;
  138. fReturn = FALSE;
  139. goto SAVECOPYOUT;
  140. }
  141. mmioSeek (hmmioDest, 0L, SEEK_SET); // Back to the beginning
  142. UpdateWindow(lpcs->hwnd); // Make everything pretty
  143. hOldCursor = SetCursor( lpcs->hWaitCursor );
  144. /* lock our buffer and start xfering data */
  145. lpstr = GlobalLock(hMem);
  146. if (!lpstr) {
  147. fReturn = FALSE;
  148. goto SAVECOPYOUT;
  149. }
  150. while (lFileSize > 0) {
  151. if (lFileSize < lBuffSize)
  152. lBuffSize = lFileSize;
  153. mmioRead(hmmioSource, (HPSTR)lpstr, lBuffSize);
  154. if (mmioWrite(hmmioDest, (HPSTR)lpstr, lBuffSize) <= 0) {
  155. /* we got a write error on the file, error on it */
  156. errorUpdateError (lpcs, IDS_CAP_WRITEERROR, (LPTSTR)lpcs->achSaveAsFile);
  157. /* close the file and delete it */
  158. mmioClose(hmmioDest, 0);
  159. mmioOpen(lpcs->achSaveAsFile, NULL, MMIO_DELETE);
  160. hmmioDest = NULL;
  161. fReturn = FALSE;
  162. goto SAVECOPYOUT0;
  163. }
  164. // Let the user hit escape to get out
  165. if (GetAsyncKeyState(VK_ESCAPE) & 0x0001) {
  166. /* close the file and delete it */
  167. mmioClose(hmmioDest, 0);
  168. mmioOpen(lpcs->achSaveAsFile, NULL, MMIO_DELETE);
  169. hmmioDest = NULL;
  170. goto SAVECOPYOUT0;
  171. }
  172. lFileSize -= lBuffSize;
  173. // lTemp is percentage complete
  174. lTemp = MulDiv (lFileSizeTotal - lFileSize, 100L, lFileSizeTotal);
  175. statusUpdateStatus (lpcs, IDS_CAP_SAVEASPERCENT, lTemp);
  176. Yield();
  177. } // endwhile more bytes to copy
  178. SAVECOPYOUT:
  179. SAVECOPYOUT0:
  180. SetCursor( hOldCursor );
  181. /* close files, free up mem, restore cursor and get out */
  182. if (hmmioSource) mmioClose(hmmioSource, 0);
  183. if (hmmioDest){
  184. mmioSeek(hmmioDest, 0L, SEEK_END);
  185. mmioClose(hmmioDest, 0);
  186. }
  187. if (hMem) {
  188. if (lpstr) {
  189. GlobalUnlock(hMem);
  190. }
  191. GlobalFree(hMem);
  192. }
  193. statusUpdateStatus (lpcs, 0);
  194. return fReturn;
  195. }
  196. /*--------------------------------------------------------------+
  197. | fileAllocCapFile - allocate the capture file |
  198. | |
  199. +--------------------------------------------------------------*/
  200. BOOL FAR PASCAL fileAllocCapFile(LPCAPSTREAM lpcs, DWORD dwNewSize)
  201. {
  202. BOOL fOK = FALSE;
  203. HMMIO hmmio;
  204. UINT w;
  205. HCURSOR hOldCursor;
  206. lpcs->fCapFileExists = FALSE;
  207. hmmio = mmioOpen(lpcs->achFile, NULL, MMIO_WRITE);
  208. if( !hmmio ) {
  209. /* try and create */
  210. hmmio = mmioOpen(lpcs-> achFile, NULL,
  211. MMIO_CREATE | MMIO_WRITE);
  212. if( !hmmio ) {
  213. /* find out if the file was read only or we are just */
  214. /* totally hosed up here. */
  215. hmmio = mmioOpen(lpcs-> achFile, NULL, MMIO_READ);
  216. if (hmmio){
  217. /* file was read only, error on it */
  218. errorUpdateError (lpcs, IDS_CAP_READONLYFILE, (LPTSTR)lpcs-> achFile);
  219. mmioClose(hmmio, 0);
  220. return FALSE;
  221. } else {
  222. /* even weirder error has occured here, give CANTOPEN */
  223. errorUpdateError (lpcs, IDS_CAP_CANTOPEN, (LPTSTR) lpcs-> achFile);
  224. return FALSE;
  225. }
  226. }
  227. }
  228. /* find the size */
  229. lpcs-> lCapFileSize = mmioSeek(hmmio, 0L, SEEK_END);
  230. if( dwNewSize == 0 )
  231. dwNewSize = 1;
  232. lpcs-> lCapFileSize = dwNewSize;
  233. hOldCursor = SetCursor( lpcs-> hWaitCursor );
  234. // Delete the existing file so we can recreate to the correct size
  235. mmioClose(hmmio, 0); // close the file before deleting
  236. mmioOpen(lpcs-> achFile, NULL, MMIO_DELETE);
  237. /* now create a new file with that name */
  238. hmmio = mmioOpen(lpcs-> achFile, NULL, MMIO_CREATE | MMIO_WRITE);
  239. if( !hmmio ) {
  240. return FALSE;
  241. }
  242. /*
  243. * rather than just leaving the allocated space as garbage, we
  244. * create it as a junk filler chunk
  245. */
  246. {
  247. MMCKINFO ck;
  248. ck.ckid = mmioFOURCC('J', 'U', 'N', 'K');
  249. ck.cksize = dwNewSize - 8L;
  250. fOK = (mmioCreateChunk(hmmio, &ck, 0) == 0);
  251. fOK &= (mmioSeek(hmmio, dwNewSize - 9, SEEK_CUR) == (LONG)dwNewSize-1);
  252. fOK &= (mmioWrite( hmmio, (HPSTR) &w, 1L ) == 1);
  253. mmioAscend(hmmio, &ck, 0);
  254. }
  255. mmioClose( hmmio, 0 );
  256. SetCursor( hOldCursor );
  257. if (!fOK)
  258. errorUpdateError (lpcs, IDS_CAP_NODISKSPACE);
  259. return fOK;
  260. }