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

📄 filesvr.cxx

📁 这个是微软WINCE的OBEX协议例子
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
//    Known problems:
//        1. Encodes XML stream into multibytes, not UTF-8
//
#include <windows.h>
#include <obexparser.h>
#include <obexserver.h>
#include <stdio.h>
#include <tchar.h>
#include <winsock.h>
#include <svslog.hxx>

#include "MD5.h"

#define OBEX_FTP_DEBUG_REG L"Software\\Microsoft\\Obex"
#define OBEX_FTP_BASE_REG  OBEX_KEY_SERVERS L"\\{F9ec7bc4-953c-11d2-984e-525400dc9e09}"
#define OBEX_FTP_BASE_DIR  L"\\temp\\ftp"

#define DEBUG_FTP_TRACE        0x00000002

#define OBEX_FTP_MAXPACKET    32 * 1024
#define OBEX_BIGBUFFER            1024
#define OBEX_SMALLBUFFER        128

#define OBEX_TIMEOUT_AUTHENTICATIONS_AFTER_N_MILLISEC  5000

#define CRLF                    L"\r\n"




enum CURRENT_OP {
    NONE,
    SEND,
    RECEIVE,
    FILELIST
};


class AuthList
{
    public:
      BYTE challenge[16];    
      BYTE nonce[18]; //target+size+nonce
      AuthList *pNext;
      DWORD startTime;
};


class FileXFer {
public:
    FileXFer        *pNext;
    WCHAR            szCurDir[_MAX_PATH];
    WCHAR            szBaseDir[_MAX_PATH];
    WCHAR            szCurFile[_MAX_PATH];
    BYTE             nonce[18];
    
    BOOL            fIsAuthenticated;
    BOOL            fNonceSet;
    BOOL            fNameHeaderFound;
    BOOL            fDir;

    unsigned int    uiConnectionId;
    unsigned int    uiPacketLimit;

    CURRENT_OP        op;

    HANDLE            hFile;

    unsigned char    *ucListing;

    int                cListingSize;
    int                cCompleted;
};

class MemStream {
    unsigned char    *ucBuffer;

    int                cAllocated;
    int                cFilled;

    MemAlloc        alloc;
    MemFree         free;

public:
    MemStream (MemAlloc ma, MemFree mf) {
        memset (this, 0, sizeof(*this));

        alloc = ma;
        free = mf;
    }

    int Length (void) {
        return cFilled > 0 ? cFilled - 1 : 0;
    }

    unsigned char *Buffer (void) {
        return ucBuffer;
    }

    int wSTREAMprintf (WCHAR *lpszFormat, ...) {
    
        if(!alloc || !free)
            return FALSE;
            
        va_list args;
        va_start (args, lpszFormat);

        WCHAR szBigBuffer[OBEX_BIGBUFFER];
        wvsprintf (szBigBuffer, lpszFormat, args);

        va_end (args);

        int cNewNeeded = WideCharToMultiByte (CP_ACP, 0, szBigBuffer, -1, NULL, 0, NULL, NULL);

        if (cNewNeeded <= 0)
            return FALSE;

        if (cAllocated < cFilled + cNewNeeded - 1) {
            unsigned char *sz = (unsigned char *)alloc (cFilled + cNewNeeded - 1 + OBEX_SMALLBUFFER);

            if (! sz)
                return FALSE;

            cAllocated = cFilled + cNewNeeded - 1 + OBEX_SMALLBUFFER;

            if (ucBuffer)
            {
                memcpy (sz, ucBuffer, cFilled);
                free(ucBuffer);
            }

            ucBuffer = sz;
        }

        if (cFilled > 0)
            cFilled -= 1;    // account for extra 0

        WideCharToMultiByte (CP_ACP, 0, szBigBuffer, -1, (char *)&ucBuffer[cFilled], cNewNeeded, NULL, NULL);
        cFilled += cNewNeeded;

        return cFilled;
    }
};


