Windows NT 4.0 source code leak
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.

315 lines
10 KiB

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