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.

326 lines
7.4 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. COUT.CPP
  5. Abstract:
  6. Declares the COut class.
  7. History:
  8. a-davj 06-April-97 Created.
  9. --*/
  10. #include "precomp.h"
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <stdio.h>
  14. #include <sys/stat.h>
  15. #include <arrtempl.h>
  16. #include "cout.h"
  17. #include "trace.h"
  18. #include "strings.h"
  19. #include "mrciclass.h"
  20. #include "bmof.h"
  21. //***************************************************************************
  22. //
  23. // COut::COut
  24. //
  25. // DESCRIPTION:
  26. //
  27. // Constructor. Allocates initial buffer.
  28. //
  29. //***************************************************************************
  30. COut::COut(PDBG pDbg)
  31. {
  32. m_pDbg = pDbg;
  33. m_dwSize = INIT_SIZE;
  34. m_pMem = (BYTE *)malloc(m_dwSize);
  35. m_dwCurr = 0;
  36. m_bPadString = TRUE;
  37. }
  38. //***************************************************************************
  39. //
  40. // COut::~COut
  41. //
  42. // DESCRIPTION:
  43. //
  44. // Destructor. Frees the buffer.
  45. //
  46. //***************************************************************************
  47. COut::~COut()
  48. {
  49. if(m_pMem)
  50. free(m_pMem);
  51. }
  52. //***************************************************************************
  53. //
  54. // void COut::WriteToFile
  55. //
  56. // DESCRIPTION:
  57. //
  58. // Creates a file and writes the buffer to it. Like other compilers, it
  59. // overwrites any existing files.
  60. //
  61. // PARAMETERS:
  62. //
  63. // pFile File name to write to.
  64. //
  65. //***************************************************************************
  66. BOOL COut::WriteToFile(
  67. IN LPSTR pFile)
  68. {
  69. BOOL bRet = FALSE;
  70. BYTE * pCompressed = NULL;
  71. DWORD one = 1;
  72. DWORD dwSize;
  73. int iRet;
  74. DWORD dwCompressedSize;
  75. DWORD dwSignature = BMOF_SIG;
  76. CMRCICompression * pCompress = new CMRCICompression;
  77. if(pCompress == NULL)
  78. return FALSE;
  79. CDeleteMe<CMRCICompression> dm(pCompress);
  80. // Test if there are flavors
  81. if(m_Flavors.Size() > 0)
  82. {
  83. // write out the flavor information
  84. void * lOffSet;
  85. void * lFlavor;
  86. AppendBytes((BYTE *)"BMOFQUALFLAVOR11", 16);
  87. long lNum = m_Flavors.Size();
  88. AppendBytes( (BYTE *)&lNum, 4);
  89. for(long lCnt = 0; lCnt < lNum; lCnt++)
  90. {
  91. lOffSet = m_Offsets.GetAt(lCnt);
  92. lFlavor = m_Flavors.GetAt(lCnt);
  93. AppendBytes( (BYTE *)&lOffSet, 4);
  94. AppendBytes( (BYTE *)&lFlavor, 4);
  95. }
  96. }
  97. int fh = NULL;
  98. if(pFile == NULL)
  99. return FALSE;
  100. fh = _open(pFile, _O_BINARY | O_RDWR | _O_TRUNC | _O_CREAT, _S_IREAD |_S_IWRITE);
  101. if(fh == -1)
  102. {
  103. Trace(true, m_pDbg, FILE_CREATE_FAILED, pFile, errno);
  104. goto Cleanup;
  105. }
  106. // Create a compressed version of the blob
  107. dwSize = (m_dwCurr > 0x7000) ? m_dwCurr : 0x7000;
  108. pCompressed = new BYTE[dwSize];
  109. if(pCompressed == NULL)
  110. return FALSE;
  111. dwCompressedSize = pCompress->Mrci1MaxCompress( m_pMem, m_dwCurr, pCompressed, dwSize);
  112. if(dwCompressedSize == 0xffffffff || dwCompressedSize == 0)
  113. {
  114. Trace(true, m_pDbg, COMPRESSION_FAILED);
  115. goto Cleanup;
  116. }
  117. // write the decomression signature, the decompressed size, and the compressed size
  118. iRet = _write(fh, (BYTE *)&dwSignature, sizeof(DWORD));
  119. if(iRet != sizeof(DWORD))
  120. {
  121. Trace(true, m_pDbg, FILE_WRITE_FAILED, pFile, errno);
  122. goto Cleanup;
  123. }
  124. iRet = _write(fh, (BYTE *)&one, sizeof(DWORD));
  125. iRet = _write(fh, (BYTE *)&dwCompressedSize, sizeof(DWORD));
  126. iRet = _write(fh, (BYTE *)&m_dwCurr, sizeof(DWORD));
  127. // write the compressed data and then free the buffer
  128. iRet = _write(fh, pCompressed, dwCompressedSize);
  129. if((DWORD)iRet != dwCompressedSize)
  130. Trace(true, m_pDbg, FILE_WRITE_FAILED, pFile, errno);
  131. else
  132. bRet = TRUE;
  133. Cleanup:
  134. if(fh != NULL)
  135. _close(fh);
  136. if(pCompressed)
  137. delete pCompressed;
  138. return bRet;
  139. }
  140. //***************************************************************************
  141. //
  142. // DWORD COut::AppendBytes
  143. //
  144. // DESCRIPTION:
  145. //
  146. // Adds bytes to the end of the buffer.
  147. //
  148. // PARAMETERS:
  149. //
  150. // pSrc Pointer to data source.
  151. // dwSize Number of bytes to add.
  152. //
  153. // RETURN VALUE:
  154. //
  155. // Number of bytes added.
  156. //
  157. //***************************************************************************
  158. DWORD COut::AppendBytes(
  159. IN BYTE * pSrc,
  160. IN DWORD dwSize)
  161. {
  162. char * pZero = "\0\0\0\0\0\0\0";
  163. DWORD dwRet = WriteBytes(m_dwCurr, pSrc, dwSize);
  164. m_dwCurr += dwRet;
  165. DWORD dwLeftOver = dwSize & 3;
  166. if(dwLeftOver && m_bPadString)
  167. {
  168. dwRet = WriteBytes(m_dwCurr, (BYTE *)pZero, dwLeftOver);
  169. m_dwCurr += dwLeftOver;
  170. }
  171. return dwRet;
  172. }
  173. //***************************************************************************
  174. //
  175. // DWORD COut::WriteBSTR
  176. //
  177. // DESCRIPTION:
  178. //
  179. // Adds a bstr to the buffer. Quite simple for now, by might be enhanced
  180. // later on to compress.
  181. //
  182. // PARAMETERS:
  183. //
  184. // bstr bstr to add.
  185. //
  186. // RETURN VALUE:
  187. //
  188. // Number of bytes added.
  189. //
  190. //***************************************************************************
  191. DWORD COut::WriteBSTR(
  192. IN BSTR bstr)
  193. {
  194. return AppendBytes((BYTE *)bstr, 2*(wcslen(bstr) + 1));
  195. }
  196. //***************************************************************************
  197. //
  198. // DWORD COut::WriteBytes
  199. //
  200. // DESCRIPTION:
  201. //
  202. // writes some bytes to the buffer, or possibly adds to the end.
  203. //
  204. // PARAMETERS:
  205. //
  206. // dwOffset Offset in buffer where bytes should go
  207. // pSrc points to source data
  208. // dwSize number of bytes to copy
  209. //
  210. // RETURN VALUE:
  211. //
  212. // Number of bytes copied
  213. //
  214. //***************************************************************************
  215. DWORD COut::WriteBytes(
  216. IN DWORD dwOffset,
  217. IN BYTE * pSrc,
  218. IN DWORD dwSize)
  219. {
  220. if(m_pMem == NULL)
  221. return 0;
  222. // check if reallocation is needed!
  223. if(dwOffset + dwSize > m_dwSize)
  224. {
  225. DWORD dwAddSize = ADDITIONAL_SIZE;
  226. if(dwSize > dwAddSize)
  227. dwAddSize = dwSize;
  228. BYTE * pNew = (BYTE *)realloc(m_pMem, m_dwSize + dwAddSize);
  229. if(pNew == NULL)
  230. {
  231. free(m_pMem);
  232. m_pMem = NULL;
  233. return 0;
  234. }
  235. else
  236. {
  237. m_pMem = pNew;
  238. m_dwSize += dwAddSize;
  239. }
  240. }
  241. memcpy(m_pMem+dwOffset, pSrc, dwSize);
  242. return dwSize;
  243. }
  244. //***************************************************************************
  245. //
  246. // DWORD COut::AddFlavor
  247. //
  248. // DESCRIPTION:
  249. //
  250. // Save the flavor value for the current offset.
  251. //
  252. // PARAMETERS:
  253. //
  254. // long flavor to be saved
  255. //
  256. // RETURN VALUE:
  257. //
  258. // TRUE if OK;
  259. //
  260. //***************************************************************************
  261. BOOL COut::AddFlavor(IN long lFlavor)
  262. {
  263. #ifdef _WIN64
  264. m_Offsets.Add((void *)IntToPtr(m_dwCurr));
  265. m_Flavors.Add((void *)IntToPtr(lFlavor));
  266. #else
  267. m_Offsets.Add((void *)m_dwCurr);
  268. m_Flavors.Add((void *)lFlavor);
  269. #endif
  270. return TRUE;
  271. }