📄 transfer.c
字号:
/*-----------------------------------------------------------------------------
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: Transfer.c
PURPOSE: Transfer a file (receive or send).
FUNCTIONS:
TransferRepeatCreate - Preps program for a repeated send
TransferRepeatDestroy - Completes a repeated send
TransferRepeatDo - Sends the data to the writer thread
TransferFileTextStart - Preps program for a text file send
TransferFileTextEnd - Completes a file transfer
TransferThreadProc - Thread procedure to do actual transfer
TransferFileText - Preps program for a text file send
ReceiveFileText - Preps program for a text file capture
OpenTheFile - Opens a file
CreateTheFile - Creates a file
GetTransferSizes - Determines transfer metrics from file and buffer sizes
ShowTransferStatistics - Displays transfer stats
CheckForMessges - Peek message check to keep things flowing
during a transfer
SendFile - Send a file
CaptureFile - Sets the receive state for file capture
-----------------------------------------------------------------------------*/
#include <windows.h>
#include <commctrl.h>
#include "mttty.h"
//
// Globals used in this file only
//
HANDLE hFile;
HANDLE hTransferAbortEvent;
HANDLE hTransferThread;
UINT uTimerId;
MMRESULT mmTimer = (MMRESULT)NULL;
char * lpBuf;
//
// Prototypes for functions called only within this file
//
DWORD WINAPI TransferThreadProc(LPVOID);
HANDLE OpenTheFile( LPCTSTR );
HANDLE CreateTheFile( LPCTSTR );
void CaptureFile( HANDLE, HWND );
UINT CheckForMessages( void );
BOOL GetTransferSizes( HANDLE, DWORD *, DWORD *, DWORD *);
/*-----------------------------------------------------------------------------
FUNCTION: TransferRepeatCreate(LPCTSTR, DWORD)
PURPOSE: Prepares program for a repeated text file transfer (send)
PARAMETERS:
lpstrFileName - name of file selected to send
dwFrequency - frequency of timer
COMMENTS: This function sets up a window timer to fire off
every so often. When it fires, TransferRepeatDo is
called with the same name as above. This causes the file transfer
to actuall take place.
TransferRepeatDestroy is called to kill the timer.
This function disables certain menu items that should not be
available for the duration of a repeated send even if the actual
Tx is not taking place.
HISTORY: Date: Author: Comment:
1/29/96 AllenD Wrote it
-----------------------------------------------------------------------------*/
void TransferRepeatCreate(LPCTSTR lpszFileName, DWORD dwFrequency)
{
HMENU hMenu;
UINT MenuFlags ;
DWORD dwFileSize;
DWORD dwMaxPackets;
DWORD dwPacketSize;
DWORD dwRead;
//
// open the file
//
hFile = OpenTheFile(lpszFileName);
if (hFile == INVALID_HANDLE_VALUE)
return;
//
// modify transfer menu
//
hMenu = GetMenu(ghwndMain);
MenuFlags = MF_DISABLED | MF_GRAYED;
EnableMenuItem(hMenu, ID_TRANSFER_SENDFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_SENDREPEATEDLY, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_ABORTREPEATEDSENDING, MF_ENABLED);
EnableMenuItem(hMenu, ID_TRANSFER_RECEIVEFILETEXT, MenuFlags);
//
// enable abort button and progress bar
//
SetWindowText(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), "Abort Tx");
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), SW_SHOW);
if (!GetTransferSizes(hFile, &dwPacketSize, &dwMaxPackets, &dwFileSize)) {
TransferRepeatDestroy();
return;
}
// Allocate a buffer
lpBuf = HeapAlloc(ghWriterHeap, 0, dwFileSize);
if (lpBuf == NULL) {
ErrorReporter("HeapAlloc (data block from writer heap).\r\nFile is too large");
TransferRepeatDestroy();
return;
}
// fill the buffer
if (!ReadFile(hFile, lpBuf, dwFileSize, &dwRead, NULL)) {
ErrorReporter("Can't read from file\n");
TransferRepeatDestroy();
}
if (dwRead != dwFileSize)
ErrorReporter("Didn't read entire file\n");
//mmTimer = timeSetEvent((UINT) dwFrequency, 10, TransferRepeatDo, dwRead, TIME_PERIODIC);
if (mmTimer == (MMRESULT) NULL) {
ErrorReporter("Could not create mm timer");
TransferRepeatDestroy();
}
else {
REPEATING(TTYInfo) = TRUE;
OutputDebugString("Timer setup.\n");
}
return;
}
/*-----------------------------------------------------------------------------
FUNCTION: TransferRepeatDestroy( void )
PURPOSE: Stops a repeated text file transfer (send)
COMMENTS: Kills the repeated-send timer.
HISTORY: Date: Author: Comment:
1/29/96 AllenD Wrote it
-----------------------------------------------------------------------------*/
void TransferRepeatDestroy()
{
HMENU hMenu;
DWORD MenuFlags;
MMRESULT mmRes;
if (mmTimer != (MMRESULT) NULL) {
// mmRes = timeKillEvent(mmTimer);
if (mmRes != TIMERR_NOERROR)
ErrorReporter("Can't kill mm timer");
mmTimer = (MMRESULT) NULL;
}
// close the file
CloseHandle(hFile);
// inform writer to abort all pending write requests
if (!WriterAddFirstNodeTimeout(WRITE_ABORT, 0, 0, NULL, NULL, NULL, 500))
ErrorReporter("Couldn't inform writer to abort sending.");
// free the buffer
if (!HeapFree(ghWriterHeap, 0, lpBuf))
ErrorReporter("HeapFree (data block from writer heap)");
REPEATING(TTYInfo) = FALSE;
OutputDebugString("Repeated transfer destroyed.\r\n");
//
// enable transfer menu
//
hMenu = GetMenu(ghwndMain);
MenuFlags = MF_ENABLED;
EnableMenuItem(hMenu, ID_TRANSFER_ABORTREPEATEDSENDING, MF_DISABLED | MF_GRAYED);
EnableMenuItem(hMenu, ID_TRANSFER_SENDFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_SENDREPEATEDLY, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_RECEIVEFILETEXT, MenuFlags);
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), SW_HIDE);
return;
}
/*-----------------------------------------------------------------------------
FUNCTION: TransferRepeatDo( void )
PURPOSE: Performs a single text file transfer (send)
COMMENTS: Allocates a block to hold the file.
Prepares the writer packet.
HISTORY: Date: Author: Comment:
1/29/96 AllenD Wrote it
-----------------------------------------------------------------------------*/
void CALLBACK TransferRepeatDo( UINT uTimerId,
UINT uRes,
DWORD dwFileSize,
DWORD dwRes1,
DWORD dwRes2)
{
if (!WriterAddNewNodeTimeout(WRITE_BLOCK, dwFileSize, 0, lpBuf, 0, 0, 10))
PostMessage(ghwndMain, WM_COMMAND, ID_TRANSFER_ABORTSENDING, MAKELPARAM(IDC_ABORTBTN, 0) );
return;
}
/*-----------------------------------------------------------------------------
FUNCTION: TransferFileTextStart(LPCTSTR)
PURPOSE: Prepares program for a text file transfer (send)
PARAMETERS:
lpstrFileName - name of file selected to send
COMMENTS: Modifies menus and dialog control, then restores them
HISTORY: Date: Author: Comment:
1/26/96 AllenD Wrote it
-----------------------------------------------------------------------------*/
void TransferFileTextStart(LPCTSTR lpstrFileName)
{
DWORD dwThreadId;
HMENU hMenu;
UINT MenuFlags ;
//
// open the file
//
hFile = OpenTheFile(lpstrFileName);
if (hFile == INVALID_HANDLE_VALUE)
return;
//
// modify transfer menu
//
hMenu = GetMenu(ghwndMain);
MenuFlags = MF_DISABLED | MF_GRAYED;
EnableMenuItem(hMenu, ID_TRANSFER_SENDFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_SENDREPEATEDLY, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_ABORTSENDING, MF_ENABLED);
EnableMenuItem(hMenu, ID_TRANSFER_RECEIVEFILETEXT, MenuFlags);
//
// enable abort button and progress bar
//
gfAbortTransfer = FALSE;
SetWindowText(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), "Abort Tx");
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), SW_SHOW);
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_TRANSFERPROGRESS), SW_SHOW);
// start the transfer thread
hTransferAbortEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (hTransferAbortEvent == NULL)
ErrorReporter("CreateEvent(Transfer Abort Event)");
hTransferThread = CreateThread(NULL, 0,
TransferThreadProc,
(LPVOID) hFile, 0, &dwThreadId);
if (hTransferThread == NULL) {
ErrorReporter("CreateThread (Transfer Thread)");
TransferFileTextEnd();
}
else
TRANSFERRING(TTYInfo) = TRUE;
return;
}
/*-----------------------------------------------------------------------------
FUNCTION: TransferFileTextEnd()
PURPOSE: Stops a text file transfer (send)
COMMENTS: Modifies menus and dialog control, then restores them
HISTORY: Date: Author: Comment:
1/26/96 AllenD Wrote it
-----------------------------------------------------------------------------*/
void TransferFileTextEnd()
{
HMENU hMenu;
UINT MenuFlags ;
// stop the transfer thread
SetEvent(hTransferAbortEvent);
OutputDebugString("Waiting for transfer thread...\n");
if (WaitForSingleObject(hTransferThread, 3000) != WAIT_OBJECT_0) {
ErrorReporter("TransferThread didn't stop.");
TerminateThread(hTransferThread, 0);
}
else
OutputDebugString("Transfer thread exited\n");
CloseHandle(hTransferAbortEvent);
CloseHandle(hTransferThread);
TRANSFERRING(TTYInfo) = FALSE;
//
// enable transfer menu
//
hMenu = GetMenu(ghwndMain);
MenuFlags = MF_ENABLED;
EnableMenuItem(hMenu, ID_TRANSFER_SENDFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_SENDREPEATEDLY, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_RECEIVEFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_ABORTSENDING, MF_DISABLED | MF_GRAYED);
//
// disable abort button and progress bar
//
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), SW_HIDE);
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_TRANSFERPROGRESS), SW_HIDE);
//
// close the file
//
CloseHandle(hFile);
}
/*-----------------------------------------------------------------------------
FUNCTION: ReceiveFileText(LPCTSTR)
PURPOSE: Prepares program for a text file transfer (receive)
PARAMETERS:
lpstrFileName - name of file selected for receiving
COMMENTS: Modifies menus and control, then restores them
HISTORY: Date: Author: Comment:
10/27/95 AllenD Wrote it
-----------------------------------------------------------------------------*/
void ReceiveFileText(LPCTSTR lpstrFileName)
{
HMENU hMenu;
UINT MenuFlags ;
//
// create the file
//
ghFileCapture = CreateTheFile(lpstrFileName);
if (ghFileCapture == INVALID_HANDLE_VALUE)
return;
/*
setup transfer
disable file menu
*/
hMenu = GetMenu(ghwndMain);
MenuFlags = MF_DISABLED | MF_GRAYED;
EnableMenuItem(hMenu, ID_FILE_CONNECT, MenuFlags);
EnableMenuItem(hMenu, ID_FILE_DISCONNECT, MenuFlags);
//
// disable transfer menu
//
EnableMenuItem(hMenu, ID_TRANSFER_SENDFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_RECEIVEFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_SENDREPEATEDLY, MenuFlags);
//
// enable abort button and progress bar
//
gfAbortTransfer = FALSE;
SetWindowText(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), "Close Capture");
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), SW_SHOW);
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_TRANSFERPROGRESS), SW_SHOW);
//
// send file until done or abort
//
CaptureFile(ghFileCapture, GetDlgItem(ghWndStatusDlg, IDC_TRANSFERPROGRESS));
//
// enable menu
//
hMenu = GetMenu(ghwndMain);
MenuFlags = MF_ENABLED;
ChangeConnection(ghwndMain, CONNECTED(TTYInfo));
//
// enable transfer menu
//
EnableMenuItem(hMenu, ID_TRANSFER_SENDFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_RECEIVEFILETEXT, MenuFlags);
EnableMenuItem(hMenu, ID_TRANSFER_SENDREPEATEDLY, MenuFlags);
//
// hide abort button and progress bar
//
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_ABORTBTN), SW_HIDE);
ShowWindow(GetDlgItem(ghWndStatusDlg, IDC_TRANSFERPROGRESS), SW_HIDE);
gfAbortTransfer = FALSE;
CloseHandle(ghFileCapture);
return; // returns when file transfer is complete or aborted
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -