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.

396 lines
8.0 KiB

  1. /*++
  2. Copyright (c) 1990 - 1995 Microsoft Corporation
  3. Module Name:
  4. memory.c
  5. Abstract:
  6. This module provides all the memory management functions for all spooler
  7. components
  8. Author:
  9. Krishna Ganugapati (KrishnaG) 03-Feb-1994
  10. Revision History:
  11. Matthew Felton (MattFe) Jan 21 1995
  12. Add Failure Count
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. BOOL
  17. SetAllocFailCount(
  18. HANDLE hPrinter,
  19. DWORD dwFailCount,
  20. LPDWORD lpdwAllocCount,
  21. LPDWORD lpdwFreeCount,
  22. LPDWORD lpdwFailCountHit
  23. )
  24. {
  25. SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
  26. return FALSE;
  27. }
  28. LPVOID
  29. DllAllocSplMem(
  30. DWORD cbAlloc
  31. )
  32. /*++
  33. Routine Description:
  34. This function will allocate local memory. It will possibly allocate extra
  35. memory and fill this with debugging information for the debugging version.
  36. Arguments:
  37. cb - The amount of memory to allocate
  38. Return Value:
  39. NON-NULL - A pointer to the allocated memory
  40. FALSE/NULL - The operation failed. Extended error status is available
  41. using GetLastError.
  42. --*/
  43. {
  44. PVOID pvMemory;
  45. pvMemory = AllocMem( cbAlloc );
  46. if( pvMemory ){
  47. ZeroMemory( pvMemory, cbAlloc );
  48. }
  49. return pvMemory;
  50. }
  51. BOOL
  52. DllFreeSplMem(
  53. LPVOID pMem
  54. )
  55. {
  56. FreeMem( pMem );
  57. return TRUE;
  58. }
  59. LPVOID
  60. ReallocSplMem(
  61. LPVOID pOldMem,
  62. DWORD cbOld,
  63. DWORD cbNew
  64. )
  65. {
  66. LPVOID pNewMem;
  67. pNewMem=AllocSplMem(cbNew);
  68. if (pOldMem && pNewMem) {
  69. if (cbOld) {
  70. CopyMemory( pNewMem, pOldMem, min(cbNew, cbOld));
  71. }
  72. FreeSplMem(pOldMem);
  73. }
  74. return pNewMem;
  75. }
  76. BOOL
  77. DllFreeSplStr(
  78. LPWSTR pStr
  79. )
  80. {
  81. return pStr ?
  82. FreeSplMem(pStr) :
  83. FALSE;
  84. }
  85. LPWSTR
  86. AllocSplStr(
  87. LPCWSTR pStr
  88. )
  89. /*++
  90. Routine Description:
  91. This function will allocate enough local memory to store the specified
  92. string, and copy that string to the allocated memory
  93. Arguments:
  94. pStr - Pointer to the string that needs to be allocated and stored
  95. Return Value:
  96. NON-NULL - A pointer to the allocated memory containing the string
  97. FALSE/NULL - The operation failed. Extended error status is available
  98. using GetLastError.
  99. --*/
  100. {
  101. LPWSTR pMem;
  102. DWORD cbStr;
  103. if (!pStr) {
  104. return NULL;
  105. }
  106. cbStr = wcslen(pStr)*sizeof(WCHAR) + sizeof(WCHAR);
  107. if (pMem = AllocSplMem( cbStr )) {
  108. CopyMemory( pMem, pStr, cbStr );
  109. }
  110. return pMem;
  111. }
  112. BOOL
  113. ReallocSplStr(
  114. LPWSTR *ppStr,
  115. LPCWSTR pStr
  116. )
  117. {
  118. LPWSTR pNewStr;
  119. pNewStr = AllocSplStr(pStr);
  120. if( pStr && !pNewStr ){
  121. return FALSE;
  122. }
  123. FreeSplStr(*ppStr);
  124. *ppStr = pNewStr;
  125. return TRUE;
  126. }
  127. LPBYTE
  128. PackStrings(
  129. LPWSTR *pSource,
  130. LPBYTE pDest,
  131. DWORD *DestOffsets,
  132. LPBYTE pEnd
  133. )
  134. {
  135. DWORD cbStr;
  136. LPBYTE pRet = NULL;
  137. //
  138. // Make sure all our parameters are valid.
  139. // This will return NULL if one of the parameters is NULL.
  140. //
  141. if (pSource && pDest && DestOffsets && pEnd) {
  142. WORD_ALIGN_DOWN(pEnd);
  143. while (*DestOffsets != -1) {
  144. if (*pSource) {
  145. cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR);
  146. pEnd -= cbStr;
  147. CopyMemory( pEnd, *pSource, cbStr);
  148. *(LPWSTR UNALIGNED *)(pDest+*DestOffsets) = (LPWSTR)pEnd;
  149. } else {
  150. *(LPWSTR UNALIGNED *)(pDest+*DestOffsets)=0;
  151. }
  152. pSource++;
  153. DestOffsets++;
  154. }
  155. pRet = pEnd;
  156. }
  157. return pRet;
  158. }
  159. LPVOID
  160. AlignRpcPtr (
  161. LPVOID pBuffer,
  162. LPDWORD pcbBuf
  163. )
  164. /*++
  165. Routine Description:
  166. This routine is called on the server side for methods using custom marshalling.
  167. These methods cheat on RPC by asking for LPBYTE pointers and using the buffer as
  168. pointer to structures. The LPBYTE pointer that RPC sends us can be unaligned.
  169. Here is where we take data missalignments.
  170. The reason the size of the buffer is aligned down is because providers will use
  171. the end of the buffer as a pEnd = pBuffer + cbBuf pointer.
  172. If cbBuf is an unaligned value, pEnd will be unaligned as well. This will generate unaligned
  173. pointers inside the structure as well.
  174. Arguments:
  175. pBuffer - Pointer to a buffer
  176. pcbBuf - Pointer to a DWORD representing the size of the buffer
  177. Return Value:
  178. Aligned pointer
  179. --*/
  180. {
  181. LPVOID pAligned = NULL;
  182. pAligned = (LPVOID)ALIGN_PTR_UP(pBuffer);
  183. *pcbBuf = (DWORD)ALIGN_DOWN(*pcbBuf, ULONG_PTR);
  184. if (pAligned != pBuffer)
  185. {
  186. pAligned = AllocSplMem(*pcbBuf);
  187. }
  188. return pAligned;
  189. }
  190. VOID
  191. UndoAlignRpcPtr (
  192. LPVOID pBuffer,
  193. LPVOID pAligned,
  194. SIZE_T cbSize,
  195. LPDWORD pcbNeeded
  196. )
  197. /*++
  198. Routine Description:
  199. This routine is called on the server side for methods using custom marshalling.
  200. These methods cheat on RPC by asking for LPBYTE pointers and using the buffer as
  201. pointer to structures. The LPBYTE pointer that RPC sends us can be unaligned.
  202. Here is where we take data missalignments.
  203. This routine moves data between pointers if they are different.
  204. Free pSource pointer after copy data to pDestination.
  205. pcbNeeded is adjusted evey time. The providor could request a a buffer size which is unaligned.
  206. We always align up the needed size, no matter the provider.
  207. Arguments:
  208. pDestination - Pointer to a destination buffer
  209. pSource - Pointer to a source buffer
  210. cbSize - Number of bites
  211. Return Value:
  212. --*/
  213. {
  214. //
  215. // pBuffer and pAligned will be either both NULL or both not NULL. See AlignRpcPtr.
  216. //
  217. if (pBuffer != pAligned)
  218. {
  219. //
  220. // The way AlignRpcPtr and UndoAlignRpcPtr use the pBuffer and pAligned is
  221. // very subtle and confusing. UndoAlignRpcPtr doesn't offer any indication
  222. // that it won't access NULL pointers in CopyMemory. That's why the if
  223. // statement is here, though not required.
  224. //
  225. if (pBuffer && pAligned)
  226. {
  227. CopyMemory(pBuffer, pAligned, cbSize);
  228. }
  229. FreeSplMem(pAligned);
  230. }
  231. if (pcbNeeded)
  232. {
  233. *pcbNeeded = (DWORD)ALIGN_UP(*pcbNeeded, ULONG_PTR);
  234. }
  235. }
  236. LPVOID
  237. AlignKMPtr (
  238. LPVOID pBuffer,
  239. DWORD cbBuf
  240. )
  241. /*++
  242. Routine Description:
  243. This routine is called for Do* methods inside splkernl.c
  244. The buffer used by spooler in user mode is a pointer inside
  245. The message send by GDI from kernel mode. This pointer can be unaligned.
  246. This method duplicates the pBuffer if unaligned.
  247. !!! All Do* methods could have this problem is the pointer is unaligned.
  248. Even so, not all of them fault. To minimize the regression chances and code pollution,
  249. I only call this functions for the methods where I coulds see missalignent faults.!!!
  250. Arguments:
  251. pBuffer - Pointer to a buffer
  252. bBuf - Size of the buffer
  253. Return Value:
  254. Aligned pointer
  255. --*/
  256. {
  257. LPVOID pAligned = NULL;
  258. pAligned = (LPVOID)ALIGN_PTR_UP(pBuffer);
  259. if (pAligned != pBuffer)
  260. {
  261. pAligned = AllocSplMem(cbBuf);
  262. if (pAligned)
  263. {
  264. CopyMemory( pAligned, pBuffer, cbBuf);
  265. }
  266. }
  267. return pAligned;
  268. }
  269. VOID
  270. UndoAlignKMPtr (
  271. LPVOID pBuffer,
  272. LPVOID pAligned
  273. )
  274. /*++
  275. Routine Description:
  276. This method frees the duplicated memory allocated in the case where the
  277. pointer is misaligned.
  278. Arguments:
  279. pBuffer - Pointer to potentially unaligned buffer
  280. pAligned - Pointer to an aligned buffer; pAligned is a copy of pBuffer
  281. Return Value:
  282. --*/
  283. {
  284. if (pAligned != pBuffer)
  285. {
  286. FreeSplMem(pBuffer);
  287. }
  288. }