2286 lines
42 KiB
C++
2286 lines
42 KiB
C++
|
|
/*
|
|
* Class:
|
|
*
|
|
* WmiIoScheduler
|
|
*
|
|
* Description:
|
|
*
|
|
* Provides abstraction above heap allocation functions
|
|
*
|
|
* Version:
|
|
*
|
|
* Initial
|
|
*
|
|
* Last Changed:
|
|
*
|
|
* See Source Depot for change history
|
|
*
|
|
*/
|
|
|
|
#include <precomp.h>
|
|
#include <windows.h>
|
|
#include <objbase.h>
|
|
#include <stdio.h>
|
|
#include <typeinfo.h>
|
|
#include <wbemcli.h>
|
|
|
|
#include <IoScheduler.h>
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode Win32ToApi ( DWORD a_Error )
|
|
{
|
|
WmiStatusCode t_Status = e_StatusCode_Success ;
|
|
switch ( a_Error )
|
|
{
|
|
case STATUS_NO_MEMORY:
|
|
{
|
|
t_Status = e_StatusCode_OutOfMemory ;
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
t_Status = e_StatusCode_Unknown ;
|
|
}
|
|
break ;
|
|
}
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode Win32ToApi ()
|
|
{
|
|
WmiStatusCode t_Status = e_StatusCode_Success ;
|
|
|
|
DWORD t_LastError = GetLastError () ;
|
|
t_Status = Win32ToApi ( t_LastError ) ;
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
HRESULT GetSecurityDescriptor ( SECURITY_DESCRIPTOR &a_SecurityDescriptor , DWORD a_Access )
|
|
{
|
|
HRESULT t_Result = S_OK ;
|
|
|
|
BOOL t_BoolResult = InitializeSecurityDescriptor ( & a_SecurityDescriptor , SECURITY_DESCRIPTOR_REVISION ) ;
|
|
if ( t_BoolResult )
|
|
{
|
|
SID_IDENTIFIER_AUTHORITY t_NtAuthoritySid = SECURITY_NT_AUTHORITY ;
|
|
|
|
PSID t_Administrator_Sid = NULL ;
|
|
ACCESS_ALLOWED_ACE *t_Administrator_ACE = NULL ;
|
|
WORD t_Administrator_ACESize = 0 ;
|
|
|
|
BOOL t_BoolResult = AllocateAndInitializeSid (
|
|
|
|
& t_NtAuthoritySid ,
|
|
2 ,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
& t_Administrator_Sid
|
|
);
|
|
|
|
if ( t_BoolResult )
|
|
{
|
|
DWORD t_SidLength = ::GetLengthSid ( t_Administrator_Sid );
|
|
t_Administrator_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ;
|
|
t_Administrator_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_Administrator_ACESize ] ;
|
|
if ( t_Administrator_ACE )
|
|
{
|
|
CopySid ( t_SidLength, (PSID) & t_Administrator_ACE->SidStart, t_Administrator_Sid ) ;
|
|
t_Administrator_ACE->Mask = 0x1F01FF;
|
|
t_Administrator_ACE->Header.AceType = 0 ;
|
|
t_Administrator_ACE->Header.AceFlags = 3 ;
|
|
t_Administrator_ACE->Header.AceSize = t_Administrator_ACESize ;
|
|
}
|
|
else
|
|
{
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD t_LastError = ::GetLastError();
|
|
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
|
|
PSID t_System_Sid = NULL ;
|
|
ACCESS_ALLOWED_ACE *t_System_ACE = NULL ;
|
|
WORD t_System_ACESize = 0 ;
|
|
|
|
t_BoolResult = AllocateAndInitializeSid (
|
|
|
|
& t_NtAuthoritySid ,
|
|
1 ,
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
& t_System_Sid
|
|
);
|
|
|
|
if ( t_BoolResult )
|
|
{
|
|
DWORD t_SidLength = ::GetLengthSid ( t_System_Sid );
|
|
t_System_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ;
|
|
t_System_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_System_ACESize ] ;
|
|
if ( t_System_ACE )
|
|
{
|
|
CopySid ( t_SidLength, (PSID) & t_System_ACE->SidStart, t_System_Sid ) ;
|
|
t_System_ACE->Mask = 0x1F01FF;
|
|
t_System_ACE->Header.AceType = 0 ;
|
|
t_System_ACE->Header.AceFlags = 3 ;
|
|
t_System_ACE->Header.AceSize = t_System_ACESize ;
|
|
}
|
|
else
|
|
{
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD t_LastError = ::GetLastError();
|
|
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
|
|
SID_IDENTIFIER_AUTHORITY t_WorldAuthoritySid = SECURITY_WORLD_SID_AUTHORITY ;
|
|
|
|
PSID t_Everyone_Sid = NULL ;
|
|
ACCESS_ALLOWED_ACE *t_Everyone_ACE = NULL ;
|
|
USHORT t_Everyone_ACESize = 0 ;
|
|
|
|
t_BoolResult = AllocateAndInitializeSid (
|
|
|
|
& t_WorldAuthoritySid ,
|
|
1 ,
|
|
SECURITY_WORLD_RID ,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
& t_Everyone_Sid
|
|
);
|
|
|
|
if ( t_BoolResult )
|
|
{
|
|
DWORD t_SidLength = ::GetLengthSid ( t_Everyone_Sid );
|
|
t_Everyone_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ;
|
|
t_Everyone_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_Everyone_ACESize ] ;
|
|
if ( t_Everyone_ACE )
|
|
{
|
|
CopySid ( t_SidLength, (PSID) & t_Everyone_ACE->SidStart, t_Everyone_Sid ) ;
|
|
t_Everyone_ACE->Mask = a_Access ;
|
|
t_Everyone_ACE->Header.AceType = 0 ;
|
|
t_Everyone_ACE->Header.AceFlags = 3 ;
|
|
t_Everyone_ACE->Header.AceSize = t_Everyone_ACESize ;
|
|
}
|
|
else
|
|
{
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD t_LastError = ::GetLastError();
|
|
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
|
|
// Now we need to set permissions on the registry: Everyone read; Admins full.
|
|
// We have the sid for admins from the above code. Now get the sid for "Everyone"
|
|
|
|
DWORD t_TotalAclSize = sizeof(ACL) + t_Administrator_ACESize + t_System_ACESize + t_Everyone_ACESize ;
|
|
PACL t_Dacl = (PACL) new BYTE [ t_TotalAclSize ] ;
|
|
if ( t_Dacl )
|
|
{
|
|
if ( :: InitializeAcl ( t_Dacl, t_TotalAclSize, ACL_REVISION ) )
|
|
{
|
|
DWORD t_AceIndex = 0 ;
|
|
|
|
if ( t_System_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_System_ACE , t_System_ACESize ) )
|
|
{
|
|
t_AceIndex ++ ;
|
|
}
|
|
|
|
if ( t_Administrator_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_Administrator_ACE , t_Administrator_ACESize ) )
|
|
{
|
|
t_AceIndex ++ ;
|
|
}
|
|
|
|
if ( t_Everyone_ACESize && :: AddAce ( t_Dacl , ACL_REVISION, t_AceIndex , t_Everyone_ACE , t_Everyone_ACESize ) )
|
|
{
|
|
t_AceIndex ++ ;
|
|
}
|
|
|
|
t_BoolResult = SetSecurityDescriptorDacl (
|
|
|
|
& a_SecurityDescriptor ,
|
|
TRUE ,
|
|
t_Dacl ,
|
|
FALSE
|
|
) ;
|
|
|
|
if ( t_BoolResult == FALSE )
|
|
{
|
|
delete [] ( ( BYTE * ) t_Dacl ) ;
|
|
|
|
t_Result = WBEM_E_CRITICAL_ERROR ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
|
|
if ( t_Administrator_ACE )
|
|
{
|
|
delete [] ( ( BYTE * ) t_Administrator_ACE ) ;
|
|
}
|
|
|
|
if ( t_System_ACE )
|
|
{
|
|
delete [] ( ( BYTE * ) t_System_ACE ) ;
|
|
}
|
|
|
|
if ( t_Everyone_ACE )
|
|
{
|
|
delete [] ( ( BYTE * ) t_Everyone_ACE ) ;
|
|
}
|
|
|
|
if ( t_System_Sid )
|
|
{
|
|
FreeSid ( t_System_Sid ) ;
|
|
}
|
|
|
|
if ( t_Administrator_Sid )
|
|
{
|
|
FreeSid ( t_Administrator_Sid ) ;
|
|
}
|
|
|
|
if ( t_Everyone_Sid )
|
|
{
|
|
FreeSid ( t_Everyone_Sid ) ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Result = WBEM_E_CRITICAL_ERROR ;
|
|
}
|
|
|
|
return t_Result ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiOverlapped :: WmiOverlapped ( OverLappedType a_Type )
|
|
{
|
|
ZeroMemory ( & m_Overlapped , sizeof ( m_Overlapped ) ) ;
|
|
m_Type = a_Type ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiOverlapped :: ~WmiOverlapped ()
|
|
{
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiScheduledOverlapped :: WmiScheduledOverlapped (
|
|
|
|
OverLappedType a_Type ,
|
|
WmiIoScheduler &a_Scheduler
|
|
|
|
) : WmiOverlapped ( a_Type ) ,
|
|
m_Scheduler ( a_Scheduler )
|
|
{
|
|
m_Scheduler.AddRef () ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiScheduledOverlapped :: ~WmiScheduledOverlapped ()
|
|
{
|
|
m_Scheduler.Release () ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiTerminateOverlapped :: WmiTerminateOverlapped () : WmiOverlapped ( e_OverLapped_Terminate )
|
|
{
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiTaskOverlapped :: WmiTaskOverlapped (
|
|
|
|
WmiIoScheduler &a_Scheduler ,
|
|
WmiTaskOperation *a_OperationFunction
|
|
|
|
) : WmiScheduledOverlapped ( e_OverLapped_Task , a_Scheduler ) ,
|
|
m_Status ( 0 ) ,
|
|
m_State ( 0 ) ,
|
|
m_OperationFunction ( a_OperationFunction )
|
|
{
|
|
m_Overlapped.Offset = 0 ;
|
|
m_Overlapped.OffsetHigh = 0 ;
|
|
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->AddRef () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiTaskOverlapped :: ~WmiTaskOverlapped ()
|
|
{
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->Release () ;
|
|
}
|
|
}
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiReadOverlapped :: WmiReadOverlapped (
|
|
|
|
WmiIoScheduler &a_Scheduler ,
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
BYTE *a_Buffer ,
|
|
DWORD a_BufferSize
|
|
|
|
) : WmiScheduledOverlapped ( e_OverLapped_Read , a_Scheduler ) ,
|
|
m_Buffer ( a_Buffer ) ,
|
|
m_BufferSize ( a_BufferSize ) ,
|
|
m_Status ( 0 ) ,
|
|
m_State ( 0 ) ,
|
|
m_OperationFunction ( a_OperationFunction )
|
|
{
|
|
m_Overlapped.Offset = a_OffSet & 0xFFFFFFFF ;
|
|
m_Overlapped.OffsetHigh = a_OffSet >> 32 ;
|
|
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->AddRef () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiReadOverlapped :: ~WmiReadOverlapped ()
|
|
{
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->Release () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiWriteOverlapped :: WmiWriteOverlapped (
|
|
|
|
WmiIoScheduler &a_Scheduler ,
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
BYTE *a_Buffer ,
|
|
DWORD a_BufferSize
|
|
|
|
) : WmiScheduledOverlapped ( e_OverLapped_Write , a_Scheduler ) ,
|
|
m_Buffer ( a_Buffer ) ,
|
|
m_BufferSize ( a_BufferSize ) ,
|
|
m_Status ( 0 ) ,
|
|
m_State ( 0 ) ,
|
|
m_OperationFunction ( a_OperationFunction )
|
|
{
|
|
m_Overlapped.Offset = a_OffSet & 0xFFFFFFFF ;
|
|
m_Overlapped.OffsetHigh = a_OffSet >> 32 ;
|
|
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->AddRef () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiWriteOverlapped :: ~WmiWriteOverlapped ()
|
|
{
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->Release () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiLockOverlapped :: WmiLockOverlapped (
|
|
|
|
WmiIoScheduler &a_Scheduler ,
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
WmiFileOffSet a_OffSetSize
|
|
|
|
) : WmiScheduledOverlapped ( e_OverLapped_Lock , a_Scheduler ) ,
|
|
m_OffSetSize ( a_OffSetSize ) ,
|
|
m_Status ( 0 ) ,
|
|
m_State ( 0 ) ,
|
|
m_OperationFunction ( a_OperationFunction )
|
|
{
|
|
m_Overlapped.Offset = a_OffSet & 0xFFFFFFFF ;
|
|
m_Overlapped.OffsetHigh = a_OffSet >> 32 ;
|
|
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->AddRef () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiLockOverlapped :: ~WmiLockOverlapped ()
|
|
{
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->Release () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiUnLockOverlapped :: WmiUnLockOverlapped (
|
|
|
|
WmiIoScheduler &a_Scheduler ,
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
WmiFileOffSet a_OffSetSize
|
|
|
|
) : WmiScheduledOverlapped ( e_OverLapped_UnLock , a_Scheduler ) ,
|
|
m_OffSetSize ( a_OffSetSize ) ,
|
|
m_Status ( 0 ) ,
|
|
m_State ( 0 ) ,
|
|
m_OperationFunction ( a_OperationFunction )
|
|
{
|
|
m_Overlapped.Offset = a_OffSet & 0xFFFFFFFF ;
|
|
m_Overlapped.OffsetHigh = a_OffSet >> 32 ;
|
|
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->AddRef () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiUnLockOverlapped :: ~WmiUnLockOverlapped ()
|
|
{
|
|
if ( m_OperationFunction )
|
|
{
|
|
m_OperationFunction->Release () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiCompletionPortOperation :: WmiCompletionPortOperation (
|
|
|
|
WmiAllocator &a_Allocator ,
|
|
WmiThreadPool *a_ThreadPool
|
|
|
|
) : WmiTask <ULONG> ( a_Allocator ) ,
|
|
m_ThreadPool ( a_ThreadPool )
|
|
{
|
|
if ( m_ThreadPool )
|
|
{
|
|
m_ThreadPool->AddRef () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiCompletionPortOperation :: ~WmiCompletionPortOperation ()
|
|
{
|
|
if ( m_ThreadPool )
|
|
{
|
|
m_ThreadPool->Release () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiCompletionPortOperation :: Process ( WmiThread <ULONG> &a_Thread )
|
|
{
|
|
DWORD t_Continue = TRUE ;
|
|
while ( t_Continue )
|
|
{
|
|
OVERLAPPED *t_Overlapped = NULL ;
|
|
DWORD t_Key = 0 ;
|
|
DWORD t_Bytes = 0 ;
|
|
|
|
BOOL t_Status = GetQueuedCompletionStatus (
|
|
|
|
m_ThreadPool->GetCompletionPort () ,
|
|
& t_Bytes ,
|
|
& t_Key ,
|
|
& t_Overlapped ,
|
|
INFINITE
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
WmiOverlapped *t_WmiOverlapped = ( WmiOverlapped * ) t_Overlapped ;
|
|
switch ( t_WmiOverlapped->GetType () )
|
|
{
|
|
case WmiOverlapped :: OverLappedType :: e_OverLapped_Terminate:
|
|
{
|
|
WmiTerminateOverlapped *t_TerminateOverlapped = ( WmiTerminateOverlapped * ) t_Overlapped ;
|
|
delete t_TerminateOverlapped ;
|
|
t_Continue = FALSE ;
|
|
}
|
|
break ;
|
|
|
|
case WmiOverlapped :: OverLappedType :: e_OverLapped_Task:
|
|
{
|
|
WmiTaskOverlapped *t_TaskOverlapped = ( WmiTaskOverlapped * ) t_Overlapped ;
|
|
WmiIoScheduler &t_Allocator = t_TaskOverlapped->GetScheduler () ;
|
|
|
|
t_Allocator.TaskBegin ( t_TaskOverlapped ) ;
|
|
}
|
|
break ;
|
|
|
|
case WmiOverlapped :: OverLappedType :: e_OverLapped_Read:
|
|
{
|
|
WmiReadOverlapped *t_ReadOverlapped = ( WmiReadOverlapped * ) t_Overlapped ;
|
|
WmiIoScheduler &t_Allocator = t_ReadOverlapped->GetScheduler () ;
|
|
|
|
switch ( t_ReadOverlapped->GetState () )
|
|
{
|
|
case 0:
|
|
{
|
|
t_Allocator.ReadBegin ( t_ReadOverlapped , t_Bytes ) ;
|
|
}
|
|
break ;
|
|
|
|
case 1:
|
|
{
|
|
t_Allocator.ReadComplete ( t_ReadOverlapped , t_Bytes ) ;
|
|
}
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
break ;
|
|
|
|
case WmiOverlapped :: OverLappedType :: e_OverLapped_Lock:
|
|
{
|
|
WmiLockOverlapped *t_LockOverlapped = ( WmiLockOverlapped * ) t_Overlapped ;
|
|
WmiIoScheduler &t_Allocator = t_LockOverlapped->GetScheduler () ;
|
|
|
|
switch ( t_LockOverlapped->GetState () )
|
|
{
|
|
case 0:
|
|
{
|
|
t_Allocator.LockBegin ( t_LockOverlapped , t_Bytes ) ;
|
|
}
|
|
break ;
|
|
|
|
case 1:
|
|
{
|
|
t_Allocator.LockComplete ( t_LockOverlapped , t_Bytes ) ;
|
|
}
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
break ;
|
|
|
|
case WmiOverlapped :: OverLappedType :: e_OverLapped_UnLock:
|
|
{
|
|
WmiUnLockOverlapped *t_UnLockOverlapped = ( WmiUnLockOverlapped * ) t_Overlapped ;
|
|
WmiIoScheduler &t_Allocator = t_UnLockOverlapped->GetScheduler () ;
|
|
|
|
switch ( t_UnLockOverlapped->GetState () )
|
|
{
|
|
case 0:
|
|
{
|
|
t_Allocator.UnLockBegin ( t_UnLockOverlapped , t_Bytes ) ;
|
|
}
|
|
break ;
|
|
|
|
case 1:
|
|
{
|
|
t_Allocator.UnLockComplete ( t_UnLockOverlapped , t_Bytes ) ;
|
|
}
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
break ;
|
|
|
|
case WmiOverlapped :: OverLappedType :: e_OverLapped_Write:
|
|
{
|
|
WmiWriteOverlapped *t_WriteOverlapped = ( WmiWriteOverlapped * ) t_Overlapped ;
|
|
WmiIoScheduler &t_Allocator = t_WriteOverlapped->GetScheduler () ;
|
|
|
|
switch ( t_WriteOverlapped->GetState () )
|
|
{
|
|
case 0:
|
|
{
|
|
t_Allocator.WriteBegin ( t_WriteOverlapped , t_Bytes ) ;
|
|
}
|
|
break ;
|
|
|
|
case 1:
|
|
{
|
|
t_Allocator.WriteComplete ( t_WriteOverlapped , t_Bytes ) ;
|
|
}
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
t_Continue = FALSE ;
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD t_LastError = GetLastError () ;
|
|
|
|
if ( t_Overlapped == NULL )
|
|
{
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
|
|
Complete () ;
|
|
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiThreadPool :: WmiThreadPool (
|
|
|
|
WmiAllocator &a_Allocator ,
|
|
const ULONG &a_Threads
|
|
|
|
) : m_Allocator ( a_Allocator ) ,
|
|
m_ReferenceCount ( 0 ) ,
|
|
m_ThreadPool ( NULL ) ,
|
|
m_CompletionPort ( NULL )
|
|
{
|
|
if ( a_Threads == 0 )
|
|
{
|
|
SYSTEM_INFO t_SystemInformation ;
|
|
GetSystemInfo ( & t_SystemInformation ) ;
|
|
|
|
m_Threads = t_SystemInformation.dwNumberOfProcessors ;
|
|
}
|
|
else
|
|
{
|
|
m_Threads = a_Threads ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiThreadPool :: ~WmiThreadPool ()
|
|
{
|
|
UnInitialize () ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
ULONG WmiThreadPool :: AddRef ()
|
|
{
|
|
return InterlockedIncrement ( & m_ReferenceCount ) ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
ULONG WmiThreadPool :: Release ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
delete this ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiThreadPool :: Initialize ()
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
t_StatusCode = WmiThread <ULONG> :: Static_Initialize ( m_Allocator ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
m_CompletionPort = CreateIoCompletionPort (
|
|
|
|
INVALID_HANDLE_VALUE ,
|
|
NULL ,
|
|
NULL ,
|
|
0
|
|
) ;
|
|
|
|
if ( m_CompletionPort == NULL )
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfResources ;
|
|
}
|
|
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
m_ThreadPool = new WmiThread <ULONG> * [ m_Threads ] ;
|
|
if ( m_ThreadPool )
|
|
{
|
|
for ( ULONG t_Index = 0 ; t_Index < m_Threads ; t_Index ++ )
|
|
{
|
|
m_ThreadPool [ t_Index ] = new WmiThread <ULONG> ( m_Allocator ) ;
|
|
if ( m_ThreadPool [ t_Index ] )
|
|
{
|
|
m_ThreadPool [ t_Index ]->AddRef () ;
|
|
|
|
t_StatusCode = m_ThreadPool [ t_Index ]->Initialize () ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
WmiCompletionPortOperation *t_Operation = new WmiCompletionPortOperation (
|
|
|
|
m_Allocator ,
|
|
this
|
|
) ;
|
|
|
|
if ( t_Operation )
|
|
{
|
|
t_StatusCode = t_Operation->Initialize () ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
m_ThreadPool [ t_Index ]->EnQueue ( 0 , *t_Operation ) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiThreadPool :: UnInitialize ()
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
if ( m_ThreadPool )
|
|
{
|
|
for ( ULONG t_Index = 0 ; t_Index < m_Threads ; t_Index ++ )
|
|
{
|
|
if ( m_ThreadPool [ t_Index ] )
|
|
{
|
|
WmiTerminateOverlapped *t_Terminate = new WmiTerminateOverlapped ;
|
|
if ( t_Terminate )
|
|
{
|
|
BOOL t_Status = PostQueuedCompletionStatus (
|
|
|
|
GetCompletionPort () ,
|
|
0 ,
|
|
NULL ,
|
|
( OVERLAPPED * ) t_Terminate
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
HANDLE t_ThreadHandle = NULL ;
|
|
|
|
BOOL t_Status = DuplicateHandle (
|
|
|
|
GetCurrentProcess () ,
|
|
m_ThreadPool [ t_Index ]->GetHandle () ,
|
|
GetCurrentProcess () ,
|
|
& t_ThreadHandle,
|
|
0 ,
|
|
FALSE ,
|
|
DUPLICATE_SAME_ACCESS
|
|
) ;
|
|
|
|
m_ThreadPool [ t_Index ]->Release () ;
|
|
|
|
WaitForSingleObject ( t_ThreadHandle , INFINITE ) ;
|
|
|
|
CloseHandle ( t_ThreadHandle ) ;
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_Failed ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
delete [] m_ThreadPool ;
|
|
m_ThreadPool = NULL ;
|
|
}
|
|
|
|
if ( m_CompletionPort )
|
|
{
|
|
CloseHandle ( m_CompletionPort ) ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiIoScheduler :: WmiIoScheduler (
|
|
|
|
WmiAllocator &a_Allocator ,
|
|
WmiThreadPool *a_ThreadPool ,
|
|
wchar_t *a_FileName ,
|
|
WmiFileSize a_InitialSize ,
|
|
WmiFileSize a_MaximumSize
|
|
|
|
) : m_Allocator ( a_Allocator ) ,
|
|
m_InitialSize ( a_InitialSize ) ,
|
|
m_MaximumSize ( a_MaximumSize ) ,
|
|
m_ReferenceCount ( 0 ) ,
|
|
m_ThreadPool ( a_ThreadPool ) ,
|
|
m_FileHandle ( NULL ) ,
|
|
m_FileName ( NULL )
|
|
{
|
|
m_FileName = new wchar_t [ wcslen ( a_FileName ) + 1 ] ;
|
|
if ( m_FileName )
|
|
{
|
|
wcscpy ( m_FileName , a_FileName ) ;
|
|
}
|
|
|
|
if ( m_ThreadPool )
|
|
{
|
|
m_ThreadPool->AddRef () ;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiIoScheduler :: ~WmiIoScheduler ()
|
|
{
|
|
UnInitialize () ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
ULONG WmiIoScheduler :: AddRef ()
|
|
{
|
|
return InterlockedIncrement ( & m_ReferenceCount ) ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
ULONG WmiIoScheduler :: Release ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
delete this ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Initialize ()
|
|
{
|
|
WmiStatusCode t_StatusCode = Create () ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
HANDLE t_CompletionPort = CreateIoCompletionPort (
|
|
|
|
m_FileHandle ,
|
|
m_ThreadPool->GetCompletionPort () ,
|
|
( ULONG_PTR ) this ,
|
|
0
|
|
) ;
|
|
|
|
if ( t_CompletionPort != INVALID_HANDLE_VALUE )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: UnInitialize ()
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
if ( m_FileName )
|
|
{
|
|
delete [] m_FileName ;
|
|
m_FileName = NULL ;
|
|
}
|
|
|
|
t_StatusCode = Close () ;
|
|
|
|
if ( m_ThreadPool )
|
|
{
|
|
m_ThreadPool->Release () ;
|
|
m_ThreadPool = NULL ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Task (
|
|
|
|
WmiTaskOperation *a_OperationFunction
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiTaskOverlapped *t_Overlapped = new WmiTaskOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
BOOL t_Status = PostQueuedCompletionStatus (
|
|
|
|
m_ThreadPool->GetCompletionPort () ,
|
|
0 ,
|
|
( ULONG_PTR ) this ,
|
|
( OVERLAPPED * ) t_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status == FALSE )
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Read (
|
|
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
BYTE *a_ReadBytes ,
|
|
DWORD a_Bytes
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiReadOverlapped *t_Overlapped = new WmiReadOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction ,
|
|
a_OffSet ,
|
|
a_ReadBytes ,
|
|
a_Bytes
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
BOOL t_Status = PostQueuedCompletionStatus (
|
|
|
|
m_ThreadPool->GetCompletionPort () ,
|
|
a_Bytes ,
|
|
( ULONG_PTR ) this ,
|
|
( OVERLAPPED * ) t_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status == FALSE )
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Write (
|
|
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
BYTE *a_WriteBytes ,
|
|
DWORD a_Bytes
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiWriteOverlapped *t_Overlapped = new WmiWriteOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction ,
|
|
a_OffSet ,
|
|
a_WriteBytes ,
|
|
a_Bytes
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
BOOL t_Status = PostQueuedCompletionStatus (
|
|
|
|
m_ThreadPool->GetCompletionPort () ,
|
|
a_Bytes ,
|
|
( ULONG_PTR ) this ,
|
|
( OVERLAPPED * ) t_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status == FALSE )
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Lock (
|
|
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
WmiFileOffSet a_OffSetSize
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiLockOverlapped *t_Overlapped = new WmiLockOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction ,
|
|
a_OffSet ,
|
|
a_OffSetSize
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
BOOL t_Status = PostQueuedCompletionStatus (
|
|
|
|
m_ThreadPool->GetCompletionPort () ,
|
|
0 ,
|
|
( ULONG_PTR ) this ,
|
|
( OVERLAPPED * ) t_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status == FALSE )
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: UnLock (
|
|
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
WmiFileOffSet a_OffSetSize
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiUnLockOverlapped *t_Overlapped = new WmiUnLockOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction ,
|
|
a_OffSet ,
|
|
a_OffSetSize
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
BOOL t_Status = PostQueuedCompletionStatus (
|
|
|
|
m_ThreadPool->GetCompletionPort () ,
|
|
0 ,
|
|
( ULONG_PTR ) this ,
|
|
( OVERLAPPED * ) t_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status == FALSE )
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: ReadOnThread (
|
|
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
BYTE *a_ReadBytes ,
|
|
DWORD a_Bytes
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiReadOverlapped *t_Overlapped = new WmiReadOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction ,
|
|
a_OffSet ,
|
|
a_ReadBytes ,
|
|
a_Bytes
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
t_Overlapped->SetState ( 1 ) ;
|
|
|
|
t_StatusCode = ReadBegin (
|
|
|
|
t_Overlapped ,
|
|
0
|
|
) ;
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: WriteOnThread (
|
|
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
BYTE *a_WriteBytes ,
|
|
DWORD a_Bytes
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiWriteOverlapped *t_Overlapped = new WmiWriteOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction ,
|
|
a_OffSet ,
|
|
a_WriteBytes ,
|
|
a_Bytes
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
t_Overlapped->SetState ( 1 ) ;
|
|
|
|
t_StatusCode = WriteBegin (
|
|
|
|
t_Overlapped ,
|
|
0
|
|
) ;
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: LockOnThread (
|
|
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
WmiFileOffSet a_OffSetSize
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiLockOverlapped *t_Overlapped = new WmiLockOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction ,
|
|
a_OffSet ,
|
|
a_OffSetSize
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
t_Overlapped->SetState ( 1 ) ;
|
|
|
|
t_StatusCode = LockBegin (
|
|
|
|
t_Overlapped ,
|
|
0
|
|
) ;
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: TaskBegin (
|
|
|
|
WmiTaskOverlapped *a_Overlapped
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
a_Overlapped->SetState ( 1 ) ;
|
|
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
t_StatusCode
|
|
) ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: UnLockOnThread (
|
|
|
|
WmiFileOperation *a_OperationFunction ,
|
|
WmiFileOffSet a_OffSet ,
|
|
WmiFileOffSet a_OffSetSize
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
WmiUnLockOverlapped *t_Overlapped = new WmiUnLockOverlapped (
|
|
|
|
*this ,
|
|
a_OperationFunction ,
|
|
a_OffSet ,
|
|
a_OffSetSize
|
|
) ;
|
|
|
|
if ( t_Overlapped )
|
|
{
|
|
t_Overlapped->SetState ( 1 ) ;
|
|
|
|
t_StatusCode = UnLockBegin (
|
|
|
|
t_Overlapped ,
|
|
0
|
|
) ;
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: ReadBegin (
|
|
|
|
WmiReadOverlapped *a_Overlapped ,
|
|
DWORD a_Bytes
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
a_Overlapped->SetState ( 1 ) ;
|
|
|
|
DWORD t_Bytes = 0 ;
|
|
|
|
t_StatusCode = Read (
|
|
|
|
a_Overlapped->GetBuffer () ,
|
|
a_Overlapped->GetBufferSize () ,
|
|
& t_Bytes ,
|
|
( OVERLAPPED * ) a_Overlapped
|
|
) ;
|
|
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
t_StatusCode ,
|
|
a_Overlapped->GetBuffer () ,
|
|
a_Overlapped->GetBufferSize ()
|
|
) ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: WriteBegin (
|
|
|
|
WmiWriteOverlapped *a_Overlapped ,
|
|
DWORD a_Bytes
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
a_Overlapped->SetState ( 1 ) ;
|
|
|
|
DWORD t_Bytes = 0 ;
|
|
|
|
t_StatusCode = Write (
|
|
|
|
a_Overlapped->GetBuffer () ,
|
|
a_Overlapped->GetBufferSize () ,
|
|
& t_Bytes ,
|
|
( OVERLAPPED * ) a_Overlapped
|
|
) ;
|
|
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
t_StatusCode ,
|
|
a_Overlapped->GetBuffer () ,
|
|
a_Overlapped->GetBufferSize ()
|
|
) ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: LockBegin (
|
|
|
|
WmiLockOverlapped *a_Overlapped ,
|
|
DWORD a_Bytes
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
a_Overlapped->SetState ( 1 ) ;
|
|
|
|
t_StatusCode = Lock (
|
|
|
|
LOCKFILE_EXCLUSIVE_LOCK ,
|
|
a_Overlapped->GetOffSetSize () & 0xFFFFFFFF ,
|
|
a_Overlapped->GetOffSetSize () >> 32 ,
|
|
( OVERLAPPED * ) a_Overlapped
|
|
) ;
|
|
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
t_StatusCode ,
|
|
NULL ,
|
|
0
|
|
) ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: UnLockBegin (
|
|
|
|
WmiUnLockOverlapped *a_Overlapped ,
|
|
DWORD a_Bytes
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
a_Overlapped->SetState ( 1 ) ;
|
|
|
|
t_StatusCode = UnLock (
|
|
|
|
a_Overlapped->GetOffSetSize () & 0xFFFFFFFF ,
|
|
a_Overlapped->GetOffSetSize () >> 32 ,
|
|
( OVERLAPPED * ) a_Overlapped
|
|
) ;
|
|
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
t_StatusCode ,
|
|
NULL ,
|
|
0
|
|
) ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void WmiIoScheduler :: ReadComplete ( WmiReadOverlapped *a_Overlapped , DWORD a_Bytes )
|
|
{
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
a_Overlapped->GetStatus () ,
|
|
a_Overlapped->GetBuffer () ,
|
|
a_Overlapped->GetBufferSize ()
|
|
) ;
|
|
|
|
delete a_Overlapped ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void WmiIoScheduler :: WriteComplete ( WmiWriteOverlapped *a_Overlapped , DWORD a_Bytes )
|
|
{
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
a_Overlapped->GetStatus () ,
|
|
a_Overlapped->GetBuffer () ,
|
|
a_Overlapped->GetBufferSize ()
|
|
) ;
|
|
|
|
delete a_Overlapped ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void WmiIoScheduler :: LockComplete ( WmiLockOverlapped *a_Overlapped , DWORD a_Bytes )
|
|
{
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
a_Overlapped->GetStatus () ,
|
|
NULL ,
|
|
0
|
|
) ;
|
|
|
|
delete a_Overlapped ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void WmiIoScheduler :: UnLockComplete ( WmiUnLockOverlapped *a_Overlapped , DWORD a_Bytes )
|
|
{
|
|
a_Overlapped->GetOperationFunction ()->Operation (
|
|
|
|
a_Overlapped->GetStatus () ,
|
|
NULL ,
|
|
0
|
|
) ;
|
|
|
|
delete a_Overlapped ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: SetFileExtent (
|
|
|
|
const WmiFileOffSet &a_FileOffSet
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
LARGE_INTEGER t_Integer ;
|
|
t_Integer.QuadPart = a_FileOffSet ;
|
|
|
|
BOOL t_Status = SetFilePointerEx (
|
|
|
|
GetFileHandle () ,
|
|
t_Integer ,
|
|
NULL ,
|
|
FILE_END
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
t_Status = SetEndOfFile ( GetFileHandle () ) ;
|
|
if ( t_Status == FALSE )
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfResources ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfResources ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Create ()
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
if ( m_FileName )
|
|
{
|
|
SECURITY_DESCRIPTOR t_SecurityDescriptor ;
|
|
|
|
HRESULT t_Result = GetSecurityDescriptor ( t_SecurityDescriptor , 0 ) ;
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
SECURITY_ATTRIBUTES t_SecurityAttributes ;
|
|
|
|
t_SecurityAttributes.nLength = sizeof ( SECURITY_ATTRIBUTES ) ;
|
|
t_SecurityAttributes.lpSecurityDescriptor = & t_SecurityDescriptor ;
|
|
t_SecurityAttributes.bInheritHandle = FALSE ;
|
|
|
|
#if 0
|
|
m_FileHandle = CreateFile (
|
|
|
|
m_FileName ,
|
|
GENERIC_READ | GENERIC_WRITE | MAXIMUM_ALLOWED ,
|
|
0 ,
|
|
& t_SecurityAttributes ,
|
|
OPEN_ALWAYS ,
|
|
FILE_FLAG_OVERLAPPED | FILE_FLAG_RANDOM_ACCESS ,
|
|
NULL
|
|
) ;
|
|
#else
|
|
m_FileHandle = CreateFile (
|
|
|
|
m_FileName ,
|
|
GENERIC_READ | GENERIC_WRITE | MAXIMUM_ALLOWED ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE ,
|
|
NULL ,
|
|
OPEN_ALWAYS ,
|
|
FILE_FLAG_OVERLAPPED | FILE_FLAG_RANDOM_ACCESS ,
|
|
NULL
|
|
) ;
|
|
|
|
#endif
|
|
if ( m_FileHandle != INVALID_HANDLE_VALUE )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
|
|
delete [] t_SecurityDescriptor.Dacl ;
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_OutOfMemory ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = e_StatusCode_InvalidArgs ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Close ()
|
|
{
|
|
if ( m_FileHandle )
|
|
{
|
|
CloseHandle ( m_FileHandle ) ;
|
|
m_FileHandle = 0 ;
|
|
}
|
|
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Read (
|
|
|
|
LPVOID a_Buffer ,
|
|
DWORD a_NumberOfBytesToRead ,
|
|
LPDWORD a_NumberOfBytesRead ,
|
|
LPOVERLAPPED a_Overlapped
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
DWORD t_Bytes = 0 ;
|
|
|
|
BOOL t_Status = ReadFile (
|
|
|
|
m_FileHandle ,
|
|
a_Buffer ,
|
|
a_NumberOfBytesToRead ,
|
|
a_NumberOfBytesRead ,
|
|
( OVERLAPPED * ) a_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Write (
|
|
|
|
LPVOID a_Buffer ,
|
|
DWORD a_NumberOfBytesToWrite ,
|
|
LPDWORD a_NumberOfBytesWritten ,
|
|
LPOVERLAPPED a_Overlapped
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
BOOL t_Status = WriteFile (
|
|
|
|
m_FileHandle ,
|
|
a_Buffer ,
|
|
a_NumberOfBytesToWrite ,
|
|
a_NumberOfBytesWritten ,
|
|
a_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: Lock (
|
|
|
|
DWORD a_Flags ,
|
|
DWORD a_NumberOfBytesToLockLow ,
|
|
DWORD a_NumberOfBytesToLockHigh ,
|
|
LPOVERLAPPED a_Overlapped
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
BOOL t_Status = LockFileEx (
|
|
|
|
m_FileHandle ,
|
|
a_Flags ,
|
|
0 ,
|
|
a_NumberOfBytesToLockLow ,
|
|
a_NumberOfBytesToLockHigh ,
|
|
a_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
WmiStatusCode WmiIoScheduler :: UnLock (
|
|
|
|
DWORD a_NumberOfBytesToUnlockLow ,
|
|
DWORD a_NumberOfBytesToUnlockHigh ,
|
|
LPOVERLAPPED a_Overlapped
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
BOOL t_Status = UnlockFileEx (
|
|
|
|
m_FileHandle ,
|
|
0 ,
|
|
a_NumberOfBytesToUnlockLow ,
|
|
a_NumberOfBytesToUnlockHigh ,
|
|
a_Overlapped
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = Win32ToApi () ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|