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

📄 writer.c

📁 用于串口的测试调试
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-----------------------------------------------------------------------------
    This is a part of the Microsoft Source Code Samples. 
    Copyright (C) 1995 Microsoft Corporation.
    All rights reserved. 
    This source code is only intended as a supplement to 
    Microsoft Development Tools and/or WinHelp documentation.
    See these sources for detailed information regarding the 
    Microsoft samples programs.

    MODULE: Writer.c

    PURPOSE: Handles all port writing and write request linked list

    FUNCTIONS:
        WriterProc - Thread procedure handles all writing
        HandleWriteRequests - calls writing procedures based on write request type
        WriterTerminate     - sets the transfer complete event
        WriterFile          - Writes a file transfer packet out the port
        WriterFileStart     - initializes a file transfer
        WriterChar          - Writes a char out the port
        WriterGeneric       - Actual writing funciton handles all i/o operations
        WriterAddNewNode    - Adds new write request packet to linked list
        WriterAddNewNodeTimeout - Adds new node, but can timeout.
        WriterAddExistingNode - Modifies an existing packet and 
                                links it to the linked list
        AddToLinkedList     - Adds the node to the list
        RemoveFromLinkedList - Removes a node
        
-----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------

    Write request packets are put into the writer request linked list
    and processed by the functions in this module.

    The members of the WRITEREQUEST structure are described as follows:
              
          DWORD     dwWriteType;       // dictates the type of request
          DWORD     dwSize;            // size of data to write
          char      ch;                // character to send
          char *    lpBuf;             // address of data buffer
          HANDLE    hHeap;             // heap containing data buffer
          HWND      hWndProgress;      // hwnd for progress indicator


    dwWriteType can be one of the following values:
                
        WRITE_CHAR       0x01    // indicates the request is for sending a single character

            WriteRequest.ch contains the character to send
                             

        WRITE_FILE       0x02    // indicates the request is for a file transfer

            WriteRequest.dwSize       : contains the size of the buffer
            WriteReqeust.lpBuf        : points to the buffer containing the data to send
            WriteRequest.hHeap        : contains the handle of the heap containing the data buffer
            WriteReqeust.hWndProgress : contains the hwnd of the file transfer progress indicator


        WRITE_FILESTART  0x03    // indicates the a file transfer is starting

            WriteRequest.dwSize : indicates the total size of the file


        WRITE_FILEEND    0x04    // indicates the last block in a file transfer
      

        WRITE_ABORT      0x05    // indicates the file transfer is aborted

        WRITE_BLOCK      0x06    // indicates the request is for sending
                                 // a block of data
             WriteRequest.dwSize : containst the size of the buffer
             WriteRequest.lpBuf  : points to the buffer containing the data to send


-----------------------------------------------------------------------------*/

#include <windows.h>
#include <commctrl.h>

#include "MTTTY.h"

//
// Prototypes for function called only within this file
//
PWRITEREQUEST RemoveFromLinkedList( PWRITEREQUEST );
BOOL WriterAddExistingNode( PWRITEREQUEST, DWORD, DWORD, char, char *, HANDLE, HWND );
BOOL WriterAddNewNode( DWORD, DWORD, char, char *, HANDLE, HWND );
void HandleWriteRequests( void );
void WriterFileStart( DWORD );
void WriterComplete( void );
void WriterAbort( PWRITEREQUEST );
void AddToLinkedList( PWRITEREQUEST );
void AddToFrontOfLinkedList( PWRITEREQUEST );
void WriterGeneric( char *, DWORD );
void WriterFile( PWRITEREQUEST );
void WriterChar( PWRITEREQUEST );
void WriterBlock( PWRITEREQUEST );


