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.

2285 lines
42 KiB

  1. /*
  2. * Class:
  3. *
  4. * WmiIoScheduler
  5. *
  6. * Description:
  7. *
  8. * Provides abstraction above heap allocation functions
  9. *
  10. * Version:
  11. *
  12. * Initial
  13. *
  14. * Last Changed:
  15. *
  16. * See Source Depot for change history
  17. *
  18. */
  19. #include <precomp.h>
  20. #include <windows.h>
  21. #include <objbase.h>
  22. #include <stdio.h>
  23. #include <typeinfo.h>
  24. #include <wbemcli.h>
  25. #include <IoScheduler.h>
  26. /******************************************************************************
  27. *
  28. * Name:
  29. *
  30. *
  31. * Description:
  32. *
  33. *
  34. *****************************************************************************/
  35. WmiStatusCode Win32ToApi ( DWORD a_Error )
  36. {
  37. WmiStatusCode t_Status = e_StatusCode_Success ;
  38. switch ( a_Error )
  39. {
  40. case STATUS_NO_MEMORY:
  41. {
  42. t_Status = e_StatusCode_OutOfMemory ;
  43. }
  44. break ;
  45. default:
  46. {
  47. t_Status = e_StatusCode_Unknown ;
  48. }
  49. break ;
  50. }
  51. return t_Status ;
  52. }
  53. /******************************************************************************
  54. *
  55. * Name:
  56. *
  57. *
  58. * Description:
  59. *
  60. *
  61. *****************************************************************************/
  62. WmiStatusCode Win32ToApi ()
  63. {
  64. WmiStatusCode t_Status = e_StatusCode_Success ;
  65. DWORD t_LastError = GetLastError () ;
  66. t_Status = Win32ToApi ( t_LastError ) ;
  67. return t_Status ;
  68. }
  69. /******************************************************************************
  70. *
  71. * Name:
  72. *
  73. *
  74. * Description:
  75. *
  76. *
  77. *****************************************************************************/
  78. HRESULT GetSecurityDescriptor ( SECURITY_DESCRIPTOR &a_SecurityDescriptor , DWORD a_Access )
  79. {
  80. HRESULT t_Result = S_OK ;
  81. BOOL t_BoolResult = InitializeSecurityDescriptor ( & a_SecurityDescriptor , SECURITY_DESCRIPTOR_REVISION ) ;
  82. if ( t_BoolResult )
  83. {
  84. SID_IDENTIFIER_AUTHORITY t_NtAuthoritySid = SECURITY_NT_AUTHORITY ;
  85. PSID t_Administrator_Sid = NULL ;
  86. ACCESS_ALLOWED_ACE *t_Administrator_ACE = NULL ;
  87. WORD t_Administrator_ACESize = 0 ;
  88. BOOL t_BoolResult = AllocateAndInitializeSid (
  89. & t_NtAuthoritySid ,
  90. 2 ,
  91. SECURITY_BUILTIN_DOMAIN_RID,
  92. DOMAIN_ALIAS_RID_ADMINS,
  93. 0,
  94. 0,
  95. 0,
  96. 0,
  97. 0,
  98. 0,
  99. & t_Administrator_Sid
  100. );
  101. if ( t_BoolResult )
  102. {
  103. DWORD t_SidLength = ::GetLengthSid ( t_Administrator_Sid );
  104. t_Administrator_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ;
  105. t_Administrator_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_Administrator_ACESize ] ;
  106. if ( t_Administrator_ACE )
  107. {
  108. CopySid ( t_SidLength, (PSID) & t_Administrator_ACE->SidStart, t_Administrator_Sid ) ;
  109. t_Administrator_ACE->Mask = 0x1F01FF;
  110. t_Administrator_ACE->Header.AceType = 0 ;
  111. t_Administrator_ACE->Header.AceFlags = 3 ;
  112. t_Administrator_ACE->Header.AceSize = t_Administrator_ACESize ;
  113. }
  114. else
  115. {
  116. t_Result = WBEM_E_OUT_OF_MEMORY ;
  117. }
  118. }
  119. else
  120. {
  121. DWORD t_LastError = ::GetLastError();
  122. t_Result = WBEM_E_OUT_OF_MEMORY ;
  123. }
  124. PSID t_System_Sid = NULL ;
  125. ACCESS_ALLOWED_ACE *t_System_ACE = NULL ;
  126. WORD t_System_ACESize = 0 ;
  127. t_BoolResult = AllocateAndInitializeSid (
  128. & t_NtAuthoritySid ,
  129. 1 ,
  130. SECURITY_LOCAL_SYSTEM_RID,
  131. 0,
  132. 0,
  133. 0,
  134. 0,
  135. 0,
  136. 0,
  137. 0,
  138. & t_System_Sid
  139. );
  140. if ( t_BoolResult )
  141. {
  142. DWORD t_SidLength = ::GetLengthSid ( t_System_Sid );
  143. t_System_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ;
  144. t_System_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_System_ACESize ] ;
  145. if ( t_System_ACE )
  146. {
  147. CopySid ( t_SidLength, (PSID) & t_System_ACE->SidStart, t_System_Sid ) ;
  148. t_System_ACE->Mask = 0x1F01FF;
  149. t_System_ACE->Header.AceType = 0 ;
  150. t_System_ACE->Header.AceFlags = 3 ;
  151. t_System_ACE->Header.AceSize = t_System_ACESize ;
  152. }
  153. else
  154. {
  155. t_Result = WBEM_E_OUT_OF_MEMORY ;
  156. }
  157. }
  158. else
  159. {
  160. DWORD t_LastError = ::GetLastError();
  161. t_Result = WBEM_E_OUT_OF_MEMORY ;
  162. }
  163. SID_IDENTIFIER_AUTHORITY t_WorldAuthoritySid = SECURITY_WORLD_SID_AUTHORITY ;
  164. PSID t_Everyone_Sid = NULL ;
  165. ACCESS_ALLOWED_ACE *t_Everyone_ACE = NULL ;
  166. USHORT t_Everyone_ACESize = 0 ;
  167. t_BoolResult = AllocateAndInitializeSid (
  168. & t_WorldAuthoritySid ,
  169. 1 ,
  170. SECURITY_WORLD_RID ,
  171. 0,
  172. 0,
  173. 0,
  174. 0,
  175. 0,
  176. 0,
  177. 0,
  178. & t_Everyone_Sid
  179. );
  180. if ( t_BoolResult )
  181. {
  182. DWORD t_SidLength = ::GetLengthSid ( t_Everyone_Sid );
  183. t_Everyone_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ;
  184. t_Everyone_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_Everyone_ACESize ] ;
  185. if ( t_Everyone_ACE )
  186. {
  187. CopySid ( t_SidLength, (PSID) & t_Everyone_ACE->SidStart, t_Everyone_Sid ) ;
  188. t_Everyone_ACE->Mask = a_Access ;
  189. t_Everyone_ACE->Header.AceType = 0 ;
  190. t_Everyone_ACE->Header.AceFlags = 3 ;
  191. t_Everyone_ACE->Header.AceSize = t_Everyone_ACESize ;
  192. }
  193. else
  194. {
  195. t_Result = WBEM_E_OUT_OF_MEMORY ;
  196. }
  197. }
  198. else
  199. {
  200. DWORD t_LastError = ::GetLastError();
  201. t_Result = WBEM_E_OUT_OF_MEMORY ;
  202. }
  203. // Now we need to set permissions on the registry: Everyone read; Admins full.
  204. // We have the sid for admins from the above code. Now get the sid for "Everyone"
  205. DWORD t_TotalAclSize = sizeof(ACL) + t_Administrator_ACESize + t_System_ACESize + t_Everyone_ACESize ;
  206. PACL t_Dacl = (PACL) new BYTE [ t_TotalAclSize ] ;
  207. if ( t_Dacl )
  208. {
  209. if ( :: InitializeAcl ( t_Dacl, t_TotalAclSize, ACL_REVISION ) )
  210. {
  211. DWORD t_AceIndex = 0 ;
  212. if ( t_System_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_System_ACE , t_System_ACESize ) )
  213. {
  214. t_AceIndex ++ ;
  215. }
  216. if ( t_Administrator_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_Administrator_ACE , t_Administrator_ACESize ) )
  217. {
  218. t_AceIndex ++ ;
  219. }
  220. if ( t_Everyone_ACESize && :: AddAce ( t_Dacl , ACL_REVISION, t_AceIndex , t_Everyone_ACE , t_Everyone_ACESize ) )
  221. {
  222. t_AceIndex ++ ;
  223. }
  224. t_BoolResult = SetSecurityDescriptorDacl (
  225. & a_SecurityDescriptor ,
  226. TRUE ,
  227. t_Dacl ,
  228. FALSE
  229. ) ;
  230. if ( t_BoolResult == FALSE )
  231. {
  232. delete [] ( ( BYTE * ) t_Dacl ) ;
  233. t_Result = WBEM_E_CRITICAL_ERROR ;
  234. }
  235. }
  236. }
  237. else
  238. {
  239. t_Result = WBEM_E_OUT_OF_MEMORY ;
  240. }
  241. if ( t_Administrator_ACE )
  242. {
  243. delete [] ( ( BYTE * ) t_Administrator_ACE ) ;
  244. }
  245. if ( t_System_ACE )
  246. {
  247. delete [] ( ( BYTE * ) t_System_ACE ) ;
  248. }
  249. if ( t_Everyone_ACE )
  250. {
  251. delete [] ( ( BYTE * ) t_Everyone_ACE ) ;
  252. }
  253. if ( t_System_Sid )
  254. {
  255. FreeSid ( t_System_Sid ) ;
  256. }
  257. if ( t_Administrator_Sid )
  258. {
  259. FreeSid ( t_Administrator_Sid ) ;
  260. }
  261. if ( t_Everyone_Sid )
  262. {
  263. FreeSid ( t_Everyone_Sid ) ;
  264. }
  265. }
  266. else
  267. {
  268. t_Result = WBEM_E_CRITICAL_ERROR ;
  269. }
  270. return t_Result ;
  271. }
  272. /******************************************************************************
  273. *
  274. * Name:
  275. *
  276. *
  277. * Description:
  278. *
  279. *
  280. *****************************************************************************/
  281. WmiOverlapped :: WmiOverlapped ( OverLappedType a_Type )
  282. {
  283. ZeroMemory ( & m_Overlapped , sizeof ( m_Overlapped ) ) ;
  284. m_Type = a_Type ;
  285. }
  286. /******************************************************************************
  287. *
  288. * Name:
  289. *
  290. *
  291. * Description:
  292. *
  293. *
  294. *****************************************************************************/
  295. WmiOverlapped :: ~WmiOverlapped ()
  296. {
  297. }
  298. /******************************************************************************
  299. *
  300. * Name:
  301. *
  302. *
  303. * Description:
  304. *
  305. *
  306. *****************************************************************************/
  307. WmiScheduledOverlapped :: WmiScheduledOverlapped (
  308. OverLappedType a_Type ,
  309. WmiIoScheduler &a_Scheduler
  310. ) : WmiOverlapped ( a_Type ) ,
  311. m_Scheduler ( a_Scheduler )
  312. {
  313. m_Scheduler.AddRef () ;
  314. }
  315. /******************************************************************************
  316. *
  317. * Name:
  318. *
  319. *
  320. * Description:
  321. *
  322. *
  323. *****************************************************************************/
  324. WmiScheduledOverlapped :: ~WmiScheduledOverlapped ()
  325. {
  326. m_Scheduler.Release () ;
  327. }
  328. /******************************************************************************
  329. *
  330. * Name:
  331. *
  332. *
  333. * Description:
  334. *
  335. *
  336. *****************************************************************************/
  337. WmiTerminateOverlapped :: WmiTerminateOverlapped () : WmiOverlapped ( e_OverLapped_Terminate )
  338. {
  339. }
  340. /******************************************************************************
  341. *
  342. * Name:
  343. *
  344. *
  345. * Description:
  346. *
  347. *
  348. *****************************************************************************/
  349. WmiTaskOverlapped :: WmiTaskOverlapped (
  350. WmiIoScheduler &a_Scheduler ,
  351. WmiTaskOperation *a_OperationFunction
  352. ) : WmiScheduledOverlapped ( e_OverLapped_Task , a_Scheduler ) ,
  353. m_Status ( 0 ) ,
  354. m_State ( 0 ) ,
  355. m_OperationFunction ( a_OperationFunction )
  356. {
  357. m_Overlapped.Offset = 0 ;
  358. m_Overlapped.OffsetHigh = 0 ;
  359. if ( m_OperationFunction )
  360. {
  361. m_OperationFunction->AddRef () ;
  362. }
  363. }
  364. /******************************************************************************
  365. *
  366. * Name:
  367. *
  368. *
  369. * Description:
  370. *
  371. *
  372. *****************************************************************************/
  373. WmiTaskOverlapped :: ~WmiTaskOverlapped ()
  374. {
  375. if ( m_OperationFunction )
  376. {
  377. m_OperationFunction->Release () ;
  378. }
  379. }
  380. /******************************************************************************
  381. *
  382. * Name:
  383. *
  384. *
  385. * Description:
  386. *
  387. *
  388. *****************************************************************************/
  389. WmiReadOverlapped :: WmiReadOverlapped (
  390. WmiIoScheduler &a_Scheduler ,
  391. WmiFileOperation *a_OperationFunction ,
  392. WmiFileOffSet a_OffSet ,
  393. BYTE *a_Buffer ,
  394. DWORD a_BufferSize
  395. ) : WmiScheduledOverlapped ( e_OverLapped_Read , a_Scheduler ) ,
  396. m_Buffer ( a_Buffer ) ,
  397. m_BufferSize ( a_BufferSize ) ,
  398. m_Status ( 0 ) ,
  399. m_State ( 0 ) ,
  400. m_OperationFunction ( a_OperationFunction )
  401. {
  402. m_Overlapped.Offset = a_OffSet & 0xFFFFFFFF ;
  403. m_Overlapped.OffsetHigh = a_OffSet >> 32 ;
  404. if ( m_OperationFunction )
  405. {
  406. m_OperationFunction->AddRef () ;
  407. }
  408. }
  409. /******************************************************************************
  410. *
  411. * Name:
  412. *
  413. *
  414. * Description:
  415. *
  416. *
  417. *****************************************************************************/
  418. WmiReadOverlapped :: ~WmiReadOverlapped ()
  419. {
  420. if ( m_OperationFunction )
  421. {
  422. m_OperationFunction->Release () ;
  423. }
  424. }
  425. /******************************************************************************
  426. *
  427. * Name:
  428. *
  429. *
  430. * Description:
  431. *
  432. *
  433. *****************************************************************************/
  434. WmiWriteOverlapped :: WmiWriteOverlapped (
  435. WmiIoScheduler &a_Scheduler ,
  436. WmiFileOperation *a_OperationFunction ,
  437. WmiFileOffSet a_OffSet ,
  438. BYTE *a_Buffer ,
  439. DWORD a_BufferSize
  440. ) : WmiScheduledOverlapped ( e_OverLapped_Write , a_Scheduler ) ,
  441. m_Buffer ( a_Buffer ) ,
  442. m_BufferSize ( a_BufferSize ) ,
  443. m_Status ( 0 ) ,
  444. m_State ( 0 ) ,
  445. m_OperationFunction ( a_OperationFunction )
  446. {
  447. m_Overlapped.Offset = a_OffSet & 0xFFFFFFFF ;
  448. m_Overlapped.OffsetHigh = a_OffSet >> 32 ;
  449. if ( m_OperationFunction )
  450. {
  451. m_OperationFunction->AddRef () ;
  452. }
  453. }
  454. /******************************************************************************
  455. *
  456. * Name:
  457. *
  458. *
  459. * Description:
  460. *
  461. *
  462. *****************************************************************************/
  463. WmiWriteOverlapped :: ~WmiWriteOverlapped ()
  464. {
  465. if ( m_OperationFunction )
  466. {
  467. m_OperationFunction->Release () ;
  468. }
  469. }
  470. /******************************************************************************
  471. *
  472. * Name:
  473. *
  474. *
  475. * Description:
  476. *
  477. *
  478. *****************************************************************************/
  479. WmiLockOverlapped :: WmiLockOverlapped (
  480. WmiIoScheduler &a_Scheduler ,
  481. WmiFileOperation *a_OperationFunction ,
  482. WmiFileOffSet a_OffSet ,
  483. WmiFileOffSet a_OffSetSize
  484. ) : WmiScheduledOverlapped ( e_OverLapped_Lock , a_Scheduler ) ,
  485. m_OffSetSize ( a_OffSetSize ) ,
  486. m_Status ( 0 ) ,
  487. m_State ( 0 ) ,
  488. m_OperationFunction ( a_OperationFunction )
  489. {
  490. m_Overlapped.Offset = a_OffSet & 0xFFFFFFFF ;
  491. m_Overlapped.OffsetHigh = a_OffSet >> 32 ;
  492. if ( m_OperationFunction )
  493. {
  494. m_OperationFunction->AddRef () ;
  495. }
  496. }
  497. /******************************************************************************
  498. *
  499. * Name:
  500. *
  501. *
  502. * Description:
  503. *
  504. *
  505. *****************************************************************************/
  506. WmiLockOverlapped :: ~WmiLockOverlapped ()
  507. {
  508. if ( m_OperationFunction )
  509. {
  510. m_OperationFunction->Release () ;
  511. }
  512. }
  513. /******************************************************************************
  514. *
  515. * Name:
  516. *
  517. *
  518. * Description:
  519. *
  520. *
  521. *****************************************************************************/
  522. WmiUnLockOverlapped :: WmiUnLockOverlapped (
  523. WmiIoScheduler &a_Scheduler ,
  524. WmiFileOperation *a_OperationFunction ,
  525. WmiFileOffSet a_OffSet ,
  526. WmiFileOffSet a_OffSetSize
  527. ) : WmiScheduledOverlapped ( e_OverLapped_UnLock , a_Scheduler ) ,
  528. m_OffSetSize ( a_OffSetSize ) ,
  529. m_Status ( 0 ) ,
  530. m_State ( 0 ) ,
  531. m_OperationFunction ( a_OperationFunction )
  532. {
  533. m_Overlapped.Offset = a_OffSet & 0xFFFFFFFF ;
  534. m_Overlapped.OffsetHigh = a_OffSet >> 32 ;
  535. if ( m_OperationFunction )
  536. {
  537. m_OperationFunction->AddRef () ;
  538. }
  539. }
  540. /******************************************************************************
  541. *
  542. * Name:
  543. *
  544. *
  545. * Description:
  546. *
  547. *
  548. *****************************************************************************/
  549. WmiUnLockOverlapped :: ~WmiUnLockOverlapped ()
  550. {
  551. if ( m_OperationFunction )
  552. {
  553. m_OperationFunction->Release () ;
  554. }
  555. }
  556. /******************************************************************************
  557. *
  558. * Name:
  559. *
  560. *
  561. * Description:
  562. *
  563. *
  564. *****************************************************************************/
  565. WmiCompletionPortOperation :: WmiCompletionPortOperation (
  566. WmiAllocator &a_Allocator ,
  567. WmiThreadPool *a_ThreadPool
  568. ) : WmiTask <ULONG> ( a_Allocator ) ,
  569. m_ThreadPool ( a_ThreadPool )
  570. {
  571. if ( m_ThreadPool )
  572. {
  573. m_ThreadPool->AddRef () ;
  574. }
  575. }
  576. /******************************************************************************
  577. *
  578. * Name:
  579. *
  580. *
  581. * Description:
  582. *
  583. *
  584. *****************************************************************************/
  585. WmiCompletionPortOperation :: ~WmiCompletionPortOperation ()
  586. {
  587. if ( m_ThreadPool )
  588. {
  589. m_ThreadPool->Release () ;
  590. }
  591. }
  592. /******************************************************************************
  593. *
  594. * Name:
  595. *
  596. *
  597. * Description:
  598. *
  599. *
  600. *****************************************************************************/
  601. WmiStatusCode WmiCompletionPortOperation :: Process ( WmiThread <ULONG> &a_Thread )
  602. {
  603. DWORD t_Continue = TRUE ;
  604. while ( t_Continue )
  605. {
  606. OVERLAPPED *t_Overlapped = NULL ;
  607. DWORD t_Key = 0 ;
  608. DWORD t_Bytes = 0 ;
  609. BOOL t_Status = GetQueuedCompletionStatus (
  610. m_ThreadPool->GetCompletionPort () ,
  611. & t_Bytes ,
  612. & t_Key ,
  613. & t_Overlapped ,
  614. INFINITE
  615. ) ;
  616. if ( t_Status )
  617. {
  618. WmiOverlapped *t_WmiOverlapped = ( WmiOverlapped * ) t_Overlapped ;
  619. switch ( t_WmiOverlapped->GetType () )
  620. {
  621. case WmiOverlapped :: OverLappedType :: e_OverLapped_Terminate:
  622. {
  623. WmiTerminateOverlapped *t_TerminateOverlapped = ( WmiTerminateOverlapped * ) t_Overlapped ;
  624. delete t_TerminateOverlapped ;
  625. t_Continue = FALSE ;
  626. }
  627. break ;
  628. case WmiOverlapped :: OverLappedType :: e_OverLapped_Task:
  629. {
  630. WmiTaskOverlapped *t_TaskOverlapped = ( WmiTaskOverlapped * ) t_Overlapped ;
  631. WmiIoScheduler &t_Allocator = t_TaskOverlapped->GetScheduler () ;
  632. t_Allocator.TaskBegin ( t_TaskOverlapped ) ;
  633. }
  634. break ;
  635. case WmiOverlapped :: OverLappedType :: e_OverLapped_Read:
  636. {
  637. WmiReadOverlapped *t_ReadOverlapped = ( WmiReadOverlapped * ) t_Overlapped ;
  638. WmiIoScheduler &t_Allocator = t_ReadOverlapped->GetScheduler () ;
  639. switch ( t_ReadOverlapped->GetState () )
  640. {
  641. case 0:
  642. {
  643. t_Allocator.ReadBegin ( t_ReadOverlapped , t_Bytes ) ;
  644. }
  645. break ;
  646. case 1:
  647. {
  648. t_Allocator.ReadComplete ( t_ReadOverlapped , t_Bytes ) ;
  649. }
  650. default:
  651. {
  652. }
  653. break ;
  654. }
  655. }
  656. break ;
  657. case WmiOverlapped :: OverLappedType :: e_OverLapped_Lock:
  658. {
  659. WmiLockOverlapped *t_LockOverlapped = ( WmiLockOverlapped * ) t_Overlapped ;
  660. WmiIoScheduler &t_Allocator = t_LockOverlapped->GetScheduler () ;
  661. switch ( t_LockOverlapped->GetState () )
  662. {
  663. case 0:
  664. {
  665. t_Allocator.LockBegin ( t_LockOverlapped , t_Bytes ) ;
  666. }
  667. break ;
  668. case 1:
  669. {
  670. t_Allocator.LockComplete ( t_LockOverlapped , t_Bytes ) ;
  671. }
  672. default:
  673. {
  674. }
  675. break ;
  676. }
  677. }
  678. break ;
  679. case WmiOverlapped :: OverLappedType :: e_OverLapped_UnLock:
  680. {
  681. WmiUnLockOverlapped *t_UnLockOverlapped = ( WmiUnLockOverlapped * ) t_Overlapped ;
  682. WmiIoScheduler &t_Allocator = t_UnLockOverlapped->GetScheduler () ;
  683. switch ( t_UnLockOverlapped->GetState () )
  684. {
  685. case 0:
  686. {
  687. t_Allocator.UnLockBegin ( t_UnLockOverlapped , t_Bytes ) ;
  688. }
  689. break ;
  690. case 1:
  691. {
  692. t_Allocator.UnLockComplete ( t_UnLockOverlapped , t_Bytes ) ;
  693. }
  694. default:
  695. {
  696. }
  697. break ;
  698. }
  699. }
  700. break ;
  701. case WmiOverlapped :: OverLappedType :: e_OverLapped_Write:
  702. {
  703. WmiWriteOverlapped *t_WriteOverlapped = ( WmiWriteOverlapped * ) t_Overlapped ;
  704. WmiIoScheduler &t_Allocator = t_WriteOverlapped->GetScheduler () ;
  705. switch ( t_WriteOverlapped->GetState () )
  706. {
  707. case 0:
  708. {
  709. t_Allocator.WriteBegin ( t_WriteOverlapped , t_Bytes ) ;
  710. }
  711. break ;
  712. case 1:
  713. {
  714. t_Allocator.WriteComplete ( t_WriteOverlapped , t_Bytes ) ;
  715. }
  716. default:
  717. {
  718. }
  719. break ;
  720. }
  721. }
  722. break ;
  723. default:
  724. {
  725. t_Continue = FALSE ;
  726. }
  727. break ;
  728. }
  729. }
  730. else
  731. {
  732. DWORD t_LastError = GetLastError () ;
  733. if ( t_Overlapped == NULL )
  734. {
  735. break ;
  736. }
  737. }
  738. }
  739. Complete () ;
  740. return e_StatusCode_Success ;
  741. }
  742. /******************************************************************************
  743. *
  744. * Name:
  745. *
  746. *
  747. * Description:
  748. *
  749. *
  750. *****************************************************************************/
  751. WmiThreadPool :: WmiThreadPool (
  752. WmiAllocator &a_Allocator ,
  753. const ULONG &a_Threads
  754. ) : m_Allocator ( a_Allocator ) ,
  755. m_ReferenceCount ( 0 ) ,
  756. m_ThreadPool ( NULL ) ,
  757. m_CompletionPort ( NULL )
  758. {
  759. if ( a_Threads == 0 )
  760. {
  761. SYSTEM_INFO t_SystemInformation ;
  762. GetSystemInfo ( & t_SystemInformation ) ;
  763. m_Threads = t_SystemInformation.dwNumberOfProcessors ;
  764. }
  765. else
  766. {
  767. m_Threads = a_Threads ;
  768. }
  769. }
  770. /******************************************************************************
  771. *
  772. * Name:
  773. *
  774. *
  775. * Description:
  776. *
  777. *
  778. *****************************************************************************/
  779. WmiThreadPool :: ~WmiThreadPool ()
  780. {
  781. UnInitialize () ;
  782. }
  783. /******************************************************************************
  784. *
  785. * Name:
  786. *
  787. *
  788. * Description:
  789. *
  790. *
  791. *****************************************************************************/
  792. ULONG WmiThreadPool :: AddRef ()
  793. {
  794. return InterlockedIncrement ( & m_ReferenceCount ) ;
  795. }
  796. /******************************************************************************
  797. *
  798. * Name:
  799. *
  800. *
  801. * Description:
  802. *
  803. *
  804. *****************************************************************************/
  805. ULONG WmiThreadPool :: Release ()
  806. {
  807. ULONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
  808. if ( t_ReferenceCount == 0 )
  809. {
  810. delete this ;
  811. }
  812. return t_ReferenceCount ;
  813. }
  814. /******************************************************************************
  815. *
  816. * Name:
  817. *
  818. *
  819. * Description:
  820. *
  821. *
  822. *****************************************************************************/
  823. WmiStatusCode WmiThreadPool :: Initialize ()
  824. {
  825. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  826. t_StatusCode = WmiThread <ULONG> :: Static_Initialize ( m_Allocator ) ;
  827. if ( t_StatusCode == e_StatusCode_Success )
  828. {
  829. m_CompletionPort = CreateIoCompletionPort (
  830. INVALID_HANDLE_VALUE ,
  831. NULL ,
  832. NULL ,
  833. 0
  834. ) ;
  835. if ( m_CompletionPort == NULL )
  836. {
  837. t_StatusCode = e_StatusCode_OutOfResources ;
  838. }
  839. if ( t_StatusCode == e_StatusCode_Success )
  840. {
  841. m_ThreadPool = new WmiThread <ULONG> * [ m_Threads ] ;
  842. if ( m_ThreadPool )
  843. {
  844. for ( ULONG t_Index = 0 ; t_Index < m_Threads ; t_Index ++ )
  845. {
  846. m_ThreadPool [ t_Index ] = new WmiThread <ULONG> ( m_Allocator ) ;
  847. if ( m_ThreadPool [ t_Index ] )
  848. {
  849. m_ThreadPool [ t_Index ]->AddRef () ;
  850. t_StatusCode = m_ThreadPool [ t_Index ]->Initialize () ;
  851. if ( t_StatusCode == e_StatusCode_Success )
  852. {
  853. WmiCompletionPortOperation *t_Operation = new WmiCompletionPortOperation (
  854. m_Allocator ,
  855. this
  856. ) ;
  857. if ( t_Operation )
  858. {
  859. t_StatusCode = t_Operation->Initialize () ;
  860. if ( t_StatusCode == e_StatusCode_Success )
  861. {
  862. m_ThreadPool [ t_Index ]->EnQueue ( 0 , *t_Operation ) ;
  863. }
  864. }
  865. }
  866. }
  867. else
  868. {
  869. t_StatusCode = e_StatusCode_OutOfMemory ;
  870. }
  871. }
  872. }
  873. else
  874. {
  875. t_StatusCode = e_StatusCode_OutOfMemory ;
  876. }
  877. }
  878. }
  879. return t_StatusCode ;
  880. }
  881. /******************************************************************************
  882. *
  883. * Name:
  884. *
  885. *
  886. * Description:
  887. *
  888. *
  889. *****************************************************************************/
  890. WmiStatusCode WmiThreadPool :: UnInitialize ()
  891. {
  892. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  893. if ( m_ThreadPool )
  894. {
  895. for ( ULONG t_Index = 0 ; t_Index < m_Threads ; t_Index ++ )
  896. {
  897. if ( m_ThreadPool [ t_Index ] )
  898. {
  899. WmiTerminateOverlapped *t_Terminate = new WmiTerminateOverlapped ;
  900. if ( t_Terminate )
  901. {
  902. BOOL t_Status = PostQueuedCompletionStatus (
  903. GetCompletionPort () ,
  904. 0 ,
  905. NULL ,
  906. ( OVERLAPPED * ) t_Terminate
  907. ) ;
  908. if ( t_Status )
  909. {
  910. HANDLE t_ThreadHandle = NULL ;
  911. BOOL t_Status = DuplicateHandle (
  912. GetCurrentProcess () ,
  913. m_ThreadPool [ t_Index ]->GetHandle () ,
  914. GetCurrentProcess () ,
  915. & t_ThreadHandle,
  916. 0 ,
  917. FALSE ,
  918. DUPLICATE_SAME_ACCESS
  919. ) ;
  920. m_ThreadPool [ t_Index ]->Release () ;
  921. WaitForSingleObject ( t_ThreadHandle , INFINITE ) ;
  922. CloseHandle ( t_ThreadHandle ) ;
  923. }
  924. else
  925. {
  926. t_StatusCode = e_StatusCode_Failed ;
  927. }
  928. }
  929. }
  930. }
  931. delete [] m_ThreadPool ;
  932. m_ThreadPool = NULL ;
  933. }
  934. if ( m_CompletionPort )
  935. {
  936. CloseHandle ( m_CompletionPort ) ;
  937. }
  938. return t_StatusCode ;
  939. }
  940. /******************************************************************************
  941. *
  942. * Name:
  943. *
  944. *
  945. * Description:
  946. *
  947. *
  948. *****************************************************************************/
  949. WmiIoScheduler :: WmiIoScheduler (
  950. WmiAllocator &a_Allocator ,
  951. WmiThreadPool *a_ThreadPool ,
  952. wchar_t *a_FileName ,
  953. WmiFileSize a_InitialSize ,
  954. WmiFileSize a_MaximumSize
  955. ) : m_Allocator ( a_Allocator ) ,
  956. m_InitialSize ( a_InitialSize ) ,
  957. m_MaximumSize ( a_MaximumSize ) ,
  958. m_ReferenceCount ( 0 ) ,
  959. m_ThreadPool ( a_ThreadPool ) ,
  960. m_FileHandle ( NULL ) ,
  961. m_FileName ( NULL )
  962. {
  963. m_FileName = new wchar_t [ wcslen ( a_FileName ) + 1 ] ;
  964. if ( m_FileName )
  965. {
  966. wcscpy ( m_FileName , a_FileName ) ;
  967. }
  968. if ( m_ThreadPool )
  969. {
  970. m_ThreadPool->AddRef () ;
  971. }
  972. }
  973. /******************************************************************************
  974. *
  975. * Name:
  976. *
  977. *
  978. * Description:
  979. *
  980. *
  981. *****************************************************************************/
  982. WmiIoScheduler :: ~WmiIoScheduler ()
  983. {
  984. UnInitialize () ;
  985. }
  986. /******************************************************************************
  987. *
  988. * Name:
  989. *
  990. *
  991. * Description:
  992. *
  993. *
  994. *****************************************************************************/
  995. ULONG WmiIoScheduler :: AddRef ()
  996. {
  997. return InterlockedIncrement ( & m_ReferenceCount ) ;
  998. }
  999. /******************************************************************************
  1000. *
  1001. * Name:
  1002. *
  1003. *
  1004. * Description:
  1005. *
  1006. *
  1007. *****************************************************************************/
  1008. ULONG WmiIoScheduler :: Release ()
  1009. {
  1010. ULONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
  1011. if ( t_ReferenceCount == 0 )
  1012. {
  1013. delete this ;
  1014. }
  1015. return t_ReferenceCount ;
  1016. }
  1017. /******************************************************************************
  1018. *
  1019. * Name:
  1020. *
  1021. *
  1022. * Description:
  1023. *
  1024. *
  1025. *****************************************************************************/
  1026. WmiStatusCode WmiIoScheduler :: Initialize ()
  1027. {
  1028. WmiStatusCode t_StatusCode = Create () ;
  1029. if ( t_StatusCode == e_StatusCode_Success )
  1030. {
  1031. HANDLE t_CompletionPort = CreateIoCompletionPort (
  1032. m_FileHandle ,
  1033. m_ThreadPool->GetCompletionPort () ,
  1034. ( ULONG_PTR ) this ,
  1035. 0
  1036. ) ;
  1037. if ( t_CompletionPort != INVALID_HANDLE_VALUE )
  1038. {
  1039. }
  1040. else
  1041. {
  1042. t_StatusCode = Win32ToApi () ;
  1043. }
  1044. }
  1045. return t_StatusCode ;
  1046. }
  1047. /******************************************************************************
  1048. *
  1049. * Name:
  1050. *
  1051. *
  1052. * Description:
  1053. *
  1054. *
  1055. *****************************************************************************/
  1056. WmiStatusCode WmiIoScheduler :: UnInitialize ()
  1057. {
  1058. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1059. if ( m_FileName )
  1060. {
  1061. delete [] m_FileName ;
  1062. m_FileName = NULL ;
  1063. }
  1064. t_StatusCode = Close () ;
  1065. if ( m_ThreadPool )
  1066. {
  1067. m_ThreadPool->Release () ;
  1068. m_ThreadPool = NULL ;
  1069. }
  1070. return t_StatusCode ;
  1071. }
  1072. /******************************************************************************
  1073. *
  1074. * Name:
  1075. *
  1076. *
  1077. * Description:
  1078. *
  1079. *
  1080. *****************************************************************************/
  1081. WmiStatusCode WmiIoScheduler :: Task (
  1082. WmiTaskOperation *a_OperationFunction
  1083. )
  1084. {
  1085. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1086. WmiTaskOverlapped *t_Overlapped = new WmiTaskOverlapped (
  1087. *this ,
  1088. a_OperationFunction
  1089. ) ;
  1090. if ( t_Overlapped )
  1091. {
  1092. BOOL t_Status = PostQueuedCompletionStatus (
  1093. m_ThreadPool->GetCompletionPort () ,
  1094. 0 ,
  1095. ( ULONG_PTR ) this ,
  1096. ( OVERLAPPED * ) t_Overlapped
  1097. ) ;
  1098. if ( t_Status == FALSE )
  1099. {
  1100. t_StatusCode = Win32ToApi () ;
  1101. }
  1102. }
  1103. else
  1104. {
  1105. t_StatusCode = e_StatusCode_OutOfMemory ;
  1106. }
  1107. return t_StatusCode ;
  1108. }
  1109. /******************************************************************************
  1110. *
  1111. * Name:
  1112. *
  1113. *
  1114. * Description:
  1115. *
  1116. *
  1117. *****************************************************************************/
  1118. WmiStatusCode WmiIoScheduler :: Read (
  1119. WmiFileOperation *a_OperationFunction ,
  1120. WmiFileOffSet a_OffSet ,
  1121. BYTE *a_ReadBytes ,
  1122. DWORD a_Bytes
  1123. )
  1124. {
  1125. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1126. WmiReadOverlapped *t_Overlapped = new WmiReadOverlapped (
  1127. *this ,
  1128. a_OperationFunction ,
  1129. a_OffSet ,
  1130. a_ReadBytes ,
  1131. a_Bytes
  1132. ) ;
  1133. if ( t_Overlapped )
  1134. {
  1135. BOOL t_Status = PostQueuedCompletionStatus (
  1136. m_ThreadPool->GetCompletionPort () ,
  1137. a_Bytes ,
  1138. ( ULONG_PTR ) this ,
  1139. ( OVERLAPPED * ) t_Overlapped
  1140. ) ;
  1141. if ( t_Status == FALSE )
  1142. {
  1143. t_StatusCode = Win32ToApi () ;
  1144. }
  1145. }
  1146. else
  1147. {
  1148. t_StatusCode = e_StatusCode_OutOfMemory ;
  1149. }
  1150. return t_StatusCode ;
  1151. }
  1152. /******************************************************************************
  1153. *
  1154. * Name:
  1155. *
  1156. *
  1157. * Description:
  1158. *
  1159. *
  1160. *****************************************************************************/
  1161. WmiStatusCode WmiIoScheduler :: Write (
  1162. WmiFileOperation *a_OperationFunction ,
  1163. WmiFileOffSet a_OffSet ,
  1164. BYTE *a_WriteBytes ,
  1165. DWORD a_Bytes
  1166. )
  1167. {
  1168. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1169. WmiWriteOverlapped *t_Overlapped = new WmiWriteOverlapped (
  1170. *this ,
  1171. a_OperationFunction ,
  1172. a_OffSet ,
  1173. a_WriteBytes ,
  1174. a_Bytes
  1175. ) ;
  1176. if ( t_Overlapped )
  1177. {
  1178. BOOL t_Status = PostQueuedCompletionStatus (
  1179. m_ThreadPool->GetCompletionPort () ,
  1180. a_Bytes ,
  1181. ( ULONG_PTR ) this ,
  1182. ( OVERLAPPED * ) t_Overlapped
  1183. ) ;
  1184. if ( t_Status == FALSE )
  1185. {
  1186. t_StatusCode = Win32ToApi () ;
  1187. }
  1188. }
  1189. else
  1190. {
  1191. t_StatusCode = e_StatusCode_OutOfMemory ;
  1192. }
  1193. return t_StatusCode ;
  1194. }
  1195. /******************************************************************************
  1196. *
  1197. * Name:
  1198. *
  1199. *
  1200. * Description:
  1201. *
  1202. *
  1203. *****************************************************************************/
  1204. WmiStatusCode WmiIoScheduler :: Lock (
  1205. WmiFileOperation *a_OperationFunction ,
  1206. WmiFileOffSet a_OffSet ,
  1207. WmiFileOffSet a_OffSetSize
  1208. )
  1209. {
  1210. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1211. WmiLockOverlapped *t_Overlapped = new WmiLockOverlapped (
  1212. *this ,
  1213. a_OperationFunction ,
  1214. a_OffSet ,
  1215. a_OffSetSize
  1216. ) ;
  1217. if ( t_Overlapped )
  1218. {
  1219. BOOL t_Status = PostQueuedCompletionStatus (
  1220. m_ThreadPool->GetCompletionPort () ,
  1221. 0 ,
  1222. ( ULONG_PTR ) this ,
  1223. ( OVERLAPPED * ) t_Overlapped
  1224. ) ;
  1225. if ( t_Status == FALSE )
  1226. {
  1227. t_StatusCode = Win32ToApi () ;
  1228. }
  1229. }
  1230. else
  1231. {
  1232. t_StatusCode = e_StatusCode_OutOfMemory ;
  1233. }
  1234. return t_StatusCode ;
  1235. }
  1236. /******************************************************************************
  1237. *
  1238. * Name:
  1239. *
  1240. *
  1241. * Description:
  1242. *
  1243. *
  1244. *****************************************************************************/
  1245. WmiStatusCode WmiIoScheduler :: UnLock (
  1246. WmiFileOperation *a_OperationFunction ,
  1247. WmiFileOffSet a_OffSet ,
  1248. WmiFileOffSet a_OffSetSize
  1249. )
  1250. {
  1251. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1252. WmiUnLockOverlapped *t_Overlapped = new WmiUnLockOverlapped (
  1253. *this ,
  1254. a_OperationFunction ,
  1255. a_OffSet ,
  1256. a_OffSetSize
  1257. ) ;
  1258. if ( t_Overlapped )
  1259. {
  1260. BOOL t_Status = PostQueuedCompletionStatus (
  1261. m_ThreadPool->GetCompletionPort () ,
  1262. 0 ,
  1263. ( ULONG_PTR ) this ,
  1264. ( OVERLAPPED * ) t_Overlapped
  1265. ) ;
  1266. if ( t_Status == FALSE )
  1267. {
  1268. t_StatusCode = Win32ToApi () ;
  1269. }
  1270. }
  1271. else
  1272. {
  1273. t_StatusCode = e_StatusCode_OutOfMemory ;
  1274. }
  1275. return t_StatusCode ;
  1276. }
  1277. /******************************************************************************
  1278. *
  1279. * Name:
  1280. *
  1281. *
  1282. * Description:
  1283. *
  1284. *
  1285. *****************************************************************************/
  1286. WmiStatusCode WmiIoScheduler :: ReadOnThread (
  1287. WmiFileOperation *a_OperationFunction ,
  1288. WmiFileOffSet a_OffSet ,
  1289. BYTE *a_ReadBytes ,
  1290. DWORD a_Bytes
  1291. )
  1292. {
  1293. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1294. WmiReadOverlapped *t_Overlapped = new WmiReadOverlapped (
  1295. *this ,
  1296. a_OperationFunction ,
  1297. a_OffSet ,
  1298. a_ReadBytes ,
  1299. a_Bytes
  1300. ) ;
  1301. if ( t_Overlapped )
  1302. {
  1303. t_Overlapped->SetState ( 1 ) ;
  1304. t_StatusCode = ReadBegin (
  1305. t_Overlapped ,
  1306. 0
  1307. ) ;
  1308. }
  1309. else
  1310. {
  1311. t_StatusCode = e_StatusCode_OutOfMemory ;
  1312. }
  1313. return t_StatusCode ;
  1314. }
  1315. /******************************************************************************
  1316. *
  1317. * Name:
  1318. *
  1319. *
  1320. * Description:
  1321. *
  1322. *
  1323. *****************************************************************************/
  1324. WmiStatusCode WmiIoScheduler :: WriteOnThread (
  1325. WmiFileOperation *a_OperationFunction ,
  1326. WmiFileOffSet a_OffSet ,
  1327. BYTE *a_WriteBytes ,
  1328. DWORD a_Bytes
  1329. )
  1330. {
  1331. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1332. WmiWriteOverlapped *t_Overlapped = new WmiWriteOverlapped (
  1333. *this ,
  1334. a_OperationFunction ,
  1335. a_OffSet ,
  1336. a_WriteBytes ,
  1337. a_Bytes
  1338. ) ;
  1339. if ( t_Overlapped )
  1340. {
  1341. t_Overlapped->SetState ( 1 ) ;
  1342. t_StatusCode = WriteBegin (
  1343. t_Overlapped ,
  1344. 0
  1345. ) ;
  1346. }
  1347. else
  1348. {
  1349. t_StatusCode = e_StatusCode_OutOfMemory ;
  1350. }
  1351. return t_StatusCode ;
  1352. }
  1353. /******************************************************************************
  1354. *
  1355. * Name:
  1356. *
  1357. *
  1358. * Description:
  1359. *
  1360. *
  1361. *****************************************************************************/
  1362. WmiStatusCode WmiIoScheduler :: LockOnThread (
  1363. WmiFileOperation *a_OperationFunction ,
  1364. WmiFileOffSet a_OffSet ,
  1365. WmiFileOffSet a_OffSetSize
  1366. )
  1367. {
  1368. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1369. WmiLockOverlapped *t_Overlapped = new WmiLockOverlapped (
  1370. *this ,
  1371. a_OperationFunction ,
  1372. a_OffSet ,
  1373. a_OffSetSize
  1374. ) ;
  1375. if ( t_Overlapped )
  1376. {
  1377. t_Overlapped->SetState ( 1 ) ;
  1378. t_StatusCode = LockBegin (
  1379. t_Overlapped ,
  1380. 0
  1381. ) ;
  1382. }
  1383. else
  1384. {
  1385. t_StatusCode = e_StatusCode_OutOfMemory ;
  1386. }
  1387. return t_StatusCode ;
  1388. }
  1389. /******************************************************************************
  1390. *
  1391. * Name:
  1392. *
  1393. *
  1394. * Description:
  1395. *
  1396. *
  1397. *****************************************************************************/
  1398. WmiStatusCode WmiIoScheduler :: TaskBegin (
  1399. WmiTaskOverlapped *a_Overlapped
  1400. )
  1401. {
  1402. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1403. a_Overlapped->SetState ( 1 ) ;
  1404. a_Overlapped->GetOperationFunction ()->Operation (
  1405. t_StatusCode
  1406. ) ;
  1407. return t_StatusCode ;
  1408. }
  1409. /******************************************************************************
  1410. *
  1411. * Name
  1412. *
  1413. *
  1414. * Description:
  1415. *
  1416. *
  1417. *****************************************************************************/
  1418. WmiStatusCode WmiIoScheduler :: UnLockOnThread (
  1419. WmiFileOperation *a_OperationFunction ,
  1420. WmiFileOffSet a_OffSet ,
  1421. WmiFileOffSet a_OffSetSize
  1422. )
  1423. {
  1424. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1425. WmiUnLockOverlapped *t_Overlapped = new WmiUnLockOverlapped (
  1426. *this ,
  1427. a_OperationFunction ,
  1428. a_OffSet ,
  1429. a_OffSetSize
  1430. ) ;
  1431. if ( t_Overlapped )
  1432. {
  1433. t_Overlapped->SetState ( 1 ) ;
  1434. t_StatusCode = UnLockBegin (
  1435. t_Overlapped ,
  1436. 0
  1437. ) ;
  1438. }
  1439. else
  1440. {
  1441. t_StatusCode = e_StatusCode_OutOfMemory ;
  1442. }
  1443. return t_StatusCode ;
  1444. }
  1445. /******************************************************************************
  1446. *
  1447. * Name:
  1448. *
  1449. *
  1450. * Description:
  1451. *
  1452. *
  1453. *****************************************************************************/
  1454. WmiStatusCode WmiIoScheduler :: ReadBegin (
  1455. WmiReadOverlapped *a_Overlapped ,
  1456. DWORD a_Bytes
  1457. )
  1458. {
  1459. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1460. a_Overlapped->SetState ( 1 ) ;
  1461. DWORD t_Bytes = 0 ;
  1462. t_StatusCode = Read (
  1463. a_Overlapped->GetBuffer () ,
  1464. a_Overlapped->GetBufferSize () ,
  1465. & t_Bytes ,
  1466. ( OVERLAPPED * ) a_Overlapped
  1467. ) ;
  1468. if ( t_StatusCode == e_StatusCode_Success )
  1469. {
  1470. }
  1471. else
  1472. {
  1473. a_Overlapped->GetOperationFunction ()->Operation (
  1474. t_StatusCode ,
  1475. a_Overlapped->GetBuffer () ,
  1476. a_Overlapped->GetBufferSize ()
  1477. ) ;
  1478. }
  1479. return t_StatusCode ;
  1480. }
  1481. /******************************************************************************
  1482. *
  1483. * Name:
  1484. *
  1485. *
  1486. * Description:
  1487. *
  1488. *
  1489. *****************************************************************************/
  1490. WmiStatusCode WmiIoScheduler :: WriteBegin (
  1491. WmiWriteOverlapped *a_Overlapped ,
  1492. DWORD a_Bytes
  1493. )
  1494. {
  1495. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1496. a_Overlapped->SetState ( 1 ) ;
  1497. DWORD t_Bytes = 0 ;
  1498. t_StatusCode = Write (
  1499. a_Overlapped->GetBuffer () ,
  1500. a_Overlapped->GetBufferSize () ,
  1501. & t_Bytes ,
  1502. ( OVERLAPPED * ) a_Overlapped
  1503. ) ;
  1504. if ( t_StatusCode == e_StatusCode_Success )
  1505. {
  1506. }
  1507. else
  1508. {
  1509. a_Overlapped->GetOperationFunction ()->Operation (
  1510. t_StatusCode ,
  1511. a_Overlapped->GetBuffer () ,
  1512. a_Overlapped->GetBufferSize ()
  1513. ) ;
  1514. }
  1515. return t_StatusCode ;
  1516. }
  1517. /******************************************************************************
  1518. *
  1519. * Name:
  1520. *
  1521. *
  1522. * Description:
  1523. *
  1524. *
  1525. *****************************************************************************/
  1526. WmiStatusCode WmiIoScheduler :: LockBegin (
  1527. WmiLockOverlapped *a_Overlapped ,
  1528. DWORD a_Bytes
  1529. )
  1530. {
  1531. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1532. a_Overlapped->SetState ( 1 ) ;
  1533. t_StatusCode = Lock (
  1534. LOCKFILE_EXCLUSIVE_LOCK ,
  1535. a_Overlapped->GetOffSetSize () & 0xFFFFFFFF ,
  1536. a_Overlapped->GetOffSetSize () >> 32 ,
  1537. ( OVERLAPPED * ) a_Overlapped
  1538. ) ;
  1539. if ( t_StatusCode == e_StatusCode_Success )
  1540. {
  1541. }
  1542. else
  1543. {
  1544. a_Overlapped->GetOperationFunction ()->Operation (
  1545. t_StatusCode ,
  1546. NULL ,
  1547. 0
  1548. ) ;
  1549. }
  1550. return t_StatusCode ;
  1551. }
  1552. /******************************************************************************
  1553. *
  1554. * Name:
  1555. *
  1556. *
  1557. * Description:
  1558. *
  1559. *
  1560. *****************************************************************************/
  1561. WmiStatusCode WmiIoScheduler :: UnLockBegin (
  1562. WmiUnLockOverlapped *a_Overlapped ,
  1563. DWORD a_Bytes
  1564. )
  1565. {
  1566. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1567. a_Overlapped->SetState ( 1 ) ;
  1568. t_StatusCode = UnLock (
  1569. a_Overlapped->GetOffSetSize () & 0xFFFFFFFF ,
  1570. a_Overlapped->GetOffSetSize () >> 32 ,
  1571. ( OVERLAPPED * ) a_Overlapped
  1572. ) ;
  1573. if ( t_StatusCode == e_StatusCode_Success )
  1574. {
  1575. }
  1576. else
  1577. {
  1578. t_StatusCode = Win32ToApi () ;
  1579. a_Overlapped->GetOperationFunction ()->Operation (
  1580. t_StatusCode ,
  1581. NULL ,
  1582. 0
  1583. ) ;
  1584. }
  1585. return t_StatusCode ;
  1586. }
  1587. /******************************************************************************
  1588. *
  1589. * Name:
  1590. *
  1591. *
  1592. * Description:
  1593. *
  1594. *
  1595. *****************************************************************************/
  1596. void WmiIoScheduler :: ReadComplete ( WmiReadOverlapped *a_Overlapped , DWORD a_Bytes )
  1597. {
  1598. a_Overlapped->GetOperationFunction ()->Operation (
  1599. a_Overlapped->GetStatus () ,
  1600. a_Overlapped->GetBuffer () ,
  1601. a_Overlapped->GetBufferSize ()
  1602. ) ;
  1603. delete a_Overlapped ;
  1604. }
  1605. /******************************************************************************
  1606. *
  1607. * Name:
  1608. *
  1609. *
  1610. * Description:
  1611. *
  1612. *
  1613. *****************************************************************************/
  1614. void WmiIoScheduler :: WriteComplete ( WmiWriteOverlapped *a_Overlapped , DWORD a_Bytes )
  1615. {
  1616. a_Overlapped->GetOperationFunction ()->Operation (
  1617. a_Overlapped->GetStatus () ,
  1618. a_Overlapped->GetBuffer () ,
  1619. a_Overlapped->GetBufferSize ()
  1620. ) ;
  1621. delete a_Overlapped ;
  1622. }
  1623. /******************************************************************************
  1624. *
  1625. * Name:
  1626. *
  1627. *
  1628. * Description:
  1629. *
  1630. *
  1631. *****************************************************************************/
  1632. void WmiIoScheduler :: LockComplete ( WmiLockOverlapped *a_Overlapped , DWORD a_Bytes )
  1633. {
  1634. a_Overlapped->GetOperationFunction ()->Operation (
  1635. a_Overlapped->GetStatus () ,
  1636. NULL ,
  1637. 0
  1638. ) ;
  1639. delete a_Overlapped ;
  1640. }
  1641. /******************************************************************************
  1642. *
  1643. * Name:
  1644. *
  1645. *
  1646. * Description:
  1647. *
  1648. *
  1649. *****************************************************************************/
  1650. void WmiIoScheduler :: UnLockComplete ( WmiUnLockOverlapped *a_Overlapped , DWORD a_Bytes )
  1651. {
  1652. a_Overlapped->GetOperationFunction ()->Operation (
  1653. a_Overlapped->GetStatus () ,
  1654. NULL ,
  1655. 0
  1656. ) ;
  1657. delete a_Overlapped ;
  1658. }
  1659. /******************************************************************************
  1660. *
  1661. * Name:
  1662. *
  1663. *
  1664. * Description:
  1665. *
  1666. *
  1667. *****************************************************************************/
  1668. WmiStatusCode WmiIoScheduler :: SetFileExtent (
  1669. const WmiFileOffSet &a_FileOffSet
  1670. )
  1671. {
  1672. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1673. LARGE_INTEGER t_Integer ;
  1674. t_Integer.QuadPart = a_FileOffSet ;
  1675. BOOL t_Status = SetFilePointerEx (
  1676. GetFileHandle () ,
  1677. t_Integer ,
  1678. NULL ,
  1679. FILE_END
  1680. ) ;
  1681. if ( t_Status )
  1682. {
  1683. t_Status = SetEndOfFile ( GetFileHandle () ) ;
  1684. if ( t_Status == FALSE )
  1685. {
  1686. t_StatusCode = e_StatusCode_OutOfResources ;
  1687. }
  1688. }
  1689. else
  1690. {
  1691. t_StatusCode = e_StatusCode_OutOfResources ;
  1692. }
  1693. return t_StatusCode ;
  1694. }
  1695. /******************************************************************************
  1696. *
  1697. * Name:
  1698. *
  1699. *
  1700. * Description:
  1701. *
  1702. *
  1703. *****************************************************************************/
  1704. WmiStatusCode WmiIoScheduler :: Create ()
  1705. {
  1706. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1707. if ( m_FileName )
  1708. {
  1709. SECURITY_DESCRIPTOR t_SecurityDescriptor ;
  1710. HRESULT t_Result = GetSecurityDescriptor ( t_SecurityDescriptor , 0 ) ;
  1711. if ( SUCCEEDED ( t_Result ) )
  1712. {
  1713. SECURITY_ATTRIBUTES t_SecurityAttributes ;
  1714. t_SecurityAttributes.nLength = sizeof ( SECURITY_ATTRIBUTES ) ;
  1715. t_SecurityAttributes.lpSecurityDescriptor = & t_SecurityDescriptor ;
  1716. t_SecurityAttributes.bInheritHandle = FALSE ;
  1717. #if 0
  1718. m_FileHandle = CreateFile (
  1719. m_FileName ,
  1720. GENERIC_READ | GENERIC_WRITE | MAXIMUM_ALLOWED ,
  1721. 0 ,
  1722. & t_SecurityAttributes ,
  1723. OPEN_ALWAYS ,
  1724. FILE_FLAG_OVERLAPPED | FILE_FLAG_RANDOM_ACCESS ,
  1725. NULL
  1726. ) ;
  1727. #else
  1728. m_FileHandle = CreateFile (
  1729. m_FileName ,
  1730. GENERIC_READ | GENERIC_WRITE | MAXIMUM_ALLOWED ,
  1731. FILE_SHARE_READ | FILE_SHARE_WRITE ,
  1732. NULL ,
  1733. OPEN_ALWAYS ,
  1734. FILE_FLAG_OVERLAPPED | FILE_FLAG_RANDOM_ACCESS ,
  1735. NULL
  1736. ) ;
  1737. #endif
  1738. if ( m_FileHandle != INVALID_HANDLE_VALUE )
  1739. {
  1740. }
  1741. else
  1742. {
  1743. t_StatusCode = Win32ToApi () ;
  1744. }
  1745. delete [] t_SecurityDescriptor.Dacl ;
  1746. }
  1747. else
  1748. {
  1749. t_StatusCode = e_StatusCode_OutOfMemory ;
  1750. }
  1751. }
  1752. else
  1753. {
  1754. t_StatusCode = e_StatusCode_InvalidArgs ;
  1755. }
  1756. return t_StatusCode ;
  1757. }
  1758. /******************************************************************************
  1759. *
  1760. * Name:
  1761. *
  1762. *
  1763. * Description:
  1764. *
  1765. *
  1766. *****************************************************************************/
  1767. WmiStatusCode WmiIoScheduler :: Close ()
  1768. {
  1769. if ( m_FileHandle )
  1770. {
  1771. CloseHandle ( m_FileHandle ) ;
  1772. m_FileHandle = 0 ;
  1773. }
  1774. return e_StatusCode_Success ;
  1775. }
  1776. /******************************************************************************
  1777. *
  1778. * Name:
  1779. *
  1780. *
  1781. * Description:
  1782. *
  1783. *
  1784. *****************************************************************************/
  1785. WmiStatusCode WmiIoScheduler :: Read (
  1786. LPVOID a_Buffer ,
  1787. DWORD a_NumberOfBytesToRead ,
  1788. LPDWORD a_NumberOfBytesRead ,
  1789. LPOVERLAPPED a_Overlapped
  1790. )
  1791. {
  1792. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1793. DWORD t_Bytes = 0 ;
  1794. BOOL t_Status = ReadFile (
  1795. m_FileHandle ,
  1796. a_Buffer ,
  1797. a_NumberOfBytesToRead ,
  1798. a_NumberOfBytesRead ,
  1799. ( OVERLAPPED * ) a_Overlapped
  1800. ) ;
  1801. if ( t_Status )
  1802. {
  1803. }
  1804. else
  1805. {
  1806. t_StatusCode = Win32ToApi () ;
  1807. }
  1808. return t_StatusCode ;
  1809. }
  1810. /******************************************************************************
  1811. *
  1812. * Name:
  1813. *
  1814. *
  1815. * Description:
  1816. *
  1817. *
  1818. *****************************************************************************/
  1819. WmiStatusCode WmiIoScheduler :: Write (
  1820. LPVOID a_Buffer ,
  1821. DWORD a_NumberOfBytesToWrite ,
  1822. LPDWORD a_NumberOfBytesWritten ,
  1823. LPOVERLAPPED a_Overlapped
  1824. )
  1825. {
  1826. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1827. BOOL t_Status = WriteFile (
  1828. m_FileHandle ,
  1829. a_Buffer ,
  1830. a_NumberOfBytesToWrite ,
  1831. a_NumberOfBytesWritten ,
  1832. a_Overlapped
  1833. ) ;
  1834. if ( t_Status )
  1835. {
  1836. }
  1837. else
  1838. {
  1839. t_StatusCode = Win32ToApi () ;
  1840. }
  1841. return t_StatusCode ;
  1842. }
  1843. /******************************************************************************
  1844. *
  1845. * Name:
  1846. *
  1847. *
  1848. * Description:
  1849. *
  1850. *
  1851. *****************************************************************************/
  1852. WmiStatusCode WmiIoScheduler :: Lock (
  1853. DWORD a_Flags ,
  1854. DWORD a_NumberOfBytesToLockLow ,
  1855. DWORD a_NumberOfBytesToLockHigh ,
  1856. LPOVERLAPPED a_Overlapped
  1857. )
  1858. {
  1859. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1860. BOOL t_Status = LockFileEx (
  1861. m_FileHandle ,
  1862. a_Flags ,
  1863. 0 ,
  1864. a_NumberOfBytesToLockLow ,
  1865. a_NumberOfBytesToLockHigh ,
  1866. a_Overlapped
  1867. ) ;
  1868. if ( t_Status )
  1869. {
  1870. }
  1871. else
  1872. {
  1873. t_StatusCode = Win32ToApi () ;
  1874. }
  1875. return t_StatusCode ;
  1876. }
  1877. /******************************************************************************
  1878. *
  1879. * Name:
  1880. *
  1881. *
  1882. * Description:
  1883. *
  1884. *
  1885. *****************************************************************************/
  1886. WmiStatusCode WmiIoScheduler :: UnLock (
  1887. DWORD a_NumberOfBytesToUnlockLow ,
  1888. DWORD a_NumberOfBytesToUnlockHigh ,
  1889. LPOVERLAPPED a_Overlapped
  1890. )
  1891. {
  1892. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1893. BOOL t_Status = UnlockFileEx (
  1894. m_FileHandle ,
  1895. 0 ,
  1896. a_NumberOfBytesToUnlockLow ,
  1897. a_NumberOfBytesToUnlockHigh ,
  1898. a_Overlapped
  1899. ) ;
  1900. if ( t_Status )
  1901. {
  1902. }
  1903. else
  1904. {
  1905. t_StatusCode = Win32ToApi () ;
  1906. }
  1907. return t_StatusCode ;
  1908. }