⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cracker.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "SMB_Globals.h"
#include "PC_NET_PROG.h"
#include "SMBErrors.h"
#include "Cracker.h"
#include "CriticalSection.h"
#include "ShareInfo.h"
#include "FileServer.h"
#include "ConnectionManager.h"

//
// Init global variables defined in Cracker.h
ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC>    Cracker::g_PacketsToDelayCrack;
CRITICAL_SECTION                                 Cracker::g_csCrackLock;
HANDLE                                           Cracker::g_hStopEvent = NULL;
HANDLE                                           Cracker::g_hCrackDelaySem = NULL;
HANDLE                                           Cracker::g_hCrackerDelayThread = NULL;
const UINT                                       Cracker::g_uiMaxPacketsInQueue = 100;
BOOL                                             Cracker::g_fIsRunning = FALSE;

#ifdef DEBUG    
CRITICAL_SECTION                                 Cracker::g_csPerfLock;
DOUBLE                                           Cracker::g_dblPerfAvePacketTime[0xFF];
DWORD                                            Cracker::g_dwPerfPacketsProcessed[0xFF];
#endif


//
// Forward Declared fn's()
extern HRESULT CloseConnectionTransport(ULONG ulConnectionID);

HRESULT
StopCracker() {
    HRESULT hr = E_FAIL;
    
    //
    // If the cracker isnt running just return failure
    if(FALSE == Cracker::g_fIsRunning) {        
        TRACEMSG(ZONE_DETAIL, (L"CRACKER:  not running, so stopping doesnt do anything"));
        return S_OK;    
    }
    
    //
    // First things first set a stop event
    if(0 == SetEvent(Cracker::g_hStopEvent)) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: setting stop event FAILED!!"));
        ASSERT(FALSE);
        hr = E_FAIL;
        goto Done;
    }

    //
    // Wait for the delay write thread to terminate
    if(WAIT_FAILED == WaitForSingleObject(Cracker::g_hCrackerDelayThread, INFINITE)) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: error waiting for cracker thread to exit!! (%d)", GetLastError()));
        ASSERT(FALSE);
    }
       

    //
    // Delete our cracking pool
    ASSERT(SMB_Globals::g_pCrackingPool);
    if(SMB_Globals::g_pCrackingPool) {
        delete SMB_Globals::g_pCrackingPool;
        SMB_Globals::g_pCrackingPool = NULL;
    }

    
#ifdef DEBUG 
    {for(UINT i=0; i<0xFF; i++) {
        if(0 != Cracker::g_dwPerfPacketsProcessed[i]) {
            TRACEMSG(ZONE_STATS, (L"SMBSRV-CRACKER: Perf for packet (0x%x -- %10s) -- %d calls ave time %d", i, GetCMDName(i) ,Cracker::g_dwPerfPacketsProcessed[i], (UINT)Cracker::g_dblPerfAvePacketTime[i]));
        }
    }
    DeleteCriticalSection(&Cracker::g_csPerfLock);
    }
#endif

    //
    // Clean up handles and critical sections
    CloseHandle(Cracker::g_hStopEvent);
    Cracker::g_hStopEvent = NULL;
    
    DeleteCriticalSection(&Cracker::g_csCrackLock);

    hr = S_OK;
    Done:
        if(SUCCEEDED(hr)) {
            Cracker::g_fIsRunning = FALSE;
        }
        return hr;
}


HRESULT 
StartCracker() {
    HRESULT hr = E_FAIL;
    WORD    wErr = 0;
         
    //
    // If the cracker is running just return okay
    if(TRUE == Cracker::g_fIsRunning) {
        ASSERT(FALSE);       
        TRACEMSG(ZONE_DETAIL, (L"CRACKER:  is already running, so starting dosent do anything"));
        return E_FAIL;        
    }
    
    //
    // Init our critical section
    InitializeCriticalSection(&(Cracker::g_csCrackLock));    

    //
    // Create a thread pool for packets
    if(NULL == SMB_Globals::g_pCrackingPool) {
        if(!(SMB_Globals::g_pCrackingPool = new SVSThreadPool(SMB_Globals::g_uiMaxCrackingThreads))) {
            hr = E_UNEXPECTED;
            goto Done;
        }
        if(NULL == (SMB_Globals::g_CrackingSem = CreateSemaphore(NULL, SMB_Globals::g_uiMaxCrackingThreads, SMB_Globals::g_uiMaxCrackingThreads, NULL))) {
            hr = E_OUTOFMEMORY;
            goto Done;
        }        
    }

   
    //
    // Init data to pre-processing state (so if error we can cleanup)
    //
    // NOTE: these all should be null (or else we have leaked something)
    ASSERT(NULL == Cracker::g_hStopEvent);
    Cracker::g_hStopEvent = NULL;
    Cracker::g_hCrackerDelayThread = NULL;
    Cracker::g_hCrackDelaySem = NULL;
    Cracker::g_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    if(NULL == Cracker::g_hStopEvent) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER:  cant create stop event!"));
        ASSERT(FALSE);
        hr = E_UNEXPECTED;
        goto Done;
    }    
    
#ifdef DEBUG
    //
    // Init perf measurements
    {
    for(UINT i=0; i<0xFF; i++) {
        Cracker::g_dblPerfAvePacketTime[i] = 0;
        Cracker::g_dwPerfPacketsProcessed[i] = 0;
    }
    InitializeCriticalSection(&Cracker::g_csPerfLock);  
    }   
