📄 inbox.cxx
字号:
//
// 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.
//
/**************************************************************************/
/* Inbox.cpp */
/* */
/* This file contains routines to process the default inbox */
/* */
/* *'ed Functions are DLL entry points */
/* */
/* Functions included: */
/* CloseConnection -- clean up a connection that has ended */
/* ServiceRequest -- process a request (GET/PUT/CONNECT/etc) */
/* *DllServiceCallback -- the entry point from the OBEX server */
/* *DllRegisterServer -- init any required vars that can't be done*/
/* in DLL main */
/* *DllUnregisterServer -- undoes DllRegisterServer */
/* *DllMain -- init critical sections */
/* */
/* Other related files: */
/* */
/* */
/**************************************************************************/
#include <windows.h>
#include <obexparser.h>
#include <obexserver.h>
#include <stdio.h>
#include <tchar.h>
#include <winsock.h>
//MAX_GET_HEADER_SIZE plus the # byes of data sent must be
// <= the max packet size given by the client
#define MAX_GET_HEADER_SIZE 20
#define OBEX_PROMPT_BEFORE_UPLOAD L"PromptBeforeUpload"
#define OBEX_PROMT_OVERWRITE L"PromptForOverwrite"
#define OBEX_INBOX_MIME_REG OBEX_KEY_SERVERS L"\\{00000000-0000-0000-0000-000000000000}\\MimeTypes"
#define OBEX_INBOX_BASE_REG OBEX_KEY_SERVERS L"\\{00000000-0000-0000-0000-000000000000}"
#define OBEX_INBOX_DEBUG_REG L"Software\\Microsoft\\Obex"
#define DEBUG_INBOX_TRACE 0x00000001
#define OBEX_INBOX_MAXPACKET 1024
typedef BOOL (*OBEXClientPFunct) (LPCTSTR objectName);
//the location of the inbox directory
static WCHAR szInboxDir[MAX_PATH];
//global variables
static CRITICAL_SECTION g_cs;
static HINSTANCE g_hMod;
//debug zones
#define INBOX_GENERAL_ZONE DEBUGZONE(0)
#define INBOX_CONNECT_ZONE DEBUGZONE(1)
#define INBOX_DISCONNECT_ZONE DEBUGZONE(2)
#define INBOX_GET_ZONE DEBUGZONE(3)
#define INBOX_PUT_ZONE DEBUGZONE(4)
#define INBOX_SERVICE_ZONE DEBUGZONE(5)
#define INBOX_ABORT_ZONE DEBUGZONE(6)
#if defined(DEBUG) || defined(_DEBUG)
void *operator new(UINT size)
{
return g_funcAlloc(size, 0);
}
void operator delete(void *pVoid)
{
g_funcFree(pVoid, 0);
}
#endif
#define NO_MODE 0
#define PUT_MODE 1
#define GET_MODE 2
class InboxState {
public:
InboxState() {
pNext = NULL;
pFileChunk = NULL;
uiConnectionId = 0;
uiPacketLimit = 0;
uiBytesSent = 0;
uiBytesRecv = 0;
uiMode = NO_MODE;
hFile = INVALID_HANDLE_VALUE;
szFileName = NULL;
szName = NULL;
}
~InboxState() {
ASSERT(NULL == szFileName);
ASSERT(NULL == szName);
ASSERT(INVALID_HANDLE_VALUE == hFile);
ASSERT(NULL == pFileChunk);
}
//pointer to next item in InboxState linked list (each node represents a
// connection)
InboxState *pNext;
//pointer to memory that is used to buffer the file before going onto
// disk
unsigned char *pFileChunk;
//unique ID of the connection
unsigned int uiConnectionId;
//max size of a packet
unsigned int uiPacketLimit;
//number of bytes that have been sent
unsigned int uiBytesSent;
//number of bytes that have been written to file
unsigned int uiBytesRecv;
//the current mode we are in
unsigned int uiMode;
//handle to output file
HANDLE hFile;
//pointer to the name of the file (the output name)
LPTSTR szFileName;
//pointer to the name of the object (specified by the NAME field)
LPTSTR szName;
};
//pointer to the linked list of ongoing connections
static InboxState *g_pConn = NULL;
#if defined (SDK_BUILD)
static int GetTempFileName(WCHAR *szBaseDir, WCHAR *szPrefix, int iIndex,WCHAR *szTargetName) {
int c = wcslen (szBaseDir);
int fHasSlash = ((c > 0) && (szBaseDir[c - 1] == '\\')) ? TRUE : FALSE;
for (int i = iIndex ; i != iIndex - 1 ; ++i) {
if (fHasSlash)
wsprintf (szTargetName, L"%s%s%d.tmp", szBaseDir, szPrefix, i);
else
wsprintf (szTargetName, L"%s\\%s%d.tmp", szBaseDir, szPrefix, i);
if (GetFileAttributes (szTargetName) == 0xffffffff)
break;
}
if (i != iIndex - 1)
return TRUE;
return FALSE;
}
#endif
// Return flags for PathGetCharType
#define GCT_INVALID 0x0000
#define GCT_LFNCHAR 0x0001
#define GCT_SHORTCHAR 0x0002
#define GCT_WILD 0x0004
#define GCT_SEPARATOR 0x0008
/*****************************************************************************/
/* PathGetCharType */
/* returns the character type */
/*****************************************************************************/
UINT PathGetCharType(TCHAR ch)
{
switch (ch)
{
case TEXT('|'):
case TEXT('>'):
case TEXT('<'):
case TEXT('"'):
case TEXT('/'):
return GCT_INVALID;
case TEXT('?'):
case TEXT('*'):
return GCT_WILD;
case TEXT('\\'): // path separator
case TEXT(':'): // drive colon
return GCT_SEPARATOR;
case TEXT(';'):
case TEXT(','):
case TEXT(' '):
return GCT_LFNCHAR; // actually valid in short names
// but we want to avoid this
default:
if (ch > TEXT(' '))
{
return GCT_SHORTCHAR | GCT_LFNCHAR;
}
else
{
// control character
return GCT_INVALID;
}
}
}
/*****************************************************************************/
/* PathIsValidFileName */
/* returns true if the filename passed is okay (no invalid chars */
/*****************************************************************************/
BOOL WINAPI PathIsValidFileName(LPCTSTR pPath)
{
if (pPath) {
while (*pPath) {
if ( ! (PathGetCharType(*pPath) & (GCT_SHORTCHAR|GCT_LFNCHAR))) {
return FALSE;
}
pPath ++;
}
return TRUE;
}
return FALSE;
}
/*****************************************************************************/
/* RetrieveServiceDLL */
/* retrive the service DLL name from the registry based on mime type or ext*/
/* */
/* Begin by enuming through the k_szRegPathMIME keys looking for the */
/* correct extension, when found return FALSE (success) else return TRUE */
/*****************************************************************************/
int RetrieveServiceDLL(WCHAR *psMimeType,
WCHAR *pszExtension,
WCHAR *pszDest,
DWORD *uiDestSize) {
DEBUGMSG(INBOX_SERVICE_ZONE, (L"[OBEX-INBOX] RetrieveServiceDLL %s %s\n", psMimeType ? psMimeType : L"<no mtype>", pszExtension ? pszExtension : L"<no ext>"));
HKEY hMainMIMEKey;
DWORD dwType, dwRes;
int iError = ERROR_NOT_FOUND;
//open the main MIME registry key, and enumerate through it
if ((ERROR_SUCCESS == (dwRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
OBEX_INBOX_MIME_REG, 0, KEY_QUERY_VALUE, &hMainMIMEKey)))) {
UINT indx = 0;
WCHAR szMIMEName[MAX_PATH];
DWORD uiNameSize = MAX_PATH;
HKEY hMIMEKey;
//if a MIME type was given, use it (it will be quicker than searching)
if(psMimeType) {
if ((ERROR_SUCCESS == (dwRes = RegOpenKeyEx(hMainMIMEKey,
psMimeType, 0, KEY_QUERY_VALUE, &hMIMEKey)))) {
DWORD dwOldSize = *uiDestSize;
if((ERROR_SUCCESS == (dwRes = RegQueryValueEx(hMIMEKey,
L"DLL", NULL, &dwType, (LPBYTE)pszDest,
uiDestSize))))
iError = ERROR_SUCCESS;
else
*uiDestSize = dwOldSize;
RegCloseKey(hMIMEKey);
}
}
//if MIME failed, or was not given try enuming through all the keys
while((iError != ERROR_SUCCESS) && (ERROR_SUCCESS == RegEnumKeyEx(hMainMIMEKey, indx, szMIMEName,&uiNameSize,0,0,0,0))) {
//see if this is the correct key
if ((ERROR_SUCCESS == (dwRes = RegOpenKeyEx(hMainMIMEKey,
szMIMEName, 0, KEY_QUERY_VALUE, &hMIMEKey)))) {
//fetch the file extension
WCHAR szRegExtension[MAX_PATH];
DWORD dwExtensionSize = MAX_PATH;
if((ERROR_SUCCESS == (dwRes = RegQueryValueEx(hMIMEKey,
L"Extension", NULL, &dwType, (LPBYTE)szRegExtension,
&dwExtensionSize)))) {
//see if the extensions match, if so, return success
if(0 == wcscmp(szRegExtension, pszExtension)) {
DWORD dwOldSize = *uiDestSize;
if((ERROR_SUCCESS == (dwRes = RegQueryValueEx(hMIMEKey,
L"DLL", NULL, &dwType, (LPBYTE)pszDest, uiDestSize))))
iError = ERROR_SUCCESS;
else
*uiDestSize = dwOldSize;
RegCloseKey(hMIMEKey);
break;
}
}
RegCloseKey(hMIMEKey);
}
indx ++;
uiNameSize = MAX_PATH;
}
RegCloseKey(hMainMIMEKey);
}
DEBUGMSG(INBOX_SERVICE_ZONE, (L"[OBEX-INBOX] RetrieveServiceDLL returns %d <%s>\n", iError, iError == ERROR_SUCCESS ? pszDest : L""));
return iError;
}
/*****************************************************************************/
/* ResetConnection */
/* Clean up everything but the state structure */
/* */
/*****************************************************************************/
static void ResetConnection(InboxState *pConn)
{
DEBUGMSG(INBOX_GENERAL_ZONE, (L"[OBEX-INBOX] Reseting inbox connection 0x%08x\n", pConn->uiConnectionId));
//close our filehandle
if(pConn->hFile != INVALID_HANDLE_VALUE)
{
DEBUGMSG(INBOX_GENERAL_ZONE, (L"[OBEX-INBOX] closing file: %s\n", pConn->szName));
CloseHandle(pConn->hFile);
}
//do some memory cleaup
if(pConn->szFileName)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -