Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1130 lines
24 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 ( argc >= 2 && _stricmp (argv[1], "/ReservedMapSetSize") == 0) {
  80. TdReservedMapSetSize( argc, argv );
  81. }
  82. else if ( argc >= 2 && _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 (argc >= 2 && 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 && BuggyFuns[Index].Command != NULL; 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 (BuggyFuns[Index].Command != NULL && _stricmp (BuggyFuns[Index].Command, Option) == 0) {
  169. if ( TdOpenDevice ("buggy", &Device) ) {
  170. TdSendIoctl (Device, BuggyFuns[Index].Ioctl, NULL, 0);
  171. if (BuggyFuns[Index].Ioctl == IOCTL_TD_NONPAGEDPOOLMDLTEST_MAP)
  172. {
  173. //
  174. // Sleep for a while
  175. //
  176. //DWORD SleepTime = 2 * 60 * 1000;
  177. DWORD SleepTime = 10 * 1000;
  178. printf ("Sleeping for %u millisec\n",
  179. SleepTime);
  180. Sleep (SleepTime);
  181. //
  182. // Unmap the memory.
  183. //
  184. printf ("Unmapping memory.\n");
  185. TdSendIoctl (Device, IOCTL_TD_NONPAGEDPOOLMDLTEST_UNMAP, NULL, 0);
  186. }
  187. TdCloseDevice (Device);
  188. Result = TRUE;
  189. break;
  190. }
  191. }
  192. }
  193. return Result;
  194. }
  195. ///////////////////////////////////////////////////////////////////////////////
  196. //////////////////////////////////////////////////////////// Driver load/unload
  197. ///////////////////////////////////////////////////////////////////////////////
  198. bool
  199. TdCreateService (
  200. LPCTSTR DriverName)
  201. {
  202. SC_HANDLE ServiceManager = NULL;
  203. SC_HANDLE ServiceHandle = NULL;
  204. BOOL ReturnValue;
  205. HANDLE Driver;
  206. TCHAR ScratchBuffer [MAX_PATH];
  207. TCHAR DriverPath [MAX_PATH];
  208. TCHAR DevicePath [MAX_PATH];
  209. try {
  210. GetSystemDirectory (ScratchBuffer, sizeof ScratchBuffer);
  211. _stprintf (DriverPath, "%s\\drivers\\%s.sys", ScratchBuffer, DriverName);
  212. _stprintf (DevicePath, "\\\\.\\%s", DriverName);
  213. //
  214. // Open the service control manager
  215. //
  216. ServiceManager = OpenSCManager (
  217. NULL,
  218. NULL,
  219. SC_MANAGER_ALL_ACCESS);
  220. if (ServiceManager == NULL) {
  221. throw "OpenScManager()";
  222. }
  223. //
  224. // Create the service
  225. //
  226. printf("Driver path: %s \n", DriverPath);
  227. printf("Device path: %s \n", DevicePath);
  228. ServiceHandle = CreateService (
  229. ServiceManager, // handle to SC manager
  230. DriverName, // name of service
  231. DriverName, // display name
  232. SERVICE_ALL_ACCESS, // access mask
  233. SERVICE_KERNEL_DRIVER, // service type
  234. SERVICE_DEMAND_START, // start type
  235. SERVICE_ERROR_NORMAL, // error control
  236. DriverPath, // full path to driver
  237. NULL, // load ordering
  238. NULL, // tag id
  239. NULL, // dependency
  240. NULL, // account name
  241. NULL); // password
  242. if (ServiceHandle == NULL && GetLastError() != ERROR_SERVICE_EXISTS) {
  243. throw "CreateService()";
  244. }
  245. ReturnValue = TRUE;
  246. }
  247. catch (char * Msg) {
  248. printf("Error: %u: %s\n", GetLastError(), Msg);
  249. fflush (stdout);
  250. ReturnValue = FALSE;
  251. }
  252. //
  253. // Close handles and return.
  254. //
  255. if (ServiceHandle) {
  256. CloseServiceHandle (ServiceHandle);
  257. }
  258. if (ServiceManager) {
  259. CloseServiceHandle (ServiceManager);
  260. }
  261. return ReturnValue;
  262. }
  263. bool
  264. TdStartService (
  265. LPCTSTR DriverName)
  266. {
  267. SC_HANDLE ServiceManager = NULL;
  268. SC_HANDLE ServiceHandle = NULL;
  269. BOOL ReturnValue;
  270. HANDLE Driver;
  271. TCHAR ScratchBuffer [MAX_PATH];
  272. TCHAR DriverPath [MAX_PATH];
  273. TCHAR DevicePath [MAX_PATH];
  274. try {
  275. GetSystemDirectory (ScratchBuffer, sizeof ScratchBuffer);
  276. _stprintf (DriverPath, "%s\\drivers\\%s.sys", ScratchBuffer, DriverName);
  277. _stprintf (DevicePath, "\\\\.\\%s", DriverName);
  278. //
  279. // Open the service control manager
  280. //
  281. ServiceManager = OpenSCManager (
  282. NULL,
  283. NULL,
  284. SC_MANAGER_ALL_ACCESS);
  285. if (ServiceManager == NULL) {
  286. throw "OpenScManager()";
  287. }
  288. //
  289. // Open the service. The function assumes that
  290. // TdCreateService has been called before this one
  291. // and the service is already installed.
  292. //
  293. ServiceHandle = OpenService (
  294. ServiceManager,
  295. DriverName,
  296. SERVICE_ALL_ACCESS);
  297. if (ServiceHandle == NULL) {
  298. throw "OpenService()";
  299. }
  300. //
  301. // Start the service
  302. //
  303. if (! StartService (ServiceHandle, 0, NULL)) {
  304. if (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) {
  305. throw "StartService()";
  306. }
  307. }
  308. ReturnValue = TRUE;
  309. }
  310. catch (char * Msg) {
  311. printf("Error: %u: %s\n", GetLastError(), Msg);
  312. fflush (stdout);
  313. ReturnValue = FALSE;
  314. }
  315. //
  316. // Close handles and return.
  317. //
  318. if (ServiceHandle) {
  319. CloseServiceHandle (ServiceHandle);
  320. }
  321. if (ServiceManager) {
  322. CloseServiceHandle (ServiceManager);
  323. }
  324. return ReturnValue;
  325. }
  326. bool
  327. TdStopService (
  328. LPCTSTR DriverName)
  329. {
  330. SC_HANDLE ServiceManager = NULL;
  331. SC_HANDLE ServiceHandle = NULL;
  332. SERVICE_STATUS ServiceStatus;
  333. BOOL ReturnValue;
  334. try {
  335. //
  336. // Open the service control manager
  337. //
  338. ServiceManager = OpenSCManager (
  339. NULL,
  340. NULL,
  341. SC_MANAGER_ALL_ACCESS);
  342. if (ServiceManager == NULL) {
  343. throw "OpenSCManager()";
  344. }
  345. //
  346. // Open the service so we can stop it
  347. //
  348. ServiceHandle = OpenService (
  349. ServiceManager,
  350. DriverName,
  351. SERVICE_ALL_ACCESS);
  352. if (ServiceHandle == NULL) {
  353. throw "OpenService()";
  354. }
  355. //
  356. // Stop the service
  357. //
  358. if (! ControlService (ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus)) {
  359. throw "ControlService()";
  360. }
  361. ReturnValue = TRUE;
  362. }
  363. catch (char * Msg) {
  364. printf("Error: %u: %s\n", GetLastError(), Msg);
  365. fflush (stdout);
  366. ReturnValue = FALSE;
  367. }
  368. //
  369. // Close handles ans return.
  370. //
  371. if (ServiceHandle) {
  372. CloseServiceHandle (ServiceHandle);
  373. }
  374. if (ServiceManager) {
  375. CloseServiceHandle (ServiceManager);
  376. }
  377. return ReturnValue;
  378. }
  379. bool
  380. TdDeleteService (
  381. LPCTSTR DriverName)
  382. {
  383. SC_HANDLE ServiceManager = NULL;
  384. SC_HANDLE ServiceHandle = NULL;
  385. SERVICE_STATUS ServiceStatus;
  386. BOOL ReturnValue;
  387. try {
  388. //
  389. // Open the service control manager
  390. //
  391. ServiceManager = OpenSCManager (
  392. NULL,
  393. NULL,
  394. SC_MANAGER_ALL_ACCESS);
  395. if (ServiceManager == NULL) {
  396. throw "OpenSCManager()";
  397. }
  398. //
  399. // Open the service so we can stop it
  400. //
  401. ServiceHandle = OpenService (
  402. ServiceManager,
  403. DriverName,
  404. SERVICE_ALL_ACCESS);
  405. if (ServiceHandle == NULL) {
  406. throw "OpenService()";
  407. }
  408. //
  409. // Delete the service
  410. //
  411. if (! DeleteService (ServiceHandle)) {
  412. if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) {
  413. throw "DeleteService()";
  414. }
  415. }
  416. ReturnValue = TRUE;
  417. }
  418. catch (char * Msg) {
  419. printf("Error: %u: %s\n", GetLastError(), Msg);
  420. fflush (stdout);
  421. ReturnValue = FALSE;
  422. }
  423. //
  424. // Close handles ans return.
  425. //
  426. if (ServiceHandle) {
  427. CloseServiceHandle (ServiceHandle);
  428. }
  429. if (ServiceManager) {
  430. CloseServiceHandle (ServiceManager);
  431. }
  432. return ReturnValue;
  433. }
  434. bool
  435. TdOpenDevice (
  436. LPCTSTR DriverName,
  437. PHANDLE DeviceHandle)
  438. {
  439. SC_HANDLE ServiceManager = NULL;
  440. SC_HANDLE ServiceHandle = NULL;
  441. BOOL ReturnValue;
  442. HANDLE Device;
  443. TCHAR ScratchBuffer [MAX_PATH];
  444. TCHAR DriverPath [MAX_PATH];
  445. TCHAR DevicePath [MAX_PATH];
  446. //
  447. // Sanity checks
  448. //
  449. if (DeviceHandle == NULL) {
  450. return FALSE;
  451. }
  452. try {
  453. GetSystemDirectory (ScratchBuffer, sizeof ScratchBuffer);
  454. _stprintf (DriverPath, "%s\\drivers\\%s.sys", ScratchBuffer, DriverName);
  455. _stprintf (DevicePath, "\\\\.\\%s", DriverName);
  456. //
  457. // Open the service control manager
  458. //
  459. ServiceManager = OpenSCManager (
  460. NULL,
  461. NULL,
  462. SC_MANAGER_ALL_ACCESS);
  463. if (ServiceManager == NULL) {
  464. throw "OpenScManager()";
  465. }
  466. //
  467. // Service should already exist.
  468. //
  469. ServiceHandle = OpenService (
  470. ServiceManager,
  471. DriverName,
  472. SERVICE_ALL_ACCESS);
  473. if (ServiceHandle == NULL) {
  474. throw "OpenService()";
  475. }
  476. //
  477. // Open the device
  478. //
  479. Device = CreateFile (
  480. DevicePath,
  481. GENERIC_READ|GENERIC_WRITE,
  482. 0,
  483. NULL,
  484. OPEN_EXISTING,
  485. FILE_ATTRIBUTE_NORMAL,
  486. NULL);
  487. if (Device == INVALID_HANDLE_VALUE) {
  488. throw "CreateFile()";
  489. }
  490. ReturnValue = TRUE;
  491. }
  492. catch (char * Msg) {
  493. printf("Error: %u: %s\n", GetLastError(), Msg);
  494. fflush (stdout);
  495. ReturnValue = FALSE;
  496. }
  497. //
  498. // Close handles and return.
  499. //
  500. if (ServiceHandle) {
  501. CloseServiceHandle (ServiceHandle);
  502. }
  503. if (ServiceManager) {
  504. CloseServiceHandle (ServiceManager);
  505. }
  506. if (Device != INVALID_HANDLE_VALUE) {
  507. *DeviceHandle = Device;
  508. }
  509. return ReturnValue;
  510. }
  511. bool
  512. TdCloseDevice (
  513. HANDLE Device)
  514. {
  515. if (Device == INVALID_HANDLE_VALUE) {
  516. return false;
  517. }
  518. return CloseHandle(Device);
  519. }
  520. //
  521. // Function:
  522. //
  523. // SendIoctl
  524. //
  525. // Description:
  526. //
  527. // This function sends an ioctl code to the driver.
  528. //
  529. bool
  530. TdSendIoctl (
  531. IN HANDLE Driver,
  532. IN DWORD Ioctl,
  533. IN PVOID pData OPTIONAL,
  534. IN ULONG uDataSize OPTIONAL )
  535. {
  536. DWORD BytesReturned;
  537. BOOL Result;
  538. if (Driver == INVALID_HANDLE_VALUE) {
  539. return false;
  540. }
  541. Result = DeviceIoControl (
  542. Driver,
  543. Ioctl,
  544. pData,
  545. uDataSize,
  546. NULL,
  547. 0,
  548. &BytesReturned,
  549. NULL);
  550. return Result == TRUE;
  551. }
  552. //
  553. //
  554. //
  555. #if _MSC_FULL_VER >= 13008827
  556. #pragma warning(push)
  557. #pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
  558. #endif
  559. DWORD
  560. MapProcessAddressSpaceThread( LPVOID lpData )
  561. {
  562. HANDLE hDevice;
  563. DWORD dwTimeToSleep;
  564. hDevice = (HANDLE)lpData;
  565. while( TRUE )
  566. {
  567. dwTimeToSleep = rand() % 5000;
  568. Sleep( dwTimeToSleep );
  569. TdSendIoctl (hDevice, IOCTL_TD_SECTION_MAP_TEST_PROCESS_SPACE, NULL, 0);
  570. }
  571. return 0;
  572. }
  573. #if _MSC_FULL_VER >= 13008827
  574. #pragma warning(pop)
  575. #endif
  576. //
  577. //
  578. //
  579. #define TD_MAPSECT_TEST_THREADS 4
  580. void TdSectMapProcessAddressSpaceTest()
  581. {
  582. HANDLE Device;
  583. time_t theTime;
  584. int nCrtThread;
  585. DWORD dwThreadId;
  586. TCHAR strMessage[ 128 ];
  587. time( &theTime );
  588. _stprintf(
  589. strMessage,
  590. "Process %u, rand seed = %u\n",
  591. GetCurrentProcessId(),
  592. (unsigned int)theTime );
  593. OutputDebugString( strMessage );
  594. srand( (unsigned int)theTime );
  595. if( TdOpenDevice ("buggy", &Device) )
  596. {
  597. for( nCrtThread = 0; nCrtThread < TD_MAPSECT_TEST_THREADS - 1; nCrtThread++ )
  598. {
  599. CreateThread(
  600. NULL,
  601. 0,
  602. MapProcessAddressSpaceThread,
  603. (LPVOID)Device,
  604. 0,
  605. &dwThreadId );
  606. }
  607. //
  608. // reuse the main thread
  609. //
  610. MapProcessAddressSpaceThread( (LPVOID)Device );
  611. TdCloseDevice (Device);
  612. }
  613. }
  614. //
  615. //
  616. //
  617. #if _MSC_FULL_VER >= 13008827
  618. #pragma warning(push)
  619. #pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
  620. #endif
  621. DWORD
  622. MapSystemAddressSpaceThread( LPVOID lpData )
  623. {
  624. HANDLE hDevice;
  625. DWORD dwTimeToSleep;
  626. hDevice = (HANDLE)lpData;
  627. while( TRUE )
  628. {
  629. dwTimeToSleep = rand() % 5000;
  630. Sleep( dwTimeToSleep );
  631. TdSendIoctl (hDevice, IOCTL_TD_SECTION_MAP_TEST_SYSTEM_SPACE, NULL, 0);
  632. }
  633. return 0;
  634. }
  635. #if _MSC_FULL_VER >= 13008827
  636. #pragma warning(pop)
  637. #endif
  638. //
  639. //
  640. //
  641. void TdSectMapSystemAddressSpaceTest()
  642. {
  643. HANDLE Device;
  644. time_t theTime;
  645. int nCrtThread;
  646. DWORD dwThreadId;
  647. TCHAR strMessage[ 128 ];
  648. time( &theTime );
  649. _stprintf(
  650. strMessage,
  651. "Process %u, rand seed = %u\n",
  652. GetCurrentProcessId(),
  653. (unsigned int)theTime );
  654. OutputDebugString( strMessage );
  655. srand( (unsigned int)theTime );
  656. if( TdOpenDevice ("buggy", &Device) )
  657. {
  658. for( nCrtThread = 0; nCrtThread < TD_MAPSECT_TEST_THREADS - 1; nCrtThread++ )
  659. {
  660. CreateThread(
  661. NULL,
  662. 0,
  663. MapProcessAddressSpaceThread,
  664. (LPVOID)Device,
  665. 0,
  666. &dwThreadId );
  667. }
  668. //
  669. // reuse the main thread - only this thread will map into system address space
  670. //
  671. MapSystemAddressSpaceThread( (LPVOID)Device );
  672. TdCloseDevice (Device);
  673. }
  674. }
  675. //
  676. // Convert a hex string from the command line to an UNLONG_PTR
  677. //
  678. ULONG_PTR
  679. UtilHexStringToUlongPtr( char *szHexNumber )
  680. {
  681. ULONG_PTR uNewDigit;
  682. ULONG_PTR uResult = 0;
  683. char *pCrtChar = szHexNumber;
  684. while( ( *pCrtChar ) != (char)0 )
  685. {
  686. uNewDigit = 0;
  687. if( ( *pCrtChar ) >= '0' && ( *pCrtChar ) <= '9' )
  688. {
  689. uNewDigit = ( *pCrtChar ) - '0';
  690. }
  691. else
  692. {
  693. if( ( *pCrtChar ) >= 'A' && ( *pCrtChar ) <= 'F' )
  694. {
  695. uNewDigit = ( *pCrtChar ) - 'A' + 10;
  696. }
  697. else
  698. {
  699. if( ( *pCrtChar ) >= 'a' && ( *pCrtChar ) <= 'f' )
  700. {
  701. uNewDigit = ( *pCrtChar ) - 'a' + 10;
  702. }
  703. }
  704. }
  705. uResult = uResult * 16 + uNewDigit;
  706. pCrtChar++;
  707. }
  708. return uResult;
  709. }
  710. //
  711. // Set the current reserved size and address as asked by the user
  712. //
  713. VOID
  714. TdReservedMapSetSize(
  715. int argc,
  716. char *argv[] )
  717. {
  718. SIZE_T NewSize;
  719. HANDLE Device;
  720. time_t theTime;
  721. TCHAR strMessage[ 128 ];
  722. if( argc >= 3 )
  723. {
  724. //
  725. // User-specified buffer size
  726. //
  727. NewSize = atoi( argv[ 2 ] );
  728. }
  729. else
  730. {
  731. //
  732. // Seed the random numbers generator
  733. //
  734. time( &theTime );
  735. _stprintf(
  736. strMessage,
  737. "Process %u, rand seed = %u\n",
  738. GetCurrentProcessId(),
  739. (unsigned int)theTime );
  740. OutputDebugString( strMessage );
  741. srand( (unsigned int)theTime );
  742. //
  743. // New size is random, up to 10 pages
  744. //
  745. NewSize = ( abs( rand() ) % 10 + 1 ) * 0x1000;
  746. }
  747. if( TdOpenDevice ("buggy", &Device) )
  748. {
  749. printf( "TdReservedMapSetSize: sending size %p\n",
  750. NewSize );
  751. TdSendIoctl (
  752. Device,
  753. IOCTL_TD_RESERVEDMAP_SET_SIZE,
  754. &NewSize,
  755. sizeof( NewSize ) );
  756. TdCloseDevice (Device);
  757. }
  758. }
  759. //
  760. // Ask for a "read" operation from our driver
  761. //
  762. VOID
  763. TdReservedMapRead( VOID )
  764. {
  765. HANDLE Device;
  766. time_t theTime;
  767. SIZE_T ReadBufferSize;
  768. SIZE_T ReadPages;
  769. SIZE_T CrtReadPage;
  770. PSIZE_T CrtPageAddress;
  771. PVOID UserBuffer;
  772. BOOL Success;
  773. SYSTEM_INFO SystemInfo;
  774. TCHAR strMessage[ 128 ];
  775. //
  776. // Get the page size
  777. //
  778. GetSystemInfo(
  779. &SystemInfo );
  780. //
  781. // Seed the random numbers generator
  782. //
  783. time( &theTime );
  784. _stprintf(
  785. strMessage,
  786. "Process %u, rand seed = %u\n",
  787. GetCurrentProcessId(),
  788. (unsigned int)theTime );
  789. //OutputDebugString( strMessage );
  790. puts( strMessage );
  791. srand( (unsigned int)theTime );
  792. //
  793. // Choose a size >= PAGE_SIZE and <= ~1 Mb
  794. //
  795. ReadBufferSize = abs( rand() * rand() * rand() ) % ( 1024 * 1024 ) + SystemInfo.dwPageSize;
  796. UserBuffer = VirtualAlloc(
  797. NULL,
  798. ReadBufferSize,
  799. MEM_RESERVE | MEM_COMMIT,
  800. PAGE_READWRITE );
  801. if( NULL != UserBuffer )
  802. {
  803. if( TdOpenDevice ("buggy", &Device) )
  804. {
  805. //
  806. // Prepare the parameters to the driver
  807. //
  808. USER_READ_BUFFER UserReadBuffer;
  809. UserReadBuffer.UserBuffer = UserBuffer;
  810. UserReadBuffer.UserBufferSize = ReadBufferSize;
  811. _stprintf(
  812. strMessage,
  813. "TdReservedMapRead: sending buffer %p, size %p\n",
  814. UserReadBuffer.UserBuffer,
  815. UserReadBuffer.UserBufferSize );
  816. //OutputDebugString( strMessage );
  817. puts( strMessage );
  818. //
  819. // Send the request to the driver
  820. //
  821. Success = TdSendIoctl (
  822. Device,
  823. IOCTL_TD_RESERVEDMAP_READ_OP,
  824. &UserReadBuffer,
  825. sizeof( UserReadBuffer ) );
  826. if( TRUE == Success )
  827. {
  828. //
  829. // If the call succeeded then we check the validity of data returned by the driver
  830. //
  831. ReadPages = ReadBufferSize / SystemInfo.dwPageSize;
  832. CrtPageAddress = (PSIZE_T)UserBuffer;
  833. for( CrtReadPage = 1; CrtReadPage <= ReadPages; CrtReadPage++ )
  834. {
  835. if( *CrtPageAddress != CrtReadPage )
  836. {
  837. _stprintf(
  838. strMessage,
  839. "Incorrect data received from buggy.sys: page %p, expected %p, actual data %p\n",
  840. CrtPageAddress,
  841. CrtReadPage,
  842. *CrtPageAddress );
  843. OutputDebugString( strMessage );
  844. DebugBreak();
  845. }
  846. CrtPageAddress = (PSIZE_T) ( (PCHAR)CrtPageAddress + SystemInfo.dwPageSize );
  847. ReadPages -= 1;
  848. }
  849. }
  850. TdCloseDevice (Device);
  851. }
  852. VirtualFree(
  853. UserBuffer,
  854. 0,
  855. MEM_RELEASE );
  856. }
  857. }
  858. //
  859. // End of file
  860. //