/*-----------------------------------------------------------------------------

FUNCTION: WriterProc(LPVOID)

PURPOSE: Thread function controls console input and comm port writing

HISTORY:   Date:      Author:     Comment:
           10/27/95   AllenD      Wrote it

-----------------------------------------------------------------------------*/
DWORD WINAPI WriterProc(LPVOID lpV)
{
    SYSTEM_INFO sysInfo;
    HANDLE hArray[2];
    DWORD dwRes;
    DWORD dwSize;
    BOOL fDone = FALSE;

    //
    // create a heap for WRITE_REQUEST packets
    //
    GetSystemInfo(&sysInfo);
    ghWriterHeap = HeapCreate(0, sysInfo.dwPageSize*2, sysInfo.dwPageSize*4);
    if (ghWriterHeap == NULL)
        ErrorInComm("HeapCreate (write request heap)");

    //
    // create synchronization events for write requests and file transfers
    //
    ghWriterEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (ghWriterEvent == NULL)
        ErrorInComm("CreateEvent(writ request event)");

    ghTransferCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (ghTransferCompleteEvent == NULL)
        ErrorInComm("CreateEvent(transfer complete event)");

    //
    // initialize write request linked list
    //
    dwSize = sizeof(WRITEREQUEST);
    gpWriterHead = HeapAlloc(ghWriterHeap, HEAP_ZERO_MEMORY, dwSize);
    gpWriterTail = HeapAlloc(ghWriterHeap, HEAP_ZERO_MEMORY, dwSize);
    gpWriterHead->pNext = gpWriterTail;
    gpWriterTail->pPrev = gpWriterHead;

    hArray[0] = ghWriterEvent;
    hArray[1] = ghThreadExitEvent;
   
    while ( !fDone ) {
        dwRes = WaitForMultipleObjects(2, hArray, FALSE, WRITE_CHECK_TIMEOUT);
        switch(dwRes)
        {
            case WAIT_TIMEOUT:
                    break;

            case WAIT_FAILED:
                    ErrorReporter("WaitForMultipleObjects( writer proc )");
                    break;

            //
            // write request event
            //
            case WAIT_OBJECT_0:
                    HandleWriteRequests();
                    break;
            //
            // thread exit event
            //
            case WAIT_OBJECT_0 + 1:
                    fDone = TRUE;
                    break;
        }
    }

    CloseHandle(ghTransferCompleteEvent);
    CloseHandle(ghWriterEvent);

    //
    // Destroy WRITE_REQUEST heap
    //
    HeapDestroy(ghWriterHeap);
    return 1;
}

/*-----------------------------------------------------------------------------

FUNCTION: HandleWriteRequests

PURPOSE: Retrieves write request and calls the proper function
         depending on the write request type.

HISTORY:   Date:      Author:     Comment:
           10/27/95   AllenD      Wrote it

            5/25/96   AllenD      Modified to include

-----------------------------------------------------------------------------*/
void HandleWriteRequests()
{
    PWRITEREQUEST pWrite;
    BOOL fRes;
    
    pWrite = gpWriterHead->pNext;
    
    while(pWrite != gpWriterTail) {
        switch(pWrite->dwWriteType)
        {
            case WRITE_CHAR:          WriterChar(pWrite);                break;

            case WRITE_FILESTART:     WriterFileStart(pWrite->dwSize);   break;

            case WRITE_FILE:          WriterFile(pWrite);
                                      //
                                      // free data block
                                      //
                                      EnterCriticalSection(&gcsDataHeap);
                                      fRes = HeapFree(pWrite->hHeap, 0, pWrite->lpBuf);
                                      LeaveCriticalSection(&gcsDataHeap);
                                      if (!fRes)
                                          ErrorReporter("HeapFree(file transfer buffer)");
                                      break;

            case WRITE_FILEEND:       WriterComplete();                 break;

            case WRITE_ABORT:         WriterAbort(pWrite);              break;

            case WRITE_BLOCK:         WriterBlock(pWrite);              break;

            default:                  ErrorReporter("Bad write request"); 
                                      break;
        }

        //
        // remove current node and get next node
        //
        pWrite = RemoveFromLinkedList(pWrite);
        pWrite = gpWriterHead->pNext;
    }

    return;
}

/*-----------------------------------------------------------------------------

FUNCTION: WriterComplete

PURPOSE: Handle an transfer completion

HISTORY:   Date:      Author:     Comment:
            1/26/96   AllenD      Wrote it

-----------------------------------------------------------------------------*/
void WriterComplete()
{
    if (!SetEvent(ghTransferCompleteEvent))
        ErrorReporter("SetEvent (transfer complete event)");

    return;
}

