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.

2400 lines
68 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. Client.c
  5. Abstract:
  6. Client side of Data Transfer test.
  7. Author:
  8. Brian Wong (t-bwong) 10-Mar-1996
  9. Revision History:
  10. --*/
  11. #include <rpcperf.h>
  12. #include <assert.h>
  13. #include <WinINet.h>
  14. #include <DataTran.h>
  15. #include <DTCommon.h>
  16. //
  17. // Uncomment this for debugging (to make sure files are sent
  18. // properly). Note that under normal circumstances, only
  19. // the receiver retains the temp file - if A creates a temp
  20. // file to sends it to B (ie B gets a copy of the file), then after the
  21. // transfer A deletes its temp file while B keeps its copy.
  22. //
  23. // If DELETE_TEMP_FILES is defined, then B will also delete its copy
  24. // of the temp file.
  25. //
  26. #define DELETE_TEMP_FILES
  27. /////////////////////////////////////////////////////////////////////
  28. #ifdef MAC
  29. extern void _cdecl PrintToConsole(const char *lpszFormat, ...) ;
  30. extern unsigned long ulSecurityPackage ;
  31. #else
  32. #define PrintToConsole printf
  33. unsigned long ulSecurityPackage = RPC_C_AUTHN_WINNT ;
  34. #endif
  35. // Usage
  36. const char *USAGE = "-n <threads> -a <authnlevel> -s <server> -t <protseq>\n"
  37. "Server controls iterations, test cases, and compiles the results.\n"
  38. "AuthnLevel: none, connect, call, pkt, integrity, privacy.\n"
  39. "Default threads=1, authnlevel=none\n";
  40. #define CHECK_RET(status, string) if (status)\
  41. { PrintToConsole("%s failed -- %lu (0x%08X)\n", string,\
  42. (unsigned long)status, (unsigned long)status);\
  43. return (status); }
  44. static HINTERNET hInternet = NULL;
  45. //
  46. // Note: ulBufferSize should be greater than the largest chunk size used.
  47. //
  48. const unsigned long ulBufferSize = 512*1024L;
  49. /////////////////////////////////////////////////////////////////////
  50. RPC_STATUS DoRpcBindingSetAuthInfo(handle_t Binding)
  51. {
  52. if (AuthnLevel != RPC_C_AUTHN_LEVEL_NONE)
  53. return RpcBindingSetAuthInfo(Binding,
  54. NULL,
  55. AuthnLevel,
  56. ulSecurityPackage,
  57. NULL,
  58. RPC_C_AUTHZ_NONE);
  59. else
  60. return(RPC_S_OK);
  61. }
  62. /********************************************************************
  63. * Test wrappers
  64. ********************************************************************/
  65. //===================================================================
  66. // Regular RPC
  67. //===================================================================
  68. unsigned long Do_S_to_C_NBytes (handle_t __RPC_FAR * b,
  69. long i,
  70. unsigned long Length,
  71. unsigned long ChunkSize,
  72. char __RPC_FAR *p)
  73. /*++
  74. Routine Description:
  75. Do_S_to_C_NBytes
  76. Arguments:
  77. b - Binding Handle
  78. i - number of iterations
  79. Length - Length of data to transfer in bytes
  80. ChunkSize - Size of the chunks in which data is to be transfered
  81. Buffer - the buffer allocated for this Worker thread
  82. Return Value:
  83. The time it took to perform the test.
  84. --*/
  85. {
  86. unsigned long n;
  87. unsigned long Time = 0;
  88. //
  89. // Division by zero is evil, make sure this doesn't happen.
  90. //
  91. assert( (Length == 0) || (ChunkSize != 0));
  92. while (i--)
  93. {
  94. n = Length; // Reset length to send.
  95. StartTime(); // Start the timer for this iteration.
  96. //
  97. // Send in complete chunks.
  98. //
  99. for (; n > ChunkSize; n -= ChunkSize)
  100. {
  101. S_to_C_Buffer(*b, ChunkSize, p);
  102. }
  103. //
  104. // Send last bit that doesn't fit into a chunk.
  105. //
  106. S_to_C_Buffer(*b, n, p);
  107. Time += FinishTiming(); // Update total time elapsed.
  108. }
  109. return Time;
  110. }
  111. //---------------------------------------------------------
  112. unsigned long Do_C_to_S_NBytes (handle_t __RPC_FAR * b,
  113. long i,
  114. unsigned long Length,
  115. unsigned long ChunkSize,
  116. char __RPC_FAR *p)
  117. {
  118. char __RPC_FAR *pCur;
  119. unsigned long n;
  120. unsigned long Time = 0;
  121. assert( (Length == 0) || (ChunkSize != 0));
  122. StartTime();
  123. while(i--)
  124. {
  125. n = Length;
  126. pCur = p;
  127. StartTime();
  128. for (; n > ChunkSize; n -= ChunkSize, pCur+=ChunkSize)
  129. {
  130. C_to_S_Buffer(*b, ChunkSize, pCur);
  131. }
  132. C_to_S_Buffer(*b, n, pCur);
  133. Time += FinishTiming();
  134. }
  135. return Time;
  136. }
  137. //---------------------------------------------------------
  138. unsigned long Do_S_to_C_NBytesWithFile (handle_t __RPC_FAR * b,
  139. long i,
  140. unsigned long Length,
  141. unsigned long ChunkSize,
  142. char __RPC_FAR *p)
  143. /*++
  144. Routine Description:
  145. Get a stream of bytes from the Server and save it to a file.
  146. --*/
  147. {
  148. static const char *szFuncName = "Do_S_to_C_NBytesWithFile";
  149. TCHAR pFileName[MAX_PATH];
  150. unsigned long Time = 0;
  151. HANDLE hFile = INVALID_HANDLE_VALUE;
  152. DT_FILE_HANDLE hRemoteContext;
  153. assert( (Length == 0) || (ChunkSize != 0));
  154. //
  155. // Create a temporary file to transfer
  156. //
  157. if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
  158. return 0;
  159. //
  160. // Open the temporary file.
  161. //
  162. hFile = CreateFile ((LPCTSTR) pFileName,
  163. GENERIC_WRITE,
  164. 0,
  165. (LPSECURITY_ATTRIBUTES) NULL,
  166. CREATE_ALWAYS,
  167. FILE_ATTRIBUTE_NORMAL,
  168. (HANDLE) NULL
  169. );
  170. if (hFile == INVALID_HANDLE_VALUE)
  171. {
  172. printf(szFormatCantOpenTempFile,
  173. szFuncName,
  174. pFileName);
  175. PrintSysErrorStringA(GetLastError());
  176. return 0;
  177. }
  178. //
  179. // Get the server to prepare a file to send us.
  180. //
  181. if (0 == (hRemoteContext = RemoteOpen(*b, Length)))
  182. {
  183. printf(szFormatCantOpenServFile, szFuncName);
  184. CloseHandle (hFile);
  185. DeleteFile (pFileName);
  186. return 0;
  187. }
  188. //
  189. // The Actual Test
  190. //
  191. {
  192. DWORD dwBytesRead;
  193. DWORD dwBytesWritten;
  194. while(i--)
  195. {
  196. SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
  197. RemoteResetFile (hRemoteContext);
  198. StartTime();
  199. do
  200. {
  201. //
  202. // Assume that the transfer is finished when we receive zero bytes.
  203. //
  204. if (0 == (dwBytesRead = S_to_C_BufferWithFile(*b,
  205. hRemoteContext,
  206. ChunkSize,
  207. p)))
  208. {
  209. break;
  210. }
  211. WriteFile(hFile, p, dwBytesRead, &dwBytesWritten, NULL);
  212. } while (dwBytesRead == ChunkSize);
  213. Time += FinishTiming();
  214. }
  215. }
  216. //
  217. // Clean Up
  218. //
  219. RemoteClose(&hRemoteContext, TRUE); // Close and delete remote file
  220. CloseHandle(hFile); // Close local temp file
  221. #ifdef DELETE_TEMP_FILES
  222. DeleteFile (pFileName);
  223. #endif
  224. return (Time);
  225. }
  226. //---------------------------------------------------------
  227. unsigned long Do_C_to_S_NBytesWithFile (handle_t __RPC_FAR * b,
  228. long i,
  229. unsigned long Length,
  230. unsigned long ChunkSize,
  231. char __RPC_FAR *p)
  232. /*++
  233. Routine Description:
  234. Create a temporary file of size Length, then send it to the server.
  235. --*/
  236. {
  237. static const char *szFuncName = "Do_C_to_S_NBytesWithFile";
  238. TCHAR pFileName[MAX_PATH];
  239. unsigned long Time = 0;
  240. HANDLE hFile = INVALID_HANDLE_VALUE;
  241. DT_FILE_HANDLE hRemoteContext;
  242. assert( (Length == 0) || (ChunkSize != 0));
  243. //
  244. // Create a temporary file to send.
  245. //
  246. if (FALSE == CreateTempFile (NULL, TEXT("FCS"), Length, pFileName))
  247. return 0;
  248. //
  249. // Open that temp file.
  250. //
  251. hFile = CreateFile ((LPCTSTR) pFileName,
  252. GENERIC_READ,
  253. 0,
  254. (LPSECURITY_ATTRIBUTES) NULL,
  255. OPEN_EXISTING,
  256. FILE_ATTRIBUTE_NORMAL,
  257. (HANDLE) NULL);
  258. if (hFile == INVALID_HANDLE_VALUE)
  259. {
  260. printf(szFormatCantOpenTempFile,
  261. szFuncName,
  262. pFileName);
  263. PrintSysErrorStringA(GetLastError());
  264. return 0;
  265. }
  266. //
  267. // Open a temp file on the server to receive our data.
  268. //
  269. if (0 == (hRemoteContext = RemoteOpen (*b, 0)))
  270. {
  271. printf(szFormatCantOpenServFile, szFuncName);
  272. DeleteFile (pFileName);
  273. return 0;
  274. }
  275. //
  276. // The Actual Test
  277. //
  278. {
  279. DWORD dwBytesRead;
  280. while(i--)
  281. {
  282. SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
  283. RemoteResetFile (hRemoteContext);
  284. StartTime();
  285. for(;;)
  286. {
  287. //
  288. // If ReadFile fails we keep trying.
  289. // This could go on forever, though.
  290. //
  291. if (FALSE == ReadFile (hFile, p, ChunkSize, &dwBytesRead, NULL))
  292. {
  293. printf("%s: ReadFile failed.\n", szFuncName);
  294. PrintSysErrorStringA(GetLastError());
  295. continue;
  296. }
  297. if (0 == dwBytesRead)
  298. break;
  299. C_to_S_BufferWithFile (*b, hRemoteContext, dwBytesRead, p);
  300. }
  301. Time += FinishTiming ();
  302. }
  303. }
  304. //
  305. // Clean Up
  306. //
  307. #ifdef DELETE_TEMP_FILES
  308. RemoteClose (&hRemoteContext, TRUE); // Close and Delete remote file.
  309. #else
  310. RemoteClose (&hRemoteContext, FALSE); // Close Remote File but don't delete it.
  311. #endif
  312. CloseHandle (hFile); // Close local file.
  313. DeleteFile (pFileName); // Delete local file.
  314. return (Time);
  315. }
  316. //===================================================================
  317. // RPC PIPES
  318. //===================================================================
  319. typedef struct
  320. {
  321. unsigned long BufferSize;
  322. char __RPC_FAR *pBuffer;
  323. unsigned long nBytesToGo;
  324. }PIPE_STATE, *P_PIPE_STATE;
  325. typedef struct
  326. {
  327. unsigned long BufferSize;
  328. char __RPC_FAR *pBuffer;
  329. HANDLE hFile;
  330. } FILE_PIPE_STATE;
  331. //---------------------------------------------------------
  332. void PipeAlloc (PIPE_STATE *state,
  333. unsigned long RequestedSize,
  334. unsigned char **buf,
  335. unsigned long *ActualSize)
  336. {
  337. *buf = state->pBuffer;
  338. *ActualSize = (RequestedSize < state->BufferSize ?
  339. RequestedSize :
  340. state->BufferSize);
  341. }
  342. //---------------------------------------------------------
  343. void PipePull (PIPE_STATE *state,
  344. unsigned char *pBuffer,
  345. unsigned long BufferSize,
  346. unsigned long *ActualSizePulled)
  347. {
  348. if (state->nBytesToGo > BufferSize)
  349. {
  350. *ActualSizePulled = BufferSize;
  351. state->nBytesToGo -= BufferSize;
  352. }
  353. else
  354. {
  355. *ActualSizePulled = state->nBytesToGo;
  356. state->nBytesToGo = 0;
  357. }
  358. }
  359. //---------------------------------------------------------
  360. void PipePush (PIPE_STATE *state,
  361. unsigned char *pBuffer,
  362. unsigned long BufferSize)
  363. {
  364. state->nBytesToGo -= BufferSize;
  365. }
  366. //---------------------------------------------------------
  367. void FilePipePull (FILE_PIPE_STATE *state,
  368. unsigned char *pBuffer,
  369. unsigned long BufferSize,
  370. unsigned long *ActualSizePulled)
  371. {
  372. ReadFile (state->hFile,
  373. pBuffer,
  374. BufferSize,
  375. ActualSizePulled,
  376. NULL);
  377. }
  378. //---------------------------------------------------------
  379. void FilePipePush (FILE_PIPE_STATE *state,
  380. unsigned char *pBuffer,
  381. unsigned long BufferSize)
  382. {
  383. DWORD dwBytesWritten;
  384. if (BufferSize != 0)
  385. {
  386. WriteFile (state->hFile,
  387. pBuffer,
  388. BufferSize,
  389. &dwBytesWritten,
  390. NULL);
  391. }
  392. }
  393. //---------------------------------------------------------
  394. unsigned long Do_S_to_C_Pipe (handle_t __RPC_FAR * b,
  395. long i,
  396. unsigned long Length,
  397. unsigned long ChunkSize,
  398. char __RPC_FAR *p)
  399. {
  400. const static char *szFuncName = "Do_S_to_C_Pipe";
  401. PIPE_STATE State;
  402. UCHAR_PIPE ThePipe;
  403. unsigned long Time = 0;
  404. DT_MEM_HANDLE hRemoteMem;
  405. assert( (Length == 0) || (ChunkSize != 0));
  406. //
  407. // Allocate a buffer on the server
  408. // This is done so that each server thread will have its own buffer
  409. // without forcing a memory allocation on every RPC call.
  410. //
  411. if (NULL == (hRemoteMem = RemoteAllocate (*b, ChunkSize)))
  412. {
  413. printf("%s: RemoteAllocate failed.\n", szFuncName);
  414. return 0;
  415. }
  416. State.pBuffer = p; // Use the thread's buffer as the buffer.
  417. State.BufferSize = ChunkSize;
  418. ThePipe.state = (char __RPC_FAR *) &State;
  419. ThePipe.alloc = (void __RPC_FAR *) PipeAlloc;
  420. ThePipe.push = (void __RPC_FAR *) PipePush;
  421. //
  422. // The Actual Test
  423. //
  424. while (i--)
  425. {
  426. State.nBytesToGo = Length; // Reset the pipe's state.
  427. StartTime();
  428. S_to_C_Pipe (*b, ThePipe, Length, hRemoteMem);
  429. Time += FinishTiming();
  430. }
  431. //
  432. // Clean Up
  433. //
  434. RemoteFree(&hRemoteMem);
  435. return Time;
  436. }
  437. //---------------------------------------------------------
  438. unsigned long Do_C_to_S_Pipe(handle_t __RPC_FAR * b,
  439. long i,
  440. unsigned long Length,
  441. unsigned long ChunkSize,
  442. char __RPC_FAR *p)
  443. {
  444. const static char *szFuncName = "Do_C_to_S_Pipe";
  445. PIPE_STATE State;
  446. UCHAR_PIPE ThePipe;
  447. unsigned long Time = 0;
  448. DT_MEM_HANDLE hRemoteMem;
  449. assert( (Length == 0) || (ChunkSize != 0));
  450. //
  451. // Allocate a buffer on the server.
  452. // This is done so that each server thread will have its own buffer
  453. // without forcing a memory allocation on every RPC call.
  454. //
  455. if (NULL == (hRemoteMem = RemoteAllocate (*b, ChunkSize)))
  456. {
  457. printf("%s: RemoteAllocate failed.\n", szFuncName);
  458. return 0;
  459. }
  460. State.pBuffer = p; // Use the thread's buffer as the buffer.
  461. State.BufferSize = ChunkSize;
  462. ThePipe.state = (char __RPC_FAR *) &State;
  463. ThePipe.alloc = (void __RPC_FAR *) PipeAlloc;
  464. ThePipe.pull = (void __RPC_FAR *) PipePull;
  465. //
  466. // The Actual Test
  467. //
  468. while (i--)
  469. {
  470. State.nBytesToGo = Length;
  471. StartTime();
  472. C_to_S_Pipe (*b, ThePipe, hRemoteMem);
  473. Time += FinishTiming();
  474. }
  475. //
  476. // Clean up
  477. //
  478. RemoteFree(&hRemoteMem);
  479. return Time;
  480. }
  481. //---------------------------------------------------------
  482. unsigned long Do_S_to_C_PipeWithFile(handle_t __RPC_FAR * b,
  483. long i,
  484. unsigned long Length,
  485. unsigned long ChunkSize,
  486. char __RPC_FAR *p)
  487. /*++
  488. Routine Description:
  489. Receives a file from server via a pipe
  490. --*/
  491. {
  492. static const char *szFuncName = "Do_S_to_C_PipeWithFile";
  493. FILE_PIPE_STATE State;
  494. UCHAR_PIPE ThePipe;
  495. TCHAR pFileName[MAX_PATH];
  496. unsigned long Time = 0;
  497. HANDLE hFile;
  498. DT_MEM_HANDLE hRemoteMem;
  499. DT_FILE_HANDLE hRemoteFile;
  500. assert( (Length == 0) || (ChunkSize != 0));
  501. //
  502. // Create a temporary file.
  503. //
  504. if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
  505. return 0;
  506. //
  507. // Open that temp file.
  508. //
  509. hFile = CreateFile ((LPCTSTR) pFileName,
  510. GENERIC_WRITE,
  511. 0,
  512. (LPSECURITY_ATTRIBUTES) NULL,
  513. CREATE_ALWAYS,
  514. FILE_ATTRIBUTE_NORMAL,
  515. (HANDLE) NULL);
  516. if (hFile == INVALID_HANDLE_VALUE)
  517. {
  518. printf(szFormatCantOpenTempFile,
  519. szFuncName,
  520. pFileName);
  521. PrintSysErrorStringA(GetLastError());
  522. return 0;
  523. }
  524. //
  525. // Allocate a buffer on the server
  526. // This is done so that each server thread will have its own buffer
  527. // without forcing a memory allocation on every RPC call.
  528. //
  529. if (NULL == (hRemoteMem = RemoteAllocate (*b, ChunkSize)))
  530. {
  531. printf("%s: RemoteAllocate failed.\n", szFuncName);
  532. CloseHandle (hFile);
  533. DeleteFile (pFileName);
  534. return 0;
  535. }
  536. //
  537. // Get the server to prepare a file to send us.
  538. //
  539. if (0 == (hRemoteFile = RemoteOpen(*b, Length)))
  540. {
  541. printf(szFormatCantOpenServFile, szFuncName);
  542. RemoteFree(&hRemoteMem);
  543. CloseHandle(hFile);
  544. DeleteFile(pFileName);
  545. return 0;
  546. }
  547. State.pBuffer = p; // Use the thread's buffer as the buffer
  548. State.BufferSize = ChunkSize;
  549. State.hFile = hFile;
  550. ThePipe.state = (char __RPC_FAR *) &State;
  551. ThePipe.alloc = (void __RPC_FAR *) PipeAlloc;
  552. ThePipe.push = (void __RPC_FAR *) FilePipePush;
  553. //
  554. // The Actual Test
  555. //
  556. while (i--)
  557. {
  558. SetFilePointer (State.hFile, 0, NULL, FILE_BEGIN);
  559. RemoteResetFile (hRemoteFile);
  560. StartTime();
  561. S_to_C_PipeWithFile (*b, ThePipe, hRemoteFile, hRemoteMem);
  562. Time += FinishTiming();
  563. }
  564. //
  565. // Clean Up
  566. //
  567. RemoteClose (&hRemoteFile, TRUE);
  568. RemoteFree (&hRemoteMem);
  569. CloseHandle (hFile);
  570. #ifdef DELETE_TEMP_FILES
  571. DeleteFile (pFileName);
  572. #endif
  573. return Time;
  574. }
  575. //---------------------------------------------------------
  576. unsigned long Do_C_to_S_PipeWithFile (handle_t __RPC_FAR * b,
  577. long i,
  578. unsigned long Length,
  579. unsigned long ChunkSize,
  580. char __RPC_FAR *p)
  581. /*++
  582. Routine Description:
  583. Sends a file to server via a pipe
  584. --*/
  585. {
  586. static const char *szFuncName = "Do_C_to_S_PipeWithFile";
  587. FILE_PIPE_STATE State;
  588. UCHAR_PIPE ThePipe;
  589. TCHAR pFileName[MAX_PATH];
  590. unsigned long Time = 0;
  591. HANDLE hFile;
  592. DT_MEM_HANDLE hRemoteMem;
  593. DT_FILE_HANDLE hRemoteFile;
  594. assert( (Length == 0) || (ChunkSize != 0));
  595. //
  596. // Create a temporary file to send.
  597. //
  598. if (FALSE == CreateTempFile (NULL, TEXT("FCS"), Length, pFileName))
  599. return 0;
  600. //
  601. // Open that temp file.
  602. //
  603. hFile = CreateFile ((LPCTSTR) pFileName,
  604. GENERIC_READ,
  605. 0,
  606. (LPSECURITY_ATTRIBUTES) NULL,
  607. OPEN_EXISTING,
  608. FILE_ATTRIBUTE_NORMAL,
  609. (HANDLE) NULL);
  610. if (hFile == INVALID_HANDLE_VALUE)
  611. {
  612. printf(szFormatCantOpenTempFile,
  613. szFuncName,
  614. pFileName);
  615. PrintSysErrorStringA(GetLastError());
  616. return 0;
  617. }
  618. //
  619. // Allocate a buffer on the server
  620. // This is done so that each server thread will have its own buffer
  621. // without forcing a memory allocation on every RPC call.
  622. //
  623. if (NULL == (hRemoteMem = RemoteAllocate (*b, ChunkSize)))
  624. {
  625. printf("%s: RemoteAllocate failed.\n", szFuncName);
  626. CloseHandle (hFile);
  627. DeleteFile (pFileName);
  628. return 0;
  629. }
  630. //
  631. // Open a temporary file on server to receive our data
  632. //
  633. if (0 == (hRemoteFile = RemoteOpen(*b, 0)))
  634. {
  635. printf(szFormatCantOpenServFile, szFuncName);
  636. RemoteFree (&hRemoteMem);
  637. CloseHandle (hFile);
  638. DeleteFile (pFileName);
  639. return 0;
  640. }
  641. State.pBuffer = p; // Use the thread's buffer as the buffer
  642. State.BufferSize = ChunkSize;
  643. State.hFile = hFile;
  644. ThePipe.state = (char __RPC_FAR *) &State;
  645. ThePipe.alloc = (void __RPC_FAR *) PipeAlloc;
  646. ThePipe.pull = (void __RPC_FAR *) FilePipePull;
  647. //
  648. // The Actual Test
  649. //
  650. while (i--)
  651. {
  652. SetFilePointer (State.hFile, 0, NULL, FILE_BEGIN);
  653. RemoteResetFile (hRemoteFile);
  654. StartTime();
  655. C_to_S_PipeWithFile (*b, ThePipe, hRemoteFile, hRemoteMem);
  656. Time += FinishTiming();
  657. }
  658. //
  659. // Clean up
  660. //
  661. #ifdef DELETE_TEMP_FILES
  662. RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
  663. #else
  664. RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
  665. #endif
  666. RemoteFree (&hRemoteMem);
  667. CloseHandle (hFile);
  668. DeleteFile (pFileName);
  669. return Time;
  670. }
  671. //===================================================================
  672. // Internet APIs
  673. //===================================================================
  674. static void PrintInternetError (LPCSTR lpszStr)
  675. {
  676. unsigned long ulBufLength = 255;
  677. char szErrorString[256];
  678. DWORD ulErrorCode;
  679. DWORD ulWinErrCode;
  680. ulWinErrCode = GetLastError();
  681. printf("%s: %ld:", lpszStr, ulWinErrCode);
  682. PrintSysErrorStringA(ulWinErrCode);
  683. if (TRUE == InternetGetLastResponseInfoA ((DWORD __RPC_FAR *) &ulErrorCode,
  684. (char __RPC_FAR *) szErrorString,
  685. (unsigned long __RPC_FAR *) &ulBufLength))
  686. {
  687. assert (NULL != szErrorString);
  688. printf(" %s", szErrorString);
  689. }
  690. }
  691. //---------------------------------------------------------
  692. static BOOL InternetCommonSetup (LPCSTR szCallerId, // [in]
  693. BOOL f_Ftp, // [in]
  694. BOOL f_StoC, // [in]
  695. handle_t __RPC_FAR *b, // [in]
  696. unsigned long ulLength, // [in]
  697. HINTERNET *phINetSession, // [out]
  698. DT_FILE_HANDLE *phRemoteFile, // [out]
  699. LPTSTR szFtpFilePath // [out]
  700. )
  701. /*++
  702. Routine Description:
  703. Performs several common setup functions in FTP tests
  704. Arguments:
  705. szCallerId - a string that identifies the invoker for display
  706. in error messages
  707. f_Ftp - indicates whether to perform setup for an FTP test.
  708. TRUE indicates FTP
  709. f_StoC - indicates whether to set up a file for a Server-to-Client
  710. or a Client-to-Server transfer. TRUE indicates the former.
  711. b - the binding handle
  712. ulLength - specifies the length of the file
  713. phFtpSession - where to store the handle for an FTP session
  714. phRemoteFile - where to store the handle for the server's file
  715. szFtpFilePath - the path to the file on the FTP server
  716. Return Value:
  717. TRUE if successful,
  718. FALSE if otherwise
  719. --*/
  720. {
  721. TCHAR szServerName[81];
  722. //
  723. // Get Server's machine name.
  724. //
  725. GetServerName (*b, 80, szServerName);
  726. //
  727. // Open an Internet session.
  728. //
  729. *phINetSession = InternetConnect (hInternet,
  730. szServerName,
  731. 0, // Default Port
  732. NULL, // Anonymous
  733. NULL, // Default Password
  734. (TRUE == f_Ftp ?
  735. INTERNET_SERVICE_FTP :
  736. INTERNET_SERVICE_HTTP),
  737. 0,
  738. 0);
  739. if (NULL == *phINetSession)
  740. {
  741. PrintInternetError (szCallerId);
  742. return FALSE;
  743. }
  744. //
  745. // Get the server to set up a file that we can get.
  746. // Or get a filename from the server so we can send
  747. // data to it if ulLength is zero.
  748. //
  749. if (TRUE == f_Ftp)
  750. {
  751. if (NULL == (*phRemoteFile = RemoteCreateFtpFile (*b,
  752. (boolean)f_StoC,
  753. ulLength,
  754. MAX_PATH,
  755. szFtpFilePath)))
  756. {
  757. printf(szFormatCantOpenServFile, szCallerId);
  758. InternetCloseHandle (*phINetSession);
  759. return FALSE;
  760. }
  761. }
  762. else
  763. {
  764. if (NULL == (*phRemoteFile = RemoteCreateHttpFile (*b,
  765. (boolean)f_StoC,
  766. ulLength,
  767. MAX_PATH,
  768. szFtpFilePath)))
  769. {
  770. printf(szFormatCantOpenServFile, szCallerId);
  771. InternetCloseHandle (*phINetSession);
  772. return FALSE;
  773. }
  774. }
  775. return TRUE;
  776. }
  777. //---------------------------------------------------------
  778. unsigned long Do_S_to_C_FtpWithFile (handle_t __RPC_FAR * b,
  779. long i,
  780. unsigned long Length,
  781. unsigned long ChunkSize,
  782. char __RPC_FAR *p)
  783. /*++
  784. Routine Description:
  785. Get a file from the server's FTP directory. The server
  786. must have the FTP root directory set or the test will
  787. fail.
  788. --*/
  789. {
  790. const static char *szFuncName = "Do_S_to_C_FtpWithFile";
  791. TCHAR pFileName[MAX_PATH];
  792. TCHAR szFtpFilePath[MAX_PATH];
  793. unsigned long Time=0;
  794. HINTERNET hFtpSession;
  795. DT_FILE_HANDLE hRemoteFile;
  796. assert( (Length == 0) || (ChunkSize != 0));
  797. //
  798. // Create a temporary file.
  799. //
  800. if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
  801. return 0;
  802. //
  803. // Common setup for Internet API tests...
  804. //
  805. if (FALSE == InternetCommonSetup (szFuncName,
  806. TRUE, // FTP setup
  807. TRUE, // S_to_C
  808. b,
  809. Length,
  810. &hFtpSession,
  811. &hRemoteFile,
  812. szFtpFilePath))
  813. {
  814. DeleteFile (pFileName);
  815. return 0;
  816. }
  817. //
  818. // The Actual Test
  819. //
  820. StartTime();
  821. while (i--)
  822. {
  823. if (FALSE == FtpGetFile (hFtpSession,
  824. szFtpFilePath,
  825. pFileName,
  826. FALSE,
  827. FILE_ATTRIBUTE_NORMAL,
  828. FTP_TRANSFER_TYPE_BINARY,
  829. 0))
  830. {
  831. PrintInternetError (szFuncName);
  832. RemoteClose (&hRemoteFile, TRUE);
  833. InternetCloseHandle (hFtpSession);
  834. return 0;
  835. }
  836. }
  837. Time = FinishTiming();
  838. RemoteClose (&hRemoteFile, TRUE);
  839. InternetCloseHandle (hFtpSession);
  840. #ifdef DELETE_TEMP_FILES
  841. DeleteFile (pFileName);
  842. #endif
  843. return Time;
  844. }
  845. //---------------------------------------------------------
  846. unsigned long Do_C_to_S_FtpWithFile (handle_t __RPC_FAR * b,
  847. long i,
  848. unsigned long Length,
  849. unsigned long ChunkSize,
  850. char __RPC_FAR *p)
  851. {
  852. const static char *szFuncName = "Do_C_to_S_FtpWithFile";
  853. TCHAR pFileName[MAX_PATH];
  854. TCHAR szFtpFilePath[MAX_PATH];
  855. unsigned long Time=0;
  856. HINTERNET hFtpSession;
  857. DT_FILE_HANDLE hRemoteFile;
  858. assert( (Length == 0) || (ChunkSize != 0));
  859. //
  860. // Create a temporary file.
  861. //
  862. if (FALSE == CreateTempFile (NULL, TEXT("FCS"), Length, pFileName))
  863. return 0;
  864. //
  865. // Common setup for Internet API tests...
  866. //
  867. if (FALSE == InternetCommonSetup (szFuncName,
  868. TRUE, // FTP setup
  869. FALSE, // C_to_S
  870. b,
  871. 0,
  872. &hFtpSession,
  873. &hRemoteFile,
  874. szFtpFilePath))
  875. {
  876. DeleteFile(pFileName);
  877. return 0;
  878. }
  879. //
  880. // The Actual Test
  881. //
  882. while (i--)
  883. {
  884. StartTime();
  885. if (FALSE == FtpPutFile (hFtpSession,
  886. pFileName,
  887. szFtpFilePath,
  888. FTP_TRANSFER_TYPE_BINARY,
  889. 0))
  890. {
  891. PrintInternetError (szFuncName);
  892. RemoteClose (&hRemoteFile, TRUE);
  893. InternetCloseHandle (hFtpSession);
  894. DeleteFile (pFileName);
  895. return 0;
  896. }
  897. Time += FinishTiming();
  898. }
  899. #ifdef DELETE_TEMP_FILES
  900. RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
  901. #else
  902. RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
  903. #endif
  904. InternetCloseHandle (hFtpSession);
  905. DeleteFile (pFileName);
  906. return Time;
  907. }
  908. //---------------------------------------------------------
  909. unsigned long Do_S_to_C_Ftp1(handle_t __RPC_FAR * b,
  910. long i,
  911. unsigned long Length,
  912. unsigned long ChunkSize,
  913. char __RPC_FAR *p)
  914. {
  915. const static char *szFuncName = "Do_S_to_C_Ftp1";
  916. TCHAR szFtpFilePath[MAX_PATH];
  917. unsigned long Time=0;
  918. HINTERNET hFtpSession;
  919. DT_FILE_HANDLE hRemoteFile;
  920. //
  921. // Common setup for Internet API tests...
  922. //
  923. if (FALSE == InternetCommonSetup (szFuncName,
  924. TRUE, // FTP setup
  925. TRUE, // S_to_C
  926. b,
  927. Length,
  928. &hFtpSession,
  929. &hRemoteFile,
  930. szFtpFilePath))
  931. {
  932. return 0;
  933. }
  934. //
  935. // The Actual Test
  936. //
  937. {
  938. HINTERNET hFtpFile;
  939. DWORD nBytesRead;
  940. while (i--)
  941. {
  942. //
  943. // Open file on the server to read from.
  944. //
  945. hFtpFile = FtpOpenFile (hFtpSession,
  946. szFtpFilePath,
  947. GENERIC_READ,
  948. FTP_TRANSFER_TYPE_BINARY,
  949. 0);
  950. if (NULL == hFtpFile)
  951. {
  952. PrintInternetError (szFuncName);
  953. RemoteClose (&hRemoteFile, TRUE);
  954. InternetCloseHandle (hFtpSession);
  955. return 0;
  956. }
  957. StartTime();
  958. //
  959. // Transfer the file!
  960. //
  961. do
  962. {
  963. if (FALSE == InternetReadFile (hFtpFile,
  964. p,
  965. ChunkSize,
  966. &nBytesRead))
  967. {
  968. PrintInternetError (szFuncName);
  969. InternetCloseHandle (hFtpFile);
  970. RemoteClose (&hRemoteFile, TRUE);
  971. InternetCloseHandle (hFtpSession);
  972. return 0;
  973. }
  974. } while (0 != nBytesRead);
  975. Time += FinishTiming();
  976. InternetCloseHandle (hFtpFile);
  977. }
  978. }
  979. RemoteClose (&hRemoteFile, TRUE);
  980. InternetCloseHandle (hFtpSession);
  981. return Time;
  982. }
  983. //---------------------------------------------------------
  984. unsigned long Do_C_to_S_Ftp1(handle_t __RPC_FAR * b,
  985. long i,
  986. unsigned long Length,
  987. unsigned long ChunkSize,
  988. char __RPC_FAR *p)
  989. {
  990. const static char *szFuncName = "Do_C_to_S_Ftp1";
  991. TCHAR szFtpFilePath[MAX_PATH];
  992. unsigned long Time=0;
  993. HINTERNET hFtpSession;
  994. DT_FILE_HANDLE hRemoteFile;
  995. assert( (Length == 0) || (ChunkSize != 0));
  996. //
  997. // Common setup for Internet API tests...
  998. //
  999. if (FALSE == InternetCommonSetup (szFuncName,
  1000. TRUE, // FTP setup
  1001. FALSE, // C_to_S
  1002. b,
  1003. 0,
  1004. &hFtpSession,
  1005. &hRemoteFile,
  1006. szFtpFilePath))
  1007. {
  1008. return 0;
  1009. }
  1010. //
  1011. // The Actual Test
  1012. //
  1013. {
  1014. DWORD dwBytesWritten;
  1015. DWORD dwBytesRead;
  1016. HINTERNET hFtpFile;
  1017. unsigned int n;
  1018. while (i--)
  1019. {
  1020. //
  1021. // Open a file on server to write to.
  1022. //
  1023. hFtpFile = FtpOpenFile (hFtpSession,
  1024. szFtpFilePath,
  1025. GENERIC_WRITE,
  1026. FTP_TRANSFER_TYPE_BINARY,
  1027. 0);
  1028. if (NULL == hFtpFile)
  1029. {
  1030. PrintInternetError (szFuncName);
  1031. RemoteClose (&hRemoteFile, TRUE);
  1032. InternetCloseHandle (hFtpSession);
  1033. return 0;
  1034. }
  1035. n = Length;
  1036. StartTime();
  1037. //
  1038. // Transfer in complete chunks
  1039. //
  1040. for (; n > ChunkSize; n -= ChunkSize)
  1041. {
  1042. if (FALSE == InternetWriteFile (hFtpFile,
  1043. p,
  1044. ChunkSize,
  1045. &dwBytesWritten))
  1046. {
  1047. PrintInternetError (szFuncName);
  1048. InternetCloseHandle (hFtpFile);
  1049. RemoteClose (&hRemoteFile, TRUE);
  1050. InternetCloseHandle (hFtpSession);
  1051. return 0;
  1052. }
  1053. }
  1054. //
  1055. // Transfer the last bit that doesn't fill a chunk
  1056. //
  1057. if (FALSE == InternetWriteFile (hFtpFile,
  1058. p,
  1059. n,
  1060. &dwBytesWritten))
  1061. {
  1062. PrintInternetError (szFuncName);
  1063. InternetCloseHandle (hFtpFile);
  1064. RemoteClose (&hRemoteFile, TRUE);
  1065. InternetCloseHandle (hFtpSession);
  1066. return 0;
  1067. }
  1068. Time += FinishTiming();
  1069. InternetCloseHandle (hFtpFile);
  1070. }
  1071. }
  1072. RemoteClose (&hRemoteFile, FALSE);
  1073. InternetCloseHandle (hFtpSession);
  1074. return Time;
  1075. }
  1076. //---------------------------------------------------------
  1077. unsigned long Do_S_to_C_Ftp1WithFile(handle_t __RPC_FAR * b,
  1078. long i,
  1079. unsigned long Length,
  1080. unsigned long ChunkSize,
  1081. char __RPC_FAR *p)
  1082. {
  1083. const static char *szFuncName = "Do_S_to_C_Ftp1WithFile";
  1084. TCHAR pFileName[MAX_PATH];
  1085. TCHAR szFtpFilePath[MAX_PATH];
  1086. unsigned long Time = 0;
  1087. HANDLE hFile;
  1088. HINTERNET hFtpSession;
  1089. DT_FILE_HANDLE hRemoteFile;
  1090. assert( (Length == 0) || (ChunkSize != 0));
  1091. //
  1092. // Create a temporary file.
  1093. //
  1094. if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
  1095. return 0;
  1096. //
  1097. // Open the temporary file.
  1098. //
  1099. hFile = CreateFile ((LPCTSTR) pFileName,
  1100. GENERIC_WRITE,
  1101. 0,
  1102. (LPSECURITY_ATTRIBUTES) NULL,
  1103. CREATE_ALWAYS,
  1104. FILE_ATTRIBUTE_NORMAL,
  1105. (HANDLE) NULL
  1106. );
  1107. if (hFile == INVALID_HANDLE_VALUE)
  1108. {
  1109. printf(szFormatCantOpenTempFile,
  1110. szFuncName,
  1111. pFileName);
  1112. PrintSysErrorStringA(GetLastError());
  1113. return 0;
  1114. }
  1115. //
  1116. // Common setup for Internet API tests...
  1117. //
  1118. if (FALSE == InternetCommonSetup (szFuncName,
  1119. TRUE, // FTP setup
  1120. TRUE, // S_to_C
  1121. b,
  1122. Length,
  1123. &hFtpSession,
  1124. &hRemoteFile,
  1125. szFtpFilePath))
  1126. {
  1127. CloseHandle(hFile);
  1128. DeleteFile(pFileName);
  1129. return 0;
  1130. }
  1131. //
  1132. // The Actual Test
  1133. //
  1134. {
  1135. DWORD dwBytesWritten;
  1136. DWORD dwBytesRead;
  1137. HINTERNET hFtpFile;
  1138. while (i--)
  1139. {
  1140. //
  1141. // Open the remote file.
  1142. //
  1143. hFtpFile = FtpOpenFile (hFtpSession,
  1144. szFtpFilePath,
  1145. GENERIC_READ,
  1146. FTP_TRANSFER_TYPE_BINARY,
  1147. 0);
  1148. if (NULL == hFtpFile)
  1149. {
  1150. PrintInternetError (szFuncName);
  1151. RemoteClose (&hRemoteFile, TRUE);
  1152. InternetCloseHandle (hFtpSession);
  1153. CloseHandle(hFile);
  1154. DeleteFile(pFileName);
  1155. return 0;
  1156. }
  1157. //
  1158. // Reset the local file.
  1159. //
  1160. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  1161. StartTime();
  1162. for (;;)
  1163. {
  1164. //
  1165. // Transfer in complete chunks
  1166. //
  1167. if (FALSE == InternetReadFile (hFtpFile,
  1168. p,
  1169. ChunkSize,
  1170. &dwBytesRead))
  1171. {
  1172. PrintInternetError (szFuncName);
  1173. InternetCloseHandle (hFtpFile);
  1174. RemoteClose (&hRemoteFile, TRUE);
  1175. InternetCloseHandle (hFtpSession);
  1176. CloseHandle(hFile);
  1177. return 0;
  1178. }
  1179. //
  1180. // Return value == TRUE and dwBytesRead == 0 means EOF
  1181. //
  1182. if (0 == dwBytesRead)
  1183. break;
  1184. WriteFile(hFile, p, dwBytesRead, &dwBytesWritten, NULL);
  1185. }
  1186. Time += FinishTiming();
  1187. //
  1188. // Close and re-open the file after each write.
  1189. //
  1190. InternetCloseHandle (hFtpFile);
  1191. }
  1192. }
  1193. RemoteClose (&hRemoteFile, TRUE);
  1194. InternetCloseHandle (hFtpSession);
  1195. CloseHandle(hFile);
  1196. #ifdef DELETE_TEMP_FILES
  1197. DeleteFile (pFileName);
  1198. #endif
  1199. return Time;
  1200. }
  1201. //---------------------------------------------------------
  1202. unsigned long Do_C_to_S_Ftp1WithFile(handle_t __RPC_FAR * b,
  1203. long i,
  1204. unsigned long Length,
  1205. unsigned long ChunkSize,
  1206. char __RPC_FAR *p)
  1207. {
  1208. static const char *szFuncName="Do_C_to_S_Ftp1WithFile";
  1209. HINTERNET hFtpSession;
  1210. HANDLE hFile;
  1211. TCHAR pFileName[MAX_PATH];
  1212. unsigned long Time=0;
  1213. DT_FILE_HANDLE hRemoteFile;
  1214. char szFtpFilePath[MAX_PATH];
  1215. assert( (Length == 0) || (ChunkSize != 0));
  1216. //
  1217. // Create a temporary file.
  1218. //
  1219. if (FALSE == CreateTempFile (NULL, "FCS", Length, pFileName))
  1220. return 0;
  1221. //
  1222. // Open the temporary file.
  1223. //
  1224. hFile = CreateFile ((LPTSTR) pFileName,
  1225. GENERIC_READ,
  1226. 0,
  1227. (LPSECURITY_ATTRIBUTES) NULL,
  1228. OPEN_EXISTING,
  1229. FILE_ATTRIBUTE_NORMAL,
  1230. (HANDLE) NULL
  1231. );
  1232. if (hFile == INVALID_HANDLE_VALUE)
  1233. {
  1234. printf(szFormatCantOpenTempFile,
  1235. szFuncName,
  1236. pFileName);
  1237. PrintSysErrorStringA(GetLastError());
  1238. DeleteFile(pFileName);
  1239. return 0;
  1240. }
  1241. //
  1242. // Common setup for Internet API tests...
  1243. //
  1244. if (FALSE == InternetCommonSetup (szFuncName,
  1245. TRUE, // FTP setup
  1246. FALSE, // C_to_S
  1247. b,
  1248. 0,
  1249. &hFtpSession,
  1250. &hRemoteFile,
  1251. szFtpFilePath))
  1252. {
  1253. CloseHandle(hFile);
  1254. DeleteFile(pFileName);
  1255. return 0;
  1256. }
  1257. //
  1258. // The Actual Test
  1259. //
  1260. {
  1261. DWORD dwBytesWritten;
  1262. DWORD dwBytesRead;
  1263. HINTERNET hFtpFile;
  1264. while (i--)
  1265. {
  1266. //
  1267. // Open the remote file.
  1268. //
  1269. hFtpFile = FtpOpenFile (hFtpSession,
  1270. szFtpFilePath,
  1271. GENERIC_WRITE,
  1272. FTP_TRANSFER_TYPE_BINARY,
  1273. 0);
  1274. if (NULL == hFtpFile)
  1275. {
  1276. PrintInternetError (szFuncName);
  1277. RemoteClose (&hRemoteFile, TRUE);
  1278. InternetCloseHandle (hFtpSession);
  1279. CloseHandle(hFile);
  1280. DeleteFile(pFileName);
  1281. return 0;
  1282. }
  1283. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  1284. StartTime();
  1285. for (;;)
  1286. {
  1287. if (FALSE == ReadFile(hFile, p, ChunkSize, &dwBytesRead, NULL))
  1288. {
  1289. printf("%s: ReadFile failed.\n", szFuncName);
  1290. continue;
  1291. }
  1292. //
  1293. // Return value == TRUE and dwBytesRead == 0 means EOF
  1294. //
  1295. if (0 == dwBytesRead)
  1296. break;
  1297. if (FALSE == InternetWriteFile (hFtpFile,
  1298. p,
  1299. dwBytesRead,
  1300. &dwBytesWritten))
  1301. {
  1302. PrintInternetError (szFuncName);
  1303. InternetCloseHandle (hFtpFile);
  1304. RemoteClose (&hRemoteFile, FALSE);
  1305. CloseHandle(hFile);
  1306. InternetCloseHandle (hFtpSession);
  1307. return 0;
  1308. }
  1309. }
  1310. Time += FinishTiming();
  1311. //
  1312. // Close and re-open the file after each write.
  1313. //
  1314. InternetCloseHandle (hFtpFile);
  1315. }
  1316. }
  1317. #ifdef DELETE_TEMP_FILES
  1318. RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
  1319. #else
  1320. RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
  1321. #endif
  1322. InternetCloseHandle (hFtpSession);
  1323. CloseHandle(hFile);
  1324. DeleteFile(pFileName);
  1325. return Time;
  1326. }
  1327. //---------------------------------------------------------
  1328. // We want to accept all types of files, even binary.
  1329. static LPCTSTR lpszAcceptTypes[] = {TEXT("*"),0};
  1330. //---------------------------------------------------------
  1331. unsigned long Do_S_to_C_Http(handle_t __RPC_FAR * b,
  1332. long i,
  1333. unsigned long Length,
  1334. unsigned long ChunkSize,
  1335. char __RPC_FAR *p)
  1336. {
  1337. static const char *szFuncName = "Do_S_to_C_Http";
  1338. TCHAR szHttpFilePath[MAX_PATH];
  1339. unsigned long Time=0;
  1340. HINTERNET hHttpSession;
  1341. DT_FILE_HANDLE hRemoteFile;
  1342. assert( (Length == 0) || (ChunkSize != 0));
  1343. //
  1344. // Common setup for Internet API tests...
  1345. //
  1346. if (FALSE == InternetCommonSetup (szFuncName,
  1347. FALSE, // HTTP setup
  1348. TRUE, // S_to_C
  1349. b,
  1350. Length,
  1351. &hHttpSession,
  1352. &hRemoteFile,
  1353. szHttpFilePath))
  1354. {
  1355. return 0;
  1356. }
  1357. //
  1358. // The Actual Test
  1359. //
  1360. {
  1361. HINTERNET hHttpFile;
  1362. DWORD nBytesRead;
  1363. while (i--)
  1364. {
  1365. //
  1366. // Open file on the server to read from.
  1367. //
  1368. hHttpFile = HttpOpenRequest (hHttpSession,
  1369. TEXT("GET"),
  1370. szHttpFilePath,
  1371. HTTP_VERSION,
  1372. NULL,
  1373. lpszAcceptTypes,
  1374. INTERNET_FLAG_RELOAD,
  1375. 0);
  1376. if (NULL == hHttpFile)
  1377. {
  1378. PrintInternetError (szFuncName);
  1379. RemoteClose (&hRemoteFile, TRUE);
  1380. InternetCloseHandle (hHttpSession);
  1381. return 0;
  1382. }
  1383. if (FALSE == HttpSendRequest (hHttpFile,
  1384. NULL,
  1385. 0,
  1386. NULL,
  1387. 0))
  1388. {
  1389. PrintInternetError (szFuncName);
  1390. InternetCloseHandle (hHttpFile);
  1391. RemoteClose (&hRemoteFile, TRUE);
  1392. InternetCloseHandle (hHttpSession);
  1393. return 0;
  1394. }
  1395. StartTime();
  1396. //
  1397. // Transfer the file!
  1398. //
  1399. do
  1400. {
  1401. if (FALSE == InternetReadFile (hHttpFile,
  1402. p,
  1403. ChunkSize,
  1404. &nBytesRead))
  1405. {
  1406. PrintInternetError (szFuncName);
  1407. InternetCloseHandle (hHttpFile);
  1408. RemoteClose (&hRemoteFile, TRUE);
  1409. InternetCloseHandle (hHttpSession);
  1410. return 0;
  1411. }
  1412. } while (0 != nBytesRead);
  1413. Time += FinishTiming();
  1414. InternetCloseHandle (hHttpFile);
  1415. }
  1416. }
  1417. RemoteClose (&hRemoteFile, TRUE);
  1418. InternetCloseHandle (hHttpSession);
  1419. return Time;
  1420. }
  1421. //---------------------------------------------------------
  1422. unsigned long Do_C_to_S_Http(handle_t __RPC_FAR * b,
  1423. long i,
  1424. unsigned long Length,
  1425. unsigned long ChunkSize,
  1426. char __RPC_FAR *p)
  1427. {
  1428. static const char *szFuncName="Do_C_to_S_HttpWithFile";
  1429. HINTERNET hHttpSession;
  1430. unsigned long Time=0;
  1431. DT_FILE_HANDLE hRemoteFile;
  1432. char szHttpFilePath[MAX_PATH];
  1433. assert( (Length == 0) || (ChunkSize != 0));
  1434. //
  1435. // Common setup for Internet API tests...
  1436. //
  1437. if (FALSE == InternetCommonSetup (szFuncName,
  1438. FALSE, // HTTP setup
  1439. FALSE, // C_to_S
  1440. b,
  1441. 0,
  1442. &hHttpSession,
  1443. &hRemoteFile,
  1444. szHttpFilePath))
  1445. {
  1446. return 0;
  1447. }
  1448. //
  1449. // The Actual Test
  1450. //
  1451. {
  1452. DWORD dwBytesWritten;
  1453. DWORD dwBytesRead;
  1454. unsigned int n;
  1455. HINTERNET hHttpFile;
  1456. while (i--)
  1457. {
  1458. //
  1459. // Open the remote file.
  1460. //
  1461. hHttpFile = HttpOpenRequest (hHttpSession,
  1462. TEXT("PUT"),
  1463. szHttpFilePath,
  1464. HTTP_VERSION,
  1465. NULL,
  1466. lpszAcceptTypes,
  1467. INTERNET_FLAG_RELOAD,
  1468. 0);
  1469. if (NULL == hHttpFile)
  1470. {
  1471. PrintInternetError (szFuncName);
  1472. RemoteClose (&hRemoteFile, TRUE);
  1473. InternetCloseHandle (hHttpSession);
  1474. return 0;
  1475. }
  1476. if (FALSE == HttpSendRequest (hHttpFile,
  1477. NULL,
  1478. 0,
  1479. NULL,
  1480. 0))
  1481. {
  1482. PrintInternetError (szFuncName);
  1483. InternetCloseHandle (hHttpFile);
  1484. RemoteClose (&hRemoteFile, TRUE);
  1485. InternetCloseHandle (hHttpSession);
  1486. return 0;
  1487. }
  1488. StartTime();
  1489. //
  1490. // Transfer in complete chunks
  1491. //
  1492. for (n = Length; n > ChunkSize; n -= ChunkSize)
  1493. {
  1494. if (FALSE == InternetWriteFile (hHttpFile,
  1495. p,
  1496. ChunkSize,
  1497. &dwBytesWritten))
  1498. {
  1499. PrintInternetError (szFuncName);
  1500. InternetCloseHandle (hHttpFile);
  1501. RemoteClose (&hRemoteFile, FALSE);
  1502. InternetCloseHandle (hHttpSession);
  1503. return 0;
  1504. }
  1505. }
  1506. //
  1507. // Transfer the last bit that doesn't fill a chunk
  1508. //
  1509. if (FALSE == InternetWriteFile (hHttpFile,
  1510. p,
  1511. n,
  1512. &dwBytesWritten))
  1513. {
  1514. PrintInternetError (szFuncName);
  1515. InternetCloseHandle (hHttpFile);
  1516. RemoteClose (&hRemoteFile, FALSE);
  1517. InternetCloseHandle (hHttpSession);
  1518. return 0;
  1519. }
  1520. Time += FinishTiming();
  1521. //
  1522. // Close and re-open the file after each write.
  1523. //
  1524. InternetCloseHandle (hHttpFile);
  1525. }
  1526. }
  1527. #ifdef DELETE_TEMP_FILES
  1528. RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
  1529. #else
  1530. RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
  1531. #endif
  1532. InternetCloseHandle (hHttpSession);
  1533. return Time;
  1534. }
  1535. //---------------------------------------------------------
  1536. unsigned long Do_S_to_C_HttpWithFile(handle_t __RPC_FAR * b,
  1537. long i,
  1538. unsigned long Length,
  1539. unsigned long ChunkSize,
  1540. char __RPC_FAR *p)
  1541. /*++
  1542. Routine Description:
  1543. Grabs a file from the server using HTTP
  1544. --*/
  1545. {
  1546. static const char *szFuncName = "Do_S_to_C_HttpWithFile";
  1547. TCHAR pFileName[MAX_PATH];
  1548. TCHAR szHttpFilePath[MAX_PATH];
  1549. unsigned long Time=0;
  1550. HANDLE hFile;
  1551. HINTERNET hHttpSession;
  1552. DT_FILE_HANDLE hRemoteFile;
  1553. assert( (Length == 0) || (ChunkSize != 0));
  1554. //
  1555. // Create a temporary file.
  1556. //
  1557. if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
  1558. return 0;
  1559. //
  1560. // Open the temporary file.
  1561. //
  1562. hFile = CreateFile ((LPCTSTR) pFileName,
  1563. GENERIC_WRITE,
  1564. 0,
  1565. (LPSECURITY_ATTRIBUTES) NULL,
  1566. CREATE_ALWAYS,
  1567. FILE_ATTRIBUTE_NORMAL,
  1568. (HANDLE) NULL
  1569. );
  1570. if (hFile == INVALID_HANDLE_VALUE)
  1571. {
  1572. printf(szFormatCantOpenTempFile,
  1573. szFuncName,
  1574. pFileName);
  1575. PrintSysErrorStringA(GetLastError());
  1576. return 0;
  1577. }
  1578. //
  1579. // Common setup for Internet API tests...
  1580. //
  1581. if (FALSE == InternetCommonSetup (szFuncName,
  1582. FALSE, // HTTP setup
  1583. TRUE, // S_to_C
  1584. b,
  1585. Length,
  1586. &hHttpSession,
  1587. &hRemoteFile,
  1588. szHttpFilePath))
  1589. {
  1590. CloseHandle(hFile);
  1591. DeleteFile(pFileName);
  1592. return 0;
  1593. }
  1594. //
  1595. // The Actual Test
  1596. //
  1597. {
  1598. DWORD dwBytesWritten;
  1599. DWORD dwBytesRead;
  1600. HINTERNET hHttpFile;
  1601. while (i--)
  1602. {
  1603. hHttpFile = HttpOpenRequest (hHttpSession,
  1604. TEXT("GET"),
  1605. szHttpFilePath,
  1606. HTTP_VERSION,
  1607. NULL,
  1608. lpszAcceptTypes,
  1609. INTERNET_FLAG_RELOAD,
  1610. 0);
  1611. if (NULL == hHttpFile)
  1612. {
  1613. PrintInternetError (szFuncName);
  1614. RemoteClose (&hRemoteFile, TRUE);
  1615. InternetCloseHandle (hHttpSession);
  1616. CloseHandle(hFile);
  1617. DeleteFile(pFileName);
  1618. return 0;
  1619. }
  1620. if (FALSE == HttpSendRequest (hHttpFile,
  1621. NULL,
  1622. 0,
  1623. NULL,
  1624. 0))
  1625. {
  1626. PrintInternetError (szFuncName);
  1627. InternetCloseHandle (hHttpFile);
  1628. RemoteClose (&hRemoteFile, TRUE);
  1629. InternetCloseHandle (hHttpSession);
  1630. return 0;
  1631. }
  1632. //
  1633. // Reset the local file.
  1634. //
  1635. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  1636. StartTime();
  1637. for (;;)
  1638. {
  1639. if (FALSE == InternetReadFile (hHttpFile,
  1640. p,
  1641. ChunkSize,
  1642. &dwBytesRead))
  1643. {
  1644. PrintInternetError (szFuncName);
  1645. InternetCloseHandle (hHttpFile);
  1646. RemoteClose (&hRemoteFile, TRUE);
  1647. InternetCloseHandle (hHttpSession);
  1648. CloseHandle(hFile);
  1649. return 0;
  1650. }
  1651. //
  1652. // Return value == TRUE and dwBytesRead == 0 means EOF
  1653. //
  1654. if (0 == dwBytesRead)
  1655. break;
  1656. WriteFile(hFile, p, dwBytesRead, &dwBytesWritten, NULL);
  1657. }
  1658. Time += FinishTiming();
  1659. //
  1660. // Close and re-open the file after each write.
  1661. //
  1662. InternetCloseHandle (hHttpFile);
  1663. }
  1664. }
  1665. RemoteClose (&hRemoteFile, TRUE);
  1666. InternetCloseHandle (hHttpSession);
  1667. CloseHandle(hFile);
  1668. #ifdef DELETE_TEMP_FILES
  1669. DeleteFile (pFileName);
  1670. #endif
  1671. return Time;
  1672. }
  1673. //---------------------------------------------------------
  1674. unsigned long Do_C_to_S_HttpWithFile(handle_t __RPC_FAR * b,
  1675. long i,
  1676. unsigned long Length,
  1677. unsigned long ChunkSize,
  1678. char __RPC_FAR *p)
  1679. {
  1680. static const char *szFuncName="Do_C_to_S_HttpWithFile";
  1681. HINTERNET hHttpSession;
  1682. HANDLE hFile;
  1683. TCHAR pFileName[MAX_PATH];
  1684. unsigned long Time=0;
  1685. DT_FILE_HANDLE hRemoteFile;
  1686. char szHttpFilePath[MAX_PATH];
  1687. assert( (Length == 0) || (ChunkSize != 0));
  1688. //
  1689. // Create a temporary file.
  1690. //
  1691. if (FALSE == CreateTempFile (NULL, "FCS", Length, pFileName))
  1692. return 0;
  1693. //
  1694. // Open the temporary file.
  1695. //
  1696. hFile = CreateFile ((LPTSTR) pFileName,
  1697. GENERIC_READ,
  1698. 0,
  1699. (LPSECURITY_ATTRIBUTES) NULL,
  1700. OPEN_EXISTING,
  1701. FILE_ATTRIBUTE_NORMAL,
  1702. (HANDLE) NULL
  1703. );
  1704. if (hFile == INVALID_HANDLE_VALUE)
  1705. {
  1706. printf(szFormatCantOpenTempFile,
  1707. szFuncName,
  1708. pFileName);
  1709. PrintSysErrorStringA(GetLastError());
  1710. DeleteFile(pFileName);
  1711. return 0;
  1712. }
  1713. //
  1714. // Common setup for Internet API tests...
  1715. //
  1716. if (FALSE == InternetCommonSetup (szFuncName,
  1717. FALSE, // HTTP setup
  1718. FALSE, // C_to_S
  1719. b,
  1720. 0,
  1721. &hHttpSession,
  1722. &hRemoteFile,
  1723. szHttpFilePath))
  1724. {
  1725. CloseHandle(hFile);
  1726. DeleteFile(pFileName);
  1727. return 0;
  1728. }
  1729. //
  1730. // The Actual Test
  1731. //
  1732. {
  1733. DWORD dwBytesWritten;
  1734. DWORD dwBytesRead;
  1735. HINTERNET hHttpFile;
  1736. while (i--)
  1737. {
  1738. //
  1739. // Open the remote file.
  1740. //
  1741. hHttpFile = HttpOpenRequest (hHttpSession,
  1742. TEXT("PUT"),
  1743. szHttpFilePath,
  1744. HTTP_VERSION,
  1745. NULL,
  1746. lpszAcceptTypes,
  1747. INTERNET_FLAG_RELOAD,
  1748. 0);
  1749. if (NULL == hHttpFile)
  1750. {
  1751. PrintInternetError (szFuncName);
  1752. RemoteClose (&hRemoteFile, TRUE);
  1753. InternetCloseHandle (hHttpSession);
  1754. CloseHandle(hFile);
  1755. DeleteFile(pFileName);
  1756. return 0;
  1757. }
  1758. if (FALSE == HttpSendRequest (hHttpFile,
  1759. NULL,
  1760. 0,
  1761. NULL,
  1762. 0))
  1763. {
  1764. PrintInternetError (szFuncName);
  1765. InternetCloseHandle (hHttpFile);
  1766. RemoteClose (&hRemoteFile, TRUE);
  1767. InternetCloseHandle (hHttpSession);
  1768. return 0;
  1769. }
  1770. //
  1771. // Reset the local file.
  1772. //
  1773. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  1774. StartTime();
  1775. for (;;)
  1776. {
  1777. if (FALSE == ReadFile(hFile, p, ChunkSize, &dwBytesRead, NULL))
  1778. {
  1779. printf("%s: ReadFile failed.\n", szFuncName);
  1780. continue;
  1781. }
  1782. //
  1783. // Return value == TRUE and dwBytesRead == 0 means EOF
  1784. //
  1785. if (0 == dwBytesRead)
  1786. break;
  1787. if (FALSE == InternetWriteFile (hHttpFile,
  1788. p,
  1789. dwBytesRead,
  1790. &dwBytesWritten))
  1791. {
  1792. PrintInternetError (szFuncName);
  1793. InternetCloseHandle (hHttpFile);
  1794. RemoteClose (&hRemoteFile, FALSE);
  1795. CloseHandle(hFile);
  1796. InternetCloseHandle (hHttpSession);
  1797. return 0;
  1798. }
  1799. }
  1800. Time += FinishTiming();
  1801. //
  1802. // Close and re-open the file after each write.
  1803. //
  1804. InternetCloseHandle (hHttpFile);
  1805. }
  1806. }
  1807. #ifdef DELETE_TEMP_FILES
  1808. RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
  1809. #else
  1810. RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
  1811. #endif
  1812. InternetCloseHandle (hHttpSession);
  1813. CloseHandle(hFile);
  1814. DeleteFile(pFileName);
  1815. return Time;
  1816. }
  1817. /////////////////////////////////////////////////////////////////////
  1818. static const unsigned long (*TestTable[TEST_MAX])(handle_t __RPC_FAR *,long,long,long, char __RPC_FAR *) =
  1819. {
  1820. Do_S_to_C_NBytes,
  1821. Do_C_to_S_NBytes,
  1822. Do_S_to_C_Pipe,
  1823. Do_C_to_S_Pipe,
  1824. Do_S_to_C_Ftp1,
  1825. Do_C_to_S_Ftp1,
  1826. Do_S_to_C_Http,
  1827. Do_C_to_S_Http,
  1828. Do_S_to_C_NBytesWithFile,
  1829. Do_C_to_S_NBytesWithFile,
  1830. Do_S_to_C_PipeWithFile,
  1831. Do_C_to_S_PipeWithFile,
  1832. Do_S_to_C_FtpWithFile,
  1833. Do_C_to_S_FtpWithFile,
  1834. Do_S_to_C_Ftp1WithFile,
  1835. Do_C_to_S_Ftp1WithFile,
  1836. Do_S_to_C_HttpWithFile,
  1837. Do_C_to_S_HttpWithFile
  1838. };
  1839. //---------------------------------------------------------
  1840. //
  1841. // Worker calls the correct tests. Maybe multithreaded on NT
  1842. //
  1843. unsigned long Worker(unsigned long l)
  1844. {
  1845. unsigned long status;
  1846. unsigned long lTest;
  1847. long lIterations, lClientId;
  1848. unsigned long lTime;
  1849. long lLength, lChunkSize;
  1850. char __RPC_FAR *pBuffer;
  1851. char __RPC_FAR *stringBinding;
  1852. handle_t binding;
  1853. unsigned int i;
  1854. pBuffer = MIDL_user_allocate(ulBufferSize);
  1855. if (pBuffer == 0)
  1856. {
  1857. PrintToConsole("Out of memory!");
  1858. return 1;
  1859. }
  1860. for (i = 0; i< ulBufferSize;i++)
  1861. {
  1862. pBuffer[i] = (char) (i&0xff);
  1863. }
  1864. status = RpcStringBindingCompose(0,
  1865. Protseq,
  1866. NetworkAddr,
  1867. Endpoint,
  1868. 0,
  1869. &stringBinding);
  1870. CHECK_RET(status, "RpcStringBindingCompose");
  1871. status = RpcBindingFromStringBinding(stringBinding, &binding);
  1872. CHECK_RET(status, "RpcBindingFromStringBinding");
  1873. status = DoRpcBindingSetAuthInfo(binding);
  1874. CHECK_RET(status, "RpcBindingSetAuthInfo");
  1875. RpcStringFree(&stringBinding);
  1876. RpcTryExcept
  1877. {
  1878. status = BeginTest(binding, &lClientId);
  1879. }
  1880. RpcExcept(1)
  1881. {
  1882. PrintToConsole("First call failed %ld (%08lx)\n",
  1883. (unsigned long)RpcExceptionCode(),
  1884. (unsigned long)RpcExceptionCode());
  1885. goto Cleanup;
  1886. }
  1887. RpcEndExcept
  1888. if (status == PERF_TOO_MANY_CLIENTS)
  1889. {
  1890. PrintToConsole("Too many clients, I'm exiting\n");
  1891. goto Cleanup ;
  1892. }
  1893. CHECK_RET(status, "ClientConnect");
  1894. PrintToConsole("Client %ld connected\n", lClientId);
  1895. do
  1896. {
  1897. status = NextTest(binding, &lTest, &lIterations, &lLength, &lChunkSize);
  1898. if (status == PERF_TESTS_DONE)
  1899. {
  1900. goto Cleanup;
  1901. }
  1902. CHECK_RET(status, "NextTest");
  1903. PrintToConsole("(%4ld iterations of case %2ld, Length: %7ld, Chunk: %7ld: ",
  1904. lIterations,
  1905. lTest,
  1906. lLength,
  1907. lChunkSize);
  1908. RpcTryExcept
  1909. {
  1910. lTime = ( (TestTable[lTest])(&binding, lIterations, lLength, lChunkSize, pBuffer));
  1911. PrintToConsole("% 5ld mseconds)\n", lTime);
  1912. status = EndTest(binding, lTime);
  1913. CHECK_RET(status, "EndTest");
  1914. }
  1915. RpcExcept(1)
  1916. {
  1917. PrintToConsole("\nTest case %ld raised exception %lu (0x%08lX)\n",
  1918. lTest,
  1919. (unsigned long)RpcExceptionCode(),
  1920. (unsigned long)RpcExceptionCode());
  1921. status = RpcExceptionCode();
  1922. }
  1923. RpcEndExcept
  1924. }
  1925. while(status == 0);
  1926. Cleanup:
  1927. RpcBindingFree(&binding) ; //BUGBUG
  1928. return status;
  1929. }
  1930. //---------------------------------------------------------
  1931. //
  1932. // The Win32 main starts worker threads, otherwise we just call the worker.
  1933. //
  1934. #ifdef WIN32
  1935. int __cdecl
  1936. main (int argc, char **argv)
  1937. {
  1938. char option;
  1939. unsigned long status, i;
  1940. HANDLE *pClientThreads;
  1941. ParseArgv(argc, argv);
  1942. PrintToConsole("Authentication Level is: %s\n", AuthnLevelStr);
  1943. if (Options[0] < 0)
  1944. Options[0] = 1;
  1945. pClientThreads = MIDL_user_allocate(sizeof(HANDLE) * Options[0]);
  1946. //
  1947. // Setup for the use of the WinINet functions
  1948. //
  1949. hInternet = InternetOpen ("Data Transfer Test",
  1950. LOCAL_INTERNET_ACCESS,
  1951. NULL,
  1952. 0,
  1953. (DWORD) 0);
  1954. for(i = 0; i < (unsigned long)Options[0]; i++)
  1955. {
  1956. pClientThreads[i] = CreateThread(0,
  1957. 0,
  1958. (LPTHREAD_START_ROUTINE)Worker,
  1959. 0,
  1960. 0,
  1961. &status);
  1962. if (pClientThreads[i] == 0)
  1963. ApiError("CreateThread", GetLastError());
  1964. }
  1965. status = WaitForMultipleObjects(Options[0],
  1966. pClientThreads,
  1967. TRUE, // Wait for all client threads
  1968. INFINITE);
  1969. if (status == WAIT_FAILED)
  1970. {
  1971. ApiError("WaitForMultipleObjects", GetLastError());
  1972. }
  1973. if (NULL != hInternet)
  1974. {
  1975. InternetCloseHandle (hInternet);
  1976. }
  1977. PrintToConsole("TEST DONE\n");
  1978. return(0);
  1979. }
  1980. #else // !WIN32
  1981. #ifdef WIN
  1982. #define main c_main
  1983. // We need the following to force the linker to load WinMain from the
  1984. // Windows STDIO library
  1985. extern int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
  1986. static int (PASCAL *wm_ptr)(HANDLE, HANDLE, LPSTR, int) = WinMain;
  1987. #endif
  1988. #ifndef MAC
  1989. #ifndef FAR
  1990. #define FAR __far
  1991. #endif
  1992. #else
  1993. #define FAR
  1994. #define main c_main
  1995. #endif
  1996. int main (int argc, char FAR * FAR * argv)
  1997. {
  1998. #ifndef MAC
  1999. ParseArgv(argc, argv);
  2000. #endif
  2001. Worker(0);
  2002. PrintToConsole("TEST DONE\n");
  2003. return(0);
  2004. }
  2005. #endif // NTENV