//functions
static int HandlePacketAuthentication(ObexTransaction *pOT, FileXFer *pConn);


//globals
static HMODULE                g_hMod;
static CRITICAL_SECTION    g_cs;
static FileXFer            *g_pConn = NULL;
static AuthList            *g_pAuthList = NULL;

//////////////////////////////////////////////////////////////////////
// Utility section
//////////////////////////////////////////////////////////////////////

static HRESULT MakeResponse (const WCHAR *_pszPassToUse, BYTE *bChallenge, BYTE *bResponse) {
    INT cp = CP_UTF8;

    UCHAR ucPassLen = WideCharToMultiByte(cp, 0, _pszPassToUse, -1, NULL, 0, NULL, NULL);

    if (! ucPassLen)
    {
        cp = CP_ACP;
        ucPassLen = WideCharToMultiByte(cp, 0, _pszPassToUse, -1, NULL, 0, NULL, NULL);
    }

    if (! ucPassLen)
        return E_FAIL;    

    UINT uiEncodeSize = 16 + 1 + ucPassLen;
    BYTE bEncodeBuffer[512];
    BYTE *bToEncode = (uiEncodeSize > sizeof(bEncodeBuffer)) ? new BYTE[uiEncodeSize] : bEncodeBuffer;

    if (! bToEncode)
        return E_FAIL;    

    memcpy (bToEncode, bChallenge, 16);

    bToEncode[16] = ':';

    HRESULT hr = E_FAIL;

    if (WideCharToMultiByte (cp, 0, _pszPassToUse, -1, (char *)(bToEncode + 17), ucPassLen, NULL, NULL))
    {
        MD5(bResponse, bToEncode, uiEncodeSize - 1);    // -1 because we don't want terminating '\0'
        hr = ERROR_SUCCESS;
    }

    if (bToEncode != bEncodeBuffer)
        delete [] bToEncode;

    return ERROR_SUCCESS;
}

static HRESULT MakeNonce (const WCHAR *_pszPassToUse, BYTE *bMyNonce)
{
    SYSTEMTIME st;
    GetSystemTime(&st); 

    INT cp = CP_UTF8;

    UCHAR ucPassLen = WideCharToMultiByte(cp, 0, _pszPassToUse, -1, NULL, 0, NULL, NULL);

    if (! ucPassLen)
    {
        cp = CP_ACP;
        ucPassLen = WideCharToMultiByte(cp, 0, _pszPassToUse, -1, NULL, 0, NULL, NULL);
    }

    if (! ucPassLen)
        return E_FAIL;    

    UINT uiEncodeSize = 16 + 1 + ucPassLen;
    BYTE bEncodeBuffer[512];
    BYTE *bToEncode = (uiEncodeSize > sizeof(bEncodeBuffer)) ? new BYTE[uiEncodeSize] : bEncodeBuffer;

    if (! bToEncode)
        return E_FAIL;    

    //16 bytes plus NULL ... so its okay to directly write in bToEncode... the NULL will be replaced!
    sprintf((char *)bToEncode, "%4.4d%2.2d%2.2dT%2.2d%2.2d%2.2dZ", st.wYear,st.wMonth,st.wDay, st.wHour,st.wMinute,st.wSecond);
    SVSUTIL_ASSERT(16 == strlen((char *)bToEncode));

    bToEncode[16] = ':';

    HRESULT hr = E_FAIL;

    if (WideCharToMultiByte (cp, 0, _pszPassToUse, -1, (char *)(bToEncode + 17), ucPassLen, NULL, NULL))
    {
        MD5(bMyNonce, bToEncode, uiEncodeSize - 1);    // -1 because we don't want terminating '\0'
        hr = ERROR_SUCCESS;
    }

    if (bToEncode != bEncodeBuffer)
        delete [] bToEncode;

    return hr;
}