/*-----------------------------------------------------------------------------

FUNCTION: WriterAbort

PURPOSE: Handle an transfer abort.  Delete all writer packets.
         Data packets get deleted with the entire data heap in the transfer
         thread.

HISTORY:   Date:      Author:     Comment:
            1/26/96   AllenD      Wrote it

-----------------------------------------------------------------------------*/
void WriterAbort(PWRITEREQUEST pAbortNode)
{
    PWRITEREQUEST pCurrent;
    PWRITEREQUEST pNextNode;
    BOOL fRes;
    int i = 0;
    char szMessage[30];

    EnterCriticalSection(&gcsWriterHeap);
    // remove all nodes after me
    pCurrent = pAbortNode->pNext;

    while (pCurrent != gpWriterTail) {
        pNextNode = pCurrent->pNext;
        fRes = HeapFree(ghWriterHeap, 0, pCurrent);
        if (!fRes)
            break;
        i++;
        pCurrent = pNextNode;
    }

    pAbortNode->pNext = gpWriterTail;
    gpWriterTail->pPrev = pAbortNode;
    LeaveCriticalSection(&gcsWriterHeap);

    wsprintf(szMessage, "%d packets ignored.\n", i);
    OutputDebugString(szMessage);

    if (!fRes)
        ErrorReporter("HeapFree (Writer heap)");

    if (!SetEvent(ghTransferCompleteEvent))
        ErrorReporter("SetEvent (transfer complete event)");

    return;
}

/*-----------------------------------------------------------------------------

FUNCTION: WriterFile(PWRITEREQUEST)

PURPOSE: Handles a file transfer request

PARAMETERS:
    pWrite - pointer to write request packet

COMMENTS: WRITEREQUEST packet contains the following:
            lpBuf       : Address of data buffer
            dwSize      : size of data buffer
            hWndProgress: hwnd of progress indicator
            hHeap       : handle to heap which contains the data buffer

HISTORY:   Date:      Author:     Comment:
           10/27/95   AllenD      Wrote it

-----------------------------------------------------------------------------*/
void WriterFile(PWRITEREQUEST pWrite)
{
    WriterGeneric(pWrite->lpBuf, pWrite->dwSize);

    //
    // update progress indicator (even if aborting)
    //
    if (!PostMessage(pWrite->hWndProgress, PBM_STEPIT, 0, 0))
        ErrorReporter("PostMessage (file transfer status)");

    return;
}

/*-----------------------------------------------------------------------------

FUNCTION: WriterBlock(PWRITEREQUEST)

PURPOSE: Sends a block of characters

PARAMETERS:
    pWrite - pointer to write request packet

COMMENTS: WRITEREQUEST packet contains the following:
            lpBuf       : Address of data buffer
            dwSize      : size of data buffer

HISTORY:   Date:      Author:     Comment:
            1/29/96   AllenD      Wrote it

-----------------------------------------------------------------------------*/
void WriterBlock(PWRITEREQUEST pWrite)
{   

    WriterGeneric(pWrite->lpBuf, pWrite->dwSize);
    return;
}

/*-----------------------------------------------------------------------------

FUNCTION: WriterFileStart(DWORD)

PURPOSE: Initializes a file transfer (send)

PARAMETER:
    dwFileSize - not used

COMMENTS: Provided to do any special initializations for transfer

HISTORY:   Date:      Author:     Comment:
           10/27/95   AllenD      Wrote it
           11/20/95   AllenD      Took out all test code

-----------------------------------------------------------------------------*/
void WriterFileStart(DWORD dwFileSize)
{
    return;
}

/*-----------------------------------------------------------------------------

FUNCTION: WriterChar(PWRITEREQUEST)

PURPOSE: Handles sending characters

PARAMETER:
    pWrite - pointer to write request packet

COMMENTS: WRITEREQUEST packet contains the following:
            ch : character to send

HISTORY:   Date:      Author:     Comment:
           10/27/95   AllenD      Wrote it

-----------------------------------------------------------------------------*/
void WriterChar(PWRITEREQUEST pWrite)
{
    WriterGeneric(&(pWrite->ch), 1);
    return;
}

/*-----------------------------------------------------------------------------

FUNCTION: WriterGeneric(char *, DWORD)

PURPOSE: Handles sending all types of data

PARAMETER:
    lpBuf     - pointer to data buffer
    dwToWrite - size of buffer

HISTORY:   Date:      Author:     Comment:
           10/27/95   AllenD      Wrote it

-----------------------------------------------------------------------------*/
void WriterGeneric(char * lpBuf, DWORD dwToWrite)
{
    OVERLAPPED osWrite = {0};
    HANDLE hArray[2];
    DWORD dwWritten;
    DWORD dwRes;

    //
    // If no writing is allowed, then just return
    //
    if (NOWRITING(TTYInfo))
        return ;

    //
    // create this writes overlapped structure hEvent
    //
    osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

⌨️ 快捷键说明

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