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.

296 lines
8.2 KiB

  1. //
  2. // Microsoft Corporation - Copyright 1997
  3. //
  4. //
  5. // READDATA.CPP - Reading data helping utilities
  6. //
  7. #include "pch.h"
  8. // Globals
  9. const char g_cszMultiPartFormData[] = "multipart/form-data";
  10. const char g_cszDebug[] = "debug";
  11. const char g_cszTextPlain[] = "text/plain";
  12. //
  13. // What: ReadData
  14. //
  15. // Desc: Reads the rest of the stream from the client. There is dwSize
  16. // bytes left to read and will be stored in lpMoreData.
  17. //
  18. // In: lpEcb is the EXTENDED_CONTROL_BLOCK.
  19. // lpMoreData is the buffer where the bits will be stored.
  20. // dwSize is the amount of bits to be saved.
  21. //
  22. // Return: FALSE if there is an error during the read, otherwise TRUE.
  23. //
  24. BOOL ReadData( LPECB lpEcb, LPVOID lpMoreData, DWORD dwSize )
  25. {
  26. BOOL fReturn;
  27. BOOL fLastRequestFail = FALSE;
  28. DWORD cb, count;
  29. LPBYTE lpBytes;
  30. TraceMsg( TF_FUNC | TF_READDATA, "ReadData( lpEcb, lpMoreData, dwSize=%u )", dwSize );
  31. lpBytes = (LPBYTE) lpMoreData;
  32. count = 0;
  33. while ( count != dwSize )
  34. {
  35. cb = dwSize - count;
  36. fReturn = ReadClient( lpEcb->ConnID, lpBytes, &cb );
  37. if ( !fReturn )
  38. goto Cleanup;
  39. count += cb; // increment the number of bytes read
  40. lpBytes += cb; // move pointer ahead
  41. if ( cb == 0 )
  42. {
  43. if ( fLastRequestFail )
  44. {
  45. DebugMsg( NULL, "Two ReadClient requests resulted in ZERO bytes read. Aborting rest of read." );
  46. break;
  47. }
  48. fLastRequestFail = TRUE;
  49. }
  50. else
  51. {
  52. fLastRequestFail = FALSE;
  53. }
  54. }
  55. TraceMsg( TF_READDATA, "Count= %u", count );
  56. Cleanup:
  57. TraceMsg( TF_FUNC | TF_READDATA, "ReadData( lpEcb, lpMoreData, dwSize=%u ) Exit = %s",
  58. dwSize, BOOLTOSTRING( fReturn ) );
  59. return fReturn;
  60. } // ReadData( )
  61. //
  62. // What: CompleteDownload
  63. //
  64. // Desc: Makes sure that we have everything the client is sending.
  65. //
  66. // In: lpEcb is the EXTENDED_CONTROL_BLOCK.
  67. //
  68. // Out: lpbData is the pointer to the return pointer where the entire
  69. // data bytes are.
  70. //
  71. BOOL CompleteDownload( LPECB lpEcb, LPBYTE *lppbData )
  72. {
  73. BOOL fReturn = TRUE; // assume success
  74. TraceMsg( TF_FUNC | TF_READDATA, "CompleteDownload( )" );
  75. // Point to what the server has already downloaded
  76. *lppbData = lpEcb->lpbData;
  77. // Do we have the whole thing?
  78. BOOL fDownloadComplete = (lpEcb->cbTotalBytes == lpEcb->cbAvailable );
  79. TraceMsg( TF_READDATA, "Does cbTotalBytes(%u) == cbAvailable(%u)? %s",
  80. lpEcb->cbTotalBytes, lpEcb->cbAvailable,
  81. BOOLTOSTRING( fDownloadComplete ) );
  82. if ( !fDownloadComplete )
  83. { // Get the rest of the data...
  84. *lppbData = (LPBYTE) GlobalAlloc( GPTR, lpEcb->cbTotalBytes );
  85. CopyMemory( *lppbData , lpEcb->lpbData, lpEcb->cbAvailable );
  86. DWORD dwSize = lpEcb->cbTotalBytes - lpEcb->cbAvailable;
  87. fReturn = ReadData( lpEcb, *lppbData + lpEcb->cbAvailable, dwSize );
  88. if ( !fReturn ) {
  89. TraceMsg( TF_ALWAYS, NULL, "CompleteDownload( ): Error recieving submission." );
  90. goto Cleanup;
  91. }
  92. }
  93. Cleanup:
  94. TraceMsg( TF_FUNC | TF_READDATA, "CompleteDownload( ) Exit = %s",
  95. BOOLTOSTRING( fReturn ) );
  96. return fReturn;
  97. } // CompleteDownload( )
  98. //
  99. // What: GetServerVarString
  100. //
  101. // Desc: Asks server for a server variable. It also allocs space for the
  102. // resulting string.
  103. //
  104. // In: lpEcb is an EXTENDED_CONTROL_BLOCK.
  105. // lpVarName is a pointer the string name of the server variable to
  106. // retrieve.
  107. // In/Out: lppszBuffer will be assign memory for the result string from the
  108. // server.
  109. // lpdwSize (if passed) will be assigned the size of the buffer.
  110. //
  111. BOOL GetServerVarString( LPECB lpEcb, LPSTR lpszVarName, LPSTR *lppszBuffer, LPDWORD lpdwSize )
  112. {
  113. CHAR szVerySmallBuf[ 1 ]; // bogus buffer
  114. DWORD dwSize;
  115. BOOL fReturn;
  116. TraceMsg( TF_FUNC | TF_READDATA, "GetServerVarString( lpEcb, lpszVarName='%s', *lppszBuffer=%x, lpdwSize=%x )",
  117. lpszVarName, *lppszBuffer, lpdwSize );
  118. // Find out how big our buffer needs to be.
  119. dwSize = 0;
  120. fReturn = GetServerVariable( lpEcb->ConnID, lpszVarName, szVerySmallBuf, &dwSize );
  121. DWORD dwErr = GetLastError( );
  122. if ( dwErr != ERROR_INSUFFICIENT_BUFFER )
  123. {
  124. TraceMsgResult( TF_ALWAYS, &ErrtoStr, dwErr, "GetServerVariable( ) returned " );
  125. goto Cleanup;
  126. }
  127. // get some memory
  128. *lppszBuffer = (LPSTR) GlobalAlloc( GPTR, dwSize );
  129. if ( !*lppszBuffer )
  130. { // not enough memory
  131. TraceMsg( TF_ALWAYS, "Operation failed. Out of Memory(?). lppszBuffer == NULL" );
  132. fReturn = FALSE;
  133. goto Cleanup;
  134. }
  135. // grab it for real this time
  136. fReturn = GetServerVariable( lpEcb->ConnID, lpszVarName, *lppszBuffer , &dwSize );
  137. if ( !fReturn )
  138. {
  139. DWORD dwErr = GetLastError( );
  140. TraceMsgResult( TF_ALWAYS, &ErrtoStr, dwErr, "GetServerVariable( ) returned " );
  141. goto Cleanup;
  142. }
  143. Cleanup:
  144. if ( !fReturn )
  145. {
  146. dwSize = 0;
  147. *lppszBuffer = NULL;
  148. }
  149. if ( lpdwSize )
  150. *lpdwSize = dwSize;
  151. TraceMsg( TF_FUNC | TF_READDATA, "GetServerVarString( lpEcb, lpszVarName='%s', *lppszBuffer=%x, lpdwSize=%x ) Exit = %s",
  152. lpszVarName, *lppszBuffer, lpdwSize, BOOLTOSTRING( fReturn ) );
  153. return fReturn;
  154. } // GetServerVarString( )
  155. //
  156. // What: CheckForMultiPartFormSubmit
  157. //
  158. // Desc: Checks "content-type" to see if it is a "multipart/form-data"
  159. // submission.
  160. // In: lpEcb is the EXTENDED_CONTROL_BLOCK
  161. //
  162. // Out: lpfMultipart: TRUE is submission is multipart, otherwise false.
  163. //
  164. // Return: FALSE is there was an error, otherwise TRUE.
  165. //
  166. BOOL CheckForMultiPartFormSubmit( LPECB lpEcb, BOOL *lpfMultipart )
  167. {
  168. BOOL fReturn = TRUE;
  169. LPSTR lpszBuffer;
  170. TraceMsg( TF_FUNC | TF_READDATA, "CheckForMultiPartFormSubmit( )" );
  171. *lpfMultipart = FALSE;
  172. fReturn = GetServerVarString( lpEcb, "CONTENT_TYPE", &lpszBuffer, NULL );
  173. if ( !fReturn )
  174. goto Cleanup;
  175. // is it found?
  176. if (( lpszBuffer ) && (StrStr( lpszBuffer, g_cszMultiPartFormData ) ))
  177. *lpfMultipart = TRUE;
  178. Cleanup:
  179. if ( lpszBuffer )
  180. GlobalFree( lpszBuffer );
  181. TraceMsg( TF_FUNC | TF_READDATA, "CheckForMultiPartFormSubmit( ) Exit = %s",
  182. BOOLTOSTRING( fReturn ) );
  183. return fReturn;
  184. } // CheckForMultiPartFormSubmit( )
  185. //
  186. // What: CheckForDebug
  187. //
  188. // Desc: Checks "query_string" to see if it is "debug".
  189. //
  190. // In: lpEcb is the EXTENDED_CONTROL_BLOCK
  191. //
  192. // Out: lpfDebug is the flag that we set.
  193. //
  194. // Return: TRUE is the submit is multipart, otherwise FALSE.
  195. //
  196. BOOL CheckForDebug( LPECB lpEcb, BOOL *lpfDebug )
  197. {
  198. BOOL fReturn = TRUE;
  199. LPSTR lpszBuffer;
  200. TraceMsg( TF_FUNC | TF_READDATA, "CheckForDebug( )" );
  201. *lpfDebug = FALSE;
  202. fReturn = GetServerVarString( lpEcb, "QUERY_STRING", &lpszBuffer, NULL );
  203. if ( !fReturn )
  204. goto Cleanup;
  205. // is it found?
  206. if (( lpszBuffer) && ( StrStr( lpszBuffer, g_cszDebug ) ))
  207. *lpfDebug = TRUE;
  208. Cleanup:
  209. if ( lpszBuffer )
  210. GlobalFree( lpszBuffer );
  211. TraceMsg( TF_FUNC | TF_READDATA, "CheckForDebug( ) Exit = %s",
  212. BOOLTOSTRING( fReturn ) );
  213. return fReturn;
  214. } // CheckForDebug( )
  215. //
  216. // What: CheckForTextPlanSubmit
  217. //
  218. // Desc: Checks "content-type" to see if it is "text/plain".
  219. //
  220. // In: lpEcb is the EXTENDED_CONTROL_BLOCK
  221. //
  222. // Out: lpfTextPlain is the flag that we set.
  223. //
  224. // Return: TRUE is the submit is multipart, otherwise FALSE.
  225. //
  226. BOOL CheckForTextPlainSubmit( LPECB lpEcb, BOOL *lpfTextPlain )
  227. {
  228. BOOL fReturn = TRUE;
  229. LPSTR lpszBuffer;
  230. TraceMsg( TF_FUNC | TF_READDATA, "CheckForTextPlainSubmit( )" );
  231. *lpfTextPlain = FALSE;
  232. fReturn = GetServerVarString( lpEcb, "CONTENT_TYPE", &lpszBuffer, NULL );
  233. if ( !fReturn )
  234. goto Cleanup;
  235. // is it found?
  236. if (( lpszBuffer) && ( StrStr( lpszBuffer, g_cszTextPlain ) ))
  237. *lpfTextPlain = TRUE;
  238. Cleanup:
  239. if ( lpszBuffer )
  240. GlobalFree( lpszBuffer );
  241. TraceMsg( TF_FUNC | TF_READDATA, "CheckForTextPlainSubmit( ) Exit = %s",
  242. BOOLTOSTRING( fReturn ) );
  243. return fReturn;
  244. } // CheckForTextPlainSubmit( )