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.

1105 lines
22 KiB

  1. //
  2. // Template driver user-mode controller
  3. // Copyright (c) Microsoft Corporation, 1999.
  4. //
  5. // Module: tcontrol.cxx
  6. // Author: Silviu Calinoiu (SilviuC)
  7. // Created: 4/20/1999 3:40pm
  8. //
  9. // This module contains a user-mode controller for a template
  10. // driver.
  11. //
  12. // --- History ---
  13. //
  14. // 4/20/1999 (SilviuC): initial version.
  15. //
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <tchar.h>
  19. #include <windows.h>
  20. #include <winioctl.h>
  21. #include <time.h>
  22. #define NO_BUGGY_FUNCTIONS
  23. #define FUNS_DEFINITION_MODULE
  24. #include "..\driver\tdriver.h"
  25. #include "..\driver\funs.h"
  26. //
  27. // Get rid of performance warnings for BOOL to bool conversions
  28. //
  29. #pragma warning (disable: 4800)
  30. bool TdCreateService (LPCTSTR DriverName);
  31. bool TdDeleteService (LPCTSTR DriverName);
  32. bool TdStartService (LPCTSTR DriverName);
  33. bool TdStopService (LPCTSTR DriverName);
  34. bool TdOpenDevice (LPCTSTR DriverName, PHANDLE DeviceHandle);
  35. bool TdCloseDevice (HANDLE Device);
  36. bool TdSendIoctl (IN HANDLE Device, IN DWORD Ioctl, IN PVOID pData OPTIONAL, IN ULONG uDataSize OPTIONAL);
  37. void TdSectMapProcessAddressSpaceTest();
  38. void TdSectMapSystemAddressSpaceTest();
  39. VOID
  40. TdReservedMapSetSize( int argc, char *argv[] );
  41. VOID
  42. TdReservedMapRead( VOID );
  43. BOOL
  44. ProcessCommandLine (
  45. LPCTSTR Option
  46. );
  47. ULONG_PTR
  48. UtilHexStringToUlongPtr( char *szHexNumber );
  49. ///////////////////////////////////////////////////////////////////////////////
  50. //////////////////////////////////////////////////////////////////////// Main()
  51. ///////////////////////////////////////////////////////////////////////////////
  52. void _cdecl
  53. main (int argc, char *argv[])
  54. {
  55. BOOL DisplayHelp;
  56. HANDLE Device;
  57. DWORD Index;
  58. char *pCrtChar;
  59. DisplayHelp = FALSE;
  60. try {
  61. if (argc == 3 && _stricmp (argv[1], "/create") == 0) {
  62. TdCreateService (argv[2]);
  63. }
  64. else if (argc == 3 && _stricmp (argv[1], "/delete") == 0) {
  65. TdDeleteService (argv[2]);
  66. }
  67. else if (argc == 3 && _stricmp (argv[1], "/start") == 0) {
  68. TdStartService (argv[2]);
  69. }
  70. else if (argc == 3 && _stricmp (argv[1], "/stop") == 0) {
  71. TdStopService (argv[2]);
  72. }
  73. else if (argc == 2 && _stricmp (argv[1], "/sectionmaptest") == 0) {
  74. TdSectMapProcessAddressSpaceTest();
  75. }
  76. else if (argc == 2 && _stricmp (argv[1], "/sectionmaptestsysspace") == 0) {
  77. TdSectMapSystemAddressSpaceTest();
  78. }
  79. else if ( _stricmp (argv[1], "/ReservedMapSetSize") == 0) {
  80. TdReservedMapSetSize( argc, argv );
  81. }
  82. else if ( _stricmp (argv[1], "/ReservedMapRead") == 0) {
  83. TdReservedMapRead();
  84. }
  85. else if (argc >= 2 && _stricmp (argv[1], "/ioctlbugcheck") == 0) {
  86. //
  87. // Send the bugcheck parameters from the command line
  88. //
  89. BUGCHECK_PARAMS BugcheckParams;
  90. ZeroMemory( &BugcheckParams, sizeof( BugcheckParams ) );
  91. //
  92. // Bugcheck code
  93. //
  94. if( argc >= 3 )
  95. {
  96. BugcheckParams.BugCheckCode = (ULONG)UtilHexStringToUlongPtr( argv[ 2 ] );
  97. }
  98. //
  99. // Bugcheck paramaters
  100. //
  101. for( int nCrtCommandLineArg = 3; nCrtCommandLineArg < argc; nCrtCommandLineArg++ )
  102. {
  103. BugcheckParams.BugCheckParameters[ nCrtCommandLineArg - 3 ] =
  104. UtilHexStringToUlongPtr( argv[ nCrtCommandLineArg ] );
  105. }
  106. //
  107. // Send the IOCTL to the driver
  108. //
  109. HANDLE Device;
  110. if ( TdOpenDevice ("buggy", &Device) ) {
  111. TdSendIoctl (
  112. Device,
  113. IOCTL_TD_BUGCHECK,
  114. &BugcheckParams,
  115. sizeof( BugcheckParams ) );
  116. TdCloseDevice (Device);
  117. }
  118. }
  119. else {
  120. if (ProcessCommandLine (argv[1]) == FALSE) {
  121. DisplayHelp = TRUE;
  122. }
  123. }
  124. }
  125. catch (char * Message) {
  126. printf ("Error: s", GetLastError(), Message);
  127. }
  128. if ( DisplayHelp == TRUE ) {
  129. printf ("ctlbuggy /create DRIVER \n");
  130. printf ("ctlbuggy /delete DRIVER \n");
  131. printf ("ctlbuggy /start DRIVER \n");
  132. printf ("ctlbuggy /stop DRIVER \n");
  133. printf (" \n");
  134. printf ("ctlbuggy /sectionmaptest \n");
  135. printf ("ctlbuggy /sectionmaptestsysspace \n");
  136. printf (" \n");
  137. printf ("ctlbuggy IOCTL-NAME \n");
  138. printf ("\n\n");
  139. for (Index = 0; BuggyFuns[Index].Ioctl != 0; Index++) {
  140. printf("ctlbuggy %s \n", BuggyFuns[Index].Command);
  141. }
  142. printf ("\n");
  143. exit (1);
  144. }
  145. exit( 0 );
  146. }
  147. BOOL
  148. ProcessCommandLine (
  149. LPCTSTR Option
  150. )
  151. /*++
  152. Routine Description:
  153. This routine tries to figure out if the command line option
  154. is specifies one of the ioctls that can be processed.
  155. Arguments:
  156. `Option' - command line option.
  157. Return Value:
  158. TRUE if an option has been found and processed.
  159. FALSE otherwise.
  160. Environment:
  161. Nothing special.
  162. --*/
  163. {
  164. DWORD Index;
  165. HANDLE Device;
  166. BOOL Result = FALSE;
  167. for (Index = 0; BuggyFuns[Index].Ioctl != 0; Index++) {
  168. if (_stricmp (BuggyFuns[Index].Command, Option) == 0) {
  169. if ( TdOpenDevice ("buggy", &Device) ) {
  170. TdSendIoctl (Device, BuggyFuns[Index].Ioctl, NULL, 0);
  171. TdCloseDevice (Device);
  172. Result = TRUE;
  173. break;
  174. }
  175. }
  176. }
  177. return Result;
  178. }
  179. ///////////////////////////////////////////////////////////////////////////////
  180. //////////////////////////////////////////////////////////// Driver load/unload
  181. ///////////////////////////////////////////////////////////////////////////////
  182. bool
  183. TdCreateService (
  184. LPCTSTR DriverName)
  185. {
  186. SC_HANDLE ServiceManager = NULL;
  187. SC_HANDLE ServiceHandle = NULL;
  188. BOOL ReturnValue;
  189. HANDLE Driver;
  190. TCHAR ScratchBuffer [MAX_PATH];
  191. TCHAR DriverPath [MAX_PATH];
  192. TCHAR DevicePath [MAX_PATH];
  193. try {
  194. GetSystemDirectory (ScratchBuffer, sizeof ScratchBuffer);
  195. _stprintf (DriverPath, "%s\\drivers\\%s.sys", ScratchBuffer, DriverName);
  196. _stprintf (DevicePath, "\\\\.\\%s", DriverName);
  197. //
  198. // Open the service control manager
  199. //
  200. ServiceManager = OpenSCManager (
  201. NULL,
  202. NULL,
  203. SC_MANAGER_ALL_ACCESS);
  204. if (ServiceManager == NULL) {
  205. throw "OpenScManager()";
  206. }
  207. //
  208. // Create the service
  209. //
  210. printf("Driver path: %s \n", DriverPath);
  211. printf("Device path: %s \n", DevicePath);
  212. ServiceHandle = CreateService (
  213. ServiceManager, // handle to SC manager
  214. DriverName, // name of service
  215. DriverName, // display name
  216. SERVICE_ALL_ACCESS, // access mask
  217. SERVICE_KERNEL_DRIVER, // service type
  218. SERVICE_DEMAND_START, // start type
  219. SERVICE_ERROR_NORMAL, // error control
  220. DriverPath, // full path to driver
  221. NULL, // load ordering
  222. NULL, // tag id
  223. NULL, // dependency
  224. NULL, // account name
  225. NULL); // password
  226. if (ServiceHandle == NULL && GetLastError() != ERROR_SERVICE_EXISTS) {
  227. throw "CreateService()";
  228. }
  229. ReturnValue = TRUE;
  230. }
  231. catch (char * Msg) {
  232. printf("Error: %u: %s\n", GetLastError(), Msg);
  233. fflush (stdout);
  234. ReturnValue = FALSE;
  235. }
  236. //
  237. // Close handles and return.
  238. //
  239. if (ServiceHandle) {
  240. CloseServiceHandle (ServiceHandle);
  241. }
  242. if (ServiceManager) {
  243. CloseServiceHandle (ServiceManager);
  244. }
  245. return ReturnValue;
  246. }
  247. bool
  248. TdStartService (
  249. LPCTSTR DriverName)
  250. {
  251. SC_HANDLE ServiceManager = NULL;
  252. SC_HANDLE ServiceHandle = NULL;
  253. BOOL ReturnValue;
  254. HANDLE Driver;
  255. TCHAR ScratchBuffer [MAX_PATH];
  256. TCHAR DriverPath [MAX_PATH];
  257. TCHAR DevicePath [MAX_PATH];
  258. try {
  259. GetSystemDirectory (ScratchBuffer, sizeof ScratchBuffer);
  260. _stprintf (DriverPath, "%s\\drivers\\%s.sys", ScratchBuffer, DriverName);
  261. _stprintf (DevicePath, "\\\\.\\%s", DriverName);
  262. //
  263. // Open the service control manager
  264. //
  265. ServiceManager = OpenSCManager (
  266. NULL,
  267. NULL,
  268. SC_MANAGER_ALL_ACCESS);
  269. if (ServiceManager == NULL) {
  270. throw "OpenScManager()";
  271. }
  272. //
  273. // Open the service. The function assumes that
  274. // TdCreateService has been called before this one
  275. // and the service is already installed.
  276. //
  277. ServiceHandle = OpenService (
  278. ServiceManager,
  279. DriverName,
  280. SERVICE_ALL_ACCESS);
  281. if (ServiceHandle == NULL) {
  282. throw "OpenService()";
  283. }
  284. //
  285. // Start the service
  286. //
  287. if (! StartService (ServiceHandle, 0, NULL)) {
  288. if (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) {
  289. throw "StartService()";
  290. }
  291. }
  292. ReturnValue = TRUE;
  293. }
  294. catch (char * Msg) {
  295. printf("Error: %u: %s\n", GetLastError(), Msg);
  296. fflush (stdout);
  297. ReturnValue = FALSE;
  298. }
  299. //
  300. // Close handles and return.
  301. //
  302. if (ServiceHandle) {
  303. CloseServiceHandle (ServiceHandle);
  304. }
  305. if (ServiceManager) {
  306. CloseServiceHandle (ServiceManager);
  307. }
  308. return ReturnValue;
  309. }
  310. bool
  311. TdStopService (
  312. LPCTSTR DriverName)
  313. {
  314. SC_HANDLE ServiceManager = NULL;
  315. SC_HANDLE ServiceHandle = NULL;
  316. SERVICE_STATUS ServiceStatus;
  317. BOOL ReturnValue;
  318. try {
  319. //
  320. // Open the service control manager
  321. //
  322. ServiceManager = OpenSCManager (
  323. NULL,
  324. NULL,
  325. SC_MANAGER_ALL_ACCESS);
  326. if (ServiceManager == NULL) {
  327. throw "OpenSCManager()";
  328. }
  329. //
  330. // Open the service so we can stop it
  331. //
  332. ServiceHandle = OpenService (
  333. ServiceManager,
  334. DriverName,
  335. SERVICE_ALL_ACCESS);
  336. if (ServiceHandle == NULL) {
  337. throw "OpenService()";
  338. }
  339. //
  340. // Stop the service
  341. //
  342. if (! ControlService (ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus)) {
  343. throw "ControlService()";
  344. }
  345. ReturnValue = TRUE;
  346. }
  347. catch (char * Msg) {
  348. printf("Error: %u: %s\n", GetLastError(), Msg);
  349. fflush (stdout);
  350. ReturnValue = FALSE;
  351. }
  352. //
  353. // Close handles ans return.
  354. //
  355. if (ServiceHandle) {
  356. CloseServiceHandle (ServiceHandle);
  357. }
  358. if (ServiceManager) {
  359. CloseServiceHandle (ServiceManager);
  360. }
  361. return ReturnValue;
  362. }
  363. bool
  364. TdDeleteService (
  365. LPCTSTR DriverName)
  366. {
  367. SC_HANDLE ServiceManager = NULL;
  368. SC_HANDLE ServiceHandle = NULL;
  369. SERVICE_STATUS ServiceStatus;
  370. BOOL ReturnValue;
  371. try {
  372. //
  373. // Open the service control manager
  374. //
  375. ServiceManager = OpenSCManager (
  376. NULL,
  377. NULL,
  378. SC_MANAGER_ALL_ACCESS);
  379. if (ServiceManager == NULL) {
  380. throw "OpenSCManager()";
  381. }
  382. //
  383. // Open the service so we can stop it
  384. //
  385. ServiceHandle = OpenService (
  386. ServiceManager,
  387. DriverName,
  388. SERVICE_ALL_ACCESS);
  389. if (ServiceHandle == NULL) {
  390. throw "OpenService()";
  391. }
  392. //
  393. // Delete the service
  394. //
  395. if (! DeleteService (ServiceHandle)) {
  396. if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) {
  397. throw "DeleteService()";
  398. }
  399. }
  400. ReturnValue = TRUE;
  401. }
  402. catch (char * Msg) {
  403. printf("Error: %u: %s\n", GetLastError(), Msg);
  404. fflush (stdout);
  405. ReturnValue = FALSE;
  406. }
  407. //
  408. // Close handles ans return.
  409. //
  410. if (ServiceHandle) {
  411. CloseServiceHandle (ServiceHandle);
  412. }
  413. if (ServiceManager) {
  414. CloseServiceHandle (ServiceManager);
  415. }
  416. return ReturnValue;
  417. }
  418. bool
  419. TdOpenDevice (
  420. LPCTSTR DriverName,
  421. PHANDLE DeviceHandle)
  422. {
  423. SC_HANDLE ServiceManager = NULL;
  424. SC_HANDLE ServiceHandle = NULL;
  425. BOOL ReturnValue;
  426. HANDLE Device;
  427. TCHAR ScratchBuffer [MAX_PATH];
  428. TCHAR DriverPath [MAX_PATH];
  429. TCHAR DevicePath [MAX_PATH];
  430. //
  431. // Sanity checks
  432. //
  433. if (DeviceHandle == NULL) {
  434. return FALSE;
  435. }
  436. try {
  437. GetSystemDirectory (ScratchBuffer, sizeof ScratchBuffer);
  438. _stprintf (DriverPath, "%s\\drivers\\%s.sys", ScratchBuffer, DriverName);
  439. _stprintf (DevicePath, "\\\\.\\%s", DriverName);
  440. //
  441. // Open the service control manager
  442. //
  443. ServiceManager = OpenSCManager (
  444. NULL,
  445. NULL,
  446. SC_MANAGER_ALL_ACCESS);
  447. if (ServiceManager == NULL) {
  448. throw "OpenScManager()";
  449. }
  450. //
  451. // Service should already exist.
  452. //
  453. ServiceHandle = OpenService (
  454. ServiceManager,
  455. DriverName,
  456. SERVICE_ALL_ACCESS);
  457. if (ServiceHandle == NULL) {
  458. throw "OpenService()";
  459. }
  460. //
  461. // Open the device
  462. //
  463. Device = CreateFile (
  464. DevicePath,
  465. GENERIC_READ|GENERIC_WRITE,
  466. 0,
  467. NULL,
  468. OPEN_EXISTING,
  469. FILE_ATTRIBUTE_NORMAL,
  470. NULL);
  471. if (Device == INVALID_HANDLE_VALUE) {
  472. throw "CreateFile()";
  473. }
  474. ReturnValue = TRUE;
  475. }
  476. catch (char * Msg) {
  477. printf("Error: %u: %s\n", GetLastError(), Msg);
  478. fflush (stdout);
  479. ReturnValue = FALSE;
  480. }
  481. //
  482. // Close handles and return.
  483. //
  484. if (ServiceHandle) {
  485. CloseServiceHandle (ServiceHandle);
  486. }
  487. if (ServiceManager) {
  488. CloseServiceHandle (ServiceManager);
  489. }
  490. if (Device != INVALID_HANDLE_VALUE) {
  491. *DeviceHandle = Device;
  492. }
  493. return ReturnValue;
  494. }
  495. bool
  496. TdCloseDevice (
  497. HANDLE Device)
  498. {
  499. if (Device == INVALID_HANDLE_VALUE) {
  500. return false;
  501. }
  502. return CloseHandle(Device);
  503. }
  504. //
  505. // Function:
  506. //
  507. // SendIoctl
  508. //
  509. // Description:
  510. //
  511. // This function sends an ioctl code to the driver.
  512. //
  513. bool
  514. TdSendIoctl (
  515. IN HANDLE Driver,
  516. IN DWORD Ioctl,
  517. IN PVOID pData OPTIONAL,
  518. IN ULONG uDataSize OPTIONAL )
  519. {
  520. DWORD BytesReturned;
  521. BOOL Result;
  522. if (Driver == INVALID_HANDLE_VALUE) {
  523. return false;
  524. }
  525. Result = DeviceIoControl (
  526. Driver,
  527. Ioctl,
  528. pData,
  529. uDataSize,
  530. NULL,
  531. 0,
  532. &BytesReturned,
  533. NULL);
  534. return Result == TRUE;
  535. }
  536. //
  537. //
  538. //
  539. #if _MSC_FULL_VER >= 13008827
  540. #pragma warning(push)
  541. #pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
  542. #endif
  543. DWORD
  544. MapProcessAddressSpaceThread( LPVOID lpData )
  545. {
  546. HANDLE hDevice;
  547. DWORD dwTimeToSleep;
  548. hDevice = (HANDLE)lpData;
  549. while( TRUE )
  550. {
  551. dwTimeToSleep = rand() % 5000;
  552. Sleep( dwTimeToSleep );
  553. TdSendIoctl (hDevice, IOCTL_TD_SECTION_MAP_TEST_PROCESS_SPACE, NULL, 0);
  554. }
  555. return 0;
  556. }
  557. #if _MSC_FULL_VER >= 13008827
  558. #pragma warning(pop)
  559. #endif
  560. //
  561. //
  562. //
  563. #define TD_MAPSECT_TEST_THREADS 4
  564. void TdSectMapProcessAddressSpaceTest()
  565. {
  566. HANDLE Device;
  567. time_t theTime;
  568. int nCrtThread;
  569. DWORD dwThreadId;
  570. TCHAR strMessage[ 128 ];
  571. time( &theTime );
  572. _stprintf(
  573. strMessage,
  574. "Process %u, rand seed = %u\n",
  575. GetCurrentProcessId(),
  576. (unsigned int)theTime );
  577. OutputDebugString( strMessage );
  578. srand( (unsigned int)theTime );
  579. if( TdOpenDevice ("buggy", &Device) )
  580. {
  581. for( nCrtThread = 0; nCrtThread < TD_MAPSECT_TEST_THREADS - 1; nCrtThread++ )
  582. {
  583. CreateThread(
  584. NULL,
  585. 0,
  586. MapProcessAddressSpaceThread,
  587. (LPVOID)Device,
  588. 0,
  589. &dwThreadId );
  590. }
  591. //
  592. // reuse the main thread
  593. //
  594. MapProcessAddressSpaceThread( (LPVOID)Device );
  595. TdCloseDevice (Device);
  596. }
  597. }
  598. //
  599. //
  600. //
  601. #if _MSC_FULL_VER >= 13008827
  602. #pragma warning(push)
  603. #pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
  604. #endif
  605. DWORD
  606. MapSystemAddressSpaceThread( LPVOID lpData )
  607. {
  608. HANDLE hDevice;
  609. DWORD dwTimeToSleep;
  610. hDevice = (HANDLE)lpData;
  611. while( TRUE )
  612. {
  613. dwTimeToSleep = rand() % 5000;
  614. Sleep( dwTimeToSleep );
  615. TdSendIoctl (hDevice, IOCTL_TD_SECTION_MAP_TEST_SYSTEM_SPACE, NULL, 0);
  616. }
  617. return 0;
  618. }
  619. #if _MSC_FULL_VER >= 13008827
  620. #pragma warning(pop)
  621. #endif
  622. //
  623. //
  624. //
  625. void TdSectMapSystemAddressSpaceTest()
  626. {
  627. HANDLE Device;
  628. time_t theTime;
  629. int nCrtThread;
  630. DWORD dwThreadId;
  631. TCHAR strMessage[ 128 ];
  632. time( &theTime );
  633. _stprintf(
  634. strMessage,
  635. "Process %u, rand seed = %u\n",
  636. GetCurrentProcessId(),
  637. (unsigned int)theTime );
  638. OutputDebugString( strMessage );
  639. srand( (unsigned int)theTime );
  640. if( TdOpenDevice ("buggy", &Device) )
  641. {
  642. for( nCrtThread = 0; nCrtThread < TD_MAPSECT_TEST_THREADS - 1; nCrtThread++ )
  643. {
  644. CreateThread(
  645. NULL,
  646. 0,
  647. MapProcessAddressSpaceThread,
  648. (LPVOID)Device,
  649. 0,
  650. &dwThreadId );
  651. }
  652. //
  653. // reuse the main thread - only this thread will map into system address space
  654. //
  655. MapSystemAddressSpaceThread( (LPVOID)Device );
  656. TdCloseDevice (Device);
  657. }
  658. }
  659. //
  660. // Convert a hex string from the command line to an UNLONG_PTR
  661. //
  662. ULONG_PTR
  663. UtilHexStringToUlongPtr( char *szHexNumber )
  664. {
  665. ULONG_PTR uNewDigit;
  666. ULONG_PTR uResult = 0;
  667. char *pCrtChar = szHexNumber;
  668. while( ( *pCrtChar ) != (char)0 )
  669. {
  670. uNewDigit = 0;
  671. if( ( *pCrtChar ) >= '0' && ( *pCrtChar ) <= '9' )
  672. {
  673. uNewDigit = ( *pCrtChar ) - '0';
  674. }
  675. else
  676. {
  677. if( ( *pCrtChar ) >= 'A' && ( *pCrtChar ) <= 'F' )
  678. {
  679. uNewDigit = ( *pCrtChar ) - 'A' + 10;
  680. }
  681. else
  682. {
  683. if( ( *pCrtChar ) >= 'a' && ( *pCrtChar ) <= 'f' )
  684. {
  685. uNewDigit = ( *pCrtChar ) - 'a' + 10;
  686. }
  687. }
  688. }
  689. uResult = uResult * 16 + uNewDigit;
  690. pCrtChar++;
  691. }
  692. return uResult;
  693. }
  694. //
  695. // Set the current reserved size and address as asked by the user
  696. //
  697. VOID
  698. TdReservedMapSetSize(
  699. int argc,
  700. char *argv[] )
  701. {
  702. SIZE_T NewSize;
  703. HANDLE Device;
  704. time_t theTime;
  705. TCHAR strMessage[ 128 ];
  706. if( argc >= 3 )
  707. {
  708. //
  709. // User-specified buffer size
  710. //
  711. NewSize = atoi( argv[ 2 ] );
  712. }
  713. else
  714. {
  715. //
  716. // Seed the random numbers generator
  717. //
  718. time( &theTime );
  719. _stprintf(
  720. strMessage,
  721. "Process %u, rand seed = %u\n",
  722. GetCurrentProcessId(),
  723. (unsigned int)theTime );
  724. OutputDebugString( strMessage );
  725. srand( (unsigned int)theTime );
  726. //
  727. // New size is random, up to 10 pages
  728. //
  729. NewSize = ( abs( rand() ) % 10 + 1 ) * 0x1000;
  730. }
  731. if( TdOpenDevice ("buggy", &Device) )
  732. {
  733. printf( "TdReservedMapSetSize: sending size %p\n",
  734. NewSize );
  735. TdSendIoctl (
  736. Device,
  737. IOCTL_TD_RESERVEDMAP_SET_SIZE,
  738. &NewSize,
  739. sizeof( NewSize ) );
  740. TdCloseDevice (Device);
  741. }
  742. }
  743. //
  744. // Ask for a "read" operation from our driver
  745. //
  746. VOID
  747. TdReservedMapRead( VOID )
  748. {
  749. HANDLE Device;
  750. time_t theTime;
  751. SIZE_T ReadBufferSize;
  752. SIZE_T ReadPages;
  753. SIZE_T CrtReadPage;
  754. PSIZE_T CrtPageAddress;
  755. PVOID UserBuffer;
  756. BOOL Success;
  757. SYSTEM_INFO SystemInfo;
  758. TCHAR strMessage[ 128 ];
  759. //
  760. // Get the page size
  761. //
  762. GetSystemInfo(
  763. &SystemInfo );
  764. //
  765. // Seed the random numbers generator
  766. //
  767. time( &theTime );
  768. _stprintf(
  769. strMessage,
  770. "Process %u, rand seed = %u\n",
  771. GetCurrentProcessId(),
  772. (unsigned int)theTime );
  773. //OutputDebugString( strMessage );
  774. puts( strMessage );
  775. srand( (unsigned int)theTime );
  776. //
  777. // Choose a size >= PAGE_SIZE and <= ~1 Mb
  778. //
  779. ReadBufferSize = abs( rand() * rand() * rand() ) % ( 1024 * 1024 ) + SystemInfo.dwPageSize;
  780. UserBuffer = VirtualAlloc(
  781. NULL,
  782. ReadBufferSize,
  783. MEM_RESERVE | MEM_COMMIT,
  784. PAGE_READWRITE );
  785. if( NULL != UserBuffer )
  786. {
  787. if( TdOpenDevice ("buggy", &Device) )
  788. {
  789. //
  790. // Prepare the parameters to the driver
  791. //
  792. USER_READ_BUFFER UserReadBuffer;
  793. UserReadBuffer.UserBuffer = UserBuffer;
  794. UserReadBuffer.UserBufferSize = ReadBufferSize;
  795. _stprintf(
  796. strMessage,
  797. "TdReservedMapRead: sending buffer %p, size %p\n",
  798. UserReadBuffer.UserBuffer,
  799. UserReadBuffer.UserBufferSize );
  800. //OutputDebugString( strMessage );
  801. puts( strMessage );
  802. //
  803. // Send the request to the driver
  804. //
  805. Success = TdSendIoctl (
  806. Device,
  807. IOCTL_TD_RESERVEDMAP_READ_OP,
  808. &UserReadBuffer,
  809. sizeof( UserReadBuffer ) );
  810. if( TRUE == Success )
  811. {
  812. //
  813. // If the call succeeded then we check the validity of data returned by the driver
  814. //
  815. ReadPages = ReadBufferSize / SystemInfo.dwPageSize;
  816. CrtPageAddress = (PSIZE_T)UserBuffer;
  817. for( CrtReadPage = 1; CrtReadPage <= ReadPages; CrtReadPage++ )
  818. {
  819. if( *CrtPageAddress != CrtReadPage )
  820. {
  821. _stprintf(
  822. strMessage,
  823. "Incorrect data received from buggy.sys: page %p, expected %p, actual data %p\n",
  824. CrtPageAddress,
  825. CrtReadPage,
  826. *CrtPageAddress );
  827. OutputDebugString( strMessage );
  828. DebugBreak();
  829. }
  830. CrtPageAddress = (PSIZE_T) ( (PCHAR)CrtPageAddress + SystemInfo.dwPageSize );
  831. ReadPages -= 1;
  832. }
  833. }
  834. TdCloseDevice (Device);
  835. }
  836. VirtualFree(
  837. UserBuffer,
  838. 0,
  839. MEM_RELEASE );
  840. }
  841. }
  842. //
  843. // End of file
  844. //