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

📄 printqueue.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 
ULONG
PrintJob::GetStartTime()
{   
    return m_ulStartTime;
}

DWORD PrintQueue::SMB_Com_Open_Spool(SMB_PACKET *pSMB, 
                                      SMB_PROCESS_CMD *_pRawRequest, 
                                      SMB_PROCESS_CMD *_pRawResponse, 
                                      UINT *puiUsed)
{
    DWORD dwRet = 0;
    SMB_OPEN_PRINT_SPOOL_CLIENT_REQUEST *pRequest =
            (SMB_OPEN_PRINT_SPOOL_CLIENT_REQUEST *)_pRawRequest->pDataPortion;
    SMB_OPEN_PRINT_SPOOL_SERVER_RESPONSE *pResponse = 
            (SMB_OPEN_PRINT_SPOOL_SERVER_RESPONSE *)_pRawResponse->pDataPortion;
    
    StringTokenizer RequestTokenizer;  
    ce::smart_ptr<TIDState> pTIDState = NULL;
    SMBPrintQueue *pPrintQueue;    
    USHORT usQueueID;
    PrintJob *pNewJob = NULL;
    SMBFileStream *pPrintStream = NULL;
    ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
    
    //
    // Find our connection state        
    if(!(pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {
       TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_INFO_ALLOCATION: -- cant find connection 0x%x!", pSMB->ulConnectionID));
       ASSERT(FALSE);
       dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
       goto Done;    
    }    

    //
    // Verify that we have enough memory
    if(_pRawRequest->uiDataSize < sizeof(SMB_OPEN_PRINT_SPOOL_CLIENT_REQUEST)) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Open_Spool -- not enough memory for request!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }
    if(_pRawResponse->uiDataSize < sizeof(SMB_OPEN_PRINT_SPOOL_SERVER_RESPONSE)) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Open_Spool -- not enough memory for response!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }        
    
    if(pRequest->SpoolMode != 1) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Open_Spool -- we dont support TextMode"));
        ASSERT(FALSE);
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done; 
    }    
        
    //
    // Find a share state 
    if(FAILED(pMyConnection->FindTIDState(_pRawRequest->pSMBHeader->Tid, pTIDState, SEC_READ)) || !pTIDState) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Open_Spool -- couldnt find share state!!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;   
    }
      
    // 
    // Make sure this is actually a print queue
    if(!pTIDState || 
       !pTIDState->GetShare () ||
       !pTIDState->GetShare()->GetPrintQueue()) {
        ASSERT(FALSE);
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Open_Spool -- the Tid is for a file -- we only do print!!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;  
    }
    
    //
    // Fetch the queue
    if(NULL == (pPrintQueue = pTIDState->GetShare()->GetPrintQueue())) {
        ASSERT(FALSE);
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Open_Spool -- we didnt get a print queue back!!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;  
    }
    
    //
    // Create a file stream
    if(NULL == (pPrintStream = pTIDState->CreateFileStream(pMyConnection))) {
        TRACEMSG(ZONE_FILES, (L"SMBSRV-CRACKER:  SMB_Com_Open_Spool-- error getting Print Stream"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }   

    //
    // Create a new print job    
    if(NULL == (pNewJob = new PrintJob(pTIDState->GetShare(), pPrintStream->FID()))) {
        TRACEMSG(ZONE_FILES, (L"SMBSRV-CRACKER:  SMB_Com_Open_Spool-- error getting creating print job"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }   
   
    //
    // Set our username
    if(FAILED(pNewJob->SetOwnerName(pMyConnection->UserName()))) {
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }
    
    //    
    // Create a new PrintStream and then add the job to TIDState
    if(NULL == (pPrintStream = new PrintStream(pNewJob,pTIDState))) {
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }   

    if(FAILED(pTIDState->AddFileStream(pPrintStream))) {
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    } 
    
     //
     // Init then fetch the file name from the request tokenizer
     RequestTokenizer.Reset((BYTE*)(pRequest+1), _pRawRequest->uiDataSize - sizeof(SMB_OPEN_PRINT_SPOOL_CLIENT_REQUEST));

     if(FALSE == pMyConnection->SupportsUnicode(pSMB->pInSMB)) { 
        CHAR *pRequestedFile;
        if(FAILED(RequestTokenizer.GetString(&pRequestedFile)) || 0x04 != pRequestedFile[0]) {
            TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Open_Spool -- error getting file name"));
            dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
            goto Done; 
        }
        // the +1 on field is to advance beyond the string id
        if(FAILED(pNewJob->SetQueueName(StringConverter(pRequestedFile+1).GetString()))) {
            dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
            goto Done;
        }        
     } else {
        WCHAR *pRequestedFile;
        if(FAILED(RequestTokenizer.GetUnicodeString(&pRequestedFile))) {
            TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Open_Spool -- error getting file name"));
            dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
            goto Done; 
        }
        // the +1 on field is to advance beyond the string id
        if(FAILED(pNewJob->SetQueueName(pRequestedFile))) {
            dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
            goto Done;
        }       
    }

    //
    // Set the job ID
    if(0xFFFF == (usQueueID = pNewJob->JobID())) {
        ASSERT(FALSE);
        TRACEMSG(ZONE_ERROR, (L"PRINT QUEUE ERROR!:  got an invalid job ID!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }
        
    //
    // Fill out return params and send back the data
    pResponse->ByteCount = 0;
    pResponse->FileID = usQueueID;
    pResponse->WordCount = (sizeof(SMB_OPEN_PRINT_SPOOL_SERVER_RESPONSE) - 1) / sizeof(WORD);
    *puiUsed = sizeof(SMB_OPEN_PRINT_SPOOL_SERVER_RESPONSE);
    
    Done:
        // 
        // Give back our handle
        if(pNewJob) {
            pNewJob->Release();
            pNewJob = 0;
        }    
        if(0 != dwRet) {            
            if(pPrintStream) {
                delete pPrintStream;
            }
        }
        return dwRet;
}


DWORD PrintQueue::SMB_Com_Close_Spool(SMB_PROCESS_CMD *_pRawRequest, 
                                      SMB_PROCESS_CMD *_pRawResponse, 
                                      UINT *puiUsed,
                                      SMB_PACKET *pSMB)
{
    DWORD dwRet = 0;
    SMB_CLOSE_PRINT_SPOOL_CLIENT_REQUEST *pRequest =
            (SMB_CLOSE_PRINT_SPOOL_CLIENT_REQUEST *)_pRawRequest->pDataPortion;
    SMB_CLOSE_PRINT_SPOOL_SERVER_RESPONSE *pResponse = 
            (SMB_CLOSE_PRINT_SPOOL_SERVER_RESPONSE *)_pRawResponse->pDataPortion;
    
    StringTokenizer RequestTokenizer;  
    ce::smart_ptr<TIDState> pTIDState = NULL;
    ce::smart_ptr<ActiveConnection> pMyConnection = NULL;

    //
    // Verify that we have enough memory
    if(_pRawRequest->uiDataSize < sizeof(SMB_CLOSE_PRINT_SPOOL_CLIENT_REQUEST)) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Close_Spool -- not enough memory for request!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }
    if(_pRawResponse->uiDataSize < sizeof(SMB_CLOSE_PRINT_SPOOL_SERVER_RESPONSE)) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Close_Spool -- not enough memory for response!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }        
    
    //
    // Find our connection state        
    if(!(pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {
       TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_INFO_ALLOCATION: -- cant find connection 0x%x!", pSMB->ulConnectionID));
       ASSERT(FALSE);
       dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
       goto Done;    
    }
    
    //
    // Find a TID state 
    if(FAILED(pMyConnection->FindTIDState(_pRawRequest->pSMBHeader->Tid, pTIDState, SEC_READ)) || !pTIDState) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Close_Spool -- couldnt find share state!!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;   
    }
    
    //
    // Close it up
    if(FAILED(pTIDState->Close(pRequest->FileID))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Close_Spool -- closing the job failed!!!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;   
    }
    
    //
    // Remove the share from the TIDState (to prevent it from being aborted
    //   if the connection goes down)
    if(FAILED(pTIDState->RemoveFileStream(pRequest->FileID))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_Com_Close -- couldnt find filestream for FID(%d) to remove from share state!", pRequest->FileID));
        ASSERT(FALSE);
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;  
    }
        
    //
    // Fill out return params and send back the data
    pResponse->ByteCount = 0; 
    pResponse->WordCount = 0;
    *puiUsed = sizeof(SMB_CLOSE_PRINT_SPOOL_SERVER_RESPONSE);
    
    Done:
        return dwRet;
}


PrintStream::PrintStream(PrintJob *_pJob, 
                       TIDState *_pMyState) : SMBFileStream(PRINT_STREAM, _pMyState) 
{
    //
    // For a print stream, the FID is the same as the JobID (see the code
    //   for PrintJob to see that it uses the global FID list for its JobID)
    this->SetFID(_pJob->JobID());
    
    
    //
    // PrintJob is something thats ref counted (the print queue owns a copy
    //   too).  So Addref it.  it will be released in the deconstructor
    pPrintJob = _pJob;
    if(pPrintJob) 
        pPrintJob->AddRef();
}
PrintStream::~PrintStream()
{
    //
    // Destroy the print job if it hasnt already been aborted or hasnt finished
    if(pPrintJob && 
      (0 == (pPrintJob->GetInternalStatus() & (JOB_STATUS_FINISHED | JOB_STATUS_ABORTED)))) {
        PrintJob   *pFoundPrintJob = NULL;
        SMBPrintQueue *pPrintQueue = NULL;
        
        TRACEMSG(ZONE_ERROR, (L"remove printjob %d to TIDState:0x%x because of delete of holder\n", pPrintJob->JobID(), (UINT)this));

        if(FAILED(SMB_Globals::g_pShareManager->SearchForPrintJob(pPrintJob->JobID(), &pFoundPrintJob, &pPrintQueue)) ||
           NULL == pFoundPrintJob ||
           NULL == pPrintQueue) 
        {
            TRACEMSG(ZONE_ERROR, (L"SMBSRV: ~TIDState -- couldnt find print job %d, maybe the job was deleted?", pPrintJob->JobID()));              
            goto Done;
        }  
        ASSERT(pFoundPrintJob == pPrintJob);

        //
        // Set its abort logic
        //   NOTE: I dont set finished here because JobsFinished does
        //   and thats the proper way to get the FINISHED bit set
        pFoundPrintJob->SetInternalStatus(pFoundPrintJob->GetInternalStatus() | 
                                          JOB_STATUS_ABORTED);
        
        //
        // Kill off the job
        pFoundPrintJob->ShutDown();
        
        //
        // Remove it from the spool
        if(FAILED(pPrintQueue->JobsFinished(pFoundPrintJob))) {
            TRACEMSG(ZONE_ERROR, (L"SMBSRV: ~TIDState -- delete the print job from the queue FID(%d)!", pPrintJob->JobID()));
            ASSERT(FALSE);
        }
        
        if(NULL != pFoundPrintJob) {
            pPrintJob->Release();
        }
        
    }
    
    Done:
    //
    // Release our ref count on the job
    if(pPrintJob)
        pPrintJob->Release();   
}

HRESULT 
PrintStream::Read(BYTE *pDest,  DWORD dwOffset, DWORD dwReqSize, DWORD *pdwRead)
{
    ASSERT(FALSE);
    return E_NOTIMPL;
}

HRESULT 
PrintStream::Write(BYTE *pSrc,  DWORD dwOffset, DWORD dwReqSize, DWORD *pdwWritten)
{
    //BUGBUG: make these line up (DWORD and UINT)
    UINT uiWritten; 
    
    //
    // If the job hasnt been sent to the queue, send it now
    if(0 == (pPrintJob->GetInternalStatus() & JOB_STATUS_HAS_DATA)) {    
        SMBPrintQueue *pMyQueue = NULL;
        pPrintJob->SetInternalStatus(pPrintJob->GetInternalStatus() | JOB_STATUS_HAS_DATA);
        
        if(pPrintJob->MyShare()) {
           pMyQueue = pPrintJob->MyShare()->GetPrintQueue();
           pMyQueue->JobReadyForPrint(pPrintJob); 
        } else {
            ASSERT(FALSE);
        }
    }       
    HRESULT hr = pPrintJob->Write(pSrc, dwReqSize, dwOffset, &uiWritten);
    *pdwWritten = uiWritten;
    return hr;
}


HRESULT 
PrintStream::Open(const WCHAR *pFileName,  
                  DWORD dwAccess, 
                  DWORD dwDisposition, 
                  DWORD dwAttributes,
                  DWORD dwShareMode,
                  DWORD *pdwActionTaken,
                  SMBFile_OpLock_PassStruct *pdwOpLock)
{
    HRESULT hr = E_FAIL;   
    SMBPrintQueue *pPrintQueue = NULL;
   
    //
    // If the request is for anything but NULL, fail it    
    if(NULL == pFileName || NULL != pFileName[0]) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: SMB_OpenX Printer -- error filename!"));
        hr = E_ACCESSDENIED;
        goto Done;   
    }   
    if(NULL == pPrintJob->MyShare() || NULL == (pPrintQueue = pPrintJob->MyShare()->GetPrintQueue())) {
        hr = E_ACCESSDENIED;
        goto Done;
    }
    if(FAILED(pPrintJob->SetQueueName(pFileName))) {
        hr = E_FAIL;
        goto Done;
    }
    
    hr = S_OK;
    
    //
    // if we were able to open the file, always say its 2 (2=file didnt exist and was created)
    if(NULL != pdwActionTaken) {
        *pdwActionTaken = 2;
    }
    Done:
        return hr;
}
   
   
HRESULT 
PrintStream::Close() 
{ 
    SMBPrintQueue *pPrintQueue = NULL;
    HRESULT hr = E_FAIL;
    
    //
    // We always should have a print job!!
    if(NULL == pPrintJob) {
        ASSERT(FALSE);
        hr = E_UNEXPECTED;
        goto Done;
    }
    
    //
    // Get the print queue for this guy
    if(NULL == pPrintJob->MyShare() || NULL == (pPrintQueue = pPrintJob->MyShare()->GetPrintQueue())) {
        hr = E_UNEXPECTED;
        goto Done;
    }
   
    //
    // Close the spool
    if(FAILED(pPrintQueue->JobsFinished(pPrintJob))){
        TRACEMSG(ZONE_ERROR, (L"SMB_PrintStream: Close() -- error setting Jobs Finished on print queue!"));
        hr = E_UNEXPECTED;
        goto Done; 
    }
    
    //nobody should set hr to success yet
    ASSERT(FAILED(hr));
    hr = S_OK;
    Done:
        return hr;
   
}

⌨️ 快捷键说明

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