static int CheckNameForValidity (WCHAR *szName) {
    if (wcscmp (szName, L"..") == 0)
        return FALSE;

    if (wcscmp (szName, L".") == 0)
        return FALSE;

    while (*szName != '\0') {
        if (*szName == '\\')
            return FALSE;
        if (*szName == '/')
            return FALSE;
        ++szName;
    }

    return TRUE;
}

static void GetTimeString (WCHAR *szBuf, FILETIME ft) {
    SYSTEMTIME st;
    FileTimeToSystemTime (&ft, &st);
    wsprintf (szBuf, L"%04d%02d%02dT%02d%02d%02dZ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
}

static int GetDirListing (FileXFer *pConn, ObexTransaction *pOT) {
    IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] Getting dir listing for %s\n", pConn->szCurFile));

    //if alloc/free functions are null return
    if(!pOT->ObexAlloc || !pOT->ObexFree)
        return FALSE;

    //if its the root directory, dont put in the \\'s   
    UINT strLen = wcslen(pConn->szCurFile);
    if(strLen && ('\\' == pConn->szCurFile[strLen-1])) 
        pConn->szCurFile[strLen-1] = 0;

    DWORD dwAttr = GetFileAttributes (pConn->szCurFile);
    if ((dwAttr == 0xffffffff) || ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0))
        return FALSE;

    wcscat (pConn->szCurFile, L"\\*.*");

    MemStream stm (pOT->ObexAlloc, pOT->ObexFree);

    if(!stm.wSTREAMprintf (L"<?xml version=\"1.0\"?>" CRLF))
        return FALSE;
        
    if(!stm.wSTREAMprintf (L"<!DOCTYPE folder-listing SYSTEM \"obex-folder-listing.dtd\">" CRLF))
        return FALSE;
        
    if(!stm.wSTREAMprintf (L"<folder-listing version=\"1.0\">" CRLF))
        return FALSE;

    WCHAR *pPath = wcsrchr(pConn->szCurDir, L'\\');
    stm.wSTREAMprintf (L"  <parent-folder name=\"%s\" />" CRLF, (pPath) ? (pPath+1) : pConn->szCurDir);

    WIN32_FIND_DATA wfd;

    HANDLE hSearch = FindFirstFile (pConn->szCurFile, &wfd);

    if (hSearch != INVALID_HANDLE_VALUE) {
        do {
            WCHAR szDateBuf[30];
            GetTimeString (szDateBuf, wfd.ftCreationTime);

            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                stm.wSTREAMprintf (L"  <folder name=\"%s\" created=\"%s\"/>" CRLF, wfd.cFileName, szDateBuf);
            else
                stm.wSTREAMprintf (L"  <file name=\"%s\" created=\"%s\" size=\"%d\"/>" CRLF, wfd.cFileName, szDateBuf, wfd.nFileSizeLow);
        } while (FindNextFile (hSearch, &wfd));
        FindClose(hSearch);
    }

    stm.wSTREAMprintf (L"</folder-listing>" CRLF);

    pConn->op = FILELIST;

    pConn->cListingSize = stm.Length ();
    pConn->cCompleted = 0;
    pConn->ucListing = stm.Buffer ();
    return TRUE;
}

static void CloseConnection (ObexTransaction *pOT, FileXFer *pConn) {
    IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] Closing the connection 0x%08x\n", pConn->uiConnectionId));

    if ((pConn->op == SEND) || (pConn->op == RECEIVE)) {
        if (pConn->hFile != INVALID_HANDLE_VALUE)
            CloseHandle (pConn->hFile);
    } else if (pConn->op == FILELIST) {
        if (pConn->ucListing)
            pOT->ObexFree (pConn->ucListing);
    }
    
    pOT->ObexFree (pConn);
}


DWORD CanWrite() 
{
    HKEY hk;
    DWORD fCanWrite = FALSE;
            
    //
    //  Fetch the read only bit from the registry
    if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, OBEX_FTP_BASE_REG, 0, KEY_READ, &hk)) 
    {             

⌨️ 快捷键说明

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