Source code of Windows XP (NT5)
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.

201 lines
6.1 KiB

  1. // --------------------------------------------------------------------------
  2. // Module Name: APIRequest.cpp
  3. //
  4. // Copyright (c) 1999-2000, Microsoft Corporation
  5. //
  6. // A class that uses multiple inheritence to allow a CPortMessage to be
  7. // included in a queue as a CQueueElement.
  8. //
  9. // History: 1999-11-07 vtan created
  10. // 2000-08-25 vtan moved from Neptune to Whistler
  11. // --------------------------------------------------------------------------
  12. #include "StandardHeader.h"
  13. #include "APIRequest.h"
  14. #include "StatusCode.h"
  15. #define STRSAFE_NO_DEPRECATE
  16. #include <strsafe.h>
  17. // --------------------------------------------------------------------------
  18. // CAPIRequest::CAPIRequest
  19. //
  20. // Arguments: pAPIDispatcher = CAPIDispatcher object to handle
  21. // this request.
  22. //
  23. // Returns: <none>
  24. //
  25. // Purpose: Constructor for CAPIRequest. Store a reference to the
  26. // CAPIDispatcher and add a reference to the object.
  27. //
  28. // History: 1999-11-07 vtan created
  29. // 2000-08-25 vtan moved from Neptune to Whistler
  30. // --------------------------------------------------------------------------
  31. CAPIRequest::CAPIRequest (CAPIDispatcher* pAPIDispatcher) :
  32. CQueueElement(),
  33. CPortMessage(),
  34. _pAPIDispatcher(pAPIDispatcher)
  35. {
  36. pAPIDispatcher->AddRef();
  37. }
  38. // --------------------------------------------------------------------------
  39. // CAPIRequest::CAPIRequest
  40. //
  41. // Arguments: pAPIDispatcher = CAPIDispatcher object to handle
  42. // this request.
  43. // portMessage = CPortMessage to copy construct.
  44. //
  45. // Returns: <none>
  46. //
  47. // Purpose: Constructor for CAPIRequest. Store a reference to the
  48. // CAPIDispatcher and add a reference to the object.
  49. //
  50. // History: 1999-11-07 vtan created
  51. // 2000-08-25 vtan moved from Neptune to Whistler
  52. // --------------------------------------------------------------------------
  53. CAPIRequest::CAPIRequest (CAPIDispatcher* pAPIDispatcher, const CPortMessage& portMessage) :
  54. CQueueElement(),
  55. CPortMessage(portMessage),
  56. _pAPIDispatcher(pAPIDispatcher)
  57. {
  58. pAPIDispatcher->AddRef();
  59. }
  60. // --------------------------------------------------------------------------
  61. // CAPIRequest::~CAPIRequest
  62. //
  63. // Arguments: <none>
  64. //
  65. // Returns: <none>
  66. //
  67. // Purpose: Destructor for CAPIRequest. Release the reference to the
  68. // CAPIDispatcher object.
  69. //
  70. // History: 99-11-07 vtan created
  71. // --------------------------------------------------------------------------
  72. CAPIRequest::~CAPIRequest (void)
  73. {
  74. _pAPIDispatcher->Release();
  75. _pAPIDispatcher = NULL;
  76. }
  77. // --------------------------------------------------------------------------
  78. // _ValidateMappedClientString
  79. //
  80. // Arguments: pszMapped = String successfully mapped from the client memory space
  81. // using _AllocAndMapClientString().
  82. // cchIn = client's count of characters, including NULL.
  83. //
  84. // Returns: NTSTATUS
  85. //
  86. // Purpose: Ensures that the length of the string is what the client said it was.
  87. //
  88. // History: 2002-02-26 scotthan created
  89. // --------------------------------------------------------------------------
  90. NTSTATUS _ValidateMappedClientString(
  91. IN LPCWSTR pszMapped,
  92. IN ULONG cchIn )
  93. {
  94. size_t cch;
  95. // note: cchIn includes the NULL terminus.
  96. return (SUCCEEDED(StringCchLengthW((LPWSTR)pszMapped, cchIn, &cch)) &&
  97. cchIn == (cch + 1)) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER;
  98. }
  99. // --------------------------------------------------------------------------
  100. // _FreeMappedClientString
  101. //
  102. // Arguments: pszMapped = String successfully mapped from the client memory space
  103. // using _AllocAndMapClientString().
  104. //
  105. // Returns: NTSTATUS
  106. //
  107. // Purpose: Release memory for mapped client string.
  108. //
  109. // History: 2002-02-26 scotthan created
  110. // --------------------------------------------------------------------------
  111. void _FreeMappedClientString(IN LPWSTR pszMapped)
  112. {
  113. delete [] pszMapped;
  114. }
  115. // --------------------------------------------------------------------------
  116. // _AllocAndMapClientString
  117. //
  118. // Arguments: hProcessClient = client process handle
  119. // pszIn = client's address of string
  120. // cchIn = client's count of characters, including NULL.
  121. // cchMax = maximum allowed characters
  122. // ppszMapped = outbound mapped string. Should be freed with _FreeClientString()
  123. //
  124. // Returns: NTSTATUS
  125. //
  126. // Purpose: Ensures that the length of the string is what the client said it was.
  127. //
  128. // History: 2002-02-26 scotthan created
  129. // --------------------------------------------------------------------------
  130. NTSTATUS _AllocAndMapClientString(
  131. IN HANDLE hProcessClient,
  132. IN LPCWSTR pszIn,
  133. IN UINT cchIn,
  134. IN UINT cchMax,
  135. OUT LPWSTR* ppszMapped )
  136. {
  137. NTSTATUS status;
  138. ASSERTMSG(ppszMapped != NULL, "_AllocAndMapClientString: NULL outbound parameter, LPWSTR*.");
  139. ASSERTMSG(hProcessClient != NULL, "_AllocAndMapClientString: NULL process handle.");
  140. *ppszMapped = NULL;
  141. if( pszIn && cchIn > 0 && cchIn <= cchMax )
  142. {
  143. LPWSTR pszMapped = new WCHAR[cchIn];
  144. if( pszMapped )
  145. {
  146. SIZE_T dwNumberOfBytesRead;
  147. if( ReadProcessMemory(hProcessClient, pszIn, pszMapped, cchIn * sizeof(WCHAR),
  148. &dwNumberOfBytesRead) )
  149. {
  150. status = _ValidateMappedClientString(pszMapped, cchIn);
  151. if( NT_SUCCESS(status) )
  152. {
  153. *ppszMapped = pszMapped;
  154. }
  155. }
  156. else
  157. {
  158. status = CStatusCode::StatusCodeOfLastError();
  159. }
  160. if( !NT_SUCCESS(status) )
  161. {
  162. _FreeMappedClientString(pszMapped);
  163. }
  164. }
  165. else
  166. {
  167. status = STATUS_NO_MEMORY;
  168. }
  169. }
  170. else
  171. {
  172. status = STATUS_INVALID_PARAMETER;
  173. }
  174. return status;
  175. }