#endif
    
    //
    // Init our delay semaphore the # in the semaphore represents the # of packets in the delay queue
    Cracker::g_hCrackDelaySem = CreateSemaphore(NULL, 0, Cracker::g_uiMaxPacketsInQueue, NULL);
    
    if(NULL == Cracker::g_hCrackDelaySem) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER:  cant create delay semaphore!"));
        ASSERT(FALSE);
        hr = E_UNEXPECTED;
        goto Done;
    }  
    
    if(NULL == (Cracker::g_hCrackerDelayThread = CreateThread(NULL, 0, Cracker::SMBSRVR_CrackerDelayThread, 0, CREATE_SUSPENDED, NULL))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: cant make cracker delay thread"));
        ASSERT(FALSE);
        hr = E_FAIL;
        goto Done;
    }    
    TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: cracker delay thread created 0x%x", (UINT)Cracker::g_hCrackerDelayThread));

      
    hr = S_OK;
    
    Done:
        if(FAILED(hr)) {
            if(SMB_Globals::g_pCrackingPool) 
                delete SMB_Globals::g_pCrackingPool;                    
            if(Cracker::g_hStopEvent)
                CloseHandle(Cracker::g_hStopEvent);    
            if(SMB_Globals::g_CrackingSem) 
                CloseHandle(SMB_Globals::g_CrackingSem);

            SMB_Globals::g_pCrackingPool = NULL;
            Cracker::g_hStopEvent = NULL;
            SMB_Globals::g_CrackingSem = NULL;
        } else {        
            //
            // Everything went okay, set the running flag
            Cracker::g_fIsRunning = TRUE;
        }
        
        if(NULL != Cracker::g_hCrackerDelayThread) {
            ResumeThread(Cracker::g_hCrackerDelayThread);
        }
        return hr;
    
}


DWORD Cracker::SMBSRVR_CrackerDelayThread(LPVOID unused) 
{
    HANDLE hWaitEvents[2];
    HRESULT hr;
    ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC> OrderedDelayList;
    ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC >::iterator it;
    DWORD dwSleepTime = INFINITE;
        
    //
    // If the stop events are nulled (invalid) we cant run! just exit with failure
    if(NULL == Cracker::g_hStopEvent || NULL == Cracker::g_hCrackDelaySem) {
        ASSERT(FALSE);
        hr = E_FAIL;
        goto Done;
    }
    
    //   
    /// This thread does the following:
    //  
    //  1. Waits for one of these 3 things:
    //     a. timeout (meaning a packet is ready to go)
    //     b. a new packet (at which time it will be inserted in order of delay on the ORderedDelayList)
    //     c. shutdown
    //  2. When it wakes up for:
    //     a. timeout -- the first packet will be sent, and the timer will be set for the next
    //        closest value
    //     b. a new packet comes in, it will be inserted in order and the timer will be set 
    //        to be what it should for the next newest packet
    //     c. shutdown -- we just exit
    hWaitEvents[0] = Cracker::g_hStopEvent;
    hWaitEvents[1] = Cracker::g_hCrackDelaySem;
    
    for(;;) {
        SMB_PACKET *pSMB = NULL;
        ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC >::iterator itDelayAdjVar;
        
        //
        // Wait for either a packet to come in, or for a STOP event
        DWORD dwStartAsleepAt = GetTickCount();
        DWORD dwStopAsleepFor;
        DWORD dwRet = WaitForMultipleObjects(2, hWaitEvents, FALSE, dwSleepTime);
          
        if(dwRet == WAIT_TIMEOUT) {
            if(0 != OrderedDelayList.size()) {
                //
                // Get the first node off the list
                pSMB = OrderedDelayList.front();
                OrderedDelayList.pop_front();

                //
                // Send the packet to its transport
                hr = pSMB->pfnQueueFunction(pSMB, TRUE);   
                ASSERT(SUCCEEDED(hr)); 
            } else {
                ASSERT(FALSE);
            }
        }
        else if(1 == dwRet - WAIT_OBJECT_0) {           
            //
            // Get an SMB from the queue (we know there is one since we were woken up)
            LockCracker();
                ASSERT(0 != Cracker::g_PacketsToDelayCrack.size());
                pSMB = Cracker::g_PacketsToDelayCrack.front();
                TRACEMSG(ZONE_DETAIL, (L"SMBSRV: Delay Cracker has packet: %x", (UINT)pSMB));
                Cracker::g_PacketsToDelayCrack.pop_front();
                ASSERT(NULL != pSMB);
            UnlockCracker(); 

            //
            // Adjust everyones timings to reflect our sleeping (so order is preserved)      
            dwStopAsleepFor = GetTickCount() - dwStartAsleepAt;
            dwStartAsleepAt = GetTickCount();
            for(itDelayAdjVar = OrderedDelayList.begin(); itDelayAdjVar != OrderedDelayList.end(); ++itDelayAdjVar) {
                if(dwStopAsleepFor <= (*itDelayAdjVar)->dwDelayBeforeSending) {
                    (*itDelayAdjVar)->dwDelayBeforeSending -= dwStopAsleepFor;
                } else {
                    (*itDelayAdjVar)->dwDelayBeforeSending = 0;
                }
            }   
          
            //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -