479 lines
11 KiB
C
479 lines
11 KiB
C
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Microsoft Windows
|
|||
|
//
|
|||
|
// Copyright (C) Microsoft Corporation, 1997 - 1999
|
|||
|
//
|
|||
|
// File: xfer.h
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
|
|||
|
#ifndef _XFER_H_
|
|||
|
#define _XFER_H_
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
#define SERVICE_NAME_1 "OBEX:IrXfer"
|
|||
|
#define SERVICE_NAME_2 "OBEX"
|
|||
|
|
|||
|
|
|||
|
#define GUARD_MAGIC 0x45454545
|
|||
|
|
|||
|
#define TIMEOUT_INFINITE (~0UL)
|
|||
|
#define ERROR_DESCRIPTION_LENGTH 1000
|
|||
|
#define IRDA_DEVICE_NAME_LENGTH 22
|
|||
|
|
|||
|
//
|
|||
|
// OBEX parameter codes
|
|||
|
//
|
|||
|
|
|||
|
#define OBEX_PARAM_UNICODE 0x00
|
|||
|
#define OBEX_PARAM_STREAM 0x40
|
|||
|
#define OBEX_PARAM_1BYTE 0x80
|
|||
|
#define OBEX_PARAM_4BYTE 0xC0
|
|||
|
|
|||
|
#define OBEX_PARAM_TYPE_MASK 0xC0
|
|||
|
|
|||
|
#define OBEX_PARAM_COUNT ( 0x00 | OBEX_PARAM_4BYTE )
|
|||
|
#define OBEX_PARAM_NAME ( 0x01 | OBEX_PARAM_UNICODE )
|
|||
|
#define OBEX_PARAM_LENGTH ( 0x03 | OBEX_PARAM_4BYTE )
|
|||
|
#define OBEX_PARAM_UNIX_TIME ( 0x04 | OBEX_PARAM_4BYTE )
|
|||
|
#define OBEX_PARAM_ISO_TIME ( 0x04 | OBEX_PARAM_STREAM )
|
|||
|
#define OBEX_PARAM_BODY ( 0x08 | OBEX_PARAM_STREAM )
|
|||
|
#define OBEX_PARAM_BODY_END ( 0x09 | OBEX_PARAM_STREAM )
|
|||
|
#define OBEX_PARAM_WHO ( 0x0A | OBEX_PARAM_STREAM )
|
|||
|
// #define OBEX_PARAM_LEN 1
|
|||
|
|
|||
|
#define PRIVATE_PARAM_WIN32_ERROR ( 0x30 | OBEX_PARAM_4BYTE )
|
|||
|
|
|||
|
// for xfer.c
|
|||
|
|
|||
|
typedef struct {
|
|||
|
BOOL fXferInProgress; // transfer in progress
|
|||
|
__int64 dwTotalSize; // total size of transfer
|
|||
|
__int64 dwTotalSent; // number of bytes sent in this transfer
|
|||
|
__int64 dwFileSize; // total size of current file
|
|||
|
__int64 dwFileSent; // number of bytes sent of the current file
|
|||
|
} DATA_XFER, *LPDATA_XFER;
|
|||
|
|
|||
|
typedef struct {
|
|||
|
FILETIME filetime; // file time
|
|||
|
WCHAR szFileName[MAX_PATH]; // name of file
|
|||
|
WCHAR szFileSave[MAX_PATH]; // path+name of final file
|
|||
|
WCHAR szFileTemp[MAX_PATH]; // path+name of temp file used
|
|||
|
HANDLE hFile; // file handle (of szFileTemp)
|
|||
|
} DATA_FILE, *LPDATA_FILE;
|
|||
|
|
|||
|
// for obex.c
|
|||
|
|
|||
|
typedef struct {
|
|||
|
BYTE1 b1Flags; // setpath flags
|
|||
|
BYTE1 b1Constants; // setpath constants
|
|||
|
} DATA_PATH, *LPDATA_PATH;
|
|||
|
|
|||
|
typedef struct {
|
|||
|
BOOL fWaiting; // indicates if waiting for a reply
|
|||
|
BYTE1 b1Status; // response status (error/success)
|
|||
|
} DATA_REPLY, *LPDATA_REPLY;
|
|||
|
|
|||
|
typedef enum {
|
|||
|
osIDLE = 0,
|
|||
|
osCONN = 1,
|
|||
|
osFILE = 2
|
|||
|
} OBEXSTATE;
|
|||
|
|
|||
|
typedef struct {
|
|||
|
LPSTORE lpStore;
|
|||
|
OBEXSTATE state;
|
|||
|
BYTE1 b1Version; // peer's version of obex
|
|||
|
BYTE1 b1Flags; // connection flags
|
|||
|
BYTE2 b2MaxPacket; // peer's maximum packet size
|
|||
|
} DATA_CONN, *LPDATA_CONN;
|
|||
|
|
|||
|
// for status.c
|
|||
|
|
|||
|
typedef struct {
|
|||
|
DWORD dwDeviceID;
|
|||
|
BOOL fClear;
|
|||
|
} TARGET_ITEM, *LPTARGET_ITEM;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//-------------------------------------
|
|||
|
|
|||
|
|
|||
|
enum TRANSFER_STATE
|
|||
|
{
|
|||
|
BLANK,
|
|||
|
CONNECTING,
|
|||
|
ACCEPTING,
|
|||
|
READING,
|
|||
|
WRITING,
|
|||
|
CLOSING
|
|||
|
};
|
|||
|
|
|||
|
enum OBEX_DIALECT
|
|||
|
{
|
|||
|
dialUnknown = 0,
|
|||
|
dialWin95,
|
|||
|
dialNt5
|
|||
|
};
|
|||
|
|
|||
|
typedef class FILE_TRANSFER * PFILE_TRANSFER;
|
|||
|
|
|||
|
|
|||
|
class FILE_TRANSFER
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
FILE_TRANSFER( );
|
|||
|
~FILE_TRANSFER();
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
Xfer_Init(
|
|||
|
wchar_t * files,
|
|||
|
unsigned length,
|
|||
|
OBEX_DIALECT dialect ,
|
|||
|
OBEX_DEVICE_TYPE DeviceType,
|
|||
|
BOOL CreateSocket,
|
|||
|
SOCKET ListenSocket
|
|||
|
);
|
|||
|
|
|||
|
BOOL
|
|||
|
SendReplyObex(
|
|||
|
BYTE1 ObexCode
|
|||
|
);
|
|||
|
|
|||
|
BOOL
|
|||
|
SendReplyWin32(
|
|||
|
BYTE1 b1Opcode,
|
|||
|
DWORD status
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
BeginSend(
|
|||
|
DWORD DeviceId,
|
|||
|
OBEX_DEVICE_TYPE DeviceType,
|
|||
|
error_status_t * pStatus,
|
|||
|
FAILURE_LOCATION * pLocation
|
|||
|
);
|
|||
|
|
|||
|
void Deactivate();
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
SyncAccept(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
handle_t _rpcHandle;
|
|||
|
COOKIE _cookie;
|
|||
|
|
|||
|
MUTEX * _mutex;
|
|||
|
|
|||
|
inline long
|
|||
|
DecrementRefCount()
|
|||
|
{
|
|||
|
|
|||
|
EnterCriticalSection(&m_Lock);
|
|||
|
|
|||
|
long count = --_refs;
|
|||
|
|
|||
|
DbgLog3(SEV_INFO, "[%x] %p: refs = %d\n", (DWORD) _cookie, this, count);
|
|||
|
|
|||
|
if (0 == count) {
|
|||
|
#if DBG
|
|||
|
DbgPrint("irmon: freeing transfer\n");
|
|||
|
#endif
|
|||
|
LeaveCriticalSection(&m_Lock);
|
|||
|
delete this;
|
|||
|
return count;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
LeaveCriticalSection(&m_Lock);
|
|||
|
}
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
inline BOOL
|
|||
|
IsActive(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
return (_state != ACCEPTING);
|
|||
|
}
|
|||
|
|
|||
|
inline long
|
|||
|
IncrementRefCount()
|
|||
|
{
|
|||
|
|
|||
|
EnterCriticalSection(&m_Lock);
|
|||
|
|
|||
|
long count = ++_refs;
|
|||
|
|
|||
|
DbgLog3(SEV_INFO, "[%x] %p: refs = %d\n", (DWORD) _cookie, this, count);
|
|||
|
|
|||
|
LeaveCriticalSection(&m_Lock);
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void Cancel()
|
|||
|
{
|
|||
|
_fCancelled = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
COOKIE
|
|||
|
GetCookie(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
return _cookie;
|
|||
|
}
|
|||
|
|
|||
|
void Send();
|
|||
|
|
|||
|
void RecordDeviceName( SOCKADDR_IRDA * s );
|
|||
|
|
|||
|
VOID
|
|||
|
StopListening(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
IncrementRefCount();
|
|||
|
EnterCriticalSection(&m_Lock);
|
|||
|
|
|||
|
m_StopListening=TRUE;
|
|||
|
if (m_ListenSocket != INVALID_SOCKET) {
|
|||
|
|
|||
|
closesocket(m_ListenSocket);
|
|||
|
m_ListenSocket=INVALID_SOCKET;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
LeaveCriticalSection(&m_Lock);
|
|||
|
DecrementRefCount();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
RecordIpDeviceName(
|
|||
|
sockaddr_in * Address
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
CRITICAL_SECTION m_Lock;
|
|||
|
BOOL m_StopListening;
|
|||
|
|
|||
|
SOCKET m_ListenSocket;
|
|||
|
OBEX_DEVICE_TYPE m_DeviceType;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL _fCancelled;
|
|||
|
BOOL _fInUiReceiveList;
|
|||
|
XFER_TYPE _xferType;
|
|||
|
TRANSFER_STATE _state;
|
|||
|
SOCKET _socket;
|
|||
|
|
|||
|
|
|||
|
wchar_t * _files;
|
|||
|
long _refs;
|
|||
|
WSABUF _buffers;
|
|||
|
HANDLE _event;
|
|||
|
BOOL _fWriteable;
|
|||
|
|
|||
|
OBEX_DIALECT _dialect;
|
|||
|
|
|||
|
wchar_t _DeviceName[MAX_PATH];
|
|||
|
|
|||
|
WSAOVERLAPPED _overlapped;
|
|||
|
HANDLE _waitHandle;
|
|||
|
BYTE _buffer[ cbSOCK_BUFFER_SIZE + 16 + sizeof(SOCKADDR_IRDA) + 16 + sizeof(SOCKADDR_IRDA) ];
|
|||
|
DWORD _guard;
|
|||
|
|
|||
|
void
|
|||
|
HandleClosure(
|
|||
|
DWORD error
|
|||
|
);
|
|||
|
|
|||
|
// for sock.c
|
|||
|
|
|||
|
|
|||
|
error_status_t Sock_Request( LPVOID lpvData, DWORD dwDataSize );
|
|||
|
error_status_t Sock_Respond( LPVOID lpvData, DWORD dwDataSize );
|
|||
|
|
|||
|
error_status_t Sock_EstablishConnection( DWORD dwDeviceID ,OBEX_DEVICE_TYPE DeviceType);
|
|||
|
|
|||
|
VOID Sock_BreakConnection( SOCKET * pSock );
|
|||
|
|
|||
|
error_status_t _SendDataOnSocket( SOCKET sock, LPVOID lpvData, DWORD dwDataSize );
|
|||
|
|
|||
|
VOID _BreakConnection( SOCKET sock );
|
|||
|
VOID _ReadConnection( SOCKET sock );
|
|||
|
|
|||
|
error_status_t Sock_CheckForReply( long Timeout );
|
|||
|
|
|||
|
// for xfer.c
|
|||
|
|
|||
|
UINT _uObjsReceived;
|
|||
|
WCHAR _szRecvFolder[MAX_PATH];
|
|||
|
DATA_FILE _dataFileRecv;
|
|||
|
DATA_XFER _dataXferRecv;
|
|||
|
|
|||
|
BOOL Xfer_FileSetSize( BYTE4 b4Size );
|
|||
|
error_status_t Xfer_FileWriteBody( LPVOID lpvData, BYTE2 b2Size, BOOL fFinal );
|
|||
|
|
|||
|
VOID Xfer_ConnEnd( VOID );
|
|||
|
error_status_t Xfer_ConnStart( VOID );
|
|||
|
VOID Xfer_FileAbort( VOID );
|
|||
|
VOID Xfer_FileInit( VOID );
|
|||
|
error_status_t Xfer_FileSetName( LPWSTR szName );
|
|||
|
VOID Xfer_FileSetTime( FILETIME * FileTime );
|
|||
|
error_status_t Xfer_SetPath( LPWSTR szPath );
|
|||
|
VOID Xfer_SetSize( BYTE4 b4Size );
|
|||
|
|
|||
|
|
|||
|
error_status_t _PutFileBody( HANDLE hFile, wchar_t FileName[] );
|
|||
|
error_status_t _SendFile( LPWSTR szFile );
|
|||
|
error_status_t _SendFolder( LPWSTR szFolder );
|
|||
|
error_status_t _FileStart( VOID );
|
|||
|
error_status_t _FileEnd( BOOL fSave );
|
|||
|
VOID _Send_StartXfer( __int64 dwTotalSize, LPWSTR szDst );
|
|||
|
VOID _Send_EndXfer( VOID );
|
|||
|
error_status_t _SetReceiveFolder( LPWSTR szFolder );
|
|||
|
|
|||
|
// for progress.c
|
|||
|
|
|||
|
DWORD _dwTimeStart;
|
|||
|
DWORD _dwSecondsLeft;
|
|||
|
int _CurrentPercentage;
|
|||
|
|
|||
|
VOID _FormatTime( LPWSTR sz, DWORD dwSeconds );
|
|||
|
|
|||
|
// for obex.c
|
|||
|
|
|||
|
DATA_CONN _dataRecv;
|
|||
|
DATA_PATH _dataPath;
|
|||
|
DATA_REPLY _dataReply;
|
|||
|
|
|||
|
ULONG _blocksSent;
|
|||
|
ULONG _blocksAcked;
|
|||
|
ULONG _blockSize;
|
|||
|
|
|||
|
__int64 _completedFilesSize;
|
|||
|
__int64 _currentFileSize;
|
|||
|
__int64 _currentFileAcked;
|
|||
|
|
|||
|
DWORD _lastAckTime;
|
|||
|
|
|||
|
error_status_t Obex_Abort( error_status_t status );
|
|||
|
error_status_t Obex_Connect( __int64 dwTotalSize );
|
|||
|
error_status_t Obex_Disconnect( error_status_t status );
|
|||
|
error_status_t Obex_PutBegin( LPWSTR wszObj, __int64 dwObjSize, FILETIME * pFileTime );
|
|||
|
error_status_t Obex_PutBody( wchar_t FileName[], LPBYTE1 pb1Data, BYTE2 b2DataSize, BOOL fFinal );
|
|||
|
error_status_t Obex_SetPath( LPWSTR wszPath );
|
|||
|
|
|||
|
BOOL Obex_ConsumePackets( XFER_TYPE xferType, error_status_t * pStatus );
|
|||
|
BOOL Obex_Init( VOID );
|
|||
|
BOOL Obex_ReceiveData( XFER_TYPE xferType, LPVOID lpvData, DWORD dwDataSize );
|
|||
|
VOID Obex_Reset( VOID );
|
|||
|
|
|||
|
error_status_t _WaitForReply( DWORD dwTimeout, BYTE1 b1NeededReply );
|
|||
|
error_status_t _Put( LPWSTR wszObj, __int64 dwObjSize, FILETIME * Time, LPBYTE1 pb1Data, BYTE2 b2DataSize, BOOL fFinal );
|
|||
|
error_status_t _Request( LPSTORE lpStore, BYTE1 b1NeededReply );
|
|||
|
error_status_t _Respond( LPSTORE lpStore );
|
|||
|
INT _ValidOpcode( OBEXSTATE state, BYTE1 b1Opcode );
|
|||
|
BOOL _HandleAbort( BYTE1 b1Opcode, BYTE2 b2Length );
|
|||
|
BOOL _HandleBadRequest( BYTE1 b1Opcode );
|
|||
|
BOOL _HandleConnect( BYTE1 b1Opcode, BYTE2 b2Length );
|
|||
|
BOOL _HandleDisconnect( BYTE1 b1Opcode, BYTE2 b2Length );
|
|||
|
BOOL _HandleNotImplemented( BYTE1 b1Opcode );
|
|||
|
error_status_t _HandlePut( BYTE1 b1Opcode, BYTE2 b2Length, BOOL fFinal );
|
|||
|
error_status_t _HandleResponse( BYTE1 b1Status, BYTE2 b2Length );
|
|||
|
error_status_t _HandleRequest( BYTE1 b1Opcode, BYTE2 b2Length );
|
|||
|
error_status_t _HandleSetPath( BYTE1 b1Opcode, BYTE2 b2Length );
|
|||
|
error_status_t _ParseParams( BYTE1 b1Opcode, BYTE2 b2Length );
|
|||
|
BOOL _PokePacketSizeIntoStore( LPSTORE lpStore );
|
|||
|
VOID _SetState( LPDATA_CONN lpDataConn, OBEXSTATE os );
|
|||
|
VOID _WaitInit( VOID );
|
|||
|
VOID _WriteBody( LPVOID lpvData, BYTE2 b2Size, BOOL fFinal );
|
|||
|
BYTE2 _SkipHeader( BYTE1 b1Param, LPSTORE lpStore );
|
|||
|
|
|||
|
BYTE1
|
|||
|
StatusToReplyCode(
|
|||
|
BYTE1 b1Opcode,
|
|||
|
DWORD status
|
|||
|
);
|
|||
|
|
|||
|
error_status_t
|
|||
|
ObexStatusToWin32(
|
|||
|
BYTE1 ObexStatus
|
|||
|
);
|
|||
|
|
|||
|
BOOL Activate();
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
error_status_t
|
|||
|
_GetObjListStats(
|
|||
|
LPWSTR lpszObjList,
|
|||
|
LPDWORD lpdwFiles,
|
|||
|
LPDWORD lpdwFolders,
|
|||
|
__int64 * pTotalSize
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
ReportFileError( DWORD mc,
|
|||
|
WCHAR * file,
|
|||
|
DWORD error
|
|||
|
);
|
|||
|
|
|||
|
BYTE1 WinErrorToObexError( DWORD Win32Error );
|
|||
|
|
|||
|
|
|||
|
BOOL IsWorkstationLocked();
|
|||
|
|
|||
|
extern RPC_BINDING_HANDLE rpcBinding;
|
|||
|
extern BOOL g_fAllowReceives;
|
|||
|
extern wchar_t g_DuplicateFileTemplate[];
|
|||
|
extern wchar_t g_UnknownDeviceName[];
|
|||
|
extern MUTEX * g_Mutex;
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
extern "C" {
|
|||
|
|
|||
|
FILE_TRANSFER* InitializeSocket(
|
|||
|
char ServiceName[]
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
FILE_TRANSFER *
|
|||
|
ListenForTransfer(
|
|||
|
SOCKET ListenSocket,
|
|||
|
OBEX_DEVICE_TYPE DeviceType
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
FILE_TRANSFER*
|
|||
|
InitializeSocket(
|
|||
|
char ServiceName[]
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#endif // _XFER_H_
|